This commit is contained in:
13121765685 2025-12-16 17:29:32 +08:00
parent b86e6fb285
commit d0ad3fcad9
11 changed files with 97 additions and 106 deletions

View File

@ -62,7 +62,7 @@ onMounted(() => {
<!-- <div v-if="qmLoading" class="sidebar-overlay" :class="{ 'sidebar-overlay-active': qmLoading }"></div> --> <!-- <div v-if="qmLoading" class="sidebar-overlay" :class="{ 'sidebar-overlay-active': qmLoading }"></div> -->
<LoadingCom v-if="qmLoading" /> <LoadingCom v-if="qmLoading" />
<!-- 登录页面全屏显示 --> <!-- 登录页面全屏显示 -->
<main style="position: relative;" v-if="isLoginPage"> <main style="position: relative;height: 100%;width: 100%;" v-if="isLoginPage">
<!-- <div v-if="loading" class="sidebar-overlay" :class="{ 'sidebar-overlay-active': loading }"></div> --> <!-- <div v-if="loading" class="sidebar-overlay" :class="{ 'sidebar-overlay-active': loading }"></div> -->
<LoadingCom v-if="loading" /> <LoadingCom v-if="loading" />
<router-view /> <router-view />
@ -74,7 +74,7 @@ onMounted(() => {
<router-view /> <router-view />
</main> </main>
<!-- 应用内页面使用布局组件 --> <!-- 应用内页面使用布局组件 -->
<div v-else style="position: relative;"> <div v-else style="position: relative;height: 100%;">
<MainLayout :loading="loading" > <MainLayout :loading="loading" >
<template #header> <template #header>
<AppHeader /> <AppHeader />
@ -93,52 +93,35 @@ onMounted(() => {
</div> </div>
</template> </template>
<style> <style>
*{
box-sizing: border-box;
outline:0;
/* margin: 0;
padding: 0; */
}
body,html{
width: 100%;
height: 100%;
}
#app,#app-container{
width: 100%;
height: 100%;
}
#nprogress .bar { #nprogress .bar {
/* 自定义加载条颜色 */ /* 自定义加载条颜色 */
background: #9c7eef !important; /* Element Plus 主色 */ background: #9c7eef !important; /* Element Plus 主色 */
height: 2px !important; /* 高度 */ height: 2px !important; /* 高度 */
border-radius: 0 !important; border-radius: 0 !important;
} }
</style> </style>
<style scoped> <style scoped>
header strong { font-size: 1.25rem; } header strong { font-size: 1.25rem; }
/* 应用容器基础样式 */
#app-container {
width: 100vw;
min-height: 98vh;
margin: 0;
padding: 0;
/* 移除 overflow: hidden 以允许页面滚动 */
}
/* 登录模式样式 - 全屏显示 */
#app-container.login-mode {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
}
#app-container.login-mode main { #app-container.login-mode main {
width: 100% !important; width: 100% !important;
height: 100% !important; height: 100% !important;
margin: 0 !important; margin: 0 !important;
padding: 0 !important; padding: 0 !important;
} overflow: hidden;
/* 全屏模式样式 */
#app-container.fullscreen-mode {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
overflow: auto !important; /* 允许全屏内容滚动 */
} }
.fullscreen-content { .fullscreen-content {
@ -149,14 +132,6 @@ header strong { font-size: 1.25rem; }
position: relative; position: relative;
} }
/* 首页全屏滚动模式 - 使用浏览器原生滚动 */
#app-container.homepage-mode {
width: 100vw;
min-height: 100vh;
position: relative;
overflow: visible; /* 允许浏览器原生滚动 */
}
.homepage-content { .homepage-content {
width: 100vw; width: 100vw;
min-height: 100vh; min-height: 100vh;
@ -187,10 +162,4 @@ html.dark .navigation-buttons .el-button--primary:hover {
border-color: #7C3AED !important; border-color: #7C3AED !important;
} }
</style> </style>
<style>
*{
box-sizing: border-box;
outline:0;
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="ip-card-container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" @touchstart="handleTouchStart" @touchend="handleTouchEnd" :class="{ 'controls-visible': isControlsVisible }"> <div class="ip-card-container" @touchstart="handleTouchStart" @touchend="handleTouchEnd" :class="{ 'controls-visible': isControlsVisible }">
<!-- 主卡片区域 --> <!-- 主卡片区域 -->
<div class="ip-card-wrapper"> <div class="ip-card-wrapper">
<!-- 文本输入框弹出层 --> <!-- 文本输入框弹出层 -->
@ -7,7 +7,7 @@
<div class="text-input-container"> <div class="text-input-container">
<div class="text-input-header"> <div class="text-input-header">
<div class="text-input-title">文本输入</div> <div class="text-input-title">文本输入</div>
<button class="text-input-close" @click="handleTextInputCancel" aria-label="关闭"> <button class="text-input-close" @click="handleTextInputCancel" @touchend.prevent="handleTextInputCancel" aria-label="关闭">
<el-icon class="close-icon"><CloseBold /></el-icon> <el-icon class="close-icon"><CloseBold /></el-icon>
</button> </button>
</div> </div>
@ -23,10 +23,10 @@
@mousedown.stop @mousedown.stop
></textarea> ></textarea>
<div class="text-input-actions"> <div class="text-input-actions">
<button class="text-input-btn cancel-btn" @click="handleTextInputCancel"> <button class="text-input-btn cancel-btn" @click="handleTextInputCancel" @touchend.prevent="handleTextInputCancel">
取消 取消
</button> </button>
<button class="text-input-btn confirm-btn" @click="handleTextInputConfirm"> <button class="text-input-btn confirm-btn" @click="handleTextInputConfirm" @touchend.prevent="handleTextInputConfirm">
确定 确定
</button> </button>
</div> </div>
@ -59,20 +59,18 @@
<div class="right-controls-container" v-if="formData.internalImageUrl"> <div class="right-controls-container" v-if="formData.internalImageUrl">
<!-- 右侧圆形按钮控件 --> <!-- 右侧圆形按钮控件 -->
<div class="right-circular-controls"> <div class="right-circular-controls">
<button class="control-button share-btn" title="Preview Image" @click="handleImageClick"> <button class="control-button share-btn" title="Preview Image" @click="handleImageClick" @touchend.prevent="handleImageClick">
<el-icon class="btn-icon"><View /></el-icon> <el-icon class="btn-icon"><View /></el-icon>
</button> </button>
<button v-if="!(props.cardData.imgyt)" class="control-button share-btn" title="model" @click="handleGenerateModel"> <button v-if="!(props.cardData.imgyt)" class="control-button share-btn" title="model" @click="handleGenerateModel" @touchend.prevent="handleGenerateModel">
<el-icon class="btn-icon"><Cpu /></el-icon> <el-icon class="btn-icon"><Cpu /></el-icon>
</button> </button>
<button v-if="!(props.cardData.imgyt)" class="control-button share-btn" title="textInput" @click="toggleTextInput"> <button v-if="!(props.cardData.imgyt)" class="control-button share-btn" title="textInput" @click="toggleTextInput" @touchend.prevent="toggleTextInput">
<el-icon class="btn-icon"><ChatDotRound /></el-icon> <el-icon class="btn-icon"><ChatDotRound /></el-icon>
</button> </button>
<button v-if="!(props.cardData.imgyt)" class="control-button share-btn" title="scene graph" @click="handleTextcjt" @touchend.prevent="handleTextcjt">
<button v-if="!(props.cardData.imgyt)" class="control-button share-btn" title="scene graph" @click="handleTextcjt">
<el-icon class="btn-icon"><Grid /></el-icon> <el-icon class="btn-icon"><Grid /></el-icon>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
@ -100,12 +98,8 @@ const isTouching = ref(false);
const isControlsVisible = ref(false); const isControlsVisible = ref(false);
const cjimg = 'https://draft-user.s3.us-east-2.amazonaws.com/images/14f98f33-06a7-4629-a42e-d7cfbced786f'; const cjimg = 'https://draft-user.s3.us-east-2.amazonaws.com/images/14f98f33-06a7-4629-a42e-d7cfbced786f';
const anTypeImg = 'https://draft-user.s3.us-east-2.amazonaws.com/images/1e82b2b6-0e5d-4a62-b65f-098952eb2f67'; const anTypeImg = 'https://draft-user.s3.us-east-2.amazonaws.com/images/1e82b2b6-0e5d-4a62-b65f-098952eb2f67';
const humanTypeImg = 'https://draft-user.s3.us-east-2.amazonaws.com/images/6569f75b-5534-49f4-9c3a-68eb35def196'; const humanTypeImg = 'https://draft-user.s3.us-east-2.amazonaws.com/images/e3e60cc7-9777-41ba-9d1e-f5ffc92e4fac.webp';
const giminiServer = new GiminiServer(); const giminiServer = new GiminiServer();
//
const showRightControls = ref(false);
//
const isHovered = ref(false);
// //
const imageAspectRatio = ref(9/16); // const imageAspectRatio = ref(9/16); //
// //
@ -114,20 +108,12 @@ const showTextInput = ref(false);
const textInputValue = ref(''); const textInputValue = ref('');
// //
const textInputRef = ref(null); const textInputRef = ref(null);
//
const handleMouseEnter = () => {
isHovered.value = true;
};
const handleImageClick = () => { const handleImageClick = () => {
// //
emit('preview-image', formData.value.internalImageUrl); emit('preview-image', formData.value.internalImageUrl);
} }
//
const handleMouseLeave = () => {
isHovered.value = false;
//
showRightControls.value = false;
};
// / // /
const toggleTextInput = () => { const toggleTextInput = () => {
showTextInput.value = !showTextInput.value; showTextInput.value = !showTextInput.value;
@ -157,7 +143,8 @@ const handleTextInputConfirm = () => {
emit('create-prompt-card', { emit('create-prompt-card', {
img: formData.value.internalImageUrl, img: formData.value.internalImageUrl,
diyPromptText:textInputValue.value, diyPromptText:textInputValue.value,
generateFourView:props.generateFourView generateFourView:props.generateFourView,
cardData: props.cardData
}); });
showTextInput.value = false; showTextInput.value = false;
textInputValue.value = ''; textInputValue.value = '';
@ -171,11 +158,9 @@ const handleTextInputCancel = () => {
// //
const handleTouchStart = () => { const handleTouchStart = () => {
isTouching.value = true; isTouching.value = true;
setTimeout(() => {
if (isTouching.value) { if (isTouching.value) {
isControlsVisible.value = true; isControlsVisible.value = true;
} }
}, 200); //
}; };
// //
const handleTouchEnd = () => { const handleTouchEnd = () => {
@ -722,8 +707,26 @@ const handleImageLoad = (event) => {
pointer-events: auto; pointer-events: auto;
} }
/* 在 iPad 及更大触控屏上,按下即显示右侧圆形控件 */
@media (hover: none) and (pointer: coarse) {
.ip-card-container:active .right-circular-controls,
.ip-card-container.controls-visible .right-circular-controls {
opacity: 1;
transform: translateX(0);
pointer-events: auto;
}
}
/* 非触控设备保持 hover 显示 */
@media (hover: hover) {
.ip-card-container:hover .right-circular-controls {
opacity: 1;
transform: translateX(0);
pointer-events: auto;
}
}
/* 移动端适配:点击卡片后显示功能按钮 */ /* 移动端适配:点击卡片后显示功能按钮 */
@media (max-width: 768px) { @media (max-width: 1024px) {
/* 点击卡片容器时显示功能按钮 */ /* 点击卡片容器时显示功能按钮 */
.ip-card-container:active .right-circular-controls, .ip-card-container:active .right-circular-controls,
.ip-card-container.controls-visible .right-circular-controls { .ip-card-container.controls-visible .right-circular-controls {
@ -928,7 +931,7 @@ const handleImageLoad = (event) => {
} }
/* 响应式设计 */ /* 响应式设计 */
@media (max-width: 768px) { @media (max-width: 1024px) {
.ip-card-container { .ip-card-container {
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;

View File

@ -296,7 +296,7 @@ const formData = ref({
const textareaRef = ref(null); const textareaRef = ref(null);
const fileInput = ref(null); // const fileInput = ref(null); //
const generateCount = ref(1); // 1 const generateCount = ref(4); // 1
const isOptimizing = ref(false); // const isOptimizing = ref(false); //
const isDragOver = ref(false); // const isDragOver = ref(false); //
const isUploading = ref(false); // const isUploading = ref(false); //

View File

@ -153,7 +153,7 @@ watch(() => window.location.pathname, () => {
.main-layout { .main-layout {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 100vh; height: 100%;
/* 移除 overflow: hidden 以允许页面滚动 */ /* 移除 overflow: hidden 以允许页面滚动 */
position: relative; position: relative;
} }
@ -172,7 +172,7 @@ watch(() => window.location.pathname, () => {
.content-row { .content-row {
display: flex; display: flex;
/* flex: 1; */ /* flex: 1; */
height: calc(100vh - 100px); height: calc(100% - 64px);
/* overflow: hidden; */ /* overflow: hidden; */
} }
@ -188,6 +188,7 @@ watch(() => window.location.pathname, () => {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
} }
@ -208,7 +209,6 @@ watch(() => window.location.pathname, () => {
position: relative; position: relative;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
background-color: red;
} }
.breadcrumb-container { .breadcrumb-container {

View File

@ -1,9 +1,8 @@
<template> <template>
<div <div
class="ip-card-container" class="ip-card-container"
@mouseenter="handleMouseEnter"
@mouseleave="handleMouseLeave" @mouseleave="handleMouseLeave"
@touchstart="handleTouchStart" @touchstart="handleTouchStart"
@touchend="handleTouchEnd" @touchend="handleTouchEnd"
:class="{ 'controls-visible': isControlsVisible }" :class="{ 'controls-visible': isControlsVisible }"
> >
@ -64,7 +63,7 @@
<div class="right-controls-container" @click.stop> <div class="right-controls-container" @click.stop>
<!-- 右侧圆形按钮控件 --> <!-- 右侧圆形按钮控件 -->
<div class="right-circular-controls" v-if="currentModelUrl"> <div class="right-circular-controls" v-if="currentModelUrl">
<button class="control-button rotate-btn" title="detail" @click="handleCardClick"> <button class="control-button rotate-btn" title="detail" @click="handleCardClick" @touchend.prevent="handleCardClick">
<span class="btn-icon">🔍</span> <span class="btn-icon">🔍</span>
</button> </button>
<!-- <button class="control-button export-btn" @click="exportModel"> <!-- <button class="control-button export-btn" @click="exportModel">
@ -203,10 +202,7 @@ onMounted(() => {
} }
}); });
//
const handleMouseEnter = () => {
// CSS
};
// //
const handleMouseLeave = () => { const handleMouseLeave = () => {
@ -217,11 +213,9 @@ const handleMouseLeave = () => {
// //
const handleTouchStart = () => { const handleTouchStart = () => {
isTouching.value = true; isTouching.value = true;
setTimeout(() => {
if (isTouching.value) { if (isTouching.value) {
isControlsVisible.value = true; isControlsVisible.value = true;
} }
}, 100); //
}; };
// //
@ -603,7 +597,7 @@ justify-content: center;
} }
/* 移动端适配:点击卡片后显示功能按钮 */ /* 移动端适配:点击卡片后显示功能按钮 */
@media (max-width: 768px) { @media (max-width: 1024px) {
/* 点击卡片容器时显示功能按钮 */ /* 点击卡片容器时显示功能按钮 */
.ip-card-container:active .right-circular-controls, .ip-card-container:active .right-circular-controls,
.ip-card-container.controls-visible .right-circular-controls { .ip-card-container.controls-visible .right-circular-controls {
@ -613,6 +607,25 @@ justify-content: center;
} }
} }
/* 在 iPad 及更大触控屏上,按下即显示右侧圆形控件 */
@media (hover: none) and (pointer: coarse) {
.ip-card-container:active .right-circular-controls,
.ip-card-container.controls-visible .right-circular-controls {
opacity: 1;
transform: translateX(0);
pointer-events: auto;
}
}
/* 非触控设备保持 hover 显示 */
@media (hover: hover) {
.ip-card-container:hover .right-circular-controls {
opacity: 1;
transform: translateX(0);
pointer-events: auto;
}
}
.control-button { .control-button {
width: 48px; width: 48px;
height: 48px; height: 48px;
@ -625,6 +638,9 @@ justify-content: center;
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
/* 添加触摸支持 */
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
} }
.control-button:hover { .control-button:hover {
@ -778,7 +794,7 @@ justify-content: center;
} }
/* 响应式设计 */ /* 响应式设计 */
@media (max-width: 768px) { @media (max-width: 1024px) {
.ip-card-container { .ip-card-container {
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;

View File

@ -139,8 +139,8 @@ const router = createRouter({
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
NProgress.start() NProgress.start()
// if(window.location.hostname=='localhost'){ // if(window.location.hostname=='localhost'){
window.localStorage.setItem('token','123') // window.localStorage.setItem('token','123')
return next() // return next()
// } // }
if (to.meta.requiresAuth) { if (to.meta.requiresAuth) {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')

View File

@ -1,4 +1,5 @@
<template> <template>
<el-scrollbar height="100%" @end-reached="loadMore">
<div class="agent-management"> <div class="agent-management">
<!-- 页面头部 --> <!-- 页面头部 -->
<div class="page-header"> <div class="page-header">
@ -24,8 +25,7 @@
</div> </div>
</div> </div>
</div> </div>
<div style="height: 10px;width: 100%"></div> <!-- <div style="height: 10px;width: 100%"></div> -->
<el-scrollbar v-if="false" height="100%" @end-reached="loadMore">
<div class="agents-section"> <div class="agents-section">
<!-- 智能体列表 --> <!-- 智能体列表 -->
<div class="agents-grid"> <div class="agents-grid">
@ -121,8 +121,8 @@
</template> </template>
</el-dialog> </el-dialog>
</div> </div>
</el-scrollbar>
</div> </div>
</el-scrollbar>
</template> </template>
<script setup> <script setup>
@ -335,7 +335,7 @@ onMounted(() => {
<style scoped> <style scoped>
.agent-management { .agent-management {
height: 100%; height: 100%;
background: var(--bg-color, #F3F4F6); /* background: var(--bg-color, #F3F4F6); */
} }
/* 页面头部样式 */ /* 页面头部样式 */
@ -516,7 +516,7 @@ onMounted(() => {
/* 暗色主题样式 */ /* 暗色主题样式 */
:root.dark .agent-management { :root.dark .agent-management {
background: linear-gradient(135deg, #1F2937 0%, #111827 50%, #030712 100%); /* background: linear-gradient(135deg, #1F2937 0%, #111827 50%, #030712 100%); */
height: 100%; height: 100%;
} }

View File

@ -127,7 +127,7 @@ onMounted(() => {
/* 登录页面基础样式 */ /* 登录页面基础样式 */
.login-page { .login-page {
position: relative; position: relative;
min-height: 100vh; min-height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@ -1,4 +1,5 @@
<template> <template>
<el-scrollbar height="100%" @end-reached="loadMore">
<div class="order-management"> <div class="order-management">
<div class="orders-section"> <div class="orders-section">
<div class="filter-section"> <div class="filter-section">
@ -43,7 +44,6 @@
</div> </div>
</div> </div>
</div> </div>
<el-scrollbar height="88vh" @end-reached="loadMore">
<div class="orders-grid"> <div class="orders-grid">
<OrderCard <OrderCard
v-for="order in order_list" v-for="order in order_list"
@ -56,7 +56,6 @@
@confirm-order="handleConfirmOrder" @confirm-order="handleConfirmOrder"
/> />
</div> </div>
</el-scrollbar>
<div v-if="order_list.length === 0" class="empty-state"> <div v-if="order_list.length === 0" class="empty-state">
<div class="empty-icon"> <div class="empty-icon">
<el-icon><DocumentDelete /></el-icon> <el-icon><DocumentDelete /></el-icon>
@ -66,6 +65,8 @@
</div> </div>
</div> </div>
</div> </div>
</el-scrollbar>
</template> </template>
<script setup> <script setup>
@ -215,6 +216,7 @@ watch(sort_by, () => {
<style scoped> <style scoped>
.order-management { .order-management {
padding: 24px; padding: 24px;
height: 100%;
} }
.page-header { margin-bottom: 24px; } .page-header { margin-bottom: 24px; }

View File

@ -461,6 +461,7 @@ const handleCreateFourViewCard = (index,params) => {
// //
const handleCreatePromptCard = (index,params) => { const handleCreatePromptCard = (index,params) => {
const { img, diyPromptText,imgyt,cardData } = params; const { img, diyPromptText,imgyt,cardData } = params;
console.log(cardData,'cardDatacardData');
// //
const newCard = createSmartCard({ const newCard = createSmartCard({
diyPromptImg:img, diyPromptImg:img,
@ -827,8 +828,8 @@ const dragScene = (e) => {
// 600400 // 600400
// 600400 // 600400
// //
const adjustedMouseX = isMobile.value ? mouseX : mouseX - 900; const adjustedMouseX = mouseX - 600;
const adjustedMouseY = isMobile.value ? mouseY : mouseY - 400; const adjustedMouseY = mouseY - 400;
// //
const currentOffsetFromMouseX = adjustedMouseX - initialOffsetX.value; const currentOffsetFromMouseX = adjustedMouseX - initialOffsetX.value;

View File

@ -186,7 +186,7 @@ export class GiminiServer extends FileServer {
// "aspectRatio": "9:16" // "aspectRatio": "9:16"
// }, // },
"aspect_ratio": "16:9", "aspect_ratio": "16:9",
"model": "gemini-2.5-flash-image",//models/gemini-3-pro-image-preview/"gemini-2.5-flash-image", "model": "gemini-3-pro-image-preview",//models/gemini-3-pro-image-preview/"gemini-2.5-flash-image",
"location": "global", "location": "global",
"vertexai": true, "vertexai": true,
...config, ...config,