|
|
@ -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() { |
|
|
goBack() { |
|
|
wx.navigateBack(); |
|
|
wx.navigateBack(); |
|
|
|