"""DocumentCategory 文档分类模型(支持树形目录结构)。""" from sqlalchemy import Boolean, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin class DocumentCategory(UUIDPrimaryKeyMixin, TimestampMixin, Base): """文档分类模型(树形结构)。 通过 parent_id 实现层级关系,path 用于高效查询子树。 is_folder=True 表示文件夹(可包含子项),False 表示叶子分类。 """ __tablename__ = "document_categories" knowledge_base_id: Mapped[str] = mapped_column( String(32), ForeignKey("knowledge_bases.id"), nullable=False, index=True, comment="所属知识库 ID", ) parent_id: Mapped[str | None] = mapped_column( String(32), ForeignKey("document_categories.id"), nullable=True, index=True, comment="父分类 ID(NULL = 顶层)", ) name: Mapped[str] = mapped_column( String(255), nullable=False, comment="分类名称", ) path: Mapped[str] = mapped_column( String(500), default="/", nullable=False, comment="物化路径,如 /01_公司层/04_岗位AI角色/", ) is_folder: Mapped[bool] = mapped_column( Boolean, default=True, nullable=False, comment="True=文件夹(可含子项),False=叶子分类", ) sort_order: Mapped[int] = mapped_column( Integer, default=0, nullable=False, comment="排序序号", ) deleted_at: Mapped[str | None] = mapped_column( String(32), nullable=True, index=True, comment="进入回收站时间(NULL=未删除),3 天后自动清理", ) # 关系 knowledge_base = relationship("KnowledgeBase", back_populates="categories", lazy="selectin") parent = relationship("DocumentCategory", remote_side="DocumentCategory.id", lazy="selectin") children = relationship("DocumentCategory", back_populates="parent", lazy="selectin") documents = relationship("Document", back_populates="category", lazy="selectin") def __repr__(self) -> str: return f""