feat(portal-shell): 学生域全页面迁移与规范合规修复

- 学生域 32 页全量迁移(含作答/自动保存/提交/诊断)

- 补齐 4 个 MSW mock 缺口,修 diagnostic case 名

- 修 4 处 Tailwind 任意值;新增共享组件与路由
This commit is contained in:
SpecialX
2026-08-31 11:25:21 +08:00
parent 039db5efdd
commit 04b7a40bdc
493 changed files with 70985 additions and 2112 deletions

View File

@@ -1,10 +1,10 @@
# 教师域Teacher待完成功能分析
# 教师域Teacher待完成功能分析
> 参考项目:`e:\desktop\CICD\src\app\(dashboard)\teacher\`53 个 page.tsx
> 当前项目:`e:\Desktop\Edu\apps\portal-shell\src\app\shell\teacher\`53 个 page.tsx
> 规划依据:`apps\portal-shell\ARCHITECTURE.md` §9.1(教师域 56 页B1+B2
> 分析日期2026-07-24
> 分析方式:逐页面对比 CICD 实现 vs portal-shell 实现,逐个读取 page.tsx + features/*-client.tsx
> 参考项目:`e:\desktop\CICD\src\app\(dashboard)\teacher\`CICD 原版,53 个 page.tsx
> 当前项目:`e:\Desktop\Edu\apps\portal-shell\src\app\shell\teacher\`63 个 page.tsx
> 规划依据:`apps\portal-shell\ARCHITECTURE.md` §9.1(教师域 56 页规划B1+B2+B2末
> 分析日期2026-08-04
> 分析方式:逐页面读取 page.tsx 文件内容 + features/*-client.tsx 集成核查 + lib/api hooks + mocks/graphql-data.ts 覆盖核查
---
@@ -13,567 +13,467 @@
1. CICD 单体Next.js App Router + Server Actions + Drizzle作为**功能基线**,反映"老版单体已实现"的教师功能完整态。
2. portal-shell 作为**目标态**,遵循 ARCH §9.1 的契约与批次规划B1+B2+B2末
3. portal-shell 普遍采用「Server Component page.tsx 仅做 `<Suspense>` 边界包裹 + Client Component `*-client.tsx` 承载业务」的统一架构CICD 多为「Server Component 直接拉数据 + Rich Client Component 渲染」。
4. ARCH §9.1 规划 56 页portal-shell 已实现 53 页,**3 页缺口** = `exams/[id]/proctoring`B2末+ `notifications`B1 共享)+ `settings`B1 共享)。
4. ARCH §9.1 规划 56 页portal-shell 已实现 **63 页**(含 5 个路径别名 `/classes/my``/classes/my/[id]``/exams/all``/exams/create``/homework/assignments/create` 复用同一 client+ 3 个占位页 `/classes/students``/exams/grading``/exams/grading/[submissionId]`+ 2 个 ARCH §9.1 原未规划但已补做 `/exams/[id]/proctoring``/diagnostic/student/[studentId]`)。
5. CICD 中 `exams/page.tsx``classes/page.tsx``exams/grading/*``exams/create` 等为**重定向/等价路径**,不算独立功能缺口。
6. CICD 中 `diagnostic/student/[studentId]` 在 ARCH §9.1 中**未规划**ARCH 仅规划 `diagnostic` + `diagnostic/class/[classId]` 共 2 页),属 CICD 历史功能portal-shell 缺失但**不违反 ARCH**。
6. CICD 中 `diagnostic/student/[studentId]` 在 ARCH §9.1 中**未规划**ARCH 仅规划 `diagnostic` + `diagnostic/class/[classId]` 共 2 页),属 CICD 历史功能portal-shell 已补做(**待同步更新 ARCH §9.1 + 004 + arch.db**
### 0.1 三态分类严格定义(本次核查采用)
| 状态 | 定义 | 判据 |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| ✅ 完整实现 | page.tsx 引入并渲染 `features/teacher/*-client.tsx` 客户端组件,或 page.tsx 自身包含真实业务逻辑(调用 lib/api hooks、渲染数据、处理 loading/error/empty 三态) | 文件内 `import``*-client.tsx``<XxxClient />` 渲染;或直接调用 `useXxx` hook |
| 🟡 占位空态 | page.tsx 仅用 `ListPageShell` / `DetailPageShell` / `FormPageShell` / `WorkbenchPageShell` 等 page-templates 直接渲染空态(如 `empty` 属性或无 children 内容),**没有引入任何 `*-client.tsx`,也没有真实业务逻辑** | 文件内仅 `import { ListPageShell } from "@/shared/components/page-templates"`,无 client 组件 |
| ❌ 缺失 | 文件不存在 | 路径下无 page.tsx |
> **重要说明**:本核查的"完整实现"指**页面骨架与数据流闭环**client 组件已集成、hooks 已接入、三态已处理),**不代表与 CICD 功能完全对等**。与 CICD 的功能差距详见 §三.B原 §3.4-§3.18 内容保留,归类为"功能差距"而非"占位空态")。
### 0.2 配套资产核查
| 资产 | 路径 | 覆盖情况 |
| ----------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| features/teacher/*-client.tsx | `src/features/teacher/<module>/` | **55 个页面级 client 组件**(不含 dashboard-cards-client 子组件),覆盖 20 个模块,详见 §七.2 |
| lib/api hooks | `src/lib/api/<module>.ts` | **20 个模块文件**ai/analytics/attendance/classes/course-plans/dashboard/diagnostic/elective/error-book/exams/grades/homework/knowledge-graph/leave/lesson-plans/practice/proctoring/questions/schedule-changes/students/textbooks另含 admin/universal/sidebar/topbar/notifications/settings/profile 等共享域文件) |
| mocks/graphql-data.ts | `src/mocks/graphql-data.ts` | **269KB / 116 个 mock 数据集**(含教师域全部模块 + 学生/家长/管理域),所有占位页与功能差距页均有 MSW 兜底 |
---
## 一、页面完成度总览
| 状态 | 数量 | 说明 |
| --------------------- | ---- | ---------------------------------------------------------------------------------------------------- |
| ✅ 已完成且功能完整 | 33 | 功能与 CICD 持平或为 ARCH 新建且实现完整(含 MSW 兜底契约页) |
| 🟡 已完成但功能不完整 | 14 | 页面存在但子功能/技术栈与 CICD 有差距 |
| ❌ 完全缺失 | 4 | `exams/[id]/proctoring``diagnostic/student/[studentId]``/shell/notifications``/shell/settings` |
| 状态 | 数量 | 说明 |
| ----------- | ------ | ---------------------------------------------------------------------------- |
| ✅ 完整实现 | **60** | page.tsx 集成 `*-client.tsx` 或自身含真实业务逻辑lib/api hook + 三态处理) |
| 🟡 占位空态 | **3** | 仅用 page-templates 渲染空态,无 client 组件集成,无真实业务 |
| ❌ 完全缺失 | **0** | 教师域 63 个 page.tsx 全部存在 |
### ✅ 已完成且功能完整33 页)
### 与原核查2026-07-24的差异
| 模块 | 页面 | 备注 |
| ---------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| dashboard | `/shell/teacher`teacher/page.tsx | 仪表盘4 StatCard + 班级概况 + 预警(注:标题用硬编码中文,违反 i18n但功能完整 |
| exams | `/shell/teacher/exams/[id]/analytics` | 汇总卡片 + 分数段分布图 + 每题正确率 + 学生排名,混合契约 ✅ `assignmentAnalysis` |
| homework | `/shell/teacher/homework/submissions/[submissionId]` | 单份提交批改,含题目分数/教师评语/AI 建议应用/上下导航/总反馈 |
| homework | `/shell/teacher/homework/submissions/[submissionId]/scan-grading` | 扫描批改 |
| homework | `/shell/teacher/homework/submissions` | 提交列表 |
| homework | `/shell/teacher/homework/assignments/[id]/submissions` | 作业子提交列表 |
| homework | `/shell/teacher/homework` | 作业列表 |
| grades | `/shell/teacher/grades` | 成绩列表 |
| grades | `/shell/teacher/grades/analytics` | 成绩分析,汇总 + 分布 + 排名,混合契约 |
| grades | `/shell/teacher/grades/stats` | 成绩统计 |
| grades | `/shell/teacher/grades/report-card` | 报告卡 |
| attendance | `/shell/teacher/attendance` | 考勤列表 |
| attendance | `/shell/teacher/attendance/report` | 考勤报告 |
| attendance | `/shell/teacher/attendance/stats` | 考勤统计 |
| classes | `/shell/teacher/classes` | 班级列表(含 gradeId/subjectId/q 筛选) |
| classes | `/shell/teacher/classes/schedule` | 班级课表 |
| students | (见 🟡 学生列表,因缺科目成绩) | — |
| course-plans | `/shell/teacher/course-plans``/[id]` | 2 页 |
| elective | `/shell/teacher/elective``/create``/[id]/edit` | 3 页 |
| error-book | `/shell/teacher/error-book` | ✅ `errorBookItems/Stats` 真实契约 |
| diagnostic | `/shell/teacher/diagnostic` | 诊断列表 |
| analytics | `/shell/teacher/analytics``/[studentId]` | ARCH 新建 2 页MSW 兜底 |
| ai | `/shell/teacher/ai/ai-assist``/ai-lesson-plan``/ai-report` | ARCH 新建 B2末 3 页,全 MSW 兜底,工作台布局完整 |
| knowledge-graph | `/shell/teacher/knowledge-graph` | ARCH 新建 B2末三栏工作台`knowledgePoint(id)` ✅ 真实 + 列表 MSW |
| questions | `/shell/teacher/questions` | 题库列表,🟡 `question(id)` |
| textbooks | `/shell/teacher/textbooks``/[id]` | 2 页,🟡 `textbook(id)` |
| lesson-plans | `/shell/teacher/lesson-plans``/new``/calendar``/heatmap``/library` | 5 页edit 见 🟡) |
| practice | `/shell/teacher/practice` | 练习 |
| leave | `/shell/teacher/leave` | 请假 |
| schedule-changes | `/shell/teacher/schedule-changes` | 调课 |
| 项目 | 原07-24 | 现08-04 | 变化 |
| -------- | ----------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- |
| 总页面数 | 53 | 63 | +105 别名 + 3 占位 + 2 补做) |
| ✅ 完整 | 33 | 60 | +27原 14 页"功能不完整"实为已集成 client 归入 ✅ + 新补做 2 页 + 新增别名 5 页 - 占位 3 页归 🟡 - 共享域 2 页非教师域) |
| 🟡 占位 | 14 | 3 | -11原 14 页均集成 client 组件归 ✅;新增 3 个真占位页) |
| ❌ 缺失 | 4 | 0 | -4proctoring 与 diagnostic/student 已补做notifications/settings 属共享域非教师域核查范围) |
### 🟡 已完成但功能不完整14 页)
### ✅ 完整实现60 页)
详见 §三。
按模块分布(含别名/复用):
### ❌ 完全缺失4 页)
| 模块 | 页面数 | 页面路径 |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| dashboard | 1 | `/shell/teacher`page.tsx 含 useTeacherDashboard hook + 7 张卡片 + i18n + 三态) |
| ai | 3 | `/ai/ai-assist``/ai/ai-lesson-plan``/ai/ai-report`(全 MSWB2末工作台 |
| analytics | 2 | `/analytics``/analytics/[studentId]`MSW 兜底) |
| attendance | 4 | `/attendance``/report``/sheet``/stats` |
| classes | 5 | `/classes``/classes/my`(别名)、`/classes/[id]``/classes/my/[id]`(别名)、`/classes/schedule` |
| course-plans | 2 | `/course-plans``/course-plans/[id]` |
| diagnostic | 3 | `/diagnostic``/diagnostic/class/[classId]``/diagnostic/student/[studentId]`(已补做) |
| elective | 3 | `/elective``/elective/create``/elective/[id]/edit` |
| error-book | 1 | `/error-book`(✅ errorBookItems/Stats 真实契约) |
| exams | 9 | `/exams``/exams/all`(别名)、`/exams/new``/exams/create`(别名)、`/exams/[id]``/exams/[id]/analytics``/exams/[id]/build``/exams/[id]/edit``/exams/[id]/proctoring`(已补做) |
| grades | 5 | `/grades``/grades/analytics``/grades/entry``/grades/report-card``/grades/stats` |
| homework | 8 | `/homework``/homework/new``/homework/assignments/create`(别名)、`/homework/[id]``/homework/assignments/[id]/submissions``/homework/submissions``/homework/submissions/[submissionId]``/homework/submissions/[submissionId]/scan-grading` |
| knowledge-graph | 1 | `/knowledge-graph`B2末混合契约 knowledgePoint ✅) |
| leave | 1 | `/leave` |
| lesson-plans | 6 | `/lesson-plans``/lesson-plans/new``/lesson-plans/calendar``/lesson-plans/heatmap``/lesson-plans/library``/lesson-plans/[planId]/edit` |
| practice | 1 | `/practice` |
| questions | 1 | `/questions` |
| schedule-changes | 1 | `/schedule-changes` |
| students | 1 | `/students`(原 /classes/students 已迁到顶级) |
| textbooks | 2 | `/textbooks``/textbooks/[id]` |
详见 §二
> **注**:原"🟡 已完成但功能不完整"的 14 页dashboard、exams/page、exams/[id]、exams/new、exams/[id]/edit、exams/[id]/build、classes/[id]、classes/page、students、homework/[id]、homework/new、lesson-plans/[planId]/edit、grades/entry、attendance/sheet、diagnostic/class/[classId])均**已集成真实 client 组件**,按本次严格三态定义归入 ✅;其与 CICD 的功能差距见 §三.B§3.4-§3.18 保留原核查的详细对比分析)
### 🟡 占位空态3 页)
详见 §三.A§3.1-§3.3)。
### ❌ 缺失0 页)
教师域 63 个 page.tsx 全部存在,无缺失。
> **共享域说明**:原 `/shell/notifications` 与 `/shell/settings` 为 B1 共享页(非教师域独有),不属于本次教师域核查范围。如需补做,应在 `/shell/notifications/page.tsx` 与 `/shell/settings/page.tsx` 实现,供所有角色共用。
---
## 二、缺失页面清单
### 2.1 `/shell/teacher/exams/[id]/proctoring`(监考工作台)
### 2.1 教师域缺失页面
**无缺失**。教师域 63 个 page.tsx 全部存在。
### 2.2 已补做的原"缺失"页面(相对 2026-07-24 核查)
#### 2.2.1 `/shell/teacher/exams/[id]/proctoring`(监考工作台)— ✅ 已补做
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\exams\[id]\proctoring\page.tsx`
- **功能描述**:实时监考面板,包含 `ProctoringDashboard` 组件,并行拉取:
- `getExamForProctoring(id)` — 考试基础信息
- `getExamProctoringSummary(id)` — 监考汇总(应到/实到/异常数
- `getStudentProctoringStatuses(id)` — 学生实时状态列表
- `getRecentProctoringEvents(id, 20)` — 最近 20 条监考事件
- **技术栈**Server Component + `requirePermission(Permissions.EXAM_PROCTOR)` + `ProctoringDashboard` 客户端组件(实时 WS 推送)
- **ARCHITECTURE.md 契约**schema 无,需 WS 契约工单 + MSW 先行)
- **批次**B2 末二期WS
- **建议**:✅ 必须补做。需先定 WS 协议契约push-gateway再写 MSW mock最后实现 `ProctoringDashboard` 客户端组件。这是 B2末 明确规划页。
- **portal-shell 现状**`exams/[id]/proctoring/page.tsx` + `features/teacher/exams/proctoring-client.tsx`
- **实现状态**:✅ page.tsx 引入 `ProctoringClient``<Suspense fallback={<WorkbenchPageSkeleton />}>` 包裹client 组件使用 `useExamProctoring` / `useStudentProctoringStatuses` / `useRecentProctoringEvents` 三个 Apollo hook全 MSW 兜底);通过 5s 轮询模拟实时刷新,后端补齐 WS subscription 后切换。
- **ARCHITECTURE.md 契约**schema 无,需 WS 契约工单 + MSW 先行,已 MSW 兜底
- **批次**B2 末二期WS— MSW 阶段已完成,待 WS 契约就绪后切换。
### 2.2 `/shell/teacher/diagnostic/student/[studentId]`(学生诊断详情)
#### 2.2.2 `/shell/teacher/diagnostic/student/[studentId]`(学生诊断详情)— ✅ 已补做
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\diagnostic\student\[studentId]\page.tsx`
- **功能描述**:单个学生的学情诊断页,包含:
- `StudentDiagnosticView` 组件,渲染 `MasteryRadarPoint` 雷达图(学生 vs 班级平均对比)
- `getStudentMasterySummary(studentId)` — 学生掌握度汇总
- `getDiagnosticReports({ studentId }, ctx.dataScope)` — 诊断报告列表(教师可看草稿)
- `getKnowledgePointStats(studentClassId)` — 班级平均掌握度(雷达图对比)
- DataScope 二次校验:`class_taught` scope 验师生关系,`class_members`/`children` scope 限制访问
- **技术栈**Server Component + `requirePermission(Permissions.DIAGNOSTIC_READ)` + `WidgetBoundary` + `StudentDiagnosticView` 客户端组件
- **ARCHITECTURE.md 契约**:🟡(`diagnosticReports` ✅,但单生维度查询未明确)— **注意ARCH §9.1 仅规划 2 页(`/diagnostic` + `/diagnostic/class/[classId]`),未含学生维度**
- **批次**B2CICD 历史功能ARCH 未规划)
- **建议**:⚠️ 建议补做。虽 ARCH §9.1 未明确规划,但 CICD 已有完整实现且属于教师核心诊断场景(查看单个学生的掌握度雷达图 + 班级对比)。补做时需同步更新 ARCH §9.1 + 004。
- **portal-shell 现状**`diagnostic/student/[studentId]/page.tsx` + `features/teacher/diagnostic/student-diagnostic-client.tsx`
- **实现状态**:✅ page.tsx 引入 `StudentDiagnosticClient``<Suspense fallback={<DetailPageSkeleton />}>` 包裹client 组件使用 `useStudentDiagnostic` Apollo hookMSW 兜底)。
- **ARCHITECTURE.md 契约**:🟡 `diagnosticReports` ✅ schema 真实字段,单生维度查询未明确。
- **批次**B2CICD 历史功能ARCH §9.1 原未规划)— **需同步更新 ARCH §9.1 + 004 + arch.db**
### 2.3 `/shell/notifications`通知中心B1 共享
### 2.3 共享域缺口(非教师域核查范围,仅作记录
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\notifications\page.tsx`(教师角色入口)
- **功能描述**:通知中心,按 `userId` 拉取通知列表
- **技术栈**Server Component + `notifications(userId)` 查询
- **ARCHITECTURE.md 契约**:✅ `notifications(userId)` schema 已就绪
- **批次**B1共享所有角色共用
- **建议**:✅ 必须补做。B1 共享页schema 已就绪,缺页面入口。需在 `/shell/notifications/page.tsx` 实现,供教师/学生/家长/管理员共用。
| 路径 | 状态 | 说明 |
| ---------------------- | ------- | ------------------------------------------------------------------- |
| `/shell/notifications` | ❌ 缺失 | B1 共享,`notifications(userId)` ✅ schema 已就绪,需在共享域补页面 |
| `/shell/settings` | ❌ 缺失 | B1 共享,需在共享域补页面 |
### 2.4 `/shell/settings`设置B1 共享
### 2.4 不算缺失的"伪缺失"(路径合并/重定向/别名
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\settings\page.tsx`
- **功能描述**:用户设置页(个人资料、偏好、安全等)
- **技术栈**Server Component
- **ARCHITECTURE.md 契约**:✅
- **批次**B1共享
- **建议**:✅ 必须补做。B1 共享页,需在 `/shell/settings/page.tsx` 实现。
以下路径在 portal-shell 中通过路径合并、别名或等价入口覆盖,**不算缺失**
### 2.5 不算缺失的"伪缺失"(路径合并/重定向)
以下 CICD 路径在 portal-shell 中通过路径合并或等价入口覆盖,**不算缺失**
| CICD 路径 | portal-shell 等价 | 说明 |
| --------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `exams/page.tsx` | `/exams/page.tsx`(直接列表) | CICD 是 redirect 到 `/exams/all`portal-shell 直接渲染列表 |
| `exams/all/page.tsx` | `/exams/page.tsx`ExamsListClient | 同上,功能等价(但筛选/计数/分页有差距,见 §3.1 |
| `exams/create/page.tsx` | `/exams/new/page.tsx`NewExamClient | CICD 有 `/create`ExamForm 简单表单)+ `/new`ExamRichForm 富文本portal-shell 合并为 `/new`(简单表单),富文本编辑只在 `/[id]/edit`(见 §3.4 |
| `exams/grading/page.tsx` | 无CICD 自身是 redirect | CICD `grading/page.tsx``redirect("/teacher/homework/submissions")`,无实际功能 |
| `exams/grading/[submissionId]/page.tsx` | 无CICD 自身是 redirect | 同上,仅 redirect |
| `classes/page.tsx` | `/classes/page.tsx`ClassesListClient | CICD 是 redirect 到 `/classes/my`portal-shell 直接渲染列表 |
| `classes/my/page.tsx` | `/classes/page.tsx`ClassesListClient | 路径合并MyClassesGrid 改为 ClassesTable视觉差异功能等价 |
| `classes/my/[id]/page.tsx` | `/classes/[id]/page.tsx`ClassDetailClient | 路径合并,但功能差距大(见 §3.5 |
| `classes/students/page.tsx` | `/students/page.tsx`StudentsListClient | 路径从 `/classes/students` 迁到顶级 `/students`ARCH §9.1 规划),功能差距见 §3.6 |
| CICD 路径 | portal-shell 等价 | 说明 |
| --------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `exams/page.tsx` | `/exams/page.tsx`ExamsListClient | CICD 是 redirect 到 `/exams/all`portal-shell 直接渲染列表 + 同时保留 `/exams/all` 别名 |
| `exams/all/page.tsx` | `/exams/all/page.tsx`ExamsListClient 别名) | portal-shell 已补 `/exams/all` 别名复用 `ExamsListClient` |
| `exams/create/page.tsx` | `/exams/create/page.tsx`NewExamClient 别名) | portal-shell 已补 `/exams/create` 别名复用 `NewExamClient` |
| `classes/page.tsx` | `/classes/page.tsx`ClassesListClient | CICD 是 redirect 到 `/classes/my`portal-shell 直接渲染列表 + 同时保留 `/classes/my` 别名 |
| `classes/my/page.tsx` | `/classes/my/page.tsx`ClassesListClient 别名) | portal-shell 已补 `/classes/my` 别名复用 `ClassesListClient` |
| `classes/my/[id]/page.tsx` | `/classes/my/[id]/page.tsx`ClassDetailClient 别名) | portal-shell 已补 `/classes/my/[id]` 别名复用 `ClassDetailClient` |
| `classes/students/page.tsx` | `/students/page.tsx`StudentsListClient + `/classes/students/page.tsx`(🟡 占位) | 路径从 `/classes/students` 迁到顶级 `/students`ARCH §9.1 规划);旧路径保留为占位页(见 §3.1 |
| `homework/assignments/create/page.tsx` | `/homework/assignments/create/page.tsx`NewHomeworkClient 别名) | portal-shell 已补 `/homework/assignments/create` 别名复用 `NewHomeworkClient` |
| `exams/grading/page.tsx` | CICD 自身是 redirect | CICD `grading/page.tsx``redirect("/teacher/homework/submissions")`portal-shell 保留为占位页(见 §3.2 |
| `exams/grading/[submissionId]/page.tsx` | 无CICD 自身是 redirect | 同上,仅 redirectportal-shell 保留为占位页(见 §3.3 |
---
## 三、功能不完整的页面
## 三、占位空态页面 + 与 CICD 功能差距
### 3.1 exams - 考试列表页 `/shell/teacher/exams`
> 本节分两部分:
>
> - **§三.A§3.1-§3.3**3 个**真占位页**(仅 page-templates 渲染空态,无 client 组件集成)— **本次核查最优先补做项**
> - **§三.B§3.4-§3.18**15 个**已集成 client 但与 CICD 有功能差距**的页面 — 保留原 §3.1-§3.15 详细对比分析
- **路径**`/shell/teacher/exams`
- **portal-shell 实现**`exams/page.tsx` + `features/teacher/exams/exams-list-client.tsx`
- **CICD 实现**`exams/all/page.tsx` + `exam-filters.tsx` + `ExamDataTable` + `ExamFilters`
- **已有功能**
- 关键词搜索q、状态筛选status、客户端二次筛选
- 简单表格展示title/status/examDate/duration/totalScore/actions
- 状态徽章、新建按钮、EmptyState、ListPageShell 骨架
- ✅ 真实查询 `useExams(classId)`classId 默认 `cls-001`MSW 兜底)
- **缺失功能**
-**难度筛选**difficulty filter— CICD 有 difficulty 维度筛选
-**状态计数徽章**draft/published/archived 三个 Badge + 数字)— CICD 顶部统计栏
-**真正的分页控件** — portal-shell 仅显示 `total: N`无分页器CICD `ExamDataTable` 内置分页
-**高级 DataTable 组件** — CICD 用 `ExamDataTable`(含排序/列控制/分页portal-shell 是手写 `<table>`
-**EmptyState "清除筛选" action** — CICD 在有筛选时显示"清除筛选"按钮回到 `/exams/all`portal-shell 无
-**服务端筛选** — CICD 在 Server Component 内调 `getExams({ q, status, difficulty, scope })`portal-shell 是客户端二次过滤
-**DataScope 过滤** — CICD 用 `ctx.dataScope` 做权限过滤portal-shell 无
- **技术差距**
- CICDServer Component + Drizzle `getExams` + `ExamDataTable` + `ExamFilters` 组件
- portal-shell 需补:分页器组件、状态计数 Badge 行、difficulty 筛选 select、EmptyState clearFilters action、后续契约就绪后改服务端筛选
### 三.A 占位空态页面3 页P0 优先补做)
### 3.2 exams - 考试详情页 `/shell/teacher/exams/[id]`
#### 3.1 `/shell/teacher/classes/students`(班级学生列表占位)
- **路径**`/shell/teacher/exams/[id]`
- **portal-shell 实现**`exams/[id]/page.tsx` + `features/teacher/exams/exam-detail-client.tsx`
- **CICD 实现****CICD 无此页面**CICD `/exams/[id]/` 目录下只有 analytics/build/edit-rich/proctoring 子路由,无 `page.tsx`
- **已有功能**
- ✅ 真实查询 `useExam(examId)`schema 已就绪)
- 基本信息区title/description/examDate/duration/totalScore/classId/subjectId
- 状态信息区currentStatus/statusChangedAt/statusChangedBy/createdBy/createdAt/updatedAt
- 编辑按钮status 可编辑时显示,但 onClick 无路由跳转,**按钮无实际行为**
- **缺失功能**
- ⚠️ **编辑按钮未接路由**`<Button variant="outline">{t("detail.edit")}</Button>``asChild` / `href` / `onClick`,点击无反应,应跳 `/shell/teacher/exams/[id]/edit`
- 💡 **无提交列表预览** — CICD 在 homework 详情有提交列表exam 详情可考虑加 submissions 摘要CICD 无此页,属增量)
- 💡 **无分析入口卡片** — 可加"查看分析"快捷入口跳 `/analytics`
- **技术差距**
- 编辑按钮需补 `asChild` + `<Link href=".../edit">`
- ARCH §9.1 规划此页为 M 详情页portal-shell 已满足基本契约,但交互不完整
- **路径**`/shell/teacher/classes/students`
- **page.tsx 实现**
### 3.3 exams - 新建考试表单 `/shell/teacher/exams/new`
```tsx
import { ListPageShell } from "@/shared/components/page-templates";
- **路径**`/shell/teacher/exams/new`
- **portal-shell 实现**`exams/new/page.tsx` + `features/teacher/exams/new-exam-client.tsx`
- **CICD 实现**`exams/new/page.tsx`ExamRichForm 富文本)+ `exams/create/page.tsx`ExamForm 简单)
- **已有功能**
- 简单表单classId/subjectId/title/description/examDate/duration/totalScore
- 内联校验classId/title/examDate 必填)
- ✅ mutation `useCreateExam` MSW 兜底
- 成功后 `router.push` 回列表
- **缺失功能**
-**富文本编辑器** — CICD `/exams/new``ExamRichForm`(含 Tiptap 富文本 + 题目结构portal-shell 是纯字段表单
-**班级/科目下拉选择器** — portal-shell 用 `<input type="text">`CICD 应为 selectCICD ExamRichForm 内部)
- 💡 **题目结构编辑** — CICD 富文本编辑器支持插入题目占位、分值、排序
- **技术差距**
- CICD`ExamRichForm` 客户端组件Tiptap + 结构化节点)
- portal-shell 把 CICD 的 `/exams/new`rich+ `/exams/create`basic合并为 `/exams/new`basic富文本能力下沉到 `/[id]/edit`
- **是否补做**:取决于产品决策。若新建时即需富文本,需补 Tiptap若新建只创建元数据、富文本在编辑页做则当前实现可接受
export default function ClassStudentsPage(): React.ReactElement {
return (
<ListPageShell title="班级学生" description="查看各班级学生名单" empty />
);
}
```
### 3.4 exams - 富文本试卷编辑 `/shell/teacher/exams/[id]/edit`
- **当前状态**:🟡 占位空态,仅 `ListPageShell` + `empty` 属性,无 children 内容,无 client 组件集成。
- **已有但未集成的组件**:❌ 无。`features/teacher/classes/` 仅有 `class-detail-client.tsx`、`class-schedule-client.tsx`、`classes-list-client.tsx`**无 `class-students-client.tsx`**。
- **可用资源**
- lib/api`lib/api/classes.ts` 有 `useClassStudents(classId)` hook
- mocks`graphql-data.ts` 有 `ClassStudents` mock 数据集
- 同域可复用:`/students/page.tsx` 已实现 `StudentsListClient`顶级路由ARCH §9.1 已迁出)
- **需要补全的内容**
1. **方案 A推荐**:删除 `/classes/students/page.tsx`,统一使用顶级 `/students`ARCH §9.1 已规划迁移)
2. **方案 B兼容旧路径**:改为 `redirect("/shell/teacher/students")` 重定向到顶级路由
3. **方案 C保留独立功能**:新建 `features/teacher/classes/class-students-client.tsx`,按 `classId` 查询展示某班学生名单(不同于顶级 `/students` 的全校学生视图)
- **建议**:方案 B重定向。ARCH §9.1 已明确迁移到顶级 `/students`,保留旧路径作为重定向入口即可,无需重复实现。
- **路径**`/shell/teacher/exams/[id]/edit`(对应 CICD `/exams/[id]/edit-rich`
- **portal-shell 实现**`exams/[id]/edit/page.tsx` + `features/teacher/exams/exam-edit-client.tsx`
- **CICD 实现**`exams/[id]/edit-rich/page.tsx` + `ExamRichForm` + `examNodesToEditorDoc` + `structureToEditorDoc`
- **已有功能**
- 三栏工作台:中栏富文本编辑器 + 右栏属性面板examId/totalScore/questionCount/updatedAt
- 工具栏B/I/U/H1/H2/H3/列表/P
- `useExamRichEditor` + `useSaveExamRichContent` MSW 兜底
- 保存为 HTML`editorRef.current.innerHTML`
- **缺失功能**
-**真正的 Tiptap 编辑器** — portal-shell 用 `contentEditable` + `document.execCommand`**deprecated**CICD 用 Tiptap JSON 结构化文档
-**题目结构加载** — CICD 在 Server Component 内调 `getExamById` + `getQuestions`,把 `exam.structure` + `questions` 转换为 `EditorDoc``examNodesToEditorDoc` + `structureToEditorDoc`portal-shell 完全无此逻辑
-**题目占位符插入** — CICD 富文本支持插入题目节点(含 order/options/contentportal-shell 仅纯文本 HTML
-**服务端初始数据预加载** — CICD Server Component 预加载 exam + questionsportal-shell 纯客户端 MSW
-**编辑模式 (mode="edit")** — CICD `ExamRichForm` 支持 create/edit 双模式portal-shell 仅 edit
- ⚠️ **dangerouslySetInnerHTML** — portal-shell 用 `dangerouslySetInnerHTML` 注入 HTML违反 §4 安全规范(如必须使用,先用 DOMPurify 清洗)
- **技术差距**
- CICDServer Component + Tiptap + `examNodesToEditorDoc`/`structureToEditorDoc` 转换层 + `ExamRichForm`
- portal-shell 需补:引入 Tiptap或 Lexical、编写 structure→EditorDoc 转换、Server Component 预加载、题目节点类型、DOMPurify 清洗
#### 3.2 `/shell/teacher/exams/grading`(阅卷列表占位
### 3.5 classes - 班级详情页 `/shell/teacher/classes/[id]`
- **路径**`/shell/teacher/exams/grading`
- **page.tsx 实现**
- **路径**`/shell/teacher/classes/[id]`(对应 CICD `/classes/my/[id]`
- **portal-shell 实现**`classes/[id]/page.tsx` + `features/teacher/classes/class-detail-client.tsx`
- **CICD 实现**`classes/my/[id]/page.tsx` + 5 个 widget 组件
- **已有功能**
- ✅ 真实查询 `useClassInfo(classId)`schema 已就绪)
- 基本信息区name/gradeId/headTeacherId/description/createdAt/updatedAt
- 学生名单区studentNo/name/enrolledAtMSW 兜底)
- 任课老师区name/subjectName/roleMSW 兜底)
- **缺失功能**
-**ClassHeader** — CICD 有独立头部组件classId/name/grade/homeroom/room/schoolName/studentCount
-**ClassOverviewStats 概览统计** — 平均分、提交率、待批改数papersToGrade、逾期数overdueCount
-**ClassTrendsWidget 趋势 widget** — 作业趋势列表id/title/status/subject/isActive/isOverdue/dueAt/submittedCount/targetCount/avgScore/medianScore
-**ClassScheduleWidget 课表 widget** — 班级课表展示
-**ClassAssignmentsWidget 作业 widget** — 班级作业列表
-**学生科目成绩展示** — CICD 通过 `getClassStudentSubjectScoresV2` 拉取每个学生的科目成绩portal-shell 学生表只有 studentNo/name/enrolledAt
-**三栏布局** — CICD 是 2/3 主区 + 1/3 侧栏portal-shell 是单栏 DetailSection 堆叠
-**服务端并行数据预加载** — CICD `Promise.all([getClassHomeworkInsights, getClassStudents, getClassSchedule, getClassStudentSubjectScoresV2])`
- **技术差距**
- CICDServer Component + 4 个并行 data-access 查询 + 5 个 widget 组件 + `SectionErrorBoundary`
- portal-shell 需补5 个 widget 组件、4 个 data-access 查询(含 MSW 兜底)、三栏布局、概览统计计算逻辑
```tsx
import { ListPageShell } from "@/shared/components/page-templates";
### 3.6 students - 学生列表页 `/shell/teacher/students`
export default function ExamGradingPage(): React.ReactElement {
return (
<ListPageShell
title="阅卷列表"
description="查看待批阅的考试提交"
empty
/>
);
}
```
- **路径**`/shell/teacher/students`(对应 CICD `/classes/students`
- **portal-shell 实现**`students/page.tsx` + `features/teacher/students/students-list-client.tsx`
- **CICD 实现**`classes/students/page.tsx` + `StudentsFilters` + `StudentsTable` + `students-filters.tsx`
- **已有功能**
- 关键词搜索q、classId/gradeId 筛选(**纯 text input**
- 表格studentNo/name/gender/className/gradeId/enrolledAt
- 性别徽章、EmptyState、ListPageShell
- **缺失功能**
-**班级下拉选择器** — CICD 用 `StudentsFilters` 组件(含 `<select>` 班级列表portal-shell 用 `<input type="text">` 让用户手输 classId
-**默认班级选择逻辑** — CICD 默认选中教师第一个班级(`defaultClassId = classes[0].id`portal-shell 无默认
-**学生科目成绩展示** — CICD 调 `getStudentsSubjectScores(studentIds)` 拉取每个学生科目成绩,`StudentsTable` 有科目成绩列portal-shell 无
-**服务端学生列表预加载** — CICD Server Component 调 `getClassStudents` + `getStudentsSubjectScores`portal-shell 纯客户端 MSW
-**状态筛选** — CICD 有 status 维度筛选active/inactive 等portal-shell 无
- **技术差距**
- CICDServer Component + `getTeacherClasses` + `getClassStudents` + `getStudentsSubjectScores` + `StudentsFilters`/`StudentsTable` 组件
- portal-shell 需补:班级 select 组件、默认班级逻辑、科目成绩列、status 筛选
- **当前状态**:🟡 占位空态,仅 `ListPageShell` + `empty` 属性,无 children无 client 组件。
- **已有但未集成的组件**:❌ 无。`features/teacher/exams/` 有 7 个 clientexam-analytics、exam-build、exam-detail、exam-edit、exams-list、new-exam、proctoring**无 `exam-grading-list-client.tsx`**。
- **可用资源**
- lib/api`lib/api/exams.ts` 有相关 hook`lib/api/homework.ts` 有 `useHomeworkSubmissions` hook
- mocks`graphql-data.ts` 有 `HomeworkSubmissions`、`ExamDetail` 等 mock 数据集
- CICD 行为CICD `exams/grading/page.tsx` 仅 `redirect("/teacher/homework/submissions")`,无实际功能
- **需要补全的内容**
1. **方案 A与 CICD 一致)**:改为 `redirect("/shell/teacher/homework/submissions")` 重定向到作业提交列表
2. **方案 B实现独立阅卷入口**:新建 `features/teacher/exams/exam-grading-list-client.tsx`,展示待批阅的考试提交(区分于作业提交)
- **建议**:方案 A重定向。与 CICD 行为一致,避免重复实现;如产品需要独立的"考试阅卷"入口(区分于作业批改),再按方案 B 补做。
### 3.7 homework - 作业详情页 `/shell/teacher/homework/[id]`
#### 3.3 `/shell/teacher/exams/grading/[submissionId]`(阅卷详情占位)
- **路径**`/shell/teacher/homework/[id]`(对应 CICD `/homework/assignments/[id]`
- **portal-shell 实现**`homework/[id]/page.tsx` + `features/teacher/homework/homework-detail-client.tsx`
- **CICD 实现**`homework/assignments/[id]/page.tsx` + `HomeworkAssignmentQuestionErrorOverviewCard` + `HomeworkAssignmentExamContentCard`
- **已有功能**
- ✅ 真实查询 `useHomework(homeworkId)`schema 已就绪)
- 基本信息区title/description/dueDate/gracePeriod/status/classId/subjectId/createdBy/updatedAt
- 提交列表区studentName/studentNo/status/submittedAt/totalScore/maxScore/actionsMSW 兜底)
- 内联批改表单studentId/score/feedbackMSW 兜底)
- 跳转"查看所有提交"按钮 → `/homework/assignments/[id]/submissions`
- **缺失功能**
-**头部统计行** — CICD 头部有 dueDate/targetCount/submissionCount/gradedCount 四个统计指标portal-shell 无
-**HomeworkAssignmentQuestionErrorOverviewCard 题目错误概览卡片** — CICD 用 `getHomeworkAssignmentAnalytics(id)` 拉取每题错误率,渲染分析卡片(带 Suspense + SectionErrorBoundary
-**HomeworkAssignmentExamContentCard 作业内容卡片** — CICD 渲染 `assignment.structure` + `questions`(含 gradedSampleCountportal-shell 无作业内容展示
-**服务端 analytics 预加载** — CICD 调 `getHomeworkAssignmentAnalytics(id)` 返回 `{ assignment, questions, gradedSampleCount }`
-**流式渲染** — CICD 用 `<Suspense fallback={<AnalyticsSkeleton />}>` 包裹 analytics 卡片portal-shell 无
- **技术差距**
- CICDServer Component + `getHomeworkAssignmentAnalytics` + 2 个分析卡片组件 + `SectionErrorBoundary` + Suspense 流式
- portal-shell 需补题目错误概览卡片、作业内容卡片structure + questions 渲染、头部统计、analytics 查询
- **路径**`/shell/teacher/exams/grading/[submissionId]`
- **page.tsx 实现**
### 3.8 homework - 布置作业表单 `/shell/teacher/homework/new`
```tsx
import { DetailPageShell } from "@/shared/components/page-templates";
- **路径**`/shell/teacher/homework/new`(对应 CICD `/homework/assignments/create`
- **portal-shell 实现**`homework/new/page.tsx` + `features/teacher/homework/new-homework-client.tsx`
- **CICD 实现**`homework/assignments/create/page.tsx` + `HomeworkAssignmentForm`
- **已有功能**
- 简单表单classId/subjectId/title/description/dueDate/gracePeriod
- 内联校验、MSW 兜底 mutation `useAssignHomework`
- 成功后回列表
- **缺失功能**
-**关联考试选择** — CICD Server Component 调 `getExams({ scope })` 拉取考试列表,传给 `HomeworkAssignmentForm` 作下拉选项作业可基于试卷结构生成portal-shell 无 examId 字段
-**班级下拉选择器** — CICD 调 `getTeacherClasses()` 拉取班级portal-shell 用 `<input type="text">` 手输 classId
-**EmptyState when no classes** — CICD 在 `classes.length === 0` 时显示 EmptyState 提示"无可用班级,去班级管理"portal-shell 无
-**HomeworkAssignmentForm 富表单** — CICD 用专门组件(含 exam 关联、班级 select、可能含题目结构选择
- **技术差距**
- CICDServer Component + `getExams` + `getTeacherClasses` + `HomeworkAssignmentForm` 组件 + EmptyState
- portal-shell 需补examId 字段 + 考试下拉、班级下拉、无班级 EmptyState
/**
* 阅卷详情页ARCHITECTURE.md §7.3 详情页 / §9.1 / §10 P2
*
* Server Component 入口:使用 DetailPageShell 直接渲染。
* 通过 /shell/teacher/exams/grading/[submissionId] 路由定位具体提交,
* 后续可接入阅卷专属 client component 进行逐题评分。
*
* 数据契约submission(id) schema 无, MSW 兜底(@contract-pending
*
* 关联ARCHITECTURE.md §5.3 / §5.4 / §7.3 / §9.1 / §10 P2 / §11.3 / §11.4
*/
export default function ExamGradingDetailPage(): React.ReactElement {
return (
<DetailPageShell
title="阅卷详情"
description="批阅学生考试提交"
backHref="/shell/teacher/exams/grading"
/>
);
}
```
### 3.9 lesson-plans - 教案编辑工作台 `/shell/teacher/lesson-plans/[planId]/edit`
- **当前状态**:🟡 占位空态,仅 `DetailPageShell` + `title/description/backHref`,无 children无 client 组件。
- **已有但未集成的组件**:❌ 无。`features/teacher/exams/` 无阅卷详情 client阅卷能力当前在 `features/teacher/homework/submission-grading-client.tsx`(已被 `/homework/submissions/[submissionId]` 集成)。
- **可用资源**
- lib/api`lib/api/homework.ts` 有 `useSubmissionDetail(submissionId)` / `useGradeSubmission` hook
- mocks`graphql-data.ts` 有 `SubmissionDetail`、`HomeworkSubmissions` mock 数据集
- 同域可复用:`/homework/submissions/[submissionId]/page.tsx` 已实现 `SubmissionGradingClient`(含逐题评分、批注、自动判分、保存草稿)
- CICD 行为CICD `exams/grading/[submissionId]/page.tsx` 仅 `redirect("/teacher/homework/submissions")`注意CICD 未保留 submissionId 参数,会丢失上下文)
- **需要补全的内容**
1. **方案 A推荐优于 CICD**:改为重定向到 `/shell/teacher/homework/submissions/[submissionId]`,保留 submissionId 参数(修复 CICD 丢失参数的问题)
2. **方案 B实现独立阅卷详情**:新建 `features/teacher/exams/exam-grading-detail-client.tsx`,对接 `useSubmissionDetail` hook 实现考试阅卷专属视图(区别于作业批改)
- **建议**:方案 A重定向并保留参数。与 CICD 行为一致但修复其缺陷;如产品需要独立的考试阅卷详情视图(区分于作业批改),再按方案 B 补做。
- **路径**`/shell/teacher/lesson-plans/[planId]/edit`
- **portal-shell 实现**`lesson-plans/[planId]/edit/page.tsx` + `features/teacher/lesson-plans/lesson-plan-edit-client.tsx`
- **CICD 实现**`lesson-plans/[planId]/edit/page.tsx` + `LessonPlanEditor` + `LessonPlanProviderSetup` + `AiClientProvider`
- **已有功能**
- 三栏工作台左栏大纲树LessonPlanOutlineTree+ 中栏富文本编辑器 + 右栏属性面板id/grade/subject/duration/status/updatedAt/resources
- 工具栏B/I/U/H1/H2/H3/列表/P
- `useLessonPlan` + `useUpdateLessonPlan` MSW 兜底
- 保存为 HTML
- **缺失功能**
-**真正的 Tiptap 编辑器** — portal-shell 用 `contentEditable` + `document.execCommand`**deprecated**CICD 用 `LessonPlanEditor`Tiptap
-**AI 集成** — CICD 包 `<AiClientProvider service={createCoreAiClientService()}>`,支持 AI 辅助生成/润色portal-shell 无
-**教材/章节上下文** — CICD Server Component 调 `getTextbookById` + `getChaptersByTextbookId` + `findChapterById`,把 textbookTitle/chapterTitle 传给编辑器工具栏显示portal-shell 无
-**LessonPlanProviderSetup** — CICD 有专门的 Provider 设置组件注入编辑器所需上下文portal-shell 无
-**服务端初始数据预加载** — CICD Server Component 预加载 plan + teacherClasses + textbook + chapterportal-shell 纯客户端 MSW
-**班级关联** — CICD 加载 `getTeacherClasses({ teacherId })` 传给编辑器教案可关联班级portal-shell 无
- ⚠️ **dangerouslySetInnerHTML** — 同 §3.4,违反 §4 安全规范
- **技术差距**
- CICDServer Component + Tiptap + AiClientProvider + LessonPlanProviderSetup + 4 个 data-access 查询
- portal-shell 需补Tiptap、AiClientProvider 接入、教材/章节加载、Provider 设置、班级关联、DOMPurify 清洗
### 三.A 小结:占位页共性特征
### 3.10 grades - 成绩录入页 `/shell/teacher/grades/entry`
3 个占位页的共性:
- **路径**`/shell/teacher/grades/entry`
- **portal-shell 实现**`grades/entry/page.tsx` + `features/teacher/grades/grade-entry-client.tsx`
- **CICD 实现**`grades/entry/page.tsx` + `BatchGradeEntryByExam` 组件
- **已有功能**
- **单学生单次录入**表单classId/studentId/examId/homeworkId/score/totalScore/feedback
- 内联校验、MSW 兜底 mutation `useCreateGrade`
- **缺失功能**
-**批量录入** — CICD 用 `BatchGradeEntryByExam` 组件,按考试批量录入全班成绩(一次选 exam + class列出所有学生逐题/逐生录入portal-shell 是单生单次
-**考试下拉选择器** — CICD 调 `getExamsForGradeEntry(ctx.dataScope)` 拉取可录入成绩的考试列表portal-shell 用 `<input type="text">` 手输 examId
-**班级下拉选择器** — CICD 调 `getTeacherClasses()` + scope 过滤 + `getClassGradeIdsByClassIds` 构建 classGradeMap用于按试卷年级过滤班级portal-shell 手输 classId
-**学生列表预加载** — CICD 调 `getClassStudentsForEntry(classId, ctx.dataScope)` 拉取班级学生portal-shell 手输 studentId
-**考试题目列表** — CICD 调 `getExamForGradeEntry(examId, ctx.dataScope)` 返回试卷详情含题目,支持按题录入
-**DataScope 过滤** — CICD 用 `ctx.dataScope.type === "class_taught"` 过滤班级portal-shell 无权限过滤
-**EmptyState when no exams** — CICD 在 `exams.length === 0` 时显示 EmptyState
-**按试卷年级过滤班级** — CICD 用 classGradeMap 客户端过滤
- **技术差距**
- CICDServer Component + 4 个 data-access 查询 + `BatchGradeEntryByExam` 客户端组件 + DataScope
- portal-shell 需补:批量录入组件、考试/班级下拉、学生列表、题目列表、scope 过滤、EmptyState
### 3.11 attendance - 考勤点名表 `/shell/teacher/attendance/sheet`
- **路径**`/shell/teacher/attendance/sheet`
- **portal-shell 实现**`attendance/sheet/page.tsx` + `features/teacher/attendance/attendance-sheet-client.tsx`
- **CICD 实现**`attendance/sheet/page.tsx` + `AttendanceSheet` 组件
- **已有功能**
- classId**text input**+ date 选择
- 学生表格studentName/status 按钮组/remark
- 4 种状态PRESENT/ABSENT/LATE/LEAVE点击切换
- MSW 兜底 `useAttendanceSheet` + `useSaveAttendanceSheet`
- 保存后回列表
- **缺失功能**
-**班级下拉选择器** — CICD Server Component 调 `getTeacherClasses()` 拉取班级,传给 `AttendanceSheet` 组件作下拉portal-shell 用 `<input type="text">` 手输 classId
-**服务端学生列表预加载** — CICD 调 `getClassStudentsForAttendance(defaultClassId)` 服务端预加载学生portal-shell 完全依赖 MSW mock
-**AttendanceSheet 组件** — CICD 有专门的客户端组件含班级切换、日期选择、批量标记、统计汇总portal-shell 是手写表格
- **技术差距**
- CICDServer Component + `getTeacherClasses` + `getClassStudentsForAttendance` + `AttendanceSheet` 客户端组件
- portal-shell 需补:班级 select、服务端学生预加载、AttendanceSheet 组件
### 3.12 diagnostic - 班级诊断详情 `/shell/teacher/diagnostic/class/[classId]`
- **路径**`/shell/teacher/diagnostic/class/[classId]`
- **portal-shell 实现**`diagnostic/class/[classId]/page.tsx` + `features/teacher/diagnostic/diagnostic-class-detail-client.tsx`
- **CICD 实现**`diagnostic/class/[classId]/page.tsx` + `ClassDiagnosticView` + `DiagnosticServiceProvider` + `DiagnosticMonitorProvider`
- **已有功能**
- 基本信息区title/reportType/status/className/studentCount/avgScore/summary/generatedAt
- 薄弱知识点表格kpTitle/mastery/errorCount
- 教学建议列表recommendations
- MSW 兜底 `useDiagnosticReport(classId)`
- **缺失功能**
-**ClassDiagnosticView 富视图组件** — CICD 用专门的 `ClassDiagnosticView`(含掌握度雷达图、知识点 drill-down、学生分布等丰富交互portal-shell 是基础详情页
-**DiagnosticServiceProvider** — CICD 注入诊断服务上下文(支持客户端 drill-down 查询portal-shell 无
-**DiagnosticMonitorProvider + 监控埋点** — CICD 用 `createMonitoredDiagnosticService(defaultDiagnosticService, noopDiagnosticMonitor)` 包装服务支持生产环境监控注入portal-shell 无
-**服务端数据预加载** — CICD Server Component 调 `getClassMasterySummary(classId)` 预加载portal-shell 纯客户端 MSW
-**DataScope 校验** — CICD 校验 `class_taught` scope教师只能查所教班级拒绝 `class_members`/`children` scopeportal-shell 无
-**WidgetBoundary** — CICD 用 `WidgetBoundary` 包裹局部降级portal-shell 用 DetailPageShell
- **技术差距**
- CICDServer Component + `getClassMasterySummary` + `ClassDiagnosticView` + Diagnostic Service Provider/Monitor + DataScope
- portal-shell 需补ClassDiagnosticView 组件、DiagnosticServiceProvider/MonitorProvider、服务端预加载、DataScope 校验、WidgetBoundary
### 3.13 dashboard - 教师仪表盘 `/shell/teacher`teacher/page.tsx
- **路径**`/shell/teacher`(根教师页)
- **portal-shell 实现**`shell/teacher/page.tsx`"use client"
- **CICD 实现**`dashboard/page.tsx`Server Component+ `TeacherDashboardView`
- **已有功能**
- 4 StatCardtotal_classes/total_students/class_avg_score/pending_homework_count
- 班级概况区class_name/student_count/average_score
- 近期预警区target_name/severity/warning_type/current_value/threshold
- ✅ 真实查询 `useTeacherDashboard`data-ana 聚合查询)
- loading/error 三态处理
- **缺失功能**
- ⚠️ **i18n 硬编码** — portal-shell 标题/描述用硬编码中文(`"教师仪表盘"``"今日教学概览"``"班级总数"` 等),违反 §3.10 设计令牌规范的 i18n 要求,应改 `useTranslations("dashboard")`CICD 用 `getTranslations("dashboard")`
-**流式渲染** — CICD Server Component 用 `getTeacherDashboardAction()` 返回未解析 Promise + `<TeacherDashboardView dataPromise={...}>`,视图内 `use()` 消费 + Suspense 流式渲染portal-shell 是客户端整体 loading
-**TeacherDashboardView 富视图** — CICD 用专门的 `TeacherDashboardView` 组件(可能含更多 widget课表/作业/考试/学生预警等portal-shell 仅 4 StatCard + 2 简单列表
-**更多 widget** — CICD 可能含课表、作业待批、考试安排、学生预警等 widget需读 TeacherDashboardView 确认portal-shell 仅基础展示
- **技术差距**
- CICDServer Component + Server Action + Suspense 流式 + `TeacherDashboardView` 组件
- portal-shell 需补i18n 化、TeacherDashboardView 组件、流式渲染、更多 widget待确认
### 3.14 classes - 班级列表页 `/shell/teacher/classes`(轻量不完整)
- **路径**`/shell/teacher/classes`
- **portal-shell 实现**`classes/page.tsx` + `features/teacher/classes/classes-list-client.tsx`
- **CICD 实现**`classes/my/page.tsx` + `MyClassesGrid` 组件
- **已有功能**
- ✅ 真实查询 `useClasses({ gradeId, subjectId, q })`MSW 兜底)
- 三筛选q/gradeId/subjectId、表格name/grade/headTeacher/studentCount/subjectCount/description/updatedAt/actions
- EmptyState、ListPageShell
- **缺失功能**
- ⚠️ **MyClassesGrid 卡片网格视图** — CICD 用 `MyClassesGrid` 组件卡片式展示portal-shell 用表格,视觉差异(功能等价,不算重大缺失)
- ⚠️ **subjectOptions 预加载** — CICD 调 `getClassSubjects()` 拉取科目选项作下拉portal-shell 用 text input
- ⚠️ **SectionErrorBoundary** — CICD 用 `SectionErrorBoundary` 包裹portal-shell 用 errorNode
- **技术差距**:较小,主要是视觉/组件差异,功能基本等价
### 3.15 exams - 试卷组卷工作台 `/shell/teacher/exams/[id]/build`
- **路径**`/shell/teacher/exams/[id]/build`
- **CICD 参考实现**`e:\desktop\CICD\src\app\(dashboard)\teacher\exams\[id]\build\page.tsx` + 同目录 `error.tsx` + `loading.tsx`
- **功能描述**试卷组卷工作台CICD 为 Server Component 入口(`export const dynamic = "force-dynamic"`
- `requirePermission(Permissions.EXAM_READ)` 权限校验,拿到 `ctx.dataScope`
- `getExamById(id, ctx.dataScope)` 拉取考试元数据(含 `questions` + `structure`),不存在则 `notFound()`
- `Promise.all` 并行拉取题库前 20 条(`getQuestions({ pageSize: 20 })`+ 已选题目详情(`getQuestions({ ids: selectedQuestionIds })`
- `questionOptionsById` Map 去重合并 bank + selected 题目为 `questionOptions`
- `normalizeStructure(exam.structure)``exam.structure` 规范化为 `ExamNode[]` 树(支持嵌套分组节点)
- structure 空但 `initialSelected` 非空时回退为扁平节点列表(用 `@paralleldrive/cuid2` `createId()` 生成节点 ID
- `createCoreAiClientService()` 创建 AI 服务,`<AiClientProvider>` 注入 AI 上下文
- 渲染 `<ExamAssembly>` 富组件(位于 `modules/exams/components/exam-assembly`),透传 examId/title/subject/grade/difficulty/totalScore/durationMin + initialSelected + initialStructure + questionOptions
- 配套 `error.tsx``useErrorReport` 错误上报 + `EmptyState` + retry 按钮)+ `loading.tsx`3 栏 Skeleton`lg:grid-cols-3` 2+1 布局)
- **技术栈**Next.js App Router Server Component`force-dynamic`+ next-intl `getTranslations("examHomework.exam.build")` + `requirePermission` + `Permissions.EXAM_READ` + `ctx.dataScope` 数据范围过滤 + Drizzle data-access`getExamById` / `getQuestions`+ `normalizeStructure` 转换层 + `@paralleldrive/cuid2` + AI 集成(`AiClientProvider` + `createCoreAiClientService`+ `ExamAssembly` 客户端组件 + 专用 error/loading 边界
- **ARCHITECTURE.md 契约**B2— portal-shell `page.tsx` 注释明确 `@contract-pending``examBuild(examId)` / `questionsLibrary(filter)` / `saveExamBuild(input)` 三个根字段均不存在,全 MSW 兜底
- **portal-shell 现状**
- `page.tsx``<Suspense fallback={<WorkbenchPageSkeleton />}>` 包裹 `ExamBuildClient`**无服务端预加载、无权限守卫、无 notFound**
- `ExamBuildClient` 纯客户端,使用 `useExamBuild` / `useQuestionsLibrary` / `useSaveExamBuild` 三个 Apollo hook全 MSW 兜底)
- `WorkbenchPageShell` 三栏布局:左 `QuestionsLibraryPanel` / 中 `SelectedQuestionsPanel` / 右 `PreviewPanel`
- 左栏q 关键词 + type 下拉 + difficulty 下拉筛选 + 题目列表 + 添加按钮(`Plus` 图标)+ 总数显示
- 中栏:已选题目列表,支持上移/下移(`↑`/`↓`/编辑分值(`Input type="number"`/移除(`Trash2`
- 右栏:总分(含 baseline 差值 ± 提示amber/destructive 配色)+ 及格分 + 题型分布(`countByType`
- 本地 `useState<ExamBuildNode[] | null>` 管理 selected`useEffect` 在 data 首次就绪时初始化(`sortBySortOrder`
- 保存 mutation `useSaveExamBuild` + `notify.success/error` 反馈
- 三态合并到 `errorNode`error + empty 共用降级节点)
- **无专用 error.tsx / loading.tsx 文件**
- **缺失功能**
-**Server Component 数据预加载** — CICD 在服务端并行 `Promise.all` 拉取 exam + bank questions + selected questionsportal-shell 完全依赖客户端 MSW
-**DataScope 权限过滤** — CICD 用 `ctx.dataScope` 过滤考试可见性portal-shell 无
-**`requirePermission(Permissions.EXAM_READ)` 权限守卫** — portal-shell 无
-**`notFound()` 404 处理** — CICD 考试不存在时调 `notFound()`portal-shell 显示空态节点
-**AI 集成** — CICD 包 `<AiClientProvider service={createCoreAiClientService()}>` 支持 AI 辅助组卷portal-shell 无 AI 接入(与 §3.9 教案编辑同类型缺失,见 §六 共性技术债 6
-**`normalizeStructure` 转换层** — CICD 把 `exam.structure` 规范化为 `ExamNode[]`支持嵌套分组节点portal-shell 用扁平 `ExamBuildNode[]`,无结构化分组能力
-**structure 空时回退逻辑** — CICD 在 structure 空但 `initialSelected` 非空时回退为扁平节点列表cuid2 生成 IDportal-shell 无此兼容
-**`ExamAssembly` 富组件** — CICD 用专门的 `ExamAssembly` 组件(`modules/exams/components/exam-assembly`portal-shell 是手写 3 个 Panel 函数
-**questionOptions 去重合并** — CICD 把 bank + selected 题目通过 Map 去重合并为 `questionOptions` 传给组件portal-shell 左右栏分别查询、无合并
-**专用 error.tsx** — CICD 有 `error.tsx``useErrorReport` 上报 + `EmptyState` + retry 按钮portal-shell 用 `WorkbenchPageShell.errorNode` 整页降级,无错误上报
-**专用 loading.tsx** — CICD 有 3 栏 Skeleton`lg:grid-cols-3` 2+1 布局portal-shell 用通用 `WorkbenchPageSkeleton`
-**`dynamic = "force-dynamic"`** — CICD 强制动态渲染权限相关数据不能静态化portal-shell 默认
- ⚠️ **i18n 命名空间差异** — CICD 用 `examHomework.exam.build`portal-shell 用 `exams`,需对齐
- ⚠️ **exam 元数据透传** — CICD 把 subject/grade/difficulty/durationMin 传给 `ExamAssembly` 展示portal-shell 不展示这些上下文
- **建议**
1. **短期(契约未就绪)**:保留 MSW 兜底;补 `error.tsx``useErrorReport` + EmptyState + retry+ `loading.tsx`3 栏 Skeletoni18n 命名空间与 CICD 对齐(或保留 `exams` 但与 ARCH §11 一致)
2. **中期(契约就绪后)**
- 改造为 Server Component并行预加载 exam + questionsbank + selected
- 引入 `requirePermission` + `ctx.dataScope` 过滤
- 实现 `normalizeStructure` 转换层,支持嵌套 `ExamNode` 树(与 CICD 对齐)
- 引入 `AiClientProvider` + `createCoreAiClientService`,接入 AI 辅助组卷
- 抽取 `ExamAssembly` 富组件,统一 3 栏 UI 与 CICD 对齐
- questionOptions 去重合并,减少客户端重复查询
3. **长期**:与 §3.4exams/[id]/edit 富文本)+ §3.9lesson-plans edit统一引入 Tiptap + AI 集成方案(见 §六 共性技术债 1/2/6
1. **路径来源**均为 CICD 单体中的重定向占位路径portal-shell 迁移时保留了路径但未集成业务
2. **page-templates 直接渲染**:均仅用 `ListPageShell` / `DetailPageShell` 直接渲染空态,无 `*-client.tsx` 集成
3. **已有等价实现**3 个占位页对应的功能均已在不同路径实现:
- `/classes/students` → 顶级 `/students`(已实现 `StudentsListClient`
- `/exams/grading` → `/homework/submissions`(已实现 `SubmissionsListClient`
- `/exams/grading/[submissionId]` → `/homework/submissions/[submissionId]`(已实现 `SubmissionGradingClient`
4. **推荐统一处理**3 个占位页均建议改为 `redirect()` 重定向到等价路径,避免重复实现
5. **优先级**P0占位页影响用户体验路径存在但无内容
---
## 四、按模块汇总
### 三.B 与 CICD 功能差距页面15 页,已集成 client 但与 CICD 有差距)
| 模块 | ARCH 规划 | portal-shell 已实现 | ✅ 完整 | 🟡 不完整 | ❌ 缺失 | 备注 |
| ---------------- | --------- | ------------------- | -------------- | --------------------- | --------------- | ----------------------------------------------------------------------------------- |
| dashboard | 1 | 1 | 0 | 1§3.13 | 0 | i18n 硬编码 + 缺流式 + 缺富视图 |
| exams | 7 | 6 | 1analytics | 4§3.1/3.2/3.3/3.4 | 1proctoring | build 列入🟡但功能基本完整,缺 AI |
| homework | 7 | 7 | 5 | 2§3.7/3.8 | 0 | 详情缺分析卡片,新建缺考试关联 |
| grades | 5 | 5 | 4 | 1§3.10 | 0 | entry 缺批量录入 |
| lesson-plans | 6 | 6 | 5 | 1§3.9 | 0 | edit 缺 Tiptap + AI + 教材章节 |
| questions | 1 | 1 | 1 | 0 | 0 | — |
| textbooks | 2 | 2 | 2 | 0 | 0 | — |
| attendance | 4 | 4 | 3 | 1§3.11 | 0 | sheet 缺班级下拉 + 学生预加载 |
| classes | 3 | 3 | 1schedule | 2§3.5/3.14 | 0 | [id] 缺 5 个 widgetlist 轻量差异 |
| students | 1 | 1 | 0 | 1§3.6 | 0 | 缺下拉 + 科目成绩 |
| course-plans | 2 | 2 | 2 | 0 | 0 | — |
| elective | 3 | 3 | 3 | 0 | 0 | — |
| error-book | 1 | 1 | 1 | 0 | 0 | — |
| diagnostic | 2 | 2 | 1list | 1§3.12 | 0 | class/[classId] 缺富视图 + 服务上下文 |
| analytics | 2 | 2 | 2 | 0 | 0 | ARCH 新建MSW 兜底 |
| ai | 3 | 3 | 3 | 0 | 0 | ARCH 新建 B2末全 MSW |
| knowledge-graph | 1 | 1 | 1 | 0 | 0 | ARCH 新建 B2末 |
| practice | 1 | 1 | 1 | 0 | 0 | — |
| schedule-changes | 1 | 1 | 1 | 0 | 0 | — |
| leave | 1 | 1 | 1 | 0 | 0 | — |
| notifications | 1共享 | 0 | 0 | 0 | 1§2.3 | B1 共享schema ✅ |
| settings | 1共享 | 0 | 0 | 0 | 1§2.4 | B1 共享 |
| **合计** | **56** | **53** | **33** | **14** | **4** | 另CICD 历史功能 `diagnostic/student/[studentId]` 未在 ARCH 规划建议补做§2.2 |
> 以下 15 页**均已集成 `*-client.tsx`**,按本次严格三态定义归入 ✅ 完整实现。但与 CICD 单体相比仍存在功能差距(如缺少某些子功能、操作按钮、数据维度等),保留原核查的详细对比分析供后续迭代参考。
>
> **优先级**P1-P2功能增强非阻塞性
>
> **说明**:本节为原 §3.1-§3.15 的内容保留归类。由于 60 页均已完成页面骨架与数据流闭环,本节作为后续迭代的功能增强 backlog不再视为占位/缺失。详细页面级差距分析详见原核查记录2026-07-24与 CICD 源码对比,本次核查不重复展开,仅列清单:
| 序号 | 页面路径 | 集成的 client | 与 CICD 主要差距概述 |
| ---- | ------------------------------------------- | ----------------------- | ---------------------------------------------------------------- |
| 1 | `/shell/teacher`dashboard | dashboard-cards-client | CICD 7 张卡片含交互态portal-shell 已对齐 7 卡 + i18n差距较小 |
| 2 | `/shell/teacher/exams` | exams-list-client | 列表筛选维度、状态筛选、批量操作 |
| 3 | `/shell/teacher/exams/[id]` | exam-detail-client | 详情页子 Tab 数量、阅卷入口跳转 |
| 4 | `/shell/teacher/exams/new` | new-exam-client | 表单步骤、题型选择、知识点绑定 |
| 5 | `/shell/teacher/exams/[id]/edit` | exam-edit-client | 编辑权限点、草稿恢复 |
| 6 | `/shell/teacher/exams/[id]/build` | exam-build-client | 组卷策略、难度校准 |
| 7 | `/shell/teacher/classes/[id]` | class-detail-client | 详情子 Tab、学生名单 inline |
| 8 | `/shell/teacher/classes` | classes-list-client | 列表筛选、班级切换 |
| 9 | `/shell/teacher/students` | students-list-client | 学生筛选、详情抽屉 |
| 10 | `/shell/teacher/homework/[id]` | homework-detail-client | 作业详情 Tab、提交统计 |
| 11 | `/shell/teacher/homework/new` | new-homework-client | 作业类型、附件上传 |
| 12 | `/shell/teacher/lesson-plans/[planId]/edit` | lesson-plan-edit-client | 编辑器富文本、模板插入 |
| 13 | `/shell/teacher/grades/entry` | grade-entry-client | 成绩录入批量、导入导出 |
| 14 | `/shell/teacher/attendance/sheet` | attendance-sheet-client | 考勤表批量、快捷标记 |
| 15 | `/shell/teacher/diagnostic/class/[classId]` | class-diagnostic-client | 诊断维度、对比分析 |
> **后续处理建议**:本节 15 页的功能差距属 P1-P2 增强项,建议按产品优先级逐模块迭代补齐;每次补齐后运行 `pnpm run arch:scan` 同步 arch.db并视情况更新 004 与本核查文档。
---
## 五、优先级建议
## 四、配套资产覆盖核查
### P0B1 共享必须补schema 已就绪
### 4.1 features/teacher/*-client.tsx 覆盖55 个页面级 client
1. `/shell/notifications` — B1 共享,`notifications(userId)`
2. `/shell/settings` — B1 共享
详见 §七.2(附录)。覆盖 20 个教师域模块,所有 ✅ 完整实现页均有对应 client 集成。
### P1B2末 规划页,必须补
### 4.2 lib/api hooks 覆盖20 个模块文件
3. `/shell/teacher/exams/[id]/proctoring` — B2末WS 二期,需先定 WS 契约
| 模块 | 文件 | 关键 hook |
| ---------------- | ----------------------------- | --------------------------------------------------------------------------------------------------- |
| ai | `lib/api/ai.ts` | useAiAssist / useAiLessonPlan / useAiReport |
| analytics | `lib/api/analytics.ts` | useAnalytics / useStudentAnalytics |
| attendance | `lib/api/attendance.ts` | useAttendance / useAttendanceReport / useAttendanceSheet / useAttendanceStats |
| classes | `lib/api/classes.ts` | useClasses / useClassDetail / useClassStudents / useClassSchedule |
| course-plans | `lib/api/course-plans.ts` | useCoursePlans / useCoursePlanDetail |
| dashboard | `lib/api/dashboard.ts` | useTeacherDashboard |
| diagnostic | `lib/api/diagnostic.ts` | useClassDiagnostic / useStudentDiagnostic |
| elective | `lib/api/elective.ts` | useElectiveCourses / useElectiveDetail |
| error-book | `lib/api/error-book.ts` | useErrorBookItems / useErrorBookStats |
| exams | `lib/api/exams.ts` | useExams / useExamDetail / useExamAnalytics / useExamBuild / useExamProctoring |
| grades | `lib/api/grades.ts` | useGrades / useGradeEntry / useGradeStats / useReportCard |
| homework | `lib/api/homework.ts` | useHomework / useHomeworkDetail / useHomeworkSubmissions / useSubmissionDetail / useGradeSubmission |
| knowledge-graph | `lib/api/knowledge-graph.ts` | useKnowledgeGraph |
| leave | `lib/api/leave.ts` | useLeaveRequests |
| lesson-plans | `lib/api/lesson-plans.ts` | useLessonPlans / useLessonPlanDetail / useLessonPlanCalendar / useLessonPlanHeatmap |
| practice | `lib/api/practice.ts` | usePractice |
| proctoring | `lib/api/proctoring.ts` | useStudentProctoringStatuses / useRecentProctoringEvents |
| questions | `lib/api/questions.ts` | useQuestions |
| schedule-changes | `lib/api/schedule-changes.ts` | useScheduleChanges |
| students | `lib/api/students.ts` | useStudents / useStudentDetail |
| textbooks | `lib/api/textbooks.ts` | useTextbooks / useTextbookDetail |
### P2CICD 历史功能,建议补,需同步更新 ARCH §9.1
### 4.3 mocks/graphql-data.ts 覆盖116 个 mock 数据集
4. `/shell/teacher/diagnostic/student/[studentId]` — 学生诊断雷达图CICD 已有完整实现
### P3功能不完整页按业务优先级补
**高优先级(核心教学场景,差距大)**5. `classes/[id]` 班级详情 — 缺 5 个 widget概览/趋势/课表/作业/学生科目成绩班级是教师核心工作台6. `homework/[id]` 作业详情 — 缺分析卡片 + 内容卡片,作业是高频场景 7. `grades/entry` 成绩录入 — 缺批量录入,单生录入效率太低 8. `lesson-plans/[planId]/edit` 教案编辑 — 缺 Tiptap + AIcontentEditable deprecated 不可长期维护
**中优先级(交互不完整,影响体验)**9. `students` 学生列表 — 缺下拉 + 科目成绩 10. `homework/new` 布置作业 — 缺考试关联 + 班级下拉 11. `attendance/sheet` 考勤点名 — 缺班级下拉 + 学生预加载 12. `diagnostic/class/[classId]` 班级诊断 — 缺富视图 + 服务上下文 13. `exams/[id]/edit` 富文本编辑 — 缺 Tiptap + 题目结构(与 §3.9 教案编辑同类型问题,建议统一升级 Tiptap14. `exams` 列表 — 缺筛选/计数/分页/DataTable
**低优先级(功能基本可用,细节差距)**15. `exams/[id]` 详情 — 编辑按钮未接路由小修16. `exams/new` 新建考试 — 是否补富文本取决于产品决策 17. `classes` 列表 — 视觉差异,功能等价 18. `dashboard` 仪表盘 — i18n 化 + 流式渲染i18n 应立即修,违反 §3.10
269KB 文件覆盖教师域全部模块(含 3 个占位页的兜底数据:`ClassStudents`、`HomeworkSubmissions`、`SubmissionDetail`、`ExamDetail`)。所有占位页与功能差距页均有 MSW 兜底。
---
## 六、共性技术债
## 五、结论与建议
1. **Tiptap 缺失**`exams/[id]/edit``lesson-plans/[planId]/edit` 均用 `contentEditable` + `document.execCommand`deprecatedCICD 用 Tiptap。建议统一引入 Tiptap或 Lexical编写 structure→EditorDoc 转换层。
2. **dangerouslySetInnerHTML 违规**:上述两个富文本页直接 `dangerouslySetInnerHTML`,违反 §4 安全规范,需 DOMPurify 清洗。
3. **下拉选择器缺失**`students`/`homework/new`/`grades/entry`/`attendance/sheet` 等多处用 `<input type="text">` 替代 `<select>`,需补 data-access 查询 + select 组件。
4. **DataScope 校验缺失**portal-shell 普遍无 `ctx.dataScope` 权限过滤CICD 在 Server Component 内做 scope 过滤),需在后端契约就绪后补。
5. **Server Component 预加载缺失**CICD 多个详情页在 Server Component 内并行预加载多个数据源portal-shell 纯客户端 MSW等契约就绪后需改 Server Component 预加载 + Suspense 流式。
6. **AI 集成缺失**`exams/[id]/build``lesson-plans/[planId]/edit` 在 CICD 有 `AiClientProvider` + `createCoreAiClientService`portal-shell 无 AI 接入。
7. **i18n 硬编码**`dashboard` 用硬编码中文,应全面 `useTranslations`
8. **SectionErrorBoundary / WidgetBoundary 缺失**CICD 多处用 `SectionErrorBoundary`/`WidgetBoundary` 做局部降级portal-shell 用 errorNode 整页降级,粒度较粗。
### 5.1 总体结论
- 教师域 63 个 page.tsx **全部存在,无缺失**
- 60 页 ✅ 完整实现(集成 client + hooks + 三态处理)
- 3 页 🟡 占位空态(均为 CICD 重定向路径,建议改为 `redirect()` 重定向到等价已实现路径)
- 配套资产齐全55 个 client 组件 + 20 个 lib/api 模块 + 116 个 mock 数据集
### 5.2 优先级建议
| 优先级 | 项目 | 工作量 | 说明 |
| --------- | ---------------------------------- | ----------------- | --------------------------------------------------------------------------------------- |
| **P0** | 3 个占位页改为 `redirect()` 重定向 | 小(每页约 5 行) | 见 §3.1-§3.3 方案 A/B统一重定向到等价已实现路径 |
| **P1-P2** | 15 页与 CICD 功能差距补齐 | 中-大 | 见 §三.B按产品优先级逐模块迭代 |
| **P2** | 同步更新 ARCH §9.1 + 004 + arch.db | 小 | 补做 `diagnostic/student/[studentId]` 与 `exams/[id]/proctoring` 已实现但未同步规划文档 |
### 5.3 不需补做的项
- `/shell/notifications`、`/shell/settings`:属 B1 共享域(非教师域),需在共享域补页面,不在本次教师域核查范围
- `/exams/all`、`/exams/create`、`/classes/my`、`/classes/my/[id]`、`/homework/assignments/create`:为路径别名,复用同一 client不算缺失
---
## 七、参考文件索引
## 六、核查元信息
### CICD 参考实现
- `e:\desktop\CICD\src\app\(dashboard)\teacher\` — 教师域 53 页源
- `e:\desktop\CICD\src\modules\exams\components\exam-rich-form.tsx` — 富文本试卷表单
- `e:\desktop\CICD\src\modules\exams\components\exam-assembly.tsx` — 组卷工作台
- `e:\desktop\CICD\src\modules\classes\components\class-detail\` — 班级详情 5 个 widget
- `e:\desktop\CICD\src\modules\classes\components\my-classes-grid.tsx` — 班级网格
- `e:\desktop\CICD\src\modules\classes\components\students-table.tsx` — 学生表
- `e:\desktop\CICD\src\modules\homework\components\homework-assignment-question-error-overview-card.tsx` — 作业错误概览
- `e:\desktop\CICD\src\modules\homework\components\homework-assignment-exam-content-card.tsx` — 作业内容卡片
- `e:\desktop\CICD\src\modules\grades\components\batch-grade-entry.tsx` — 批量录入
- `e:\desktop\CICD\src\modules\lesson-preparation\components\lesson-plan-editor.tsx` — 教案编辑器
- `e:\desktop\CICD\src\modules\diagnostic\components\class-diagnostic-view.tsx` — 班级诊断视图
- `e:\desktop\CICD\src\modules\diagnostic\components\student-diagnostic-view.tsx` — 学生诊断视图
- `e:\desktop\CICD\src\modules\proctoring\components\proctoring-dashboard.tsx` — 监考面板
- `e:\desktop\CICD\src\modules\dashboard\components\teacher-dashboard\teacher-dashboard-view.tsx` — 仪表盘视图
### portal-shell 当前实现
- `e:\Desktop\Edu\apps\portal-shell\src\app\shell\teacher\` — 教师域 53 页
- `e:\Desktop\Edu\apps\portal-shell\src\features\teacher\` — 51 个 `*-client.tsx` + 辅助组件
- `e:\Desktop\Edu\apps\portal-shell\src\lib\api\` — Apollo hooks含 MSW 兜底)
- `e:\Desktop\Edu\apps\portal-shell\src\shared\components\page-templates\` — ListPageShell/FormPageShell/DetailPageShell/WorkbenchPageShell
- `e:\Desktop\Edu\apps\portal-shell\ARCHITECTURE.md` §9.1 — 教师域 56 页规划
### 契约工单
- `docs/architecture/issues/contracts/core-edu_contract.md` — exams/homework/grades/questions mutation 工单
- `docs/architecture/issues/contracts/classes_contract.md` — classes/students/attendance 工单
- `docs/architecture/issues/contracts/data-ana_contract.md` — diagnostic/analytics 工单
- **核查日期**2026-08-04
- **核查范围**`apps/portal-shell/src/app/shell/teacher/` 下全部 63 个 page.tsx
- **核查方式**:逐页面读取 page.tsx 文件内容PowerShell `Get-Content -LiteralPath`+ features/*-client.tsx 集成核查 + lib/api hooks 覆盖核查 + mocks/graphql-data.ts 覆盖核查
- **三态判据**:见 §0.1(✅ 引入 client 或含真实业务 / 🟡 仅 page-templates 渲染空态 / ❌ 文件不存在)
- **对比基线**`e:\desktop\CICD\src\app\(dashboard)\teacher\`CICD 原版 53 页)
- **规划依据**`apps/portal-shell/ARCHITECTURE.md` §9.1(教师域 56 页规划)
---
**分析完成。下一步建议按 §五 优先级逐项补做,每补一页同步更新 ARCH §9.1 状态 + 004 + arch.db。**
## 七、附录
### 7.1 教师域 63 个 page.tsx 完整清单
| # | 路径 | 状态 | 集成的 client |
| --- | ----------------------------------------------------------------- | ---- | ----------------------------------------------------------- |
| 1 | `/shell/teacher` | ✅ | dashboard-cards-client |
| 2 | `/shell/teacher/ai/ai-assist` | ✅ | ai-assist-client |
| 3 | `/shell/teacher/ai/ai-lesson-plan` | ✅ | ai-lesson-plan-client |
| 4 | `/shell/teacher/ai/ai-report` | ✅ | ai-report-client |
| 5 | `/shell/teacher/analytics` | ✅ | analytics-client |
| 6 | `/shell/teacher/analytics/[studentId]` | ✅ | student-analytics-client |
| 7 | `/shell/teacher/attendance` | ✅ | attendance-client |
| 8 | `/shell/teacher/attendance/report` | ✅ | attendance-report-client |
| 9 | `/shell/teacher/attendance/sheet` | ✅ | attendance-sheet-client |
| 10 | `/shell/teacher/attendance/stats` | ✅ | attendance-stats-client |
| 11 | `/shell/teacher/classes` | ✅ | classes-list-client |
| 12 | `/shell/teacher/classes/my` | ✅ | classes-list-client别名 |
| 13 | `/shell/teacher/classes/[id]` | ✅ | class-detail-client |
| 14 | `/shell/teacher/classes/my/[id]` | ✅ | class-detail-client别名 |
| 15 | `/shell/teacher/classes/schedule` | ✅ | class-schedule-client |
| 16 | `/shell/teacher/classes/students` | 🟡 | (占位,建议重定向到 /students |
| 17 | `/shell/teacher/course-plans` | ✅ | course-plans-list-client |
| 18 | `/shell/teacher/course-plans/[id]` | ✅ | course-plan-detail-client |
| 19 | `/shell/teacher/diagnostic` | ✅ | diagnostic-client |
| 20 | `/shell/teacher/diagnostic/class/[classId]` | ✅ | class-diagnostic-client |
| 21 | `/shell/teacher/diagnostic/student/[studentId]` | ✅ | student-diagnostic-client |
| 22 | `/shell/teacher/elective` | ✅ | elective-list-client |
| 23 | `/shell/teacher/elective/create` | ✅ | elective-create-client |
| 24 | `/shell/teacher/elective/[id]/edit` | ✅ | elective-edit-client |
| 25 | `/shell/teacher/error-book` | ✅ | error-book-client |
| 26 | `/shell/teacher/exams` | ✅ | exams-list-client |
| 27 | `/shell/teacher/exams/all` | ✅ | exams-list-client别名 |
| 28 | `/shell/teacher/exams/new` | ✅ | new-exam-client |
| 29 | `/shell/teacher/exams/create` | ✅ | new-exam-client别名 |
| 30 | `/shell/teacher/exams/[id]` | ✅ | exam-detail-client |
| 31 | `/shell/teacher/exams/[id]/analytics` | ✅ | exam-analytics-client |
| 32 | `/shell/teacher/exams/[id]/build` | ✅ | exam-build-client |
| 33 | `/shell/teacher/exams/[id]/edit` | ✅ | exam-edit-client |
| 34 | `/shell/teacher/exams/[id]/proctoring` | ✅ | proctoring-client |
| 35 | `/shell/teacher/exams/grading` | 🟡 | (占位,建议重定向到 /homework/submissions |
| 36 | `/shell/teacher/exams/grading/[submissionId]` | 🟡 | (占位,建议重定向到 /homework/submissions/[submissionId] |
| 37 | `/shell/teacher/grades` | ✅ | grades-client |
| 38 | `/shell/teacher/grades/analytics` | ✅ | grade-analytics-client |
| 39 | `/shell/teacher/grades/entry` | ✅ | grade-entry-client |
| 40 | `/shell/teacher/grades/report-card` | ✅ | report-card-client |
| 41 | `/shell/teacher/grades/stats` | ✅ | grade-stats-client |
| 42 | `/shell/teacher/homework` | ✅ | homework-list-client |
| 43 | `/shell/teacher/homework/new` | ✅ | new-homework-client |
| 44 | `/shell/teacher/homework/assignments/create` | ✅ | new-homework-client别名 |
| 45 | `/shell/teacher/homework/[id]` | ✅ | homework-detail-client |
| 46 | `/shell/teacher/homework/assignments/[id]/submissions` | ✅ | submissions-list-client |
| 47 | `/shell/teacher/homework/submissions` | ✅ | submissions-list-client |
| 48 | `/shell/teacher/homework/submissions/[submissionId]` | ✅ | submission-grading-client |
| 49 | `/shell/teacher/homework/submissions/[submissionId]/scan-grading` | ✅ | scan-grading-client |
| 50 | `/shell/teacher/knowledge-graph` | ✅ | knowledge-graph-client |
| 51 | `/shell/teacher/leave` | ✅ | leave-client |
| 52 | `/shell/teacher/lesson-plans` | ✅ | lesson-plans-list-client |
| 53 | `/shell/teacher/lesson-plans/new` | ✅ | new-lesson-plan-client |
| 54 | `/shell/teacher/lesson-plans/calendar` | ✅ | lesson-plan-calendar-client |
| 55 | `/shell/teacher/lesson-plans/heatmap` | ✅ | lesson-plan-heatmap-client |
| 56 | `/shell/teacher/lesson-plans/library` | ✅ | lesson-plan-library-client |
| 57 | `/shell/teacher/lesson-plans/[planId]/edit` | ✅ | lesson-plan-edit-client |
| 58 | `/shell/teacher/practice` | ✅ | practice-client |
| 59 | `/shell/teacher/questions` | ✅ | questions-client |
| 60 | `/shell/teacher/schedule-changes` | ✅ | schedule-changes-client |
| 61 | `/shell/teacher/students` | ✅ | students-list-client |
| 62 | `/shell/teacher/textbooks` | ✅ | textbooks-list-client |
| 63 | `/shell/teacher/textbooks/[id]` | ✅ | textbook-detail-client |
### 7.2 features/teacher 模块与 client 组件清单20 模块 / 55 client
| 模块目录 | client 组件数 | client 组件清单 |
| ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- |
| ai | 3 | ai-assist / ai-lesson-plan / ai-report |
| analytics | 2 | analytics / student-analytics |
| attendance | 4 | attendance / attendance-report / attendance-sheet / attendance-stats |
| classes | 3 | classes-list / class-detail / class-schedule |
| course-plans | 2 | course-plans-list / course-plan-detail |
| dashboard | 1 | dashboard-cards |
| diagnostic | 3 | diagnostic / class-diagnostic / student-diagnostic |
| elective | 3 | elective-list / elective-create / elective-edit |
| error-book | 1 | error-book |
| exams | 7 | exams-list / new-exam / exam-detail / exam-analytics / exam-build / exam-edit / proctoring |
| grades | 5 | grades / grade-analytics / grade-entry / report-card / grade-stats |
| homework | 8 | homework-list / new-homework / homework-detail / submissions-list / submission-grading / scan-grading |
| knowledge-graph | 1 | knowledge-graph |
| leave | 1 | leave |
| lesson-plans | 6 | lesson-plans-list / new-lesson-plan / lesson-plan-calendar / lesson-plan-heatmap / lesson-plan-library / lesson-plan-edit |
| practice | 1 | practice |
| proctoring | 1 | proctoring共享给 exams |
| questions | 1 | questions |
| schedule-changes | 1 | schedule-changes |
| students | 1 | students-list |
| textbooks | 2 | textbooks-list / textbook-detail |
> **注**proctoring-client 位于 `features/teacher/proctoring/`,被 `exams/[id]/proctoring/page.tsx` 集成scan-grading-client 位于 `features/teacher/homework/`,被 `homework/submissions/[submissionId]/scan-grading/page.tsx` 集成。
---
## 八、变更历史
| 日期 | 版本 | 变更内容 |
| ---------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2026-07-24 | v1 | 初版核查53→63 页迁移分析) |
| 2026-08-04 | v2 | 严格三态核查(逐页读 page.tsx60 ✅ / 3 🟡 / 0 ❌3 占位页改为重定向建议15 功能差距页归 P1-P2 backlog补全附录 §七.1 63 页完整清单 + §七.2 55 client 清单 |