From d3e0053d2a80c9dd34cba3ec3558ae9cbdf73bc7 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sun, 27 Sep 2026 20:35:30 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(repo):=20=5Fto=5Fdomain/create/update?= =?UTF-8?q?=20=E8=A1=A5=E4=BC=A0=20extra=5Fmeta=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=20rendered=5Foutput=20=E8=A2=AB=E4=B8=A2=E5=BC=83=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=20finalize=20400?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapters/sqlalchemy_impl/generation_task_repository.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/adapters/sqlalchemy_impl/generation_task_repository.py b/packages/adapters/sqlalchemy_impl/generation_task_repository.py index 433aaa829..1c3a65ba8 100755 --- a/packages/adapters/sqlalchemy_impl/generation_task_repository.py +++ b/packages/adapters/sqlalchemy_impl/generation_task_repository.py @@ -43,6 +43,7 @@ def _to_domain(model: GenerationTaskModel) -> GenerationTask: output_height=getattr(model, "output_height", 720) or 720, cover_url=getattr(model, "cover_url", "") or "", title_config=dict(getattr(model, "title_config", {}) or {}), + extra_meta=dict(getattr(model, "extra_meta", {}) or {}), logs=model.logs or "[]", created_at=model.created_at, updated_at=model.updated_at, @@ -88,6 +89,7 @@ class SQLAlchemyGenerationTaskRepository: output_height=task.output_height, cover_url=task.cover_url or "", title_config=dict(task.title_config) if task.title_config else {}, + extra_meta=dict(task.extra_meta) if task.extra_meta else {}, logs=task.logs, created_at=task.created_at, updated_at=task.updated_at, @@ -322,6 +324,7 @@ class SQLAlchemyGenerationTaskRepository: model.output_height = task.output_height model.cover_url = task.cover_url or "" model.title_config = dict(task.title_config) if task.title_config else {} + model.extra_meta = dict(task.extra_meta) if task.extra_meta else {} model.logs = task.logs self.session.commit() return task -- 2.54.0 From 6283e57a235425d539e8274c431d7e2c8ee88f06 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sun, 27 Sep 2026 20:35:47 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix(finalize):=20RenderedOutput.from=5Fdict?= =?UTF-8?q?=20=E5=85=BC=E5=AE=B9=20fingerprint=5Fdict.chunks=20=E4=B8=8E?= =?UTF-8?q?=20md5=20=E5=B5=8C=E5=A5=97=E4=BD=8D=E7=BD=AE=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=9F=A5=E9=87=8D=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/generated_video_finalize.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/application/generated_video_finalize.py b/packages/application/generated_video_finalize.py index 2ab79e99b..6398d2614 100644 --- a/packages/application/generated_video_finalize.py +++ b/packages/application/generated_video_finalize.py @@ -52,6 +52,18 @@ class RenderedOutput: def from_dict(cls, data: dict[str, Any]) -> "RenderedOutput": if not isinstance(data, dict): raise ValueError("rendered_output must be a dict") + # fingerprint_chunks 历史上有两种位置: + # 1) 顶层 ``fingerprint_chunks``(由 compute_render_fingerprint_and_dedup 直接返回) + # 2) 嵌套在 ``fingerprint_dict["chunks"]``(VideoFingerprint.to_dict() 序列化的结构) + # 顶层优先;顶层为空时回退到嵌套位置,兼容旧数据。 + fp_dict = data.get("fingerprint_dict") or {} + chunks_raw = data.get("fingerprint_chunks") + if not chunks_raw and isinstance(fp_dict, dict): + chunks_raw = fp_dict.get("chunks") + # md5 同样可能在顶层或嵌套在 fingerprint_dict 内(历史数据兼容) + md5_value = data.get("video_fingerprint_md5") + if not md5_value and isinstance(fp_dict, dict): + md5_value = fp_dict.get("md5") return cls( file_url=str(data.get("file_url") or ""), file_size=int(data.get("file_size") or 0), @@ -65,14 +77,14 @@ class RenderedOutput: batch_id=str(data.get("batch_id") or ""), project_id=str(data.get("project_id") or ""), user_id=str(data.get("user_id") or ""), - fingerprint_dict=data.get("fingerprint_dict"), - fingerprint_chunks=data.get("fingerprint_chunks"), + fingerprint_dict=fp_dict or None, + fingerprint_chunks=chunks_raw if isinstance(chunks_raw, list) else None, is_duplicate=bool(data.get("is_duplicate", False)), duplicate_of=data.get("duplicate_of"), duplicate_rate=_safe_float(data.get("duplicate_rate")), match_count=_safe_int(data.get("match_count")), visual_similarity=_safe_float(data.get("visual_similarity")), - video_fingerprint_md5=str(data.get("video_fingerprint_md5") or ""), + video_fingerprint_md5=str(md5_value or ""), ) -- 2.54.0 From 6c355f5200cf2fbc3b44a8e0060659728d7312df Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sun, 27 Sep 2026 20:36:03 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(worker):=20rendered=5Foutput=20?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20dict=20=E5=B1=95=E5=BC=80=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E6=89=8B=E5=86=99=E5=AD=97=E6=AE=B5=E7=99=BD?= =?UTF-8?q?=E5=90=8D=E5=8D=95=E6=BC=8F=E4=BC=A0=20fingerprint=5Fchunks/is?= =?UTF-8?q?=5Fduplicate=20=E7=AD=89=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/worker/worker_app/tasks/generation.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/worker/worker_app/tasks/generation.py b/apps/worker/worker_app/tasks/generation.py index 1ba072f71..94e492205 100644 --- a/apps/worker/worker_app/tasks/generation.py +++ b/apps/worker/worker_app/tasks/generation.py @@ -1051,20 +1051,15 @@ def generate_video(self, task_id: str) -> dict: ) if _meta_model: meta = dict(_meta_model.extra_meta or {}) + # #2024/P0 finalize-400: 直接展开 _precompute_render_metadata 返回的 + # 完整 dict(含 file_url/fingerprint_dict/fingerprint_chunks/is_duplicate + # /duplicate_of/...),避免手写字段白名单漏传字段导致 finalize 读不到数据。 meta["rendered_output"] = { + **dict(rendered_output or {}), + # file_url/duration 由外层调用方拿到的实际上传结果,优先覆盖预计算值 "file_url": file_url, "file_size": file_size, "duration": duration, - "width": rendered_output.get("width", 1280), - "height": rendered_output.get("height", 720), - "fps": rendered_output.get("fps", 25.0), - "name": rendered_output.get("name", ""), - "thumbnail_url": rendered_output.get("thumbnail_url", ""), - "mode": rendered_output.get("mode", editing_mode.value), - "fingerprint_dict": rendered_output.get("fingerprint_dict"), - "batch_id": batch_id, - "project_id": project_id, - "user_id": user_id, } _meta_model.extra_meta = meta _finalize_meta_session.commit() -- 2.54.0