144 lines
5.5 KiB
Python
144 lines
5.5 KiB
Python
from typing import Any, Optional
|
||
|
||
from fastapi import APIRouter, Depends, Query
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from sqlalchemy import select
|
||
from app.models.resources_material import ResourcesMaterial
|
||
from app.models.pre_test_template import PreTestTemplate
|
||
|
||
from app.dependencies import get_db, get_current_user
|
||
from app.schemas.resources_material import ResourcesMaterialListResponse
|
||
from app.services.resources_material_service import get_resources_material_list
|
||
from app.services.pre_test_queue import pre_test_queue
|
||
from app.utils.id_gen import generate_id
|
||
|
||
router = APIRouter(prefix="/resources-material", tags=["resources-material"])
|
||
|
||
|
||
@router.get(
|
||
"/list",
|
||
summary="查询素材列表",
|
||
description="通过advertiser_id,material_id,upload_id,resource_type查询素材列表,同时返回关联的资源信息",
|
||
response_model=ResourcesMaterialListResponse,
|
||
)
|
||
async def get_resources_material_list_api(
|
||
advertiser_id: Optional[str] = Query(None, description="广告主id"),
|
||
material_id: Optional[str] = Query(None, description="素材id"),
|
||
upload_id: Optional[str] = Query(None, description="上传资源平台id"),
|
||
file_name: Optional[str] = Query(None, description="文件名"),
|
||
resource_type: Optional[str] = Query(None, description="资源类型,image或者video"),
|
||
page: int = Query(1, description="页码"),
|
||
page_size: int = Query(20, description="每页数量"),
|
||
db: AsyncSession = Depends(get_db),
|
||
) -> Any | dict:
|
||
items, total = await get_resources_material_list(
|
||
db=db,
|
||
advertiser_id=advertiser_id,
|
||
material_id=material_id,
|
||
upload_id=upload_id,
|
||
file_name=file_name,
|
||
resource_type=resource_type,
|
||
page=page,
|
||
page_size=page_size,
|
||
)
|
||
|
||
return {
|
||
"code": 0,
|
||
"message": "查询成功",
|
||
"data": items,
|
||
"total": total,
|
||
}
|
||
|
||
#如果素材上传的时候没有指定前测,现在可以对已经上传好的素材进行前测
|
||
@router.post(
|
||
"/pre-commit",
|
||
summary="素材列表提交前测",
|
||
description="通过素材列表提交未前测的素材,异步处理,立即返回任务ID,结果稍后通过列表查询",
|
||
)
|
||
async def pre_test_material(
|
||
resources_material_ids: list[str] = Query(..., description="资源素材表id"),
|
||
pre_test_template_id: str = Query(..., description="前测模板id"),
|
||
db: AsyncSession = Depends(get_db),
|
||
current_user: dict = Depends(get_current_user),
|
||
) -> Any | dict:
|
||
|
||
try:
|
||
invalid_ids = []
|
||
grouped_videos = {}
|
||
|
||
#检查前测模板是否有效
|
||
pre_test_template = await db.execute(
|
||
select(PreTestTemplate)
|
||
.where(
|
||
PreTestTemplate.id == pre_test_template_id,
|
||
PreTestTemplate.user_id == current_user.id,
|
||
PreTestTemplate.deleted_at.is_(None),
|
||
)
|
||
)
|
||
pre_test_template = pre_test_template.scalar_one_or_none()
|
||
if not pre_test_template:
|
||
return {"code": 1, "message": f"前测模板{pre_test_template_id}不存在或不属于当前用户"}
|
||
|
||
for resource_material_id in resources_material_ids:
|
||
resource_material = await db.execute(
|
||
select(ResourcesMaterial)
|
||
.where(
|
||
ResourcesMaterial.id == resource_material_id,
|
||
ResourcesMaterial.user_id == current_user.id,
|
||
ResourcesMaterial.deleted_at.is_(None),
|
||
)
|
||
)
|
||
resource_material = resource_material.scalar_one_or_none()
|
||
|
||
if not resource_material:
|
||
invalid_ids.append(f"{resource_material_id}: 资源不存在或不属于当前用户")
|
||
continue
|
||
|
||
if resource_material.status is not None:
|
||
invalid_ids.append(f"{resource_material_id}: 该资源已进行过前测")
|
||
continue
|
||
|
||
if not resource_material.upload_id:
|
||
invalid_ids.append(f"{resource_material_id}: 该资源未上传到平台")
|
||
continue
|
||
|
||
if resource_material.resource_type != "video":
|
||
invalid_ids.append(f"{resource_material_id}: 前测仅支持视频类型")
|
||
continue
|
||
|
||
key = f"{resource_material.oauth_id}|{resource_material.advertiser_id}"
|
||
if key not in grouped_videos:
|
||
grouped_videos[key] = []
|
||
grouped_videos[key].append({
|
||
"id": resource_material.id,
|
||
"upload_id": resource_material.upload_id,
|
||
})
|
||
|
||
if invalid_ids:
|
||
logger.error(f"前测素材提交失败,无效素材ID: {'; '.join(invalid_ids)}")
|
||
return {"code": 1, "message": "; ".join(invalid_ids)}
|
||
|
||
if not grouped_videos:
|
||
return {"code": 1, "message": "没有有效的视频资源"}
|
||
|
||
task_id = generate_id()
|
||
|
||
await pre_test_queue.enqueue({
|
||
"task_id": task_id,
|
||
"grouped_videos": grouped_videos,
|
||
"pre_test_template_id": pre_test_template_id,
|
||
})
|
||
|
||
return {
|
||
"code": 0,
|
||
"message": "任务已提交,正在处理中",
|
||
"data": {
|
||
"task_id": task_id,
|
||
"total_groups": len(grouped_videos),
|
||
},
|
||
}
|
||
|
||
except ValueError as e:
|
||
return {"code": 1, "message": str(e)}
|
||
except Exception as e:
|
||
return {"code": 1, "message": str(e)} |