7.9 KiB
7.9 KiB
Textbooks Module Implementation Details
Date: 2025-12-23
Updated: 2025-12-31
Author: DevOps Architect
Module: Textbooks (src/modules/textbooks)
1. 概述 (Overview)
本文档记录了教材模块 (Textbooks Module) 的全栈实现细节。该模块负责教材、章节结构及知识点映射的数字化管理,采用了 Vertical Slice Architecture 和 Immersive Workbench 交互设计。
2. 架构设计 (Architecture)
2.1 目录结构
所有教材相关的业务逻辑、数据访问和组件均封装在 src/modules/textbooks 下,实现了高度的模块化和隔离。
src/
├── app/
│ └── (dashboard)/
│ └── teacher/
│ └── textbooks/ # 路由层 (Server Components)
│ ├── page.tsx # 列表页
│ ├── loading.tsx # 列表骨架屏
│ └── [id]/ # 详情页
│ ├── page.tsx
│ └── loading.tsx
│
│ └── student/
│ └── learning/
│ └── textbooks/ # 学生端只读阅读(Server Components)
│ ├── page.tsx # 列表页(复用筛选与卡片)
│ └── [id]/ # 详情页(阅读器)
│ └── page.tsx
│
├── modules/
│ └── textbooks/ # 业务模块
│ ├── actions.ts # Server Actions (增删改)
│ ├── data-access.ts # 数据访问层 (Mock/DB)
│ ├── types.ts # 类型定义 (Schema-aligned)
│ └── components/ # 模块私有组件
│ ├── textbook-content-layout.tsx # [核心] 三栏布局工作台
│ ├── textbook-reader.tsx # [新增] 学生端只读阅读器(URL state)
│ ├── chapter-sidebar-list.tsx # 递归章节树
│ ├── knowledge-point-panel.tsx # 知识点管理面板
│ ├── create-chapter-dialog.tsx # 章节创建弹窗
│ └── ... (其他交互组件)
2.2 渲染策略
- Server Components: 页面入口 (
page.tsx) 负责初始数据获取 (Data Fetching),利用Promise.all并行拉取教材、章节和知识点数据,实现 "Render-as-you-fetch"。 - Client Components: 工作台布局 (
textbook-content-layout.tsx) 标记为'use client',接管后续的所有交互逻辑(状态管理、局部更新、弹窗控制),提供类似 SPA 的流畅体验。
3. UI/UX 细节
3.1 布局 (Layout)
采用 Immersive Workbench (沉浸式工作台) 三栏设计:
- 左侧 (Navigation):
- 展示递归的章节树 (
Recursive Tree)。 - 支持折叠/展开,清晰展示教材结构。
- 顶部提供 "+" 按钮快速创建新章节。
- 展示递归的章节树 (
- 中间 (Content):
- 阅读模式: 渲染 Markdown 格式的章节正文。
- 编辑模式: 提供
Textarea进行内容创作,支持实时保存。
- 右侧 (Context):
- 上下文感知: 仅显示当前选中章节的关联知识点。
- 提供知识点的快速添加 (
Dialog) 和删除操作。
3.2 交互 (Interactions)
- Selection State: 点击左侧章节,中间和右侧区域即时更新,无需页面跳转。
- Optimistic UI: 虽然使用 Server Actions,但通过本地状态 (
useState) 实现了操作的即时反馈(如保存正文后立即退出编辑模式)。 - Feedback: 使用
sonner(toast) 提供操作成功或失败的提示。
3.3 学生端阅读体验(Read-Only Reader)
- 两栏阅读:左侧章节树,右侧正文渲染(Markdown)。
- URL State:选中章节通过
?chapterId=写入 URL,支持刷新/分享后保持定位(nuqs)。 - 只读边界:学生端不暴露创建/删除/编辑/知识点管理入口,避免误用教师工作台能力。
4. 数据流与逻辑 (Data Flow)
4.1 Server Actions
所有数据变更操作均通过 src/modules/textbooks/actions.ts 定义的 Server Actions 处理:
createChapterAction: 创建章节(支持嵌套)。updateChapterContentAction: 更新正文内容。createKnowledgePointAction: 创建知识点并自动关联当前章节。deleteKnowledgePointAction: 删除知识点并刷新详情页数据。updateTextbookAction: 更新教材元数据(Title, Subject, Grade, Publisher)。deleteTextbookAction: 删除教材及其关联数据。delete...Action: 处理删除逻辑。
4.2 数据访问层 (Data Access)
- DB Implementation: 教材模块已接入真实数据库访问,
data-access.ts使用drizzle-orm直接查询并返回教材、章节、知识点数据。 - 章节树构建: 章节采用父子关系存储,通过一次性拉取后在内存中构建嵌套树结构,避免 N+1 查询。
- 级联删除: 删除章节时会同时删除其子章节以及关联的知识点,确保数据一致性。
- Type Safety: 定义严格的 TypeScript 类型(如
Chapter,KnowledgePoint,UpdateTextbookInput),保证数据契约与 UI 组件一致。
5. 组件复用
- 使用了
src/shared/components/ui中的 Shadcn 组件:Dialog,ScrollArea,Card,Button,Input,Textarea,Select.Collapsible用于实现递归章节树。AlertDialog用于危险操作的二次确认(删除章节/删除知识点)。
- 图标库统一使用
lucide-react.
6. Settings 功能实现 (New)
- 入口: 详情页右上角的 "Settings" 按钮。
- 组件:
TextbookSettingsDialog。 - 功能:
- Edit: 修改教材的基本信息。
- Delete: 提供红色删除按钮,二次确认后执行删除并跳转回列表页。
7. 关键更新记录 (Changelog)
7.1 数据与页面
- 教材模块从 Mock 切换为真实 DB:新增教材/章节/知识点的数据访问与 Server Actions 刷新策略。
- 列表页支持过滤/搜索:通过 query 参数驱动,统一空状态反馈。
7.2 章节侧边栏与弹窗
- 修复子章节创建弹窗“闪现后消失”:改为受控 Dialog 状态管理。
- 修复移动端操作按钮不可见/被遮挡:调整布局与可见性策略,确保小屏可点。
- 删除章节使用确认弹窗并提供删除中状态。
7.3 Markdown 阅读体验
- 阅读模式使用
react-markdown渲染章节内容,支持 GFM(表格/任务列表等)。 - 启用 Typography(
prose)排版样式,使h1/h2/...在视觉上有明显层级差异。 - 修复阅读模式内容区无法滚动:为 flex 容器补齐
min-h-0等必要约束。
7.4 知识点删除交互
- 删除知识点从浏览器
confirm()升级为AlertDialog:- 显示目标名称、危险样式按钮
- 删除中禁用交互并显示 loading 文案
- 删除成功后刷新页面数据
7.5 学生端 Textbooks 列表与阅读页(New)
- 新增学生端路由:
/student/learning/textbooks:教材列表页(RSC),复用筛选组件(nuqs)与卡片布局。/student/learning/textbooks/[id]:教材阅读页(RSC + client 阅读器容器),章节选择与阅读不跳页。
- 复用与适配:
TextbookCard增加可配置跳转基地址,避免学生端卡片误跳到教师端详情页。- 新增
TextbookReader(client)用于只读阅读体验:左侧章节树 + 右侧正文渲染,章节定位 URL 化(chapterId)。
- 质量门禁:
- 通过
npm run lint / typecheck / build。
- 通过
8. 后续计划 (Next Steps)
- 富文本编辑器: 集成编辑器替换当前 Markdown Textarea,提升编辑体验。
- 拖拽排序: 实现章节树拖拽排序与持久化。
- 知识点能力增强: 支持编辑、排序、分层(如需要)。