feat: 初始化考培练系统项目
- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
296
docs/规划/全链路联调/Ai工作流/coze/播课/播课功能技术方案.md
Normal file
296
docs/规划/全链路联调/Ai工作流/coze/播课/播课功能技术方案.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# 播课功能技术方案
|
||||
|
||||
## 一、需求背景
|
||||
|
||||
课程管理员需要为课程生成播课音频,学员可以在课程卡片上点击"播课"按钮收听课程内容,支持音频播放控制。
|
||||
|
||||
## 二、核心设计
|
||||
|
||||
### 2.1 触发方式
|
||||
|
||||
- **管理员手动触发**:在课程编辑页的"学习资料与知识点"选项卡,点击"生成播课"按钮
|
||||
- **生成范围**:一个课程生成一个综合播课音频(多个资料合并生成)
|
||||
- **存储方式**:只存储 mp3 URL,不存储在本地服务器
|
||||
|
||||
### 2.2 技术选型
|
||||
|
||||
| 技术项 | 选型 | 说明 |
|
||||
|--------|------|------|
|
||||
| AI 工作流 | Coze 工作流 | workflow_id: 7561161554420482088 |
|
||||
| SDK | cozepy 0.2.0 | 已安装,与陪练功能共用 |
|
||||
| 认证方式 | Personal Access Token | 与陪练功能共用 token |
|
||||
| 数据库字段 | `broadcast_audio_url` | 存储 mp3 URL |
|
||||
| 前端播放器 | HTML5 audio | 原生支持,无需额外依赖 |
|
||||
|
||||
### 2.3 数据流程
|
||||
|
||||
```
|
||||
管理员点击"生成播课"
|
||||
→ 前端调用后端 API
|
||||
→ 后端调用 Coze 工作流
|
||||
→ Coze 生成 mp3 音频
|
||||
→ 返回 mp3 URL
|
||||
→ 后端保存到数据库
|
||||
→ 前端显示成功提示
|
||||
|
||||
学员点击"播课"
|
||||
→ 前端查询播课信息
|
||||
→ 跳转到播放页面
|
||||
→ 加载并播放音频
|
||||
```
|
||||
|
||||
## 三、数据库设计
|
||||
|
||||
### 3.1 courses 表新增字段
|
||||
|
||||
```sql
|
||||
ALTER TABLE courses
|
||||
ADD COLUMN broadcast_audio_url VARCHAR(500) NULL COMMENT '播课音频URL',
|
||||
ADD COLUMN broadcast_generated_at DATETIME NULL COMMENT '播课生成时间';
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `broadcast_audio_url`: 存储 Coze 工作流返回的 mp3 文件 URL
|
||||
- `broadcast_generated_at`: 记录生成时间,用于判断是否需要重新生成
|
||||
|
||||
**索引**: 无需额外索引(查询通过主键 course_id)
|
||||
|
||||
## 四、后端架构
|
||||
|
||||
### 4.1 配置层
|
||||
|
||||
**文件**: `app/core/config.py`
|
||||
|
||||
```python
|
||||
class Settings(BaseSettings):
|
||||
# 播课工作流配置
|
||||
COZE_BROADCAST_WORKFLOW_ID: str = Field(default="7561161554420482088")
|
||||
COZE_BROADCAST_SPACE_ID: str = Field(default="7474971491470688296")
|
||||
```
|
||||
|
||||
### 4.2 服务层
|
||||
|
||||
**文件**: `app/services/coze_broadcast_service.py`
|
||||
|
||||
**职责**:
|
||||
- 封装 Coze 工作流调用逻辑
|
||||
- 解析返回的 mp3 URL
|
||||
- 错误处理和日志记录
|
||||
|
||||
**关键方法**:
|
||||
|
||||
```python
|
||||
class CozeBroadcastService:
|
||||
async def generate_broadcast(self, course_id: int) -> str:
|
||||
"""
|
||||
调用 Coze 工作流生成播课音频
|
||||
|
||||
Args:
|
||||
course_id: 课程ID
|
||||
|
||||
Returns:
|
||||
mp3 音频文件 URL
|
||||
|
||||
Raises:
|
||||
CozeError: Coze API 调用失败
|
||||
ValueError: 返回结果解析失败
|
||||
"""
|
||||
```
|
||||
|
||||
### 4.3 API 层
|
||||
|
||||
**文件**: `app/api/v1/broadcast.py`
|
||||
|
||||
**接口1**: 生成播课
|
||||
- 路径: `POST /api/v1/courses/{course_id}/generate-broadcast`
|
||||
- 权限: manager, admin
|
||||
- 超时: 180秒
|
||||
- 功能: 调用工作流生成音频,更新数据库
|
||||
|
||||
**接口2**: 获取播课信息
|
||||
- 路径: `GET /api/v1/courses/{course_id}/broadcast`
|
||||
- 权限: trainee, manager, admin
|
||||
- 功能: 查询课程是否有播课以及播课 URL
|
||||
|
||||
### 4.4 Schema 定义
|
||||
|
||||
```python
|
||||
class GenerateBroadcastResponse(BaseModel):
|
||||
"""生成播课响应"""
|
||||
mp3_url: str = Field(..., description="播课音频URL")
|
||||
generated_at: datetime = Field(..., description="生成时间")
|
||||
|
||||
class BroadcastInfo(BaseModel):
|
||||
"""播课信息"""
|
||||
has_broadcast: bool = Field(..., description="是否有播课")
|
||||
mp3_url: Optional[str] = Field(None, description="播课音频URL")
|
||||
generated_at: Optional[datetime] = Field(None, description="生成时间")
|
||||
```
|
||||
|
||||
## 五、前端架构
|
||||
|
||||
### 5.1 类型定义
|
||||
|
||||
**文件**: `src/types/broadcast.ts`
|
||||
|
||||
```typescript
|
||||
export interface BroadcastInfo {
|
||||
has_broadcast: boolean
|
||||
mp3_url?: string
|
||||
generated_at?: string
|
||||
}
|
||||
|
||||
export interface GenerateBroadcastResponse {
|
||||
mp3_url: string
|
||||
generated_at: string
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 API 封装
|
||||
|
||||
**文件**: `src/api/broadcast.ts`
|
||||
|
||||
```typescript
|
||||
export const broadcastApi = {
|
||||
generate(courseId: number): Promise<ResponseData<GenerateBroadcastResponse>>
|
||||
getInfo(courseId: number): Promise<ResponseData<BroadcastInfo>>
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 页面改造
|
||||
|
||||
**1. 课程编辑页** (`src/views/manager/edit-course.vue`)
|
||||
|
||||
新增功能:
|
||||
- 在"学习资料与知识点"选项卡添加"生成播课"按钮
|
||||
- 查询并显示播课信息(是否已生成、生成时间)
|
||||
- 生成中显示 Loading 状态
|
||||
- 生成成功后显示"重新生成"按钮
|
||||
|
||||
**2. 播放页面** (`src/views/trainee/broadcast-course.vue`)
|
||||
|
||||
播放器功能:
|
||||
- 播放/暂停控制
|
||||
- 进度条拖动
|
||||
- 当前时间/总时长显示
|
||||
- 播放速度调节(1.0x, 1.25x, 1.5x, 2.0x)
|
||||
|
||||
**3. 课程卡片** (`src/views/trainee/course-center.vue`)
|
||||
|
||||
修改播课按钮点击事件:
|
||||
- 查询播课信息
|
||||
- 如无播课,提示"该课程暂无播课内容"
|
||||
- 如有播课,跳转到播放页面
|
||||
|
||||
## 六、交互流程
|
||||
|
||||
### 6.1 生成播课流程
|
||||
|
||||
```
|
||||
1. 管理员进入课程编辑页
|
||||
2. 切换到"学习资料与知识点"选项卡
|
||||
3. 点击"生成播课"按钮
|
||||
4. 前端调用 POST /api/v1/courses/{id}/generate-broadcast
|
||||
5. 后端调用 Coze 工作流(约10分钟)
|
||||
6. Coze 返回 mp3 URL
|
||||
7. 后端更新数据库 broadcast_audio_url 和 broadcast_generated_at
|
||||
8. 前端显示"生成成功"提示
|
||||
9. 按钮文本变为"重新生成",显示生成时间
|
||||
```
|
||||
|
||||
### 6.2 播放流程
|
||||
|
||||
```
|
||||
1. 学员在课程中心查看课程卡片
|
||||
2. 点击"播课"按钮
|
||||
3. 前端调用 GET /api/v1/courses/{id}/broadcast
|
||||
4. 如 has_broadcast=false,显示"暂无播课内容"
|
||||
5. 如 has_broadcast=true,跳转到播放页面
|
||||
6. 播放页面加载 mp3 音频
|
||||
7. 学员使用播放器控制播放
|
||||
```
|
||||
|
||||
## 七、性能与安全
|
||||
|
||||
### 7.1 性能优化
|
||||
|
||||
- **超时配置**: 前后端统一设置 180 秒超时
|
||||
- **缓存策略**: 音频 URL 从数据库读取,无需额外缓存
|
||||
- **CDN 加速**: mp3 文件由 Coze 托管,自带 CDN 加速
|
||||
|
||||
### 7.2 错误处理
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
|------|---------|
|
||||
| 工作流调用超时 | 提示"生成超时,请稍后重试" |
|
||||
| 工作流执行失败 | 记录 logid,提示"生成失败,请联系管理员" |
|
||||
| mp3 URL 解析失败 | 记录错误日志,提示"结果解析失败" |
|
||||
| 播放加载失败 | 提示"音频加载失败,请检查网络" |
|
||||
|
||||
### 7.3 日志记录
|
||||
|
||||
```python
|
||||
# 生成开始
|
||||
logger.info(f"开始生成播课: course_id={course_id}, user_id={user_id}")
|
||||
|
||||
# 生成成功
|
||||
logger.info(f"播课生成成功: course_id={course_id}, mp3_url={mp3_url}, duration={duration}")
|
||||
|
||||
# 生成失败
|
||||
logger.error(
|
||||
f"播课生成失败: course_id={course_id}",
|
||||
extra={"logid": logid, "error": str(error)}
|
||||
)
|
||||
```
|
||||
|
||||
## 八、测试策略
|
||||
|
||||
### 8.1 单元测试
|
||||
|
||||
- CozeBroadcastService 工作流调用测试
|
||||
- broadcast API 接口测试
|
||||
- 前端 broadcastApi 封装测试
|
||||
|
||||
### 8.2 集成测试
|
||||
|
||||
- 管理员生成播课端到端测试
|
||||
- 学员播放端到端测试
|
||||
- 错误场景测试(无播课、生成失败、播放失败)
|
||||
|
||||
### 8.3 性能测试
|
||||
|
||||
- 工作流调用耗时(预期 10 分钟左右)
|
||||
- 前端音频加载时间
|
||||
- 并发生成请求测试
|
||||
|
||||
## 九、部署与监控
|
||||
|
||||
### 9.1 配置检查
|
||||
|
||||
部署前确认以下配置:
|
||||
- ✅ COZE_API_TOKEN 正确配置
|
||||
- ✅ COZE_BROADCAST_WORKFLOW_ID = 7561161554420482088
|
||||
- ✅ COZE_BROADCAST_SPACE_ID = 7474971491470688296
|
||||
- ✅ 工作流已在 Coze 平台发布
|
||||
|
||||
### 9.2 监控指标
|
||||
|
||||
- 生成成功率(目标 >95%)
|
||||
- 平均生成时长(预期 10 分钟)
|
||||
- 播放失败率(目标 <5%)
|
||||
- Coze API 调用错误率
|
||||
|
||||
## 十、后续优化方向
|
||||
|
||||
1. **自动生成**:资料上传后自动触发生成(需评估资源消耗)
|
||||
2. **进度提示**:显示生成进度(需 Coze 工作流支持进度回调)
|
||||
3. **音频预览**:生成后在编辑页预览播放
|
||||
4. **历史版本**:保存多个版本的播课音频
|
||||
5. **字幕支持**:工作流返回字幕文件,前端同步显示
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**创建日期**: 2025-10-14
|
||||
**维护人**: 考培练系统开发团队
|
||||
|
||||
Reference in New Issue
Block a user