| | |
| | | /// <reference types="@uni-helper/vite-plugin-uni-pages/client" /> |
| | | import { pages, subPackages } from 'virtual:uni-pages' |
| | | import { fetchMiniMe } from '@/api/auth' |
| | | import { setUnauthorizedRedirectHandler } from './authRedirect' |
| | | import { clearMiniAuthSession, getPersistedAuthState, updateMiniAuthProfile } from '@/store/auth' |
| | | import { normalizeMeProfile } from '@/types/auth' |
| | | |
| | | function generateRoutes() { |
| | | const routes = pages.map((page) => { |
| | |
| | | const router = createRouter({ |
| | | routes: generateRoutes(), |
| | | }) |
| | | |
| | | setUnauthorizedRedirectHandler(() => { |
| | | router.replaceAll({ name: 'login' }) |
| | | }) |
| | | |
| | | const PUBLIC_ROUTE_NAMES = new Set(['login', 'visitorCode']) |
| | | const HOME_ROUTE_NAME = 'home' |
| | | |
| | | function isPublicRoute(name?: string) { |
| | | return Boolean(name && PUBLIC_ROUTE_NAMES.has(name)) |
| | | } |
| | | |
| | | router.beforeEach((to, from, next) => { |
| | | console.log('🚀 beforeEach 守卫触发:', { to, from }) |
| | | const state = getPersistedAuthState() |
| | | const hasToken = Boolean(state.token) |
| | | const hasProfile = Boolean(state.profile) |
| | | const publicRoute = isPublicRoute(to.name) |
| | | |
| | | // 演示:基本的导航日志记录 |
| | | if (to.path && from.path) { |
| | | console.log(`📍 导航: ${from.path} → ${to.path}`) |
| | | if (!hasToken) { |
| | | if (publicRoute) { |
| | | next() |
| | | return |
| | | } |
| | | next({ name: 'login' }) |
| | | return |
| | | } |
| | | |
| | | // 演示:对受保护页面的简单拦截 |
| | | if (to.name === 'demo-protected') { |
| | | const { confirm: showConfirm } = useGlobalMessage() |
| | | console.log('🛡️ 检测到访问受保护页面') |
| | | |
| | | return new Promise<void>((resolve, reject) => { |
| | | showConfirm({ |
| | | title: '守卫拦截演示', |
| | | msg: '这是一个受保护的页面,需要确认后才能访问', |
| | | confirmButtonText: '允许访问', |
| | | cancelButtonText: '取消', |
| | | success() { |
| | | console.log('✅ 用户确认访问,允许导航') |
| | | next() |
| | | resolve() |
| | | }, |
| | | fail() { |
| | | console.log('❌ 用户取消访问,阻止导航') |
| | | next(false) |
| | | reject(new Error('用户取消访问')) |
| | | }, |
| | | }) |
| | | }) |
| | | const ensureProfile = async () => { |
| | | if (hasProfile) { |
| | | return true |
| | | } |
| | | try { |
| | | const profile = await fetchMiniMe() |
| | | updateMiniAuthProfile(normalizeMeProfile(profile)) |
| | | return true |
| | | } |
| | | catch (error) { |
| | | console.warn('mini auth guard fetch /me failed', error) |
| | | clearMiniAuthSession() |
| | | return false |
| | | } |
| | | } |
| | | |
| | | // 继续导航 |
| | | next() |
| | | return Promise.resolve(ensureProfile()).then((ok) => { |
| | | if (!ok) { |
| | | next({ name: 'login' }) |
| | | return |
| | | } |
| | | if (publicRoute) { |
| | | next({ name: HOME_ROUTE_NAME }) |
| | | return |
| | | } |
| | | next() |
| | | }) |
| | | }) |
| | | |
| | | router.afterEach((to, from) => { |
| | | console.log('🎯 afterEach 钩子触发:', { to, from }) |
| | | |
| | | // 演示:简单的页面切换记录 |
| | | if (to.path) { |
| | | console.log(`📄 页面切换完成: ${to.path}`) |
| | | } |
| | | |
| | | // 演示:针对 afterEach 演示页面的简单提示 |
| | | if (to.name === 'demo-aftereach') { |
| | | const { show: showToast } = useGlobalToast() |
| | | console.log('📊 进入 afterEach 演示页面') |
| | | setTimeout(() => { |
| | | showToast('afterEach 钩子已触发!') |
| | | }, 500) |
| | | if (import.meta.env.MODE === 'development' && to.path) { |
| | | console.log(`📄 页面切换完成: ${from.path || '-'} -> ${to.path}`) |
| | | } |
| | | }) |
| | | |