hurx 4 hari lalu
induk
melakukan
b5065ce74c
1 mengubah file dengan 313 tambahan dan 14 penghapusan
  1. 313 14
      src/views/enterprisePurchase/index.vue

+ 313 - 14
src/views/enterprisePurchase/index.vue

@@ -75,7 +75,7 @@
               <div class="hot-words-config">
                 <div v-for="(item, index) in form.hotWordsList" :key="index" class="hot-word-row">
                   <el-input v-model="item.name" placeholder="热词名称" class="hot-word-input-name" />
-                  <WebLinkInput v-model="item.link" placeholder="跳转地址" class="hot-word-input-link"/>
+                  <WebLinkInput v-model="item.link" placeholder="跳转地址" class="hot-word-input-link" />
                   <el-button type="danger" icon="Delete" circle plain size="small" @click="removeHotWord(index)" />
                 </div>
                 <el-button type="primary" icon="Plus" link @click="addHotWord" class="add-hotword-btn">添加热词</el-button>
@@ -92,7 +92,7 @@
             </el-form-item>
 
             <el-form-item label="跳转地址:">
-              <WebLinkInput v-model="form.rightBtnLink" placeholder="请输入跳转地址" class="settings-input"/>
+              <WebLinkInput v-model="form.rightBtnLink" placeholder="请输入跳转地址" class="settings-input" />
             </el-form-item>
 
             <el-form-item label="主题色:">
@@ -133,7 +133,7 @@
             <div class="left-ad-settings" v-if="leftAdForm.leftAdImage">
               <el-form label-width="90px" label-position="left">
                 <el-form-item label="跳转地址:">
-                  <WebLinkInput v-model="leftAdForm.leftAdLink" placeholder="请输入以 http:// 或 https:// 开头的地址" class="settings-input-ad"/>
+                  <WebLinkInput v-model="leftAdForm.leftAdLink" placeholder="请输入以 http:// 或 https:// 开头的地址" class="settings-input-ad" />
                 </el-form-item>
               </el-form>
               <div class="left-ad-tip">
@@ -272,7 +272,7 @@
                 <el-input v-model="quickEntrySettings.moduleName" placeholder="如:企业工作台" />
               </el-form-item>
               <el-form-item label="跳转地址:">
-                <WebLinkInput v-model="quickEntrySettings.jumpLink" placeholder="标题点击跳转地址" style="width: 300px"/>
+                <WebLinkInput v-model="quickEntrySettings.jumpLink" placeholder="标题点击跳转地址" style="width: 300px" />
               </el-form-item>
             </el-form>
           </div>
@@ -421,7 +421,7 @@
                 <span v-else class="text-gray">-</span>
               </template>
             </el-table-column>
-            <el-table-column label="同步分类" prop="syncCategory" width="120" />
+            <!-- <el-table-column label="同步分类" prop="syncCategory" width="120" /> -->
             <el-table-column label="标签" min-width="180">
               <template #default="scope">
                 <div class="tag-wrap">
@@ -710,7 +710,7 @@
                 <el-input v-model="scenarioSettings.btnText" placeholder="请输入按钮文字" style="width: 400px" />
               </el-form-item>
               <el-form-item label="跳转链接:">
-                <WebLinkInput v-model="scenarioSettings.jumpLink" placeholder="请输入跳转地址" style="width: 400px"/>
+                <WebLinkInput v-model="scenarioSettings.jumpLink" placeholder="请输入跳转地址" style="width: 400px" />
               </el-form-item>
               <el-form-item label="主题背景色:">
                 <div class="theme-color-setting-pro">
@@ -943,7 +943,7 @@
             <el-table-column label="排行标签" width="220">
               <template #default="{ row }">
                 <el-input v-model="row.tagText" placeholder="标签文字" size="small" class="m-b-5" />
-                <WebLinkInput v-model="row.tagLink" placeholder="跳转链接" size="small"/>
+                <WebLinkInput v-model="row.tagLink" placeholder="跳转链接" size="small" />
               </template>
             </el-table-column>
             <el-table-column label="销量数据" width="130">
@@ -1098,7 +1098,7 @@
               <div class="notes-config-list">
                 <div v-for="(tag, index) in categoryForm.tags" :key="index" class="note-config-row">
                   <el-input v-model="tag.name" placeholder="标签名称" style="width: 120px" />
-                  <WebLinkInput v-model="tag.link" placeholder="跳转地址" style="flex: 1"/>
+                  <WebLinkInput v-model="tag.link" placeholder="跳转地址" style="flex: 1" />
                   <el-button type="danger" icon="Delete" circle plain size="small" @click="removeCategoryTag(index)" />
                 </div>
                 <el-button type="primary" icon="Plus" link @click="addCategoryTag">添加标签</el-button>
@@ -1109,7 +1109,79 @@
               <el-switch v-model="categoryForm.status" :active-value="1" :inactive-value="0" active-color="#13ce66" />
             </el-form-item>
           </el-tab-pane>
+          <el-tab-pane label="子菜单">
+            <div class="panel-config-section">
+              <div class="config-subtitle" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px">
+                <span>菜单层级维护</span>
+                <el-button type="primary" size="small" icon="Plus" @click="handleOpenSubMenuAdd('root')">新增子菜单</el-button>
+              </div>
 
+              <el-table
+                :data="subMenuTree"
+                row-key="id"
+                border
+                default-expand-all
+                :tree-props="{ children: 'children' }"
+                height="480"
+                style="width: 100%; margin-top: 10px"
+                class="standard-table sub-menu-beautiful-table"
+              >
+                <el-table-column prop="name" label="分类名称" min-width="220" />
+                <el-table-column label="层级" width="90" align="center">
+                  <template #default="{ row }">
+                    <span v-if="row.level === 1" class="el-tag level-tag-1 el-tag--small">一级</span>
+                    <span v-else-if="row.level === 2" class="el-tag level-tag-2 el-tag--small">二级</span>
+                    <span v-else-if="row.level === 3" class="el-tag level-tag-3 el-tag--small">三级</span>
+                  </template>
+                </el-table-column>
+                <el-table-column label="排序" width="130" align="center">
+                  <template #default="{ row }">
+                    <el-input-number
+                      v-if="row.level !== 1"
+                      v-model="row.sortOrder"
+                      :controls="false"
+                      :min="0"
+                      size="small"
+                      placeholder="100"
+                      class="no-arrows-input"
+                      style="width: 90px"
+                      @change="sortSubMenus"
+                    />
+                    <span v-else>-</span>
+                  </template>
+                </el-table-column>
+                <el-table-column label="启用状态" width="100" align="center">
+                  <template #default="{ row }">
+                    <el-switch
+                      v-if="row.level !== 1"
+                      v-model="row.status"
+                      :active-value="1"
+                      :inactive-value="0"
+                      active-color="#13ce66"
+                      size="small"
+                    />
+                    <span v-else>-</span>
+                  </template>
+                </el-table-column>
+                <el-table-column label="操作" width="200" align="center">
+                  <template #default="{ row }">
+                    <template v-if="row.level === 1">
+                      <el-button type="primary" link size="small" @click="handleOpenSubMenuAdd(row)">新增下级</el-button>
+                    </template>
+                    <template v-else-if="row.level === 2">
+                      <el-button type="primary" link size="small" @click="handleOpenSubMenuAdd(row)">新增下级</el-button>
+                      <el-button type="primary" link size="small" @click="handleOpenSubMenuEdit(row)">编辑</el-button>
+                      <el-button type="danger" link size="small" @click="handleDeleteSubMenu(row)">删除</el-button>
+                    </template>
+                    <template v-else-if="row.level === 3">
+                      <el-button type="primary" link size="small" @click="handleOpenSubMenuEdit(row)">编辑</el-button>
+                      <el-button type="danger" link size="small" @click="handleDeleteSubMenu(row)">删除</el-button>
+                    </template>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </el-tab-pane>
           <el-tab-pane label="右滑面板配置">
             <div class="panel-config-section">
               <div class="config-subtitle">品牌位设置 (图3)</div>
@@ -1151,6 +1223,36 @@
       </template>
     </el-dialog>
 
+    <!-- 子菜单新增/编辑弹窗 -->
+    <el-dialog
+      v-model="subMenuDialogVisible"
+      :title="subMenuDialogType === 'add' ? '新增子菜单' : '编辑子菜单'"
+      width="500px"
+      append-to-body
+      destroy-on-close
+    >
+      <el-form :model="subMenuForm" label-width="100px" class="dialog-form-inner">
+        <el-form-item label="菜单名称:">
+          <el-input v-model="subMenuForm.name" placeholder="请输入子菜单名称" />
+        </el-form-item>
+        <el-form-item label="上级菜单:">
+          <el-select v-model="subMenuForm.parentId" placeholder="请选择上级菜单" style="width: 100%">
+            <el-option v-for="opt in parentMenuOptions" :key="opt.id" :label="opt.name" :value="opt.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="排序值:">
+          <el-input-number v-model="subMenuForm.sortOrder" :controls="false" :min="0" placeholder="默认 100,越小越靠前" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="启用状态:">
+          <el-switch v-model="subMenuForm.status" :active-value="1" :inactive-value="0" active-color="#13ce66" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="subMenuDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitSubMenuForm">确定</el-button>
+      </template>
+    </el-dialog>
+
     <!-- 头部分类编辑弹窗 -->
     <el-dialog v-model="headerDialogVisible" :title="headerEditIndex > -1 ? '编辑头部分类' : '新增头部分类'" width="600px" destroy-on-close>
       <el-form :model="headerForm" label-width="100px" class="dialog-form-inner">
@@ -2071,7 +2173,7 @@ const onSyncCategoryChange = (val: string | number) => {
   }
 };
 
-const categoryList = ref<CategoryMainVO[]>([]);
+const categoryList = ref<CategoryMainVO[]>([]) as any;
 
 // 获取分类列表
 const getCategoryList = async () => {
@@ -2096,7 +2198,7 @@ const getCategoryList = async () => {
             subTitle: (item as any).panelSubTitle || '',
             notes: extra.notes || [],
             groups: extra.groups || []
-          }
+          } as any
         };
       });
     }
@@ -2123,6 +2225,7 @@ const categoryForm = reactive({
   syncCategoryId: null,
   syncCategory: '',
   tags: [],
+  subMenus: [],
   status: 1,
   panelData: {
     mainTitle: '',
@@ -2132,12 +2235,207 @@ const categoryForm = reactive({
   }
 });
 
+// 子菜单弹窗控制
+const subMenuDialogVisible = ref(false);
+const subMenuDialogType = ref('add');
+const subMenuForm = reactive({
+  id: null,
+  parentId: 'root',
+  name: '',
+  sortOrder: 100,
+  status: 1
+});
+
+// 可选的父级菜单选项
+const parentMenuOptions = computed(() => {
+  const options = [{ id: 'root', name: `无(作为二级菜单挂在 ${categoryForm.name || '当前分类'} 下)` }];
+  if (categoryForm.subMenus) {
+    categoryForm.subMenus.forEach((item) => {
+      options.push({ id: item.id, name: `二级菜单:${item.name}` });
+    });
+  }
+  return options;
+});
+
+// 构造子菜单层级展示树
+const subMenuTree = computed(() => {
+  return [
+    {
+      id: 'root',
+      name: categoryForm.name || '未命名分类',
+      level: 1,
+      status: categoryForm.status,
+      sortOrder: 1,
+      children: categoryForm.subMenus || []
+    }
+  ];
+});
+
+// 打开新增子菜单
+const handleOpenSubMenuAdd = (row) => {
+  subMenuDialogType.value = 'add';
+  subMenuForm.id = null;
+  subMenuForm.name = '';
+  subMenuForm.sortOrder = 100;
+  subMenuForm.status = 1;
+
+  if (row && row.level === 1) {
+    subMenuForm.parentId = 'root';
+  } else if (row && row.level === 2) {
+    subMenuForm.parentId = row.id;
+  } else {
+    subMenuForm.parentId = 'root';
+  }
+  subMenuDialogVisible.value = true;
+};
+
+// 打开编辑子菜单
+const handleOpenSubMenuEdit = (row) => {
+  subMenuDialogType.value = 'edit';
+  subMenuForm.id = row.id;
+  subMenuForm.name = row.name;
+  subMenuForm.sortOrder = row.sortOrder;
+  subMenuForm.status = row.status;
+
+  if (row.level === 3) {
+    const parent = categoryForm.subMenus.find((sec) => sec.children && sec.children.some((third) => third.id === row.id));
+    subMenuForm.parentId = parent ? parent.id : 'root';
+  } else {
+    subMenuForm.parentId = 'root';
+  }
+  subMenuDialogVisible.value = true;
+};
+
+// 提交子菜单
+const submitSubMenuForm = () => {
+  if (!subMenuForm.name) return ElMessage.warning('请输入子菜单名称');
+
+  if (subMenuDialogType.value === 'add') {
+    const newMenu = {
+      id: Date.now() + Math.floor(Math.random() * 1000),
+      name: subMenuForm.name,
+      sortOrder: subMenuForm.sortOrder ?? 100,
+      status: subMenuForm.status,
+      level: subMenuForm.parentId === 'root' ? 2 : 3
+    } as any;
+
+    if (newMenu.level === 2) {
+      newMenu.children = [];
+      if (!categoryForm.subMenus) categoryForm.subMenus = [];
+      categoryForm.subMenus.push(newMenu);
+    } else {
+      const parent = categoryForm.subMenus.find((sec) => sec.id === subMenuForm.parentId);
+      if (parent) {
+        if (!parent.children) parent.children = [];
+        parent.children.push(newMenu);
+      } else {
+        newMenu.level = 2;
+        newMenu.children = [];
+        if (!categoryForm.subMenus) categoryForm.subMenus = [];
+        categoryForm.subMenus.push(newMenu);
+      }
+    }
+    ElMessage.success('新增成功');
+  } else {
+    let itemToMove = null;
+    const idx2 = categoryForm.subMenus.findIndex((sec) => sec.id === subMenuForm.id);
+    if (idx2 !== -1) {
+      itemToMove = categoryForm.subMenus.splice(idx2, 1)[0];
+    } else {
+      for (const sec of categoryForm.subMenus) {
+        if (sec.children) {
+          const idx3 = sec.children.findIndex((third) => third.id === subMenuForm.id);
+          if (idx3 !== -1) {
+            itemToMove = sec.children.splice(idx3, 1)[0];
+            break;
+          }
+        }
+      }
+    }
+
+    if (itemToMove) {
+      itemToMove.name = subMenuForm.name;
+      itemToMove.sortOrder = subMenuForm.sortOrder ?? 100;
+      itemToMove.status = subMenuForm.status;
+      itemToMove.level = subMenuForm.parentId === 'root' ? 2 : 3;
+
+      if (itemToMove.level === 2) {
+        if (!itemToMove.children) itemToMove.children = [];
+        categoryForm.subMenus.push(itemToMove);
+      } else {
+        delete itemToMove.children;
+        const parent = categoryForm.subMenus.find((sec) => sec.id === subMenuForm.parentId);
+        if (parent) {
+          if (!parent.children) parent.children = [];
+          parent.children.push(itemToMove);
+        } else {
+          itemToMove.level = 2;
+          itemToMove.children = [];
+          categoryForm.subMenus.push(itemToMove);
+        }
+      }
+      ElMessage.success('修改成功');
+    } else {
+      ElMessage.error('未找到对应子菜单');
+    }
+  }
+
+  sortSubMenus();
+  subMenuDialogVisible.value = false;
+};
+
+// 删除子菜单
+const handleDeleteSubMenu = (row) => {
+  ElMessageBox.confirm(`确定要删除子菜单“${row.name}”吗?${row.level === 2 ? '这将会同时删除其下所有三级菜单。' : ''}`, '提示', {
+    type: 'warning'
+  }).then(() => {
+    if (row.level === 2) {
+      const idx = categoryForm.subMenus.findIndex((sec) => sec.id === row.id);
+      if (idx !== -1) {
+        categoryForm.subMenus.splice(idx, 1);
+        ElMessage.success('删除成功');
+      }
+    } else if (row.level === 3) {
+      for (const sec of categoryForm.subMenus) {
+        if (sec.children) {
+          const idx = sec.children.findIndex((third) => third.id === row.id);
+          if (idx !== -1) {
+            sec.children.splice(idx, 1);
+            ElMessage.success('删除成功');
+            break;
+          }
+        }
+      }
+    }
+  });
+};
+
+// 排序子菜单
+const sortSubMenus = () => {
+  if (!categoryForm.subMenus) return;
+  categoryForm.subMenus.sort((a, b) => {
+    const valA = typeof a.sortOrder === 'number' ? a.sortOrder : 100;
+    const valB = typeof b.sortOrder === 'number' ? b.sortOrder : 100;
+    return valA - valB;
+  });
+  categoryForm.subMenus.forEach((sec) => {
+    if (sec.children) {
+      sec.children.sort((a, b) => {
+        const valA = typeof a.sortOrder === 'number' ? a.sortOrder : 100;
+        const valB = typeof b.sortOrder === 'number' ? b.sortOrder : 100;
+        return valA - valB;
+      });
+    }
+  });
+};
+
 const handleAddCategory = () => {
   categoryDialogType.value = 'add';
   Object.assign(categoryForm, {
     id: null,
     name: '',
     icon: '',
+    subMenus: [],
     syncCategoryId: null,
     syncCategory: '',
     tags: [],
@@ -2167,7 +2465,8 @@ const submitCategoryForm = async () => {
     remark: JSON.stringify({
       tags: categoryForm.tags,
       notes: categoryForm.panelData.notes,
-      groups: categoryForm.panelData.groups
+      groups: categoryForm.panelData.groups,
+      subMenus: categoryForm.subMenus
     })
   };
 
@@ -2258,7 +2557,7 @@ const saveScenarioGlobalSettings = async () => {
   }
 };
 
-const scenarioList = ref<ScenarioCardsVO[]>([]);
+const scenarioList = ref<ScenarioCardsVO[]>([]) as any;
 
 // 获取场景卡片列表
 const getScenarioList = async () => {
@@ -2764,7 +3063,7 @@ const getAdModuleList = async () => {
 // 推荐设置模块逻辑
 const recommendThemeColor = ref('#e60012');
 const recommendProductThemeColor = ref('#e60012');
-const recommendActiveId = ref(1);
+const recommendActiveId = ref(1) as any;
 
 const recommendThemeConfigId = ref<string | number | null>(null);
 
@@ -2854,7 +3153,7 @@ const categoryOptions = ref<categoryTreeVO[]>([]);
 
 const getCategoryTreeData = async () => {
   try {
-    const res = await categoryTree({ dataSource: 'A10' } as any);
+    const res = await categoryTree({ dataSource: 'youyi', platform: '3', classLevel: 1 } as any);
     categoryOptions.value = (res.data || []) as any[];
   } catch (error) {
     console.error('获取分类树失败:', error);