yingsa/miniprogram/pages/index/index.js
ethanfly 02937ca33c feat(天梯): 新增选手定位功能并调整挑战赛权重
- 在小程序天梯排名页添加“定位我”按钮,点击可滚动到当前用户所在位置
- 新增获取用户排名接口 `/ladder/my-rank` 用于定位计算
- 调整挑战赛权重从 1.5 降至 1.0,与日常畅打保持一致
- 新增数据库脚本 `setChallengeMatchWeightTo1.js` 用于更新历史数据
- 在管理员界面创建天梯用户时,根据所选等级自动填充默认战力值
- 修复管理员更新比赛时挑战赛权重强制设置为 1.0 的问题
- 新增天梯汇总大屏页面及相关路由
- 添加大屏比赛列表接口 `/match/display-list` 用于展示进行中和近期比赛
- 优化用户详情页的胜负场和胜率显示逻辑
- 修复小程序用户注册时的性别选择逻辑
2026-02-02 03:22:36 +08:00

205 lines
5.0 KiB
JavaScript
Raw 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");
const ALL_PAGE_SIZE = 5000;
Page({
data: {
currentStore: null,
gender: "",
list: [],
loading: false,
locating: false,
myLadderUserId: null,
pageSize: ALL_PAGE_SIZE,
},
onLoad() {
this.initData();
},
onShow() {
const newStore = app.globalData.currentStore;
const oldStoreId = this.data.currentStore
? this.data.currentStore.storeId
: null;
// 检查门店是否切换
if (newStore && newStore.storeId !== oldStoreId) {
this.setData({
currentStore: newStore,
list: [],
myLadderUserId: null,
});
this.fetchData();
} else if (app.globalData.storeChanged) {
// 全局标记门店已切换
app.globalData.storeChanged = false;
this.setData({
currentStore: newStore,
list: [],
myLadderUserId: null,
});
this.fetchData();
}
},
onPullDownRefresh() {
this.setData({ list: [], myLadderUserId: null });
this.fetchData().then(() => {
wx.stopPullDownRefresh();
});
},
async initData() {
// 检查是否已登录(有 token
if (!app.globalData.token) {
// 未登录,跳转到用户页面进行登录
wx.switchTab({ url: "/pages/user/index" });
return;
}
// 获取当前门店
try {
const store = await app.getCurrentStore();
this.setData({ currentStore: store });
this.fetchData();
} catch (e) {
console.error("获取门店失败:", e);
// 如果是认证失败,跳转到登录页
if (e.code === 401) {
wx.switchTab({ url: "/pages/user/index" });
}
}
},
async fetchData() {
if (!this.data.currentStore || !this.data.currentStore.storeId) return;
this.setData({ loading: true });
try {
const res = await app.request("/api/ladder/ranking", {
store_id: this.data.currentStore.storeId,
gender: this.data.gender,
page: 1,
pageSize: this.data.pageSize,
no_count: 1,
});
const list = res.data.list || [];
this.setData({
list,
});
} catch (e) {
console.error("获取排名失败:", e);
} finally {
this.setData({ loading: false });
}
},
setGender(e) {
const gender = e.currentTarget.dataset.gender;
this.setData({ gender, list: [], myLadderUserId: null });
this.fetchData();
},
selectStore() {
wx.navigateTo({ url: "/pages/store/index" });
},
scrollToMeInMiddle(tryCount = 0) {
const id = this.data.myLadderUserId;
if (!id) return;
const selector = `#player-${id}`;
const systemInfo = wx.getSystemInfoSync();
const windowHeight =
systemInfo && systemInfo.windowHeight ? systemInfo.windowHeight : 0;
wx.createSelectorQuery()
.select(selector)
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec((res) => {
const rect = res && res[0] ? res[0] : null;
const scroll = res && res[1] ? res[1] : null;
if (!rect || !scroll || typeof scroll.scrollTop !== "number") {
if (tryCount < 10) {
setTimeout(() => {
this.scrollToMeInMiddle(tryCount + 1);
}, 100);
}
return;
}
const targetScrollTop =
scroll.scrollTop + rect.top - windowHeight / 2 + rect.height / 2;
wx.pageScrollTo({
scrollTop: Math.max(0, targetScrollTop),
duration: 300,
});
});
},
async locateMe() {
if (!this.data.currentStore || !this.data.currentStore.storeId) return;
if (this.data.locating) return;
this.setData({ locating: true });
try {
const res = await app.request("/api/ladder/my-rank", {
store_id: this.data.currentStore.storeId,
gender: this.data.gender,
});
const data = res && res.data ? res.data : null;
if (!data) return;
if (data.qualified === false) {
wx.showToast({
title: `本月场次不足(${data.monthlyMatchCount}/${data.minMonthlyMatches}`,
icon: "none",
});
return;
}
if (!data.ladderUserId || !data.page) {
return;
}
const shouldRefetch = !this.data.list || this.data.list.length === 0;
this.setData({ myLadderUserId: data.ladderUserId });
if (shouldRefetch) {
await this.fetchData();
}
setTimeout(() => {
this.scrollToMeInMiddle();
}, 50);
} catch (e) {
console.error("定位我的排名失败:", e);
} finally {
this.setData({ locating: false });
}
},
viewPlayer(e) {
const player = e.currentTarget.dataset.player;
const id = player && player.id ? player.id : e.currentTarget.dataset.id;
if (!id) return;
wx.navigateTo({
url: `/pages/player/index?id=${id}`,
success: (res) => {
if (res && res.eventChannel && player) {
res.eventChannel.emit("player", player);
}
},
});
},
});