feat: 1. 本地化思源黑体的字体包并优先使用。
2. 添加权限映射表和全局查看权限的hook,便于路由控制不同权限按钮显示/隐藏。 3. 删除评查点分组的部分旧api方法。 4. 对接评查点分组接口,文档类型接口, 提示词管理接口, 入口模块管理的接口。 5. 优化角色权限管理的接口,完善不用地区的访问权限认证。 6. 优化主页交叉评查和设置的入口样式和布局。 7. 优化评查点分组,评查规则的功能权限校验。
This commit is contained in:
+105
-3
@@ -14,6 +14,7 @@ export interface BackendRouteInfo {
|
||||
is_hidden: boolean;
|
||||
is_cache: boolean;
|
||||
meta: string;
|
||||
permissions?: string[]; // ✅ 新增:该路由下用户拥有的权限列表
|
||||
children?: BackendRouteInfo[];
|
||||
}
|
||||
|
||||
@@ -60,6 +61,7 @@ export interface MenuItem {
|
||||
order: number;
|
||||
hideBreadcrumb?: boolean;
|
||||
requiredRole?: string;
|
||||
permissions?: string[]; // ✅ 新增:该菜单项的权限列表
|
||||
children?: MenuItem[];
|
||||
}
|
||||
|
||||
@@ -484,6 +486,88 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* 权限映射表类型
|
||||
* key: 路由路径 (如 '/prompts', '/documents')
|
||||
* value: 该路由下的权限列表
|
||||
*/
|
||||
export type PermissionMap = Map<string, string[]>;
|
||||
|
||||
/**
|
||||
* 从路由树中提取权限映射表
|
||||
* @param routes 路由树
|
||||
* @param aggregateChildren 是否聚合子路由权限到父路由(默认true)
|
||||
* @returns 权限映射表 (路径 -> 权限列表)
|
||||
*/
|
||||
export function buildPermissionMap(routes: BackendRouteInfo[], aggregateChildren: boolean = true): PermissionMap {
|
||||
const permissionMap = new Map<string, string[]>();
|
||||
|
||||
/**
|
||||
* 递归收集路由及其所有子路由的权限
|
||||
*/
|
||||
function collectAllPermissions(route: BackendRouteInfo): string[] {
|
||||
const allPermissions = new Set<string>();
|
||||
|
||||
// 添加当前路由的权限
|
||||
if (route.permissions && route.permissions.length > 0) {
|
||||
route.permissions.forEach(p => allPermissions.add(p));
|
||||
}
|
||||
|
||||
// 递归收集子路由的权限
|
||||
if (aggregateChildren && route.children && route.children.length > 0) {
|
||||
route.children.forEach(child => {
|
||||
const childPermissions = collectAllPermissions(child);
|
||||
childPermissions.forEach(p => allPermissions.add(p));
|
||||
});
|
||||
}
|
||||
|
||||
return Array.from(allPermissions);
|
||||
}
|
||||
|
||||
function traverse(routeList: BackendRouteInfo[]) {
|
||||
for (const route of routeList) {
|
||||
// 存储当前路由的权限(聚合或不聚合)
|
||||
const permissions = aggregateChildren
|
||||
? collectAllPermissions(route)
|
||||
: (route.permissions || []);
|
||||
|
||||
if (permissions.length > 0) {
|
||||
permissionMap.set(route.route_path, permissions);
|
||||
}
|
||||
|
||||
// 递归处理子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
traverse(route.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse(routes);
|
||||
return permissionMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将权限映射表转换为普通对象(用于JSON序列化)
|
||||
*/
|
||||
export function permissionMapToObject(map: PermissionMap): Record<string, string[]> {
|
||||
const obj: Record<string, string[]> = {};
|
||||
map.forEach((value, key) => {
|
||||
obj[key] = value;
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从对象恢复权限映射表
|
||||
*/
|
||||
export function objectToPermissionMap(obj: Record<string, string[]>): PermissionMap {
|
||||
const map = new Map<string, string[]>();
|
||||
Object.entries(obj).forEach(([key, value]) => {
|
||||
map.set(key, value);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色获取用户可访问的路由(调用后端统一接口)
|
||||
* @param roleKey 角色标识 (如: 'admin', 'common', 'deptLeader', 'groupLeader') - 暂时不使用,后端通过JWT自动识别
|
||||
@@ -491,7 +575,17 @@ const FALLBACK_MENU_DATA: Record<string, MenuItem[]> = {
|
||||
* @param includeHidden 是否包含隐藏路由(默认 false)。true: 用于权限校验,false: 用于菜单渲染
|
||||
* @returns 用户可访问的路由列表
|
||||
*/
|
||||
export async function getUserRoutesByRole(roleKey: string, jwt?: string, includeHidden: boolean = false): Promise<{ success: boolean; data?: MenuItem[]; error?: string; shouldRedirectToHome?: boolean }> {
|
||||
export async function getUserRoutesByRole(
|
||||
roleKey: string,
|
||||
jwt?: string,
|
||||
includeHidden: boolean = false
|
||||
): Promise<{
|
||||
success: boolean;
|
||||
data?: MenuItem[];
|
||||
permissionMap?: Record<string, string[]>; // ✅ 新增:返回权限映射表
|
||||
error?: string;
|
||||
shouldRedirectToHome?: boolean
|
||||
}> {
|
||||
try {
|
||||
// console.log(`🔍 [User Routes] 获取用户路由,角色: ${roleKey}, JWT前20字符: ${jwt?.substring(0, 20)}`);
|
||||
|
||||
@@ -598,6 +692,9 @@ export async function getUserRoutesByRole(roleKey: string, jwt?: string, include
|
||||
// console.log('🔍 [User Routes] 后端返回的原始路由数据:', JSON.stringify(routes, null, 2));
|
||||
// console.log('🔍 [User Routes] 检查第一个路由是否有children:', routes[0]?.children);
|
||||
|
||||
// ✅ 构建权限映射表
|
||||
const permissionMapObj = permissionMapToObject(buildPermissionMap(routes));
|
||||
|
||||
// 将后端路由格式转换为前端 MenuItem 格式
|
||||
const menuItems = convertBackendRoutesToMenuItems(routes, includeHidden);
|
||||
|
||||
@@ -605,7 +702,11 @@ export async function getUserRoutesByRole(roleKey: string, jwt?: string, include
|
||||
// console.log('🔍 [User Routes] 转换后的菜单数据:', JSON.stringify(menuItems, null, 2));
|
||||
// console.log('🔍 [User Routes] 检查第一个菜单项是否有children:', menuItems[0]?.children);
|
||||
|
||||
return { success: true, data: menuItems };
|
||||
return {
|
||||
success: true,
|
||||
data: menuItems,
|
||||
permissionMap: permissionMapObj // ✅ 返回权限映射表
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error("❌ [User Routes] 获取用户路由时发生错误:", error);
|
||||
@@ -801,7 +902,8 @@ function convertBackendRoutesToMenuItems(backendRoutes: BackendRouteInfo[], incl
|
||||
path: route.route_path,
|
||||
icon: convertIcon(route.icon),
|
||||
order: route.sort_order,
|
||||
hideBreadcrumb: route.is_hidden
|
||||
hideBreadcrumb: route.is_hidden,
|
||||
permissions: route.permissions // ✅ 传递权限列表
|
||||
};
|
||||
|
||||
// 递归处理子路由,传递 includeHidden 参数
|
||||
|
||||
Reference in New Issue
Block a user