184 lines
4.6 KiB
Markdown
184 lines
4.6 KiB
Markdown
|
|
# 并发控制说明 - 音乐库唱歌视频功能
|
|||
|
|
|
|||
|
|
## 🎯 问题
|
|||
|
|
|
|||
|
|
用户在视频生成过程中重复点击音乐,导致多个生成任务同时运行。
|
|||
|
|
|
|||
|
|
## ✅ 解决方案
|
|||
|
|
|
|||
|
|
实现了**前后端双重并发控制**。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔒 前端控制
|
|||
|
|
|
|||
|
|
### 1. 状态检查
|
|||
|
|
|
|||
|
|
在 `selectMusicFromLibrary` 方法中添加状态检查:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
if (this.singGenerating) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '视频生成中,请稍候...',
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**效果**:如果有视频正在生成,直接提示用户,不发送请求。
|
|||
|
|
|
|||
|
|
### 2. 错误处理
|
|||
|
|
|
|||
|
|
在 `generateSingVideoWithSongId` 方法的 `fail` 回调中添加 409 错误处理:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
fail: (err) => {
|
|||
|
|
uni.hideLoading();
|
|||
|
|
console.error('生成失败:', err);
|
|||
|
|
|
|||
|
|
// 检查是否是 409 错误(已有任务进行中)
|
|||
|
|
if (err.statusCode === 409 || (err.data && err.data.detail && err.data.detail.includes('进行中'))) {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '提示',
|
|||
|
|
content: '已有视频正在生成中,请稍后再试',
|
|||
|
|
showCancel: false
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '生成失败',
|
|||
|
|
content: '网络错误,请重试',
|
|||
|
|
showCancel: false
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**效果**:如果后端返回 409 错误,显示友好的提示信息。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔒 后端控制
|
|||
|
|
|
|||
|
|
### 1. 任务检查
|
|||
|
|
|
|||
|
|
后端在 `lover/routers/sing.py` 的 `generate_sing_video` 方法中检查是否有进行中的任务:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 检查是否有进行中的任务
|
|||
|
|
existing_task = db.query(SingSongVideo).filter(
|
|||
|
|
SingSongVideo.user_id == user.id,
|
|||
|
|
SingSongVideo.status.in_(['pending', 'processing'])
|
|||
|
|
).first()
|
|||
|
|
|
|||
|
|
if existing_task:
|
|||
|
|
raise HTTPException(status_code=409, detail="已有视频生成任务进行中,请稍后再试")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**效果**:如果有进行中的任务,返回 409 错误。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 控制流程
|
|||
|
|
|
|||
|
|
### 场景 1:正常生成
|
|||
|
|
|
|||
|
|
1. 用户点击音乐
|
|||
|
|
2. 前端检查 `singGenerating` → `false`
|
|||
|
|
3. 发送请求到后端
|
|||
|
|
4. 后端检查数据库 → 无进行中任务
|
|||
|
|
5. 创建新任务,返回成功
|
|||
|
|
6. 前端设置 `singGenerating = true`
|
|||
|
|
7. 开始轮询任务状态
|
|||
|
|
|
|||
|
|
### 场景 2:生成中再次点击(前端拦截)
|
|||
|
|
|
|||
|
|
1. 用户点击音乐
|
|||
|
|
2. 前端检查 `singGenerating` → `true`
|
|||
|
|
3. 显示提示:"视频生成中,请稍候..."
|
|||
|
|
4. **不发送请求**
|
|||
|
|
|
|||
|
|
### 场景 3:生成中再次点击(后端拦截)
|
|||
|
|
|
|||
|
|
1. 用户点击音乐
|
|||
|
|
2. 前端检查 `singGenerating` → `false`(可能状态未同步)
|
|||
|
|
3. 发送请求到后端
|
|||
|
|
4. 后端检查数据库 → **有进行中任务**
|
|||
|
|
5. 返回 409 错误:"已有视频生成任务进行中,请稍后再试"
|
|||
|
|
6. 前端捕获 409 错误
|
|||
|
|
7. 显示提示:"已有视频正在生成中,请稍后再试"
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 用户体验
|
|||
|
|
|
|||
|
|
### 提示信息
|
|||
|
|
|
|||
|
|
1. **前端拦截**:
|
|||
|
|
- 提示:`视频生成中,请稍候...`
|
|||
|
|
- 类型:Toast(2秒后自动消失)
|
|||
|
|
- 场景:用户在生成中点击
|
|||
|
|
|
|||
|
|
2. **后端拦截**:
|
|||
|
|
- 提示:`已有视频正在生成中,请稍后再试`
|
|||
|
|
- 类型:Modal(需要点击确定)
|
|||
|
|
- 场景:前端状态未同步时
|
|||
|
|
|
|||
|
|
### 状态管理
|
|||
|
|
|
|||
|
|
- `singGenerating`:标记是否有视频正在生成
|
|||
|
|
- `singGeneratingTaskId`:当前生成任务的 ID
|
|||
|
|
- 生成完成后自动重置状态
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 测试方法
|
|||
|
|
|
|||
|
|
### 测试 1:前端拦截
|
|||
|
|
|
|||
|
|
1. 点击音乐 A,开始生成
|
|||
|
|
2. 立即再次点击音乐 A
|
|||
|
|
3. 应该看到 Toast:"视频生成中,请稍候..."
|
|||
|
|
4. 不应该发送新的请求
|
|||
|
|
|
|||
|
|
### 测试 2:后端拦截
|
|||
|
|
|
|||
|
|
1. 点击音乐 A,开始生成
|
|||
|
|
2. 刷新页面(清除前端状态)
|
|||
|
|
3. 再次点击音乐 A
|
|||
|
|
4. 应该看到 Modal:"已有视频正在生成中,请稍后再试"
|
|||
|
|
5. 后端日志应该显示 409 错误
|
|||
|
|
|
|||
|
|
### 测试 3:生成完成后
|
|||
|
|
|
|||
|
|
1. 点击音乐 A,等待生成完成
|
|||
|
|
2. 再次点击音乐 A
|
|||
|
|
3. 应该立即成功(使用缓存)
|
|||
|
|
4. 不应该看到任何拦截提示
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 技术亮点
|
|||
|
|
|
|||
|
|
1. **双重保护**:前端 + 后端,确保不会有重复任务
|
|||
|
|
2. **友好提示**:区分前端拦截和后端拦截,提供不同的提示
|
|||
|
|
3. **状态同步**:使用 `singGenerating` 标记,自动管理状态
|
|||
|
|
4. **错误处理**:完善的 409 错误处理逻辑
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 注意事项
|
|||
|
|
|
|||
|
|
1. 前端状态可能因为刷新页面而丢失,所以需要后端检查
|
|||
|
|
2. 后端检查是最终保障,确保数据库不会有重复任务
|
|||
|
|
3. 409 错误是标准的 HTTP 状态码,表示"冲突"
|
|||
|
|
4. 生成完成后会自动重置 `singGenerating` 状态
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**并发控制说明版本**: 1.0
|
|||
|
|
**创建时间**: 2026-02-04 18:30
|
|||
|
|
**状态**: ✅ 已实现并测试
|
|||
|
|
|