admin-vben5/packages/effects/access/src/accessible.ts

101 lines
2.5 KiB
TypeScript
Raw Normal View History

import type {
AccessModeType,
GenerateMenuAndRoutesOptions,
RouteRecordRaw,
} from '@vben/types';
import {
cloneDeep,
generateMenus,
generateRoutesByBackend,
generateRoutesByFrontend,
mapTree,
2024-10-10 11:48:26 +08:00
setObjToUrlParams,
} from '@vben/utils';
async function generateAccessible(
mode: AccessModeType,
options: GenerateMenuAndRoutesOptions,
) {
const { router } = options;
options.routes = cloneDeep(options.routes);
// 生成路由
const accessibleRoutes = await generateRoutes(mode, options);
// 动态添加到router实例内
accessibleRoutes.forEach((route) => {
2024-08-07 08:57:56 +08:00
/**
* menu处理
*/
if (/^https?:\/\//.test(route.path)) {
2024-08-07 08:57:56 +08:00
return;
}
router.addRoute(route);
});
// 生成菜单
const accessibleMenus = await generateMenus(accessibleRoutes, options.router);
return { accessibleMenus, accessibleRoutes };
}
/**
* Generate routes
* @param mode
* @param options
*/
async function generateRoutes(
mode: AccessModeType,
options: GenerateMenuAndRoutesOptions,
) {
const { forbiddenComponent, roles, routes } = options;
let resultRoutes: RouteRecordRaw[] = routes;
switch (mode) {
case 'backend': {
resultRoutes = await generateRoutesByBackend(options);
break;
}
case 'frontend': {
resultRoutes = await generateRoutesByFrontend(
routes,
roles || [],
forbiddenComponent,
);
break;
}
}
/**
*
* 1. redirect的路由添加redirect
*/
resultRoutes = mapTree(resultRoutes, (route) => {
// 如果有redirect或者没有子路由则直接返回
if (route.redirect || !route.children || route.children.length === 0) {
return route;
}
const firstChild = route.children[0];
// 如果子路由不是以/开头,则直接返回,这种情况需要计算全部父级的path才能得出正确的path这里不做处理
if (!firstChild?.path || !firstChild.path.startsWith('/')) {
return route;
}
2024-10-10 11:48:26 +08:00
// 第一个路由如果有query参数 需要加上参数
const fistChildQuery = route.children[0]?.meta?.query;
// 根目录菜单固定只有一个children 且path为/ 不需要添加redirect
route.redirect =
fistChildQuery && route.children.length !== 1 && route.path !== '/'
? setObjToUrlParams(firstChild.path, fistChildQuery)
: firstChild.path;
return route;
});
return resultRoutes;
}
export { generateAccessible };