deploy-ease-platform/frontend/src/utils/permission.ts
2025-11-06 10:56:17 +08:00

105 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}