import os from typing import Any, Optional from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, Field from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_current_user, get_db from app.models.user import User from app.services.upload_material_service import upload_material_to_platform router = APIRouter(prefix="/upload-material", tags=["上传素材"]) class UploadTask(BaseModel): advertiser_ids: list[str] = Field(..., description="广告主id数组,支持多条") resource_ids: list[str] = Field(..., description="资源id数组(generated_resources表主键)") oauth_id: str = Field(..., description="授权表id") is_pre_test: Optional[str] = Field(None, description="是否开启前测:是/否/0/1,预留字段") pre_test_template: Optional[str] = Field(None, description="前测模板id,预留字段") class BatchUploadRequest(BaseModel): tasks: list[UploadTask] = Field(..., description="批量上传任务列表") @router.post( "/batch-upload", summary="批量上传素材到平台", description="支持批量上传多个授权账户下的资源到素材库,预留下前测功能", ) async def batch_upload_material( req: BatchUploadRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any | dict: if not req.tasks: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="上传任务列表不能为空", ) all_results = [] total_success = 0 total_fail = 0 for task_index, task in enumerate(req.tasks, 1): task_result = { "task_index": task_index, "oauth_id": task.oauth_id, "advertiser_ids": task.advertiser_ids, "resource_ids": task.resource_ids, "is_pre_test": task.is_pre_test, "pre_test_template": task.pre_test_template, "result": None, } try: if not task.advertiser_ids: raise ValueError("广告主id数组不能为空") if not task.resource_ids: raise ValueError("资源id数组不能为空") result = await upload_material_to_platform( task.resource_ids, task.advertiser_ids, task.oauth_id, db, current_user.id, ) task_result["result"] = { "success": True, **result, } total_success += result["success_count"] total_fail += result["fail_count"] if task.is_pre_test and task.is_pre_test in ["是", "1", "true", True]: task_result["pre_test_reserved"] = { "status": "reserved", "message": "前测功能已预留,待后续开通", "template": task.pre_test_template, } except ValueError as e: task_result["result"] = { "success": False, "error": str(e), } total_fail += len(task.resource_ids) * len(task.advertiser_ids) except Exception as e: task_result["result"] = { "success": False, "error": f"上传失败: {str(e)}", } total_fail += len(task.resource_ids) * len(task.advertiser_ids) all_results.append(task_result) return { "code": 0, "message": "批量上传完成", "summary": { "total_tasks": len(req.tasks), "total_success_count": total_success, "total_fail_count": total_fail, "total_requested": sum(len(t.resource_ids) * len(t.advertiser_ids) for t in req.tasks), }, "details": all_results, }