feat(排行榜): 页头显示当前在线人数,在线绿点只给老师
Some checks failed
Deploy / deploy (push) Has been cancelled

新增匿名可读的 GET /api/site/online,一条 ZCOUNT 让 Redis 自己数,
不拉成员、也不写(清理过期成员留给后台列表,匿名接口不带写操作)。
榜单页进页面拉一次,为 0 时不显示。

/rankings/users 的 isOnline 是三态:null 表示「这个调用方不该知道」,
只有老师及以上拿到 true/false。写成普通 boolean 的话学生看到的 false
和真的离线分不开,等于默认把每个人的在线状态摊给全校同学看。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xu912Rv5JUUuy6MqMcQW2
This commit is contained in:
2026-09-07 19:36:12 -06:00
parent 856b7a280e
commit 6a438872b9
8 changed files with 69 additions and 6 deletions

View File

@@ -27,6 +27,12 @@ export const rankProfileSchema = z.object({
acceptedNumber: z.number().int(),
submissionNumber: z.number().int(),
mood: z.string().nullable(),
/**
* 在线与否。**null 表示「这个调用方不该知道」** —— 学生之间互相盯着谁在刷题
* 不合适,所以只对老师及以上下发 true/false其余一律 null。
* 三态是有意的:写成 boolean 的话,学生看到的 false 和真的离线分不开。
*/
isOnline: z.boolean().nullable().default(null),
})
/**

View File

@@ -11,6 +11,11 @@ export const websiteConfigSchema = z.object({
enableMaxkb: z.boolean(),
})
/** 当前在线人数。只有聚合值 —— 「某某在不在线」是个人状态,不往匿名接口放 */
export const onlineCountSchema = z.object({
count: z.number().int().nonnegative(),
})
export const quoteSchema = z.union([
z.string(),
z.record(z.string(), z.unknown()),
@@ -18,3 +23,4 @@ export const quoteSchema = z.union([
export type WebsiteConfig = z.infer<typeof websiteConfigSchema>
export type Quote = z.infer<typeof quoteSchema>
export type OnlineCount = z.infer<typeof onlineCountSchema>