index.js 3.13 KB
/*
 * @Date: 2025-03-20 20:36:36
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-12-19 00:16:42
 * @FilePath: /mlaj/src/router/index.js
 * @Description: 路由实例创建和导出
 */
import { createRouter, createWebHashHistory } from 'vue-router'
import { routes } from './routes'
import { checkAuth, hasVisitedWelcome, markWelcomeVisited } from './guards'
import { getUserIsLoginAPI } from '@/api/auth'
import { getUserInfoAPI } from '@/api/users'

const router = createRouter({
    history: createWebHashHistory(import.meta.env.VITE_BASE || '/'),
    routes,
    scrollBehavior(to, from, savedPosition) {
        if (savedPosition) {
            return savedPosition
        }
        // 每次路由切换后,页面滚动到顶部
        return { top: 0, left: 0 }
    },
})

// 导航守卫
router.beforeEach(async (to, from, next) => {
  // 欢迎页访问逻辑
  if (import.meta.env.VITE_WELCOME_PAGE_ENABLED === 'true') {
    // 重置欢迎页标志(URL 参数)
    if (to.query.reset_welcome === 'true') {
      const { resetWelcomeFlag } = await import('./guards.js')
      resetWelcomeFlag()
      // 移除 URL 参数
      const query = { ...to.query }
      delete query.reset_welcome
      return next({ path: to.path, query })
    }

    // 欢迎页访问检测
    if (to.path === '/welcome') {
      if (hasVisitedWelcome()) {
        // 已访问过,跳转到首页
        return next('/')
      } else {
        // 首次访问,标记并显示欢迎页
        markWelcomeVisited()
      }
    }
  }

  // 检查用户是否已登录
  const currentUser = JSON.parse(localStorage.getItem('currentUser') || 'null')
  const redirectRaw = to.query && to.query.redirect

    // 登录权限检查(不再自动触发微信授权)
    const authResult = checkAuth(to)
    if (authResult !== true) {
        next(authResult)
        return
    }

    // 登录页统一处理授权回跳与默认重定向
    if (to.path === '/login') {
        /**
         * 情况1:本地已有登录态
         * - 有 redirect:跳回来源页
         * - 无 redirect:默认跳首页
         */
        if (currentUser) {
            const redirect = redirectRaw ? decodeURIComponent(redirectRaw) : '/'
            next(redirect)
            return
        }

        /**
         * 情况2:授权回跳但本地未写入登录态
         * - 统一在路由层探测登录
         * - 登录为真:写入用户信息,并按 redirect 或首页跳转
         */
        try {
            const { code, data } = await getUserIsLoginAPI()
            if (code && data && data.is_login) {
                const { code: uiCode, data: uiData } = await getUserInfoAPI()
                if (uiCode) {
                    const mergedUser = { ...uiData.user, ...uiData.checkin }
                    localStorage.setItem('currentUser', JSON.stringify(mergedUser))
                }
                const redirect = redirectRaw ? decodeURIComponent(redirectRaw) : '/'
                next(redirect)
                return
            }
        } catch (e) {
            // 静默失败,进入登录页
        }
    }

    next()
})

export default router