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

```
feat(goods-center): 新增商品中心门店商品管理功能

- 新增 store-goods 页面和相关路由配置
- 添加商品分页查询、设置销售渠道及价格等API接口
- 实现商品渠道导入功能

feat(xsb-manage): 新增销售宝管理模块

- 新增 advertisement、fright-config、search、store-info 四个子模块
- 添加相应的路由配置和国际化配置
- 实现广告管理、运费配置、搜索管理等功能

fix(government): 修正政府端API接口地址

- 更新积分管理相关接口地址
- 修正用户列表接口地址

feat(table): 优化表格组件时间字段处理

- 支持多个时间字段映射处理
- 使用 Reflect.deleteProperty 替代 delete 操作

refactor(importTemplate): 优化导入模板下载功能

- 使用 commonExport 替代 window.open 实现文件下载

chore(env): 更新测试环境配置

- 更新测试服务器地址配置
- 添加多个测试环境URL配置选项

style(apiSelect): 添加调试日志输出
```

wenjie 1 день назад
Родитель
Сommit
6fb0ae442c

+ 6 - 3
.env.test

@@ -1,9 +1,12 @@
 # backend service base url, test environment
-# VITE_SERVICE_BASE_URL=http://192.168.0.157:9999 #王
-# VITE_SERVICE_BASE_URL=http://192.168.1.101:8080 #邓
-VITE_SERVICE_BASE_URL=http://192.168.1.89:8080 #田
+
+# VITE_SERVICE_BASE_URL=http://89561bkaq794.vicp.fun:53846 #张
+VITE_SERVICE_BASE_URL=https://70b4ca59.r9.vip.cpolar.cn #田
+# VITE_SERVICE_BASE_URL=https://2f3c6d21.r24.cpolar.top #邓
+# VITE_SERVICE_BASE_URL=http://74949mkfh190.vicp.fun #付
 # VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default
 
+# VITE_SERVICE_BASE_URL=http://192.168.1.242:8080 #测试本地服务器
 
 # other backend service base url, test environment
 VITE_OTHER_SERVICE_BASE_URL= `{

+ 2 - 0
src/components/zt/ApiSelect/api-select.vue

@@ -50,6 +50,8 @@ async function fetchApi() {
   }
   const res = await api(params);
   options.value = unref(bindValue).pagination ? [...options.value, ...res.data.records] : get(res, props.resultFeild);
+  console.log('options', options, unref(bindValue).pagination);
+
   fetchLoading.value = false;
   if (props.setDefaultValue) {
     console.log(options.value[0], unref(bindValue).valueFeild, 'options.value');

+ 21 - 3
src/components/zt/Table/z-table.vue

@@ -128,12 +128,30 @@ export default defineComponent({
     }
     function handleSearch() {
       const form = getSeachForm();
+      console.log(form);
+
       if (getTableProps.value.fieldMapToTime && form[getTableProps.value.fieldMapToTime[0][0] as unknown as string]) {
         const [startTimeKey, endTimeKey] = getTableProps.value.fieldMapToTime[0][1];
-        form[startTimeKey] = form.Time[0];
-        form[endTimeKey] = form.Time[1];
-        delete form.Time;
+        const formTimeKey = getTableProps.value.fieldMapToTime[0][0];
+        form[startTimeKey] = form[formTimeKey][0];
+        form[endTimeKey] = form[formTimeKey][1];
+        // delete form[formTimeKey];
+        Reflect.deleteProperty(form, formTimeKey);
+      }
+
+      if (
+        getTableProps.value.fieldMapToTime &&
+        getTableProps.value.fieldMapToTime[1] &&
+        form[getTableProps.value.fieldMapToTime[1][0] as unknown as string]
+      ) {
+        const [startTimeKey, endTimeKey] = getTableProps.value.fieldMapToTime[1][1];
+        const formTimeKey = getTableProps.value.fieldMapToTime[1][0];
+        form[startTimeKey] = form[formTimeKey][0];
+        form[endTimeKey] = form[formTimeKey][1];
+        // delete form[formTimeKey];
+        Reflect.deleteProperty(form, formTimeKey);
       }
+
       // 查询默认值,重置的时候不重置这个参数
       if (getTableProps.value.defaultParamsNotReset) {
         commonKeyData.value = form[getTableProps.value.defaultParamsNotReset];

+ 4 - 1
src/components/zt/importTemplate/z-import-template.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import type { UploadFileInfo } from 'naive-ui';
+import { commonExport } from '@/utils/common';
 import { useModal } from '../Modal/hooks/useModal';
 import BasicModal from '../Modal/basic-modal.vue';
 const emit = defineEmits<{ (e: 'submit', file: File): void }>();
@@ -33,7 +34,9 @@ function handleDownloadTemplate() {
     window.$message?.error('请传入下载模版URL');
     return;
   }
-  window.open(`${import.meta.env.VITE_SERVICE_BASE_URL}${props.url}`, '_blank');
+  // window.open(`${import.meta.env.VITE_SERVICE_BASE_URL}${props.url}`, '_blank');
+  commonExport(`${import.meta.env.VITE_SERVICE_BASE_URL}${props.url}`, '', '商品渠道及价格导入模版.xlsx');
+  // downloadTemplate();
 }
 </script>
 

+ 7 - 1
src/locales/langs/en-us.ts

@@ -254,11 +254,17 @@ const local: App.I18n.Schema = {
     'user-management_user-list': '',
     'goods-center': '',
     'goods-center_type-admin': '',
+    'goods-center_store-goods': '',
     government: '',
     'government_government-list': '',
     government_points: '',
     'government_user-list': '',
-    test: ''
+    test: '',
+    'xsb-manage': '',
+    'xsb-manage_advertisement': '',
+    'xsb-manage_fright-config': '',
+    'xsb-manage_search': '',
+    'xsb-manage_store-info': ''
   },
   page: {
     login: {

+ 7 - 1
src/locales/langs/zh-cn.ts

@@ -251,11 +251,17 @@ const local: App.I18n.Schema = {
     'user-management_user-list': '',
     'goods-center': '',
     'goods-center_type-admin': '',
+    'goods-center_store-goods': '',
     government: '',
     'government_government-list': '',
     government_points: '',
     'government_user-list': '',
-    test: ''
+    test: '',
+    'xsb-manage': '',
+    'xsb-manage_advertisement': '',
+    'xsb-manage_fright-config': '',
+    'xsb-manage_search': '',
+    'xsb-manage_store-info': ''
   },
   page: {
     login: {

+ 5 - 0
src/router/elegant/imports.ts

@@ -20,6 +20,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
   500: () => import("@/views/_builtin/500/index.vue"),
   "iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
   login: () => import("@/views/_builtin/login/index.vue"),
+  "goods-center_store-goods": () => import("@/views/goods-center/store-goods/index.vue"),
   "goods-center_type-admin": () => import("@/views/goods-center/type-admin/index.vue"),
   "government_government-list": () => import("@/views/government/government-list/index.vue"),
   government_points: () => import("@/views/government/points/index.vue"),
@@ -36,4 +37,8 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
   test: () => import("@/views/test/index.vue"),
   "user-center": () => import("@/views/user-center/index.vue"),
   "user-management_user-list": () => import("@/views/user-management/user-list/index.vue"),
+  "xsb-manage_advertisement": () => import("@/views/xsb-manage/advertisement/index.vue"),
+  "xsb-manage_fright-config": () => import("@/views/xsb-manage/fright-config/index.vue"),
+  "xsb-manage_search": () => import("@/views/xsb-manage/search/index.vue"),
+  "xsb-manage_store-info": () => import("@/views/xsb-manage/store-info/index.vue"),
 };

+ 56 - 0
src/router/elegant/routes.ts

@@ -48,6 +48,15 @@ export const generatedRoutes: GeneratedRoute[] = [
       i18nKey: 'route.goods-center'
     },
     children: [
+      {
+        name: 'goods-center_store-goods',
+        path: '/goods-center/store-goods',
+        component: 'view.goods-center_store-goods',
+        meta: {
+          title: 'goods-center_store-goods',
+          i18nKey: 'route.goods-center_store-goods'
+        }
+      },
       {
         name: 'goods-center_type-admin',
         path: '/goods-center/type-admin',
@@ -265,5 +274,52 @@ export const generatedRoutes: GeneratedRoute[] = [
         }
       }
     ]
+  },
+  {
+    name: 'xsb-manage',
+    path: '/xsb-manage',
+    component: 'layout.base',
+    meta: {
+      title: 'xsb-manage',
+      i18nKey: 'route.xsb-manage'
+    },
+    children: [
+      {
+        name: 'xsb-manage_advertisement',
+        path: '/xsb-manage/advertisement',
+        component: 'view.xsb-manage_advertisement',
+        meta: {
+          title: 'xsb-manage_advertisement',
+          i18nKey: 'route.xsb-manage_advertisement'
+        }
+      },
+      {
+        name: 'xsb-manage_fright-config',
+        path: '/xsb-manage/fright-config',
+        component: 'view.xsb-manage_fright-config',
+        meta: {
+          title: 'xsb-manage_fright-config',
+          i18nKey: 'route.xsb-manage_fright-config'
+        }
+      },
+      {
+        name: 'xsb-manage_search',
+        path: '/xsb-manage/search',
+        component: 'view.xsb-manage_search',
+        meta: {
+          title: 'xsb-manage_search',
+          i18nKey: 'route.xsb-manage_search'
+        }
+      },
+      {
+        name: 'xsb-manage_store-info',
+        path: '/xsb-manage/store-info',
+        component: 'view.xsb-manage_store-info',
+        meta: {
+          title: 'xsb-manage_store-info',
+          i18nKey: 'route.xsb-manage_store-info'
+        }
+      }
+    ]
   }
 ];

+ 7 - 1
src/router/elegant/transform.ts

@@ -182,6 +182,7 @@ const routeMap: RouteMap = {
   "404": "/404",
   "500": "/500",
   "goods-center": "/goods-center",
+  "goods-center_store-goods": "/goods-center/store-goods",
   "goods-center_type-admin": "/goods-center/type-admin",
   "government": "/government",
   "government_government-list": "/government/government-list",
@@ -202,7 +203,12 @@ const routeMap: RouteMap = {
   "test": "/test",
   "user-center": "/user-center",
   "user-management": "/user-management",
-  "user-management_user-list": "/user-management/user-list"
+  "user-management_user-list": "/user-management/user-list",
+  "xsb-manage": "/xsb-manage",
+  "xsb-manage_advertisement": "/xsb-manage/advertisement",
+  "xsb-manage_fright-config": "/xsb-manage/fright-config",
+  "xsb-manage_search": "/xsb-manage/search",
+  "xsb-manage_store-info": "/xsb-manage/store-info"
 };
 
 /**

+ 36 - 0
src/service/api/common.ts

@@ -19,6 +19,17 @@ export function fetchUpload(data: File, config?: any) {
   });
 }
 
+/**
+ * 下载模板
+ * @returns
+ */
+export function downloadTemplate() {
+  return request({
+    url: '/smqjh-pms/api/v1/channelProd/template/download',
+    method: 'get'
+  });
+}
+
 /**
  *新增或更新运费模板
  * @param data
@@ -49,3 +60,28 @@ export function fetchGetLoginUserList() {
     method: 'get'
   });
 }
+
+/**
+ * 企业ID查询运费模板
+ * @param channelId
+ * @returns
+ */
+export function fetchGetTransport(channelId: number) {
+  return request<Api.delivery.Transport2>({
+    url: `/platform/transport2/queryTransport2ByChannelId/${channelId}`,
+    method: 'get'
+  });
+}
+
+/**
+ * 后管端-企业运费列表
+ * @returns
+ */
+
+export function fetchChannelList(data: any) {
+  return request<{ records: Api.delivery.Transport2[] }>({
+    url: '/platform/transport2/transport2List',
+    method: 'get',
+    params: data
+  });
+}

+ 52 - 0
src/service/api/goods-center/store-goods/index.ts

@@ -0,0 +1,52 @@
+import { request } from '@/service/request';
+/**
+ * 分页获取商品
+ * @param params
+ * @returns
+ */
+export function fetchProductList(data: any) {
+  return request({
+    url: '/smqjh-pms/api/v1/product/page',
+    method: 'post',
+    data
+  });
+}
+
+/**
+ * 设置销售渠道及价格
+ * @param data
+ * @returns
+ */
+export function fetchSetUpChannels(data: any) {
+  return request<any>({
+    url: '/smqjh-pms/api/v1/channelProd/setUpChannels',
+    method: 'PUT',
+    data
+  });
+}
+
+/**
+ * 获取全部渠道商
+ * @returns
+ */
+export function fetchGetAllChannelList() {
+  return request<Api.goods.Channel[]>({
+    url: '/smqjh-system/api/v1/channel/listAll',
+    method: 'get'
+  });
+}
+/**
+ *
+ * @param data 导入渠道商品数据
+ * @returns
+ */
+export function fetchImportGoods(data: { file: File }) {
+  return request({
+    url: 'smqjh-pms/api/v1/channelProd/import',
+    method: 'post',
+    data,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
+  });
+}

+ 53 - 0
src/service/api/goods-center/type-admin/index.ts

@@ -34,6 +34,16 @@ export function fetchGetCategoryList(data: any) {
     data
   });
 }
+/**
+ * 三方应用下的列表
+ *
+ */
+export function fetchGetCategoryDetail(id: number | undefined) {
+  return request({
+    url: `/smqjh-pms/api/v1/categories/${id}`,
+    method: 'get'
+  });
+}
 /**
  *
     新增分类一级
@@ -48,3 +58,46 @@ export function fetchAddCategoryOne(data: any) {
     data
   });
 }
+
+/**
+ *
+    新增分类二级
+ * @param data
+ * @returns
+ */
+
+export function fetchAddCategoryTwo(data: any) {
+  return request({
+    url: `/smqjh-pms/api/v1/categories/saveCategoryForm`,
+    method: 'post',
+    data
+  });
+}
+/**
+ *
+    新增分类二级
+ * @param data
+ * @returns
+ */
+
+export function fetchEditCategory(data: any) {
+  return request({
+    url: `/smqjh-pms/api/v1/categories/updateCategory`,
+    method: 'post',
+    data
+  });
+}
+
+/**
+ *
+    删除分类
+ * @param data
+ * @returns
+ */
+
+export function delCategory(ids: any) {
+  return request({
+    url: `/smqjh-pms/api/v1/categories/${ids}`,
+    method: 'DELETE'
+  });
+}

+ 3 - 3
src/service/api/government/points/index.ts

@@ -7,7 +7,7 @@ import { request } from '@/service/request';
  */
 export function fetchGetPointsList(params: any) {
   return request<Api.government.PointsRecharge[]>({
-    url: '/platform/pointsRecharge/page',
+    url: '/smqjh-system/api/v1/pointsRecharge/page',
     method: 'get',
     params
   });
@@ -20,7 +20,7 @@ export function fetchGetPointsList(params: any) {
  */
 export function fetchImportPoints(params: File) {
   return request({
-    url: '/platform/pointsRecharge/import',
+    url: '/smqjh-system/api/v1/pointsRecharge/import',
     method: 'post',
     data: {
       file: params
@@ -38,7 +38,7 @@ export function fetchImportPoints(params: File) {
  */
 export function fetchGetPointsOutList(params: any) {
   return request<Api.government.PointsRechargeVO[]>({
-    url: '/platform/pointsRecharge/statisticsList',
+    url: '/smqjh-system/api/v1/pointsRecharge/statisticsList',
     method: 'get',
     params
   });

+ 1 - 1
src/service/api/government/user-list/index.ts

@@ -5,7 +5,7 @@ import { request } from '@/service/request';
  */
 export function fetchGetUserList(params: any) {
   return request<Api.government.userList[]>({
-    url: '/admin/enterprise/enterpriseUserList',
+    url: '/smqjh-system/api/v1/members/enterprise/enterpriseUserList',
     method: 'get',
     params
   });

+ 65 - 0
src/service/api/xsb-manage/advertisement/index.ts

@@ -0,0 +1,65 @@
+import { request } from '@/service/request';
+
+/**
+ * 分页获取广告列表
+ * @param params
+ * @returns
+ */
+export function fetchGetadvertInfoList(params: any) {
+  return request<Api.operation.AdvertInfo[]>({
+    url: '/smqjh-system/app/v1/advertInfo/page',
+    method: 'get',
+    params
+  });
+}
+/**
+ * 添加广告
+ * @param params
+ * @returns
+ */
+
+export function fetchAddAdvertInfo(params: any) {
+  return request({
+    url: '/smqjh-system/app/v1/advertInfo',
+    method: 'post',
+    data: params
+  });
+}
+
+/**
+ * 删除广告
+ * @param id
+ */
+export function fetchDeleteAdvertInfo(id: any) {
+  return request({
+    url: `/smqjh-system/app/v1/advertInfo/${id}`,
+    method: 'delete'
+  });
+}
+
+/**
+ * 更新广告
+ * @param params
+ * @returns
+
+ */
+export function fetchUpdateAdvertInfo(params: any) {
+  return request({
+    url: '/smqjh-system/app/v1/advertInfo',
+    method: 'put',
+    data: params
+  });
+}
+
+/**
+ * 更新广告
+ * @param params
+ * @returns
+
+ */
+export function fetchUpdateAdvertInfoStatus(id: any) {
+  return request({
+    url: `/smqjh-system/app/v1/advertInfo/operate/${id}`,
+    method: 'put'
+  });
+}

+ 53 - 0
src/service/api/xsb-manage/advertisement/search/index.ts

@@ -0,0 +1,53 @@
+import { request } from '@/service/request';
+
+/**
+ * 分页获取热门搜索
+ * @param params
+ * @returns
+ */
+export function fetchGethotSearch(params: any) {
+  return request<Api.operation.HotSearch[]>({
+    url: '/platform/SearchTerm/page',
+    method: 'get',
+    params
+  });
+}
+/**
+ * 新增热门搜索
+ * @param params
+ * @returns
+ */
+
+export function fetchAddHotSearch(params: any) {
+  return request({
+    url: '/platform/SearchTerm',
+    method: 'post',
+    data: params
+  });
+}
+
+/**
+ * 删除热门搜索
+
+*/
+export function fetchDeleteHotSearch(params: any) {
+  return request({
+    url: '/platform/SearchTerm',
+    method: 'delete',
+    data: params
+  });
+}
+
+/**
+ * 修改热门搜索
+ * @param params
+ * @returns
+
+ */
+export function fetchUpdateHotSearch(params: any) {
+  return request({
+    url: '/platform/SearchTerm',
+    method: 'put',
+    data: params
+  });
+}

+ 53 - 0
src/service/api/xsb-manage/search/index.ts

@@ -0,0 +1,53 @@
+import { request } from '@/service/request';
+
+/**
+ * 分页获取热门搜索
+ * @param params
+ * @returns
+ */
+export function fetchGethotSearch(params: any) {
+  return request<Api.operation.HotSearch[]>({
+    url: '/smqjh-system/app/v1/SearchTerm/page',
+    method: 'get',
+    params
+  });
+}
+/**
+ * 新增热门搜索
+ * @param params
+ * @returns
+ */
+
+export function fetchAddHotSearch(params: any) {
+  return request({
+    url: '/smqjh-system/app/v1/SearchTerm',
+    method: 'post',
+    data: params
+  });
+}
+
+/**
+ * 删除热门搜索
+
+*/
+export function fetchDeleteHotSearch(params: any) {
+  return request({
+    url: '/smqjh-system/app/v1/SearchTerm',
+    method: 'delete',
+    data: params
+  });
+}
+
+/**
+ * 修改热门搜索
+ * @param params
+ * @returns
+
+ */
+export function fetchUpdateHotSearch(params: any) {
+  return request({
+    url: '/smqjh-system/app/v1/SearchTerm',
+    method: 'put',
+    data: params
+  });
+}

+ 14 - 0
src/service/api/xsb-manage/store-info/index.ts

@@ -0,0 +1,14 @@
+import { request } from '@/service/request';
+
+/**
+ * 分页获取门店详细列表
+ * @param data
+ * @returns
+ */
+export function fetchGetStoreList(data: any) {
+  return request<Api.Store.ShopDetail[]>({
+    url: '/platform/shopDetail/page',
+    method: 'GET',
+    params: data
+  });
+}

+ 1324 - 0
src/typings/api.d.ts

@@ -401,5 +401,1329 @@ declare namespace Api {
       visible?: number;
       [property: string]: any;
     }
+    interface Channel {
+      /**
+       * 渠道名称
+       */
+      channelName?: string;
+      /**
+       * 主键
+       */
+      id?: number;
+      /**
+       * 渠道类型(1-企业用户,2-B端用户,3-C端用户)
+       */
+      type?: string;
+      [property: string]: any;
+    }
+    interface ChannelProd {
+      /**
+       * 渠道ID
+       */
+      channelId?: number;
+      /**
+       * 渠道对应商品售价
+       */
+      channelProdPrice?: number;
+      /**
+       * 出货价
+       */
+      deliveryPrice?: number;
+      /**
+       * 海博商品ID
+       */
+      hbSkuId?: string;
+      /**
+       * 主键
+       */
+      id?: number;
+      /**
+       * 删除状态(0-正常,1-删除)
+       */
+      isDelete?: number;
+      /**
+       * 进货价
+       */
+      purchasePrice?: number;
+      /**
+       * 记录时间
+       */
+      recTime?: string;
+      /**
+       * 门店ID
+       */
+      shopId?: number;
+      /**
+       * 门店名称
+       */
+      shopName?: string;
+      /**
+       * 单品ID
+       */
+      skuId?: number;
+      /**
+       * 修改时间
+       */
+      updateTime?: string;
+      /**
+       * 渠道名称       */
+      channelName?: string;
+      [property: string]: any;
+    }
+    interface Sku {
+      /**
+       * 实际库存
+       */
+      actualStocks?: number;
+      /**
+       * 单品编码(海博)
+       */
+      hbSkuId?: number;
+      /**
+       * 商品编码(海博)
+       */
+      hbSpuId?: number;
+      /**
+       * 0 正常 1 已被删除
+       */
+      isDelete?: number;
+      /**
+       * 商品条形码
+       */
+      modelId?: string;
+      /**
+       * 原价
+       */
+      oriPrice?: number;
+      /**
+       * 商家编码
+       */
+      partyCode?: string;
+      /**
+       * sku图片
+       */
+      pic: string;
+      /**
+       * 价格
+       */
+      price?: number;
+      /**
+       * 商品ID
+       */
+      prodId?: number;
+      /**
+       * 商品名称
+       */
+      prodName?: string;
+      /**
+       * 销售属性组合字符串,格式是p1:v1;p2:v2
+       */
+      properties?: string;
+      /**
+       * 记录时间
+       */
+      recTime?: string;
+      skuCode?: string;
+      /**
+       * 单品ID
+       */
+      skuId?: number;
+      /**
+       * sku名称
+       */
+      skuName?: string;
+      /**
+       * 积分价格
+       */
+      skuScore?: number;
+      /**
+       * 状态:0禁用 1 启用
+       */
+      status?: number;
+      /**
+       * 库存
+       */
+      stocks?: number;
+      /**
+       * 修改时间
+       */
+      updateTime?: string;
+      version?: number;
+      /**
+       * 体积
+       */
+      volume?: number;
+      /**
+       * 重量
+       */
+      weight?: number;
+      weightUnit?: string;
+      [property: string]: any;
+    }
+    interface ShopSku {
+      /**
+       * 渠道商品
+       */
+      channelProdList?: ChannelProd[];
+      /**
+       * 门店商品表ID
+       */
+      id?: number;
+      /**
+       * 0 正常 1 已被删除
+       */
+      isDelete?: number;
+      /**
+       * 记录时间
+       */
+      recTime?: string;
+      /**
+       * 门店ID
+       */
+      shopId?: number;
+      /**
+       * 商品对应门店价格
+       */
+      shopSkuPrice?: number;
+      /**
+       * 商品对应门店库存
+       */
+      shopSkuStocks?: number;
+      /**
+       * 单品ID
+       */
+      skuId?: number;
+      /**
+       * 商品详细
+       */
+      sku: Sku;
+      /**
+       * 修改时间
+       */
+      updateTime?: string;
+      [property: string]: any;
+    }
+  }
+  namespace delivery {
+    interface Transport2 {
+      /**
+       * 订单需要满多少
+       */
+      amount: number;
+      /**
+       * 渠道ID
+       */
+      channelId: number;
+      /**
+       * 创建时间
+       */
+      createTime: string;
+      /**
+       * 配送距离
+       */
+      distance: number;
+      /**
+       * 费用(元/20kg)
+       */
+      freightFee: number;
+      /**
+       * 配送费
+       */
+      piece: number;
+      /**
+       * 店铺id
+       */
+      shopId: number;
+      /**
+       * 运费模板名称
+       */
+      transName: string;
+      /**
+       * 运费模板id
+       */
+      transportId: number;
+      /**
+       * 重量限制
+       */
+      weight: number;
+      [property: string]: any;
+    }
+
+    interface devList {
+      /**
+       * 公司主页
+       */
+      companyHomeUrl?: string;
+      /**
+       * ID
+       */
+      dvyId?: number;
+      /**
+       * 物流公司名称
+       */
+      dvyName?: string;
+      /**
+       * 物流公司编号
+       */
+      dvyNo?: string;
+      /**
+       * 修改时间
+       */
+      modifyTime?: string;
+      /**
+       * 物流查询接口
+       */
+      queryUrl?: string;
+      /**
+       * 建立时间
+       */
+      recTime?: string;
+      [property: string]: any;
+    }
+    interface deliveryOrder {
+      /**
+       * 取消原因
+       */
+      cancelReason?: string;
+      /**
+       * 实际总值
+       */
+      actualTotal?: number;
+      /**
+       * 用户订单地址Id
+       */
+      addrOrderId?: number;
+      /**
+       * 取消时间
+       */
+      cancelTime?: string;
+      /**
+       * 渠道ID
+       */
+      channelId?: number;
+      /**
+       * 订单关闭原因 (1:超时未支付 2:退款关闭 4:买家取消 15:已通过货到付款交易)
+       */
+      closeType?: number;
+      /**
+       * 订购时间
+       */
+      createTime?: string;
+      /**
+       * 用户订单删除状态,0:没有删除, 1:回收站, 2:永久删除
+       */
+      deleteStatus?: number;
+      /**
+       * 物流单号
+       */
+      dvyFlowId?: string;
+      /**
+       * 配送方式ID
+       */
+      dvyId?: number;
+      /**
+       * 麦芽条状态 0 失败 1 成功 null为暂未创建
+       */
+      dvyStatus?: number;
+      /**
+       * 发货时间
+       */
+      dvyTime?: string;
+      /**
+       * 配送类型(1:快递 2:自提 3:及时配送)
+       */
+      dvyType: number;
+      /**
+       * 完成时间
+       */
+      finallyTime?: string;
+      /**
+       * 订单运费
+       */
+      freightAmount?: number;
+      /**
+       * 海博物流状态
+       * 20:已抢单,30:配送员到店,40:取货完成,50:配送单取消,100:已送达
+       */
+      hbLogisticStatus: number;
+      /**
+       * 海博订单状态
+       * 0-待支付 1-待发货,20-订单已接单(待拣货),30-订单待配送(拣货完成/自提类订单为待自提),40-订单配送中
+       * ,50-订单取消待审核,60-订单已取消,70-订单已送达,80-订单已完成
+       */
+      hbOrderStatus: number;
+      /**
+       * 是否已经支付,1:已经支付过,0:,没有支付过
+       */
+      isPayed?: number;
+      /**
+       * 亏损金额
+       */
+      lossAmount?: number;
+      nextPay?: boolean;
+      /**
+       * 买家昵称
+       * 买家名称
+       */
+      nickName?: string;
+      /**
+       * 积分
+       */
+      offsetPoints?: number;
+      /**
+       * 订单ID
+       */
+      orderId?: number;
+      orderItems?: OrderItemElement[];
+      subOrders?: OrderItemElement[];
+
+      /**
+       * 订购流水号
+       */
+      orderNumber?: string;
+      /**
+       * 订单类型参考orderType ,1团购订单 2秒杀订单,3积分订单
+       */
+      orderType?: number;
+      payScore?: number;
+      /**
+       * 付款时间
+       */
+      payTime?: string;
+      /**
+       * 支付方式 1 微信支付 2 支付宝,0积分支付
+       */
+      payType?: number;
+      /**
+       * 平台优惠总额
+       */
+      platformAmount?: number;
+      /**
+       * 产品名称,多个产品将会以逗号隔开
+       */
+      prodName?: string;
+      /**
+       * 订单商品总数
+       */
+      productNums?: number;
+      /**
+       * 牵牛花订单id
+       */
+      qnhOrderId?: string;
+      /**
+       * 牵牛花订单状态 0 失败 1 成功 null为暂未创建
+       */
+      qnhOrderStatus?: string;
+      /**
+       * 收货人
+       */
+      receiver?: string;
+      /**
+       * 优惠总额
+       */
+      reduceAmount?: number;
+      /**
+       * 退款订单编号
+       */
+      refundSn?: string;
+      /**
+       * 订单退款状态(1:申请退款 2:退款成功 3:部分退款成功 4:退款失败)
+       */
+      refundStatus?: number;
+      /**
+       * 退款类型
+       */
+      refundType?: number;
+      /**
+       * 用户备注
+       */
+      remarks?: string;
+      /**
+       * 退款状态
+       */
+      returnMoneySts?: number;
+      /**
+       * 订单所用积分
+       */
+      score?: number;
+      /**
+       * 店铺id
+       */
+      shopId?: number;
+      /**
+       * 店铺名称
+       */
+      shopName?: string;
+      /**
+       * 卖家备注
+       */
+      shopRemarks?: string;
+      /**
+       * 总值
+       */
+      total?: number;
+      /**
+       * 订单更新时间
+       */
+      updateTime?: string;
+      /**
+       * 用户订单地址
+       */
+      userAddrOrder?: UserAddrOrder;
+      /**
+       * 订购用户ID
+       */
+      userId?: string;
+      /**
+       * 买家手机号
+       */
+      userMobile?: string;
+      [property: string]: any;
+    }
+    interface OrderItemElement {
+      /**
+       * 商品实际金额 = 商品总金额 - 分摊的优惠金额
+       */
+      actualTotal?: number;
+      /**
+       * 加入购物车的时间
+       */
+      basketDate?: string;
+      /**
+       * 订单减少金额
+       */
+      chageAmount?: number;
+      /**
+       * 发货改变的数量
+       */
+      changeNum?: number;
+      /**
+       * 评论状态: 0 未评价  1 已评价
+       */
+      commSts?: number;
+      /**
+       * 分销佣金
+       */
+      distributionAmount?: number;
+      /**
+       * 推广员使用的推销卡号
+       */
+      distributionCardNo?: string;
+      /**
+       * 上级分销佣金
+       */
+      distributionParentAmount?: number;
+      /**
+       * 单个orderItem的配送类型 1:快递 2:自提 3:无需快递
+       */
+      dvyType?: number;
+      /**
+       * 订单确认收货获取的积分
+       */
+      gainScore?: number;
+      goodsTotal?: number;
+      /**
+       * 订单项ID
+       */
+      orderItemId?: number;
+      /**
+       * 订单orderNumber
+       */
+      orderNumber?: string;
+      /**
+       * 产品主图片路径
+       */
+      pic?: string;
+      /**
+       * 平台补贴的优惠金额
+       */
+      platformShareReduce?: number;
+      /**
+       * 产品价格
+       */
+      price?: number;
+      /**
+       * 购物车产品个数
+       */
+      prodCount?: number;
+      /**
+       * 产品ID
+       */
+      prodId?: number;
+      /**
+       * 产品名称
+       */
+      prodName?: string;
+      productCount?: number;
+      /**
+       * 商品总金额
+       */
+      productTotalAmount?: number;
+      /**
+       * 购物时间
+       */
+      recTime?: string;
+      /**
+       * 退款编号(退款编号为null时,说明订单为正常状态)
+       */
+      refundSn?: string;
+      /**
+       * 退款状态
+       */
+      returnMoneySts?: number;
+      /**
+       * 分摊的优惠金额
+       */
+      shareReduce?: number;
+      shopId?: number;
+      /**
+       * 产品SkuID
+       */
+      skuId?: number;
+      /**
+       * sku名称
+       */
+      skuName?: string;
+      /**
+       * 状态 -1待发货 0全部发货 其他数量为剩余待发货数量
+       */
+      status?: number;
+      /**
+       * 用户Id
+       */
+      userId?: string;
+      /**
+       * 使用积分
+       */
+      useScore?: number;
+      /**
+       * 售后处理中
+       */
+      refundIngCount?: number;
+      /**
+       * 退款成功
+       */
+      refundSuccessCount?: number;
+      [property: string]: any;
+    }
+    interface UserAddrOrder {
+      /**
+       * 地址
+       */
+      addr?: string;
+      /**
+       * 地址详情
+       */
+      addrDetail?: string;
+      /**
+       * 地址名称
+       */
+      address?: string;
+      /**
+       * 地址名称
+       */
+      addressName?: string;
+      /**
+       * 地址ID
+       */
+      addrId?: number;
+      /**
+       * ID
+       */
+      addrOrderId?: number;
+      /**
+       * 区
+       */
+      area?: string;
+      /**
+       * 区域ID
+       */
+      areaId?: number;
+      /**
+       * 城市
+       */
+      city?: string;
+      /**
+       * 城市ID
+       */
+      cityId?: number;
+      /**
+       * 建立时间
+       */
+      createTime?: string;
+      /**
+       * 纬度
+       */
+      latitude?: number;
+      /**
+       * 经度
+       */
+      longitude?: number;
+      /**
+       * 手机
+       */
+      mobile?: string;
+      /**
+       * 邮编
+       */
+      postCode?: string;
+      /**
+       * 省
+       */
+      province?: string;
+      /**
+       * 省ID
+       */
+      provinceId?: number;
+      /**
+       * 收货人
+       */
+      receiver?: string;
+      /**
+       * 用户ID
+       */
+      userId?: string;
+      /**
+       * 版本号
+       */
+      version?: number;
+      [property: string]: any;
+    }
+    interface DeliveryStatusNum {
+      all: number;
+      paddingPay: number;
+      paddingShipped: number;
+      paddingReceived: number;
+      completed: number;
+      cancel: number;
+    }
+    interface RefundAppointment {
+      /**
+       * 预约时间
+       */
+      appointmentTime?: string;
+      /**
+       * 客户姓名
+       */
+      customerName?: string;
+      /**
+       * 配送地址
+       */
+      deliveryAddress?: string;
+      /**
+       * 是否已经支付运费
+       */
+      hasPaidShippingFee?: boolean;
+      /**
+       * 预约ID
+       */
+      id?: number;
+      /**
+       * 联系电话
+       */
+      phoneNumber?: string;
+      /**
+       * 退货方式(1-上门取件,2用户自送)
+       */
+      refundMethod?: number;
+      /**
+       * 退款单号
+       */
+      refundNumber?: string;
+      /**
+       * 运费
+       */
+      shippingFee?: number;
+      /**
+       * 特殊要求
+       */
+      specialRequirements?: string;
+      /**
+       * 预约状态(0-待处理,1-已确认,2-已完成,3-已取消)
+       */
+      status?: number;
+      [property: string]: any;
+    }
+    interface OrderRefundDelivery {
+      /**
+       * 创建时间
+       */
+      createTime?: string;
+      /**
+       * 期望送达时间
+       */
+      deliveryTime?: number;
+      /**
+       * 物流公司id
+       */
+      deyId: number;
+      /**
+       * 物流公司名称
+       */
+      deyName: string;
+      /**
+       * 物流编号
+       */
+      deyNu: string;
+      /**
+       * 图片凭证
+       */
+      imgs?: string;
+      /**
+       * 是否支付
+       */
+      pay?: boolean;
+      /**
+       * 支付方 1 店铺、2 买家
+       */
+      payer?: string;
+      /**
+       * 配送价格
+       */
+      price?: number;
+      /**
+       * 收件人地址
+       */
+      receiverAddr?: string;
+      /**
+       * 收件人手机
+       */
+      receiverMobile?: string;
+      /**
+       * 收件人姓名
+       */
+      receiverName?: string;
+      /**
+       * 收件人邮政编码
+       */
+      receiverPostCode?: string;
+      /**
+       * 收件人座机
+       */
+      receiverTelephone?: string;
+      /**
+       * 退货物流信息id
+       */
+      refundDeliveryId?: number;
+      /**
+       * 退款编号
+       */
+      refundSn: string;
+      /**
+       * 发送人手机号码
+       */
+      senderMobile?: string;
+      /**
+       * 描述
+       */
+      senderRemarks?: string;
+      /**
+       * 店铺id
+       */
+      shopId: number;
+      /**
+       * 计算价格时间
+       */
+      touchTime?: number;
+      /**
+       * 用户id
+       */
+      userId: string;
+      [property: string]: any;
+    }
+    interface OrderRefund {
+      /**
+       * 配送预约信息
+       */
+      RefundAppointment: RefundAppointment;
+      /**
+       * 退货信息
+       */
+      refundDelivery: OrderRefundDelivery;
+
+      /**
+       * dvyType
+       *
+       * 1:快递 2:自提 3:无需快递
+       */
+      dvyType: number;
+      /**
+       * 退款单总分销金额
+       */
+      refundTotalMoney: number;
+      /**
+       * 退款轨迹
+       */
+      orderRefundRecordList?: OrderRefundRecord[];
+      /**
+       * 申请时间
+       */
+      applyTime?: string;
+      /**
+       * 申请类型:1,仅退款,2退款退货,5差价退款
+       */
+      applyType: number;
+      /**
+       * 申请说明
+       */
+      buyerDesc?: string;
+      /**
+       * 联系方式
+       */
+      buyerMobile?: string;
+      /**
+       * 申请原因
+       */
+      buyerReason?: string;
+      /**
+       * 撤销时间
+       */
+      cancelTime?: string;
+      /**
+       * 同意退款时间
+       */
+      decisionTime?: string;
+      /**
+       * 退款单总分销金额
+       */
+      distributionTotalAmount?: number;
+      freightAmount?: number;
+      /**
+       * 退货数量(0:为全部订单项)
+       */
+      goodsNum?: number;
+      /**
+       * 受理时间
+       */
+      handelTime?: string;
+      handler?: boolean;
+      /**
+       * 是否接收到商品(1:已收到,0:未收到)
+       */
+      isReceiver?: boolean;
+      /**
+       * 是否填写了退货物流信息(1:已填写,0:未填写)
+       */
+      isReturnLogistics?: boolean;
+      offsetPoints?: number;
+      /**
+       * 订单ID
+       */
+      orderId?: number;
+      /**
+       * 订单项ID
+       */
+      orderItemId?: number;
+      /**
+       * 订单编号
+       */
+      orderNumber: string;
+      /**
+       * 退款商品详情
+       */
+      orderRefundSkuList?: OrderRefundSku[];
+      /**
+       * 文件凭证json
+       */
+      photoFiles?: string;
+      /**
+       * 平台退款金额(退款时将这部分钱退回给平台,所以商家要扣除从平台这里获取的金额)
+       */
+      platformRefundAmount?: number;
+      /**
+       * 收货时间
+       */
+      receiveTime?: string;
+      /**
+       * 退款金额
+       */
+      refundAmount?: number;
+      /**
+       * 过期的积分
+       */
+      refundExpiredScore?: number;
+      /**
+       * 记录ID
+       */
+      refundId: number;
+      /**
+       * 退还积分
+       */
+      refundScore?: number;
+      /**
+       * 退款编号
+       */
+      refundSn: string;
+      /**
+       * 退款时间
+       */
+      refundTime?: string;
+      /**
+       * 退款单类型(1:整单退款,2:单个物品退款)
+       */
+      refundType?: number;
+      /**
+       * 拒绝原因
+       */
+      rejectMessage?: string;
+      /**
+       * 拒绝时间
+       */
+      rejectTime?: string;
+      /**
+       * 退款单状态 10:待审核 20:处理中 30:驳回退款 40:撤销退款 60:待退货(一审同意) 65:待确认收货(二审待审核) 70:退款完成
+       */
+      returnMoneySts: number;
+      /**
+       * 卖家备注
+       */
+      sellerMsg?: string;
+      /**
+       * 发货时间
+       */
+      shipTime?: string;
+      /**
+       * 店铺ID
+       */
+      shopId?: number;
+      /**
+       * 更新时间
+       */
+      updateTime?: string;
+      /**
+       * 买家ID
+       */
+      userId?: string;
+      /**
+       * 订单抵扣积分
+       */
+      OrderOffsetPoints: number;
+      /**
+       * 订单实际总值
+       */
+      actualTotal: number;
+      [property: string]: any;
+    }
+    interface OrderRefundRecord {
+      /**
+       * 审核状态(1-申请原因,2-商家待审核,5-用户待发货,7-待商家收货,10-审核通过,20-驳回,30-退款成功)
+       */
+      auditStatus?: number;
+      /**
+       * 创建时间
+       */
+      createTime?: string;
+      /**
+       * 退款记录ID
+       */
+      id?: number;
+      /**
+       * 说明
+       */
+      instructions?: string;
+      /**
+       * 退款单ID
+       */
+      orderRefundId?: number;
+      /**
+       * 排序
+       */
+      sort?: number;
+      /**
+       * 修改时间
+       */
+      updateTime?: string;
+      [property: string]: any;
+    }
+
+    /**
+     * OrderRefundSku
+     */
+    interface OrderRefundSku {
+      /**
+       * 记录ID
+       */
+      id?: number;
+      /**
+       * 订单项id
+       */
+      orderItemId?: number;
+      /**
+       * 退款单ID
+       */
+      orderRefundId?: number;
+      /**
+       * 退款商品数量
+       */
+      productCount?: number;
+      /**
+       * 退款商品ID
+       */
+      skuId?: number;
+      /**
+       * 商品单价
+       */
+      skuPrice?: number;
+      /**
+       * 规格
+       */
+      spec: string;
+      [property: string]: any;
+    }
+    interface OrderRefundCountParam {
+      /**
+       * 全部数量
+       */
+      allCount?: number;
+      /**
+       * 买家发货(65)
+       */
+      buyerDeliveryCount?: number;
+      /**
+       * 退款完成(70)
+       */
+      refundCompleteCount?: number;
+      /**
+       * 卖家接受(60)
+       */
+      sellerAcceptCount?: number;
+      /**
+       * 卖家申请(10)
+       */
+      sellerApplyCount?: number;
+      /**
+       * 卖家拒绝(30)
+       */
+      sellerRejectCount?: number;
+      /**
+       * 配送中数量(40)
+       */
+      shippingCount?: number;
+      /**
+       * 撤回申请(40)
+       */
+      withdrawApplyCount?: number;
+      [property: string]: any;
+    }
+  }
+  namespace Store {
+    interface ShopDetail {
+      /**
+       * 店铺所在区域(描述)
+       */
+      area?: string;
+      /**
+       * 店铺所在区域Id
+       */
+      areaId?: number;
+      /**
+       * 营业执照
+       */
+      businessLicense?: string;
+      /**
+       * 物品类型
+       */
+      category?: string;
+      /**
+       * 店铺所在城市(描述)
+       */
+      city?: string;
+      /**
+       * 店铺所在城市Id
+       */
+      cityId?: number;
+      /**
+       * 创建时间
+       */
+      createTime?: string;
+      /**
+       * 海博门店ID
+       */
+      hbStationId?: string;
+      /**
+       * 海博门店编码
+       */
+      hbStationNo?: string;
+      /**
+       * 身份证正面
+       */
+      identityCardFront?: string;
+      /**
+       * 身份证反面
+       */
+      identityCardLater?: string;
+      /**
+       * 店铺简介(可修改)
+       */
+      intro?: string;
+      /**
+       * 分销设置(0关闭 1开启)
+       */
+      isDistribution?: number;
+      /**
+       * 坐标类型 1 高德|腾讯 2 百度
+       */
+      mapType?: string;
+      /**
+       * 店铺绑定的手机(登录账号:唯一)
+       */
+      mobile?: string;
+      /**
+       * ERP门店编码
+       */
+      outStationNo?: string;
+      /**
+       * 登录密码
+       */
+      password?: string;
+      /**
+       * 店铺所在省份(描述)
+       */
+      province?: string;
+      /**
+       * 店铺所在省份Id
+       */
+      provinceId?: number;
+      /**
+       * 店铺详细地址
+       */
+      shopAddress?: string;
+      /**
+       * 配送平台店铺编码
+       */
+      shopCode?: string;
+      /**
+       * 店铺id
+       */
+      shopId?: number;
+      /**
+       * 店铺所在纬度(可修改)
+       */
+      shopLat?: string;
+      /**
+       * 店铺所在经度(可修改)
+       */
+      shopLng?: string;
+      /**
+       * 店铺logo(可修改)
+       */
+      shopLogo?: string;
+      /**
+       * 店铺名称(数字、中文,英文(可混合,不可有特殊字符),可修改)、不唯一
+       */
+      shopName?: string;
+      /**
+       * 店长
+       */
+      shopOwner?: string;
+      /**
+       * 店铺状态(-1:未开通 0: 停业中 1:营业中),可修改
+       */
+      shopStatus?: Api.Common.commonStatus;
+      /**
+       * 是否同步到配送平台
+       */
+      sync?: boolean;
+      /**
+       * 店铺联系电话
+       */
+      tel?: string;
+      /**
+       * 第三方id
+       */
+      thirdPartyCode?: string;
+      /**
+       * 更新时间
+       */
+      updateTime?: string;
+      /**
+       * 店长用户id
+       */
+      userId?: string;
+      /**
+       * 经营状态(0:停业,1正常)
+       */
+      runStatus?: Api.Common.commonStatus;
+      /**
+       * 营业状态(0:营业,1:打烊)
+       */
+      businessTime?: { startTime: string; endTime: string }[];
+
+      [property: string]: any;
+    }
+  }
+  namespace operation {
+    interface HotSearch {
+      /**
+       * 	创建时间
+       */
+      createTime: string;
+      /**
+       * 	有效时间
+       */
+      effectiveTime: string;
+      /**
+       *  结束时间
+       */
+      endTime: string;
+      /**
+       *  id
+       */
+      id: number;
+      /**
+       * 	跳转参数
+       */
+      jumpUrl: string;
+      /**
+       * 	落地页名称
+       */
+      reachName: string;
+      /**
+       * 	搜索名称
+       */
+      searchName: string;
+      /**
+       * 	状态 1正常 0关闭
+       */
+      status: Common.commonStatus;
+      /**
+       * 类型 1-关键词 2-热门搜索词 3-推荐搜索词
+       */
+      type: number;
+      [property: string]: any;
+    }
+    /**
+     * 广告
+     */
+    interface AdvertInfo {
+      /**
+       * 背景图
+       */
+      advertBack?: string;
+      /**
+       * 广告图片
+       */
+      advertImg?: string;
+      /**
+       * 广告名称
+       */
+      advertName?: string;
+      /**
+       * 排序
+       */
+      advertSort?: number;
+      createTime?: string;
+      deleted?: number;
+      id?: number;
+      /**
+       * 跳转路径
+       */
+      jumpUrl?: string;
+      /**
+       * 状态 1正常 2删除
+       */
+      status?: Api.Common.commonStatus;
+      [property: string]: any;
+    }
   }
 }

+ 12 - 0
src/typings/elegant-router.d.ts

@@ -36,6 +36,7 @@ declare module "@elegant-router/types" {
     "404": "/404";
     "500": "/500";
     "goods-center": "/goods-center";
+    "goods-center_store-goods": "/goods-center/store-goods";
     "goods-center_type-admin": "/goods-center/type-admin";
     "government": "/government";
     "government_government-list": "/government/government-list";
@@ -57,6 +58,11 @@ declare module "@elegant-router/types" {
     "user-center": "/user-center";
     "user-management": "/user-management";
     "user-management_user-list": "/user-management/user-list";
+    "xsb-manage": "/xsb-manage";
+    "xsb-manage_advertisement": "/xsb-manage/advertisement";
+    "xsb-manage_fright-config": "/xsb-manage/fright-config";
+    "xsb-manage_search": "/xsb-manage/search";
+    "xsb-manage_store-info": "/xsb-manage/store-info";
   };
 
   /**
@@ -115,6 +121,7 @@ declare module "@elegant-router/types" {
     | "test"
     | "user-center"
     | "user-management"
+    | "xsb-manage"
   >;
 
   /**
@@ -138,6 +145,7 @@ declare module "@elegant-router/types" {
     | "500"
     | "iframe-page"
     | "login"
+    | "goods-center_store-goods"
     | "goods-center_type-admin"
     | "government_government-list"
     | "government_points"
@@ -154,6 +162,10 @@ declare module "@elegant-router/types" {
     | "test"
     | "user-center"
     | "user-management_user-list"
+    | "xsb-manage_advertisement"
+    | "xsb-manage_fright-config"
+    | "xsb-manage_search"
+    | "xsb-manage_store-info"
   >;
 
   /**

+ 458 - 0
src/views/goods-center/store-goods/index.vue

@@ -0,0 +1,458 @@
+<script setup lang="tsx">
+import { computed, ref, useTemplateRef } from 'vue';
+import { NButton, NInputNumber, NSelect } from 'naive-ui';
+import dayjs from 'dayjs';
+// import { fetchGetAllStoreList } from '@/service/api/goods/desk-category';
+// import {
+// fetchGetAllChannelList
+// fetchImportGoods,
+// fetchSetUpChannels
+// } from '@/service/api/goods/store-goods';
+import { fetchGetDictDataList } from '@/service/api/system-manage';
+import {
+  fetchGetAllChannelList,
+  fetchImportGoods,
+  fetchProductList,
+  fetchSetUpChannels
+} from '@/service/api/goods-center/store-goods';
+import { areAllItemsAllFieldsFilled } from '@/utils/zt';
+import { commonExport } from '@/utils/common';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import SvgIcon from '@/components/custom/svg-icon.vue';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+type Price = { channelId: number | undefined; channelProdPrice: number; id: number; channelName: string };
+const importTemplateRef = useTemplateRef('importTemplateRef');
+
+const options = ref<Api.goods.Channel[]>([]);
+// const TypeName = ['企业用户', 'B端用户', 'C端用户'];
+const statusList = ['商家下架', '上架', '违规下架', '平台审核'];
+const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
+  {
+    type: 'selection',
+    align: 'center',
+    width: 48,
+    fixed: 'left'
+  },
+  {
+    key: 'supId',
+    title: '商品ID',
+    align: 'center',
+    width: 120
+  },
+  {
+    key: 'shopName',
+    title: '商品图片',
+    align: 'center',
+    width: 120,
+    render: (row: any) => {
+      return <n-image src={row.pic} width={60} height={60}></n-image>;
+    }
+  },
+
+  {
+    key: 'prodName',
+    title: '商品名称',
+    align: 'center',
+    width: 120,
+    ellipsis: {
+      tooltip: true
+    }
+  },
+  {
+    key: 'channelCode',
+    title: '业务类型',
+    align: 'center',
+    width: 120,
+    ellipsis: {
+      tooltip: true
+    }
+  },
+  {
+    key: 'shopName',
+    title: '商户',
+    align: 'center',
+    width: 120,
+    ellipsis: {
+      tooltip: true
+    }
+  },
+  {
+    key: 'shopName',
+    title: '价格',
+    align: 'center',
+    width: 120,
+    ellipsis: {
+      tooltip: true
+    }
+  },
+  {
+    key: 'shopSkuStocks',
+    title: '库存',
+    align: 'center',
+    width: 120,
+    ellipsis: {
+      tooltip: true
+    }
+  },
+  {
+    key: 'status',
+    title: '状态',
+    align: 'center',
+    width: 120,
+    render: (row: any) => {
+      return (
+        <div class="flex items-center justify-center">
+          <n-badge color={row.status == 1 ? 'green' : 'red'} value={row.status} dot />
+          <span class="ml-2">{statusList[row.status]}</span>
+        </div>
+      );
+    }
+  },
+  {
+    key: 'updateTime',
+    title: '更新时间',
+    align: 'center',
+    width: 120,
+    ellipsis: {
+      tooltip: true
+    }
+  }
+];
+const PriceColumns: NaiveUI.TableColumn<Price>[] = [
+  {
+    title: '销售渠道',
+    key: 'channelId',
+    align: 'center',
+    width: 250,
+    render: row => {
+      return (
+        <NSelect
+          options={options.value}
+          labelField="channelName"
+          valueField="id"
+          value={row.channelId}
+          clearable
+          onUpdate:value={value => {
+            options.value.map(it => {
+              if (it.id == row.channelId) {
+                it.disabled = false;
+              }
+              return it;
+            });
+            row.channelId = value ? Number(value) : undefined;
+          }}
+          onUpdate:show={value => {
+            options.value.map(it => {
+              if (it.id == row.channelId) {
+                if (value) {
+                  it.disabled = false;
+                }
+                if (!value) {
+                  it.disabled = true;
+                }
+              }
+              return it;
+            });
+          }}
+        ></NSelect>
+      );
+    }
+  },
+  {
+    title: '售价(元)',
+    key: 'channelProdPrice',
+    align: 'center',
+    width: 250,
+    render: row => {
+      return (
+        <NInputNumber
+          value={row.channelProdPrice}
+          precision={2}
+          onUpdate:value={value => {
+            row.channelProdPrice = Number(value);
+          }}
+          min={0}
+        />
+      );
+    }
+  },
+  {
+    title: () => {
+      return (
+        <div onClick={() => handleAddPrice()} class={'w-full flex items-center justify-center'}>
+          <SvgIcon
+            icon={'proicons:add-square'}
+            class={'cursor-pointer text-24px'}
+            style={'color:var(--n-color)'}
+          ></SvgIcon>
+        </div>
+      );
+    },
+    key: 'action',
+    width: 80,
+    align: 'center',
+    render: row => {
+      return (
+        <div onClick={() => handleDelPrice(row.id)} class={'w-full flex items-center justify-center'}>
+          <SvgIcon
+            icon={'proicons:subtract-square'}
+            class={'cursor-pointer text-24px'}
+            style={'color:#f5222d'}
+          ></SvgIcon>
+        </div>
+      );
+    }
+  }
+];
+const PriceData = ref<Price[]>([]);
+const selectData = ref<Api.goods.ShopSku>();
+const [registerTable, { getTableCheckedRowKeys, refresh, getTableData, getSeachForm, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      // {
+      //   label: '门店名称',
+      //   component: 'ApiSelect',
+      //   field: 'shopId',
+      //   componentProps: {
+      //     api: fetchGetAllStoreList,
+      //     labelFeild: 'shopName',
+      //     valueFeild: 'shopId'
+      //   }
+      // },
+      {
+        label: '关键词',
+        component: 'NInput',
+        field: 'keywords'
+      },
+      {
+        label: '业务类型',
+        field: 'channelCode',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchGetDictDataList,
+          labelFeild: 'name',
+          valueFeild: 'value',
+          resultFeild: 'data.list',
+          params: {
+            typeCode: 'sys_business_type'
+          }
+        }
+      },
+      {
+        label: '状态',
+        field: 'status',
+        component: 'NSelect',
+        componentProps: {
+          options: [
+            {
+              label: '上架',
+              value: 1
+            },
+            {
+              label: '商家下架',
+              value: 0
+            },
+            {
+              label: '违规下架',
+              value: 2
+            },
+            {
+              label: '平台审核',
+              value: 3
+            }
+          ]
+        }
+      },
+      {
+        label: '分类',
+        component: 'NCascader',
+        field: 'skuName',
+        componentProps: {}
+      },
+      {
+        label: '更新时间',
+        component: 'NDatePicker',
+        field: 'createTime',
+        componentProps: {
+          type: 'datetimerange',
+          defaultTime: ['00:00:00', '23:59:59']
+        }
+      },
+      {
+        label: '价格范围',
+        component: 'NInput',
+        field: 'price',
+        componentProps: {
+          separator: '-',
+          pair: true,
+          placeholder: ['最低价', '最高价'],
+          allowInput: (value: string) => !value || /^\d+$/.test(value)
+        }
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '商品列表',
+    showAddButton: false,
+    scrollX: 1800,
+    fieldMapToTime: [
+      ['price', ['minPrice', 'maxPrice']],
+      ['createTime', ['startTime', 'endTime']]
+    ]
+  }
+});
+
+const [
+  registerModalPrice,
+  { openModal: openPriceModal, setSubLoading: setSubModalLoding, closeModal: closePriceModal }
+] = useModal({
+  title: '设置渠道及价格',
+  width: 800,
+  height: 300
+});
+
+const isDisabledExport = computed(() => {
+  return !getTableCheckedRowKeys().length;
+});
+const tableData = computed(() => {
+  return getTableData();
+});
+
+async function handleSubmitImport(file: File) {
+  const { error } = await fetchImportGoods({ file });
+  if (!error) {
+    importTemplateRef.value?.closeModal();
+  }
+  importTemplateRef.value?.setSubLoading(false);
+}
+function openImportModal() {
+  importTemplateRef.value?.openModal();
+}
+function handleModalPrice(row: Api.goods.ShopSku) {
+  selectData.value = row;
+
+  if (row.channelVOS) {
+    PriceData.value = row.channelVOS?.map((it: Api.government.ChannelVO) => {
+      options.value.map(its => {
+        if (its.id == it.channelId) {
+          its.disabled = true;
+        }
+        return its;
+      });
+
+      return {
+        channelName: it.channelName,
+        channelId: Number(it.channelId),
+        channelProdPrice: Number(it.price),
+        id: Number(it.id)
+      };
+    });
+  }
+
+  openPriceModal();
+}
+function handleAddPrice() {
+  if (PriceData.value.length == 3) {
+    window.$message?.error('最多只能添加3条数据');
+    return;
+  }
+  PriceData.value.push({
+    channelName: '',
+    channelId: undefined,
+    channelProdPrice: 1,
+    id: dayjs().valueOf()
+  });
+}
+function handleDelPrice(id: number) {
+  PriceData.value = PriceData.value.filter(item => item.id != id);
+}
+
+async function handleSubmitPrice() {
+  if (!PriceData.value.length) {
+    window.$message?.error('最少填写一条数据');
+    return;
+  }
+  if (!areAllItemsAllFieldsFilled(PriceData.value)) {
+    window.$message?.error('请填写完整数据');
+    return;
+  }
+  setSubModalLoding(true);
+  const form = {
+    shopId: selectData.value?.shopId,
+    skuId: selectData.value?.skuId,
+    // purchasePrice: selectData.value?.channelProdList?.length ? selectData.value.channelProdList[0].purchasePrice : null,
+    // deliveryPrice: selectData.value?.channelProdList?.length ? selectData.value.channelProdList[0].deliveryPrice : null,
+    purchasePrice: selectData.value?.channelVOS?.length ? selectData.value.channelVOS[0].purchasePrice : null,
+    deliveryPrice: selectData.value?.channelVOS?.length ? selectData.value.channelVOS[0].deliveryPrice : null,
+    setChannelPriceFormList: PriceData.value.map(item => {
+      return {
+        channelName: item.channelName,
+        channelId: item.channelId,
+        channelProdPrice: item.channelProdPrice
+      };
+    })
+  };
+  const { error } = await fetchSetUpChannels(form);
+  if (!error) {
+    closePriceModal();
+    refresh();
+    PriceData.value = [];
+    options.value.map(it => (it.disabled = false));
+  } else {
+    setSubModalLoding(false);
+  }
+  console.log(PriceData.value, 'asdsad');
+}
+async function getData() {
+  const { data, error } = await fetchGetAllChannelList();
+  if (!error) {
+    options.value = data;
+  }
+}
+getData();
+async function handleExport() {
+  setTableLoading(true);
+  try {
+    await commonExport('/shop/shopProd/export', getSeachForm(), '商品列表.xlsx');
+  } finally {
+    setTableLoading(false);
+  }
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchProductList" @register="registerTable">
+      <template #op="{ row }">
+        <NButton size="small" ghost type="primary" @click="handleModalPrice(row)">设置渠道及价格</NButton>
+      </template>
+      <template #prefix="{ loading }">
+        <NSpace>
+          <NButton size="small" @click="openImportModal">导入商品销售渠道及价格</NButton>
+          <NButton size="small" :disabled="tableData.length == 0" :loading="loading" @click="handleExport">
+            导出全部
+          </NButton>
+          <NButton size="small" :disabled="isDisabledExport">导出选中数据</NButton>
+          <NButton size="small">修改记录</NButton>
+        </NSpace>
+      </template>
+    </ZTable>
+    <ZImportTemplate
+      ref="importTemplateRef"
+      url="/smqjh-pms/api/v1/channelProd/template/download"
+      template-text="商品渠道及价格导入模版.xlsx"
+      modal-text="导入商品销售渠道及价格"
+      @submit="handleSubmitImport"
+    ></ZImportTemplate>
+    <BasicModal @register="registerModalPrice" @ok="handleSubmitPrice">
+      <NDataTable :columns="PriceColumns" :data="PriceData" :row-key="row => row.id" />
+    </BasicModal>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

+ 149 - 35
src/views/goods-center/type-admin/index.vue

@@ -2,11 +2,24 @@
 import { nextTick, ref } from 'vue';
 import type { TreeOption } from 'naive-ui';
 import { NButton, NImage, NSwitch, NTree } from 'naive-ui';
-import { fetchGetAllCategory, fetchGetCategoryList } from '@/service/api/goods-center/type-admin';
+import {
+  delCategory,
+  fetchAddCategoryOne,
+  fetchAddCategoryTwo,
+  fetchEditCategory,
+  fetchGetAllCategory,
+  fetchGetCategoryDetail,
+  fetchGetCategoryList
+} from '@/service/api/goods-center/type-admin';
 import { useAppStore } from '@/store/modules/app';
 import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
 import { useForm } from '@/components/zt/Form/hooks/useForm';
 import DictTag from '@/components/zt/dict-tag/index.vue';
+interface ContactForm {
+  otherCategoryId: any;
+  code: string;
+  programCode: string;
+}
 const appStore = useAppStore();
 const deskData = ref<Api.goods.ShopCategory[]>([]);
 const loading = ref(false);
@@ -46,8 +59,10 @@ const [registerSearchForm, { getFieldsValue: getSearchForm }] = useForm({
   collapsedRows: 1
 });
 const loadedTreeData = ref<Record<string, any[]>>({});
+const chooseData = ref<Record<string, any[]>>({});
+
 const loadingStates = ref<Record<string, boolean>>({});
-const selectChekedKeys = ref<TreeOption[]>([]);
+const selectChekedKeys = ref<Record<string, TreeOption[]>>({});
 
 // 模拟接口请求函数
 const fetchTreeDataByCode = async (code: string) => {
@@ -55,6 +70,8 @@ const fetchTreeDataByCode = async (code: string) => {
   try {
     // 这里替换为实际的 API 调用
     const { data } = await fetchGetAllCategory(code); // 或其他获取树形数据的接口
+    console.log('dadads', data);
+
     loadedTreeData.value[code] = data;
   } finally {
     loadingStates.value[code] = false;
@@ -66,7 +83,7 @@ const [
     openModal: openModalForm,
     setFieldsValue: setModalFormValue,
     getFieldsValue: getModalFormValue,
-
+    closeModal: closeModalForm,
     setModalProps,
     setSubLoading,
     updateSchema
@@ -78,12 +95,54 @@ const [
   },
   formConfig: {
     schemas: [
+      {
+        field: 'createTime',
+        label: 'createTime',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'updateTime',
+        label: 'updateTime',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'sort',
+        label: 'sort',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'categoryCode',
+        label: 'categoryCode',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'isDelete',
+        label: 'isDelete',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'children',
+        label: 'children',
+        show: false,
+        component: 'NInput'
+      },
       {
         field: 'id',
         label: '分类ID',
         show: false,
         component: 'NInput'
       },
+      {
+        field: 'level',
+        label: 'level',
+        show: false,
+        component: 'NInput'
+      },
       {
         field: 'parentId',
         label: '上级分类',
@@ -186,7 +245,7 @@ const [
           multiple: true
         },
         ifShow({ model }) {
-          return model.businessType == 0;
+          return model.businessType == 0 && model.parentId;
         }
       },
       {
@@ -211,16 +270,28 @@ const [
                       {loadingStates.value[code] ? (
                         <div>加载中...</div>
                       ) : (
-                        <NTree
-                          data={loadedTreeData.value[code] || []}
-                          key-field={'code'}
-                          label-field={'name'}
-                          onUpdate:checked-keys={handleCheckedKeys}
-                          expand-on-click
-                          checkable
-                          block-line
-                          default-expand-all
-                        />
+                        loadedTreeData.value[code] &&
+                        loadedTreeData.value[code].map((item: any) => {
+                          return (
+                            <div>
+                              <div>{item.shopName}</div>
+                              <NTree
+                                data={item.shopCategoryVOS || []}
+                                key-field={'code'}
+                                label-field={'name'}
+                                onUpdate:checked-keys={(keys: Array<string | number>, options: Array<TreeOption>) =>
+                                  handleCheckedKeys(code, keys, options)
+                                }
+                                default-checked-keys={chooseData.value[code]}
+                                expand-on-click
+                                cascade
+                                checkable
+                                block-line
+                                default-expand-all
+                              />
+                            </div>
+                          );
+                        })
                       )}
                     </div>
                   </div>
@@ -278,7 +349,7 @@ const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
     width: 230,
     render: row => (
       <div class="flex-center gap-8px">
-        {row.level == 2 && (
+        {row.level == 1 && (
           <NButton type="primary" size="small" ghost onClick={() => add(row)}>
             添加二级分类
           </NButton>
@@ -288,40 +359,56 @@ const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
             编辑
           </NButton>
         }
-
-        {row.level == 3 && (
-          <NButton type="primary" size="small" ghost onClick={() => del(row)}>
-            删除
-          </NButton>
-        )}
+        <NButton type="primary" size="small" ghost onClick={() => del(row)}>
+          删除
+        </NButton>
       </div>
     )
   }
 ];
 
-function edit(row: Api.goods.ShopCategory) {
+async function edit(row: Api.goods.ShopCategory) {
   openModalForm(row);
+  const { data } = await fetchGetCategoryDetail(row.id);
+  data.businessType = Number(data.businessType);
+  let code: string[] = [];
+  data.children?.forEach((item: Api.goods.ShopCategory) => {
+    code.push(item.programCode);
+    if (chooseData.value[item.programCode as string]) {
+      chooseData.value[item.programCode as string].push(item.code);
+    } else {
+      chooseData.value[item.programCode] = [item.code];
+    }
+  });
+  code = Array.from(new Set(code));
+  // if (code.length) {
+  //   code.forEach(item => {
+  //     fetchTreeDataByCode(item);
+  //   });
+  // }
+  data.code = code;
+  console.log(data);
   setModalProps({ title: `修改${Number(row.level)}级分类` });
-  setModalFormValue({ ...row, label: row.label });
+  setModalFormValue({ ...data, label: row.label });
 }
 function add(row: Api.goods.ShopCategory) {
   openModalForm();
   console.log(row, 'row-key');
   updateSchema({ field: 'iconUrl', required: true });
   setModalProps({ title: `新增二级分类` });
-  setModalFormValue({ parentName: row.name, name: '', parentId: row.parentId });
+  setModalFormValue({ parentName: row.name, name: '', parentId: row.id });
 }
-function del(_row: Api.goods.ShopCategory) {
+function del(row: Api.goods.ShopCategory) {
   window.$dialog?.info({
     title: '删除分类',
     content: '你确定要删除吗?',
     positiveText: '确定',
     negativeText: '取消',
     onPositiveClick: async () => {
-      // const { error } = await fetchDeleteCategory(row.id);
-      // if (!error) {
-      //   getData();
-      // }
+      const { error } = await delCategory(row.id);
+      if (!error) {
+        getData();
+      }
     }
   });
 }
@@ -338,15 +425,42 @@ async function handleSubmit() {
   const form = await getModalFormValue();
   console.log(form, '表单');
   setSubLoading(false);
-  // if (!form.id) {
-  //   await fetchAddCategoryOne(form);
-  // }
-  // closeModalForm();
+  // 二级分类数据处理
+  if (form.parentId) {
+    const contactsForm: ContactForm[] = [];
+    for (const key in selectChekedKeys.value) {
+      if (Object.hasOwn(selectChekedKeys.value, key)) {
+        selectChekedKeys.value[key].forEach(i => {
+          contactsForm.push({
+            otherCategoryId: i.id,
+            code: i.code as string,
+            programCode: key
+          });
+        });
+      }
+    }
+    form.contactsForm = contactsForm;
+  }
+  if (!form.id) {
+    if (!form.parentId) {
+      // 新增一级分类
+      await fetchAddCategoryOne(form);
+    } else {
+      // 新增二级分类
+
+      await fetchAddCategoryTwo(form);
+    }
+  } else {
+    // 修改
+    await fetchEditCategory(form);
+  }
+  closeModalForm();
   getData();
 }
 getData();
-function handleCheckedKeys(_keys: Array<string | number>, option: Array<TreeOption>) {
-  selectChekedKeys.value = option;
+function handleCheckedKeys(code: string, _keys: Array<string | number>, option: Array<TreeOption>) {
+  selectChekedKeys.value[code] = option;
+  console.log(code, selectChekedKeys.value);
 }
 </script>
 

+ 69 - 68
src/views/government/points/index.vue

@@ -1,12 +1,12 @@
 <script setup lang="tsx">
-import { ref, useTemplateRef } from 'vue';
+import { nextTick, ref, useTemplateRef } from 'vue';
 import {
   fetchGetFailPointsList,
   fetchGetPointsList,
   fetchGetPointsOutList,
   fetchImportPoints
 } from '@/service/api/government/points';
-// import { fetchGetLoginUserList } from '@/service/api/common';
+import { fetchGetLoginUserList } from '@/service/api/common';
 import { useAuth } from '@/hooks/business/auth';
 import { commonExport } from '@/utils/common';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
@@ -71,26 +71,26 @@ const outColumns: NaiveUI.TableColumn<Api.government.PointsRechargeVO>[] = [
   }
 ];
 const searchSchemas: FormSchema[] = [
-  // {
-  //   field: 'channelIdList',
-  //   label: '所属企业',
-  //   component: 'ApiSelect',
-  //   componentProps: {
-  //     api: fetchGetLoginUserList,
-  //     labelFeild: 'channelName',
-  //     valueFeild: 'id',
-  //     multiple: true,
-  //     onUpdateValue: () => {
-  //       nextTick(() => {
-  //         handleSearch();
-  //       });
-  //     },
-  //     getOptions: async (options: any) => {
-  //       await setSearchForm({ channelIdList: [options[0].id] });
-  //       handleSearch();
-  //     }
-  //   }
-  // },
+  {
+    field: 'channelNoList',
+    label: '所属企业',
+    component: 'ApiSelect',
+    componentProps: {
+      api: fetchGetLoginUserList,
+      labelFeild: 'channelName',
+      valueFeild: 'channelNo',
+      multiple: true,
+      onUpdateValue: () => {
+        nextTick(() => {
+          handleSearch();
+        });
+      },
+      getOptions: async (options: any) => {
+        await setSearchForm({ channelNoList: [options[0].channelNo] });
+        handleSearch();
+      }
+    }
+  },
   {
     field: 'userAttrType',
     label: '人员属性',
@@ -175,29 +175,29 @@ const failColumns: NaiveUI.TableColumn<Api.government.PointsFailureRecordVO>[] =
   }
 ];
 const failData = ref<Api.government.PointsFailureRecordVO[]>([]);
-const [registerTable, { refresh }] = useTable({
+const [registerTable, { refresh, setFieldsValue: setSearchValues }] = useTable({
   searchFormConfig: {
     schemas: [
-      // {
-      //   field: 'channelIdList',
-      //   label: '所属企业',
-      //   component: 'ApiSelect',
-      //   componentProps: {
-      //     api: fetchGetLoginUserList,
-      //     labelFeild: 'channelName',
-      //     valueFeild: 'id',
-      //     multiple: true,
-      //     onUpdateValue: () => {
-      //       nextTick(() => {
-      //         listHandleSearch();
-      //       });
-      //     },
-      //     getOptions: async (options: any) => {
-      //       await setSearchValues({ channelIdList: [options[0].id] });
-      //       listHandleSearch();
-      //     }
-      //   }
-      // },
+      {
+        field: 'channelNoList',
+        label: '所属企业',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchGetLoginUserList,
+          labelFeild: 'channelName',
+          valueFeild: 'channelNo',
+          multiple: true,
+          onUpdateValue: () => {
+            nextTick(() => {
+              listHandleSearch();
+            });
+          },
+          getOptions: async (options: any) => {
+            await setSearchValues({ channelNoList: [options[0].channelNo] });
+            listHandleSearch();
+          }
+        }
+      },
       {
         field: 'userAttrType',
         label: '人员属性',
@@ -221,22 +221,23 @@ const [registerTable, { refresh }] = useTable({
     defaultParamsNotReset: 'channelIdList'
   }
 });
-const [registerModalTable, { refresh: refreshModal, getSeachForm, setTableLoading, getTableData }] = useTable({
-  searchFormConfig: {
-    schemas: searchSchemas,
-    inline: false,
-    size: 'small',
-    labelPlacement: 'left',
-    isFull: false
-  },
-  tableConfig: {
-    keyField: 'id',
-    title: '积分列表',
-    showAddButton: false,
-    minHeight: 400,
-    defaultParamsNotReset: 'channelIdList'
-  }
-});
+const [registerModalTable, { refresh: refreshModal, setFieldsValue, getSeachForm, setTableLoading, getTableData }] =
+  useTable({
+    searchFormConfig: {
+      schemas: searchSchemas,
+      inline: false,
+      size: 'small',
+      labelPlacement: 'left',
+      isFull: false
+    },
+    tableConfig: {
+      keyField: 'id',
+      title: '积分列表',
+      showAddButton: false,
+      minHeight: 400,
+      defaultParamsNotReset: 'channelIdList'
+    }
+  });
 
 const [registerModal, { openModal }] = useModal({
   title: '充值积分',
@@ -288,17 +289,17 @@ async function exportIntegral() {
   }
 }
 
-// function handleSearch() {
-//   refreshModal();
-// }
+function handleSearch() {
+  refreshModal();
+}
 
-// function listHandleSearch() {
-//   refresh();
-// }
+function listHandleSearch() {
+  refresh();
+}
 
-// async function setSearchForm(value: Recordable) {
-//   await setFieldsValue(value);
-// }
+async function setSearchForm(value: Recordable) {
+  await setFieldsValue(value);
+}
 </script>
 
 <template>

+ 38 - 36
src/views/government/user-list/index.vue

@@ -1,5 +1,5 @@
 <script setup lang="tsx">
-import { useTemplateRef } from 'vue';
+import { nextTick, useTemplateRef } from 'vue';
 import { NButton, NPopconfirm, NSwitch } from 'naive-ui';
 import {
   fetchAddUser,
@@ -9,8 +9,8 @@ import {
   fetchGetImportRecordList,
   fetchGetUserList
 } from '@/service/api/government/user-list';
-// import { fetchGetLoginUserList } from '@/service/api/common';
-// import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
+import { fetchGetLoginUserList } from '@/service/api/common';
+import { fetchGetAllChannelList } from '@/service/api/goods-center/store-goods';
 import { useAuth } from '@/hooks/business/auth';
 import { commonExport } from '@/utils/common';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
@@ -75,29 +75,29 @@ const columns: NaiveUI.TableColumn<Api.government.userList>[] = [
   }
 ];
 
-const [registerTable, { refresh, setTableLoading, getSeachForm }] = useTable({
+const [registerTable, { refresh, setTableLoading, setFieldsValue: setSearchValues, getSeachForm }] = useTable({
   searchFormConfig: {
     schemas: [
-      // {
-      //   field: 'channelIdList',
-      //   label: '所属企业',
-      //   component: 'ApiSelect',
-      //   componentProps: {
-      //     api: fetchGetLoginUserList,
-      //     labelFeild: 'channelName',
-      //     valueFeild: 'id',
-      //     multiple: true,
-      //     onUpdateValue: () => {
-      //       nextTick(() => {
-      //         handleSearch();
-      //       });
-      //     },
-      //     getOptions: async (options: any) => {
-      //       await setSearchValues({ channelIdList: [options[0].id] });
-      //       handleSearch();
-      //     }
-      //   }
-      // },
+      {
+        field: 'channelNoList',
+        label: '所属企业',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchGetLoginUserList,
+          labelFeild: 'channelName',
+          valueFeild: 'channelNo',
+          multiple: true,
+          onUpdateValue: () => {
+            nextTick(() => {
+              handleSearch();
+            });
+          },
+          getOptions: async (options: any) => {
+            await setSearchValues({ channelNoList: [options[0].channelNo] });
+            handleSearch();
+          }
+        }
+      },
       {
         field: 'realName',
         label: '员工姓名',
@@ -248,17 +248,17 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
           }
         ]
       },
-      // {
-      //   field: 'channelId',
-      //   label: '所属企业',
-      //   component: 'ApiSelect',
-      //   componentProps: {
-      //     api: fetchGetAllChannelList,
-      //     labelFeild: 'channelName',
-      //     valueFeild: 'id'
-      //   },
-      //   required: true
-      // },
+      {
+        field: 'channelId',
+        label: '所属企业',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchGetAllChannelList,
+          labelFeild: 'channelName',
+          valueFeild: 'id'
+        },
+        required: true
+      },
       {
         field: 'userAttrType',
         label: '人员属性',
@@ -310,7 +310,9 @@ async function handleSubmitImport(file: File) {
   }
   importTemplateRef.value?.setSubLoading(false);
 }
-
+function handleSearch() {
+  refresh();
+}
 async function handleExport() {
   setTableLoading(true);
   try {

+ 217 - 0
src/views/xsb-manage/advertisement/index.vue

@@ -0,0 +1,217 @@
+<script setup lang="tsx">
+import { NButton, NImage, NPopconfirm, NSwitch } from 'naive-ui';
+import {
+  fetchAddAdvertInfo,
+  fetchDeleteAdvertInfo,
+  fetchGetadvertInfoList,
+  fetchUpdateAdvertInfo
+} from '@/service/api/xsb-manage/advertisement';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+
+const columns: NaiveUI.TableColumn<Api.operation.AdvertInfo>[] = [
+  {
+    key: 'advertName',
+    title: '广告位名称',
+    align: 'center'
+  },
+  {
+    key: 'advertImg',
+    title: '广告图',
+    align: 'center',
+    render: row => {
+      return <NImage src={row.advertImg} class={'h90px w180px'}></NImage>;
+    }
+  },
+  {
+    key: 'advertBack',
+    title: '背景图',
+    align: 'center',
+    render: row => {
+      return <NImage src={row.advertBack} class={'h90px w180px'}></NImage>;
+    }
+  },
+  {
+    key: 'jumpUrl',
+    title: '跳转链接',
+    align: 'center'
+  },
+  {
+    key: 'advertSort',
+    title: '排序',
+    align: 'center'
+  },
+  {
+    key: 'status',
+    title: '状态',
+    align: 'center',
+    render: row => {
+      return (
+        <NSwitch
+          uncheckedValue={0}
+          checkedValue={1}
+          value={row.status}
+          onUpdate:value={val => {
+            row.status = val;
+            fetchUpdateAdvertInfo(row);
+          }}
+        ></NSwitch>
+      );
+    }
+  }
+];
+
+const [registerTable, { refresh, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        field: 'advertName',
+        label: '广告位名称',
+        component: 'NInput'
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NSelect',
+        componentProps: {
+          options: [
+            {
+              label: '启用',
+              value: 1
+            },
+            {
+              label: '禁用',
+              value: 0
+            }
+          ]
+        }
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '广告位列表',
+    showAddButton: true
+  }
+});
+
+async function handleDelete(row: Recordable) {
+  setTableLoading(true);
+  await fetchDeleteAdvertInfo(row.id);
+  refresh();
+}
+const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
+  modalConfig: {
+    title: '广告位',
+    width: 800,
+    isShowHeaderText: true,
+    height: 600
+  },
+  formConfig: {
+    schemas: [
+      {
+        label: '',
+        field: 'id',
+        component: 'NInput',
+        show: false
+      },
+      {
+        field: 'advertName',
+        label: '广告位名称',
+        component: 'NInput',
+        required: true
+      },
+      {
+        field: 'advertImg',
+        label: '广告图',
+        component: 'zUpload',
+        required: true,
+        componentProps: {
+          tipText: '单张,仅支持png,jpg,jpeg格式,建议尺寸比例 16:9;图片大小不能超过3m。',
+          max: 1,
+          FileSize: 3
+        }
+      },
+      {
+        field: 'advertBack',
+        label: '背景图',
+        component: 'zUpload',
+        required: true,
+        componentProps: {
+          tipText: '单张,仅支持png,jpg,jpeg格式,建议尺寸比例 16:9;图片大小不能超过3m。',
+          max: 1,
+          FileSize: 3
+        }
+      },
+      {
+        field: 'jumpUrl',
+        label: '链接和参数',
+        component: 'NInput',
+        componentProps: {
+          placeholder: '列如:/pages/xxx?id=1'
+        },
+        required: true
+      },
+      {
+        field: 'advertSort',
+        label: '排序',
+        component: 'NInputNumber',
+        required: true
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NSwitch',
+        required: true,
+        componentProps: {
+          checkedValue: 1,
+          uncheckedValue: 0
+        },
+        defaultValue: 1
+      }
+    ],
+    gridProps: {
+      cols: '1'
+    },
+    labelWidth: 120
+  }
+});
+async function handleSubmit() {
+  const form = await getFieldsValue();
+  if (form.id) {
+    await fetchUpdateAdvertInfo(form);
+  } else {
+    await fetchAddAdvertInfo(form);
+  }
+  closeModal();
+  refresh();
+}
+
+async function edit(row: Recordable) {
+  openModal(row);
+  setFieldsValue(row);
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchGetadvertInfoList" @register="registerTable" @add="openModal">
+      <template #op="{ row }">
+        <NButton size="small" ghost type="primary" @click="edit(row)">编辑</NButton>
+        <NPopconfirm @positive-click="handleDelete(row)">
+          <template #trigger>
+            <NButton size="small" type="error" ghost>删除</NButton>
+          </template>
+          确定删除吗?
+        </NPopconfirm>
+      </template>
+    </ZTable>
+    <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

+ 209 - 0
src/views/xsb-manage/fright-config/index.vue

@@ -0,0 +1,209 @@
+<script setup lang="tsx">
+import { ref } from 'vue';
+import { NDynamicInput, NInputNumber, NSelect } from 'naive-ui';
+import { fetchGetAllChannelList } from '@/service/api/goods-center/store-goods';
+import { fetchChannelList, fetchGetAddOrEditTransport, fetchGetTransport } from '@/service/api/common';
+import { useTabStore } from '@/store/modules/tab';
+import { useForm } from '@/components/zt/Form/hooks/useForm';
+const isSubmit = ref(false);
+const tabStore = useTabStore();
+interface Options {
+  value: any;
+  index: number;
+}
+const ChannelOptions = ref<Api.goods.Channel[]>([]);
+const [registerForm, { getFieldsValue, validate, setFieldsValue }] = useForm({
+  schemas: [
+    {
+      field: 'transportId',
+      component: 'NInput',
+      label: 'false',
+      show: false
+    },
+    {
+      field: 'name',
+      component: 'NDynamicInput',
+      label: '配送费/运费',
+      render({ model, field }) {
+        return (
+          <div class={'flex flex-wrap items-center'}>
+            <div class={'h38px flex items-center'}>
+              <div class={'w-200px text-center'}> 企业 </div>
+              <div class={'ml-3 w-200px text-center'}> 费用(元) </div>
+              <div class={'ml-3 w-200px text-center'}> 重量(kg) </div>
+              <div class={'ml-3 w-200px text-center'}> 分单(km) </div>
+            </div>
+            <NDynamicInput
+              value={model[field]}
+              onUpdate:value={value => (model[field] = value)}
+              v-slots={(row: Options) => handleCreatInput(model, field, row)}
+              onCreate={() => handleAdd()}
+              max={ChannelOptions.value.length}
+              onRemove={handleRemove}
+            ></NDynamicInput>
+          </div>
+        );
+      },
+      required: true,
+      defaultValue: []
+    }
+  ],
+  labelWidth: 120,
+  layout: 'horizontal',
+  collapsedRows: 1,
+  showActionButtonGroup: false,
+  gridProps: {
+    cols: '1',
+    itemResponsive: true
+  }
+});
+function handleCreatInput(model: any, field: any, row: Options) {
+  return (
+    <div class={'flex items-center'}>
+      <div class={'w-200px'}>
+        <NSelect
+          value={model[field][row.index].channelId}
+          labelField="channelName"
+          valueField="id"
+          options={ChannelOptions.value}
+          onUpdate:value={vlaue => {
+            ChannelOptions.value.map(it => {
+              if (it.id == model[field][row.index].channelId) {
+                it.disabled = false;
+              }
+              return it;
+            });
+            model[field][row.index].channelId = vlaue ? Number(vlaue) : undefined;
+            handleGetChannelId(vlaue, row.index);
+          }}
+          onUpdate:show={value => {
+            ChannelOptions.value.map(it => {
+              if (it.id == model[field][row.index].channelId) {
+                if (value) {
+                  it.disabled = false;
+                }
+                if (!value) {
+                  it.disabled = true;
+                }
+              }
+              return it;
+            });
+          }}
+        ></NSelect>
+      </div>
+      <div class={'ml-3 w-200px'}>
+        <NInputNumber
+          value={model[field][row.index].freightFee}
+          min={1}
+          onUpdate:value={value => {
+            model[field][row.index].freightFee = value;
+          }}
+        ></NInputNumber>
+      </div>
+      <div class={'ml-3 w-200px'}>
+        <NInputNumber
+          value={model[field][row.index].weight}
+          min={1}
+          onUpdate:value={value => {
+            model[field][row.index].weight = value;
+          }}
+          v-slots={{ prefix: () => '每', suffix: () => 'Kg' }}
+        ></NInputNumber>
+      </div>
+      <div class={'ml-3 w-200px'}>
+        <NInputNumber
+          placeholder={'请输入配送距离'}
+          value={model[field][row.index].distance}
+          onUpdate:value={val => (model[field][row.index].distance = val)}
+          v-slots={{ prefix: () => '大于', suffix: () => 'km' }}
+        ></NInputNumber>
+      </div>
+    </div>
+  );
+}
+function close() {
+  tabStore.removeTab(tabStore.activeTabId);
+}
+
+async function getChannelList() {
+  const { data } = await fetchGetAllChannelList();
+  if (!data) return;
+  ChannelOptions.value = data;
+}
+getChannelList();
+
+async function getData() {
+  const { data } = await fetchChannelList({ current: 1, size: 100 });
+  if (data) {
+    setFieldsValue({
+      name: data.records.map(it => {
+        return {
+          transportId: it.transportId,
+          channelId: it.channelId,
+          freightFee: it.freightFee,
+          distance: it.distance,
+          weight: it.weight
+        };
+      })
+    });
+    const dataKey = data.records.map(it => it.channelId);
+    ChannelOptions.value.map(it => {
+      if (dataKey.includes(Number(it.id))) {
+        it.disabled = true;
+      }
+      return it;
+    });
+  }
+}
+getData();
+function handleAdd() {
+  return {
+    channelId: null,
+    freightFee: 1,
+    distance: null,
+    weight: 10
+  };
+}
+
+async function save() {
+  await validate();
+  isSubmit.value = true;
+  const form = getFieldsValue();
+  await fetchGetAddOrEditTransport(form.name);
+  isSubmit.value = false;
+  window.$message?.success('保存成功');
+  getData();
+}
+function handleRemove(idx: number) {
+  const form = getFieldsValue();
+  const id = form.name[idx].channelId;
+  ChannelOptions.value.map(it => (it.id == id ? (it.disabled = false) : it));
+}
+async function handleGetChannelId(channelId: number, idx: number) {
+  const res = await fetchGetTransport(channelId);
+  const form = getFieldsValue();
+  const newName = JSON.parse(JSON.stringify(form.name));
+  newName[idx].distance = res.data?.distance || null;
+  newName[idx].freightFee = res.data?.freightFee || null;
+  newName[idx].weight = res.data?.weight || null;
+  setFieldsValue({ name: newName });
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <NCard title="配送费&运费配置" :bordered="false" size="small" segmented class="card-wrapper">
+      <NScrollbar x-scrollable>
+        <BasicForm @register-form="registerForm"></BasicForm>
+      </NScrollbar>
+      <template #footer>
+        <NSpace justify="end">
+          <NButton size="small" @click="close">关闭</NButton>
+          <NButton type="primary" size="small" :loading="isSubmit" @click="save">保存</NButton>
+        </NSpace>
+      </template>
+    </NCard>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

+ 216 - 0
src/views/xsb-manage/search/index.vue

@@ -0,0 +1,216 @@
+<script setup lang="tsx">
+import { NButton, NPopconfirm, NTag } from 'naive-ui';
+import { commonStatus } from '@/constants/business';
+import {
+  fetchAddHotSearch,
+  fetchDeleteHotSearch,
+  fetchGethotSearch,
+  fetchUpdateHotSearch
+} from '@/service/api/xsb-manage/search';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+import { $t } from '@/locales';
+
+const columns: NaiveUI.TableColumn<Api.operation.HotSearch>[] = [
+  {
+    key: 'searchName',
+    title: '名称',
+    align: 'center'
+  },
+  {
+    key: 'type',
+    title: '类型',
+    align: 'center',
+    render: row => {
+      const arr = ['关键词', '热门搜索词', '推荐搜索词'];
+      return arr[row.type - 1] || '暂无数据';
+    }
+  },
+  {
+    key: 'reachName',
+    title: '落地页',
+    align: 'center'
+  },
+  {
+    key: 'jumpUrl',
+    title: '跳转参数',
+    align: 'center'
+  },
+  {
+    key: 'effectiveTime',
+    title: '有效时间',
+    align: 'center'
+  },
+  {
+    key: 'endTime',
+    title: '截止时间',
+    align: 'center'
+  },
+  {
+    key: 'status',
+    title: '经营状态',
+    align: 'center',
+    render: row => {
+      const tagMap: Record<Api.Common.commonStatus, NaiveUI.ThemeColor> = {
+        1: 'success',
+        0: 'warning'
+      };
+      const status = row.status || 0;
+      const label = $t(commonStatus[status]);
+      return <NTag type={tagMap[status]}>{label}</NTag>;
+    }
+  }
+];
+
+const [registerTable, { refresh, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        field: 'searchName',
+        label: '名称',
+        component: 'NInput'
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '搜索词列表',
+    showAddButton: true
+  }
+});
+
+async function handleDelete(row: Api.operation.HotSearch) {
+  setTableLoading(true);
+  await fetchDeleteHotSearch([row.id]);
+  refresh();
+}
+const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
+  modalConfig: {
+    title: '跳转 ',
+    width: 700,
+    isShowHeaderText: true,
+    height: 500
+  },
+  formConfig: {
+    schemas: [
+      {
+        label: '',
+        field: 'id',
+        component: 'NInput',
+        show: false
+      },
+      {
+        field: 'searchName',
+        label: '名称',
+        component: 'NInput',
+        required: true
+      },
+      {
+        field: 'type',
+        label: '类型',
+        component: 'NSelect',
+        componentProps: {
+          options: [
+            {
+              label: '关键词',
+              value: 1
+            },
+            {
+              label: '热门搜索词',
+              value: 2
+            },
+            {
+              label: '推荐搜索词',
+              value: 3
+            }
+          ]
+        },
+        required: true
+      },
+      {
+        field: 'reachName',
+        label: '落地页名称',
+        component: 'NInput'
+      },
+      {
+        field: 'jumpUrl',
+        label: '跳转参数',
+        component: 'NInput'
+      },
+      {
+        field: 'effectiveTime',
+        label: '有效时间',
+        component: 'NDatePicker',
+        required: true,
+        componentProps: {
+          type: 'date',
+          valueFormat: 'yyyy-MM-dd'
+        }
+      },
+      {
+        field: 'endTime',
+        label: '截止时间',
+        component: 'NDatePicker',
+        required: true,
+        componentProps: {
+          type: 'date',
+          valueFormat: 'yyyy-MM-dd'
+        }
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NSwitch',
+        required: true,
+        defaultValue: 1,
+        componentProps: {
+          checkedValue: 1,
+          uncheckedValue: 0
+        }
+      }
+    ],
+    gridProps: {
+      cols: '1'
+    },
+    labelWidth: 120
+  }
+});
+async function handleSubmit() {
+  const form = await getFieldsValue();
+  if (form.id) {
+    await fetchUpdateHotSearch(form);
+  } else {
+    await fetchAddHotSearch(form);
+  }
+  closeModal();
+  refresh();
+}
+
+async function edit(row: Api.operation.HotSearch) {
+  openModal(row);
+  setFieldsValue(row);
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchGethotSearch" @register="registerTable" @add="openModal">
+      <template #op="{ row }">
+        <NButton size="small" ghost type="primary" @click="edit(row)">编辑</NButton>
+        <NPopconfirm @positive-click="handleDelete(row)">
+          <template #trigger>
+            <NButton size="small" type="error" ghost>删除</NButton>
+          </template>
+          确定删除吗?
+        </NPopconfirm>
+      </template>
+    </ZTable>
+    <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

+ 138 - 0
src/views/xsb-manage/store-info/index.vue

@@ -0,0 +1,138 @@
+<script setup lang="tsx">
+import { NCollapse, NCollapseItem, NTag } from 'naive-ui';
+import { commonStatus } from '@/constants/business';
+import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { $t } from '@/locales';
+const columns: NaiveUI.TableColumn<Api.Store.ShopDetail>[] = [
+  {
+    key: 'hbStationNo',
+    title: '商家门店编码',
+    width: 250,
+    render: row => {
+      return (
+        <NCollapse>
+          <NCollapseItem title={row.hbStationNo} name={`${row.hbStationId}hbStationNo`}>
+            <div class={'ml-6'}>
+              联系电话:<span class={'text-gray'}>{row.tel} </span>
+            </div>
+            <div class={'ml-6'}>
+              联系人:<span class={'text-gray'}>{row.shopOwner} </span>
+            </div>
+            <div class={'ml-6'}>
+              门店经度:<span class={'text-gray'}>{row.shopLng} </span>
+            </div>
+            <div class={'ml-6'}>
+              门店维度:<span class={'text-gray'}>{row.shopLat} </span>
+            </div>
+            {/* <div class={'ml-6'}>
+              时段接单量: <span class={'text-gray'}>{row.shopOwner} </span>
+            </div> */}
+          </NCollapseItem>
+        </NCollapse>
+      );
+    }
+  },
+  {
+    key: 'shopName',
+    title: '门店名称',
+    align: 'center',
+    width: 200
+  },
+  {
+    key: 'address',
+    title: '地址',
+    align: 'center',
+    width: 200,
+    render: row => {
+      return (
+        <div>
+          {row.province}
+          {row.city}
+          {row.shopAddress}
+        </div>
+      );
+    }
+  },
+  {
+    key: 'runStatus',
+    title: '经营状态',
+    align: 'center',
+    render: row => {
+      const tagMap: Record<Api.Common.commonStatus, NaiveUI.ThemeColor> = {
+        1: 'success',
+        0: 'warning'
+      };
+      const status = row.runStatus || 0;
+      const label = $t(commonStatus[status]);
+      return <NTag type={tagMap[status]}>{label}</NTag>;
+    }
+  },
+  {
+    key: 'shopStatus',
+    title: '营业状态',
+    align: 'center',
+    render: row => {
+      const tagMap: Record<Api.Common.commonStatus, NaiveUI.ThemeColor> = {
+        1: 'success',
+        0: 'error'
+      };
+      const labelArr = ['停业中', '营业中'];
+      const status = row.shopStatus || 0;
+      const label = labelArr[status];
+      return <NTag type={tagMap[status]}>{label}</NTag>;
+    }
+  },
+  {
+    key: 'businessTime',
+    title: '营业时间',
+    align: 'center',
+    width: 200,
+    ellipsis: {
+      tooltip: true
+    }
+  },
+  {
+    key: 'notice',
+    title: '门店公告',
+    align: 'center',
+    render: row => {
+      return <div>{row.notice || '--'}</div>;
+    }
+  }
+];
+
+const [registerTable] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        label: '门店名称',
+        component: 'NInput',
+        field: 'shopName'
+      },
+      {
+        field: 'hbStationNo',
+        label: '商家门店编码',
+        component: 'NInput'
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '门店信息',
+    showAddButton: false
+  }
+});
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :show-table-action="false" :api="fetchGetStoreList" @register="registerTable"></ZTable>
+  </LayoutTable>
+</template>
+
+<style scoped></style>