浏览代码

Merge remote-tracking branch 'origin/dev-frontend_v132' into feature-frontend

panqiuyao 6 天之前
父节点
当前提交
ab72193060

+ 1 - 1
frontend/src/views/Photography/components/ProgressSteps.vue

@@ -29,7 +29,7 @@
           <div class="step-status">
             {{ getStepTitle(step) }}
             <div v-if="step.status !== '等待处理'" class="step-details">
-              第{{ step.status === '正在处理' && step.name === '抠图' ?  step.current+1 : step.current }}/{{ step.total }}款
+              第{{ step.current }}/{{ step.total }}款
               {{ getCurrentGoodsNo(step) }}
               <span v-if="step.error" style="color: red; margin-left:5px;">失败:{{step.error}}款</span>
 

+ 64 - 47
frontend/src/views/Photography/detail.vue

@@ -234,9 +234,10 @@
                   </div>
                 </div>
 
-                <div class="template-tips c-333 fs-14 line-20 te-l mar-top-20 flex left">
+                <div class="template-tips c-333 fs-14 line-20 te-l mar-top-20 flex left" >
                   <el-icon><Warning /></el-icon>
-                  <span class="mar-left-10">该模版需提供{{form.selectTemplate?.template_image_order?.split(',').length || 5}}张标准视角的商品图:{{form.selectTemplate?.template_image_order || '俯视、侧视、后跟、鞋底、内里'}}。请确保图片清晰度高,背景干净。</span>
+                  <span class="mar-left-10"  v-if="!isDetailServiceSelected">请先选中详情页生成,后在选择模板详情</span>
+                  <span class="mar-left-10"  v-else>该模版需提供{{form.selectTemplate?.template_image_order?.split(',').length || 5}}张标准视角的商品图:{{form.selectTemplate?.template_image_order || '俯视,侧视,后跟,鞋底,内里'}}。请确保图片清晰度高,背景干净。</span>
                 </div>
               </div>
             </div>
@@ -250,16 +251,22 @@
                   主图LOGO
                 </div>
                 <div class="logo-upload-area">
-                  <div v-if="!form.logo_path" class="logo-upload-placeholder" @click="openLogoUpload">
+                  <div
+                    v-if="!form.logo_path"
+                    class="logo-upload-placeholder"
+                    :class="{ 'is-error': logoLoadError }"
+                    @click="openLogoUpload"
+                  >
                     <div class="logo-upload-icon">
                       <img src="@/assets/images/detail/sctp.png" />
 
                     </div>
                     <div class="logo-upload-text">点击或拖拽上传</div>
-                    <div class="logo-upload-hint">支持PNG、JPG格式</div>
+                    <div class="logo-upload-hint" v-if="logoLoadError">LOGO指向的文件不存在或加载失败,请重新上传</div>
+                    <div class="logo-upload-hint" v-else>支持PNG、JPG格式</div>
                   </div>
                   <div v-else class="logo-upload-preview">
-                    <img :src="'file:///' + form.logo_path" alt="LOGO预览" class="logo-preview-image" />
+                    <img  :src="'file:///' + form.logo_path" alt="LOGO预览" class="logo-preview-image" @error="handleLogoLoadError" />
                     <div class="logo-upload-actions">
                       <span class="logo-action-btn" @click.stop="previewLogo">
                         <el-icon><ZoomIn /></el-icon>
@@ -268,6 +275,10 @@
                         <el-icon><Delete /></el-icon>
                       </span>
                     </div>
+                    <div class="logo-upload-footer">
+                      <el-button type="primary" link @click.stop="openLogoUpload">重新上传</el-button>
+                      <el-button type="danger" link @click.stop="removeLogo">删除</el-button>
+                    </div>
                   </div>
                 </div>
               </div>
@@ -906,7 +917,7 @@ const scenePrompt = ref('')
 // 本地缓存键(与弹窗组件保持一致)
 const DETAIL_MODEL_CACHE_KEY = 'model_selection_cache'
 const DETAIL_SCENE_PROMPT_CACHE_KEY = 'scene_prompt_cache'
-const DETAIL_LOGO_CACHE_KEY = 'detail_logo_cache'
+const detail_logo_cache_1_KEY = 'detail_logo_cache_1'
 const DETAIL_DATA_TYPE_CACHE_KEY = 'detail_data_type_cache'
 const DETAIL_SERVICES_CACHE_KEY = 'detail_services_cache'
 const DETAIL_TEMPLATE_CACHE_KEY = 'detail_template_cache'
@@ -936,9 +947,10 @@ const loadDetailCache = () => {
 
   // 加载LOGO缓存
   try {
-    const logo = localStorage.getItem(DETAIL_LOGO_CACHE_KEY)
+    const logo = localStorage.getItem(detail_logo_cache_1_KEY)
     if (logo) {
-      form.logo_path = logo
+      form.logo_path = logo || ''
+      console.log(form.logo_path);
       console.log('loadDetailCache - logo:', logo);
     }
   } catch {}
@@ -1001,10 +1013,7 @@ const saveScenePromptToCache = (prompt: string) => {
 // 保存LOGO到缓存
 const saveLogoToCache = (logoPath: string) => {
   try {
-    if (logoPath) {
-      localStorage.setItem(DETAIL_LOGO_CACHE_KEY, logoPath)
-      console.log('saveLogoToCache:', logoPath);
-    }
+      localStorage.setItem(detail_logo_cache_1_KEY, logoPath)
   } catch {}
 }
 
@@ -1587,16 +1596,24 @@ const openLoadingDialog = (timer: number) => {
 
 //logo
 const logoList = ref([])
+const logoLoadError = ref(false)
 const logoPreviewVisible = ref(false)
 const logoPreviewUrl = ref('')
 
 // 打开LOGO上传
+const handleLogoSelected = (path?: string) => {
+  if (!path) return
+  form.logo_path = path
+  logoLoadError.value = false
+  saveLogoToCache(form.logo_path)
+}
+
 const openLogoUpload = () => {
   clientStore.ipc.removeAllListeners(icpList.utils.openImage);
   clientStore.ipc.send(icpList.utils.openImage);
   clientStore.ipc.on(icpList.utils.openImage, async (event, result) => {
     if (result && result.filePath) {
-      await addLogo(result.filePath)
+      handleLogoSelected(result.filePath)
     }
     clientStore.ipc.removeAllListeners(icpList.utils.openImage);
   })
@@ -1613,7 +1630,9 @@ const previewLogo = () => {
 // 删除LOGO
 const removeLogo = () => {
   if (form.logo_path) {
-    const currentLogoPath = form.logo_path
+    saveLogoToCache('')
+    form.logo_path = ''
+  /*  const currentLogoPath = form.logo_path
     clientStore.ipc.send(icpList.generate.deleteLogo, {
       path: currentLogoPath
     });
@@ -1621,13 +1640,24 @@ const removeLogo = () => {
       console.log('deleteLogo', result);
       form.logo_path = ''
       saveLogoToCache('')
+      logoLoadError.value = false
       // 从列表中移除
       const index = logoList.value.indexOf(currentLogoPath)
       if (index > -1) {
         logoList.value.splice(index, 1)
       }
       clientStore.ipc.removeAllListeners(icpList.generate.deleteLogo);
-    })
+    })*/
+  }
+}
+
+const handleLogoLoadError = () => {
+  if (!form.logo_path) return
+  if (!logoLoadError.value) {
+    logoLoadError.value = true
+    form.logo_path = ''
+    saveLogoToCache('')
+    ElMessage.warning('LOGO加载出错或文件已被删除,请重新上传')
   }
 }
 
@@ -1640,6 +1670,7 @@ const getLogolist = async () => {
     // 只使用第一个LOGO(如果存在且当前没有选择)
     if(logoList.value.length && !form.logo_path){
       form.logo_path = logoList.value[0]
+      logoLoadError.value = false
       // 保存默认LOGO到缓存
       saveLogoToCache(form.logo_path)
     }
@@ -1647,38 +1678,6 @@ const getLogolist = async () => {
   })
 }
 
-const addLogo = async (path) => {
-  console.log('addLogo', path);
-  clientStore.ipc.send(icpList.generate.addLogo, {
-    logo_path: path
-  });
-  clientStore.ipc.on(icpList.generate.addLogo, async (event, result) => {
-    console.log('addLogo result', result);
-
-    if (result.code === 0) {
-      console.log("添加成功")
-      if(result.data.logo){
-        const newLogo = result.data.logo
-        form.logo_path = newLogo
-        // 保存新添加的LOGO到缓存
-        saveLogoToCache(form.logo_path)
-        // 保持数组格式:如果列表中没有,添加到数组;如果已有,更新数组(保持兼容性)
-        const index = logoList.value.indexOf(newLogo)
-        if(index < 0){
-          // 新LOGO,添加到数组(保持数组格式兼容性)
-          logoList.value.push(newLogo)
-        } else {
-          // 已存在的LOGO,移动到第一个位置(UI只显示第一个)
-          logoList.value.splice(index, 1)
-          logoList.value.unshift(newLogo)
-        }
-      }
-    }
-    clientStore.ipc.removeAllListeners(icpList.generate.addLogo);
-  })
-}
-
-
 function selectExcel() {
   clientStore.ipc.removeAllListeners(icpList.utils.openFile);
   clientStore.ipc.send(icpList.utils.openFile, {
@@ -2352,6 +2351,16 @@ const selectFolder = () => {
     font-size: 12px;
     color: #999;
   }
+
+  &.is-error {
+    border-color: #FF4D4F;
+    background: #FFF2F0;
+
+    .logo-upload-text,
+    .logo-upload-hint {
+      color: #FF4D4F;
+    }
+  }
 }
 
 .logo-upload-preview {
@@ -2409,6 +2418,13 @@ const selectFolder = () => {
   &:hover .logo-upload-actions {
     opacity: 1;
   }
+
+  .logo-upload-footer {
+    display: flex;
+    justify-content: flex-end;
+    gap: 12px;
+    padding: 8px 4px 0;
+  }
 }
 
 .logo-upload {
@@ -2468,6 +2484,7 @@ const selectFolder = () => {
 
   .template-item {
     flex:1;
+    max-width: 33%;
     border: 1px solid #ccc;
     border-radius: 10px;
     cursor: pointer;

+ 1 - 0
frontend/src/views/Photography/mixin/usePhotography.ts

@@ -847,6 +847,7 @@ export default function usePhotography() {
       getPhotoRecords,
       delAll,
       delGoods,
+      del,
       reTakePicture,
       reTakePictureNos,
       oneClickStop,

+ 5 - 3
frontend/src/views/Photography/processImage.vue

@@ -146,6 +146,8 @@ const {
   getFilePath,
   getPhotoRecords,
   delGoods,
+  del,
+  openPhotographyDetail,
   onGenerateCLick,
   initEventListeners,
   cleanupEventListeners,
@@ -156,7 +158,7 @@ const Router = useRouter()
 const route = useRoute();
 const clientStore = client();
 // 覆盖 openPhotographyDetail 方法,只传递选中的货号
-const openPhotographyDetail = () => {
+/*const openPhotographyDetail = () => {
 
   if (selectedGoods.value.size === 0) {
     ElMessage.error('请选择要生成的货号')
@@ -184,7 +186,7 @@ const openPhotographyDetail = () => {
     url: getRouterUrl(href)
   }
   clientStore.ipc.send(icpList.utils.openMain, params);
-}
+}*/
 
 // 选中的货号列表
 const selectedGoods = ref<Set<string>>(new Set())
@@ -256,7 +258,7 @@ const deleteSelected = async () => {
     )
 
     const goodsArtNos = Array.from(selectedGoods.value)
-    await delGoods({ goods_art_nos: goodsArtNos })
+    await  del({ goods_art_nos: goodsArtNos })
     // 删除成功后清空选中状态
     selectedGoods.value.clear()
   } catch (e) {