- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
7.8 KiB
7.8 KiB
播课功能技术方案
一、需求背景
课程管理员需要为课程生成播课音频,学员可以在课程卡片上点击"播课"按钮收听课程内容,支持音频播放控制。
二、核心设计
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 表新增字段
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 文件 URLbroadcast_generated_at: 记录生成时间,用于判断是否需要重新生成
索引: 无需额外索引(查询通过主键 course_id)
四、后端架构
4.1 配置层
文件: app/core/config.py
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
- 错误处理和日志记录
关键方法:
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 定义
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
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
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 日志记录
# 生成开始
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 调用错误率
十、后续优化方向
- 自动生成:资料上传后自动触发生成(需评估资源消耗)
- 进度提示:显示生成进度(需 Coze 工作流支持进度回调)
- 音频预览:生成后在编辑页预览播放
- 历史版本:保存多个版本的播课音频
- 字幕支持:工作流返回字幕文件,前端同步显示
文档版本: v1.0
创建日期: 2025-10-14
维护人: 考培练系统开发团队