49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
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()
|
|
|
|
// 首次导航时验证 token 有效性(检查持久化的 token 是否过期)
|
|
await accountStore.initAuth()
|
|
|
|
// 已登录用户访问公开路由(如登录页),直接跳转首页
|
|
if (accountStore.isLoggedIn() && isPublicPath(to.path)) {
|
|
return '/'
|
|
}
|
|
|
|
// 未登录用户访问非公开路由,跳转登录页
|
|
if (!accountStore.isLoggedIn() && !isPublicPath(to.path)) {
|
|
// 将原本要访问的路径作为 redirect 参数传递,登录后可跳回
|
|
return { path: '/auth/login', query: { redirect: to.fullPath } }
|
|
}
|
|
|
|
return true
|
|
})
|
|
}
|
|
|
|
// 路由守卫
|
|
function createRouterGuard(router: Router) {
|
|
setupCommonGuard(router)
|
|
}
|
|
|
|
export { createRouterGuard }
|