diff --git a/src/api/system/sysMenu.js b/src/api/system/sysMenu.js index 81c0024..9a3e3a5 100644 --- a/src/api/system/sysMenu.js +++ b/src/api/system/sysMenu.js @@ -65,5 +65,33 @@ export default { method: 'put', data: sysMenu }) + }, + /** + * 查看某个角色的权限列表 + * + * @param roleId + * @returns {AxiosPromise} + */ + + toAssign(roleId) { + return request({ + url: `${api_name}/toAssign/${roleId}`, + method: 'get' + }) + }, + + /** + * 给某个角色授权 + * + * @param assignMenuVo + * @returns {AxiosPromise} + */ + + doAssign(assignMenuVo) { + return request({ + url: `${api_name}/doAssign`, + method: 'post', + data: assignMenuVo + }) } } diff --git a/src/api/user.js b/src/api/user.js index cc79a94..1995ec6 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -12,7 +12,7 @@ export function getInfo(token) { return request({ url: '/admin/system/index/info', method: 'get', - params: {token} + params: { token } }) } diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue new file mode 100644 index 0000000..98240ae --- /dev/null +++ b/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ + diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue index da39034..61d677b 100644 --- a/src/layout/components/Sidebar/index.vue +++ b/src/layout/components/Sidebar/index.vue @@ -3,16 +3,16 @@ - + @@ -31,7 +31,8 @@ export default { 'sidebar' ]), routes() { - return this.$router.options.routes + // return this.$router.options.routes + return this.$router.options.routes.concat(global.antRouter) }, activeMenu() { const route = this.$route diff --git a/src/main.js b/src/main.js index 01cba2f..5aad0cc 100644 --- a/src/main.js +++ b/src/main.js @@ -1,19 +1,20 @@ import Vue from 'vue' import 'normalize.css/normalize.css' // A modern alternative to CSS resets - import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import locale from 'element-ui/lib/locale/lang/en' // lang i18n - import '@/styles/index.scss' // global css - import App from './App' import store from './store' import router from './router' import '@/icons' // icon import '@/permission' // permission control +// 新增 +import hasBtnPermission from '@/utils/btn-permission' + +Vue.prototype.$hasBP = hasBtnPermission /** * If you don't want to use mock-server @@ -29,9 +30,9 @@ if (process.env.NODE_ENV === 'production') { } // set ElementUI lang to EN -Vue.use(ElementUI, { locale }) +// Vue.use(ElementUI, { locale }) // 如果想要中文版 element-ui,按如下方式声明 -// Vue.use(ElementUI) +Vue.use(ElementUI) Vue.config.productionTip = false diff --git a/src/permission.js b/src/permission.js index fa1ea19..bc6f49a 100644 --- a/src/permission.js +++ b/src/permission.js @@ -1,25 +1,23 @@ import router from './router' import store from './store' +import { getToken } from '@/utils/auth' import { Message } from 'element-ui' -import NProgress from 'nprogress' // progress bar -import 'nprogress/nprogress.css' // progress bar style -import { getToken } from '@/utils/auth' // get token from cookie -import getPageTitle from '@/utils/get-page-title' +import NProgress from 'nprogress' // 水平进度条提示: 在跳转路由时使用 +import 'nprogress/nprogress.css' // 水平进度条样式 +import getPageTitle from '@/utils/get-page-title' // 获取应用头部标题的函数 +import Layout from '@/layout' +import ParentView from '@/components/ParentView' + +const _import = require('./router/_import_' + process.env.NODE_ENV) // 获取组件的方法 NProgress.configure({ showSpinner: false }) // NProgress Configuration - const whiteList = ['/login'] // no redirect whitelist - router.beforeEach(async(to, from, next) => { - // start progress bar NProgress.start() - // set page title document.title = getPageTitle(to.meta.title) - // determine whether the user has logged in const hasToken = getToken() - if (hasToken) { if (to.path === '/login') { // if is logged in, redirect to the home page @@ -32,11 +30,25 @@ router.beforeEach(async(to, from, next) => { } else { try { // get user info - await store.dispatch('user/getInfo') - - next() + await store.dispatch('user/getInfo')// 请求获取用户信息 + if (store.getters.menus.length < 1) { + global.antRouter = [] + next() + } + const menus = filterAsyncRouter(store.getters.menus)// 1.过滤路由 + console.log(menus) + router.addRoutes(menus) // 2.动态添加路由 + const lastRou = [{ path: '*', redirect: '/404', hidden: true }] + router.addRoutes(lastRou) + global.antRouter = menus // 3.将路由数据传递给全局变量,做侧边栏菜单渲染工作 + next({ + ...to, + replace: true + }) + // next() } catch (error) { // remove token and go to login page to re-login + console.log(error) await store.dispatch('user/resetToken') Message.error(error || 'Has Error') next(`/login?redirect=${to.path}`) @@ -44,9 +56,7 @@ router.beforeEach(async(to, from, next) => { } } } - } else { - /* has no token*/ - + } else { /* has no token*/ if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() @@ -58,7 +68,32 @@ router.beforeEach(async(to, from, next) => { } }) -router.afterEach(() => { - // finish progress bar +router.afterEach(() => { // finish progress bar NProgress.done() -}) +}) // // 遍历后台传来的路由字符串,转换为组件对象 +function filterAsyncRouter(asyncRouterMap) { + const accessedRouters = asyncRouterMap.filter(route => { + if (route.component) { + if (route.component === 'Layout') { + route.component = Layout + } else if (route.component === 'ParentView') { + route.component = ParentView + } else { + try { + route.component = _import(route.component)// 导入组件 + } catch (error) { + debugger + console.log(error) + route.component = _import('dashboard/index')// 导入组件 + } + } + } + if (route.children && route.children.length > 0) { + route.children = filterAsyncRouter(route.children) + } else { + delete route.children + } + return true + }) + return accessedRouters +} diff --git a/src/router/_import_development.js b/src/router/_import_development.js new file mode 100644 index 0000000..42de012 --- /dev/null +++ b/src/router/_import_development.js @@ -0,0 +1,2 @@ +// 开发环境导入组件 +module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+ diff --git a/src/router/_import_production.js b/src/router/_import_production.js new file mode 100644 index 0000000..796b0da --- /dev/null +++ b/src/router/_import_production.js @@ -0,0 +1,2 @@ +// 生产环境导入组件 +module.exports = file => () => import('@/views/' + file + '.vue') diff --git a/src/router/index.js b/src/router/index.js index 1ea6c14..3eb4a02 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -35,13 +35,6 @@ export const constantRoutes = [ component: () => import('@/views/login/index'), hidden: true }, - - { - path: '/404', - component: () => import('@/views/404'), - hidden: true - }, - { path: '/', component: Layout, @@ -52,152 +45,7 @@ export const constantRoutes = [ component: () => import('@/views/dashboard/index'), meta: { title: 'Dashboard', icon: 'dashboard' } }] - }, - { - path: '/system', - component: Layout, - meta: { - title: '系统管理', - icon: 'el-icon-s-tools' - }, - alwaysShow: true, - children: [ - { - name: 'sysUser', - path: 'sysUser', - component: () => import('@/views/system/sysUser/list'), - meta: { - title: '用户管理', - icon: 'el-icon-s-custom' - } - }, - { - path: 'sysRole', - component: () => import('@/views/system/sysRole/list'), - meta: { - title: '角色管理', - icon: 'el-icon-s-help' - } - }, - { - name: 'sysMenu', - path: 'sysMenu', - component: () => import('@/views/system/sysMenu/list'), - meta: { - title: '菜单管理', - icon: 'el-icon-s-unfold' - } - } - ] - }, - - { - path: '/example', - component: Layout, - redirect: '/example/table', - name: 'Example', - meta: { title: 'Example', icon: 'el-icon-s-help' }, - children: [ - { - path: 'table', - name: 'Table', - component: () => import('@/views/table/index'), - meta: { title: 'Table', icon: 'table' } - }, - { - path: 'tree', - name: 'Tree', - component: () => import('@/views/tree/index'), - meta: { title: 'Tree', icon: 'tree' } - } - ] - }, - - { - path: '/form', - component: Layout, - children: [ - { - path: 'index', - name: 'Form', - component: () => import('@/views/form/index'), - meta: { title: 'Form', icon: 'form' } - } - ] - }, - - { - path: '/nested', - component: Layout, - redirect: '/nested/menu1', - name: 'Nested', - meta: { - title: 'Nested', - icon: 'nested' - }, - children: [ - { - path: 'menu1', - component: () => import('@/views/nested/menu1/index'), // Parent router-view - name: 'Menu1', - meta: { title: 'Menu1' }, - children: [ - { - path: 'menu1-1', - component: () => import('@/views/nested/menu1/menu1-1'), - name: 'Menu1-1', - meta: { title: 'Menu1-1' } - }, - { - path: 'menu1-2', - component: () => import('@/views/nested/menu1/menu1-2'), - name: 'Menu1-2', - meta: { title: 'Menu1-2' }, - children: [ - { - path: 'menu1-2-1', - component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), - name: 'Menu1-2-1', - meta: { title: 'Menu1-2-1' } - }, - { - path: 'menu1-2-2', - component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), - name: 'Menu1-2-2', - meta: { title: 'Menu1-2-2' } - } - ] - }, - { - path: 'menu1-3', - component: () => import('@/views/nested/menu1/menu1-3'), - name: 'Menu1-3', - meta: { title: 'Menu1-3' } - } - ] - }, - { - path: 'menu2', - component: () => import('@/views/nested/menu2/index'), - name: 'Menu2', - meta: { title: 'menu2' } - } - ] - }, - - { - path: 'external-link', - component: Layout, - children: [ - { - path: 'https://panjiachen.github.io/vue-element-admin-site/#/', - meta: { title: 'External Link', icon: 'link' } - } - ] - }, - - // 404 page must be placed at the end !!! - { path: '*', redirect: '/404', hidden: true } + } ] const createRouter = () => new Router({ diff --git a/src/store/getters.js b/src/store/getters.js index 5ab7b4c..1b69f16 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -3,6 +3,9 @@ const getters = { device: state => state.app.device, token: state => state.user.token, avatar: state => state.user.avatar, - name: state => state.user.name + name: state => state.user.name, + // 新增 + buttons: state => state.user.buttons, + menus: state => state.user.menus } export default getters diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 2f6423f..35737aa 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -1,12 +1,15 @@ -import { login, logout, getInfo } from '@/api/user' -import { getToken, setToken, removeToken } from '@/utils/auth' +import { getInfo, login, logout } from '@/api/user' +import { getToken, removeToken, setToken } from '@/utils/auth' import { resetRouter } from '@/router' const getDefaultState = () => { return { token: getToken(), name: '', - avatar: '' + avatar: '', + + buttons: [], // 新增 + menus: '' // 新增 } } @@ -24,6 +27,14 @@ const mutations = { }, SET_AVATAR: (state, avatar) => { state.avatar = avatar + }, + // 新增 + SET_BUTTONS: (state, buttons) => { + state.buttons = buttons + }, + // 新增 + SET_MENUS: (state, menus) => { + state.menus = menus } } @@ -46,7 +57,7 @@ const actions = { // get user info getInfo({ commit, state }) { return new Promise((resolve, reject) => { - getInfo(state.token).then(response => { + getInfo().then(response => { const { data } = response if (!data) { @@ -57,6 +68,9 @@ const actions = { commit('SET_NAME', name) commit('SET_AVATAR', avatar) + + commit('SET_BUTTONS', data.buttons) + commit('SET_MENUS', data.routers) resolve(data) }).catch(error => { reject(error) diff --git a/src/utils/btn-permission.js b/src/utils/btn-permission.js new file mode 100644 index 0000000..a23e573 --- /dev/null +++ b/src/utils/btn-permission.js @@ -0,0 +1,12 @@ +import store from '@/store' + +/** + * 判断当前用户是否有此按钮权限 + * 按钮权限字符串 permission + */ +export default function hasBtnPermission(permission) { + // 得到当前用户的所有按钮权限 + const myBtns = store.getters.buttons + // 如果指定的功能权限在myBtns中, 返回true ==> 这个按钮就会显示, 否则隐藏 + return myBtns.indexOf(permission) !== -1 +} diff --git a/src/utils/request.js b/src/utils/request.js index 0976d23..8a5d384 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -19,7 +19,7 @@ service.interceptors.request.use( // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation - config.headers['X-Token'] = getToken() + config.headers['token'] = getToken() } return config }, diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 1db2464..72b01dc 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -1,6 +1,13 @@ diff --git a/src/views/system/sysRole/assignAuth.vue b/src/views/system/sysRole/assignAuth.vue new file mode 100644 index 0000000..b1b7074 --- /dev/null +++ b/src/views/system/sysRole/assignAuth.vue @@ -0,0 +1,94 @@ + + diff --git a/src/views/system/sysRole/list.vue b/src/views/system/sysRole/list.vue index fb841de..43db12a 100644 --- a/src/views/system/sysRole/list.vue +++ b/src/views/system/sysRole/list.vue @@ -1,6 +1,5 @@ -