auto-save 2026-05-13 16:17 (~3)

This commit is contained in:
2026-05-13 16:18:05 +08:00
parent 3cea152177
commit f891cbc2e2
3 changed files with 72 additions and 14 deletions

View File

@@ -1868,6 +1868,19 @@
"type": "session-heartbeat", "type": "session-heartbeat",
"message": "Claude 会话活跃 · 最近命令claude · 1 项未提交变更 · 最近提交auto-save 2026-05-13 16:06 (+1, ~3)", "message": "Claude 会话活跃 · 最近命令claude · 1 项未提交变更 · 最近提交auto-save 2026-05-13 16:06 (+1, ~3)",
"files_changed": 1 "files_changed": 1
},
{
"ts": "2026-05-13T16:12:33+08:00",
"type": "commit",
"message": "auto-save 2026-05-13 16:12 (~1)",
"hash": "3cea152",
"files_changed": 1
},
{
"ts": "2026-05-13T08:17:40Z",
"type": "session-heartbeat",
"message": "Claude 会话活跃 · 最近命令claude · 3 项未提交变更 · 最近提交auto-save 2026-05-13 16:12 (~1)",
"files_changed": 3
} }
] ]
} }

View File

@@ -64,13 +64,21 @@ class GeneratedImage(BaseModel):
class StoryboardScene(BaseModel): class StoryboardScene(BaseModel):
"""分镜头编排:每个 selected 分镜对应一个 scene 描述""" """分镜头编排:每个 selected 分镜对应一个 scene 描述
subject: str = "" # 主体(如:戴头带的骨架人) v2: 4 图槽 + 时长(复制粘贴模式)— 主体 / 场景 / 产品 / 动作 各一张图
product: str = "" # 产品Goli 营养软糖) v1 字段保留兼容subject/product/scene/action/reference_ids"""
scene: str = "" # 场景(如:药店柜台) duration: float = 0
action: str = "" # 在干什么(如:递给顾客一瓶软糖) # 4 图槽dict 含 {kind, frame_idx, element_id?, cutout_id?, label}
duration: float = 0 # 视频片段时长(秒) subject_image: dict | None = None
reference_ids: list[str] = [] # 参考图:选用该分镜里已提取的 element ids 作 reference scene_image: dict | None = None
product_image: dict | None = None
action_image: dict | None = None
# v1 兼容
subject: str = ""
product: str = ""
scene: str = ""
action: str = ""
reference_ids: list[str] = []
class StoryboardImage(BaseModel): class StoryboardImage(BaseModel):
@@ -1413,11 +1421,16 @@ def delete_cutout(job_id: str, idx: int, element_id: str, cutout_id: str) -> Job
class UpdateStoryboardReq(BaseModel): class UpdateStoryboardReq(BaseModel):
duration: float = 0
subject_image: dict | None = None
scene_image: dict | None = None
product_image: dict | None = None
action_image: dict | None = None
# v1 字段(前端可不传)
subject: str = "" subject: str = ""
product: str = "" product: str = ""
scene: str = "" scene: str = ""
action: str = "" action: str = ""
duration: float = 0
reference_ids: list[str] = [] reference_ids: list[str] = []
@@ -1434,11 +1447,15 @@ def update_storyboard(job_id: str, idx: int, req: UpdateStoryboardReq) -> Job:
for f in job.frames: for f in job.frames:
if f.index == idx: if f.index == idx:
f.storyboard = StoryboardScene( f.storyboard = StoryboardScene(
duration=max(0.0, float(req.duration)),
subject_image=req.subject_image,
scene_image=req.scene_image,
product_image=req.product_image,
action_image=req.action_image,
subject=req.subject.strip(), subject=req.subject.strip(),
product=req.product.strip(), product=req.product.strip(),
scene=req.scene.strip(), scene=req.scene.strip(),
action=req.action.strip(), action=req.action.strip(),
duration=max(0.0, float(req.duration)),
reference_ids=list(req.reference_ids), reference_ids=list(req.reference_ids),
) )
new_frames.append(f) new_frames.append(f)

View File

@@ -47,13 +47,41 @@ export interface KeyElement {
created_at?: number created_at?: number
} }
export interface ImageRef {
kind: "keyframe" | "cutout"
frame_idx: number
element_id?: string | null
cutout_id?: string | null
label?: string
}
export interface StoryboardScene { export interface StoryboardScene {
subject: string
product: string
scene: string
action: string
duration: number duration: number
reference_ids: string[] subject_image?: ImageRef | null
scene_image?: ImageRef | null
product_image?: ImageRef | null
action_image?: ImageRef | null
// v1 兼容
subject?: string
product?: string
scene?: string
action?: string
reference_ids?: string[]
}
// 把 ImageRef 解析成可显示的 src URL
export function resolveImageRefUrl(jobId: string, ref: ImageRef): string {
if (ref.kind === "keyframe") {
return effectiveFrameUrl(jobId, { index: ref.frame_idx, cleaned_applied: false })
}
if (ref.element_id && ref.cutout_id) {
if (ref.cutout_id === ref.element_id) {
// legacy v1
return cutoutUrl(jobId, ref.frame_idx, ref.element_id)
}
return cutoutUrl(jobId, ref.frame_idx, ref.element_id, ref.cutout_id)
}
return ""
} }
export interface KeyFrame { export interface KeyFrame {