生成项目任务/chat任务软删|生成资源管控回收|生成资源token验签API预处理

This commit is contained in:
2026-06-01 11:10:09 +08:00
parent edef601f7c
commit dfbf51b5c0
26 changed files with 1296 additions and 63 deletions
@@ -25,6 +25,8 @@ from app.schemas.generation_ai import (
GenerationAIVideoEngineOptionOut,
)
from app.services.generation_billing_service import charge_generation_media_by_params
from app.services.resource_accounting_service import soft_delete_chat_task_resources
from app.services.resource_signed_url_service import build_resource_signed_url
from app.utils.id_gen import generate_id
IMAGE_DEFAULT_SIZE = "2K"
@@ -201,6 +203,7 @@ async def create_async_generation_task(db: AsyncSession, current_user: User, req
ChatGenerationTask.user_id == current_user.id,
ChatGenerationTask.idempotency_key == req.idempotency_key,
ChatGenerationTask.generation_mode == "chatapi_async",
ChatGenerationTask.deleted_at.is_(None),
).order_by(ChatGenerationTask.created_at.desc()).limit(1)
)
existing = result.scalar_one_or_none()
@@ -330,8 +333,8 @@ def record_to_out(task: ChatGenerationTask) -> GenerationAITaskOut:
provider_task_id=task.provider_task_id,
seedance_task_id=task.seedance_task_id,
# remote_result_url=task.remote_result_url,
image_url=task.image_url,
video_url=task.video_url,
image_url=build_resource_signed_url(task.image_url) if task.image_url else "",
video_url=build_resource_signed_url(task.video_url) if task.video_url else "",
engine_id=task.engine_id,
engine_snapshot=snapshot,
credits_cost=task.credits_cost or 0.0,
@@ -381,6 +384,7 @@ async def list_async_generation_tasks(
query = select(ChatGenerationTask).where(
ChatGenerationTask.user_id == user_id,
ChatGenerationTask.generation_mode == "chatapi_async",
ChatGenerationTask.deleted_at.is_(None),
)
if gen_type:
query = query.where(ChatGenerationTask.gen_type == gen_type)
@@ -436,6 +440,7 @@ def _history_base_filters(user_id: str, gen_type: str):
return [
ChatGenerationTask.user_id == user_id,
ChatGenerationTask.generation_mode == "chatapi_async",
ChatGenerationTask.deleted_at.is_(None),
ChatGenerationTask.status == "completed",
ChatGenerationTask.gen_type == gen_type,
ChatGenerationTask.generated_at.is_not(None),
@@ -445,6 +450,7 @@ def _history_base_filters(user_id: str, gen_type: str):
def _generation_record_history_base_filters(user_id: str, gen_type: str):
return [
GenerationRecord.user_id == user_id,
GenerationRecord.deleted_at.is_(None),
GenerationRecord.status == "completed",
GenerationRecord.gen_type == gen_type,
GenerationRecord.generated_at.is_not(None),
@@ -478,8 +484,8 @@ def generation_record_to_history_out(
provider_task_id=record.seedance_task_id,
seedance_task_id=record.seedance_task_id,
remote_result_url=None,
image_url=record.image_url,
video_url=record.video_url,
image_url=build_resource_signed_url(record.image_url) if record.image_url else '',
video_url=build_resource_signed_url(record.video_url) if record.video_url else '',
engine_id=None,
engine_snapshot=None,
credits_cost=record.credits_cost or 0.0,
@@ -544,7 +550,7 @@ async def list_generation_record_history_grouped_days(
for generated_day, day_total in day_rows:
item_result = await db.execute(
select(GenerationRecord, Project.name.label("project_name"))
.outerjoin(Project, GenerationRecord.project_id == Project.id)
.outerjoin(Project, (GenerationRecord.project_id == Project.id) & (Project.deleted_at.is_(None)))
.where(
*filters,
func.date(GenerationRecord.generated_at) == generated_day,
@@ -603,7 +609,7 @@ async def list_generation_record_history_day_items(
result = await db.execute(
select(GenerationRecord, Project.name.label("project_name"))
.outerjoin(Project, GenerationRecord.project_id == Project.id)
.outerjoin(Project, (GenerationRecord.project_id == Project.id) & (Project.deleted_at.is_(None)))
.where(
*filters,
day_expr == target_day,
@@ -773,4 +779,15 @@ async def list_generation_history_day_items(
"page": page,
"page_size": page_size,
"items": [record_to_out(task) for task in tasks],
}
}
async def soft_delete_chat_generation_task(
db: AsyncSession,
*,
task: ChatGenerationTask,
deleted_at: datetime | None = None,
) -> int:
"""软删 ChatGenerationTask 并联动软删资源账本,返回释放的 active 空间字节数。"""
deleted_at = deleted_at or datetime.now(timezone.utc)
task.deleted_at = deleted_at
return await soft_delete_chat_task_resources(db, task.id, deleted_at=deleted_at)