""" 字段映射相关 Pydantic Schema """ from datetime import datetime from typing import List, Optional, Dict, Any from pydantic import BaseModel, Field # ===== 字段映射 Schema ===== class FieldMappingBase(BaseModel): """字段映射基础 schema""" source_field: str = Field(..., description="源字段名") standard_field: str = Field(..., description="标准字段名") confidence: float = Field(..., ge=0, le=1, description="置信度 0-1") reasoning: Optional[str] = Field(None, description="AI 判断依据") sample_values: Optional[List[Any]] = Field(None, description="样例值") is_skipped: bool = Field(False, description="是否跳过") class FieldMappingCreate(FieldMappingBase): """创建字段映射""" file_id: int = Field(..., description="文件ID") class FieldMappingUpdate(BaseModel): """更新字段映射""" standard_field: Optional[str] = Field(None, description="标准字段名") is_skipped: Optional[bool] = Field(None, description="是否跳过") class FieldMappingResponse(FieldMappingBase): """字段映射响应""" id: int company_id: int file_id: int confirmed: bool confirmed_by: Optional[int] = None confirmed_at: Optional[datetime] = None class Config: from_attributes = True class FieldMappingWithFileResponse(FieldMappingResponse): """带文件信息的字段映射响应""" file_type: Optional[str] = None file_name: Optional[str] = None # ===== 批量操作 Schema ===== class ConfirmMappingsRequest(BaseModel): """批量确认映射请求""" mapping_ids: List[int] = Field(..., description="要确认的映射ID列表") class ConfirmMappingsResponse(BaseModel): """批量确认映射响应""" confirmed_count: int = Field(..., description="确认数量") mappings: List[FieldMappingResponse] class SaveAsRuleRequest(BaseModel): """保存为规则请求""" mapping_id: int = Field(..., description="映射ID") class SaveAsRuleResponse(BaseModel): """保存为规则响应""" rule_id: int source_field: str target_field: str message: str # ===== 规则 Schema ===== class CompanyRuleBase(BaseModel): """企业规则基础 schema""" rule_type: str = Field(..., description="规则类型") match_condition: Dict[str, Any] = Field(..., description="匹配条件") target_value: str = Field(..., description="目标值") priority: int = Field(0, description="优先级") description: Optional[str] = Field(None, description="规则描述") class CompanyRuleResponse(CompanyRuleBase): """企业规则响应""" id: int company_id: int status: str match_count: int last_used_at: Optional[datetime] = None created_at: datetime updated_at: datetime class Config: from_attributes = True class UpdateRuleStatusRequest(BaseModel): """更新规则状态请求""" status: str = Field(..., description="状态 ACTIVE/INACTIVE") class RecognizeFieldsRequest(BaseModel): """识别字段请求""" file_id: int = Field(..., description="文件ID") file_type: str = Field("工资表", description="文件类型") class RecognizeFieldsResponse(BaseModel): """识别字段响应""" file_id: int mappings: List[FieldMappingResponse] high_confidence_count: int = Field(..., description="高置信度数量") medium_confidence_count: int = Field(..., description="中等置信度数量") low_confidence_count: int = Field(..., description="低置信度数量") needs_review: bool = Field(..., description="是否需要人工确认") # ===== 文件映射概览 ===== class FileMappingSummary(BaseModel): """文件映射概览""" file_id: int file_type: str file_name: str total_fields: int confirmed_fields: int high_confidence: int medium_confidence: int low_confidence: int mappings: List[FieldMappingResponse] class TaskMappingOverview(BaseModel): """任务映射概览""" task_id: int total_files: int total_fields: int confirmed_fields: int needs_review: bool files: List[FileMappingSummary]