fix: 修复资产/视频/三视图三处 bug + 脚本模型切 YunQi gemini
1. 视频「全部生成」串行短路:任一段提交失败就 break 致后面段不提交 (4 个框只跑 2 个)→ 改 Promise.allSettled 并发,单段失败不拖累其余, 部分失败也刷新并如实报告。(App.tsx) 2. 基础资产/三视图 AI 出图偶发失败「生成不出来」:中转站瞬时抖动 (网络/5xx/429/空返回)一次失败即退费 → 加退避重试 3 次,永久错误 (4xx 内容违规)仍立即退费。(services.py run_base_asset_task/run_triview_task) 3. 商品三视图无法用已有素材:商品卡加「使用已有素材」,选商品已有图 / 上传本地图直接 attach 成三视图(不走平台 AI 生成、不计费)。(pipeline.tsx) 4. 脚本助手:tokenssr 欠费致 GPT-5.5/Gemini 全挂 → 文本模型切 YunQi。 实测 YunQi gpt-5.5 频道扛不住重型结构化任务(skill 全提示词仅 1/5 成功、 常吐空无 JSON),gemini-3.1-pro 5/5 稳定 → 默认改 gemini,停用 gpt-5.5。 按「一 provider 一 key」拆 yunqi_gpt / yunqi_gemini 两 provider。 (.env / settings / 迁移 0017+0018) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -916,7 +916,7 @@ export function App() {
|
||||
onAdoptBaseAsset={(groupId, assetId) => action(() => api.adoptBaseAsset(pipelineProject.id, { group_id: groupId, asset_id: assetId }), "已采用该候选")}
|
||||
onSetAdoptState={(groupId, state) => action(() => api.setBaseAssetAdopt(pipelineProject.id, { group_id: groupId, state }), state === "adopted" ? "已采用" : "已标为未采用")}
|
||||
onDeleteBaseAsset={(groupId) => action(() => api.deleteBaseAsset(pipelineProject.id, groupId), "已删除")}
|
||||
onAttachBaseAsset={(target, assetId) => action(() => api.attachBaseAsset(pipelineProject.id, { ...target, asset_id: assetId }), "已替换为所选演员")}
|
||||
onAttachBaseAsset={(target, assetId) => action(() => api.attachBaseAsset(pipelineProject.id, { ...target, asset_id: assetId }), "已采用所选素材")}
|
||||
onGenerateTriview={async (portraitAssetId) => {
|
||||
// 异步:image_edit 慢出图在 worker 跑,轮询期间整站不卡;出图后刷新即见三视图
|
||||
const assetId = await submitAndPollAsset(() => api.generateTriview(pipelineProject.id, { portrait_asset_id: portraitAssetId }), "三视图已据立绘生成");
|
||||
@@ -940,11 +940,24 @@ export function App() {
|
||||
action(async () => {
|
||||
// 「全部重跑」要把已完成的也重跑(否则全成功的项目点了等于没点);只跳过在途(running/queued)避免重复提交
|
||||
const targets = pipelineProject.video_segments.filter((segment) => !["running", "queued"].includes(segment.status));
|
||||
for (const segment of targets) {
|
||||
await api.submitVideo(pipelineProject.id, {
|
||||
video_segment_id: segment.id,
|
||||
prompt: `${prompt} 第 ${segment.sort_order + 1} 段,时长 ${segment.target_duration_seconds} 秒`
|
||||
});
|
||||
// ★ 并发提交,且单段失败绝不拖累其余段。旧实现用 for+await 串行,任一段抛错(如人脸需走素材库
|
||||
// 的 502、中转限流)整个循环就 break → 后面的段永不提交,前端出现「4 个框只有 2 个在跑」。
|
||||
// 改 allSettled:每段各自独立提交,失败只标该段,成功的照常进生成。
|
||||
const results = await Promise.allSettled(
|
||||
targets.map((segment) =>
|
||||
api.submitVideo(pipelineProject.id, {
|
||||
video_segment_id: segment.id,
|
||||
prompt: `${prompt} 第 ${segment.sort_order + 1} 段,时长 ${segment.target_duration_seconds} 秒`,
|
||||
})
|
||||
)
|
||||
);
|
||||
const failed = results.filter((r): r is PromiseRejectedResult => r.status === "rejected");
|
||||
if (failed.length) {
|
||||
// 部分失败也要刷新,让已成功提交的段立刻进「生成中」(否则 action 走 catch 分支会跳过刷新)
|
||||
await refreshProjectDetail();
|
||||
const firstErr = failed[0].reason;
|
||||
const detail = firstErr instanceof Error ? firstErr.message : "提交失败";
|
||||
throw new Error(`${targets.length - failed.length}/${targets.length} 段已提交,${failed.length} 段失败:${detail}(可对失败的段单独点重跑)`);
|
||||
}
|
||||
return targets.length;
|
||||
}, "多段视频已提交,生成中…")
|
||||
|
||||
Reference in New Issue
Block a user