You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1503 lines
49 KiB

// pages/profile/index.js
Page({
// 分享给朋友/群聊
onShareAppMessage() {
return {
title: '鸡蛋贸易平台 - 个人中心,查看我的信息',
path: '/pages/profile/index',
imageUrl: '/images/你有好蛋.png'
}
},
// 分享到朋友圈
onShareTimeline() {
return {
title: '鸡蛋贸易平台 - 个人中心,查看我的信息',
query: '',
imageUrl: '/images/你有好蛋.png'
}
},
data: {
userInfo: {},
userType: '',
userTags: [],
needPhoneAuth: false, // 是否需要重新授权手机号
locationInfo: '', // 位置信息
hasLocationAuth: false, // 是否已经授权位置
isInPersonnel: false, // 用户手机号是否在personnel表中
currentAvatarIndex: 0, // 当前显示的头像索引,默认显示第一张
rawAvatarUrl: null, // 存储原始的头像URL数据(可能是数组)
// 固定的头像URL数组
avatarUrls: [
"https://my-supplier-photos.oss-cn-chengdu.aliyuncs.com/products/%E6%B5%B7%E8%93%9D%E7%81%B0/image/7a2a8a17a83ba4d3d4270828531e2041.jpeg",
"https://my-supplier-photos.oss-cn-chengdu.aliyuncs.com/products/%E4%BC%8A%E8%8E%8E%E7%B2%89/image/1b2a0ba28eaa17c16c3674985ccee05c.jpeg"
]
},
onLoad() {
this.loadUserInfo();
this.checkLocationAuth();
},
onShow() {
this.loadUserInfo();
this.checkLocationAuth();
// 更新自定义tabBar状态
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
this.getTabBar().setData({
selected: 4
});
}
// 更新全局tab状态
const app = getApp();
app.updateCurrentTab('profile');
},
// 隐藏电话号码中间4位
hidePhoneNumber(phoneNumber) {
if (!phoneNumber) return ''
const phoneStr = String(phoneNumber)
if (phoneStr.length !== 11) return phoneStr
return phoneStr.substring(0, 3) + '****' + phoneStr.substring(7)
},
// 处理头像URL,确保正确解析数组形式的OSS URL
processAvatarUrl(avatarUrl) {
if (!avatarUrl) {
return 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0';
}
// 如果是字符串,尝试解析为JSON数组
if (typeof avatarUrl === 'string') {
// 去除字符串两端的空格和引号
let cleanedUrl = avatarUrl.trim();
// 去除可能存在的前后引号
if ((cleanedUrl.startsWith('"') && cleanedUrl.endsWith('"')) ||
(cleanedUrl.startsWith('`') && cleanedUrl.endsWith('`'))) {
cleanedUrl = cleanedUrl.substring(1, cleanedUrl.length - 1);
}
try {
const parsedUrl = JSON.parse(cleanedUrl);
// 如果解析成功且是数组且不为空,使用第一个元素
if (Array.isArray(parsedUrl) && parsedUrl.length > 0) {
// 清理第一个元素中的空格和引号
let firstUrl = parsedUrl[0];
if (typeof firstUrl === 'string') {
firstUrl = firstUrl.trim();
if ((firstUrl.startsWith('"') && firstUrl.endsWith('"')) ||
(firstUrl.startsWith('`') && firstUrl.endsWith('`'))) {
firstUrl = firstUrl.substring(1, firstUrl.length - 1);
}
}
return firstUrl;
}
// 如果解析成功但不是数组,直接返回清理后的URL
return cleanedUrl;
} catch (e) {
// 解析失败,返回清理后的URL
return cleanedUrl;
}
}
// 如果是数组且不为空,使用第一个元素
if (Array.isArray(avatarUrl) && avatarUrl.length > 0) {
let firstUrl = avatarUrl[0];
if (typeof firstUrl === 'string') {
// 清理第一个元素中的空格和引号
firstUrl = firstUrl.trim();
if ((firstUrl.startsWith('"') && firstUrl.endsWith('"')) ||
(firstUrl.startsWith('`') && firstUrl.endsWith('`'))) {
firstUrl = firstUrl.substring(1, firstUrl.length - 1);
}
}
return firstUrl;
}
// 其他情况返回默认头像
return 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0';
},
// 加载用户信息
loadUserInfo() {
console.log('开始加载用户信息')
const app = getApp()
// 从本地存储获取用户信息
const localUserInfo = wx.getStorageSync('userInfo') || {}
if (app.globalData.userInfo) {
const userInfo = { ...app.globalData.userInfo }
// 使用固定的头像URL数组
const avatarUrls = this.data.avatarUrls;
// 保持用户当前的头像URL,如果没有则使用第一张作为默认
if (!userInfo.avatarUrl) {
userInfo.avatarUrl = avatarUrls[0];
}
userInfo.hiddenPhoneNumber = this.hidePhoneNumber(userInfo.phoneNumber)
// 根据当前的avatarUrl更新currentAvatarIndex
let currentAvatarIndex = 0;
if (userInfo.avatarUrl) {
const index = avatarUrls.indexOf(userInfo.avatarUrl);
if (index !== -1) {
currentAvatarIndex = index;
}
}
this.setData({
userInfo,
rawAvatarUrl: avatarUrls,
currentAvatarIndex: currentAvatarIndex
})
// 更新全局状态中的头像URL,确保下次加载时使用处理后的URL
app.globalData.userInfo = userInfo;
wx.setStorageSync('userInfo', userInfo);
} else {
const userInfo = { ...localUserInfo }
// 使用固定的头像URL数组
const avatarUrls = this.data.avatarUrls;
// 保持用户当前的头像URL,如果没有则使用第一张作为默认
if (!userInfo.avatarUrl) {
userInfo.avatarUrl = avatarUrls[0];
}
userInfo.hiddenPhoneNumber = this.hidePhoneNumber(userInfo.phoneNumber)
// 根据当前的avatarUrl更新currentAvatarIndex
let currentAvatarIndex = 0;
if (userInfo.avatarUrl) {
const index = avatarUrls.indexOf(userInfo.avatarUrl);
if (index !== -1) {
currentAvatarIndex = index;
}
}
app.globalData.userInfo = userInfo
wx.setStorageSync('userInfo', userInfo);
this.setData({
userInfo,
needPhoneAuth: !userInfo.phoneNumber,
rawAvatarUrl: avatarUrls,
currentAvatarIndex: currentAvatarIndex
})
}
// 加载用户类型和标签
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)
// 先使用本地存储的用户类型更新标签,后续会被服务器返回的最新值覆盖
this.updateUserTags(userId, user.type)
}
// 检查用户手机号是否在personnel表中
this.checkPhoneInPersonnel()
},
// 检查用户手机号是否在personnel表中
checkPhoneInPersonnel() {
const userInfo = this.data.userInfo
const phoneNumber = userInfo.phoneNumber
if (!phoneNumber) {
this.setData({ isInPersonnel: false })
return
}
console.log('开始检查手机号是否在personnel表中:', phoneNumber)
// 引入API服务
const API = require('../../utils/api.js')
API.checkPhoneInPersonnel(phoneNumber).then(isInPersonnel => {
console.log('用户手机号是否在personnel表中:', isInPersonnel)
this.setData({ isInPersonnel })
}).catch(err => {
console.error('检查personnel表失败:', err)
this.setData({ isInPersonnel: false })
})
},
// 更新用户标签
updateUserTags(userId, userType) {
// 确保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 = []
// 查找第一个偏好品类标签
for (let i = 0; i < userTags.length; i++) {
if (userTags[i].indexOf('偏好品类') !== -1) {
firstCategoryTag = [userTags[i]]
break
}
}
// 合并保留的标签
let filteredTags = [...firstCategoryTag]
// 始终根据当前用户类型显示对应的身份标签
if (userType && userType !== '') {
let identityLabel = '身份:not_set'
switch (userType) {
case 'buyer': identityLabel = '身份:买家'; break
case 'seller': identityLabel = '身份:卖家'; break
}
filteredTags.push(identityLabel)
console.log('加载用户信息 - 根据当前用户类型显示身份标签:', identityLabel)
}
console.log('加载用户信息 - 过滤后的标签:', filteredTags)
this.setData({ userTags: filteredTags })
},
// 从服务器刷新用户信息并同步身份数据
refreshUserInfoFromServer(openid, userId) {
const API = require('../../utils/api.js')
API.getUserInfo(openid).then(res => {
console.log('从服务器获取用户信息成功:', res)
console.log('服务器返回的完整数据:', JSON.stringify(res))
if (res.success && res.data) {
const serverUserInfo = res.data
console.log('服务器返回的用户信息:', JSON.stringify(serverUserInfo))
console.log('是否包含idcardstatus:', 'idcardstatus' in serverUserInfo)
console.log('是否包含reason:', 'reason' in serverUserInfo)
// 更新本地用户信息
const app = getApp()
// 先保存当前的头像URL
const currentAvatarUrl = app.globalData.userInfo.avatarUrl;
// 构建更新后的用户信息,优先使用服务器返回的值
const updatedUserInfo = {
...app.globalData.userInfo,
...serverUserInfo
}
// 使用固定的头像URL数组
const avatarUrls = this.data.avatarUrls;
// 检查服务器返回的用户信息中是否包含avatarUrl
let finalAvatarUrl = updatedUserInfo.avatarUrl;
// 如果服务器返回的avatarUrl为空字符串或null,且本地有,则使用本地的
if ((!finalAvatarUrl || finalAvatarUrl === '') && currentAvatarUrl) {
finalAvatarUrl = currentAvatarUrl;
}
// 如果两者都没有,则使用第一张作为默认
else if (!finalAvatarUrl || finalAvatarUrl === '') {
finalAvatarUrl = avatarUrls[0];
}
// 更新头像URL
updatedUserInfo.avatarUrl = finalAvatarUrl;
// 添加隐藏的电话号码
updatedUserInfo.hiddenPhoneNumber = this.hidePhoneNumber(updatedUserInfo.phoneNumber)
app.globalData.userInfo = updatedUserInfo
wx.setStorageSync('userInfo', updatedUserInfo)
this.setData({
userInfo: updatedUserInfo,
rawAvatarUrl: avatarUrls
})
// 检查服务器返回的用户信息是否包含位置信息
if (serverUserInfo.address) {
// 更新位置信息
this.setData({ locationInfo: serverUserInfo.address });
wx.setStorageSync('locationInfo', serverUserInfo.address);
console.log('从服务器获取位置信息:', serverUserInfo.address);
}
// 同步更新用户身份信息(当前身份由数据库决定)
if (serverUserInfo.type) {
this.syncUserTypeFromServer(userId, serverUserInfo.type)
}
// 重新检查用户手机号是否在personnel表中
this.checkPhoneInPersonnel()
console.log('用户信息已更新,昵称:', updatedUserInfo.name, '手机号:', updatedUserInfo.phoneNumber, '身份:', serverUserInfo.type, '头像URL:', finalAvatarUrl)
}
}).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()
// 先保存当前的头像URL
const currentAvatarUrl = app.globalData.userInfo.avatarUrl;
const updatedUserInfo = {
...app.globalData.userInfo,
...serverUserInfo
}
// 使用固定的头像URL数组
const avatarUrls = this.data.avatarUrls;
// 检查服务器返回的用户信息中是否包含avatarUrl
let finalAvatarUrl = updatedUserInfo.avatarUrl;
// 如果服务器返回的avatarUrl为空字符串或null,且本地有,则使用本地的
if ((!finalAvatarUrl || finalAvatarUrl === '') && currentAvatarUrl) {
finalAvatarUrl = currentAvatarUrl;
}
// 如果两者都没有,则使用第一张作为默认
else if (!finalAvatarUrl || finalAvatarUrl === '') {
finalAvatarUrl = avatarUrls[0];
}
// 更新头像URL
updatedUserInfo.avatarUrl = finalAvatarUrl;
// 添加隐藏的电话号码
updatedUserInfo.hiddenPhoneNumber = this.hidePhoneNumber(updatedUserInfo.phoneNumber)
app.globalData.userInfo = updatedUserInfo
wx.setStorageSync('userInfo', updatedUserInfo)
this.setData({
userInfo: updatedUserInfo,
rawAvatarUrl: avatarUrls
})
// 检查服务器返回的用户信息是否包含位置信息
if (serverUserInfo.address) {
// 更新位置信息
this.setData({ locationInfo: serverUserInfo.address });
wx.setStorageSync('locationInfo', serverUserInfo.address);
console.log('从服务器(备选方案)获取位置信息:', serverUserInfo.address);
}
// 同步更新用户身份信息(当前身份由数据库决定)
if (serverUserInfo.type) {
this.syncUserTypeFromServer(userId, serverUserInfo.type)
}
// 重新检查用户手机号是否在personnel表中
this.checkPhoneInPersonnel()
console.log('用户信息已更新(备选方案):', updatedUserInfo, '头像URL:', finalAvatarUrl)
}
}).catch(validateErr => {
console.error('从服务器获取用户信息失败(包括备选方案):', validateErr)
// 如果服务器请求失败,继续使用本地缓存的信息
})
})
},
// 从服务器同步用户身份信息
syncUserTypeFromServer(userId, serverType) {
if (!userId || !serverType) {
console.error('同步用户身份信息失败: 参数不完整')
return
}
console.log('从服务器同步用户身份信息:', { userId, serverType })
// 更新本地存储的用户身份
let users = wx.getStorageSync('users') || {}
if (!users[userId]) {
users[userId] = {}
}
// 如果当前类型是 Colleague,直接返回,不允许从服务器同步覆盖
if (users[userId].type === 'Colleague') {
console.log('当前用户是 Colleague 类型,不允许从服务器同步覆盖用户类型')
return
}
// 移除serverType中的customer(如果存在)
let processedServerType = serverType.replace(/,?customer/g, '').replace(/^,|,$/g, '')
// 构建新的用户类型
let newUserType = processedServerType
// 只有当新构建的用户类型与本地不同时才更新
if (users[userId].type !== newUserType) {
users[userId].type = newUserType
wx.setStorageSync('users', users)
// 更新全局用户类型
const app = getApp()
app.globalData.userType = newUserType
// 更新页面显示的用户类型
this.setData({
userType: this.formatUserType(newUserType)
})
console.log('用户身份已从服务器同步并保留客服标识:', newUserType)
} else {
console.log('用户身份与服务器一致,无需更新:', newUserType)
}
// 更新用户标签,确保传入正确的参数
this.updateUserTags(userId, newUserType)
},
// 格式化用户类型显示
formatUserType(type) {
switch (type) {
case 'buyer': return '买家';
case 'seller': return '卖家';
case 'both': return '买卖家';
case 'buyer+seller': return '买卖家';
default: return type || 'not_set';
}
},
// 设置为买家
setAsBuyer() {
this.switchUserType('buyer', 'buyer')
},
// 设置为卖家
setAsSeller() {
this.switchUserType('seller', 'seller')
},
// 切换用户类型的通用方法
switchUserType(newType, typeName) {
const userId = wx.getStorageSync('userId')
const openid = wx.getStorageSync('openid')
if (!userId || !openid) {
wx.navigateTo({ url: '/pages/index/index' })
return
}
// 显示操作中的提示
wx.showLoading({ title: 'Switching...' })
// 引入API服务
const API = require('../../utils/api.js')
// 使用API更新用户类型,确保与服务器同步
API.updateUserType(newType).then(res => {
console.log('用户类型更新成功:', res)
// 更新页面显示
const app = getApp()
this.setData({
userType: this.formatUserType(app.globalData.userType)
})
// 更新用户标签
this.updateUserTags(userId, app.globalData.userType)
wx.showToast({
title: `Switched to ${typeName}`,
icon: 'success',
duration: 2000
})
}).catch(err => {
console.error('用户类型更新失败:', err)
wx.showToast({
title: 'Failed to switch, please retry',
icon: 'none',
duration: 2000
})
}).finally(() => {
wx.hideLoading()
})
},
// 上传用户类型到服务器
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
})
})
},
// 处理手机号授权结果
async onPhoneNumberResult(e) {
console.log('手机号授权结果:', e)
// 首先检查用户是否拒绝授权
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
console.log('用户拒绝授权手机号')
wx.showToast({
title: '您已拒绝授权,操作已取消',
icon: 'none'
})
// 直接返回,取消所有后续操作
return
}
wx.showLoading({
title: '登录中...',
mask: true
})
try {
// 引入API服务
const API = require('../../utils/api.js')
// 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;
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) {
throw new Error('获取openid失败: ' + (openidRes && openidRes.message ? openidRes.message : '未知错误'))
}
// 存储openid和session_key
wx.setStorageSync('openid', openid)
if (sessionKey) {
wx.setStorageSync('sessionKey', sessionKey)
}
// 确保始终使用从服务器获取的正式用户ID,不再生成临时ID
if (userId) {
wx.setStorageSync('userId', userId)
} else {
const app = getApp();
if (app.globalData.userInfo && app.globalData.userInfo.userId) {
const serverUserId = String(app.globalData.userInfo.userId);
wx.setStorageSync('userId', serverUserId);
userId = serverUserId;
console.log('使用从全局获取的正式用户ID:', serverUserId);
} else {
console.warn('未找到有效的用户ID,请确保用户已授权登录');
}
}
console.log('获取openid成功并存储:', openid)
// 3. 上传手机号加密数据到服务器解密
const phoneData = {
...e.detail,
openid: openid,
sessionKey: sessionKey || ''
}
console.log('准备上传手机号加密数据到服务器')
const phoneRes = await API.uploadPhoneNumberData(phoneData)
// 改进手机号解密结果的处理逻辑
if (!phoneRes || (!phoneRes.success && !phoneRes.phoneNumber)) {
// 如果服务器返回格式不标准但包含手机号,也接受
if (!(phoneRes && phoneRes.phoneNumber)) {
throw new Error('获取手机号失败: ' + (phoneRes && phoneRes.message ? phoneRes.message : '未知错误'))
}
}
// 检查是否有手机号冲突
const hasPhoneConflict = phoneRes.phoneNumberConflict || false
const isNewPhone = phoneRes.isNewPhone || true
const phoneNumber = phoneRes.phoneNumber || null
console.log('手机号解密结果:', {
phoneNumber: phoneNumber,
hasPhoneConflict: hasPhoneConflict,
isNewPhone: isNewPhone
})
// 4. 获取用户微信名称和头像
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);
// 如果获取失败,使用默认值
}
// 5. 创建用户信息
const app = getApp()
const existingUserInfo = app.globalData.userInfo || wx.getStorageSync('userInfo') || {}
const userInfo = {
// 优先使用最新获取的微信头像和昵称,如果没有获取到则使用本地存储的
name: (userProfile ? (userProfile.userInfo.name || userProfile.userInfo.nickName) : existingUserInfo.name) || '微信用户',
avatarUrl: (userProfile ? userProfile.userInfo.avatarUrl : existingUserInfo.avatarUrl) || 'https://my-supplier-photos.oss-cn-chengdu.aliyuncs.com/products/%E6%B5%B7%E8%93%9D%E7%81%B0/image/7a2a8a17a83ba4d3d4270828531e2041.jpeg',
gender: (userProfile ? userProfile.userInfo.gender : existingUserInfo.gender) || 0,
country: (userProfile ? userProfile.userInfo.country : existingUserInfo.country) || '',
province: (userProfile ? userProfile.userInfo.province : existingUserInfo.province) || '',
city: (userProfile ? userProfile.userInfo.city : existingUserInfo.city) || '',
language: (userProfile ? userProfile.userInfo.language : existingUserInfo.language) || 'zh_CN',
phoneNumber: phoneNumber
}
// 6. 获取用户类型
const users = wx.getStorageSync('users') || {}
let currentUserType = users[userId] && users[userId].type ? users[userId].type : ''
// 如果没有用户类型,尝试从全局获取
if (!currentUserType) {
currentUserType = app.globalData.userType || ''
}
// 7. 保存用户信息并等待上传完成
console.log('开始保存用户信息并上传到服务器...')
await this.uploadUserInfoToServer(userInfo, userId, currentUserType)
console.log('用户信息保存并上传完成')
// 更新本地和全局用户信息
app.globalData.userInfo = userInfo
wx.setStorageSync('userInfo', userInfo)
// 更新页面状态
this.setData({
needPhoneAuth: false,
userInfo: userInfo
})
// 重新加载用户信息以更新UI
this.loadUserInfo()
wx.hideLoading()
// 登录成功后检查位置授权状态,确保位置信息正确显示
this.checkLocationAuth();
// 根据服务器返回的结果显示不同的提示
if (hasPhoneConflict) {
wx.showModal({
title: '登录成功',
content: '您的手机号已被其他账号绑定',
showCancel: false,
confirmText: '我知道了',
success(res) {
if (res.confirm) {
console.log('用户点击了我知道了');
}
}
});
} else {
const that = this;
wx.showModal({
title: '登录成功',
content: '🥚 允许获取位置,为你优先展示附近新鲜鸡蛋供应商、自提门店及精准配送时效,无需手动填地址,位置信息仅用于优化购物体验,隐私有保障,放心开启~',
showCancel: true,
cancelText: '取消',
confirmText: '允许',
success(res) {
if (res.confirm) {
console.log('用户点击了允许');
// 调用位置授权函数
that.requestLocationAuth();
} else if (res.cancel) {
console.log('用户点击了取消');
// 关闭弹窗,不执行任何操作
}
}
});
}
} catch (error) {
wx.hideLoading()
console.error('登录过程中发生错误:', error)
// 更具体的错误提示
let errorMsg = '登录失败,请重试'
if (error.message.includes('网络')) {
errorMsg = '网络连接失败,请检查网络后重试'
} else if (error.message.includes('服务器')) {
errorMsg = '服务器连接失败,请稍后重试'
} else if (error.message.includes('openid')) {
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)
}
}
},
// 上传用户信息到服务器
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;
}
// 构造上传数据(不包含头像URL,避免登录时覆盖用户选择的头像)
const uploadData = {
userId: userId,
openid: openid,
name: userInfo.name,
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);
}
});
},
// 修改用户名称
onEditName() {
const currentName = this.data.userInfo.name || '未登录';
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.updateName(newName).finally(() => {
// 无论成功失败,都隐藏加载提示
wx.hideLoading();
});
}
}
});
},
// 检查位置授权状态
checkLocationAuth() {
const that = this;
// 检查用户是否登录
const userInfo = this.data.userInfo;
const isLoggedIn = userInfo && userInfo.phoneNumber;
if (!isLoggedIn) {
// 未登录状态,重置位置信息
that.setData({
hasLocationAuth: false,
locationInfo: ''
});
return;
}
wx.getSetting({
success(res) {
if (res.authSetting['scope.userLocation']) {
// 用户已经授权位置
that.setData({ hasLocationAuth: true });
// 从本地存储读取位置信息,不自动获取当前位置
const savedLocationInfo = wx.getStorageSync('locationInfo');
if (savedLocationInfo) {
that.setData({ locationInfo: savedLocationInfo });
}
} else {
// 用户未授权位置
that.setData({ hasLocationAuth: false });
}
}
});
},
// 请求位置授权
requestLocationAuth() {
const that = this;
wx.authorize({
scope: 'scope.userLocation',
success() {
// 授权成功
that.setData({ hasLocationAuth: true });
// 从本地存储读取位置信息,不自动获取当前位置
const savedLocationInfo = wx.getStorageSync('locationInfo');
if (savedLocationInfo) {
that.setData({ locationInfo: savedLocationInfo });
} else {
// 如果本地没有位置信息,再获取当前位置
that.getUserLocation();
}
},
fail() {
// 授权失败,弹出模态框引导用户重新授权
wx.showModal({
title: '需要位置授权',
content: '请在设置中开启位置授权,以便我们为您提供相关服务',
showCancel: true,
cancelText: '取消',
confirmText: '去授权',
success: (res) => {
if (res.confirm) {
// 打开设置页面让用户手动开启授权
wx.openSetting({
success: (settingRes) => {
if (settingRes.authSetting['scope.userLocation']) {
// 用户在设置中开启了位置授权
that.setData({ hasLocationAuth: true });
// 从本地存储读取位置信息,不自动获取当前位置
const savedLocationInfo = wx.getStorageSync('locationInfo');
if (savedLocationInfo) {
that.setData({ locationInfo: savedLocationInfo });
} else {
// 如果本地没有位置信息,再获取当前位置
that.getUserLocation();
}
} else {
// 用户在设置中仍未开启位置授权
that.setData({ hasLocationAuth: false });
wx.showToast({
title: '您已拒绝位置授权',
icon: 'none'
});
}
},
fail: () => {
that.setData({ hasLocationAuth: false });
wx.showToast({
title: '打开设置失败',
icon: 'none'
});
}
});
} else {
// 用户点击了取消
that.setData({ hasLocationAuth: false });
}
}
});
}
});
},
// 获取用户当前位置
getUserLocation() {
const that = this;
// 先检查位置授权状态
wx.getSetting({
success(res) {
if (res.authSetting['scope.userLocation']) {
// 用户已经授权位置
wx.showLoading({ title: '获取位置中...' });
wx.getLocation({
type: 'gcj02',
success(res) {
const latitude = res.latitude;
const longitude = res.longitude;
// 将位置信息存储到本地
wx.setStorageSync('userLocation', { latitude, longitude });
// 检查openid是否存在
let openid = wx.getStorageSync('openid');
if (!openid) {
// 尝试从用户信息中获取openid
const globalUserInfo = wx.getStorageSync('userInfo');
openid = globalUserInfo?.openid;
}
// 确保openid存在
if (!openid) {
console.error('位置上传失败: 未找到openid');
wx.hideLoading();
wx.showToast({
title: '位置上传失败,请先登录',
icon: 'none',
duration: 2000
});
return;
}
// 调用逆地理编码API获取详细地址,然后统一上传
that.reverseGeocode(latitude, longitude, openid);
},
fail() {
wx.hideLoading();
wx.showToast({
title: '获取位置失败',
icon: 'none'
});
}
});
} else {
// 用户未授权位置,调用请求授权函数
that.requestLocationAuth();
}
}
});
},
// 逆地理编码获取详细地址并上传到数据库
reverseGeocode(latitude, longitude, openid) {
const that = this;
wx.request({
url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77`,
success(res) {
wx.hideLoading();
if (res.data.status === 0) {
const address = res.data.result.address;
that.setData({ locationInfo: address });
// 将地址信息保存到本地存储
wx.setStorageSync('locationInfo', address);
// 保存地址信息到数据库
const api = require('../../utils/api.js');
const locationUpdateData = {
openid: openid,
latitude: latitude,
longitude: longitude,
address: address
};
console.log('保存地址到数据库:', locationUpdateData);
// 调用API保存地址信息
api.request('/api/user/update-location', 'POST', locationUpdateData)
.then(res => {
console.log('地址保存成功:', res);
// 显示上传成功提示
wx.showToast({
title: '位置更新成功',
icon: 'success',
duration: 1500
});
}).catch(err => {
console.error('地址保存失败:', err);
// 显示上传失败提示
wx.showToast({
title: '位置上传失败',
icon: 'none',
duration: 2000
});
});
} else {
wx.showToast({
title: '获取地址失败',
icon: 'none'
});
}
},
fail() {
wx.hideLoading();
wx.showToast({
title: '获取地址失败',
icon: 'none'
});
}
});
},
// 更新用户名称
updateName(newName) {
return new Promise((resolve, reject) => {
try {
// 更新本地和全局用户信息
const app = getApp();
const updatedUserInfo = {
...this.data.userInfo,
name: 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);
}
});
},
// 跳转到收藏页面
goToFavorites() {
wx.switchTab({
url: '/pages/favorites/index'
});
},
// 跳转到订单页面
goToOrders() {
wx.navigateTo({
url: '/pages/order/index'
});
},
// 跳转到货源管理页面
navigateToGoods() {
wx.navigateTo({
url: '/pages/goods/index'
});
},
// 退出登录
logout() {
wx.showModal({
title: '退出登录',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
// 保存位置信息,避免退出登录后丢失
const savedLocationInfo = wx.getStorageSync('locationInfo');
const savedUserLocation = wx.getStorageSync('userLocation');
// 清除本地缓存
wx.clearStorageSync();
// 恢复位置信息
if (savedLocationInfo) {
wx.setStorageSync('locationInfo', savedLocationInfo);
}
if (savedUserLocation) {
wx.setStorageSync('userLocation', savedUserLocation);
}
// 重置全局用户信息
const app = getApp();
app.globalData.userInfo = {};
app.globalData.userType = '';
// 重新加载页面
this.setData({
userInfo: {},
userType: '',
userTags: [],
needPhoneAuth: true,
locationInfo: '',
hasLocationAuth: false,
isInPersonnel: false
});
wx.showToast({
title: '退出登录成功',
icon: 'success',
duration: 2000
});
}
}
});
},
// 手动选择位置
chooseLocation() {
const that = this;
wx.chooseLocation({
success(res) {
console.log('用户选择的位置信息:', res);
const name = res.name;
const address = res.address;
const latitude = res.latitude;
const longitude = res.longitude;
// 将位置信息存储到本地
wx.setStorageSync('userLocation', { latitude, longitude });
// 更新页面显示
const locationInfo = `${name} ${address}`;
that.setData({ locationInfo });
// 将地址信息保存到本地存储
wx.setStorageSync('locationInfo', locationInfo);
// 检查openid是否存在
let openid = wx.getStorageSync('openid');
if (!openid) {
// 尝试从用户信息中获取openid
const globalUserInfo = wx.getStorageSync('userInfo');
openid = globalUserInfo?.openid;
}
// 确保openid存在
if (!openid) {
console.error('位置上传失败: 未找到openid');
wx.showToast({
title: '位置上传失败,请先登录',
icon: 'none',
duration: 2000
});
return;
}
// 保存地址信息到数据库
const api = require('../../utils/api.js');
const locationUpdateData = {
openid: openid,
latitude: latitude,
longitude: longitude,
address: locationInfo
};
console.log('保存手动选择的地址到数据库:', locationUpdateData);
// 调用API保存地址信息
api.request('/api/user/update-location', 'POST', locationUpdateData)
.then(res => {
console.log('地址保存成功:', res);
// 显示上传成功提示
wx.showToast({
title: '位置选择成功',
icon: 'success',
duration: 1500
});
}).catch(err => {
console.error('地址保存失败:', err);
// 显示上传失败提示
wx.showToast({
title: '位置上传失败',
icon: 'none',
duration: 2000
});
});
},
fail(err) {
console.error('选择位置失败:', err);
if (err.errMsg === 'chooseLocation:fail auth deny') {
wx.showToast({
title: '需要位置授权才能选择地点',
icon: 'none',
duration: 2000
});
// 引导用户重新授权
that.requestLocationAuth();
} else {
wx.showToast({
title: '选择位置失败',
icon: 'none',
duration: 2000
});
}
}
});
},
// 跳转到个人认证页面
navigateToAuthentication() {
wx.navigateTo({
url: '/pages/profile/authentication/index'
});
},
// 点击头像切换图片
onAvatarClick() {
console.log('开始切换头像');
// 使用固定的头像URL数组
const avatarUrls = this.data.avatarUrls;
console.log('头像URL数组:', avatarUrls);
// 检查是否有至少两张图片可以切换
if (avatarUrls.length < 2) {
wx.showToast({
title: '没有足够的头像可以切换',
icon: 'none',
duration: 2000
});
return;
}
// 先根据当前的avatarUrl更新currentAvatarIndex,确保它们保持一致
let currentAvatarIndex = 0;
const currentAvatarUrl = this.data.userInfo.avatarUrl;
if (currentAvatarUrl) {
const index = avatarUrls.indexOf(currentAvatarUrl);
if (index !== -1) {
currentAvatarIndex = index;
// 更新currentAvatarIndex到页面数据
this.setData({ currentAvatarIndex: currentAvatarIndex });
console.log('根据当前avatarUrl更新currentAvatarIndex:', currentAvatarIndex);
}
}
// 切换到下一张头像
let nextIndex = currentAvatarIndex + 1;
if (nextIndex >= avatarUrls.length) {
nextIndex = 0; // 如果已经是最后一张,回到第一张
}
console.log('当前头像索引:', currentAvatarIndex);
console.log('下一张头像索引:', nextIndex);
console.log('下一张头像URL:', avatarUrls[nextIndex]);
// 显示切换头像的提示
const avatarType = nextIndex === 0 ? '男' : '女';
wx.showModal({
title: '切换头像',
content: `确定要切换到${avatarType}头像吗?`,
success: (res) => {
if (res.confirm) {
console.log('用户确认切换头像');
// 切换到下一张图片
const app = getApp();
// 只更新显示用的avatarUrl
const updatedUserInfo = {
...this.data.userInfo,
avatarUrl: avatarUrls[nextIndex] // 直接使用下一张图片用于显示
};
// 更新页面显示
this.setData({
userInfo: updatedUserInfo,
currentAvatarIndex: nextIndex
});
console.log('页面显示已更新');
// 将选中的头像URL写入数据库
console.log('准备更新头像到数据库:', avatarUrls[nextIndex]);
this.updateAvatarInDatabase(avatarUrls[nextIndex]);
wx.showToast({
title: '头像切换成功',
icon: 'success',
duration: 2000
});
}
}
});
},
// 将头像URL更新到数据库
updateAvatarInDatabase(avatarUrl) {
console.log('开始更新头像到数据库:', avatarUrl);
const API = require('../../utils/api.js');
const openid = wx.getStorageSync('openid');
const userId = wx.getStorageSync('userId');
console.log('用户信息:', { openid, userId });
if (!openid) {
console.error('更新头像失败:缺少openid');
return;
}
// 构造更新数据
const updateData = {
openid: openid,
userId: userId,
avatarUrl: avatarUrl
};
console.log('构造的更新数据:', updateData);
// 调用API更新用户信息
console.log('准备调用API.uploadUserInfo');
API.uploadUserInfo(updateData).then(res => {
console.log('更新头像到数据库成功:', res);
// 更新本地存储和全局数据中的头像URL
const app = getApp();
app.globalData.userInfo.avatarUrl = avatarUrl;
wx.setStorageSync('userInfo', app.globalData.userInfo);
console.log('更新本地存储和全局数据中的头像URL成功:', avatarUrl);
}).catch(err => {
console.error('更新头像到数据库失败:', err);
wx.showToast({
title: '更新头像失败,请重试',
icon: 'none',
duration: 2000
});
});
},
})