const app = getApp(); Page({ data: { userInfo: null, ladderUser: null, currentStore: null, showQrcode: false, qrcodeImage: "", qrcodeLoading: false, // 完善资料弹框 showProfileModal: false, profileForm: { avatar: "", nickname: "", gender: 0, }, isEditMode: false, // true: 编辑模式,false: 完善模式(登录时) showGenderModal: false, registerGender: 0, }, normalizeLadderUser(ladderUser) { if (!ladderUser) return null; const matchCount = Number(ladderUser.matchCount || 0); const winCount = Number(ladderUser.winCount || 0); const loseCount = Math.max(matchCount - winCount, 0); const winRate = matchCount > 0 ? Math.round((winCount / matchCount) * 100) : 0; return Object.assign({}, ladderUser, { matchCount, winCount, loseCount, winRate, }); }, onLoad() { this.initData(); }, onShow() { // 检查门店是否切换 if (app.globalData.storeChanged) { app.globalData.storeChanged = false; this.refreshData(); } else { // 同步最新数据 this.setData({ userInfo: app.globalData.userInfo, ladderUser: this.normalizeLadderUser(app.globalData.ladderUser), currentStore: app.globalData.currentStore, }); } }, async onPullDownRefresh() { try { await this.refreshData(); } finally { wx.stopPullDownRefresh(); } }, async initData() { // 先进行微信登录获取openid if (!app.globalData.wxLoginInfo) { try { await app.wxLogin(); } catch (e) { console.error("微信登录失败:", e); } } if (app.globalData.token) { await this.refreshData(); } }, async refreshData() { if (!app.globalData.token) return; try { await app.getUserInfo(); // 如果当前门店有 ladderUserId,确保获取该门店的天梯用户信息 if ( app.globalData.currentStore && app.globalData.currentStore.storeId && !app.globalData.ladderUser ) { try { await app.getLadderUser(app.globalData.currentStore.storeId); } catch (e) { console.error("获取天梯用户信息失败:", e); } } this.setData({ userInfo: app.globalData.userInfo, ladderUser: this.normalizeLadderUser(app.globalData.ladderUser), currentStore: app.globalData.currentStore, }); } catch (e) { console.error("获取用户信息失败:", e); } }, // 获取手机号授权 async onGetPhoneNumber(e) { if (e.detail.errMsg !== "getPhoneNumber:ok") { wx.showToast({ title: "需要授权手机号才能登录", icon: "none" }); return; } try { wx.showLoading({ title: "登录中..." }); // 如果没有微信登录信息,先登录 if (!app.globalData.wxLoginInfo) { await app.wxLogin(); } const needGender = app.globalData.wxLoginInfo && app.globalData.wxLoginInfo.isNewUser; if ( needGender && !(this.data.registerGender === 1 || this.data.registerGender === 2) ) { this._pendingPhoneLogin = { encryptedData: e.detail.encryptedData, iv: e.detail.iv, }; wx.hideLoading(); this.setData({ showGenderModal: true }); return; } await this.doPhoneLogin( e.detail.encryptedData, e.detail.iv, needGender ? this.data.registerGender : 0, ); // 获取门店信息 await app.getCurrentStore(); const userInfo = app.globalData.userInfo; this.setData({ userInfo: userInfo, ladderUser: this.normalizeLadderUser(app.globalData.ladderUser), currentStore: app.globalData.currentStore, }); // 检查是否需要完善资料(没有头像或昵称为默认值) const needProfile = !userInfo.avatar || userInfo.avatar === "" || !userInfo.nickname || userInfo.nickname === "新用户" || userInfo.nickname === ""; if (needProfile) { // 弹出完善资料弹框 this.setData({ showProfileModal: true, isEditMode: false, profileForm: { avatar: userInfo.avatar || "/images/avatar-default.svg", nickname: userInfo.nickname === "新用户" ? "" : userInfo.nickname || "", }, }); wx.showToast({ title: "登录成功,请完善资料", icon: "none" }); } else { wx.showToast({ title: "登录成功", icon: "success" }); } } catch (e) { console.error("登录失败:", e); wx.showToast({ title: e.message || "登录失败", icon: "none" }); } finally { wx.hideLoading(); } }, async doPhoneLogin(encryptedData, iv, gender) { const g = gender === 1 || gender === 2 ? gender : 0; await app.phoneLogin(encryptedData, iv, g ? { gender: g } : null); this._pendingPhoneLogin = null; this.setData({ showGenderModal: false }); }, onSelectRegisterGender(e) { const gender = Number(e.currentTarget.dataset.gender); if (gender !== 1 && gender !== 2) return; this.setData({ registerGender: gender }); }, async onConfirmRegisterGender() { if (!(this.data.registerGender === 1 || this.data.registerGender === 2)) { wx.showToast({ title: "请选择性别", icon: "none" }); return; } const pending = this._pendingPhoneLogin; if (!pending) { this.setData({ showGenderModal: false }); return; } wx.showLoading({ title: "登录中..." }); try { await this.doPhoneLogin( pending.encryptedData, pending.iv, this.data.registerGender, ); await app.getCurrentStore(); const userInfo = app.globalData.userInfo; this.setData({ userInfo: userInfo, ladderUser: this.normalizeLadderUser(app.globalData.ladderUser), currentStore: app.globalData.currentStore, }); const needProfile = !userInfo.avatar || userInfo.avatar === "" || !userInfo.nickname || userInfo.nickname === "新用户" || userInfo.nickname === ""; if (needProfile) { this.setData({ showProfileModal: true, isEditMode: false, profileForm: { avatar: userInfo.avatar || "/images/avatar-default.svg", nickname: userInfo.nickname === "新用户" ? "" : userInfo.nickname || "", gender: userInfo.gender || 0, }, }); wx.showToast({ title: "登录成功,请完善资料", icon: "none" }); } else { wx.showToast({ title: "登录成功", icon: "success" }); } } catch (e) { console.error("登录失败:", e); wx.showToast({ title: e.message || "登录失败", icon: "none" }); } finally { wx.hideLoading(); } }, onCancelRegisterGender() { this._pendingPhoneLogin = null; this.setData({ showGenderModal: false, registerGender: 0 }); }, // 点击头像,打开编辑资料弹框 onTapAvatar() { if (!this.data.userInfo || !this.data.userInfo.phone) return; this.setData({ showProfileModal: true, isEditMode: true, profileForm: { avatar: this.data.userInfo.avatar || "/images/avatar-default.svg", nickname: this.data.userInfo.nickname || "", gender: this.data.userInfo.gender || 0, }, }); }, // 选择头像(新API:button open-type="chooseAvatar") onChooseAvatarNew(e) { const avatarUrl = e.detail.avatarUrl; this.setData({ "profileForm.avatar": avatarUrl, }); }, // 输入昵称 onNicknameInput(e) { this.setData({ "profileForm.nickname": e.detail.value, }); }, onProfileGenderSelect(e) { const gender = Number(e.currentTarget.dataset.gender); if (gender !== 1 && gender !== 2) return; this.setData({ "profileForm.gender": gender, }); }, // 确认保存资料 async saveProfile() { const { avatar, nickname, gender } = this.data.profileForm; if (!nickname || nickname.trim() === "") { wx.showToast({ title: "请输入昵称", icon: "none" }); return; } wx.showLoading({ title: "保存中..." }); try { // 如果选择了新头像,先上传 let avatarUrl = avatar; if ( avatar && (avatar.startsWith("wxfile://") || avatar.startsWith("http://tmp")) ) { avatarUrl = await this.uploadAvatar(avatar); } // 调用更新资料接口 const payload = { nickname: nickname.trim(), avatar: avatarUrl, }; if (gender === 1 || gender === 2) { payload.gender = gender; } const res = await app.request("/api/user/profile", payload, "PUT"); // 更新本地数据(服务端已返回完整URL) const userInfo = Object.assign({}, this.data.userInfo, { nickname: (res.data && res.data.nickname) || nickname.trim(), avatar: (res.data && res.data.avatar) || avatarUrl, gender: (res.data && res.data.gender) || this.data.userInfo.gender || 0, }); app.globalData.userInfo = userInfo; this.setData({ userInfo: userInfo, showProfileModal: false, profileForm: { avatar: "", nickname: "", gender: 0 }, }); wx.hideLoading(); wx.showToast({ title: "保存成功", icon: "success" }); } catch (e) { wx.hideLoading(); console.error("保存资料失败:", e); wx.showToast({ title: e.message || "保存失败", icon: "none" }); } }, // 上传头像 async uploadAvatar(filePath) { return new Promise((resolve, reject) => { wx.uploadFile({ url: `${app.globalData.baseUrl}/api/upload/avatar`, filePath: filePath, name: "file", header: { Authorization: `Bearer ${app.globalData.token}`, }, success: (res) => { try { const data = JSON.parse(res.data); if (data.code === 0 && data.data && data.data.url) { resolve(data.data.url); } else { console.error("上传头像失败:", data); resolve(filePath); } } catch (e) { resolve(filePath); } }, fail: (err) => { console.error("上传头像失败:", err); resolve(filePath); }, }); }); }, // 关闭资料弹框 closeProfileModal() { // 如果是完善模式,提示用户 if (!this.data.isEditMode) { wx.showModal({ title: "提示", content: "完善资料后可以让好友更容易找到你,确定跳过?", confirmText: "跳过", cancelText: "继续完善", success: (res) => { if (res.confirm) { this.setData({ showProfileModal: false }); } }, }); } else { this.setData({ showProfileModal: false }); } }, async showMemberCode() { if (!this.data.userInfo || !this.data.userInfo.memberCode) return; this.setData({ showQrcode: true, qrcodeLoading: true, }); try { // 调用接口获取二维码 const res = await app.request("/api/user/qrcode"); if (res.data && res.data.qrcode) { this.setData({ qrcodeImage: res.data.qrcode, qrcodeLoading: false, }); } } catch (e) { console.error("获取二维码失败:", e); this.setData({ qrcodeLoading: false }); wx.showToast({ title: "获取二维码失败", icon: "none" }); } }, hideQrcode() { this.setData({ showQrcode: false, qrcodeImage: "", }); }, goTo(e) { const url = e.currentTarget.dataset.url; if (!app.globalData.token) { wx.showToast({ title: "请先登录", icon: "none" }); return; } wx.navigateTo({ url }); }, // 阻止事件冒泡 preventBubble() { // 空函数,仅用于阻止事件冒泡 }, });