feat(统计): 统计接口补上每人每道题的每一次提交、流程图每人最好的一次,流程图也能一次查几道题
- 新增 GET /submissions/statistics/grid:范围内每个学生的每次提交(只含普通学生,最多 5000 条), 没选班级时附带各班花名册人数,统计页按「人 × 题」画方块串、按班级汇总 - /flowcharts/statistics 题号可以一次填几道,多返回 people(每人分数最高的那张) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
99c158498c
commit
f09da88ff7
8 files changed
+288
-1492
No files matched your search
@@ -106,6 +106,19 @@ export const flowchartStatisticsSchema = z.object({
|
||||
wordFrequencies: z.array(z.object({ word: z.string(), count: z.number().int() })),
|
||||
// 与提交统计共用「未完成学生」的形状,见 submission.ts 的 unacceptedStudentSchema
|
||||
dataUnaccepted: z.array(z.object({ username: z.string(), realName: z.string() })),
|
||||
/**
|
||||
* 每人**最好的一次**(分数最高的那张),统计页的「每人最好的一次」表用。
|
||||
* 只含普通学生;按最好成绩从低到高排,没拿到 A 的排前面 —— 老师要先看的是他们
|
||||
*/
|
||||
people: z.array(
|
||||
z.object({
|
||||
username: z.string(),
|
||||
realName: z.string(),
|
||||
bestScore: z.number().nullable(),
|
||||
bestGrade: z.string().nullable(),
|
||||
count: z.number().int(),
|
||||
}),
|
||||
),
|
||||
})
|
||||
|
||||
export const flowchartUpdateSchema = z.object({
|
||||
|
||||
@@ -386,6 +386,38 @@ export const submissionStatisticsItemsSchema = z.object({
|
||||
truncated: z.boolean(),
|
||||
})
|
||||
|
||||
/**
|
||||
* 统计页的方块串(GET /submissions/statistics/grid):范围内每个学生的每一次提交,
|
||||
* 前端按「人 × 题」排成方块串,并据此算每道题做完几人。计数口径(正确率、做完、没交)
|
||||
* 仍以 submissionStatisticsSchema 为准,这里只给「每一次交了什么结果」。
|
||||
*
|
||||
* 只含普通学生(老师试题留下的提交不混进来),最多 5000 条最近的,超了 `truncated`。
|
||||
* `classSizes` 只在没传用户名(从题目页进来、按班级汇总)时给:各班花名册人数。
|
||||
*/
|
||||
export const submissionStatisticsGridSchema = z.object({
|
||||
/** 传了题号就按传的顺序;没传就是范围内出现过的题,按第一次有人交的时间排 */
|
||||
problems: z.array(z.object({ problemDisplayId: z.string(), title: z.string() })),
|
||||
rows: z.array(
|
||||
z.object({
|
||||
username: z.string(),
|
||||
/** 剥掉 `ks<班级号>` 前缀后的那段,同 unacceptedStudentSchema.realName */
|
||||
realName: z.string(),
|
||||
className: z.string().nullable(),
|
||||
/** 从早到晚 */
|
||||
submissions: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
problemDisplayId: z.string(),
|
||||
result: judgeStatusSchema,
|
||||
createTime: z.string(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
classSizes: z.record(z.string(), z.number().int()),
|
||||
truncated: z.boolean(),
|
||||
})
|
||||
|
||||
export const submissionStatisticsSchema = z.object({
|
||||
submissionCount: z.number().int(),
|
||||
acceptedCount: z.number().int(),
|
||||
@@ -528,6 +560,7 @@ export type SubmissionStatistics = z.infer<typeof submissionStatisticsSchema>
|
||||
export type TodaySubmissionStatistics = z.infer<typeof todaySubmissionStatisticsSchema>
|
||||
export type SubmissionStatisticsUser = z.infer<typeof submissionStatisticsUserSchema>
|
||||
export type SubmissionStatisticsItems = z.infer<typeof submissionStatisticsItemsSchema>
|
||||
export type SubmissionStatisticsGrid = z.infer<typeof submissionStatisticsGridSchema>
|
||||
export type UnacceptedStudent = z.infer<typeof unacceptedStudentSchema>
|
||||
export type AttemptedStudent = z.infer<typeof attemptedStudentSchema>
|
||||
|
||||
|
||||
Reference in new issue
Block a user