pet/utils/wechat-auth.js

264 lines
6.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 微信小程序认证工具类
// 封装微信小程序登录的核心逻辑
import { HTTP_CONFIG } from '@/http/config/config.js'
/**
* 微信小程序认证工具类
*/
export class WechatAuth {
/**
* 微信登录获取code
* @returns {Promise<string>} 微信授权码
*/
static async getWxCode() {
return new Promise((resolve, reject) => {
wx.login({
success: (res) => {
console.log(res)
if (res.code) {
resolve(res.code)
} else {
reject(new Error('获取微信授权码失败'))
}
},
fail: (error) => {
reject(new Error('微信登录失败: ' + (error.errMsg || '未知错误')))
}
})
})
}
/**
* 获取用户信息(需要用户授权)
* @param {string} desc 申请理由
* @returns {Promise<Object>} 用户信息
*/
static async getUserProfile(desc = '获取用户头像昵称') {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
wx.getUserProfile({
desc: desc,
success: (res) => {
resolve(res)
},
fail: (error) => {
if (error.errMsg && error.errMsg.includes('auth deny')) {
reject(new Error('用户拒绝授权'))
} else {
reject(new Error('获取用户信息失败: ' + (error.errMsg || '未知错误')))
}
}
})
// #endif
// #ifndef MP-WEIXIN
reject(new Error('当前环境不支持微信授权'))
// #endif
})
}
/**
* 获取用户基本信息(无需授权,但信息有限)
* @returns {Promise<Object>} 用户基本信息
*/
static async getUserInfo() {
return new Promise((resolve, reject) => {
uni.getUserInfo({
success: (res) => {
resolve(res)
},
fail: (error) => {
reject(new Error('获取用户基本信息失败: ' + (error.errMsg || '未知错误')))
}
})
})
}
/**
* 获取用户手机号(需要用户授权)
* 注意这个方法需要在button组件的open-type="getPhoneNumber"的回调中使用
* @param {Object} e 手机号授权回调事件对象
* @returns {Object} 手机号相关数据
*/
static getPhoneNumber(e) {
if (e.detail.errMsg === 'getPhoneNumber:ok') {
return {
success: true,
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
cloudID: e.detail.cloudID
}
} else {
return {
success: false,
error: e.detail.errMsg || '获取手机号失败'
}
}
}
/**
* 生成随机头像
* @returns {string} 随机头像URL
*/
static generateRandomAvatar() {
const avatars = [
'https://img.yzcdn.cn/vant/cat.jpeg',
'https://img.yzcdn.cn/vant/dog.jpeg',
'https://img.yzcdn.cn/vant/rabbit.jpeg',
'https://img.yzcdn.cn/vant/bird.jpeg'
]
return avatars[Math.floor(Math.random() * avatars.length)]
}
/**
* 保存登录信息到本地存储
* @param {string} token 访问令牌
* @param {string} refreshToken 刷新令牌(可选)
* @param {Object} userInfo 用户信息
*/
static saveLoginInfo(token, refreshToken = null, userInfo = null) {
try {
// 使用配置中定义的存储键名
uni.setStorageSync(HTTP_CONFIG.storageKeys.token, token)
if (refreshToken) {
uni.setStorageSync(HTTP_CONFIG.storageKeys.refreshToken, refreshToken)
}
if (userInfo) {
uni.setStorageSync(HTTP_CONFIG.storageKeys.userInfo, userInfo)
}
console.log('登录信息保存成功')
} catch (error) {
console.error('保存登录信息失败:', error)
throw new Error('保存登录信息失败')
}
}
/**
* 获取本地存储的token
* @returns {string|null} 访问令牌
*/
static getToken() {
try {
return uni.getStorageSync(HTTP_CONFIG.storageKeys.token) || null
} catch (error) {
console.error('获取token失败:', error)
return null
}
}
/**
* 获取本地存储的刷新令牌
* @returns {string|null} 刷新令牌
*/
static getRefreshToken() {
try {
return uni.getStorageSync(HTTP_CONFIG.storageKeys.refreshToken) || null
} catch (error) {
console.error('获取refreshToken失败:', error)
return null
}
}
/**
* 获取本地存储的用户信息
* @returns {Object|null} 用户信息
*/
static getUserInfoFromStorage() {
try {
const userInfo = uni.getStorageSync(HTTP_CONFIG.storageKeys.userInfo)
return userInfo ? (typeof userInfo === 'string' ? JSON.parse(userInfo) : userInfo) : null
} catch (error) {
console.error('获取用户信息失败:', error)
return null
}
}
/**
* 检查是否已登录
* @returns {boolean} 是否已登录
*/
static isLoggedIn() {
const token = this.getToken()
return !!token
}
/**
* 清除所有登录信息
* @deprecated 使用 http/utils/auth-helper.js 中的 clearAuthData 替代
*/
static clearLoginInfo() {
const { clearAuthData } = require('../http/utils/auth-helper.js')
clearAuthData()
}
/**
* 跳转到登录页面
* @deprecated 使用 http/utils/auth-helper.js 中的 navigateToLogin 替代
*/
static navigateToLogin() {
const { navigateToLogin } = require('../http/utils/auth-helper.js')
navigateToLogin()
}
/**
* 检查登录状态并处理
* @returns {boolean} 是否已登录
* @deprecated 使用 http/utils/auth-helper.js 中的 checkLoginStatus 替代
*/
static checkLoginStatus() {
const { checkLoginStatus } = require('../http/utils/auth-helper.js')
return checkLoginStatus()
}
/**
* 完整的微信小程序登录流程
* @param {boolean} needUserInfo 是否需要获取用户详细信息
* @returns {Promise<Object>} 登录结果
*/
static async performWxLogin(needUserInfo = true) {
try {
// 1. 获取微信授权码
const code = await this.getWxCode()
// 2. 准备登录数据
const loginData = { code }
// 3. 如果需要用户信息,尝试获取
if (needUserInfo) {
try {
const userProfile = await this.getUserProfile()
loginData.encryptedData = userProfile.encryptedData
loginData.iv = userProfile.iv
loginData.signature = userProfile.signature
loginData.userInfo = userProfile.userInfo
} catch (userInfoError) {
console.warn('获取用户详细信息失败,使用基本登录:', userInfoError.message)
// 继续使用基本登录,不中断流程
}
}
return {
success: true,
data: loginData,
message: '微信授权成功'
}
} catch (error) {
console.error('微信登录流程失败:', error)
return {
success: false,
error: error.message,
message: '微信登录失败'
}
}
}
}
/**
* 默认导出,便于直接导入使用
*/
export default WechatAuth