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 数据库迁移配置 - 添加初始化示例数据脚本 - 更新项目文档
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
"""
|
||||
字段映射相关 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]
|
||||
Reference in New Issue
Block a user