// pages/profile/index.js Page({ data: { userInfo: {}, userType: '', userTags: [], needPhoneAuth: false // 是否需要重新授权手机号 }, onLoad() { this.loadUserInfo() }, onShow() { this.loadUserInfo() // 更新自定义tabBar状态 if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ selected: 3 }); } // 更新全局tab状态 const app = getApp(); app.updateCurrentTab('profile'); }, // 加载用户信息 loadUserInfo() { console.log('开始加载用户信息') const app = getApp() // 从本地存储获取用户信息 const localUserInfo = wx.getStorageSync('userInfo') || {} if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo }) } else { app.globalData.userInfo = localUserInfo this.setData({ userInfo: localUserInfo, needPhoneAuth: !localUserInfo.phoneNumber }) } // 加载用户类型和标签 const userId = wx.getStorageSync('userId') const openid = wx.getStorageSync('openid') console.log('加载用户信息 - userId:', userId, 'openid:', openid ? '已获取' : '未获取') if (userId && openid) { // 从服务器获取最新的用户信息,确保手机号是最新的 this.refreshUserInfoFromServer(openid, userId) // 确保users存储结构存在 let users = wx.getStorageSync('users') if (!users) { users = {} wx.setStorageSync('users', users) } if (!users[userId]) { users[userId] = { type: '' } wx.setStorageSync('users', users) } const user = users[userId] const currentType = this.formatUserType(user.type) this.setData({ userType: currentType }) console.log('加载用户信息 - 当前用户类型:', currentType) // 确保tags存储结构存在 let tags = wx.getStorageSync('tags') if (!tags) { tags = {} wx.setStorageSync('tags', tags) } if (!tags[userId]) { tags[userId] = [] wx.setStorageSync('tags', tags) } const userTags = tags[userId] || [] console.log('加载用户信息 - 原始标签:', userTags) // 使用indexOf替代includes以解决Babel兼容性问题 let firstCategoryTag = [] let identityTags = [] // 查找第一个偏好品类标签 for (let i = 0; i < userTags.length; i++) { if (userTags[i].indexOf('偏好品类') !== -1) { firstCategoryTag = [userTags[i]] break } } // 合并保留的标签 let filteredTags = [...firstCategoryTag] // 始终根据当前用户类型显示对应的身份标签,而不是使用存储的标签 if (user.type && user.type !== '') { let identityLabel = '身份:not_set' switch (user.type) { case 'buyer': identityLabel = '身份:buyer'; break case 'seller': identityLabel = '身份:seller'; break case 'both': identityLabel = '身份:buyer+seller'; break } filteredTags.push(identityLabel) console.log('加载用户信息 - 根据当前用户类型显示身份标签:', identityLabel) } else { // 如果没有用户类型,但有存储的身份标签,显示第一个 for (let i = 0; i < userTags.length; i++) { if (userTags[i].indexOf('身份') !== -1) { filteredTags.push(userTags[i]) console.log('加载用户信息 - 显示存储的身份标签:', userTags[i]) break } } } console.log('加载用户信息 - 过滤后的标签:', filteredTags) this.setData({ userTags: filteredTags }) } }, // 从服务器刷新用户信息 refreshUserInfoFromServer(openid, userId) { const API = require('../../utils/api.js') API.getUserInfo(openid).then(res => { console.log('从服务器获取用户信息成功:', res) if (res.success && res.data) { const serverUserInfo = res.data // 更新本地用户信息 const app = getApp() const updatedUserInfo = { ...app.globalData.userInfo, ...serverUserInfo } app.globalData.userInfo = updatedUserInfo wx.setStorageSync('userInfo', updatedUserInfo) this.setData({ userInfo: updatedUserInfo }) console.log('用户信息已更新,昵称:', updatedUserInfo.nickName, '手机号:', updatedUserInfo.phoneNumber) } }).catch(err => { console.error('从服务器获取用户信息失败:', err) // 如果getUserInfo失败,尝试使用validateUserLogin作为备选 API.validateUserLogin().then(res => { console.log('使用validateUserLogin获取用户信息成功:', res) if (res.success && res.data) { const serverUserInfo = res.data // 更新本地用户信息 const app = getApp() const updatedUserInfo = { ...app.globalData.userInfo, ...serverUserInfo } app.globalData.userInfo = updatedUserInfo wx.setStorageSync('userInfo', updatedUserInfo) this.setData({ userInfo: updatedUserInfo }) console.log('用户信息已更新(备选方案):', updatedUserInfo) } }).catch(validateErr => { console.error('从服务器获取用户信息失败(包括备选方案):', validateErr) // 如果服务器请求失败,继续使用本地缓存的信息 }) }) }, // 格式化用户类型显示 formatUserType(type) { switch (type) { case 'buyer': return '买家' case 'seller': return '卖家' case 'both': return '买家+卖家' default: return '未设置' } }, // 设置为买家 setAsBuyer() { this.switchUserType('buyer', '买家') }, // 设置为卖家 setAsSeller() { this.switchUserType('seller', '卖家') }, // 切换用户类型的通用方法 switchUserType(newType, typeName) { const userId = wx.getStorageSync('userId') const openid = wx.getStorageSync('openid') const userInfo = wx.getStorageSync('userInfo') if (!userId || !openid) { wx.navigateTo({ url: '/pages/index/index' }) return } // 更新本地存储中的用户类型 let users = wx.getStorageSync('users') || {} if (!users[userId]) { users[userId] = {} } users[userId].type = newType wx.setStorageSync('users', users) // 更新全局数据 const app = getApp() app.globalData.userType = newType // 上传更新后的用户信息到服务器 this.uploadUserTypeToServer(openid, userId, userInfo, newType) // 更新页面显示 this.setData({ userType: this.formatUserType(newType) }) wx.showToast({ title: `已切换为${typeName}`, icon: 'success', duration: 2000 }) }, // 上传用户类型到服务器 uploadUserTypeToServer(openid, userId, userInfo, type) { // 引入API服务 const API = require('../../utils/api.js') // 构造上传数据 const uploadData = { userId: userId, openid: openid, ...userInfo, type: type, timestamp: Date.now() } // 调用API上传用户信息 API.uploadUserInfo(uploadData).then(res => { console.log('用户类型更新成功:', res) }).catch(err => { console.error('用户类型更新失败:', err) wx.showToast({ title: '身份更新失败,请重试', icon: 'none', duration: 2000 }) }) }, // 处理手机号授权结果 onPhoneNumberResult(e) { console.log('手机号授权结果:', e) // 首先检查用户是否拒绝授权 if (e.detail.errMsg !== 'getPhoneNumber:ok') { console.log('用户拒绝授权手机号') wx.showToast({ title: '您已拒绝授权,操作已取消', icon: 'none' }) // 直接返回,取消所有后续操作 return } // 用户同意授权,继续执行后续操作 // 检查是否有openid,如果没有则先登录 const openid = wx.getStorageSync('openid') if (!openid) { console.log('未登录,执行登录流程') // 显示登录loading提示 wx.showLoading({ title: '登录中...' }) // 调用微信登录接口 wx.login({ success: loginRes => { if (loginRes.code) { // 引入API服务 const API = require('../../utils/api.js') // 获取openid API.getOpenid(loginRes.code) .then(openidRes => { wx.hideLoading() console.log('获取openid响应:', openidRes) // 增强版响应处理逻辑,支持多种返回格式 let openid = null; let userId = null; let sessionKey = null; // 优先从data字段获取数据 if (openidRes && openidRes.data && typeof openidRes.data === 'object') { openid = openidRes.data.openid || openidRes.data.OpenID || null; userId = openidRes.data.userId || openidRes.data.userid || null; sessionKey = openidRes.data.session_key || openidRes.data.sessionKey || null; } // 如果data为空或不存在,尝试从响应对象直接获取 if (!openid && openidRes && typeof openidRes === 'object') { console.warn('服务器返回格式可能不符合预期,data字段为空或不存在,但尝试从根对象提取信息:', openidRes); openid = openidRes.openid || openidRes.OpenID || null; userId = openidRes.userId || openidRes.userid || null; sessionKey = openidRes.session_key || openidRes.sessionKey || null; } // 检查服务器状态信息 const isSuccess = openidRes && (openidRes.success === true || openidRes.code === 200); if (openid) { // 存储openid和session_key wx.setStorageSync('openid', openid) if (sessionKey) { wx.setStorageSync('sessionKey', sessionKey) } // 如果有userId,也存储起来 if (userId) { wx.setStorageSync('userId', userId) } console.log('获取openid成功并存储:', openid) // 登录成功,显示提示并重新加载页面 wx.showToast({ title: '登录成功', icon: 'none' }) // 在登录成功后重新加载页面 wx.reLaunch({ url: '/pages/profile/index' }) } else { console.error('获取openid失败,响应数据:', openidRes) wx.showToast({ title: '登录失败,请重试', icon: 'none' }) } }) .catch(err => { wx.hideLoading() console.error('获取openid失败:', err) wx.showToast({ title: '登录失败,请重试', icon: 'none' }) }) } else { wx.hideLoading() console.error('微信登录失败:', loginRes) wx.showToast({ title: '登录失败,请重试', icon: 'none' }) } }, fail: err => { wx.hideLoading() console.error('wx.login失败:', err) wx.showToast({ title: '获取登录状态失败,操作已取消', icon: 'none' }) } }) return } // 已登录且用户同意授权,获取加密数据 const phoneData = e.detail wx.showLoading({ title: '获取手机号中...' }) // 引入API服务 const API = require('../../utils/api.js') // 上传到服务器解密 API.uploadPhoneNumberData(phoneData) .then(res => { wx.hideLoading() if (res.success) { console.log('获取手机号结果:', res) // 检查是否有手机号冲突 const hasPhoneConflict = res.phoneNumberConflict || false const isNewPhone = res.isNewPhone || true const phoneNumber = res.phoneNumber || null // 如果有手机号冲突,直接提示用户 if (hasPhoneConflict) { wx.showToast({ title: '手机号已被其他账号绑定,请更换账号后重试', icon: 'none', duration: 3000 }) } else if (phoneNumber) { // 保存手机号到用户信息 const app = getApp() const userInfo = app.globalData.userInfo || wx.getStorageSync('userInfo') || {} userInfo.phoneNumber = phoneNumber // 更新本地和全局用户信息 app.globalData.userInfo = userInfo wx.setStorageSync('userInfo', userInfo) // 获取userId const userId = wx.getStorageSync('userId') const users = wx.getStorageSync('users') || {} const currentUserType = users[userId] && users[userId].type ? users[userId].type : '' // 同时更新服务器用户信息 this.uploadUserInfoToServer(userInfo, userId, currentUserType) // 更新页面状态 this.setData({ needPhoneAuth: false }) // 重新加载用户信息以更新UI this.loadUserInfo() wx.showToast({ title: '手机号绑定成功', icon: 'success' }) } else { console.error('获取手机号失败:', res) wx.showToast({ title: '获取手机号失败', icon: 'none' }) } } }) .catch(err => { wx.hideLoading() console.error('获取手机号失败:', err) wx.showToast({ title: '获取手机号失败', icon: 'none' }) }) }, // 上传用户信息到服务器 uploadUserInfoToServer(userInfo, userId, type) { // 返回Promise以便调用者可以进行错误处理 return new Promise((resolve, reject) => { try { // 引入API服务 const API = require('../../utils/api.js') // 获取openid const openid = wx.getStorageSync('openid') // 验证必要参数 if (!userId || !openid) { const error = new Error('缺少必要的用户信息'); console.error('用户信息上传失败:', error); reject(error); return; } // 构造上传数据(包含所有必要字段,包括phoneNumber) const uploadData = { userId: userId, openid: openid, nickName: userInfo.nickName, phoneNumber: userInfo.phoneNumber, // 添加phoneNumber字段,满足服务器要求 type: type, timestamp: Date.now() } // 调用API上传用户信息 API.uploadUserInfo(uploadData).then(res => { console.log('用户信息上传成功:', res) resolve(res); }).catch(err => { console.error('用户信息上传失败:', err) reject(err); }) } catch (error) { console.error('上传用户信息时发生异常:', error); reject(error); } }); }, // 修改用户名称 onEditNickName() { const currentName = this.data.userInfo.nickName || '未登录'; wx.showModal({ title: '修改用户名称', editable: true, placeholderText: '请输入新的名称最多10个字符', confirmText: '确认', cancelText: '取消', success: (res) => { if (res.confirm) { // 移除首尾空格并过滤多余空格 let newName = res.content.trim(); newName = newName.replace(/\s+/g, ' '); // 验证昵称不能为空 if (!newName) { wx.showToast({ title: '名称不能为空', icon: 'none', duration: 2000 }); return; } // 验证昵称长度 if (newName.length > 10) { wx.showToast({ title: '名称长度不能超过10个字符', icon: 'none', duration: 2000 }); return; } // 检查名称是否变化 if (newName === currentName) { wx.showToast({ title: '名称未变化', icon: 'none', duration: 2000 }); return; } // 显示加载提示 wx.showLoading({ title: '正在更新...', mask: true }); // 更新用户信息 this.updateNickName(newName).finally(() => { // 无论成功失败,都隐藏加载提示 wx.hideLoading(); }); } } }); }, // 更新用户名称 updateNickName(newName) { return new Promise((resolve, reject) => { try { // 更新本地和全局用户信息 const app = getApp(); const updatedUserInfo = { ...this.data.userInfo, nickName: newName }; // 保存到本地存储和全局状态 app.globalData.userInfo = updatedUserInfo; wx.setStorageSync('userInfo', updatedUserInfo); // 更新页面显示 this.setData({ userInfo: updatedUserInfo }); // 更新服务器信息 const userId = wx.getStorageSync('userId'); const currentUserType = this.data.userType; // 如果有用户ID,则上传到服务器 if (userId) { // 使用Promise链处理上传 this.uploadUserInfoToServer(updatedUserInfo, userId, currentUserType) .then(() => { wx.showToast({ title: '名称修改成功', icon: 'success', duration: 2000 }); resolve(); }) .catch((err) => { console.error('服务器同步失败,但本地已更新:', err); // 即使服务器同步失败,本地也已成功更新 wx.showToast({ title: '本地更新成功,服务器同步稍后进行', icon: 'none', duration: 3000 }); resolve(); // 即使服务器失败,也视为成功,因为本地已经更新 }); } else { // 没有用户ID,只更新本地 console.warn('没有用户ID,仅更新本地用户名称'); wx.showToast({ title: '名称修改成功', icon: 'success', duration: 2000 }); resolve(); } } catch (error) { console.error('更新用户名称失败:', error); wx.showToast({ title: '更新失败,请稍后重试', icon: 'none', duration: 2000 }); reject(error); } }); }, })