- 新增选手资料页面,支持查看选手信息及比赛记录 - 添加多个SVG图标替换原有emoji,提升视觉一致性 - 扩展CSS变量系统,增加信息、成功、警告、危险等状态颜色 - 优化多个页面的样式,统一使用CSS变量和现代设计语言 - 修复可选链操作符兼容性问题,改用传统条件判断 - 改进数据加载逻辑,使用Object.assign替代展开运算符 - 调整开发环境配置,使用本地服务器地址
330 lines
8.2 KiB
JavaScript
330 lines
8.2 KiB
JavaScript
const app = getApp();
|
||
|
||
Page({
|
||
data: {
|
||
userInfo: null,
|
||
ladderUser: null,
|
||
currentStore: null,
|
||
showQrcode: false,
|
||
qrcodeImage: "",
|
||
qrcodeLoading: false,
|
||
// 完善资料弹框
|
||
showProfileModal: false,
|
||
profileForm: {
|
||
avatar: "",
|
||
nickname: "",
|
||
},
|
||
isEditMode: false, // true: 编辑模式,false: 完善模式(登录时)
|
||
},
|
||
|
||
onLoad() {
|
||
this.initData();
|
||
},
|
||
|
||
onShow() {
|
||
// 检查门店是否切换
|
||
if (app.globalData.storeChanged) {
|
||
app.globalData.storeChanged = false;
|
||
this.refreshData();
|
||
} else {
|
||
// 同步最新数据
|
||
this.setData({
|
||
userInfo: app.globalData.userInfo,
|
||
ladderUser: 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: 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;
|
||
}
|
||
|
||
wx.showLoading({ title: "登录中..." });
|
||
|
||
try {
|
||
// 如果没有微信登录信息,先登录
|
||
if (!app.globalData.wxLoginInfo) {
|
||
await app.wxLogin();
|
||
}
|
||
|
||
// 手机号登录(先不传头像昵称)
|
||
await app.phoneLogin(e.detail.encryptedData, e.detail.iv, null);
|
||
|
||
// 获取门店信息
|
||
await app.getCurrentStore();
|
||
|
||
const userInfo = app.globalData.userInfo;
|
||
|
||
this.setData({
|
||
userInfo: userInfo,
|
||
ladderUser: app.globalData.ladderUser,
|
||
currentStore: app.globalData.currentStore,
|
||
});
|
||
|
||
wx.hideLoading();
|
||
|
||
// 检查是否需要完善资料(没有头像或昵称为默认值)
|
||
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) {
|
||
wx.hideLoading();
|
||
console.error("登录失败:", e);
|
||
wx.showToast({ title: e.message || "登录失败", icon: "none" });
|
||
}
|
||
},
|
||
|
||
// 点击头像,打开编辑资料弹框
|
||
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 || "",
|
||
},
|
||
});
|
||
},
|
||
|
||
// 选择头像(新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,
|
||
});
|
||
},
|
||
|
||
// 确认保存资料
|
||
async saveProfile() {
|
||
const { avatar, nickname } = 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 res = await app.request(
|
||
"/api/user/profile",
|
||
{
|
||
nickname: nickname.trim(),
|
||
avatar: avatarUrl,
|
||
},
|
||
"PUT",
|
||
);
|
||
|
||
// 更新本地数据(服务端已返回完整URL)
|
||
const userInfo = Object.assign({}, this.data.userInfo, {
|
||
nickname: (res.data && res.data.nickname) || nickname.trim(),
|
||
avatar: (res.data && res.data.avatar) || avatarUrl,
|
||
});
|
||
app.globalData.userInfo = userInfo;
|
||
|
||
this.setData({
|
||
userInfo: userInfo,
|
||
showProfileModal: false,
|
||
profileForm: { avatar: "", nickname: "" },
|
||
});
|
||
|
||
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() {
|
||
// 空函数,仅用于阻止事件冒泡
|
||
},
|
||
});
|