33b4c734aa
后端: - 新增认证(auth)、任务(tasks)、映射(mappings)、对账(reconciliation)、异常(exceptions)、导出(exports) API - 新增核心模块: database, security, permissions, tenant, exceptions, error_handlers - 新增数据模型: user, company, reconciliation_task, field_mapping, uploaded_file 等 - 新增服务层: ai_recognizer, file_parser, file_storage, mapping, reconciliation 等 - 添加数据库迁移脚本 前端: - 新增登录页面和仪表盘页面 - 新增任务列表、任务详情、字段映射页面 - 新增异常处理页面和规则设置页面 - 新增 API 代理路由 /api/[...path] - 新增 UI 组件库 (button, card, dialog, input, table 等) - 新增 auth 组件 (ProtectedRoute, PermissionGate) - 新增 layout 组件 (Header, Sidebar) - 新增 mapping 组件 (FieldMappingTable, AISuggestionPanel) - 新增 API 客户端和 hooks (useAsync, useToast, usePermission 等) - 新增状态管理 (auth-store, company-store, ui-store) - 集成 Tailwind CSS 和 shadcn/ui 组件库 其他: - 添加 Alembic 数据库迁移配置 - 添加初始化示例数据脚本 - 更新项目文档
147 lines
4.1 KiB
Python
147 lines
4.1 KiB
Python
"""
|
|
字段映射相关 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] |