From c5588374ba98468b7650d9669f6b4088c8a5c8aa Mon Sep 17 00:00:00 2001 From: Zzz1zz Date: Mon, 14 Jul 2025 01:15:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=9A=84=E5=8A=9F=E8=83=BD=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=92=8C=E7=94=A8=E6=88=B7=E5=88=86=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/setting.ts | 324 ++++++++----- src/components/message-box/locale/zh-CN.ts | 2 +- src/locale/zh-CN.ts | 16 + src/types/api.ts | 3 + src/views/business/space/house-view.vue | 2 +- .../user/components/change-role-drawer.vue | 98 ++++ src/views/setting/user/components/mock.json | 268 +++++++++++ .../user/components/permission-collapse.vue | 145 ++++++ .../user/components/permission-node.vue | 237 ++++++++++ .../user/components/role-form-drawer.vue | 150 ++++++ src/views/setting/user/list.vue | 4 +- src/views/setting/user/role.vue | 446 +++++++++++++++++- 12 files changed, 1562 insertions(+), 133 deletions(-) create mode 100644 src/views/setting/user/components/change-role-drawer.vue create mode 100644 src/views/setting/user/components/mock.json create mode 100644 src/views/setting/user/components/permission-collapse.vue create mode 100644 src/views/setting/user/components/permission-node.vue create mode 100644 src/views/setting/user/components/role-form-drawer.vue diff --git a/src/api/setting.ts b/src/api/setting.ts index 4f3318b..e52aeaf 100644 --- a/src/api/setting.ts +++ b/src/api/setting.ts @@ -1,6 +1,30 @@ import axios from 'axios'; +import type { UserPermission } from '@/types/api'; import { HttpResponse } from './interceptor'; +// ==================== 通用类型定义 ==================== +export interface BaseEntity { + id: number; + createdAt: string; + updatedAt: string; +} + +export interface PaginationParams { + role_id?: number | null; + page?: number; + page_size?: number; +} + +export interface PaginationResult { + total?: number; + total_pages?: number; +} + +export type UserStatus = 1 | 2; // 1: 启用, 2: 禁用 +export type ManagerStatus = 1 | 2; // 1: 是主管, 2: 否 +export type DataType = 1 | 2 | 3; // 1: 全部数据权限, 2: 自定义数据权限, 3: 仅本人数据 + +// ==================== 部门相关类型 ==================== export interface DepartmentFormParams { parent_id: number | null; name: string; @@ -12,21 +36,8 @@ export interface DepartmentFormParams { export interface DepartmentIdData { departmentId: number | string; } -type DepartmentFormRes = HttpResponse; -// 创建部门 -export function createDepartment( - params: DepartmentFormParams -): Promise { - return axios.post('/department/createDepartment', params); -} -// 更新(编辑)部门 -export function updateDepartment( - params: DepartmentFormParams -): Promise { - return axios.post('/department/updateDepartment', params); -} -export interface DepartmentItem { - id: number; + +export interface DepartmentItem extends BaseEntity { systemTenantId: number; name: string; parentId: number; @@ -35,24 +46,127 @@ export interface DepartmentItem { path: string; remark: string; isDelete: number; - createdAt: string; - updatedAt: string; sort: number; children?: DepartmentItem[]; // 递归结构 isShowEditIcon?: boolean; // 是否展示编辑icon username?: string; parentName?: string; } + +export interface DepartmentDetailData { + department: DepartmentItem; +} + +// ==================== 用户相关类型 ==================== +export interface UserItem { + id: number; + username: string; + realname: string; + email: string; + tel: string; + status: UserStatus; + roleId: number; + departmentId: number; + roleName: string; + deptName: string; + lastLoginTime: string; +} + +export interface FormUserItem { + username: string; + realname: string; + tel: string | number; + password: string; + repassword: string; + role_id: number | null; + department_id: number | null; + email: string; + is_manager: ManagerStatus; +} + +export interface DisableUserParam { + id: number; + status: UserStatus; +} + +export interface UserInfo { + user: FormUserItem; +} + +export interface AllUserList { + page: PaginationParams & PaginationResult; + user?: UserItem[]; + userList?: UserItem[]; +} + +// ==================== 角色相关类型 ==================== +export interface RoleItem extends BaseEntity { + systemTenantId: number; + name: string; + createUserId?: number; + isDelete?: number; + remark?: string; + dataType: DataType; +} + +export interface RoleFormParam { + id?: number; + name: string; + remark?: string; +} + +export interface RoleList { + rolesList: RoleItem[]; +} + +export interface UserPermissionItem { + permission: UserPermission; +} + +export interface UserPermissionItemList { + permission: number[]; +} + +export interface SaveRolePermissionParam { + id: number; + children?: Array<{ + id: number; + path: string; + }>; +} +export interface UpdateUserRoleParam { + role_id: number | null; + user_id: number | null; +} + +// ==================== 响应类型别名 ==================== +export type DepartmentFormRes = HttpResponse; export type DepartmentList = DepartmentItem[]; export type DepartmentListRes = HttpResponse<{ departmentList: DepartmentItem[]; }>; -export interface DepartmentDetailData { - department: DepartmentItem; -} export type DepartmentDetailRes = HttpResponse; +export type UserList = UserItem[]; +export type UserListRes = HttpResponse; +export type AllUserListRes = HttpResponse; +export type UserInfoRes = HttpResponse; +export type RoleListRes = HttpResponse; +export type PermissionRes = HttpResponse; +export type RolePermissionRes = HttpResponse; + +// ==================== 部门相关 API ==================== +export function createDepartment( + params: DepartmentFormParams +): Promise { + return axios.post('/department/createDepartment', params); +} + +export function updateDepartment( + params: DepartmentFormParams +): Promise { + return axios.post('/department/updateDepartment', params); +} -// 获取部门列表 export function getDepartmentList(): Promise { return axios.get('/department/getDepartmentList'); } @@ -61,137 +175,89 @@ export function getDepartmentDetail(id: number): Promise { return axios.get(`/department/getDepartment?id=${id}`); } -export interface UserItem { - id: number; // 用户id - username: string; // 用户名称 - realname: string; // 姓名 - email: string; // 邮箱 - tel: string; // 手机号 - status: 1 | 2; // 状态:1 启用,2 禁用 - roleId: number; // 角色id - departmentId: number; // 部门id - roleName: string; // 角色名称 - deptName: string; // 部门名称 - lastLoginTime: string; // 最后登录时间 -} -export type UserList = UserItem[]; -export type UserListRes = HttpResponse; -export interface Pagination { - page: number; - page_size: number; - total?: number; - total_pages?: number; -} -export interface AllUserList { - page: Pagination; - user: UserListRes; -} -export type AllUserListRes = HttpResponse; -// 后台-用户列表(除主管外所有用户) -export function getAllUserList(params): Promise { - return axios.post('/user/getAllUserList', params); -} -// 后台-用户列表(所有用户) -export function getUserList(params): Promise { - return axios.post('/user/getUserList', params); -} -export interface FormUserItem { - username: string; // 用户名 - realname: string; // 姓名 - tel: string | number; // 手机号 - password: string; // 密码 - repassword: string; // 确认密码 - role_id: number | null; // 角色id - department_id: number | null; // 部门id - email: string; // 邮件 - is_manager: 1 | 2; // 是否为主管:1是,2否 -} -// 创建用户 -export function createUser(params: FormUserItem): Promise { - return axios.post('/user/createUser', params); -} -// 更新用户信息 -export function updateUser(params: FormUserItem): Promise { - return axios.post('/user/updateUser', params); -} -interface UserInfo { - user: FormUserItem; -} -export type UserInfoRES = HttpResponse; -// 获取用户信息 -export function getUserInfo(id: number): Promise { - return axios.get(`/user/getUser?id=${id}`); -} -// 删除用户 -export function delUser(id: number): Promise { - return axios.get(`/user/delUser?id=${id}`); -} -export interface DisableUserParam { - id: number; - status: number; -} -// 禁用启用用户 -export function disableUser(params: DisableUserParam): Promise { - return axios.post('/user/disableUser', params); -} - -// 部门-向上移动 export function departmentSetUp(id: number): Promise { return axios.get(`/department/setUp?id=${id}`); } -// 部门-向下移动 + export function departmentSetDown(id: number): Promise { return axios.get(`/department/setDown?id=${id}`); } -// 删除部门 + export function delDepartment(id: number): Promise { return axios.get(`/department/delDepartment?id=${id}`); } -export interface RoleItem { - id: number; // 角色id - systemTenantId: number; // 租户名称 - name: string; // 角色名称 - createUserId?: number; // 创建人id - isDelete?: number; // 是否删除 - remark?: string; - dataType: number; // 数据权限类型:1全部数据权限,2自定义数据权限,3仅本人数据 - createdAt: string; - updatedAt: string; +// ==================== 用户相关 API ==================== +export function getAllUserList( + params: PaginationParams +): Promise { + return axios.post('/user/getAllUserList', params); } -// 角色列表 -export interface RoleList { - rolesList: RoleItem[]; + +export function getUserList(params: PaginationParams): Promise { + return axios.post('/user/getUserList', params); } -export type RoleListRes = HttpResponse; -// 角色列表 + +export function createUser(params: FormUserItem): Promise { + return axios.post('/user/createUser', params); +} + +export function updateUser(params: FormUserItem): Promise { + return axios.post('/user/updateUser', params); +} + +export function getUserInfo(id: number): Promise { + return axios.get(`/user/getUser?id=${id}`); +} + +export function delUser(id: number): Promise { + return axios.get(`/user/delUser?id=${id}`); +} + +export function disableUser(params: DisableUserParam): Promise { + return axios.post('/user/disableUser', params); +} + +// ==================== 角色相关 API ==================== export function getRoleList(): Promise { return axios.get('/role/getRoleList'); } -// 创建角色 -export interface RoleFormParam { - id?: number; // 角色id - name: string; // 姓名 - remark?: string; // 备注 -} export function createRole(params: RoleFormParam): Promise { return axios.post('/role/createRole', params); } -// 更新角色 + export function updateRole(params: RoleFormParam): Promise { return axios.post('/role/updateRole', params); } -// 删除角色 + export function delRole(id: number): Promise { return axios.get(`/role/delRole?id=${id}`); } -// // 项目信息 -// export function getProjectDetail(id: string) { -// return axios.get(`/project/getProject?id=${id}`); -// } -// // 项目列表(分页) -// export function queryPolicyList(params: ProjectParams) { -// return axios.post('/project/getProjectList', { params }); -// } +export function getPermissionList(): Promise { + return axios.get('/role/getPermissionList'); +} + +export function getRolePermission(id: number): Promise { + return axios.get(`role/getRolePermission?id=${id}`); +} + +export function saveRolePermission( + params: SaveRolePermissionParam +): Promise { + return axios.post('role/saveRolePermission', params); +} + +// 角色下的用户列表 +export function getUserListFromRole( + params: PaginationParams +): Promise { + return axios.post('role/getUserList', params); +} +// 角色下的用户列表 +export function updateUserRole( + params: UpdateUserRoleParam +): Promise { + return axios.post('role/updateUserRole', params); +} diff --git a/src/components/message-box/locale/zh-CN.ts b/src/components/message-box/locale/zh-CN.ts index cf3e630..9ffcb6b 100644 --- a/src/components/message-box/locale/zh-CN.ts +++ b/src/components/message-box/locale/zh-CN.ts @@ -9,5 +9,5 @@ export default { 'messageBox.switchRoles': '切换角色', 'messageBox.userCenter': '用户中心', 'messageBox.userSettings': '用户设置', - 'messageBox.logout': '登出登录', + 'messageBox.logout': '退出登录', }; diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index f294472..3371751 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -97,6 +97,22 @@ export default { 'edit': '编辑', 'more': '更多', 'user': '用户', + 'role.list': '角色列表', + 'role.add': '新增角色', + 'role.edit': '编辑角色', + 'roleName': '角色名称', + 'roleDesc': '角色描述', + 'permission': '权限', + 'function.permission': '功能权限', + 'data.permission': '数据权限', + 'user.assignment': '用户分配', + 'submit': '保存', + 'last.updated': '最后更新', + 'all.checked': '全部选中', + 'all.clear': '全部清空', + 'function.permission.setting': '功能权限设置', + 'user.assignment.setting': '用户分配设置', + 'change.role': '变更角色', ...localeSettings, ...localeMessageBox, diff --git a/src/types/api.ts b/src/types/api.ts index 20fe34d..074b947 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -72,4 +72,7 @@ export interface UserPermission { visible: 1 | 2; // 是否可见:1显示、2隐藏 createdAt: string; // 创建时间 updatedAt: string; // 更新时间 + system_tenant_permission_id?: number; // 租客权限id + tenant_id?: number; // 租客id + children?: UserPermission[] | []; // 子集 } diff --git a/src/views/business/space/house-view.vue b/src/views/business/space/house-view.vue index df27c4b..8832739 100644 --- a/src/views/business/space/house-view.vue +++ b/src/views/business/space/house-view.vue @@ -1,3 +1,3 @@ diff --git a/src/views/setting/user/components/change-role-drawer.vue b/src/views/setting/user/components/change-role-drawer.vue new file mode 100644 index 0000000..eb8126f --- /dev/null +++ b/src/views/setting/user/components/change-role-drawer.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/views/setting/user/components/mock.json b/src/views/setting/user/components/mock.json new file mode 100644 index 0000000..7edb5d4 --- /dev/null +++ b/src/views/setting/user/components/mock.json @@ -0,0 +1,268 @@ +{ + "permission": [ + { + "system_tenant_permission_id": 100, + "tenant_id": 1, + "perm_id": 1, + "id": 1, + "parent_id": 0, + "prem_name": "业务", + "level": 1, + "perm_key": "business", + "prem_type": 1, + "path": "/1/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:00:00", + "updatedAt": "2024-06-20 10:00:00", + "children": [ + { + "system_tenant_permission_id": 101, + "tenant_id": 1, + "perm_id": 2, + "id": 2, + "parent_id": 1, + "prem_name": "项目管理", + "level": 2, + "perm_key": "project_manage", + "prem_type": 1, + "path": "/1/2/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:01:00", + "updatedAt": "2024-06-20 10:01:00", + "children": [ + { + "system_tenant_permission_id": 102, + "tenant_id": 1, + "perm_id": 3, + "id": 3, + "parent_id": 2, + "prem_name": "查看项目", + "level": 3, + "perm_key": "view_project", + "prem_type": 4, + "path": "/1/2/3/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:02:00", + "updatedAt": "2024-06-20 10:02:00", + "children": [ + { + "system_tenant_permission_id": 103, + "tenant_id": 1, + "perm_id": 4, + "id": 4, + "parent_id": 3, + "prem_name": "添加收入目标", + "level": 4, + "perm_key": "add_income_target", + "prem_type": 2, + "path": "/1/2/3/4/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:03:00", + "updatedAt": "2024-06-20 10:03:00", + "children": [] + }, + { + "system_tenant_permission_id": 104, + "tenant_id": 1, + "perm_id": 5, + "id": 5, + "parent_id": 3, + "prem_name": "编辑收入目标", + "level": 4, + "perm_key": "edit_income_target", + "prem_type": 2, + "path": "/1/2/3/5/", + "sort": 2, + "visible": 1, + "createdAt": "2024-06-20 10:04:00", + "updatedAt": "2024-06-20 10:04:00", + "children": [] + } + ] + }, + { + "system_tenant_permission_id": 105, + "tenant_id": 1, + "perm_id": 6, + "id": 6, + "parent_id": 2, + "prem_name": "编辑项目", + "level": 3, + "perm_key": "edit_project", + "prem_type": 4, + "path": "/1/2/6/", + "sort": 2, + "visible": 1, + "createdAt": "2024-06-20 10:05:00", + "updatedAt": "2024-06-20 10:05:00", + "children": [ + { + "system_tenant_permission_id": 106, + "tenant_id": 1, + "perm_id": 7, + "id": 7, + "parent_id": 6, + "prem_name": "删除收入目标", + "level": 4, + "perm_key": "delete_income_target", + "prem_type": 2, + "path": "/1/2/6/7/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:06:00", + "updatedAt": "2024-06-20 10:06:00", + "children": [] + } + ] + } + ] + }, + { + "system_tenant_permission_id": 107, + "tenant_id": 1, + "perm_id": 8, + "id": 8, + "parent_id": 1, + "prem_name": "合同管理", + "level": 2, + "perm_key": "contract_manage", + "prem_type": 1, + "path": "/1/8/", + "sort": 2, + "visible": 1, + "createdAt": "2024-06-20 10:07:00", + "updatedAt": "2024-06-20 10:07:00", + "children": [ + { + "system_tenant_permission_id": 108, + "tenant_id": 1, + "perm_id": 9, + "id": 9, + "parent_id": 8, + "prem_name": "查看合同", + "level": 3, + "perm_key": "view_contract", + "prem_type": 4, + "path": "/1/8/9/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:08:00", + "updatedAt": "2024-06-20 10:08:00", + "children": [ + { + "system_tenant_permission_id": 109, + "tenant_id": 1, + "perm_id": 10, + "id": 10, + "parent_id": 9, + "prem_name": "导出合同", + "level": 4, + "perm_key": "export_contract", + "prem_type": 2, + "path": "/1/8/9/10/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 10:09:00", + "updatedAt": "2024-06-20 10:09:00", + "children": [] + } + ] + } + ] + } + ] + }, + { + "system_tenant_permission_id": 200, + "tenant_id": 1, + "perm_id": 20, + "id": 20, + "parent_id": 0, + "prem_name": "房源视图", + "level": 1, + "perm_key": "house_view", + "prem_type": 1, + "path": "/20/", + "sort": 2, + "visible": 1, + "createdAt": "2024-06-20 11:00:00", + "updatedAt": "2024-06-20 11:00:00", + "children": [ + { + "system_tenant_permission_id": 201, + "tenant_id": 1, + "perm_id": 21, + "id": 21, + "parent_id": 20, + "prem_name": "新建房源", + "level": 2, + "perm_key": "add_house", + "prem_type": 2, + "path": "/20/21/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 11:01:00", + "updatedAt": "2024-06-20 11:01:00", + "children": [] + }, + { + "system_tenant_permission_id": 202, + "tenant_id": 1, + "perm_id": 22, + "id": 22, + "parent_id": 20, + "prem_name": "导入房源", + "level": 2, + "perm_key": "import_house", + "prem_type": 3, + "path": "/20/22/", + "sort": 2, + "visible": 1, + "createdAt": "2024-06-20 11:02:00", + "updatedAt": "2024-06-20 11:02:00", + "children": [ + { + "system_tenant_permission_id": 203, + "tenant_id": 1, + "perm_id": 23, + "id": 23, + "parent_id": 22, + "prem_name": "批量导入", + "level": 3, + "perm_key": "batch_import", + "prem_type": 3, + "path": "/20/22/23/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 11:03:00", + "updatedAt": "2024-06-20 11:03:00", + "children": [ + { + "system_tenant_permission_id": 204, + "tenant_id": 1, + "perm_id": 24, + "id": 24, + "parent_id": 23, + "prem_name": "导入校验", + "level": 4, + "perm_key": "import_check", + "prem_type": 2, + "path": "/20/22/23/24/", + "sort": 1, + "visible": 1, + "createdAt": "2024-06-20 11:04:00", + "updatedAt": "2024-06-20 11:04:00", + "children": [] + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/views/setting/user/components/permission-collapse.vue b/src/views/setting/user/components/permission-collapse.vue new file mode 100644 index 0000000..c0bf233 --- /dev/null +++ b/src/views/setting/user/components/permission-collapse.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/setting/user/components/permission-node.vue b/src/views/setting/user/components/permission-node.vue new file mode 100644 index 0000000..8488cc9 --- /dev/null +++ b/src/views/setting/user/components/permission-node.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/src/views/setting/user/components/role-form-drawer.vue b/src/views/setting/user/components/role-form-drawer.vue new file mode 100644 index 0000000..0801168 --- /dev/null +++ b/src/views/setting/user/components/role-form-drawer.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/src/views/setting/user/list.vue b/src/views/setting/user/list.vue index a83ca6d..2505403 100644 --- a/src/views/setting/user/list.vue +++ b/src/views/setting/user/list.vue @@ -133,6 +133,7 @@ FormUserItem, disableUser, delUser, + UserStatus, } from '@/api/setting'; import useDepartmentList from '@/composables/useDepartmentList'; import useDataTable from '@/composables/useDataTable'; @@ -329,7 +330,8 @@ }; const handleDisableUser = async (id: number, currentStatus: number) => { try { - const param = { id, status: currentStatus === 1 ? 2 : 1 }; + const status: UserStatus = currentStatus === 1 ? 2 : 1; + const param = { id, status }; const { code, message } = await disableUser(param); if (code === 200) { Message.success(message); diff --git a/src/views/setting/user/role.vue b/src/views/setting/user/role.vue index 0752538..912a723 100644 --- a/src/views/setting/user/role.vue +++ b/src/views/setting/user/role.vue @@ -1,3 +1,447 @@ + + + +