Skip to content
This repository was archived by the owner on May 12, 2020. It is now read-only.

Commit 2d90b23

Browse files
committed
feat(routes): dynamic routes filter and add it to global routes map
1 parent f2ac573 commit 2d90b23

5 files changed

Lines changed: 106 additions & 2 deletions

File tree

src/pages/Unauthorized/index.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template>
2+
<section class="page-unauthorized">{{info}}</section>
3+
</template>
4+
5+
<script>
6+
export default {
7+
data () {
8+
return {
9+
info: 'You are unauthorized !'
10+
}
11+
}
12+
}
13+
</script>
14+
15+
<style lang='scss' scoped>
16+
</style>

src/permission/index.js

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import router from 'ROUTER'
22
import store from 'STORE'
3+
import loginTypes from 'STORE/modules/login/mutations/types'
34
import NProgress from 'nprogress'
45
import 'nprogress/nprogress.css'
56
import { getTokenFromLocal } from 'UTILS/storage'
67
import { MessageBox } from 'element-ui'
8+
import dynamicRoutes from 'ROUTER/routes/dynamic'
9+
import constantRoutes from 'ROUTER/routes/constant'
710

811
NProgress.configure({ showSpinner: false })
912

@@ -28,13 +31,22 @@ router.beforeEach((to, from, next) => {
2831
if (getTokenFromLocal()) {
2932
// 1. fetch rolesMap if necessary (when rolesMap stored by back-end)
3033

31-
// 2. confirm route access by user role
34+
// 2. confirm route access by user role, including global routes creation.
3235
if (!store.getters['login/role']) {
3336
// 2.1 No roles: fetch user role
3437
return store.dispatch(
3538
'login/fetchUserAccess',
3639
store.getters['login/username']
3740
)
41+
.then(setDynamicRoutesToStorage)
42+
.then(setGlobalRoutesToStorage)
43+
.then(() => {
44+
router.addRoutes(store.getters['login/dynamicRoutes'])
45+
console.log(
46+
'[Routes creation]: routes has been added!',
47+
store.getters['login/dynamicRoutes']
48+
)
49+
})
3850
.catch(e => errorHandler(e, next, to.path))
3951
.finally(() => next())
4052
}
@@ -79,3 +91,59 @@ function errorHandler (e, next, redirectPath) {
7991
NProgress.done()
8092
console.error(e)
8193
}
94+
95+
/**
96+
* @param {String} role User access
97+
*/
98+
function createDynamicRoutes (role) {
99+
if (typeof role !== 'string') throw new Error('[Dynamic routes]: Wrong role.')
100+
101+
return filterRoutes(dynamicRoutes, role)
102+
// ! ADMINISTRATOR has all route access if necessary.
103+
// return role === ADMINISTRATOR
104+
// ? dynamicRoutes
105+
// : filterRoutes(dynamicRoutes, role)
106+
}
107+
108+
/**
109+
* @param {Object[]} routes Original routes
110+
* @param {String} role User access
111+
*/
112+
function filterRoutes (routes, role) {
113+
return routes.reduce((accumulator, route) => {
114+
const routeCopy = { ...route } // shallow copy
115+
if (hasAccess(route, role)) {
116+
if (routeCopy.children) {
117+
// filter original children routes, **override** all children routes.
118+
routeCopy.children = filterRoutes(routeCopy.children, role)
119+
}
120+
121+
// Skip `push` operation if all the route children has been filtered.
122+
if (!(routeCopy.children && !routeCopy.children.length)) {
123+
accumulator.push(routeCopy)
124+
}
125+
}
126+
return accumulator
127+
}, [])
128+
}
129+
130+
function hasAccess (route, role) {
131+
return route.meta && route.meta.roles
132+
? route.meta.roles.includes(role)
133+
: true
134+
}
135+
136+
function setDynamicRoutesToStorage (roles) {
137+
const currentRole = Array.isArray(roles) ? roles[0] : roles
138+
store.commit(
139+
`login/${loginTypes.SET_DYNAMIC_ROUTES}`,
140+
createDynamicRoutes(currentRole)
141+
)
142+
}
143+
144+
function setGlobalRoutesToStorage () {
145+
store.commit(`login/${loginTypes.SET_ALL_ROUTES}`, [
146+
...constantRoutes,
147+
...store.getters['login/dynamicRoutes']
148+
])
149+
}

src/router/components/constant.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export default [
66
'pages/Admin/Table',
77
'pages/Common/User',
88
'pages/Login',
9-
'pages/NotFound'
9+
'pages/NotFound',
10+
'pages/Unauthorized'
1011
]

src/router/routes/constant.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ export default [
4949
}
5050
]
5151
},
52+
{
53+
path: '/403',
54+
component: constantComponents.pagesUnauthorized
55+
},
5256
{
5357
path: '/404',
5458
component: constantComponents.pagesNotFound

src/router/routes/dynamic.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ export default [
2323
}
2424
]
2525
},
26+
// Should be hide all /private/* routes when user access exclude 'admin'
27+
// Because the only child route can only be accessed by admin
28+
{
29+
path: '/private',
30+
component: plainExport,
31+
children: [
32+
{
33+
path: 'admin',
34+
component: dynamicComponents.pagesAccess,
35+
meta: {
36+
roles: permission.access.admin
37+
}
38+
}
39+
]
40+
},
2641
{
2742
path: '*',
2843
redirect: '/404'

0 commit comments

Comments
 (0)