|
@@ -202,7 +202,13 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="状态" width="100" align="center">
|
|
<el-table-column label="状态" width="100" align="center">
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
- <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" />
|
|
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="scope.row.status"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ @change="handleCarouselStatusChange(scope.row)"
|
|
|
|
|
+ active-color="#13ce66"
|
|
|
|
|
+ />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="150" align="center">
|
|
<el-table-column label="操作" width="150" align="center">
|
|
@@ -308,7 +314,7 @@
|
|
|
<el-table-column prop="link" label="跳转地址" show-overflow-tooltip />
|
|
<el-table-column prop="link" label="跳转地址" show-overflow-tooltip />
|
|
|
<el-table-column label="状态" width="100" align="center">
|
|
<el-table-column label="状态" width="100" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
- <el-switch v-model="row.status" :active-value="1" :inactive-value="0" />
|
|
|
|
|
|
|
+ <el-switch v-model="row.status" :active-value="1" :inactive-value="0" @change="handleQuickEntryStatusChange(row)" />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="150" fixed="right" align="center">
|
|
<el-table-column label="操作" width="150" fixed="right" align="center">
|
|
@@ -423,7 +429,13 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="状态" width="100" align="center">
|
|
<el-table-column label="状态" width="100" align="center">
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
- <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" />
|
|
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="scope.row.status"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ @change="handleCategoryStatusChange(scope.row)"
|
|
|
|
|
+ active-color="#13ce66"
|
|
|
|
|
+ />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
|
@@ -510,7 +522,13 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="状态" width="100" align="center">
|
|
<el-table-column label="状态" width="100" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
- <el-switch v-model="row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" />
|
|
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="row.status"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ @change="handleHeaderCategoryStatusChange(row)"
|
|
|
|
|
+ active-color="#13ce66"
|
|
|
|
|
+ />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="150" fixed="right" align="center">
|
|
<el-table-column label="操作" width="150" fixed="right" align="center">
|
|
@@ -846,7 +864,13 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="启用状态" width="100" align="center">
|
|
<el-table-column label="启用状态" width="100" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
- <el-switch v-model="row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" />
|
|
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="row.status"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ @change="handleRecommendStatusChange(row)"
|
|
|
|
|
+ active-color="#13ce66"
|
|
|
|
|
+ />
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="220" align="center" fixed="right">
|
|
<el-table-column label="操作" width="220" align="center" fixed="right">
|
|
@@ -1371,8 +1395,8 @@
|
|
|
<el-form-item v-if="recommendForm.type === 'category'" label="映射分类:">
|
|
<el-form-item v-if="recommendForm.type === 'category'" label="映射分类:">
|
|
|
<el-cascader
|
|
<el-cascader
|
|
|
v-model="recommendForm.categoryValue"
|
|
v-model="recommendForm.categoryValue"
|
|
|
- :options="mockCategoryOptions"
|
|
|
|
|
- :props="{ checkStrictly: true, expandTrigger: 'hover' }"
|
|
|
|
|
|
|
+ :options="categoryOptions"
|
|
|
|
|
+ :props="{ value: 'id', label: 'label', children: 'children', checkStrictly: true, expandTrigger: 'hover' }"
|
|
|
placeholder="请选择一级/二级/三级分类"
|
|
placeholder="请选择一级/二级/三级分类"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
filterable
|
|
filterable
|
|
@@ -1434,6 +1458,7 @@
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
import UploadImage from '@/components/upload-image/index.vue';
|
|
import UploadImage from '@/components/upload-image/index.vue';
|
|
|
|
|
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
|
|
import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
import {
|
|
import {
|
|
@@ -1447,9 +1472,16 @@ import {
|
|
|
import { SearchConfigVO, SearchConfigQuery, SearchConfigForm } from '@/api/enterprisePurchase/searchConfig/types';
|
|
import { SearchConfigVO, SearchConfigQuery, SearchConfigForm } from '@/api/enterprisePurchase/searchConfig/types';
|
|
|
import { listAdLeft, getAdLeft, delAdLeft, addAdLeft, updateAdLeft, getCurrentAdLeft } from '@/api/enterprisePurchase/adLeft';
|
|
import { listAdLeft, getAdLeft, delAdLeft, addAdLeft, updateAdLeft, getCurrentAdLeft } from '@/api/enterprisePurchase/adLeft';
|
|
|
import { AdLeftVO, AdLeftQuery, AdLeftForm } from '@/api/enterprisePurchase/adLeft/types';
|
|
import { AdLeftVO, AdLeftQuery, AdLeftForm } from '@/api/enterprisePurchase/adLeft/types';
|
|
|
-import { listCarousel, getCarousel, delCarousel, addCarousel, updateCarousel } from '@/api/enterprisePurchase/carousel';
|
|
|
|
|
|
|
+import { listCarousel, getCarousel, delCarousel, addCarousel, updateCarousel, changeStatus } from '@/api/enterprisePurchase/carousel';
|
|
|
import { CarouselVO, CarouselQuery, CarouselForm } from '@/api/enterprisePurchase/carousel/types';
|
|
import { CarouselVO, CarouselQuery, CarouselForm } from '@/api/enterprisePurchase/carousel/types';
|
|
|
-import { listCategoryMain, getCategoryMain, delCategoryMain, addCategoryMain, updateCategoryMain } from '@/api/enterprisePurchase/categoryMain';
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ listCategoryMain,
|
|
|
|
|
+ getCategoryMain,
|
|
|
|
|
+ delCategoryMain,
|
|
|
|
|
+ addCategoryMain,
|
|
|
|
|
+ updateCategoryMain,
|
|
|
|
|
+ changeStatus as categoryMainChangeStatus
|
|
|
|
|
+} from '@/api/enterprisePurchase/categoryMain';
|
|
|
import { CategoryMainVO, CategoryMainQuery, CategoryMainForm } from '@/api/enterprisePurchase/categoryMain/types';
|
|
import { CategoryMainVO, CategoryMainQuery, CategoryMainForm } from '@/api/enterprisePurchase/categoryMain/types';
|
|
|
import { listScenarioCards, getScenarioCards, delScenarioCards, addScenarioCards, updateScenarioCards } from '@/api/enterprisePurchase/scenarioCards';
|
|
import { listScenarioCards, getScenarioCards, delScenarioCards, addScenarioCards, updateScenarioCards } from '@/api/enterprisePurchase/scenarioCards';
|
|
|
import { ScenarioCardsVO, ScenarioCardsQuery, ScenarioCardsForm } from '@/api/enterprisePurchase/scenarioCards/types';
|
|
import { ScenarioCardsVO, ScenarioCardsQuery, ScenarioCardsForm } from '@/api/enterprisePurchase/scenarioCards/types';
|
|
@@ -1462,25 +1494,23 @@ import {
|
|
|
getQuickEntryItems,
|
|
getQuickEntryItems,
|
|
|
delQuickEntryItems,
|
|
delQuickEntryItems,
|
|
|
addQuickEntryItems,
|
|
addQuickEntryItems,
|
|
|
- updateQuickEntryItems
|
|
|
|
|
|
|
+ updateQuickEntryItems,
|
|
|
|
|
+ changeStatus as quickEntryItemsUpdateStatus
|
|
|
} from '@/api/enterprisePurchase/quickEntryItems';
|
|
} from '@/api/enterprisePurchase/quickEntryItems';
|
|
|
import { QuickEntryItemsVO, QuickEntryItemsQuery, QuickEntryItemsForm } from '@/api/enterprisePurchase/quickEntryItems/types';
|
|
import { QuickEntryItemsVO, QuickEntryItemsQuery, QuickEntryItemsForm } from '@/api/enterprisePurchase/quickEntryItems/types';
|
|
|
import { listBase } from '@/api/pmsProduct/base';
|
|
import { listBase } from '@/api/pmsProduct/base';
|
|
|
import { listBrand } from '@/api/product/brand';
|
|
import { listBrand } from '@/api/product/brand';
|
|
|
-import {
|
|
|
|
|
- listAdModuleConfig,
|
|
|
|
|
- getAdModuleConfig,
|
|
|
|
|
- delAdModuleConfig,
|
|
|
|
|
- addAdModuleConfig,
|
|
|
|
|
- updateAdModuleConfig
|
|
|
|
|
-} from '@/api/enterprisePurchase/adModuleConfig';
|
|
|
|
|
|
|
+import { categoryTree } from '@/api/product/base/index';
|
|
|
|
|
+import { categoryTreeVO } from '@/api/product/category/types';
|
|
|
|
|
+import { listAdModuleConfig, getAdModuleConfig, addAdModuleConfig, updateAdModuleConfig } from '@/api/enterprisePurchase/adModuleConfig';
|
|
|
import { AdModuleConfigVO, AdModuleConfigQuery, AdModuleConfigForm } from '@/api/enterprisePurchase/adModuleConfig/types';
|
|
import { AdModuleConfigVO, AdModuleConfigQuery, AdModuleConfigForm } from '@/api/enterprisePurchase/adModuleConfig/types';
|
|
|
import {
|
|
import {
|
|
|
listHeaderCategory,
|
|
listHeaderCategory,
|
|
|
getHeaderCategory,
|
|
getHeaderCategory,
|
|
|
delHeaderCategory,
|
|
delHeaderCategory,
|
|
|
addHeaderCategory,
|
|
addHeaderCategory,
|
|
|
- updateHeaderCategory
|
|
|
|
|
|
|
+ updateHeaderCategory,
|
|
|
|
|
+ changeStatus as headerCategoryChangeStatus
|
|
|
} from '@/api/enterprisePurchase/headerCategory';
|
|
} from '@/api/enterprisePurchase/headerCategory';
|
|
|
import {
|
|
import {
|
|
|
listRecommendThemeConfig,
|
|
listRecommendThemeConfig,
|
|
@@ -1495,7 +1525,8 @@ import {
|
|
|
getRecommendCategoryConfig,
|
|
getRecommendCategoryConfig,
|
|
|
delRecommendCategoryConfig,
|
|
delRecommendCategoryConfig,
|
|
|
addRecommendCategoryConfig,
|
|
addRecommendCategoryConfig,
|
|
|
- updateRecommendCategoryConfig
|
|
|
|
|
|
|
+ updateRecommendCategoryConfig,
|
|
|
|
|
+ changeStatus as recommendThemeChangeStatus
|
|
|
} from '@/api/enterprisePurchase/recommendCategoryConfig';
|
|
} from '@/api/enterprisePurchase/recommendCategoryConfig';
|
|
|
import {
|
|
import {
|
|
|
RecommendCategoryConfigVO,
|
|
RecommendCategoryConfigVO,
|
|
@@ -1558,6 +1589,63 @@ const leftAdForm = reactive({
|
|
|
leftAdImage: '',
|
|
leftAdImage: '',
|
|
|
leftAdLink: ''
|
|
leftAdLink: ''
|
|
|
});
|
|
});
|
|
|
|
|
+// 轮播图状态切换
|
|
|
|
|
+const handleCarouselStatusChange = async (row: any) => {
|
|
|
|
|
+ const oldValue = row.status; // 保存旧值(0 或 1)
|
|
|
|
|
+ try {
|
|
|
|
|
+ await changeStatus(row.id, row.status); // 传新值
|
|
|
|
|
+ proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ row.status = oldValue; // 失败回滚
|
|
|
|
|
+ proxy?.$modal.msgError('操作失败,请重试');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 轮播图状态切换
|
|
|
|
|
+const handleCategoryStatusChange = async (row: any) => {
|
|
|
|
|
+ const oldValue = row.status; // 保存旧值(0 或 1)
|
|
|
|
|
+ try {
|
|
|
|
|
+ await categoryMainChangeStatus(row.id, row.status); // 传新值
|
|
|
|
|
+ proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ row.status = oldValue; // 失败回滚
|
|
|
|
|
+ proxy?.$modal.msgError('操作失败,请重试');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+// 头部分类状态切换
|
|
|
|
|
+const handleHeaderCategoryStatusChange = async (row: any) => {
|
|
|
|
|
+ const oldValue = row.status; // 保存旧值(0 或 1)
|
|
|
|
|
+ try {
|
|
|
|
|
+ await headerCategoryChangeStatus(row.id, row.status); // 传新值
|
|
|
|
|
+ proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ row.status = oldValue; // 失败回滚
|
|
|
|
|
+ proxy?.$modal.msgError('操作失败,请重试');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+// 快捷入口状态切换
|
|
|
|
|
+const handleQuickEntryStatusChange = async (row: any) => {
|
|
|
|
|
+ const oldValue = row.status; // 保存旧值(0 或 1)
|
|
|
|
|
+ try {
|
|
|
|
|
+ await quickEntryItemsUpdateStatus(row.id, row.status); // 传新值
|
|
|
|
|
+ proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ row.status = oldValue; // 失败回滚
|
|
|
|
|
+ proxy?.$modal.msgError('操作失败,请重试');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 推荐状态切换
|
|
|
|
|
+const handleRecommendStatusChange = async (row: any) => {
|
|
|
|
|
+ const oldValue = row.status; // 保存旧值(0 或 1)
|
|
|
|
|
+ try {
|
|
|
|
|
+ await recommendThemeChangeStatus(row.id, row.status); // 传新值
|
|
|
|
|
+ proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ row.status = oldValue; // 失败回滚
|
|
|
|
|
+ proxy?.$modal.msgError('操作失败,请重试');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
// 左侧广告配置ID(单例)
|
|
// 左侧广告配置ID(单例)
|
|
|
const leftAdId = ref<string | number>('');
|
|
const leftAdId = ref<string | number>('');
|
|
@@ -1827,7 +1915,7 @@ const moveRow = async (index: number, direction: number) => {
|
|
|
const row = carouselList.value[i];
|
|
const row = carouselList.value[i];
|
|
|
await updateCarousel({
|
|
await updateCarousel({
|
|
|
id: row.id,
|
|
id: row.id,
|
|
|
- imageUrl: row.image || row.imageUrl,
|
|
|
|
|
|
|
+ imageUrl: row.imageUrl,
|
|
|
link: row.link,
|
|
link: row.link,
|
|
|
target: row.target,
|
|
target: row.target,
|
|
|
status: row.status,
|
|
status: row.status,
|
|
@@ -1843,9 +1931,9 @@ const moveRow = async (index: number, direction: number) => {
|
|
|
// 颜色转换工具:Hex 转 RGBA
|
|
// 颜色转换工具:Hex 转 RGBA
|
|
|
const hexToRgba = (hex, opacity) => {
|
|
const hexToRgba = (hex, opacity) => {
|
|
|
if (!hex) return `rgba(255, 255, 255, ${opacity})`;
|
|
if (!hex) return `rgba(255, 255, 255, ${opacity})`;
|
|
|
- let r = parseInt(hex.slice(1, 3), 16);
|
|
|
|
|
- let g = parseInt(hex.slice(3, 5), 16);
|
|
|
|
|
- let b = parseInt(hex.slice(5, 7), 16);
|
|
|
|
|
|
|
+ const r = parseInt(hex.slice(1, 3), 16);
|
|
|
|
|
+ const g = parseInt(hex.slice(3, 5), 16);
|
|
|
|
|
+ const b = parseInt(hex.slice(5, 7), 16);
|
|
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -1960,7 +2048,9 @@ const handleDeleteLeftAd = () => {
|
|
|
|
|
|
|
|
// 分类设置模块逻辑
|
|
// 分类设置模块逻辑
|
|
|
const categoryThemeColor = ref('#e60012');
|
|
const categoryThemeColor = ref('#e60012');
|
|
|
-const syncCategoryOptions = ['办公电脑', '办公设备', '办公家电', '文具耗材', '日用百货', '工业品', '食品饮料', '车载用品', '运动户外'];
|
|
|
|
|
|
|
+const syncCategoryOptions = computed(() => {
|
|
|
|
|
+ return (categoryOptions.value || []).map((item: any) => item.label);
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
const categoryList = ref<CategoryMainVO[]>([]);
|
|
const categoryList = ref<CategoryMainVO[]>([]);
|
|
|
|
|
|
|
@@ -2502,7 +2592,7 @@ const adModules = ref([
|
|
|
{ id: 502, productName: '得力笔记本', imageUrl: '/static/images/purchase/notebook_deli.jpg', price: '34.9' }
|
|
{ id: 502, productName: '得力笔记本', imageUrl: '/static/images/purchase/notebook_deli.jpg', price: '34.9' }
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
|
-]);
|
|
|
|
|
|
|
+]) as any;
|
|
|
|
|
|
|
|
const adDialogVisible = ref(false);
|
|
const adDialogVisible = ref(false);
|
|
|
const currentAdIdx = ref(-1);
|
|
const currentAdIdx = ref(-1);
|
|
@@ -2510,29 +2600,38 @@ const currentItemIdx = ref(-1);
|
|
|
const adForm = reactive({ title: '', titleColor: '#333333', subTitle: '', subTitleColor: '#f58220', items: [] });
|
|
const adForm = reactive({ title: '', titleColor: '#333333', subTitle: '', subTitleColor: '#f58220', items: [] });
|
|
|
|
|
|
|
|
// 实时预览辅助函数
|
|
// 实时预览辅助函数
|
|
|
-const getAdTitleStyle = (index, type) => {
|
|
|
|
|
|
|
+const getAdTitleStyle = (index: number, type: string) => {
|
|
|
const isEditing = adDialogVisible.value && currentAdIdx.value === index;
|
|
const isEditing = adDialogVisible.value && currentAdIdx.value === index;
|
|
|
const key = type === 'main' ? 'titleColor' : 'subTitleColor';
|
|
const key = type === 'main' ? 'titleColor' : 'subTitleColor';
|
|
|
const defaultColor = type === 'main' ? '#333' : '#999';
|
|
const defaultColor = type === 'main' ? '#333' : '#999';
|
|
|
- const color = isEditing ? adForm[key] : adModules.value[index][key] || defaultColor;
|
|
|
|
|
|
|
+ const color = isEditing ? adForm[key] : adModules.value[index]?.[key] || defaultColor;
|
|
|
return { color };
|
|
return { color };
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const getAdTitleText = (index, type) => {
|
|
|
|
|
|
|
+const getAdTitleText = (index: number, type: string) => {
|
|
|
const isEditing = adDialogVisible.value && currentAdIdx.value === index;
|
|
const isEditing = adDialogVisible.value && currentAdIdx.value === index;
|
|
|
const key = type === 'main' ? 'title' : 'subTitle';
|
|
const key = type === 'main' ? 'title' : 'subTitle';
|
|
|
- return isEditing ? adForm[key] : adModules.value[index][key];
|
|
|
|
|
|
|
+ return isEditing ? adForm[key] : adModules.value[index]?.[key] || '';
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const handleEditAd = (index) => {
|
|
|
|
|
|
|
+const emptyItem = () => ({ id: null, productId: '', productName: '', imageUrl: '', price: '', tagText: '', tagLink: '', salesCount: '' });
|
|
|
|
|
+const slotCounts = [4, 2, 2, 2, 2]; // 每个模块固定条目数
|
|
|
|
|
+
|
|
|
|
|
+const handleEditAd = (index: number) => {
|
|
|
currentAdIdx.value = index;
|
|
currentAdIdx.value = index;
|
|
|
- const ad = adModules.value[index];
|
|
|
|
|
- Object.assign(adForm, JSON.parse(JSON.stringify(ad)));
|
|
|
|
|
|
|
+ const ad = adModules.value[index] || {};
|
|
|
|
|
+ const data = JSON.parse(JSON.stringify(ad));
|
|
|
|
|
+ // 确保 items 有固定数量的条目(不够用空模板补齐)
|
|
|
|
|
+ const count = slotCounts[index] || 2;
|
|
|
|
|
+ while (data.items.length < count) {
|
|
|
|
|
+ data.items.push(emptyItem());
|
|
|
|
|
+ }
|
|
|
|
|
+ Object.assign(adForm, data);
|
|
|
adDialogVisible.value = true;
|
|
adDialogVisible.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const submitAdForm = async () => {
|
|
const submitAdForm = async () => {
|
|
|
- const moduleData = adModules.value[currentAdIdx.value];
|
|
|
|
|
|
|
+ const moduleData = adModules.value[currentAdIdx.value] as any;
|
|
|
if (!moduleData) return;
|
|
if (!moduleData) return;
|
|
|
|
|
|
|
|
const data: AdModuleConfigForm = {
|
|
const data: AdModuleConfigForm = {
|
|
@@ -2545,15 +2644,17 @@ const submitAdForm = async () => {
|
|
|
jumpLink: '',
|
|
jumpLink: '',
|
|
|
status: 1,
|
|
status: 1,
|
|
|
sortOrder: currentAdIdx.value,
|
|
sortOrder: currentAdIdx.value,
|
|
|
- adModuleItemList: adForm.items.map((item: any) => ({
|
|
|
|
|
- productId: item.productId || item.id,
|
|
|
|
|
- productName: item.productName || '',
|
|
|
|
|
- imageUrl: item.imageUrl || '',
|
|
|
|
|
- price: item.price || 0,
|
|
|
|
|
- tagText: item.tagText || '',
|
|
|
|
|
- tagLink: item.tagLink || '',
|
|
|
|
|
- salesCount: item.salesCount || 0
|
|
|
|
|
- }))
|
|
|
|
|
|
|
+ adModuleItemList: adForm.items
|
|
|
|
|
+ .filter((item: any) => item.productId || item.imageUrl)
|
|
|
|
|
+ .map((item: any) => ({
|
|
|
|
|
+ productId: item.productId || item.id,
|
|
|
|
|
+ productName: item.productName || '',
|
|
|
|
|
+ imageUrl: item.imageUrl || '',
|
|
|
|
|
+ price: item.price || 0,
|
|
|
|
|
+ tagText: item.tagText || '',
|
|
|
|
|
+ tagLink: item.tagLink || '',
|
|
|
|
|
+ salesCount: item.salesCount || 0
|
|
|
|
|
+ }))
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
@@ -2585,10 +2686,11 @@ const submitAdForm = async () => {
|
|
|
|
|
|
|
|
// 获取广告模块配置列表
|
|
// 获取广告模块配置列表
|
|
|
const getAdModuleList = async () => {
|
|
const getAdModuleList = async () => {
|
|
|
|
|
+ const defaults = adModules.value; // 保留当前 mock 数据作为缺省填充
|
|
|
try {
|
|
try {
|
|
|
const res = await listAdModuleConfig();
|
|
const res = await listAdModuleConfig();
|
|
|
if (res.code === 200 && res.rows && res.rows.length > 0) {
|
|
if (res.code === 200 && res.rows && res.rows.length > 0) {
|
|
|
- adModules.value = res.rows.map((item: AdModuleConfigVO) => ({
|
|
|
|
|
|
|
+ const apiList = res.rows.map((item: AdModuleConfigVO) => ({
|
|
|
...item,
|
|
...item,
|
|
|
title: item.mainTitle || '',
|
|
title: item.mainTitle || '',
|
|
|
titleColor: item.mainTitleColor || '#333333',
|
|
titleColor: item.mainTitleColor || '#333333',
|
|
@@ -2606,10 +2708,11 @@ const getAdModuleList = async () => {
|
|
|
salesCount: sub.salesCount || 0
|
|
salesCount: sub.salesCount || 0
|
|
|
}))
|
|
}))
|
|
|
}));
|
|
}));
|
|
|
|
|
+ // 确保始终有 5 个模块(模板固定访问 adModules[0]~[4])
|
|
|
|
|
+ adModules.value = Array.from({ length: 5 }, (_, i) => apiList[i] || defaults[i] || { title: '', items: [] });
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('获取广告模块配置失败:', error);
|
|
console.error('获取广告模块配置失败:', error);
|
|
|
- ElMessage.error('获取广告模块配置失败');
|
|
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -2702,36 +2805,27 @@ const recommendForm = reactive({
|
|
|
status: 1
|
|
status: 1
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const mockCategoryOptions = [
|
|
|
|
|
- {
|
|
|
|
|
- value: 'bg',
|
|
|
|
|
- label: '办公设备',
|
|
|
|
|
- children: [
|
|
|
|
|
- {
|
|
|
|
|
- value: 'dn',
|
|
|
|
|
- label: '办公电脑',
|
|
|
|
|
- children: [
|
|
|
|
|
- { value: 'bjb', label: '笔记本' },
|
|
|
|
|
- { value: 'tsj', label: '台式机' }
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- value: 'wj',
|
|
|
|
|
- label: '文具耗材',
|
|
|
|
|
- children: [
|
|
|
|
|
- {
|
|
|
|
|
- value: 'dy',
|
|
|
|
|
- label: '打印耗材',
|
|
|
|
|
- children: [
|
|
|
|
|
- { value: 'fyz', label: '复印纸' },
|
|
|
|
|
- { value: 'xhg', label: '硒鼓' }
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+const categoryOptions = ref<categoryTreeVO[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+const getCategoryTreeData = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await categoryTree({ dataSource: 'A10' } as any);
|
|
|
|
|
+ categoryOptions.value = (res.data || []) as any[];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取分类树失败:', error);
|
|
|
}
|
|
}
|
|
|
-];
|
|
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const findNodeById = (nodes: any[], id: string | number): any => {
|
|
|
|
|
+ for (const node of nodes) {
|
|
|
|
|
+ if (node.id === id) return node;
|
|
|
|
|
+ if (node.children) {
|
|
|
|
|
+ const found = findNodeById(node.children, id);
|
|
|
|
|
+ if (found) return found;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
const handleAddRecommend = () => {
|
|
const handleAddRecommend = () => {
|
|
|
recommendEditIndex.value = -1;
|
|
recommendEditIndex.value = -1;
|
|
@@ -2754,22 +2848,18 @@ const handleEditRecommend = (row, index) => {
|
|
|
recommendDialogVisible.value = true;
|
|
recommendDialogVisible.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const getLabelsByValues = (values, options) => {
|
|
|
|
|
- const labels = [];
|
|
|
|
|
- let currentOptions = options;
|
|
|
|
|
|
|
+const getLabelsByValues = (values: (string | number)[], tree: any[]): string => {
|
|
|
|
|
+ const labels: string[] = [];
|
|
|
for (const val of values) {
|
|
for (const val of values) {
|
|
|
- const target = currentOptions.find((opt) => opt.value === val);
|
|
|
|
|
- if (target) {
|
|
|
|
|
- labels.push(target.label);
|
|
|
|
|
- currentOptions = target.children || [];
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const node = findNodeById(tree, val);
|
|
|
|
|
+ if (node) labels.push(node.label);
|
|
|
}
|
|
}
|
|
|
return labels.join(' > ');
|
|
return labels.join(' > ');
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleRecommendCategoryChange = (val) => {
|
|
const handleRecommendCategoryChange = (val) => {
|
|
|
if (val && val.length > 0) {
|
|
if (val && val.length > 0) {
|
|
|
- recommendForm.categoryLabel = getLabelsByValues(val, mockCategoryOptions);
|
|
|
|
|
|
|
+ recommendForm.categoryLabel = getLabelsByValues(val, categoryOptions.value);
|
|
|
} else {
|
|
} else {
|
|
|
recommendForm.categoryLabel = '';
|
|
recommendForm.categoryLabel = '';
|
|
|
}
|
|
}
|
|
@@ -3045,7 +3135,10 @@ const getProductList = async () => {
|
|
|
id: item.id,
|
|
id: item.id,
|
|
|
name: item.itemName || '',
|
|
name: item.itemName || '',
|
|
|
image: item.productImage || item.productImageUrl || '',
|
|
image: item.productImage || item.productImageUrl || '',
|
|
|
- price: item.memberPrice ?? item.minSellingPrice ?? item.marketPrice ?? ''
|
|
|
|
|
|
|
+ price: item.memberPrice ?? item.minSellingPrice ?? item.marketPrice ?? '',
|
|
|
|
|
+ productNo: item.productNo || '',
|
|
|
|
|
+ isSelf: item.isSelf,
|
|
|
|
|
+ minOrderQuantity: item.minOrderQuantity || 1
|
|
|
}));
|
|
}));
|
|
|
productTotal.value = res.total || 0;
|
|
productTotal.value = res.total || 0;
|
|
|
}
|
|
}
|
|
@@ -3304,6 +3397,7 @@ onMounted(() => {
|
|
|
getAdModuleList();
|
|
getAdModuleList();
|
|
|
getRecommendThemeConfigList();
|
|
getRecommendThemeConfigList();
|
|
|
getRecommendCategoryList();
|
|
getRecommendCategoryList();
|
|
|
|
|
+ getCategoryTreeData();
|
|
|
// 获取左侧广告配置
|
|
// 获取左侧广告配置
|
|
|
nextTick(() => {
|
|
nextTick(() => {
|
|
|
updateNavArrows();
|
|
updateNavArrows();
|