import router from '@/router'; import { RouteRecordRaw } from 'vue-router'; import { useUserStoreHook } from '@/store/modules/user'; import { usePermissionStoreHook } from '@/store/modules/permission'; import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; NProgress.configure({ showSpinner: false }); const permissionStore = usePermissionStoreHook(); // 白名单路由 const whiteList = ['/login', '/register']; //login // ✅ 新增:递归标准化路由路径,确保所有 path 以 '/' 开头 function normalizeRoutes(routes: any[]): any[] { return routes.map(route => { // 创建副本以避免直接修改原始数据(可选,视具体需求而定) const normalizedRoute = { ...route }; // 修正当前路由的 path if (normalizedRoute.path && !normalizedRoute.path.startsWith('/')) { normalizedRoute.path = `/${normalizedRoute.path}`; } // 递归修正子路由 if (normalizedRoute.children && normalizedRoute.children.length > 0) { normalizedRoute.children = normalizeRoutes(normalizedRoute.children); } return normalizedRoute; }); } // 查找第一个可用路由 function findFirstAvailableRoute(routes: any[]): string | undefined { for (const route of routes) { if (route.meta?.hidden) continue; if (route.children?.length > 0) { const child = route.children[0]; // 优先使用 opturl 或 path const targetPath = child.opturl || child.path; return targetPath?.startsWith('/') ? targetPath : `/${targetPath}`; } const targetPath = route.opturl || route.path; return targetPath; } return '/404'; } router.beforeEach(async (to, from, next) => { NProgress.start(); const userStore = useUserStoreHook(); if (userStore.Token) { // 登录成功,跳转到首页 if (to.path === '/login') { //login next({ path: '/' }); NProgress.done(); return; } else { const hasGetUserInfo = userStore.roles.length > 0; if (hasGetUserInfo) { // 已获取用户信息,检查路由匹配 if (to.matched.length === 0) { // 路由未匹配,可能是访问根路径 if (to.path === '/') { const firstRoute = findFirstAvailableRoute(permissionStore.routes); if (firstRoute) { next(firstRoute); NProgress.done(); return; } } from.name ? next({ name: from.name as any }) : next('/401'); } else { next(); } } else { try { const { roles } = await userStore.getInfo(); let accessRoutes: RouteRecordRaw[] = await permissionStore.generateRoutes(roles); // ✅ 关键修复:在添加路由前,标准化所有路径 accessRoutes = normalizeRoutes(accessRoutes); accessRoutes.forEach((route: any) => { router.addRoute(route); }); // 关键:如果是根路径,加载完路由后跳转到第一个可用路由 if (to.path === '/') { const firstRoute = findFirstAvailableRoute(accessRoutes); if (firstRoute) { next(firstRoute); NProgress.done(); return; } } next({ ...to, replace: true }); } catch (error) { console.log(error); await userStore.resetToken(); next(`/login`); NProgress.done(); } } } } else { // 未登录可以访问白名单页面 if (whiteList.indexOf(to.path) !== -1) { next(); } else { next(`/login`); NProgress.done(); } } }); router.afterEach(() => { NProgress.done(); });