Browse Source

Add login verification and partnerstatus check for evaluate2/one page

pull/18/head
徐飞洋 1 month ago
parent
commit
b6733d27d2
  1. 347
      pages/evaluate2/one.js
  2. 23
      pages/evaluate2/one.wxml
  3. 92
      pages/evaluate2/one.wxss

347
pages/evaluate2/one.js

@ -5,7 +5,8 @@ Page({
loading: false, loading: false,
error: '', error: '',
categories: [], categories: [],
selectedCategory: '' selectedCategory: '',
showOneKeyLoginModal: false // 是否显示登录弹窗
}, },
onLoad(options) { onLoad(options) {
let productName = ''; let productName = '';
@ -455,9 +456,353 @@ Page({
const category = e.currentTarget.dataset.category; const category = e.currentTarget.dataset.category;
console.log('选择分类:', category); console.log('选择分类:', category);
// 检查用户登录状态
const openid = wx.getStorageSync('openid');
const userId = wx.getStorageSync('userId');
if (!openid || !userId) {
// 用户未登录,显示登录弹窗
console.log('用户未登录,显示登录弹窗');
this.setData({
showOneKeyLoginModal: true
});
return;
}
// 检查用户合作状态
const userInfo = wx.getStorageSync('userInfo') || {};
const partnerStatus = userInfo.partnerstatus || '';
if (partnerStatus !== 'approved') {
// 合作状态未批准,显示提示
wx.showModal({
title: '提示',
content: '需要入住成功才能查看',
confirmText: '立即入驻',
success: function(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/profile/authentication/index'
});
}
}
});
return;
}
// 跳转到商品列表页面,并传递分类参数 // 跳转到商品列表页面,并传递分类参数
wx.redirectTo({ wx.redirectTo({
url: `/pages/evaluate2/product-list?category=${encodeURIComponent(category)}` url: `/pages/evaluate2/product-list?category=${encodeURIComponent(category)}`
}); });
},
// 关闭登录弹窗
closeOneKeyLoginModal() {
this.setData({
showOneKeyLoginModal: false
});
},
// 处理登录授权
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 API = require('../../utils/api');
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('用户点击了我知道了');
}
}
});
}
// 1. 登录成功提示
wx.showToast({
title: '登录成功',
icon: 'success',
duration: 1500
});
// 2. 从服务器获取最新用户信息
const userInfoRes = await API.getUserInfo(openid);
// 3. 获取服务器返回的partnerstatus
const serverUserInfo = userInfoRes.data;
const partnerStatus = serverUserInfo.partnerstatus || 'pending';
// 4. 更新本地缓存
const localUserInfo = wx.getStorageSync('userInfo') || {};
const updatedUserInfo = {
...localUserInfo,
partnerstatus: partnerStatus
};
wx.setStorageSync('userInfo', updatedUserInfo);
// 5. 检查partnerstatus值
if (partnerStatus !== 'approved') {
// 显示入驻提示
setTimeout(() => {
wx.showModal({
title: '提示',
content: '需要入住成功才能查看',
confirmText: '立即入驻',
success: function(res) {
if (res.confirm) {
wx.navigateTo({
url: '/pages/profile/authentication/index'
});
}
}
});
}, 2000);
}
}
} catch (error) {
wx.hideLoading();
console.error('登录失败:', error);
wx.showToast({
title: '登录失败,请重试',
icon: 'none',
duration: 2000
});
}
},
// 保存用户信息
async saveUserInfo(userInfo, userType = 'buyer') {
return new Promise(async (resolve, reject) => {
try {
const storedUserId = wx.getStorageSync('userId');
const users = wx.getStorageSync('users') || {};
// 更新用户信息
users[storedUserId] = {
...users[storedUserId],
...userInfo,
type: userType,
lastLogin: new Date().toISOString()
};
// 保存到本地存储
wx.setStorageSync('users', users);
wx.setStorageSync('userInfo', userInfo);
// 上传用户信息到服务器
const API = require('../../utils/api');
const submitData = {
openid: wx.getStorageSync('openid'),
userId: storedUserId,
...userInfo,
type: userType
};
await API.request('/api/user/update', 'POST', submitData).then(res => {
console.log('用户信息上传成功:', res);
resolve({ success: true, message: '用户信息保存成功' });
}).catch(err => {
console.error('用户信息上传失败:', err);
// 即使服务器上传失败,也继续流程,只在本地保存
resolve({ success: false, message: '本地保存成功,服务器同步失败' });
});
} catch (error) {
console.error('保存用户信息失败:', error);
reject(error);
}
});
} }
}); });

23
pages/evaluate2/one.wxml

@ -6,6 +6,29 @@
</view> </view>
</view> </view>
<!-- 登录弹窗 -->
<view wx:if="{{showOneKeyLoginModal}}" class="auth-modal-overlay">
<view class="auth-modal-container">
<view class="auth-modal-title">授权登录</view>
<view class="auth-modal-content">授权您的手机号后才能使用完整功能</view>
<view class="auth-modal-buttons">
<button
class="auth-primary-button"
open-type="getPhoneNumber"
bindgetphonenumber="onGetPhoneNumber"
>
授权手机号
</button>
<button
class="auth-cancel-button"
bindtap="closeOneKeyLoginModal"
>
取消
</button>
</view>
</view>
</view>
<view class="content" style="width: 600rpx; display: block; box-sizing: border-box"> <view class="content" style="width: 600rpx; display: block; box-sizing: border-box">
<!-- 加载中状态 --> <!-- 加载中状态 -->
<view wx:if="{{loading}}" class="loading"> <view wx:if="{{loading}}" class="loading">

92
pages/evaluate2/one.wxss

@ -558,3 +558,95 @@
.spec-section { .spec-section {
margin-bottom: 40rpx; margin-bottom: 40rpx;
} }
/* 登录弹窗样式 */
.auth-modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.auth-modal-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20rpx;
padding: 48rpx;
width: 80%;
max-width: 500rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
backdrop-filter: blur(12rpx);
border: 1rpx solid rgba(255, 255, 255, 0.3);
}
.auth-modal-title {
font-size: 36rpx;
font-weight: 700;
text-align: center;
margin-bottom: 24rpx;
color: #2c3e50;
letter-spacing: 2rpx;
}
.auth-modal-content {
font-size: 28rpx;
text-align: center;
margin-bottom: 48rpx;
color: #666;
line-height: 1.5;
padding: 0 20rpx;
}
.auth-modal-buttons {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.auth-primary-button {
background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%);
color: white;
border: none;
border-radius: 12rpx;
padding: 24rpx;
font-size: 30rpx;
font-weight: 700;
min-height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(96, 165, 250, 0.4);
transition: all 0.3s ease;
}
.auth-primary-button:hover {
transform: translateY(-2rpx);
box-shadow: 0 8rpx 24rpx rgba(96, 165, 250, 0.6);
}
.auth-cancel-button {
background: rgba(255, 255, 255, 0.9);
color: #2c3e50;
border: 2rpx solid #e2e8f0;
border-radius: 12rpx;
padding: 24rpx;
font-size: 28rpx;
font-weight: 600;
min-height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}
.auth-cancel-button:hover {
background: rgba(236, 240, 241, 0.8);
transform: translateY(-2rpx);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
Loading…
Cancel
Save