Files
fe.ems.vue3/src/router/index.ts
T
2024-01-18 11:20:40 +08:00

204 lines
5.4 KiB
TypeScript

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;