项目/AI生成链路合并

This commit is contained in:
2026-07-20 13:48:17 +08:00
parent 34ca98f9eb
commit fe5a59d725
73 changed files with 5819 additions and 2573 deletions
+46 -10
View File
@@ -1,10 +1,11 @@
from datetime import datetime
from datetime import datetime, timedelta, timezone
from fastapi import APIRouter, Body, Depends, HTTPException, Path, Query
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from app.config import settings
from app.dependencies import get_current_user, get_db
from app.models.chat_generation_task import ChatGenerationTask
from app.models.user import User
@@ -20,6 +21,10 @@ from app.schemas.generation_ai import (
GenerationAITaskListOut,
GenerationAITaskOut,
)
from app.services.generation.pipeline.db_lock_service import (
DatabaseRowLockBusy,
execute_with_lock_timeout,
)
from app.services.generation.ai.service import (
build_task_out_list,
list_generation_ai_engine_options,
@@ -715,13 +720,17 @@ async def retry_task(
if celery_app is None:
raise HTTPException(status_code=503, detail="Celery未启用:请配置 REDIS_URL 或 CELERY_BROKER_URL 后启动 worker")
result = await db.execute(
select(ChatGenerationTask).where(
ChatGenerationTask.id == task_id,
ChatGenerationTask.user_id == current_user.id,
ChatGenerationTask.deleted_at.is_(None),
).with_for_update().limit(1)
)
try:
result = await execute_with_lock_timeout(
db,
select(ChatGenerationTask).where(
ChatGenerationTask.id == task_id,
ChatGenerationTask.user_id == current_user.id,
ChatGenerationTask.deleted_at.is_(None),
).with_for_update().limit(1),
)
except DatabaseRowLockBusy as exc:
raise HTTPException(status_code=409, detail=exc.detail) from exc
task = result.scalar_one_or_none()
if not task:
raise HTTPException(status_code=404, detail="任务不存在")
@@ -779,7 +788,7 @@ async def retry_task(
enqueue_ids: list[str] = []
download_retry_ids: list[str] = []
for target in retry_targets:
if int(target.retry_count or 0) >= 3:
if int(target.manual_retry_count or 0) >= 3:
raise HTTPException(status_code=400, detail=f"任务 {target.id} 已超过最大重试次数")
is_download_retry = bool(
@@ -811,6 +820,17 @@ async def retry_task(
quantity=quantity,
)
target.credits_cost = round(float(target.credits_cost or 0) + media_billing.total_charged, 2)
resource_started_at = datetime.now(timezone.utc)
target.generation_attempt_no = int(attempt_no)
target.resource_generation_started_at = resource_started_at
if target.gen_type == "image":
target.deadline_at = resource_started_at + timedelta(
minutes=int(settings.CHATAPI_ASYNC_IMAGE_DEADLINE_MINUTES or 30)
)
else:
target.deadline_at = resource_started_at + timedelta(
hours=int(settings.CHATAPI_ASYNC_VIDEO_FINAL_DEADLINE_HOURS or 24)
)
target.provider_task_id = None
target.seedance_task_id = None
target.remote_result_url = None
@@ -818,6 +838,21 @@ async def retry_task(
target.provider_create_claim_token = None
target.provider_create_lease_until = None
target.provider_create_started_at = None
target.poll_started_at = None
target.poll_claim_token = None
target.poll_lease_until = None
target.poll_error_count = 0
target.next_poll_at = None
target.poll_interval_seconds = 0
target.download_celery_task_id = None
target.download_enqueued_at = None
target.download_started_at = None
target.download_claim_token = None
target.download_lease_until = None
target.download_next_retry_at = None
target.download_attempt_count = 0
target.download_last_error = None
target.download_storage_date_dir = None
target.image_url = None
target.video_url = None
target.video_cover_url = None
@@ -832,7 +867,8 @@ async def retry_task(
target.poll_count = 0
target.last_poll_at = None
target.generated_at = None
target.retry_count = int(target.retry_count or 0) + 1
target.manual_retry_count = int(target.manual_retry_count or 0) + 1
target.retry_count = int(target.manual_retry_count or 0)
if retrying_group_children:
await db.flush()