index.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import type { Menu, MenuModule } from '/@/router/types';
  2. import type { RouteRecordNormalized } from 'vue-router';
  3. import { appStore } from '/@/store/modules/app';
  4. import { permissionStore } from '/@/store/modules/permission';
  5. import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper';
  6. import { filter } from '/@/utils/helper/treeHelper';
  7. import router from '/@/router';
  8. import { PermissionModeEnum } from '/@/enums/appEnum';
  9. import { pathToRegexp } from 'path-to-regexp';
  10. const modules = import.meta.globEager('./modules/**/*.ts');
  11. const menuModules: MenuModule[] = [];
  12. Object.keys(modules).forEach((key) => {
  13. const mod = modules[key].default || {};
  14. const modList = Array.isArray(mod) ? [...mod] : [mod];
  15. menuModules.push(...modList);
  16. });
  17. const reg = /(((https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
  18. // ===========================
  19. // ==========Helper===========
  20. // ===========================
  21. const isBackMode = () => {
  22. return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
  23. };
  24. const staticMenus: Menu[] = [];
  25. (() => {
  26. menuModules.sort((a, b) => {
  27. return (a.orderNo || 0) - (b.orderNo || 0);
  28. });
  29. for (const menu of menuModules) {
  30. staticMenus.push(transformMenuModule(menu));
  31. }
  32. })();
  33. async function getAsyncMenus() {
  34. // 前端角色控制菜单 直接取菜单文件
  35. return !isBackMode() ? staticMenus : permissionStore.getBackMenuListState;
  36. }
  37. // 获取菜单 树级
  38. export const getMenus = async (): Promise<Menu[]> => {
  39. const menus = await getAsyncMenus();
  40. const routes = router.getRoutes();
  41. return !isBackMode() ? filter(menus, basicFilter(routes)) : menus;
  42. };
  43. // 获取当前路径的顶级路径
  44. export async function getCurrentParentPath(currentPath: string) {
  45. const menus = await getAsyncMenus();
  46. const allParentPath = await getAllParentPath(menus, currentPath);
  47. return allParentPath?.[0];
  48. }
  49. // 获取1级菜单,删除children
  50. export async function getShallowMenus(): Promise<Menu[]> {
  51. const menus = await getAsyncMenus();
  52. const routes = router.getRoutes();
  53. const shallowMenuList = menus.map((item) => ({ ...item, children: undefined }));
  54. return !isBackMode() ? shallowMenuList.filter(basicFilter(routes)) : shallowMenuList;
  55. }
  56. // 获取菜单的children
  57. export async function getChildrenMenus(parentPath: string) {
  58. const menus = await getAsyncMenus();
  59. const parent = menus.find((item) => item.path === parentPath);
  60. if (!parent || !parent.children) return [] as Menu[];
  61. const routes = router.getRoutes();
  62. return !isBackMode() ? filter(parent.children, basicFilter(routes)) : parent.children;
  63. }
  64. // 通用过滤方法
  65. function basicFilter(routes: RouteRecordNormalized[]) {
  66. return (menu: Menu) => {
  67. const matchRoute = routes.find((route) => {
  68. const match = route.path.match(reg)?.[0];
  69. if (match && match === menu.path) {
  70. return true;
  71. }
  72. if (route.meta?.carryParam) {
  73. return pathToRegexp(route.path).test(menu.path);
  74. }
  75. const isSame = route.path === menu.path;
  76. if (!isSame) return false;
  77. if (route.meta?.ignoreAuth) return true;
  78. return isSame || pathToRegexp(route.path).test(menu.path);
  79. });
  80. if (!matchRoute) return false;
  81. menu.icon = (menu.icon || matchRoute.meta.icon) as string;
  82. menu.meta = matchRoute.meta;
  83. return true;
  84. };
  85. }