authRedirect.js 6.73 KB
/*
 * @Date: 2025-01-25 10:00:00
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-09-04 15:33:00
 * @FilePath: /lls_program/src/utils/authRedirect.js
 * @Description: 授权重定向处理工具函数
 */
import Taro from '@tarojs/taro'
import { routerStore } from '@/stores/router'

/**
 * 获取当前页面完整路径(包含参数)
 * @returns {string} 完整的页面路径
 */
export const getCurrentPageFullPath = () => {
  const pages = getCurrentPages()
  if (pages.length === 0) return ''

  const currentPage = pages[pages.length - 1]
  const route = currentPage.route
  const options = currentPage.options

  // 构建查询参数字符串
  const queryParams = Object.keys(options)
    .map(key => `${key}=${encodeURIComponent(options[key])}`)
    .join('&')

  return queryParams ? `${route}?${queryParams}` : route
}

/**
 * 保存当前页面路径到路由存储
 * @param {string} customPath - 自定义路径,如果不提供则使用当前页面路径
 */
export const saveCurrentPagePath = (customPath) => {
  const router = routerStore()
  const path = customPath || getCurrentPageFullPath()
  router.add(path)
}

/**
 * 跳转到授权页面
 * @param {string} returnPath - 授权完成后要返回的页面路径
 */
export const navigateToAuth = (returnPath) => {
  // 保存返回路径
  if (returnPath) {
    saveCurrentPagePath(returnPath)
  } else {
    saveCurrentPagePath()
  }

  // 跳转到授权页面
  Taro.navigateTo({
    url: '/pages/auth/index'
  })
}

/**
 * 授权完成后返回原页面
 * @param {string} defaultPath - 默认返回路径,如果没有保存的路径则使用此路径
 */
/**
 * 返回到原始页面,带有容错处理机制
 * @param {string} defaultPath - 默认跳转路径
 * @param {number} retryCount - 重试次数,默认为2
 */
export const returnToOriginalPage = async (defaultPath = '/pages/Dashboard/index', retryCount = 2) => {
  const router = routerStore()
  const savedPath = router.url

  /**
   * 执行页面跳转的核心函数
   * @param {string} targetPath - 目标路径
   * @param {boolean} isHomePage - 是否为首页
   */
  const executeNavigation = async (targetPath, isHomePage = false) => {
    try {
      if (isHomePage) {
        await Taro.reLaunch({
          url: targetPath
        })
      } else {
        await Taro.redirectTo({
          url: targetPath
        })
      }
      return true
    } catch (error) {
      console.warn('页面跳转失败:', error)
      return false
    }
  }

  /**
   * 带重试机制的页面跳转
   * @param {string} targetPath - 目标路径
   * @param {boolean} isHomePage - 是否为首页
   * @param {number} maxRetries - 最大重试次数
   */
  const navigateWithRetry = async (targetPath, isHomePage, maxRetries) => {
    for (let i = 0; i <= maxRetries; i++) {
      const success = await executeNavigation(targetPath, isHomePage)
      if (success) {
        return true
      }

      // 如果不是最后一次重试,等待一段时间后重试
      if (i < maxRetries) {
        console.warn(`页面跳转重试 ${i + 1}/${maxRetries}`)
        await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))) // 递增延迟
      }
    }
    return false
  }

  try {
    if (savedPath && savedPath !== '') {
      // 清除保存的路径
      router.remove()

      const targetUrl = `/${savedPath}`
      const isHomePage = savedPath.includes('Dashboard/index') || savedPath === 'pages/Dashboard/index'

      // 尝试跳转到保存的页面
      const success = await navigateWithRetry(targetUrl, isHomePage, retryCount)

      if (!success) {
        console.warn('跳转到保存页面失败,尝试跳转到默认页面')
        // 如果跳转失败,尝试跳转到默认页面
        const fallbackSuccess = await navigateWithRetry(defaultPath, true, retryCount)

        if (!fallbackSuccess) {
          // 最后的降级方案:使用 switchTab 跳转到首页
          console.warn('所有跳转方式失败,使用 switchTab 降级方案')
          try {
            await Taro.switchTab({
              url: '/pages/Dashboard/index'
            })
          } catch (switchError) {
            console.error('switchTab 也失败了:', switchError)
            // 显示用户友好的错误提示
            Taro.showToast({
              title: '页面跳转失败,请重新打开小程序',
              icon: 'none',
              duration: 3000
            })
          }
        }
      }
    } else {
      // 没有保存的路径,直接跳转到默认页面
      const success = await navigateWithRetry(defaultPath, true, retryCount)

      if (!success) {
        // 降级方案
        console.warn('跳转到默认页面失败,使用 switchTab 降级方案')
        try {
          await Taro.switchTab({
            url: '/pages/Dashboard/index'
          })
        } catch (switchError) {
          console.error('switchTab 也失败了:', switchError)
          Taro.showToast({
            title: '页面跳转失败,请重新打开小程序',
            icon: 'none',
            duration: 3000
          })
        }
      }
    }
  } catch (error) {
    console.error('returnToOriginalPage 执行出错:', error)
    // 最终的错误处理
    try {
      await Taro.switchTab({
        url: '/pages/Dashboard/index'
      })
    } catch (finalError) {
      console.error('最终降级方案也失败了:', finalError)
      Taro.showToast({
        title: '系统异常,请重新打开小程序',
        icon: 'none',
        duration: 3000
      })
    }
  }
}

/**
 * 检查页面是否来自分享
 * @param {Object} options - 页面参数
 * @returns {boolean} 是否来自分享
 */
export const isFromShare = (options) => {
  // 检查是否有分享相关的参数或标识
  return options && (options.from_share === '1' || options.scene)
}

/**
 * 处理分享页面的授权逻辑
 * @param {Object} options - 页面参数
 * @param {Function} callback - 授权成功后的回调函数
 */
export const handleSharePageAuth = async (options, callback) => {
  const sessionid = wx.getStorageSync('sessionid')

  if (!sessionid) {
    // 没有授权,需要先授权
    if (isFromShare(options)) {
      // 来自分享,保存当前页面路径用于授权后返回
      saveCurrentPagePath()
    }

    // 跳转到授权页面
    Taro.navigateTo({
      url: '/pages/auth/index'
    })
    return false
  }

  // 已授权,执行回调
  if (callback && typeof callback === 'function') {
    callback()
  }
  return true
}

/**
 * 为分享链接添加分享标识参数
 * @param {string} path - 原始路径
 * @returns {string} 添加分享标识后的路径
 */
export const addShareFlag = (path) => {
  const separator = path.includes('?') ? '&' : '?'
  return `${path}${separator}from_share=1`
}