diff --git a/src/api/system/role.js b/src/api/system/role.js index 1cefa63..94555a3 100644 --- a/src/api/system/role.js +++ b/src/api/system/role.js @@ -31,25 +31,19 @@ export function GetRoleDetail(id){ }) } -export function AddRole(Role,MenuList){ +export function AddRole(data){ return fetch({ url: '/role/add', method: 'post', - data:{ - Role, - MenuList - } + data }) } -export function UpdateRole(Role,MenuList){ +export function UpdateRole(data){ return fetch({ url: '/role/update', method: 'post', - data:{ - Role, - MenuList - } + data }) } diff --git a/src/permission.js b/src/permission.js index f42d383..623fcfe 100644 --- a/src/permission.js +++ b/src/permission.js @@ -16,10 +16,12 @@ router.beforeEach((to, from, next) => { }) } else { if (store.getters.addRouters.length === 0) { - store.dispatch('GetInfo').then(res => { - console.log(store.getters.addRouters) - router.addRoutes(store.getters.addRouters) - next({ ...to}) + store.dispatch('GetInfo').then(res => { // 拉取user_info + const roleauthname = res.RoleAuthName.split(',') // note: roles must be a array! such as: ['editor','develop'] + store.dispatch('GenerateRoutes', { roleauthname }).then(() => { // 根据roles权限生成可访问的路由表 + router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表 + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record + }) }) } else { diff --git a/src/router/index.js b/src/router/index.js index e427597..1813932 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -41,26 +41,55 @@ export default new Router({ - export const asyncRouterMap_Map = { - "movie": ()=>import('@/views/DouBan/movie'), - "music": ()=>import('@/views/DouBan/music'), - "book": ()=>import('@/views/DouBan/book'), - "users": ()=>import('@/views/system/users'), - "role": ()=>import('@/views/system/role'), - "dept": ()=>import('@/views/system/dept'), - "menu": ()=>import('@/views/system/menu'), - - "person_edit": ()=>import('@/views/Archive/person'), - "person_detail": ()=>import('@/views/Archive/person_detail') - - } - // { - // path: '/People', - // component: Layout, - // redirect: '/People/person', - // name:"person", - // title:"人员信息", - // icon:'wujiaoxing', - // children: [{ path: 'person', name: 'person1',title:"人员信息录入", component: ()=>import('@/views/KaoQin/person'),meta:{title:"人员信息录入"}}] - // }, + export const asyncRouterMap = [ + { + path: '/Archive', + component: Layout, + redirect: '/Archive/person', + name:"Archive", + title:"廉政档案", + icon:'yonghuming', + children: [ + { path: 'person', name: 'person',title:"廉政档案编辑", component: ()=>import('@/views/Archive/person'),meta:{title:"廉政档案编辑"}}, + { path: 'person_detail', name: 'person_detail',title:"廉政档案查看", component: ()=>import('@/views/Archive/person_detail'),meta:{title:"廉政档案查看"}} + ] + }, + + { + path: '/DouBan', + component: Layout, + redirect: '/DouBan/person', + name:"DouBan", + title:"豆瓣查询", + icon:'tubiao', + children: [ + { path: 'movie', name: 'movie',title:"热门电影", component: ()=>import('@/views/DouBan/movie'),meta:{title:"热门电影"}}, + { path: 'music', name: 'music',title:"热门音乐", component: ()=>import('@/views/DouBan/music'),meta:{title:"热门音乐"}}, + { path: 'book', name: 'book',title:"热门书籍", component: ()=>import('@/views/DouBan/book'),meta:{title:"热门书籍"}} + + ] + }, + + { + path: '/system', + component: Layout, + redirect: '/system/user', + name:"system", + title:"系统设置", + icon:'zujian', + children: [ + { path: 'users', name: 'users',title:"用户设置", component: ()=>import('@/views/system/users'),meta:{title:"用户设置"}}, + { path: 'dept', name: 'dept',title:"部门设置", component: ()=>import('@/views/system/dept'),meta:{title:"部门设置"}}, + { path: 'role', name: 'role',title:"角色设置", component: ()=>import('@/views/system/role'),meta:{title:"角色设置"}}, + // { path: 'menu', name: 'menu',title:"菜单设置", component: ()=>import('@/views/system/menu'),meta:{title:"菜单设置"}} + + ] + }, + + {path:"*",redirect:"/404",hidden:true} + ] + + + + \ No newline at end of file diff --git a/src/store/getters.js b/src/store/getters.js index a84e2be..5622bd2 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -6,7 +6,8 @@ const getters = { cachedViews: state => state.tagsView.cachedViews, realname:state=>state.user.realname, name: state => state.user.name, - permission_routers: state => state.user.routers, - addRouters: state => state.user.addRouters + addRouters: state => state.permission.addRouters, + routers:state=>state.permission.routers + } export default getters diff --git a/src/store/index.js b/src/store/index.js index ec36ddf..0889660 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3,6 +3,7 @@ import Vuex from 'vuex' import app from './modules/app' import user from './modules/user' import tagsView from './modules/tagsView' +import permission from './modules/permission' import getters from './getters' @@ -12,6 +13,7 @@ const store = new Vuex.Store({ modules: { app, user, + permission, tagsView }, getters diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js new file mode 100644 index 0000000..cd72423 --- /dev/null +++ b/src/store/modules/permission.js @@ -0,0 +1,67 @@ +import { + asyncRouterMap, + constantRouterMap +} from '@/router/index' + +/** + * 通过meta.role判断是否与当前用户权限匹配 + * @param roles + * @param route + */ +function hasPermission(roles, route) { + if (route.name) { + return roles.some(role => route.name.includes(role)) + } else { + return true + } +} + +/** + * 递归过滤异步路由表,返回符合用户角色权限的路由表 + * @param asyncRouterMap + * @param roles + */ +function filterAsyncRouter(asyncRouterMap, roleauthname) { + const accessedRouters = asyncRouterMap.filter(route => { + if (hasPermission(roleauthname, route)) { + if (route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, roleauthname) + } + return true + } + return false + }) + return accessedRouters +} + +const permission = { + state: { + routers: constantRouterMap, + addRouters: [], + }, + mutations: { + SET_ROUTERS: (state, routers) => { + state.addRouters = routers + state.routers = constantRouterMap.concat(routers) + }, + }, + actions: { + GenerateRoutes({ + commit + }, data) { + return new Promise(resolve => { + const { + roleauthname + } = data + let accessedRouters + + accessedRouters = filterAsyncRouter(asyncRouterMap, roleauthname) + + commit('SET_ROUTERS', accessedRouters) + resolve() + }) + } + } +} + +export default permission diff --git a/src/store/modules/user.js b/src/store/modules/user.js index aadecd8..f26c355 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -11,33 +11,8 @@ import { import { ChangePassword } from '@/api/login' -import { constantRouterMap,asyncRouterMap_Map } from '@/router/index' import 'nprogress/nprogress.css' // Progress 进度条样式 -import Layout from '@/views/layout/Layout' - - -function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象 - const accessedRouters = asyncRouterMap.filter(route => { - if (route.component) { - if (route.component === 'Layout') {//Layout组件特殊处理 - route.component = Layout - } else { - // route.component = ()=>import(`@/views/${route.component}`) - - route.component =asyncRouterMap_Map[route.name] - - - } - } - if (route.children && route.children.length) { - route.children = filterAsyncRouter(route.children) - } - return true - }) - - return accessedRouters -} @@ -46,31 +21,15 @@ const user = { token: getToken(), name: '', //用户昵称名 realname: '', //用户登录名 - routers: constantRouterMap, //登录后 则保存的是全部路由 - addRouters: [] //后台返回的异步路由信息 - }, mutations: { - - SET_ROUTERS: (state, routers) => { - - console.log(routers) - routers.push({path:"*",redirect:'/404',hidden:true}) - state.addRouters = routers - state.routers = constantRouterMap.concat(routers) - }, - - - SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, - - SET_REALNAME: (state, realname) => { state.realname = realname } @@ -95,7 +54,6 @@ const user = { } else { commit('SET_TOKEN', '') - commit('SET_ROLES', []) removeToken() reject(data.message) } @@ -118,12 +76,6 @@ const user = { console.log(data); commit('SET_NAME', data.RealName) commit('SET_REALNAME', data.UserName) - const asyncrouters =filterAsyncRouter(data.Routers) - - commit('SET_ROUTERS', asyncrouters) - - - resolve(data) }).catch(error => { reject(error) @@ -138,11 +90,9 @@ const user = { }) { return new Promise(resolve => { logout().then(res => { - commit('SET_TOKEN', '') - removeToken() - resolve() - }).catch(err => { - reject(err) + commit('SET_TOKEN', '') + removeToken() + resolve() }) }) @@ -158,15 +108,15 @@ const user = { password: NewPassword }).then(response => { const data = response - resolve(data) - logout().then(res => { - commit('SET_TOKEN', '') - removeToken() - resolve() + resolve(data) + logout().then(res => { + commit('SET_TOKEN', '') + removeToken() + resolve() }).catch(err => { reject(err) }) - + }).catch(error => { reject(error) }) diff --git a/src/utils/fetch.js b/src/utils/fetch.js index 2b09bfa..2eca641 100644 --- a/src/utils/fetch.js +++ b/src/utils/fetch.js @@ -1,10 +1,13 @@ import axios from 'axios' import { - Message,MessageBox + Message, + MessageBox } from 'element-ui' import store from '../store' import { - getToken,setToken,removeToken + getToken, + setToken, + removeToken } from '@/utils/auth' // 创建axios实例 @@ -33,32 +36,29 @@ service.interceptors.request.use(config => { service.interceptors.response.use( response => { const res = response.data + console.log(response) // 401 403 :帐号信息与token不匹配 需要重新拉取token - if (res.code === 401||res.code === 403||(res.message.indexOf("Token")&&res.status===500)) { + if (res.code === 401 || res.code === 403) { MessageBox.alert('帐号信息发生变化,请重新登录', { confirmButtonText: '重新登录', showCancelButton: false, type: 'warning' }).then(() => { setToken("") - location.reload() // 为了重新实例化vue-router对象 避免bug + removeToken() + location.reload() // 为了重新实例化vue-router对象 避免bug }) - return Promise.reject(error) - } - else { + } else { if (res.code !== 200) { //后台报错信息显示 - - Message({ - message: res.message, - type: 'error', - duration: 1500 - }) - return Promise.reject(error) - } -console.log(res.message) - if(res.message!==""&&res.message!=null&&res.message!=="SUCCESS") //统一显示后台返回结果 + Message({ + message: res.message, + type: 'error', + duration: 1500 + }) + + } else if (res.message !== "" && res.message != null && res.message !== "SUCCESS") //统一显示后台返回结果 { Message({ @@ -70,18 +70,13 @@ console.log(res.message) } console.log(res) -return res + return res } }, error => { - console.log('err' + error) // for debug - Message({ - message: error.message, - type: 'error', - duration: 5 * 1000 - }) + return Promise.reject(error) } ) diff --git a/src/views/layout/components/Sidebar.vue b/src/views/layout/components/Sidebar.vue index 868a154..464f946 100644 --- a/src/views/layout/components/Sidebar.vue +++ b/src/views/layout/components/Sidebar.vue @@ -9,7 +9,7 @@ :default-active="$route.path"> - + @@ -23,7 +23,7 @@ export default { SidebarItem }, computed: { - ...mapGetters(["permission_routers"]), + ...mapGetters(["routers"]), isCollapse() { return !this.$store.getters.sidebar.opened; } diff --git a/src/views/login/index.vue b/src/views/login/index.vue index edbce4b..3576068 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -70,7 +70,6 @@ export default { }, 2000); }) .catch(error => { - this.$message.error(error); this.loading = false; }); diff --git a/src/views/system/role.vue b/src/views/system/role.vue index 294639d..084a5b4 100644 --- a/src/views/system/role.vue +++ b/src/views/system/role.vue @@ -46,7 +46,7 @@ - @@ -71,8 +71,9 @@ import { AddRole, UpdateRole } from "@/api/system/role" -import {GetMenuTreeByRoleID,MenuTree} from "@/api/system/menu" + +import {asyncRouterMap} from '@/router/index' import { mapGetters } from "vuex" import store from '@/store' export default { @@ -90,8 +91,8 @@ export default { id: "", rolename: "", rank: "", + roleauthname:null }, - menulist:[], menu: null, listQuery: { totalCount: 0, @@ -107,9 +108,18 @@ export default { created() { this.fetchData(this.listQuery) - MenuTree().then(response=>{ - this.menu=response.data + + + let arr = asyncRouterMap.filter(item=>{ + + if(item.hidden) + return false + else + return true + }) + this.menu=arr + }, methods: { @@ -163,10 +173,9 @@ export default { GetRoleDetail(id).then(response => { this.dialogStatus = "update" - this.temp = response.data.Role -console.log(response.data.MenuList) + this.temp = response.data this.$nextTick(() => { - this.$refs.tree.setCheckedKeys(response.data.MenuList) + this.$refs.tree.setCheckedKeys(this.temp.roleauthname.split(',')) }) this.dialogFormVisible = true @@ -175,17 +184,17 @@ console.log(response.data.MenuList) }, create() { - this.menulist = this.$refs.tree.getCheckedKeys() + this.temp.roleauthname = this.$refs.tree.getCheckedKeys().join(',') - AddRole(this.temp,this.menulist).then(response => { + AddRole(this.temp).then(response => { this.dialogFormVisible = false this.fetchData(this.listQuery) }) }, update() { - this.menulist = this.$refs.tree.getCheckedKeys() - UpdateRole(this.temp,this.menulist).then(response => { + this.temp.roleauthname = this.$refs.tree.getCheckedKeys().join(',') + UpdateRole(this.temp).then(response => { this.dialogFormVisible = false