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']; // 查找第一个可用路由 function findFirstAvailableRoute(routes: RouteRecordRaw[]): 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') { next({ path: '/' }); NProgress.done(); } 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(); const accessRoutes: RouteRecordRaw[] = await permissionStore.generateRoutes(roles); 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?redirect=${to.path}`); NProgress.done(); } } } } else { // 未登录可以访问白名单页面 if (whiteList.indexOf(to.path) !== -1) { next(); } else { next(`/login?redirect=${to.path}`); NProgress.done(); } } }); router.afterEach(() => { NProgress.done(); });