kindergarten_java/docs/design/class-and-scheduling-design.md

727 lines
38 KiB
Markdown
Raw Permalink Normal View History

2026-02-28 16:41:39 +08:00
# 班级管理与排课系统设计方案
> 版本: v1.0
> 设计日期: 2026-02-22
> 设计目标: 支持多教师协作、学生调班、智能排课、课程提醒
---
## 一、需求总结
### 1.1 核心需求
| 需求 | 描述 | 优先级 |
|-----|------|-------|
| 多教师协作 | 一个班级支持主班、配班、保育员等多教师 | P1 |
| 学生调班 | 学校端可给学生调换班级 | P1 |
| 学校排课 | 学校统一安排课程计划(时间、课程、班级、教师) | P1 |
| 教师自排课 | 教师可自行安排上课或预约上课 | P1 |
| 课程提醒 | 上课前的提醒通知 | P2 |
| 模式兼容 | 学校排课与教师自排课两种模式共存 | P1 |
### 1.2 行业最佳实践参考
根据调研,优秀的排课系统应具备:
1. **智能排课引擎**
- 多约束条件优化(教师时间、教室容量、课程优先级)
- 冲突自动检测与修复
- 支持手动调整
2. **可视化交互**
- 周/月视图课表
- 拖拽式调课
- 实时冲突提示
3. **多端协同**
- 课表变更实时推送
- 教师/家长端同步
4. **混合排课模式**
- 支持自动排课 + 手动微调
- 支持学校统一排课 + 教师自主预约
---
## 二、数据模型设计
### 2.1 班级教师关联(新增)
**问题**:当前 `Class.teacherId` 只能指向一个教师,无法支持多教师协作。
**解决方案**:引入中间表 `ClassTeacher`
```
┌─────────────────────────────────────────────────────────────┐
│ 班级-教师关联模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────┐│
│ │ Class │ ◄───────│ClassTeacher │────────►│ Teacher ││
│ │ │ 1:N │ │ N:1 │ ││
│ └──────────┘ │ - role │ └──────────┘│
│ │ - isPrimary │ │
│ │ - startDate │ │
│ │ - endDate │ │
│ └──────────────┘ │
│ │
│ 角色类型 (role): │
│ - MAIN: 主班教师 │
│ - ASSIST: 配班教师 │
│ - CARE: 保育员 │
│ │
└─────────────────────────────────────────────────────────────┘
```
**Prisma Schema**:
```prisma
model ClassTeacher {
id Int @id @default(autoincrement())
classId Int @map("class_id")
teacherId Int @map("teacher_id")
role String @default("MAIN") // MAIN, ASSIST, CARE
isPrimary Boolean @default(false) // 是否班主任
startDate DateTime? @map("start_date")
endDate DateTime? @map("end_date")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
teacher Teacher @relation(fields: [teacherId], references: [id], onDelete: Cascade)
@@unique([classId, teacherId])
@@map("class_teachers")
}
```
### 2.2 学生班级历史(新增)
**问题**:学生调班后无法追溯历史记录。
**解决方案**:引入 `StudentClassHistory`
```prisma
model StudentClassHistory {
id Int @id @default(autoincrement())
studentId Int @map("student_id")
classId Int @map("class_id")
startDate DateTime @map("start_date")
endDate DateTime? @map("end_date")
reason String? // 调班原因
createdBy Int? @map("created_by") // 操作人
createdAt DateTime @default(now()) @map("created_at")
student Student @relation(fields: [studentId], references: [id])
class Class @relation(fields: [classId], references: [id])
@@map("student_class_history")
}
```
### 2.3 排课计划表(新增)
**核心设计**:区分"排课计划"和"授课记录"
```
┌─────────────────────────────────────────────────────────────┐
│ 排课与授课模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │SchedulePlan │ 1:N │ Lesson │ │
│ │ (排课计划) │────────►│ (授课记录) │ │
│ │ │ │ │ │
│ │ 学校创建 │ │ 教师创建 │ │
│ │ 或教师预约 │ │ 或系统生成 │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ SchedulePlan (排课计划): │
│ - 学校统一安排的课程计划 │
│ - 或教师预约的上课计划 │
│ - 可重复生成多个 Lesson │
│ │
│ Lesson (授课记录): │
│ - 实际的一次授课 │
│ - 包含上课状态、评价等 │
│ │
└─────────────────────────────────────────────────────────────┘
```
**Prisma Schema**:
```prisma
model SchedulePlan {
id Int @id @default(autoincrement())
tenantId Int @map("tenant_id")
// 关联信息
classId Int @map("class_id")
courseId Int @map("course_id")
teacherId Int? @map("teacher_id") // 可选,未分配时为空
// 时间信息
scheduledDate DateTime? @map("scheduled_date") // 具体日期
scheduledTime String? @map("scheduled_time") // 时间段 "09:00-09:30"
weekDay Int? @map("week_day") // 周几 (1-7),用于重复排课
// 重复规则
repeatType String @default("NONE") @map("repeat_type") // NONE, DAILY, WEEKLY
repeatEndDate DateTime? @map("repeat_end_date")
// 排课来源
source String @default("SCHOOL") // SCHOOL(学校排课), TEACHER(教师预约)
createdBy Int @map("created_by") // 创建人ID
// 状态
status String @default("ACTIVE") // ACTIVE, CANCELLED, COMPLETED
// 提醒设置
reminderEnabled Boolean @default(true) @map("reminder_enabled")
reminderMinutes Int @default(30) @map("reminder_minutes") // 提前多少分钟提醒
note String?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
tenant Tenant @relation(fields: [tenantId], references: [id])
class Class @relation(fields: [classId], references: [id])
course Course @relation(fields: [courseId], references: [id])
teacher Teacher? @relation(fields: [teacherId], references: [id])
lessons Lesson[]
@@map("schedule_plans")
}
```
### 2.4 课程提醒(新增)
```prisma
model CourseReminder {
id Int @id @default(autoincrement())
schedulePlanId Int? @map("schedule_plan_id")
lessonId Int? @map("lesson_id")
userId Int @map("user_id") // 接收提醒的用户
userType String @map("user_type") // TEACHER, PARENT
reminderType String @map("reminder_type") // BEFORE_CLASS, AFTER_CLASS
reminderTime DateTime @map("reminder_time")
content String
sent Boolean @default(false)
sentAt DateTime? @map("sent_at")
createdAt DateTime @default(now()) @map("created_at")
schedulePlan SchedulePlan? @relation(fields: [schedulePlanId], references: [id])
lesson Lesson? @relation(fields: [lessonId], references: [id])
@@map("course_reminders")
}
```
### 2.5 更新现有模型
**Lesson 模型更新**:
```prisma
model Lesson {
id Int @id @default(autoincrement())
tenantId Int @map("tenant_id")
teacherId Int @map("teacher_id")
classId Int @map("class_id")
courseId Int @map("course_id")
// 新增:关联排课计划
schedulePlanId Int? @map("schedule_plan_id")
plannedDatetime DateTime? @map("planned_datetime")
startDatetime DateTime? @map("start_datetime")
endDatetime DateTime? @map("end_datetime")
actualDuration Int? @map("actual_duration")
status String @default("PLANNED") // PLANNED, IN_PROGRESS, COMPLETED, CANCELLED
// ... 其他字段保持不变
schedulePlan SchedulePlan? @relation(fields: [schedulePlanId], references: [id])
@@map("lessons")
}
```
**Class 模型更新**:
```prisma
model Class {
id Int @id @default(autoincrement())
tenantId Int @map("tenant_id")
name String
grade String
// 修改teacherId 改为可选,通过 ClassTeacher 关联多个教师
teacherId Int? @map("teacher_id") // 保留用于向后兼容
// 新增字段
classroom String? // 教室位置
capacity Int @default(30) // 班级容量
studentCount Int @default(0) @map("student_count")
lessonCount Int @default(0) @map("lesson_count")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
tenant Tenant @relation(fields: [tenantId], references: [id])
teacher Teacher? @relation(fields: [teacherId], references: [id])
classTeachers ClassTeacher[]
students Student[]
lessons Lesson[]
schedulePlans SchedulePlan[]
studentHistory StudentClassHistory[]
@@map("classes")
}
```
---
## 三、功能模块设计
### 3.1 学校端功能
#### 3.1.1 班级管理增强
```
┌─────────────────────────────────────────────────────────────┐
│ 学校端 - 班级管理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【班级列表】 │
│ ├── 班级基本信息(名称、年级、教室、容量) │
│ ├── 教师团队(主班、配班、保育员) │
│ ├── 学生列表 │
│ └── 操作:编辑、归档、删除 │
│ │
│ 【教师分配】 │
│ ├── 添加教师到班级 │
│ ├── 设置教师角色(主班/配班/保育) │
│ ├── 设置班主任 │
│ └── 移除教师 │
│ │
│ 【学生管理】 │
│ ├── 查看班级学生 │
│ ├── 添加学生到班级 │
│ ├── 学生调班(选择目标班级) │
│ └── 移除学生 │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### 3.1.2 排课管理(新增)
```
┌─────────────────────────────────────────────────────────────┐
│ 学校端 - 排课管理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【排课计划列表】 │
│ ├── 筛选:班级/教师/课程/日期范围 │
│ ├── 状态:待执行/已完成/已取消 │
│ └── 操作:编辑、取消、生成授课记录 │
│ │
│ 【新建排课】 │
│ ├── 选择班级 │
│ ├── 选择课程 │
│ ├── 选择教师(可选,不选则待分配) │
│ ├── 设置时间 │
│ │ ├── 单次:选择具体日期时间 │
│ │ └── 重复每周X开始日期结束日期 │
│ ├── 提醒设置 │
│ └── 保存 │
│ │
│ 【课表视图】 │
│ ├── 周视图:按班级/教师展示一周课表 │
│ ├── 月视图:月度排课概览 │
│ └── 冲突检测:实时提示时间/教师/教室冲突 │
│ │
│ 【批量排课】 │
│ ├── Excel导入排课计划 │
│ └── 复制上周排课 │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 3.2 教师端功能
#### 3.2.1 我的班级
```
┌─────────────────────────────────────────────────────────────┐
│ 教师端 - 我的班级 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【班级列表】 │
│ ├── 显示我参与的班级(主班/配班/保育) │
│ ├── 班级信息卡片 │
│ │ ├── 班级名称、年级 │
│ │ ├── 我的角色(标签显示) │
│ │ ├── 学生人数 │
│ │ └── 同班教师 │
│ └── 操作:查看学生、开始备课、查看课表 │
│ │
│ 【班级学生】 │
│ ├── 学生列表(同班所有学生) │
│ └── 学生详情 │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### 3.2.2 我的课表(新增)
```
┌─────────────────────────────────────────────────────────────┐
│ 教师端 - 我的课表 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【课表视图】 │
│ ├── 周视图:显示本周所有排课 │
│ ├── 日视图:显示今日课程详情 │
│ └── 月视图:月度课程概览 │
│ │
│ 【课程来源标识】 │
│ ├── 🏫 学校排课:由学校统一安排 │
│ └── 👤 自主预约:教师自己创建 │
│ │
│ 【课程状态】 │
│ ├── 待上课plannedDatetime 未到 │
│ ├── 进行中:已开始上课 │
│ ├── 已完成:上课结束 │
│ └── 已取消:排课被取消 │
│ │
│ 【操作】 │
│ ├── 查看课程详情 │
│ ├── 开始上课(进入上课模式) │
│ └── 申请调课(需学校审批) │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### 3.2.3 自主排课/预约上课
```
┌─────────────────────────────────────────────────────────────┐
│ 教师端 - 自主排课/预约 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【预约上课】(原有功能增强) │
│ ├── 选择课程 │
│ ├── 选择班级 │
│ ├── 设置预约时间 │
│ ├── 开启课程提醒 │
│ └── 创建 │
│ │
│ 【即时上课】(原有功能) │
│ ├── 从课程详情页直接开始 │
│ └── 自动创建 Lesson 记录 │
│ │
│ 【我的预约列表】 │
│ ├── 查看所有预约记录 │
│ ├── 修改/取消预约 │
│ └── 开始上课 │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## 四、业务流程设计
### 4.1 排课模式对比
```
┌─────────────────────────────────────────────────────────────┐
│ 两种排课模式对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【模式一:学校统一排课】 │
│ │
│ 学校教务 ──创建──► SchedulePlan ──生成──► Lesson │
│ │ │ │
│ │ ├── 关联班级 │
│ │ ├── 关联课程 │
│ │ ├── 指定教师(或待分配) │
│ │ └── 设置时间 │
│ │ │
│ └─────────── 发送通知给教师 ──────────────┘ │
│ │
│ 【模式二:教师自主预约】 │
│ │
│ 教师 ──创建──► SchedulePlan (source=TEACHER) │
│ │ │ │
│ │ └── 自动生成 Lesson │
│ │ │
│ └─────────── 设置提醒 ────────────────────┘ │
│ │
│ 【模式三:即时上课】(原有) │
│ │
│ 教师 ──开始上课──► 直接创建 Lesson │
│ │ │ │
│ │ └── 状态: IN_PROGRESS │
│ │ │
│ └─────────── 无需预约 ──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 4.2 课程提醒流程
```
┌─────────────────────────────────────────────────────────────┐
│ 课程提醒流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ SchedulePlan │ │
│ │ (有提醒) │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 定时任务扫描 │────►│ 检查提醒时间 │ │
│ │ (每分钟) │ │ │ │
│ └──────────────┘ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 创建提醒记录 │ │
│ │ CourseReminder │ │
│ └────────┬─────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 站内消息 │ │ 微信推送 │ │ 短信通知 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 提醒对象: │
│ - 主班教师、配班教师 │
│ - 可选:家长(需要家长端支持) │
│ │
│ 提醒时机: │
│ - 默认上课前30分钟 │
│ - 可配置15分钟、30分钟、1小时、1天 │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 4.3 学生调班流程
```
┌─────────────────────────────────────────────────────────────┐
│ 学生调班流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 学校端操作: │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │选择学生│────►│选择新班│────►│确认调班│ │
│ └────────┘ └────────┘ └────┬───┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────┐ │
│ │ 系统自动处理: │ │
│ │ 1. 更新 Student.classId │ │
│ │ 2. 更新旧班 studentCount │ │
│ │ 3. 更新新班 studentCount │ │
│ │ 4. 创建 StudentClassHistory│ │
│ │ 5. 记录调班原因和操作人 │ │
│ └─────────────────────────────┘ │
│ │
│ 权限控制: │
│ - 只有学校端可以调班 │
│ - 教师端只能查看,无权操作 │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## 五、API 设计
### 5.1 学校端 API
```
# 班级管理
POST /school/classes # 创建班级
GET /school/classes # 班级列表
PUT /school/classes/:id # 更新班级
DELETE /school/classes/:id # 删除班级
# 班级教师管理
GET /school/classes/:id/teachers # 获取班级教师列表
POST /school/classes/:id/teachers # 添加教师到班级
PUT /school/classes/:id/teachers/:tid # 更新教师角色
DELETE /school/classes/:id/teachers/:tid # 移除教师
# 学生调班
POST /school/students/:id/transfer # 学生调班
GET /school/students/:id/history # 学生班级历史
# 排课管理
GET /school/schedules # 排课列表
POST /school/schedules # 创建排课
PUT /school/schedules/:id # 更新排课
DELETE /school/schedules/:id # 取消排课
POST /school/schedules/:id/generate # 生成授课记录
# 课表视图
GET /school/schedules/timetable # 课表视图(周/月)
GET /school/schedules/conflicts # 冲突检测
```
### 5.2 教师端 API
```
# 我的班级
GET /teacher/classes # 我的班级列表
GET /teacher/classes/:id # 班级详情
GET /teacher/classes/:id/students # 班级学生
GET /teacher/classes/:id/teachers # 同班教师
# 我的课表
GET /teacher/schedules # 我的排课列表
GET /teacher/schedules/timetable # 我的课表视图
GET /teacher/schedules/today # 今日课程
# 自主排课/预约
POST /teacher/schedules # 创建预约
PUT /teacher/schedules/:id # 修改预约
DELETE /teacher/schedules/:id # 取消预约
# 上课
POST /teacher/lessons # 开始上课(即时或预约)
POST /teacher/lessons/:id/start # 开始上课
POST /teacher/lessons/:id/finish # 结束上课
# 提醒
GET /teacher/reminders # 我的提醒列表
PUT /teacher/reminders/:id/read # 标记已读
```
---
## 六、前端页面设计
### 6.1 学校端新增页面
| 页面 | 路由 | 功能 |
|-----|------|------|
| 排课管理 | /school/schedules | 排课列表、新建、编辑 |
| 课表视图 | /school/schedules/timetable | 周/月课表视图 |
| 班级教师 | /school/classes/:id/teachers | 管理班级教师团队 |
| 学生调班 | /school/students/:id/transfer | 学生调班操作 |
### 6.2 教师端新增/修改页面
| 页面 | 路由 | 功能 |
|-----|------|------|
| 我的课表 | /teacher/schedules | 查看排课计划 |
| 预约上课 | /teacher/schedules/create | 创建预约 |
| 我的班级 | /teacher/classes | 修改:显示教师角色 |
---
## 七、实施计划
### 7.1 阶段划分
```
┌─────────────────────────────────────────────────────────────┐
│ 实施阶段 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【Phase 1: 数据模型更新】(3天) │
│ ├── 创建 ClassTeacher 表 │
│ ├── 创建 StudentClassHistory 表 │
│ ├── 创建 SchedulePlan 表 │
│ ├── 创建 CourseReminder 表 │
│ ├── 数据迁移:现有数据兼容处理 │
│ └── 更新 Prisma schema │
│ │
│ 【Phase 2: 学校端功能】(5天) │
│ ├── 班级教师管理API + 前端 │
│ ├── 学生调班API + 前端 │
│ ├── 排课管理API + 前端 │
│ └── 课表视图前端 │
│ │
│ 【Phase 3: 教师端功能】(4天) │
│ ├── 我的班级增强(显示角色) │
│ ├── 我的课表API + 前端 │
│ ├── 自主预约功能增强 │
│ └── 课程来源标识 │
│ │
│ 【Phase 4: 提醒系统】(3天) │
│ ├── 提醒记录创建 │
│ ├── 定时任务服务 │
│ ├── 站内消息通知 │
│ └── (可选) 微信/短信推送 │
│ │
│ 【Phase 5: 测试与优化】(2天) │
│ ├── 功能测试 │
│ ├── 性能优化 │
│ └── 文档更新 │
│ │
│ 总计: 约17个工作日 │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 7.2 优先级排序
| 优先级 | 功能 | 原因 |
|-------|------|------|
| P0 | ClassTeacher 表 | 多教师协作的基础 |
| P0 | SchedulePlan 表 | 排课功能的基础 |
| P1 | 学校端排课管理 | 核心新功能 |
| P1 | 教师端课表查看 | 教师需要看到排课结果 |
| P1 | 学生调班 | 学校管理需求 |
| P2 | 课程提醒 | 提升用户体验 |
| P3 | 微信/短信推送 | 可后期扩展 |
---
## 八、风险与对策
| 风险 | 影响 | 对策 |
|-----|------|------|
| 数据迁移复杂 | 现有数据丢失 | 保留 teacherId 字段向后兼容,渐进迁移 |
| 排课冲突 | 用户体验差 | 实时冲突检测,智能推荐替代方案 |
| 提醒延迟 | 用户错过课程 | 多渠道提醒,定时任务容错处理 |
| 前端改动大 | 开发周期长 | 分阶段实施,优先核心功能 |
---
## 九、总结
本设计方案实现了以下核心目标:
1. **多教师协作**
- 通过 ClassTeacher 中间表支持主班/配班/保育员
2. **学生调班**
- 学校端可操作,记录历史,更新统计
3. **混合排课模式**
- 学校统一排课 + 教师自主预约 + 即时上课
- 三种模式共存,灵活适配不同场景
4. **课程提醒**
- 可配置提醒时间
- 多渠道通知
5. **扩展性**
- 数据模型支持学期管理、教室管理等后续扩展
---
*设计完成于 2026-02-22*
*文档版本: v1.0*