零新表零迁移;三套管理全走家长端独立页;编辑不联动积分打卡。 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
81 lines
5.6 KiB
Markdown
81 lines
5.6 KiB
Markdown
# 家长端成绩与试卷管理 - 设计文档
|
|
|
|
日期:2026-08-19
|
|
状态:已批准
|
|
|
|
## 背景
|
|
|
|
家长端「课程管理」只有一张只读的最近 10 条周测成绩列表,考试板块(试卷+作答记录)在家长端完全没有入口。
|
|
用户要求:每周检测成绩、考试中心对应的数据都可管理(已确认:成绩记录编辑+删除、试卷内容管理一次全做)。
|
|
|
|
关键现状:
|
|
|
|
- `weekly_test`:孩子周测自动写入(child+weekKey 唯一),达标联动发积分 + 当日英语打卡。
|
|
- `exam_paper`:试卷内容存库(meta + questions quiz JSON);`exam_record`:孩子作答(child+paperId 唯一),达标联动发积分 + 当日数学打卡。
|
|
- 家长端已有内容编辑器成熟模式(grammar/words/math:列表页 → 详情编辑页,保存即生效)。
|
|
- `quiz-parse` 只提供 `extractQuiz(md)` 与 `QuizQ` 类型,无独立 JSON 校验器 → 校验在保存 action 内做形状校验。
|
|
|
|
## 需求(已与用户确认)
|
|
|
|
1. **每周检测成绩管理**:家长可编辑(分数 + 达标状态)、删除记录。
|
|
2. **考试成绩记录管理**:同款编辑 + 删除。
|
|
3. **考试试卷内容管理**:新增/编辑/删除试卷(元信息表单 + 题目 JSON 文本域,保存时校验)。
|
|
4. 编辑成绩/达标**不联动**积分与打卡回滚(用户选定,简单优先)。
|
|
5. 题目编辑用 **JSON 文本域 + 保存时校验**(用户选定,非结构化逐题表单)。
|
|
|
|
## 方案选择
|
|
|
|
- **方案 A(采用):三套管理全部进家长端独立页,零新表零迁移**
|
|
- 成绩记录管理仿 wrongbook/family-manage 模式(server action + 行内编辑);试卷管理仿 grammar/math 编辑器(列表 → 详情编辑)。
|
|
- 方案 B(弃):结构化逐题表单编辑题目 → 表单工程量大,两倍工作量。
|
|
- 方案 C(弃):成绩管理塞进课程管理 Section 行内 → 交互空间挤、可扩展性差。
|
|
|
|
## 设计
|
|
|
|
### 1. 周测成绩管理 `/parent/weekly-records`
|
|
|
|
- 入口:课程管理 Section 的只读周测列表块删除,替换为「每周检测成绩管理」入口卡片(与课程编辑卡片同风格)。
|
|
- 页面(server component):鉴权同其它家长页;查询 `weekly_test` join `users`(本家庭全部孩子),按 takenAt 倒序最近 100 条,按孩子分组展示。
|
|
- 每行:孩子名 · 周 key · 分数 · 达标徽标 · 日期;操作:编辑(行内展开分数输入 + 达标开关 + 保存/取消)、删除(按钮二次确认)。
|
|
- 分数编辑:整数 0-1000 表单校验;达标独立开关,不自动按 80 分计算(家长手动决定,与"不联动回滚"精神一致)。
|
|
- 删除后孩子端 `getWeeklyRecord` 为空 → 可重测,唯一索引重建记录。
|
|
|
|
### 2. 考试成绩记录管理 `/parent/exam-records`
|
|
|
|
- 同款独立页。查询 `exam_record` join `users`(孩子)+ `exam_paper`(**left join**,卷被删时 title 显示「已删试卷」)。
|
|
- 每行:孩子名 · 试卷标题 · 分数 · 达标 · 日期;编辑(分数+达标)+ 删除(确认)。
|
|
- 删除后孩子端 `getExamRecord` 为空 → 可重考。
|
|
|
|
### 3. 考试试卷管理 `/parent/exams`
|
|
|
|
- 列表页:按月份分组(复用 exam 页 MONTH_LABEL 分组逻辑,固定 g7/s1/math,与孩子端一致),每组内每卷:标题 · 类型徽标 · 题数;编辑/删除按钮;顶部「+ 新建试卷」。
|
|
- 编辑页 `/parent/exams/[paperId]`:元信息表单(标题/考试类型/地区/年份/时长/满分/来源链接/考查说明/月份/序号)+ **题目 JSON 文本域**(初始值 `JSON.stringify(questions, null, 2)`)。
|
|
- 保存时校验(server action):`JSON.parse` → 必须是数组 → 每题形状校验(`stem`/`type`/`answer`/`explain` 非空 + type 条件字段,如 fill 的 `answers`、order/match 的 `answer` 数组、solve 的 `reference`)→ 失败返回具体错误信息不保存。
|
|
- 文本域下方实时显示"共 N 题"统计(客户端解析,失败显示红色提示)。
|
|
- 新建页 `/parent/exams/new`:同表单,paperId 手填(校验格式 `[a-z0-9-]+`、唯一),科目/年级/学期/月份/序号默认值。
|
|
- 删除试卷:允许(记录 left join 已容错);孩子端 `/exam` 列表即时消失,已打开的卷页 404。
|
|
|
|
### 4. parent/actions.ts 新增 6 个 action(全部家长身份 + 家庭归属校验)
|
|
|
|
| action | 说明 |
|
|
| --- | --- |
|
|
| `updateWeeklyRecord(id, score, passed)` / `deleteWeeklyRecord(id)` | 周测记录;按 id 查 childUserId → 归属校验 |
|
|
| `updateExamRecord(id, score, passed)` / `deleteExamRecord(id)` | 考试记录;同上 |
|
|
| `saveExamPaper(formData)` | 新增/更新试卷(带 paperId 唯一性检查 + 题目 JSON 校验) |
|
|
| `deleteExamPaper(paperId)` | 删除试卷(仅家长 + 本家庭无需校验——试卷非家庭私有,家长即可) |
|
|
|
|
- 编辑/删除周测与考试记录后 `revalidatePath("/parent")` + 对应管理页;试卷保存后 `revalidatePath("/parent/exams")` + `revalidatePath("/exam")`(孩子端立即生效)。
|
|
|
|
### 5. 不改动
|
|
|
|
- DB schema(三张表已有足够的字段)、`weekly/actions.ts`、`exam/actions.ts`、`lib/weekly.ts`、孩子端任何页面。
|
|
- 积分/打卡链路不动。
|
|
|
|
## 测试清单(手工,项目无自动化测试框架)
|
|
|
|
1. 课程管理 Section:三张入口卡片(周测管理/考试记录管理/试卷管理)替代原只读周测块。
|
|
2. 周测管理:编辑分数/达标 → 显示更新;删除 → 记录消失,孩子端 weekly 页可重测;越权孩子 id 篡改 → 拒绝。
|
|
3. 考试记录管理:编辑/删除生效;删除试卷后再看记录 → 标题显示「已删试卷」。
|
|
4. 试卷管理:新建试卷(JSON 合法)→ 孩子端 /exam 立即出现;编辑保留;JSON 非法 → 报错不保存;删除 → 孩子端消失;paperId 重复 → 报错。
|
|
5. 孩子达标积分/当日打卡在编辑周测/考试记录后不变(不联动,预期行为)。
|
|
6. 部署 jump.hn12301.net 后线上复验。 |