264 lines
6.4 KiB
JavaScript
264 lines
6.4 KiB
JavaScript
// 微信小程序认证工具类
|
||
// 封装微信小程序登录的核心逻辑
|
||
|
||
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
|