ソースを参照

feat(government): 新增渠道管理功能并优化用户列表页面

新增渠道的增删改查相关接口与类型定义,包括:
- 添加 `fetchAddChannel` 和 `fetchUpdateChannel` 接口
- 定义 `ChannelVO` 类型用于渠道数据展示
- 调整政府列表页接口为分页统计接口 `/platform/channel/statisticsPage`

同时完成以下更新:
- 政府列表页支持状态切换、新增和编辑渠道信息
- 用户列表页初始化基础表格结构和操作逻辑
- 移除部分未使用的组件声明及图标引用
- 修复商品列表图片样式问题,设置最小宽度确保显示一致性

移除了冗余的删除弹窗确认逻辑及部分无用代码注释。
zhangtao 3 週間 前
コミット
be0c9bf836

+ 28 - 2
src/service/api/government/government-list/index.ts

@@ -5,9 +5,35 @@ import { request } from '@/service/request';
  * @returns
  */
 export function fetchGetChannelList(params: any) {
-  return request({
-    url: '/platform/channel/page',
+  return request<Api.government.ChannelVO[]>({
+    url: '/platform/channel/statisticsPage',
     method: 'get',
     params
   });
 }
+
+/**
+ *
+ * @param params 修改渠道信息
+ * @returns
+ */
+export function fetchUpdateChannel(params: any) {
+  return request({
+    url: '/platform/channel',
+    method: 'put',
+    data: params
+  });
+}
+
+/**
+ *
+ * @param params 新增渠道信息
+ * @returns
+ */
+export function fetchAddChannel(params: any) {
+  return request({
+    url: '/platform/channel',
+    method: 'POST',
+    data: params
+  });
+}

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

@@ -0,0 +1,12 @@
+import { request } from '@/service/request';
+
+/**
+ * 员工列表-积分统计
+ */
+export function fetchGetUserList(params: any) {
+  return request({
+    url: '/admin/user/statisticsList',
+    method: 'get',
+    params
+  });
+}

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

@@ -650,5 +650,41 @@ declare namespace Api {
       successStatus?: number;
       [property: string]: any;
     }
+    /**
+     * 渠道统计
+     *
+     * ChannelVO
+     */
+    interface ChannelVO {
+      /**
+       * 渠道名称
+       */
+      channelName?: string;
+      /**
+       * 企业编号
+       */
+      channelNo?: string;
+      /**
+       * 创建日期
+       */
+      createTime?: { [key: string]: any };
+      /**
+       * 正常员工数
+       */
+      normalCount?: number;
+      /**
+       * 总员工数
+       */
+      staffCount?: number;
+      /**
+       * 企业状态(1-正常,0-停用)
+       */
+      status: Api.Common.commonStatus;
+      /**
+       * 渠道类型(1-企业用户,2-B端用户,3-C端用户)
+       */
+      type?: number;
+      [property: string]: any;
+    }
   }
 }

+ 0 - 22
src/typings/components.d.ts

@@ -11,27 +11,20 @@ declare module 'vue' {
     ApiSelect: typeof import('./../components/zt/ApiSelect/api-select.vue')['default']
     ApiTreeSelect: typeof import('./../components/zt/ApiTreeSelect/api-tree-select.vue')['default']
     AppProvider: typeof import('./../components/common/app-provider.vue')['default']
-    'Basic-ModelForm': typeof import('../components/zt/ModalForm/basic-model-form.vue')['default']
     BasicForm: typeof import('./../components/zt/Form/basic-form.vue')['default']
     BasicModal: typeof import('./../components/zt/Modal/basic-modal.vue')['default']
     BasicModelForm: typeof import('./../components/zt/ModalForm/basic-model-form.vue')['default']
-    BasicUpload: typeof import('./../components/zt/Upload/src/BasicUpload.vue')['default']
     BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
     ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
-    ColumnSetting: typeof import('./../components/zt/Table/src/components/settings/ColumnSetting.vue')['default']
     CountTo: typeof import('./../components/custom/count-to.vue')['default']
     CustomIconSelect: typeof import('./../components/custom/custom-icon-select.vue')['default']
     DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
-    EditableCell: typeof import('./../components/zt/Table/src/components/editable/EditableCell.vue')['default']
     ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
     FullScreen: typeof import('./../components/common/full-screen.vue')['default']
     GithubLink: typeof import('./../components/custom/github-link.vue')['default']
     IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
     IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
     IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
-    'IconBxs:download': typeof import('~icons/bxs/download')['default']
-    IconCarbonPlay: typeof import('~icons/carbon/play')['default']
-    IconCarbonStop: typeof import('~icons/carbon/stop')['default']
     'IconCharm:download': typeof import('~icons/charm/download')['default']
     'IconF7:circleFill': typeof import('~icons/f7/circle-fill')['default']
     'IconF7:flagCircleFill': typeof import('~icons/f7/flag-circle-fill')['default']
@@ -40,14 +33,10 @@ declare module 'vue' {
     'IconGg:ratio': typeof import('~icons/gg/ratio')['default']
     IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
     IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
-    'IconIc:roundPlus': typeof import('~icons/ic/round-plus')['default']
     'IconIconParkOutline:equalRatio': typeof import('~icons/icon-park-outline/equal-ratio')['default']
     'IconIconParkTwotone:mailDownload': typeof import('~icons/icon-park-twotone/mail-download')['default']
     IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
     IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
-    IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
-    IconIcRoundRemove: typeof import('~icons/ic/round-remove')['default']
-    IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
     IconLocalActivity: typeof import('~icons/local/activity')['default']
     IconLocalBanner: typeof import('~icons/local/banner')['default']
     IconLocalCast: typeof import('~icons/local/cast')['default']
@@ -68,7 +57,6 @@ declare module 'vue' {
     LayoutTable: typeof import('./../components/zt/layoutTable/layout-table.vue')['default']
     LookForward: typeof import('./../components/custom/look-forward.vue')['default']
     MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default']
-    NAlert: typeof import('naive-ui')['NAlert']
     NBadge: typeof import('naive-ui')['NBadge']
     NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
     NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
@@ -88,16 +76,13 @@ declare module 'vue' {
     NDrawer: typeof import('naive-ui')['NDrawer']
     NDrawerContent: typeof import('naive-ui')['NDrawerContent']
     NDropdown: typeof import('naive-ui')['NDropdown']
-    NDynamicInput: typeof import('naive-ui')['NDynamicInput']
     NEmpty: typeof import('naive-ui')['NEmpty']
     NFlex: typeof import('naive-ui')['NFlex']
     NForm: typeof import('naive-ui')['NForm']
     NFormItem: typeof import('naive-ui')['NFormItem']
-    NFormItemGi: typeof import('naive-ui')['NFormItemGi']
     NGi: typeof import('naive-ui')['NGi']
     NGrid: typeof import('naive-ui')['NGrid']
     NIcon: typeof import('naive-ui')['NIcon']
-    NImage: typeof import('naive-ui')['NImage']
     NInput: typeof import('naive-ui')['NInput']
     NInputGroup: typeof import('naive-ui')['NInputGroup']
     NInputNumber: typeof import('naive-ui')['NInputNumber']
@@ -129,15 +114,11 @@ declare module 'vue' {
     NTag: typeof import('naive-ui')['NTag']
     NText: typeof import('naive-ui')['NText']
     NThing: typeof import('naive-ui')['NThing']
-    NTimeline: typeof import('naive-ui')['NTimeline']
-    NTimelineItem: typeof import('naive-ui')['NTimelineItem']
     NTooltip: typeof import('naive-ui')['NTooltip']
     NTree: typeof import('naive-ui')['NTree']
     NTreeSelect: typeof import('naive-ui')['NTreeSelect']
     NUpload: typeof import('naive-ui')['NUpload']
     NUploadDragger: typeof import('naive-ui')['NUploadDragger']
-    NUploadFileList: typeof import('naive-ui')['NUploadFileList']
-    NUploadTrigger: typeof import('naive-ui')['NUploadTrigger']
     NWatermark: typeof import('naive-ui')['NWatermark']
     PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
     ProCard: typeof import('pro-naive-ui')['ProCard']
@@ -156,14 +137,11 @@ declare module 'vue' {
     SoybeanAvatar: typeof import('./../components/custom/soybean-avatar.vue')['default']
     SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default']
     SystemLogo: typeof import('./../components/common/system-logo.vue')['default']
-    Table: typeof import('./../components/zt/Table/src/Table.vue')['default']
-    TableAction: typeof import('./../components/zt/Table/src/components/TableAction.vue')['default']
     TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default']
     TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default']
     ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default']
     WaveBg: typeof import('./../components/custom/wave-bg.vue')['default']
     WebSiteLink: typeof import('./../components/custom/web-site-link.vue')['default']
-    ZEditTable: typeof import('./../components/zt/editTable/z-edit-table.vue')['default']
     ZImportTemplate: typeof import('./../components/zt/importTemplate/z-import-template.vue')['default']
     ZTable: typeof import('./../components/zt/Table/z-table.vue')['default']
     ZUpload: typeof import('./../components/zt/upload/z-upload.vue')['default']

+ 1 - 4
src/views/goods/store-goods/index.vue

@@ -32,16 +32,13 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     align: 'left',
     width: 300,
     fixed: 'left',
-    ellipsis: {
-      tooltip: true
-    },
     render: row => {
       if (!row.sku) {
         return '---';
       }
       return (
         <div class={'flex items-center'}>
-          <NImage src={row.sku.pic} class="h-[80px] w-[80px]" />
+          <NImage src={row.sku.pic} class="h-[80px] min-w-80px w-[80px]" />
           <div class={'ml-[10px]'}>
             <div class={'text-[16px] font-semibold'}>{row.sku.skuName || '--'}</div>
             <div class={'text-gray'}>海博商品ID: {row.sku.hbSkuId || '--'} </div>

+ 60 - 33
src/views/government/government-list/index.vue

@@ -1,50 +1,79 @@
 <script setup lang="tsx">
-import { NButton, NPopconfirm } from 'naive-ui';
-import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
-import { fetchGetChannelList } from '@/service/api/government/government-list';
+import { NSwitch } from 'naive-ui';
+import { fetchAddChannel, fetchGetChannelList, fetchUpdateChannel } from '@/service/api/government/government-list';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
 
-const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+const columns: NaiveUI.TableColumn<Api.government.ChannelVO>[] = [
   {
-    key: '1',
+    key: 'channelNo',
     title: '企业编号',
     align: 'center'
   },
   {
-    key: '2',
+    key: 'channelName',
     title: '企业名称',
     align: 'center'
   },
   {
-    key: '3',
+    key: 'staffCount',
     title: '总员工数',
     align: 'center'
   },
   {
-    key: '4',
+    key: 'normalCount',
     title: '正常员工数',
     align: 'center'
   },
   {
-    key: '5',
+    key: 'status',
     title: '状态',
-    align: 'center'
+    align: 'center',
+    render: row => {
+      return (
+        <NSwitch
+          uncheckedValue={0}
+          checkedValue={1}
+          value={row.status}
+          onUpdate:value={val => {
+            row.status = val;
+            fetchUpdateChannel(row);
+          }}
+        ></NSwitch>
+      );
+    }
   },
   {
-    key: '6',
+    key: 'createTime',
     title: '创建时间',
     align: 'center'
   }
 ];
 
-const [registerTable, { refresh, setTableLoading }] = useTable({
+const [registerTable, { refresh }] = useTable({
   searchFormConfig: {
     schemas: [
       {
-        field: 'name',
-        label: '标签名称',
+        field: 'channelName',
+        label: '企业名称',
         component: 'NInput'
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NSelect',
+        componentProps: {
+          options: [
+            {
+              label: '正常',
+              value: 1
+            },
+            {
+              label: '禁用',
+              value: 0
+            }
+          ]
+        }
       }
     ],
     inline: false,
@@ -59,19 +88,12 @@ const [registerTable, { refresh, setTableLoading }] = useTable({
   }
 });
 
-async function handleDelete(row: Recordable) {
-  setTableLoading(true);
-  // await fetchDeleteTag([row.id]);
-  console.log(row, 'row');
-
-  refresh();
-}
 const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
   modalConfig: {
     title: '标签 ',
-    width: 400,
+    width: 500,
     isShowHeaderText: true,
-    height: 100
+    height: 200
   },
   formConfig: {
     schemas: [
@@ -82,10 +104,21 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
         show: false
       },
       {
-        field: 'name',
-        label: '标签名称',
+        field: 'channelName',
+        label: '企业名称',
         component: 'NInput',
         required: true
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NSwitch',
+        required: true,
+        componentProps: {
+          checkedValue: 1,
+          uncheckedValue: 0
+        },
+        defaultValue: 1
       }
     ],
     gridProps: {
@@ -97,9 +130,9 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
 async function handleSubmit() {
   const form = await getFieldsValue();
   if (form.id) {
-    // await fetchEditTag(form);
+    await fetchUpdateChannel(form);
   } else {
-    // await fetchAddTag(form);
+    await fetchAddChannel(form);
   }
   closeModal();
   refresh();
@@ -116,12 +149,6 @@ async function edit(row: Recordable) {
     <ZTable :columns="columns" :api="fetchGetChannelList" @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>

+ 101 - 2
src/views/government/user-list/index.vue

@@ -1,7 +1,106 @@
-<script setup lang="ts"></script>
+<script setup lang="tsx">
+import { NButton, NPopconfirm } from 'naive-ui';
+import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
+import { fetchGetUserList } from '@/service/api/government/user-list';
+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]);
+  console.log(row, 'row');
+
+  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>
-  <LookForward></LookForward>
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchGetUserList" @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>