fix: clarify storyboard videos auto-save

This commit is contained in:
2026-05-21 17:44:40 +08:00
parent 4efb2ce456
commit eb4347a843
2 changed files with 23 additions and 18 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1384,7 +1384,7 @@ function scriptRewriteModelTrace(models?: RuntimeModels): ModelTraceSpec {
chain: [ chain: [
`主改写:${modelValue(models?.audio_rewrite)} 根据原文案、当前分镜、作者想法生成新口播`, `主改写:${modelValue(models?.audio_rewrite)} 根据原文案、当前分镜、作者想法生成新口播`,
`模型回退:依次尝试 ${modelValue(models?.asr_fallback)}${modelValue(models?.translate)};全部失败时用本地模板保留分镜可编辑`, `模型回退:依次尝试 ${modelValue(models?.asr_fallback)}${modelValue(models?.translate)};全部失败时用本地模板保留分镜可编辑`,
"返回结果写入当前分镜文案编辑框;点击保存规划后才写入 frame.storyboard.action", "返回结果会先写入当前分镜文案编辑框;生成候选前会自动同步到分镜数据,无需单独保存视频",
], ],
} }
} }
@@ -1399,7 +1399,7 @@ function videoModelTrace(models: RuntimeModels | undefined, model: string): Mode
`服务商:${modelValue(models?.video_provider)} · ${modelValue(models?.video_base_url)}`, `服务商:${modelValue(models?.video_provider)} · ${modelValue(models?.video_base_url)}`,
"当前主工作台暂停直接提交视频;旧入口误触也会被页面层保护", "当前主工作台暂停直接提交视频;旧入口误触也会被页面层保护",
"开放后输入会包含已确认首尾帧、当前分镜文案、产品素材、相似主体资产和画面规划", "开放后输入会包含已确认首尾帧、当前分镜文案、产品素材、相似主体资产和画面规划",
"输出为异步候选视频,完成后回填到对应分镜行Sora 已停用", "输出为异步候选视频,提交后立即写入当前任务,完成后自动回填 mp4 到对应分镜行Sora 已停用",
], ],
} }
} }
@@ -5898,9 +5898,9 @@ function AudioStoryboardPlanPanel({
setStoryboardSaveBusyRow(row.index) setStoryboardSaveBusyRow(row.index)
try { try {
await saveRowStoryboardDraft(row, frame) await saveRowStoryboardDraft(row, frame)
toast.success("已保存本条三字段规划") toast.success("本条三字段规划已同步")
} catch (e) { } catch (e) {
toast.error("保存本条规划失败:" + (e instanceof Error ? e.message : String(e))) toast.error("同步本条规划失败:" + (e instanceof Error ? e.message : String(e)))
} finally { } finally {
setStoryboardSaveBusyRow(null) setStoryboardSaveBusyRow(null)
} }
@@ -5912,7 +5912,7 @@ function AudioStoryboardPlanPanel({
.map((row) => ({ row: planForRow(row, referenceFrameForRow(row)), frame: referenceFrameForRow(row) })) .map((row) => ({ row: planForRow(row, referenceFrameForRow(row)), frame: referenceFrameForRow(row) }))
.filter((item): item is { row: AudioStoryboardRow; frame: KeyFrame } => !!item.frame) .filter((item): item is { row: AudioStoryboardRow; frame: KeyFrame } => !!item.frame)
if (!jobsToSubmit.length) { if (!jobsToSubmit.length) {
if (!quiet) toast.warning("先完成前置抽帧,让每条分镜有可保存的承载位置") if (!quiet) toast.warning("先完成前置抽帧,让每条分镜有可同步的承载位置")
return { ok: 0, failed: rows.length } return { ok: 0, failed: rows.length }
} }
setBatchStoryboardSaveBusy(true) setBatchStoryboardSaveBusy(true)
@@ -5926,12 +5926,12 @@ function AudioStoryboardPlanPanel({
ok += 1 ok += 1
} catch (e) { } catch (e) {
failed += 1 failed += 1
console.warn("批量保存分镜规划失败", item.row.index, e) console.warn("批量同步分镜规划失败", item.row.index, e)
} }
} }
if (!quiet) { if (!quiet) {
if (failed) toast.warning(`保存 ${ok} 条规划,${failed} 条失败`) if (failed) toast.warning(`同步 ${ok} 条规划,${failed} 条失败`)
else toast.success(`保存全部 ${ok} 条分镜规划`) else toast.success(`同步全部 ${ok} 条分镜规划`)
} }
} finally { } finally {
setStoryboardSaveBusyRow(null) setStoryboardSaveBusyRow(null)
@@ -6301,10 +6301,11 @@ function AudioStoryboardPlanPanel({
type="button" type="button"
onClick={() => void saveAllStoryboardDrafts()} onClick={() => void saveAllStoryboardDrafts()}
disabled={batchStoryboardSaveBusy || !rows.length || !orderedFrames.length} disabled={batchStoryboardSaveBusy || !rows.length || !orderedFrames.length}
className="skg-primary-action inline-flex h-9 items-center justify-center gap-1 px-2.5 text-[11px] font-semibold transition disabled:cursor-not-allowed disabled:opacity-40" title="只同步三字段规划;生成的视频会自动保存到当前任务"
className="skg-secondary-action inline-flex h-9 items-center justify-center gap-1 px-2.5 text-[11px] font-semibold transition disabled:cursor-not-allowed disabled:opacity-40"
> >
{batchStoryboardSaveBusy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Check className="h-3.5 w-3.5" />} {batchStoryboardSaveBusy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Check className="h-3.5 w-3.5" />}
</button> </button>
</div> </div>
</div> </div>
@@ -6710,10 +6711,11 @@ function AudioStoryboardPlanPanel({
type="button" type="button"
onClick={() => void saveSingleRowStoryboardDraft(plannedRow, referenceFrame)} onClick={() => void saveSingleRowStoryboardDraft(plannedRow, referenceFrame)}
disabled={!referenceFrame || savingStoryboard} disabled={!referenceFrame || savingStoryboard}
className="skg-primary-action mt-1.5 inline-flex h-8 w-full items-center justify-center gap-1 px-2 text-[11px] font-semibold transition disabled:cursor-not-allowed disabled:opacity-40" title="只同步本条三字段规划;生成的视频会自动保存到当前任务"
className="mt-1.5 inline-flex h-8 w-full items-center justify-center gap-1 rounded-md border border-white/10 bg-white/[0.04] px-2 text-[11px] font-semibold text-white/58 transition hover:border-cyan-300/35 hover:text-cyan-100 disabled:cursor-not-allowed disabled:opacity-40"
> >
{savingStoryboard ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Check className="h-3.5 w-3.5" />} {savingStoryboard ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Check className="h-3.5 w-3.5" />}
</button> </button>
</StoryboardPlanCell> </StoryboardPlanCell>
</div> </div>
@@ -7088,6 +7090,9 @@ function StoryboardVideoSlots({
<span className="shrink-0 text-[10px] text-white/34"> <span className="shrink-0 text-[10px] text-white/34">
{videos.length ? `${videos.length}${runningCount ? ` · ${runningCount} 生成中` : ""}` : enabled ? "待生成" : "待抽帧"} {videos.length ? `${videos.length}${runningCount ? ` · ${runningCount} 生成中` : ""}` : enabled ? "待生成" : "待抽帧"}
</span> </span>
{videos.length ? (
<span className="rounded border border-emerald-300/18 bg-emerald-300/[0.07] px-1.5 py-0.5 text-[10px] text-emerald-100/70"></span>
) : null}
</div> </div>
<div className="flex flex-wrap items-center gap-1.5"> <div className="flex flex-wrap items-center gap-1.5">
<label className="inline-flex h-7 items-center gap-1 rounded-md border border-white/10 bg-black/36 px-1.5 text-[10px] font-semibold text-white/48"> <label className="inline-flex h-7 items-center gap-1 rounded-md border border-white/10 bg-black/36 px-1.5 text-[10px] font-semibold text-white/48">
@@ -7913,13 +7918,13 @@ function ComposeSummary({
<PanelRight className="h-4 w-4 text-rose-200" /> <PanelRight className="h-4 w-4 text-rose-200" />
<div> <div>
<div className="text-[13px] font-semibold text-white"></div> <div className="text-[13px] font-semibold text-white"></div>
<div className="text-[11px] text-white/40">广</div> <div className="text-[11px] text-white/40">广</div>
</div> </div>
</div> </div>
<div className="flex items-center gap-2 text-[11px] text-white/52"> <div className="flex items-center gap-2 text-[11px] text-white/52">
<Requirement label="音频" ready={audioReady} detail={audioReady ? "已生成" : "待解析"} /> <Requirement label="音频" ready={audioReady} detail={audioReady ? "已生成" : "待解析"} />
<Requirement label="候选" ready={generatedVideoCount > 0} detail={`${generatedVideoCount}`} /> <Requirement label="候选" ready={generatedVideoCount > 0} detail={`${generatedVideoCount}`} />
<Requirement label="已选" ready={selectedVideoCount > 0} detail={`${selectedVideoCount}`} /> <Requirement label="自动存" ready={generatedVideoCount > 0} detail={generatedVideoCount > 0 ? "已保存" : "待候选"} />
<button type="button" disabled className="inline-flex h-10 cursor-not-allowed items-center justify-center gap-2 rounded-md border border-white/10 bg-white/[0.04] px-3 text-[12px] font-semibold text-white/34"> <button type="button" disabled className="inline-flex h-10 cursor-not-allowed items-center justify-center gap-2 rounded-md border border-white/10 bg-white/[0.04] px-3 text-[12px] font-semibold text-white/34">
<Film className="h-4 w-4" /> <Film className="h-4 w-4" />