Blame view

Yi.Vben5.Vue3/packages/utils/src/helpers/generate-routes-backend.ts 2.39 KB
515fceeb   “wangming”   框架初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  import type { RouteRecordRaw } from 'vue-router';
  
  import type {
    ComponentRecordType,
    GenerateMenuAndRoutesOptions,
    RouteRecordStringComponent,
  } from '@vben-core/typings';
  
  import { mapTree } from '@vben-core/shared/utils';
  
  /**
   * 动态生成路由 - 后端方式
   */
  async function generateRoutesByBackend(
    options: GenerateMenuAndRoutesOptions,
  ): Promise<RouteRecordRaw[]> {
    const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
  
    try {
      const menuRoutes = await fetchMenuListAsync?.();
      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'];
          console.error(`未找到对应组件: /views${component}.vue`);
          // 默认为404页面
          route.component = layoutMap.NotFoundComponent;
        }
      }
  
      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 };