diff --git a/config/webpack.base.js b/config/webpack.base.js index 3d7e801..f3a1520 100644 --- a/config/webpack.base.js +++ b/config/webpack.base.js @@ -33,7 +33,8 @@ module.exports = { 'MOCK': path.resolve(PATH.ROOT_PATH, './mock'), 'SERVICES': path.resolve(PATH.SOURCE_PATH, './services'), 'AUTH': path.resolve(PATH.SOURCE_PATH, './auth'), - 'STORE': path.resolve(PATH.SOURCE_PATH, './store') + 'STORE': path.resolve(PATH.SOURCE_PATH, './store'), + 'ROUTER': path.resolve(PATH.SOURCE_PATH, './router') } }, module: { diff --git a/src/router/components/components.js b/src/router/components/components.js index 381d5ba..68a54cf 100644 --- a/src/router/components/components.js +++ b/src/router/components/components.js @@ -1,5 +1,5 @@ // Should be a path based on 'VIEW/' -export default [ +const common = [ 'Login', 'Dashboard/Analysis', 'Dashboard/Workspace', @@ -10,3 +10,12 @@ export default [ 'Form/Step/Success', 'Form/Advanced' ] + +const dynamic = [ + 'Permission' +] + +export { + common, + dynamic +} diff --git a/src/router/components/index.js b/src/router/components/index.js index 2af6675..dd694b2 100644 --- a/src/router/components/index.js +++ b/src/router/components/index.js @@ -1,4 +1,6 @@ import createImporter from './importer' -import components from './components' +import * as components from './components' -export default createImporter(components) +export const common = createImporter(components.common) + +export const dynamic = createImporter(components.dynamic) diff --git a/src/router/index.js b/src/router/index.js index a04e905..90ba72b 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -3,23 +3,30 @@ import VueRouter from 'vue-router' import store from 'STORE' import nprogress from 'nprogress' import 'nprogress/nprogress.css' -import routes from './routes' +import { commonRoutes } from './routes' import { getTokenFromLocal } from 'AUTH' Vue.use(VueRouter) const router = new VueRouter({ // mode: 'history', - routes + routes: commonRoutes }) router.beforeEach((to, from, next) => { nprogress.start() - if (getTokenFromLocal()) { // get token from sessionStorage + + // get token from sessionStorage + if (getTokenFromLocal()) { if (!store.getters['login/role'].length && to.path !== '/') { store.dispatch('login/fetchUserInfo') .then(({ role }) => { - store.dispatch('login/createRoutes', role) + // Preset dynamic routes is used to create new global routes map, + // filtered by `role` variable. + if (!Array.isArray(role)) { + throw new TypeError(`${JSON.stringify(role)} should be a array`) + } + store.dispatch('login/createExtraRoutes', { role }) }) } } diff --git a/src/router/routes.js b/src/router/routes/common.js similarity index 56% rename from src/router/routes.js rename to src/router/routes/common.js index cdfddde..e7d4e4f 100644 --- a/src/router/routes.js +++ b/src/router/routes/common.js @@ -1,43 +1,41 @@ -// import { createRoutes } from './utils' -// import paths from './components/components' -import components from './components' +import { common } from '../components' export default [ { path: '/', - component: components.login + component: common.login }, { path: '/dashboard/analysis', - component: components.dashboardAnalysis + component: common.dashboardAnalysis }, { path: '/dashboard/workspace', - component: components.dashboardWorkspace + component: common.dashboardWorkspace }, { path: '/form/basic', - component: components.formBasic + component: common.formBasic }, { path: '/form/step', - component: components.formStepIndex, + component: common.formStepIndex, redirect: '/form/step/info', children: [ { path: 'info', - component: components.formStepInfo + component: common.formStepInfo }, { path: 'confirm', - component: components.formStepConfirm, + component: common.formStepConfirm, beforeEnter (to, from, next) { from.path !== '/form/step/info' ? next('/form/step/info') : next() } }, { path: 'success', - component: components.formStepSuccess, + component: common.formStepSuccess, beforeEnter (to, from, next) { from.path !== '/form/step/confirm' ? next('/form/step/info') : next() } @@ -46,6 +44,6 @@ export default [ }, { path: '/form/advanced', - component: components.formAdvanced + component: common.formAdvanced } ] diff --git a/src/router/routes/dynamic.js b/src/router/routes/dynamic.js new file mode 100644 index 0000000..07e7752 --- /dev/null +++ b/src/router/routes/dynamic.js @@ -0,0 +1,18 @@ +import { dynamic } from '../components' + +export default [ + { + path: '/access/admin', + component: dynamic.permission, + meta: { + role: ['admin', 'user'] + } + }, + { + path: '/access/user', + component: dynamic.permission, + meta: { + role: ['user'] + } + } +] diff --git a/src/router/routes/index.js b/src/router/routes/index.js new file mode 100644 index 0000000..1c688d2 --- /dev/null +++ b/src/router/routes/index.js @@ -0,0 +1,7 @@ +import commonRoutes from './common' +import dynamicRoutes from './dynamic' + +export { + commonRoutes, + dynamicRoutes +} diff --git a/src/router/utils.js b/src/router/utils.js index 17b22c4..2a1bf9c 100644 --- a/src/router/utils.js +++ b/src/router/utils.js @@ -10,13 +10,13 @@ export function createChunkName (path) { return normalizePath.join('') } -export function createRoutes (paths, components, routes = []) { - paths.forEach(path => { - const chunkName = createChunkName(path) - routes.push({ - path: path.toLowerCase(), - component: components[chunkName] - }) - }) - return routes -} +// export function createRoutes (paths, components, routes = []) { +// paths.forEach(path => { +// const chunkName = createChunkName(path) +// routes.push({ +// path: path.toLowerCase(), +// component: components[chunkName] +// }) +// }) +// return routes +// } diff --git a/src/store/modules/login/actions.js b/src/store/modules/login/actions.js index 338dc77..2839652 100644 --- a/src/store/modules/login/actions.js +++ b/src/store/modules/login/actions.js @@ -1,5 +1,6 @@ import { pushLogin, fetchUserInfo } from 'SERVICES' import { setTokenToLocal } from 'AUTH' +import { dynamicRoutes } from 'ROUTER/routes' import types from './mutations/types' import { Notification } from 'element-ui' @@ -41,7 +42,32 @@ export default { }) .catch(console.error) }, - createRoutes ({ commit }, role) { - console.log(role) + createExtraRoutes ({ commit }, { role }) { + let globalRoutes = role.includes('admin') + ? dynamicRoutes + : filterRoutes(dynamicRoutes, role) + + commit(types.SET_ROUTES, globalRoutes) } } + +function filterRoutes (routes, role) { + const formatRoutes = [] + routes.forEach(route => { + const routeCopy = { ...route } // Prevent edit original routes map + if (hasAccess(route, role)) { + if (routeCopy.children) { + routeCopy.children = filterRoutes(routeCopy, role) + } + formatRoutes.push(routeCopy) + } + }) + + return formatRoutes +} + +function hasAccess (route, role) { + return route.meta && route.meta.role + ? role.some(key => route.meta.role.includes(key)) + : true // common routes in dynamic routes map +} diff --git a/src/store/modules/login/getters.js b/src/store/modules/login/getters.js index 9fa4c1f..cd788db 100644 --- a/src/store/modules/login/getters.js +++ b/src/store/modules/login/getters.js @@ -5,5 +5,8 @@ export default { }, role (state) { return state.role + }, + routes (state) { + return state.routes } } diff --git a/src/store/modules/login/mutations/index.js b/src/store/modules/login/mutations/index.js index 2c2eb11..667e6ea 100644 --- a/src/store/modules/login/mutations/index.js +++ b/src/store/modules/login/mutations/index.js @@ -9,5 +9,12 @@ export default { }, [types.SET_TOKEN] (state, token) { state.token = token + }, + [types.SET_ROUTES] (state, routes) { + // store it for passing it into router.addRoutes() + state.addRoutes = routes + + // store current global routes map, filtered by state.role + state.routes = [...state.routes, ...routes] } } diff --git a/src/store/modules/login/mutations/types.js b/src/store/modules/login/mutations/types.js index 5f2d0c5..6aadda6 100644 --- a/src/store/modules/login/mutations/types.js +++ b/src/store/modules/login/mutations/types.js @@ -1,5 +1,6 @@ export default { SET_USERNAME: 'SET_USERNAME', SET_ROLE: 'SET_ROLE', - SET_TOKEN: 'SET_TOKEN' + SET_TOKEN: 'SET_TOKEN', + SET_ROUTES: 'SET_ROUTES' } diff --git a/src/store/modules/login/state.js b/src/store/modules/login/state.js index 93a777c..0077881 100644 --- a/src/store/modules/login/state.js +++ b/src/store/modules/login/state.js @@ -1,5 +1,9 @@ +import { commonRoutes } from 'ROUTER/routes' + export default { username: '', role: [], - token: '' + token: '', + routes: commonRoutes, // store current global routes map + addRoutes: [] // for router.addRoutes() function } diff --git a/src/view/Permission.vue b/src/view/Permission.vue new file mode 100644 index 0000000..bf3cdb9 --- /dev/null +++ b/src/view/Permission.vue @@ -0,0 +1,19 @@ + + + + +