from enum import Enum from typing import List from sqlalchemy import ForeignKey, Integer, String, BigInteger, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import BaseModel class FileType(str, Enum): """文件类型""" SALARY = "工资表" SOCIAL_SECURITY = "社保表" TAX = "个税表" class ParseStatus(str, Enum): """解析状态""" PENDING = "待解析" PARSING = "解析中" SUCCESS = "解析成功" FAILED = "解析失败" class UploadedFile(BaseModel): """ 上传文件模型 Attributes: company_id: 企业ID task_id: 对账任务ID(可选) file_type: 文件类型 original_filename: 原始文件名 stored_filename: 存储文件名 file_size: 文件大小(字节) mime_type: MIME类型 parse_status: 解析状态 parse_error: 解析错误信息 """ __tablename__ = "uploaded_files" company_id: Mapped[int] = mapped_column(Integer, ForeignKey("companies.id"), nullable=False, index=True) task_id: Mapped[int | None] = mapped_column(Integer, nullable=True, index=True) file_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True) original_filename: Mapped[str] = mapped_column(String(255), nullable=False) stored_filename: Mapped[str] = mapped_column(String(255), nullable=False, unique=True) file_size: Mapped[int] = mapped_column(BigInteger, nullable=False) mime_type: Mapped[str] = mapped_column(String(100), nullable=False) parse_status: Mapped[str] = mapped_column(String(20), nullable=False, default=ParseStatus.PENDING.value, index=True) parse_error: Mapped[str | None] = mapped_column(Text, nullable=True) # 关系 field_mappings: Mapped[List["FieldMapping"]] = relationship( "FieldMapping", back_populates="file", lazy="selectin" ) def __repr__(self) -> str: return f""