Files
freedakgmail 33b4c734aa feat: 完善前后端核心功能模块
后端:
- 新增认证(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 数据库迁移配置
- 添加初始化示例数据脚本
- 更新项目文档
2026-07-07 09:04:47 +08:00

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]