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;