增加动态路由;修改路由权限控制逻辑;

This commit is contained in:
huzhushan 2021-07-26 16:48:43 +08:00
parent 5a315f6fe6
commit 0d36b5c7e5
9 changed files with 146 additions and 95 deletions

View File

@ -27,7 +27,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-21 12:44:46 * @LastEditTime: 2021-07-26 13:06:50
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -40,16 +40,18 @@ export default [
method: 'post', method: 'post',
timeout: 1000, timeout: 1000,
statusCode: 200, statusCode: 200,
response: ({body}) => { response: ({ body }) => {
// 响应内容 // 响应内容
return +body.password === 123456 ? { return +body.password === 123456
? {
code: 200, code: 200,
message: '登录成功', message: '登录成功',
data: { data: {
token: '@word(50, 100)', // @word()是mockjs的语法 token: '@word(50, 100)', // @word()是mockjs的语法
refresh_token: '@word(50, 100)', // refresh_token是用来重新生成token的 refresh_token: '@word(50, 100)', // refresh_token是用来重新生成token的
},
} }
} : { : {
code: 400, code: 400,
message: '密码错误请输入123456', message: '密码错误请输入123456',
} }

View File

@ -24,7 +24,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-21 12:44:55 * @LastEditTime: 2021-07-26 16:43:22
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -36,36 +36,70 @@ export default [
url: '/api/menus', url: '/api/menus',
method: 'get', method: 'get',
timeout: 100, timeout: 100,
response: { response: ({ query }) => {
// 响应内容
const childs = [
{
name: 'testList',
title: '列表',
},
{
name: 'testAdd',
title: '添加',
},
{
name: 'testEdit',
title: '编辑',
},
{
name: 'testAuth',
title: '权限测试',
},
{
name: 'test-cache',
title: '该页面可缓存',
},
{
name: 'test-no-cache',
title: '该页面不可缓存',
},
{
name: 'nest',
title: '二级菜单',
children: [
{
name: 'nestPage1',
title: 'page1',
},
{
name: 'nestPage2',
title: 'page2',
},
],
},
{
name: 'test-error-log',
title: '测试错误日志',
},
]
if (query.role === 'admin')
childs.push({
name: 'testNoAuth',
title: '权限页面',
})
return {
code: 200, code: 200,
message: '获取菜单成功', message: '获取菜单成功',
data: [ data: [
{ {
url: '/test', name: 'test',
title: '测试页面', title: '测试页面',
icon: 'el-icon-location', children: childs,
children: [
{
url: '/test',
title: '列表',
},
{
url: '/test/auth',
title: '权限页面',
},
{
url: '/test/nest',
title: '二级菜单',
children: [
{
url: '/test/nest',
title: '子菜单',
},
],
},
],
}, },
], ],
}
}, },
}, },
] ]

View File

@ -3,7 +3,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-21 09:36:57 * @LastEditTime: 2021-07-26 13:37:30
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -12,9 +12,10 @@
import request from '@/utils/request' import request from '@/utils/request'
// 获取菜单 // 获取菜单
export const GetMenus = () => { export const GetMenus = params => {
return request({ return request({
url: '/api/menus', url: '/api/menus',
method: 'get', method: 'get',
params,
}) })
} }

View File

@ -27,7 +27,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-07-23 11:07:24 * @LastEditTime: 2021-07-26 16:02:28
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -75,10 +75,6 @@ export default defineComponent({
setup() { setup() {
const route = useRoute() const route = useRoute()
const store = useStore() const store = useStore()
store.dispatch(
'menu/generateMenus',
store.state.account.userinfo && store.state.account.userinfo.role
)
return { return {
menus: computed(() => store.state.menu.menus), menus: computed(() => store.state.menu.menus),

View File

@ -26,7 +26,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-05-06 09:21:41 * @LastEditTime: 2021-07-26 16:32:34
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -46,7 +46,7 @@ const getPageTitle = title => {
} }
// 白名单里面是路由对象的name // 白名单里面是路由对象的name
const WhiteList = ['login', 'forbidden', 'server-error', 'not-found', 'lock'] const WhiteList = ['login', 'lock']
// vue-router4的路由守卫不再是通过next放行而是通过return返回true或false或者一个路由地址 // vue-router4的路由守卫不再是通过next放行而是通过return返回true或false或者一个路由地址
router.beforeEach(async to => { router.beforeEach(async to => {
@ -74,6 +74,15 @@ router.beforeEach(async to => {
return false return false
} }
} }
// 获取动态菜单(如果你的项目有动态菜单,在此处获取动态菜单)
if (store.state.menu.menus.length <= 0) {
try {
await store.dispatch('menu/generateMenus', userinfo)
return to.fullPath // 添加动态路由后,必须加这一句触发重定向
} catch (err) {
return false
}
}
// 判断是否处于锁屏状态 // 判断是否处于锁屏状态
if (to.name !== 'lock') { if (to.name !== 'lock') {
@ -88,14 +97,5 @@ router.beforeEach(async to => {
} }
} }
} }
// 如果没有权限跳转到403页面
if (
!!to.meta &&
!!to.meta.roles &&
!to.meta.roles.includes(userinfo.role)
) {
return { path: '/403', replace: true }
}
} }
}) })

View File

@ -18,7 +18,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-23 15:26:46 * @LastEditTime: 2021-07-26 16:16:36
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -34,8 +34,11 @@ import lock from './modules/lock'
import home from './modules/home' import home from './modules/home'
import test from './modules/test' import test from './modules/test'
// 左侧菜单 /* 菜单栏的路由 */
export const allMenus = [...home, ...test] // 固定菜单
export const fixedRoutes = [...home]
// 动态菜单
export const asyncRoutes = [...test]
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(), history: createWebHashHistory(),
@ -46,9 +49,9 @@ const router = createRouter({
}, },
...redirect, // 统一的重定向配置 ...redirect, // 统一的重定向配置
...login, ...login,
...allMenus,
...error,
...lock, ...lock,
...fixedRoutes,
...error,
], ],
scrollBehavior(to, from, savedPosition) { scrollBehavior(to, from, savedPosition) {
if (savedPosition) { if (savedPosition) {

View File

@ -3,7 +3,7 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-21 09:34:35 * @LastEditTime: 2021-07-26 14:37:08
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -19,7 +19,7 @@ export default [
component: Layout, component: Layout,
name: 'Dashboard', name: 'Dashboard',
meta: { meta: {
title: 'Dashboard', title: '工作台',
}, },
icon: 'home', icon: 'home',
children: [ children: [

View File

@ -3,7 +3,7 @@
* @version: * @version:
* @Date: 2021-04-21 09:18:32 * @Date: 2021-04-21 09:18:32
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-29 11:20:14 * @LastEditTime: 2021-07-26 16:30:58
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
@ -31,7 +31,6 @@ export default [
title: '测试页面', title: '测试页面',
}, },
icon: 'el-icon-location', icon: 'el-icon-location',
roles: ['admin', 'visitor'],
children: [ children: [
{ {
path: '', path: '',
@ -39,7 +38,6 @@ export default [
component: List, component: List,
meta: { meta: {
title: '列表', title: '列表',
roles: ['admin', 'visitor'],
}, },
}, },
{ {
@ -48,7 +46,6 @@ export default [
component: Add, component: Add,
meta: { meta: {
title: '添加', title: '添加',
roles: ['admin', 'visitor'],
}, },
hidden: true, // 不在菜单中显示 hidden: true, // 不在菜单中显示
}, },
@ -58,7 +55,6 @@ export default [
component: Edit, component: Edit,
meta: { meta: {
title: '编辑', title: '编辑',
roles: ['admin', 'visitor'],
}, },
hidden: true, // 不在菜单中显示 hidden: true, // 不在菜单中显示
}, },
@ -68,7 +64,6 @@ export default [
component: Auth, component: Auth,
meta: { meta: {
title: '权限测试', title: '权限测试',
roles: ['admin', 'visitor'],
}, },
}, },
{ {
@ -77,7 +72,6 @@ export default [
component: NoAuth, component: NoAuth,
meta: { meta: {
title: '权限页面', title: '权限页面',
roles: ['admin'],
}, },
hidden: true, hidden: true,
}, },
@ -87,7 +81,6 @@ export default [
component: Iscache, component: Iscache,
meta: { meta: {
title: '该页面可缓存', title: '该页面可缓存',
roles: ['admin', 'visitor'],
}, },
}, },
{ {
@ -96,7 +89,6 @@ export default [
component: Nocache, component: Nocache,
meta: { meta: {
title: '该页面不缓存', title: '该页面不缓存',
roles: ['admin', 'visitor'],
noCache: true, // 不缓存页面 noCache: true, // 不缓存页面
}, },
}, },
@ -107,7 +99,6 @@ export default [
redirect: '/test/nest/page1', redirect: '/test/nest/page1',
meta: { meta: {
title: '二级菜单', title: '二级菜单',
roles: ['admin', 'visitor'],
}, },
children: [ children: [
{ {
@ -116,7 +107,6 @@ export default [
component: NestPage1, component: NestPage1,
meta: { meta: {
title: 'page1', title: 'page1',
roles: ['admin', 'visitor'],
}, },
}, },
{ {
@ -125,7 +115,6 @@ export default [
component: NestPage2, component: NestPage2,
meta: { meta: {
title: 'page2', title: 'page2',
roles: ['admin', 'visitor'],
}, },
}, },
], ],
@ -136,7 +125,6 @@ export default [
component: ErrorLog, component: ErrorLog,
meta: { meta: {
title: '测试错误日志', title: '测试错误日志',
roles: ['admin', 'visitor'],
}, },
}, },
], ],

View File

@ -3,21 +3,22 @@
* @version: * @version:
* @Date: 2021-04-20 11:06:21 * @Date: 2021-04-20 11:06:21
* @LastEditors: huzhushan@126.com * @LastEditors: huzhushan@126.com
* @LastEditTime: 2021-04-21 09:34:17 * @LastEditTime: 2021-07-26 16:11:08
* @Author: huzhushan@126.com * @Author: huzhushan@126.com
* @HomePage: https://huzhushan.gitee.io/vue3-element-admin * @HomePage: https://huzhushan.gitee.io/vue3-element-admin
* @Github: https://github.com/huzhushan/vue3-element-admin * @Github: https://github.com/huzhushan/vue3-element-admin
* @Donate: https://huzhushan.gitee.io/vue3-element-admin/donate/ * @Donate: https://huzhushan.gitee.io/vue3-element-admin/donate/
*/ */
import { allMenus } from '@/router' import { fixedRoutes, asyncRoutes } from '@/router'
// import { GetMenus } from '@/api/menu'; import { GetMenus } from '@/api/menu'
import router from '@/router'
const hasPermission = (role, route) => { // const hasPermission = (role, route) => {
if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) { // if (!!route.meta && !!route.meta.roles && !route.meta.roles.includes(role)) {
return false // return false
} // }
return true // return true
} // }
const generateUrl = (path, parentPath) => { const generateUrl = (path, parentPath) => {
return path.startsWith('/') return path.startsWith('/')
@ -27,11 +28,34 @@ const generateUrl = (path, parentPath) => {
: parentPath : parentPath
} }
const getFilterMenus = (arr, role, parentPath = '') => { const getFilterRoutes = (targetRoutes, ajaxRoutes) => {
const filterRoutes = []
ajaxRoutes.forEach(item => {
const target = targetRoutes.find(target => target.name === item.name)
if (target) {
const { children: targetChildren, ...rest } = target
const route = {
...rest,
}
if (item.children) {
route.children = getFilterRoutes(targetChildren, item.children)
}
filterRoutes.push(route)
}
})
return filterRoutes
}
const getFilterMenus = (arr, parentPath = '') => {
const menus = [] const menus = []
arr.forEach(item => { arr.forEach(item => {
if (hasPermission(role, item) && !item.hidden) { if (!item.hidden) {
const menu = { const menu = {
url: generateUrl(item.path, parentPath), url: generateUrl(item.path, parentPath),
title: item.meta.title, title: item.meta.title,
@ -41,7 +65,7 @@ const getFilterMenus = (arr, role, parentPath = '') => {
if (item.children.filter(child => !child.hidden).length <= 1) { if (item.children.filter(child => !child.hidden).length <= 1) {
menu.url = generateUrl(item.children[0].path, menu.url) menu.url = generateUrl(item.children[0].path, menu.url)
} else { } else {
menu.children = getFilterMenus(item.children, role, menu.url) menu.children = getFilterMenus(item.children, menu.url)
} }
} }
menus.push(menu) menus.push(menu)
@ -62,16 +86,19 @@ export default {
}, },
}, },
actions: { actions: {
async generateMenus({ commit }, role) { async generateMenus({ commit }, userinfo) {
// 方式一:根据角色生成菜单 // 从后台获取菜单
const menus = getFilterMenus(allMenus, role) const { code, data } = await GetMenus({ role: userinfo.role })
commit('SET_MENUS', menus)
// // 方式二:从后台获取菜单 if (+code === 200) {
// const { code, data } = await GetMenus(); // 过滤出需要添加的动态路由
// if (+code === 200) { const filterRoutes = getFilterRoutes(asyncRoutes, data)
// commit('SET_MENUS', data) filterRoutes.forEach(route => router.addRoute(route))
// }
// 生成菜单
const menus = getFilterMenus([...fixedRoutes, ...filterRoutes])
commit('SET_MENUS', menus)
}
}, },
}, },
} }