Files
sunProduct/src/permission.ts
2026-04-20 16:38:04 +08:00

134 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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));
};
router.beforeEach(async (to, from) => {
NProgress.start();
// ==============================================
// 🚥 调试日志:每次跳转都打印(方便看你跳去了哪)
// ==============================================
console.log('==========================================================');
console.log('🔀 路由跳转:', from.path, ' → ', to.path);
console.log('🔐 是否有Token:', !!getToken());
console.log('🚦 动态路由是否已加载:', isDynamicRoutesAdded);
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') {
console.log('✅ 已登录,访问登录页,直接跳首页');
NProgress.done();
return '/';
}
// 白名单页面直接放行
if (isWhiteList(to.path)) {
console.log('✅ 白名单页面,直接放行');
return;
}
// ==============================================
// ✅ 【关键】只在【没有角色 + 没有加载过路由】时执行一次
// ==============================================
console.log('👤 当前用户角色:', userStore.roles);
console.log('🧪 判断条件:roles.length === 0 && !isDynamicRoutesAdded');
console.log('🧪 结果:', userStore.roles.length === 0 && !isDynamicRoutesAdded);
if (userStore.roles.length === 0 && !isDynamicRoutesAdded) {
console.log('==========================================================');
console.log('🚀 【首次初始化】获取用户信息 + 生成动态路由(只执行一次)');
console.log('==========================================================');
isRelogin.show = true;
// 获取用户信息
const [err, res] = await tos(userStore.getInfo());
if (err) {
console.error('❌ 获取用户信息失败:', err);
await userStore.logout();
ElMessage.error(err);
isDynamicRoutesAdded = false;
return '/';
}
console.log('✅ 用户信息获取成功:', res);
isRelogin.show = false;
// 生成动态路由
const accessRoutes = await permissionStore.generateRoutes();
console.log('✅ 动态路由生成成功,数量:', accessRoutes.length);
// 添加路由(避免重复添加)
accessRoutes.forEach((route) => {
if (!isHttp(route.path) && !router.hasRoute(route.name)) {
router.addRoute(route);
}
});
// ✅ 标记:路由已添加
isDynamicRoutesAdded = true;
console.log('✅ 动态路由添加完成,标记 isDynamicRoutesAdded = true');
// 管理员登录强制跳转
if (res.user.userId === 1 && from.path === '/login') {
console.log('👑 管理员登录,跳转到社区列表');
return { path: '/community/communitylist', replace: true };
} else {
// 重新进入当前路由(让新添加的路由生效)
console.log('🔄 重新跳转目标页面:', to.path);
return { ...to, replace: true };
}
}
// ==============================================
// ✅ 已经初始化完成 → 直接放行!
// ==============================================
console.log('✅ 已完成初始化,直接放行');
return;
} else {
// 未登录
isDynamicRoutesAdded = false;
console.log('🔒 未登录,跳转到登录页');
if (isWhiteList(to.path)) {
return;
} else {
NProgress.done();
return `/login?redirect=${to.fullPath}`;
}
}
});
router.afterEach(() => {
NProgress.done();
console.log('✅ 跳转完成\n\n');
});