# -*- coding: utf-8 -*- """ 响应数据模型 定义 API 响应的数据结构 """ from typing import Any, Dict, List, Optional from pydantic import BaseModel, Field class ErrorDetail(BaseModel): """错误详情""" code: str = Field(..., description="错误代码") message: str = Field(..., description="错误信息") details: Optional[Dict[str, Any]] = Field( default=None, description="额外的错误详情", ) class TextBlockData(BaseModel): """文本块数据""" text: str = Field(..., description="识别出的文本内容") confidence: float = Field(..., description="置信度 (0.0 ~ 1.0)") bbox: List[List[float]] = Field( ..., description="边界框 4 个顶点坐标 [[x1,y1], [x2,y2], [x3,y3], [x4,y4]]", ) bbox_with_offset: List[List[float]] = Field( ..., description="带偏移的边界框坐标 (已还原到原图坐标系)", ) center: List[float] = Field(..., description="文本块中心点坐标 [x, y]") width: float = Field(..., description="文本块宽度 (像素)") height: float = Field(..., description="文本块高度 (像素)") class OCRResultData(BaseModel): """OCR 识别结果数据""" processing_time_ms: float = Field(..., description="处理耗时 (毫秒)") text_count: int = Field(..., description="识别出的文本块数量") average_confidence: float = Field( ..., description="所有文本块的平均置信度", ) roi_applied: bool = Field(..., description="是否应用了 ROI 裁剪") roi_rect: Optional[List[int]] = Field( default=None, description="ROI 矩形区域 [x, y, width, height]", ) text_blocks: List[TextBlockData] = Field( default_factory=list, description="识别出的文本块列表", ) annotated_image_base64: Optional[str] = Field( default=None, description="标注后的图片 (Base64 编码)", ) class OCRResponse(BaseModel): """OCR 识别响应""" success: bool = Field(..., description="请求是否成功") data: Optional[OCRResultData] = Field( default=None, description="识别结果数据", ) error: Optional[ErrorDetail] = Field( default=None, description="错误信息 (仅在失败时存在)", ) class ExpressPersonData(BaseModel): """快递单人员信息""" name: Optional[str] = Field(default=None, description="姓名") phone: Optional[str] = Field(default=None, description="电话") address: Optional[str] = Field(default=None, description="地址") class ExpressInfoData(BaseModel): """快递单结构化信息""" tracking_number: Optional[str] = Field(default=None, description="运单号") sender: ExpressPersonData = Field( default_factory=ExpressPersonData, description="寄件人信息", ) receiver: ExpressPersonData = Field( default_factory=ExpressPersonData, description="收件人信息", ) courier_company: Optional[str] = Field( default=None, description="快递公司名称", ) confidence: float = Field(default=0.0, description="平均置信度") extra_fields: Dict[str, str] = Field( default_factory=dict, description="其他识别到的额外字段", ) raw_text: str = Field(default="", description="原始合并文本") class ExpressResultData(BaseModel): """快递单解析结果数据""" processing_time_ms: float = Field(..., description="处理耗时 (毫秒)") express_info: ExpressInfoData = Field(..., description="快递单结构化信息") merged_text: str = Field(..., description="智能合并后的完整文本") annotated_image_base64: Optional[str] = Field( default=None, description="标注后的图片 (Base64 编码)", ) class ExpressResponse(BaseModel): """快递单解析响应""" success: bool = Field(..., description="请求是否成功") data: Optional[ExpressResultData] = Field( default=None, description="解析结果数据", ) error: Optional[ErrorDetail] = Field( default=None, description="错误信息 (仅在失败时存在)", ) class HealthResponse(BaseModel): """健康检查响应""" status: str = Field(..., description="服务状态: 'healthy' 或 'unhealthy'") model_loaded: bool = Field(..., description="OCR 模型是否已加载") version: str = Field(..., description="API 版本")