教学仪表盘热力图重构——从AI驱动到教师驱动的知识点管理系统
背景
教学数据中心的热力图原本是 AI 批改作业时自动生成 的:AI 按闭包知识点列表返回 knowledgePoints(掌握度),后端存入 homework_knowledge 表,前端只读渲染。老师无法干预热力图内容。
本次重构目标:把热力图从 AI 自动生成的静态展示,变成老师驱动的动态管理系统——老师创建知识点,AI 批改时按老师定义的知识点对错误进行分类,热力图变成错误聚合 + 交互式筛选入口。
数据流改造对比
1 | 旧:AI 批改 → knowledgePoints(封闭列表) → homework_knowledge → 热力图 |
核心改动
1. 数据库
| 操作 | 表名 | 说明 |
|---|---|---|
| 新建 | teacher_knowledge |
老师自定义知识点(class_id, name, color, sort_order) |
| 新建 | submission_errors |
错误分类明细(error_text, knowledge_point, severity) |
| 删除 | homework_knowledge |
旧表废弃 |
2. SKILL.md 改造
errors[]和suggestions[]增加knowledgePoint字段- 教师定义知识点优先:提供了就用,未提供/空则全部归「其他」
- 删除了旧的闭包知识点列表
3. Entity / Mapper
- 新增
TeacherKnowledge、TeacherKnowledgeMapper - 新增
SubmissionError、SubmissionErrorMapper - 删除
HomeworkKnowledge、HomeworkKnowledgeMapper DashboardServiceImpl.KP_CANONICAL(知识点评分名称归一化 Map)删除
4. Controller / Service
GET /api/dashboard/knowledge-mastery:从teacher_knowledge+submission_errors聚合,老师定义优先,自动补「其他」GET /api/dashboard/frequent-errors:增加knowledgePoint筛选参数,去掉缓存(避免新 key 没被清理的问题)POST /api/dashboard/teacher-knowledge/add:单条添加DELETE /api/dashboard/teacher-knowledge/{id}:单条删除POST /api/dashboard/teacher-knowledge/batch:批量覆盖(编辑模式)saveTeacherKnowledge/addTeacherKnowledge末尾:自动建「其他」+ 关键词重归类 + AI 异步重归类
5. GradingStreamConsumer
- 停写
homework_knowledge - 注入
TeacherKnowledgeMapper+SubmissionErrorMapper buildPrompt:传入该班级老师定义的知识点列表作为 AI 上下文saveSubmissionErrors:解析 AI 返回的errors[].knowledgePoint+suggestions[].knowledgePoint,逐条写入submission_errors
6. 前端(PageFour.vue)
- 热力图:展示错误数,不再展示掌握度百分比
- 添加知识点弹窗:输入名称 + 选颜色 → 调 POST add 直接入库
- 编辑模式:每格可改名称/颜色/删除,「其他」删除按钮禁用
- 保存按钮:批量覆盖 + 触发重归类轮询
- 点击热力图格子:弹窗展示该知识点的错误列表
遇到的问题与解决
问题 1:@Cacheable 新 key 未被清理
现象:getFrequentErrors(classId, knowledgePoint) 加了 knowledgePoint 参数后,缓存 key 从 errors:1 变成 errors:1:其他,但 GradingStreamConsumer 里只清理了 errors:1,导致新 key 缓存了空结果永远不更新。
解决:去掉 getFrequentErrors 的 @Cacheable 注解。该接口入参组合太多,不缓存更简单。
问题 2:knowledge_point = NULL 查不出数据
现象:SubmissionErrorMapper.selectByClassIdAndKnowledgePoint(classId, null, 50) 生成的 SQL 是 WHERE knowledge_point = NULL,在 SQL 里永远为假。
解决:改用 MyBatis 动态 SQL <if test='knowledgePoint != null'>,null 时不拼接该条件。
问题 3:保存时「其他」被重复插入
现象:saveKnowledge 把 knowledgeMastery 整个数组传给后端批量保存,混入了后端动态生成的「其他」项,触发 uk_class_knowledge 唯一约束冲突。
解决:改为单条操作(add/delete 各调独立接口),编辑模式批量保存时从数组里分离「其他」不再 filter,因为「其他」已由后端 ensureOtherExists() 统一管理。
问题 4:「其他」重复出现在热力图
现象:getKnowledgeMastery() 里 teacher_knowledge 已有「其他」的情况下,又追加了一次合成版「其他」。
解决:增加 hasOtherInTk 判断,teacher_knowledge 里有就不补合成版。
问题 5:数据库文件编码损坏
现象:用 PowerShell Set-Content 做字符串替换后,Java 文件的 import 语句被破坏,中文注释乱码。
解决:通过 write 工具重写整个文件,避免 PowerShell 编码副作用。
重归类机制
1 | 老师保存知识点 |
前端反馈:保存后 toast 提示,轮询「其他」错误数变化,减少时通知用户。
废弃删除清单
| 项目 | 处理 |
|---|---|
homework_knowledge 表 |
DROP TABLE |
HomeworkKnowledge.java |
删除文件 |
HomeworkKnowledgeMapper.java |
删除文件 |
KP_CANONICAL 静态块 |
删除 |
GradingStreamConsumer 写入旧表代码 |
删除 |
HomeworkResultService 知识点方法 |
删除,改用 SubmissionErrorMapper |
SubmissionService 未使用方法 |
清理 |
API 变更汇总
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/dashboard/knowledge-mastery |
改造:从 teacher_knowledge + submission_errors 聚合 |
GET |
/api/dashboard/frequent-errors |
增加 ?knowledgePoint= 可选参数 |
GET |
/api/dashboard/teacher-knowledge |
新增:查询老师自定义知识点 |
POST |
/api/dashboard/teacher-knowledge/add |
新增:单条添加 |
DELETE |
/api/dashboard/teacher-knowledge/{id} |
新增:单条删除 |
POST |
/api/dashboard/teacher-knowledge/batch |
新增:批量覆盖 |
