提交 | 用户 | age
|
c303ec
|
1 |
import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types'; |
e12c58
|
2 |
import type { Router, RouteRecordNormalized } from 'vue-router'; |
c303ec
|
3 |
|
V |
4 |
import { getParentLayout, LAYOUT } from '/@/router/constant'; |
df8cd8
|
5 |
import { cloneDeep, omit } from 'lodash-es'; |
99ac30
|
6 |
import { warn } from '/@/utils/log'; |
e12c58
|
7 |
import { createRouter, createWebHashHistory } from 'vue-router'; |
c303ec
|
8 |
|
c774a6
|
9 |
export type LayoutMapKey = 'LAYOUT'; |
c6b766
|
10 |
const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue'); |
c774a6
|
11 |
|
327d71
|
12 |
const LayoutMap = new Map<string, () => Promise<typeof import('*.vue')>>(); |
c6b766
|
13 |
|
无 |
14 |
LayoutMap.set('LAYOUT', LAYOUT); |
|
15 |
LayoutMap.set('IFRAME', IFRAME); |
c774a6
|
16 |
|
e12c58
|
17 |
let dynamicViewsModules: Record<string, () => Promise<Recordable>>; |
664035
|
18 |
|
e12c58
|
19 |
// Dynamic introduction |
c303ec
|
20 |
function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { |
e5b2cc
|
21 |
dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}'); |
c303ec
|
22 |
if (!routes) return; |
V |
23 |
routes.forEach((item) => { |
c6b766
|
24 |
if (!item.component && item.meta?.frameSrc) { |
无 |
25 |
item.component = 'IFRAME'; |
|
26 |
} |
c303ec
|
27 |
const { component, name } = item; |
V |
28 |
const { children } = item; |
|
29 |
if (component) { |
327d71
|
30 |
const layoutFound = LayoutMap.get(component as string); |
c6b766
|
31 |
if (layoutFound) { |
无 |
32 |
item.component = layoutFound; |
|
33 |
} else { |
|
34 |
item.component = dynamicImport(dynamicViewsModules, component as string); |
|
35 |
} |
c303ec
|
36 |
} else if (name) { |
e12c58
|
37 |
item.component = getParentLayout(); |
c303ec
|
38 |
} |
V |
39 |
children && asyncImportRoute(children); |
|
40 |
}); |
|
41 |
} |
|
42 |
|
664035
|
43 |
function dynamicImport( |
e12c58
|
44 |
dynamicViewsModules: Record<string, () => Promise<Recordable>>, |
664035
|
45 |
component: string |
V |
46 |
) { |
|
47 |
const keys = Object.keys(dynamicViewsModules); |
99ac30
|
48 |
const matchKeys = keys.filter((key) => { |
b476e1
|
49 |
let k = key.replace('../../views', ''); |
V |
50 |
const lastIndex = k.lastIndexOf('.'); |
|
51 |
k = k.substring(0, lastIndex); |
|
52 |
return k === component; |
99ac30
|
53 |
}); |
V |
54 |
if (matchKeys?.length === 1) { |
|
55 |
const matchKey = matchKeys[0]; |
664035
|
56 |
return dynamicViewsModules[matchKey]; |
99ac30
|
57 |
} |
V |
58 |
if (matchKeys?.length > 1) { |
|
59 |
warn( |
|
60 |
'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure' |
|
61 |
); |
|
62 |
return; |
|
63 |
} |
|
64 |
} |
|
65 |
|
c303ec
|
66 |
// Turn background objects into routing objects |
V |
67 |
export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] { |
|
68 |
routeList.forEach((route) => { |
327d71
|
69 |
const component = route.component as string; |
V |
70 |
if (component) { |
|
71 |
if (component.toUpperCase() === 'LAYOUT') { |
|
72 |
route.component = LayoutMap.get(component.toUpperCase()); |
c303ec
|
73 |
} else { |
V |
74 |
route.children = [cloneDeep(route)]; |
|
75 |
route.component = LAYOUT; |
|
76 |
route.name = `${route.name}Parent`; |
|
77 |
route.path = ''; |
|
78 |
const meta = route.meta || {}; |
|
79 |
meta.single = true; |
|
80 |
meta.affix = false; |
|
81 |
route.meta = meta; |
|
82 |
} |
|
83 |
} |
|
84 |
route.children && asyncImportRoute(route.children); |
|
85 |
}); |
df8cd8
|
86 |
return routeList as unknown as T[]; |
c303ec
|
87 |
} |
V |
88 |
|
e12c58
|
89 |
/** |
V |
90 |
* Convert multi-level routing to level 2 routing |
|
91 |
*/ |
e2cc5a
|
92 |
export function flatMultiLevelRoutes(routeModules: AppRouteModule[]) { |
V |
93 |
const modules: AppRouteModule[] = cloneDeep(routeModules); |
|
94 |
for (let index = 0; index < modules.length; index++) { |
|
95 |
const routeModule = modules[index]; |
e12c58
|
96 |
if (!isMultipleRoute(routeModule)) { |
V |
97 |
continue; |
|
98 |
} |
|
99 |
promoteRouteLevel(routeModule); |
|
100 |
} |
e2cc5a
|
101 |
return modules; |
e12c58
|
102 |
} |
V |
103 |
|
|
104 |
// Routing level upgrade |
|
105 |
function promoteRouteLevel(routeModule: AppRouteModule) { |
|
106 |
// Use vue-router to splice menus |
|
107 |
let router: Router | null = createRouter({ |
df8cd8
|
108 |
routes: [routeModule as unknown as RouteRecordNormalized], |
e12c58
|
109 |
history: createWebHashHistory(), |
V |
110 |
}); |
|
111 |
|
|
112 |
const routes = router.getRoutes(); |
e2cc5a
|
113 |
addToChildren(routes, routeModule.children || [], routeModule); |
e12c58
|
114 |
router = null; |
V |
115 |
|
df8cd8
|
116 |
routeModule.children = routeModule.children?.map((item) => omit(item, 'children')); |
e12c58
|
117 |
} |
V |
118 |
|
|
119 |
// Add all sub-routes to the secondary route |
|
120 |
function addToChildren( |
|
121 |
routes: RouteRecordNormalized[], |
|
122 |
children: AppRouteRecordRaw[], |
|
123 |
routeModule: AppRouteModule |
|
124 |
) { |
|
125 |
for (let index = 0; index < children.length; index++) { |
|
126 |
const child = children[index]; |
|
127 |
const route = routes.find((item) => item.name === child.name); |
e2cc5a
|
128 |
if (!route) { |
V |
129 |
continue; |
|
130 |
} |
|
131 |
routeModule.children = routeModule.children || []; |
|
132 |
if (!routeModule.children.find((item) => item.name === route.name)) { |
df8cd8
|
133 |
routeModule.children?.push(route as unknown as AppRouteModule); |
e2cc5a
|
134 |
} |
V |
135 |
if (child.children?.length) { |
|
136 |
addToChildren(routes, child.children, routeModule); |
e12c58
|
137 |
} |
V |
138 |
} |
|
139 |
} |
|
140 |
|
|
141 |
// Determine whether the level exceeds 2 levels |
|
142 |
function isMultipleRoute(routeModule: AppRouteModule) { |
|
143 |
if (!routeModule || !Reflect.has(routeModule, 'children') || !routeModule.children?.length) { |
|
144 |
return false; |
|
145 |
} |
|
146 |
|
|
147 |
const children = routeModule.children; |
|
148 |
|
|
149 |
let flag = false; |
|
150 |
for (let index = 0; index < children.length; index++) { |
|
151 |
const child = children[index]; |
|
152 |
if (child.children?.length) { |
|
153 |
flag = true; |
|
154 |
break; |
|
155 |
} |
|
156 |
} |
|
157 |
return flag; |
c303ec
|
158 |
} |