Browse Source

feat(photography): 优化详情页生成界面和功能

- 更新场景图、模特图、详情页图标状态显示逻辑
- 移除编辑按钮的条件渲染限制
- 为模板选择添加激活状态样式
- 替换警告图标并优化提示文案展示
- 重构主图LOGO上传区域为单文件上传模式
- 优化详情资料准备区域的UI布局和交互
- 改进一键上架平台选择器样式和禁用状态
- 调整底部开始生成按钮的视觉效果
- 添加LOGO预览弹窗功能
- 重新实现LOGO上传、预览和删除逻辑
- 优化模板选择区域的样式和交互反馈
- 统一各模块标题样式并增加装饰线条
- 改进数据准备区域的选项卡和上传区域设计
- 优化发布平台选择区域的样式表现
- 调整整体页面布局和间距设置
panqiuyao 1 week ago
parent
commit
1691cb6411

+ 11 - 0
frontend/src/assets/images/detail/cjt_h.svg

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>cjt</title>
+    <g id="8.22" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="cjt" fill-rule="nonzero">
+            <rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="32" height="32"></rect>
+            <path d="M6.4,7.4 C6.06862915,7.4 5.8,7.66862915 5.8,8 L5.8,24 C5.8,24.3311875 6.0688125,24.6 6.4,24.6 L25.6,24.6 C25.9313708,24.6 26.2,24.3313708 26.2,24 L26.2,8 C26.2,7.66862915 25.9313708,7.4 25.6,7.4 L6.4,7.4 Z M6.4,5.4 L25.6,5.4 C27.0351875,5.4 28.2,6.5648125 28.2,8 L28.2,24 C28.2,25.4351875 27.0351875,26.6 25.6,26.6 L6.4,26.6 C4.96405965,26.6 3.8,25.4359403 3.8,24 L3.8,8 C3.8,6.5648125 4.9648125,5.4 6.4,5.4 Z" id="形状" fill="#FFFFFF"></path>
+            <path d="M25.6,24.6 C25.9313708,24.6 26.2,24.3313708 26.2,24 L26.2,19.5775938 C26.2,18.7455938 25.7295938,17.9824063 24.984,17.6095938 L22.0575938,16.1471875 C21.3357465,15.7862168 20.4741982,15.8494719 19.8128125,16.312 L7.9728125,24.6 L25.6,24.6 Z M25.8784062,15.8208125 C27.301317,16.5323196 28.2,17.986708 28.2,19.5775938 L28.2,24 C28.2,25.4351875 27.0351875,26.6000003 25.6,26.6000003 L6.83040625,26.6000003 C6.11426415,26.600433 5.48065289,26.1361387 5.26531291,25.4531392 C5.04997292,24.7701396 5.30270633,24.0263935 5.88959375,23.616 L18.665625,14.6735938 C19.9283816,13.790051 21.5736182,13.6690736 22.9520312,14.3584063 L25.8784375,15.8208125 L25.8784062,15.8208125 Z M10.4,13.6 C11.2836556,13.6 12,12.8836556 12,12 C12,11.1163444 11.2836556,10.4 10.4,10.4 C9.51634442,10.4 8.80000005,11.1163444 8.80000005,12 C8.80000005,12.8836556 9.51634442,13.6 10.4,13.6 L10.4,13.6 Z" id="形状" fill="#FFFFFF"></path>
+        </g>
+    </g>
+</svg>

BIN
frontend/src/assets/images/detail/excel.png


BIN
frontend/src/assets/images/detail/excel_h.png


BIN
frontend/src/assets/images/detail/file-excel.png


+ 10 - 0
frontend/src/assets/images/detail/mtt_h.svg

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>mtt</title>
+    <g id="8.22" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="mtt" fill-rule="nonzero">
+            <rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="32" height="32"></rect>
+            <path d="M19.2,16.64 C24.8556875,16.64 29.44,21.2243125 29.44,26.88 L29.44,27.52 C29.44,28.933849 28.293849,30.08 26.88,30.08 L5.12,30.08 C3.70615104,30.08 2.56,28.933849 2.56,27.52 L2.56,26.88 C2.56,21.2243125 7.1443125,16.64 12.8,16.64 L19.2,16.64 L19.2,16.64 Z M19.2,18.56 L12.8,18.56 C8.27071875,18.56 4.586875,22.1791875 4.4825625,26.6835313 L4.48,26.88 L4.48,27.52 C4.48,27.8444699 4.72288331,28.1175708 5.045125,28.1555312 L5.12,28.16 L26.88,28.16 C27.2044699,28.16 27.4775708,27.9171167 27.5155313,27.594875 L27.52,27.52 L27.52,26.88 C27.52,22.3507188 23.9008125,18.666875 19.3964688,18.5625625 L19.2,18.56 Z M16,1.92 C19.5347187,1.92 22.4,4.78528125 22.4,8.32 C22.4,11.8547188 19.5347187,14.72 16,14.72 C12.4652813,14.72 9.6,11.8547188 9.6,8.32 C9.6,4.78528125 12.4652813,1.92 16,1.92 Z M16,3.84 C13.5257643,3.84 11.52,5.84576432 11.52,8.32 C11.52,10.7942357 13.5257643,12.8 16,12.8 C18.4742357,12.8 20.48,10.7942357 20.48,8.32 C20.48,5.84576432 18.4742357,3.84 16,3.84 Z" id="形状" fill="#FFFFFF"></path>
+        </g>
+    </g>
+</svg>

BIN
frontend/src/assets/images/detail/sctp.png


+ 11 - 0
frontend/src/assets/images/detail/xqy_h.svg

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>xqy</title>
+    <g id="8.22" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="xqy" fill-rule="nonzero">
+            <rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="32" height="32"></rect>
+            <path d="M22.125,30 L9.875,30 C6.55,30 3.75,27.2 3.75,23.875 L3.75,8.125 C3.75,4.8 6.55,2 9.875,2 L22.125,2 C25.45,2 28.25,4.8 28.25,8.125 L28.25,23.875 C28.25,27.2 25.45,30 22.125,30 Z M9.875,3.75 C7.425,3.75 5.5,5.675 5.5,8.125 L5.5,23.875 C5.5,26.325 7.425,28.25 9.875,28.25 L22.125,28.25 C24.575,28.25 26.5,26.325 26.5,23.875 L26.5,8.125 C26.5,5.675 24.575,3.75 22.125,3.75 L9.875,3.75 Z" id="形状" fill="#FFFFFF"></path>
+            <path d="M22.125,9.875 L9.875,9.875 C9.35,9.875 9,9.525 9,9 C9,8.475 9.35,8.125 9.875,8.125 L22.125,8.125 C22.65,8.125 23,8.475 23,9 C23,9.525 22.65,9.875 22.125,9.875 Z M22.125,15.125 L9.875,15.125 C9.35,15.125 9,14.775 9,14.25 C9,13.725 9.35,13.375 9.875,13.375 L22.125,13.375 C22.65,13.375 23,13.725 23,14.25 C23,14.775 22.65,15.125 22.125,15.125 Z M22.125,20.375 L9.875,20.375 C9.35,20.375 9,20.025 9,19.5 C9,18.975 9.35,18.625 9.875,18.625 L22.125,18.625 C22.65,18.625 23,18.975 23,19.5 C23,20.025 22.65,20.375 22.125,20.375 Z" id="形状" fill="#FFFFFF"></path>
+        </g>
+    </g>
+</svg>

BIN
frontend/src/assets/images/detail/xtdj.png


BIN
frontend/src/assets/images/detail/xtdj_h.png


+ 407 - 98
frontend/src/views/Photography/detail.vue

@@ -21,11 +21,12 @@
           />
           <div class="tab-content">
             <div class="tab-img flex">
-              <img src="@/assets/images/detail/cjt.svg" alt="场景图生成" class="tab-icon" />
+              <img v-if="form.services.includes('is_product_scene')" src="@/assets/images/detail/cjt_h.svg" alt="场景图生成" class="tab-icon" />
+              <img v-else src="@/assets/images/detail/cjt.svg" alt="场景图生成" class="tab-icon" />
             </div>
             <span class="tab-name">场景图生成</span>
           </div>
-          <div class="tab-edit-btn" @click.stop="openScenePromptDialog" v-if="form.services.includes('is_product_scene')" v-log="{ describe: { action: '点击编辑场景图', service: '场景图生成-弹窗' } }">
+          <div class="tab-edit-btn" @click.stop="openScenePromptDialog"  v-log="{ describe: { action: '点击编辑场景图', service: '场景图生成-弹窗' } }">
             <el-icon><EditPen /></el-icon>
           </div>
         </div>
@@ -47,11 +48,12 @@
           />
           <div class="tab-content">
             <div class="tab-img flex">
-              <img src="@/assets/images/detail/mtt.svg" alt="模特图生成" class="tab-icon" />
+              <img v-if="form.services.includes('is_upper_footer')" src="@/assets/images/detail/mtt_h.svg" alt="模特图生成" class="tab-icon" />
+              <img v-else src="@/assets/images/detail/mtt.svg" alt="模特图生成" class="tab-icon" />
             </div>
             <span class="tab-name">模特图生成</span>
           </div>
-          <div class="tab-edit-btn" @click.stop="openModelDialog" v-if="form.services.includes('is_upper_footer')" v-log="{ describe: { action: '点击编辑模特图', service: '模特图生成-弹窗' } }">
+          <div class="tab-edit-btn" @click.stop="openModelDialog"  v-log="{ describe: { action: '点击编辑模特图', service: '模特图生成-弹窗' } }">
             <el-icon><EditPen /></el-icon>
           </div>
         </div>
@@ -73,7 +75,8 @@
           />
           <div class="tab-content">
             <div class="tab-img flex">
-              <img src="@/assets/images/detail/xqy.svg" alt="详情页生成" class="tab-icon" />
+              <img v-if="form.services.includes('is_detail')" src="@/assets/images/detail/xqy_h.svg" alt="详情页生成" class="tab-icon" />
+              <img v-else src="@/assets/images/detail/xqy.svg" alt="详情页生成" class="tab-icon" />
             </div>
             <span class="tab-name">详情页生成</span>
           </div>
@@ -205,6 +208,7 @@
                     v-for="(template, index) in visibleTemplates"
                     :key="index"
                     class="template-item"
+                    :class="form.selectTemplate?.id == template.id ? 'active' : ''"
                     @click="handleTemplateItemClick(template)"
                     v-log="{ describe: { action: '点击选择详情模板', template_name: template.template_name } }"
                   >
@@ -222,7 +226,7 @@
                 </div>
 
                 <div class="template-tips c-333 fs-14 line-20 te-l mar-top-20 flex left">
-                  <el-icon><WarningFilled /></el-icon>
+                  <el-icon><Warning /></el-icon>
                   <span class="mar-left-10">该模版需提供{{form.selectTemplate?.template_image_order?.split(',').length || 5}}张标准视角的商品图:{{form.selectTemplate?.template_image_order || '俯视、侧视、后跟、鞋底、内里'}}。请确保图片清晰度高,背景干净。</span>
                 </div>
               </div>
@@ -233,46 +237,57 @@
               <!-- 主图LOGO -->
               <div class="right-section">
                 <div class="section-title">
-                  <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
+                  <div class="section-title-line"></div>
                   主图LOGO
                 </div>
-                <div class="logo-section flex left top multi-line">
-                  <upload
-                    v-for="item,index in logoList"
-                    :value="item"
-                    :key="item"
-                    v-show="item"
-                    @input="onRemove(index)"
-                    class="mar-right-10 upload-item"
-                    :class="{ active: item === form.logo_path }"
-                    @click.native="selectLogo(item)"
-                  ></upload>
-                  <upload @input="onInput"></upload>
+                <div class="logo-upload-area">
+                  <div v-if="!form.logo_path" class="logo-upload-placeholder" @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>
+                  <div v-else class="logo-upload-preview">
+                    <img :src="'file:///' + form.logo_path" alt="LOGO预览" class="logo-preview-image" />
+                    <div class="logo-upload-actions">
+                      <span class="logo-action-btn" @click.stop="previewLogo">
+                        <el-icon><ZoomIn /></el-icon>
+                      </span>
+                      <span class="logo-action-btn" @click.stop="removeLogo">
+                        <el-icon><Delete /></el-icon>
+                      </span>
+                    </div>
+                  </div>
                 </div>
               </div>
 
               <!-- 详情资料准备 -->
-              <div class="right-section">
+              <div class="right-section data-prep-section">
                 <div class="section-title">
-                  <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
+                  <div class="section-title-line"></div>
                   详情资料准备
                 </div>
                 <div class="data-prep-content">
-                  <el-radio-group v-model="form.dataType" class="ml-4">
-                    <el-radio label="1" size="large">Excel上传</el-radio>
-                    <el-radio label="2" size="large">系统对接</el-radio>
+                  <el-radio-group v-model="form.dataType" class="data-type-radio">
+                    <el-radio-button label="1" size="large">
+                      <img v-if="form.dataType == 1" src="@/assets/images/detail/excel_h.png"  />
+                      <img v-else src="@/assets/images/detail/excel.png"  />
+                      Excel上传</el-radio-button>
+                    <el-radio-button label="2" size="large">
+                      <img  v-if="form.dataType == 2" src="@/assets/images/detail/xtdj_h.png" />
+                      <img v-else src="@/assets/images/detail/xtdj.png" />
+                      系统对接</el-radio-button>
                   </el-radio-group>
 
                   <div v-if="form.dataType == '1'" class="excel-upload-section">
-                    <el-button
-                      type="primary"
-                      class="select-file-btn"
-                      @click="selectExcel"
-                      v-log="{ describe: { action: '点击选择Excel文件' } }"
-                    >
-                      <img src="@/assets/images/Photography/wenjian.png" style="width: 16px; margin-right: 4px;" />
-                      点击选择文件
-                    </el-button>
+                    <div class="excel-upload-area" @click="selectExcel" v-log="{ describe: { action: '点击选择Excel文件' } }">
+                      <div class="excel-icon">
+                        <img src="@/assets/images/detail/file-excel.png" class="tab-icon" />
+                      </div>
+                      <div class="excel-upload-text">点击选择文件</div>
+                    </div>
                     <el-button
                       type="text"
                       class="download-link"
@@ -287,22 +302,22 @@
 
               <!-- 一键上架平台 -->
               <div
-                class="right-section"
+                class="right-section publish-section"
                 :class="{ 'publish-section--disabled': !canUsePublishSection }"
                 v-if="onlineStoreTempList.length || onlineStoreTempListForeign.length"
               >
                 <div class="section-title">
-                  <img src="@/assets/images/Photography/zhuangshi.png" style="width: 32px; height: 32px;" />
+                  <div class="section-title-line"></div>
                   一键上架平台
                 </div>
                 <div class="publish-content">
-                  <div class="form-item" v-if="onlineStoreTempList.length">
-                    <div class="label">国内电商平台:</div>
+                  <div class="publish-form-item" v-if="onlineStoreTempList.length">
+                    <div class="publish-label">国内电商平台:</div>
                     <el-select
                       v-model="domesticPlatforms"
                       multiple
                       placeholder="请选择"
-                      style="width: 100%;"
+                      class="publish-select"
                       :disabled="!canUsePublishSection"
                     >
                       <el-option
@@ -314,13 +329,13 @@
                       />
                     </el-select>
                   </div>
-                  <div class="form-item" v-if="onlineStoreTempListForeign.length">
-                    <div class="label">跨境电商平台:</div>
+                  <div class="publish-form-item" v-if="onlineStoreTempListForeign.length">
+                    <div class="publish-label">跨境电商平台:</div>
                     <el-select
                       v-model="foreignPlatforms"
                       multiple
                       placeholder="请选择"
-                      style="width: 100%;"
+                      class="publish-select"
                       :disabled="!canUsePublishSection"
                     >
                       <el-option
@@ -334,8 +349,6 @@
                   </div>
                 </div>
               </div>
-
-
               <!-- 底部按钮 -->
               <div class="footer">
                 <el-button
@@ -345,9 +358,12 @@
                     @click="generate"
                     v-log="{ describe: { action: '点击开始生成详情页' } }"
                 >
-                  开始生成→
+                  <img src="@/assets/images/processImage.vue/sc.png" />
+                  开始生成
+                  <img src="@/assets/images/processImage.vue/go.png"  class="go"/>
                 </el-button>
               </div>
+
             </div>
           </div>
 
@@ -428,6 +444,11 @@
     <img style="width: 100%;" :src="dialogImageUrl" alt="Preview Image" />
   </el-dialog>
 
+  <!-- LOGO预览弹窗 -->
+  <el-dialog v-model="logoPreviewVisible" title="LOGO预览">
+    <img style="width: 100%;" :src="logoPreviewUrl" alt="LOGO Preview" />
+  </el-dialog>
+
   <!-- 模特生成弹窗 -->
   <ModelGenerationDialog
     v-model="modelDialogVisible"
@@ -460,8 +481,8 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 
 import BlueHeaderBar from '@/components/header-bar/blue-header.vue'
 import { ref, computed, reactive, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
-import { Select, EditPen } from '@element-plus/icons-vue'
-import upload from '@/components/upload'
+import { Select, EditPen, ZoomIn, Delete, Picture, Document } from '@element-plus/icons-vue'
+// import upload from '@/components/upload' // 不再需要,改为单LOGO上传
 import client from "@/stores/modules/client";
 import icpList from '@/utils/ipc'
 const clientStore = client();
@@ -953,11 +974,7 @@ const openScenePromptDialog = () => {
 }
 
 // 选择LOGO
-const selectLogo = (logoPath: string) => {
-  form.logo_path = logoPath
-  // 保存LOGO选择到缓存
-  saveLogoToCache(logoPath)
-}
+// selectLogo 函数已移除,现在只支持单个LOGO上传
 const handleModelSelection = (models: { female: any; male: any }) => {
   selectedModels.value = models
   saveModelsToCache(models)
@@ -1493,31 +1510,57 @@ const openLoadingDialog = (timer: number) => {
 
 //logo
 const logoList = ref([])
-const onInput = (value) => {
-  addLogo(value)
+const logoPreviewVisible = ref(false)
+const logoPreviewUrl = ref('')
+
+// 打开LOGO上传
+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)
+    }
+    clientStore.ipc.removeAllListeners(icpList.utils.openImage);
+  })
 }
-const onRemove = (index) => {
-  if(logoList.value[index] === form.logo_path){
-    form.logo_path = ''
+
+// 预览LOGO
+const previewLogo = () => {
+  if (form.logo_path) {
+    logoPreviewUrl.value = 'file:///' + form.logo_path
+    logoPreviewVisible.value = true
   }
-  clientStore.ipc.send(icpList.generate.deleteLogo,{
-    path:logoList.value[index]
-  });
-  logoList.value.splice(index, 1)
-  clientStore.ipc.on(icpList.generate.deleteLogo, async (event, result) => {
-    console.log('deleteLogo');
-    console.log(result);
+}
 
-    clientStore.ipc.removeAllListeners(icpList.generate.deleteLogo);
-  })
+// 删除LOGO
+const removeLogo = () => {
+  if (form.logo_path) {
+    const currentLogoPath = form.logo_path
+    clientStore.ipc.send(icpList.generate.deleteLogo, {
+      path: currentLogoPath
+    });
+    clientStore.ipc.on(icpList.generate.deleteLogo, async (event, result) => {
+      console.log('deleteLogo', result);
+      form.logo_path = ''
+      saveLogoToCache('')
+      // 从列表中移除
+      const index = logoList.value.indexOf(currentLogoPath)
+      if (index > -1) {
+        logoList.value.splice(index, 1)
+      }
+      clientStore.ipc.removeAllListeners(icpList.generate.deleteLogo);
+    })
+  }
 }
 
 const getLogolist = async () => {
   clientStore.ipc.send(icpList.generate.getLogoList);
   clientStore.ipc.on(icpList.generate.getLogoList, async (event, result) => {
+    // 保持数组格式,兼容老的格式
     logoList.value = result.data || []
-    console.log('getLogoList')
-    console.log(result.data)
+    console.log('getLogoList', result.data)
+    // 只使用第一个LOGO(如果存在且当前没有选择)
     if(logoList.value.length && !form.logo_path){
       form.logo_path = logoList.value[0]
       // 保存默认LOGO到缓存
@@ -1527,24 +1570,30 @@ const getLogolist = async () => {
   })
 }
 
-
 const addLogo = async (path) => {
-  console.log(path);
-  clientStore.ipc.send(icpList.generate.addLogo,{
-    logo_path: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(result);
+    console.log('addLogo result', result);
 
     if (result.code === 0) {
-        console.log("添加成功")
-      console.log(result)
+      console.log("添加成功")
       if(result.data.logo){
-        form.logo_path = result.data.logo
+        const newLogo = result.data.logo
+        form.logo_path = newLogo
         // 保存新添加的LOGO到缓存
         saveLogoToCache(form.logo_path)
-        if(logoList.value.indexOf(result.data.logo) <0){
-          logoList.value.push(result.data.logo)
+        // 保持数组格式:如果列表中没有,添加到数组;如果已有,更新数组(保持兼容性)
+        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)
         }
       }
     }
@@ -1653,6 +1702,16 @@ const selectFolder = () => {
       position: absolute;
       left: 10px;
       top:10px;
+      ::v-deep {
+        .is-checked .el-checkbox__inner {
+          background: #2957FF;
+          border-color: #2957FF;
+        }
+        .el-checkbox__inner {
+          border-radius: 18px;
+          transform: scale(1.2);
+        }
+      }
     }
 
     .tab-img {
@@ -1706,6 +1765,10 @@ const selectFolder = () => {
     &.active {
       border-color: #2957FF;
       border-bottom: 4px solid #2957FF;
+
+      .tab-img {
+        background: #2957FF;
+      }
     }
 
     &.disabled {
@@ -1718,7 +1781,7 @@ const selectFolder = () => {
 
 .detail-container {
   background: #F5F6F7;
-  padding: 0 20px 20px 20px;
+  padding: 0 20px 20px 20px; // 底部留出空间给固定按钮
 
   .detail-content {
     max-width: 100%;
@@ -1838,7 +1901,6 @@ const selectFolder = () => {
 .logo-section,
 .template-section,
 .data-prep-section {
-  margin-bottom: 20px;
 }
 
 .template-section {
@@ -1852,6 +1914,16 @@ const selectFolder = () => {
     justify-content: space-between;
     align-items: center;
   }
+
+  .template-tips {
+    height: 40px;
+    line-height: 40px;
+    padding: 0 10px;
+    background: #FFFBEA;
+    border-radius: 10px;
+    border: 1px solid #FEEEB0;
+    color: #9B4D26;
+  }
 }
 
 .template-section--disabled {
@@ -1893,30 +1965,130 @@ const selectFolder = () => {
   border-radius: 8px;
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
 
+  &.data-prep-section {
+    height: 225px;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+  }
+
   .section-title {
+    display: flex;
+    align-items: center;
+    gap: 10px;
     font-weight: 600;
     font-size: 16px;
     color: #333333;
+    margin-bottom: 16px;
+
+    .section-title-line {
+      width: 3px;
+      height: 16px;
+      background: linear-gradient(135deg, #7C3AED 0%, #2957FF 100%);
+      border-radius: 2px;
+    }
+
+    .section-title-hint {
+      font-weight: normal;
+      font-size: 14px;
+      color: #999;
+    }
   }
 
   .data-prep-content {
     display: flex;
     flex-direction: column;
-    gap: 15px;
+    gap: 12px;
+    flex: 1;
+
+    .data-type-radio {
+      padding:5px;
+      background:#F3F5F6;
+      border-radius:10px;
+      ::v-deep {
+        .el-radio {
+          margin-right: 20px;
+        }
+        .el-radio-button {
+          flex:1;
+          box-shadow:none !important;
+
+          .el-radio-button__inner {
+            width: 100%;
+            background: none !important;
+            border: none !important;
+            display: flex;
+            align-items: center;
+            border-radius:10px !important;
+            justify-content: center;
+            img {
+              height: 14px;
+              margin: 0 5px;
+              position: relative;
+              top:-1px;
+            }
+          }
+          &.is-active {
+            background: #F8F9FF;
+            .el-radio-button__inner {
+              background: #fff !important;
+              color: #2957FF !important;
+              border-radius: 10px !important;
+              box-shadow: none !important;
+            }
+          }
+        }
+      }
+    }
 
     .excel-upload-section {
       display: flex;
       flex-direction: column;
-      gap: 10px;
+      gap: 8px;
+      flex: 1;
 
-      .select-file-btn {
+      .excel-upload-area {
         width: 100%;
+        height: 64px;
+        border: 1px dashed #D9D9D9;
+        border-radius: 8px;
+        display: flex;
+        align-items: center;
+        padding: 0 16px;
+        cursor: pointer;
+        transition: all 0.3s;
+        background: #fff;
+
+        &:hover {
+          border-color: #2957FF;
+          background: #F8F9FF;
+        }
+
+        .excel-icon {
+          width: 32px;
+          height:32px;
+          margin-right: 10px;
+          img {
+            width: 32px;
+            height:32px;
+            display: block;
+          }
+        }
+
+        .excel-upload-text {
+          font-size: 14px;
+          color: #333;
+          font-weight: 500;
+        }
       }
 
       .download-link {
         color: #2957FF;
         text-decoration: underline;
         padding: 0;
+        font-size: 14px;
+        margin-top: 0;
+        justify-content: flex-start;
       }
     }
   }
@@ -1926,16 +2098,28 @@ const selectFolder = () => {
     flex-direction: column;
     gap: 15px;
 
-    .form-item {
+    .publish-form-item {
       display: flex;
       flex-direction: column;
       gap: 8px;
 
-      .label {
-        min-width: auto;
-        margin-right: 0;
+      .publish-label {
         font-size: 14px;
-        color: #666;
+        color: #333;
+        margin-bottom: 4px;
+        text-align: left;
+      }
+
+      .publish-select {
+        width: 100%;
+
+        ::v-deep {
+          .el-input.is-disabled .el-input__inner {
+            background-color: #F5F6F7;
+            border-color: #E8E8E8;
+            color: #999;
+          }
+        }
       }
     }
   }
@@ -1972,6 +2156,116 @@ const selectFolder = () => {
     }
   }
 }
+// LOGO上传区域样式
+.logo-upload-area {
+  width: 100%;
+}
+
+.logo-upload-placeholder {
+  width: 100%;
+  height: 160px;
+  border: 1px dashed #D9D9D9;
+  border-radius: 10px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+  transition: all 0.3s;
+  background: #fff;
+
+  &:hover {
+    border-color: #2957FF;
+    background: #F8F9FF;
+  }
+
+  .logo-upload-icon {
+    width: 42px;
+    height: 42px;
+    margin-bottom: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: linear-gradient(135deg, #EFF6FF 0%, #F3E8FF 100%);
+    border-radius: 8px;
+    color: #2957FF;
+
+    img {
+      width: 42px;
+      height: 42px;
+    }
+  }
+
+  .logo-upload-text {
+    font-size: 14px;
+    color: #333;
+    margin-bottom: 8px;
+    font-weight: 500;
+  }
+
+  .logo-upload-hint {
+    font-size: 12px;
+    color: #999;
+  }
+}
+
+.logo-upload-preview {
+  width: 100%;
+  height: 160px;
+  border: 1px solid #E8E8E8;
+  border-radius: 8px;
+  position: relative;
+  overflow: hidden;
+  background: #F5F5F5;
+  cursor: pointer;
+
+  .logo-preview-image {
+    width: 100%;
+    height: 100%;
+    object-fit: contain;
+  }
+
+  .logo-upload-actions {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 40px;
+    background: rgba(0, 0, 0, 0.5);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 20px;
+    opacity: 0;
+    transition: opacity 0.3s;
+
+    .logo-action-btn {
+      width: 32px;
+      height: 32px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: rgba(255, 255, 255, 0.2);
+      border-radius: 4px;
+      cursor: pointer;
+      color: #fff;
+      transition: background 0.3s;
+
+      &:hover {
+        background: rgba(255, 255, 255, 0.3);
+      }
+
+      .el-icon {
+        font-size: 18px;
+      }
+    }
+  }
+
+  &:hover .logo-upload-actions {
+    opacity: 1;
+  }
+}
+
 .logo-upload {
   border: 1px dashed #ccc;
   border-radius: 5px;
@@ -2034,25 +2328,29 @@ const selectFolder = () => {
     cursor: pointer;
     background: #f0f0f0;
     position: relative;
-    height: 700px;
+    height: 660px;
     overflow: hidden;
 
+    &.active {
+
+      border-color: #1677FF;
+    }
+
 
     .template-info {
       position: absolute;
       bottom: 0;
       left: 0;
-      background: rgba($color: #000000, $alpha: .3);
+      background: #fff;
       width: 100%;
-      height: 36px;
-      line-height: 36px;
-      color: #eee;
+      height: 40px;
+      line-height: 40px;
+      color: #333;
       display: flex;
       align-items: center;
       justify-content: space-between;
 
       .template-view {
-        background: #DFE2E3;
         color: #3366FF;
         height: 30px;
         line-height: 30px;
@@ -2104,9 +2402,14 @@ const selectFolder = () => {
 .select-warp {
   width: 18px;
   height: 18px;
-  border-radius: 4px;
+  border-radius: 18px;
   background-color: #fff;
   position: absolute;
+  font-size: 12px;
+  line-height: 18px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
   top: 10px;
   left: 10px;
 
@@ -2226,16 +2529,22 @@ const selectFolder = () => {
 
 .footer {
   display: flex;
-  justify-content: flex-end;
-  padding: 20px;
-  background: #fff;
-  border-top: 1px solid #e8e8e8;
   z-index: 100;
 
   .footer-button {
     padding: 12px 40px;
     font-size: 16px;
     border-radius: 8px;
+    display: block;
+    width: 100%;
+    height: 50px;
+    img {
+      height: 16px;;
+      margin: 0 10px;
+    }
+    .go {
+      opacity: .5;
+    }
   }
 }