fix: 修复图片补图删除回填
This commit is contained in:
@@ -2775,7 +2775,7 @@ def _reap_stale_standalone_image_tasks(*, team) -> None:
|
||||
continue
|
||||
|
||||
|
||||
def enqueue_standalone_images(*, team, user, prompt: str, mode: str = "image", count: int = 1, product_id: str | None = None, reference_product: bool = False, model_id: str | None = None, model_entity_id: str | None = None, ratio: str | None = None, image_model: str | None = None, conversation=None, reference_image_ids: list[str] | None = None, platform_id: str | None = None, batch_id: str | None = None, tryon_prompt_v2_override: bool = False, tryon_ab: dict | None = None, dispatch: bool = True) -> list[AITask]:
|
||||
def enqueue_standalone_images(*, team, user, prompt: str, mode: str = "image", count: int = 1, product_id: str | None = None, reference_product: bool = False, model_id: str | None = None, model_entity_id: str | None = None, ratio: str | None = None, image_model: str | None = None, conversation=None, reference_image_ids: list[str] | None = None, platform_id: str | None = None, batch_id: str | None = None, retry_of_task_id: str | None = None, tryon_prompt_v2_override: bool = False, tryon_ab: dict | None = None, dispatch: bool = True) -> list[AITask]:
|
||||
"""独立生图(图片创作 / 模特上身图 / 平台套图)改为**异步**:本函数在 Web 请求里只做「建任务 +
|
||||
预留额度」这种秒级的活,真正 ~30s 的 ARK 出图交给 Celery worker(generate_standalone_image_task)。
|
||||
|
||||
@@ -2812,6 +2812,18 @@ def enqueue_standalone_images(*, team, user, prompt: str, mode: str = "image", c
|
||||
batch_id = None
|
||||
if not is_append:
|
||||
batch_id = str(uuid.uuid4())
|
||||
retry_of_task_id = None
|
||||
elif retry_of_task_id:
|
||||
retry_of_task = AITask.objects.filter(
|
||||
id=retry_of_task_id,
|
||||
team=team,
|
||||
project__isnull=True,
|
||||
is_deleted=False,
|
||||
purged_at__isnull=True,
|
||||
request_payload__batch_id=batch_id,
|
||||
status__in=(AITask.Status.FAILED, AITask.Status.CANCELLED),
|
||||
).first()
|
||||
retry_of_task_id = str(retry_of_task.id) if retry_of_task else None
|
||||
# 平台套图:规范化平台 id(前端 dy/tb… → canonical),用于注入平台版式块(优化版);非 cover 模式忽略。
|
||||
platform_key = str(platform_id or "").strip() if mode == "cover" else ""
|
||||
platform_name = _PLATFORM_NAMES.get(platform_key, "")
|
||||
@@ -2884,6 +2896,8 @@ def enqueue_standalone_images(*, team, user, prompt: str, mode: str = "image", c
|
||||
# 只在重跑/补图时落键(不落 False):workbench 用 KeyTextTransform 抽文本,"false" 字符串也是真值,会误判
|
||||
if is_append:
|
||||
request_payload["batch_append"] = True
|
||||
if retry_of_task_id:
|
||||
request_payload["retry_of_task_id"] = retry_of_task_id
|
||||
if quote.meta.get("rate"):
|
||||
request_payload["points_per_yuan_snapshot"] = quote.meta["rate"]
|
||||
task = AITask.objects.create(
|
||||
|
||||
@@ -1215,10 +1215,13 @@ class ImageConversationTests(TestCase):
|
||||
conv_id = first.json()["conversation_id"]
|
||||
batch_id = first.json()["batch_id"]
|
||||
self.assertTrue(batch_id)
|
||||
failed_task = AITask.objects.filter(conversation_id=conv_id).order_by("created_at").first()
|
||||
failed_task.status = AITask.Status.FAILED
|
||||
failed_task.save(update_fields=["status"])
|
||||
# 重跑一张:带原对话 + 原 batch_id → 归回原批次
|
||||
second = self.client.post(
|
||||
"/api/ai/generate-image/",
|
||||
{"prompt": "一只猫", "mode": "image", "count": 1, "conversation_id": conv_id, "batch_id": batch_id},
|
||||
{"prompt": "一只猫", "mode": "image", "count": 1, "conversation_id": conv_id, "batch_id": batch_id, "retry_of_task_id": str(failed_task.id)},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(second.status_code, 202, second.content)
|
||||
@@ -1227,6 +1230,7 @@ class ImageConversationTests(TestCase):
|
||||
self.assertEqual(len(tasks), 3)
|
||||
self.assertTrue(all(t["batch_id"] == batch_id for t in tasks))
|
||||
self.assertEqual([t["rerun"] for t in tasks], [False, False, True])
|
||||
self.assertEqual(tasks[-1]["retry_of_task_id"], str(failed_task.id))
|
||||
# 非法 batch_id(不是 UUID):不沿用,铸新批次,不打 append 标记
|
||||
third = self.client.post(
|
||||
"/api/ai/generate-image/",
|
||||
|
||||
@@ -48,6 +48,7 @@ class GenerateImageView(APIView):
|
||||
conversation_id = str(request.data.get("conversation_id") or "").strip() or None
|
||||
# 重跑/补图:前端带原批次 batch_id → enqueue 沿用(UUID 校验),记录归回原批次不裂新卡
|
||||
batch_id = str(request.data.get("batch_id") or "").strip() or None
|
||||
retry_of_task_id = str(request.data.get("retry_of_task_id") or "").strip() or None
|
||||
# 用户在图片创作里上传的参考图(已先传成 Asset),按 id 列表带入 → 生成时作多图参考(image_edit)
|
||||
raw_refs = request.data.get("reference_image_ids") or []
|
||||
if isinstance(raw_refs, str):
|
||||
@@ -69,7 +70,7 @@ class GenerateImageView(APIView):
|
||||
title=(prompt[:24] or "默认创作"),
|
||||
)
|
||||
try:
|
||||
tasks = enqueue_standalone_images(team=team, user=request.user, prompt=prompt, mode=mode, count=count, product_id=product_id, reference_product=reference_product, model_id=model_id, model_entity_id=model_entity_id, ratio=ratio, image_model=image_model, conversation=conversation, reference_image_ids=reference_image_ids, platform_id=platform_id, batch_id=batch_id)
|
||||
tasks = enqueue_standalone_images(team=team, user=request.user, prompt=prompt, mode=mode, count=count, product_id=product_id, reference_product=reference_product, model_id=model_id, model_entity_id=model_entity_id, ratio=ratio, image_model=image_model, conversation=conversation, reference_image_ids=reference_image_ids, platform_id=platform_id, batch_id=batch_id, retry_of_task_id=retry_of_task_id)
|
||||
except ValueError as exc: # 无可用模型 / 余额不足等,立即反馈
|
||||
internal_kind = "user_credit_insufficient" if str(exc).strip().lower() == "insufficient credit" else ""
|
||||
public_error = classify_generation_error(
|
||||
@@ -365,6 +366,7 @@ class AITaskViewSet(TeamScopedViewSetMixin, ReadOnlyModelViewSet):
|
||||
"model_entity_id": t.rp_model_entity_id or "",
|
||||
"platform_id": t.rp_platform_id or "",
|
||||
"rerun": bool(t.rp_batch_append),
|
||||
"retry_of_task_id": str((t.request_payload or {}).get("retry_of_task_id") or ""),
|
||||
"created_at": t.created_at,
|
||||
# 软删的图不再出现在工作台记录里(R109:删除资产库图片 → 任务记录联动)
|
||||
"assets": AssetSerializer(
|
||||
@@ -499,6 +501,7 @@ class ImageConversationViewSet(TeamScopedViewSetMixin, ModelViewSet):
|
||||
"ratio": (t.request_payload or {}).get("ratio") or "",
|
||||
# 重跑/补图任务:不计入批次「应出张数」,前端据此正确渲染失败格数量
|
||||
"rerun": bool((t.request_payload or {}).get("batch_append")),
|
||||
"retry_of_task_id": str((t.request_payload or {}).get("retry_of_task_id") or ""),
|
||||
"reference_images": resolve_refs((t.request_payload or {}).get("reference_image_ids")),
|
||||
"created_at": t.created_at,
|
||||
"assets": AssetSerializer(
|
||||
|
||||
Reference in New Issue
Block a user