fix: 1. 接入入口模块的管理接口,优化样式。

2. 将查看文档评查结果详情对接接口,采用接口的方式进行查询。
This commit is contained in:
2025-11-26 23:37:14 +08:00
parent ae24b82384
commit d5827a2146
13 changed files with 563 additions and 673 deletions
@@ -11,32 +11,6 @@
*/
const RBAC_API_BASE = '/api/v3/rbac';
/**
* RBAC专用API客户端 - 使用fetch直接请求Remix API路由
*/
async function rbacFetch<T>(url: string, options: RequestInit = {}): Promise<T> {
console.log('🔗 [RBAC Fetch] 请求:', url, options.method || 'GET');
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers
}
});
console.log('📡 [RBAC Fetch] 响应状态:', response.status, response.statusText);
const data = await response.json();
console.log('📦 [RBAC Fetch] 响应数据:', data);
if (!response.ok) {
throw new Error(data.detail || data.message || `HTTP ${response.status}`);
}
return data;
}
/**
* 统一响应处理函数
* 处理后端返回的统一格式响应
@@ -180,278 +154,6 @@ export interface RolePermissionDetail {
data_scope: 'ALL' | 'DEPT' | 'SELF';
}
// ==================== 模拟数据 ====================
/**
* 模拟路由数据(树形结构)
*/
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
}
];
/**
* 模拟角色数据(与数据库实际数据一致)
* 仅用于开发阶段API失败时的降级方案
*/
const mockRoles: RoleInfo[] = [
{
id: 1,
role_key: 'admin',
role_name: '市级管理员',
data_scope: 'DEPT',
description: '负责本地区的所有业务管理,不包括系统设置和角色权限管理',
priority: 0,
is_system_role: false,
created_at: '2025-07-18 10:35:39',
updated_at: '2025-07-18 10:35:39'
},
{
id: 2,
role_key: 'common',
role_name: '普通员工',
data_scope: 'SELF',
description: '仅能操作自己的数据',
priority: 0,
is_system_role: false,
created_at: '2025-07-18 10:35:39',
updated_at: '2025-07-18 10:35:39'
},
{
id: 52,
role_key: 'provincial_admin',
role_name: '省级管理员',
data_scope: 'ALL',
description: '拥有全部权限,可以管理所有地区的评查点规则、提示词、动态按钮、评查组',
priority: 1,
is_system_role: true,
created_at: '2025-11-19 17:25:45',
updated_at: '2025-11-19 17:25:45'
}
];
/**
* 模拟角色-路由权限关联数据
*/
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 函数 ====================
/**
* 获取所有角色列表
* @param params 查询参数
@@ -467,11 +169,9 @@ export async function getRoles(params?: {
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
console.log('🔍 [getRoles] 开始调用后端API:', `/api/v3/rbac/roles`, params);
// 使用 axios-client 的 get 函数调用真实后端API
const response = await get<any>(`/api/v3/rbac/roles`, params || {});
console.log('📦 [getRoles] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -485,7 +185,6 @@ export async function getRoles(params?: {
items = response.data.items;
}
console.log('✅ [getRoles] 解析出的角色数组:', items);
// 数据格式转换(后端字段 -> 前端字段)
const roles = items.map(role => ({
@@ -501,7 +200,6 @@ export async function getRoles(params?: {
updated_at: role.updated_at
}));
console.log('✅ [getRoles] 最终返回的角色列表,共', roles.length, '个角色');
return roles;
} catch (error) {
console.error('❌ [getRoles] 获取角色列表失败:', error);
@@ -545,7 +243,6 @@ export async function getRoutes(): Promise<RouteInfo[]> {
try {
const { get } = await import('~/api/axios-client');
console.log('🔍 [getRoutes] 开始调用后端API: /rbac/user/routes');
// 调用后端API获取当前用户的路由(provincial_admin应该有所有路由权限)
const response = await get<any>('/rbac/user/routes');
@@ -564,8 +261,6 @@ export async function getRoutes(): Promise<RouteInfo[]> {
routes = response.data.routes;
}
console.log('✅ [getRoutes] 成功获取路由数据,共', routes.length, '个顶级路由');
// 将后端数据转换为前端RouteInfo格式
const mapRouteData = (route: any): RouteInfo => ({
id: route.id,
@@ -599,11 +294,8 @@ export async function getRoleRoutePermissions(roleId: number): Promise<RoleRoute
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
console.log('🔍 [getRoleRoutePermissions] 开始调用后端API:', `/rbac/roles/${roleId}/routes`);
// 使用 axios-client 的 get 函数调用真实后端API
const response = await get<any>(`/rbac/roles/${roleId}/routes`);
console.log('📦 [getRoleRoutePermissions] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -624,7 +316,6 @@ export async function getRoleRoutePermissions(roleId: number): Promise<RoleRoute
created_at: new Date().toISOString()
}));
console.log('✅ [getRoleRoutePermissions] 获取角色路由权限成功:', permissions);
return permissions;
} catch (error) {
console.error('❌ [getRoleRoutePermissions] 获取角色路由权限失败:', error);
@@ -646,10 +337,7 @@ export async function getRoleRoutesWithPermissions(roleId: number): Promise<{
try {
const { get } = await import('~/api/axios-client');
console.log('🔍 [getRoleRoutesWithPermissions] 开始调用后端API:', `/rbac/roles/${roleId}/routes`);
const response = await get<any>(`/rbac/roles/${roleId}/routes`);
console.log('📦 [getRoleRoutesWithPermissions] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -718,11 +406,6 @@ export async function getRoleRoutesWithPermissions(roleId: number): Promise<{
const selectedRouteIds = collectRouteIds(mappedRoutes);
const selectedPermissionIds = collectPermissionIds(mappedRoutes);
console.log('✅ [getRoleRoutesWithPermissions] 成功获取路由权限数据');
console.log(' - 路由数量:', mappedRoutes.length);
console.log(' - 已选路由ID:', selectedRouteIds);
console.log(' - 已选权限ID:', selectedPermissionIds);
return {
routes: mappedRoutes,
selectedRouteIds,
@@ -750,8 +433,6 @@ export async function saveRoleApiPermissions(
try {
const { post } = await import('~/api/axios-client');
console.log('🔍 [saveRoleApiPermissions] 开始调用后端API:', `/api/v3/rbac/roles/${roleId}/permissions`, permissionIds);
// 构建权限配置
const permissions = permissionIds.map(id => ({
permission_id: id,
@@ -764,8 +445,6 @@ export async function saveRoleApiPermissions(
replace: true // 替换模式:先删除现有权限,再插入新权限
});
console.log('📦 [saveRoleApiPermissions] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
}
@@ -778,7 +457,6 @@ export async function saveRoleApiPermissions(
message = `成功分配 ${assigned_count} 个API权限`;
}
console.log('✅ [saveRoleApiPermissions] API权限保存成功');
return { success: true, message };
} catch (error) {
console.error('❌ [saveRoleApiPermissions] 保存API权限失败:', error);
@@ -802,14 +480,12 @@ export async function updateRoleRoutePermissions(
// 导入 axios-client 的 put 函数
const { put } = await import('~/api/axios-client');
console.log('🔍 [updateRoleRoutePermissions] 开始调用后端API:', `/rbac/roles/${roleId}/routes`, routeIds);
// 使用 axios-client 的 put 函数调用真实后端API
const response = await put<any>(`/rbac/roles/${roleId}/routes`, {
route_ids: routeIds,
permission: 'RW'
});
console.log('📦 [updateRoleRoutePermissions] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -824,7 +500,6 @@ export async function updateRoleRoutePermissions(
message = `成功分配 ${assigned_count} 个路由,移除了 ${removed_count} 个旧路由`;
}
console.log('✅ [updateRoleRoutePermissions] 角色权限更新成功');
return { success: true, message };
} catch (error) {
console.error('❌ [updateRoleRoutePermissions] 更新角色权限失败:', error);
@@ -855,8 +530,6 @@ export async function getRoleUsers(
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
console.log('🔍 [getRoleUsers] 开始调用后端API:', `/api/v3/rbac/roles/${roleId}/users`, params);
// 构建查询参数对象
const queryParams: Record<string, any> = {};
if (params?.page) queryParams.page = params.page;
@@ -866,7 +539,6 @@ export async function getRoleUsers(
// 使用 axios-client 的 get 函数调用真实后端API
const response = await get<any>(`/api/v3/rbac/roles/${roleId}/users`, queryParams);
console.log('📦 [getRoleUsers] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -880,8 +552,6 @@ export async function getRoleUsers(
items = response.data.items;
}
console.log('✅ [getRoleUsers] 解析出的用户数组:', items);
const users = items.map((user: any) => ({
id: user.user_id || user.id,
username: user.username,
@@ -893,7 +563,6 @@ export async function getRoleUsers(
is_leader: user.is_leader || false
}));
console.log('✅ [getRoleUsers] 最终返回的用户列表:', users);
return users;
} catch (error) {
console.error('❌ [getRoleUsers] 获取角色用户列表失败:', error);
@@ -915,8 +584,6 @@ export async function getAllUsers(params?: {
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
console.log('🔍 [getAllUsers] 开始调用后端API:', '/admin/users/users', params);
// 构建查询参数对象
const queryParams: Record<string, any> = {};
if (params?.page) queryParams.page = params.page;
@@ -925,7 +592,6 @@ export async function getAllUsers(params?: {
// 使用 axios-client 的 get 函数,会自动添加 baseURL 和 Authorization
const response = await get<any>('/admin/users/users', queryParams);
console.log('📦 [getAllUsers] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -946,8 +612,6 @@ export async function getAllUsers(params?: {
}
}
console.log('✅ [getAllUsers] 解析出的用户数组:', users);
console.log('✅ [getAllUsers] 用户数量:', users.length);
const userList = users.map(user => ({
id: user.user_id || user.id, // 优先使用 user_id,兼容不同的后端响应格式
@@ -960,7 +624,6 @@ export async function getAllUsers(params?: {
is_leader: user.is_leader || false
}));
console.log('✅ [getAllUsers] 最终返回的用户列表:', userList);
return userList;
} catch (error) {
console.error('❌ [getAllUsers] 获取用户列表失败:', error);
@@ -981,13 +644,10 @@ export async function assignUserRoles(
// 导入 axios-client 的 post 函数
const { post } = await import('~/api/axios-client');
console.log('🔍 [assignUserRoles] 开始调用后端API:', `/api/v3/rbac/users/${userId}/roles`, roleIds);
// 使用 axios-client 的 post 函数调用真实后端API
const response = await post<any>(`/api/v3/rbac/users/${userId}/roles`, {
role_ids: roleIds
});
console.log('📦 [assignUserRoles] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -998,8 +658,6 @@ export async function assignUserRoles(
if (response.data && response.data.message) {
message = response.data.message;
}
console.log('✅ [assignUserRoles] 角色分配成功');
return { success: true, message };
} catch (error) {
console.error('❌ [assignUserRoles] 分配用户角色失败:', error);
@@ -1023,11 +681,8 @@ export async function revokeUserRole(
// 导入 axios-client 的 del 函数
const { del } = await import('~/api/axios-client');
console.log('🔍 [revokeUserRole] 开始调用后端API:', `/api/v3/rbac/users/${userId}/roles/${roleId}`);
// 使用 axios-client 的 del 函数调用真实后端API
const response = await del<any>(`/api/v3/rbac/users/${userId}/roles/${roleId}`);
console.log('📦 [revokeUserRole] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -1039,7 +694,6 @@ export async function revokeUserRole(
message = response.data.message;
}
console.log('✅ [revokeUserRole] 角色移除成功');
return { success: true, message };
} catch (error) {
console.error('❌ [revokeUserRole] 移除用户角色失败:', error);
@@ -1061,8 +715,6 @@ export async function createRole(
// 导入 axios-client 的 post 函数
const { post } = await import('~/api/axios-client');
console.log('🔍 [createRole] 开始调用后端API:', `/api/v3/rbac/roles`, roleData);
// 使用 axios-client 的 post 函数调用真实后端API
const response = await post<any>(`/api/v3/rbac/roles`, {
role_key: roleData.role_key,
@@ -1072,8 +724,6 @@ export async function createRole(
metadata: {}
});
console.log('📦 [createRole] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
}
@@ -1127,12 +777,8 @@ export async function updateRole(
if (roleData.priority !== undefined) updatePayload.priority = roleData.priority;
if (roleData.parent_role_id !== undefined) updatePayload.parent_role_id = roleData.parent_role_id;
console.log('🔍 [updateRole] 开始调用后端API:', `/api/v3/rbac/roles/${roleId}`, updatePayload);
const response = await put<any>(`/api/v3/rbac/roles/${roleId}`, updatePayload);
console.log('📦 [updateRole] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
}
@@ -1162,12 +808,8 @@ export async function deleteRole(
const url = `/api/v3/rbac/roles/${roleId}${force ? '?force=true' : ''}`;
console.log('🔍 [deleteRole] 开始调用后端API:', url);
const response = await del<any>(url);
console.log('📦 [deleteRole] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
}
@@ -1321,10 +963,7 @@ export async function getRolePermissions(roleId: number): Promise<RolePermission
try {
const { get } = await import('~/api/axios-client');
console.log('🔍 [getRolePermissions] 开始调用后端API:', `/api/v3/rbac/roles/${roleId}/permissions`);
const response = await get<any>(`/api/v3/rbac/roles/${roleId}/permissions`);
console.log('📦 [getRolePermissions] 后端API完整响应:', JSON.stringify(response, null, 2));
if (response.error) {
throw new Error(response.error);
@@ -1342,8 +981,6 @@ export async function getRolePermissions(roleId: number): Promise<RolePermission
permissions = response.data;
}
console.log('✅ [getRolePermissions] 解析出的权限数组:', permissions);
return permissions.map(perm => ({
id: perm.id,
permission_id: perm.permission_id || perm.id, // 兼容:如果没有 permission_id,使用 id
@@ -1451,8 +1088,6 @@ export async function getUserRoles(userId: number): Promise<RoleInfo[]> {
try {
const { get } = await import('~/api/axios-client');
console.log('🔍 [getUserRoles] 开始调用后端API:', `/api/v3/rbac/users/${userId}/roles`);
const response = await get<any>(`/api/v3/rbac/users/${userId}/roles`);
if (response.error) {
@@ -1469,8 +1104,6 @@ export async function getUserRoles(userId: number): Promise<RoleInfo[]> {
roles = response.data.roles;
}
console.log('✅ [getUserRoles] 成功获取用户角色,共', roles.length, '个角色');
// 将后端数据转换为RoleInfo格式
return roles.map(role => ({
id: role.id || role.role_id,