inleft
2022-02-09 9bcb19959eeb9da9bde2561e7278f6d0a55eb151
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 }