Просмотр исходного кода

feat(marketingEdit): 添加商品文字功能支持

- 在菜单中新增商品文字添加入口和对话框组件
- 实现商品文字的新增、编辑和删除功能
- 更新文字占位符处理逻辑,使用 data-key 替代 text 字段
- 扩展商品文字字段映射,支持颜色、货号、设计理念等标准字段
- 移除模板编辑中的默认商品图片示例数据
- 优化模板保存时的商品文字头信息处理逻辑
panqiuyao 21 часов назад
Родитель
Сommit
c1e70e351a

+ 3 - 30
frontend/src/views/Tpl/Edit/index.vue

@@ -102,26 +102,6 @@ const defaultGoodsText = [
 
 // 从路由 query 中解析 goods_images,如果没有就使用默认示例
 const defaultGoodsImages = [
-  {
-    key: '俯视',
-    value: 'C:\\Users\\Administrator\\Desktop\\img\\A596351\\1.png'
-  },
-  {
-    key: '侧视',
-    value: 'C:\\Users\\Administrator\\Desktop\\img\\A596351\\2.png'
-  },
-  {
-    key: '后跟',
-    value: 'C:\\Users\\Administrator\\Desktop\\img\\A596351\\3.png'
-  },
-  {
-    key: '鞋底',
-    value: 'C:\\Users\\Administrator\\Desktop\\img\\A596351\\4.png'
-  },
-  {
-    key: '内里',
-    value: 'C:\\Users\\Administrator\\Desktop\\img\\A596351\\5.png'
-  }
 ]
 
 const goodsImages = computed(() => {
@@ -162,18 +142,11 @@ const doSave = async (payload: any) => {
     // 封面图:取第一张画布的 preview
     if (payload && payload.length > 0 && payload[0].preview) {
       requestData.template_cover_image = payload[0].preview
-    } 
+    }
     requestData.customer_template_images = goodsImages.value
     requestData.template_image_order =  route.query.template_image_order as string | undefined
-    let template_excel_headers = []
-    requestData.customer_template_json.map(item =>  {
-      const canvas_json =  JSON.parse( item.canvas_json )
-      canvas_json.objects.map(itm => {
-        if(itm.type =="textbox" && itm.text) 
-        template_excel_headers.push(itm.text)
-      })
-    })
-    requestData.template_excel_headers = template_excel_headers
+    // 直接从 goodsText 中获取所有商品文字的 key
+    requestData.template_excel_headers = goodsText.map(item => item.key)
     await saveCustomerTemplate(requestData)
     ElMessage.success(isEdit ? '模板保存成功' : '模板创建成功')
     router.back()

+ 15 - 8
frontend/src/views/components/marketingEdit/generateImagesRender.js

@@ -498,7 +498,7 @@ export async function renderImagesByPlans(plans, canvasList, skus) {
         }
 
         // 2) 处理文字占位(data-type = text)
-        const textPlaceholders = objs.filter((o) => o && (o['data-type'] === 'text' || o['type'] === "textbox") &&  o['text'] )
+        const textPlaceholders = objs.filter((o) => o && o['data-key'] && (o['data-type'] === 'text' || o['type'] === "textbox"))
         console.log('=====textPlaceholders========', textPlaceholders)
 
         if (textPlaceholders.length) {
@@ -506,11 +506,18 @@ export async function renderImagesByPlans(plans, canvasList, skus) {
           const mapKeyToText = (sku, key, defaultVal) => {
             if (!sku) return defaultVal
             let textVal = defaultVal || ''
-            // if (key === '颜色') {
-            //   textVal = sku.color || textVal
-            // } else if (key === '货号') {
-            //   textVal = sku.sku || textVal
-            // }
+            // 标准字段映射
+            if (key === '颜色') {
+              textVal = sku.color || textVal
+            } else if (key === '货号') {
+              textVal = sku.sku || textVal
+            } else if (key === '设计理念') {
+              textVal = sku.design || textVal
+            } else if (key === '标题') {
+              textVal = sku.styleNo || textVal
+            } else if (key === '款号') {
+              textVal = sku.styleNo || textVal
+            }
             // 兜底:去 raw 里找同名字段(支持 卖点 / 使用场景 / 其他自定义字段)
             if ((!textVal || textVal === defaultVal) && sku.raw && sku.raw[key] != null) {
               textVal = sku.raw[key]
@@ -528,7 +535,7 @@ export async function renderImagesByPlans(plans, canvasList, skus) {
             // - 如果该 slot 没有对应货号(usedSkus[slotIndex] 为 null),则隐藏该文字层
             const keyCounter = {}
             textPlaceholders.forEach((obj) => {
-              const key = obj['text']
+              const key = obj['data-key']
               if (!key) return
               const idxForKey = keyCounter[key] || 0
               keyCounter[key] = idxForKey + 1
@@ -552,7 +559,7 @@ export async function renderImagesByPlans(plans, canvasList, skus) {
             const sku = usedSkus[0]
             if (sku) {
               textPlaceholders.forEach((obj) => {
-                const key = obj['text']
+                const key = obj['data-key']
                 if (!key) return
                 const origin = obj['data-value'] || ''
                 const textVal = mapKeyToText(sku, key, origin)

+ 58 - 0
frontend/src/views/components/marketingEdit/index.vue

@@ -79,6 +79,13 @@ export default {
         canvas_type: 'normal', // normal:普通画布 model:模特图 scene:场景图
         multi_goods_mode: '', // 多货号模式:''(默认单货号), 'single'(一个货号多角度), 'multiple'(多个货号同角度)
         max_goods_count: null, // 多货号模式下,最多可追加多少个货号
+      },
+
+      // 新增商品文字对话框
+      addGoodsTextForm: {
+        visible: false,
+        key: '',
+        value: ''
       }
 
     }
@@ -691,6 +698,37 @@ export default {
         this.fcanvas = null
         this.fcanvasId = ''
       }
+    },
+
+    // 显示新增商品文字对话框
+    showAddGoodsTextDialog() {
+      this.addGoodsTextForm.key = ''
+      this.addGoodsTextForm.value = ''
+      this.addGoodsTextForm.visible = true
+    },
+
+    // 确认新增商品文字
+    confirmAddGoodsText() {
+      if (!this.addGoodsTextForm.key.trim() || !this.addGoodsTextForm.value.trim()) {
+        this.$message.warning('请填写完整的商品文字信息')
+        return
+      }
+
+      // 检查是否已存在相同的 key
+      const existingIndex = this.goods_text.findIndex(item => item.key === this.addGoodsTextForm.key.trim())
+      if (existingIndex !== -1) {
+        this.$message.warning('该商品文字键名已存在,请使用不同的键名')
+        return
+      }
+
+      // 添加到 goods_text 数组
+      this.goods_text.push({
+        key: this.addGoodsTextForm.key.trim(),
+        value: this.addGoodsTextForm.value.trim()
+      })
+
+      this.addGoodsTextForm.visible = false
+      this.$message.success('商品文字添加成功')
     }
   }
 }
@@ -912,6 +950,26 @@ export default {
   color: #666;
 }
 
+.add-goods-text-item {
+  border-top: 1px solid #f0f0f0;
+  margin-top: 8px;
+  padding-top: 8px;
+
+  &:hover {
+    background-color: #f5f7fa;
+  }
+
+  .el-icon {
+    margin-right: 6px;
+    color: #67c23a;
+  }
+
+  span {
+    color: #67c23a;
+    font-weight: 500;
+  }
+}
+
 
 </style>
 

+ 5 - 1
frontend/src/views/components/marketingEdit/tpl/add.js

@@ -59,7 +59,11 @@ let add = () => {
                                   >
                                     {{item.key}}
                                   </el-tooltip>
-                            
+
+                           </el-menu-item>
+                           <el-menu-item @click.native="showAddGoodsTextDialog" index="1-3-add" class="add-goods-text-item">
+                             <el-icon><Plus /></el-icon>
+                             <span>新增商品文字</span>
                            </el-menu-item>
                           </el-menu-item-group>
                         </el-sub-menu>

+ 17 - 1
frontend/src/views/components/marketingEdit/tpl/header.js

@@ -98,7 +98,7 @@ export  default function tpl(){
                   <div class="fixed-width-tip">800(固定)</div>
                 </el-form-item>-->
                 <template v-if="canvasForm.canvas_type === 'normal'">
-                
+
                   <el-form-item label="高度">
                     <el-input v-model.number="canvasForm.height" placeholder="请输入高度"></el-input>
                   </el-form-item>
@@ -140,6 +140,22 @@ export  default function tpl(){
                 <el-button type="primary" @click="submitCanvasInfo">确 定</el-button>
               </div>
             </el-dialog>
+
+            <!-- 新增商品文字对话框 -->
+            <el-dialog title="新增商品文字" v-model="addGoodsTextForm.visible" width="400px" append-to-body>
+              <el-form :model="addGoodsTextForm" label-width="80px">
+                <el-form-item label="文字键名">
+                  <el-input v-model="addGoodsTextForm.key" placeholder="请输入文字键名,如:颜色、尺寸等"></el-input>
+                </el-form-item>
+                <el-form-item label="默认内容">
+                  <el-input v-model="addGoodsTextForm.value" placeholder="请输入默认显示内容"></el-input>
+                </el-form-item>
+              </el-form>
+              <div slot="footer" class="dialog-footer flex right">
+                <el-button @click="addGoodsTextForm.visible = false">取 消</el-button>
+                <el-button type="primary" @click="confirmAddGoodsText">确 定</el-button>
+              </div>
+            </el-dialog>