Files
webgame-frontend/src/router/guard.ts
2026-06-22 11:19:11 +08:00

74 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Router } from 'vue-router'
import { useAccountStore } from '@/stores'
/** 无需登录即可访问的路由路径前缀 */
const PUBLIC_PATHS = ['/auth']
/**
* 判断目标路由是否为公开路由(无需登录)
* @param path - 目标路由路径
*/
function isPublicPath(path: string): boolean {
return PUBLIC_PATHS.some((prefix) => path.startsWith(prefix))
}
/**
* 通用路由守卫
* - 首次导航时验证 token 是否有效
* - 未登录用户访问非公开路由 → 跳转登录页
* - 已登录用户访问登录相关页面 → 跳转首页
*/
function setupCommonGuard(router: Router) {
router.beforeEach(async (to) => {
const accountStore = useAccountStore()
// 已登录用户访问公开路由(如登录页),直接跳转首页
if (!!accountStore.accessToken && isPublicPath(to.path)) {
return '/'
}
// 有 token 但未加载用户信息(页面刷新后 Pinia 只持久化了 token
if (accountStore.accessToken && !accountStore.accountInfo) {
try {
await accountStore.fetchUserInfo()
} catch {
// 获取失败token 过期等),由刷新拦截器处理,此处静默
}
}
// accessToken 检查
if (!accountStore.accessToken) {
// 明确声明忽略权限访问权限,则可以访问
if (to.meta.ignoreAccess) {
return true
}
// 未登录用户访问非公开路由,跳转登录页
if (!isPublicPath(to.path)) {
// 将原本要访问的路径作为 redirect 参数传递,登录后可跳回
return { path: '/auth/login', query: { redirect: to.fullPath }, replace: true }
}
// 没有访问权限,跳转登录页面
if (to.fullPath !== '/auth/login') {
return {
path: '/auth/login',
query: { redirect: to.fullPath },
// 携带当前跳转的页面,登录后重新跳转该页面
replace: true
}
}
return to
}
return true
})
}
// 路由守卫
function createRouterGuard(router: Router) {
setupCommonGuard(router)
}
export { createRouterGuard }