feat(排名): 排名页重做成领奖台加全班赛道,一眼看出自己第几、该追谁、谁在追自己
Deploy / deploy (push) Canceled after 0s

- 一张榜两个开关:本班 / 本年级 / 全服 × 这周 / 这学期 / 全部,默认本班 · 这学期。
  原来最大那张全服 Top100 里,这学期在用的 25 级学生一个都进不去
- 做对一样多的不再按「提交少的在前」排,改成先做到的在前;名次旁边写比周一升降了几名
- 「你」那张卡:第几名、再做对几道上领奖台,要追的人早你几秒、追你的人晚你几秒
- 本年级 / 全服只列前面一段和你附近一段,中间折起来,点开再看
- 班级对抗按人均做对比,另有我和对手的名次走势、这周本班、每周冠军
- 老师不上榜,选班看;每行「⋯」能把怀疑抄代码的学生设成不计入排名(新增 user.rank_hidden_at,
  首页周榜同样不算他),随时能恢复
- 去掉全服 Top10、日活两张图、在线人数和班级详情弹框里的统计词,以及它们背后的旧接口

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-10 07:26:15 +08:00
1 parent 0cee4ef779
commit 1c6e2b9d82
31 files changed
+6633 -1392

No files matched your search

-9
View File
@@ -41,15 +41,6 @@ export async function onlineUserIds() {
return new Set(members.map(Number).filter(Number.isInteger))
}
/**
* 在线人数。前台榜单页要的就是这一个数 —— 不必像 onlineUserIds 那样把成员全拉回来,
* ZCOUNT 让 Redis 自己数(O(log N))。这里不顺手清过期成员:清理是写操作,
* 而这个端点是匿名可访问的。
*/
export async function onlineCount() {
return redis.zcount(PRESENCE_KEY, Date.now() - ONLINE_WINDOW_MS, "+inf")
}
/** 登出、被禁用、被踢下线:立刻从在线名单里摘掉,别等窗口自然过期 */
export async function clearOnline(userId: number) {
await redis.zrem(PRESENCE_KEY, String(userId))