import 'nprogress/nprogress.css'; // progress bar style import NProgress from 'nprogress'; // progress bar import { MessagePlugin } from 'tdesign-vue-next'; import type { RouteRecordRaw } from 'vue-router'; import router from '@/router'; import { getPermissionStore, useUserStore } from '@/store'; import { normalizePath } from '@/utils/route'; import { PAGE_NOT_FOUND_ROUTE } from '@/utils/route/constant'; NProgress.configure({ showSpinner: false }); /** 在每次导航前检查登录状态、初始化权限路由并维护进度条。 */ router.beforeEach(async (to, from, next) => { NProgress.start(); const permissionStore = getPermissionStore(); const { whiteListRouters } = permissionStore; const userStore = useUserStore(); if (userStore.token) { if (normalizePath(to.path) === '/login') { next(); return; } try { await userStore.getUserInfo(); const { asyncRoutes } = permissionStore; // 用户资料加载成功后,首次进入受保护页面时再构建动态菜单路由。 if (asyncRoutes && asyncRoutes.length === 0) { const routeList = await permissionStore.buildAsyncRoutes(); routeList.forEach((item: RouteRecordRaw) => { router.addRoute(item); }); // 路由刚添加时需要重新匹配当前 URL,避免首次导航落到 404。 if (to.name === PAGE_NOT_FOUND_ROUTE.name) { // 动态添加路由后,此处应当重定向到fullPath,否则会加载404页面内容 next({ path: to.fullPath, replace: true, query: to.query }); } else { // 直接基于 to 重新导航以加载动态路由; // 若用 from.query.redirect 手动拼接 path+query,当 redirect 带参(如 /dashboard/base?tab=1)时 // to.path !== redirect 恒成立,且显式 query 会覆盖 path 内嵌参数,导致参数丢失,故统一用 to。 next({ ...to, replace: true }); return; } } if (router.hasRoute(to.name!)) { next(); } else { next(`/`); } } catch (error) { MessagePlugin.error((error as Error).message); next({ path: '/login', query: { redirect: to.fullPath }, }); NProgress.done(); } } else { // 未登录用户仅可进入白名单;其他地址记录目标路径后转向登录页。 if (whiteListRouters.includes(normalizePath(to.path))) { next(); } else { next({ path: '/login', query: { redirect: to.fullPath }, }); } NProgress.done(); } }); /** 路由完成后收尾进度条;进入登录页时同步清理用户和动态路由状态。 */ router.afterEach((to) => { if (normalizePath(to.path) === '/login') { const userStore = useUserStore(); const permissionStore = getPermissionStore(); userStore.logout(); permissionStore.restoreRoutes(); } NProgress.done(); });