Sfoglia il codice sorgente

feat(photography): 添加Excel文件删除功能并优化界面样式

- 添加删除Excel文件按钮及对应清除逻辑
- 修复详情页生成时Excel路径参数传递问题
- 移除商品基础资料上传验证中的冗余条件判断
- 优化Excel文件信息显示区域的布局和样式
- 调整模型卡片组件图片适配方式为cover模式
- 更新场景卡片组件移除背景提示输入框
- 优化组件响应式设计支持容器查询
- 调整按钮和标签的间距及字体大小样式
panqiuyao 3 settimane fa
parent
commit
c0bebaa0c2

+ 36 - 13
frontend/src/views/Photography/components/ModelCard.vue

@@ -32,7 +32,7 @@
             v-if="imagesReady"
             :src="thumbUrl(model.image_url)"
             :alt="model.name"
-            fit="contain"
+            fit="cover"
             lazy
             :scroll-container="libScrollRef || undefined"
             class="model-img"
@@ -108,7 +108,7 @@
             v-if="imagesReady"
             :src="thumbUrl(model.image_url)"
             :alt="model.name"
-            fit="contain"
+            fit="cover"
             lazy
             :scroll-container="mineScrollRef || undefined"
             class="model-img"
@@ -205,9 +205,9 @@ const visibleMineModels = computed(() => filterByGender(myModels.value))
 
 const gridOpts = {
   minItemWidth: 84,
-  minItemHeight: 108,
+  minItemHeight: 134,
   minRows: 1,
-  maxRows: 4,
+  maxRows: 3,
   cols: 2,
   gap: 11,
 }
@@ -476,6 +476,7 @@ onMounted(() => {
   min-height: 0;
   flex: 1 1 0;
   overflow: hidden;
+  container-type: inline-size;
 }
 
 .tabs-row {
@@ -534,28 +535,31 @@ onMounted(() => {
 .chips-row {
   display: flex;
   align-items: center;
-  gap: 10px;
+  flex-wrap: wrap;
+  gap: 8px 10px;
   flex: none;
 }
 .chips {
   display: flex;
-  gap: 8px;
-  flex-wrap: wrap;
-  flex: 1;
+  gap: 6px;
+  flex-wrap: nowrap;
+  flex: 1 1 auto;
   min-width: 0;
 }
 .chip {
   appearance: none;
-  padding: 5px 14px;
+  padding: 4px 10px;
   border-radius: 999px;
   border: 1.5px solid #d9dfec;
   background: #fff;
-  font-size: 13.5px;
+  font-size: 12.5px;
   font-weight: 700;
   color: #46516a;
   cursor: pointer;
   outline: none;
   box-sizing: border-box;
+  white-space: nowrap;
+  flex: none;
   &:hover {
     border-color: #3d63f2;
     color: #3d63f2;
@@ -574,7 +578,12 @@ onMounted(() => {
     box-shadow: 0 4px 12px rgba(61, 99, 242, 0.28);
   }
 }
-.hbtns { display: flex; gap: 6px; flex: none; }
+.hbtns {
+  display: flex;
+  gap: 6px;
+  flex: none;
+  margin-left: auto;
+}
 .hbtn {
   width: 27px;
   height: 27px;
@@ -644,7 +653,7 @@ onMounted(() => {
     :deep(.el-image__inner) {
       width: 100%;
       height: 100%;
-      object-fit: contain;
+      object-fit: cover;
     }
     :deep(.el-image__placeholder),
     :deep(.el-image__error),
@@ -669,7 +678,6 @@ onMounted(() => {
     z-index: 2;
   }
   &:hover {
-    transform: translateY(-2px);
     box-shadow: 0 8px 18px rgba(23, 43, 99, 0.14);
   }
   &.sel {
@@ -835,6 +843,7 @@ onMounted(() => {
   flex-direction: column;
   gap: 8px;
   min-width: 0;
+  .chips { flex-wrap: wrap; }
 }
 .up-label {
   font-size: 12.5px;
@@ -874,4 +883,18 @@ onMounted(() => {
     &:hover:not(:disabled) { filter: brightness(1.05); }
   }
 }
+
+@container (max-width: 360px) {
+  .tabs { gap: 14px; }
+  .tab { font-size: 13.5px; }
+  .chip {
+    padding: 3px 8px;
+    font-size: 12px;
+  }
+  .chips { gap: 4px; }
+  .hbtn {
+    width: 24px;
+    height: 24px;
+  }
+}
 </style>

+ 0 - 18
frontend/src/views/Photography/components/SceneCard.vue

@@ -83,19 +83,6 @@
       </div>
 
       <div class="flab">
-        <b>场景描述 <small>(可选)</small></b>
-      </div>
-      <div class="ta">
-        <textarea
-          :value="bgPrompt"
-          maxlength="500"
-          placeholder="不填则默认:把鞋子融合到背景图中"
-          @input="onBgPromptInput"
-        />
-        <span class="cnt">{{ (bgPrompt || '').length }}/500</span>
-      </div>
-
-      <div class="flab">
         <b>历史上传背景图 <small>(点击选用)</small></b>
         <span class="hbtns">
           <button class="hbtn" type="button" title="向左" @click="scrollGrid(histScrollRef, -1)"><svg><use href="#i-left"/></svg></button>
@@ -212,10 +199,6 @@ function onInput(e: Event) {
   emit('update:modelValue', (e.target as HTMLTextAreaElement).value)
 }
 
-function onBgPromptInput(e: Event) {
-  emit('update:bgPrompt', (e.target as HTMLTextAreaElement).value)
-}
-
 function fillExample() {
   emit('update:modelValue', EXAMPLE_TEXT)
 }
@@ -641,7 +624,6 @@ onMounted(() => {
     white-space: nowrap;
   }
   &:hover .ph {
-    transform: translateY(-2px);
     box-shadow: 0 8px 18px rgba(23, 43, 99, 0.14);
   }
   &.sel .ph {

+ 137 - 69
frontend/src/views/Photography/detail.vue

@@ -248,19 +248,22 @@
                   <svg><use href="#i-sheet"/></svg>选择 Excel 文件
                 </button>
                 <div v-else class="excel-selected-info">
-                  <div class="excel-file-info">
-                    <div class="excel-icon">
-                      <img src="@/assets/images/detail/file-excel.png" class="tab-icon" />
-                    </div>
-                    <div class="excel-file-text">
-                      <div class="excel-file-label">已选择文件</div>
-                      <div class="excel-file-name" :title="excelFileName">{{ excelFileName }}</div>
+                  <div class="excel-icon">
+                    <img src="@/assets/images/detail/file-excel.png" class="tab-icon" />
+                  </div>
+                  <div class="excel-file-text">
+                    <div class="excel-file-name" :title="excelFileName">{{ excelFileName }}</div>
+                    <div class="excel-file-actions">
+                      <el-button type="primary" link class="reupload-btn" @click="selectExcel"
+                        v-log="{ describe: { action: '重新上传Excel文件' } }">
+                        重新上传
+                      </el-button>
+                      <el-button type="danger" link class="delete-excel-btn" @click="clearExcel"
+                        v-log="{ describe: { action: '删除Excel文件' } }">
+                        删除
+                      </el-button>
                     </div>
                   </div>
-                  <el-button type="primary" link class="reupload-btn" @click="selectExcel"
-                    v-log="{ describe: { action: '重新上传Excel文件' } }">
-                    重新上传
-                  </el-button>
                 </div>
                 <button class="lk data-prep-link" type="button" @click="downloadExcel"
                   title="用于非自定义详情页的商品基础资料模版"
@@ -1340,7 +1343,7 @@ const checkParams = async function () {
     goods_art_no: JSON.parse(JSON.stringify(goods_art_nos.value)),
     logo_path: form.logo_path || '',
     temp_name: form.selectTemplate?.template_id || '',
-    excel_path: form.dataType == '1' ? form.excel_path : '',
+    excel_path: (isDetail && form.dataType == '1') ? (form.excel_path || '') : '',
     template_image_order: form.selectTemplate?.template_image_order,
     temp_list,
     token,
@@ -1419,11 +1422,9 @@ const generate = async function () {
     }
   }
 
-  if (form.services.includes('is_detail') || form.services.includes('is_upper_footer')) {
-    if (form.dataType == '1' && !form.excel_path) {
-      ElMessage.error('请上传商品基础资料')
-      return
-    }
+  if (form.services.includes('is_detail') && form.dataType == '1' && !form.excel_path) {
+    ElMessage.error('请上传商品基础资料')
+    return
   }
 
   // 埋点:开始生成详情页
@@ -1472,7 +1473,7 @@ const generate = async function () {
     goods_art_no: JSON.parse(JSON.stringify(goods_art_nos.value)),
     logo_path: form.logo_path || '',
     temp_name: form.selectTemplate?.template_id || '',
-    excel_path: form.dataType == '1' ? form.excel_path : '',
+    excel_path: (isDetail && form.dataType == '1') ? (form.excel_path || '') : '',
     template_image_order: form.selectTemplate?.template_image_order,
     temp_list,
     token,
@@ -1758,6 +1759,10 @@ const getLogolist = async () => {
   })
 }
 
+function clearExcel() {
+  form.excel_path = ''
+}
+
 function selectExcel() {
   clientStore.ipc.removeAllListeners(icpList.utils.openFile);
   clientStore.ipc.send(icpList.utils.openFile, {
@@ -1940,25 +1945,27 @@ const selectFolder = () => {
   margin-top: 4px;
   text-align: left;
   align-self: flex-start;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
+  white-space: normal;
+  overflow: visible;
+  line-height: 1.4;
   max-width: 100%;
 }
 
 .toggle {
   margin-left: auto;
-  align-self: center;
+  align-self: flex-start;
   flex: none;
   display: flex;
-  align-items: center;
-  gap: 7px;
+  flex-direction: column;
+  align-items: flex-end;
+  gap: 4px;
   .swl {
-    font-size: 13.5px;
+    font-size: 12px;
     font-weight: 600;
     color: #8b95ab;
-    min-width: 38px;
+    min-width: 0;
     text-align: right;
+    line-height: 1;
   }
 }
 
@@ -2154,7 +2161,6 @@ const selectFolder = () => {
   margin: 0;
   transition: all 0.15s;
   &:hover {
-    transform: translateY(-2px);
     box-shadow: 0 10px 22px rgba(23, 43, 99, 0.14);
   }
   &.sel {
@@ -2280,11 +2286,13 @@ const selectFolder = () => {
   border-radius: 14px;
   box-shadow: 0 1px 2px rgba(23, 43, 99, 0.04), 0 10px 30px rgba(23, 43, 99, 0.06);
   padding: 11px 15px;
+  text-align: left;
   .stitle {
     font-size: 15.5px;
     font-weight: 800;
     margin-bottom: 9px;
     color: #1a2233;
+    text-align: left;
   }
 }
 
@@ -2949,62 +2957,60 @@ const selectFolder = () => {
 
       .excel-selected-info {
         width: 100%;
-        height: 64px;
+        min-height: 64px;
         border: 1px solid #E5E6EB;
         border-radius: 8px;
-        padding: 12px 16px;
+        padding: 10px 12px;
         background: #fff;
         display: flex;
         align-items: center;
-        justify-content: space-between;
-        gap: 16px;
+        gap: 10px;
         box-sizing: border-box;
+        text-align: left;
 
-        .excel-file-info {
-          display: flex;
-          align-items: center;
-          flex: 1;
-          min-width: 0;
-
-          .excel-icon {
-            width: 32px;
-            height: 32px;
-            margin-right: 10px;
+        .excel-icon {
+          width: 36px;
+          height: 36px;
+          flex: none;
 
-            img {
-              width: 32px;
-              height: 32px;
-              display: block;
-            }
+          img {
+            width: 36px;
+            height: 36px;
+            display: block;
           }
+        }
 
-          .excel-file-text {
-            display: flex;
-            flex-direction: column;
-            min-width: 0;
-            max-width: 100%;
-
-            .excel-file-label {
-              font-size: 12px;
-              text-align: left;
-              color: #888;
-              margin-bottom: 4px;
-            }
+        .excel-file-text {
+          display: flex;
+          flex-direction: column;
+          align-items: flex-start;
+          gap: 2px;
+          min-width: 0;
+          flex: 1;
+        }
 
-            .excel-file-name {
-              font-size: 14px;
-              color: #1D2129;
-              font-weight: 500;
-              white-space: nowrap;
-              overflow: hidden;
-              text-overflow: ellipsis;
-              max-width: 100%;
-            }
-          }
+        .excel-file-name {
+          font-size: 14px;
+          color: #1D2129;
+          font-weight: 500;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          max-width: 100%;
+          text-align: left;
+        }
+
+        .excel-file-actions {
+          display: flex;
+          align-items: center;
+          gap: 8px;
         }
 
-        .reupload-btn {
+        .reupload-btn,
+        .delete-excel-btn {
           flex-shrink: 0;
+          padding: 0;
+          height: auto;
         }
       }
 
@@ -3600,5 +3606,67 @@ const selectFolder = () => {
 .side .right-section {
   padding: 11px 15px;
 }
+.side .excel-selected-info {
+  width: 100%;
+  min-height: 72px;
+  border: 1px solid #E5E6EB;
+  border-radius: 8px;
+  padding: 10px 12px;
+  background: #fff;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  gap: 12px;
+  box-sizing: border-box;
+  text-align: left;
+  .excel-icon {
+    width: 53px;
+    height: 53px;
+    flex: none;
+    img {
+      width: 53px;
+      height: 53px;
+      display: block;
+      object-fit: contain;
+    }
+  }
+  .excel-file-text {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    justify-content: center;
+    gap: 6px;
+    min-width: 0;
+    flex: 1;
+  }
+  .excel-file-name {
+    font-size: 14px;
+    color: #1D2129;
+    font-weight: 600;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    max-width: 100%;
+    text-align: left;
+    line-height: 1.3;
+  }
+  .excel-file-actions {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    gap: 10px;
+  }
+  .reupload-btn,
+  .delete-excel-btn {
+    padding: 5px !important;
+    height: auto;
+    font-size: 13px;
+    font-weight: 600;
+    :deep(span) {
+      font-size: 13px;
+      font-weight: 600;
+    }
+  }
+}
 </style>
 

+ 15 - 16
public/dist/index.html

@@ -1,17 +1,16 @@
-<!doctype html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="./vite.svg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>智惠映AI自动拍照机</title>
-    <script type="module" crossorigin src="./assets/index-wGSb5LOF.js"></script>
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="./vite.svg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>智惠映AI自动拍照机</title>
+    <script type="module" crossorigin src="./assets/index-Cu4duvgh.js"></script>
     <link rel="stylesheet" crossorigin href="./assets/index-CUtW5LTp.css">
-  </head>
-  <body>
-    <div id="app"></div>
-<!--    <script  src="/src/views/components/PictureEditor/js/fabric.js"></script>-->
-    <script src="./js/fabric.js"></script>
-
-  </body>
-</html>
+  </head>
+  <body>
+    <div id="app"></div>
+<!--    <script  src="/src/views/components/PictureEditor/js/fabric.js"></script>-->
+    <script src="./js/fabric.js"></script>

+  </body>
+</html>