""" 模板 API 路由 """ from fastapi import APIRouter, HTTPException from pydantic import BaseModel from typing import Optional, List, Dict from services.template_service import get_template_service from models.schemas import ( CreateTemplateResponse, GetTemplateResponse, TemplateApplyResponse, DeleteTemplateResponse, ) router = APIRouter(prefix="/api/templates", tags=["templates"]) class CreateTemplateRequest(BaseModel): """创建模板请求""" name: str structure: Dict image_size: Dict description: Optional[str] = "" class PreviewApplyRequest(BaseModel): """预览应用请求""" target_image_size: Dict target_table_bbox: Optional[List] = None # 目标页面的 table_bbox [x1, y1, x2, y2] mode: Optional[str] = "relative" # "relative" 或 "absolute" class ApplyTemplateRequest(BaseModel): """应用模板请求""" target_image_size: Dict target_table_bbox: Optional[List] = None # 目标页面的 table_bbox [x1, y1, x2, y2] mode: Optional[str] = "relative" class TemplateInfo(BaseModel): """模板信息""" name: str description: Optional[str] = "" created_at: Optional[str] = "" stats: Optional[Dict] = {} source_image_size: Optional[Dict] = {} class TemplateListResponse(BaseModel): """模板列表响应""" templates: List[Dict] total: int @router.get("", response_model=TemplateListResponse) async def list_templates(): """列出所有模板""" service = get_template_service() templates = service.list_templates() return TemplateListResponse( templates=templates, total=len(templates) ) @router.post("", response_model=CreateTemplateResponse) async def create_template(request: CreateTemplateRequest): """从当前结构创建模板""" service = get_template_service() try: result = service.create_template( name=request.name, structure=request.structure, image_size=request.image_size, description=request.description or "" ) return CreateTemplateResponse( success=True, data=result, message="模板创建成功" ) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=f"创建模板失败: {str(e)}") @router.get("/{name}", response_model=GetTemplateResponse) async def get_template(name: str): """获取模板详情""" service = get_template_service() template = service.get_template(name) if not template: raise HTTPException(status_code=404, detail=f"模板 '{name}' 不存在") return GetTemplateResponse( success=True, data=template, message="获取成功" ) @router.delete("/{name}", response_model=DeleteTemplateResponse) async def delete_template(name: str): """删除模板""" service = get_template_service() if service.delete_template(name): return DeleteTemplateResponse( success=True, message=f"模板 '{name}' 已删除" ) raise HTTPException(status_code=404, detail=f"模板 '{name}' 不存在") @router.post("/{name}/preview", response_model=TemplateApplyResponse) async def preview_apply(name: str, request: PreviewApplyRequest): """预览模板应用效果""" service = get_template_service() try: structure = service.preview_apply( template_name=name, target_image_size=request.target_image_size, target_table_bbox=request.target_table_bbox, mode=request.mode or "relative" ) return TemplateApplyResponse( success=True, data=structure, message="预览成功" ) except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=f"预览失败: {str(e)}") @router.post("/{name}/apply", response_model=TemplateApplyResponse) async def apply_template(name: str, request: ApplyTemplateRequest): """确认应用模板""" service = get_template_service() try: structure = service.apply_template( template_name=name, target_image_size=request.target_image_size, target_table_bbox=request.target_table_bbox, mode=request.mode or "relative" ) return TemplateApplyResponse( success=True, data=structure, message="应用成功" ) except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=f"应用模板失败: {str(e)}")