auto-save 2026-05-18 21:08 (+2, ~4)
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -20,6 +20,11 @@ deploy/.htpasswd
|
|||||||
# api
|
# api
|
||||||
api/.venv/
|
api/.venv/
|
||||||
api/jobs/
|
api/jobs/
|
||||||
|
asset_library/*
|
||||||
|
!asset_library/.gitkeep
|
||||||
|
prompt_library/*
|
||||||
|
!prompt_library/.gitkeep
|
||||||
|
_trash/
|
||||||
|
|
||||||
# web
|
# web
|
||||||
web/.next/
|
web/.next/
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"hash": "258bc10",
|
|
||||||
"message": "auto-save 2026-05-16 15:49 (~1)",
|
|
||||||
"ts": "2026-05-16T15:49:30+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files_changed": 1,
|
"files_changed": 1,
|
||||||
"hash": "a391ca6",
|
"hash": "a391ca6",
|
||||||
@@ -3212,6 +3205,13 @@
|
|||||||
"type": "session-heartbeat",
|
"type": "session-heartbeat",
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 3 项未提交变更 · 最近提交:auto-save 2026-05-18 20:57 (~3)",
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 3 项未提交变更 · 最近提交:auto-save 2026-05-18 20:57 (~3)",
|
||||||
"files_changed": 3
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-18T21:03:11+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-18 21:03 (+1, ~3)",
|
||||||
|
"hash": "73e8ffe",
|
||||||
|
"files_changed": 4
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
0
asset_library/.gitkeep
Normal file
0
asset_library/.gitkeep
Normal file
File diff suppressed because one or more lines are too long
0
prompt_library/.gitkeep
Normal file
0
prompt_library/.gitkeep
Normal file
@@ -3403,6 +3403,33 @@ function AudioStoryboardPlanPanel({
|
|||||||
setPlanOverrides((prev) => ({ ...prev, [rowIndex]: { ...(prev[rowIndex] ?? {}), ...patch } }))
|
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 applyVisualMode = (rowIndex: number, mode: StoryboardVisualMode) => {
|
||||||
const defaults = visualModeDefaults(mode)
|
const defaults = visualModeDefaults(mode)
|
||||||
const row = rows.find((item) => item.index === rowIndex)
|
const row = rows.find((item) => item.index === rowIndex)
|
||||||
@@ -3882,6 +3909,16 @@ function AudioStoryboardPlanPanel({
|
|||||||
/>
|
/>
|
||||||
<div className="flex items-center justify-end gap-2">
|
<div className="flex items-center justify-end gap-2">
|
||||||
<ModelTrace trace={scriptRewriteModelTrace(runtimeModels)} compact />
|
<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
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowChineseMirror((value) => !value)}
|
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" />}
|
{scriptRewriteBusy === row.index ? <Loader2 className="h-3 w-3 animate-spin" /> : <Wand2 className="h-3 w-3" />}
|
||||||
单段改写
|
单段改写
|
||||||
</button>
|
</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>
|
||||||
|
|
||||||
<StoryboardPlanCell label={`${sceneStep.no} 画面规划 / 产品融入`}>
|
<StoryboardPlanCell label={`${sceneStep.no} 画面规划 / 产品融入`}>
|
||||||
@@ -4052,6 +4098,31 @@ function AudioStoryboardPlanPanel({
|
|||||||
{showChineseMirror && plannedRow.productPlacementZh ? (
|
{showChineseMirror && plannedRow.productPlacementZh ? (
|
||||||
<p className="-mt-1 line-clamp-2 text-[10px] leading-snug text-white/32" title={plannedRow.productPlacementZh}>中:{plannedRow.productPlacementZh}</p>
|
<p className="-mt-1 line-clamp-2 text-[10px] leading-snug text-white/32" title={plannedRow.productPlacementZh}>中:{plannedRow.productPlacementZh}</p>
|
||||||
) : null}
|
) : 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="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="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">
|
<div className="mb-1 flex items-center justify-between gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user