longz
2026-04-27 25df88d0ab9d7444ed1d162b9efa1259ac2f6f66
yuyueMiniProgram/src/router/index.ts
@@ -1,5 +1,9 @@
/// <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) => {
@@ -21,58 +25,65 @@
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}`)
  }
})