存量榜(/rankings/users、班级榜)排的都是 user_profile 的 AC 总数,名次几乎不动, 中位学生看一眼就知道追不上 —— 榜单在那批人身上是负反馈。这张榜的分母换成「这一周」, 每周一 0:00(东八区)清零,谁都可能进前十。 口径是**本周首次 AC 的题目数**,不是「本周 AC 过的去重题数」:后者把上周就做出来的题 重交一遍也算成绩,一分钟能刷满一屏。靠 NOT EXISTS 排掉本周之前已通过的 (user, problem) 对,四个条件正好是 submission_public_metrics_idx 的全部列。 - time.ts 加 weekStart():localWeekday 的 0 是周日,要先折成 7,否则周日单独成一周 - GET /rankings/weekly?scope=global|class,入榜人群与全服榜一致(教师/超管不参与) - 前端默认落在本班 —— 全服周榜上中位学生仍然看不到自己,班内 30 人那张才有答案 - 本周一题没做出来时 me 是 null,footer 那句「做出 1 题就能上榜」照样出现: 它是说给还没上榜的人听的,而那正是最需要被推一把的一批 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,34 @@ export const activityRankItemSchema = z.object({
|
||||
count: z.number().int().nonnegative(),
|
||||
})
|
||||
|
||||
/**
|
||||
* 周榜的一行。`solvedCount` 是**本周首次 AC 的题目数** —— 不是「本周 AC 过的去重题数」。
|
||||
* 后者会把上周就做出来的题重交一次也算成本周成绩,等于给刷榜留了个口子;
|
||||
* 而周榜的全部意义是「这一周你往前走了多少」,只有首次通过才算往前走。
|
||||
*/
|
||||
export const weeklyRankItemSchema = z.object({
|
||||
user: sampleUserSchema,
|
||||
solvedCount: z.number().int().positive(),
|
||||
submissionCount: z.number().int().nonnegative(),
|
||||
rank: z.number().int().positive(),
|
||||
})
|
||||
|
||||
export const weeklyRankSchema = z.object({
|
||||
/** 本周一 0:00(东八区)对应的 UTC 时刻,前端拿它显示统计区间 */
|
||||
start: z.string(),
|
||||
scope: z.enum(["global", "class"]),
|
||||
/** `scope = "class"` 时是我的班号,全服榜为 null */
|
||||
className: z.string().nullable(),
|
||||
/** 本周有新增 AC 的总人数。榜面只回前几名,这个数是全量 */
|
||||
total: z.number().int().nonnegative(),
|
||||
results: z.array(weeklyRankItemSchema),
|
||||
/**
|
||||
* 我这周的位置。**本周一题没做出来就是 null**,和「没登录」「身份不入榜」同一个值 ——
|
||||
* 这三种情况前端都该显示「做出 1 题就能上榜」那句,不需要区分。
|
||||
*/
|
||||
me: weeklyRankItemSchema.nullable(),
|
||||
})
|
||||
|
||||
export const problemRankSchema = z.object({
|
||||
className: z.string(),
|
||||
rank: z.number().int(),
|
||||
@@ -72,6 +100,8 @@ export type RankProfile = z.infer<typeof rankProfileSchema>
|
||||
export type UserRank = z.infer<typeof userRankSchema>
|
||||
export type MyRank = z.infer<typeof myRankSchema>
|
||||
export type ActivityRankItem = z.infer<typeof activityRankItemSchema>
|
||||
export type WeeklyRankItem = z.infer<typeof weeklyRankItemSchema>
|
||||
export type WeeklyRank = z.infer<typeof weeklyRankSchema>
|
||||
export type Metrics = z.infer<typeof metricsSchema>
|
||||
|
||||
export type PublicProfile = z.infer<typeof publicProfileSchema>
|
||||
|
||||
Reference in New Issue
Block a user