kindergarten_java/docs/design/23-校本课程包功能完善设计.md

554 lines
19 KiB
Markdown
Raw Normal View History

# 校本课程包功能完善设计
> 设计日期: 2026-03-11
> 设计者: Claude
> 版本: 1.0
---
## 一、需求概述
### 1.1 核心概念
**校本课程包** = 课程中心标准课程包的副本 + 二次编辑 + 保存到个人/校本中心
```
标准课程包 → 复制 → 编辑 → 保存到个人课程中心 / 校本课程中心
```
### 1.2 使用场景
| 场景 | 描述 | 保存位置 |
|------|------|----------|
| 教师个人使用 | 教师复制标准课程包,根据自己班级情况调整 | 个人课程中心 |
| 学校共享 | 教师创建优质校本课程包,分享给本校其他教师 | 校本课程中心 |
### 1.3 功能目标
1. **完整编辑** - 复用超管端7步编辑流程
2. **灵活保存** - 支持保存到个人或提交到学校
3. **数据隔离** - 校本课程包数据独立存储,不修改原始课程包
---
## 二、数据模型设计
### 2.1 现有模型
```prisma
// 校本课程包V2新增
model SchoolCourse {
id Int @id @default(autoincrement())
tenantId Int @map("tenant_id")
sourceCourseId Int @map("source_course_id") // 源课程包ID
name String
description String?
createdBy Int @map("created_by")
changesSummary String? @map("changes_summary") // 修改说明
usageCount Int @default(0) @map("usage_count")
status String @default("ACTIVE") // ACTIVE, PENDING_REVIEW, REJECTED
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
tenant Tenant @relation(fields: [tenantId], references: [id])
sourceCourse Course @relation(fields: [sourceCourseId], references: [id])
lessons SchoolCourseLesson[]
reservations SchoolCourseReservation[]
@@index([tenantId])
@@map("school_courses")
}
// 校本课程
model SchoolCourseLesson {
id Int @id @default(autoincrement())
schoolCourseId Int @map("school_course_id")
sourceLessonId Int @map("source_lesson_id")
lessonType String @map("lesson_type") // INTRODUCTION, COLLECTIVE, LANGUAGE, etc.
// 可编辑字段(当前已支持)
objectives String?
preparation String?
extension String?
reflection String?
changeNote String? @map("change_note")
// 需要扩展
stepsData String? @map("steps_data") // JSON: 完整的课程配置数据
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
schoolCourse SchoolCourse @relation(fields: [schoolCourseId], references: [id])
@@index([schoolCourseId])
@@map("school_course_lessons")
}
```
### 2.2 数据模型扩展
#### 2.2.1 SchoolCourse 扩展
```prisma
model SchoolCourse {
// ... 现有字段 ...
// ===== 新增:完整课程数据字段 =====
// 基本信息(从 Course 复制)
themeId Int? @map("theme_id")
gradeTags String @default("[]") @map("grade_tags")
domainTags String @default("[]") @map("domain_tags")
duration Int @default(25)
coverImagePath String? @map("cover_image_path")
// 课程介绍8个字段
introSummary String? @map("intro_summary")
introHighlights String? @map("intro_highlights")
introGoals String? @map("intro_goals")
introSchedule String? @map("intro_schedule")
introKeyPoints String? @map("intro_key_points")
introMethods String? @map("intro_methods")
introEvaluation String? @map("intro_evaluation")
introNotes String? @map("intro_notes")
// 排课参考和环创建设
scheduleRefData String? @map("schedule_ref_data")
environmentConstruction String? @map("environment_construction")
// ===== 新增:保存位置和状态 =====
// 保存位置PERSONAL个人 / SCHOOL校本中心
saveLocation String @default("PERSONAL") @map("save_location")
// 审核状态(仅 SCHOOL 需要审核)
reviewStatus String @default("PENDING") @map("review_status") // PENDING, APPROVED, REJECTED
reviewedBy Int? @map("reviewed_by")
reviewedAt DateTime? @map("reviewed_at")
reviewComment String? @map("review_comment")
}
```
#### 2.2.2 SchoolCourseLesson 扩展
```prisma
model SchoolCourseLesson {
// ... 现有字段 ...
// ===== 新增:完整课程配置 =====
name String
description String?
duration Int @default(25)
// 资源
videoPath String? @map("video_path")
videoName String? @map("video_name")
pptPath String? @map("ppt_path")
pptName String? @map("ppt_name")
pdfPath String? @map("pdf_path")
pdfName String? @map("pdf_name")
// stepsData: JSON格式存储完整课程配置
// 结构:
// {
// "resources": { "images": [], "videos": [], "audioList": [], "pptFiles": [], "documents": [] },
// "steps": [
// { "id": 1, "name": "热身", "stepType": "WARMUP", "duration": 5, "objective": "...", "description": "...", "script": "...", "resources": {...} },
// ...
// ]
// }
stepsData String? @map("steps_data")
}
```
---
## 三、功能设计
### 3.1 创建流程
```
1. 选择源课程包
2. 复制源课程包数据7步数据 + 课程配置)
3. 进入编辑页面复用超管端7步组件
4. 编辑课程内容
5. 选择保存位置
- 保存到个人课程中心 → 直接保存
- 提交到校本课程中心 → 进入审核流程
```
### 3.2 编辑页面设计
#### 方案A创建新页面推荐
**文件路径:**
- 教师端:`/views/teacher/school-courses/SchoolCourseEditView.vue`
- 学校端:`/views/school/school-courses/SchoolCourseEditView.vue`
**页面结构:**
```
┌─────────────────────────────────────────────┐
│ [返回] 编辑校本课程包 │
│ [保存草稿] [保存到个人] [提交到校本中心] │
├─────────────────────────────────────────────┤
│ 步骤: [基本信息] → [课程介绍] → ... → [环创建设] │
├─────────────────────────────────────────────┤
│ │
│ 当前步骤内容(复用超管端组件) │
│ │
├─────────────────────────────────────────────┤
│ [上一步] [下一步] [保存] │
└─────────────────────────────────────────────┘
```
#### 方案B扩展现有编辑页面
在超管端 `CourseEditView.vue` 增加模式参数:
```typescript
interface Props {
mode?: 'admin' | 'school'; // 编辑模式
sourceCourseId?: number; // 源课程包IDschool模式
}
```
**评估:**
- 方案A代码独立易于维护但需要复制较多代码
- 方案B代码复用但耦合度高可能影响超管端功能
**推荐方案A** - 独立页面,但通过以下方式复用组件:
1. 将超管端的7个 Step 组件提取到 `src/components/course-edit/`
2. 教师端/学校端编辑页面引用这些共享组件
### 3.3 数据流转
```
┌─────────────────────────────────────────────────────────────┐
│ 数据流转 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 源课程包 (Course + CourseLesson + LessonStep) │
│ ↓ │
│ 复制数据到 formData │
│ ↓ │
│ 7步编辑Step1-7 组件) │
│ ↓ │
│ 保存到 SchoolCourse + SchoolCourseLesson │
│ ↓ │
│ 上课时读取 SchoolCourse 数据 │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 3.4 步骤数据结构
```typescript
interface SchoolCourseFormData {
// 基本信息
basic: {
name: string;
themeId?: number;
grades: string[];
pictureBookName: string;
coreContent: string;
duration: number;
domainTags: string[];
coverImagePath: string;
};
// 课程介绍
intro: {
introSummary: string;
introHighlights: string;
introGoals: string;
introSchedule: string;
introKeyPoints: string;
introMethods: string;
introEvaluation: string;
introNotes: string;
};
// 排课参考
scheduleRefData: string;
// 环创建设
environmentConstruction: string;
// 课程配置Step4-6
lessons: {
// 导入课
introduction?: {
name: string;
objectives: string;
preparation: string;
extension: string;
reflection: string;
resources: LessonResources;
steps: LessonStepData[];
};
// 集体课
collective?: {
name: string;
objectives: string;
preparation: string;
extension: string;
reflection: string;
resources: LessonResources;
steps: LessonStepData[];
};
// 五大领域课
domainLessons: {
[key in 'LANGUAGE' | 'HEALTH' | 'SCIENCE' | 'SOCIAL' | 'ART']?: {
name: string;
objectives: string;
preparation: string;
extension: string;
reflection: string;
resources: LessonResources;
steps: LessonStepData[];
};
};
};
}
```
---
## 四、API设计
### 4.1 后端API
```
# 创建校本课程包
POST /teacher/school-courses/from-source
Body: { sourceCourseId, saveLocation: 'PERSONAL' | 'SCHOOL' }
# 获取校本课程包详情(含完整数据)
GET /teacher/school-courses/:id
Response: { schoolCourse, lessons: { introduction, collective, domainLessons } }
# 更新校本课程包(完整更新)
PUT /teacher/school-courses/:id
Body: SchoolCourseFormData
# 更新单个课程配置
PUT /teacher/school-courses/:schoolCourseId/lessons/:lessonType
Body: { objectives, preparation, extension, reflection, stepsData }
# 学校端API类似增加审核相关
POST /school/school-courses/:id/approve
POST /school/school-courses/:id/reject
```
### 4.2 前端API
```typescript
// src/api/school-course.ts
export interface SchoolCourseFormData {
basic: { ... };
intro: { ... };
scheduleRefData: string;
environmentConstruction: string;
lessons: { ... };
}
// 从源课程包创建
export function createSchoolCourseFromSource(sourceCourseId: number, saveLocation: 'PERSONAL' | 'SCHOOL') {
return http.post('/teacher/school-courses/from-source', { sourceCourseId, saveLocation });
}
// 获取完整详情(含课程配置)
export function getSchoolCourseFullDetail(id: number): Promise<SchoolCourseFormData> {
return http.get(`/teacher/school-courses/${id}/full`);
}
// 更新完整数据
export function updateSchoolCourseFull(id: number, data: SchoolCourseFormData) {
return http.put(`/teacher/school-courses/${id}/full`, data);
}
```
---
## 五、UI设计
### 5.1 创建入口
**教师端 - 课程详情页**
```
┌─────────────────────────────────────────────┐
│ [课程详情内容] │
│ │
│ [开始备课] [选择课程上课] │
│ [创建校本版本] ← 新增按钮 │
└─────────────────────────────────────────────┘
```
点击 "创建校本版本" 后:
1. 弹窗确认:将创建该课程包的校本副本,您可以自由编辑
2. 确认后跳转到编辑页面
### 5.2 编辑页面
**复用超管端7步组件顶部操作按钮调整**
```
┌─────────────────────────────────────────────┐
│ [← 返回] 编辑校本课程包 │
│ │
│ [保存草稿] [保存到个人] [提交到校本中心] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ 步骤: [基本信息] → [课程介绍] → ... → [环创建设] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ 当前步骤内容(复用超管端组件) │
└─────────────────────────────────────────────┘
```
**按钮说明:**
- **保存草稿** - 保存为草稿状态,可继续编辑
- **保存到个人** - 保存到个人课程中心,立即可用
- **提交到校本中心** - 提交审核,通过后本校教师可见
### 5.3 保存位置选择
首次保存时弹窗:
```
┌─────────────────────────────────────────────┐
│ 选择保存位置 │
├─────────────────────────────────────────────┤
│ │
│ ○ 保存到个人课程中心 │
│ 仅您自己可以看到和使用 │
│ │
│ ○ 提交到校本课程中心 │
│ 本校所有教师都可以看到(需审核) │
│ │
│ [取消] [确认保存] │
└─────────────────────────────────────────────┘
```
### 5.4 个人课程中心
**新增页面:`/views/teacher/my-courses/MyCourseListView.vue`**
```
┌─────────────────────────────────────────────┐
│ 我的课程包 │
│ [校本课程包] [标准课程包收藏] │
├─────────────────────────────────────────────┤
│ 统计: 3个校本课程包 | 本周使用2次 │
├─────────────────────────────────────────────┤
│ ┌────────────┐ ┌────────────┐ │
│ │ 课程包A │ │ 课程包B │ │
│ │ [校本版] │ │ [校本版] │ │
│ │ [编辑][删除]│ │ [编辑][删除]│ │
│ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────┘
```
---
## 六、开发阶段规划
### Phase 6.1: 数据模型扩展0.5天)
- [ ] 扩展 SchoolCourse 表字段
- [ ] 扩展 SchoolCourseLesson 表字段
- [ ] 创建数据库迁移
### Phase 6.2: 后端API开发1-1.5天)
- [ ] 创建校本课程包 APIfrom-source
- [ ] 获取完整详情 API
- [ ] 更新完整数据 API
- [ ] 更新单个课程配置 API
- [ ] 学校端审核 API
### Phase 6.3: 共享组件提取0.5天)
- [ ] 将超管端7个Step组件提取到共享目录
- [ ] 创建共享的类型定义
- [ ] 确保超管端功能不受影响
### Phase 6.4: 编辑页面开发1.5-2天
- [ ] 教师端编辑页面
- [ ] 学校端编辑页面
- [ ] 保存位置选择弹窗
- [ ] 数据加载和保存逻辑
### Phase 6.5: 个人课程中心1天
- [ ] 教师端我的课程包列表页
- [ ] 课程包卡片组件
- [ ] 编辑/删除功能
### Phase 6.6: 上课集成0.5天)
- [ ] 从校本课程包开始上课
- [ ] 数据读取适配
### Phase 6.7: 测试与修复0.5天)
- [ ] 功能测试
- [ ] Bug修复
**总计5.5 - 6.5天**
---
## 七、注意事项
### 7.1 兼容性
1. **现有数据兼容**
- 已创建的 SchoolCourse 需要数据迁移
- 旧数据只有 objectives/preparation 等基础字段
- 新数据包含完整的 stepsData
2. **新旧版本共存**
- 如果 stepsData 为空,使用 sourceCourse 的原始数据
- 如果 stepsData 存在,使用校本版本的配置
### 7.2 性能考虑
1. **数据加载优化**
- 列表页只加载基本信息
- 编辑页按需加载详细配置
2. **数据存储优化**
- stepsData 使用JSON存储避免过度拆分表
### 7.3 权限控制
| 操作 | 教师端 | 学校端 |
|------|--------|--------|
| 创建校本课程包 | ✅ 个人 | ✅ 学校中心 |
| 编辑自己的课程包 | ✅ | ✅ |
| 删除自己的课程包 | ✅ | ✅ |
| 查看校本中心课程 | ✅ | ✅ |
| 审核校本中心课程 | ❌ | ✅ |
| 使用校本课程上课 | ✅ | ✅ |
---
## 八、后续扩展
1. **版本管理** - 支持校本课程包的版本迭代
2. **变更对比** - 可视化展示与源课程包的差异
3. **分享功能** - 支持跨学校分享校本课程包
4. **模板功能** - 将校本课程包保存为模板
5. **使用统计** - 详细的课程使用数据和分析
---
*本文档创建于 2026-03-11*