295 lines
8.9 KiB
Python
295 lines
8.9 KiB
Python
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)}",
|
||
)
|