commit | author | age
|
9bcb19
|
1 |
|
I |
2 |
import { BasicLayout, BlankLayout, PageView, RouteView, Iframe } from '@/layouts' |
|
3 |
|
|
4 |
// 前端路由表 |
|
5 |
const constantRouterComponents = { |
|
6 |
// 基础页面 layout 必须引入 |
|
7 |
BasicLayout: BasicLayout, |
|
8 |
BlankLayout: BlankLayout, |
|
9 |
RouteView: RouteView, |
|
10 |
PageView: PageView, |
|
11 |
Iframe: Iframe, |
|
12 |
'403': () => import('@/views/system/exception/403'), |
|
13 |
'404': () => import('@/views/system/exception/404'), |
|
14 |
'500': () => import('@/views/system/exception/500'), |
|
15 |
|
|
16 |
'Workplace': () => import('@/views/system/dashboard/Workplace'), |
|
17 |
// account |
|
18 |
'AccountCenter': () => import('@/views/system/account/center/Index'), |
|
19 |
'AccountSettings': () => import('@/views/system/account/settings/Index'), |
|
20 |
'BaseSettings': () => import('@/views/system/account/settings/BaseSetting'), |
|
21 |
'SecuritySettings': () => import('@/views/system/account/settings/Security'), |
|
22 |
'CustomSettings': () => import('@/views/system/account/settings/Custom'), |
|
23 |
'BindingSettings': () => import('@/views/system/account/settings/Binding'), |
|
24 |
'NotificationSettings': () => import('@/views/system/account/settings/Notification'), |
|
25 |
|
|
26 |
// 默认首页 |
|
27 |
'Console': () => import('@/views/system/index/welcome') |
|
28 |
} |
|
29 |
|
|
30 |
// 前端未找到页面路由(固定不用改)、原来为 /404 |
|
31 |
const notFoundRouter = { |
|
32 |
path: '*', redirect: '/welcome', hidden: true |
|
33 |
} |
|
34 |
// 个人中心页面 |
|
35 |
const userAccount = [ |
|
36 |
// account |
|
37 |
{ |
|
38 |
'name': 'account', |
|
39 |
'pid': 0, |
|
40 |
'id': 10028, |
|
41 |
'meta': { |
|
42 |
'title': '个人页', |
|
43 |
'icon': 'user', |
|
44 |
'show': false |
|
45 |
}, |
|
46 |
'redirect': '/account/center', |
|
47 |
'component': 'RouteView' |
|
48 |
}, |
|
49 |
{ |
|
50 |
'name': 'center', |
|
51 |
'pid': 10028, |
|
52 |
'id': 10029, |
|
53 |
'meta': { |
|
54 |
'title': '个人中心', |
|
55 |
'show': false |
|
56 |
}, |
|
57 |
'component': 'AccountCenter' |
|
58 |
}, |
|
59 |
// 特殊三级菜单 |
|
60 |
{ |
|
61 |
'name': 'settings', |
|
62 |
'pid': '10028', |
|
63 |
'id': '10030', |
|
64 |
'meta': { |
|
65 |
'title': '个人设置', |
|
66 |
'hideHeader': true, |
|
67 |
'hideChildren': true, |
|
68 |
'show': false |
|
69 |
}, |
|
70 |
'redirect': '/account/settings/base', |
|
71 |
'component': 'AccountSettings' |
|
72 |
}, |
|
73 |
{ |
|
74 |
'name': 'BaseSettings', |
|
75 |
'path': '/account/settings/base', |
|
76 |
'pid': 10030, |
|
77 |
'id': 10031, |
|
78 |
'meta': { |
|
79 |
'title': '基本设置', |
|
80 |
'show': false |
|
81 |
}, |
|
82 |
'component': 'BaseSettings' |
|
83 |
}, |
|
84 |
{ |
|
85 |
'name': 'SecuritySettings', |
|
86 |
'path': '/account/settings/security', |
|
87 |
'pid': 10030, |
|
88 |
'id': 10032, |
|
89 |
'meta': { |
|
90 |
'title': '安全设置', |
|
91 |
'show': false |
|
92 |
}, |
|
93 |
'component': 'SecuritySettings' |
|
94 |
}, |
|
95 |
{ |
|
96 |
'name': 'CustomSettings', |
|
97 |
'path': '/account/settings/custom', |
|
98 |
'pid': 10030, |
|
99 |
'id': 10033, |
|
100 |
'meta': { |
|
101 |
'title': '个性化设置', |
|
102 |
'show': false |
|
103 |
}, |
|
104 |
'component': 'CustomSettings' |
|
105 |
}, |
|
106 |
{ |
|
107 |
'name': 'BindingSettings', |
|
108 |
'path': '/account/settings/binding', |
|
109 |
'pid': 10030, |
|
110 |
'id': 10034, |
|
111 |
'meta': { |
|
112 |
'title': '账户绑定', |
|
113 |
'show': false |
|
114 |
}, |
|
115 |
'component': 'BindingSettings' |
|
116 |
}, |
|
117 |
{ |
|
118 |
'name': 'NotificationSettings', |
|
119 |
'path': '/account/settings/notification', |
|
120 |
'pid': 10030, |
|
121 |
'id': 10034, |
|
122 |
'meta': { |
|
123 |
'title': '新消息通知', |
|
124 |
'show': false |
|
125 |
}, |
|
126 |
'component': 'NotificationSettings' |
|
127 |
}, |
|
128 |
{ |
|
129 |
'name': 'Console', |
|
130 |
'path': '/welcome', |
|
131 |
'pid': 0, |
|
132 |
'id': 183183, |
|
133 |
'meta': { |
|
134 |
'title': '首页', |
|
135 |
'show': false |
|
136 |
}, |
|
137 |
'component': 'Console' |
|
138 |
} |
|
139 |
|
|
140 |
] |
|
141 |
|
|
142 |
// 根级菜单 |
|
143 |
const rootRouter = { |
|
144 |
key: '', |
|
145 |
name: 'MenuIndex.vue', |
|
146 |
path: '', |
|
147 |
component: 'BasicLayout', |
|
148 |
redirect: '/welcome', |
|
149 |
meta: { |
|
150 |
title: '首页' |
|
151 |
}, |
|
152 |
children: [] |
|
153 |
} |
|
154 |
|
|
155 |
/** |
|
156 |
* 动态生成菜单 |
|
157 |
* @param data |
|
158 |
* @returns {Promise<Router>} |
|
159 |
*/ |
|
160 |
export const generatorDynamicRouter = (data) => { |
|
161 |
return new Promise((resolve, reject) => { |
|
162 |
const resNav = data.antDesignmenus |
|
163 |
const menuNav = [] |
|
164 |
const childrenNav = [] |
|
165 |
// 后端数据, 根级树数组, 根级 PID |
|
166 |
listToTree(resNav, childrenNav, 0) |
|
167 |
|
|
168 |
/** |
|
169 |
* 增加静态网页 |
|
170 |
*/ |
|
171 |
listToTree(userAccount, childrenNav, 0) |
|
172 |
rootRouter.children = childrenNav |
|
173 |
menuNav.push(rootRouter) |
|
174 |
const routers = generator(menuNav) |
|
175 |
routers.push(notFoundRouter) |
|
176 |
resolve(routers) |
|
177 |
}).catch(err => { |
|
178 |
// reject('加载菜单失败') |
|
179 |
return Promise.reject(err) |
|
180 |
}) |
|
181 |
} |
|
182 |
|
|
183 |
/** |
|
184 |
* 格式化树形结构数据 生成 vue-router 层级路由表 |
|
185 |
* |
|
186 |
* @param routerMap |
|
187 |
* @param parent |
|
188 |
* @returns {*} |
|
189 |
*/ |
|
190 |
export const generator = (routerMap, parent) => { |
|
191 |
return routerMap.map(item => { |
|
192 |
// eslint-disable-next-line no-unused-vars |
|
193 |
const { title, show, hideChildren, hiddenHeaderContent, target, icon, link } = item.meta || {} |
|
194 |
const currentRouter = { |
|
195 |
// 如果路由设置了 path,则作为默认 path,否则 路由地址 动态拼接生成如 /dashboard/workplace |
|
196 |
path: item.path || `${parent && parent.path || ''}/${item.key}`, |
|
197 |
// 路由名称,建议唯一 |
|
198 |
name: item.name || item.key || '', |
|
199 |
// 该路由对应页面的 组件 :方案1 |
|
200 |
// component: constantRouterComponents[item.component || item.key], |
|
201 |
// 该路由对应页面的 组件 :方案2 (动态加载) |
|
202 |
component: (constantRouterComponents[item.component || item.key]) || (() => import(`@/views/${item.component}`)), |
|
203 |
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉) |
|
204 |
meta: { |
|
205 |
title: title, |
|
206 |
icon: icon || undefined, |
|
207 |
// hiddenHeaderContent: hiddenHeaderContent, |
|
208 |
target: target, |
|
209 |
link: link |
|
210 |
} |
|
211 |
} |
|
212 |
// 是否设置了隐藏菜单 |
|
213 |
if (show === false) { |
|
214 |
currentRouter.hidden = true |
|
215 |
} |
|
216 |
// 是否设置了隐藏子菜单 |
|
217 |
if (hideChildren) { |
|
218 |
currentRouter.hideChildrenInMenu = true |
|
219 |
} |
|
220 |
// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠 |
|
221 |
if (!currentRouter.path.startsWith('http')) { |
|
222 |
currentRouter.path = currentRouter.path.replace('//', '/') |
|
223 |
} |
|
224 |
// 重定向 |
|
225 |
item.redirect && (currentRouter.redirect = item.redirect) |
|
226 |
// 是否有子菜单,并递归处理 |
|
227 |
if (item.children && item.children.length > 0) { |
|
228 |
// Recursion |
|
229 |
currentRouter.children = generator(item.children, currentRouter) |
|
230 |
} |
|
231 |
return currentRouter |
|
232 |
}) |
|
233 |
} |
|
234 |
|
|
235 |
/** |
|
236 |
* 数组转树形结构 |
|
237 |
* @param list 源数组 |
|
238 |
* @param tree 树 |
|
239 |
* @param parentId 父ID |
|
240 |
*/ |
|
241 |
const listToTree = (list, tree, parentId) => { |
|
242 |
list.forEach(item => { |
|
243 |
// 判断是否为父级菜单 |
|
244 |
// eslint-disable-next-line eqeqeq |
|
245 |
if (item.pid == parentId) { |
|
246 |
const child = { |
|
247 |
...item, |
|
248 |
key: item.key || item.name, |
|
249 |
children: [] |
|
250 |
} |
|
251 |
// 迭代 list, 找到当前菜单相符合的所有子菜单 |
|
252 |
listToTree(list, child.children, item.id) |
|
253 |
// 删掉不存在 children 值的属性 |
|
254 |
if (child.children.length <= 0) { |
|
255 |
delete child.children |
|
256 |
} |
|
257 |
// 加入到树中 |
|
258 |
tree.push(child) |
|
259 |
} |
|
260 |
}) |
|
261 |
} |