Files
ai_dianshang/miniprogram/services/auth/wechat.js
2025-11-17 14:11:46 +08:00

344 lines
9.9 KiB
JavaScript
Raw 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.

const { config } = require('../../config/index');
/**
* 微信登录服务
*/
class WeChatAuthService {
constructor() {
this.apiBase = config.apiBase;
}
/**
* 微信授权登录
* @param {Object} options - 登录选项
* @param {boolean} options.withUserInfo - 是否获取用户信息
* @returns {Promise} 登录结果
*/
async login(options = {}) {
const { withUserInfo = false } = options;
try {
// 1. 获取微信登录code
const loginResult = await this.getWeChatLoginCode();
if (withUserInfo) {
// 2. 如果需要用户信息,先获取用户信息
const userInfo = await this.getUserInfo();
return await this.loginWithUserInfo(loginResult.code, userInfo);
} else {
// 3. 仅使用code登录
return await this.loginWithCode(loginResult.code);
}
} catch (error) {
console.error('微信登录失败:', error);
throw error;
}
}
/**
* 微信授权登录
* @returns {Promise} 登录结果
*/
async authorizeLogin(userInfo = null) {
try {
console.log('开始微信授权登录...');
// 1. 获取微信登录code
const loginResult = await this.getWeChatLoginCode();
console.log('获取微信登录code成功:', loginResult.code);
// 2. 使用一次性 code 完成登录(避免重复获取)
let loginData;
if (userInfo) {
console.log('使用code+用户信息登录');
loginData = await this.loginWithUserInfo(loginResult.code, userInfo);
} else {
console.log('使用code登录');
loginData = await this.loginWithCode(loginResult.code);
}
console.log('登录成功:', loginData);
return {
success: true,
data: {
...loginData,
userInfo: userInfo || null
},
message: '授权登录成功'
};
} catch (error) {
console.error('微信授权登录失败:', error);
return {
success: false,
message: error.message || '授权登录失败'
};
}
}
/**
* 更新用户资料
* @param {Object} userInfo - 用户信息对象
* @returns {Promise} 更新结果
*/
async updateUserProfile(userInfo) {
return new Promise((resolve, reject) => {
console.log('开始更新用户资料...');
console.log('用户信息:', userInfo);
console.log('API地址:', `${this.apiBase}/users/profile`);
console.log('Token:', wx.getStorageSync('token'));
wx.request({
url: `${this.apiBase}/users/profile`,
method: 'PUT',
header: {
'Authorization': `Bearer ${wx.getStorageSync('token')}`,
'Content-Type': 'application/json'
},
data: {
nickname: userInfo.nickName || userInfo.nickname,
avatar: userInfo.avatarUrl || userInfo.avatar,
gender: userInfo.gender || 0,
phone: userInfo.phoneNumber || userInfo.phone,
email: userInfo.email
},
success: (res) => {
if (res.statusCode === 200 && res.data.code === 200) {
console.log('用户资料更新成功:', res.data);
resolve(res.data.data);
} else {
reject(new Error(res.data.message || '更新用户资料失败'));
}
},
fail: (error) => {
console.error('更新用户资料失败:', error);
reject(new Error(`网络请求失败: ${error.errMsg}`));
}
});
});
}
/**
* 获取微信登录code临时登录凭证
* 按照微信官方文档标准实现
* @returns {Promise} 登录结果
*/
getWeChatLoginCode() {
return new Promise((resolve, reject) => {
wx.login({
success: (res) => {
if (res.code) {
console.log('获取微信登录code成功:', res.code);
// 验证code格式微信code通常是32位字符串
if (res.code.length < 10) {
reject(new Error('获取的登录凭证格式异常'));
return;
}
resolve(res);
} else {
console.error('wx.login成功但未返回code');
reject(new Error('获取微信登录凭证失败'));
}
},
fail: (error) => {
console.error('wx.login调用失败:', error);
reject(new Error(`微信登录失败: ${error.errMsg || '未知错误'}`));
}
});
});
}
/**
* 获取用户信息(新版本兼容方式)
* 由于getUserProfile已废弃现在使用头像昵称填写组件或直接跳过用户信息获取
* @returns {Promise} 用户信息
*/
getUserInfo() {
return new Promise((resolve, reject) => {
// 由于getUserProfile已废弃我们提供一个默认的用户信息结构
// 实际的头像和昵称应该通过头像昵称填写组件获取
console.log('注意getUserProfile API已废弃建议使用头像昵称填写组件');
// 返回一个基础的用户信息结构
const defaultUserInfo = {
nickName: '微信用户',
avatarUrl: '', // 空头像,后续可通过头像组件更新
gender: 0,
country: '',
province: '',
city: ''
};
console.log('使用默认用户信息:', defaultUserInfo);
resolve(defaultUserInfo);
});
}
/**
* 通过头像昵称组件获取用户信息
* @param {Object} userInfo - 从头像昵称组件获取的用户信息
* @returns {Promise} 处理后的用户信息
*/
getUserInfoFromComponent(userInfo) {
return new Promise((resolve, reject) => {
try {
// 验证用户信息
if (!userInfo) {
reject(new Error('用户信息不能为空'));
return;
}
// 构建标准的用户信息格式
const standardUserInfo = {
nickName: userInfo.nickName || '微信用户',
avatarUrl: userInfo.avatarUrl || '',
gender: userInfo.gender || 0,
country: userInfo.country || '',
province: userInfo.province || '',
city: userInfo.city || ''
};
console.log('从组件获取用户信息成功:', standardUserInfo);
resolve(standardUserInfo);
} catch (error) {
console.error('处理用户信息失败:', error);
reject(new Error('处理用户信息失败'));
}
});
}
/**
* 使用code登录
* @param {string} code - 微信登录code
* @returns {Promise} 登录结果
*/
loginWithCode(code) {
return new Promise((resolve, reject) => {
wx.request({
url: `${this.apiBase}/users/wechat-login`,
method: 'POST',
data: {
code: code
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200 && res.data.code === 200) {
const result = res.data.data;
// 保存token到本地存储
if (result.token) {
wx.setStorageSync('token', result.token);
wx.setStorageSync('jwt_token', result.token);
}
resolve(result);
} else {
reject(new Error(res.data.message || '登录失败'));
}
},
fail: (error) => {
reject(new Error(`网络请求失败: ${error.errMsg}`));
}
});
});
}
/**
* 使用code和用户信息登录
* @param {string} code - 微信登录code
* @param {Object} userInfo - 用户信息
* @returns {Promise} 登录结果
*/
loginWithUserInfo(code, userInfo) {
return new Promise((resolve, reject) => {
wx.request({
url: `${this.apiBase}/users/wechat-login`,
method: 'POST',
data: {
code: code,
userInfo: {
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
gender: userInfo.gender,
country: userInfo.country,
province: userInfo.province,
city: userInfo.city
}
},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200 && res.data.code === 200) {
const result = res.data.data;
// 保存token到本地存储
if (result.token) {
wx.setStorageSync('token', result.token);
wx.setStorageSync('jwt_token', result.token);
}
resolve(result);
} else {
reject(new Error(res.data.message || '登录失败'));
}
},
fail: (error) => {
reject(new Error(`网络请求失败: ${error.errMsg}`));
}
});
});
}
/**
* 获取微信会话信息
* @returns {Promise} 会话信息
*/
getWeChatSession() {
return new Promise((resolve, reject) => {
const token = wx.getStorageSync('token');
if (!token) {
reject(new Error('未找到登录token'));
return;
}
wx.request({
url: `${this.apiBase}/users/wechat-session`,
method: 'GET',
header: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200 && res.data.code === 200) {
resolve(res.data.data);
} else {
reject(new Error(res.data.message || '获取会话信息失败'));
}
},
fail: (error) => {
reject(new Error(`网络请求失败: ${error.errMsg}`));
}
});
});
}
/**
* 检查登录状态
* @returns {boolean} 是否已登录
*/
isLoggedIn() {
const token = wx.getStorageSync('token');
return !!token;
}
/**
* 退出登录
*/
logout() {
wx.removeStorageSync('token');
wx.removeStorageSync('jwt_token');
}
}
// 创建单例实例
const weChatAuthService = new WeChatAuthService();
module.exports = weChatAuthService;