import type { MenuResponse } from '@/pages/System/Menu/List/types'; import { MenuTypeEnum } from '@/pages/System/Menu/List/types'; /** * 递归检查用户是否有访问指定路径的权限 * @param path 路由路径 * @param menus 用户菜单列表 * @returns 是否有权限 */ export function checkPermission(path: string, menus: MenuResponse[]): boolean { if (!menus || menus.length === 0) { // 如果菜单数据还未加载,默认允许访问(避免白屏) // 实际权限会在菜单加载后重新验证 return true; } // 规范化路径:移除开头的斜杠,便于比较 const normalizedPath = path.replace(/^\//, ''); for (const menu of menus) { // 只检查菜单类型(不检查目录和按钮) if (menu.type === MenuTypeEnum.MENU && menu.path) { const menuPath = menu.path.replace(/^\//, ''); // 精确匹配或前缀匹配(支持子路由) if (menuPath === normalizedPath || normalizedPath.startsWith(menuPath + '/')) { return true; } } // 递归检查子菜单 if (menu.children && menu.children.length > 0) { if (checkPermission(path, menu.children)) { return true; } } } return false; } /** * 检查用户是否拥有任意一个路径的权限 * @param paths 路由路径数组 * @param menus 用户菜单列表 * @returns 是否有权限 */ export function hasAnyPermission(paths: string[], menus: MenuResponse[]): boolean { return paths.some(path => checkPermission(path, menus)); } /** * 获取用户可访问的所有路径列表(扁平化) * @param menus 用户菜单列表 * @returns 可访问的路径数组 */ export function getAccessiblePaths(menus: MenuResponse[]): string[] { const paths: string[] = []; function traverse(menuList: MenuResponse[]) { for (const menu of menuList) { if (menu.type === MenuTypeEnum.MENU && menu.path) { paths.push(menu.path); } if (menu.children && menu.children.length > 0) { traverse(menu.children); } } } traverse(menus); return paths; } /** * 检查特定权限标识 * @param permission 权限标识(如 'system:user:add') * @param menus 用户菜单列表 * @returns 是否有权限 */ export function checkPermissionCode(permission: string, menus: MenuResponse[]): boolean { if (!permission || !menus || menus.length === 0) { return false; } function traverse(menuList: MenuResponse[]): boolean { for (const menu of menuList) { if (menu.permission === permission) { return true; } if (menu.children && menu.children.length > 0) { if (traverse(menu.children)) { return true; } } } return false; } return traverse(menus); }