ソースを参照

feat(projects): 政企管理门店管理等模块搭建

zhangtao 4 週間 前
コミット
10af9a651f

+ 1 - 1
src/components/zt/Modal/basic-modal.vue

@@ -102,7 +102,7 @@ export default defineComponent({
         </NScrollbar>
       </NSpin>
     </template>
-    <template v-if="!$slots.action" #action>
+    <template v-if="!$slots.action && getBindValue.showFooter" #action>
       <NSpace v-if="!loading" justify="end">
         <NButton @click="closeModal">取消</NButton>
         <NButton type="primary" :loading="subLoading" @click="handleSubmit">{{ getBindValue.subBtuText }}</NButton>

+ 4 - 0
src/components/zt/Modal/props.ts

@@ -38,5 +38,9 @@ export const basicModalProps = {
   height: {
     default: 500,
     type: Number
+  },
+  showFooter: {
+    type: Boolean,
+    default: true
   }
 };

+ 1 - 0
src/components/zt/Modal/types/index.ts

@@ -44,6 +44,7 @@ export interface modalProps extends ModalProps {
    * 弹窗内容高度
    */
   height?: number;
+  showFooter?: boolean;
 }
 
 export type RegisterFn = (ModalInstance: ModalMethods) => void;

+ 4 - 0
src/components/zt/Table/hooks/useTable.ts

@@ -41,6 +41,9 @@ export function useTable(tableProps: ztTableProps): UseTableReturnType {
     },
     getTableCheckedRowKeys() {
       return tableRef.value?.getTableCheckedRowKeys() as string[];
+    },
+    getTableData() {
+      return tableRef.value?.getTableData() as any[];
     }
   };
   return [register, methods];
@@ -52,6 +55,7 @@ export interface TableMethods {
   setTableLoading: (loading: boolean) => void;
   setTableConfig: (config: tableProp) => void;
   getTableCheckedRowKeys: () => string[];
+  getTableData: () => any[];
 }
 
 export type RegisterFn = (TableInstance: TableMethods) => void;

+ 7 - 1
src/components/zt/Table/props.ts

@@ -1,6 +1,10 @@
 import type { FormProps } from '../Form/types/form';
 import type { tableProp } from './types';
 export const basicProps = {
+  showTableAction: {
+    type: Boolean,
+    default: true
+  },
   api: {
     type: Function as PropType<tableProp['api']>,
     default: () => Promise.resolve()
@@ -21,6 +25,7 @@ export const basicProps = {
       collapsedRows: 1
     }
   },
+
   tableConfig: {
     type: Object as PropType<tableProp>,
     default: {
@@ -29,7 +34,8 @@ export const basicProps = {
       showDeleteButton: false,
       showAddButton: true,
       keyField: 'id',
-      scrollX: 1000
+      scrollX: 1000,
+      showTableHeaderAction: true
     }
   }
 };

+ 4 - 0
src/components/zt/Table/types/index.ts

@@ -37,6 +37,10 @@ export interface tableProp extends DataTableProps {
    * 表格内容的横向宽度,如果列被水平固定了,则需要设定它
    */
   scrollX?: number;
+  /**
+   * 是否显示表格头部操作列
+   */
+  showTableHeaderAction?: boolean;
 }
 
 export interface ztTableProps {

+ 19 - 8
src/components/zt/Table/z-table.vue

@@ -59,31 +59,39 @@ export default defineComponent({
       paginationProps: {
         pageSizes: [10, 20, 50, 100, 150, 200]
       },
-      columns: () => [
-        ...propsData.columns,
-        {
+      columns: () => handleGetColumns()
+    });
+    const { checkedRowKeys } = useTableOperate(data, getTableProps.value.keyField, getData);
+    function handleGetColumns() {
+      const columnsData = [...propsData.columns];
+      if (propsData.showTableAction) {
+        columnsData.push({
           key: 'operate',
           title: '操作',
           align: 'center',
           width: getTableProps.value.opWdith,
           fixed: 'right',
           render: row => <div class="flex-center gap-8px">{slots.op ? slots.op({ row }) : ''}</div>
-        }
-      ]
-    });
-    const { checkedRowKeys } = useTableOperate(data, getTableProps.value.keyField, getData);
+        });
+      }
+      return columnsData;
+    }
     function setTableConfig(config: tableProp) {
       tableProps.value = config;
     }
     function getTableCheckedRowKeys() {
       return checkedRowKeys.value;
     }
+    function getTableData() {
+      return data.value;
+    }
     const TableMethod: TableMethods = {
       refresh: getData,
       setSearchProps,
       setTableLoading,
       setTableConfig,
-      getTableCheckedRowKeys
+      getTableCheckedRowKeys,
+      getTableData
     };
     function setTableLoading(flage: boolean) {
       loading.value = flage;
@@ -109,6 +117,8 @@ export default defineComponent({
         form[endTimeKey] = form.Time[1];
         delete form.Time;
       }
+      console.log(form, '请求参数');
+
       getForm.value = form;
       getData();
     }
@@ -145,6 +155,7 @@ export default defineComponent({
   <NCard :bordered="false" :title="getTableProps.title" size="small" class="card-wrapper sm:flex-1-hidden">
     <template #header-extra>
       <TableHeaderOperation
+        v-if="getTableProps.showTableHeaderAction"
         v-model:columns="columnChecks"
         :disabled-delete="checkedRowKeys.length === 0"
         :loading="loading"

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

@@ -6,7 +6,7 @@ import BasicModal from '../Modal/basic-modal.vue';
 const emit = defineEmits<{ (e: 'submit', file: File): void }>();
 const fileList = ref<UploadFileInfo[]>([]);
 const props = defineProps<{ url: string; modalText: string; templateText: string }>();
-const [registerModalImport, { openModal, setSubLoading, closeModal }] = useModal({
+const [registerModalImport, { openModal, setSubLoading, closeModal: closeModalImport }] = useModal({
   title: props.modalText,
   subBtuText: '确定导入'
 });
@@ -15,6 +15,10 @@ defineExpose({
   setSubLoading,
   closeModal
 });
+function closeModal() {
+  closeModalImport();
+  fileList.value = [];
+}
 function handleSubmitImport() {
   setSubLoading(false);
   if (!fileList.value.length) {

+ 5 - 0
src/constants/business.ts

@@ -28,3 +28,8 @@ export const menuIconTypeRecord: Record<Api.SystemManage.IconType, App.I18n.I18n
 };
 
 export const menuIconTypeOptions = transformRecordToOption(menuIconTypeRecord);
+
+export const commonStatus: Record<Api.Common.commonStatus, App.I18n.I18nKey> = {
+  1: 'page.manage.common.status.enable',
+  0: 'page.manage.common.status.disable'
+};

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

@@ -285,7 +285,15 @@ const local: App.I18n.Schema = {
     goods: '',
     'goods_desk-category': '',
     'goods_store-goods': '',
-    goods_tag: ''
+    goods_tag: '',
+    government: '',
+    'government_government-list': '',
+    government_points: '',
+    'government_user-list': '',
+    'store-management': '',
+    'store-management_store-info': '',
+    'user-management': '',
+    'user-management_user-list': ''
   },
   page: {
     login: {

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

@@ -282,7 +282,15 @@ const local: App.I18n.Schema = {
     goods: '',
     'goods_desk-category': '',
     'goods_store-goods': '',
-    goods_tag: ''
+    goods_tag: '',
+    government: '',
+    'government_government-list': '',
+    government_points: '',
+    'government_user-list': '',
+    'store-management': '',
+    'store-management_store-info': '',
+    'user-management': '',
+    'user-management_user-list': ''
   },
   page: {
     login: {

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

@@ -24,6 +24,9 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
   "goods_desk-category": () => import("@/views/goods/desk-category/index.vue"),
   "goods_store-goods": () => import("@/views/goods/store-goods/index.vue"),
   goods_tag: () => import("@/views/goods/tag/index.vue"),
+  "government_government-list": () => import("@/views/government/government-list/index.vue"),
+  government_points: () => import("@/views/government/points/index.vue"),
+  "government_user-list": () => import("@/views/government/user-list/index.vue"),
   home: () => import("@/views/home/index.vue"),
   manage_config: () => import("@/views/manage/config/index.vue"),
   manage_department: () => import("@/views/manage/department/index.vue"),
@@ -56,5 +59,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
   "pro-naive_form_step": () => import("@/views/pro-naive/form/step/index.vue"),
   "pro-naive_table_remote": () => import("@/views/pro-naive/table/remote/index.vue"),
   "pro-naive_table_row-edit": () => import("@/views/pro-naive/table/row-edit/index.vue"),
+  "store-management_store-info": () => import("@/views/store-management/store-info/index.vue"),
   "user-center": () => import("@/views/user-center/index.vue"),
+  "user-management_user-list": () => import("@/views/user-management/user-list/index.vue"),
 };

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

@@ -88,6 +88,44 @@ export const generatedRoutes: GeneratedRoute[] = [
       }
     ]
   },
+  {
+    name: 'government',
+    path: '/government',
+    component: 'layout.base',
+    meta: {
+      title: 'government',
+      i18nKey: 'route.government'
+    },
+    children: [
+      {
+        name: 'government_government-list',
+        path: '/government/government-list',
+        component: 'view.government_government-list',
+        meta: {
+          title: 'government_government-list',
+          i18nKey: 'route.government_government-list'
+        }
+      },
+      {
+        name: 'government_points',
+        path: '/government/points',
+        component: 'view.government_points',
+        meta: {
+          title: 'government_points',
+          i18nKey: 'route.government_points'
+        }
+      },
+      {
+        name: 'government_user-list',
+        path: '/government/user-list',
+        component: 'view.government_user-list',
+        meta: {
+          title: 'government_user-list',
+          i18nKey: 'route.government_user-list'
+        }
+      }
+    ]
+  },
   {
     name: 'home',
     path: '/home',
@@ -538,6 +576,26 @@ export const generatedRoutes: GeneratedRoute[] = [
       }
     ]
   },
+  {
+    name: 'store-management',
+    path: '/store-management',
+    component: 'layout.base',
+    meta: {
+      title: 'store-management',
+      i18nKey: 'route.store-management'
+    },
+    children: [
+      {
+        name: 'store-management_store-info',
+        path: '/store-management/store-info',
+        component: 'view.store-management_store-info',
+        meta: {
+          title: 'store-management_store-info',
+          i18nKey: 'route.store-management_store-info'
+        }
+      }
+    ]
+  },
   {
     name: 'user-center',
     path: '/user-center',
@@ -547,5 +605,25 @@ export const generatedRoutes: GeneratedRoute[] = [
       i18nKey: 'route.user-center',
       hideInMenu: true
     }
+  },
+  {
+    name: 'user-management',
+    path: '/user-management',
+    component: 'layout.base',
+    meta: {
+      title: 'user-management',
+      i18nKey: 'route.user-management'
+    },
+    children: [
+      {
+        name: 'user-management_user-list',
+        path: '/user-management/user-list',
+        component: 'view.user-management_user-list',
+        meta: {
+          title: 'user-management_user-list',
+          i18nKey: 'route.user-management_user-list'
+        }
+      }
+    ]
   }
 ];

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

@@ -186,6 +186,10 @@ const routeMap: RouteMap = {
   "goods_desk-category": "/goods/desk-category",
   "goods_store-goods": "/goods/store-goods",
   "goods_tag": "/goods/tag",
+  "government": "/government",
+  "government_government-list": "/government/government-list",
+  "government_points": "/government/points",
+  "government_user-list": "/government/user-list",
   "home": "/home",
   "iframe-page": "/iframe-page/:url",
   "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
@@ -229,7 +233,11 @@ const routeMap: RouteMap = {
   "pro-naive_table": "/pro-naive/table",
   "pro-naive_table_remote": "/pro-naive/table/remote",
   "pro-naive_table_row-edit": "/pro-naive/table/row-edit",
-  "user-center": "/user-center"
+  "store-management": "/store-management",
+  "store-management_store-info": "/store-management/store-info",
+  "user-center": "/user-center",
+  "user-management": "/user-management",
+  "user-management_user-list": "/user-management/user-list"
 };
 
 /**

+ 0 - 0
src/service/api/government/government-list/index.ts


+ 32 - 0
src/service/api/government/points/index.ts

@@ -0,0 +1,32 @@
+import { request } from '@/service/request';
+
+/**
+ * 分页获取积分列表
+ * @param params
+ * @returns
+ */
+export function fetchGetPointsList(params: any) {
+  return request({
+    url: '/platform/pointsRecharge/page',
+    method: 'get',
+    params
+  });
+}
+
+/**
+ * 导入积分充值数据
+ * @param params
+ * @returns
+ */
+export function fetchImportPoints(params: File) {
+  return request({
+    url: '/platform/pointsRecharge/import',
+    method: 'post',
+    data: {
+      file: params
+    },
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
+  });
+}

+ 14 - 0
src/service/api/store-management/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
+  });
+}

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

@@ -46,6 +46,10 @@ declare namespace Api {
       /** record status */
       status: EnableStatus | null;
     } & T;
+    /**
+     * 通用状态
+     */
+    type commonStatus = 0 | 1;
   }
 
   /**
@@ -91,6 +95,9 @@ declare namespace Api {
       home: import('@elegant-router/types').LastLevelRouteKey;
     }
   }
+  /**
+   * 商品管理模块
+   */
 
   namespace goods {
     interface ShopCategory {
@@ -371,4 +378,153 @@ declare namespace Api {
       [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;
+    }
+  }
 }

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

@@ -40,6 +40,10 @@ declare module "@elegant-router/types" {
     "goods_desk-category": "/goods/desk-category";
     "goods_store-goods": "/goods/store-goods";
     "goods_tag": "/goods/tag";
+    "government": "/government";
+    "government_government-list": "/government/government-list";
+    "government_points": "/government/points";
+    "government_user-list": "/government/user-list";
     "home": "/home";
     "iframe-page": "/iframe-page/:url";
     "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
@@ -83,7 +87,11 @@ declare module "@elegant-router/types" {
     "pro-naive_table": "/pro-naive/table";
     "pro-naive_table_remote": "/pro-naive/table/remote";
     "pro-naive_table_row-edit": "/pro-naive/table/row-edit";
+    "store-management": "/store-management";
+    "store-management_store-info": "/store-management/store-info";
     "user-center": "/user-center";
+    "user-management": "/user-management";
+    "user-management_user-list": "/user-management/user-list";
   };
 
   /**
@@ -135,13 +143,16 @@ declare module "@elegant-router/types" {
     | "500"
     | "about"
     | "goods"
+    | "government"
     | "home"
     | "iframe-page"
     | "login"
     | "manage"
     | "plugin"
     | "pro-naive"
+    | "store-management"
     | "user-center"
+    | "user-management"
   >;
 
   /**
@@ -169,6 +180,9 @@ declare module "@elegant-router/types" {
     | "goods_desk-category"
     | "goods_store-goods"
     | "goods_tag"
+    | "government_government-list"
+    | "government_points"
+    | "government_user-list"
     | "home"
     | "manage_config"
     | "manage_department"
@@ -201,7 +215,9 @@ declare module "@elegant-router/types" {
     | "pro-naive_form_step"
     | "pro-naive_table_remote"
     | "pro-naive_table_row-edit"
+    | "store-management_store-info"
     | "user-center"
+    | "user-management_user-list"
   >;
 
   /**

+ 73 - 14
src/views/goods/store-goods/index.vue

@@ -3,7 +3,12 @@ import { computed, ref } from 'vue';
 import { NButton, NImage, NInputNumber, NSelect } from 'naive-ui';
 import dayjs from 'dayjs';
 import { fetchGetAllStoreList } from '@/service/api/goods/desk-category';
-import { fetchGetAllChannelList, fetchGetGoodsList, fetchImportGoods } from '@/service/api/goods/store-goods';
+import {
+  fetchGetAllChannelList,
+  fetchGetGoodsList,
+  fetchImportGoods,
+  fetchSetUpChannels
+} from '@/service/api/goods/store-goods';
 import { areAllItemsAllFieldsFilled } from '@/utils/zt';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import type { ModalMethods } from '@/components/zt/Modal/types';
@@ -11,6 +16,9 @@ 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 };
 const importTemplateRef = ref<ModalMethods>();
+const options = ref<Api.goods.Channel[]>([]);
+const TypeName = ['C端用户', '企业用户', 'B端用户'];
+
 const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
   {
     type: 'selection',
@@ -59,7 +67,7 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     },
     render: row => {
       const nameList = row.channelProdList?.map(it => it.shopName);
-      return <div>{nameList?.join(',')}</div>;
+      return <div>{nameList?.join(',') || '--'}</div>;
     }
   },
   {
@@ -74,6 +82,7 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     align: 'center',
     width: 120,
     render: row => {
+      if (!row.channelProdList?.length) return '--';
       if (row.channelProdList) return <div>{row.channelProdList[0].purchasePrice}</div>;
       return '--';
     }
@@ -84,6 +93,7 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     align: 'center',
     width: 150,
     render: row => {
+      if (!row.channelProdList?.length) return '--';
       if (row.channelProdList) return <div>{row.channelProdList[0].deliveryPrice}</div>;
       return '--';
     }
@@ -92,19 +102,18 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     key: 'name',
     title: '销售渠道及价格',
     align: 'center',
-    width: 150,
+    width: 250,
     render: row => {
       return row.channelProdList?.map(it => {
         return (
           <div>
-            {it.channelName} : {it.channelProdPrice}
+            {TypeName[Number(it.channelId) - 1]} ({it.channelName || '--'}) : {it.channelProdPrice || '--'}
           </div>
         );
       });
     }
   }
 ];
-const options = ref<Api.goods.Channel[]>([]);
 const PriceColumns: NaiveUI.TableColumn<Price>[] = [
   {
     title: '销售渠道',
@@ -118,8 +127,28 @@ const PriceColumns: NaiveUI.TableColumn<Price>[] = [
           labelField="channelName"
           valueField="id"
           value={row.channelId}
+          clearable
           onUpdate:value={value => {
-            row.channelId = Number(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>
       );
@@ -146,7 +175,7 @@ const PriceColumns: NaiveUI.TableColumn<Price>[] = [
   {
     title: () => {
       return (
-        <div onClick={() => handleAddPrice()}>
+        <div onClick={() => handleAddPrice()} class={'w-full flex items-center justify-center'}>
           <SvgIcon
             icon={'proicons:add-square'}
             class={'cursor-pointer text-24px'}
@@ -157,9 +186,10 @@ const PriceColumns: NaiveUI.TableColumn<Price>[] = [
     },
     key: 'action',
     width: 80,
+    align: 'center',
     render: row => {
       return (
-        <div onClick={() => handleDelPrice(row.id)}>
+        <div onClick={() => handleDelPrice(row.id)} class={'w-full flex items-center justify-center'}>
           <SvgIcon
             icon={'proicons:subtract-square'}
             class={'cursor-pointer text-24px'}
@@ -172,7 +202,7 @@ const PriceColumns: NaiveUI.TableColumn<Price>[] = [
 ];
 const PriceData = ref<Price[]>([]);
 const selectData = ref<Api.goods.ShopSku>();
-const [registerTable, { getTableCheckedRowKeys }] = useTable({
+const [registerTable, { getTableCheckedRowKeys, refresh, getTableData }] = useTable({
   searchFormConfig: {
     schemas: [
       {
@@ -204,7 +234,10 @@ const [registerTable, { getTableCheckedRowKeys }] = useTable({
   }
 });
 
-const [registerModalPrice, { openModal: openPriceModal, setSubLoading: setSubModalLoding }] = useModal({
+const [
+  registerModalPrice,
+  { openModal: openPriceModal, setSubLoading: setSubModalLoding, closeModal: closePriceModal }
+] = useModal({
   title: '设置渠道及价格',
   width: 800,
   height: 300
@@ -213,6 +246,9 @@ const [registerModalPrice, { openModal: openPriceModal, setSubLoading: setSubMod
 const isDisabledExport = computed(() => {
   return !getTableCheckedRowKeys().length;
 });
+const tableData = computed(() => {
+  return getTableData();
+});
 
 async function handleSubmitImport(file: File) {
   const { error } = await fetchImportGoods({ file });
@@ -229,7 +265,10 @@ function handleModalPrice(row: Api.goods.ShopSku) {
   openPriceModal();
 }
 function handleAddPrice() {
-  if (PriceData.value.length == 3) return;
+  if (PriceData.value.length == 3) {
+    window.$message?.error('最多只能添加3条数据');
+    return;
+  }
   PriceData.value.push({
     channelId: undefined,
     channelProdPrice: 1,
@@ -240,7 +279,7 @@ function handleDelPrice(id: number) {
   PriceData.value = PriceData.value.filter(item => item.id != id);
 }
 
-function handleSubmitPrice() {
+async function handleSubmitPrice() {
   setSubModalLoding(false);
   if (!PriceData.value.length) {
     window.$message?.error('最少填写一条数据');
@@ -251,7 +290,27 @@ function handleSubmitPrice() {
     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,
+    setChannelPriceDtoList: PriceData.value.map(item => {
+      return {
+        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() {
@@ -272,7 +331,7 @@ getData();
       <template #prefix>
         <NSpace>
           <NButton size="small" @click="openImportModal">导入商品销售渠道及价格</NButton>
-          <NButton size="small">导出全部</NButton>
+          <NButton size="small" :disabled="tableData.length == 0">导出全部</NButton>
           <NButton size="small" :disabled="isDisabledExport">导出选中数据</NButton>
           <NButton size="small">修改记录</NButton>
         </NSpace>

+ 105 - 0
src/views/government/government-list/index.vue

@@ -0,0 +1,105 @@
+<script setup lang="tsx">
+import { NButton, NPopconfirm } from 'naive-ui';
+import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
+import { fetchAddTag, fetchDeleteTag, fetchEditTag, fetchGetTagList } from '@/service/api/goods/tag';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+
+const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+  {
+    key: 'name',
+    title: '标签名称',
+    align: 'center',
+    minWidth: 100
+  }
+];
+
+const [registerTable, { refresh, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        field: 'name',
+        label: '标签名称',
+        component: 'NInput'
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '标签列表',
+    showAddButton: true
+  }
+});
+
+async function handleDelete(row: Recordable) {
+  setTableLoading(true);
+  await fetchDeleteTag([row.id]);
+  refresh();
+}
+const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
+  modalConfig: {
+    title: '标签 ',
+    width: 400,
+    isShowHeaderText: true,
+    height: 100
+  },
+  formConfig: {
+    schemas: [
+      {
+        label: '',
+        field: 'id',
+        component: 'NInput',
+        show: false
+      },
+      {
+        field: 'name',
+        label: '标签名称',
+        component: 'NInput',
+        required: true
+      }
+    ],
+    gridProps: {
+      cols: '1'
+    },
+    labelWidth: 120
+  }
+});
+async function handleSubmit() {
+  const form = await getFieldsValue();
+  if (form.id) {
+    await fetchEditTag(form);
+  } else {
+    await fetchAddTag(form);
+  }
+  closeModal();
+  refresh();
+}
+
+async function edit(row: Recordable) {
+  openModal(row);
+  setFieldsValue(row);
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchGetTagList" @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>

+ 98 - 0
src/views/government/points/index.vue

@@ -0,0 +1,98 @@
+<script setup lang="tsx">
+import { ref } from 'vue';
+import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
+import { fetchGetPointsList, fetchImportPoints } from '@/service/api/government/points';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+import type { ModalMethods } from '@/components/zt/Modal/types';
+import type { FormSchema } from '@/components/zt/Form/types/form';
+const importTemplateRef = ref<ModalMethods>();
+const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+  {
+    key: 'name',
+    title: '标签名称',
+    align: 'center',
+    minWidth: 100
+  }
+];
+const searchSchemas: FormSchema[] = [
+  {
+    field: 'name',
+    label: '企业名称',
+    component: 'NInput'
+  }
+];
+
+const [registerTable] = useTable({
+  searchFormConfig: {
+    schemas: searchSchemas,
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '标签列表',
+    showAddButton: false
+  }
+});
+const [registerModalTable] = useTable({
+  searchFormConfig: {
+    schemas: searchSchemas,
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '标签列表',
+    showAddButton: false
+  }
+});
+
+const [registerModal, { openModal }] = useModal({
+  title: '充值积分',
+  height: 800,
+  showFooter: false
+});
+async function handleSubmitImport(file: File) {
+  const { error } = await fetchImportPoints(file);
+  if (!error) {
+    importTemplateRef.value?.closeModal();
+  } else {
+    importTemplateRef.value?.setSubLoading(false);
+  }
+}
+function handleOpenPoints() {
+  importTemplateRef.value?.openModal();
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :show-table-action="false" :columns="columns" :api="fetchGetPointsList" @register="registerTable">
+      <template #prefix>
+        <NButton size="small" @click="openModal">充值积分</NButton>
+      </template>
+    </ZTable>
+    <BasicModal @register="registerModal">
+      <ZTable :show-table-action="false" :columns="columns" :api="fetchGetPointsList" @register="registerModalTable">
+        <template #prefix>
+          <NButton size="small" @click="handleOpenPoints">导入积分</NButton>
+          <NButton size="small">导入记录</NButton>
+        </template>
+      </ZTable>
+    </BasicModal>
+    <ZImportTemplate
+      ref="importTemplateRef"
+      url="/platform/pointsRecharge/exportTemplate"
+      template-text="导入积分模版.xlsx"
+      modal-text="导入积分"
+      @submit="handleSubmitImport"
+    ></ZImportTemplate>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

+ 7 - 0
src/views/government/user-list/index.vue

@@ -0,0 +1,7 @@
+<script setup lang="ts"></script>
+
+<template>
+  <LookForward></LookForward>
+</template>
+
+<style scoped></style>

+ 3 - 0
src/views/manage/menu/modules/shared.ts

@@ -135,6 +135,9 @@ export const formSchems: FormSchema[] = [
     componentProps: {
       disabled: true,
       placeholder: '输入路由名称自动生成'
+    },
+    ifShow({ model }) {
+      return model.type != 2;
     }
   },
 

+ 121 - 0
src/views/store-management/store-info/index.vue

@@ -0,0 +1,121 @@
+<script setup lang="tsx">
+import { NTag } from 'naive-ui';
+import { commonStatus } from '@/constants/business';
+import { fetchGetStoreList } from '@/service/api/store-management/store-info';
+import { fetchGetAllStoreList } from '@/service/api/goods/desk-category';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { $t } from '@/locales';
+const columns: NaiveUI.TableColumn<Api.Store.ShopDetail>[] = [
+  {
+    key: 'hbStationNo',
+    title: '商家门店编码',
+    align: 'center'
+  },
+  {
+    key: 'shopName',
+    title: '门店名称',
+    align: 'center'
+  },
+  {
+    key: 'address',
+    title: '地址',
+    align: 'center',
+    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',
+    render: row => {
+      return row.businessTime?.map(it => {
+        return (
+          <div>
+            {it.startTime} - {it.endTime}
+          </div>
+        );
+      });
+    }
+  },
+  {
+    key: 'notice',
+    title: '门店公告',
+    align: 'center'
+  }
+];
+
+const [registerTable] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        label: '门店名称',
+        component: 'ApiSelect',
+        field: 'shopId',
+        componentProps: {
+          api: fetchGetAllStoreList,
+          labelFeild: 'shopName',
+          valueFeild: 'hbStationId'
+        }
+      },
+      {
+        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>

+ 43 - 0
src/views/user-management/user-list/index.vue

@@ -0,0 +1,43 @@
+<script setup lang="tsx">
+import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
+import { fetchGetTagList } from '@/service/api/goods/tag';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+
+const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+  {
+    key: 'name',
+    title: '标签名称',
+    align: 'center',
+    minWidth: 100
+  }
+];
+
+const [registerTable] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        field: 'name',
+        label: '用户昵称',
+        component: 'NInput'
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '标签列表',
+    showAddButton: true
+  }
+});
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchGetTagList" :show-table-action="false" @register="registerTable"></ZTable>
+  </LayoutTable>
+</template>
+
+<style scoped></style>