3850d05bdd
2. 给文档类型添加入口模块和相关数据的渲染。并且给文档类型进行功能上的角色权限区分 3. 新增角色权限管理页面
561 lines
14 KiB
TypeScript
561 lines
14 KiB
TypeScript
/**
|
|
* 角色权限管理 API
|
|
* 用于角色、路由权限、用户角色的管理
|
|
*/
|
|
|
|
// ==================== 类型定义 ====================
|
|
|
|
/**
|
|
* 路由信息
|
|
*/
|
|
export interface RouteInfo {
|
|
id: number;
|
|
route_path: string;
|
|
route_name: string;
|
|
route_title: string;
|
|
component?: string;
|
|
parent_id?: number | null;
|
|
icon?: string;
|
|
sort_order: number;
|
|
is_hidden: boolean;
|
|
is_cache: boolean;
|
|
status: number;
|
|
children?: RouteInfo[];
|
|
}
|
|
|
|
/**
|
|
* 角色信息
|
|
*/
|
|
export interface RoleInfo {
|
|
id: number;
|
|
role_key: string;
|
|
role_name: string;
|
|
data_scope: string;
|
|
description: string;
|
|
parent_role_id?: number | null;
|
|
priority: number;
|
|
is_system_role: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
/**
|
|
* 角色-路由权限关联
|
|
*/
|
|
export interface RoleRoutePermission {
|
|
id: number;
|
|
role_id: number;
|
|
route_id: number;
|
|
permission: string; // 'R' | 'RW' | 'NONE'
|
|
created_at: string;
|
|
}
|
|
|
|
/**
|
|
* 用户信息
|
|
*/
|
|
export interface UserInfo {
|
|
id: number;
|
|
username: string;
|
|
nick_name: string;
|
|
phone_number?: string;
|
|
email?: string;
|
|
ou_name: string;
|
|
status: number;
|
|
is_leader: boolean;
|
|
}
|
|
|
|
/**
|
|
* 用户-角色关联
|
|
*/
|
|
export interface UserRoleRelation {
|
|
id: number;
|
|
user_id: number;
|
|
role_id: number;
|
|
created_at: string;
|
|
}
|
|
|
|
// ==================== 模拟数据 ====================
|
|
|
|
/**
|
|
* 模拟路由数据(树形结构)
|
|
*/
|
|
const mockRoutes: RouteInfo[] = [
|
|
{
|
|
id: 1,
|
|
route_path: '/documents',
|
|
route_name: 'documents',
|
|
route_title: '文档管理',
|
|
icon: 'ri-file-text-line',
|
|
sort_order: 1,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: null,
|
|
children: [
|
|
{
|
|
id: 11,
|
|
route_path: '/documents/list',
|
|
route_name: 'documents-list',
|
|
route_title: '文档列表',
|
|
icon: 'ri-list-check',
|
|
sort_order: 1,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: 1
|
|
},
|
|
{
|
|
id: 12,
|
|
route_path: '/documents/upload',
|
|
route_name: 'documents-upload',
|
|
route_title: '文档上传',
|
|
icon: 'ri-upload-line',
|
|
sort_order: 2,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: 1
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 2,
|
|
route_path: '/cross-checking',
|
|
route_name: 'cross-checking',
|
|
route_title: '交叉评查',
|
|
icon: 'ri-exchange-line',
|
|
sort_order: 2,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: null,
|
|
children: [
|
|
{
|
|
id: 21,
|
|
route_path: '/cross-checking/tasks',
|
|
route_name: 'cross-checking-tasks',
|
|
route_title: '评查任务',
|
|
icon: 'ri-task-line',
|
|
sort_order: 1,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: 2
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 3,
|
|
route_path: '/settings',
|
|
route_name: 'settings',
|
|
route_title: '系统设置',
|
|
icon: 'ri-settings-3-line',
|
|
sort_order: 3,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: null,
|
|
children: [
|
|
{
|
|
id: 31,
|
|
route_path: '/settings/document-types',
|
|
route_name: 'document-types',
|
|
route_title: '文档类型管理',
|
|
icon: 'ri-file-list-line',
|
|
sort_order: 1,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: 3
|
|
},
|
|
{
|
|
id: 32,
|
|
route_path: '/settings/rule-groups',
|
|
route_name: 'rule-groups',
|
|
route_title: '评查点分组',
|
|
icon: 'ri-folder-line',
|
|
sort_order: 2,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: 3
|
|
},
|
|
{
|
|
id: 33,
|
|
route_path: '/settings/prompts',
|
|
route_name: 'prompts',
|
|
route_title: '提示词管理',
|
|
icon: 'ri-message-line',
|
|
sort_order: 3,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: 3
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: 4,
|
|
route_path: '/role-permissions',
|
|
route_name: 'role-permissions',
|
|
route_title: '角色权限管理',
|
|
icon: 'ri-shield-user-line',
|
|
sort_order: 4,
|
|
is_hidden: false,
|
|
is_cache: true,
|
|
status: 1,
|
|
parent_id: null
|
|
}
|
|
];
|
|
|
|
/**
|
|
* 模拟角色数据
|
|
*/
|
|
const mockRoles: RoleInfo[] = [
|
|
{
|
|
id: 1,
|
|
role_key: 'admin',
|
|
role_name: '系统管理员',
|
|
data_scope: 'ALL',
|
|
description: '拥有系统所有权限',
|
|
priority: 1,
|
|
is_system_role: true,
|
|
created_at: '2024-01-01 10:00:00',
|
|
updated_at: '2024-01-01 10:00:00'
|
|
},
|
|
{
|
|
id: 2,
|
|
role_key: 'provincial',
|
|
role_name: '省级管理员',
|
|
data_scope: 'PROVINCE',
|
|
description: '省级权限,可管理文档类型和评查点',
|
|
priority: 2,
|
|
is_system_role: false,
|
|
created_at: '2024-01-02 10:00:00',
|
|
updated_at: '2024-01-02 10:00:00'
|
|
},
|
|
{
|
|
id: 3,
|
|
role_key: 'city_admin',
|
|
role_name: '市级管理员',
|
|
data_scope: 'CITY',
|
|
description: '市级权限,可管理本市文档',
|
|
priority: 3,
|
|
is_system_role: false,
|
|
created_at: '2024-01-03 10:00:00',
|
|
updated_at: '2024-01-03 10:00:00'
|
|
},
|
|
{
|
|
id: 4,
|
|
role_key: 'common_user',
|
|
role_name: '普通用户',
|
|
data_scope: 'SELF',
|
|
description: '普通用户,只能查看自己的文档',
|
|
priority: 4,
|
|
is_system_role: false,
|
|
created_at: '2024-01-04 10:00:00',
|
|
updated_at: '2024-01-04 10:00:00'
|
|
},
|
|
{
|
|
id: 5,
|
|
role_key: 'reviewer',
|
|
role_name: '评审员',
|
|
data_scope: 'DEPARTMENT',
|
|
description: '负责文档评审工作',
|
|
priority: 5,
|
|
is_system_role: false,
|
|
created_at: '2024-01-05 10:00:00',
|
|
updated_at: '2024-01-05 10:00:00'
|
|
}
|
|
];
|
|
|
|
/**
|
|
* 模拟角色-路由权限关联数据
|
|
*/
|
|
const mockRoleRoutePermissions: RoleRoutePermission[] = [
|
|
// 系统管理员拥有所有权限
|
|
{ id: 1, role_id: 1, route_id: 1, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 2, role_id: 1, route_id: 11, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 3, role_id: 1, route_id: 12, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 4, role_id: 1, route_id: 2, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 5, role_id: 1, route_id: 21, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 6, role_id: 1, route_id: 3, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 7, role_id: 1, route_id: 31, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 8, role_id: 1, route_id: 32, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 9, role_id: 1, route_id: 33, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
{ id: 10, role_id: 1, route_id: 4, permission: 'RW', created_at: '2024-01-01 10:00:00' },
|
|
|
|
// 省级管理员
|
|
{ id: 11, role_id: 2, route_id: 1, permission: 'RW', created_at: '2024-01-02 10:00:00' },
|
|
{ id: 12, role_id: 2, route_id: 11, permission: 'RW', created_at: '2024-01-02 10:00:00' },
|
|
{ id: 13, role_id: 2, route_id: 12, permission: 'RW', created_at: '2024-01-02 10:00:00' },
|
|
{ id: 14, role_id: 2, route_id: 3, permission: 'RW', created_at: '2024-01-02 10:00:00' },
|
|
{ id: 15, role_id: 2, route_id: 31, permission: 'RW', created_at: '2024-01-02 10:00:00' },
|
|
{ id: 16, role_id: 2, route_id: 32, permission: 'RW', created_at: '2024-01-02 10:00:00' },
|
|
|
|
// 普通用户
|
|
{ id: 17, role_id: 4, route_id: 1, permission: 'R', created_at: '2024-01-04 10:00:00' },
|
|
{ id: 18, role_id: 4, route_id: 11, permission: 'R', created_at: '2024-01-04 10:00:00' },
|
|
];
|
|
|
|
/**
|
|
* 模拟用户数据
|
|
*/
|
|
const mockUsers: UserInfo[] = [
|
|
{
|
|
id: 1,
|
|
username: 'admin',
|
|
nick_name: '系统管理员',
|
|
phone_number: '13800138000',
|
|
email: 'admin@example.com',
|
|
ou_name: '系统管理部',
|
|
status: 1,
|
|
is_leader: true
|
|
},
|
|
{
|
|
id: 2,
|
|
username: 'zhangsan',
|
|
nick_name: '张三',
|
|
phone_number: '13800138001',
|
|
email: 'zhangsan@example.com',
|
|
ou_name: '广东省局',
|
|
status: 1,
|
|
is_leader: true
|
|
},
|
|
{
|
|
id: 3,
|
|
username: 'lisi',
|
|
nick_name: '李四',
|
|
phone_number: '13800138002',
|
|
email: 'lisi@example.com',
|
|
ou_name: '梅州市局',
|
|
status: 1,
|
|
is_leader: false
|
|
},
|
|
{
|
|
id: 4,
|
|
username: 'wangwu',
|
|
nick_name: '王五',
|
|
phone_number: '13800138003',
|
|
email: 'wangwu@example.com',
|
|
ou_name: '云浮市局',
|
|
status: 1,
|
|
is_leader: false
|
|
},
|
|
{
|
|
id: 5,
|
|
username: 'zhaoliu',
|
|
nick_name: '赵六',
|
|
phone_number: '13800138004',
|
|
email: 'zhaoliu@example.com',
|
|
ou_name: '揭阳市局',
|
|
status: 1,
|
|
is_leader: false
|
|
}
|
|
];
|
|
|
|
/**
|
|
* 模拟用户-角色关联数据
|
|
*/
|
|
const mockUserRoles: UserRoleRelation[] = [
|
|
{ id: 1, user_id: 1, role_id: 1, created_at: '2024-01-01 10:00:00' },
|
|
{ id: 2, user_id: 2, role_id: 2, created_at: '2024-01-02 10:00:00' },
|
|
{ id: 3, user_id: 3, role_id: 3, created_at: '2024-01-03 10:00:00' },
|
|
{ id: 4, user_id: 4, role_id: 4, created_at: '2024-01-04 10:00:00' },
|
|
{ id: 5, user_id: 5, role_id: 5, created_at: '2024-01-05 10:00:00' }
|
|
];
|
|
|
|
// ==================== API 函数 ====================
|
|
|
|
/**
|
|
* 获取所有角色列表
|
|
*/
|
|
export async function getRoles(): Promise<RoleInfo[]> {
|
|
// 模拟网络延迟
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
return mockRoles;
|
|
}
|
|
|
|
/**
|
|
* 获取所有路由(树形结构)
|
|
*/
|
|
export async function getRoutes(): Promise<RouteInfo[]> {
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
return mockRoutes;
|
|
}
|
|
|
|
/**
|
|
* 获取指定角色的路由权限
|
|
* @param roleId 角色ID
|
|
*/
|
|
export async function getRoleRoutePermissions(roleId: number): Promise<RoleRoutePermission[]> {
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
return mockRoleRoutePermissions.filter(p => p.role_id === roleId);
|
|
}
|
|
|
|
/**
|
|
* 更新角色的路由权限
|
|
* @param roleId 角色ID
|
|
* @param routeIds 路由ID数组
|
|
*/
|
|
export async function updateRoleRoutePermissions(
|
|
roleId: number,
|
|
routeIds: number[]
|
|
): Promise<{ success: boolean; message: string }> {
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
// 在实际应用中,这里会调用后端API
|
|
console.log('更新角色权限:', { roleId, routeIds });
|
|
|
|
// 模拟更新本地数据
|
|
// 删除该角色的旧权限
|
|
const oldPermissions = mockRoleRoutePermissions.filter(p => p.role_id === roleId);
|
|
oldPermissions.forEach(p => {
|
|
const index = mockRoleRoutePermissions.indexOf(p);
|
|
if (index > -1) {
|
|
mockRoleRoutePermissions.splice(index, 1);
|
|
}
|
|
});
|
|
|
|
// 添加新权限
|
|
routeIds.forEach((routeId, index) => {
|
|
mockRoleRoutePermissions.push({
|
|
id: Date.now() + index,
|
|
role_id: roleId,
|
|
route_id: routeId,
|
|
permission: 'RW',
|
|
created_at: new Date().toISOString()
|
|
});
|
|
});
|
|
|
|
return { success: true, message: '角色权限更新成功' };
|
|
}
|
|
|
|
/**
|
|
* 获取指定角色的用户列表
|
|
* @param roleId 角色ID
|
|
*/
|
|
export async function getRoleUsers(roleId: number): Promise<UserInfo[]> {
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
// 查找具有该角色的用户ID
|
|
const userIds = mockUserRoles
|
|
.filter(ur => ur.role_id === roleId)
|
|
.map(ur => ur.user_id);
|
|
|
|
// 返回用户详细信息
|
|
return mockUsers.filter(u => userIds.includes(u.id));
|
|
}
|
|
|
|
/**
|
|
* 获取所有用户列表
|
|
*/
|
|
export async function getAllUsers(): Promise<UserInfo[]> {
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
return mockUsers;
|
|
}
|
|
|
|
/**
|
|
* 为用户分配角色
|
|
* @param userId 用户ID
|
|
* @param roleIds 角色ID数组
|
|
*/
|
|
export async function assignUserRoles(
|
|
userId: number,
|
|
roleIds: number[]
|
|
): Promise<{ success: boolean; message: string }> {
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
console.log('为用户分配角色:', { userId, roleIds });
|
|
|
|
// 模拟更新本地数据
|
|
// 删除该用户的旧角色
|
|
const oldRoles = mockUserRoles.filter(ur => ur.user_id === userId);
|
|
oldRoles.forEach(ur => {
|
|
const index = mockUserRoles.indexOf(ur);
|
|
if (index > -1) {
|
|
mockUserRoles.splice(index, 1);
|
|
}
|
|
});
|
|
|
|
// 添加新角色
|
|
roleIds.forEach((roleId, index) => {
|
|
mockUserRoles.push({
|
|
id: Date.now() + index,
|
|
user_id: userId,
|
|
role_id: roleId,
|
|
created_at: new Date().toISOString()
|
|
});
|
|
});
|
|
|
|
return { success: true, message: '用户角色分配成功' };
|
|
}
|
|
|
|
/**
|
|
* 创建新角色
|
|
* @param roleData 角色数据
|
|
*/
|
|
export async function createRole(
|
|
roleData: Omit<RoleInfo, 'id' | 'created_at' | 'updated_at'>
|
|
): Promise<{ success: boolean; message: string; data?: RoleInfo }> {
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
const newRole: RoleInfo = {
|
|
...roleData,
|
|
id: Math.max(...mockRoles.map(r => r.id)) + 1,
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString()
|
|
};
|
|
|
|
mockRoles.push(newRole);
|
|
|
|
return { success: true, message: '角色创建成功', data: newRole };
|
|
}
|
|
|
|
/**
|
|
* 更新角色信息
|
|
* @param roleId 角色ID
|
|
* @param roleData 角色数据
|
|
*/
|
|
export async function updateRole(
|
|
roleId: number,
|
|
roleData: Partial<Omit<RoleInfo, 'id' | 'created_at' | 'updated_at'>>
|
|
): Promise<{ success: boolean; message: string }> {
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
const roleIndex = mockRoles.findIndex(r => r.id === roleId);
|
|
if (roleIndex === -1) {
|
|
return { success: false, message: '角色不存在' };
|
|
}
|
|
|
|
mockRoles[roleIndex] = {
|
|
...mockRoles[roleIndex],
|
|
...roleData,
|
|
updated_at: new Date().toISOString()
|
|
};
|
|
|
|
return { success: true, message: '角色更新成功' };
|
|
}
|
|
|
|
/**
|
|
* 删除角色
|
|
* @param roleId 角色ID
|
|
*/
|
|
export async function deleteRole(roleId: number): Promise<{ success: boolean; message: string }> {
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
const role = mockRoles.find(r => r.id === roleId);
|
|
if (!role) {
|
|
return { success: false, message: '角色不存在' };
|
|
}
|
|
|
|
if (role.is_system_role) {
|
|
return { success: false, message: '系统角色不能删除' };
|
|
}
|
|
|
|
const roleIndex = mockRoles.indexOf(role);
|
|
mockRoles.splice(roleIndex, 1);
|
|
|
|
return { success: true, message: '角色删除成功' };
|
|
}
|