feat(system): 完善系统管理接口及权限管理功能
Some checks failed
Lint Code / Lint Code (push) Failing after 10m12s

- 删除 mock 中系统管理路由冗余数据,前端统一路由管理
- 飞书登录接口响应数据结构重构,新增登录状态及用户信息查询方法
- 重构系统接口模块,新增权限、角色、用户、部门、菜单等完整类型及API实现
- 新增项目初始化相关接口及数据类型支持
- 调整登录页及相关调用,适配飞书登录新接口返回
- 统一接口响应状态码判定,修正多处 code === 0 为 code === 200
- 新增系统管理路由模块,包含用户、角色、权限、菜单、部门页面
- 账号设置页面新增角色与权限展示,丰富用户信息显示
- 权限管理页面新增增删改查功能,提供表单校验与列表操作
- 优化权限表格展示和操作体验,支持批量删除及树形结构显示
- 兼容性优化,调整部门与菜单管理hook中code判断,避免误判
- 新增菜单和部门管理相关接口及类型定义
- 更新 OpenAPI 配置,规范角色菜单权限相关接口定义
- 新增权限管理表单组件及校验规则,支持增删改权限项
- 规范权限管理模块代码结构及变量命名,提高维护性
This commit is contained in:
2026-03-27 20:06:58 +08:00
parent bd809479e6
commit 1b3271fa35
21 changed files with 1432 additions and 224 deletions

View File

@@ -1,28 +1,30 @@
import { http } from "@/utils/http";
/** 飞书登录响应数据 */
export type FeishuLoginData = {
/** 真实姓名 */
realName: string;
/** 手机号 */
phone: string;
/** token名称 */
tokenName: string;
/** 头像 */
avatar: string;
/** 用户ID */
userId: number;
/** 邮箱 */
email: string;
/** token */
token: string;
/** 用户名 */
username: string;
};
/** 飞书登录响应结果 */
export type FeishuLoginResult = {
code: number;
data: FeishuLoginData;
message: string;
data: {
/** 是否登录成功 */
isLogin: boolean;
/** 用户ID */
userId: string | number;
/** 用户名 */
username: string;
/** 真实姓名 */
realName: string;
/** 头像 */
avatar: string;
/** 手机号 */
phone: string;
/** 邮箱 */
email: string;
/** token */
token: string;
/** token名称 */
tokenName: string;
};
};
/** 飞书OAuth登录接口前端回调后调用 */
@@ -31,3 +33,21 @@ export const getFeishuLogin = (code: string) => {
params: { code }
});
};
/** 检查当前登录状态 */
export const checkFeishuLoginStatus = () => {
return http.request<{
code: number;
data: Record<string, any>;
message: string;
}>("get", "/api/v1/auth/feishu/check");
};
/** 获取当前登录用户信息 */
export const getFeishuUserInfo = () => {
return http.request<{
code: number;
data: Record<string, any>;
message: string;
}>("get", "/api/v1/auth/feishu/user/info");
};

View File

@@ -1,17 +1,19 @@
import { http } from "@/utils/http";
type Result = {
/** 通用响应结果 */
type Result<T = any> = {
code: number;
message: string;
data?: Array<any>;
data?: T;
};
type ResultTable = {
/** 分页响应结果 */
type ResultTable<T = any> = {
code: number;
message: string;
data?: {
/** 列表数据 */
list: Array<any>;
list: Array<T>;
/** 总条目数 */
total?: number;
/** 每页显示条目个数 */
@@ -21,34 +23,444 @@ type ResultTable = {
};
};
/** 获取系统管理-用户管理列表 */
export const getUserList = (data?: object) => {
return http.request<ResultTable>("post", "/user", { data });
/** 后端分页数据结构 */
type PageResult<T = any> = {
records: Array<T>;
total: number;
size: number;
current: number;
pages?: number;
};
/** 系统管理-用户管理-获取所有角色列表 */
/** 后端分页响应 */
type BasePageResponse<T = any> = {
code: number;
message: string;
data: PageResult<T>;
};
// ==================== 权限管理 ====================
/** 权限对象 */
export type SysPermission = {
id?: number;
parentId?: number;
permissionCode?: string;
permissionName?: string;
permissionType?: number;
path?: string;
component?: string;
icon?: string;
apiUrl?: string;
apiMethod?: string;
sortOrder?: number;
visible?: number;
status?: number;
createTime?: string;
updateTime?: string;
deleted?: number;
};
/** 分页查询权限列表 */
export const getPermissionList = (params?: {
pageNum?: number;
pageSize?: number;
keyword?: string;
}) => {
return http.request<BasePageResponse<SysPermission>>(
"get",
"/api/v1/system/permission/list",
{ params }
);
};
/** 查询权限树 */
export const getPermissionTree = () => {
return http.request<Result<SysPermission[]>>(
"get",
"/api/v1/system/permission/tree"
);
};
/** 根据ID查询权限 */
export const getPermissionById = (id: number) => {
return http.request<Result<SysPermission>>(
"get",
`/api/v1/system/permission/${id}`
);
};
/** 新增权限 */
export const addPermission = (data: SysPermission) => {
return http.request<Result<number>>("post", "/api/v1/system/permission", {
data
});
};
/** 修改权限 */
export const updatePermission = (data: SysPermission) => {
return http.request<Result<void>>("put", "/api/v1/system/permission", {
data
});
};
/** 删除权限 */
export const deletePermission = (id: number) => {
return http.request<Result<void>>(
"delete",
`/api/v1/system/permission/${id}`
);
};
// ==================== 角色管理 ====================
/** 角色对象 */
export type SysRole = {
id?: number;
roleCode?: string;
roleName?: string;
roleType?: string;
description?: string;
dataScope?: number;
sortOrder?: number;
status?: number;
createBy?: number;
createTime?: string;
updateBy?: number;
updateTime?: string;
deleted?: number;
};
/** 分页查询角色列表 */
export const getRoleList = (params?: {
pageNum?: number;
pageSize?: number;
keyword?: string;
}) => {
return http.request<BasePageResponse<SysRole>>(
"get",
"/api/v1/system/role/list",
{ params }
);
};
/** 查询所有角色(用于下拉选择) */
export const getAllRoleList = () => {
return http.request<Result>("get", "/list-all-role");
return http.request<Result<SysRole[]>>("get", "/api/v1/system/role/all");
};
/** 系统管理-用户管理-根据userId获取对应角色id列表userId用户id */
export const getRoleIds = (data?: object) => {
return http.request<Result>("post", "/list-role-ids", { data });
/** 根据ID查询角色 */
export const getRoleById = (id: number) => {
return http.request<Result<SysRole>>("get", `/api/v1/system/role/${id}`);
};
/** 获取系统管理-角色管理列表 */
export const getRoleList = (data?: object) => {
return http.request<ResultTable>("post", "/role", { data });
/** 新增角色 */
export const addRole = (data: SysRole) => {
return http.request<Result<number>>("post", "/api/v1/system/role", { data });
};
/** 获取系统管理-菜单管理列表 */
export const getMenuList = (data?: object) => {
return http.request<Result>("post", "/menu", { data });
/** 修改角色 */
export const updateRole = (data: SysRole) => {
return http.request<Result<void>>("put", "/api/v1/system/role", { data });
};
/** 获取系统管理-部门管理列表 */
export const getDeptList = (data?: object) => {
return http.request<Result>("post", "/dept", { data });
/** 删除角色 */
export const deleteRole = (id: number) => {
return http.request<Result<void>>("delete", `/api/v1/system/role/${id}`);
};
/** 查询角色的权限列表(返回完整权限对象列表) */
export const getRolePermissions = (id: number) => {
return http.request<Result<SysPermission[]>>(
"get",
`/api/v1/system/role/${id}/permissions`
);
};
/** 为角色分配权限 */
export const assignRolePermissions = (id: number, permissionIds: number[]) => {
return http.request<Result<void>>(
"post",
`/api/v1/system/role/${id}/permissions`,
{ data: permissionIds }
);
};
// ==================== 用户管理 ====================
/** 用户对象 */
export type SysUser = {
id?: number;
username?: string;
password?: string;
realName?: string;
nickname?: string;
avatar?: string;
gender?: number;
phone?: string;
email?: string;
deptId?: number;
position?: string;
employeeNo?: string;
entryDate?: string;
status?: number;
lastLoginTime?: string;
lastLoginIp?: string;
createBy?: number;
createTime?: string;
updateBy?: number;
updateTime?: string;
deleted?: number;
};
/** 分页查询用户列表 */
export const getUserList = (params?: {
pageNum?: number;
pageSize?: number;
keyword?: string;
}) => {
return http.request<BasePageResponse<SysUser>>(
"get",
"/api/v1/system/user/list",
{ params }
);
};
/** 根据ID查询用户 */
export const getUserById = (id: number) => {
return http.request<Result<SysUser>>("get", `/api/v1/system/user/${id}`);
};
/** 新增用户 */
export const addUser = (data: SysUser) => {
return http.request<Result<number>>("post", "/api/v1/system/user", { data });
};
/** 修改用户 */
export const updateUser = (data: SysUser) => {
return http.request<Result<void>>("put", "/api/v1/system/user", { data });
};
/** 删除用户 */
export const deleteUser = (id: number) => {
return http.request<Result<void>>("delete", `/api/v1/system/user/${id}`);
};
/** 查询用户的角色列表 */
export const getUserRoles = (id: number) => {
return http.request<Result<SysRole[]>>(
"get",
`/api/v1/system/user/${id}/roles`
);
};
/** 为用户绑定角色 */
export const assignUserRoles = (id: number, roleIds: number[]) => {
return http.request<Result<void>>("post", `/api/v1/system/user/${id}/roles`, {
data: roleIds
});
};
/** 查询用户角色ID列表用于回显 */
export const getUserRoleIds = (id: number) => {
return http.request<Result<number[]>>(
"get",
`/api/v1/system/user/${id}/roleIds`
);
};
// ==================== 项目初始化 ====================
/** 项目信息 */
export type ProjectInfo = {
project_name?: string;
project_type?: string;
description?: string;
objectives?: string;
plan_start_date?: string;
plan_end_date?: string;
budget?: number;
currency?: string;
priority?: string;
tags?: string[];
};
/** 里程碑信息 */
export type MilestoneInfo = {
milestone_name?: string;
description?: string;
plan_date?: string;
deliverables?: string;
owner_role?: string;
};
/** 任务信息 */
export type TaskInfo = {
task_id?: string;
task_name?: string;
parent_task_id?: string;
description?: string;
plan_start_date?: string;
plan_end_date?: string;
estimated_hours?: number;
priority?: string;
assignee_role?: string;
dependencies?: string[];
deliverables?: string;
};
/** 成员信息 */
export type MemberInfo = {
name?: string;
role_code?: string;
responsibility?: string;
department?: string;
weekly_hours?: number;
};
/** 资源信息 */
export type ResourceInfo = {
resource_name?: string;
resource_type?: string;
quantity?: number;
unit?: string;
unit_price?: number;
supplier?: string;
};
/** 风险信息 */
export type RiskInfo = {
risk_name?: string;
category?: string;
description?: string;
probability?: number;
impact?: number;
mitigation_plan?: string;
};
/** 时间节点信息 */
export type TimelineNodeInfo = {
node_name?: string;
node_type?: string;
plan_date?: string;
description?: string;
kb_scope?: string[];
};
/** 项目初始化结果 */
export type ProjectInitResult = {
project: ProjectInfo;
milestones: MilestoneInfo[];
tasks: TaskInfo[];
members: MemberInfo[];
resources: ResourceInfo[];
risks: RiskInfo[];
timeline_nodes: TimelineNodeInfo[];
};
/** 上传文件并生成项目初始化预览数据 */
export const previewProjectInit = (file: File) => {
const formData = new FormData();
formData.append("file", file);
return http.request<Result<ProjectInitResult>>(
"post",
"/api/v1/project-init/preview",
{ data: formData }
);
};
/** 确认并保存项目初始化数据 */
export const confirmProjectInit = (data: ProjectInitResult) => {
return http.request<Result<ProjectInitResult>>(
"post",
"/api/v1/project-init/confirm",
{ data }
);
};
// ==================== 部门管理 ====================
/** 部门对象 */
export type SysDept = {
id?: number;
parentId?: number;
deptName?: string;
deptCode?: string;
leader?: string;
phone?: string;
email?: string;
sortOrder?: number;
status?: number;
createTime?: string;
};
/** 获取部门列表(树形结构) */
export const getDeptList = () => {
return http.request<Result<SysDept[]>>("get", "/api/v1/system/dept/tree");
};
/** 获取部门详情 */
export const getDeptById = (id: number) => {
return http.request<Result<SysDept>>("get", `/api/v1/system/dept/${id}`);
};
/** 新增部门 */
export const addDept = (data: SysDept) => {
return http.request<Result<number>>("post", "/api/v1/system/dept", { data });
};
/** 修改部门 */
export const updateDept = (data: SysDept) => {
return http.request<Result<void>>("put", "/api/v1/system/dept", { data });
};
/** 删除部门 */
export const deleteDept = (id: number) => {
return http.request<Result<void>>("delete", `/api/v1/system/dept/${id}`);
};
// ==================== 菜单管理 ====================
/** 菜单对象 */
export type SysMenu = {
id?: number;
parentId?: number;
menuName?: string;
menuType?: number;
icon?: string;
path?: string;
component?: string;
permission?: string;
sortOrder?: number;
status?: number;
visible?: number;
keepAlive?: number;
createTime?: string;
};
/** 获取菜单列表(树形结构) */
export const getMenuList = () => {
return http.request<Result<SysMenu[]>>("get", "/api/v1/system/menu/tree");
};
/** 获取菜单详情 */
export const getMenuById = (id: number) => {
return http.request<Result<SysMenu>>("get", `/api/v1/system/menu/${id}`);
};
/** 新增菜单 */
export const addMenu = (data: SysMenu) => {
return http.request<Result<number>>("post", "/api/v1/system/menu", { data });
};
/** 修改菜单 */
export const updateMenu = (data: SysMenu) => {
return http.request<Result<void>>("put", "/api/v1/system/menu", { data });
};
/** 删除菜单 */
export const deleteMenu = (id: number) => {
return http.request<Result<void>>("delete", `/api/v1/system/menu/${id}`);
};
/** 获取系统监控-在线用户列表 */
@@ -77,11 +489,23 @@ export const getSystemLogsDetail = (data?: object) => {
};
/** 获取角色管理-权限-菜单权限 */
export const getRoleMenu = (data?: object) => {
return http.request<Result>("post", "/role-menu", { data });
export const getRoleMenu = () => {
return http.request<Result<SysMenu[]>>("get", "/api/v1/system/menu/tree");
};
/** 获取角色管理-权限-菜单权限-根据角色 id 查对应菜单 */
export const getRoleMenuIds = (data?: object) => {
return http.request<Result>("post", "/role-menu-ids", { data });
export const getRoleMenuIds = (roleId: number) => {
return http.request<Result<number[]>>(
"get",
`/api/v1/system/role/${roleId}/menu-ids`
);
};
/** 为角色分配菜单权限 */
export const assignRoleMenus = (roleId: number, menuIds: number[]) => {
return http.request<Result<void>>(
"post",
`/api/v1/system/role/${roleId}/menus`,
{ data: menuIds }
);
};

View File

@@ -7,20 +7,30 @@
},
"tags": [],
"paths": {
"/api/v1/auth/feishu/login": {
"post": {
"summary": "飞书OAuth登录接口前端回调后调用",
"/api/v1/system/role/{id}/menu-ids": {
"get": {
"summary": "查询角色的菜单权限ID列表只返回菜单类型的权限",
"deprecated": false,
"description": "前端从飞书回调中获取code然后调用此接口完成登录",
"description": "",
"tags": [],
"parameters": [
{
"name": "code",
"in": "query",
"description": "飞书授权码",
"name": "id",
"in": "path",
"description": "",
"required": true,
"schema": {
"type": "string"
"type": "integer"
}
},
{
"name": "Authorization",
"in": "header",
"description": "",
"example": "Bearer 000b7e25-53b2-42a3-a39b-9f4cb03644ba",
"schema": {
"type": "string",
"default": "Bearer 000b7e25-53b2-42a3-a39b-9f4cb03644ba"
}
}
],
@@ -30,8 +40,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BaseResponseMapObject",
"description": "登录结果包含token和用户信息"
"$ref": "#/components/schemas/BaseResponseListLong"
}
}
}
@@ -43,7 +52,7 @@
},
"components": {
"schemas": {
"BaseResponseMapObject": {
"BaseResponseListLong": {
"type": "object",
"properties": {
"code": {
@@ -51,26 +60,17 @@
"description": ""
},
"data": {
"type": "object",
"properties": {
"isLogin": {
"type": "boolean"
},
"userId": {
"$ref": "#/components/schemas/userId"
}
"type": "array",
"items": {
"type": "integer"
},
"description": ""
},
"message": {
"description": "",
"type": "null"
"type": "string",
"description": ""
}
}
},
"userId": {
"type": "object",
"properties": {}
}
},
"responses": {},