Codex Assistant
昨天 0a48616045ddce1562584543a0e89e5144051fde
wx/app.js
@@ -4,7 +4,7 @@
    userInfo: null,
    token: null,
    sessionKey: null, // 微信会话密钥,用于解密手机号等敏感数据
    baseUrl: 'http://localhost:8080/graphql', // 后台GraphQL接口地址
    baseUrl: 'http://localhost:8080/api/graphql', // 后台GraphQL接口地址
    hasPhoneAuth: false, // 是否已授权手机号
    rejectPhone: false, // 是否拒绝过手机号授权
    cos: {
@@ -276,56 +276,174 @@
  // GraphQL请求封装
  graphqlRequest(query, variables = {}) {
    return new Promise((resolve, reject) => {
      // 确保token的一致性:优先使用globalData中的token,如果没有则从storage获取
      let token = this.globalData.token
      if (!token) {
        token = wx.getStorageSync('token')
        if (token) {
          this.globalData.token = token // 同步到globalData
        }
      }
      this._makeGraphQLRequest(query, variables, resolve, reject, false)
    })
  },
      wx.request({
        url: this.globalData.baseUrl,
        method: 'POST',
        header: {
          'Content-Type': 'application/json',
          'Authorization': token ? `Bearer ${token}` : ''
        },
        data: {
          query: query,
          variables: variables
        },
        success: (res) => {
          console.log('GraphQL响应:', res.data)
          // 检查HTTP状态码
          if (res.statusCode !== 200) {
  // 内部GraphQL请求方法,支持重试机制
  _makeGraphQLRequest(query, variables, resolve, reject, isRetry = false) {
    // 确保token的一致性:优先使用globalData中的token,如果没有则从storage获取
    let token = this.globalData.token
    if (!token) {
      token = wx.getStorageSync('token')
      if (token) {
        this.globalData.token = token // 同步到globalData
      }
    }
    wx.request({
      url: this.globalData.baseUrl,
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'Authorization': token ? `Bearer ${token}` : ''
      },
      data: {
        query: query,
        variables: variables
      },
      success: (res) => {
        console.log('GraphQL响应:', res.data)
        // 检查HTTP状态码
        if (res.statusCode !== 200) {
          // 对于401状态码,可能是认证错误,需要检查响应内容
          if (res.statusCode === 401 && res.data && res.data.errors) {
            console.log('收到401状态码,检查是否为认证错误')
            // 继续处理,让下面的GraphQL错误检查逻辑处理认证错误
          } else {
            console.error('GraphQL HTTP错误:', res.statusCode)
            reject(new Error(`HTTP错误: ${res.statusCode}`))
            return
          }
        }
          // 检查GraphQL错误
          if (res.data.errors) {
            console.error('GraphQL错误:', res.data.errors)
            reject(new Error(res.data.errors[0]?.message || 'GraphQL请求错误'))
        // 检查GraphQL错误
        if (res.data && res.data.errors) {
          console.error('GraphQL错误:', res.data.errors)
          // 检查是否是认证错误(token过期或无效)
          const authErrors = res.data.errors.filter(error =>
            error.message && (
              error.message.includes('没有权限访问') ||
              error.message.includes('请先登录') ||
              error.message.includes('UNAUTHORIZED') ||
              error.extensions?.code === 'UNAUTHORIZED'
            )
          )
          if (authErrors.length > 0 && !isRetry) {
            console.log('🔄 检测到认证错误,尝试重新登录...')
            // 清除过期的认证信息
            this.globalData.token = null
            this.globalData.userInfo = null
            this.globalData.sessionKey = null
            wx.removeStorageSync('token')
            wx.removeStorageSync('userInfo')
            wx.removeStorageSync('sessionKey')
            // 重新登录
            wx.login({
              success: (loginRes) => {
                if (loginRes.code) {
                  console.log('🔄 重新获取微信code成功,调用后端登录...')
                  this._retryAfterLogin(loginRes.code, query, variables, resolve, reject)
                } else {
                  console.error('❌ 重新获取微信code失败')
                  reject(new Error('重新登录失败'))
                }
              },
              fail: (err) => {
                console.error('❌ 重新登录失败:', err)
                reject(new Error('重新登录失败'))
              }
            })
            return
          }
          // 检查数据
          if (res.data.data !== undefined) {
            resolve(res.data.data)
          } else {
            console.error('GraphQL响应异常:', res.data)
            reject(new Error('GraphQL响应数据异常'))
          }
        },
        fail: (err) => {
          console.error('GraphQL网络请求失败:', err)
          reject(new Error('网络请求失败'))
          reject(new Error(res.data.errors[0]?.message || 'GraphQL请求错误'))
          return
        }
      })
        // 检查数据
        if (res.data.data !== undefined) {
          resolve(res.data.data)
        } else {
          console.error('GraphQL响应异常:', res.data)
          reject(new Error('GraphQL响应数据异常'))
        }
      },
      fail: (err) => {
        console.error('GraphQL网络请求失败:', err)
        reject(new Error('网络请求失败'))
      }
    })
  },
  // 重新登录后重试GraphQL请求
  _retryAfterLogin(code, query, variables, resolve, reject) {
    const that = this
    const deviceInfo = this.getDeviceInfo()
    const requestData = {
      code: code,
      loginIp: '127.0.0.1', // 小程序无法获取真实IP,使用默认值
      deviceInfo: deviceInfo
    }
    wx.request({
      url: 'http://localhost:8080/api/auth/wx-login',
      method: 'POST',
      header: {
        'Content-Type': 'application/json'
      },
      data: requestData,
      success: (res) => {
        console.log('🔄 重新登录响应:', res.data)
        if (res.statusCode !== 200 || res.data.error) {
          console.error('❌ 重新登录失败:', res.data.error || res.data.message)
          reject(new Error('重新登录失败'))
          return
        }
        // 检查响应数据格式
        let loginResult = null
        if (res.data.token && res.data.userInfo) {
          loginResult = res.data
        } else if (res.data.success && res.data.data) {
          loginResult = res.data.data
        }
        if (loginResult && loginResult.token) {
          console.log('✅ 重新登录成功,更新token')
          // 保存新的登录信息
          try {
            wx.setStorageSync('token', loginResult.token)
            wx.setStorageSync('userInfo', loginResult.userInfo)
            if (loginResult.sessionKey) {
              wx.setStorageSync('sessionKey', loginResult.sessionKey)
            }
          } catch (storageErr) {
            console.error('❌ 保存重新登录信息失败:', storageErr)
          }
          that.globalData.token = loginResult.token
          that.globalData.userInfo = loginResult.userInfo
          that.globalData.sessionKey = loginResult.sessionKey
          // 使用新token重试原始请求
          console.log('🔄 使用新token重试GraphQL请求...')
          that._makeGraphQLRequest(query, variables, resolve, reject, true)
        } else {
          console.error('❌ 重新登录响应格式错误')
          reject(new Error('重新登录响应格式错误'))
        }
      },
      fail: (err) => {
        console.error('❌ 重新登录网络请求失败:', err)
        reject(new Error('重新登录网络请求失败'))
      }
    })
  }
})