Bladeren bron

feat(product): 更新商品方案管理功能

- 实现商品关联关系的独立接口管理,替换原有的 productIds 字段方式
- 新增 programLink 相关 API 接口用于商品关联关系的增删改查
- 优化表单详情加载逻辑,通过 programLink 接口获取已关联商品
- 完善编辑模式下的商品关联差异同步机制
- 修复分类页面平台选项值映射问题
- 修正专题页面下拉选项 key 和 value 类型转换
- 更新表格组件中封面图片字段名称映射
肖路 1 maand geleden
bovenliggende
commit
9c934217d0

+ 2 - 2
src/views/product/category/index.vue

@@ -126,8 +126,8 @@
           <el-col :span="12">
             <el-form-item label="平台" prop="platform">
               <el-select v-model="form.platform" placeholder="请选择所属平台" style="width: 100%">
-                <el-option label="工业品" :value="0" />
-                <el-option label="PC端" :value="1" />
+                <el-option label="PC端" :value="0" />
+                <el-option label="工业品" :value="1" />
               </el-select>
             </el-form-item>
           </el-col>

+ 46 - 13
src/views/product/productProgram/form.vue

@@ -271,6 +271,8 @@ import FileSelector from '@/components/FileSelector/index.vue';
 import { img } from '@/utils/common';
 import { listBase, getBase } from '@/api/pmsProduct/base';
 import { BaseVO } from '@/api/pmsProduct/base/types';
+import { listProgramLink, addProgramLink, delProgramLink } from '@/api/product/programLink';
+import { ProgramLinkVO } from '@/api/product/programLink/types';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const router = useRouter();
@@ -379,7 +381,7 @@ const getTagList = async () => {
 const getDetail = async (id: string | number) => {
   const res = await getProgram(id);
   const data: any = res.data;
-  
+
   // 复制字段
   Object.assign(form.value, data);
   // 确保 adaptNo、label、industry、category 是字符串类型
@@ -387,12 +389,14 @@ const getDetail = async (id: string | number) => {
   form.value.label = data.label ? String(data.label) : undefined;
   form.value.industry = data.industry ? String(data.industry) : undefined;
   form.value.category = data.category ? String(data.category) : undefined;
-  
-  // 通过 productIds 查询商品列表并回显
-  const ids: Array<string | number> = data.productIds || [];
-  if (ids.length > 0) {
-    try {
-      const results = await Promise.all(ids.map((pid: string | number) => getBase(pid)));
+
+  // 通过 programLink 接口查询已关联商品并回显
+  try {
+    const linkRes = await listProgramLink({ programId: id, pageNum: 1, pageSize: 500 });
+    const links: ProgramLinkVO[] = linkRes.rows || [];
+    console.log('已关联商品列表', links);
+    if (links.length > 0) {
+      const results = await Promise.all(links.map(link => getBase(link.productId)));
       productList.value = results
         .map(r => r.data)
         .filter(Boolean)
@@ -411,9 +415,9 @@ const getDetail = async (id: string | number) => {
           profitRate: item.tempGrossMargin ? `${item.tempGrossMargin}%` : '-',
           minOrder: item.minOrderQuantity || 1
         }));
-    } catch (error) {
-      console.error('查询商品详情失败', error);
     }
+  } catch (error) {
+    console.error('查询关联商品失败', error);
   }
 };
 
@@ -577,14 +581,43 @@ const handleSubmit = async () => {
     if (valid) {
       submitLoading.value = true;
       try {
-        // 收集商品ID
-        form.value.productIds = productList.value.map(item => item.id).filter(id => id);
-        
+        let programId: string | number;
+
         if (form.value.id) {
+          // 编辑:更新方案基本信息
           await updateProgram(form.value);
+          programId = form.value.id;
+
+          // 获取已有关联,进行差异同步
+          const existRes = await listProgramLink({ programId, pageNum: 1, pageSize: 500 });
+          const existLinks: ProgramLinkVO[] = existRes.data || [];
+          const existProductIds = existLinks.map(l => String(l.productId));
+          const newProductIds = productList.value.map(item => String(item.id)).filter(Boolean);
+
+          // 需要删除的关联
+          const toDelete = existLinks.filter(l => !newProductIds.includes(String(l.productId)));
+          // 需要新增的关联
+          const toAdd = newProductIds.filter(pid => !existProductIds.includes(pid));
+
+          await Promise.all([
+            ...toDelete.map(l => delProgramLink(l.id)),
+            ...toAdd.map(pid => addProgramLink({ programId, productId: pid }))
+          ]);
         } else {
-          await addProgram(form.value);
+          // 新增:先创建方案
+          const addRes = await addProgram(form.value);
+          const addData: any = addRes.data;
+          programId = addData?.id || addData?.data?.id;
+
+          // 新增所有关联商品
+          const newProductIds = productList.value.map(item => item.id).filter(Boolean);
+          if (programId && newProductIds.length > 0) {
+            await Promise.all(
+              newProductIds.map(pid => addProgramLink({ programId, productId: pid }))
+            );
+          }
         }
+
         proxy?.$modal.msgSuccess('操作成功');
         router.back();
       } finally {

+ 1 - 1
src/views/product/productProgram/index.vue

@@ -41,7 +41,7 @@
         <el-table-column label="编号" align="center" prop="programNo" width="120" />
         <el-table-column label="封面图片" align="center" prop="coverImageUrl" width="120">
           <template #default="scope">
-            <image-preview :src="scope.row.coverImageUrl" :width="60" :height="60"/>
+            <image-preview :src="scope.row.coverImage" :width="60" :height="60"/>
           </template>
         </el-table-column>
         <el-table-column label="推文标题" align="center" prop="title" min-width="200" show-overflow-tooltip>

+ 4 - 4
src/views/product/topics/form.vue

@@ -74,9 +74,9 @@
               <el-select v-model="form.adaptIndustry" placeholder="请选择" clearable style="width: 100%">
                 <el-option
                   v-for="item in industryOptions"
-                  :key="item.id"
+                  :key="String(item.id)"
                   :label="item.industryCategoryName"
-                  :value="item.id"
+                  :value="String(item.id)"
                 />
               </el-select>
             </el-form-item>
@@ -96,9 +96,9 @@
               <el-select v-model="form.lable" placeholder="请选择" clearable style="width: 100%">
                 <el-option
                   v-for="item in tagOptions"
-                  :key="item.id"
+                  :key="String(item.id)"
                   :label="item.tagName"
-                  :value="item.id"
+                  :value="String(item.id)"
                 />
               </el-select>
             </el-form-item>