import json from typing import Any, Optional from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.models.pre_test_template import PreTestTemplate from app.dependencies import get_current_user, get_db from app.models.user import User from app.schemas.pre_test_template import ( PreTestTemplateCreate, PreTestTemplateListResponse, PreTestTemplateOut, PreTestTemplateUpdate, ) from app.services.pre_test_template_service import ( create_pre_test_template, delete_pre_test_template, get_default_template, get_pre_test_template, get_pre_test_template_list, update_pre_test_template, ) router = APIRouter(prefix="/pre-test-template", tags=["前测模板"]) def _template_to_dict(template): return { "id": template.id, "name": template.name, "note": template.note, "platform": template.platform, "external_action": template.external_action, "cpa_bid": template.cpa_bid, "audience_gender": template.audience_gender, "audience_age": json.loads(template.audience_age) if template.audience_age else None, "audience_region": json.loads(template.audience_region) if template.audience_region else None, "audience_network": json.loads(template.audience_network) if template.audience_network else None, "cus_name": template.cus_name, "pricing_type": template.pricing_type, "cost_cap": template.cost_cap, "target_cost": template.target_cost, "nobid": template.nobid, "cpc_bid": template.cpc_bid, "budget": template.budget, "is_default": template.is_default, "user_id": template.user_id, "created_at": template.created_at, "updated_at": template.updated_at, } @router.post( "/create", summary="创建前测模板", description="创建一个新的前测模板", ) async def create_template( req: PreTestTemplateCreate, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any: try: #新增一个判断,如果模板名称重复,提示用户修改 result = await db.execute( select(PreTestTemplate).where( PreTestTemplate.name == req.name, PreTestTemplate.user_id == current_user.id, PreTestTemplate.deleted_at.is_(None), ) ) existing_template = result.scalar() if existing_template: raise ValueError("模板名称已存在") template = await create_pre_test_template( user_id=current_user.id, db=db, name=req.name, note=req.note, platform=req.platform, external_action=req.external_action, cpa_bid=req.cpa_bid, audience_gender=req.audience_gender, audience_age=req.audience_age, audience_region=req.audience_region, audience_network=req.audience_network, cus_name=req.cus_name, pricing_type=req.pricing_type, cost_cap=req.cost_cap, target_cost=req.target_cost, nobid=req.nobid, cpc_bid=req.cpc_bid, budget=req.budget, is_default=req.is_default, ) return { "code": 0, "message": "创建成功", } except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"创建失败: {str(e)}", ) @router.get( "/list", summary="获取前测模板列表", description="获取当前用户的前测模板列表,支持按平台筛选和分页", response_model=PreTestTemplateListResponse, ) async def list_templates( platform: Optional[str] = Query(None, description="投放平台筛选(AD/QIANCHUAN/LOCAL)"), page: int = Query(1, description="页码,默认1"), page_size: int = Query(10, description="每页数量,默认10,最大100"), current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any: try: result = await get_pre_test_template_list( user_id=current_user.id, db=db, platform=platform, page=page, page_size=page_size, ) return { "code": 0, "message": "查询成功", "data": [_template_to_dict(t) for t in result["data"]], "pagination": { "page": result["page"], "page_size": result["page_size"], "total": result["total"], "total_pages": (result["total"] + result["page_size"] - 1) // result["page_size"], }, } except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"查询失败: {str(e)}", ) @router.get( "/default", summary="获取默认前测模板", description="获取当前用户的默认前测模板", ) async def get_default( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any: try: template = await get_default_template(current_user.id, db) if not template: return { "code": 0, "message": "未设置默认模板", "data": None, } return { "code": 0, "message": "查询成功", "data": _template_to_dict(template), } except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"查询失败: {str(e)}", ) @router.get( "/select/{template_id}", summary="获取前测模板详情", description="根据模板id获取前测模板详情", ) async def get_template( template_id: str, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any: try: template = await get_pre_test_template(template_id, current_user.id, db) if not template: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="模板不存在", ) return { "code": 0, "message": "查询成功", "data": _template_to_dict(template), } except HTTPException: raise except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"查询失败: {str(e)}", ) @router.post( "/update/{template_id}", summary="更新前测模板", description="更新指定的前测模板", ) async def update_template( template_id: str, req: PreTestTemplateUpdate, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any: try: update_data = req.dict(exclude_none=True) template = await update_pre_test_template(template_id, current_user.id, db, **update_data) if not template: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="模板不存在", ) return { "code": 0, "message": "更新成功", "data": _template_to_dict(template), } except HTTPException: raise except ValueError as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=str(e), ) except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"更新失败: {str(e)}", ) @router.get( "/delete/{template_id}", summary="删除前测模板", description="软删除指定的前测模板", ) async def delete_template( template_id: str, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ) -> Any: try: success = await delete_pre_test_template(template_id, current_user.id, db) if not success: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="模板不存在", ) return { "code": 0, "message": "删除成功", } except HTTPException: raise except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"删除失败: {str(e)}", )