# 并发控制说明 - 音乐库唱歌视频功能 ## 🎯 问题 用户在视频生成过程中重复点击音乐,导致多个生成任务同时运行。 ## ✅ 解决方案 实现了**前后端双重并发控制**。 --- ## 🔒 前端控制 ### 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 **状态**: ✅ 已实现并测试