Blame view

src/router/menus/index.ts 3.38 KB
vben authored
1
import type { Menu, MenuModule } from '/@/router/types';
陈文彬 authored
2
import type { RouteRecordNormalized } from 'vue-router';
3
陈文彬 authored
4
5
import { appStore } from '/@/store/modules/app';
import { permissionStore } from '/@/store/modules/permission';
6
import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper';
陈文彬 authored
7
8
9
import { filter } from '/@/utils/helper/treeHelper';
import router from '/@/router';
import { PermissionModeEnum } from '/@/enums/appEnum';
10
import { pathToRegexp } from 'path-to-regexp';
vben authored
11
12
const modules = import.meta.globEager('./modules/**/*.ts');
13
vben authored
14
const menuModules: MenuModule[] = [];
陈文彬 authored
15
vben authored
16
Object.keys(modules).forEach((key) => {
vben authored
17
18
19
  const mod = modules[key].default || {};
  const modList = Array.isArray(mod) ? [...mod] : [mod];
  menuModules.push(...modList);
vben authored
20
21
});
vben authored
22
23
const reg = /(((https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
陈文彬 authored
24
25
26
// ===========================
// ==========Helper===========
// ===========================
vben authored
27
28
29
const isBackMode = () => {
  return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
};
陈文彬 authored
30
31
32
33
34
35

const staticMenus: Menu[] = [];
(() => {
  menuModules.sort((a, b) => {
    return (a.orderNo || 0) - (b.orderNo || 0);
  });
36
陈文彬 authored
37
38
39
40
41
42
43
  for (const menu of menuModules) {
    staticMenus.push(transformMenuModule(menu));
  }
})();

async function getAsyncMenus() {
  // 前端角色控制菜单 直接取菜单文件
44
  return !isBackMode() ? staticMenus : permissionStore.getBackMenuListState;
陈文彬 authored
45
46
47
}

// 获取菜单 树级
vben authored
48
export const getMenus = async (): Promise<Menu[]> => {
陈文彬 authored
49
50
51
52
53
54
55
56
57
  const menus = await getAsyncMenus();
  const routes = router.getRoutes();
  return !isBackMode() ? filter(menus, basicFilter(routes)) : menus;
};

// 获取当前路径的顶级路径
export async function getCurrentParentPath(currentPath: string) {
  const menus = await getAsyncMenus();
  const allParentPath = await getAllParentPath(menus, currentPath);
58
  return allParentPath?.[0];
陈文彬 authored
59
60
61
}

// 获取1级菜单,删除children
vben authored
62
export async function getShallowMenus(): Promise<Menu[]> {
陈文彬 authored
63
64
  const menus = await getAsyncMenus();
  const routes = router.getRoutes();
vben authored
65
陈文彬 authored
66
67
68
69
70
71
72
73
  const shallowMenuList = menus.map((item) => ({ ...item, children: undefined }));
  return !isBackMode() ? shallowMenuList.filter(basicFilter(routes)) : shallowMenuList;
}

// 获取菜单的children
export async function getChildrenMenus(parentPath: string) {
  const menus = await getAsyncMenus();
  const parent = menus.find((item) => item.path === parentPath);
74
75
76
77
  if (!parent || !parent.children) return [] as Menu[];
  const routes = router.getRoutes();

  return !isBackMode() ? filter(parent.children, basicFilter(routes)) : parent.children;
陈文彬 authored
78
79
80
81
82
}

// 通用过滤方法
function basicFilter(routes: RouteRecordNormalized[]) {
  return (menu: Menu) => {
83
    const matchRoute = routes.find((route) => {
84
85
      const match = route.path.match(reg)?.[0];
      if (match && match === menu.path) {
86
87
88
        return true;
      }
89
90
      if (route.meta?.carryParam) {
        return pathToRegexp(route.path).test(menu.path);
91
      }
92
93
94
95
      const isSame = route.path === menu.path;
      if (!isSame) return false;

      if (route.meta?.ignoreAuth) return true;
96
97
      return isSame || pathToRegexp(route.path).test(menu.path);
98
99
100
    });

    if (!matchRoute) return false;
陈文彬 authored
101
102
103
104
105
    menu.icon = menu.icon || matchRoute.meta.icon;
    menu.meta = matchRoute.meta;
    return true;
  };
}