Files
s2f/backend/app/models/reconciliation_task.py
T
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

73 lines
3.0 KiB
Python

"""
对账任务模型
用于管理工资对账任务的生命周期
"""
from datetime import datetime
from enum import Enum
from typing import List, Optional
from sqlalchemy import ForeignKey, Integer, String, DateTime, JSON, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.models.base import BaseModel
class TaskStatus(str, Enum):
"""任务状态"""
CREATED = "CREATED" # 已创建
FILES_UPLOADED = "FILES_UPLOADED" # 文件已上传
PARSING = "PARSING" # 解析中
WAITING_MAPPING_CONFIRM = "WAITING_MAPPING_CONFIRM" # 等待字段映射确认
MAPPING_CONFIRMED = "MAPPING_CONFIRMED" # 字段映射已确认
RECONCILING = "RECONCILING" # 对账中
COMPLETED = "COMPLETED" # 完成
FAILED = "FAILED" # 失败
class ReconciliationTask(BaseModel):
"""
对账任务模型
管理一次完整的工资对账流程
"""
__tablename__ = "reconciliation_tasks"
company_id: Mapped[int] = mapped_column(Integer, ForeignKey("companies.id"), nullable=False, index=True)
name: Mapped[str] = mapped_column(String(200), nullable=False, comment="任务名称")
period: Mapped[str] = mapped_column(String(20), nullable=False, index=True, comment="对账期间,如 2024-01")
status: Mapped[str] = mapped_column(String(30), nullable=False, default=TaskStatus.CREATED.value, index=True)
# 文件信息 (JSON 格式存储)
file_ids: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True, comment="关联的文件ID")
# 字段映射状态
mapping_completed: Mapped[bool] = mapped_column(Integer, nullable=False, default=False)
mapping_confirmed_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
mapping_confirmed_by: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("users.id"), nullable=True)
# 对账结果摘要
total_employees: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
matched_count: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
exception_count: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
# 结果数据 (JSON)
reconciliation_result: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
# 错误信息
error_message: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
# 确认信息
created_by: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("users.id"), nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
# 关系
company = relationship("Company", back_populates="tasks")
creator = relationship("User", foreign_keys=[created_by])
confirm_user = relationship("User", foreign_keys=[mapping_confirmed_by])
def __repr__(self) -> str:
return f"<ReconciliationTask(id={self.id}, name='{self.name}', status='{self.status}')>"