Blame view

Yi.Vben5.Vue3/packages/utils/src/helpers/generate-menus.ts 2.18 KB
515fceeb   “wangming”   框架初始化
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  import type { Router, RouteRecordRaw } from 'vue-router';
  
  import type {
    ExRouteRecordRaw,
    MenuRecordRaw,
    RouteMeta,
  } from '@vben-core/typings';
  
  import { filterTree, mapTree } from '@vben-core/shared/utils';
  
  /**
   * 根据 routes 生成菜单列表
   * @param routes - 路由配置列表
   * @param router - Vue Router 实例
   * @returns 生成的菜单列表
   */
  function generateMenus(
    routes: RouteRecordRaw[],
    router: Router,
  ): MenuRecordRaw[] {
    // 将路由列表转换为一个以 name 为键的对象映射
    const finalRoutesMap: { [key: string]: string } = Object.fromEntries(
      router.getRoutes().map(({ name, path }) => [name, path]),
    );
  
    let menus = mapTree<ExRouteRecordRaw, MenuRecordRaw>(routes, (route) => {
      // 获取最终的路由路径
      const path = finalRoutesMap[route.name as string] ?? route.path ?? '';
  
      const {
        meta = {} as RouteMeta,
        name: routeName,
        redirect,
        children = [],
      } = route;
      const {
        activeIcon,
        badge,
        badgeType,
        badgeVariants,
        hideChildrenInMenu = false,
        icon,
        link,
        order,
        title = '',
      } = meta;
  
      // 确保菜单名称不为空
      const name = (title || routeName || '') as string;
  
      // 处理子菜单
      const resultChildren = hideChildrenInMenu
        ? []
        : ((children as MenuRecordRaw[]) ?? []);
  
      // 设置子菜单的父子关系
      if (resultChildren.length > 0) {
        resultChildren.forEach((child) => {
          child.parents = [...(route.parents ?? []), path];
          child.parent = path;
        });
      }
  
      // 确定最终路径
      const resultPath = hideChildrenInMenu ? redirect || path : link || path;
  
      return {
        activeIcon,
        badge,
        badgeType,
        badgeVariants,
        icon,
        name,
        order,
        parent: route.parent,
        parents: route.parents,
        path: resultPath,
        show: !meta.hideInMenu,
        children: resultChildren,
      };
    });
  
    // 对菜单进行排序,避免order=0时被替换成999的问题
    menus = menus.sort((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
  
    // 过滤掉隐藏的菜单项
    return filterTree(menus, (menu) => !!menu.show);
  }
  
  export { generateMenus };