yingsa/miniprogram/pages/match/challenge/index.js
ethanfly 1a530ebf02 feat: Implement default store retrieval for new users and enhance login flow
- Added a new method to fetch the default store for users without a login, allowing them to browse store rankings.
- Updated the wxLogin function to streamline the login process for users with existing phone numbers, enabling direct token retrieval.
- Refactored various page components to utilize the new getDefaultStore method for better user experience when accessing store information.
- Enhanced error handling and data synchronization for user and store information across multiple pages.
2026-02-07 14:04:31 +08:00

364 lines
9.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const app = getApp();
const util = require("../../../utils/util");
Page({
data: {
userInfo: null,
ladderUser: null,
currentStore: null,
ongoingMatches: [], // 正在进行中的比赛
pendingGames: [], // 待确认的比赛
recentMatches: [], // 最近比赛用于预览前10场
},
onLoad() {
this.initData();
},
onShow() {
this.initData();
},
async onPullDownRefresh() {
try {
await this.initData();
} finally {
wx.stopPullDownRefresh();
}
},
async initData() {
// 获取门店(已登录用 ensureCurrentStore未登录用 getDefaultStore 可浏览)
try {
if (app.globalData.token) {
await app.ensureCurrentStore();
if (app.globalData.currentStore?.storeId) {
await app.getLadderUser(app.globalData.currentStore.storeId);
}
} else {
await app.getDefaultStore();
}
} catch (e) {
console.error("获取门店/天梯信息失败:", e);
}
this.refreshData();
},
refreshData() {
this.setData({
userInfo: app.globalData.userInfo,
ladderUser: app.globalData.ladderUser,
currentStore: app.globalData.currentStore,
});
if (app.globalData.ladderUser) {
this.fetchOngoingMatches();
this.fetchPendingGames();
this.fetchRecentMatches();
}
},
// 获取正在进行中的比赛
async fetchOngoingMatches() {
try {
const res = await app.request("/api/match/ongoing", {
store_id: this.data.currentStore
? this.data.currentStore.storeId
: null,
});
this.setData({ ongoingMatches: res.data || [] });
} catch (e) {
console.error("获取进行中比赛失败:", e);
}
},
// 手动刷新天梯信息
async refreshLadderInfo() {
wx.showLoading({ title: "刷新中..." });
try {
// 重新获取门店信息
await app.ensureCurrentStore();
// 重新获取天梯信息
if (app.globalData.currentStore && app.globalData.currentStore.storeId) {
await app.getLadderUser(app.globalData.currentStore.storeId);
}
this.refreshData();
wx.hideLoading();
if (app.globalData.ladderUser) {
wx.showToast({ title: "已加入天梯", icon: "success" });
} else {
wx.showToast({ title: "暂未开通天梯", icon: "none" });
}
} catch (e) {
wx.hideLoading();
console.error("刷新天梯信息失败:", e);
wx.showToast({ title: "刷新失败", icon: "none" });
}
},
async fetchPendingGames() {
try {
const res = await app.request("/api/match/pending-confirm", {
store_id: this.data.currentStore
? this.data.currentStore.storeId
: null,
});
this.setData({ pendingGames: res.data || [] });
} catch (e) {
console.error("获取待确认比赛失败:", e);
}
},
// 获取最近比赛近7天最多10场用于比赛页预览
async fetchRecentMatches() {
try {
const storeId = this.data.currentStore
? this.data.currentStore.storeId
: null;
const res = await app.request("/api/match/display-list", {
store_id: storeId,
days: 7,
limit: 10,
});
const raw = res.data || [];
const recentMatches = raw.map((item) => {
const time = item.startTime || item.createdAt || item.endTime || null;
const stageName = item.stageName || "";
const statusName = item.statusName || "";
const showStage = !!stageName && stageName !== statusName;
let statusType = "pending";
switch (item.status) {
case 1:
statusType = "ongoing";
break;
case 2:
statusType = "finished";
break;
case 3:
statusType = "cancelled";
break;
default:
statusType = "pending";
}
return Object.assign({}, item, {
timeText: time ? util.formatDate(time) : "",
stageName,
statusName,
showStage,
statusType,
});
});
this.setData({ recentMatches });
} catch (e) {
console.error("获取最近比赛失败:", e);
}
},
startChallenge() {
if (!this.data.ladderUser) {
wx.showToast({ title: "请先加入天梯系统", icon: "none" });
return;
}
if (!this.data.currentStore || !this.data.currentStore.storeId) {
wx.showToast({ title: "请先选择门店", icon: "none" });
wx.navigateTo({ url: "/pages/store/index" });
return;
}
wx.scanCode({
onlyFromCamera: false,
scanType: ["qrCode"],
success: async (res) => {
const memberCode = res.result;
this.checkAndChallenge(memberCode);
},
fail: (err) => {
if (err.errMsg !== "scanCode:fail cancel") {
wx.showToast({ title: "扫码失败", icon: "none" });
}
},
});
},
async checkAndChallenge(memberCode) {
wx.showLoading({ title: "检查中..." });
try {
const res = await app.request(
`/api/match/challenge/check/${memberCode}`,
{
store_id: this.data.currentStore.storeId,
},
);
wx.hideLoading();
if (!res.data.canChallenge) {
wx.showModal({
title: "无法挑战",
content: res.data.reason,
showCancel: false,
});
return;
}
// 显示确认弹窗
const target = res.data.targetUser;
wx.showModal({
title: "确认挑战",
content: `确定要向 ${target.ladderUser.realName}(Lv${target.ladderUser.level}, 战力${target.ladderUser.powerScore}) 发起挑战吗?`,
success: async (modalRes) => {
if (modalRes.confirm) {
await this.createChallenge(memberCode);
}
},
});
} catch (e) {
wx.hideLoading();
console.error("检查挑战失败:", e);
}
},
async createChallenge(memberCode) {
wx.showLoading({ title: "发起挑战中..." });
try {
const res = await app.request(
"/api/match/challenge/create",
{
store_id: this.data.currentStore.storeId,
target_member_code: memberCode,
},
"POST",
);
wx.hideLoading();
wx.showToast({ title: "挑战已发起", icon: "success" });
// 跳转到挑战赛详情页面
if (res.data && res.data.matchId) {
setTimeout(() => {
wx.navigateTo({
url: `/pages/match/challenge-detail/index?id=${res.data.matchId}`,
});
}, 1500);
}
} catch (e) {
wx.hideLoading();
console.error("发起挑战失败:", e);
const errorMsg =
e.message || (e.data && e.data.message) || "发起挑战失败";
wx.showToast({ title: errorMsg, icon: "none", duration: 2000 });
}
},
joinRankingMatch() {
if (!this.data.ladderUser) {
wx.showToast({ title: "请先加入天梯系统", icon: "none" });
return;
}
wx.scanCode({
onlyFromCamera: false,
scanType: ["qrCode"],
success: async (res) => {
const matchCode = res.result;
wx.showLoading({ title: "加入中..." });
try {
const joinRes = await app.request(
"/api/match/ranking/join",
{
match_code: matchCode,
},
"POST",
);
wx.hideLoading();
wx.showToast({ title: "加入成功", icon: "success" });
// 跳转到排位赛详情
wx.navigateTo({
url: `/pages/match/ranking/index?code=${matchCode}`,
});
} catch (e) {
wx.hideLoading();
console.error("加入排位赛失败:", e);
}
},
fail: (err) => {
if (err.errMsg !== "scanCode:fail cancel") {
wx.showToast({ title: "扫码失败", icon: "none" });
}
},
});
},
goToStore() {
wx.navigateTo({ url: "/pages/store/index" });
},
// 跳转到最近比赛列表页
goToRecentMatches() {
wx.navigateTo({ url: "/pages/match/recent/index" });
},
// 跳转到比赛详情
goToMatchDetail(e) {
const match = e.currentTarget.dataset.match;
if (match.type === 1) {
// 挑战赛详情
wx.navigateTo({
url: `/pages/match/challenge-detail/index?id=${match.id}`,
});
} else {
// 排位赛详情
wx.navigateTo({
url: `/pages/match/ranking/index?code=${match.matchCode}`,
});
}
},
confirmGame(e) {
const game = e.currentTarget.dataset.game;
wx.showModal({
title: "确认比分",
content: `确认比分 ${game.myScore} : ${game.opponentScore} 吗?`,
confirmText: "确认",
cancelText: "有争议",
success: async (res) => {
wx.showLoading({ title: "处理中..." });
try {
await app.request(
"/api/match/challenge/confirm-score",
{
game_id: game.id,
confirm: res.confirm,
},
"POST",
);
wx.hideLoading();
wx.showToast({
title: res.confirm ? "确认成功" : "已标记争议",
icon: "success",
});
this.fetchPendingGames();
} catch (e) {
wx.hideLoading();
console.error("确认比分失败:", e);
}
},
});
},
});