@@ -254,12 +254,8 @@ export default { | |||||
}, | }, | ||||
routerTitle: { | routerTitle: { | ||||
dashboard: { | dashboard: { | ||||
zh: '', | |||||
en: '', | |||||
dashboard: { | |||||
zh: '仪表盘', | |||||
en: 'Dashboard' | |||||
} | |||||
zh: '仪表盘', | |||||
en: 'Dashboard' | |||||
}, | }, | ||||
basic: { | basic: { | ||||
zh: '系统管理', | zh: '系统管理', | ||||
@@ -1,8 +1,8 @@ | |||||
<!-- | <!-- | ||||
* @Author: your name | * @Author: your name | ||||
* @Date: 2021-01-27 10:07:42 | * @Date: 2021-01-27 10:07:42 | ||||
* @LastEditTime: 2021-03-08 11:59:59 | |||||
* @LastEditors: gtz | |||||
* @LastEditTime: 2021-12-22 16:06:25 | |||||
* @LastEditors: zwq | |||||
* @Description: In User Settings Edit | * @Description: In User Settings Edit | ||||
* @FilePath: \mt-bus-fe\src\layout\components\Sidebar\index.vue | * @FilePath: \mt-bus-fe\src\layout\components\Sidebar\index.vue | ||||
--> | --> | ||||
@@ -31,31 +31,17 @@ import { mapGetters } from 'vuex' | |||||
import Logo from './Logo' | import Logo from './Logo' | ||||
import SidebarItem from './SidebarItem' | import SidebarItem from './SidebarItem' | ||||
import variables from '@/styles/variables.scss' | import variables from '@/styles/variables.scss' | ||||
// import { constantRoutes } from '@/router' | |||||
import store from '@/store' | |||||
import { constantRoutes } from '@/router' | |||||
export default { | export default { | ||||
components: { SidebarItem, Logo }, | components: { SidebarItem, Logo }, | ||||
computed: { | computed: { | ||||
...mapGetters([ | ...mapGetters([ | ||||
'sidebar', | 'sidebar', | ||||
'choicepart', | |||||
'permission_routes', | |||||
'language' | 'language' | ||||
]), | ]), | ||||
partList() { | |||||
const cangoList = [] | |||||
const constantRoutes = store.getters.permission_routes | |||||
constantRoutes.map(item => { | |||||
if (!item.hidden && item.meta) { | |||||
cangoList.push(item) | |||||
} | |||||
}) | |||||
const formatList = cangoList.map((item, index) => { | |||||
return this.setIndex(item, index) | |||||
}) | |||||
return formatList | |||||
}, | |||||
routeList() { | routeList() { | ||||
return [this.partList[this.choicepart]] | |||||
return constantRoutes | |||||
}, | }, | ||||
activeMenu() { | activeMenu() { | ||||
const route = this.$route | const route = this.$route | ||||
@@ -67,6 +53,7 @@ export default { | |||||
return path | return path | ||||
}, | }, | ||||
showLogo() { | showLogo() { | ||||
console.log(this.$route) | |||||
return this.$store.state.settings.sidebarLogo | return this.$store.state.settings.sidebarLogo | ||||
}, | }, | ||||
variables() { | variables() { | ||||
@@ -75,24 +62,6 @@ export default { | |||||
isCollapse() { | isCollapse() { | ||||
return !this.sidebar.opened | return !this.sidebar.opened | ||||
} | } | ||||
}, | |||||
watch: { | |||||
$route: function(val) { | |||||
if (val.meta.routeIndex >= 0) { | |||||
this.$store.dispatch('app/setChoicepart', val.meta.routeIndex) | |||||
} | |||||
} | |||||
}, | |||||
methods: { | |||||
setIndex(list, index) { | |||||
list.meta.routeIndex = index | |||||
if (list.children) { | |||||
list.children.map(item => { | |||||
this.setIndex(item, index) | |||||
}) | |||||
} | |||||
return list | |||||
} | |||||
} | } | ||||
} | } | ||||
</script> | </script> |
@@ -45,8 +45,8 @@ export default { | |||||
return this.$store.state.tagsView.visitedViews | return this.$store.state.tagsView.visitedViews | ||||
}, | }, | ||||
routes() { | routes() { | ||||
// return this.$store.state.permission.routes | |||||
return [] | |||||
return this.$store.state.permission.routes | |||||
// return [] | |||||
} | } | ||||
}, | }, | ||||
watch: { | watch: { | ||||
@@ -1,12 +1,11 @@ | |||||
/* | /* | ||||
* @Date: 2020-12-14 09:07:03 | * @Date: 2020-12-14 09:07:03 | ||||
* @LastEditors: gtz | |||||
* @LastEditTime: 2021-02-25 09:42:36 | |||||
* @LastEditors: zwq | |||||
* @LastEditTime: 2021-12-22 16:13:30 | |||||
* @FilePath: \basic-admin\src\permission.js | * @FilePath: \basic-admin\src\permission.js | ||||
* @Description: 路由权限检查 | * @Description: 路由权限检查 | ||||
*/ | */ | ||||
import router from './router' | import router from './router' | ||||
// import { resetRouter } from '@/router' | |||||
import { Message } from 'element-ui' | import { Message } from 'element-ui' | ||||
import NProgress from 'nprogress' // progress bar | import NProgress from 'nprogress' // progress bar | ||||
import 'nprogress/nprogress.css' // progress bar style | import 'nprogress/nprogress.css' // progress bar style | ||||
@@ -35,38 +34,28 @@ router.beforeEach(async(to, from, next) => { | |||||
next({ path: '/' }) | next({ path: '/' }) | ||||
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 | NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 | ||||
} else { | } else { | ||||
const hasRoles = store.getters.menus && store.getters.menus.length > 0 | |||||
console.log('store.getters.menus', store.getters.menus) | |||||
console.log('store.getters', store.getters) | |||||
console.log('hasRoles=', hasRoles) | |||||
if (hasRoles) { | |||||
console.log('hasRoles=', store.getters.menus) | |||||
// next() | |||||
NProgress.done() | |||||
try { | |||||
// // generate accessible routes map based on roles | |||||
// const accessRoutes = await store.dispatch('permission/generateRoutes') | |||||
// console.log(accessRoutes) | |||||
// router.addRoutes(accessRoutes) | |||||
next() | next() | ||||
NProgress.done() | |||||
} else { | |||||
try { | |||||
// // generate accessible routes map based on roles | |||||
const { menus } = await store.dispatch('user/getInfo') | |||||
console.log(menus) | |||||
const accessRoutes = await store.dispatch('permission/generateRoutes', menus) | |||||
console.log('accessRoutes', accessRoutes) | |||||
router.addRoutes(accessRoutes) | |||||
next({ ...to, replace: true }) | |||||
// hack method to ensure that addRoutes is complete | // hack method to ensure that addRoutes is complete | ||||
// set the replace: true, so the navigation will not leave a history record | // set the replace: true, so the navigation will not leave a history record | ||||
// next({ ...to, replace: true }) | // next({ ...to, replace: true }) | ||||
} catch (error) { | |||||
} catch (error) { | |||||
// remove token and go to login page to re-login | // remove token and go to login page to re-login | ||||
next(`/login?redirect=${to.path}`) | |||||
await store.dispatch('user/resetToken') | |||||
Message.error(error || 'Has Error') | |||||
NProgress.done() | |||||
} | |||||
next(`/login?redirect=${to.path}`) | |||||
await store.dispatch('user/resetToken') | |||||
Message.error(error || 'Has Error') | |||||
NProgress.done() | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
/* has no token*/ | /* has no token*/ | ||||
console.log('has no token to.path=' + to.path) | |||||
console.log('to.path=' + to.path) | |||||
console.log('whiteList.indexOf(to.path)=' + whiteList.indexOf(to.path)) | console.log('whiteList.indexOf(to.path)=' + whiteList.indexOf(to.path)) | ||||
if (whiteList.indexOf(to.path) !== -1) { | if (whiteList.indexOf(to.path) !== -1) { | ||||
// in the free login whitelist, go directly | // in the free login whitelist, go directly | ||||
@@ -2,7 +2,6 @@ import Vue from 'vue' | |||||
import Router from 'vue-router' | import Router from 'vue-router' | ||||
import i18n from '@/lang/i18n' | import i18n from '@/lang/i18n' | ||||
import Cookies from 'js-cookie' | import Cookies from 'js-cookie' | ||||
import store from '@/store' | |||||
const routerTitle = i18n.routerTitle | const routerTitle = i18n.routerTitle | ||||
const language = Cookies.get('language') | const language = Cookies.get('language') | ||||
@@ -60,11 +59,24 @@ export const constantRoutes = [ | |||||
}, | }, | ||||
{ | { | ||||
path: '/', | path: '/', | ||||
component: () => import('@/views/ChoicePart'), | |||||
hidden: true, | |||||
meta: { requireToken: true } | |||||
component: Layout, | |||||
redirect: '/dashboard', | |||||
children: [ | |||||
{ | |||||
path: 'dashboard', | |||||
component: () => import('@/views/dashboard/index'), | |||||
name: 'Dashboard', | |||||
meta: { title: routerTitle.dashboard?.[language] || routerTitle.dashboard.en, icon: 'form', iconPart: 'dashboard', affix: true, required: true, requireToken: true } | |||||
} | |||||
] | |||||
}, | }, | ||||
// { | // { | ||||
// path: '/', | |||||
// component: () => import('@/views/ChoicePart'), | |||||
// hidden: true, | |||||
// meta: { requireToken: true } | |||||
// }, | |||||
// { | |||||
// path: '/auth-redirect', | // path: '/auth-redirect', | ||||
// component: () => import('@/views/login/auth-redirect'), | // component: () => import('@/views/login/auth-redirect'), | ||||
// hidden: true | // hidden: true | ||||
@@ -78,28 +90,7 @@ export const constantRoutes = [ | |||||
path: '/401', | path: '/401', | ||||
component: () => import('@/views/error-page/401'), | component: () => import('@/views/error-page/401'), | ||||
hidden: true | hidden: true | ||||
} | |||||
// 工单管理、厂务管理、包装管理、接口管理、数据采集、报表、质量管理、SPC | |||||
/** when your routing map is too long, you can split it into small modules **/ | |||||
// 404 page must be placed at the end !!! | |||||
// { path: '*', redirect: '/404', hidden: true } | |||||
] | |||||
export const dynamicRoutes = [ | |||||
// { | |||||
// path: '/dashboard', | |||||
// component: Layout, | |||||
// redirect: '/dashboard', | |||||
// name: 'dashboard', | |||||
// children: [ | |||||
// { | |||||
// path: 'dashboard', | |||||
// component: () => import('@/views/dashboard/index'), | |||||
// name: 'Dashboard', | |||||
// meta: { title: routerTitle.dashboard.dashboard?.[language] || routerTitle.dashboard.dashboard.en, icon: 'dashboard', affix: true } | |||||
// } | |||||
// ] | |||||
// }, | |||||
}, | |||||
{ | { | ||||
path: '/basicData', | path: '/basicData', | ||||
component: Layout, | component: Layout, | ||||
@@ -511,7 +502,7 @@ export const dynamicRoutes = [ | |||||
path: 'recipe', | path: 'recipe', | ||||
component: () => import('@/views/EquipmentManager/RecipeManager'), | component: () => import('@/views/EquipmentManager/RecipeManager'), | ||||
name: 'RecipeManage', | name: 'RecipeManage', | ||||
meta: { title: routerTitle.equipment.recipe?.[language] || routerTitle.equipment.recipe?.en, icon: 'form', affix: true } | |||||
meta: { title: routerTitle.equipment.recipe?.[language] || routerTitle.equipment.recipe.en, icon: 'form', affix: true } | |||||
}, { | }, { | ||||
path: 'sparepart', | path: 'sparepart', | ||||
component: () => import('@/views/EquipmentManager/sqarepart'), | component: () => import('@/views/EquipmentManager/sqarepart'), | ||||
@@ -529,7 +520,7 @@ export const dynamicRoutes = [ | |||||
component: () => import('@/views/EquipmentManager/RecipeManager/subpage/detail'), | component: () => import('@/views/EquipmentManager/RecipeManager/subpage/detail'), | ||||
name: 'RecipeParamManage', | name: 'RecipeParamManage', | ||||
hidden: true, | hidden: true, | ||||
meta: { title: routerTitle.equipment.recipeform?.[language] || routerTitle.equipment.recipeform?.en, icon: 'form', affix: true } | |||||
meta: { title: routerTitle.equipment.recipeform?.[language] || routerTitle.equipment.recipeform.en, icon: 'form', affix: true } | |||||
}, { | }, { | ||||
path: 'statussetting', | path: 'statussetting', | ||||
component: () => import('@/views/EquipmentManager/StatusSetting'), | component: () => import('@/views/EquipmentManager/StatusSetting'), | ||||
@@ -1187,18 +1178,18 @@ export const dynamicRoutes = [ | |||||
path: 'plan', | path: 'plan', | ||||
component: () => import('@/views/QualityManager/plan'), | component: () => import('@/views/QualityManager/plan'), | ||||
name: 'PlanManage', | name: 'PlanManage', | ||||
meta: { title: routerTitle.quality.plan?.[language] || routerTitle.quality.plan?.en, icon: 'form', affix: true } | |||||
meta: { title: routerTitle.quality.plan?.[language] || routerTitle.quality.plan.en, icon: 'form', affix: true } | |||||
}, { | }, { | ||||
path: 'planparam', | path: 'planparam', | ||||
component: () => import('@/views/QualityManager/plan/subpage/detail'), | component: () => import('@/views/QualityManager/plan/subpage/detail'), | ||||
name: 'PlanParamManage', | name: 'PlanParamManage', | ||||
hidden: true, | hidden: true, | ||||
meta: { title: routerTitle.quality.planform?.[language] || routerTitle.quality.planform?.en, icon: 'form', affix: true } | |||||
meta: { title: routerTitle.quality.planform?.[language] || routerTitle.quality.planform.en, icon: 'form', affix: true } | |||||
}, { | }, { | ||||
path: 'issue', | path: 'issue', | ||||
component: () => import('@/views/QualityManager/plan/issuedplan'), | component: () => import('@/views/QualityManager/plan/issuedplan'), | ||||
name: 'PlanIssuedManage', | name: 'PlanIssuedManage', | ||||
meta: { title: routerTitle.quality.issuedplan?.[language] || routerTitle.quality.issuedplan?.en, icon: 'form', affix: true } | |||||
meta: { title: routerTitle.quality.issuedplan?.[language] || routerTitle.quality.issuedplan.en, icon: 'form', affix: true } | |||||
}, | }, | ||||
{ | { | ||||
path: '/offlineDetec', | path: '/offlineDetec', | ||||
@@ -1296,49 +1287,23 @@ export const dynamicRoutes = [ | |||||
}, | }, | ||||
{ path: '*', redirect: '/404', hidden: true } | { path: '*', redirect: '/404', hidden: true } | ||||
] | ] | ||||
export const asyncRoutes = [ | |||||
// 404 page must be placed at the end !!! | |||||
{ path: '*', redirect: '/404', hidden: true } | |||||
] | |||||
const createRouter = (r) => | |||||
const createRouter = () => | |||||
new Router({ | new Router({ | ||||
// mode: 'history', // require service support | // mode: 'history', // require service support | ||||
scrollBehavior: () => ({ y: 0 }), | scrollBehavior: () => ({ y: 0 }), | ||||
routes: r | |||||
routes: constantRoutes | |||||
}) | }) | ||||
const router = createRouter(constantRoutes) | |||||
router.beforeEach((to, from, next) => { | |||||
console.log('route.index', to, to.meta.routeIndex) | |||||
if (to.meta.routeIndex >= 0) { | |||||
store.dispatch('app/setChoicepart', to.meta.routeIndex) | |||||
} | |||||
// 拦截器 | |||||
console.log('route,to.path:', to.path) | |||||
if (to.meta.requireToken) { | |||||
if (Cookies.get('Admin-Token')) { | |||||
if (to.meta.required) { | |||||
if (Cookies.get('choicepart') === 'undefined' || !Cookies.get('choicepart')) { | |||||
next({ | |||||
path: '/' | |||||
}) | |||||
} else { | |||||
next() | |||||
} | |||||
} else { | |||||
next() | |||||
} | |||||
} else { | |||||
next({ | |||||
path: '/login' | |||||
}) | |||||
} | |||||
} else { | |||||
next() | |||||
} | |||||
}) | |||||
const router = createRouter() | |||||
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 | // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465 | ||||
export function resetRouter() { | export function resetRouter() { | ||||
const newRouter = createRouter(constantRoutes) | |||||
const newRouter = createRouter() | |||||
router.matcher = newRouter.matcher // reset router | router.matcher = newRouter.matcher // reset router | ||||
} | } | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* @Date: 2020-12-14 09:07:03 | * @Date: 2020-12-14 09:07:03 | ||||
* @LastEditors: gtz | |||||
* @LastEditTime: 2021-01-29 14:24:20 | |||||
* @LastEditors: zwq | |||||
* @LastEditTime: 2021-12-22 11:38:46 | |||||
* @FilePath: \basic-admin\src\store\getters.js | * @FilePath: \basic-admin\src\store\getters.js | ||||
* @Description: | * @Description: | ||||
*/ | */ | ||||
@@ -19,7 +19,6 @@ const getters = { | |||||
introduction: state => state.user.introduction, | introduction: state => state.user.introduction, | ||||
username: state => state.user.username, | username: state => state.user.username, | ||||
roles: state => state.user.roles, | roles: state => state.user.roles, | ||||
menus: state => state.user.menus, | |||||
permission_routes: state => state.permission.routes | permission_routes: state => state.permission.routes | ||||
} | } | ||||
export default getters | export default getters |
@@ -1,36 +1,38 @@ | |||||
import { dynamicRoutes, constantRoutes } from '@/router' | |||||
import { getListItems } from '@/utils/tree' | |||||
/* | |||||
* @Author: zwq | |||||
* @Date: 2021-09-18 16:09:08 | |||||
* @LastEditors: zwq | |||||
* @LastEditTime: 2021-12-22 15:43:46 | |||||
* @Description: | |||||
*/ | |||||
import { asyncRoutes, constantRoutes } from '@/router' | |||||
/** | /** | ||||
* Use meta.role to determine if the current user has permission | * Use meta.role to determine if the current user has permission | ||||
* @param roles | * @param roles | ||||
* @param route | * @param route | ||||
*/ | */ | ||||
function hasPermission(menuList, route) { | |||||
// if (route.meta && route.meta.roles) { | |||||
// return roles.some(role => route.meta.roles.includes(role)) | |||||
// } else { | |||||
// return true | |||||
// } | |||||
if (route.hidden) { | |||||
function hasPermission(roles, route) { | |||||
if (route.meta && route.meta.roles) { | |||||
return roles.some(role => route.meta.roles.includes(role)) | |||||
} else { | |||||
return true | return true | ||||
} | } | ||||
return menuList.some(m => route.path === m.h) | |||||
} | } | ||||
/** | /** | ||||
* Filter asynchronous routing tables by recursion | * Filter asynchronous routing tables by recursion | ||||
* @param routes asyncRoutes | * @param routes asyncRoutes | ||||
* @param menuList | |||||
* @param roles | |||||
*/ | */ | ||||
export function filterAsyncRoutes(routes, menuList) { | |||||
export function filterAsyncRoutes(routes, roles) { | |||||
const res = [] | const res = [] | ||||
routes.forEach(route => { | routes.forEach(route => { | ||||
const tmp = { ...route } | const tmp = { ...route } | ||||
if (hasPermission(menuList, tmp)) { | |||||
if (hasPermission(roles, tmp)) { | |||||
if (tmp.children) { | if (tmp.children) { | ||||
tmp.children = filterAsyncRoutes(tmp.children, menuList) | |||||
tmp.children = filterAsyncRoutes(tmp.children, roles) | |||||
} | } | ||||
res.push(tmp) | res.push(tmp) | ||||
} | } | ||||
@@ -52,19 +54,13 @@ const mutations = { | |||||
} | } | ||||
const actions = { | const actions = { | ||||
generateRoutes({ commit }, menus) { | |||||
generateRoutes({ commit }, roles) { | |||||
return new Promise(resolve => { | return new Promise(resolve => { | ||||
let accessedRoutes | let accessedRoutes | ||||
console.log(menus) | |||||
if (!menus) { | |||||
accessedRoutes = [] | |||||
if (roles.includes('admin')) { | |||||
accessedRoutes = asyncRoutes || [] | |||||
} else { | } else { | ||||
const menuList = [] | |||||
getListItems(menus, node => menuList.push(node)) | |||||
console.log(menuList) | |||||
console.log(dynamicRoutes) | |||||
accessedRoutes = filterAsyncRoutes(dynamicRoutes, menuList) | |||||
console.log(accessedRoutes) | |||||
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) | |||||
} | } | ||||
commit('SET_ROUTES', accessedRoutes) | commit('SET_ROUTES', accessedRoutes) | ||||
resolve(accessedRoutes) | resolve(accessedRoutes) | ||||
@@ -9,7 +9,6 @@ const state = { | |||||
avatar: '', | avatar: '', | ||||
introduction: '', | introduction: '', | ||||
roles: [], | roles: [], | ||||
menus: [], | |||||
username: Cookies.get('username') || '' | username: Cookies.get('username') || '' | ||||
} | } | ||||
@@ -26,9 +25,6 @@ const mutations = { | |||||
SET_AVATAR: (state, avatar) => { | SET_AVATAR: (state, avatar) => { | ||||
state.avatar = avatar | state.avatar = avatar | ||||
}, | }, | ||||
SET_MENUS: (state, menus) => { | |||||
state.menus = menus | |||||
}, | |||||
SET_ROLES: (state, roles) => { | SET_ROLES: (state, roles) => { | ||||
state.roles = roles | state.roles = roles | ||||
}, | }, | ||||
@@ -70,17 +66,16 @@ const actions = { | |||||
reject('Verification failed, please Login again.') | reject('Verification failed, please Login again.') | ||||
} | } | ||||
const { roles, name, avatar, introduction, menus } = data | |||||
const { roles, name, avatar, introduction } = data | |||||
// roles must be a non-empty array | // roles must be a non-empty array | ||||
if (!menus || menus.length <= 0) { | |||||
reject('getInfo: menus must be a non-null array!') | |||||
if (!roles || roles.length <= 0) { | |||||
reject('getInfo: roles must be a non-null array!') | |||||
} | } | ||||
commit('SET_ROLES', roles || []) | |||||
commit('SET_ROLES', roles) | |||||
commit('SET_NAME', name) | commit('SET_NAME', name) | ||||
commit('SET_AVATAR', avatar) | commit('SET_AVATAR', avatar) | ||||
commit('SET_MENUS', menus) | |||||
commit('SET_INTRODUCTION', introduction) | commit('SET_INTRODUCTION', introduction) | ||||
resolve(data) | resolve(data) | ||||
}).catch(error => { | }).catch(error => { | ||||
@@ -97,7 +92,6 @@ const actions = { | |||||
dispatch('tagsView/delAllViews', null, { root: true }) | dispatch('tagsView/delAllViews', null, { root: true }) | ||||
commit('SET_TOKEN', '') | commit('SET_TOKEN', '') | ||||
commit('SET_ROLES', []) | commit('SET_ROLES', []) | ||||
commit('SET_MENUS', []) | |||||
commit('SET_USERNAME') | commit('SET_USERNAME') | ||||
Cookies.set('username', '') | Cookies.set('username', '') | ||||
localStorage.clear() | localStorage.clear() | ||||