116 lines
3.3 KiB
TypeScript
116 lines
3.3 KiB
TypeScript
import { to as tos } from 'await-to-js';
|
|
import router from './router';
|
|
import NProgress from 'nprogress';
|
|
import 'nprogress/nprogress.css';
|
|
import { getToken } from '@/utils/auth';
|
|
import { isHttp, isPathMatch } from '@/utils/validate';
|
|
import { isRelogin } from '@/utils/request';
|
|
import { useUserStore } from '@/store/modules/user';
|
|
import { useSettingsStore } from '@/store/modules/settings';
|
|
import { usePermissionStore } from '@/store/modules/permission';
|
|
import { ElMessage } from 'element-plus/es';
|
|
|
|
NProgress.configure({ showSpinner: false });
|
|
|
|
// 白名单:不需要登录就能访问的页面
|
|
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*'];
|
|
|
|
// 全局标记:动态路由是否已经添加过(只加载一次!)
|
|
let isDynamicRoutesAdded = false;
|
|
|
|
// 判断是否在白名单
|
|
const isWhiteList = (path: string) => {
|
|
return whiteList.some((pattern) => isPathMatch(pattern, path));
|
|
};
|
|
// ✅ 关键修改:记录当前已添加的动态路由名称列表
|
|
let currentDynamicRouteNames: string[] = [];
|
|
// ✅ 关键修改:清除所有已记录的动态路由
|
|
const removeDynamicRoutes = () => {
|
|
currentDynamicRouteNames.forEach((name) => {
|
|
if (name && router.hasRoute(name)) {
|
|
router.removeRoute(name);
|
|
}
|
|
});
|
|
// 清空记录数组
|
|
currentDynamicRouteNames = [];
|
|
};
|
|
router.beforeEach(async (to, from) => {
|
|
NProgress.start();
|
|
|
|
const hasToken = getToken();
|
|
const userStore = useUserStore();
|
|
const permissionStore = usePermissionStore();
|
|
|
|
if (hasToken) {
|
|
// 设置标题
|
|
to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
|
|
|
|
// 已登录 且 去登录页 → 跳首页
|
|
if (to.path === '/login') {
|
|
NProgress.done();
|
|
return '/';
|
|
}
|
|
|
|
// 白名单页面直接放行
|
|
if (isWhiteList(to.path)) {
|
|
return;
|
|
}
|
|
if (userStore.roles.length === 0) {
|
|
isRelogin.show = true;
|
|
removeDynamicRoutes();
|
|
|
|
// 获取用户信息
|
|
const [err, res] = await tos(userStore.getInfo());
|
|
if (err) {
|
|
await userStore.logout();
|
|
ElMessage.error(err);
|
|
isDynamicRoutesAdded = false;
|
|
return '/';
|
|
}
|
|
|
|
isRelogin.show = false;
|
|
permissionStore.resetRoutes();
|
|
// 生成动态路由
|
|
const accessRoutes = await permissionStore.generateRoutes();
|
|
// 添加路由(避免重复添加)
|
|
accessRoutes.forEach((route) => {
|
|
if (route.name && router.hasRoute(route.name)) {
|
|
router.removeRoute(route.name);
|
|
}
|
|
if (!isHttp(route.path) && !router.hasRoute(route.name)) {
|
|
router.addRoute(route);
|
|
// 记录顶层路由名称
|
|
if (route.name) {
|
|
currentDynamicRouteNames.push(route.name as string);
|
|
}
|
|
}
|
|
});
|
|
// ✅ 标记:路由已添加
|
|
isDynamicRoutesAdded = true;
|
|
|
|
// 管理员登录强制跳转
|
|
if (from.path === '/login') {
|
|
return { path: '/community/communitylist', replace: true };
|
|
} else {
|
|
// 重新进入当前路由(让新添加的路由生效)
|
|
return { ...to, replace: true };
|
|
}
|
|
}
|
|
return;
|
|
} else {
|
|
// 未登录
|
|
isDynamicRoutesAdded = false;
|
|
|
|
if (isWhiteList(to.path)) {
|
|
return;
|
|
} else {
|
|
NProgress.done();
|
|
return `/login`;
|
|
}
|
|
}
|
|
});
|
|
|
|
router.afterEach(() => {
|
|
NProgress.done();
|
|
});
|