model.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. # -*- coding: utf-8 -*-
  2. from typing import TYPE_CHECKING
  3. from sqlalchemy import Boolean, String, Integer, JSON, ForeignKey
  4. from sqlalchemy.orm import relationship, Mapped, mapped_column
  5. from app.core.base_model import ModelMixin
  6. if TYPE_CHECKING:
  7. from app.api.v1.module_system.role.model import RoleModel
  8. class MenuModel(ModelMixin):
  9. """
  10. 菜单表 - 用于存储系统菜单信息
  11. 菜单类型说明:
  12. - 1: 目录(一级菜单)
  13. - 2: 菜单(二级菜单)
  14. - 3: 按钮/权限(页面内按钮权限)
  15. - 4: 外部链接
  16. """
  17. __tablename__: str = "sys_menu"
  18. __table_args__: dict[str, str] = ({'comment': '菜单表'})
  19. __loader_options__: list[str] = ["roles"]
  20. name: Mapped[str] = mapped_column(String(50), nullable=False, comment='菜单名称')
  21. type: Mapped[int] = mapped_column(Integer, nullable=False, default=2, comment='菜单类型(1:目录 2:菜单 3:按钮/权限 4:链接)')
  22. order: Mapped[int] = mapped_column(Integer, nullable=False, default=999, comment='显示排序')
  23. permission: Mapped[str | None] = mapped_column(String(100), comment='权限标识(如:module_system:user:list)')
  24. icon: Mapped[str | None] = mapped_column(String(50), comment='菜单图标')
  25. route_name: Mapped[str | None] = mapped_column(String(100), comment='路由名称')
  26. route_path: Mapped[str | None] = mapped_column(String(200), comment='路由路径')
  27. component_path: Mapped[str | None] = mapped_column(String(200), comment='组件路径')
  28. redirect: Mapped[str | None] = mapped_column(String(200), comment='重定向地址')
  29. hidden: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, comment='是否隐藏(True:隐藏 False:显示)')
  30. keep_alive: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, comment='是否缓存(True:是 False:否)')
  31. always_show: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, comment='是否始终显示(True:是 False:否)')
  32. title: Mapped[str | None] = mapped_column(String(50), comment='菜单标题')
  33. params: Mapped[list[dict[str, str]] | None] = mapped_column(JSON, comment='路由参数(JSON对象)')
  34. affix: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, comment='是否固定标签页(True:是 False:否)')
  35. # 树形结构
  36. parent_id: Mapped[int | None] = mapped_column(
  37. Integer,
  38. ForeignKey('sys_menu.id', ondelete='SET NULL'),
  39. default=None,
  40. index=True,
  41. comment='父菜单ID'
  42. )
  43. # 关联关系
  44. parent: Mapped["MenuModel | None"] = relationship(
  45. back_populates='children',
  46. remote_side="MenuModel.id",
  47. foreign_keys="MenuModel.parent_id",
  48. uselist=False
  49. )
  50. children: Mapped[list["MenuModel"] | None] = relationship(
  51. back_populates='parent',
  52. foreign_keys="MenuModel.parent_id",
  53. order_by="MenuModel.order"
  54. )
  55. roles: Mapped[list["RoleModel"]] = relationship(
  56. secondary="sys_role_menus",
  57. back_populates="menus",
  58. lazy="selectin"
  59. )