generate-routes-backend.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import type {
  2. ComponentRecordType,
  3. RouteRecordStringComponent,
  4. } from '@vben/types';
  5. import type { RouteRecordRaw } from 'vue-router';
  6. import type { GeneratorMenuAndRoutesOptions } from '../types';
  7. import { $t } from '@vben/locales';
  8. import { mapTree } from '@vben-core/toolkit';
  9. /**
  10. * 动态生成路由 - 后端方式
  11. */
  12. async function generateRoutesByBackend(
  13. options: GeneratorMenuAndRoutesOptions,
  14. ): Promise<RouteRecordRaw[]> {
  15. const { fetchMenuListAsync, layoutMap, pageMap } = options;
  16. try {
  17. const menuRoutes = await fetchMenuListAsync?.();
  18. if (!menuRoutes) {
  19. return [];
  20. }
  21. const normalizePageMap: ComponentRecordType = {};
  22. for (const [key, value] of Object.entries(pageMap)) {
  23. normalizePageMap[normalizeViewPath(key)] = value;
  24. }
  25. const routes = convertRoutes(menuRoutes, layoutMap, normalizePageMap);
  26. return routes;
  27. } catch (error) {
  28. console.error(error);
  29. return [];
  30. }
  31. }
  32. function convertRoutes(
  33. routes: RouteRecordStringComponent[],
  34. layoutMap: ComponentRecordType,
  35. pageMap: ComponentRecordType,
  36. ): RouteRecordRaw[] {
  37. return mapTree(routes, (node) => {
  38. const route = node as unknown as RouteRecordRaw;
  39. const { component, name } = node;
  40. if (!name) {
  41. console.error('route name is required', route);
  42. }
  43. // layout转换
  44. if (component && layoutMap[component]) {
  45. route.component = layoutMap[component];
  46. // 页面组件转换
  47. } else if (component) {
  48. const normalizePath = normalizeViewPath(component);
  49. route.component =
  50. pageMap[
  51. normalizePath.endsWith('.vue')
  52. ? normalizePath
  53. : `${normalizePath}.vue`
  54. ];
  55. }
  56. // 国际化转化
  57. if (route.meta?.title) {
  58. route.meta.title = $t(route.meta.title);
  59. }
  60. return route;
  61. });
  62. }
  63. function normalizeViewPath(path: string): string {
  64. // 去除相对路径前缀
  65. const normalizedPath = path.replace(/^(\.\/|\.\.\/)+/, '');
  66. // 确保路径以 '/' 开头
  67. const viewPath = normalizedPath.startsWith('/')
  68. ? normalizedPath
  69. : `/${normalizedPath}`;
  70. return viewPath.replace(/^\/views/, '');
  71. }
  72. export { generateRoutesByBackend };