备课模块审计报告 v5
审计日期:2026-07-03
审计范围:src/modules/lesson-preparation/ 场景覆盖度维度(区别于 v4 的架构合规维度)
审计依据:用户实际备课工作流反馈 + v4 审计报告 + K12 行业产品对标(Planboard / Nearpod / Common Curriculum)
前序报告:lesson-preparation-audit-report-v4.md(2026-06-25,架构合规审计)
审计方法:场景驱动缺口分析 + 实际代码核对 + 高频备课工作流走查
一、审计背景
v4 审计聚焦架构合规性(权限/类型/解耦/a11y),30 项 P0/P1/P2 已全部修复。M1-M12 中长期计划已部分实施(M1 课标 / M2 评论 / M3 审核 / M4 课程地图 / M5 形成性 / M6 附件表 / M8 AI 评估 / M9 日历 / M10 分析 / M11 diff / M12 代课)。
但用户反馈显示:M1-M12 虽建了数据层,UI 集成度不够(M6 附件表无 UI、M9 日历不绑课表、M2 评论无协同编辑),且完全遗漏了 4 项核心能力(导出/打印、撤销/重做、多媒体嵌入、发布前预览)。
v5 审计聚焦"场景覆盖度"维度,对照教师日常备课工作流识别缺口。
二、教师备课工作流与模块覆盖度
2.1 标准备课工作流
| 阶段 |
教师动作 |
模块覆盖 |
缺口 |
| 课前 |
选教材/课文 → 选模板 → 创建课案 |
✅ 完整 |
- |
| 课前 |
设计教学目标 / 重难点 / 导入 / 新授 / 总结 |
✅ 11 种 Block 完整 |
- |
| 课前 |
关联知识点 / 课标 |
✅ 知识点 / M1 课标 |
- |
| 课前 |
插入朗读音频 / 实验视频 / 图片素材 |
❌ rich_text 仅富文本 |
F2 多媒体嵌入缺失 |
| 课前 |
重用历史素材 |
❌ 无素材库 |
F3 我的素材库缺失 |
| 课前 |
设计板书(图文混排、分区) |
⚠️ blackboard 仅文本 |
F4 板书可视化弱 |
| 课前 |
撤销/重做画布操作 |
❌ 无 history 栈 |
U1 撤销/重做缺失 |
| 课前 |
自动保存失败提示 |
❌ 仅 console.error |
S1 UI 兜底缺失 |
| 课前 |
题库选题 → 一键发布作业 |
⚠️ 无预览步骤 |
W2 发布前预览缺失 |
| 课前 |
导出 PDF / 打印教案 |
❌ 完全缺失 |
F1 导出/打印缺失 |
| 课中 |
学生查看发布课案 |
✅ 只读视图 |
- |
| 课后 |
教学反思 + 二次备课 |
⚠️ reflection 节点存在,无锁定/diff |
T2 反思闭环不完整 |
2.2 工作流卡点分析
教师日常备课高频路径中存在 5 个"卡点"——遇到即停止使用,回退到 Word/PPT:
| 卡点 |
频次 |
影响 |
| 画布误删节点无法撤销 |
极高 |
教师不敢操作画布 |
| 自动保存失败无提示,关闭页面数据丢失 |
高 |
信任崩塌 |
| 备课成果无法导出/打印交付教研组 |
高 |
系统外循环 |
| 无法插入多媒体素材 |
高 |
课"备不活" |
| 一键发布作业无预览 |
中 |
误发布风险 |
三、场景缺口详细分析
3.1 S1 - 自动保存失败 UI 兜底(🔴 极紧急)
- 位置:lesson-plan-editor.tsx L97-116
- 现状:自动保存失败仅
console.error("[LessonPlanEditor] auto-save failed", e),UI 无任何提示
- 后果:
- 教师关闭页面时数据丢失(beforeunload 仅检查 isDirty,不区分"保存失败"与"未触发保存")
- 断网场景下教师继续编辑,所有改动静默丢失
- 违反需求:用户 §五"怕丢数据:必须要有强自动保存,以及断网恢复提示"
3.2 U1 - 撤销/重做(🔴 极紧急)
- 位置:editor-slice.ts 全文
- 现状:Zustand store 无 history 栈,所有 mutation 直接 set
- 后果:
- 画布上误删一个节点,只能去版本抽屉回滚到 30 分钟前的状态
- 教师不敢操作画布,回退到列表式备课
- 违反需求:用户 §三.5"撤销/重做:画布操作没有撤销,简直没法用。必须支持至少 50 步撤销"
3.3 W2 - 发布前作业单预览(🔴 极紧急)
- 位置:publish-homework-dialog.tsx 全文
- 现状:对话框仅选班级 + 时间,点击"发布"直接调用 service.publishLessonPlanHomework
- 缺失:
- 无题目列表预览(题干/选项/答案/分值)
- 无总分预览
- 无班级学生数提示
- 无"返回修改"步骤
- 后果:一键发布到学生/家长端,误发布无法收回
- 违反需求:用户 §五"怕误发布:发布前必须有预览"
3.4 F1 - 导出/打印(🔴 极紧急)
- 位置:全模块无导出/打印相关代码
- 现状:画布做得再好,备课成果无法走出系统
- 缺失:
- 无 PDF 导出
- 无打印视图
- 无"详细版/简洁版"切换
- 后果:教研组检查无纸质交付,教师回退到 Word
- 违反需求:用户 §二.1"没有导出,备课成果无法走出系统"
3.5 F2/F3 - 多媒体嵌入 + 我的素材库(🔴 极紧急)
- 位置:
- 现状:rich_text 节点不支持图片/音视频;M6 附件表与 UI 完全断链
- 后果:
- 教师无法插入朗读音频 / 实验视频 / PPT 截图
- 每次都得从本地重新上传,无沉淀
- 违反需求:用户 §二.2"这决定了我能不能把课'备活'"
四、改进方案与实施
4.1 第一阶段实施(v5 P0,本次完成)
| ID |
缺口 |
实施方案 |
验收标准 |
| V5-1 |
S1 自动保存失败 UI 兜底 |
editor 添加 saveError 状态 + toast 提示 + 在线状态监听 + 重试按钮 |
断网时 toast 显示"保存失败",恢复时 toast 显示"已恢复在线" |
| V5-2 |
U1 撤销/重做 |
新增 hooks/history-slice.ts(past/future 栈,50 步上限)+ 编辑器顶部 Undo/Redo 按钮 + Cmd/Ctrl+Z / Cmd+Shift+Z 快捷键 |
误删节点后 Cmd+Z 可恢复 |
| V5-3 |
W2 发布前作业单预览 |
publish-homework-dialog 改为 3 步流程(选班级 → 预览题目+总分+学生数 → 确认发布) |
发布前可见所有题干、选项、答案、分值、班级学生数 |
| V5-4 |
F1 导出/打印 |
新增 lib/export.ts(文档扁平化)+ components/print-view.tsx(打印视图)+ 编辑器"导出/打印"按钮 + 详细版/简洁版切换 |
浏览器打印对话框可保存为 PDF,含教材/教师/班级信息 |
| V5-5 |
F2/F3 多媒体嵌入 + 素材库 |
rich-text-block 集成 Tiptap Image 扩展 + 新增 components/attachment-picker.tsx 附件库 picker + 集成 M6 附件表 |
可在 rich_text 中插入图片,从素材库选择已有附件 |
4.2 第二阶段计划(v5 P1,本次仅记录)
| ID |
缺口 |
优先级 |
| V5-6 |
W1 题库组卷预览(题干展开) |
🟠 |
| V5-7 |
W3/W4 课案绑定课时 |
🟠 |
| V5-8 |
U2 画布自动布局 |
🟠 |
| V5-9 |
F5 教材模糊搜索 + 最近使用 |
🟠 |
| V5-10 |
P1 大课案画布性能压测 |
🟠 |
4.3 第三阶段计划(v5 P2,本次仅记录)
| ID |
缺口 |
优先级 |
| V5-11 |
R3 协同编辑(Yjs/Liveblocks 评估) |
🟡 |
| V5-12 |
R4 校内课案库 |
🟡 |
| V5-13 |
P3 移动端只读视图 |
🟡 |
| V5-14 |
F4 板书可视化工具 |
🟡 |
| V5-15 |
T1 教学阶段分组 |
🟡 |
| V5-16 |
T2 反思闭环 |
🟡 |
| V5-17 |
A1/A2 AI 反馈闭环 + 解释性 |
🟡 |
4.4 第四阶段计划(v5 P3,本次仅记录)
| ID |
缺口 |
优先级 |
| V5-18 |
W6 差异化教学标记 |
🟢 |
| V5-19 |
T3 目标-评价一致性 |
🟢 |
| V5-20 |
T4 教师端课标热力图 |
🟢 |
| V5-21 |
A3/A4/A5 AI 差异化生成 + 课标实时核对 + 评估可解释 |
🟢 |
五、架构影响
5.1 新增文件
| 文件 |
用途 |
hooks/history-slice.ts |
Zustand history slice(past/future 栈,50 步上限) |
lib/export.ts |
文档扁平化导出工具(详细版/简洁版) |
components/print-view.tsx |
打印视图组件(含教材/教师/班级信息) |
components/attachment-picker.tsx |
附件库 picker(集成 M6 附件表) |
5.2 修改文件
| 文件 |
修改内容 |
hooks/use-lesson-plan-editor.ts |
组合 history slice |
hooks/editor-slice.ts |
mutation 方法包装 history 推送 |
components/lesson-plan-editor.tsx |
自动保存失败 UI 兜底 + Undo/Redo 按钮 + 快捷键 + 导出按钮 |
components/publish-homework-dialog.tsx |
3 步发布流程(选班级 → 预览 → 确认) |
components/blocks/rich-text-block.tsx |
集成 Tiptap Image 扩展 + 附件库入口 |
shared/i18n/messages/zh-CN/lesson-preparation.json |
新增 undo/redo/export/print/saveError 等键 |
shared/i18n/messages/en/lesson-preparation.json |
同步英文翻译 |
5.3 架构图同步
修改 docs/architecture/004_architecture_impact_map.md §2.27 章节末尾追加"V5 场景缺口修复"小节。
修改 docs/architecture/005_architecture_data.json modules.lesson_preparation.auditFixes 新增 V5-1 至 V5-5 条目。
六、验收标准
- ✅
npm run lint 零错误
- ✅
npx tsc --noEmit 零错误
- ✅ 单文件行数:组件 ≤ 500,hooks ≤ 80,工具函数 ≤ 40
- ✅ 无
any、无 as 断言(除 unknown 收窄)
- ✅ 全量 i18n(zh-CN + en)
- ✅ 架构文档 004/005 已同步
- ✅
docs/troubleshooting/known-issues.md 已记录
v5 审计完成。本次实施第一阶段 V5-1 至 V5-5 共 5 项场景缺口修复。
七、V5 第二阶段实施结果(2026-07-03 续)
7.1 已完成清单
| ID |
缺口 |
状态 |
实施摘要 |
| V5-6 |
W1 题库组卷预览 |
✅ |
exercise-block.tsx 增加组卷预览模式 |
| V5-7 |
W3/W4 课案绑定课时 |
✅ |
新增 data-access-schedules.ts + actions-schedules.ts + schedule-dialog.tsx + lesson_plan_schedules 表 |
| V5-8 |
U2 画布自动布局 |
✅ |
新增 lib/auto-layout.ts(@dagrejs/dagre,复用已安装依赖) |
| V5-9 |
F5 教材模糊搜索 + 最近使用 |
✅ |
template-picker.tsx 增加客户端模糊搜索 + localStorage 最近使用 |
| V5-10 |
P1 大画布性能优化 |
✅ |
node-editor.tsx ReactFlow onlyRenderVisibleElements + zoom 限制 |
| V5-12 |
R4 校内课案库 |
✅ |
新增 teacher/lesson-plans/library 路由 + duplicateLessonPlanFormAction |
| V5-13 |
P3 移动端只读视图 |
✅ |
新增 lesson-plan-mobile-view.tsx + useMediaQuery 切换 |
| V5-14 |
F4 板书可视化工具 |
✅ |
blackboard-block.tsx 增加轻量级可视化预览(不引入新库,纯 CSS + 文本解析) |
| V5-15 |
T1 教学阶段分组 |
✅ |
types.ts TeachingStage 类型 + node-edit-panel 选择器 |
| V5-16 |
T2 反思闭环 |
✅ |
新增 lib/version-diff.ts 纯函数 + version-diff-view 组件 + 抽屉集成 |
| V5-17 |
A1/A2 AI 反馈闭环 |
✅ |
新增 lib/ai-feedback.ts 纯服务端函数 + ai-feedback-dialog + 工具栏集成 |
| V5-18 |
W6 差异化教学标记 |
✅ |
types.ts DifferentiationLevel 类型 + node-edit-panel 选择器 |
| V5-19 |
T3 一致性校验 |
✅ |
新增 lib/consistency-check.ts 纯函数 + consistency-check-dialog + 工具栏集成 |
| V5-20 |
T4 课标热力图 |
✅ |
新增 lib/curriculum-coverage.ts 纯函数 + curriculum-heatmap + teacher/lesson-plans/heatmap 路由 |
| V5-21 |
A3/A4/A5 AI 差异化 |
✅ |
新增 lib/ai-differentiation.ts 3 个纯服务端函数 + ai-differentiation-dialog(3 Tab) + 4 个 server actions + 工具栏集成 |
7.2 待规划
| ID |
缺口 |
状态 |
备注 |
| V5-11 |
R3 协同编辑 |
🟡 长远计划 |
详见 §7.5 Yjs 方案评估(2026-07-03 评估,因架构改造复杂度高暂不实施) |
7.3 i18n 修复
- 修复 zh-CN/en lesson-preparation.json 重复键问题(JSON 后者覆盖前者)
- 新增命名空间:
editor.stage*/editor.differentiation*/editor.consistency*/consistency.*/diff.*/library.*/feedback.*/heatmap.*/aiDifferentiation.*/blackboard.editMode/previewMode/editHint/previewEmpty/untitled
7.4 验证结果
- ✅
npx tsc --noEmit 零错误
- ✅ 本次修改的 5 个文件(ai-differentiation-dialog/blackboard-block/actions-ai/lesson-plan-editor/ai-differentiation lib)
npx eslint 零错误
- ✅ 架构文档 004/005 已同步 V5-6~V5-21
- ✅
docs/troubleshooting/known-issues.md 新增"V5 第二阶段 V5-6~V5-21 通用规则"小节
V5 第二阶段完成 15 项(V5-6~V5-21 除 V5-11),V5-11 作为长远计划记录于 §7.5。
7.5 V5-11 R3 协同编辑长远规划(Yjs + y-websocket 方案)
决策:2026-07-03 评估,因架构改造复杂度高,暂不实施,作为长远计划。
7.5.1 Yjs 工作原理(澄清)
Yjs 是 CRDT(无冲突复制数据类型) 库,不是邮箱/消息系统,而是实时状态同步机制。当 A 老师在编辑器输入"导入",B 老师的屏幕上立刻出现"导入"——这是实时同步,不是发消息。
- Yjs:CRDT 数据结构库,保证多端最终一致性
- y-websocket:传输层,需要独立的 WebSocket 服务器作为中转
- y-prosemirror:Yjs 与 ProseMirror(Tiptap 底层)的绑定,让富文本编辑器支持多人光标
7.5.2 与当前项目的关键冲突
| 冲突点 |
当前项目 |
Yjs 要求 |
| 服务器类型 |
Next.js HTTP |
需独立 WebSocket 服务器进程 |
| 持久化 |
Drizzle ORM + MySQL |
Yjs document 状态需独立持久化(LevelDB 或自定义 adapter) |
| 权限校验 |
Server Actions + requirePermission |
WS 连接时需校验 JWT/session |
| 编辑器状态 |
Zustand store(editor-slice) |
Yjs document 作为真相源,Zustand 降级为视图层 |
| 数据结构 |
LessonPlanDocument JSON |
Yjs.XmlFragment(Tiptap 文档)或 Yjs.Map |
7.5.3 推荐架构(未来实施时)
- WS 服务器部署:项目内独立进程(
server/ws-server.ts,npm run ws 启动,生产环境用 PM2/Docker 管理)
- 协同范围:仅 RichTextBlock(Tiptap)节点实现多人实时协同,其他节点保持单人编辑
- 持久化策略:双写——Yjs document 作为实时层,每隔 N 秒(或用户离开时)将状态序列化为 JSON 写入
lessonPlans.content,兼容现有数据结构
- 权限校验:WS 连接握手时校验 JWT,按 planId 校验
LESSON_PLAN_UPDATE 权限
7.5.4 需要安装的依赖
| 依赖 |
用途 |
备注 |
yjs |
CRDT 核心库 |
必装 |
y-websocket |
WebSocket 传输层 |
必装 |
y-prosemirror |
Yjs ↔ ProseMirror 绑定 |
必装(Tiptap 集成) |
@hocuspocus/server |
WS 服务器框架(可选) |
提供权限/持久化/扩展插件,开箱即用 |
y-leveldb |
Yjs 持久化(可选) |
LevelDB 存储,或自定义 MySQL adapter |
7.5.5 替代方案
若未来评估认为 Yjs 复杂度过高,可考虑轻量协作方案作为替代:
- 不引入实时协同库
- 复用现有 messaging/notifications 模块 + V5-16 版本对比
- 实现「Block 级评论 + @提醒 + 版本对比」
- 无需新依赖,开发快,与项目现有架构契合