fix(voices): 配音素材上传卡「处理中…」修复 #1552
Reference in New Issue
Block a user
Delete Branch "fix/voice-upload-polling-dedup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
配音素材上传弹窗卡在「处理中…」,根本原因:轮询循环里判断的成功状态写成了
"ready",但后端 IngestJobStatus 枚举是pending/processing/completed/failed,"ready"是音色克隆(voice-clones)的状态,此处误用导致循环永远不退出,直到maxRetries=60(5分钟)超时。另外,后端
complete接口在同库已存在相同file_hash素材时会返回{ duplicated: true, ingest_job_id: "" },当前代码直接解构ingest_job_id去轮询空 id,必卡死。改动
1. 轮询成功状态修正
jobStatus !== "ready"→jobStatus !== "completed"2. 去重命中分支
uploadAssetDirect调 complete 接口后,若duplicated === true或ingest_job_id为空,不轮询、直接按上传成功处理(刷新列表、关闭弹窗、toast 提示)。3. 轮询体验优化
complete 后立即查第一次(后端实际不到 1s 就处理完),未完成再每 5s 轮询。原代码先 sleep 5s 才首次查询,浪费时间。
4. 两个上传 hook 同步修改
pages/voices/hooks/useVoiceUpload.ts(旧配音库页,菜单实际入口)pages/voice-materials/hooks/useVoiceMaterials/actions/useVoiceUpload.ts(新配音库页;去重命中时跳过轮询 + 打标签,直接走 onSuccess)5. API 类型补齐
api/assets/types.ts的DirectUploadCompleteResult补上duplicated?: boolean和asset_id?: string字段。验收
- 轮询成功状态从 'ready' 改为 'completed'('ready' 是 voice-clones 状态,误用) - 去重命中分支:complete 接口返回 duplicated=true 或 ingest_job_id 为空时, 不轮询直接按上传成功处理(刷新列表、关闭弹窗) - 轮询优化:complete 后立即查第一次(后端通常 <1s 处理完),未完成再每 5s 轮询 - 两个上传 hook 同步修改: - pages/voices/hooks/useVoiceUpload.ts(旧配音库页) - pages/voice-materials/hooks/useVoiceMaterials/actions/useVoiceUpload.ts (新配音库页;去重命中时跳过轮询和打标签) - api/assets/types.ts 的 DirectUploadCompleteResult 补充 duplicated/asset_id 字段🚀 预览环境已部署
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
[apps/web/src/pages/voice-materials/hooks/useVoiceMaterials/actions/useVoiceUpload.ts: 54] 去重逻辑导致流程中断
if (complete.duplicated === true || !complete.ingest_job_id) { return }会直接退出函数。根据注释“直接走 onSuccess”,意图是让上传流程正常结束并触发成功回调。但直接return会跳过后续的onSuccess调用(通常位于 try 块末尾),导致 UI 不刷新或无成功提示。此外,这也跳过了“打标签”步骤,如果用户本次上传选择了标签,去重后这些标签将丢失。return。应跳过轮询逻辑,但需确保后续的onSuccess仍能被调用。如果需要打标签,应使用返回的complete.asset_id对已存在的素材进行打标签。[apps/web/src/pages/voices/hooks/useVoiceUpload.ts: 40] 去重逻辑导致流程中断
if (complete.duplicated === true || !complete.ingest_job_id) { return }会直接退出函数。注释明确要求“直接按上传成功处理(onSuccess 分支 toast + 刷新列表)”,但代码实现直接返回,导致用户看不到成功提示且列表不刷新。return,改为设置标志位或调整逻辑流,确保能走到onSuccess分支。[apps/web/src/pages/voice-materials/hooks/useVoiceMaterials/actions/useVoiceUpload.ts: 54] 异常状态被误判为成功
!complete.ingest_job_id过于宽泛。如果后端因错误未返回ingest_job_id且duplicated不为 true,代码会将其误判为去重成功而直接返回,掩盖了真实的上传失败。if (complete.duplicated === true)。对于!complete.ingest_job_id且非 duplicated 的情况,应抛出错误或进行重试。💡 改进建议(不阻塞合并)
duplicated与ingest_job_id的互斥关系,虽然 TS 难以完美运行时约束,但可以通过注释或 Discriminated Union 提示开发者这两个字段的关系。✅ 良好实践
useVoiceMaterials和useVoiceUpload中,将轮询逻辑改为“先立即查询一次,未完成再轮询”,这能有效减少快速完成任务时的等待时间,提升用户体验。useVoiceUpload.ts中修正了轮询状态的判断,从错误的"ready"改为正确的"completed",修复了潜在的死循环或状态误判问题。🤖 由 AI 代码审查机器人自动生成 | 2026-08-30 03:32:39 | 模型:
01ff4b6777to008664512fCI全绿,自动审批通过。
CI全绿,自动审批通过。
🗑️ 预览环境已清理
PR #1552 已关闭或合并,对应的预览环境已被清理。