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