fix: 1. 继续对齐交叉评查的接口,完善创建交叉评查的逻辑 和 相关组件的渲染布局。

2. 文档的基本信息修改改用接口。      3. 重新完善角色权限管理的页面逻辑。     4.将评查点列表中的返回逻辑改用浏览器的记忆返回。
This commit is contained in:
2025-12-12 12:00:36 +08:00
parent a5c49a5c95
commit d4000cd292
25 changed files with 4750 additions and 28293 deletions
+158 -29
View File
@@ -3,6 +3,20 @@
* 用于角色、路由权限、用户角色的管理
*/
import { get, post, put, del } from '~/api/axios-client';
// ==================== 类型定义 ====================
/**
* API 响应类型
*/
interface ApiResponse<T> {
data?: T;
error?: string;
status?: number;
headers?: Record<string, string>;
}
// ==================== 常量定义 ====================
/**
@@ -36,6 +50,8 @@ function handleApiResponse<T>(response: ApiResponse<any>): T {
/**
* API权限信息(关联到路由的权限)
* v3.0新增:每个路由可以关联多个API操作权限
* v3.6新增:支持通用权限(related_routes 字段)
* v3.7新增:is_shared 字段由后端直接返回
*/
export interface ApiPermission {
id: number;
@@ -43,6 +59,9 @@ export interface ApiPermission {
display_name: string; // 显示名称,如 "创建评查点分组"
api_method: string; // HTTP方法:GET | POST | PUT | DELETE
api_path: string; // API路径,如 "/api/v3/evaluation-point-groups"
route_id?: number | null; // v3.6: 关联的路由ID(独立权限使用)
related_routes?: number[] | null; // v3.6: 关联的多个路由ID(通用权限使用)
is_shared?: boolean; // v3.7: 是否为通用权限(后端返回)
}
/**
@@ -167,10 +186,6 @@ export async function getRoles(params?: {
include_system?: boolean;
}): Promise<RoleInfo[]> {
try {
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
// 使用 axios-client 的 get 函数调用真实后端API
const response = await get<any>(`/api/v3/rbac/roles`, params || {});
@@ -242,9 +257,6 @@ export async function getRoleDetail(roleId: number): Promise<RoleInfo | null> {
*/
export async function getRoutes(): Promise<RouteInfo[]> {
try {
const { get } = await import('~/api/axios-client');
// 调用后端API获取当前用户的路由(provincial_admin应该有所有路由权限)
const response = await get<any>('/rbac/user/routes');
@@ -278,8 +290,6 @@ export async function getRoutes(): Promise<RouteInfo[]> {
children: route.children ? route.children.map(mapRouteData) : undefined
});
console.log('获取当前用户的路由', routes.map(mapRouteData) )
return routes.map(mapRouteData);
} catch (error) {
console.error('❌ [getRoutes] 获取路由数据失败:', error);
@@ -288,15 +298,69 @@ export async function getRoutes(): Promise<RouteInfo[]> {
}
}
/**
* v3.7: 获取所有路由列表(管理员接口)
* 使用 /api/v3/routes 接口获取所有路由
* @param format 返回格式(tree/flat
* @param includeHidden 是否包含隐藏路由
*/
export async function getAllRoutes(
format: 'tree' | 'flat' = 'tree',
includeHidden = false
): Promise<RouteInfo[]> {
try {
const response = await get<any>('/api/v3/routes', {
format,
include_hidden: includeHidden
});
if (response.error) {
console.error('❌ [getAllRoutes] API调用失败:', response.error);
throw new Error(response.error);
}
// 后端响应格式: 直接返回路由数组(树形或平铺)
let routes: any[] = [];
if (response.data) {
// 如果是包装格式 { code, message, data: [...] }
if (response.data.code === 200 && Array.isArray(response.data.data)) {
routes = response.data.data;
}
// 如果直接是数组
else if (Array.isArray(response.data)) {
routes = response.data;
}
}
// 将后端数据转换为前端RouteInfo格式
const mapRouteData = (route: any): RouteInfo => ({
id: route.id,
route_path: route.route_path,
route_name: route.route_name,
route_title: route.route_title,
icon: route.icon || '',
sort_order: route.sort_order || 0,
is_hidden: route.is_hidden || false,
is_cache: route.is_cache !== false,
status: route.status || 1,
parent_id: route.parent_id || null,
component: route.component,
children: route.children ? route.children.map(mapRouteData) : undefined
});
return routes.map(mapRouteData);
} catch (error) {
console.error('❌ [getAllRoutes] 获取路由数据失败:', error);
return [];
}
}
/**
* 获取指定角色的路由权限
* @param roleId 角色ID
*/
export async function getRoleRoutePermissions(roleId: number): Promise<RoleRoutePermission[]> {
try {
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
// 使用 axios-client 的 get 函数调用真实后端API
const response = await get<any>(`/rbac/roles/${roleId}/routes`);
@@ -340,8 +404,6 @@ export async function getRoleRoutesWithPermissions(roleId: number): Promise<{
selectedPermissionIds: number[];
}> {
try {
const { get } = await import('~/api/axios-client');
const response = await get<any>(`/rbac/roles/${roleId}/routes`);
if (response.error) {
@@ -444,8 +506,6 @@ export async function saveRoleApiPermissions(
permissionIds: number[]
): Promise<{ success: boolean; message: string }> {
try {
const { post } = await import('~/api/axios-client');
// 构建权限配置
const permissions = permissionIds.map(id => ({
permission_id: id,
@@ -492,10 +552,6 @@ export async function updateRoleRoutePermissions(
routeIds: number[]
): Promise<{ success: boolean; message: string; code?: number }> {
try {
// 导入 axios-client 的 put 函数
const { put } = await import('~/api/axios-client');
// 使用 axios-client 的 put 函数调用真实后端API
const response = await put<any>(`/rbac/roles/${roleId}/routes`, {
route_ids: routeIds,
@@ -563,7 +619,6 @@ export async function getRoleUsers(
): Promise<UserInfo[]> {
try {
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
// 构建查询参数对象
const queryParams: Record<string, any> = {};
@@ -618,7 +673,6 @@ export async function getAllUsers(params?: {
}): Promise<UserInfo[]> {
try {
// 导入 axios-client 的 get 函数
const { get } = await import('~/api/axios-client');
// 构建查询参数对象
const queryParams: Record<string, any> = {};
@@ -683,7 +737,6 @@ export async function assignUserRoles(
): Promise<{ success: boolean; message: string }> {
try {
// 导入 axios-client 的 post 函数
const { post } = await import('~/api/axios-client');
// 使用 axios-client 的 post 函数调用真实后端API
const response = await post<any>(`/api/v3/rbac/users/${userId}/roles`, {
@@ -729,7 +782,6 @@ export async function revokeUserRole(
): Promise<{ success: boolean; message: string }> {
try {
// 导入 axios-client 的 del 函数
const { del } = await import('~/api/axios-client');
// 使用 axios-client 的 del 函数调用真实后端API
const response = await del<any>(`/api/v3/rbac/users/${userId}/roles/${roleId}`);
@@ -763,7 +815,6 @@ export async function createRole(
): Promise<{ success: boolean; message: string; data?: RoleInfo }> {
try {
// 导入 axios-client 的 post 函数
const { post } = await import('~/api/axios-client');
// 使用 axios-client 的 post 函数调用真实后端API
const response = await post<any>(`/api/v3/rbac/roles`, {
@@ -817,7 +868,6 @@ export async function updateRole(
): Promise<{ success: boolean; message: string }> {
try {
// 导入 axios-client 的 put 函数
const { put } = await import('~/api/axios-client');
const updatePayload: any = {};
@@ -854,7 +904,6 @@ export async function deleteRole(
): Promise<{ success: boolean; message: string }> {
try {
// 导入 axios-client 的 del 函数
const { del } = await import('~/api/axios-client');
const url = `/api/v3/rbac/roles/${roleId}${force ? '?force=true' : ''}`;
@@ -1011,7 +1060,6 @@ export async function deletePermission(
*/
export async function getRolePermissions(roleId: number): Promise<RolePermissionDetail[]> {
try {
const { get } = await import('~/api/axios-client');
// v3.4: 使用文档规范的API路径(查询参数方式)
const response = await get<any>('/api/v3/rbac/role-permissions', {
@@ -1143,7 +1191,6 @@ export async function revokeRolePermission(
*/
export async function getUserRoles(userId: number): Promise<RoleInfo[]> {
try {
const { get } = await import('~/api/axios-client');
const response = await get<any>(`/api/v3/rbac/users/${userId}/roles`);
@@ -1179,3 +1226,85 @@ export async function getUserRoles(userId: number): Promise<RoleInfo[]> {
return [];
}
}
/**
* v3.7: 获取指定路由的所有权限(包含通用权限)
* 使用专用 API 接口 /api/v3/routes/{route_id}/permissions
* @param routeId 路由ID
* @returns 权限列表(包含独立权限和通用权限,带 is_shared 标识)
*/
export async function getRoutePermissions(routeId: number): Promise<ApiPermission[]> {
try {
// v3.7: 使用专用 API 接口获取路由权限(包含通用权限)
const response = await get<any>(`/api/v3/routes/${routeId}/permissions`);
if (response.error) {
console.error('❌ [getRoutePermissions] API调用失败:', response.error);
return [];
}
// 处理响应数据
// 后端响应格式: { route_id, route_path, route_title, permissions: [...] }
let permissions: any[] = [];
if (response.data) {
// 如果是包装格式 { code, message, data: { permissions: [...] } }
if (response.data.code === 200 && response.data.data?.permissions) {
permissions = response.data.data.permissions;
}
// 如果直接返回 { route_id, permissions: [...] }
else if (response.data.permissions) {
permissions = response.data.permissions;
}
// 如果直接是数组
else if (Array.isArray(response.data)) {
permissions = response.data;
}
}
// 转换为 ApiPermission 格式,保留 is_shared 字段
return permissions.map(p => ({
id: p.id,
permission_key: p.permission_key,
display_name: p.display_name,
api_method: p.api_method || '',
api_path: p.api_path || '',
route_id: p.route_id,
related_routes: p.related_routes,
is_shared: p.is_shared || false // v3.7: 使用后端返回的 is_shared 字段
}));
} catch (error) {
console.error('❌ [getRoutePermissions] 获取路由权限失败:', error);
return [];
}
}
/**
* v3.7: 判断权限是否为通用权限
* 优先使用后端返回的 is_shared 字段,降级时使用 related_routes 判断
* @param permission 权限对象
* @returns 是否为通用权限
*/
export function isSharedPermission(permission: ApiPermission): boolean {
// v3.7: 优先使用后端返回的 is_shared 字段
if (permission.is_shared !== undefined) {
return permission.is_shared === true;
}
// 降级:通过 related_routes 字段判断
return permission.related_routes !== null &&
permission.related_routes !== undefined &&
Array.isArray(permission.related_routes) &&
permission.related_routes.length > 1;
}
/**
* v3.6: 获取通用权限关联的所有路由ID
* @param permission 权限对象
* @returns 路由ID数组
*/
export function getRelatedRouteIds(permission: ApiPermission): number[] {
if (isSharedPermission(permission)) {
return permission.related_routes || [];
}
return permission.route_id ? [permission.route_id] : [];
}