Files
ai_dianshang/miniprogram/services/auth/wechat.js

344 lines
9.9 KiB
JavaScript
Raw Normal View History

2025-11-17 14:11:46 +08:00
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;