소스 검색

广告模块提交

hurx 1 주 전
부모
커밋
f36953fbf5

+ 63 - 0
src/api/enterprisePurchase/adModuleConfig/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { AdModuleConfigVO, AdModuleConfigForm, AdModuleConfigQuery } from '@/api/enterprisePurchase/adModuleConfig/types';
+
+/**
+ * 查询广告模块主配置列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listAdModuleConfig = (query?: AdModuleConfigQuery): AxiosPromise<AdModuleConfigVO[]> => {
+  return request({
+    url: '/mall/adModuleConfig/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询广告模块主配置详细
+ * @param id
+ */
+export const getAdModuleConfig = (id: string | number): AxiosPromise<AdModuleConfigVO> => {
+  return request({
+    url: '/mall/adModuleConfig/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增广告模块主配置
+ * @param data
+ */
+export const addAdModuleConfig = (data: AdModuleConfigForm) => {
+  return request({
+    url: '/mall/adModuleConfig',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改广告模块主配置
+ * @param data
+ */
+export const updateAdModuleConfig = (data: AdModuleConfigForm) => {
+  return request({
+    url: '/mall/adModuleConfig',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除广告模块主配置
+ * @param id
+ */
+export const delAdModuleConfig = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/mall/adModuleConfig/' + id,
+    method: 'delete'
+  });
+};

+ 174 - 0
src/api/enterprisePurchase/adModuleConfig/types.ts

@@ -0,0 +1,174 @@
+export interface AdModuleConfigVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 模块编码
+   */
+  moduleCode: string;
+
+  /**
+   * 模块名称
+   */
+  moduleName: string;
+
+  /**
+   * 主标题
+   */
+  mainTitle: string;
+
+  /**
+   * 主标题颜色
+   */
+  mainTitleColor: string;
+
+  /**
+   * 副标题
+   */
+  subTitle: string;
+
+  /**
+   * 副标题颜色
+   */
+  subTitleColor: string;
+
+  /**
+   * 跳转链接
+   */
+  jumpLink: string;
+
+  /**
+   * 排序
+   */
+  sortOrder: number;
+
+  /**
+   * 状态 (1启用 0禁用)
+   */
+  status: number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+  adModuleItemList: any[];
+}
+
+export interface AdModuleConfigForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 模块编码
+   */
+  moduleCode?: string;
+
+  /**
+   * 模块名称
+   */
+  moduleName?: string;
+
+  /**
+   * 主标题
+   */
+  mainTitle?: string;
+
+  /**
+   * 主标题颜色
+   */
+  mainTitleColor?: string;
+
+  /**
+   * 副标题
+   */
+  subTitle?: string;
+
+  /**
+   * 副标题颜色
+   */
+  subTitleColor?: string;
+
+  /**
+   * 跳转链接
+   */
+  jumpLink?: string;
+
+  /**
+   * 排序
+   */
+  sortOrder?: number;
+
+  /**
+   * 状态 (1启用 0禁用)
+   */
+  status?: number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+  adModuleItemList?: any[];
+}
+
+export interface AdModuleConfigQuery extends PageQuery {
+  /**
+   * 模块编码
+   */
+  moduleCode?: string;
+
+  /**
+   * 模块名称
+   */
+  moduleName?: string;
+
+  /**
+   * 主标题
+   */
+  mainTitle?: string;
+
+  /**
+   * 主标题颜色
+   */
+  mainTitleColor?: string;
+
+  /**
+   * 副标题
+   */
+  subTitle?: string;
+
+  /**
+   * 副标题颜色
+   */
+  subTitleColor?: string;
+
+  /**
+   * 跳转链接
+   */
+  jumpLink?: string;
+
+  /**
+   * 排序
+   */
+  sortOrder?: number;
+
+  /**
+   * 状态 (1启用 0禁用)
+   */
+  status?: number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}

+ 63 - 0
src/api/enterprisePurchase/adModuleItem/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { AdModuleItemVO, AdModuleItemForm, AdModuleItemQuery } from '@/api/enterprisePurchase/adModuleItem/types';
+
+/**
+ * 查询广告模块子项列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listAdModuleItem = (query?: AdModuleItemQuery): AxiosPromise<AdModuleItemVO[]> => {
+  return request({
+    url: '/mall/adModuleItem/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询广告模块子项详细
+ * @param id
+ */
+export const getAdModuleItem = (id: string | number): AxiosPromise<AdModuleItemVO> => {
+  return request({
+    url: '/mall/adModuleItem/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增广告模块子项
+ * @param data
+ */
+export const addAdModuleItem = (data: AdModuleItemForm) => {
+  return request({
+    url: '/mall/adModuleItem',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改广告模块子项
+ * @param data
+ */
+export const updateAdModuleItem = (data: AdModuleItemForm) => {
+  return request({
+    url: '/mall/adModuleItem',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除广告模块子项
+ * @param id
+ */
+export const delAdModuleItem = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/mall/adModuleItem/' + id,
+    method: 'delete'
+  });
+};

+ 174 - 0
src/api/enterprisePurchase/adModuleItem/types.ts

@@ -0,0 +1,174 @@
+export interface AdModuleItemVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 关联模块ID
+   */
+  moduleId: string | number;
+
+  brandId: string | number;
+
+  /**
+   * 产品id
+   */
+  productId: string | number;
+
+  /**
+   * 商品或品牌名称
+   */
+  productName: string;
+
+  /**
+   * 图片链接
+   */
+  imageUrl: string;
+
+  /**
+   * 价格
+   */
+  price: number;
+
+  /**
+   * 标签文本
+   */
+  tagText: string;
+
+  /**
+   * 标签链接
+   */
+  tagLink: string;
+
+  /**
+   * 销量
+   */
+  salesCount: number;
+
+  /**
+   * 排序
+   */
+  sortOrder: number;
+
+  /**
+   * 备注
+   */
+  remark: string;
+}
+
+export interface AdModuleItemForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 关联模块ID
+   */
+  moduleId?: string | number;
+
+  brandId?: string | number;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 商品或品牌名称
+   */
+  productName?: string;
+
+  /**
+   * 图片链接
+   */
+  imageUrl?: string;
+
+  /**
+   * 价格
+   */
+  price?: number;
+
+  /**
+   * 标签文本
+   */
+  tagText?: string;
+
+  /**
+   * 标签链接
+   */
+  tagLink?: string;
+
+  /**
+   * 销量
+   */
+  salesCount?: number;
+
+  /**
+   * 排序
+   */
+  sortOrder?: number;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+}
+
+export interface AdModuleItemQuery extends PageQuery {
+  /**
+   * 关联模块ID
+   */
+  moduleId?: string | number;
+
+  /**
+   * 产品id
+   */
+  productId?: string | number;
+
+  /**
+   * 商品或品牌名称
+   */
+  productName?: string;
+
+  /**
+   * 图片链接
+   */
+  imageUrl?: string;
+
+  /**
+   * 价格
+   */
+  price?: number;
+
+  /**
+   * 标签文本
+   */
+  tagText?: string;
+
+  /**
+   * 标签链接
+   */
+  tagLink?: string;
+
+  /**
+   * 销量
+   */
+  salesCount?: number;
+
+  /**
+   * 排序
+   */
+  sortOrder?: number;
+
+  /**
+   * 平台标识
+   */
+  platformCode?: string;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}

+ 223 - 68
src/views/enterprisePurchase/index.vue

@@ -540,7 +540,7 @@
               </div>
               <div class="ad-products-subsidy">
                 <div v-for="item in adModules[0].items" :key="item.id" class="product-item">
-                  <div class="product-img"><img :src="item.image" alt="" /></div>
+                  <div class="product-img"><img :src="item.imageUrl" alt="" /></div>
                   <div class="product-price">¥{{ item.price }}</div>
                 </div>
               </div>
@@ -557,9 +557,9 @@
               </div>
               <div class="ad-products-ranking">
                 <div v-for="item in adModules[1].items" :key="item.id" class="ranking-item">
-                  <div class="ranking-badge">{{ item.tag || '排行榜' }} ></div>
-                  <div class="product-img"><img :src="item.image" alt="" /></div>
-                  <div class="ranking-footer">已售{{ item.sales }}件</div>
+                  <div class="ranking-badge">{{ item.tagText || '排行榜' }} ></div>
+                  <div class="product-img"><img :src="item.imageUrl" alt="" /></div>
+                  <div class="ranking-footer">已售{{ item.salesCount }}件</div>
                 </div>
               </div>
               <div class="ad-hover-mask">
@@ -575,9 +575,9 @@
               </div>
               <div class="ad-brands-content">
                 <div v-for="item in adModules[2].items" :key="item.id" class="brand-item">
-                  <div class="brand-logo"><img :src="item.image" alt="" /></div>
-                  <div class="brand-name">{{ item.tagLink || item.name }}</div>
-                  <div class="brand-tag-btn">{{ item.tag || '品质保障' }}</div>
+                  <div class="brand-logo"><img :src="item.imageUrl" alt="" /></div>
+                  <div class="brand-name">{{ item.tagLink || item.productName }}</div>
+                  <div class="brand-tag-btn">{{ item.tagText || '品质保障' }}</div>
                 </div>
               </div>
               <div class="ad-hover-mask">
@@ -593,7 +593,7 @@
               </div>
               <div class="ad-products-selection">
                 <div v-for="item in adModules[3].items" :key="item.id" class="selection-item">
-                  <div class="product-img"><img :src="item.image" alt="" /></div>
+                  <div class="product-img"><img :src="item.imageUrl" alt="" /></div>
                   <div class="product-price-row">
                     <span class="p-unit">¥</span>
                     <span class="p-val">{{ item.price }}</span>
@@ -613,7 +613,7 @@
               </div>
               <div class="ad-products-selection">
                 <div v-for="item in adModules[4].items" :key="item.id" class="selection-item">
-                  <div class="product-img"><img :src="item.image" alt="" /></div>
+                  <div class="product-img"><img :src="item.imageUrl" alt="" /></div>
                   <div class="product-price-row center">
                     <span class="p-unit">¥</span>
                     <span class="p-val">{{ item.price }}</span>
@@ -896,14 +896,14 @@
           </el-table-column>
           <el-table-column label="图片" width="100" align="center">
             <template #default="{ row }">
-              <img :src="row.image" style="width: 50px; height: 50px; object-fit: contain" />
+              <img :src="row.imageUrl" style="width: 50px; height: 50px; object-fit: contain" />
             </template>
           </el-table-column>
           <!-- 通用商品信息列 (百亿补贴、企采精选、京东新品) -->
           <el-table-column v-if="currentAdIdx === 0 || currentAdIdx === 3 || currentAdIdx === 4" label="商品信息" min-width="180">
             <template #default="{ row }">
               <div class="table-info-cell">
-                <div class="info-name">{{ row.name || '未选择' }}</div>
+                <div class="info-name">{{ row.productName || '未选择' }}</div>
                 <div class="info-price">价格:¥{{ row.price }}</div>
                 <div class="info-id">ID: {{ row.id || '-' }}</div>
               </div>
@@ -914,19 +914,19 @@
           <template v-if="currentAdIdx === 1">
             <el-table-column label="商品信息" min-width="150">
               <template #default="{ row }">
-                <div class="info-name">{{ row.name || '未选择' }}</div>
+                <div class="info-name">{{ row.productName || '未选择' }}</div>
                 <div class="info-id">ID: {{ row.id || '-' }}</div>
               </template>
             </el-table-column>
             <el-table-column label="排行标签" width="220">
               <template #default="{ row }">
-                <el-input v-model="row.tag" placeholder="标签文字" size="small" class="m-b-5" />
+                <el-input v-model="row.tagText" placeholder="标签文字" size="small" class="m-b-5" />
                 <el-input v-model="row.tagLink" placeholder="跳转链接" size="small" />
               </template>
             </el-table-column>
             <el-table-column label="销量数据" width="130">
               <template #default="{ row }">
-                <el-input v-model="row.sales" placeholder="销量" size="small">
+                <el-input v-model="row.salesCount" placeholder="销量" size="small">
                   <template #prepend>已售</template>
                 </el-input>
               </template>
@@ -937,14 +937,14 @@
           <template v-if="currentAdIdx === 2">
             <el-table-column label="品牌名称" min-width="180">
               <template #default="{ row }">
-                <div class="brand-name-display">{{ row.name || '未选择' }}</div>
+                <div class="brand-name-display">{{ row.productName || '未选择' }}</div>
                 <div class="info-id m-t-5">ID: {{ row.id || '-' }}</div>
               </template>
             </el-table-column>
             <el-table-column label="品牌标签" width="300">
               <template #default="{ row }">
                 <div class="flex-column gap-10">
-                  <el-input v-model="row.tag" placeholder="标签文字 (如: 品质保障)" />
+                  <el-input v-model="row.tagText" placeholder="标签文字 (如: 品质保障)" />
                   <el-input v-model="row.tagLink" placeholder="描述文字 (控制预览品牌名称)" />
                 </div>
               </template>
@@ -971,12 +971,12 @@
     <el-drawer v-model="selectDialogVisible" :title="currentAdIdx === 2 ? '选择品牌' : '选择商品'" size="850px" append-to-body>
       <div class="select-dialog-content">
         <el-input
-          v-model="selectSearchQuery"
+          v-model="productQueryParams.itemName"
           :placeholder="currentAdIdx === 2 ? '输入品牌名称搜索' : '输入商品名称或ID搜索'"
           prefix-icon="Search"
           clearable
           style="margin-bottom: 20px"
-          @input="selectCurrentPage = 1"
+          @input="getProductList"
         />
         <div class="select-list">
           <div
@@ -1001,10 +1001,12 @@
           <el-pagination
             v-model:current-page="selectCurrentPage"
             v-model:page-size="selectPageSize"
-            :total="filteredSelectList.length"
+            :total="productTotal"
             :page-sizes="[8, 12, 20, 50]"
             layout="total, sizes, prev, pager, next, jumper"
             background
+            @current-change="onProductPageChange"
+            @size-change="onProductPageSizeChange"
           />
         </div>
       </div>
@@ -1257,7 +1259,7 @@
     >
       <div class="drawer-content-wrapper">
         <div class="drawer-search-bar">
-          <el-input v-model="selectSearchQuery" placeholder="输入商品名称或ID搜索" prefix-icon="Search" clearable @input="selectCurrentPage = 1" />
+          <el-input v-model="productQueryParams.itemName" placeholder="输入商品名称或ID搜索" prefix-icon="Search" clearable @input="getProductList" />
         </div>
 
         <div class="drawer-stat-bar">
@@ -1295,10 +1297,12 @@
           <el-pagination
             v-model:current-page="selectCurrentPage"
             v-model:page-size="selectPageSize"
-            :total="filteredSelectList.length"
+            :total="productTotal"
             :page-sizes="[10, 20, 50, 100]"
             layout="total, sizes, prev, pager, next, jumper"
             background
+            @current-change="onProductPageChange"
+            @size-change="onProductPageSizeChange"
           />
         </div>
       </div>
@@ -1484,6 +1488,16 @@ import {
   updateQuickEntryItems
 } from '@/api/enterprisePurchase/quickEntryItems';
 import { QuickEntryItemsVO, QuickEntryItemsQuery, QuickEntryItemsForm } from '@/api/enterprisePurchase/quickEntryItems/types';
+import { listBase } from '@/api/pmsProduct/base';
+import { listBrand } from '@/api/product/brand';
+import {
+  listAdModuleConfig,
+  getAdModuleConfig,
+  delAdModuleConfig,
+  addAdModuleConfig,
+  updateAdModuleConfig
+} from '@/api/enterprisePurchase/adModuleConfig';
+import { AdModuleConfigVO, AdModuleConfigQuery, AdModuleConfigForm } from '@/api/enterprisePurchase/adModuleConfig/types';
 import {
   listHeaderCategory,
   getHeaderCategory,
@@ -2429,10 +2443,10 @@ const adModules = ref([
     subTitleColor: '#999999',
     type: 'subsidy',
     items: [
-      { id: 101, name: '企业商用台式机', image: '/static/images/purchase/pc_desktop.jpg', price: '69.9' },
-      { id: 102, name: '商务笔记本', image: '/static/images/purchase/laptop_hp.jpg', price: '84.8' },
-      { id: 103, name: '智能打印机', image: '/static/images/purchase/printer_office.jpg', price: '139.9' },
-      { id: 104, name: '高效办公组网', image: '/static/images/purchase/network_router.jpg', price: '1749' }
+      { id: 101, productName: '企业商用台式机', imageUrl: '/static/images/purchase/pc_desktop.jpg', price: '69.9' },
+      { id: 102, productName: '商务笔记本', imageUrl: '/static/images/purchase/laptop_hp.jpg', price: '84.8' },
+      { id: 103, productName: '智能打印机', imageUrl: '/static/images/purchase/printer_office.jpg', price: '139.9' },
+      { id: 104, productName: '高效办公组网', imageUrl: '/static/images/purchase/network_router.jpg', price: '1749' }
     ]
   },
   {
@@ -2443,8 +2457,24 @@ const adModules = ref([
     subTitleColor: '#f58220',
     type: 'ranking',
     items: [
-      { id: 201, name: '办公电脑榜', image: '/static/images/purchase/laptop_lenovo.jpg', price: '0', tag: '办公电脑榜', tagLink: '', sales: '1543' },
-      { id: 202, name: '文具榜', image: '/static/images/purchase/stationery_ranking.jpg', price: '0', tag: '文具榜', tagLink: '', sales: '2.3万' }
+      {
+        id: 201,
+        productName: '办公电脑榜',
+        imageUrl: '/static/images/purchase/laptop_lenovo.jpg',
+        price: '0',
+        tagText: '办公电脑榜',
+        tagLink: '',
+        salesCount: '1543'
+      },
+      {
+        id: 202,
+        productName: '文具榜',
+        imageUrl: '/static/images/purchase/stationery_ranking.jpg',
+        price: '0',
+        tagText: '文具榜',
+        tagLink: '',
+        salesCount: '1200'
+      }
     ]
   },
   {
@@ -2455,8 +2485,8 @@ const adModules = ref([
     subTitleColor: '#f58220',
     type: 'brand',
     items: [
-      { id: 301, name: '鲁花', image: '/static/images/purchase/oil_luhua.jpg', tag: '品质保障', tagLink: '鲁花京东自营旗舰店' },
-      { id: 302, name: '金龙鱼', image: '/static/images/purchase/oil_jinlongyu.jpg', tag: '热销品牌', tagLink: '金龙鱼京东自营旗舰店' }
+      { id: 301, productName: '鲁花', imageUrl: '/static/images/purchase/oil_luhua.jpg', tagText: '品质保障', tagLink: '鲁花京东自营旗舰店' },
+      { id: 302, productName: '金龙鱼', imageUrl: '/static/images/purchase/oil_jinlongyu.jpg', tagText: '热销品牌', tagLink: '金龙鱼京东自营旗舰店' }
     ]
   },
   {
@@ -2467,8 +2497,8 @@ const adModules = ref([
     subTitleColor: '#999999',
     type: 'selection',
     items: [
-      { id: 401, name: '高性能工作站', image: '/static/images/purchase/pc_desktop.jpg', price: '10740' },
-      { id: 402, name: '办公咖啡机', image: '/static/images/purchase/coffee_machine.jpg', price: '877' }
+      { id: 401, productName: '高性能工作站', imageUrl: '/static/images/purchase/pc_desktop.jpg', price: '10740' },
+      { id: 402, productName: '办公咖啡机', imageUrl: '/static/images/purchase/coffee_machine.jpg', price: '877' }
     ]
   },
   {
@@ -2479,8 +2509,8 @@ const adModules = ref([
     subTitleColor: '#f58220',
     type: 'new',
     items: [
-      { id: 501, name: '商用冷柜', image: '/static/images/purchase/freezer.jpg', price: '7188' },
-      { id: 502, name: '得力笔记本', image: '/static/images/purchase/notebook_deli.jpg', price: '34.9' }
+      { id: 501, productName: '商用冷柜', imageUrl: '/static/images/purchase/freezer.jpg', price: '7188' },
+      { id: 502, productName: '得力笔记本', imageUrl: '/static/images/purchase/notebook_deli.jpg', price: '34.9' }
     ]
   }
 ]);
@@ -2512,10 +2542,86 @@ const handleEditAd = (index) => {
   adDialogVisible.value = true;
 };
 
-const submitAdForm = () => {
-  adModules.value[currentAdIdx.value] = JSON.parse(JSON.stringify(adForm));
-  adDialogVisible.value = false;
-  ElMessage.success('配置保存成功');
+const submitAdForm = async () => {
+  const moduleData = adModules.value[currentAdIdx.value];
+  if (!moduleData) return;
+
+  const data: AdModuleConfigForm = {
+    moduleCode: moduleData.type || '',
+    moduleName: moduleData.title || '',
+    mainTitle: adForm.title,
+    mainTitleColor: adForm.titleColor,
+    subTitle: adForm.subTitle,
+    subTitleColor: adForm.subTitleColor,
+    jumpLink: '',
+    status: 1,
+    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
+    }))
+  };
+
+  try {
+    let res;
+    // 从 API 加载的真实数据才有有效 id,mock id(1-5)用 POST 新增
+    const isFromApi = moduleData.moduleCode && moduleData.id && String(moduleData.id).length > 10;
+    if (isFromApi) {
+      res = await updateAdModuleConfig({ ...data, id: moduleData.id });
+    } else {
+      res = await addAdModuleConfig(data);
+    }
+    if (res.code === 200) {
+      // 新增时回写后端返回的 id
+      const savedData = JSON.parse(JSON.stringify(adForm));
+      if (!isFromApi && res.data?.id) {
+        savedData.id = res.data.id;
+      }
+      adModules.value[currentAdIdx.value] = savedData;
+      adDialogVisible.value = false;
+      ElMessage.success('配置保存成功');
+    } else {
+      ElMessage.error(res.msg || '保存失败');
+    }
+  } catch (error) {
+    console.error('保存广告模块配置失败:', error);
+    ElMessage.error('保存失败');
+  }
+};
+
+// 获取广告模块配置列表
+const getAdModuleList = async () => {
+  try {
+    const res = await listAdModuleConfig();
+    if (res.code === 200 && res.rows && res.rows.length > 0) {
+      adModules.value = res.rows.map((item: AdModuleConfigVO) => ({
+        ...item,
+        title: item.mainTitle || '',
+        titleColor: item.mainTitleColor || '#333333',
+        subTitle: item.subTitle || '',
+        subTitleColor: item.subTitleColor || '#999999',
+        type: item.moduleCode || '',
+        items: (item.adModuleItemList || []).map((sub: any) => ({
+          id: sub.id,
+          productId: sub.productId || '',
+          productName: sub.productName || '',
+          imageUrl: sub.imageUrl || '',
+          price: sub.price || 0,
+          tagText: sub.tagText || '',
+          tagLink: sub.tagLink || '',
+          salesCount: sub.salesCount || 0
+        }))
+      }));
+    }
+  } catch (error) {
+    console.error('获取广告模块配置失败:', error);
+    ElMessage.error('获取广告模块配置失败');
+  }
 };
 
 // 推荐设置模块逻辑
@@ -2751,19 +2857,21 @@ const submitSelectedProducts = () => {
   ElMessage.success('已选商品配置已保存');
 };
 
-const openProductDrawer = () => {
+const openProductDrawer = async () => {
   const currentList = recommendList.value[currentRecommendIndex.value]?.selectedProducts || [];
   drawerSelection.value = JSON.parse(JSON.stringify(currentList));
-  selectSearchQuery.value = '';
+  productQueryParams.itemName = '';
+  productQueryParams.pageNum = 1;
+  productQueryParams.pageSize = selectPageSize.value;
   selectCurrentPage.value = 1;
   productSelectionDrawerVisible.value = true;
+  await getProductList();
 
   // 回显勾选逻辑
   nextTick(() => {
     if (drawerTableRef.value) {
       drawerTableRef.value.clearSelection();
-      // 由于启用了 reserve-selection,我们直接遍历库中匹配的项进行勾选
-      mockProductList.forEach((item) => {
+      productList.value.forEach((item) => {
         if (currentList.some((exist) => exist.id === item.id)) {
           drawerTableRef.value.toggleRowSelection(item, true);
         }
@@ -2826,51 +2934,97 @@ const scrollRecommend = (direction) => {
 
 // 商品选择逻辑
 const selectDialogVisible = ref(false);
-const selectSearchQuery = ref('');
 const selectedTempId = ref(null);
 const selectCurrentPage = ref(1);
 const selectPageSize = ref(8);
 
-const mockProductList = [
-  { id: 1001, name: 'Lenovo 联想 昭阳K4e 轻薄办公本 14英寸 i7/16G/512G', image: '/static/images/purchase/laptop_lenovo.jpg', price: '4599' },
-  { id: 1002, name: 'HP 惠普 战66 六代 商务笔记本电脑 锐龙版 15.6英寸', image: '/static/images/purchase/laptop_hp.jpg', price: '3899' },
-  { id: 1003, name: 'Apple iPad Air 10.9英寸 256G 银色 蜂窝版', image: '/static/images/purchase/ipad.jpg', price: '4799' },
-  { id: 1004, name: 'Logitech 罗技 MX Master 3S 无线鼠标 石墨黑', image: '/static/images/purchase/mouse.jpg', price: '699' },
-  { id: 1005, name: 'Dell 戴尔 U2723QE 27英寸 4K 核心显示器 IPS黑', image: '/static/images/purchase/monitor.jpg', price: '3299' },
-  { id: 3001, name: '鲁花 5S一级压榨花生油 5L 礼盒装 物理压榨', image: '/static/images/purchase/oil_luhua.jpg', price: '159.9' },
-  { id: 3002, name: '金龙鱼 阳光葵花籽油 5L 瓶装 零反式脂肪', image: '/static/images/purchase/oil_jinlongyu.jpg', price: '69.9' },
-  { id: 3003, name: '蒙牛 特仑苏 纯牛奶 250ml*12 提装 高钙低脂', image: '/static/images/purchase/water_nongfu.jpg', price: '65.0' },
-  { id: 3004, name: '三只松鼠 坚果礼盒 1.5kg 聚享版 办公室零食', image: '/static/images/purchase/coffee_machine.jpg', price: '128.0' },
-  { id: 3005, name: '农夫山泉 饮用天然水 550ml*24 整箱 弱碱性', image: '/static/images/purchase/water_nongfu.jpg', price: '28.8' },
-  { id: 5001, name: '得力 办公A4复印纸 80g 500张/包 5包/箱', image: '/static/images/purchase/paper_deli.jpg', price: '145.0' },
-  { id: 5002, name: '公牛 插座 10位 5米总控 办公专用排插', image: '/static/images/purchase/socket_bull.jpg', price: '89.0' }
-];
+// 商品列表(API数据)
+const productList = ref<any[]>([]);
+const productTotal = ref(0);
 
-const filteredSelectList = computed(() => {
-  if (!selectSearchQuery.value) return mockProductList;
-  return mockProductList.filter((item) => item.name.includes(selectSearchQuery.value) || item.id.toString().includes(selectSearchQuery.value));
+const productQueryParams = reactive({
+  pageNum: 1,
+  pageSize: 8,
+  itemName: '',
+  productStatus: 1
 });
 
-const pagedSelectList = computed(() => {
-  const start = (selectCurrentPage.value - 1) * selectPageSize.value;
-  const end = start + selectPageSize.value;
-  return filteredSelectList.value.slice(start, end);
+const brandQueryParams = reactive({
+  pageNum: 1,
+  pageSize: 8,
+  brandName: ''
 });
 
-const openProductSelect = (index) => {
+/** 获取商品/品牌列表(根据广告模块类型自动切换) */
+const getProductList = async () => {
+  try {
+    if (selectDialogVisible.value && currentAdIdx.value === 2) {
+      // 品牌好店:查询品牌
+      brandQueryParams.brandName = productQueryParams.itemName;
+      brandQueryParams.pageNum = productQueryParams.pageNum;
+      brandQueryParams.pageSize = productQueryParams.pageSize;
+      const res = await listBrand(brandQueryParams);
+      productList.value = (res.rows || []).map((item: any) => ({
+        id: item.id,
+        name: item.brandName || '',
+        image: item.brandLogo || '',
+        price: ''
+      }));
+      productTotal.value = res.total || 0;
+    } else {
+      // 其他广告模块:查询商品
+      const res = await listBase(productQueryParams);
+      productList.value = (res.rows || []).map((item: any) => ({
+        id: item.id,
+        name: item.itemName || '',
+        image: item.productImage || item.productImageUrl || '',
+        price: item.memberPrice ?? item.minSellingPrice ?? item.marketPrice ?? ''
+      }));
+      productTotal.value = res.total || 0;
+    }
+  } catch (error) {
+    console.error('获取列表失败:', error);
+    ElMessage.error('获取列表失败');
+  }
+};
+
+const filteredSelectList = computed(() => productList.value);
+
+const pagedSelectList = computed(() => productList.value);
+
+const onProductPageChange = (page: number) => {
+  productQueryParams.pageNum = page;
+  selectCurrentPage.value = page;
+  getProductList();
+};
+
+const onProductPageSizeChange = (size: number) => {
+  productQueryParams.pageSize = size;
+  productQueryParams.pageNum = 1;
+  selectCurrentPage.value = 1;
+  selectPageSize.value = size;
+  getProductList();
+};
+
+const openProductSelect = (index: number) => {
   currentItemIdx.value = index;
   selectedTempId.value = adForm.items[index].id;
-  selectSearchQuery.value = '';
+  productQueryParams.itemName = '';
+  productQueryParams.pageNum = 1;
+  productQueryParams.pageSize = selectPageSize.value;
+  selectCurrentPage.value = 1;
   selectDialogVisible.value = true;
+  getProductList();
 };
 
 const confirmSelect = () => {
-  const item = mockProductList.find((i) => i.id === selectedTempId.value);
+  const item = productList.value.find((i) => i.id === selectedTempId.value);
   if (item) {
     const target = adForm.items[currentItemIdx.value];
     target.id = item.id;
-    target.name = item.name;
-    target.image = item.image;
+    target.productId = item.id;
+    target.productName = item.name;
+    target.imageUrl = item.image;
     target.price = item.price;
     selectDialogVisible.value = false;
     ElMessage.success('选择成功');
@@ -3080,6 +3234,7 @@ onMounted(() => {
   getScenarioList();
   getQuickEntryModuleList();
   getQuickEntryItemsList();
+  getAdModuleList();
   // 获取左侧广告配置
   nextTick(() => {
     updateNavArrows();