import { createRouter, createWebHashHistory, RouteLocationRaw, RouteLocationNormalizedLoaded, } from 'vue-router' import NProgress from 'nprogress' import 'nprogress/nprogress.css' import { STATIC_ROUTES, NO_LOGIN_ROUTES, ROOT_ROUTER, ADMIN_ROUTE, findFirstValidRoute, } from './routers' import { language } from '@/lang' import useSystemStore from '@/stores/modules/system' import useUserStore from '@/stores/modules/user' import { setWindowTitle, getAppType, urlToRouteRaw } from '@/utils/common' const router = createRouter({ history: createWebHashHistory(import.meta.env.BASE_URL), routes: [ADMIN_ROUTE, ...STATIC_ROUTES], }) /** * 重写push方法 */ const originPush = router.push router.push = (to: RouteLocationRaw) => { const route: any = typeof to == 'string' ? urlToRouteRaw(to) : to if (route.path) { const paths = route.path.split('/').filter((item: string) => { return item }) route.path = ['admin'].indexOf(paths[0]) == -1 ? `/${getAppType()}${route.path}` : route.path } return originPush(route) } /** * 重写resolve方法 */ const originResolve = router.resolve router.resolve = ( to: RouteLocationRaw, currentLocation?: RouteLocationNormalizedLoaded ) => { const route: any = typeof to == 'string' ? urlToRouteRaw(to) : to if (route.path) { const paths = route.path.split('/').filter((item: string) => { return item }) route.path = ['admin'].indexOf(paths[0]) == -1 ? `/${getAppType()}${route.path}` : route.path } return originResolve(route, currentLocation) } // 全局前置守卫 router.beforeEach(async (to: any, from, next) => { NProgress.configure({ showSpinner: false }) NProgress.start() to.redirectedFrom && (to.query = to.redirectedFrom.query) const userStore = useUserStore() const systemStore = useSystemStore() let title: string = to.meta.title ?? '' // 设置网站标题 setWindowTitle(title) // 加载语言包 await language.loadLocaleMessages( to.meta.addon || '', to.meta.view || to.path, systemStore.lang ) const loginPath = '/admin/login' // 判断是否需登录 if (NO_LOGIN_ROUTES.includes(to.path)) { next() } else if (userStore.token) { // 如果已加载路由 if (userStore.routers.length) { console.log('路由守卫: 已加载路由数量=', userStore.routers.length, '目标路径=', to.path) if (to.path === loginPath) { console.log('路由守卫: 从登录页跳转到应用根路径') next(`/${getAppType()}`) } else if (to.path === `/${getAppType()}`) { // 如果访问的是应用根路径,重定向到第一个有效路由 const firstRoute = findFirstValidRoute(userStore.routers) console.log('路由守卫: 访问根路径,找到的第一个路由=', firstRoute) if (firstRoute) { console.log('路由守卫: 重定向到第一个路由', { name: firstRoute }) next({ name: firstRoute }) } else { console.log('路由守卫: 没有找到有效路由') next() } } else { console.log('路由守卫: 正常访问', to.path) next() } } else { console.log('路由守卫: 未加载路由,开始加载...') try { if (!systemStore.apps.length) { await systemStore.getInstallAddons() } await userStore.getAuthMenusFn() // 设置首页路由 let firstRoute: symbol | string | undefined = findFirstValidRoute( userStore.routers ) if (systemStore.apps[0]) { firstRoute = userStore.addonIndexRoute[systemStore.apps[0].key] } console.log('路由守卫: 首个路由=', firstRoute, '路由列表=', userStore.routers) // 如果没有找到有效路由,使用默认的登录页面或404页面 if (!firstRoute) { console.warn('未找到有效的菜单路由,请检查用户权限配置') // 清除token并重新登录 userStore.logout() return } ROOT_ROUTER.redirect = { name: firstRoute } router.addRoute(ROOT_ROUTER) // 设置应用首页路由 ADMIN_ROUTE.children[0].redirect = { name: firstRoute } router.addRoute(ADMIN_ROUTE) // 添加动态路由 userStore.routers.forEach((route) => { if (!route.children) { router.addRoute(ADMIN_ROUTE.name, route) return } // 动态添加可访问路由表 router.addRoute(ADMIN_ROUTE.name, route) }) console.log('路由守卫: 动态路由已添加,目标路径=', to.path) // 如果访问的是登录页或应用根路径,跳转到第一个有效路由 if (to.path === loginPath || to.path === `/${getAppType()}`) { console.log('路由守卫: 跳转到首个路由', { name: firstRoute }) next({ name: firstRoute }) } else { console.log('路由守卫: 继续访问目标页面', to.path) next(to) } } catch (err) { console.error('路由守卫: 加载路由失败', err) next({ path: loginPath, query: { redirect: to.fullPath } }) } } } else { if (to.path === loginPath) { next() } else { next({ path: loginPath, query: { redirect: to.fullPath } }) } } }) // 全局后置钩子 router.afterEach(() => { NProgress.done() }) export default router