kindergarten_java/docs/design/class-and-scheduling-design.md
2026-02-28 16:41:39 +08:00

727 lines
38 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 班级管理与排课系统设计方案
> 版本: 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*