Files
NextEdu/docs/superpowers/specs/2026-06-23-lesson-preparation-usage-fixes-design.md
SpecialX e4254f0f8e docs: update architecture map and add lesson-preparation usage fixes design
- 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
2026-06-24 12:01:35 +08:00

196 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 备课模块使用问题修复设计
> **日期**2026-06-23
> **前置文档**[2026-06-22-lesson-preparation-anchor-canvas-design.md](./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 无权限/路由 无权限/路由
```
## 二、功能定位
### 备课模块核心闭环
1. **教师备课**:选定教材+章节 → 锚点画布编辑 → 保存版本 → **发布**
2. **学生查看**:按班级可见 published 课案,只读画布视图
3. **家长查看**:通过孩子关系自动可见 published 课案
4. **教研监督**:教研组长/年级主任查看本年级教师备课(只读)
5. **管理员管理**:全校课案列表 + 统计
## 三、角色使用矩阵
| 角色 | 权限 | 路由 | 视图 |
|------|------|------|------|
| 教师 | 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`
```typescript
export async function publishLessonPlan(planId: string, userId: string): Promise<void>
export async function unpublishLessonPlan(planId: string, userId: string): Promise<void>
```
**actions 新增**`actions.ts`
```typescript
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.anchorId`
- `fromRfEdges``e.data?.anchorId` 读取
**P1-4 修复锚点边颜色**
- `rf-mappers.ts` 导入 `getNodeColor`
- `toRfEdges``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.unpublish`
- `action.publishConfirm` / `action.unpublishConfirm`
- `action.publishSuccess` / `action.unpublishSuccess`
- `status.published` / `status.draft` / `status.archived`
- `readonly.title` / `readonly.hint`
- `admin.title` / `admin.stats` / `admin.totalPlans` / `admin.publishedPlans`
- `gradeHead.title`
- `anchor.selectNode` / `anchor.createNode` / `anchor.nodeTypePrompt`
## 八、架构文档同步
- `004_architecture_impact_map.md`:补充路由、权限、新组件
- `005_architecture_data.json`:补充 routes、permissions、exports
## 九、验证标准
- `npx tsc --noEmit` 零错误
- `npm run lint` 零错误
- 教师可发布课案,学生/家长可查看 published 课案
- 教研组长可查看本年级教师备课
- 锚点交互完整可用(选中文本 → 选择节点 → 创建锚点)
- 锚点边颜色与关联节点一致