- Update architecture impact map (004) and data (005) with new modules - Add lesson-preparation usage fixes design spec - Add teacher web test post-audit report
8.1 KiB
8.1 KiB
备课模块使用问题修复设计
日期:2026-06-23 前置文档:2026-06-22-lesson-preparation-anchor-canvas-design.md 审计来源:深度分析备课模块现状后发现的使用问题
一、问题背景
备课模块 v3 锚点画布重构已完成,但实际使用中存在 15 个问题(3 个 P0 阻塞性 + 6 个 P1 严重 + 6 个 P2 一般),导致核心流程断裂、角色使用不完整。
核心闭环断裂
教师备课 → 发布课案 → 学生查看 → 家长查看
↑ ❌ P0-1 ❌ P0-2/3 ❌ P0-2/3
无"发布"action 无权限/路由 无权限/路由
二、功能定位
备课模块核心闭环
- 教师备课:选定教材+章节 → 锚点画布编辑 → 保存版本 → 发布
- 学生查看:按班级可见 published 课案,只读画布视图
- 家长查看:通过孩子关系自动可见 published 课案
- 教研监督:教研组长/年级主任查看本年级教师备课(只读)
- 管理员管理:全校课案列表 + 统计
三、角色使用矩阵
| 角色 | 权限 | 路由 | 视图 |
|---|---|---|---|
| 教师 | CREATE/READ/UPDATE/DELETE/PUBLISH | /teacher/lesson-plans |
完整编辑画布 + 发布按钮 |
| 学生 | READ(仅 published) | /student/lesson-plans/[planId]/view |
只读画布视图 |
| 家长 | READ(仅孩子的 published) | /parent/lesson-plans/[planId]/view |
只读画布视图 |
| 管理员 | 全部 | /admin/lesson-plans |
全校课案列表 + 统计 |
| 教研组长 | READ(本年级教师) | /grade-head/lesson-plans |
本年级教师课案列表(只读) |
| 年级主任 | READ(本年级教师) | /teaching-head/lesson-plans |
同上 |
学生查看视图设计
只读画布视图:复用 React Flow,配置:
nodesDraggable={false}nodesConnectable={false}elementsSelectable={true}(可点击查看节点详情)panOnDrag={true}、zoomOnScroll={true}(可缩放平移)
保留正文+节点+锚点的完整视觉关系,学生可缩放平移但不可编辑。
发布机制
- 发布到班级所有学生,家长通过孩子关系自动可见
- 状态流转:
draft→published(发布)→draft(撤回)或archived(归档) - 发布后学生/家长立即可见,撤回后立即不可见
四、修复范围(P0+P1 优先)
P0 阻塞性问题
| 编号 | 问题 | 修复方案 |
|---|---|---|
| P0-1 | 无"发布课案"action | 新增 publishLessonPlanAction / unpublishLessonPlanAction |
| P0-2 | 学生/家长无权限 | 给 student/parent 添加 LESSON_PLAN_READ 权限 |
| P0-3 | 无学生/家长/管理员路由 | 新增路由 + 导航入口 |
P1 严重问题
| 编号 | 问题 | 修复方案 |
|---|---|---|
| P1-1 | 锚点节点选择器占位 | 完善 AnchorNodeSelector,接收节点列表 + 实现"锚定到新节点" |
| P1-2 | 锚点偏移计算不可靠 | 改用 markdownToPlainText 搜索定位,支持跨段落 |
| P1-3 | 边回写丢失 anchorId | anchorId 存入 edge.data,fromRfEdges 从 data 读取 |
| P1-4 | 锚点边颜色无区分 | 使用 getNodeColor(anchor.nodeId) |
| P1-5 | 教研组长无权限 | 给 grade_head/teaching_head 添加 LESSON_PLAN_READ 权限 |
| P1-6 | 个人模板不显示 | TemplatePicker 调用 getLessonPlanTemplatesAction 合并显示 |
P2 一般问题(本次顺带修复)
| 编号 | 问题 | 修复方案 |
|---|---|---|
| P2-1 | 正文节点侧边面板提示误导 | 改为"请在画布上直接操作正文"或显示锚点列表 |
| P2-5 | 默认骨架节点位置重叠 | 增大列间距,避免与正文节点重叠 |
五、实施阶段
阶段 1:权限与路由基础(P0-2、P0-3、P1-5)
权限修改(shared/lib/permissions.ts):
- student 数组添加
Permissions.LESSON_PLAN_READ - parent 数组添加
Permissions.LESSON_PLAN_READ - grade_head 数组添加
Permissions.LESSON_PLAN_READ - teaching_head 数组添加
Permissions.LESSON_PLAN_READ
路由新增:
app/(dashboard)/student/lesson-plans/page.tsx— 课案列表(按班级 published)app/(dashboard)/student/lesson-plans/[planId]/view/page.tsx— 只读画布app/(dashboard)/parent/lesson-plans/page.tsx— 课案列表(按孩子 published)app/(dashboard)/parent/lesson-plans/[planId]/view/page.tsx— 只读画布app/(dashboard)/admin/lesson-plans/page.tsx— 全校课案列表 + 统计app/(dashboard)/admin/lesson-plans/[planId]/view/page.tsx— 查看任意课案
导航入口(shared/lib/navigation.ts 或 modules/layout/config/navigation.ts):
- student 导航添加"我的课案"
- parent 导航添加"孩子课案"
- admin 导航添加"课案管理"
只读画布组件:
- 新建
components/lesson-plan-readonly-view.tsx - 复用 React Flow,配置只读模式
- 复用
toRfNodes/toRfEdges渲染
阶段 2:发布机制(P0-1)
data-access 新增(data-access.ts):
export async function publishLessonPlan(planId: string, userId: string): Promise<void>
export async function unpublishLessonPlan(planId: string, userId: string): Promise<void>
actions 新增(actions.ts):
export async function publishLessonPlanAction(planId: string): Promise<ActionState<string>>
export async function unpublishLessonPlanAction(planId: string): Promise<ActionState<string>>
UI 修改:
LessonPlanEditor工具栏添加"发布"/"撤回发布"按钮LessonPlanCard添加"发布"/"撤回"操作菜单项- 发布时显示确认对话框
阶段 3:锚点交互完善(P1-1、P1-2、P1-3、P1-4)
P1-1 完善 AnchorNodeSelector:
- 接收
doc.nodes列表(过滤掉 textbook_content) - 渲染节点下拉选择器(显示节点标题 + 颜色标识)
- 实现"锚定到新节点":弹出节点类型选择 → 创建节点 → 自动锚定
P1-2 修复锚点偏移计算:
handleMouseUp改用Range.toString()获取选中文本- 在
markdownToPlainText(content)中搜索定位 start/end 偏移 - 支持跨段落、跨行内元素的选择
P1-3 修复 fromRfEdges anchorId 丢失:
toRfEdges时将anchorId存入edge.data.anchorIdfromRfEdges从e.data?.anchorId读取
P1-4 修复锚点边颜色:
rf-mappers.ts导入getNodeColortoRfEdges中stroke: getNodeColor(anchor.nodeId)
阶段 4:模板与体验(P1-6 + P2)
P1-6 TemplatePicker 显示个人模板:
- 初始化时调用
getLessonPlanTemplatesAction() - 合并系统模板和个人模板展示
- 个人模板标记"个人"徽章
P2-1 修复正文节点侧边面板:
NodeEditPanel选中 textbook_content 时显示锚点列表- 或显示提示"请在画布上直接操作正文,点击正文选中文本可创建锚点"
P2-5 优化默认骨架节点位置:
- 增大列间距,左列 x=80,右列 x=900
- 正文节点居中 (500, 250)
六、数据模型变更
无数据模型变更。发布机制仅修改 lessonPlans.status 字段(已存在)。
七、i18n 键新增
zh-CN / en grades 命名空间(lesson-preparation.json)
action.publish/action.unpublishaction.publishConfirm/action.unpublishConfirmaction.publishSuccess/action.unpublishSuccessstatus.published/status.draft/status.archivedreadonly.title/readonly.hintadmin.title/admin.stats/admin.totalPlans/admin.publishedPlansgradeHead.titleanchor.selectNode/anchor.createNode/anchor.nodeTypePrompt
八、架构文档同步
004_architecture_impact_map.md:补充路由、权限、新组件005_architecture_data.json:补充 routes、permissions、exports
九、验证标准
npx tsc --noEmit零错误npm run lint零错误- 教师可发布课案,学生/家长可查看 published 课案
- 教研组长可查看本年级教师备课
- 锚点交互完整可用(选中文本 → 选择节点 → 创建锚点)
- 锚点边颜色与关联节点一致