| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- """自定义业务角色模型:角色、权限矩阵。
- 内置 ADMIN/USER 之外的第三层授权体系:
- - Role 本体(含全局唯一默认角色标记);
- - RolePermission 权限矩阵(密级 × 部门范围 × 7 操作,每角色固定 10 行)。
- """
- from __future__ import annotations
- from sqlalchemy import (
- BigInteger,
- Boolean,
- CheckConstraint,
- Computed,
- ForeignKey,
- Index,
- Integer,
- String,
- UniqueConstraint,
- text,
- )
- from sqlalchemy.orm import Mapped, mapped_column
- from dms.database.base import BusinessTableMixin
- from dms.extensions import db
- class Role(BusinessTableMixin, db.Model):
- __tablename__ = "sys_role"
- __table_args__ = (
- CheckConstraint(
- "status IN ('ENABLED', 'DISABLED')",
- name="role_status",
- ),
- # 活跃行角色名唯一:软删后可重建同名角色
- UniqueConstraint(
- "role_name",
- "active_marker",
- name="uq_sys_role_role_name_active",
- ),
- # 全局至多一个默认角色:default_marker 虚拟生成列(非默认/已软删 → NULL)
- UniqueConstraint(
- "default_marker",
- name="uq_sys_role_default_active",
- ),
- Index(
- "ix_sys_role_status_active",
- "status",
- "is_deleted",
- ),
- )
- role_name: Mapped[str] = mapped_column(String(64), nullable=False)
- sort_no: Mapped[int] = mapped_column(
- Integer,
- nullable=False,
- server_default=text("0"),
- )
- status: Mapped[str] = mapped_column(
- String(20),
- nullable=False,
- server_default=text("'ENABLED'"),
- )
- remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
- is_default: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- active_marker: Mapped[int | None] = mapped_column(
- Integer,
- Computed("IF(is_deleted = 0, 1, NULL)", persisted=False),
- nullable=True,
- )
- default_marker: Mapped[int | None] = mapped_column(
- Integer,
- Computed(
- "IF(is_default = 1 AND is_deleted = 0, 1, NULL)",
- persisted=False,
- ),
- nullable=True,
- )
- class RolePermission(BusinessTableMixin, db.Model):
- """角色权限矩阵行:密级 × 部门范围 → 7 个操作布尔位。
- 每角色固定 10 行(5 密级 × 2 部门范围),整存整取;
- 与文档 ACL 为 OR 叠加,矩阵是主权限源。
- """
- __tablename__ = "sys_role_permission"
- __table_args__ = (
- CheckConstraint(
- "security_level IN "
- "('PUBLIC', 'INTERNAL', 'SECRET', 'CONFIDENTIAL', 'TOP_SECRET')",
- name="role_permission_security_level",
- ),
- CheckConstraint(
- "dept_scope IN ('OWN', 'OTHER')",
- name="dept_scope_v2",
- ),
- UniqueConstraint(
- "role_id",
- "security_level",
- "dept_scope",
- "active_marker",
- name="uq_sys_role_permission_active",
- ),
- Index(
- "ix_sys_role_permission_role_active",
- "role_id",
- "is_deleted",
- ),
- )
- role_id: Mapped[int] = mapped_column(
- BigInteger,
- ForeignKey("sys_role.id", ondelete="RESTRICT"),
- nullable=False,
- )
- security_level: Mapped[str] = mapped_column(String(32), nullable=False)
- dept_scope: Mapped[str] = mapped_column(String(32), nullable=False)
- can_view: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- can_download: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- can_edit: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- can_delete: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- can_config_permission: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- can_bind_attachment: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- can_unbind_attachment: Mapped[bool] = mapped_column(
- Boolean,
- nullable=False,
- server_default=text("0"),
- )
- active_marker: Mapped[int | None] = mapped_column(
- Integer,
- Computed("IF(is_deleted = 0, 1, NULL)", persisted=False),
- nullable=True,
- )
|