from datetime import datetime from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, SmallInteger, String, UniqueConstraint, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base from app.models.base import BaseModel, SoftDeleteMixin class MenuRole(Base): __tablename__ = "bx_menu_role" __table_args__ = (UniqueConstraint("menu_id", "role_id"),) id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) menu_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("bx_menu.id"), nullable=False) role_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("bx_role.id"), nullable=False, index=True) create_by: Mapped[str | None] = mapped_column(String(64)) create_time: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) class Menu(BaseModel, SoftDeleteMixin): __tablename__ = "bx_menu" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) parent_id: Mapped[int] = mapped_column( BigInteger, ForeignKey("bx_menu.id"), nullable=False, default=0, server_default="0" ) menu_name: Mapped[str] = mapped_column(String(64), nullable=False) menu_code: Mapped[str | None] = mapped_column(String(64)) menu_type: Mapped[int] = mapped_column(SmallInteger, nullable=False) path: Mapped[str | None] = mapped_column(String(256)) icon: Mapped[str | None] = mapped_column(String(64)) sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") visible: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=1, server_default="1") status: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=1, server_default="1") remark: Mapped[str | None] = mapped_column(String(512)) parent: Mapped["Menu | None"] = relationship( "Menu", remote_side=[id], back_populates="children" ) children: Mapped[list["Menu"]] = relationship("Menu", back_populates="parent") roles: Mapped[list["Role"]] = relationship( "Role", secondary="bx_menu_role", back_populates="menus" )