From 11a8971ee9492b701027a81d5ebf71f5e04b3197 Mon Sep 17 00:00:00 2001 From: AaronWu <2463371514@qq.com> Date: Tue, 1 Apr 2025 09:41:38 +0800 Subject: [PATCH] feat: add user manage module --- src/api/typings.d.ts | 62 +++--- src/api/user/index.ts | 155 +++++++++++++++ src/api/user/model.d.ts | 44 ++++ src/locales/lang/en-US/routes/system.ts | 9 + src/locales/lang/zh-CN/routes/system.ts | 1 + src/router/staticModules/system.ts | 20 +- src/views/system/user/columns.tsx | 143 +++++++++++++ src/views/system/user/data.ts | 14 ++ src/views/system/user/formSchemas.ts | 100 ++++++++++ src/views/system/user/index.vue | 254 ++++++++++++++++++++++++ 10 files changed, 773 insertions(+), 29 deletions(-) create mode 100644 src/api/user/index.ts create mode 100644 src/api/user/model.d.ts create mode 100644 src/views/system/user/columns.tsx create mode 100644 src/views/system/user/data.ts create mode 100644 src/views/system/user/formSchemas.ts create mode 100644 src/views/system/user/index.vue diff --git a/src/api/typings.d.ts b/src/api/typings.d.ts index 643b9c9..7c345b9 100644 --- a/src/api/typings.d.ts +++ b/src/api/typings.d.ts @@ -1,37 +1,43 @@ +/* + * @Author: AaronWu 2463371514@qq.com + * @Date: 2025-03-31 15:12:17 + * @LastEditors: AaronWu 2463371514@qq.com + * @LastEditTime: 2025-04-01 09:14:02 + * @FilePath: /IssueSupportManage/src/api/typings.d.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ // @ts-ignore /* eslint-disable */ declare namespace API { + /** 查询列表参数 */ + type SearchListParams = { + name?: string; + }; + /** 查询分页列表参数 */ + type SearchPageListParams = { + model: SearchListParams; + current: number; + size: number; + sort?: string; + order?: string; + }; - /** 查询列表参数 */ - type SearchListParams = { - name?: string; - }; - - /** 查询分页列表参数 */ - type SearchPageListParams = { - model: SearchListParams; - current: number; - size: number; - sort?: string; - order?: string; - }; - - /** 查询列表成功结果 */ - type SearchListResult = any[] - - /** 查询分页列表成功结果 */ - type SearchPageListResult = { - // code: string; - // data: { - // list:TenantInfoType[] - // total:string - // }; - // msg: string; - list:any[] - total:string - }; + /** 查询列表成功结果 */ + type SearchListResult = any[]; + + /** 查询分页列表成功结果 */ + type SearchPageListResult = { + // code: string; + // data: { + // list:TenantInfoType[] + // total:string + // }; + // msg: string; + list: any[]; + total: string; + }; /** 全局通过表格查询返回结果 */ type TableListResult = { diff --git a/src/api/user/index.ts b/src/api/user/index.ts new file mode 100644 index 0000000..0bb42c4 --- /dev/null +++ b/src/api/user/index.ts @@ -0,0 +1,155 @@ +import type { BaseResponse } from '@/utils/request'; +import { request } from '@/utils/request'; +/** + * @description 查询列表 + * @param {SearchListParams} data + * @returns + */ +export function fetchUserList(data: API.SearchListParams) { + return request>( + { + url: 'user/query', + method: 'post', + data, + }, + { + isGetDataDirectly: false, + }, + ); +} + +/** + * @description 获取租户下绑定的用户 + * @param {SearchPageListParams} data + * @returns + */ +export function fetchTenantBindUsers(data: any) { + return request>( + { + url: `tenantUser/bindPage?tenantId=${data.tenantId}`, + method: 'post', + data, + }, + { + isGetDataDirectly: false, + }, + ); +} + +/** + * @description 获取租户下未绑定的用户 + * @param {SearchPageListParams} data + * @returns + */ +export function fetchUnTenantBindUsers(data: any) { + return request>( + { + url: `tenantUser/unBindPage?tenantId=${data.tenantId}`, + method: 'post', + data, + }, + { + isGetDataDirectly: false, + }, + ); +} + +/** + * @description 授权租户管理员 + * @param data + * @returns + */ +export function assignTenantAdmin(data: { tenantId?: string; userId?: string; isAdmin?: boolean }) { + return request({ + url: `tenantUser/assignTenantAdmin`, + method: 'post', + data, + }); +} + +/** + * @description 查询分页列表 + * @param {SearchPageListParams} data + * @returns + */ +export function fetchUserPageList(data: API.SearchPageListParams) { + return request>( + { + url: 'user/page', + method: 'post', + data, + }, + { + isGetDataDirectly: false, + }, + ); +} + +/** + * @description 新增单条 + * @param {UserInfoType} data + * @returns + */ +export function createUser(data: API.UserInfoType) { + return request>( + { + url: 'user/create', + method: 'post', + data, + }, + { + isGetDataDirectly: false, + }, + ); +} + +/** + * @description 修改单条 + * @param {UserInfoType} data + * @returns + */ +export function updateUser(data: API.UserInfoType) { + return request>( + { + url: 'user/update', + method: 'post', + data, + }, + { + isGetDataDirectly: false, + }, + ); +} + +/** + * @description 查询单条 + */ +export function findOneById(params: { id: string }) { + return request({ + url: `user/getById`, + method: 'get', + params, + }); +} + +/** + * @description 删除单条 ?id=${data.id} + */ +export function deleteUserById(params: API.DeleteUserParams) { + return request({ + url: `user/delById`, + method: 'post', + params, + }); +} + +/** + * @description 删除多条 + */ +export function deleteBatchUserById(data: API.DeleteBatchUserParams) { + return request({ + url: `user/deleteBatch`, + method: 'delete', + data, + }); +} diff --git a/src/api/user/model.d.ts b/src/api/user/model.d.ts new file mode 100644 index 0000000..dfd123f --- /dev/null +++ b/src/api/user/model.d.ts @@ -0,0 +1,44 @@ +/* + * @Author: AaronWu 2463371514@qq.com + * @Date: 2025-04-01 09:09:04 + * @LastEditors: AaronWu 2463371514@qq.com + * @LastEditTime: 2025-04-01 09:14:00 + * @FilePath: /IssueSupportManage/src/api/user/model.d.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +declare namespace API { + /** 用户信息类型 */ + type UserInfoType = { + id?: string; + userId?: string; + pendingStatus?: boolean; + username: string; + realName: any; + mobile: string; + idCard: string; + sex: string; + avatar: string; + state: number; + remark: string; + createTime: string; + isAdmin?: boolean; + }; + + type CreateUserParams = { + username: string; + realName: any; + mobile: string; + idCard: string; + sex: string; + avatar: string; + state: number; + remark: string; + isAdmin?: boolean; + }; + + type DeleteUserParams = { + id: string; + }; + + type DeleteBatchUserParams = string[]; +} diff --git a/src/locales/lang/en-US/routes/system.ts b/src/locales/lang/en-US/routes/system.ts index 9d1fb3d..695d8a6 100644 --- a/src/locales/lang/en-US/routes/system.ts +++ b/src/locales/lang/en-US/routes/system.ts @@ -1,4 +1,13 @@ +/* + * @Author: AaronWu 2463371514@qq.com + * @Date: 2025-03-31 15:38:04 + * @LastEditors: AaronWu 2463371514@qq.com + * @LastEditTime: 2025-04-01 09:11:14 + * @FilePath: /IssueSupportManage/src/locales/lang/en-US/routes/system.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ export default { system: 'system', dictionary: 'Dictionary', + user: 'User', }; diff --git a/src/locales/lang/zh-CN/routes/system.ts b/src/locales/lang/zh-CN/routes/system.ts index 9bd38c2..6da83bd 100644 --- a/src/locales/lang/zh-CN/routes/system.ts +++ b/src/locales/lang/zh-CN/routes/system.ts @@ -1,4 +1,5 @@ export default { system: '系统管理', dictionary: '字典维护', + user: '用户管理', }; diff --git a/src/router/staticModules/system.ts b/src/router/staticModules/system.ts index e6749af..c3b9c69 100644 --- a/src/router/staticModules/system.ts +++ b/src/router/staticModules/system.ts @@ -1,3 +1,11 @@ +/* + * @Author: AaronWu 2463371514@qq.com + * @Date: 2025-03-31 15:36:46 + * @LastEditors: AaronWu 2463371514@qq.com + * @LastEditTime: 2025-04-01 09:11:18 + * @FilePath: /IssueSupportManage/src/router/staticModules/system.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ import type { RouteRecordRaw } from 'vue-router'; import RouterView from '@/layout/routerView/index.vue'; import { t } from '@/hooks/useI18n'; @@ -25,7 +33,17 @@ const routes: Array = [ component: () => import(/* webpackChunkName: "system-dictionary" */ '@/views/system/dictionary/index.vue'), }, - + { + path: 'user', + name: `${moduleName}-user`, + meta: { + title: t('routes.system.user'), + icon: 'icon-yonghu', + keepAlive: true, + }, + component: () => + import(/* webpackChunkName: "tenant-user" */ '@/views/system/user/index.vue'), + }, ], }, ]; diff --git a/src/views/system/user/columns.tsx b/src/views/system/user/columns.tsx new file mode 100644 index 0000000..33c88c9 --- /dev/null +++ b/src/views/system/user/columns.tsx @@ -0,0 +1,143 @@ +import { debounce } from 'lodash-es'; +import type { TableColumn } from '@/components/core/dynamic-table'; +import { formatToDateTime } from '@/utils/dateUtil'; +import { updateUser } from '@/api/user'; +import { h } from 'vue'; +import { Switch } from 'ant-design-vue'; +import { sexTypeList } from './data'; +export type TableListItem = API.UserInfoType; +export type TableColumnItem = TableColumn; +// 数据项类型 +// export type ListItemType = typeof tableData[number]; +// 使用TableColumn 将会限制dataIndex的类型,但换来的是dataIndex有类型提示 +export const baseColumns: TableColumnItem[] = [ + // { + // title: '用户名', + // align: 'center', + // dataIndex: 'username', + // // sorter: true, + // width: 150, + // resizable: true, + // formItemProps: { + // defaultValue: '', + // required: false, + // }, + // }, + { + title: '姓名', + align: 'center', + dataIndex: 'realName', + width: 150, + resizable: true, + formItemProps: { + defaultValue: '', + required: false, + }, + }, + { + title: '手机号码', + align: 'center', + dataIndex: 'mobile', + width: 150, + formItemProps: { + defaultValue: '', + required: false, + }, + }, + // { + // title: '身份证', + // align: 'center', + // dataIndex: 'idCard', + // width: 150, + // formItemProps: { + // defaultValue: '', + // required: false, + // }, + // }, + + { + title: '性别', + align: 'center', + dataIndex: 'sex', + width: 100, + formItemProps: { + defaultValue: '', + required: false, + component: 'Select', + label: '性别', + componentProps: { + mode: 'single', + request: async () => { + // const data = await getSexList(); + return sexTypeList; + }, + }, + }, + customRender: ({ record }) => { + const text = sexTypeList.find((e) => e.value === record.sex)?.label; + return
{text}
; + }, + }, + { + title: '帐号状态', + align: 'center', + width: 100, + dataIndex: 'state', + hideInSearch: true, + formItemProps: { + component: 'Select', + componentProps: { + options: [ + { + label: '启用', + value: 1, + }, + { + label: '禁用', + value: 0, + }, + ], + }, + }, + customRender: ({ record }) => { + const onChange = (checked: boolean) => { + console.log('checked: ', checked); + record.pendingStatus = true; + const newState = checked ? 1 : 0; + record.state = newState; + updateUser(record) + .then(() => { + record.state = newState; + }) + .catch(() => {}) + .finally(() => { + record.pendingStatus = false; + }); + }; + // return ( + // + // ); + // 渲染函数写法 + return h(Switch, { + checked: record.state === 1 ? true : false, + loading: record.pendingStatus, + onChange, + }); + }, + }, + { + title: '创建时间', + align: 'center', + width: 200, + dataIndex: 'createTime', + formItemProps: { + defaultValue: '', + required: false, + component: 'RangePicker', + }, + }, +]; diff --git a/src/views/system/user/data.ts b/src/views/system/user/data.ts new file mode 100644 index 0000000..bdb34c7 --- /dev/null +++ b/src/views/system/user/data.ts @@ -0,0 +1,14 @@ +export const sexTypeList:any = [ + { + label: '男', + value: 1, + }, + { + label: '女', + value: 2, + }, + { + label: '未知', + value: 3, + }, +]; diff --git a/src/views/system/user/formSchemas.ts b/src/views/system/user/formSchemas.ts new file mode 100644 index 0000000..2da1176 --- /dev/null +++ b/src/views/system/user/formSchemas.ts @@ -0,0 +1,100 @@ +import type { FormSchema } from '@/components/core/schema-form/'; +import { sexTypeList } from './data'; + +export const userSchemas: FormSchema[] = [ + // { + // field: 'username', + // component: 'Input', + // label: '用户名', + // colProps: { + // span: 12, + // }, + // rules: [{ required: true }], + // }, + { + field: 'realName', + component: 'Input', + label: '姓名', + colProps: { + span: 12, + }, + rules: [{ required: true }], + }, + { + field: 'mobile', + component: 'Input', + label: '手机号码', + colProps: { + span: 12, + }, + rules: [ + { + required: true, + message: '请输入正确格式的电话号码', + pattern: /^1(3[0-9]|4[01456879]|5[0-3,5-9]|6[2567]|7[0-8]|8[0-9]|9[0-3,5-9])\d{8}$/, + }, + ], + }, + // { + // field: 'idCard', + // component: 'Input', + // label: '身份证', + // colProps: { + // span: 12, + // }, + // }, + + { + field: 'sex', + component: 'Select', + label: '性别', + colProps: { + span: 12, + }, + componentProps: { + mode: 'single', + request: async () => { + // const data = await getSexList(); + return sexTypeList; + }, + }, + }, + { + field: 'avatar', + component: 'Input', + colProps: { + span: 12, + }, + label: '头像', + }, + { + field: 'state', + component: 'RadioGroup', + label: '帐号状态', + defaultValue: true, + colProps: { + span: 12, + }, + componentProps: { + options: [ + { + label: '启用', + value: 1, + }, + { + label: '禁用', + value: 0, + }, + ], + }, + // required:true, + rules: [{ required: true, type: 'number' }], + + }, + + { + field: 'remark', + component: 'InputTextArea', + label: '备注', + }, +]; diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue new file mode 100644 index 0000000..75de11d --- /dev/null +++ b/src/views/system/user/index.vue @@ -0,0 +1,254 @@ + + + + + +