| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import type { RouteRecordRaw } from 'vue-router';
- import type {
- ComponentRecordType,
- GenerateMenuAndRoutesOptions,
- RouteRecordStringComponent,
- } from '@vben-core/typings';
- import { mapTree } from '@vben-core/shared/utils';
- import { getRoles } from './role.tool';
- /**
- * 动态生成路由 - 后端方式
- */
- async function generateRoutesByBackend(
- options: GenerateMenuAndRoutesOptions,
- ): Promise<RouteRecordRaw[]> {
- const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
- try {
- const menuRoutes = await fetchMenuListAsync?.(
- getRoles('backend', options.roles),
- );
- if (!menuRoutes) {
- return [];
- }
- const normalizePageMap: ComponentRecordType = {};
- for (const [key, value] of Object.entries(pageMap)) {
- normalizePageMap[normalizeViewPath(key)] = value;
- }
- const routes = convertRoutes(menuRoutes, layoutMap, normalizePageMap);
- return routes;
- } catch (error) {
- console.error(error);
- throw error;
- }
- }
- function convertRoutes(
- routes: RouteRecordStringComponent[],
- layoutMap: ComponentRecordType,
- pageMap: ComponentRecordType,
- ): RouteRecordRaw[] {
- return mapTree(routes, (node) => {
- const route = node as unknown as RouteRecordRaw;
- const { component, name } = node;
- if (!name) {
- console.error('route name is required', route);
- }
- // layout转换
- if (component && layoutMap[component]) {
- route.component = layoutMap[component];
- // 页面组件转换
- } else if (component) {
- const normalizePath = normalizeViewPath(component);
- const pageKey = normalizePath.endsWith('.vue')
- ? normalizePath
- : `${normalizePath}.vue`;
- if (pageMap[pageKey]) {
- route.component = pageMap[pageKey];
- } else {
- console.error(`route component is invalid: ${pageKey}`, route);
- route.component = pageMap['/_core/fallback/not-found.vue'];
- }
- }
- return route;
- });
- }
- function normalizeViewPath(path: string): string {
- // 去除相对路径前缀
- const normalizedPath = path.replace(/^(\.\/|\.\.\/)+/, '');
- // 确保路径以 '/' 开头
- const viewPath = normalizedPath.startsWith('/')
- ? normalizedPath
- : `/${normalizedPath}`;
- // 这里耦合了vben-admin的目录结构
- return viewPath.replace(/^\/views/, '');
- }
- export { generateRoutesByBackend };
|