Files
Edu/apps/portal-shell/docs/needtodo/student-NeedTodo.md
SpecialX 04b7a40bdc feat(portal-shell): 学生域全页面迁移与规范合规修复
- 学生域 32 页全量迁移(含作答/自动保存/提交/诊断)

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

- 修 4 处 Tailwind 任意值;新增共享组件与路由
2026-08-31 11:25:21 +08:00

36 KiB
Raw Blame History

学生域Student实现完整性核查报告

参考项目:e:\desktop\CICD\src\app\(dashboard)\student\ 当前项目:e:\Desktop\Edu\apps\portal-shell\src\app\shell\student\ 规划依据:apps/portal-shell/ARCHITECTURE.md §9.236 页B3 批次) 核查日期2026-08-04 任务范围:仅核查,不修改源代码


一、页面完成度总览

1.1 portal-shell 学生域现状2026-08-04 核查)

apps/portal-shell/src/app/shell/student/ 下共有 32 个 page.tsx 文件全部为真实业务页Server Component 入口 + Client Component 业务实现)。

状态 数量 说明
完整实现 32 page.tsx 引入 @/features/student/*-client.tsx 并渲染,三态完整
🟡 占位空态 0 无(原 2026-07-24 报告中的 34 个缺失页已全部补齐)
缺失 0
本次核查总数 32 不含 announcements / messages / notifications / settings 共享路由

1.2 架构模式统一(与 2026-07-24 报告对比)

原报告指出仪表盘为 Client Component 硬编码中文、无权限校验。当前所有 32 页已统一为:

维度 当前实现
渲染模式 Server Component 入口 + Client Component 业务(统一 Suspense 边界)
数据获取 useWidgetQuery / useWidgetMutation Hook走 Apollo Client + BFF
国际化 next-intl useTranslations(全部页面已接入 i18n key
三态规范 loadingSkeleton/ error局部降级/ emptyEmptyState均按 §11.3
加载骨架 ListPageSkeleton / DetailPageSkeleton / WorkbenchPageSkeleton
契约状态 全部 @contract-pendingschema 根字段未定义MSW 兜底)

1.3 文件统计

类别 数量 说明
page.tsx 32 全部存在,全部引入 client 组件
features/student/*.tsx 38 全部为真实实现115-698 行)
lib/api student 相关 hook 40+ student-portal.ts + student.ts + 各域文件
graphql-data.ts mock handler 28/32 4 个页面存在 mock 缺口(见 §七)

二、按模块核查清单

2.1 dashboard 模块3 页, 全部完整)

2.1.1 /shell/student/page.tsx(仪表盘首页)

  • page.tsx:引入 StudentDashboardClientSuspense + DetailPageSkeleton
  • client 组件features/student/dashboard/dashboard-client.tsx632 行)
  • API hookuseStudentDashboard()lib/api/dashboard.ts
  • mock 数据 case "GetStudentDashboard"graphql-data.ts L5575
  • 三态loading/error/empty 完整

2.1.2 /shell/student/trend(学习趋势详情页)

  • page.tsx:引入 StudentTrendClientSuspense + DetailPageSkeleton
  • client 组件features/student/dashboard/trend-client.tsx166 行)
  • API hookuseStudentTrend()lib/api/student-portal.ts
  • mock 数据 case "GetStudentTrend"graphql-data.ts L9633
  • 三态loading/error/empty 完整

2.1.3 /shell/student/weakness(薄弱知识点详情页)

  • page.tsx:引入 StudentWeaknessClientSuspense + DetailPageSkeleton
  • client 组件features/student/dashboard/weakness-client.tsx194 行)
  • API hookuseStudentPortalWeakness()lib/api/student-portal.ts
  • mock 数据 case "GetStudentPortalWeakness"graphql-data.ts L9636
  • 三态loading/error/empty 完整

2.2 grades 模块2 页, 全部完整)

2.2.1 /shell/student/grades(成绩列表页)

  • page.tsx:引入 StudentGradesListClientSuspense + ListPageSkeleton
  • client 组件features/student/grades/grades-list-client.tsx516 行)
  • API hookuseStudentGrades(subject, type, q)lib/api/student-portal.ts
  • mock 数据 case "GetStudentGrades"graphql-data.ts L9586
  • 三态loading/error/empty 完整

2.2.2 /shell/student/grades/report-card(成绩报告卡页)

  • page.tsx:引入 StudentReportCardClient,导入 report-card-print.cssSuspense + DetailPageSkeleton
  • client 组件features/student/grades/report-card-client.tsx693 行)+ 子组件growth-archive-card / ranking-trend-card / score-distribution-card
  • API hookuseStudentReportCard(academicYearId, semester)lib/api/student-portal.ts
  • mock 数据 case "GetStudentReportCard"graphql-data.ts L9588
  • 三态loading/error/empty 完整

2.3 exams 模块3 页, 全部完整)

2.3.1 /shell/student/exams(考试列表页)

  • page.tsx:引入 StudentExamsListClientSuspense + ListPageSkeleton
  • client 组件features/student/exams/exams-list-client.tsx331 行)
  • API hookuseStudentExams(status)lib/api/student-portal.ts
  • mock 数据 case "GetStudentExams"graphql-data.ts L9591
  • 三态loading/error/empty 完整

2.3.2 /shell/student/exams/[id]/result(考试结果页)

  • page.tsx:引入 StudentExamResultClientSuspense + DetailPageSkeleton
  • client 组件features/student/exams/exam-result-client.tsx252 行)
  • API hookuseStudentExamResult(id)lib/api/student-portal.ts
  • mock 数据 case "GetStudentExamResult"graphql-data.ts L9593
  • 三态loading/error/empty 完整

2.3.3 /shell/student/exams/[id]/take(考试作答工作台页)

  • page.tsx:引入 StudentExamTakeClientSuspense + WorkbenchPageSkeleton
  • client 组件features/student/exams/exam-take-client.tsx665 行)
  • API hookuseStudentExamTake(id) + useSubmitStudentExam()lib/api/student-portal.ts
  • mock 数据 case "GetStudentExamTake" + case "SubmitStudentExam"L9595, L9669
  • 三态loading/error/empty 完整

2.4 homework 模块3 页, 全部完整)

2.4.1 /shell/student/homework(作业列表页)

  • page.tsx:引入 StudentHomeworkListClientSuspense + ListPageSkeleton
  • client 组件features/student/homework/homework-list-client.tsx547 行)
  • API hookuseStudentHomework(status)lib/api/student-portal.ts
  • mock 数据 case "GetStudentHomework"graphql-data.ts L9598
  • 三态loading/error/empty 完整

2.4.2 /shell/student/homework/[id]/submit(作业作答工作台页)

  • page.tsx:引入 StudentHomeworkSubmitClientSuspense + WorkbenchPageSkeleton
  • client 组件features/student/homework/homework-submit-client.tsx698 行,学生域最大文件)
  • API hookuseStudentHomeworkSubmit(id) + useSubmitStudentHomework()lib/api/student-portal.ts
  • mock 数据 case "GetStudentHomeworkSubmit" + case "SubmitStudentHomework"L9600, L9671
  • 三态loading/error/empty 完整

2.4.3 /shell/student/homework/[id]/analysis(作业分析页)

  • page.tsx:引入 StudentHomeworkAnalysisClientSuspense + DetailPageSkeleton
  • client 组件features/student/homework/homework-analysis-client.tsx139 行)
  • API hookuseStudentHomeworkAnalysis(id)lib/api/student-portal.ts
  • mock 数据 case "GetStudentHomeworkAnalysis"graphql-data.ts L9602
  • 三态loading/error/empty 完整

2.5 schedule 模块1 页, 完整)

2.5.1 /shell/student/schedule(课表页)

  • page.tsx:引入 StudentScheduleListClientSuspense + ListPageSkeleton
  • client 组件features/student/schedule/schedule-list-client.tsx244 行)
  • API hookuseStudentSchedule() + useStudentClasses()lib/api/student-portal.ts
  • mock 数据 case "GetStudentSchedule" + case "GetStudentClasses"L9605, L9609
  • 三态loading/error/empty 完整

2.6 attendance 模块1 页, 完整)

2.6.1 /shell/student/attendance(考勤页)

  • page.tsx:引入 StudentAttendanceClientSuspense + DetailPageSkeleton
  • client 组件features/student/attendance/attendance-client.tsx252 行)
  • API hookuseStudentAttendance()lib/api/student-portal.ts
  • mock 数据 case "GetStudentAttendance"graphql-data.ts L9607
  • 三态loading/error/empty 完整

2.7 classes 模块1 页, 完整)

2.7.1 /shell/student/classes(班级列表页)

  • page.tsx:引入 StudentClassesListClientSuspense + ListPageSkeleton
  • client 组件features/student/classes/classes-list-client.tsx134 行)
  • API hookuseStudentClasses()lib/api/student-portal.ts
  • mock 数据 case "GetStudentClasses"graphql-data.ts L9609
  • 三态loading/error/empty 完整

2.8 courses 模块2 页, 全部完整)

2.8.1 /shell/student/courses(课程列表页)

  • page.tsx:引入 StudentCoursesListClientSuspense + ListPageSkeleton
  • client 组件features/student/courses/courses-list-client.tsx473 行)
  • API hookuseStudentCourses(q) + useJoinClassByInvitationCode()lib/api/student-portal.ts
  • mock 数据 case "GetStudentCourses"graphql-data.ts L9611
  • 三态loading/error/empty 完整

2.8.2 /shell/student/courses/[id](课程详情页)

  • page.tsx:引入 StudentCourseDetailClientSuspense + DetailPageSkeleton
  • client 组件features/student/courses/course-detail-client.tsx248 行)
  • API hookuseStudentCourseDetail(id)lib/api/student-portal.ts
  • mock 数据 case "GetStudentCourseDetail"graphql-data.ts L9613
  • 三态loading/error/empty 完整

2.9 course-plans 模块2 页, 全部完整)

2.9.1 /shell/student/course-plans(课程计划列表页)

  • page.tsx:引入 StudentCoursePlansListClientSuspense + ListPageSkeleton
  • client 组件features/student/course-plans/course-plan-list-client.tsx340 行)
  • API hookuseStudentCoursePlans()lib/api/student-portal.ts
  • mock 数据 case "GetStudentCoursePlans"graphql-data.ts L9616
  • 三态loading/error/empty 完整

2.9.2 /shell/student/course-plans/[id](课程计划详情页)

  • page.tsx:引入 StudentCoursePlanDetailClientSuspense + DetailPageSkeleton
  • client 组件features/student/course-plans/course-plan-detail-client.tsx486 行)
  • API hookuseStudentCoursePlanDetail(id)lib/api/student-portal.ts
  • mock 数据 case "GetStudentCoursePlanDetail"graphql-data.ts L9618
  • 三态loading/error/empty 完整

2.10 lesson-plans 模块2 页, 全部完整)

2.10.1 /shell/student/lesson-plans(教案列表页)

  • page.tsx:引入 StudentLessonPlansListClientSuspense + ListPageSkeleton
  • client 组件features/student/lesson-plans/lesson-plan-list-client.tsx167 行)
  • API hookuseStudentLessonPlans() + useSubjectOptions()lib/api/student-portal.ts
  • mock 数据 case "GetStudentLessonPlans"graphql-data.ts L9620
  • 三态loading/error/empty 完整

2.10.2 /shell/student/lesson-plans/[planId]/view(教案只读查看页)

  • page.tsx:引入 StudentLessonPlanViewClientSuspense + DetailPageSkeleton
  • client 组件features/student/lesson-plans/lesson-plan-view-client.tsx422 行)
  • API hookuseStudentLessonPlanView(planId)lib/api/student-portal.ts
  • mock 数据 case "GetStudentLessonPlanView"graphql-data.ts L9622
  • 三态loading/error/empty 完整

2.11 textbooks 模块2 页, 全部完整)

2.11.1 /shell/student/textbooks(教材列表页)

  • page.tsx:引入 StudentTextbooksListClientSuspense + ListPageSkeleton
  • client 组件features/student/textbooks/textbooks-list-client.tsx270 行)
  • API hookuseStudentTextbooks(q, subject, grade)lib/api/student-portal.ts
  • mock 数据 case "GetStudentTextbooks"graphql-data.ts L9624
  • 三态loading/error/empty 完整

2.11.2 /shell/student/textbooks/[id]/chapters(教材章节阅读器页)

  • page.tsx:引入 StudentTextbookChaptersClientSuspense + DetailPageSkeleton
  • client 组件features/student/textbooks/textbook-chapters-client.tsx362 行)
  • API hookuseStudentTextbookChapters(id)lib/api/student-portal.ts
  • mock 数据 case "GetStudentTextbookChapters"graphql-data.ts L9626
  • 三态loading/error/empty 完整

2.12 error-book 模块1 页, 完整)

2.12.1 /shell/student/error-book(错题本页)

  • page.tsx:引入 StudentErrorBookListClientSuspense + ListPageSkeleton
  • client 组件features/student/error-book/error-book-list-client.tsx648 行)+ error-book-detail-dialog.tsx199 行,详情弹窗子组件)
  • API hookuseStudentErrorBookV2(q, status, source, dueOnly)lib/api/student-portal.ts
  • mock 数据 case "GetStudentErrorBookV2"graphql-data.ts L9629
  • 三态loading/error/empty 完整

2.13 learning 模块1 页, 完整)

2.13.1 /shell/student/learning(学习中心首页)

  • page.tsx:引入 StudentLearningCenterClientSuspense + ListPageSkeleton
  • client 组件features/student/learning/learning-center-client.tsx153 行)
  • API hookuseStudentLearningCenter()lib/api/student-portal.ts
  • mock 数据 case "GetStudentLearningCenter"graphql-data.ts L9631
  • 三态loading/error/empty 完整

2.14 learning-path 模块1 页,🟡 页面完整但缺 mock 数据)

2.14.1 🟡 /shell/student/learning-pathAI 学习路径页)

  • page.tsx:引入 StudentLearningPathClientSuspense + DetailPageSkeleton
  • client 组件features/student/learning-path/learning-path-client.tsx224 行)
  • API hookuseLearningPath(subjectId)lib/api/student.ts
  • GraphQL operationquery MyLearningPath($subjectId: ID!)student.graphql.ts L37
  • mock 数据 缺失 — graphql-data.ts 中无 case "MyLearningPath" 处理器
  • 运行时影响MSW 未命中 → 返回 { data: null } → 页面显示空态
  • 需补全:在 graphql-data.ts graphqlResponse() 中添加 case "MyLearningPath" 返回 mockLearningPath 数据

2.15 practice 模块2 页, 全部完整)

2.15.1 /shell/student/practice(自适应练习首页)

  • page.tsx:引入 StudentPracticeListClientSuspense + ListPageSkeleton
  • client 组件features/student/practice/practice-list-client.tsx507 行)
  • API hookuseStudentPractice() + useStartPracticeSession()lib/api/student-portal.ts
  • mock 数据 case "GetStudentPractice" + case "StartPracticeSession"L9639, L9673
  • 三态loading/error/empty 完整

2.15.2 /shell/student/practice/[sessionId](练习会话详情页)

  • page.tsx:引入 StudentPracticeSessionClientSuspense + DetailPageSkeleton
  • client 组件features/student/practice/practice-session-client.tsx191 行)
  • API hookuseStudentPracticeSession(sessionId) + useSubmitPracticeAnswer()lib/api/student-portal.ts
  • mock 数据 case "GetStudentPracticeSession" + case "SubmitPracticeAnswer"L9641, L9675
  • 三态loading/error/empty 完整

2.16 elective 模块2 页,🟡 列表页部分缺 mock / 详情页缺 mock

2.16.1 🟡 /shell/student/elective(选课列表页)

  • page.tsx:引入 StudentElectiveListClientSuspense + ListPageSkeleton
  • client 组件features/student/elective/elective-list-client.tsx636 行)
  • API hookuseElectiveCourses(termId) + useStudentSelections(termId) + useEnrollCourse() + useDropCourse()lib/api/student.ts
  • GraphQL operationsquery ElectiveCourses + query StudentSelectionsstudent.graphql.ts L53, L87
  • mock 数据
    • case "ElectiveCourses"graphql-data.ts L9681→ 可选课程列表有数据
    • case "EnrollCourse" + case "DropCourse"L9683, L9685→ 选退课 mutation 有数据
    • 缺失 case "StudentSelections" → 学生已选课程列表无数据
  • 运行时影响:可选课程正常展示,但"我的选课"区域为空
  • 需补全:在 graphql-data.ts 添加 case "StudentSelections" 返回学生已选课程 mock 数据

2.16.2 🟡 /shell/student/elective/[id](选课详情页)

  • page.tsx:引入 StudentElectiveDetailClientSuspense + DetailPageSkeleton
  • client 组件features/student/elective/elective-detail-client.tsx187 行)
  • API hookuseStudentElectiveDetail(id)lib/api/student-portal.ts
  • GraphQL operationquery GetStudentElectiveDetail($id: ID!)student.graphql.ts L439
  • mock 数据 缺失 — graphql-data.ts 中无 case "GetStudentElectiveDetail" 处理器
  • 运行时影响MSW 未命中 → 返回 { data: null } → 页面显示空态
  • 需补全:在 graphql-data.ts 添加 case "GetStudentElectiveDetail" 返回 mockStudentElectiveDetail 数据

2.17 diagnostic 模块1 页,🟡 页面完整但 mock handler 名不匹配)

2.17.1 🟡 /shell/student/diagnostic(诊断报告页)

  • page.tsx:引入 StudentSelfDiagnosticClientSuspense + DetailPageSkeleton
  • client 组件features/student/diagnostic/diagnostic-client.tsx603 行)
  • API hookuseStudentSelfDiagnostic()lib/api/student-portal.ts
  • GraphQL operationquery GetStudentSelfDiagnosticstudent.graphql.ts L711
  • mock 数据 名称不匹配 — graphql-data.ts 中有 case "GetStudentDiagnostic"L9804但 hook 发送的 operationName 是 GetStudentSelfDiagnostic
  • 运行时影响MSW case 不匹配 → 返回 { data: null } → 页面显示空态
  • 需补全:在 graphql-data.ts 将 case "GetStudentDiagnostic" 改为 case "GetStudentSelfDiagnostic"(或新增同名 case

2.18 ai-tutor 模块1 页, 完整)

2.18.1 /shell/student/ai-tutorAI 辅导页)

  • page.tsx:引入 StudentAiTutorClientSuspense + DetailPageSkeleton
  • client 组件features/student/ai-tutor/ai-tutor-client.tsx241 行)
  • API hookuseAiTutorSessions(limit) + useSendAiTutorMessage()lib/api/student.ts
  • mock 数据 case "AiTutorSessions" + case "SendAiTutorMessage"graphql-data.ts L9687, L9689
  • 三态loading/error/empty 完整

2.19 leave 模块1 页, 完整)

2.19.1 /shell/student/leave(在线请假页)

  • page.tsx:引入 StudentLeaveClientSuspense + DetailPageSkeleton
  • client 组件features/student/leave/leave-client.tsx115 行)+ leave-request-form.tsx202 行)+ leave-request-list.tsx253 行)
  • API hookuseStudentLeave(page, pageSize) + useSubmitLeaveRequest() + useStudentClasses()lib/api/student-portal.ts
  • mock 数据 case "GetStudentLeave" + case "SubmitLeaveRequest"graphql-data.ts L9643, L9677
  • 三态loading/error/empty 完整

三、按模块汇总

模块 页数 完整 🟡 mock 缺口 备注
dashboard 3 3 0 仪表盘 + trend + weakness 全部完成
grades 2 2 0 列表 + 报告卡(含 3 个子组件 + 打印 CSS
exams 3 3 0 列表 + result + take 工作台665 行最复杂之一)
homework 3 3 0 列表 + submit 工作台698 行最大文件)+ analysis
schedule 1 1 0
attendance 1 1 0
classes 1 1 0
courses 2 2 0
course-plans 2 2 0
lesson-plans 2 2 0
textbooks 2 2 0
error-book 1 1 0 列表 + 详情弹窗
learning 1 1 0
learning-path 1 0 1 MyLearningPath mock handler
practice 2 2 0
elective 2 0 2 列表缺 StudentSelections mock详情缺 GetStudentElectiveDetail mock
ai-tutor 1 1 0
leave 1 1 0 表单 + 列表分页
diagnostic 1 0 1 mock handler 名不匹配(GetStudentDiagnostic vs GetStudentSelfDiagnostic
合计 32 28 4 28 页完全可用4 页存在 mock 缺口

结论32 个页面在结构上全部完整page.tsx + client 组件 + API hook + 三态处理),其中 28 页 mock 数据齐全可完整运行4 页存在 mock 数据缺口需补齐。


四、关键技术实现差异 & 迁移完成情况

4.1 架构模式迁移(已全部完成)

维度 CICD参考 portal-shell当前 迁移状态
渲染模式 Server Component 为主 Server Component 入口 + Client Component 业务 已统一
数据获取 Server Action + Drizzle 直查 DB useWidgetQuery Hook → Apollo Client → BFF / 微服务 已迁移
国际化 next-intl getTranslations next-intl useTranslations(全部页面接入) 已统一
三态规范 各页不一致 统一 loadingSkeleton/ error局部降级/ emptyEmptyState 已统一
权限校验 requirePermission + getAuthContext 前端 usePermission().hasPermission(),后端 Gateway + BFF 已迁移
共享 UI @/modules/<domain>/components/* @/features/student/<module>/*-client.tsx + @/shared/components/ui/* 已迁移

4.2 路由路径对齐(已全部完成)

CICD 路径 目标路由 迁移状态
learning/assignments homework
learning/assignments/[assignmentId] homework/[id]/submit
learning/assignments/[assignmentId]/result homework/[id]/analysis
learning/courses courses
learning/courses/[classId] courses/[id]
learning/textbooks textbooks
learning/textbooks/[id] textbooks/[id]/chapters
learning/study-path learning-path
(无) exams/* 全新
(无) ai-tutor 全新
(无) classes 全新

4.3 共享组件清单(已全部建立)

原报告列出的 40+ 共享组件已全部在 portal-shell 中以 client 组件形式实现:

  • ListPageShell / DetailPageShell / WorkbenchPageShellpage-templates
  • ListPageSkeleton / DetailPageSkeleton / WorkbenchPageSkeleton(骨架)
  • EmptyState(空态)
  • Button / Badge / Card 等 UI 基础组件(@/shared/components/ui/*
  • 各域专用组件(@/features/student/<module>/*-client.tsx

五、CICD 与 ARCHITECTURE.md §9.2 对照表2026-08-04 核查)

ARCH §9.2 目标路由 CICD 源页面 portal-shell 实现状态 mock 数据状态 备注
/shell/student 完整 仪表盘
/shell/student/trend 完整 全新设计
/shell/student/weakness 完整 全新设计
/shell/student/grades 完整
/shell/student/grades/report-card 完整 含打印 CSS
/shell/student/exams 完整 全新设计
/shell/student/exams/[id]/result 完整 全新设计
/shell/student/exams/[id]/take 完整 665 行,最复杂之一
/shell/student/homework 完整
/shell/student/homework/[id]/submit 完整 698 行,最大文件
/shell/student/homework/[id]/analysis 完整
/shell/student/schedule 完整
/shell/student/attendance 完整
/shell/student/classes 完整 全新设计
/shell/student/courses 完整
/shell/student/courses/[id] 完整
/shell/student/course-plans 完整
/shell/student/course-plans/[id] 完整
/shell/student/lesson-plans 完整
/shell/student/lesson-plans/[planId]/view 完整
/shell/student/textbooks 完整
/shell/student/textbooks/[id]/chapters 完整
/shell/student/error-book 完整
/shell/student/learning 完整
/shell/student/learning-path 完整 缺 mock
/shell/student/practice 完整
/shell/student/practice/[sessionId] 完整
/shell/student/elective 完整 🟡 部分缺 mock
/shell/student/elective/[id] 完整 缺 mock
/shell/student/ai-tutor 完整 全新设计
/shell/student/leave 完整
/shell/student/diagnosticCICD 额外) 完整 mock 名不匹配

六、风险与建议

6.1 当前风险点

  1. Mock 数据缺口4 页)learning-path / elective/[id] / diagnostic / elective部分的 MSW handler 缺失或名称不匹配,开发环境下这 4 页将显示空态而非 mock 数据。详见 §七。
  2. 契约全部 @contract-pending32 页的 GraphQL 查询字段在 schema 中均未定义根字段,全部依赖 MSW 兜底。后端补齐 schema 后需逐页切换 fetcher。
  3. 权限校验待确认:前端 client 组件未见 usePermission().hasPermission() 调用,权限校验可能依赖 Gateway + BFF 层(需确认后端实现)。

6.2 建议

  1. 优先补齐 mock 缺口:按 §七 列出的 4 个 mock 缺口补齐 graphql-data.ts 中的 case handler使全部 32 页在开发环境可完整运行。
  2. 契约补齐计划:按 §9.2 优先级P0 exams/homework → P1 grades/schedule → P2 其余)逐步在 shared-proto / BFF schema 中补齐 studentXxx 根字段。
  3. diagnostic 决策ARCHITECTURE.md §9.2 未将 diagnostic 列入 36 页清单,但页面已实现。需产品确认是否保留并补充到 §9.2。
  4. 权限点映射:确认前端是否需要在 client 组件中添加 usePermission().hasPermission() 调用,或完全依赖 Gateway 层鉴权。

七、Mock 数据缺口清单(需补齐)

以下 4 个页面的 page.tsx + client 组件 + API hook 均已完整实现,但 src/mocks/graphql-data.ts 中缺少对应的 MSW case handler导致开发环境下页面无法展示 mock 数据:

# 页面 GraphQL operationName student.graphql.ts 位置 graphql-data.ts 状态 影响
1 /shell/student/learning-path MyLearningPath L37 无 case 学习路径页全空
2 /shell/student/elective/[id] GetStudentElectiveDetail L439 无 case 选课详情页全空
3 /shell/student/diagnostic GetStudentSelfDiagnostic L711 case 名不匹配(现有 GetStudentDiagnostic L9804 诊断报告页全空
4 /shell/student/elective(部分) StudentSelections L87 无 case "我的选课"区域空(可选课程正常)

补齐方案

  1. MyLearningPath:在 graphql-data.ts 添加 case "MyLearningPath" + 新建 mockMyLearningPath 数据(含 nodes/edges 结构)
  2. GetStudentElectiveDetail:在 graphql-data.ts 添加 case "GetStudentElectiveDetail" + 新建 mockStudentElectiveDetail 数据(含课程详情 + 选课状态)
  3. GetStudentSelfDiagnostic:将 graphql-data.ts L9804 的 case "GetStudentDiagnostic" 改为 case "GetStudentSelfDiagnostic"(或新增同名 case 保留原 case
  4. StudentSelections:在 graphql-data.ts 添加 case "StudentSelections" + 新建 mockStudentSelections 数据(含已选课程列表)

八、与 2026-07-24 报告对比(变更总结)

维度 2026-07-24 报告 2026-08-04 核查结果
完成页面数 1仅 dashboard 基础版) 32全部页面结构完整
缺失页面数 34 0
部分完成页面数 1dashboard 缺 trend/weakness 0trend/weakness 已实现)
架构模式 Client Component + 硬编码中文 Server Component + Client Component + next-intl
路由路径对齐 6 类路径需迁移 全部已对齐
共享组件 40+ 组件需建立 全部已建立
Mock 数据覆盖 未评估 28/32 页完整4 页有缺口
最大风险 35 页未实现 4 页 mock 缺口(结构均完整)

总结:原报告识别的 35 个待完成页面已全部实现。当前仅剩 4 个页面的 MSW mock 数据需补齐,不影响页面结构完整性,仅影响开发环境的 mock 数据展示。


核查完成。32 个页面全部为真实业务实现page.tsx + client 组件 + API hook + 三态处理),其中 28 页 mock 数据齐全可完整运行4 页存在 mock 数据缺口需补齐(详见 §七)。