import { createRouter, createWebHistory, createWebHashHistory, RouteRecordRaw, } from 'vue-router'; import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; import BasicLayout from '../layouts/BasicLayout.vue'; import BlankLayout from '../layouts/BlankLayout.vue'; import { getToken } from '@/plugins/auth-token'; import { validHttp } from '@/utils/regular-utils'; import useUserStore from '@/store/modules/user'; import useAppStore from '@/store/modules/app'; import useRouterStore from '@/store/modules/router'; // NProgress Configuration NProgress.configure({ showSpinner: false }); // import { MetaRecord, MenuDataItem } from 'antdv-pro-layout'; // mate数据类型 MetaRecord // 根据/路径构建菜单列表,列表项类型 MenuDataItem // https://github.com/vueComponent/pro-components/blob/a19279f3a28190bf11e8c36f316c92dbd3387a6d/packages/pro-layout/src/typings.ts#L16 // 菜单图标来源 https://ant.design/components/icon 自定义iconfont /**公共路由 */ const constantRoutes: RouteRecordRaw[] = [ { path: '/', name: 'Root', component: BasicLayout, redirect: '/index', children: [ { path: '/index', name: 'Index', meta: { title: 'router.index', icon: 'icon-pcduan' }, component: () => import('@/views/index.vue'), }, { path: '/account', name: 'Account', meta: { title: 'router.account.index', hideInMenu: true, }, component: BlankLayout, redirect: '/account/settings', children: [ { path: 'profile', name: 'Profile', meta: { title: 'router.account.profile', cache: true }, component: () => import('@/views/account/profile.vue'), }, { path: 'settings', name: 'Settings', meta: { title: 'router.account.settings', cache: true }, component: () => import('@/views/account/settings.vue'), }, ], }, ], }, { path: '/login', name: 'Login', meta: { title: 'router.login' }, component: () => import('@/views/login.vue'), }, { path: '/register', name: 'Register', meta: { title: 'router.register' }, component: () => import('@/views/register.vue'), }, { path: '/403', name: 'NotPermission', meta: { title: 'router.page403' }, component: () => import('@/views/error/403.vue'), }, { path: '/help', name: 'HelpDoc', meta: { title: 'router.helpDoc' }, component: () => import('@/views/tool/help/index.vue'), }, { path: '/redirect', name: 'Redirect', component: BasicLayout, children: [ { path: '/redirect/:path(.*)', component: () => import('@/views/redirect/index.vue'), }, ], }, { path: '/:pathMatch(.*)*', meta: { title: 'router.page404' }, component: () => import('@/views/error/404.vue'), }, ]; // 根据.env配置获取是否带井号和基础路径 const hasHash = import.meta.env.VITE_HISTORY_HASH; const bashUrl = import.meta.env.VITE_HISTORY_BASE_URL; /**全局路由 */ const router = createRouter({ history: hasHash === 'true' ? createWebHashHistory(bashUrl) : createWebHistory(bashUrl), routes: constantRoutes, scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition; } else { return { top: 0 }; } }, }); /**全局路由-后置守卫 */ router.afterEach((to, from, failure) => { NProgress.done(); const title = to.meta?.title // 设置标题 if (!failure && title) { useAppStore().setTitle(to.meta.title); } }); /**无Token可访问页面地址白名单 */ const WHITE_LIST: string[] = ['/login', '/auth-redirect', '/help', '/register']; /**全局路由-前置守卫 */ router.beforeEach((to, from, next) => { NProgress.start(); const token = getToken(); // 获取系统配置信息 const appStore =useAppStore() if (!appStore.loginBackground) { appStore.fnSysConf(); } // 没有token if (!token) { if (WHITE_LIST.includes(to.path)) { // 在免登录白名单,直接进入 next(); } else { // 否则全部重定向到登录页 next(`/login?redirect=${to.fullPath}`); } } // 有Token if (token) { // 防止重复访问登录页面 if (to.path === '/login') { next({ name: 'Index' }); } else { // 判断当前用户是否有角色信息 const user = useUserStore(); if (user.roles && user.roles.length === 0) { // 获取用户信息 user .fnGetInfo() .then(() => { return useRouterStore().generateRoutes(); }) .then(accessRoutes => { // 根据后台配置生成可访问的路由表 if (accessRoutes && accessRoutes.length !== 0) { for (const route of accessRoutes) { // 动态添加可访问路由表,http开头会异常 if (!validHttp(route.path)) { router.addRoute(route); } } } // 刷新替换原先路由,确保addRoutes已完成 next({ ...to, replace: true }); }) .catch(e => { console.error(`[${to.path}]: ${e.message}`); user.fnLogOut().finally(() => { next({ name: 'Login' }); }); }); } else { next(); } } } }); export default router;