105 lines
2.7 KiB
TypeScript
105 lines
2.7 KiB
TypeScript
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);
|
||
}
|
||
|