diff --git a/images/1.jpg b/images/1.jpg deleted file mode 100644 index 693a51a..0000000 Binary files a/images/1.jpg and /dev/null differ diff --git a/images/2.jpg b/images/2.jpg deleted file mode 100644 index 77bd750..0000000 Binary files a/images/2.jpg and /dev/null differ diff --git a/images/3.jpg b/images/3.jpg deleted file mode 100644 index 051ee9a..0000000 Binary files a/images/3.jpg and /dev/null differ diff --git a/images/4.jpg b/images/4.jpg deleted file mode 100644 index 3eee6fe..0000000 Binary files a/images/4.jpg and /dev/null differ diff --git a/pages/goods-detail/goods-detail.js b/pages/goods-detail/goods-detail.js index 0cbfc9a..e29ca53 100644 --- a/pages/goods-detail/goods-detail.js +++ b/pages/goods-detail/goods-detail.js @@ -1024,6 +1024,324 @@ Page({ } }, + // 处理登录授权 + async onGetPhoneNumber(e) { + console.log('收到手机号授权事件:', e.detail); + + // 关闭手机号授权弹窗 + this.setData({ showOneKeyLoginModal: false }) + + // 用户点击拒绝授权 + if (e.detail.errMsg === 'getPhoneNumber:fail user deny') { + wx.showToast({ + title: '需要授权手机号才能使用', + icon: 'none', + duration: 2000 + }) + return + } + + // 处理没有权限的情况 + if (e.detail.errMsg === 'getPhoneNumber:fail no permission') { + wx.showToast({ + title: '当前环境无法获取手机号权限', + icon: 'none', + duration: 3000 + }) + return + } + + // 检查是否已经登录,避免重复授权 + const existingOpenid = wx.getStorageSync('openid') + const existingUserId = wx.getStorageSync('userId') + const existingUserInfo = wx.getStorageSync('userInfo') + + if (existingOpenid && existingUserId && existingUserInfo && existingUserInfo.phoneNumber) { + console.log('用户已登录且手机号有效,登录流程已完成') + wx.showToast({ + title: '您已登录', + icon: 'success', + duration: 1500 + }) + return + } + + wx.showLoading({ + title: '登录中...', + mask: true + }) + + try { + if (e.detail.errMsg === 'getPhoneNumber:ok') { + // 用户同意授权,实际处理授权流程 + console.log('用户同意授权获取手机号') + + // 1. 先执行微信登录获取code + const loginRes = await new Promise((resolve, reject) => { + wx.login({ + success: resolve, + fail: reject + }) + }) + + if (!loginRes.code) { + throw new Error('获取登录code失败') + } + + console.log('获取登录code成功:', loginRes.code) + + // 2. 使用code换取openid + const openidRes = await API.getOpenid(loginRes.code) + + // 改进错误处理逻辑,更宽容地处理服务器返回格式 + let openid = null; + let userId = null; + console.log('openidRes完整响应:', JSON.stringify(openidRes)); + + if (openidRes && typeof openidRes === 'object') { + // 适配服务器返回格式:{success: true, code: 200, message: '获取openid成功', data: {openid, userId}} + if (openidRes.data && typeof openidRes.data === 'object') { + console.log('识别到标准服务器返回格式,从data字段提取信息'); + openid = openidRes.data.openid || openidRes.data.OpenID || null; + userId = openidRes.data.userId || null; + } else { + // 尝试从响应对象中直接提取openid + console.log('尝试从根对象直接提取openid'); + openid = openidRes.openid || openidRes.OpenID || null; + userId = openidRes.userId || null; + } + } + + if (!openid) { + console.error('无法从服务器响应中提取openid,完整响应:', JSON.stringify(openidRes)); + throw new Error(`获取openid失败: 服务器返回数据格式可能不符合预期`); + } + + console.log('获取openid成功:', openid) + + // 3. 存储openid和session_key + wx.setStorageSync('openid', openid) + + // 从服务器返回中获取session_key + if (openidRes && openidRes.session_key) { + wx.setStorageSync('sessionKey', openidRes.session_key) + } else if (openidRes && openidRes.data && openidRes.data.session_key) { + wx.setStorageSync('sessionKey', openidRes.data.session_key) + } + + // 优先使用从服务器响应data字段中提取的userId + if (userId) { + wx.setStorageSync('userId', userId) + console.log('使用从服务器data字段提取的userId:', userId) + } else if (openidRes && openidRes.userId) { + wx.setStorageSync('userId', openidRes.userId) + console.log('使用服务器根对象中的userId:', openidRes.userId) + } else { + // 生成临时userId + const tempUserId = 'user_' + Date.now() + wx.setStorageSync('userId', tempUserId) + console.log('生成临时userId:', tempUserId) + } + + // 4. 上传手机号加密数据到服务器解密 + const phoneData = { + ...e.detail, + openid: openid + } + + console.log('准备上传手机号加密数据到服务器') + const phoneRes = await API.uploadPhoneNumberData(phoneData) + + // 改进手机号解密结果的处理逻辑 + if (!phoneRes || (!phoneRes.success && !phoneRes.phoneNumber)) { + // 如果服务器返回格式不标准但包含手机号,也接受 + if (phoneRes && phoneRes.phoneNumber) { + console.warn('服务器返回格式可能不符合预期,但成功获取手机号'); + } else { + throw new Error('获取手机号失败: ' + (phoneRes && phoneRes.message ? phoneRes.message : '未知错误')) + } + } + + // 检查是否有手机号冲突 + const hasPhoneConflict = phoneRes.phoneNumberConflict || false + const isNewPhone = phoneRes.isNewPhone || true + const phoneNumber = phoneRes.phoneNumber || null + + // 如果有手机号冲突且没有返回手机号,使用实际返回的手机号 + const finalPhoneNumber = phoneNumber + + console.log('手机号解密结果:', { + phoneNumber: finalPhoneNumber, + hasPhoneConflict: hasPhoneConflict, + isNewPhone: isNewPhone + }) + + // 5. 获取用户微信名称和头像 + let userProfile = null; + try { + userProfile = await new Promise((resolve, reject) => { + wx.getUserProfile({ + desc: '用于完善会员资料', + success: resolve, + fail: reject + }); + }); + console.log('获取用户信息成功:', userProfile); + } catch (err) { + console.warn('获取用户信息失败:', err); + // 如果获取失败,使用默认值 + } + + // 6. 创建用户信息 + const tempUserInfo = { + name: userProfile ? (userProfile.userInfo.name || userProfile.userInfo.nickName) : '微信用户', + // 获取微信头像失败时使用微信默认头像 + avatarUrl: userProfile ? userProfile.userInfo.avatarUrl : 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0', + gender: userProfile ? userProfile.userInfo.gender : 0, + country: userProfile ? userProfile.userInfo.country : '', + province: userProfile ? userProfile.userInfo.province : '', + city: userProfile ? userProfile.userInfo.city : '', + language: userProfile ? userProfile.userInfo.language : 'zh_CN', + phoneNumber: finalPhoneNumber + } + + // 7. 保存用户信息 + const storedUserId = wx.getStorageSync('userId') + const users = wx.getStorageSync('users') || {} + const currentUserType = users[storedUserId] && users[storedUserId].type ? users[storedUserId].type : 'buyer' + + console.log('用户身份类型:', currentUserType) + + // 8. 保存用户信息到本地和服务器 + console.log('开始保存用户信息...') + await this.saveUserInfo(tempUserInfo, currentUserType) + console.log('用户信息保存完成') + + wx.hideLoading() + + // 根据服务器返回的结果显示不同的提示 + if (phoneRes && phoneRes.phoneNumberConflict) { + wx.showModal({ + title: '登录成功', + content: '您的手机号已被其他账号绑定', + showCancel: false, + confirmText: '我知道了', + success(res) { + if (res.confirm) { + console.log('用户点击了我知道了'); + } + } + }); + } + + // 显示登录成功提示 + wx.showToast({ + title: '登录成功', + icon: 'success', + duration: 1500 + }) + + // 登录成功后,重新加载商品详情以刷新收藏状态 + const productId = String(this.data.goodsDetail.id || this.data.goodsDetail.productId); + this.loadGoodsFavoriteStatus(productId); + + // 触发全局事件,通知其他页面登录状态已更改 + const app = getApp(); + if (app && app.eventBus) { + app.eventBus.emit('userLoginStatusChanged', { + isLoggedIn: true, + userId: storedUserId, + phoneNumber: finalPhoneNumber + }); + } + + } else { + // 用户拒绝授权或其他情况 + console.log('手机号授权失败:', e.detail.errMsg) + // 不再抛出错误,而是显示友好的提示 + wx.hideLoading() + wx.showToast({ + title: '需要授权手机号才能使用', + icon: 'none', + duration: 2000 + }) + return + } + } catch (error) { + wx.hideLoading() + console.error('登录过程中发生错误:', error) + + // 更具体的错误提示 + let errorMsg = '登录失败,请重试' + if (error.message.includes('网络')) { + errorMsg = '网络连接失败,请检查网络后重试' + } else if (error.message.includes('服务器')) { + errorMsg = '服务器连接失败,请稍后重试' + } + + wx.showToast({ + title: errorMsg, + icon: 'none', + duration: 3000 + }) + + // 清除可能已经保存的不完整信息 + try { + wx.removeStorageSync('openid') + wx.removeStorageSync('sessionKey') + wx.removeStorageSync('userId') + } catch (e) { + console.error('清除临时登录信息失败:', e) + } + } + }, + + // 保存用户信息的方法 + async saveUserInfo(userInfo, userType) { + return new Promise((resolve, reject) => { + // 1. 保存到本地users对象 + const users = wx.getStorageSync('users') || {}; + const userId = wx.getStorageSync('userId'); + + if (!userId) { + reject(new Error('用户ID不存在')); + return; + } + + // 合并用户信息 + users[userId] = { + ...users[userId], + ...userInfo, + type: userType || 'buyer', + updatedAt: new Date().toISOString() + }; + + wx.setStorageSync('users', users); + + // 2. 保存到全局userInfo对象 + wx.setStorageSync('userInfo', { + ...userInfo, + userType: userType || 'buyer' + }); + + // 3. 上传到服务器 + const API = require('../../utils/api.js'); + + API.uploadUserInfo({ + userId: userId, + ...userInfo, + type: userType || 'buyer' + }).then(res => { + console.log('用户信息上传成功:', res); + resolve(res); + }).catch(err => { + console.error('用户信息上传失败:', err); + // 即使服务器上传失败,也继续流程,只在本地保存 + resolve({ success: false, message: '本地保存成功,服务器同步失败' }); + }); + }); + }, + // 返回上一页 goBack() { wx.navigateBack(); diff --git a/pages/goods-detail/goods-detail.wxml b/pages/goods-detail/goods-detail.wxml index cee2680..d2c75e8 100644 --- a/pages/goods-detail/goods-detail.wxml +++ b/pages/goods-detail/goods-detail.wxml @@ -145,7 +145,7 @@