刘光辉
10 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
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
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
 */
function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[] {
  // 将路由列表转换为一个以 name 为键的对象映射
  // 获取所有router最终的path及name
  const finalRoutesMap: { [key: string]: string } = Object.fromEntries(router.getRoutes().map(({ name, path }) => [name, path]));
 
  const 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 = '', i18nCode = '', type } = 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 {
      type,
      i18nCode,
      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 };