This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
export interface MenuAccessIdentity {
|
||||
currentRole: string | null;
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
export function hasRoleAccess(roles: string[], currentRole: string | null): boolean {
|
||||
return roles.length === 0 || currentRole === 'SYSTEM_ADMIN' || roles.includes(currentRole || '');
|
||||
}
|
||||
|
||||
export function hasPermissionAccess(
|
||||
currentRole: string | null,
|
||||
permissions: string[],
|
||||
required: string | string[],
|
||||
): boolean {
|
||||
if (currentRole === 'SYSTEM_ADMIN') return true;
|
||||
return Array.isArray(required)
|
||||
? required.some((permission) => permissions.includes(permission))
|
||||
: permissions.includes(required);
|
||||
}
|
||||
|
||||
export function canAccess(route: RouteRecordRaw, user: MenuAccessIdentity): boolean {
|
||||
const meta = route.meta || {};
|
||||
const roles = (meta.roleCodes || []) as string[];
|
||||
const permission = meta.permission as string | string[] | undefined;
|
||||
if (!hasRoleAccess(roles, user.currentRole)) return false;
|
||||
if (permission && !hasPermissionAccess(user.currentRole, user.permissions, permission)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function childLocation(parentPath: string, childPath: string): string {
|
||||
if (childPath.startsWith('/')) return childPath;
|
||||
if (!childPath) return parentPath;
|
||||
return `${parentPath}/${childPath}`.replace(/\/{2,}/g, '/');
|
||||
}
|
||||
|
||||
export function filterMenu(routes: RouteRecordRaw[], user: MenuAccessIdentity): RouteRecordRaw[] {
|
||||
return routes
|
||||
.map((route) => {
|
||||
const children = route.children ? filterMenu(route.children, user) : [];
|
||||
const selfAllowed = canAccess(route, user);
|
||||
if (route.children && children.length === 0) return null;
|
||||
if (!route.children && !selfAllowed) return null;
|
||||
const copy: RouteRecordRaw = {
|
||||
...route,
|
||||
meta: route.meta ? { ...route.meta } : undefined,
|
||||
...(route.children ? { children } : {}),
|
||||
} as RouteRecordRaw;
|
||||
if (route.children) {
|
||||
const firstChild = children[0];
|
||||
if (firstChild) copy.redirect = childLocation(route.path, firstChild.path);
|
||||
}
|
||||
return copy;
|
||||
})
|
||||
.filter((route): route is RouteRecordRaw => route !== null);
|
||||
}
|
||||
Reference in New Issue
Block a user