diff --git a/.memory/worklog.json b/.memory/worklog.json
index 0a1a3b0..9b053fb 100644
--- a/.memory/worklog.json
+++ b/.memory/worklog.json
@@ -1,19 +1,5 @@
{
"entries": [
- {
- "files_changed": 1,
- "hash": "8e3b365",
- "message": "auto-save 2026-05-12 22:36 (~1)",
- "ts": "2026-05-12T22:36:36+08:00",
- "type": "commit"
- },
- {
- "files_changed": 1,
- "hash": "2009c43",
- "message": "auto-save 2026-05-12 22:41 (~1)",
- "ts": "2026-05-12T22:42:07+08:00",
- "type": "commit"
- },
{
"files_changed": 1,
"hash": "9279e55",
@@ -3331,6 +3317,19 @@
"type": "session-heartbeat",
"message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-14 09:13 (~1)",
"files_changed": 1
+ },
+ {
+ "ts": "2026-05-14T09:19:35+08:00",
+ "type": "commit",
+ "message": "auto-save 2026-05-14 09:19 (~2)",
+ "hash": "1ac55e5",
+ "files_changed": 2
+ },
+ {
+ "ts": "2026-05-14T01:20:31Z",
+ "type": "session-heartbeat",
+ "message": "Claude 会话活跃 · 最近命令:claude · 1 项未提交变更 · 最近提交:auto-save 2026-05-14 09:19 (~2)",
+ "files_changed": 1
}
]
}
diff --git a/web/components/lightbox.tsx b/web/components/lightbox.tsx
index d6efb3f..fd3de51 100644
--- a/web/components/lightbox.tsx
+++ b/web/components/lightbox.tsx
@@ -696,7 +696,7 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
} : {
top: 80,
right: 16,
- width: 740,
+ width: isProductTab ? "min(1280px, calc(100vw - 32px))" : 740,
maxHeight: "calc(100vh - 96px)",
boxShadow: "0 40px 100px -20px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,255,255,0.05)",
animation: "drawer-in 0.24s cubic-bezier(0.32, 0.72, 0, 1)",
@@ -930,118 +930,237 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
- 每行一条镜头:产品图、白底人物图、人物图上的产品区域、场景图和描述词一一对应。
+ 6 条视频镜头从上到下排列;每条都能直接看到产品图、白底人物、融合区域、场景、描述和秒数。
-
+
{fusionShots.map((shot, i) => {
const active = i === activeFusionShot
+ const productUrl = shot.product_image ? resolveImageRefUrl(jobId, shot.product_image) : ""
+ const personUrl = shot.person_image ? resolveImageRefUrl(jobId, shot.person_image) : ""
+ const sceneUrl = shot.scene_image ? resolveImageRefUrl(jobId, shot.scene_image) : ""
const ready = !!(shot.product_image && shot.person_image && shot.product_region && shot.scene_image && shot.action_text?.trim())
+ const busy = fusionGenerating === i || fusionGenerating === "all"
+ const pasteIntoSlot = (slot: "product_image" | "person_image" | "scene_image", label: string) => {
+ setActiveFusionShot(i)
+ if (clipboard) {
+ assignFusionImage(slot, clipboard, i)
+ toast.success(`已粘贴到镜头 ${i + 1}「${label}」:${clipboard.label || "剪贴板图片"}`)
+ return
+ }
+ setFusionUploadTarget(slot)
+ toast.message(`镜头 ${i + 1} 已选中「${label}」槽位,现在可 Cmd+V 粘贴系统图片`)
+ }
+ const imageSlot = (slot: "product_image" | "scene_image", label: string, url: string) => {
+ const ref = shot[slot]
+ return (
+
+
+ {url ? (
+
+ ) : (
+
+ )}
+
+
+
{ref?.label || label}
+
+
+
+
+
+
+ )
+ }
return (
-
- )
- })}
-
-
- {([
- ["product_image", "产品图", currentFusionProductUrl],
- ["person_image", "白底人物图", currentFusionPersonUrl],
- ["scene_image", "场景图", currentFusionSceneUrl],
- ] as const).map(([slot, label, url]) => (
-
-
- {url ? (
-

- ) : (
-
- )}
-
-
-
{label}
-
-
-
+
+
+
+
+ {ready ? "就绪" : "待补"}
+
+
+
+ {imageSlot("product_image", "产品图", productUrl)}
+
+
+
{
+ setActiveFusionShot(i)
+ if (active) onFusionRegionDown(ev)
+ } : undefined}
+ onMouseMove={active ? onFusionRegionMove : undefined}
+ onMouseUp={active ? onFusionRegionUp : undefined}
+ onMouseLeave={active ? onFusionRegionUp : undefined}
+ className={`relative aspect-[4/5] bg-white ${
+ personUrl ? (active ? "cursor-crosshair" : "cursor-pointer") : ""
+ }`}
+ title={personUrl ? (active ? "拖动画出产品融合区域" : "点击后编辑此镜头区域") : "上传白底人物图"}
+ >
+ {personUrl ? (
+ <>
+

+ {!active && (
+
+ 点此编辑区域
+
+ )}
+ >
+ ) : (
+
+ )}
+ {[shot.product_region, active ? fusionDraftRegion : null].filter(Boolean).map((region, regionIdx) => region && (
+
+ ))}
+
+
+
+ {shot.person_image?.label || (shot.product_region ? "人物图 · 已画区域" : "白底人物图")}
+
+
+
+
+
+
+
+
+ {imageSlot("scene_image", "场景图", sceneUrl)}
+
+
+
+
+
+
+
+
-
- ))}
-
-
-
-
产品区域 · 在人物图上画框
-
产品只在框内融合
-
-
- {currentFusionPersonUrl ? (
-

- ) : (
-
先上传白底人物图
- )}
- {[currentFusionShot?.product_region, fusionDraftRegion].filter(Boolean).map((region, i) => region && (
-
- ))}
-
+ )
+ })}
) : (
@@ -1412,7 +1531,7 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
<>
-
镜头 {activeFusionShot + 1} 设置
+
产品融合辅助
{fusionSaving ? "保存中" : "自动保存"}
@@ -1425,46 +1544,29 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
Seedance
-
-