user.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. """系统用户模型。"""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from sqlalchemy import (
  5. BigInteger,
  6. CheckConstraint,
  7. Computed,
  8. ForeignKey,
  9. Index,
  10. Integer,
  11. String,
  12. UniqueConstraint,
  13. text,
  14. )
  15. from sqlalchemy.dialects.mysql import DATETIME
  16. from sqlalchemy.orm import Mapped, mapped_column
  17. from dms.database.base import BusinessTableMixin
  18. from dms.extensions import db
  19. class User(BusinessTableMixin, db.Model):
  20. __tablename__ = "sys_user"
  21. __table_args__ = (
  22. UniqueConstraint(
  23. "external_id",
  24. "active_marker",
  25. name="uq_sys_user_external_id_active",
  26. ),
  27. Index(
  28. "ix_sys_user_external_active",
  29. "external_id",
  30. "is_deleted",
  31. ),
  32. CheckConstraint(
  33. "role_code IN ('USER', 'ADMIN')",
  34. name="user_role_code",
  35. ),
  36. CheckConstraint(
  37. "security_level IN "
  38. "('PUBLIC', 'INTERNAL', 'SECRET', 'CONFIDENTIAL', 'TOP_SECRET')",
  39. name="user_security_level",
  40. ),
  41. CheckConstraint(
  42. "status IN ('ENABLED', 'DISABLED')",
  43. name="user_status",
  44. ),
  45. Index(
  46. "ix_sys_user_organization_active_status",
  47. "organization_id",
  48. "is_deleted",
  49. "status",
  50. ),
  51. Index(
  52. "ix_sys_user_role_status_active",
  53. "role_code",
  54. "status",
  55. "is_deleted",
  56. ),
  57. Index(
  58. "ix_sys_user_role_active",
  59. "role_id",
  60. "is_deleted",
  61. ),
  62. )
  63. username: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
  64. password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
  65. real_name: Mapped[str] = mapped_column(String(64), nullable=False)
  66. organization_id: Mapped[int | None] = mapped_column(
  67. BigInteger,
  68. ForeignKey("sys_organization.id", ondelete="RESTRICT"),
  69. nullable=True,
  70. )
  71. organization_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
  72. role_code: Mapped[str] = mapped_column(
  73. String(32),
  74. nullable=False,
  75. server_default=text("'USER'"),
  76. )
  77. role_id: Mapped[int | None] = mapped_column(
  78. BigInteger,
  79. ForeignKey("sys_role.id", ondelete="RESTRICT"),
  80. nullable=True,
  81. )
  82. security_level: Mapped[str] = mapped_column(
  83. String(32),
  84. nullable=False,
  85. server_default=text("'INTERNAL'"),
  86. )
  87. status: Mapped[str] = mapped_column(
  88. String(20),
  89. nullable=False,
  90. server_default=text("'ENABLED'"),
  91. )
  92. auth_version: Mapped[int] = mapped_column(
  93. Integer,
  94. nullable=False,
  95. server_default=text("0"),
  96. )
  97. last_login_at: Mapped[datetime | None] = mapped_column(
  98. DATETIME(fsp=3),
  99. nullable=True,
  100. )
  101. last_login_ip: Mapped[str | None] = mapped_column(String(64), nullable=True)
  102. external_id: Mapped[str | None] = mapped_column(String(128), nullable=True)
  103. active_marker: Mapped[int | None] = mapped_column(
  104. Integer(),
  105. Computed("IF(is_deleted = 0, 1, NULL)", persisted=False),
  106. nullable=True,
  107. )