119 lines
3.7 KiB
TypeScript
119 lines
3.7 KiB
TypeScript
import { createRouter, createWebHistory } from 'vue-router'
|
|
|
|
import { useAdminSessionStore } from '@/stores/adminSession'
|
|
import { useSessionStore } from '@/stores/session'
|
|
import { getAccessToken, getLoginPath } from '@/shared/utils/authStorage'
|
|
import { ADMIN_DASHBOARD_PATH, ADMIN_LOGIN_PATH } from '@/shared/utils/adminPath'
|
|
import { accountRoutes } from './accountRoutes'
|
|
import { adminRoutes } from './adminRoutes'
|
|
import { isMobileHost, isMobileDevice, getMobilePath, getPcPath } from './mobileHost'
|
|
import { mobileRoutes } from './mobileRoutes'
|
|
import { publicRoutes } from './publicRoutes'
|
|
import { sellerRoutes } from './sellerRoutes'
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes: [...adminRoutes, ...mobileRoutes, ...publicRoutes, ...accountRoutes, ...sellerRoutes],
|
|
scrollBehavior(to, from, savedPosition) {
|
|
// 浏览器前进/后退用历史滚动;移动端首页列表在内部容器滚动,不依赖 window
|
|
if (savedPosition) return savedPosition
|
|
// 同路径仅改 query(筛选/排序)时保持当前滚动,避免点筛选被弹回顶部
|
|
// from.matched 为空表示首次进入,仍滚到顶部
|
|
if (to.path === from.path && from.matched.length > 0) {
|
|
return false
|
|
}
|
|
return { left: 0, top: 0 }
|
|
},
|
|
})
|
|
|
|
router.beforeEach(async to => {
|
|
const isMobile = isMobileHost() || isMobileDevice()
|
|
|
|
if (isMobile) {
|
|
const targetPath = getMobilePath(to.path)
|
|
if (to.path !== targetPath) {
|
|
return { path: targetPath, query: to.query, hash: to.hash }
|
|
}
|
|
} else {
|
|
const targetPath = getPcPath(to.path)
|
|
if (to.path !== targetPath) {
|
|
return { path: targetPath, query: to.query, hash: to.hash }
|
|
}
|
|
}
|
|
|
|
if (to.meta.requiresAuth) {
|
|
const session = useSessionStore()
|
|
session.syncFromStorage()
|
|
const hasToken = !!session.token
|
|
if (!hasToken) {
|
|
const loginPath = getLoginPath('user', to.path)
|
|
return { path: loginPath, query: { redirect: to.fullPath } }
|
|
}
|
|
// 优化: 只有当用户信息未加载时才调用 loadMe
|
|
if (!session.phone) {
|
|
try {
|
|
await session.loadMe()
|
|
} catch {
|
|
const loginPath = getLoginPath('user', to.path)
|
|
return { path: loginPath, query: { redirect: to.fullPath } }
|
|
}
|
|
}
|
|
}
|
|
|
|
if (to.meta.requiresRealname) {
|
|
const session = useSessionStore()
|
|
session.syncFromStorage()
|
|
const loginPath = getLoginPath('user', to.path)
|
|
const realnamePath = to.path.startsWith('/m') ? '/m/realname' : '/realname'
|
|
|
|
// 优化: 只有当状态未知或未验证时才重新加载
|
|
if (session.realnameStatus !== 'verified') {
|
|
// 如果没有 phone 信息,说明用户数据未加载
|
|
if (!session.phone) {
|
|
try {
|
|
await session.loadMe()
|
|
} catch {
|
|
if (!getAccessToken('user')) {
|
|
return { path: loginPath, query: { redirect: to.fullPath } }
|
|
}
|
|
}
|
|
}
|
|
|
|
// 再次检查实名状态
|
|
if (session.realnameStatus !== 'verified') {
|
|
return { path: realnamePath, query: { redirect: to.fullPath } }
|
|
}
|
|
}
|
|
}
|
|
|
|
const adminSession = useAdminSessionStore()
|
|
adminSession.syncFromStorage()
|
|
if (to.path === ADMIN_LOGIN_PATH) {
|
|
if (!adminSession.hasSessionHint) return true
|
|
try {
|
|
await adminSession.loadMe()
|
|
return ADMIN_DASHBOARD_PATH
|
|
} catch {
|
|
adminSession.logout()
|
|
return true
|
|
}
|
|
}
|
|
if (to.meta.requiresAdmin) {
|
|
try {
|
|
if (
|
|
!adminSession.hasSessionHint ||
|
|
adminSession.permissions.length === 0 ||
|
|
adminSession.passwordMustChange
|
|
) {
|
|
await adminSession.loadMe()
|
|
}
|
|
} catch {
|
|
adminSession.logout()
|
|
return { path: ADMIN_LOGIN_PATH, query: { redirect: to.fullPath } }
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
|
|
export default router
|