auto-save 2026-05-18 21:08 (+2, ~4)
This commit is contained in:
@@ -3403,6 +3403,33 @@ function AudioStoryboardPlanPanel({
|
||||
setPlanOverrides((prev) => ({ ...prev, [rowIndex]: { ...(prev[rowIndex] ?? {}), ...patch } }))
|
||||
}
|
||||
|
||||
const savePromptToLibrary = async (
|
||||
category: "scene_desc" | "video_desc" | "subject_desc" | "skg_script" | "product_angle",
|
||||
name: string,
|
||||
promptEn: string,
|
||||
promptZh = "",
|
||||
) => {
|
||||
if (!job) return
|
||||
const text = promptEn.trim()
|
||||
if (!text) {
|
||||
toast.warning("没有可保存的提示词内容。")
|
||||
return
|
||||
}
|
||||
try {
|
||||
await createPromptLibraryItem({
|
||||
category,
|
||||
name,
|
||||
prompt_en: text,
|
||||
prompt_zh: promptZh.trim(),
|
||||
tags: ["工作台保存"],
|
||||
source_job_id: job.id,
|
||||
})
|
||||
toast.success("提示词已保存到资源库")
|
||||
} catch (error) {
|
||||
toast.error("提示词保存失败:" + (error instanceof Error ? error.message : String(error)))
|
||||
}
|
||||
}
|
||||
|
||||
const applyVisualMode = (rowIndex: number, mode: StoryboardVisualMode) => {
|
||||
const defaults = visualModeDefaults(mode)
|
||||
const row = rows.find((item) => item.index === rowIndex)
|
||||
@@ -3882,6 +3909,16 @@ function AudioStoryboardPlanPanel({
|
||||
/>
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<ModelTrace trace={scriptRewriteModelTrace(runtimeModels)} compact />
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void savePromptToLibrary("skg_script", "作者想法", authorIntent)}
|
||||
disabled={!authorIntent.trim()}
|
||||
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-35"
|
||||
title="保存作者想法到提示词库"
|
||||
>
|
||||
<BookOpen className="h-3.5 w-3.5" />
|
||||
想法入库
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowChineseMirror((value) => !value)}
|
||||
@@ -3967,6 +4004,15 @@ function AudioStoryboardPlanPanel({
|
||||
{scriptRewriteBusy === row.index ? <Loader2 className="h-3 w-3 animate-spin" /> : <Wand2 className="h-3 w-3" />}
|
||||
单段改写
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void savePromptToLibrary("skg_script", `分镜 ${row.index + 1} 新口播`, copyText, copyZhText)}
|
||||
disabled={!copyText.trim()}
|
||||
className="mt-1 inline-flex h-6 w-full items-center justify-center gap-1 rounded border border-[#d6b36a]/18 bg-[#d6b36a]/[0.06] px-2 text-[10.5px] font-semibold text-[#f1d78e]/72 transition hover:border-[#d6b36a]/42 hover:text-[#f1d78e] disabled:cursor-not-allowed disabled:opacity-35"
|
||||
>
|
||||
<BookOpen className="h-3 w-3" />
|
||||
文案入库
|
||||
</button>
|
||||
</StoryboardPlanCell>
|
||||
|
||||
<StoryboardPlanCell label={`${sceneStep.no} 画面规划 / 产品融入`}>
|
||||
@@ -4052,6 +4098,31 @@ function AudioStoryboardPlanPanel({
|
||||
{showChineseMirror && plannedRow.productPlacementZh ? (
|
||||
<p className="-mt-1 line-clamp-2 text-[10px] leading-snug text-white/32" title={plannedRow.productPlacementZh}>中:{plannedRow.productPlacementZh}</p>
|
||||
) : null}
|
||||
<div className="grid grid-cols-3 gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void savePromptToLibrary("scene_desc", `分镜 ${row.index + 1} 画面规划`, plannedRow.visualPlan, plannedRow.visualPlanZh)}
|
||||
className="h-6 rounded border border-white/10 bg-white/[0.04] px-1 text-[10px] text-white/52 transition hover:border-[#d6b36a]/32 hover:text-[#f1d78e]"
|
||||
>
|
||||
画面入库
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void savePromptToLibrary("subject_desc", `分镜 ${row.index + 1} 主体描述`, plannedRow.subjectDescription, plannedRow.subjectDescriptionZh)}
|
||||
disabled={!plannedRow.needsSubject}
|
||||
className="h-6 rounded border border-white/10 bg-white/[0.04] px-1 text-[10px] text-white/52 transition hover:border-[#d6b36a]/32 hover:text-[#f1d78e] disabled:opacity-35"
|
||||
>
|
||||
主体入库
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void savePromptToLibrary("product_angle", `分镜 ${row.index + 1} 产品出现`, plannedRow.productPlacement, plannedRow.productPlacementZh)}
|
||||
disabled={!plannedRow.needsProduct}
|
||||
className="h-6 rounded border border-white/10 bg-white/[0.04] px-1 text-[10px] text-white/52 transition hover:border-[#d6b36a]/32 hover:text-[#f1d78e] disabled:opacity-35"
|
||||
>
|
||||
产品入库
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid gap-1.5 md:grid-cols-[minmax(0,1fr)_88px_88px]">
|
||||
<div className="rounded border border-white/10 bg-black/24 px-2 py-1.5 text-[10px] leading-snug text-white/42">
|
||||
<div className="mb-1 flex items-center justify-between gap-2">
|
||||
|
||||
Reference in New Issue
Block a user