一 路由文件里定义两类路由
- 没有权限要求的路由页面 constantRoutes
//router/index.js
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
}
]
- 用于权限动态生成的路由页面 asyncRoutes
//router/index.js
/**
* constantRoutes
* 用于权限动态生成的页面都在这里定义
*/
export const asyncRoutes = [
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: {
title: 'Dashboard',
icon: 'dashboard',
affix: true,
noCache: true
}
}
]
},
{
path: '/chatbot', //法务咨询AI助手
component: Layout,
redirect: '/chatbot/index',
children: [
{
path: 'index',
name: 'ChatBot',
component: () => import('@/views/chatbot/index'),
meta: {
title: 'LegalChatbot'
}
}
]
},
{
path: '/translation', //法务文档翻译
component: Layout,
redirect: '/translation/index',
children: [
{
path: 'index',
name: 'Translation',
component: () => import('@/views/translation/index'),
meta: {
title: 'Translation'
}
}
]
},
{
path: '/interpretation', // 法务文档解读
component: Layout,
redirect: '/interpretation/index',
children: [
{
path: 'index',
name: 'Interpretation',
component: () => import('@/views/interpretation/index'),
meta: {
title: 'Interpretation'
}
}
]
},
{
path: '/document', //合同 AI
component: Layout,
redirect: '/document/index',
meta: {
title: 'ContractAI'
},
children: [
{
path: 'index',
name: 'ContractReview',
component: () => import('@/views/document/index'),
meta: {
title: 'ContractReview'
}
},
{
path: 'ai-analysis',
name: 'AiAnalysis',
component: () => import('@/views/document/ai-analysis'),
meta: {
title: 'AiAnalysis'
},
hidden: true
},
{
path: 'version-comparison',
name: 'VersionComparison',
component: () => import('@/views/document/version-comparison'),
meta: {
title: 'VersionComparison'
}
},
{
path: 'draft-contract',
name: 'DraftContract',
component: () => import('@/views/document/draft-contract'),
meta: {
title: 'DraftContract'
}
},
{
path: 'legal-letter',
name: 'LegalLetter',
component: () => import('@/views/document/legal-letter'),
meta: {
title: 'LegalLetter'
}
},
{
path: 'ai-analysis-onlyoffice',
name: 'AiAnalysisOnlyoffice',
component: () => import('@/views/document/ai-analysis-onlyoffice'),
meta: {
title: 'AiAnalysisOnlyoffice'
}
},
]
},
{
path: '/tradeCompliance',
component: Layout,
redirect: '/tradeCompliance/index',
children: [
{
path: 'index',
name: 'TradeCompliance',
component: () => import('@/views/tradeCompliance/index'),
meta: {
title: 'TradeCompliance'
}
}
]
},
{
path: '/esg',
component: Layout,
redirect: '/esg/index',
children: [
{
path: 'index',
name: 'ESG',
component: () => import('@/views/esg/index'),
meta: {
title: 'ESG AI'
}
}
]
},
{
path: '/dataSecurity',
component: Layout,
redirect: '/dataSecurity/index',
children: [
{
path: 'index',
name: 'DataSecurity',
component: () => import('@/views/dataSecurity/index'),
meta: {
title: 'DataSecurity'
}
}
]
},
{
path: '/litigation',
component: Layout,
redirect: '/litigation/doc-drafting',
name: 'LitigationAI',
meta: {
title: 'LitigationAI'
},
children: [
{
path: 'case-analysis',
name: 'CaseAnalysis',
component: () => import('@/views/litigation/case-analysis'),
meta: {
title: 'CaseAnalysis'
}
},
{
path: 'doc-drafting',
name: 'DocDrafting',
component: () => import('@/views/litigation/doc-drafting'),
meta: {
title: 'DocDrafting'
}
},
{
path: 'trial-report-summary',
name: 'TrialReportSummary',
component: () => import('@/views/litigation/trial-report-summary'),
meta: {
title: 'TrialReportSummary'
}
},
{
path: 'business-execution-strategy',
name: 'BusinessExecutionStrategy',
component: () =>
import('@/views/litigation/business-execution-strategy'),
meta: {
title: 'BusinessExecutionStrategy'
}
},
{
path: 'similar-litigation-prevention',
name: 'SimilarLitigationPrevention',
component: () =>
import('@/views/litigation/similar-litigation-prevention'),
meta: {
title: 'SimilarLitigationPrevention'
}
},
{
path: 'dispute-alternatives',
name: 'DisputeAlternatives',
component: () => import('@/views/litigation/dispute-alternatives'),
meta: {
title: 'DisputeAlternatives'
}
},
{
path: 'foreign-lawyer-expert-matching',
name: 'ForeignLawyerExpertMatching',
component: () =>
import('@/views/litigation/foreign-lawyer-expert-matching'),
meta: {
title: 'ForeignLawyerExpertMatching'
}
}
]
},
{
path: '/knowledge',
component: Layout,
redirect: '/knowledge/check-rules',
name: 'Knowledge',
meta: {
title: 'AIConfig'
},
children: [
{
path: 'check-rules',
name: 'CheckRules',
component: () => import('@/views/knowledge/check-rules'),
meta: {
title: 'ReviewRules'
}
},
{
path: 'professional-knowledge',
name: 'ProfessionalKnowledge',
component: () => import('@/views/knowledge/professional-knowledge'),
meta: {
title: 'Knowledge'
}
},
{
path: 'professional-knowledge2',
name: 'ProfessionalKnowledge2',
component: () => import('@/views/knowledge/professional-knowledge'),
meta: {
title: 'Knowledge2'
}
}
]
},
{
path: '/systemsetting',
component: Layout,
redirect: '/systemsetting/role-management',
name: 'SystemSetting',
meta: {
title: 'SystemSetting'
},
children: [
{
path: 'role-management',
name: 'RoleManagement',
component: () => import('@/views/systemsetting/role-management'),
meta: {
title: 'RoleManagement'
}
},
{
path: 'log-management',
name: 'LogManagement',
component: () => import('@/views/systemsetting/log-management'),
meta: {
title: 'LogManagement'
}
}
]
},
// 404 page must be placed at the end !!!
{
path: '*',
redirect: '/404',
hidden: true
}
]
二 在全局前置守卫通过接口user/getMenus
获取用户有权限的路由页面 userRouterList
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 searchParams = new URLSearchParams(window.location.href)
// const urlToken = searchParams.get('token')
// urlToken && setToken(urlToken)
// searchParams.delete('token')
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (hasGetUserInfo) {
next()
} else {
try {
// get user info
await store.dispatch('user/getInfo')
// 获取权限列表
store.dispatch('user/getMenus').then(roles => {
// 根据拿到的权限列表,获取动态路由
store.dispatch('permission/recursiveRouter', roles).then(res => {
// 解决下方第七步中的报错 需要在上方引入该方法 import { resetRouter } from '@/router'
resetRouter()
// 解决路由name重复警告,如果报Router undefined需要在上面引入import Router from 'vue-router'
router.matcher = new Router().matcher
// 添加路由
router.addRoutes(res)
})
})
next()
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${window.location.href}`)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
// await store.dispatch('user/loginByAdfs')
next(`/login?redirect=${window.location.href}`)
NProgress.done()
}
}
})
三 通过循环递归 asyncRoutes 和 userRouterList 出符合用户权限的路由表
const actions = {
/**
* 根据用户路由权限递归路由表
* @param commit
* @param userRouterList 用户路由权限表
* @returns {Promise}
*/
recursiveRouter ({ commit }, userRouterList) {
return new Promise(resolve => {
let accessedRoutes = recursiveAsyncRoutes(asyncRoutes, userRouterList)
commit('SET_ROUTES', accessedRoutes)
commit('SET_ROUTER_STATE', true)
resolve(accessedRoutes)
})
},
}
/**
* 通过循环递归出符合用户权限的路由表
* @param asyncRouterList
* @param userRouterList
* @returns {*[]}
*/
export function recursiveAsyncRoutes (asyncRouterList, userRouterList) {
let res = []
asyncRouterList.forEach(route => {
const tmp = { ...route }
if (tmp.path === '*' && !tmp.hasOwnProperty('children')) {
res.push(tmp)
} else {
userRouterList.forEach(uRoute => {
if (uRoute.menuType != 2) {
if (hasPath(tmp, uRoute)) {
if (tmp.children && uRoute.subMenus) {
tmp.children = recursiveAsyncRoutes(tmp.children, uRoute.subMenus)
}
res.push(tmp)
}
}
})
}
})
return res
}
四 通过router.addRoutes(res)
把符合用户权限的页面添加到路由中
五 把最终生成的路由页面(包括 constantRoutes 和第三部中循环遍历出来的符合用户权限的页面)数组保存在store中
const mutations = {
/**
* 设置路由表
* @param state 数据
* @param routes 路由
* @constructor
*/
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
六 通过store中的路由信息生成导航栏
<template>
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
v-if="isShow"
>
<sidebar-item
v-for="route in routes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</template>
<script>
export default {
computed: {
routes () {
return this.$store.state.permission.routes
}
}
}
</script>
参考文献
网友评论