audit_log.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. """追加写审计日志模型。"""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from sqlalchemy import BigInteger, CheckConstraint, Index, JSON, String, Text, text
  5. from sqlalchemy.dialects.mysql import DATETIME
  6. from sqlalchemy.orm import Mapped, mapped_column
  7. from dms.extensions import db
  8. class AuditLog(db.Model):
  9. __tablename__ = "sys_audit_log"
  10. __table_args__ = (
  11. CheckConstraint(
  12. "action_type IN ("
  13. "'LOGIN', 'LOGOUT', 'VIEW_DOCUMENT', 'DOWNLOAD_DOCUMENT', "
  14. "'UPLOAD_DOCUMENT', 'BATCH_IMPORT', 'EDIT_DOCUMENT', "
  15. "'DELETE_DOCUMENT', 'CREATE_CATEGORY', 'EDIT_CATEGORY', "
  16. "'DELETE_CATEGORY', 'CHANGE_PERMISSION', 'BIND_ATTACHMENT', "
  17. "'UNBIND_ATTACHMENT', 'RESTORE_DOCUMENT'"
  18. ")",
  19. name="audit_action_type",
  20. ),
  21. CheckConstraint(
  22. "target_type IS NULL OR target_type IN ("
  23. "'AUTH', 'CATEGORY', 'DOCUMENT', 'ATTACHMENT', "
  24. "'PERMISSION', 'ATTACHMENT_BINDING'"
  25. ")",
  26. name="audit_target_type",
  27. ),
  28. CheckConstraint(
  29. "operation_result IN ('SUCCESS', 'FAILURE')",
  30. name="audit_operation_result",
  31. ),
  32. Index("ix_sys_audit_log_created_at", "created_at"),
  33. Index("ix_sys_audit_log_user_created", "user_id", "created_at"),
  34. Index(
  35. "ix_sys_audit_log_organization_created",
  36. "organization_id",
  37. "created_at",
  38. ),
  39. Index("ix_sys_audit_log_action_created", "action_type", "created_at"),
  40. Index(
  41. "ix_sys_audit_log_target_created",
  42. "target_type",
  43. "target_id",
  44. "created_at",
  45. ),
  46. Index(
  47. "ix_sys_audit_log_result_created",
  48. "operation_result",
  49. "created_at",
  50. ),
  51. Index("ix_sys_audit_log_request_id", "request_id"),
  52. )
  53. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  54. user_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  55. username: Mapped[str | None] = mapped_column(String(64), nullable=True)
  56. real_name: Mapped[str | None] = mapped_column(String(64), nullable=True)
  57. organization_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  58. organization_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
  59. action_type: Mapped[str] = mapped_column(String(32), nullable=False)
  60. target_type: Mapped[str | None] = mapped_column(String(32), nullable=True)
  61. target_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
  62. target_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
  63. operation_result: Mapped[str] = mapped_column(String(20), nullable=False)
  64. failure_reason: Mapped[str | None] = mapped_column(String(1000), nullable=True)
  65. client_ip: Mapped[str | None] = mapped_column(String(64), nullable=True)
  66. user_agent: Mapped[str | None] = mapped_column(String(500), nullable=True)
  67. request_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
  68. operation_detail: Mapped[dict[str, object] | None] = mapped_column(
  69. JSON,
  70. nullable=True,
  71. )
  72. created_at: Mapped[datetime] = mapped_column(
  73. DATETIME(fsp=3),
  74. nullable=False,
  75. server_default=text("CURRENT_TIMESTAMP(3)"),
  76. )