wsj
2026-10-17 5630cce7759c27d910fbeeec370a2e9f6b4b26b1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import type { MenuProps } from 'antd';
import type { AppRouteItem } from '@/router/routeConfig';
 
type MenuItem = Required<MenuProps>['items'][number];
 
/** 根据权限过滤路由树,并转换成 antd Menu 需要的结构。 */
export function buildMenuItems(
  routes: AppRouteItem[],
  hasPermission: (permission?: string) => boolean,
): MenuItem[] {
  const items: MenuItem[] = [];
 
  for (const route of routes) {
    if (route.hideInMenu) continue;
    if (route.permission && !hasPermission(route.permission)) continue;
 
    const children = route.children
      ? buildMenuItems(route.children, hasPermission)
      : [];
 
    // 分组节点下没有任何可访问页面时,整个分组也一并隐藏
    if (route.children?.length && children.length === 0) continue;
 
    items.push({
      key: route.path,
      icon: route.icon,
      label: route.title,
      ...(children.length > 0 ? { children } : {}),
    } as MenuItem);
  }
 
  return items;
}
 
/** 根据当前地址推导需要展开的父级菜单 key。 */
export function getOpenKeys(pathname: string): string[] {
  const segments = pathname.split('/').filter(Boolean);
  return segments.slice(0, -1).map((_, index) => `/${segments.slice(0, index + 1).join('/')}`);
}