mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 11:54:00 +08:00
104 lines
3.3 KiB
TypeScript
104 lines
3.3 KiB
TypeScript
import type { Menu, MenuModule } from '/@/router/types';
|
||
import type { RouteRecordNormalized } from 'vue-router';
|
||
|
||
import { appStore } from '/@/store/modules/app';
|
||
import { permissionStore } from '/@/store/modules/permission';
|
||
import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper';
|
||
import { filter } from '/@/utils/helper/treeHelper';
|
||
import router from '/@/router';
|
||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||
import { pathToRegexp } from 'path-to-regexp';
|
||
|
||
import modules from 'globby!/@/router/menus/modules/**/*.@(ts)';
|
||
|
||
const reg = /(((https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
|
||
|
||
const menuModules: MenuModule[] = [];
|
||
|
||
Object.keys(modules).forEach((key) => {
|
||
const moduleItem = modules[key];
|
||
const menuModule = Array.isArray(moduleItem) ? [...moduleItem] : [moduleItem];
|
||
menuModules.push(...menuModule);
|
||
});
|
||
|
||
// ===========================
|
||
// ==========Helper===========
|
||
// ===========================
|
||
const isBackMode = () => {
|
||
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
|
||
};
|
||
|
||
const staticMenus: Menu[] = [];
|
||
(() => {
|
||
menuModules.sort((a, b) => {
|
||
return (a.orderNo || 0) - (b.orderNo || 0);
|
||
});
|
||
|
||
for (const menu of menuModules) {
|
||
staticMenus.push(transformMenuModule(menu));
|
||
}
|
||
})();
|
||
|
||
async function getAsyncMenus() {
|
||
// 前端角色控制菜单 直接取菜单文件
|
||
return !isBackMode() ? staticMenus : permissionStore.getBackMenuListState;
|
||
}
|
||
|
||
// 获取菜单 树级
|
||
export const getMenus = async (): Promise<Menu[]> => {
|
||
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);
|
||
return allParentPath?.[0];
|
||
}
|
||
|
||
// 获取1级菜单,删除children
|
||
export async function getShallowMenus(): Promise<Menu[]> {
|
||
const menus = await getAsyncMenus();
|
||
const routes = router.getRoutes();
|
||
|
||
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);
|
||
if (!parent) return [] as Menu[];
|
||
return parent.children;
|
||
}
|
||
|
||
// 通用过滤方法
|
||
function basicFilter(routes: RouteRecordNormalized[]) {
|
||
return (menu: Menu) => {
|
||
const matchRoute = routes.find((route) => {
|
||
const match = route.path.match(reg)?.[0];
|
||
if (match && match === menu.path) {
|
||
return true;
|
||
}
|
||
|
||
if (route.meta?.carryParam) {
|
||
return pathToRegexp(route.path).test(menu.path);
|
||
}
|
||
const isSame = route.path === menu.path;
|
||
if (!isSame) return false;
|
||
|
||
if (route.meta?.ignoreAuth) return true;
|
||
|
||
return isSame || pathToRegexp(route.path).test(menu.path);
|
||
});
|
||
|
||
if (!matchRoute) return false;
|
||
menu.icon = menu.icon || matchRoute.meta.icon;
|
||
menu.meta = matchRoute.meta;
|
||
return true;
|
||
};
|
||
}
|