Bladeren bron

```
feat(table): 为表格组件添加搜索功能支持

- 在 `tableProp` 接口中新增 `showSearch` 属性,用于控制是否显示搜索区域
- 更新 `z-table.vue` 组件,根据 `showSearch` 属性控制搜索表单的显示
- 修改 `searchFormConfig` 为可选属性,以适配不需要搜索的场景
- 调整了部分类型定义和组件属性传参方式

fix(api): 修正政府用户列表接口 URL 和方法

- 将员工列表接口从 `/admin/user/statisticsList` 更改为 `/admin/enterprise/enterpriseUserList`
- 新增员工、修改员工、删除员工、导入员工及获取导入记录等接口实现
- 修复请求参数传递方式,统一使用 `params` 传递查询参数

feat(login): 更新登录页面样式并添加底部波浪图形

- 移除了动态背景颜色计算逻辑
- 添加静态 SVG 波浪图形作为页面底部装饰
- 调整布局结构,增加 banner 图标展示区域

chore(env): 更新测试环境后端服务地址

- 注释原地址 `http://192.168.1.206:8114`
- 启用新地址 `http://192.168.0.157:8114` 并标注负责人

refactor(layout): 更新全局页脚版权信息

- 修改页脚内容为:“技术支持:中数未来 Copyright © 2025 zhongshuweilai (Developer: ZT)”
- 添加点击指针样式提升交互体验

feat(goods): 优化商品图片展示逻辑

- 当图片不存在时,显示警告图标替代空白占位
- 修复商品名称字段绑定错误问题,由 `shopId` 改为 `skuName`

refactor(theme): 调整主题布局模式与水印文本

- 布局模式更改为 `top-hybrid-sidebar-first`,滚动模式设为 `wrapper`
- 水印文本由 "SoybeanAdmin" 更改为 "zhongshuweilai"

feat(user): 实现用户管理模块基础功能

- 新建用户管理 API 模块,提供分页获取用户列表功能
- 完善用户列表视图,展示用户昵称、头像、手机号等信息
- 补充相关类型定义,包括 `userList` 接口结构

refactor(store): 优化门店信息表格列配置

- 设置门店名称与地址列宽度为 200px
- 为营业时间列启用 tooltip 提示以处理文本溢出情况

refactor(operation): 修正热搜管理字段映射

- 将标题字段由 `name` 改为 `title` 以匹配后端返回数据结构
```

zhangtao 1 week geleden
bovenliggende
commit
b29816539b

+ 2 - 1
.env.test

@@ -1,6 +1,7 @@
 # backend service base url, test environment
 # VITE_SERVICE_BASE_URL=http://74949mkfh190.vicp.fun
-VITE_SERVICE_BASE_URL=http://192.168.1.206:8114
+# VITE_SERVICE_BASE_URL=http://192.168.1.206:8114 #付
+VITE_SERVICE_BASE_URL=http://192.168.0.157:8114 #王
 # VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default
 
 

BIN
src/assets/imgs/image.png


+ 1 - 1
src/components/zt/Table/hooks/useTable.ts

@@ -15,7 +15,7 @@ export function useTable(tableProps: ztTableProps): UseTableReturnType {
       () => tableProps,
       () => {
         if (tableProps) {
-          instance.setSearchProps(tableProps.searchFormConfig);
+          instance.setSearchProps(tableProps.searchFormConfig as FormProps);
           instance.setTableConfig(tableProps.tableConfig);
         }
       },

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

@@ -35,7 +35,8 @@ export const basicProps = {
       showAddButton: true,
       keyField: 'id',
       scrollX: 1000,
-      showTableHeaderAction: true
+      showTableHeaderAction: true,
+      showSearch: true
     }
   }
 };

+ 5 - 1
src/components/zt/Table/types/index.ts

@@ -41,9 +41,13 @@ export interface tableProp extends DataTableProps {
    * 是否显示表格头部操作列
    */
   showTableHeaderAction?: boolean;
+  /**
+   * 是否显示搜索组件
+   */
+  showSearch?: boolean;
 }
 
 export interface ztTableProps {
-  searchFormConfig: FormProps;
+  searchFormConfig?: FormProps;
   tableConfig: tableProp;
 }

+ 1 - 1
src/components/zt/Table/z-table.vue

@@ -145,7 +145,7 @@ export default defineComponent({
 </script>
 
 <template>
-  <NCard :bordered="false" size="small">
+  <NCard v-if="getTableProps.showSearch" :bordered="false" size="small">
     <NCollapse display-directive="show" :default-expanded-names="['role-search']">
       <NCollapseItem title="搜索" name="role-search">
         <BasicForm @register-form="registerSearchForm" @submit="handleSearch" @reset="handleReset" />

+ 1 - 1
src/layouts/modules/global-footer/index.vue

@@ -6,7 +6,7 @@ defineOptions({
 
 <template>
   <DarkModeContainer class="h-full flex-center">
-    <div>中数未来</div>
+    <div class="cursor-pointer text-center">技术支持:中数未来 Copyright © 2025 zhongshuweilai (Developer: ZT)</div>
   </DarkModeContainer>
 </template>
 

+ 1 - 1
src/service/api/goods/store-goods/index.ts

@@ -25,7 +25,7 @@ export function fetchGetGoodsList(data: any) {
   return request<Api.goods.ShopSku[]>({
     url: '/shop/shopProd/page',
     method: 'get',
-    data
+    params: data
   });
 }
 

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

@@ -4,9 +4,68 @@ import { request } from '@/service/request';
  * 员工列表-积分统计
  */
 export function fetchGetUserList(params: any) {
-  return request({
-    url: '/admin/user/statisticsList',
+  return request<Api.government.userList[]>({
+    url: '/admin/enterprise/enterpriseUserList',
     method: 'get',
     params
   });
 }
+
+/**
+ * 新增员工
+ */
+export function fetchAddUser(data: any) {
+  return request({
+    url: '/admin/enterprise/addUser',
+    method: 'POST',
+    data
+  });
+}
+
+/**
+ * 修改员工
+ */
+export function fetchEditUser(data: any) {
+  return request({
+    url: '/admin/enterprise',
+    method: 'PUT',
+    data
+  });
+}
+
+/**
+ * 删除员工
+ */
+export function fetchDeleteUser(id: number) {
+  return request({
+    url: `/admin/enterprise/deleteUserById?userId=${id}`,
+    method: 'DELETE'
+  });
+}
+
+/**
+ * 导入员工
+ * @param data
+ * @returns
+ */
+export function fetchExportUser(data: { file: File }) {
+  return request({
+    url: '/admin/enterprise/uploadExcelGoods',
+    method: 'post',
+    data,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
+  });
+}
+
+/**
+ * 导入记录
+ */
+
+export function fetchGetImportRecordList() {
+  return request<Api.government.importRecordList[]>({
+    url: '/admin/enterprise/enterpriseUserLogList',
+    method: 'get'
+  });
+}

+ 14 - 0
src/service/api/user-management/user-list/index.ts

@@ -0,0 +1,14 @@
+import { request } from '@/service/request';
+
+/**
+ * 分页获取用户列表
+ * @param data
+ * @returns
+ */
+export function fetchGetUserList(data: any) {
+  return request<Api.userManagement.userList[]>({
+    url: '/admin/user/userList',
+    method: 'GET',
+    params: data
+  });
+}

+ 7 - 3
src/theme/settings.ts

@@ -14,8 +14,12 @@ export const themeSettings: App.Theme.ThemeSetting = {
   isInfoFollowPrimary: true,
   resetCacheStrategy: 'refresh',
   layout: {
-    mode: 'vertical',
-    scrollMode: 'content'
+    // mode: 'vertical',默认模式
+    // scrollMode: 'content'
+    // mode: 'vertical-mix',
+    // scrollMode: 'wrapper'
+    mode: 'top-hybrid-sidebar-first',
+    scrollMode: 'wrapper'
   },
   page: {
     animate: true,
@@ -57,7 +61,7 @@ export const themeSettings: App.Theme.ThemeSetting = {
   },
   watermark: {
     visible: false,
-    text: 'SoybeanAdmin',
+    text: 'zhongshuweilai',
     enableUserName: false,
     enableTime: false,
     timeFormat: 'YYYY-MM-DD HH:mm'

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

@@ -686,6 +686,69 @@ declare namespace Api {
       type?: number;
       [property: string]: any;
     }
+    /**
+     * 员工列表
+     */
+    interface userList {
+      /**
+       * 可用
+       */
+      available: number;
+      /**
+       * 所属企业
+       */
+      channelName: string;
+
+      /**
+       * 已过期积分
+       */
+      expired: number;
+      /**
+       * 真实姓名
+       */
+      realName: string;
+      /**
+       * 状态  1正常 ,0 无效
+       */
+      status: Common.commonStatus;
+      /**
+       * 总积分
+       */
+      total: number;
+      /**
+       * 使用积分
+       */
+      used: number;
+      /**
+       *  手机号
+       */
+      userMobile: string;
+      /**
+       * 员工id
+       */
+      userId: number;
+    }
+    /**
+     * 员工导入记录
+     */
+    interface importRecordList {
+      /**
+       * 导入结果
+       */
+      result: string;
+      /**
+       * 创建时间
+       */
+      createTime: string;
+      /**
+       * 任务名称
+       */
+      taskName: string;
+      /**
+       * 操作人
+       */
+      operator: string;
+    }
   }
   namespace operation {
     interface HotSearch {
@@ -753,4 +816,64 @@ declare namespace Api {
       [property: string]: any;
     }
   }
+  namespace userManagement {
+    interface userList {
+      userId: string;
+      /**
+       * 账户名
+       */
+      userName: string;
+      /**
+       * 昵称
+       */
+      nickName: string;
+      /**
+       * 真实姓名
+       */
+      realName: string;
+      /**
+       * 邮箱
+       */
+      userMail: string;
+      /**
+       * 登录密码
+       */
+      loginPassword: string;
+      /**
+       * 支付密码
+       */
+      payPassword: string;
+      /**
+       * 手机号
+       */
+      userMobile: string;
+      modifyTime: string;
+      userRegtime: string;
+      userRegip: string;
+      userMemo: string;
+      sex: string;
+      birthDate: string;
+      /**
+       * 用户头像
+       */
+      pic: string;
+      /**
+       * 状态 1正常 0禁用
+       */
+      status: Common.commonStatus;
+      growth: string;
+      level: number;
+      levelType: number;
+      vipEndTime: string;
+      levelName: string;
+      /**
+       * 平台1企业用户,2夫妻店,3市民请集合
+       */
+      platform: number;
+      /**
+       * 渠道id
+       */
+      channelId: number;
+    }
+  }
 }

+ 37 - 36
src/views/_builtin/login/index.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import { computed } from 'vue';
 import type { Component } from 'vue';
-import { getPaletteColorByNumber, mixColor } from '@sa/color';
 import { loginModuleRecord } from '@/constants/app';
 import { useThemeStore } from '@/store/modules/theme';
 import { $t } from '@/locales';
@@ -34,47 +33,49 @@ const moduleMap: Record<UnionKey.LoginModule, LoginModule> = {
 };
 
 const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
-
-const bgThemeColor = computed(() =>
-  themeStore.darkMode ? getPaletteColorByNumber(themeStore.themeColor, 600) : themeStore.themeColor
-);
-
-const bgColor = computed(() => {
-  const COLOR_WHITE = '#ffffff';
-
-  const ratio = themeStore.darkMode ? 0.5 : 0.2;
-
-  return mixColor(COLOR_WHITE, themeStore.themeColor, ratio);
-});
 </script>
 
 <template>
-  <div class="relative size-full flex-center overflow-hidden" :style="{ backgroundColor: bgColor }">
-    <WaveBg :theme-color="bgThemeColor" />
+  <div class="relative size-full flex-center overflow-hidden">
+    <!-- <WaveBg :theme-color="bgThemeColor" /> -->
+
     <NCard :bordered="false" class="relative z-4 w-auto rd-12px">
-      <div class="w-400px lt-sm:w-300px">
-        <header class="flex-y-center justify-between">
-          <SystemLogo class="text-64px text-primary lt-sm:text-48px" />
-          <h3 class="text-28px text-primary font-500 lt-sm:text-22px">{{ $t('system.title') }}</h3>
-          <div class="i-flex-col">
-            <ThemeSchemaSwitch
-              :theme-schema="themeStore.themeScheme"
-              :show-tooltip="false"
-              class="text-20px lt-sm:text-18px"
-              @switch="themeStore.toggleThemeScheme"
-            />
-          </div>
-        </header>
-        <main class="pt-24px">
-          <h3 class="text-18px text-primary font-medium">{{ $t(activeModule.label) }}</h3>
-          <div class="pt-24px">
-            <Transition :name="themeStore.page.animateMode" mode="out-in" appear>
-              <component :is="activeModule.component" />
-            </Transition>
-          </div>
-        </main>
+      <div class="flex items-center">
+        <div class="w-400px lt-sm:w-300px">
+          <header class="flex-y-center justify-between">
+            <SystemLogo class="text-64px text-primary lt-sm:text-48px" />
+            <h3 class="text-28px text-primary font-500 lt-sm:text-22px">{{ $t('system.title') }}</h3>
+            <div class="i-flex-col">
+              <ThemeSchemaSwitch
+                :theme-schema="themeStore.themeScheme"
+                :show-tooltip="false"
+                class="text-20px lt-sm:text-18px"
+                @switch="themeStore.toggleThemeScheme"
+              />
+            </div>
+          </header>
+          <main class="pt-24px">
+            <h3 class="text-18px text-primary font-medium">{{ $t(activeModule.label) }}</h3>
+            <div class="pt-24px">
+              <Transition :name="themeStore.page.animateMode" mode="out-in" appear>
+                <component :is="activeModule.component" />
+              </Transition>
+            </div>
+          </main>
+        </div>
+        <Transition name="fade-bottom" mode="out-in" appear>
+          <SvgIcon local-icon="banner" class="text-400px text-primary max-md:hidden"></SvgIcon>
+        </Transition>
       </div>
     </NCard>
+
+    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 600" class="absolute bottom-0 left-0 right-0">
+      <path
+        fill="#f97316"
+        fill-opacity="1"
+        d="M0,480L48,453.3C96,427,192,373,288,373.3C384,373,480,427,576,405.3C672,384,768,288,864,240C960,192,1056,192,1152,213.3C1248,235,1344,277,1392,298.7L1440,320L1440,600L1392,600C1344,600,1248,600,1152,600C1056,600,960,600,864,600C768,600,672,600,576,600C480,600,384,600,288,600C192,600,96,600,48,600L0,600Z"
+      ></path>
+    </svg>
   </div>
 </template>
 

+ 5 - 2
src/views/goods/store-goods/index.vue

@@ -39,7 +39,10 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
       const img = row.sku.pic?.split(',');
       return (
         <div class={'flex items-center'}>
-          <NImage src={img[0]} class="h-[80px] min-w-80px w-[80px]" lazy />
+          {img && img.length > 0 && <NImage src={img[0]} class="h-[80px] min-w-80px w-[80px]" lazy />}
+          {!img && (
+            <SvgIcon icon={'proicons:alert-triangle'} class={'cursor-pointer text-80px'} style={'color:#ccc'}></SvgIcon>
+          )}
           <div class={'ml-[10px]'}>
             <div class={'text-[16px] font-semibold'}>{row.sku.skuName || '--'}</div>
             <div class={'text-gray'}>海博商品ID: {row.sku.hbSkuId || '--'} </div>
@@ -216,7 +219,7 @@ const [registerTable, { getTableCheckedRowKeys, refresh, getTableData }] = useTa
       {
         label: '商品名称',
         component: 'NInput',
-        field: 'shopId'
+        field: 'skuName'
       }
     ],
     inline: false,

+ 208 - 23
src/views/government/user-list/index.vue

@@ -1,15 +1,73 @@
 <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 { ref } from 'vue';
+import { NButton, NPopconfirm, NSwitch } from 'naive-ui';
+import {
+  fetchAddUser,
+  fetchDeleteUser,
+  fetchEditUser,
+  fetchExportUser,
+  fetchGetImportRecordList,
+  fetchGetUserList
+} from '@/service/api/government/user-list';
+import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
-const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+import type { ModalMethods } from '@/components/zt/Modal/types';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+const importTemplateRef = ref<ModalMethods>();
+const columns: NaiveUI.TableColumn<Api.government.userList>[] = [
   {
-    key: 'name',
-    title: '标签名称',
+    key: 'channelName',
+    title: '所属企业',
+    align: 'center'
+  },
+  {
+    key: 'realName',
+    title: '员工姓名',
+    align: 'center'
+  },
+  {
+    key: 'userMobile',
+    title: '手机号码',
+    align: 'center'
+  },
+  {
+    key: 'total',
+    title: '总充值积分',
+    align: 'center'
+  },
+  {
+    key: 'available',
+    title: '当前可用积分',
+    align: 'center'
+  },
+  {
+    key: 'expired',
+    title: '已过期积分',
+    align: 'center'
+  },
+  {
+    key: 'used',
+    title: '已消耗积分',
+    align: 'center'
+  },
+  {
+    key: 'status',
+    title: '状态',
     align: 'center',
-    minWidth: 100
+    render: row => {
+      return (
+        <NSwitch
+          uncheckedValue={0}
+          checkedValue={1}
+          value={row.status}
+          onUpdate:value={val => {
+            row.status = val;
+            fetchEditUser(row);
+          }}
+        ></NSwitch>
+      );
+    }
   }
 ];
 
@@ -17,8 +75,18 @@ const [registerTable, { refresh, setTableLoading }] = useTable({
   searchFormConfig: {
     schemas: [
       {
-        field: 'name',
-        label: '标签名称',
+        field: 'channelName',
+        label: '所属企业',
+        component: 'NInput'
+      },
+      {
+        field: 'realName',
+        label: '员工姓名',
+        component: 'NInput'
+      },
+      {
+        field: 'userMobile',
+        label: '手机号码',
         component: 'NInput'
       }
     ],
@@ -28,39 +96,115 @@ const [registerTable, { refresh, setTableLoading }] = useTable({
     isFull: false
   },
   tableConfig: {
-    keyField: 'id',
-    title: '标签列表',
+    keyField: 'userId',
+    title: '员工列表',
     showAddButton: true
   }
 });
+const [registerModalTable] = useTable({
+  tableConfig: {
+    keyField: 'id',
+    title: '导入记录',
+    showTableHeaderAction: false,
+    showSearch: false,
+    minHeight: 400
+  }
+});
+
+const failColumns: NaiveUI.TableColumn<Api.government.importRecordList>[] = [
+  {
+    key: 'index',
+    title: '序号',
+    align: 'center',
+    render(_, rowIndex) {
+      return rowIndex + 1;
+    }
+  },
+  {
+    key: 'taskName',
+    title: '任务名称',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '时间',
+    align: 'center'
+  },
+  {
+    key: 'operator',
+    title: '操作人',
+    align: 'center'
+  },
+  {
+    key: 'result',
+    title: '状态',
+    align: 'center',
+    width: 240,
+    render(row) {
+      const resultText = row.result;
+      // 使用正则表达式匹配"失败X条"部分
+      const failedMatch = resultText.match(/(失败\d+条)/);
+
+      if (failedMatch) {
+        const failedText = failedMatch[1];
+        const parts = resultText.split(failedText);
 
-async function handleDelete(row: Recordable) {
+        return (
+          <div>
+            {parts[0]}
+            <span class={'text-red-500'}>{failedText}</span>
+            {parts[1]}
+          </div>
+        );
+      }
+
+      return <div>{resultText}</div>;
+    }
+  }
+];
+async function handleDelete(row: Api.government.userList) {
   setTableLoading(true);
-  // await fetchDeleteTag([row.id]);
+  await fetchDeleteUser(row.userId);
   console.log(row, 'row');
 
   refresh();
 }
 const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
   modalConfig: {
-    title: '标签 ',
-    width: 400,
+    title: '员工 ',
+    width: 600,
     isShowHeaderText: true,
-    height: 100
+    height: 200
   },
   formConfig: {
     schemas: [
       {
         label: '',
-        field: 'id',
+        field: 'userId',
         component: 'NInput',
         show: false
       },
       {
-        field: 'name',
-        label: '标签名称',
+        field: 'realName',
+        label: '员工姓名',
+        component: 'NInput'
+      },
+      {
+        field: 'userMobile',
+        label: '手机号码',
         component: 'NInput',
         required: true
+      },
+      {
+        field: 'channelId',
+        label: '所属企业',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchGetAllChannelList,
+          labelFeild: 'channelName',
+          valueFeild: 'id'
+        },
+        required: true
       }
     ],
     gridProps: {
@@ -69,12 +213,18 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
     labelWidth: 120
   }
 });
+const [registerModalFail, { openModal: openModalFail }] = useModal({
+  title: '导入记录',
+  height: 600,
+  showFooter: false,
+  width: 1200
+});
 async function handleSubmit() {
   const form = await getFieldsValue();
-  if (form.id) {
-    // await fetchEditTag(form);
+  if (form.userId) {
+    await fetchEditUser(form);
   } else {
-    // await fetchAddTag(form);
+    await fetchAddUser(form);
   }
   closeModal();
   refresh();
@@ -84,13 +234,25 @@ async function edit(row: Recordable) {
   openModal(row);
   setFieldsValue(row);
 }
+
+function openImportModal() {
+  importTemplateRef.value?.openModal();
+}
+async function handleSubmitImport(file: File) {
+  const { error } = await fetchExportUser({ file });
+  if (!error) {
+    importTemplateRef.value?.closeModal();
+    refresh();
+  }
+  importTemplateRef.value?.setSubLoading(false);
+}
 </script>
 
 <template>
   <LayoutTable>
     <ZTable :columns="columns" :api="fetchGetUserList" @register="registerTable" @add="openModal">
       <template #op="{ row }">
-        <NButton size="small" ghost type="primary" @click="edit(row)">编辑</NButton>
+        <NButton size="small" ghost type="primary" :disabled="Boolean(row.used)" @click="edit(row)">编辑</NButton>
         <NPopconfirm @positive-click="handleDelete(row)">
           <template #trigger>
             <NButton size="small" type="error" ghost>删除</NButton>
@@ -98,7 +260,30 @@ async function edit(row: Recordable) {
           确定删除吗?
         </NPopconfirm>
       </template>
+      <template #prefix>
+        <NSpace>
+          <NButton size="small" @click="openImportModal">导入员工</NButton>
+          <NButton size="small" @click="openModalFail">导入记录</NButton>
+        </NSpace>
+      </template>
     </ZTable>
+    <ZImportTemplate
+      ref="importTemplateRef"
+      url="/admin/enterprise/downloadExcel"
+      template-text="员工导入模版.xlsx"
+      modal-text="导入员工"
+      @submit="handleSubmitImport"
+    ></ZImportTemplate>
+    <BasicModal @register="registerModalFail">
+      <LayoutTable>
+        <ZTable
+          :columns="failColumns"
+          :show-table-action="false"
+          :api="fetchGetImportRecordList"
+          @register="registerModalTable"
+        ></ZTable>
+      </LayoutTable>
+    </BasicModal>
     <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
   </LayoutTable>
 </template>

+ 15 - 1
src/views/operation/search/index.vue

@@ -12,7 +12,7 @@ import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
 
 const columns: NaiveUI.TableColumn<InternalRowData>[] = [
   {
-    key: 'name',
+    key: 'title',
     title: '名称',
     align: 'center'
   },
@@ -21,6 +21,20 @@ const columns: NaiveUI.TableColumn<InternalRowData>[] = [
     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({

+ 7 - 2
src/views/store-management/store-info/index.vue

@@ -36,12 +36,14 @@ const columns: NaiveUI.TableColumn<Api.Store.ShopDetail>[] = [
   {
     key: 'shopName',
     title: '门店名称',
-    align: 'center'
+    align: 'center',
+    width: 200
   },
   {
     key: 'address',
     title: '地址',
     align: 'center',
+    width: 200,
     render: row => {
       return (
         <div>
@@ -85,7 +87,10 @@ const columns: NaiveUI.TableColumn<Api.Store.ShopDetail>[] = [
     key: 'businessTime',
     title: '营业时间',
     align: 'center',
-    width: 200
+    width: 200,
+    ellipsis: {
+      tooltip: true
+    }
   },
   {
     key: 'notice',

+ 30 - 10
src/views/user-management/user-list/index.vue

@@ -1,14 +1,34 @@
 <script setup lang="tsx">
-import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
-import { fetchGetTagList } from '@/service/api/goods/tag';
+import { NImage } from 'naive-ui';
+import { fetchGetUserList } from '@/service/api/user-management/user-list';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 
-const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+const columns: NaiveUI.TableColumn<Api.userManagement.userList>[] = [
   {
-    key: 'name',
-    title: '标签名称',
+    key: 'nickName',
+    title: '用户昵称',
+    align: 'center'
+  },
+  {
+    key: 'pic',
+    title: '头像',
     align: 'center',
-    minWidth: 100
+    render: row => <NImage src={row.pic} class="h-[80px] min-w-80px w-[80px]" lazy />
+  },
+  {
+    key: 'userMobile',
+    title: '手机号码',
+    align: 'center'
+  },
+  {
+    key: 'name',
+    title: '渠道',
+    align: 'center'
+  },
+  {
+    key: 'userRegtime',
+    title: '创建时间',
+    align: 'center'
   }
 ];
 
@@ -16,7 +36,7 @@ const [registerTable] = useTable({
   searchFormConfig: {
     schemas: [
       {
-        field: 'name',
+        field: 'nickName',
         label: '用户昵称',
         component: 'NInput'
       }
@@ -28,15 +48,15 @@ const [registerTable] = useTable({
   },
   tableConfig: {
     keyField: 'id',
-    title: '标签列表',
-    showAddButton: true
+    title: '用户列表',
+    showAddButton: false
   }
 });
 </script>
 
 <template>
   <LayoutTable>
-    <ZTable :columns="columns" :api="fetchGetTagList" :show-table-action="false" @register="registerTable"></ZTable>
+    <ZTable :columns="columns" :api="fetchGetUserList" :show-table-action="false" @register="registerTable"></ZTable>
   </LayoutTable>
 </template>