Przeglądaj źródła

feat(config): 更新环境变量配置并调整接口地址

- 修改项目标题与描述为“市民请集合管理系统”
- 调整后端服务成功码从 200 改为 00000
- 更新 OSS 基础路径至新域名
- 更改测试环境后端服务地址并优化代理配置
- 替换 logo 图片资源路径并更新引用
- 统一表格分页字段命名:current → pageNum,size → pageSize
- 规范字典标签组件的数据结构字段名
- 修正文件上传返回 URL 拼接逻辑
- 更新菜单类型常量值使用枚举形式代替数字
- 将验证码相关请求迁移到认证模块下,并适配 OAuth2 表单提交
- 移除部分旧业务 API 接口定义
- 新增政企管理、商品中心等路由和对应视图组件
- 引入政府相关页面及权限控制路由
```
zhangtao 14 godzin temu
rodzic
commit
edcd8ac332
73 zmienionych plików z 2622 dodań i 4098 usunięć
  1. 5 5
      .env
  2. 3 8
      .env.test
  3. 0 2
      build/config/proxy.ts
  4. 1 1
      packages/axios/src/constant.ts
  5. 2 2
      packages/hooks/src/use-table.ts
  6. BIN
      public/favicon.png
  7. BIN
      src/assets/imgs/logo.png
  8. BIN
      src/assets/svg-icon/logo.png
  9. 1 1
      src/components/common/system-logo.vue
  10. 4 4
      src/components/zt/Table/z-table.vue
  11. 4 11
      src/components/zt/dict-tag/index.vue
  12. 1 1
      src/components/zt/upload/z-upload.vue
  13. 8 3
      src/constants/business.ts
  14. 7 7
      src/hooks/business/dict.ts
  15. 2 2
      src/hooks/common/form.ts
  16. 3 4
      src/hooks/common/table.ts
  17. 8 2
      src/locales/langs/en-us.ts
  18. 8 2
      src/locales/langs/zh-cn.ts
  19. 4 0
      src/router/elegant/imports.ts
  20. 58 0
      src/router/elegant/routes.ts
  21. 6 0
      src/router/elegant/transform.ts
  22. 18 9
      src/service/api/auth.ts
  23. 11 29
      src/service/api/common.ts
  24. 0 93
      src/service/api/config/dict/index.ts
  25. 0 85
      src/service/api/delivery/after-sales-order/index.ts
  26. 0 61
      src/service/api/delivery/normal-orde/index.ts
  27. 0 14
      src/service/api/finance/commodity-freight/index.ts
  28. 0 14
      src/service/api/finance/summary/index.ts
  29. 50 0
      src/service/api/goods-center/type-admin/index.ts
  30. 0 129
      src/service/api/goods/desk-category/index.ts
  31. 0 66
      src/service/api/goods/store-goods/index.ts
  32. 0 62
      src/service/api/goods/tag/index.ts
  33. 14 3
      src/service/api/government/government-list/index.ts
  34. 0 52
      src/service/api/operation/advertisement/index.ts
  35. 0 52
      src/service/api/operation/delivery-admin/index.ts
  36. 0 53
      src/service/api/operation/search/index.ts
  37. 1 1
      src/service/api/route.ts
  38. 0 14
      src/service/api/store-management/store-info/index.ts
  39. 1 1
      src/service/api/system-department.ts
  40. 136 27
      src/service/api/system-manage.ts
  41. 0 14
      src/service/api/user-management/user-list/index.ts
  42. 1 8
      src/service/request/index.ts
  43. 3 3
      src/service/request/shared.ts
  44. 19 15
      src/store/modules/auth/index.ts
  45. 1 3
      src/store/modules/dict/index.ts
  46. 3 4
      src/store/modules/route/index.ts
  47. 1 1
      src/theme/settings.ts
  48. 182 1765
      src/typings/api.d.ts
  49. 4 2
      src/typings/api/auth.d.ts
  50. 180 43
      src/typings/api/system-manage.d.ts
  51. 12 0
      src/typings/elegant-router.d.ts
  52. 1 2
      src/utils/service.ts
  53. 32 155
      src/utils/zt/index.ts
  54. 2 2
      src/views/_builtin/login/index.vue
  55. 11 14
      src/views/_builtin/login/modules/pwd-login.vue
  56. 386 0
      src/views/goods-center/type-admin/index.vue
  57. 297 0
      src/views/government/government-list/index.vue
  58. 353 0
      src/views/government/points/index.vue
  59. 383 0
      src/views/government/user-list/index.vue
  60. 1 1
      src/views/manage/department/department.data.ts
  61. 4 13
      src/views/manage/department/index.vue
  62. 19 54
      src/views/manage/dict/dict.data.ts
  63. 19 23
      src/views/manage/dict/index.vue
  64. 50 55
      src/views/manage/menu/index.vue
  65. 0 467
      src/views/manage/menu/modules/menu-operate-modal.vue
  66. 17 17
      src/views/manage/menu/modules/shared.ts
  67. 224 130
      src/views/manage/role/index.vue
  68. 0 101
      src/views/manage/role/modules/button-auth-modal.vue
  69. 0 107
      src/views/manage/role/modules/menu-auth-modal.vue
  70. 0 150
      src/views/manage/role/modules/role-operate-drawer.vue
  71. 0 64
      src/views/manage/role/modules/role-search.vue
  72. 50 64
      src/views/manage/user/index.vue
  73. 11 1
      src/views/user-management/user-list/index.vue

+ 5 - 5
.env

@@ -2,9 +2,9 @@
 # if use a sub directory, it must be end with "/", like "/admin/" but not "/admin"
 VITE_BASE_URL=/
 
-VITE_APP_TITLE=中数星闪豹管理系统
+VITE_APP_TITLE=市民请集合管理系统
 
-VITE_APP_DESC=中数星闪豹管理系统 admin template
+VITE_APP_DESC=市民请集合管理系统 admin template
 
 # the prefix of the icon name
 VITE_ICON_PREFIX=icon
@@ -29,8 +29,8 @@ VITE_HTTP_PROXY=Y
 VITE_ROUTER_HISTORY_MODE=history
 
 # success code of backend service, when the code is received, the request is successful
-VITE_SERVICE_SUCCESS_CODE=200
-# VITE_SERVICE_SUCCESS_CODE=0000
+# VITE_SERVICE_SUCCESS_CODE=200
+VITE_SERVICE_SUCCESS_CODE=00000
 
 # logout codes of backend service, when the code is received, the user will be logged out and redirected to login page
 VITE_SERVICE_LOGOUT_CODES=8888,8889
@@ -60,7 +60,7 @@ VITE_PROXY_LOG=Y
 # by the way, this plugin is only available in dev mode, not in build mode
 VITE_DEVTOOLS_LAUNCH_EDITOR=code
 
-VITE_OSS_BASE_URL =  https://zswl-shop.oss-cn-chengdu.aliyuncs.com/
+VITE_OSS_BASE_URL =  https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/
 
 #分页配置
 VITE_PAGE_SIZE=10,100,500,1000,1500

+ 3 - 8
.env.test

@@ -1,13 +1,8 @@
 # backend service base url, test environment
-# VITE_SERVICE_BASE_URL=http://74949mkfh190.vicp.fun
-# VITE_SERVICE_BASE_URL=http://192.168.1.253:8114 #付
-# VITE_SERVICE_BASE_URL=http://192.168.0.157:8114 #王
-# VITE_SERVICE_BASE_URL=http://192.168.1.166:8114 #张
-# VITE_SERVICE_BASE_URL=http://192.168.1.66:8114 #邓
+# 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=https://mock.apifox.cn/m1/3109515-0-default
-VITE_SERVICE_BASE_URL=https://shop.platform.zswlgz.com #服务器
-# VITE_SERVICE_BASE_URL=/plt #测试打包服务器
-# VITE_SERVICE_BASE_URL=http://47.109.84.152:8114 #测试本地服务器
 
 
 # other backend service base url, test environment

+ 0 - 2
build/config/proxy.ts

@@ -23,13 +23,11 @@ export function createViteProxy(env: Env.ImportMeta, enable: boolean) {
   other.forEach(item => {
     Object.assign(proxy, createProxyItem(item, isEnableProxyLog));
   });
-
   return proxy;
 }
 
 function createProxyItem(item: App.Service.ServiceConfigItem, enableLog: boolean) {
   const proxy: Record<string, ProxyOptions> = {};
-
   proxy[item.proxyPattern] = {
     target: item.baseURL,
     changeOrigin: true,

+ 1 - 1
packages/axios/src/constant.ts

@@ -2,4 +2,4 @@
 export const REQUEST_ID_KEY = 'X-Request-Id';
 
 /** the backend error code key */
-export const BACKEND_ERROR_CODE = 'ERR_BAD_RESPONSE';
+export const BACKEND_ERROR_CODE = 'ERR_BAD_REQUEST';

+ 2 - 2
packages/hooks/src/use-table.ts

@@ -4,7 +4,7 @@ import useBoolean from './use-boolean';
 import useLoading from './use-loading';
 
 export interface PaginationData<T> {
-  records: T[];
+  list: T[];
   pages: number;
   size: number;
   total: number;
@@ -125,7 +125,7 @@ function getTableData<ApiData, Pagination extends boolean>(
   pagination?: Pagination
 ) {
   if (pagination) {
-    return (data as PaginationData<ApiData>).records;
+    return (data as PaginationData<ApiData>).list;
   }
 
   return data as ApiData[];

BIN
public/favicon.png


BIN
src/assets/imgs/logo.png


BIN
src/assets/svg-icon/logo.png


+ 1 - 1
src/components/common/system-logo.vue

@@ -8,7 +8,7 @@ const props = defineProps<{
 
 <template>
   <!-- <icon-local-logo /> -->
-  <img src="@/assets/svg-icon/logo.png" alt="" :style="{ width: props.width + 'px', height: props.height + 'px' }" />
+  <img src="@/assets/imgs/logo.png" alt="" :style="{ width: props.width + 'px', height: props.height + 'px' }" />
 </template>
 
 <style scoped></style>

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

@@ -47,16 +47,16 @@ export default defineComponent({
     const [registerSearchForm, { getFieldsValue: getSeachForm, setFormProps: setSearchProps, setFieldsValue }] =
       useForm(getFormSearch.value);
     const searchPage = reactive({
-      current: 1,
-      size: 10
+      pageNum: 1,
+      pageSize: 10
     });
     const getForm = ref();
     const { columns, columnChecks, data, getData, loading, mobilePagination, getDataByPage } = useNaivePaginatedTable({
       api: () => propsData.api({ ...searchPage, ...getForm.value, ...propsData.defaultParams }),
       transform: response => defaultTransform(response),
       onPaginationParamsChange: params => {
-        searchPage.current = Number(params.page);
-        searchPage.size = Number(params.pageSize);
+        searchPage.pageNum = Number(params.page);
+        searchPage.pageSize = Number(params.pageSize);
       },
       immediate: propsData.immediate,
       paginationProps: {

+ 4 - 11
src/components/zt/dict-tag/index.vue

@@ -30,8 +30,8 @@ const { transformDictData } = useDict(props.dictCode, props.immediate);
 const dictTagData = computed<Api.System.DictData[]>(() => {
   if (props.dictData) {
     const dictData = jsonClone(props.dictData);
-    if (dictData.dictLabel?.startsWith(`dict.${dictData.dictType}.`)) {
-      dictData.dictLabel = $t(dictData.dictLabel as App.I18n.I18nKey);
+    if (dictData.name?.startsWith(`dict.${dictData.value}.`)) {
+      dictData.name = $t(dictData.name as App.I18n.I18nKey);
     }
     return [dictData];
   }
@@ -46,15 +46,8 @@ const dictTagData = computed<Api.System.DictData[]>(() => {
 
 <template>
   <div v-if="dictTagData.length">
-    <NTag
-      v-for="item in dictTagData"
-      :key="item.dictValue"
-      class="m-1"
-      :class="[item.cssClass]"
-      v-bind="attrs"
-      :type="item.listClass || 'default'"
-    >
-      {{ item.dictLabel }}
+    <NTag v-for="item in dictTagData" :key="item.value" class="m-1" v-bind="attrs" type="default">
+      {{ item.name }}
     </NTag>
   </div>
 </template>

+ 1 - 1
src/components/zt/upload/z-upload.vue

@@ -49,7 +49,7 @@ async function customRequest({ file, onFinish, onError, onProgress }: UploadCust
   };
   const { error, response, data: res } = await fetchUpload(file.file as File, config);
   if (!error) {
-    file.url = viewUrl + res;
+    file.url = viewUrl + res.name;
     window.$message?.success(response.data.msg || '上传成功');
     onFinish();
   } else {

+ 8 - 3
src/constants/business.ts

@@ -14,10 +14,15 @@ export const userGenderRecord: Record<Api.SystemManage.UserGender, App.I18n.I18n
 
 export const userGenderOptions = transformRecordToOption(userGenderRecord);
 
+// export const menuTypeRecord: Record<Api.SystemManage.MenuType, App.I18n.I18nKey> = {
+//   '0': 'page.manage.menu.type.directory',
+//   '1': 'page.manage.menu.type.menu',
+//   '2': 'page.manage.menu.type.button'
+// };
 export const menuTypeRecord: Record<Api.SystemManage.MenuType, App.I18n.I18nKey> = {
-  '0': 'page.manage.menu.type.directory',
-  '1': 'page.manage.menu.type.menu',
-  '2': 'page.manage.menu.type.button'
+  CATALOG: 'page.manage.menu.type.directory',
+  MENU: 'page.manage.menu.type.menu',
+  BUTTON: 'page.manage.menu.type.button'
 };
 
 export const menuTypeOptions = transformRecordToOption(menuTypeRecord);

+ 7 - 7
src/hooks/business/dict.ts

@@ -1,6 +1,6 @@
 import { ref, watch } from 'vue';
 import { storeToRefs } from 'pinia';
-import { fetchGetDictDataByType } from '@/service/api/config/dict';
+import { fetchGetDictDataByType } from '@/service/api/system-manage';
 import { useDictStore } from '@/store/modules/dict';
 import { isNull } from '@/utils/common';
 import { $t } from '@/locales';
@@ -22,8 +22,8 @@ export function useDict(dictType: string, immediate: boolean = true) {
     const { data: dictData, error } = await fetchGetDictDataByType(dictType);
     if (error) return;
     dictData.forEach(dict => {
-      if (dict.dictLabel?.startsWith(`dict.${dictType}.`)) {
-        dict.dictLabel = $t(dict.dictLabel as App.I18n.I18nKey);
+      if (dict.name?.startsWith(`dict.${dictType}.`)) {
+        dict.name = $t(dict.name as App.I18n.I18nKey);
       }
     });
     dictStore.setDict(dictType, dictData);
@@ -35,7 +35,7 @@ export function useDict(dictType: string, immediate: boolean = true) {
       await getData();
     }
     data.value.forEach(dict => {
-      record.value[dict.dictValue!] = dict.dictLabel!;
+      record.value[dict.value!] = dict.name!;
     });
   }
 
@@ -44,15 +44,15 @@ export function useDict(dictType: string, immediate: boolean = true) {
       await getData();
     }
 
-    options.value = data.value.map(dict => ({ label: dict.dictLabel!, value: dict.dictValue! }));
+    options.value = data.value.map(dict => ({ label: dict.name!, value: dict.value! }));
   }
 
   function transformDictData(dictValue: string[] | number[] | string | number) {
     if (!data.value.length || isNull(dictValue)) return undefined;
     if (Array.isArray(dictValue)) {
-      return data.value.filter(dict => dictValue.some(value => dict.dictValue === value.toString()));
+      return data.value.filter(dict => dictValue.some(value => dict.value === value.toString()));
     }
-    return data.value.filter(dict => dict.dictValue === dictValue.toString());
+    return data.value.filter(dict => dict.value === dictValue.toString());
   }
 
   if (immediate) {

+ 2 - 2
src/hooks/common/form.ts

@@ -29,7 +29,7 @@ export function useFormRules() {
       message: $t('form.email.invalid'),
       trigger: 'change'
     },
-    imageCode: {
+    captchaCode: {
       message: $t('form.code.invalid'),
       trigger: 'change'
     }
@@ -41,7 +41,7 @@ export function useFormRules() {
     pwd: [createRequiredRule($t('form.pwd.required')), patternRules.pwd],
     code: [createRequiredRule($t('form.code.required')), patternRules.code],
     email: [createRequiredRule($t('form.email.required')), patternRules.email],
-    imageCode: [createRequiredRule('请输入验证码'), patternRules.imageCode]
+    captchaCode: [createRequiredRule('请输入验证码'), patternRules.captchaCode]
   } satisfies Record<string, App.Global.FormRule[]>;
 
   /** the default required rule */

+ 3 - 4
src/hooks/common/table.ts

@@ -233,13 +233,12 @@ export function defaultTransform<ApiData>(
   response: FlatResponseData<any, Api.Common.PaginatingQueryRecord<ApiData>>
 ): PaginationData<ApiData> {
   const { data, error } = response;
-  // console.log(response, 'asdasdsa');
 
   if (!error) {
-    const { records, current, size, total } = data;
+    const { list, current, size, total } = data;
 
     return {
-      records,
+      list,
       pages: current,
       size,
       total
@@ -247,7 +246,7 @@ export function defaultTransform<ApiData>(
   }
 
   return {
-    records: [],
+    list: [],
     pages: 1,
     size: 10,
     total: 0

+ 8 - 2
src/locales/langs/en-us.ts

@@ -1,6 +1,6 @@
 const local: App.I18n.Schema = {
   system: {
-    title: 'zswlxshapex admin',
+    title: 'city-gather admin',
     updateTitle: 'System Version Update Notification',
     updateContent: 'A new version of the system has been detected. Do you want to refresh the page immediately?',
     updateConfirm: 'Refresh immediately',
@@ -251,7 +251,13 @@ const local: App.I18n.Schema = {
     manage_log: '',
     manage_schedule: '',
     'user-management': '',
-    'user-management_user-list': ''
+    'user-management_user-list': '',
+    'goods-center': '',
+    'goods-center_type-admin': '',
+    government: '',
+    'government_government-list': '',
+    government_points: '',
+    'government_user-list': ''
   },
   page: {
     login: {

+ 8 - 2
src/locales/langs/zh-cn.ts

@@ -1,6 +1,6 @@
 const local: App.I18n.Schema = {
   system: {
-    title: '中数星闪豹 管理系统',
+    title: '市民请集合 管理系统',
     updateTitle: '系统版本更新通知',
     updateContent: '检测到系统有新版本发布,是否立即刷新页面?',
     updateConfirm: '立即刷新',
@@ -248,7 +248,13 @@ const local: App.I18n.Schema = {
     manage_log: '',
     manage_schedule: '',
     'user-management': '',
-    'user-management_user-list': ''
+    'user-management_user-list': '',
+    'goods-center': '',
+    'goods-center_type-admin': '',
+    government: '',
+    'government_government-list': '',
+    government_points: '',
+    'government_user-list': ''
   },
   page: {
     login: {

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

@@ -20,6 +20,10 @@ 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_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"),
+  "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"),

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

@@ -39,6 +39,64 @@ export const generatedRoutes: GeneratedRoute[] = [
       hideInMenu: true
     }
   },
+  {
+    name: 'goods-center',
+    path: '/goods-center',
+    component: 'layout.base',
+    meta: {
+      title: 'goods-center',
+      i18nKey: 'route.goods-center'
+    },
+    children: [
+      {
+        name: 'goods-center_type-admin',
+        path: '/goods-center/type-admin',
+        component: 'view.goods-center_type-admin',
+        meta: {
+          title: 'goods-center_type-admin',
+          i18nKey: 'route.goods-center_type-admin'
+        }
+      }
+    ]
+  },
+  {
+    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',

+ 6 - 0
src/router/elegant/transform.ts

@@ -181,6 +181,12 @@ const routeMap: RouteMap = {
   "403": "/403",
   "404": "/404",
   "500": "/500",
+  "goods-center": "/goods-center",
+  "goods-center_type-admin": "/goods-center/type-admin",
+  "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)?",

+ 18 - 9
src/service/api/auth.ts

@@ -19,24 +19,33 @@ import { request } from '../request';
 // }
 
 /**
- * Login
+ *captchaCode:验证码
+ * captchaKey:验证码key
  *
- * @param principal User name
- * @param credentials Password
- * @param imageCode 验证码
+ * Login
+ * @param data
+ * @returns
  */
-export function fetchLogin(data: { principal: string; credentials: string; imageCode: string; sessionUUID: string }) {
+export function fetchLogin(data: { username: string; password: string; captchaCode: string; captchaKey: string }) {
+  const formData = new FormData();
+  formData.append('username', data.username);
+  formData.append('password', data.password);
+  formData.append('captchaId', data.captchaKey as string);
+  formData.append('captchaCode', data.captchaCode as string);
+  formData.append('grant_type', 'password');
   return request<Api.Auth.LoginToken>({
-    url: '/platformLogin',
-    // url: '/auth/login',
+    url: '/smqjh-auth/oauth2/token',
     method: 'post',
-    data
+    data: formData,
+    headers: {
+      'Content-Type': 'multipart/form-data'
+    }
   });
 }
 
 /** Get user info */
 export function fetchGetUserInfo() {
-  return request<Api.Auth.UserInfo>({ url: '/sys/user/info' });
+  return request<Api.Auth.UserInfo>({ url: '/smqjh-system/api/v1/users/me' });
   // return request<Api.Auth.UserInfo>({ url: '/auth/getUserInfo' });
 }
 

+ 11 - 29
src/service/api/common.ts

@@ -6,12 +6,12 @@ import { request } from '@/service/request';
  * @returns
  */
 export function fetchUpload(data: File, config?: any) {
+  const formData = new FormData();
+  formData.append('file', data);
   return request({
-    url: '/admin/file/upload/img',
+    url: '/smqjh-system/api/v1/files',
     method: 'post',
-    data: {
-      file: data
-    },
+    data: formData,
     headers: {
       'Content-Type': 'multipart/form-data'
     },
@@ -19,18 +19,6 @@ export function fetchUpload(data: File, config?: any) {
   });
 }
 
-/**
- * 企业ID查询运费模板
- * @param channelId
- * @returns
- */
-export function fetchGetTransport(channelId: number) {
-  return request<Api.delivery.Transport2>({
-    url: `/platform/transport2/queryTransport2ByChannelId/${channelId}`,
-    method: 'get'
-  });
-}
-
 /**
  *新增或更新运费模板
  * @param data
@@ -45,25 +33,19 @@ export function fetchGetAddOrEditTransport(data: any) {
 }
 
 /**
- * 后管端-企业运费列表
+ * 获取验证码
  * @returns
  */
-
-export function fetchChannelList(data: any) {
-  return request<{ records: Api.delivery.Transport2[] }>({
-    url: '/platform/transport2/transport2List',
-    method: 'get',
-    params: data
+export function fetchGetCaptcha() {
+  return request<{ captchaBase64: string; captchaId: string }>({
+    url: '/smqjh-auth/api/v1/auth/captcha',
+    method: 'get'
   });
 }
 
-/**
- * 获取当前登录用户的所属企业
- * @returns
- */
 export function fetchGetLoginUserList() {
-  return request<Api.goods.Channel[]>({
-    url: '/platform/channel/list',
+  return request({
+    url: '/smqjh-system/api/v1/channel/list/LoginUserEnterprise',
     method: 'get'
   });
 }

+ 0 - 93
src/service/api/config/dict/index.ts

@@ -1,93 +0,0 @@
-import { request } from '@/service/request';
-
-/** 根据字典类型查询字典数据信息 */
-export function fetchGetDictDataByType(dictType: string) {
-  return request<Api.System.DictData[]>({
-    url: `/system/dict/data/type/${dictType}`,
-    method: 'get'
-  });
-}
-
-/** 获取字典选择框列表 */
-export function fetchGetDictTypeOption() {
-  return request<Api.System.DictType[]>({
-    url: '/system/dict/type/optionselect',
-    method: 'get'
-  });
-}
-
-/** 获取字典类型列表 */
-export function fetchGetDictTypeList(params?: Api.System.DictTypeSearchParams) {
-  return request<Api.System.DictTypeList>({
-    url: '/system/dict/type/list',
-    method: 'get',
-    params
-  });
-}
-
-/** 新增字典类型 */
-export function fetchCreateDictType(data: Api.System.DictTypeOperateParams) {
-  return request<boolean>({
-    url: '/system/dict/type',
-    method: 'post',
-    data
-  });
-}
-
-/** 修改字典类型 */
-export function fetchUpdateDictType(data: Api.System.DictTypeOperateParams) {
-  return request<boolean>({
-    url: '/system/dict/type',
-    method: 'put',
-    data
-  });
-}
-
-/** 批量删除字典类型 */
-export function fetchBatchDeleteDictType(dictIds: CommonType.IdType[]) {
-  return request<boolean>({
-    url: `/system/dict/type/${dictIds.join(',')}`,
-    method: 'delete'
-  });
-}
-/** 刷新缓存 */
-export function fetchRefreshCache() {
-  return request<boolean>({
-    url: `/system/dict/type/refreshCache`,
-    method: 'delete'
-  });
-}
-/** 获取字典数据列表 */
-export function fetchGetDictDataList(params?: Api.System.DictDataSearchParams) {
-  return request<Api.System.DictDataList>({
-    url: '/system/dict/data/list',
-    method: 'get',
-    params
-  });
-}
-
-/** 新增字典数据 */
-export function fetchCreateDictData(data: Api.System.DictDataOperateParams) {
-  return request<boolean>({
-    url: '/system/dict/data',
-    method: 'post',
-    data
-  });
-}
-
-/** 修改字典数据 */
-export function fetchUpdateDictData(data: Api.System.DictDataOperateParams) {
-  return request<boolean>({
-    url: '/system/dict/data',
-    method: 'put',
-    data
-  });
-}
-
-/** 批量删除字典数据 */
-export function fetchBatchDeleteDictData(dictCodes: CommonType.IdType[]) {
-  return request<boolean>({
-    url: `/system/dict/data/${dictCodes.join(',')}`,
-    method: 'delete'
-  });
-}

+ 0 - 85
src/service/api/delivery/after-sales-order/index.ts

@@ -1,85 +0,0 @@
-import { request } from '@/service/request';
-
-/**
- * 售后快递订单
- * @param data
- * @returns
- */
-export function fetchGetAfterSalesOrderList(data: any) {
-  return request<Api.Common.PaginatingQueryRecord<Api.delivery.OrderRefund>>({
-    url: '/platform/orderRefund/orderRefundPage',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- * 导出售后快递订单
- * @param data
- */
-export function fetchExportAfterSalesOrderList(data: any) {
-  return request<any>({
-    url: '/platform/orderRefund/export',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- *  获取售后快递订单状态数量
- * @returns
- */
-export function fetchGetAfterSalesStatusNum(data: any) {
-  return request<Api.delivery.OrderRefundCountParam>({
-    url: '/platform/orderRefund/orderRefundCount',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- * 获取快递订单详情
- * @param orderNumber
- * @returns
- */
-export function fetchGetNomalOrderInfo(orderNumber: string) {
-  return request<Api.delivery.deliveryOrder>({
-    url: `/platform/order/orderInfo/${orderNumber}`,
-    method: 'get'
-  });
-}
-
-/**
- *
- * 快递公司列表
- *  */
-export function fetchGetDevList(data: any) {
-  return request<Api.delivery.devList>({
-    url: '/platform/delivery/list',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- * 发货
- */
-export function fetchDeliveryOrder(data: any) {
-  return request({
-    url: '/platform/order/delivery',
-    method: 'PUT',
-    data
-  });
-}
-
-/**
- * 查看退款订单详情
- * @param refundId
- * @returns
- */
-export function fetchGetAfterSalesOrderDetail(refundId: number) {
-  return request<Api.delivery.OrderRefund>({
-    url: `/platform/orderRefund/orderRefundInfo/${refundId}`,
-    method: 'get'
-  });
-}

+ 0 - 61
src/service/api/delivery/normal-orde/index.ts

@@ -1,61 +0,0 @@
-import { request } from '@/service/request';
-
-/**
- * 正常快递订单
- * @param data
- * @returns
- */
-export function fetchGetDeliveryOrderList(data: any) {
-  return request<Api.Common.PaginatingQueryRecord<Api.delivery.deliveryOrder>>({
-    url: '/platform/order/deliverList',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- *  获取快递订单状态数量
- * @returns
- */
-export function fetchGetDeliveryStatusNum(data: any) {
-  return request<Api.delivery.DeliveryStatusNum>({
-    url: '/platform/order/deliverListStatusNum',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- * 获取快递订单详情
- * @param orderNumber
- * @returns
- */
-export function fetchGetNomalOrderInfo(orderNumber: string) {
-  return request<Api.delivery.deliveryOrder>({
-    url: `/platform/order/orderInfo/${orderNumber}`,
-    method: 'get'
-  });
-}
-
-/**
- *
- * 快递公司列表
- *  */
-export function fetchGetDevList(data: any) {
-  return request<Api.delivery.devList>({
-    url: '/platform/delivery/list',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- * 发货
- */
-export function fetchDeliveryOrder(data: any) {
-  return request({
-    url: '/platform/order/delivery',
-    method: 'PUT',
-    data
-  });
-}

+ 0 - 14
src/service/api/finance/commodity-freight/index.ts

@@ -1,14 +0,0 @@
-import { request } from '@/service/request';
-
-/**
- * 运费明细表-列表
- * @param data
- * @returns
- */
-export function fetchGetfreightStatisticsList(data: any) {
-  return request<Api.finance.FreightStatisticsVo[]>({
-    url: '/platform/sku/freightStatisticsList',
-    method: 'get',
-    params: data
-  });
-}

+ 0 - 14
src/service/api/finance/summary/index.ts

@@ -1,14 +0,0 @@
-import { request } from '@/service/request';
-
-/**
- * 对账单汇总表(商品)-列表
- * @param data
- * @returns
- */
-export function fetchGetskuStatisticsList(data: any) {
-  return request<Api.finance.SkuStatisticsVo[]>({
-    url: '/platform/sku/skuStatisticsList',
-    method: 'get',
-    params: data
-  });
-}

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

@@ -0,0 +1,50 @@
+import { request } from '@/service/request';
+
+/**
+ * 三方应用下的所有分类列表
+ * @param code
+ * @returns
+ */
+export function fetchGetAllCategory(code: string) {
+  return request({
+    url: `/smqjh-pms/api/v1/front_category/${code}`,
+    method: 'get'
+  });
+}
+
+/**
+ * 三方应用下的列表
+ *
+ */
+export function fetchGetAllAppList() {
+  return request({
+    url: `/smqjh-pms/api/v1/other_type`,
+    method: 'get'
+  });
+}
+
+/**
+ * 商品分类所有列表
+ * @returns
+ */
+export function fetchGetCategoryList(data: any) {
+  return request({
+    url: `/smqjh-pms/api/v1/categories/getCategoryList`,
+    method: 'post',
+    data
+  });
+}
+/**
+ *
+    新增分类一级
+ * @param data
+ * @returns
+ */
+
+export function fetchAddCategoryOne(data: any) {
+  return request({
+    url: `/smqjh-pms/api/v1/categories/addTopCategory`,
+    method: 'post',
+    data
+  });
+}

+ 0 - 129
src/service/api/goods/desk-category/index.ts

@@ -1,129 +0,0 @@
-import { request } from '@/service/request';
-
-export function fetchGetDeskCategoryList(data: any) {
-  return request<Api.goods.ShopCategory[]>({
-    url: '/platform/shopCategory/list',
-    method: 'get',
-    params: data
-  });
-}
-
-export function fetchGategoryImport(data: File) {
-  return request({
-    url: '/platform/shopCategory/import',
-    method: 'post',
-    data: {
-      file: data
-    },
-    headers: {
-      'Content-Type': 'multipart/form-data'
-    }
-  });
-}
-
-/**
- * 获取所有门店列表
- * @returns
- */
-export function fetchGetAllStoreList() {
-  return request({
-    url: '/hb/store/list',
-    method: 'get'
-  });
-}
-
-/**
- * 修改前台类目
- * @param data
- * @returns
- */
-export function fetchUpdateCategory(data: any) {
-  return request({
-    url: '/platform/shopCategory',
-    method: 'PUT',
-    data
-  });
-}
-/**
- * 新增分类
- * @param data
- * @returns
- */
-export function fetchAddCategory(data: any) {
-  return request({
-    url: '/platform/shopCategory',
-    method: 'POST',
-    data
-  });
-}
-/**
- * 删除分类
- */
-export function fetchDeleteCategory(id: any) {
-  return request({
-    url: `/platform/shopCategory/${id}`,
-    method: 'DELETE'
-  });
-}
-
-/**
- * 查询门店前台类目导入记录
- * @returns
- */
-export function fetchGetFailLogList() {
-  return request<Api.goods.ShopCategoryLogVO[]>({
-    url: '/platform/shopCategoryLog/list',
-    method: 'get'
-  });
-}
-
-/**
- *
- * 查询已关联商品传三级分类code
- *
- * 分页通过code查询分类绑定商品
- * @param data
- * @returns
- */
-export function fetchGetCategoryProdList(data: any) {
-  return request<Api.goods.CategoryProd[]>({
-    url: '/platform/categoryProd/pageByCode',
-    method: 'get',
-    params: data
-  });
-}
-
-/**
- *
- * @param data 查询未关联商品传二级分类code
- * @returns
- */
-export function fetchGetCategoryProdHb(data: any) {
-  return request<Api.goods.CategoryProd[]>({
-    url: '/platform/categoryProdHb/pageByCode',
-    method: 'get',
-    params: data
-  });
-}
-
-/***
- * 绑定门店分类商品
- */
-export function fetchEditCategoryProd(data: any) {
-  return request({
-    url: '/platform/categoryProd/categoryProduct',
-    method: 'POST',
-    data
-  });
-}
-
-/**
- * 取消分类绑定商品
- */
-export function fetchCancelCategoryProd(data: any) {
-  return request({
-    url: '/platform/categoryProd/cancelCategoryProduct',
-    method: 'POST',
-    data
-  });
-}

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

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

+ 0 - 62
src/service/api/goods/tag/index.ts

@@ -1,62 +0,0 @@
-import { request } from '@/service/request';
-
-/**
- *
- * @returns 获取所有标签列表
- */
-export function fetchGetAllTagList() {
-  return request<Api.goods.tag[]>({
-    url: '/platform/label/listAll',
-    method: 'get'
-  });
-}
-
-/**
- * 分页获取标签列表
- * @param params
- * @returns
- */
-export function fetchGetTagList(params: any) {
-  return request<Api.goods.tag[]>({
-    url: '/platform/label/page',
-    method: 'get',
-    params
-  });
-}
-
-/**
- * 添加标签
- * @param data
- * @returns
- */
-export function fetchAddTag(data: any) {
-  return request({
-    url: '/platform/label',
-    method: 'post',
-    data
-  });
-}
-
-/**
- * 编辑标签
- */
-export function fetchEditTag(data: any) {
-  return request({
-    url: '/platform/label',
-    method: 'put',
-    data
-  });
-}
-
-/**
- * 删除标签
- * @param data
- * @returns
- */
-export function fetchDeleteTag(data: any) {
-  return request({
-    url: '/platform/label',
-    method: 'delete',
-    data
-  });
-}

+ 14 - 3
src/service/api/government/government-list/index.ts

@@ -6,7 +6,7 @@ import { request } from '@/service/request';
  */
 export function fetchGetChannelList(params: any) {
   return request<Api.government.ChannelVO[]>({
-    url: '/platform/channel/statisticsPage',
+    url: '/smqjh-system/api/v1/channel/statisticsPage',
     method: 'get',
     params
   });
@@ -19,7 +19,7 @@ export function fetchGetChannelList(params: any) {
  */
 export function fetchUpdateChannel(params: any) {
   return request({
-    url: '/platform/channel',
+    url: '/smqjh-system/api/v1/channel',
     method: 'put',
     data: params
   });
@@ -32,8 +32,19 @@ export function fetchUpdateChannel(params: any) {
  */
 export function fetchAddChannel(params: any) {
   return request({
-    url: '/platform/channel',
+    url: '/smqjh-system/api/v1/channel',
     method: 'POST',
     data: params
   });
 }
+
+/**
+ * 删除政企
+ * @returns
+ */
+export function fetchDelChannel(id: number) {
+  return request({
+    url: `/smqjh-system/api/v1/channel/${id}`,
+    method: 'delete'
+  });
+}

+ 0 - 52
src/service/api/operation/advertisement/index.ts

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

+ 0 - 52
src/service/api/operation/delivery-admin/index.ts

@@ -1,52 +0,0 @@
-import { request } from '@/service/request';
-
-/**
- * 分页获取物流公司
- * @param params
- * @returns
- */
-export function fetchGetDelivery(params: any) {
-  return request<Api.delivery.devList>({
-    url: '/platform/delivery/page',
-    method: 'get',
-    params
-  });
-}
-/**
- * 新增物流公司
- * @param params
- * @returns
- */
-
-export function fetchAddDelivery(params: any) {
-  return request({
-    url: '/platform/delivery',
-    method: 'post',
-    data: params
-  });
-}
-
-/**
- * 删除物流公司
-
-*/
-export function fetchDeleteDelivery(dvyId: number) {
-  return request({
-    url: `/platform/delivery/${dvyId}`,
-    method: 'delete'
-  });
-}
-
-/**
- * 修改物流公司
- * @param params
- * @returns
-
- */
-export function fetchUpdateDelivery(params: any) {
-  return request({
-    url: '/platform/delivery',
-    method: 'put',
-    data: params
-  });
-}

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

@@ -1,53 +0,0 @@
-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
-  });
-}

+ 1 - 1
src/service/api/route.ts

@@ -9,7 +9,7 @@ export function fetchGetConstantRoutes() {
 /** get user routes */
 export function fetchGetUserRoutes() {
   // return request<Api.Route.UserRoute>({ url: '/route/getUserRoutes' });
-  return request<Api.Route.UserRoute>({ url: 'sys/menu/nav' });
+  return request<Api.Route.MenuRoute[]>({ url: '/smqjh-system/api/v1/menus/routes' });
 }
 
 /**

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

@@ -1,14 +0,0 @@
-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
-  });
-}

+ 1 - 1
src/service/api/system-department.ts

@@ -4,7 +4,7 @@ import { request } from '../request';
  */
 export function fetchGetDepartmentList(data: Recordable) {
   return request<Api.SystemManage.DepartmentModel[]>({
-    url: '/admin/dept/list',
+    url: '/smqjh-system/api/v1/dept',
     method: 'GET',
     params: data
   });

+ 136 - 27
src/service/api/system-manage.ts

@@ -3,7 +3,7 @@ import { request } from '../request';
 /** get role list */
 export function fetchGetRoleList(params?: Api.SystemManage.RoleSearchParams) {
   return request<Api.SystemManage.RoleList>({
-    url: '/sys/role/page',
+    url: '/smqjh-system/api/v1/roles/page',
     method: 'get',
     params
   });
@@ -16,15 +16,15 @@ export function fetchGetRoleList(params?: Api.SystemManage.RoleSearchParams) {
  */
 export function fetchGetAllRoles() {
   return request<Api.SystemManage.AllRole[]>({
-    url: '/systemManage/getAllRoles',
+    url: '/smqjh-system/api/v1/roles/options',
     method: 'get'
   });
 }
 
 /** get user list */
-export function fetchGetUserList(params?: Api.SystemManage.UserSearchParams) {
-  return request<Api.SystemManage.UserList>({
-    url: '/sys/user/page',
+export function fetchGetUserList(params?: { keywords?: string; status?: number; deptId?: number }) {
+  return request<Api.SystemManage.userList[]>({
+    url: '/smqjh-system/api/v1/users/page',
     method: 'get',
     params
   });
@@ -32,9 +32,9 @@ export function fetchGetUserList(params?: Api.SystemManage.UserSearchParams) {
 
 /** get menu list */
 export function fetchGetMenuList() {
-  return request<Api.SystemManage.MenuList>({
+  return request<Api.SystemManage.Menu[]>({
     // url: '/systemManage/getMenuList/v2',
-    url: '/sys/menu/table',
+    url: '/smqjh-system/api/v1/menus',
     method: 'get'
   });
 }
@@ -50,7 +50,7 @@ export function fetchGetAllPages() {
 /** get menu tree */
 export function fetchGetMenuTree() {
   return request<Api.SystemManage.MenuTree[]>({
-    url: '/systemManage/getMenuTree',
+    url: '/smqjh-system/api/v1/menus/options',
     method: 'get'
   });
 }
@@ -62,7 +62,7 @@ export function fetchGetMenuTree() {
  */
 export function fetchAddMenu(data: Api.SystemManage.AddMenu) {
   return request({
-    url: '/sys/menu',
+    url: '/smqjh-system/api/v1/menus',
     method: 'post',
     data
   });
@@ -74,7 +74,7 @@ export function fetchAddMenu(data: Api.SystemManage.AddMenu) {
  */
 export function fetchEditMenu(data: Api.SystemManage.AddMenu) {
   return request({
-    url: '/sys/menu',
+    url: `/smqjh-system/api/v1/menus/${data.id}`,
     method: 'put',
     data
   });
@@ -87,7 +87,7 @@ export function fetchEditMenu(data: Api.SystemManage.AddMenu) {
  */
 export function fetchDelMenu(id: number) {
   return request({
-    url: `/sys/menu/${id}`,
+    url: `/smqjh-system/api/v1/menus/${id}`,
     method: 'delete'
   });
 }
@@ -108,9 +108,9 @@ export function fetchGetRoleMenuList(roleId: number) {
  * @param data
  * @returns
  */
-export function fetchAddRoleMenu(data: Api.SystemManage.RoleMenuList) {
+export function fetchAddRoleMenu(data: any) {
   return request({
-    url: '/sys/role',
+    url: '/smqjh-system/api/v1/roles',
     method: 'post',
     data
   });
@@ -120,24 +120,46 @@ export function fetchAddRoleMenu(data: Api.SystemManage.RoleMenuList) {
  * @param data
  * @returns
  */
-export function fetchEditRoleMenu(data: Api.SystemManage.RoleMenuList) {
+export function fetchEditRoleMenu(data: any) {
   return request({
-    url: '/sys/role',
+    url: `/smqjh-system/api/v1/roles/${data.id}`,
     method: 'put',
     data
   });
 }
+/**
+ * 分配菜单权限给角色
+ *
+ * @param queryParams
+ */
+export function fetchUpdateRoleMenus(roleId: number, data: number[]) {
+  return request({
+    url: `/smqjh-system/api/v1/roles/${roleId}/menus`,
+    method: 'put',
+    data
+  });
+}
+/**
+ * 获取角色详情
+ *
+ * @param id
+ */
+export function fetchGetRoleForm(id: number) {
+  return request({
+    url: `/smqjh-system/api/v1/roles/${id}/form`,
+    method: 'get'
+  });
+}
 /**
  * 删除角色
  * @param roleId
  * @returns
  */
 
-export function fetchDelRoleMenu(roleId: number) {
+export function fetchDelRoleMenu(roleId: string) {
   return request({
-    url: `/sys/role`,
-    method: 'delete',
-    data: [roleId]
+    url: `/smqjh-system/api/v1/roles/${roleId}`,
+    method: 'delete'
   });
 }
 
@@ -147,7 +169,7 @@ export function fetchDelRoleMenu(roleId: number) {
  */
 export function fetchGetRoleAllList() {
   return request<Api.SystemManage.RoleList>({
-    url: '/sys/role/list',
+    url: '/smqjh-system/api/v1/roles/options',
     method: 'get'
   });
 }
@@ -159,11 +181,22 @@ export function fetchGetRoleAllList() {
  */
 export function fetchAddUser(data: Api.SystemManage.UserModel) {
   return request({
-    url: '/sys/user',
+    url: '/smqjh-system/api/v1/users',
     method: 'post',
     data
   });
 }
+/**
+ * 获取角色的菜单ID集合
+ *
+ * @param queryParams
+ */
+export function fetchGetRoleMenuIds(roleId: number) {
+  return request({
+    url: `/smqjh-system/api/v1/roles/${roleId}/menuIds`,
+    method: 'get'
+  });
+}
 
 /**
  * 修改用户
@@ -171,7 +204,7 @@ export function fetchAddUser(data: Api.SystemManage.UserModel) {
  * @returns
  */ export function fetchEditUser(data: Api.SystemManage.UserModel) {
   return request({
-    url: '/sys/user',
+    url: `/smqjh-system/api/v1/users/${data.id}`,
     method: 'put',
     data
   });
@@ -184,7 +217,7 @@ export function fetchAddUser(data: Api.SystemManage.UserModel) {
  */
 export function fetchDetaileUser(id: string) {
   return request<Api.SystemManage.UserModel>({
-    url: `/sys/user/info/${id}`,
+    url: `/smqjh-system/api/v1/users/${id}/form`,
     method: 'get'
   });
 }
@@ -194,10 +227,86 @@ export function fetchDetaileUser(id: string) {
  * @param id
  * @returns
  */
-export function fetchDeleteUser(id: number) {
+export function fetchDeleteUser(id: string) {
   return request({
-    url: `/sys/user`,
-    method: 'delete',
-    data: [id]
+    url: `/smqjh-system/api/v1/users/${id}`,
+    method: 'delete'
+  });
+}
+
+/** 根据字典类型查询字典数据信息 */
+export function fetchGetDictDataByType(dictType: string) {
+  return request<Api.System.DictData[]>({
+    url: `/smqjh-system/api/v1/dict/types/${dictType}/list`,
+    method: 'get'
+  });
+}
+
+/** 获取字典选择框列表 */
+export function fetchGetDictTypeOption() {
+  return request<Api.System.DictType[]>({
+    url: '/smqjh-system/api/v1/dict/types/getDictTypeList',
+    method: 'get'
+  });
+}
+
+/** 新增字典类型 */
+export function fetchCreateDictType(data: any) {
+  return request<boolean>({
+    url: '/smqjh-system/api/v1/dict/types',
+    method: 'post',
+    data
+  });
+}
+
+/** 修改字典类型 */
+export function fetchUpdateDictType(data: any) {
+  return request<boolean>({
+    url: `/smqjh-system/api/v1/dict/types/${data.id}`,
+    method: 'put',
+    data
+  });
+}
+
+/** 批量删除字典类型 */
+export function fetchBatchDeleteDictType(dictIds: number) {
+  return request<boolean>({
+    url: `/smqjh-system/api/v1/dict/types/${dictIds}`,
+    method: 'delete'
+  });
+}
+
+/** 获取字典数据列表 */
+export function fetchGetDictDataList(params?: any) {
+  return request<Api.System.DictDataList>({
+    url: `/smqjh-system/api/v1/dict/page`,
+    method: 'get',
+    params
+  });
+}
+
+/** 新增字典数据 */
+export function fetchCreateDictData(data: any) {
+  return request<boolean>({
+    url: '/smqjh-system/api/v1/dict',
+    method: 'post',
+    data
+  });
+}
+
+/** 修改字典数据 */
+export function fetchUpdateDictData(data: any) {
+  return request<boolean>({
+    url: `/smqjh-system/api/v1/dict/${data.id}`,
+    method: 'put',
+    data
+  });
+}
+
+/** 批量删除字典数据 */
+export function fetchBatchDeleteDictData(dictCodes: CommonType.IdType[]) {
+  return request<boolean>({
+    url: `/smqjh-system/api/v1/dict/${dictCodes.join(',')}`,
+    method: 'delete'
   });
 }

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

@@ -1,14 +0,0 @@
-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
-  });
-}

+ 1 - 8
src/service/request/index.ts

@@ -29,19 +29,12 @@ export const request = createFlatRequest(
     async onRequest(config) {
       const Authorization = getAuthorization();
       Object.assign(config.headers, { Authorization });
-
       return config;
     },
     isBackendSuccess(response) {
       // when the backend response code is "0000"(default), it means the request is success
       // to change this logic by yourself, you can modify the `VITE_SERVICE_SUCCESS_CODE` in `.env` file
-      // return String(response.data.code) === import.meta.env.VITE_SERVICE_SUCCESS_CODE;
-
-      const isLogin = response.config?.url?.includes('platformLogin');
-
-      const isSuccess =
-        (isLogin ? String(response.status) : String(response.data.code)) === import.meta.env.VITE_SERVICE_SUCCESS_CODE;
-      return isSuccess;
+      return String(response.data.code) === import.meta.env.VITE_SERVICE_SUCCESS_CODE;
     },
     async onBackendFail(response, instance) {
       const authStore = useAuthStore();

+ 3 - 3
src/service/request/shared.ts

@@ -5,7 +5,7 @@ import type { RequestInstanceState } from './type';
 
 export function getAuthorization() {
   const token = localStg.get('token');
-  const Authorization = token ? `bearer${token}` : null;
+  const Authorization = token ? `Bearer ${token}` : 'Basic bWFsbC1hZG1pbjoxMjM0NTY='; // 客户端信息Base64明文:mall-admin:123456
 
   return Authorization;
 }
@@ -17,8 +17,8 @@ async function handleRefreshToken() {
   const rToken = localStg.get('refreshToken') || '';
   const { error, data } = await fetchRefreshToken(rToken);
   if (!error) {
-    localStg.set('token', data.token);
-    localStg.set('refreshToken', data.refreshToken);
+    localStg.set('token', data.access_token);
+    localStg.set('refreshToken', data.refresh_token);
     return true;
   }
 

+ 19 - 15
src/store/modules/auth/index.ts

@@ -27,7 +27,9 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
     roles: [],
     buttons: [],
     email: '',
-    mobile: ''
+    mobile: '',
+    perms: [],
+    nickname: ''
   });
 
   /** is super role in static route */
@@ -99,22 +101,24 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
    * @param [redirect=true] Whether to redirect after login. Default is `true`
    */
   async function login(
-    model: { userName: string; password: string; imageCode: string; sessionUUID: string },
+    model: { userName: string; password: string; captchaCode: string; captchaKey: string },
     redirect = true
   ) {
-    const { userName, password, imageCode, sessionUUID } = model;
+    const { userName, password, captchaCode, captchaKey } = model;
+    console.log(model, 'model');
+
     startLoading();
-    const { error, response } = await fetchLogin({
-      principal: userName,
-      credentials: password,
-      imageCode,
-      sessionUUID
+    const { error, data } = await fetchLogin({
+      username: userName,
+      password,
+      captchaCode,
+      captchaKey
     });
-    // console.log('login', error, response);
+    console.log('login', data);
 
     const loginToken: Api.Auth.LoginToken = {
-      token: response.data.access_token,
-      refreshToken: response.data.refreshToken
+      access_token: String(data?.access_token),
+      refresh_token: String(data?.refresh_token)
     };
     if (!error) {
       const pass = await loginByToken(loginToken);
@@ -132,7 +136,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
 
         window.$notification?.success({
           title: $t('page.login.common.loginSuccess'),
-          content: $t('page.login.common.welcomeBack', { username: userInfo.username }),
+          content: $t('page.login.common.welcomeBack', { username: userInfo.nickname }),
           duration: 4500
         });
       }
@@ -145,14 +149,14 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
 
   async function loginByToken(loginToken: Api.Auth.LoginToken) {
     // 1. stored in the localStorage, the later requests need it in headers
-    localStg.set('token', loginToken.token);
-    localStg.set('refreshToken', loginToken.refreshToken);
+    localStg.set('token', loginToken.access_token);
+    localStg.set('refreshToken', loginToken.refresh_token);
 
     // 2. get user info
     const pass = await getUserInfo();
 
     if (pass) {
-      token.value = loginToken.token;
+      token.value = loginToken.access_token;
 
       return true;
     }

+ 1 - 3
src/store/modules/dict/index.ts

@@ -9,9 +9,7 @@ export const useDictStore = defineStore(SetupStoreId.Dict, () => {
   const getDict = (key: string) => {
     return dictData.value[key]?.map(item => ({
       ...item,
-      dictLabel: item.dictLabel?.startsWith(`dict.${item.dictType}.`)
-        ? $t(item.dictLabel as App.I18n.I18nKey)
-        : item.dictLabel
+      dictLabel: item.name?.startsWith(`dict.${item.name}.`) ? $t(item.name as App.I18n.I18nKey) : item.name
     }));
   };
 

+ 3 - 4
src/store/modules/route/index.ts

@@ -5,7 +5,7 @@ import { useBoolean } from '@sa/hooks';
 import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
 import { router } from '@/router';
 import { fetchGetUserRoutes, fetchIsRouteExist } from '@/service/api';
-import { convertMenuData } from '@/utils/zt';
+import { convertToCustomRoutes } from '@/utils/zt';
 import { SetupStoreId } from '@/enum';
 import { createStaticRoutes, getAuthVueRoutes } from '@/router/routes';
 import { ROOT_ROUTE } from '@/router/routes/builtin';
@@ -213,6 +213,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
   /** Init dynamic auth route */
   async function initDynamicAuthRoute() {
     const { data, error } = await fetchGetUserRoutes();
+
     console.log(
       [
         '                   _ooOoo_',
@@ -239,9 +240,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
     );
 
     if (!error) {
-      const menu = convertMenuData({ menuList: data?.menuList });
-      const authBtn = data.authorities.map((it: any) => it.perms);
-      authStore.userInfo.buttons = authBtn;
+      const menu = convertToCustomRoutes(data);
       addAuthRoutes(menu);
 
       handleConstantAndAuthRoutes();

+ 1 - 1
src/theme/settings.ts

@@ -4,7 +4,7 @@ export const themeSettings: App.Theme.ThemeSetting = {
   grayscale: false,
   colourWeakness: false,
   recommendColor: false,
-  themeColor: '#f97316',
+  themeColor: '#9ED605',
   otherColor: {
     info: '#f97316',
     success: '#52c41a',

+ 182 - 1765
src/typings/api.d.ts

@@ -17,7 +17,7 @@ declare namespace Api {
 
     /** common params of paginating query list data */
     interface PaginatingQueryRecord<T = any> extends PaginatingCommonParams {
-      records: T[];
+      list: T[];
     }
 
     /** common search params of table */
@@ -59,8 +59,8 @@ declare namespace Api {
    */
   namespace Auth {
     interface LoginToken {
-      token: string;
-      refreshToken: string;
+      access_token: string;
+      refresh_token: string;
     }
 
     interface UserInfo {
@@ -70,6 +70,7 @@ declare namespace Api {
       buttons: string[];
       email: string;
       mobile: string;
+      perms: string[];
     }
     interface UserPassWord {
       password: string;
@@ -98,1891 +99,307 @@ declare namespace Api {
   /**
    * 商品管理模块
    */
-
-  namespace goods {
-    interface CategoryProd {
-      /**
-       * 分类id
-       */
-      categoryId?: number;
-      code?: string;
-      /**
-       * 创建时间
-       */
-      createTime?: string;
-      id?: number;
-      /**
-       * 0 正常,1 删除
-       */
-      isDelete?: number;
-      /**
-       * 商品属性id即表tz_prod_prop中的prop_id
-       */
-      prodId?: number;
-      /**
-       * 商品名称
-       */
-      prodName?: string;
+  /**
+   * 政企管理模块
+   */
+  namespace government {
+    /**
+     * 积分充值实体类
+     *
+     * PointsRecharge
+     */
+    interface PointsRecharge {
       /**
-       * 门店
+       * 渠道(企业ID)
        */
-      shopId?: number;
+      channelId?: number;
       /**
-       * 商品上架状态(0:商家下架、1:上架、2:违规下架、3:平台审核)
+       * 渠道(企业)名称
        */
-      status: number;
-      [property: string]: any;
-    }
-    interface ShopCategoryLogVO {
+      channelName?: string;
       /**
-       * 操作人
+       * 创建者
        */
       createBy?: string;
-      /**
-       * 操作人名称
-       */
-      createByName?: string;
-      /**
-       * 操作人角色
-       */
-      createByRole?: string;
       /**
        * 创建时间
        */
       createTime?: string;
       /**
-       * 失败状态数量
-       */
-      failureStatus?: number;
-      /**
-       * 成功状态数量
-       */
-      successStatus?: number;
-      /**
-       * 任务编号
-       */
-      taskCode: string;
-      /**
-       * 任务名称
-       */
-      taskName?: string;
-      [property: string]: any;
-    }
-
-    interface ShopCategory {
-      children?: ShopCategory[];
-      /**
-       * 编码
-       */
-      code?: string;
-      /**
-       * 前台类目模板id(一级时有)
+       * 过期日期
        */
-      frontCategoryId?: number;
+      expiryDate?: string;
       /**
        * 主键
        */
       id?: number;
       /**
-       * 是否删除(0 正常 1 已被删除)
+       * 充值积分
        */
-      isDelete?: number;
+      points?: number;
       /**
-       * 是否叶子(1-是,2-不是)
+       * 充值单号
        */
-      isLeaves?: number;
+      rechargeNumber?: string;
       /**
-       * 类目等级
+       * 积分状态(1-未过期,2-过期)
        */
-      level?: number;
+      rechargeStatus?: number;
       /**
-       * 类目名称
+       * 备注
        */
-      name?: string;
+      remark?: string;
       /**
-       * 序号
+       * 充值类型
        */
-      num: number;
+      type?: number;
       /**
-       * 操作人
+       * 更新时间
        */
-      operateUser?: string;
+      updateTime?: string;
       /**
-       * 父级分类编码
+       * 用户ID
        */
-      parentCode?: string;
+      userId?: number;
       /**
-       * 父级分类名称
+       * 员工名称
        */
-      parentName?: string;
+      userName?: string;
       /**
-       * 门店ID
+       * 电话号码
        */
-      shopId?: number;
+      userPhone?: string;
       [property: string]: any;
     }
-    interface tag {
-      /**
-       * 创建日期
-       */
-      creationDate?: string;
+
+    /**
+     * 充值积分记录统计列表
+     *
+     * PointsRechargeVO
+     */
+    interface PointsRechargeVO {
       /**
-       * 主键
+       * 渠道(企业)名称
        */
-      id?: number;
+      channelName?: string;
       /**
-       * 是否删除(0-未删除,1-已删除)
+       * 操作时间
        */
-      isDelete?: number;
+      createTime?: string;
       /**
-       * 标签名称
+       * 总充值积分
        */
-      name?: string;
+      totalPoints?: number;
       /**
-       * 标签类型
+       * 总充值人数
        */
-      type?: number;
+      totalUserCount?: number;
       [property: string]: any;
     }
-    interface ChannelProd {
-      /**
-       * 渠道ID
-       */
-      channelId?: number;
-      /**
-       * 渠道对应商品售价
-       */
-      channelProdPrice?: number;
-      /**
-       * 出货价
-       */
-      deliveryPrice?: number;
-      /**
-       * 海博商品ID
-       */
-      hbSkuId?: string;
-      /**
-       * 主键
-       */
-      id?: number;
-      /**
-       * 删除状态(0-正常,1-删除)
-       */
-      isDelete?: number;
-      /**
-       * 进货价
-       */
-      purchasePrice?: number;
+    /**
+     * 积分任务执行失败记录列表
+     */
+    interface PointsFailureRecordVO {
       /**
-       * 记录时间
+       * 操作人
        */
-      recTime?: string;
+      createBy?: string;
       /**
-       * 门店ID
+       * 时间
        */
-      shopId?: number;
+      createTime?: string;
       /**
-       * 门店名称
+       * 失败状态数量
        */
-      shopName?: string;
+      failureStatus?: number;
       /**
-       * 单品ID
+       * 任务名称
        */
-      skuId?: number;
+      name?: string;
       /**
-       * 修改时间
+       * 成功状态数量
        */
-      updateTime?: string;
-      /**
-       * 渠道名称       */
-      channelName?: string;
+      successStatus?: number;
       [property: string]: any;
     }
-    interface Sku {
-      /**
-       * 实际库存
-       */
-      actualStocks?: number;
-      /**
-       * 单品编码(海博)
-       */
-      hbSkuId?: number;
+    /**
+     * 渠道统计
+     *
+     * ChannelVO
+     */
+    interface ChannelVO {
       /**
-       * 商品编码(海博)
+       * 渠道名称
        */
-      hbSpuId?: number;
+      channelName?: string;
       /**
-       * 0 正常 1 已被删除
+       * 企业编号
        */
-      isDelete?: number;
+      channelNo?: string;
       /**
-       * 商品条形码
+       * 创建日期
        */
-      modelId?: string;
+      createTime?: { [key: string]: any };
       /**
-       * 原价
+       * 正常员工数
        */
-      oriPrice?: number;
+      normalCount?: number;
       /**
-       * 商家编码
+       * 总员工数
        */
-      partyCode?: string;
+      staffCount?: number;
       /**
-       * sku图片
+       * 企业状态(1-正常,0-停用)
        */
-      pic: string;
+      status: Api.Common.commonStatus;
       /**
-       * 价格
+       * 渠道类型(1-企业用户,2-B端用户,3-C端用户)
        */
-      price?: number;
+      type?: number;
       /**
-       * 商品ID
+       * 渠道等级
        */
-      prodId?: number;
+      level?: number;
+      [property: string]: any;
+    }
+    /**
+     * 员工列表
+     */
+    interface userList {
       /**
-       * 商品名称
+       * 可用
        */
-      prodName?: string;
+      available: number;
       /**
-       * 销售属性组合字符串,格式是p1:v1;p2:v2
+       * 所属企业
        */
-      properties?: string;
+      channelName: string;
+
       /**
-       * 记录时间
+       * 已过期积分
        */
-      recTime?: string;
-      skuCode?: string;
+      expired: number;
       /**
-       * 单品ID
+       * 真实姓名
        */
-      skuId?: number;
+      realName: string;
       /**
-       * sku名称
+       * 状态  1正常 ,0 无效
        */
-      skuName?: string;
+      status: Common.commonStatus;
       /**
-       * 积分价格
+       * 积分
        */
-      skuScore?: number;
+      total: number;
       /**
-       * 状态:0禁用 1 启用
+       * 使用积分
        */
-      status?: number;
+      used: number;
       /**
-       * 库存
+       *  手机号
        */
-      stocks?: number;
+      userMobile: string;
       /**
-       * 修改时间
+       * 员工id
        */
-      updateTime?: string;
-      version?: number;
+      userId: number;
+    }
+    /**
+     * 员工导入记录
+     */
+    interface importRecordList {
+      batchNo: string;
+      channel: string;
+      completeTime: string;
+      createTime: string;
+      error: number;
+      id: number;
+      operator: string;
+      phone: string;
+      realName: string;
+      success: number;
+      taskName: string;
+      total: number;
+    }
+  }
+  namespace System {
+    /** 字典类型 */
+    type DictType = {
       /**
-       * 体积
+       * 字典类型ID
        */
-      volume?: number;
+      id: number;
       /**
-       * 重量
+       * 类型编码
        */
-      weight?: number;
-      weightUnit?: string;
-      [property: string]: any;
-    }
-    interface ShopSku {
+      code: string;
       /**
-       * 渠道商品
+       * 类型名称
        */
-      channelProdList?: ChannelProd[];
+      name: string;
       /**
-       * 门店商品表ID
+       * 状态(1:启用;0:禁用)
        */
-      id?: number;
+      status?: number;
       /**
-       * 0 正常 1 已被删除
+       * 备注
        */
-      isDelete?: number;
+      remark?: string;
+    };
+    type roleList = Common.CommonRecord<{
       /**
-       * 记录时间
+       * 角色编码
        */
-      recTime?: string;
+      code?: string;
       /**
-       * 门店ID
+       * 角色名称
        */
-      shopId?: number;
+      name?: string;
       /**
-       * 商品对应门店价格
+       * 排序
        */
-      shopSkuPrice?: number;
+      sort?: number;
+    }>;
+    type DictData = Common.CommonRecord<{
       /**
-       * 商品对应门店库存
+       * 字典名称
        */
-      shopSkuStocks?: number;
+      name?: string;
       /**
-       * 单品ID
+       * 字典值
        */
-      skuId?: number;
+      value?: string;
+    }>;
+    type DictDataList = {
       /**
-       * 商品详细
+       * 字典ID
        */
-      sku: Sku;
+      id?: number;
       /**
-       * 修改时间
+       * 字典名称
        */
-      updateTime?: string;
-      [property: string]: any;
-    }
-    interface Channel {
+      name?: string;
       /**
-       * 渠道名称
+       * 状态(1:启用;0:禁用)
        */
-      channelName?: string;
+      status?: number;
       /**
-       * 主键
+       * 字典值
        */
+      value?: string;
+    };
+  }
+  namespace goods {
+    interface ShopCategory {
+      children?: ShopCategory[];
+      iconUrl?: string;
       id?: number;
-      /**
-       * 渠道类型(1-企业用户,2-B端用户,3-C端用户)
-       */
-      type?: string;
+      level?: number;
+      name?: string;
+      parentId?: number;
+      sort?: number;
+      visible?: 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 government {
-    /**
-     * 积分充值实体类
-     *
-     * PointsRecharge
-     */
-    interface PointsRecharge {
-      /**
-       * 渠道(企业ID)
-       */
-      channelId?: number;
-      /**
-       * 渠道(企业)名称
-       */
-      channelName?: string;
-      /**
-       * 创建者
-       */
-      createBy?: string;
-      /**
-       * 创建时间
-       */
-      createTime?: string;
-      /**
-       * 过期日期
-       */
-      expiryDate?: string;
-      /**
-       * 主键
-       */
-      id?: number;
-      /**
-       * 充值积分
-       */
-      points?: number;
-      /**
-       * 充值单号
-       */
-      rechargeNumber?: string;
-      /**
-       * 积分状态(1-未过期,2-过期)
-       */
-      rechargeStatus?: number;
-      /**
-       * 备注
-       */
-      remark?: string;
-      /**
-       * 充值类型
-       */
-      type?: number;
-      /**
-       * 更新时间
-       */
-      updateTime?: string;
-      /**
-       * 用户ID
-       */
-      userId?: number;
-      /**
-       * 员工名称
-       */
-      userName?: string;
-      /**
-       * 电话号码
-       */
-      userPhone?: string;
-      [property: string]: any;
-    }
-
-    /**
-     * 充值积分记录统计列表
-     *
-     * PointsRechargeVO
-     */
-    interface PointsRechargeVO {
-      /**
-       * 渠道(企业)名称
-       */
-      channelName?: string;
-      /**
-       * 操作时间
-       */
-      createTime?: string;
-      /**
-       * 总充值积分
-       */
-      totalPoints?: number;
-      /**
-       * 总充值人数
-       */
-      totalUserCount?: number;
-      [property: string]: any;
-    }
-    /**
-     * 积分任务执行失败记录列表
-     */
-    interface PointsFailureRecordVO {
-      /**
-       * 操作人
-       */
-      createBy?: string;
-      /**
-       * 时间
-       */
-      createTime?: string;
-      /**
-       * 失败状态数量
-       */
-      failureStatus?: number;
-      /**
-       * 任务名称
-       */
-      name?: string;
-      /**
-       * 成功状态数量
-       */
-      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;
-    }
-    /**
-     * 员工列表
-     */
-    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 {
-      batchNo: string;
-      channel: string;
-      completeTime: string;
-      createTime: string;
-      error: number;
-      id: number;
-      operator: string;
-      phone: string;
-      realName: string;
-      success: number;
-      taskName: string;
-      total: number;
-    }
-  }
-  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;
-    }
-  }
-  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;
-    }
-  }
-  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[];
-      /**
-       * 订购流水号
-       */
-      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 finance {
-    interface SkuStatisticsVo {
-      /**
-       * 单价
-       */
-      price?: number;
-      /**
-       * 商品总数量
-       */
-      prodCount?: number;
-      /**
-       * skuId
-       */
-      skuId?: number;
-      /**
-       * skuName
-       */
-      skuName?: string;
-      /**
-       * 规格
-       */
-      spec?: string;
-      [property: string]: any;
-    }
-    interface FreightStatisticsVo {
-      /**
-       * 日期
-       */
-      date?: string;
-      /**
-       * 运输公司
-       */
-      delivery?: string;
-      /**
-       * 运单号
-       */
-      deliveryNo?: string;
-      /**
-       * 费用
-       */
-      money?: string;
-      /**
-       * 订/退单号
-       */
-      orderNo?: string;
-      /**
-       * 收方
-       */
-      receiver?: string;
-      /**
-       * 寄件地区
-       */
-      sendArea?: string;
-      /**
-       * 寄方
-       */
-      sendSize?: string;
-      /**
-       * 到件地址
-       */
-      toAddress?: string;
-      [property: string]: any;
-    }
-  }
-  namespace System {
-    /** 字典类型 */
-    type DictType = Common.CommonRecord<{
-      /** 字典主键 */
-      dictId: CommonType.IdType;
-      /** 字典名称 */
-      dictName: string;
-      /** 字典类型 */
-      dictType: string;
-      /** 备注 */
-      remark: string;
-    }>;
-
-    /** dict type search params */
-    type DictTypeSearchParams = CommonType.RecordNullable<
-      Pick<Api.System.DictType, 'dictName' | 'dictType'> & Api.Common.CommonSearchParams
-    >;
-
-    /** dict type operate params */
-    type DictTypeOperateParams = CommonType.RecordNullable<
-      Pick<Api.System.DictType, 'dictId' | 'dictName' | 'dictType' | 'remark'>
-    >;
-
-    /** dict type list */
-    type DictTypeList = Api.Common.PaginatingQueryRecord<DictType>;
-
-    /** 字典数据 */
-    type DictData = Common.CommonRecord<{
-      /** 样式属性(其他样式扩展) */
-      cssClass: string;
-      /** 字典编码 */
-      dictCode: CommonType.IdType;
-      /** 字典标签 */
-      dictLabel: string;
-      /** 字典排序 */
-      dictSort: number;
-      /** 字典类型 */
-      dictType: string;
-      /** 字典键值 */
-      dictValue: string;
-      /** 是否默认(Y是 N否) */
-      isDefault: Common.commonStatus;
-      /** 表格回显样式 */
-      listClass: NaiveUI.ThemeColor;
-      /** 备注 */
-      remark: string;
-    }>;
-
-    /** dict data search params */
-    type DictDataSearchParams = CommonType.RecordNullable<
-      Pick<Api.System.DictData, 'dictLabel' | 'dictType'> & Api.Common.CommonSearchParams
-    >;
-
-    /** dict data operate params */
-    type DictDataOperateParams = CommonType.RecordNullable<
-      Pick<
-        Api.System.DictData,
-        | 'dictCode'
-        | 'dictSort'
-        | 'dictLabel'
-        | 'dictValue'
-        | 'dictType'
-        | 'cssClass'
-        | 'listClass'
-        | 'isDefault'
-        | 'remark'
-      >
-    >;
-
-    /** dict data list */
-    type DictDataList = Api.Common.PaginatingQueryRecord<DictData>;
-  }
 }

+ 4 - 2
src/typings/api/auth.d.ts

@@ -6,8 +6,8 @@ declare namespace Api {
    */
   namespace Auth {
     interface LoginToken {
-      token: string;
-      refreshToken: string;
+      access_token: string;
+      refresh_token: string;
     }
 
     interface UserInfo {
@@ -15,6 +15,8 @@ declare namespace Api {
       username: string;
       roles: string[];
       buttons: string[];
+      perms: string[];
+      nickname: string;
     }
   }
 }

+ 180 - 43
src/typings/api/system-manage.d.ts

@@ -62,7 +62,7 @@ declare namespace Api {
       [property: string]: any;
     };
     type UserModel = {
-      userId?: number;
+      id?: number;
       username: string;
       password: string;
       email: string;
@@ -110,18 +110,50 @@ declare namespace Api {
 
     /** user */
     type User = Common.CommonRecord<{
-      /** user name */
-      userName: string;
-      /** user gender */
-      userGender: UserGender | null;
-      /** user nick name */
-      nickName: string;
-      /** user phone */
-      userPhone: string;
-      /** user email */
-      userEmail: string;
-      /** user role code collection */
-      userRoles: string[];
+      /**
+       * 用户头像地址
+       */
+      avatar?: string;
+      /**
+       * 创建时间
+       */
+      createTime?: Date;
+      /**
+       * 部门名称
+       */
+      deptName?: string;
+      /**
+       * 用户邮箱
+       */
+      email?: string;
+      /**
+       * 性别
+       */
+      genderLabel?: string;
+      /**
+       * 用户ID
+       */
+      id?: number;
+      /**
+       * 手机号
+       */
+      mobile?: string;
+      /**
+       * 用户昵称
+       */
+      nickname?: string;
+      /**
+       * 角色名称,多个使用英文逗号(,)分割
+       */
+      roleNames?: string;
+      /**
+       * 用户状态(1:启用;0:禁用)
+       */
+      status?: number;
+      /**
+       * 用户名
+       */
+      username?: string;
     }>;
 
     /** user search params */
@@ -132,6 +164,52 @@ declare namespace Api {
 
     /** user list */
     type UserList = Common.PaginatingQueryRecord<User>;
+    type userList = {
+      /**
+       * 用户头像地址
+       */
+      avatar?: string;
+      /**
+       * 创建时间
+       */
+      createTime?: Date;
+      /**
+       * 部门名称
+       */
+      deptName?: string;
+      /**
+       * 用户邮箱
+       */
+      email?: string;
+      /**
+       * 性别
+       */
+      genderLabel?: string;
+      /**
+       * 用户ID
+       */
+      id?: number;
+      /**
+       * 手机号
+       */
+      mobile?: string;
+      /**
+       * 用户昵称
+       */
+      nickname?: string;
+      /**
+       * 角色名称,多个使用英文逗号(,)分割
+       */
+      roleNames?: string;
+      /**
+       * 用户状态(1:启用;0:禁用)
+       */
+      status?: string;
+      /**
+       * 用户名
+       */
+      username?: string;
+    };
 
     /**
      * menu type
@@ -140,7 +218,8 @@ declare namespace Api {
      * - "2": menu
      */
     // type MenuType = '1' | '2';
-    type MenuType = '0' | '1' | '2';
+    // type MenuType = '0' | '1' | '2';
+    type MenuType = 'CATALOG' | 'MENU' | 'BUTTON';
 
     type MenuButton = {
       /**
@@ -176,24 +255,20 @@ declare namespace Api {
     >;
 
     type Menu = Common.CommonRecord<{
-      /** parent menu id */
-      parentId: number;
-      /** menu type */
-      menuType: MenuType;
-      /** menu name */
-      menuName: string;
-      /** route name */
-      routeName: string;
-      /** route path */
-      routePath: string;
-      /** component */
-      component?: string;
-      /** iconify icon name or local icon name */
+      component: string;
       icon: string;
-      /** icon type */
-      iconType: IconType;
-      /** buttons */
-      buttons?: MenuButton[] | null;
+      id: number;
+      name: string;
+      parentId: number;
+      path: string;
+      perm: string;
+      redirect: string;
+      sort: number;
+      type: string;
+      /**
+       * 是否显示菜单
+       */
+      visible: number;
       /** children menu */
       children?: Menu[] | null;
     }> &
@@ -203,22 +278,84 @@ declare namespace Api {
     type MenuList = Common.PaginatingQueryRecord<Menu>;
 
     type MenuTree = {
-      id: number;
+      value: number;
       label: string;
-      pId: number;
       children?: MenuTree[];
     };
+    enum MenuTypeEnum {
+      /**
+       * 目录
+       */
+      CATALOG = 'CATALOG',
+      /**
+       * 菜单
+       */
+      MENU = 'MENU',
+
+      /**
+       * 按钮
+       */
+      BUTTON = 'BUTTON',
+      /**
+       * 外链
+       */
+      EXTLINK = 'EXTLINK'
+    }
+
     type AddMenu = {
-      menuId: string;
-      type: number;
-      name: string;
-      parentId: string;
-      url: string;
-      perms: string;
-      orderNum: number;
-      icon: string;
-      component: string;
-      hideInMenu: number;
+      /**
+       * 菜单ID
+       */
+      id?: string;
+      /**
+       * 父菜单ID
+       */
+      parentId?: number;
+      /**
+       * 菜单名称
+       */
+      name?: string;
+      /**
+       * 菜单是否可见(1:是;0:否;)
+       */
+      visible: number;
+      icon?: string;
+      /**
+       * 排序
+       */
+      sort: number;
+      /**
+       * 组件路径
+       */
+      component?: string;
+      /**
+       * 路由路径
+       */
+      path?: string;
+      /**
+       * 跳转路由路径
+       */
+      redirect?: string;
+
+      /**
+       * 菜单类型
+       */
+      type: MenuTypeEnum;
+
+      /**
+       * 权限标识
+       */
+      perm?: string;
+
+      /**
+       * 【菜单】是否开启页面缓存
+       */
+      keepAlive?: number;
+
+      /**
+       * 【目录】只有一个子路由是否始终显示
+       */
+      alwaysShow?: number;
     };
   }
 }

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

@@ -35,6 +35,12 @@ declare module "@elegant-router/types" {
     "403": "/403";
     "404": "/404";
     "500": "/500";
+    "goods-center": "/goods-center";
+    "goods-center_type-admin": "/goods-center/type-admin";
+    "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)?";
@@ -99,6 +105,8 @@ declare module "@elegant-router/types" {
     | "403"
     | "404"
     | "500"
+    | "goods-center"
+    | "government"
     | "home"
     | "iframe-page"
     | "login"
@@ -128,6 +136,10 @@ declare module "@elegant-router/types" {
     | "500"
     | "iframe-page"
     | "login"
+    | "goods-center_type-admin"
+    | "government_government-list"
+    | "government_points"
+    | "government_user-list"
     | "home"
     | "manage_config"
     | "manage_department"

+ 1 - 2
src/utils/service.ts

@@ -36,7 +36,6 @@ export function createServiceConfig(env: Env.ImportMeta) {
     proxyPattern: createProxyPattern(),
     other: otherConfig
   };
-
   return config;
 }
 
@@ -67,7 +66,7 @@ export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) {
  */
 function createProxyPattern(key?: App.Service.OtherBaseURLKey) {
   if (!key) {
-    return '/proxy-default';
+    return '/dev-api';
   }
 
   return `/proxy-${key}`;

+ 32 - 155
src/utils/zt/index.ts

@@ -2,6 +2,7 @@ import { h, unref } from 'vue';
 import type { App, Component, Plugin } from 'vue';
 import { NIcon, NTag } from 'naive-ui';
 import { isObject } from './is/index';
+
 /**
  * render 图标
  * */
@@ -126,162 +127,7 @@ export function lighten(color: string, amount: number) {
 export function isUrl(url: string) {
   return /^(http|https):\/\//g.test(url);
 }
-/**
- * 获取uuid
- */
-export function getUUID() {
-  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
-    const r = Math.random() * 16;
-    const v = c === 'x' ? Math.floor(r) : Math.floor((r * 4) % 4) + 8;
-    return v.toString(16);
-  });
-}
-interface OriginalMenuItem {
-  menuId: number;
-  parentId: number;
-  parentName: string | null;
-  name: string;
-  url: string;
-  perms: string;
-  type: number;
-  icon: string | null;
-  orderNum: number;
-  list: OriginalMenuItem[] | null;
-  component: string;
-  hideInMenu: boolean;
-}
-
-interface OriginalMenuData {
-  menuList: OriginalMenuItem[];
-}
-
-interface ConvertedMenuItem {
-  name: string;
-  path: string;
-  component: string;
-  meta: {
-    title: string;
-    // i18nKey: string;
-    icon?: string;
-    order?: number;
-    hideInMenu?: boolean;
-  };
-  children?: ConvertedMenuItem[];
-}
-
-export function convertMenuData(originalData: OriginalMenuData): ConvertedMenuItem[] {
-  // 首先过滤出顶级菜单 (parentId === 0)
-  const topLevelMenus = originalData.menuList.filter(menu => menu.parentId === 0);
-
-  return topLevelMenus.map(menu => {
-    return convertMenuItem(menu, originalData.menuList);
-  });
-}
-
-function convertMenuItem(menu: OriginalMenuItem, allMenus: OriginalMenuItem[]): ConvertedMenuItem {
-  // 生成路由名称 (使用小写字母和下划线)
-  const routeName = menu.url
-    .replace(/^\/+/, '') // 去掉开头的一个或多个 '/'
-    .replace(/[/\s]/g, '_') // 替换剩余的 '/' 和空格为 '_'
-    .toLowerCase();
-
-  // 生成路由路径
-  let routePath = `${routeName}`;
-  if (menu.url && menu.url.trim() !== '') {
-    routePath = `${menu.url}`;
-  }
-
-  // 转换基本信息
-  const converted: ConvertedMenuItem = {
-    name: routeName,
-    path: routePath,
-    component: menu.component,
-    meta: {
-      title: menu.name,
-      // i18nKey: `route.${routeName}`,
-      order: menu.orderNum,
-      hideInMenu: menu.hideInMenu,
-      icon: String(menu.icon)
-    }
-  };
-
-  // 处理子菜单
-  if (menu.list && menu.list.length > 0) {
-    converted.children = menu.list.map(child => convertMenuItem(child, allMenus));
-  } else {
-    // 如果没有直接子菜单,但可能有其他关联的子菜单
-    const children = allMenus.filter(m => m.parentId === menu.menuId);
-    if (children.length > 0) {
-      converted.children = children.map(child => convertMenuItem(child, allMenus));
-    }
-  }
-
-  return converted;
-}
 
-/**
- * 菜单转为树型结构
- * @param data
- * @returns
- */
-export function buildMenuTree(data: any) {
-  // 创建根节点数组和映射表
-  const rootNodes: any = [];
-  const nodeMap: any = {};
-
-  // 首先将所有节点存入映射表
-  data.forEach((item: any) => {
-    nodeMap[item.menuId] = { ...item };
-  });
-
-  // 构建树形结构
-  data.forEach((item: any) => {
-    const node = nodeMap[item.menuId];
-
-    if (item.parentId === 0) {
-      // 根节点
-      rootNodes.push(node);
-    } else {
-      // 子节点,找到父节点并添加到父节点的children中
-      const parent = nodeMap[item.parentId];
-      if (parent) {
-        if (!parent.children) {
-          parent.children = [];
-        }
-        parent.children.push(node);
-      } else {
-        // 如果父节点不存在,也作为根节点
-        rootNodes.push(node);
-      }
-    }
-  });
-
-  // 删除空children字段
-  const removeEmptyChildren = (nodes: any) => {
-    nodes.forEach((node: any) => {
-      if (node.children && node.children.length === 0) {
-        delete node.children;
-      } else if (node.children) {
-        removeEmptyChildren(node.children);
-      }
-    });
-    return nodes;
-  };
-
-  // 对根节点和子节点按orderNum排序
-  const sortByOrderNum = (nodes: any) => {
-    return nodes
-      .sort((a: any, b: any) => a.orderNum - b.orderNum)
-      .map((node: any) => {
-        if (node.children) {
-          node.children = sortByOrderNum(node.children);
-        }
-        return node;
-      });
-  };
-
-  return removeEmptyChildren(sortByOrderNum(rootNodes));
-}
 /**
  * 判断一个对象的所有字段是否有值(非 null 和 undefined)
  * @param obj 要检查的对象
@@ -335,4 +181,35 @@ export async function copyTextToClipboard(text: string): Promise<boolean> {
     console.error('复制文本失败:', error);
     return false;
   }
+} /**
+ * 转换路由格式为项目所需的CustomRoute格式
+ * @param originalRoutes 原始路由数据
+ * @returns 转换后的CustomRoute数组
+ */
+export function convertToCustomRoutes(originalRoutes: any[]) {
+  return originalRoutes.map(route => {
+    return convertMenuItem(route);
+  });
+}
+
+function convertMenuItem(menu: any) {
+  const routeName = menu.name
+    .replace(/^\/+/, '') // 去掉开头的一个或多个 '/'
+    .replace(/[/\s]/g, '_') // 替换剩余的 '/' 和空格为 '_'
+    .toLowerCase();
+  const routeData: any = {
+    path: menu.path,
+    name: routeName,
+    meta: {
+      title: menu.meta.title,
+      icon: menu.meta.icon,
+      hideInMenu: Number(menu.meta.hidden)
+    },
+    component: menu.component == 'Layout' ? `layout.base` : menu.component
+  };
+  if (menu.children && menu.children.length) {
+    routeData.children = menu.children.map((child: any) => convertMenuItem(child));
+  }
+
+  return routeData;
 }

+ 2 - 2
src/views/_builtin/login/index.vue

@@ -41,7 +41,7 @@ const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
       <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" />
+            <SystemLogo class="text-64px text-primary lt-sm:text-48px" width="80" />
             <h3 class="text-28px text-primary font-500 lt-sm:text-22px">{{ $t('system.title') }}</h3>
             <div class="i-flex-col">
               <ThemeSchemaSwitch
@@ -69,7 +69,7 @@ const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
 
     <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="#9ED605"
         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>

+ 11 - 14
src/views/_builtin/login/modules/pwd-login.vue

@@ -1,9 +1,9 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive, ref, watch } from 'vue';
 import { Crypto } from '@sa/utils';
+import { fetchGetCaptcha } from '@/service/api/common';
 import { useAuthStore } from '@/store/modules/auth';
 import { useFormRules, useNaiveForm } from '@/hooks/common/form';
-import { getUUID } from '@/utils/zt';
 import { localStg } from '@/utils/storage';
 import { $t } from '@/locales';
 defineOptions({
@@ -18,13 +18,13 @@ const imgPath = ref('');
 interface FormModel {
   userName: string;
   password: string;
-  imageCode: string;
+  captchaCode: string;
 }
 
 const model: FormModel = reactive({
   userName: '',
   password: '',
-  imageCode: ''
+  captchaCode: ''
 });
 
 onMounted(() => {
@@ -45,10 +45,10 @@ const rules = computed<Record<keyof FormModel, App.Global.FormRule[]>>(() => {
   return {
     userName: formRules.userName,
     password: formRules.pwd,
-    imageCode: formRules.imageCode
+    captchaCode: formRules.captchaCode
   };
 });
-const sessionUUID = ref('');
+const captchaKey = ref('');
 async function handleSubmit() {
   await validate();
   if (isRememberMe.value) {
@@ -56,16 +56,13 @@ async function handleSubmit() {
     localStg.set('userName', model.userName);
     localStg.set('password', pwd);
   }
-  await authStore.login({ ...model, sessionUUID: sessionUUID.value });
+  await authStore.login({ ...model, captchaKey: captchaKey.value });
 }
 async function getDataCode() {
-  const uuid = getUUID();
-  console.log(import.meta.env.MODE, '当前环境');
-  imgPath.value =
-    import.meta.env.MODE == 'test'
-      ? `${import.meta.env.VITE_SERVICE_BASE_URL}/captcha.jpg?uuid=${uuid}`
-      : `https://shop.backend.zswlgz.com/plt/captcha.jpg?uuid=${uuid}`;
-  sessionUUID.value = uuid;
+  const { data } = await fetchGetCaptcha();
+  imgPath.value = String(data?.captchaBase64);
+  captchaKey.value = String(data?.captchaId);
+  model.captchaCode = '';
 }
 getDataCode();
 watch(
@@ -92,7 +89,7 @@ watch(
       />
     </NFormItem>
     <NFormItem path="imageCode">
-      <NInput v-model:value="model.imageCode" placeholder="请输入验证码" />
+      <NInput v-model:value="model.captchaCode" placeholder="请输入验证码" />
       <img :src="imgPath" alt="" class="ml20px h40px w220px cursor-pointer" @click="getDataCode" />
     </NFormItem>
     <NSpace vertical :size="24">

+ 386 - 0
src/views/goods-center/type-admin/index.vue

@@ -0,0 +1,386 @@
+<script setup lang="tsx">
+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 { 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';
+const appStore = useAppStore();
+const deskData = ref<Api.goods.ShopCategory[]>([]);
+const loading = ref(false);
+const [registerSearchForm, { getFieldsValue: getSearchForm }] = useForm({
+  schemas: [
+    {
+      field: 'name',
+      component: 'NInput',
+      label: '分类名称'
+    }
+    // {
+    //   label: '门店列表',
+    //   component: 'ApiSelect',
+    //   field: 'shopId',
+    //   componentProps: {
+    //     api: fetchGetAllStoreList,
+    //     labelFeild: 'shopName',
+    //     valueFeild: 'shopId',
+    //     onUpdateValue: () => {
+    //       nextTick(() => {
+    //         getData();
+    //       });
+    //     },
+    //     getOptions: async (options: any) => {
+    //       await setFieldsValue({ shopId: options[0].shopId });
+    //       getData();
+    //     }
+    //   }
+    // }
+  ],
+  labelWidth: 120,
+  layout: 'horizontal',
+  gridProps: {
+    cols: '1 xl:4 s:1 l:3',
+    itemResponsive: true
+  },
+  collapsedRows: 1
+});
+const loadedTreeData = ref<Record<string, any[]>>({});
+const loadingStates = ref<Record<string, boolean>>({});
+const selectChekedKeys = ref<TreeOption[]>([]);
+
+// 模拟接口请求函数
+const fetchTreeDataByCode = async (code: string) => {
+  loadingStates.value[code] = true;
+  try {
+    // 这里替换为实际的 API 调用
+    const { data } = await fetchGetAllCategory(code); // 或其他获取树形数据的接口
+    loadedTreeData.value[code] = data;
+  } finally {
+    loadingStates.value[code] = false;
+  }
+};
+const [
+  registerModalForm,
+  {
+    openModal: openModalForm,
+    setFieldsValue: setModalFormValue,
+    getFieldsValue: getModalFormValue,
+
+    setModalProps,
+    setSubLoading,
+    updateSchema
+  }
+] = useModalFrom({
+  modalConfig: {
+    title: '一级分类',
+    isShowHeaderText: true
+  },
+  formConfig: {
+    schemas: [
+      {
+        field: 'id',
+        label: '分类ID',
+        show: false,
+        component: 'NInput'
+      },
+      {
+        field: 'parentId',
+        label: '上级分类',
+        component: 'ApiSelect',
+        show: false
+      },
+      {
+        field: 'parentName',
+        label: '上级分类名称',
+        component: 'NInput',
+        componentProps: {
+          disabled: true
+        },
+        ifShow({ model }) {
+          return model.parentId;
+        }
+      },
+      {
+        field: 'name',
+        component: 'NInput',
+        label: '分类名称',
+        required: true
+      },
+      {
+        field: 'iconUrl',
+        component: 'zUpload',
+        label: '分类图标',
+        componentProps: {
+          max: 1
+        }
+      },
+      {
+        field: 'adPicture',
+        component: 'zUpload',
+        label: '广告位图片',
+        componentProps: {
+          max: 1
+        },
+        ifShow({ model }) {
+          return !model.parentId;
+        }
+      },
+      {
+        field: 'adLink',
+        component: 'NInput',
+        label: '广告位链接',
+        ifShow({ model }) {
+          return !model.parentId;
+        }
+      },
+      {
+        field: 'visible',
+        component: 'NSwitch',
+        label: '状态',
+        defaultValue: 1,
+        required: true,
+        componentProps: {
+          checkedValue: 1,
+          uncheckedValue: 0
+        }
+      },
+      {
+        field: 'businessType',
+        label: '适用业务',
+        component: 'NSelect',
+        required: true,
+        componentProps: {
+          options: [
+            {
+              label: '关联分类',
+              value: 0
+            },
+            {
+              label: '活动链接	',
+              value: 1
+            }
+          ]
+        },
+        ifShow({ model }) {
+          return model.parentId;
+        }
+      },
+      {
+        field: 'adLink',
+        component: 'NInput',
+        label: '跳转链接',
+        required: true,
+        ifShow({ model }) {
+          return model.businessType == 1;
+        }
+      },
+      {
+        field: 'code',
+        label: '业务类型',
+        required: true,
+        component: 'dictSelect',
+        componentProps: {
+          dictCode: 'sys_business_type',
+          immediate: true,
+          multiple: true
+        },
+        ifShow({ model }) {
+          return model.businessType == 0;
+        }
+      },
+      {
+        field: 'contactsForm',
+        label: '',
+        component: 'NInput',
+        render: ({ model }) => {
+          return (
+            <div>
+              {model.code?.map((code: string) => {
+                // 自动加载数据 - 如果数据不存在且未在加载中,则发起请求
+                if (!loadedTreeData.value[code] && !loadingStates.value[code]) {
+                  nextTick(() => {
+                    fetchTreeDataByCode(code);
+                  });
+                }
+
+                return (
+                  <div class={'ml120px w500px border rounded-16px border-solid px8px py4px'} key={code}>
+                    <DictTag dictCode={'sys_business_type'} value={code}></DictTag>
+                    <div class={'ml20px'}>
+                      {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
+                        />
+                      )}
+                    </div>
+                  </div>
+                );
+              })}
+            </div>
+          );
+        },
+        ifShow({ model }) {
+          return model.code;
+        }
+      }
+    ],
+    labelWidth: 120,
+    layout: 'horizontal',
+    gridProps: {
+      cols: '1',
+      itemResponsive: true
+    }
+  }
+});
+const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
+  {
+    title: '分类名称',
+    key: 'name'
+  },
+  {
+    title: '关联商品',
+    key: 'prodCount',
+    render: row => {
+      return row.level == 3 ? `${row.prodCount}个商品` : '';
+    }
+  },
+  {
+    title: '广告位',
+    key: 'adPicture',
+    render: row => {
+      return <NImage src={row.adPicture} width={60} height={60}></NImage>;
+    }
+  },
+  {
+    title: '跳转链接',
+    key: 'adLink'
+  },
+  {
+    title: '状态',
+    key: 'visible',
+    render: row => <NSwitch uncheckedValue={0} checkedValue={1} value={row.visible}></NSwitch>
+  },
+  {
+    title: '操作',
+    key: 'op',
+    fixed: 'right',
+    align: 'center',
+    width: 230,
+    render: row => (
+      <div class="flex-center gap-8px">
+        {row.level == 2 && (
+          <NButton type="primary" size="small" ghost onClick={() => add(row)}>
+            添加二级分类
+          </NButton>
+        )}
+        {
+          <NButton type="primary" size="small" ghost onClick={() => edit(row)}>
+            编辑
+          </NButton>
+        }
+
+        {row.level == 3 && (
+          <NButton type="primary" size="small" ghost onClick={() => del(row)}>
+            删除
+          </NButton>
+        )}
+      </div>
+    )
+  }
+];
+
+function edit(row: Api.goods.ShopCategory) {
+  openModalForm(row);
+  setModalProps({ title: `修改${Number(row.level)}级分类` });
+  setModalFormValue({ ...row, 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 });
+}
+function del(_row: Api.goods.ShopCategory) {
+  window.$dialog?.info({
+    title: '删除分类',
+    content: '你确定要删除吗?',
+    positiveText: '确定',
+    negativeText: '取消',
+    onPositiveClick: async () => {
+      // const { error } = await fetchDeleteCategory(row.id);
+      // if (!error) {
+      //   getData();
+      // }
+    }
+  });
+}
+async function getData() {
+  const { data, error } = await fetchGetCategoryList({ categoryListQuery: getSearchForm() });
+  if (!error) {
+    deskData.value = data;
+  }
+}
+function handleOpenModal() {
+  openModalForm();
+}
+async function handleSubmit() {
+  const form = await getModalFormValue();
+  console.log(form, '表单');
+  setSubLoading(false);
+  // if (!form.id) {
+  //   await fetchAddCategoryOne(form);
+  // }
+  // closeModalForm();
+  getData();
+}
+getData();
+function handleCheckedKeys(_keys: Array<string | number>, option: Array<TreeOption>) {
+  selectChekedKeys.value = option;
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <NCard :bordered="false" size="small">
+      <NCollapse display-directive="show" :default-expanded-names="['desk-search']">
+        <NCollapseItem title="搜索" name="desk-search">
+          <BasicForm @register-form="registerSearchForm" @submit="getData" @reset="getData" />
+        </NCollapseItem>
+      </NCollapse>
+    </NCard>
+    <NCard title="统一分类" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
+      <template #header-extra>
+        <TableHeaderOperation :loading="loading" @refresh="getData">
+          <template #prefix>
+            <NButton size="small" @click="handleOpenModal">新增一级分类</NButton>
+          </template>
+        </TableHeaderOperation>
+      </template>
+      <NDataTable
+        :columns="tableColumns"
+        :data="deskData"
+        size="small"
+        :flex-height="!appStore.isMobile"
+        :scroll-x="1088"
+        :loading="loading"
+        :row-key="row => row.id"
+        remote
+        class="sm:h-full"
+      />
+    </NCard>
+    <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

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

@@ -0,0 +1,297 @@
+<script setup lang="tsx">
+import { nextTick } from 'vue';
+import { NSwitch } from 'naive-ui';
+import {
+  fetchAddChannel,
+  fetchDelChannel,
+  fetchGetChannelList,
+  fetchUpdateChannel
+} from '@/service/api/government/government-list';
+import { fetchGetLoginUserList } from '@/service/api/common';
+import { useAuth } from '@/hooks/business/auth';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+
+const columns: NaiveUI.TableColumn<Api.government.ChannelVO>[] = [
+  {
+    key: 'channelNo',
+    title: '企业编号',
+    align: 'center',
+    width: 150
+  },
+  {
+    key: 'channelName',
+    title: '企业名称',
+    align: 'center'
+  },
+  {
+    key: 'staffCount',
+    title: '总员工数',
+    align: 'center'
+  },
+  {
+    key: 'normalCount',
+    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;
+            fetchUpdateChannel(row);
+          }}
+        ></NSwitch>
+      );
+    }
+  },
+  {
+    key: 'createTime',
+    title: '创建时间',
+    align: 'center'
+  }
+];
+
+const [registerTable, { refresh, setFieldsValue: setSearchValues, getTableData }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        field: 'channelNos',
+        label: '企业名称',
+        component: 'ApiSelect',
+        componentProps: {
+          api: fetchGetLoginUserList,
+          labelFeild: 'channelName',
+          valueFeild: 'channelNo',
+          multiple: true,
+          onUpdateValue: () => {
+            nextTick(() => {
+              handleSearch();
+            });
+          },
+          getOptions: async (options: any) => {
+            await setSearchValues({ channelNos: [options[0].channelNo] });
+            handleSearch();
+          }
+        }
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NSelect',
+        componentProps: {
+          options: [
+            {
+              label: '正常',
+              value: 1
+            },
+            {
+              label: '禁用',
+              value: 0
+            }
+          ]
+        }
+      },
+      {
+        field: 'userAttrType',
+        label: '人员属性',
+        component: 'dictSelect',
+        componentProps: {
+          dictCode: 'user_attr_type',
+          immediate: true
+        },
+        show: useAuth().hasAuth('user:attr:type')
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '企业列表',
+    showAddButton: true,
+    defaultParamsNotReset: 'channelNos',
+    opWdith: 220
+  }
+});
+
+const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue, setModalProps }] = useModalFrom({
+  modalConfig: {
+    title: '标签 ',
+    width: 500,
+    isShowHeaderText: true,
+    height: 200
+  },
+  formConfig: {
+    schemas: [
+      {
+        label: '',
+        field: 'id',
+        component: 'NInput',
+        show: false
+      },
+      {
+        label: '企业编码',
+        field: 'channelNo',
+        component: 'NInput',
+        show: false
+      },
+      {
+        label: '所属企业',
+        field: 'appName',
+        component: 'NInput',
+        componentProps: {
+          readonly: true,
+          disabled: true
+        }
+      },
+      {
+        field: 'channelName',
+        label: '企业名称',
+        component: 'NInput',
+        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 fetchUpdateChannel(form);
+  } else {
+    await fetchAddChannel(form);
+  }
+  closeModal();
+  refresh();
+}
+
+function handleSearch() {
+  refresh();
+}
+
+async function edit(row: Recordable) {
+  openModal(row);
+  setFieldsValue(row);
+}
+function handleOpenModal() {
+  openModal();
+  setModalProps({ title: '新增一级企业' });
+}
+function addtwo(row: Api.government.ChannelVO) {
+  // 获取完整的层级路径名称
+  const fullPathName = findParentNames(row);
+  const levelDesc = getLevelDescription(row);
+  openModal();
+  setFieldsValue({ appName: fullPathName, channelNo: row.channelNo });
+  setModalProps({ title: `新增${levelDesc}` });
+}
+function findParentNames(row: Api.government.ChannelVO): string {
+  const tableData = getTableData();
+
+  // 如果没有父级ID,说明是顶级节点
+  if (!row.fatherId) {
+    return row.channelName || '';
+  }
+
+  const nodeMap = new Map<string, Api.government.ChannelVO>();
+  function buildNodeMap(nodes: Api.government.ChannelVO[]) {
+    nodes.forEach((item: Api.government.ChannelVO) => {
+      nodeMap.set(item.id, item);
+      if (item.children && item.children.length > 0) {
+        buildNodeMap(item.children);
+      }
+    });
+  }
+
+  buildNodeMap(tableData);
+
+  function findPath(currentId: string, path: string[] = []): string[] {
+    const currentNode = nodeMap.get(currentId);
+    if (!currentNode) {
+      return path;
+    }
+
+    const currentPath = [currentNode.channelName || '', ...path];
+
+    if (!currentNode.fatherId) {
+      return currentPath;
+    }
+
+    return findPath(currentNode.fatherId, currentPath);
+  }
+
+  const fullPath = findPath(row.fatherId, [row.channelName || '']);
+  return fullPath.join('>');
+}
+function getLevelDescription(row: Api.government.ChannelVO): string {
+  if (row.level === undefined || row.level < 0) {
+    return '未知层级';
+  }
+
+  const levelMap: Record<number, string> = {
+    0: '一级',
+    1: '二级',
+    2: '三级',
+    3: '四级',
+    4: '五级'
+  };
+
+  return `${levelMap[row.level] || `${row.level + 1}级`}企业`;
+}
+async function handleDelete(row: Api.government.ChannelVO) {
+  await fetchDelChannel(row.id);
+  refresh();
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable
+      :columns="columns"
+      :api="fetchGetChannelList"
+      :immediate="false"
+      @register="registerTable"
+      @add="handleOpenModal"
+    >
+      <template #op="{ row }">
+        <NButton v-if="row.level < 5" size="small" ghost type="primary" @click="addtwo(row)">
+          添加{{ row.level + 1 }}级企业
+        </NButton>
+        <NButton size="small" ghost type="primary" @click="edit(row)">编辑</NButton>
+        <NPopconfirm @positive-click="handleDelete(row)">
+          <template #trigger>
+            <NButton size="small" type="error" ghost :disabled="Boolean(row.staffCount)">删除</NButton>
+          </template>
+          确定删除吗?
+        </NPopconfirm>
+      </template>
+    </ZTable>
+    <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

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

@@ -0,0 +1,353 @@
+<script setup lang="tsx">
+import { ref, useTemplateRef } from 'vue';
+import {
+  fetchGetFailPointsList,
+  fetchGetPointsList,
+  fetchGetPointsOutList,
+  fetchImportPoints
+} from '@/service/api/government/points';
+// 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';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+import type { FormSchema } from '@/components/zt/Form/types/form';
+import SVGIcon from '@/components/custom/svg-icon.vue';
+const importTemplateRef = useTemplateRef('importTemplateRef');
+const loading = ref(false);
+
+const ModalColumns: NaiveUI.TableColumn<Api.government.PointsRecharge>[] = [
+  {
+    key: 'channelName',
+    title: '所属企业',
+    align: 'center'
+  },
+  {
+    key: 'userName',
+    title: '员工姓名',
+    align: 'center'
+  },
+  {
+    key: 'userPhone',
+    title: '员工手机号',
+    align: 'center'
+  },
+  {
+    key: 'points',
+    title: '充值积分',
+    align: 'center'
+  },
+  {
+    key: 'expiryDate',
+    title: '过期日期',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '创建时间',
+    align: 'center'
+  }
+];
+const outColumns: NaiveUI.TableColumn<Api.government.PointsRechargeVO>[] = [
+  {
+    key: 'channelName',
+    title: '所属企业',
+    align: 'center'
+  },
+  {
+    key: 'totalPoints',
+    title: '总充值积分',
+    align: 'center'
+  },
+  {
+    key: 'totalUserCount',
+    title: '总充值人次',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '操作时间',
+    align: 'center'
+  }
+];
+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: 'userAttrType',
+    label: '人员属性',
+    component: 'dictSelect',
+    componentProps: {
+      dictCode: 'user_attr_type',
+      immediate: true
+    },
+    show: useAuth().hasAuth('user:attr:type')
+  },
+  {
+    field: 'userPhone',
+    label: '员工手机号',
+    component: 'NInput'
+  }
+];
+const failColumns: NaiveUI.TableColumn<Api.government.PointsFailureRecordVO>[] = [
+  {
+    key: 'index',
+    title: '序号',
+    align: 'center',
+    render(_, rowIndex) {
+      return rowIndex + 1;
+    }
+  },
+  {
+    key: 'name',
+    title: '任务名称',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '时间',
+    align: 'center',
+    render(row) {
+      return (
+        <div>
+          <div>创建时间:{row.createTime}</div>
+          <div>完成时间:{row.createTime}</div>
+        </div>
+      );
+    }
+  },
+  {
+    key: 'totalUserCount',
+    title: '操作人',
+    align: 'center',
+    render(row) {
+      return (
+        <div>
+          <div>{row.createByRole}</div>
+          <div>({row.createByName})</div>
+        </div>
+      );
+    }
+  },
+  {
+    key: 'successStatus',
+    title: '状态',
+    align: 'center',
+    width: 240,
+    render(row) {
+      return (
+        <div class={'flex items-center'}>
+          共{Number(row.successStatus) + Number(row.failureStatus)}条,成功:{row.successStatus},
+          <span class={'flex items-center text-red-500'}>
+            失败:
+            {row.failureStatus}
+            {row.failureStatus != 0 && (
+              <div onClick={() => hanleExportFailure(row.code)}>
+                <SVGIcon
+                  icon={'tdesign:download'}
+                  class={'ml-1 cursor-pointer text-20px'}
+                  style={'color:var(--n-color)'}
+                ></SVGIcon>
+              </div>
+            )}
+          </span>
+        </div>
+      );
+    }
+  }
+];
+const failData = ref<Api.government.PointsFailureRecordVO[]>([]);
+const [registerTable, { refresh }] = 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: 'userAttrType',
+        label: '人员属性',
+        component: 'dictSelect',
+        componentProps: {
+          dictCode: 'user_attr_type',
+          immediate: true
+        },
+        show: useAuth().hasAuth('user:attr:type')
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '充值积分',
+    showAddButton: false,
+    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 [registerModal, { openModal }] = useModal({
+  title: '充值积分',
+  height: 800,
+  showFooter: false,
+  width: 1200
+});
+const [registerModalFail, { openModal: openModalFail }] = useModal({
+  title: '导入记录',
+  height: 400,
+  showFooter: false
+});
+async function handleSubmitImport(file: File) {
+  const { error } = await fetchImportPoints(file);
+  if (!error) {
+    importTemplateRef.value?.closeModal();
+    refreshModal();
+  } else {
+    importTemplateRef.value?.setSubLoading(false);
+  }
+}
+function handleOpenPoints() {
+  importTemplateRef.value?.openModal();
+}
+async function openImportModal() {
+  openModalFail();
+  const { data } = await fetchGetFailPointsList();
+  failData.value = data as Api.government.PointsFailureRecordVO[];
+}
+async function hanleExportFailure(code: string) {
+  if (loading.value) {
+    window.$message?.error('正在导出,请勿重复点击');
+    return;
+  }
+  loading.value = true;
+  try {
+    await commonExport('/platform/pointsFailureRecord/export', { code }, '失败的记录.xlsx');
+  } finally {
+    loading.value = false;
+  }
+}
+
+async function exportIntegral() {
+  setTableLoading(true);
+  try {
+    await commonExport('/platform/pointsRecharge/export', getSeachForm(), '积分列表.xlsx');
+  } finally {
+    setTableLoading(false);
+  }
+}
+
+// function handleSearch() {
+//   refreshModal();
+// }
+
+// function listHandleSearch() {
+//   refresh();
+// }
+
+// async function setSearchForm(value: Recordable) {
+//   await setFieldsValue(value);
+// }
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="outColumns" :immediate="false" :api="fetchGetPointsOutList" @register="registerTable">
+      <template #prefix>
+        <NButton size="small" @click="openModal">充值积分</NButton>
+      </template>
+    </ZTable>
+    <BasicModal @register="registerModal" @after-leave="refresh">
+      <LayoutTable>
+        <ZTable
+          :immediate="false"
+          :show-table-action="false"
+          :columns="ModalColumns"
+          :api="fetchGetPointsList"
+          @register="registerModalTable"
+        >
+          <template #prefix="{ loading: tabloading }">
+            <NButton
+              v-if="useAuth().hasAuth('points:user:export')"
+              size="small"
+              :loading="tabloading"
+              :disabled="getTableData().length == 0"
+              @click="exportIntegral"
+            >
+              导出
+            </NButton>
+            <NButton v-if="useAuth().hasAuth('points:user:import')" size="small" @click="handleOpenPoints">
+              导入积分
+            </NButton>
+            <NButton v-if="useAuth().hasAuth('points:user:import-record')" size="small" @click="openImportModal">
+              导入记录
+            </NButton>
+          </template>
+        </ZTable>
+      </LayoutTable>
+    </BasicModal>
+    <BasicModal @register="registerModalFail">
+      <NDataTable :columns="failColumns" :data="failData" size="small" remote class="sm:h-full" />
+    </BasicModal>
+    <ZImportTemplate
+      ref="importTemplateRef"
+      url="/platform/pointsRecharge/exportTemplate"
+      template-text="导入积分模版.xlsx"
+      modal-text="导入积分"
+      @submit="handleSubmitImport"
+    ></ZImportTemplate>
+  </LayoutTable>
+</template>
+
+<style scoped></style>

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

@@ -0,0 +1,383 @@
+<script setup lang="tsx">
+import { useTemplateRef } from 'vue';
+import { NButton, NPopconfirm, NSwitch } from 'naive-ui';
+import {
+  fetchAddUser,
+  fetchDeleteUser,
+  fetchEditUser,
+  fetchExportUser,
+  fetchGetImportRecordList,
+  fetchGetUserList
+} from '@/service/api/government/user-list';
+// import { fetchGetLoginUserList } from '@/service/api/common';
+// import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
+import { useAuth } from '@/hooks/business/auth';
+import { commonExport } from '@/utils/common';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+import SVGIcon from '@/components/custom/svg-icon.vue';
+const importTemplateRef = useTemplateRef('importTemplateRef');
+const columns: NaiveUI.TableColumn<Api.government.userList>[] = [
+  {
+    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',
+    render: row => {
+      return (
+        <NSwitch
+          uncheckedValue={0}
+          checkedValue={1}
+          value={row.status}
+          disabled={!useAuth().hasAuth('user:list:statusbtn')}
+          onUpdate:value={val => {
+            row.status = val;
+            fetchEditUser(row);
+          }}
+        ></NSwitch>
+      );
+    }
+  }
+];
+
+const [registerTable, { refresh, setTableLoading, 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: 'realName',
+        label: '员工姓名',
+        component: 'NInput'
+      },
+      {
+        field: 'userMobile',
+        label: '手机号码',
+        component: 'NInput'
+      },
+      {
+        field: 'userAttrType',
+        label: '人员属性',
+        component: 'dictSelect',
+        componentProps: {
+          dictCode: 'user_attr_type',
+          immediate: true
+        },
+        show: useAuth().hasAuth('user:attr:type')
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'userId',
+    title: '员工列表',
+    showAddButton: useAuth().hasAuth('user:list:add'),
+    defaultParamsNotReset: 'channelIdList'
+  }
+});
+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) {
+      return (
+        <div class={'flex items-center'}>
+          共{Number(row.success) + Number(row.error)}条,成功:{row.success},
+          <span class={'flex items-center text-red-500'}>
+            失败:
+            {row.error}
+            {row.error != 0 && (
+              <div onClick={() => hanleExportFailure(row.batchNo)}>
+                <SVGIcon
+                  icon={'tdesign:download'}
+                  class={'ml-1 cursor-pointer text-20px'}
+                  style={'color:var(--n-loading-color)'}
+                ></SVGIcon>
+              </div>
+            )}
+          </span>
+        </div>
+      );
+    }
+  }
+];
+async function hanleExportFailure(batchNo: string) {
+  await commonExport(`/admin/enterprise/downloadErrorExcel`, { batchNo }, '员工失败列表.xlsx');
+}
+async function handleDelete(row: Api.government.userList) {
+  setTableLoading(true);
+  await fetchDeleteUser(row.userId);
+  // console.log(row, 'row');
+
+  refresh();
+}
+const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
+  modalConfig: {
+    title: '员工 ',
+    width: 600,
+    isShowHeaderText: true,
+    height: 400
+  },
+  formConfig: {
+    schemas: [
+      {
+        label: '',
+        field: 'userId',
+        component: 'NInput',
+        show: false
+      },
+      {
+        field: 'realName',
+        label: '员工姓名',
+        component: 'NInput',
+        required: true
+      },
+      {
+        field: 'userMobile',
+        label: '手机号码',
+        component: 'NInput',
+        required: true,
+        componentProps: {
+          maxlength: 11
+        },
+        rules: [
+          {
+            // pattern: /^1[3456789]\d{9}$/,
+            message: '请输入正确的手机号',
+            trigger: ['blur', 'input'],
+            required: true,
+            validator: (_rule, value, callback) => {
+              if (!value) {
+                callback(new Error('请输入手机号'));
+              } else if (!/^1[3456789]\d{9}$/.test(value)) {
+                callback(new Error('请输入正确的手机号'));
+              }
+              callback();
+              return true;
+            }
+          }
+        ]
+      },
+      // {
+      //   field: 'channelId',
+      //   label: '所属企业',
+      //   component: 'ApiSelect',
+      //   componentProps: {
+      //     api: fetchGetAllChannelList,
+      //     labelFeild: 'channelName',
+      //     valueFeild: 'id'
+      //   },
+      //   required: true
+      // },
+      {
+        field: 'userAttrType',
+        label: '人员属性',
+        component: 'dictSelect',
+        componentProps: {
+          dictCode: 'user_attr_type',
+          immediate: true,
+          disabledLables: ['全部']
+        },
+        required: true
+      }
+    ],
+    gridProps: {
+      cols: '1'
+    },
+    labelWidth: 120
+  }
+});
+const [registerModalFail, { openModal: openModalFail }] = useModal({
+  title: '导入记录',
+  height: 600,
+  showFooter: false,
+  width: 1200
+});
+async function handleSubmit() {
+  const form = await getFieldsValue();
+  if (form.userId) {
+    await fetchEditUser(form);
+  } else {
+    await fetchAddUser(form);
+  }
+  closeModal();
+  refresh();
+}
+
+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);
+}
+
+async function handleExport() {
+  setTableLoading(true);
+  try {
+    await commonExport('/admin/enterprise/export', getSeachForm(), '员工列表.xlsx');
+  } finally {
+    setTableLoading(false);
+  }
+}
+</script>
+
+<template>
+  <LayoutTable>
+    <ZTable :columns="columns" :immediate="false" :api="fetchGetUserList" @register="registerTable" @add="openModal">
+      <template #op="{ row }">
+        <NButton
+          v-if="useAuth().hasAuth('user:list:edit')"
+          size="small"
+          ghost
+          type="primary"
+          :disabled="Boolean(row.available)"
+          @click="edit(row)"
+        >
+          编辑
+        </NButton>
+        <NPopconfirm v-if="useAuth().hasAuth('user:list:del')" @positive-click="handleDelete(row)">
+          <template #trigger>
+            <NButton size="small" type="error" ghost :disabled="Boolean(row.available)">删除</NButton>
+          </template>
+          确定删除吗?
+        </NPopconfirm>
+      </template>
+      <template #prefix="{ loading }">
+        <NSpace>
+          <NButton
+            v-if="useAuth().hasAuth('user:list:export-btn')"
+            size="small"
+            :loading="loading"
+            @click="handleExport"
+          >
+            导出
+          </NButton>
+          <NButton v-if="useAuth().hasAuth('user:list:export')" size="small" @click="openImportModal">导入员工</NButton>
+          <NButton v-if="useAuth().hasAuth('user:list:exportRecord')" 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>
+
+<style scoped></style>

+ 1 - 1
src/views/manage/department/department.data.ts

@@ -99,7 +99,7 @@ export const formSchems: FormSchema[] = [
 
 export const searchSchems: FormSchema[] = [
   {
-    field: 'deptName',
+    field: 'keywords',
     label: '部门名称',
     component: 'NInput'
   },

+ 4 - 13
src/views/manage/department/index.vue

@@ -48,28 +48,19 @@ const [registerSearchForm, { getFieldsValue: getSeachForm }] = useForm({
 
 const colums: NaiveUI.TableColumn<InternalRowData>[] = [
   {
-    key: 'deptId',
+    key: 'id',
     title: '部门ID',
     align: 'center'
   },
   {
-    key: 'deptName',
+    key: 'name',
     title: '部门名称',
     align: 'center',
     minWidth: 120
   },
+
   {
-    key: 'leaderUserName',
-    title: '部门负责人',
-    align: 'center'
-  },
-  {
-    key: 'phone',
-    title: '负责人电话',
-    align: 'center'
-  },
-  {
-    key: 'seq',
+    key: 'sort',
     title: '排序',
     align: 'center'
   },

+ 19 - 54
src/views/manage/dict/dict.data.ts

@@ -1,19 +1,19 @@
 import { h } from 'vue';
-import { NSwitch, NTag } from 'naive-ui';
-import { fetchUpdateDictData } from '@/service/api/config/dict';
+import { NSwitch } from 'naive-ui';
+import { fetchUpdateDictData } from '@/service/api/system-manage';
 import type { FormSchema } from '@/components/zt/Form/types/form';
 import DictTag from '@/components/zt/dict-tag/index.vue';
 
 export const modelTypeDict: FormSchema[] = [
   {
     label: '字典名称',
-    field: 'dictName',
+    field: 'name',
     component: 'NInput',
     required: true
   },
   {
     label: '字典类型',
-    field: 'dictType',
+    field: 'code',
     component: 'NInput',
     required: true
   },
@@ -21,10 +21,10 @@ export const modelTypeDict: FormSchema[] = [
     label: '是否启用',
     field: 'status',
     component: 'NSwitch',
-    defaultValue: 0,
+    defaultValue: 1,
     componentProps: {
-      checkedValue: 0,
-      uncheckedValue: 1
+      checkedValue: 1,
+      uncheckedValue: 0
     }
   },
   {
@@ -37,32 +37,22 @@ export const modelTypeDict: FormSchema[] = [
   },
   {
     label: 'dictId',
-    field: 'dictId',
+    field: 'id',
     component: 'NInput',
     show: false
   }
 ];
-const listClassOptions: Record<string, string>[] = [
-  { label: 'Text', value: 'text' },
-  { label: 'Default', value: 'default' },
-  { label: 'Tertiary', value: 'tertiary' },
-  { label: 'Primary', value: 'primary' },
-  { label: 'Info', value: 'info' },
-  { label: 'Success', value: 'success' },
-  { label: 'Warning', value: 'warning' },
-  { label: 'Error', value: 'error' }
-];
 
 export const modelDataDict: FormSchema[] = [
   {
     label: '字典类型',
-    field: 'dictCode',
+    field: 'id',
     component: 'NInput',
     show: false
   },
   {
     label: '字典类型',
-    field: 'dictType',
+    field: 'typeCode',
     component: 'NInput',
     componentProps: {
       disabled: true
@@ -70,13 +60,13 @@ export const modelDataDict: FormSchema[] = [
   },
   {
     label: '字典标签',
-    field: 'dictLabel',
+    field: 'name',
     component: 'NInput',
     required: true
   },
   {
     label: '字典键值',
-    field: 'dictValue',
+    field: 'value',
     component: 'NInput',
     required: true
   },
@@ -84,10 +74,10 @@ export const modelDataDict: FormSchema[] = [
     label: '是否启用',
     field: 'status',
     component: 'NSwitch',
-    defaultValue: 0,
+    defaultValue: 1,
     componentProps: {
-      checkedValue: 0,
-      uncheckedValue: 1
+      checkedValue: 1,
+      uncheckedValue: 0
     }
   },
   {
@@ -99,15 +89,6 @@ export const modelDataDict: FormSchema[] = [
       min: 1
     }
   },
-  {
-    label: '标签样式',
-    field: 'listClass',
-    component: 'NSelect',
-    componentProps: {
-      options: listClassOptions,
-      renderLabel: renderTagLabel
-    }
-  },
   {
     label: '备注',
     field: 'remark',
@@ -119,7 +100,7 @@ export const modelDataDict: FormSchema[] = [
 ];
 export const columns: NaiveUI.TableColumn<Api.System.DictData>[] = [
   {
-    key: 'dictLabel',
+    key: 'name',
     title: '字典标签',
     align: 'center',
     minWidth: 80,
@@ -133,7 +114,7 @@ export const columns: NaiveUI.TableColumn<Api.System.DictData>[] = [
   },
 
   {
-    key: 'dictValue',
+    key: 'value',
     title: '字典键值',
     align: 'center',
     minWidth: 80,
@@ -149,8 +130,8 @@ export const columns: NaiveUI.TableColumn<Api.System.DictData>[] = [
     render(rowData) {
       return h(NSwitch, {
         value: Number(rowData.status),
-        uncheckedValue: 1,
-        checkedValue: 0,
+        uncheckedValue: 0,
+        checkedValue: 1,
         onUpdateValue: async e => {
           const oldStatus = rowData.status;
           rowData.status = e;
@@ -162,16 +143,6 @@ export const columns: NaiveUI.TableColumn<Api.System.DictData>[] = [
       });
     }
   },
-  {
-    key: 'dictSort',
-    title: '字典排序',
-    align: 'center',
-    minWidth: 80,
-    resizable: true,
-    ellipsis: {
-      tooltip: true
-    }
-  },
   {
     key: 'remark',
     title: '备注',
@@ -193,9 +164,3 @@ export const columns: NaiveUI.TableColumn<Api.System.DictData>[] = [
     }
   }
 ];
-function renderTagLabel(option: { label: string; value: string }) {
-  if (option.value === 'text') {
-    return option.label;
-  }
-  return h(NTag, { size: 'small', type: option.value as any }, () => option.label);
-}

+ 19 - 23
src/views/manage/dict/index.vue

@@ -11,8 +11,7 @@ import {
   fetchGetDictTypeOption,
   fetchUpdateDictData,
   fetchUpdateDictType
-} from '@/service/api/config/dict';
-import { useDict } from '@/hooks/business/dict';
+} from '@/service/api/system-manage';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import { $t } from '@/locales';
 import ButtonIcon from '@/components/custom/button-icon.vue';
@@ -23,12 +22,12 @@ const [registerTable, { refresh, getTableLoding, setTableConfig, setFieldsValue,
     schemas: [
       {
         label: '字典标签',
-        field: 'dictLabel',
+        field: 'name',
         component: 'NInput'
       },
       {
         label: '字典类型',
-        field: 'dictType',
+        field: 'typeCode',
         component: 'NInput',
         show: false
       }
@@ -92,7 +91,6 @@ const [
     isShowHeaderText: true
   }
 });
-useDict('sys_user_sex');
 
 const route = useRoute();
 const dictData = ref<Api.System.DictType[]>([]);
@@ -107,15 +105,13 @@ async function getTreeData() {
 }
 getTreeData();
 async function handleClickTree(keys: string[]) {
-  console.log(keys, '点事件');
-
   const dictType = keys.length ? keys[0] : null;
   selectedKeys.value = keys;
-  await setFieldsValue({ dictType });
-  const dictDataType = dictData.value.find(item => item.dictType === dictType);
+  await setFieldsValue({ typeCode: dictType });
+  const dictDataType = dictData.value.find(item => item.code === dictType);
 
   setTableConfig({
-    title: dictDataType ? `${dictDataType.dictName}(${dictDataType.dictType} )` : '字典列表',
+    title: dictDataType ? `${dictDataType.name}(${dictDataType.code})` : '字典列表',
     keyField: 'dictCode',
     showAddButton: Boolean(dictDataType)
   });
@@ -125,8 +121,8 @@ async function handleClickTree(keys: string[]) {
 }
 
 function dictFilter(pattern: string, node: TreeOption) {
-  const dictName = node.dictName as string;
-  const dictType = node.dictType as string;
+  const dictName = node.name as string;
+  const dictType = node.code as string;
   return dictName.includes(pattern) || dictType.includes(pattern);
 }
 function renderLabel({ option }: { option: TreeOption }) {
@@ -135,14 +131,14 @@ function renderLabel({ option }: { option: TreeOption }) {
       {{
         trigger: () => (
           <div class="w-200px flex gap-6px overflow-hidden text-ellipsis whitespace-nowrap">
-            <span>{option.dictName}</span>
-            <span class="text-12px text-gray-500">( {option.dictType} )</span>
+            <span>{option.name}</span>
+            <span class="text-12px text-gray-500">( {option.code} )</span>
           </div>
         ),
         default: () => (
           <div class="flex-col">
             <span>
-              {option.dictName} {option.dictType}
+              {option.name} {option.code}
             </span>
             {option.remark ? <span>( {option.remark} )</span> : null}
             <span>{option.createTime}</span>
@@ -171,7 +167,7 @@ function renderSuffix({ option }: { option: TreeOption }) {
         type="error"
         icon="material-symbols:delete-outline"
         tooltip-content={$t('common.delete')}
-        popconfirm-content={`确定删除 ${option.dictType} ?`}
+        popconfirm-content={`确定删除 ${option.code} ?`}
         onClick={(event: Event) => event.stopPropagation()}
         onPositiveClick={() => handleDeleteType(option as Api.System.DictType)}
       />
@@ -183,7 +179,7 @@ function handleResetTreeData() {
   getTreeData();
 }
 async function handleDeleteType(dictType: Api.System.DictType) {
-  const { error } = await fetchBatchDeleteDictType([dictType.dictId]);
+  const { error } = await fetchBatchDeleteDictType(dictType.id);
   if (error) return;
   window.$message?.success($t('common.deleteSuccess'));
   getTreeData();
@@ -194,7 +190,7 @@ function handleEditType(row: Api.System.DictType) {
 }
 async function handleSubmitDictType() {
   const form = await getModalTypeFields();
-  if (form.dictId) {
+  if (form.id) {
     await fetchUpdateDictType(form);
   } else {
     await fetchCreateDictType(form);
@@ -204,7 +200,7 @@ async function handleSubmitDictType() {
 }
 async function handleSubmitDictData() {
   const form = await getModalDataFields();
-  if (form.dictCode) {
+  if (form.id) {
     await fetchUpdateDictData(form);
   } else {
     await fetchCreateDictData(form);
@@ -217,11 +213,11 @@ function handleAddModalData() {
   setModalDataFields(getSeachForm());
 }
 function handleEditData(row: Api.System.DictData) {
-  openModalData();
+  openModalData(row);
   setModalDataFields(row);
 }
 async function handleDelete(row: Api.System.DictData) {
-  await fetchBatchDeleteDictData([row.dictCode]);
+  await fetchBatchDeleteDictData([Number(row.id)]);
   refresh();
 }
 </script>
@@ -256,8 +252,8 @@ async function handleDelete(row: Api.System.DictData) {
           :pattern="dictPattern"
           :filter="dictFilter"
           class="infinite-scroll h-full min-h-200px py-3"
-          key-field="dictType"
-          label-field="dictName"
+          key-field="code"
+          label-field="name"
           virtual-scroll
           :selectable="!getTableLoding"
           :render-label="renderLabel"

+ 50 - 55
src/views/manage/menu/index.vue

@@ -1,22 +1,19 @@
 <script setup lang="tsx">
 import { nextTick, ref } from 'vue';
 import { NButton, NPopconfirm, NTag } from 'naive-ui';
-import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
 import { yesOrNoRecord } from '@/constants/common';
 import { menuTypeRecord } from '@/constants/business';
 import { fetchAddMenu, fetchDelMenu, fetchEditMenu, fetchGetMenuList } from '@/service/api';
 import { useAppStore } from '@/store/modules/app';
-import { buildMenuTree } from '@/utils/zt';
 import { $t } from '@/locales';
 import SvgIcon from '@/components/custom/svg-icon.vue';
 import { useForm } from '@/components/zt/Form/hooks/useForm';
-import { type OperateType } from './modules/menu-operate-modal.vue';
 import { formSchems } from './modules/shared';
 const appStore = useAppStore();
 const checkedRowKeys = ref([]);
 
 const wrapperRef = ref<HTMLElement | null>(null);
-const menusData = ref([]);
+const menusData = ref<any>([]);
 const loading = ref(false);
 const showModal = ref(false);
 const formLoading = ref(false);
@@ -36,7 +33,7 @@ const [registerForm, { setFieldsValue, validate, getFieldsValue, updateSchema }]
   collapsedRows: 1
 });
 
-const colums: NaiveUI.TableColumn<InternalRowData>[] = [
+const colums: NaiveUI.TableColumn<Api.SystemManage.Menu>[] = [
   {
     type: 'selection',
     align: 'center',
@@ -52,15 +49,17 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
     title: $t('page.manage.menu.menuType'),
     align: 'center',
     width: 80,
-    render: (row: InternalRowData) => {
+    render: row => {
       const tagMap: Record<Api.SystemManage.MenuType, NaiveUI.ThemeColor> = {
-        0: 'default',
-        1: 'primary',
-        2: 'error'
+        MENU: 'default',
+        CATALOG: 'primary',
+        BUTTON: 'error'
       };
 
       const type = row.type as keyof typeof menuTypeRecord;
       const label = $t(menuTypeRecord[type]);
+      console.log(label, 'label');
+
       return <NTag type={tagMap[type]}>{label}</NTag>;
     }
   },
@@ -68,13 +67,10 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
     key: 'name',
     title: $t('page.manage.menu.menuName'),
     align: 'center',
-    minWidth: 120,
-    render: (row: InternalRowData) => {
-      return <span>{row.name}</span>;
-    }
+    minWidth: 120
   },
   {
-    key: 'perms',
+    key: 'perm',
     title: $t('page.manage.menu.menuPerms'),
     align: 'center',
     minWidth: 120
@@ -84,7 +80,7 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
     title: $t('page.manage.menu.icon'),
     align: 'center',
     width: 60,
-    render: (row: InternalRowData) => {
+    render: row => {
       return (
         <div class="flex-center">
           <SvgIcon icon={String(row.icon)} class="text-icon" />
@@ -99,22 +95,18 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
     minWidth: 120
   },
   {
-    key: 'url',
+    key: 'path',
     title: $t('page.manage.menu.routePath'),
     align: 'center',
-    minWidth: 120,
-    render: (row: InternalRowData) => {
-      return <div>{row.type == 2 ? '' : row.url}</div>;
-    }
+    minWidth: 120
   },
   {
-    key: 'hideInMenu',
+    key: 'visible',
     title: $t('page.manage.menu.hideInMenu'),
     align: 'center',
     width: 80,
-    render: (row: InternalRowData) => {
-      const hide: CommonType.YesOrNo = row.hideInMenu ? 'Y' : 'N';
-
+    render: row => {
+      const hide: CommonType.YesOrNo = !row.visible ? 'Y' : 'N';
       const tagMap: Record<CommonType.YesOrNo, NaiveUI.ThemeColor> = {
         Y: 'error',
         N: 'default'
@@ -132,7 +124,7 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
     align: 'center'
   },
   {
-    key: 'orderNum',
+    key: 'sort',
     title: $t('page.manage.menu.order'),
     align: 'center',
     width: 60
@@ -145,7 +137,7 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
     fixed: 'right',
     render: (row: any) => (
       <div class="flex-center justify-end gap-8px">
-        {row.type != 2 && (
+        {row.type != 'BUTTON' && (
           <NButton type="primary" ghost size="small" onClick={() => handleAddChildMenu(row)}>
             {$t('page.manage.menu.addChildMenu')}
           </NButton>
@@ -153,16 +145,18 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
         <NButton type="primary" ghost size="small" onClick={() => handleEdit(row)}>
           {$t('common.edit')}
         </NButton>
-        <NPopconfirm onPositiveClick={() => handleDelete(row.menuId)}>
-          {{
-            default: () => $t('common.confirmDelete'),
-            trigger: () => (
-              <NButton type="error" ghost size="small" loading={formLoading.value}>
-                {$t('common.delete')}
-              </NButton>
-            )
-          }}
-        </NPopconfirm>
+        {row.children.length == 0 && (
+          <NPopconfirm onPositiveClick={() => handleDelete(row.id)}>
+            {{
+              default: () => $t('common.confirmDelete'),
+              trigger: () => (
+                <NButton type="error" ghost size="small" loading={formLoading.value}>
+                  {$t('common.delete')}
+                </NButton>
+              )
+            }}
+          </NPopconfirm>
+        )}
       </div>
     )
   }
@@ -170,7 +164,7 @@ const colums: NaiveUI.TableColumn<InternalRowData>[] = [
 
 // const { checkedRowKeys, onBatchDeleted, onDeleted } = useTableOperate(data, 'id', getData);
 
-const operateType = ref<OperateType>('add');
+const operateType = ref('add');
 
 function handleAdd() {
   operateType.value = 'add';
@@ -203,18 +197,28 @@ function handleEdit(item: Api.SystemManage.Menu) {
 function handleAddChildMenu(item: any) {
   operateType.value = 'addChild';
   showModal.value = true;
-  console.log(item, 'asdsadsa');
-
-  nextTick(() => {
-    setFieldsValue({ parentId: item.menuId, url: item.url, type: item.type == 1 ? 2 : item.type });
+  nextTick(async () => {
+    let type = item.type;
+    let parentId = item.parentId;
+    if (item.type === 'CATALOG') {
+      type = 'MENU';
+      parentId = item.id;
+    } else if (item.type === 'MENU') {
+      type = 'BUTTON';
+    }
+    await setFieldsValue({
+      parentId,
+      url: item.url,
+      type
+    });
+    console.log(item.parentId);
   });
 }
 
 async function getAllPages() {
   const { data } = await fetchGetMenuList();
-  const menuData = buildMenuTree(data);
-  menusData.value = menuData;
-  console.log(menusData.value, 'menusData.value');
+  menusData.value = data as Api.SystemManage.Menu[];
+  console.log(data, 'menusData.value');
 }
 
 function init() {
@@ -264,19 +268,10 @@ async function handleSubmit() {
         :flex-height="!appStore.isMobile"
         :scroll-x="1088"
         :loading="loading"
-        :row-key="row => row.menuId"
+        :row-key="row => row.id"
         remote
         class="sm:h-full"
       />
-      <!--
- <MenuOperateModal
-        v-model:visible="visible"
-        :operate-type="operateType"
-        :row-data="editingData"
-        :all-pages="allPages"
-      />
-
--->
       <NModal v-model:show="showModal">
         <NCard class="w-800px">
           <template #header>
@@ -290,7 +285,7 @@ async function handleSubmit() {
                 v-model:value="model[field]"
                 :options="menusData"
                 label-field="name"
-                key-field="menuId"
+                key-field="id"
               ></NTreeSelect>
             </template>
           </BasicForm>

+ 0 - 467
src/views/manage/menu/modules/menu-operate-modal.vue

@@ -1,467 +0,0 @@
-<script setup lang="tsx">
-import { computed, ref, watch } from 'vue';
-import type { SelectOption } from 'naive-ui';
-import { enableStatusOptions, menuIconTypeOptions, menuTypeOptions } from '@/constants/business';
-import { fetchGetAllRoles } from '@/service/api';
-import { useFormRules, useNaiveForm } from '@/hooks/common/form';
-import { getLocalIcons } from '@/utils/icon';
-import { $t } from '@/locales';
-import SvgIcon from '@/components/custom/svg-icon.vue';
-import {
-  getLayoutAndPage,
-  getPathParamFromRoutePath,
-  getRoutePathByRouteName,
-  getRoutePathWithParam,
-  transformLayoutAndPageToComponent
-} from './shared';
-
-defineOptions({
-  name: 'MenuOperateModal'
-});
-
-export type OperateType = NaiveUI.TableOperateType | 'addChild';
-
-interface Props {
-  /** the type of operation */
-  operateType: OperateType;
-  /** the edit menu data or the parent menu data when adding a child menu */
-  rowData?: Api.SystemManage.Menu | null;
-  /** all pages */
-  allPages: string[];
-}
-
-const props = defineProps<Props>();
-
-interface Emits {
-  (e: 'submitted'): void;
-}
-
-const emit = defineEmits<Emits>();
-
-const visible = defineModel<boolean>('visible', {
-  default: false
-});
-
-const { formRef, validate, restoreValidation } = useNaiveForm();
-const { defaultRequiredRule } = useFormRules();
-
-const title = computed(() => {
-  const titles: Record<OperateType, string> = {
-    add: $t('page.manage.menu.addMenu'),
-    addChild: $t('page.manage.menu.addChildMenu'),
-    edit: $t('page.manage.menu.editMenu')
-  };
-  return titles[props.operateType];
-});
-
-type Model = Pick<
-  Api.SystemManage.Menu,
-  | 'menuType'
-  | 'menuName'
-  | 'routeName'
-  | 'routePath'
-  | 'component'
-  | 'order'
-  | 'i18nKey'
-  | 'icon'
-  | 'iconType'
-  | 'status'
-  | 'parentId'
-  | 'keepAlive'
-  | 'constant'
-  | 'href'
-  | 'hideInMenu'
-  | 'activeMenu'
-  | 'multiTab'
-  | 'fixedIndexInTab'
-> & {
-  query: NonNullable<Api.SystemManage.Menu['query']>;
-  buttons: NonNullable<Api.SystemManage.Menu['buttons']>;
-  layout: string;
-  page: string;
-  pathParam: string;
-};
-
-const model = ref(createDefaultModel());
-
-function createDefaultModel(): Model {
-  return {
-    menuType: '1',
-    menuName: '',
-    routeName: '',
-    routePath: '',
-    pathParam: '',
-    component: '',
-    layout: '',
-    page: '',
-    i18nKey: null,
-    icon: '',
-    iconType: '1',
-    parentId: 0,
-    status: '1',
-    keepAlive: false,
-    constant: false,
-    order: 0,
-    href: null,
-    hideInMenu: false,
-    activeMenu: null,
-    multiTab: false,
-    fixedIndexInTab: null,
-    query: [],
-    buttons: []
-  };
-}
-
-type RuleKey = Extract<keyof Model, 'menuName' | 'status' | 'routeName' | 'routePath'>;
-
-const rules: Record<RuleKey, App.Global.FormRule> = {
-  menuName: defaultRequiredRule,
-  status: defaultRequiredRule,
-  routeName: defaultRequiredRule,
-  routePath: defaultRequiredRule
-};
-
-const disabledMenuType = computed(() => props.operateType === 'edit');
-
-const localIcons = getLocalIcons();
-const localIconOptions = localIcons.map<SelectOption>(item => ({
-  label: () => (
-    <div class="flex-y-center gap-16px">
-      <SvgIcon localIcon={item} class="text-icon" />
-      <span>{item}</span>
-    </div>
-  ),
-  value: item
-}));
-
-const showLayout = computed(() => model.value.parentId === 0);
-
-const showPage = computed(() => model.value.menuType === '1');
-
-const pageOptions = computed(() => {
-  const allPages = [...props.allPages];
-
-  if (model.value.routeName && !allPages.includes(model.value.routeName)) {
-    allPages.unshift(model.value.routeName);
-  }
-
-  const opts: CommonType.Option[] = allPages.map(page => ({
-    label: page,
-    value: page
-  }));
-
-  return opts;
-});
-
-const layoutOptions: CommonType.Option[] = [
-  {
-    label: 'base',
-    value: 'base'
-  },
-  {
-    label: 'blank',
-    value: 'blank'
-  }
-];
-
-/** the enabled role options */
-const roleOptions = ref<CommonType.Option<string>[]>([]);
-
-async function getRoleOptions() {
-  const { error, data } = await fetchGetAllRoles();
-
-  if (!error) {
-    const options = data.map(item => ({
-      label: item.roleName,
-      value: item.roleCode
-    }));
-
-    roleOptions.value = [...options];
-  }
-}
-
-function handleInitModel() {
-  model.value = createDefaultModel();
-
-  if (!props.rowData) return;
-
-  if (props.operateType === 'addChild') {
-    const { id } = props.rowData;
-
-    Object.assign(model.value, { parentId: id });
-  }
-
-  if (props.operateType === 'edit') {
-    const { component, ...rest } = props.rowData;
-
-    const { layout, page } = getLayoutAndPage(component);
-    const { path, param } = getPathParamFromRoutePath(rest.routePath);
-
-    Object.assign(model.value, rest, { layout, page, routePath: path, pathParam: param });
-  }
-
-  if (!model.value.query) {
-    model.value.query = [];
-  }
-  if (!model.value.buttons) {
-    model.value.buttons = [];
-  }
-}
-
-function closeDrawer() {
-  visible.value = false;
-}
-
-function handleUpdateRoutePathByRouteName() {
-  if (model.value.routeName) {
-    model.value.routePath = getRoutePathByRouteName(model.value.routeName);
-  } else {
-    model.value.routePath = '';
-  }
-}
-
-function handleUpdateI18nKeyByRouteName() {
-  if (model.value.routeName) {
-    model.value.i18nKey = `route.${model.value.routeName}` as App.I18n.I18nKey;
-  } else {
-    model.value.i18nKey = null;
-  }
-}
-
-function handleCreateButton() {
-  const buttonItem: Api.SystemManage.MenuButton = {
-    code: '',
-    desc: ''
-  };
-
-  return buttonItem;
-}
-
-function getSubmitParams() {
-  const { layout, page, pathParam, ...params } = model.value;
-
-  const component = transformLayoutAndPageToComponent(layout, page);
-  const routePath = getRoutePathWithParam(model.value.routePath, pathParam);
-
-  params.component = component;
-  params.routePath = routePath;
-
-  return params;
-}
-
-async function handleSubmit() {
-  await validate();
-
-  const params = getSubmitParams();
-
-  console.log('params: ', params);
-
-  // request
-  window.$message?.success($t('common.updateSuccess'));
-  closeDrawer();
-  emit('submitted');
-}
-
-watch(visible, () => {
-  if (visible.value) {
-    handleInitModel();
-    restoreValidation();
-    getRoleOptions();
-  }
-});
-
-watch(
-  () => model.value.routeName,
-  () => {
-    handleUpdateRoutePathByRouteName();
-    handleUpdateI18nKeyByRouteName();
-  }
-);
-</script>
-
-<template>
-  <NModal v-model:show="visible" :title="title" preset="card" class="w-800px">
-    <NScrollbar class="h-480px pr-20px">
-      <NForm ref="formRef" :model="model" :rules="rules" label-placement="left" :label-width="100">
-        <NGrid responsive="screen" item-responsive>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.menuType')" path="menuType">
-            <NRadioGroup v-model:value="model.menuType" :disabled="disabledMenuType">
-              <NRadio v-for="item in menuTypeOptions" :key="item.value" :value="item.value" :label="$t(item.label)" />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.menuName')" path="menuName">
-            <NInput v-model:value="model.menuName" :placeholder="$t('page.manage.menu.form.menuName')" />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.routeName')" path="routeName">
-            <NInput v-model:value="model.routeName" :placeholder="$t('page.manage.menu.form.routeName')" />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.routePath')" path="routePath">
-            <NInput v-model:value="model.routePath" disabled :placeholder="$t('page.manage.menu.form.routePath')" />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.pathParam')" path="pathParam">
-            <NInput v-model:value="model.pathParam" :placeholder="$t('page.manage.menu.form.pathParam')" />
-          </NFormItemGi>
-          <NFormItemGi v-if="showLayout" span="24 m:12" :label="$t('page.manage.menu.layout')" path="layout">
-            <NSelect
-              v-model:value="model.layout"
-              :options="layoutOptions"
-              :placeholder="$t('page.manage.menu.form.layout')"
-            />
-          </NFormItemGi>
-          <NFormItemGi v-if="showPage" span="24 m:12" :label="$t('page.manage.menu.page')" path="page">
-            <NSelect
-              v-model:value="model.page"
-              :options="pageOptions"
-              :placeholder="$t('page.manage.menu.form.page')"
-            />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.i18nKey')" path="i18nKey">
-            <NInput v-model:value="model.i18nKey" :placeholder="$t('page.manage.menu.form.i18nKey')" />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.order')" path="order">
-            <NInputNumber v-model:value="model.order" class="w-full" :placeholder="$t('page.manage.menu.form.order')" />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.iconTypeTitle')" path="iconType">
-            <NRadioGroup v-model:value="model.iconType">
-              <NRadio
-                v-for="item in menuIconTypeOptions"
-                :key="item.value"
-                :value="item.value"
-                :label="$t(item.label)"
-              />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.icon')" path="icon">
-            <template v-if="model.iconType === '1'">
-              <NInput v-model:value="model.icon" :placeholder="$t('page.manage.menu.form.icon')" class="flex-1">
-                <template #suffix>
-                  <SvgIcon v-if="model.icon" :icon="model.icon" class="text-icon" />
-                </template>
-              </NInput>
-            </template>
-            <template v-if="model.iconType === '2'">
-              <NSelect
-                v-model:value="model.icon"
-                :placeholder="$t('page.manage.menu.form.localIcon')"
-                :options="localIconOptions"
-              />
-            </template>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.menuStatus')" path="status">
-            <NRadioGroup v-model:value="model.status">
-              <NRadio
-                v-for="item in enableStatusOptions"
-                :key="item.value"
-                :value="item.value"
-                :label="$t(item.label)"
-              />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.keepAlive')" path="keepAlive">
-            <NRadioGroup v-model:value="model.keepAlive">
-              <NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
-              <NRadio :value="false" :label="$t('common.yesOrNo.no')" />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.constant')" path="constant">
-            <NRadioGroup v-model:value="model.constant">
-              <NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
-              <NRadio :value="false" :label="$t('common.yesOrNo.no')" />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.href')" path="href">
-            <NInput v-model:value="model.href" :placeholder="$t('page.manage.menu.form.href')" />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.hideInMenu')" path="hideInMenu">
-            <NRadioGroup v-model:value="model.hideInMenu">
-              <NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
-              <NRadio :value="false" :label="$t('common.yesOrNo.no')" />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi
-            v-if="model.hideInMenu"
-            span="24 m:12"
-            :label="$t('page.manage.menu.activeMenu')"
-            path="activeMenu"
-          >
-            <NSelect
-              v-model:value="model.activeMenu"
-              :options="pageOptions"
-              clearable
-              :placeholder="$t('page.manage.menu.form.activeMenu')"
-            />
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.multiTab')" path="multiTab">
-            <NRadioGroup v-model:value="model.multiTab">
-              <NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
-              <NRadio :value="false" :label="$t('common.yesOrNo.no')" />
-            </NRadioGroup>
-          </NFormItemGi>
-          <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.fixedIndexInTab')" path="fixedIndexInTab">
-            <NInputNumber
-              v-model:value="model.fixedIndexInTab"
-              class="w-full"
-              clearable
-              :placeholder="$t('page.manage.menu.form.fixedIndexInTab')"
-            />
-          </NFormItemGi>
-          <NFormItemGi span="24" :label="$t('page.manage.menu.query')">
-            <NDynamicInput
-              v-model:value="model.query"
-              preset="pair"
-              :key-placeholder="$t('page.manage.menu.form.queryKey')"
-              :value-placeholder="$t('page.manage.menu.form.queryValue')"
-            >
-              <template #action="{ index, create, remove }">
-                <NSpace class="ml-12px">
-                  <NButton size="medium" @click="() => create(index)">
-                    <icon-ic:round-plus class="text-icon" />
-                  </NButton>
-                  <NButton size="medium" @click="() => remove(index)">
-                    <icon-ic-round-remove class="text-icon" />
-                  </NButton>
-                </NSpace>
-              </template>
-            </NDynamicInput>
-          </NFormItemGi>
-          <NFormItemGi span="24" :label="$t('page.manage.menu.button')">
-            <NDynamicInput v-model:value="model.buttons" :on-create="handleCreateButton">
-              <template #default="{ value }">
-                <div class="ml-8px flex-y-center flex-1 gap-12px">
-                  <NInput
-                    v-model:value="value.code"
-                    :placeholder="$t('page.manage.menu.form.buttonCode')"
-                    class="flex-1"
-                  />
-                  <NInput
-                    v-model:value="value.desc"
-                    :placeholder="$t('page.manage.menu.form.buttonDesc')"
-                    class="flex-1"
-                  />
-                </div>
-              </template>
-              <template #action="{ index, create, remove }">
-                <NSpace class="ml-12px">
-                  <NButton size="medium" @click="() => create(index)">
-                    <icon-ic:round-plus class="text-icon" />
-                  </NButton>
-                  <NButton size="medium" @click="() => remove(index)">
-                    <icon-ic-round-remove class="text-icon" />
-                  </NButton>
-                </NSpace>
-              </template>
-            </NDynamicInput>
-          </NFormItemGi>
-        </NGrid>
-      </NForm>
-    </NScrollbar>
-    <template #footer>
-      <NSpace justify="end" :size="16">
-        <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
-        <NButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
-      </NSpace>
-    </template>
-  </NModal>
-</template>
-
-<style scoped></style>

+ 17 - 17
src/views/manage/menu/modules/shared.ts

@@ -85,7 +85,7 @@ export function getRoutePathWithParam(routePath: string, param: string) {
 
 export const formSchems: FormSchema[] = [
   {
-    field: 'menuId',
+    field: 'id',
     label: '',
     show: false,
     component: 'NInput'
@@ -95,21 +95,21 @@ export const formSchems: FormSchema[] = [
     label: '菜单类型',
     field: 'type',
     component: 'NRadioGroup',
-    defaultValue: 1,
+    defaultValue: 'CATALOG',
     required: true,
     componentProps: {
       options: [
         {
           label: '目录',
-          value: 0
+          value: 'CATALOG'
         },
         {
           label: '菜单',
-          value: 1
+          value: 'MENU'
         },
         {
           label: '按钮',
-          value: 2
+          value: 'BUTTON'
         }
       ]
     }
@@ -137,17 +137,17 @@ export const formSchems: FormSchema[] = [
       placeholder: '输入路由名称自动生成'
     },
     ifShow({ model }) {
-      return model.type != 2;
+      return model.type != 'BUTTON';
     }
   },
 
   {
     label: '路由名称',
-    field: 'url',
+    field: 'path',
     component: 'NInput',
     required: true,
     ifShow({ model }) {
-      return model.type != 2;
+      return model.type != 'BUTTON';
     },
     render({ model, field }) {
       return h(NInput, {
@@ -157,7 +157,7 @@ export const formSchems: FormSchema[] = [
           model[field] = value;
         },
         onInput: value => {
-          if (model.type == 1) {
+          if (model.type == 'MENU') {
             const cop = model.parentId
               ? `view.${value.replace(/^\//, '').replace(/\//g, '_')}`
               : `layout.base$view.${value.replace(/^\//, '')}`;
@@ -172,14 +172,14 @@ export const formSchems: FormSchema[] = [
 
   {
     label: '排序',
-    field: 'orderNum',
+    field: 'sort',
     component: 'NInputNumber',
     defaultValue: 1,
     required: true
   },
   {
     label: '授权标识',
-    field: 'perms',
+    field: 'perm',
     component: 'NInput'
   },
   {
@@ -198,27 +198,27 @@ export const formSchems: FormSchema[] = [
       });
     },
     ifShow({ model }) {
-      return model.type != 2;
+      return model.type != 'BUTTON';
     }
   },
   {
     label: '隐藏菜单',
-    field: 'hideInMenu',
+    field: 'visible',
     component: 'NRadioGroup',
     required: true,
-    defaultValue: 0,
+    defaultValue: 1,
     ifShow({ model }) {
-      return model.type != 2;
+      return model.type != 'BUTTON';
     },
     componentProps: {
       options: [
         {
           label: '是',
-          value: 1
+          value: 0
         },
         {
           label: '否',
-          value: 0
+          value: 1
         }
       ]
     }

+ 224 - 130
src/views/manage/role/index.vue

@@ -1,151 +1,245 @@
 <script setup lang="tsx">
-import { reactive, ref } from 'vue';
-import { NButton, NPopconfirm } from 'naive-ui';
-import { fetchDelRoleMenu, fetchGetRoleList } from '@/service/api';
-import { useAppStore } from '@/store/modules/app';
-import { defaultTransform, useNaivePaginatedTable, useTableOperate } from '@/hooks/common/table';
+import { ref } from 'vue';
+import { NButton, NPopconfirm, NTag } from 'naive-ui';
+import { enableStatusRecord } from '@/constants/business';
+import {
+  fetchAddRoleMenu,
+  fetchDelRoleMenu,
+  fetchEditRoleMenu,
+  fetchGetMenuTree,
+  fetchGetRoleForm,
+  fetchGetRoleList,
+  fetchGetRoleMenuIds,
+  fetchUpdateRoleMenus
+} from '@/service/api';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
 import { $t } from '@/locales';
-import RoleOperateDrawer from './modules/role-operate-drawer.vue';
+import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+const columns: NaiveUI.TableColumn<Api.System.roleList>[] = [
+  {
+    type: 'selection',
+    align: 'center',
+    width: 48
+  },
+  {
+    key: 'index',
+    title: $t('common.index'),
+    align: 'center',
+    width: 64,
+    render: (_, index) => index + 1
+  },
+  {
+    key: 'name',
+    title: '角色名称',
+    align: 'center',
+    minWidth: 100
+  },
+  {
+    key: 'code',
+    title: '角色编码',
+    align: 'center',
+    minWidth: 100
+  },
+  {
+    key: 'status',
+    title: '状态',
+    align: 'center',
+    width: 100,
+    render: row => {
+      if (row.status === null) {
+        return null;
+      }
 
-const appStore = useAppStore();
+      const tagMap: Record<Api.Common.EnableStatus, NaiveUI.ThemeColor> = {
+        1: 'success',
+        0: 'error'
+      };
 
-const searchParams: Api.SystemManage.RoleSearchParams = reactive({
-  current: 1,
-  size: 10,
-  roleName: null,
-  roleCode: null,
-  status: null
+      const status = row.status as unknown as Api.Common.EnableStatus;
+      const label = $t(enableStatusRecord[status]);
+      return <NTag type={tagMap[status]}>{label}</NTag>;
+    }
+  }
+];
+const menuData = ref<Api.SystemManage.MenuTree[]>([]);
+const checkedKeys = ref([]);
+const rowData = ref<Api.System.roleList>();
+const [registerTable, { refresh, setTableLoading }] = useTable({
+  searchFormConfig: {
+    schemas: [
+      {
+        field: 'keywords',
+        label: '角色名称',
+        component: 'NInput'
+      }
+    ],
+    inline: false,
+    size: 'small',
+    labelPlacement: 'left',
+    isFull: false
+  },
+  tableConfig: {
+    keyField: 'id',
+    title: '角色列表',
+    showAddButton: true,
+    scrollX: 1200,
+    opWdith: 220
+  }
 });
-const delLoading = ref(false);
 
-const { columns, columnChecks, data, loading, getData, getDataByPage, mobilePagination } = useNaivePaginatedTable({
-  api: () => fetchGetRoleList(searchParams),
-  transform: response => defaultTransform(response),
-  onPaginationParamsChange: params => {
-    searchParams.current = params.page;
-    searchParams.size = params.pageSize;
+async function handleDelete(row: Recordable) {
+  setTableLoading(true);
+  await fetchDelRoleMenu([row.id].join(','));
+  refresh();
+}
+const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue, setModalLoading }] = useModalFrom({
+  modalConfig: {
+    title: '角色 ',
+    width: 800,
+    isShowHeaderText: true
   },
-  columns: () => [
-    {
-      type: 'selection',
-      align: 'center',
-      width: 48
-    },
-    {
-      key: 'index',
-      title: $t('common.index'),
-      width: 64,
-      align: 'center',
-      render: (_, index) => index + 1
-    },
-    {
-      key: 'roleName',
-      title: $t('page.manage.role.roleName'),
-      align: 'center',
-      minWidth: 120
-    },
-    {
-      key: 'remark',
-      title: $t('page.manage.role.roleDesc'),
-      minWidth: 120
-    },
-    {
-      key: 'operate',
-      title: $t('common.operate'),
-      align: 'center',
-      width: 130,
-      fixed: 'right',
-      render: row => (
-        <div class="flex-center gap-8px">
-          <NButton type="primary" ghost size="small" onClick={() => edit(row)}>
-            {$t('common.edit')}
-          </NButton>
-          <NPopconfirm onPositiveClick={() => handleDelete(row.roleId)}>
-            {{
-              default: () => $t('common.confirmDelete'),
-              trigger: () => (
-                <NButton type="error" ghost size="small" loading={delLoading.value}>
-                  {$t('common.delete')}
-                </NButton>
-              )
-            }}
-          </NPopconfirm>
-        </div>
-      )
+  formConfig: {
+    schemas: [
+      {
+        field: 'id',
+        label: '',
+        component: 'NInput',
+        show: false
+      },
+      {
+        field: 'name',
+        label: '角色名称',
+        component: 'NInput',
+        required: true
+      },
+      {
+        field: 'code',
+        label: '角色编码',
+        component: 'NInput',
+        required: true
+      },
+      {
+        field: 'dataScope',
+        label: '数据权限',
+        component: 'NSelect',
+        required: true,
+        componentProps: {
+          options: [
+            {
+              label: '全部数据',
+              value: 0
+            },
+            {
+              label: '部门及子部门数据',
+              value: 1
+            },
+            {
+              label: '本部门数据',
+              value: 2
+            },
+            {
+              label: '本人数据',
+              value: 3
+            }
+          ]
+        }
+      },
+      {
+        field: 'status',
+        label: '状态',
+        component: 'NRadioGroup',
+        required: true,
+        componentProps: {
+          options: [
+            {
+              label: '启用',
+              value: 1
+            },
+            {
+              label: '禁用',
+              value: 0
+            }
+          ]
+        },
+        defaultValue: 1
+      }
+    ],
+    labelWidth: 120,
+    gridProps: {
+      cols: '1'
     }
-  ]
+  }
 });
-
-const {
-  drawerVisible,
-  operateType,
-  editingData,
-  handleAdd,
-  handleEdit,
-  checkedRowKeys,
-  onBatchDeleted,
-  onDeleted
-  // closeDrawer
-} = useTableOperate(data, 'roleId', getData);
-
-async function handleBatchDelete() {
-  // request
-  console.log(checkedRowKeys.value);
-
-  onBatchDeleted();
+const [registerModalMenu, { openModal: openMenu, closeModal: closeMenu, setSubLoading }] = useModal({
+  title: '权限分配',
+  height: 800
+});
+async function handleSubmit() {
+  const form = await getFieldsValue();
+  if (form.id) {
+    await fetchEditRoleMenu(form);
+  } else {
+    await fetchAddRoleMenu(form);
+  }
+  closeModal();
+  refresh();
 }
 
-async function handleDelete(id: number) {
-  // request
-  if (delLoading.value) return;
-  delLoading.value = true;
-  console.log(id);
-  await fetchDelRoleMenu(id);
-  onDeleted();
-  delLoading.value = false;
+async function edit(row: Recordable) {
+  setModalLoading(true);
+  openModal(row);
+  const res = await fetchGetRoleForm(row.id);
+  setModalLoading(false);
+  setFieldsValue({ ...res.data });
 }
-
-function edit(item: any) {
-  handleEdit(item.roleId);
+async function handleOpenMenu(row: Api.System.roleList) {
+  openMenu();
+  rowData.value = row;
+  const { data } = await fetchGetMenuTree();
+  menuData.value = data as Api.SystemManage.MenuTree[];
+  const { data: menuId } = await fetchGetRoleMenuIds(Number(row.id));
+  console.log(menuId, '数据');
+  checkedKeys.value = menuId;
+}
+async function handleSubmitMenu() {
+  if (checkedKeys.value.length) {
+    setSubLoading(true);
+    await fetchUpdateRoleMenus(rowData.value?.id as number, checkedKeys.value);
+    closeMenu();
+  } else {
+    window.$message?.error('请选择需要分配的权限');
+  }
 }
 </script>
 
 <template>
-  <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
-    <!-- <RoleSearch v-model:model="searchParams" @search="getDataByPage" /> -->
-    <NCard :title="$t('page.manage.role.title')" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
-      <template #header-extra>
-        <TableHeaderOperation
-          v-model:columns="columnChecks"
-          :disabled-delete="checkedRowKeys.length === 0"
-          :loading="loading"
-          is-add
-          @add="handleAdd"
-          @delete="handleBatchDelete"
-          @refresh="getData"
-        />
+  <LayoutTable>
+    <ZTable :columns="columns" :api="fetchGetRoleList" @register="registerTable" @add="openModal">
+      <template #op="{ row }">
+        <NButton size="small" ghost type="primary" @click="handleOpenMenu(row)">分配权限</NButton>
+        <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>
-      <NDataTable
-        v-model:checked-row-keys="checkedRowKeys"
-        :columns="columns"
-        :data="data"
-        size="small"
-        :flex-height="!appStore.isMobile"
-        :scroll-x="702"
-        :loading="loading"
-        remote
-        :row-key="row => row.roleId"
-        :pagination="mobilePagination"
-        class="sm:h-full"
-      />
-      <RoleOperateDrawer
-        v-model:visible="drawerVisible"
-        :operate-type="operateType"
-        :row-data="editingData"
-        @submitted="getDataByPage"
+    </ZTable>
+    <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
+    <BasicModal @register="registerModalMenu" @ok="handleSubmitMenu">
+      <NTree
+        v-model:checked-keys="checkedKeys"
+        :data="menuData"
+        key-field="value"
+        checkable
+        default-expand-all
+        cascade
+        block-line
       />
-    </NCard>
-  </div>
+    </BasicModal>
+  </LayoutTable>
 </template>
 
 <style scoped></style>

+ 0 - 101
src/views/manage/role/modules/button-auth-modal.vue

@@ -1,101 +0,0 @@
-<script setup lang="ts">
-import { computed, shallowRef } from 'vue';
-import { $t } from '@/locales';
-
-defineOptions({
-  name: 'ButtonAuthModal'
-});
-
-interface Props {
-  /** the roleId */
-  roleId: number;
-}
-
-const props = defineProps<Props>();
-
-const visible = defineModel<boolean>('visible', {
-  default: false
-});
-
-function closeModal() {
-  visible.value = false;
-}
-
-const title = computed(() => $t('common.edit') + $t('page.manage.role.buttonAuth'));
-
-type ButtonConfig = {
-  id: number;
-  label: string;
-  code: string;
-};
-
-const tree = shallowRef<ButtonConfig[]>([]);
-
-async function getAllButtons() {
-  // request
-  tree.value = [
-    { id: 1, label: 'button1', code: 'code1' },
-    { id: 2, label: 'button2', code: 'code2' },
-    { id: 3, label: 'button3', code: 'code3' },
-    { id: 4, label: 'button4', code: 'code4' },
-    { id: 5, label: 'button5', code: 'code5' },
-    { id: 6, label: 'button6', code: 'code6' },
-    { id: 7, label: 'button7', code: 'code7' },
-    { id: 8, label: 'button8', code: 'code8' },
-    { id: 9, label: 'button9', code: 'code9' },
-    { id: 10, label: 'button10', code: 'code10' }
-  ];
-}
-
-const checks = shallowRef<number[]>([]);
-
-async function getChecks() {
-  console.log(props.roleId);
-  // request
-  checks.value = [1, 2, 3, 4, 5];
-}
-
-function handleSubmit() {
-  console.log(checks.value, props.roleId);
-  // request
-
-  window.$message?.success?.($t('common.modifySuccess'));
-
-  closeModal();
-}
-
-function init() {
-  getAllButtons();
-  getChecks();
-}
-
-// init
-init();
-</script>
-
-<template>
-  <NModal v-model:show="visible" :title="title" preset="card" class="w-480px">
-    <NTree
-      v-model:checked-keys="checks"
-      :data="tree"
-      key-field="id"
-      block-line
-      checkable
-      expand-on-click
-      virtual-scroll
-      class="h-280px"
-    />
-    <template #footer>
-      <NSpace justify="end">
-        <NButton size="small" class="mt-16px" @click="closeModal">
-          {{ $t('common.cancel') }}
-        </NButton>
-        <NButton type="primary" size="small" class="mt-16px" @click="handleSubmit">
-          {{ $t('common.confirm') }}
-        </NButton>
-      </NSpace>
-    </template>
-  </NModal>
-</template>
-
-<style scoped></style>

+ 0 - 107
src/views/manage/role/modules/menu-auth-modal.vue

@@ -1,107 +0,0 @@
-<script setup lang="ts">
-import { computed, shallowRef, watch } from 'vue';
-import { fetchGetMenuList } from '@/service/api';
-import { buildMenuTree } from '@/utils/zt';
-import { $t } from '@/locales';
-
-defineOptions({
-  name: 'MenuAuthModal'
-});
-
-interface Props {
-  /** the roleId */
-  roleId: number;
-}
-
-const props = defineProps<Props>();
-
-const visible = defineModel<boolean>('visible', {
-  default: false
-});
-
-function closeModal() {
-  visible.value = false;
-}
-
-const title = computed(() => $t('common.edit') + $t('page.manage.role.menuAuth'));
-
-const home = shallowRef('');
-
-async function getHome() {
-  console.log(props.roleId);
-  home.value = 'home';
-}
-
-const tree = shallowRef<Api.SystemManage.MenuTree[]>([]);
-
-async function getTree() {
-  const { data } = await fetchGetMenuList();
-  const menuData = buildMenuTree(data);
-  if (menuData) {
-    tree.value = menuData;
-  }
-}
-
-const checks = shallowRef<number[]>([]);
-
-// async function getChecks() {
-//   console.log(props.roleId);
-//   // request
-//   checks.value = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21];
-// }
-
-function handleSubmit() {
-  console.log(checks.value, props.roleId);
-  // request
-
-  window.$message?.success?.($t('common.modifySuccess'));
-
-  closeModal();
-}
-
-function init() {
-  getHome();
-  getTree();
-}
-
-watch(visible, val => {
-  if (val) {
-    init();
-  }
-});
-</script>
-
-<template>
-  <NModal v-model:show="visible" :title="title" preset="card" class="w-480px">
-    <!--
- <div class="flex-y-center gap-16px pb-12px">
-      <div>{{ $t('page.manage.menu.home') }}</div>
-      <NSelect :value="home" :options="pageSelectOptions" size="small" class="w-160px" @update:value="updateHome" />
-    </div>
--->
-    <NTree
-      v-model:checked-keys="checks"
-      :data="tree"
-      checkable
-      expand-on-click
-      virtual-scroll
-      block-line
-      class="h-280px"
-      label-field="name"
-      key-field="menuId"
-      cascade
-    />
-    <template #footer>
-      <NSpace justify="end">
-        <NButton size="small" class="mt-16px" @click="closeModal">
-          {{ $t('common.cancel') }}
-        </NButton>
-        <NButton type="primary" size="small" class="mt-16px" @click="handleSubmit">
-          {{ $t('common.confirm') }}
-        </NButton>
-      </NSpace>
-    </template>
-  </NModal>
-</template>
-
-<style scoped></style>

+ 0 - 150
src/views/manage/role/modules/role-operate-drawer.vue

@@ -1,150 +0,0 @@
-<script setup lang="ts">
-import { computed, ref, watch } from 'vue';
-import { fetchAddRoleMenu, fetchEditRoleMenu, fetchGetMenuList, fetchGetRoleMenuList } from '@/service/api';
-import { useFormRules, useNaiveForm } from '@/hooks/common/form';
-import { buildMenuTree } from '@/utils/zt';
-import { $t } from '@/locales';
-defineOptions({
-  name: 'RoleOperateDrawer'
-});
-
-interface Props {
-  /** the type of operation */
-  operateType: NaiveUI.TableOperateType;
-  /** the edit row data */
-  rowData?: Api.SystemManage.Role | null;
-}
-
-const props = defineProps<Props>();
-
-interface Emits {
-  (e: 'submitted'): void;
-}
-
-const emit = defineEmits<Emits>();
-
-const visible = defineModel<boolean>('visible', {
-  default: false
-});
-
-const { formRef, validate, restoreValidation } = useNaiveForm();
-const { defaultRequiredRule } = useFormRules();
-
-const title = computed(() => {
-  const titles: Record<NaiveUI.TableOperateType, string> = {
-    add: $t('page.manage.role.addRole'),
-    edit: $t('page.manage.role.editRole')
-  };
-  return titles[props.operateType];
-});
-const tree = ref([]);
-const checks = ref<number[]>([]);
-type Model = Pick<Api.SystemManage.RoleMenuList, 'roleName' | 'remark'>;
-
-const model = ref(createDefaultModel());
-
-function createDefaultModel(): Model {
-  return {
-    roleName: '',
-    remark: ''
-  };
-}
-
-type RuleKey = Exclude<keyof Model, 'remark'>;
-
-const rules: Record<RuleKey, App.Global.FormRule> = {
-  roleName: defaultRequiredRule
-};
-
-const roleId = computed(() => props.rowData?.roleId || -1);
-
-async function handleEdit() {
-  const { data } = await fetchGetRoleMenuList(roleId.value);
-  checks.value = data?.menuIdList as number[];
-}
-
-function handleInitModel() {
-  model.value = createDefaultModel();
-
-  if (props.operateType === 'edit' && props.rowData) {
-    Object.assign(model.value, props.rowData);
-    handleEdit();
-  }
-}
-
-function closeDrawer() {
-  visible.value = false;
-}
-
-async function handleSubmit() {
-  await validate();
-  // request
-
-  if (props.operateType == 'add') {
-    await fetchAddRoleMenu({ ...model.value, menuIdList: checks.value });
-  } else {
-    await fetchEditRoleMenu({ ...model.value, menuIdList: checks.value, roleId: roleId.value });
-  }
-  window.$message?.success($t('common.updateSuccess'));
-  closeDrawer();
-  emit('submitted');
-}
-async function getTree() {
-  const { data } = await fetchGetMenuList();
-  const menuData = buildMenuTree(data);
-  if (menuData) {
-    tree.value = menuData;
-  }
-}
-getTree();
-watch(visible, () => {
-  if (visible.value) {
-    handleInitModel();
-    restoreValidation();
-  }
-});
-</script>
-
-<template>
-  <NDrawer v-model:show="visible" display-directive="show" :width="360">
-    <NDrawerContent :title="title" :native-scrollbar="false" closable>
-      <NForm ref="formRef" :model="model" :rules="rules">
-        <NFormItem :label="$t('page.manage.role.roleName')" path="roleName">
-          <NInput v-model:value="model.roleName" :placeholder="$t('page.manage.role.form.roleName')" />
-        </NFormItem>
-        <NFormItem :label="$t('page.manage.role.roleDesc')" path="remark">
-          <NInput v-model:value="model.remark" :placeholder="$t('page.manage.role.form.roleDesc')" />
-        </NFormItem>
-      </NForm>
-      <!--
- <NSpace>
-        <NButton @click="openMenuAuthModal">{{ $t('page.manage.role.menuAuth') }}</NButton>
-        <MenuAuthModal v-model:visible="menuAuthVisible" :role-id="roleId" />
-
- <NButton @click="openButtonAuthModal">{{ $t('page.manage.role.buttonAuth') }}</NButton>
-        <ButtonAuthModal v-model:visible="buttonAuthVisible" :role-id="roleId" />
-
-      </NSpace>
--->
-      <NTree
-        v-model:checked-keys="checks"
-        :data="tree"
-        checkable
-        expand-on-click
-        virtual-scroll
-        block-line
-        class="h-280px"
-        label-field="name"
-        key-field="menuId"
-      />
-      <template #footer>
-        <NSpace :size="16">
-          <NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
-          <NButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</NButton>
-        </NSpace>
-      </template>
-    </NDrawerContent>
-  </NDrawer>
-</template>
-
-<style scoped></style>

+ 0 - 64
src/views/manage/role/modules/role-search.vue

@@ -1,64 +0,0 @@
-<script setup lang="ts">
-import { $t } from '@/locales';
-
-defineOptions({
-  name: 'RoleSearch'
-});
-
-interface Emits {
-  (e: 'search'): void;
-}
-
-const emit = defineEmits<Emits>();
-
-const model = defineModel<Api.SystemManage.RoleSearchParams>('model', { required: true });
-
-function resetModel() {
-  model.value = {
-    current: 1,
-    size: 10,
-    roleName: null,
-    roleCode: null,
-    status: null
-  };
-  console.log(model.value, 'asdasda');
-}
-
-function search() {
-  emit('search');
-}
-</script>
-
-<template>
-  <NCard :bordered="false" size="small" class="card-wrapper">
-    <NCollapse :default-expanded-names="['role-search']">
-      <NCollapseItem :title="$t('common.search')" name="role-search">
-        <NForm :model="model" label-placement="left" :label-width="80">
-          <NGrid responsive="screen" item-responsive>
-            <NFormItemGi span="24 s:12 m:6" :label="$t('page.manage.role.roleName')" path="roleName" class="pr-24px">
-              <NInput v-model:value="model.roleName" :placeholder="$t('page.manage.role.form.roleName')" />
-            </NFormItemGi>
-            <NFormItemGi span="24 s:12 m:6">
-              <NSpace class="w-full" justify="end">
-                <NButton @click="resetModel">
-                  <template #icon>
-                    <icon-ic-round-refresh class="text-icon" />
-                  </template>
-                  {{ $t('common.reset') }}
-                </NButton>
-                <NButton type="primary" ghost @click="search">
-                  <template #icon>
-                    <icon-ic-round-search class="text-icon" />
-                  </template>
-                  {{ $t('common.search') }}
-                </NButton>
-              </NSpace>
-            </NFormItemGi>
-          </NGrid>
-        </NForm>
-      </NCollapseItem>
-    </NCollapse>
-  </NCard>
-</template>
-
-<style scoped></style>

+ 50 - 64
src/views/manage/user/index.vue

@@ -1,6 +1,5 @@
 <script setup lang="tsx">
-import { NButton, NPopconfirm, NTag } from 'naive-ui';
-import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
+import { NButton, NImage, NPopconfirm, NTag } from 'naive-ui';
 import { enableStatusRecord } from '@/constants/business';
 import {
   fetchAddUser,
@@ -11,12 +10,11 @@ import {
   fetchGetUserList
 } from '@/service/api';
 import { fetchGetDepartmentList } from '@/service/api/system-department';
-import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
+import imgs from '@/assets/imgs/logo.png';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import { $t } from '@/locales';
 import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
-
-const columns: NaiveUI.TableColumn<InternalRowData>[] = [
+const columns: NaiveUI.TableColumn<Api.SystemManage.userList>[] = [
   {
     type: 'selection',
     align: 'center',
@@ -29,6 +27,15 @@ const columns: NaiveUI.TableColumn<InternalRowData>[] = [
     width: 64,
     render: (_, index) => index + 1
   },
+  {
+    key: 'avatar',
+    title: '头像',
+    align: 'center',
+    minWidth: 100,
+    render: row => {
+      return <NImage src={row.avatar || imgs} width={60} height={60} />;
+    }
+  },
   {
     key: 'username',
     title: $t('page.manage.user.userName'),
@@ -36,20 +43,18 @@ const columns: NaiveUI.TableColumn<InternalRowData>[] = [
     minWidth: 100
   },
   {
-    key: 'depts',
+    key: 'nickname',
+    title: $t('page.manage.user.nickName'),
+    align: 'center',
+    minWidth: 100
+  },
+  {
+    key: 'deptName',
     title: '所属部门',
     align: 'center',
     width: 220,
     ellipsis: {
       tooltip: true
-    },
-    render(row) {
-      const depts = row.depts as Recordable[];
-      let text = '';
-      depts.forEach(item => {
-        text += `${item.deptName};`;
-      });
-      return text;
     }
   },
 
@@ -60,10 +65,10 @@ const columns: NaiveUI.TableColumn<InternalRowData>[] = [
     width: 120
   },
   {
-    key: 'email',
-    title: $t('page.manage.user.userEmail'),
+    key: 'createTime',
+    title: '创建时间',
     align: 'center',
-    minWidth: 200
+    width: 120
   },
   {
     key: 'status',
@@ -77,7 +82,7 @@ const columns: NaiveUI.TableColumn<InternalRowData>[] = [
 
       const tagMap: Record<Api.Common.EnableStatus, NaiveUI.ThemeColor> = {
         1: 'success',
-        0: 'warning'
+        0: 'error'
       };
 
       const status = row.status as Api.Common.EnableStatus;
@@ -91,7 +96,7 @@ const [registerTable, { refresh, setTableLoading }] = useTable({
   searchFormConfig: {
     schemas: [
       {
-        field: 'username',
+        field: 'keywords',
         label: '用户名',
         component: 'NInput'
       }
@@ -102,15 +107,16 @@ const [registerTable, { refresh, setTableLoading }] = useTable({
     isFull: false
   },
   tableConfig: {
-    keyField: 'userId',
+    keyField: 'id',
     title: '用户列表',
-    showAddButton: true
+    showAddButton: true,
+    scrollX: 1200
   }
 });
 
 async function handleDelete(row: Recordable) {
   setTableLoading(true);
-  await fetchDeleteUser(row.userId);
+  await fetchDeleteUser([row.id].join(','));
   refresh();
 }
 const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue, updateSchema, setModalLoading }] =
@@ -123,7 +129,7 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
     formConfig: {
       schemas: [
         {
-          field: 'userId',
+          field: 'id',
           label: '',
           component: 'NInput',
           show: false
@@ -139,49 +145,22 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
           }
         },
         {
-          field: 'channelIdList',
-          label: '所属企业',
-          component: 'ApiSelect',
-          required: true,
-          componentProps: {
-            api: () => fetchGetAllChannelList(),
-            labelFeild: 'channelName',
-            valueFeild: 'id',
-            multiple: true
-          }
+          field: 'nickname',
+          label: '昵称',
+          component: 'NInput',
+          required: true
         },
         {
-          field: 'deptIds',
+          field: 'deptId',
           label: '归属部门',
           component: 'ApiTreeSelect',
           required: true,
           componentProps: {
             api: fetchGetDepartmentList,
-            labelFeild: 'deptName',
-            valueFeild: 'deptId',
+            labelFeild: 'label',
+            valueFeild: 'value',
             immediate: true,
-            resultFeild: 'data',
-            multiple: true
-          }
-        },
-        {
-          field: 'password',
-          label: '密码',
-          component: 'NInput',
-          required: true,
-          componentProps: {
-            type: 'password',
-            showPasswordOn: 'click'
-          }
-        },
-        {
-          field: 'comfirmPassword',
-          label: '确认密码',
-          component: 'NInput',
-          required: true,
-          componentProps: {
-            type: 'password',
-            showPasswordOn: 'click'
+            resultFeild: 'data'
           }
         },
         {
@@ -229,17 +208,24 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
           ]
         },
         {
-          field: 'roleIdList',
+          field: 'roleIds',
           label: '角色',
           component: 'ApiSelect',
           required: true,
           componentProps: {
             api: () => fetchGetRoleAllList(),
-            labelFeild: 'roleName',
-            valueFeild: 'roleId',
+
             multiple: true
           }
         },
+        {
+          field: 'avatar',
+          label: '头像',
+          component: 'zUpload',
+          componentProps: {
+            max: 1
+          }
+        },
         {
           field: 'status',
           label: '状态',
@@ -268,7 +254,7 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
   });
 async function handleSubmit() {
   const form = await getFieldsValue();
-  if (form.userId) {
+  if (form.id) {
     await fetchEditUser(form as Api.SystemManage.UserModel);
   } else {
     await fetchAddUser(form as Api.SystemManage.UserModel);
@@ -280,9 +266,9 @@ async function handleSubmit() {
 async function edit(row: Recordable) {
   setModalLoading(true);
   openModal(row);
-  const res = await fetchDetaileUser(row.userId);
+  const res = await fetchDetaileUser(row.id);
   setModalLoading(false);
-  setFieldsValue({ ...res.data, userId: row.userId, deptIds: res.data?.depts.map(it => it.deptId) });
+  setFieldsValue({ ...res.data });
   updateSchema([
     { field: 'password', required: false },
     { field: 'comfirmPassword', required: false }

+ 11 - 1
src/views/user-management/user-list/index.vue

@@ -1,4 +1,5 @@
-<script setup lang="tsx">
+<!--
+ <script setup lang="tsx">
 import { NImage } from 'naive-ui';
 import { fetchGetUserList } from '@/service/api/user-management/user-list';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
@@ -65,3 +66,12 @@ const [registerTable] = useTable({
 </template>
 
 <style scoped></style>
+-->
+
+<script setup lang="ts"></script>
+
+<template>
+  <div></div>
+</template>
+
+<style scoped></style>