You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
5.4 KiB
188 lines
5.4 KiB
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
|
|
|