Files
loom/backend/app/models/role.py
T
2026-04-24 17:46:03 +08:00

68 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""角色 + 4 维权限关联表。
关联表设计:
- role_menu 菜单/按钮权限
- role_product_scope 产品数据范围(P3 建表后 product_id 再加 FK)
- role_skill_scope Skill 权限范围
- role_account_scope 平台账号权限范围
P2 仅强依赖 role_menu;其余三张为 role 的可选能力边界,等 P3/P4 相应主表建好后补 FK。
"""
from __future__ import annotations
from sqlalchemy import ForeignKey, Integer, String, Table, Column, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db.base import Base, TimestampMixin
# Role <-> Menu(含按钮级权限)
role_menu = Table(
"role_menu",
Base.metadata,
Column("role_id", Integer, ForeignKey("role.id", ondelete="CASCADE"), primary_key=True),
Column("menu_id", Integer, ForeignKey("menu.id", ondelete="CASCADE"), primary_key=True),
)
# Role 的产品 / Skill / 平台账号 范围(P3+ 再绑 FK)
role_product_scope = Table(
"role_product_scope",
Base.metadata,
Column("role_id", Integer, ForeignKey("role.id", ondelete="CASCADE"), primary_key=True),
Column("product_id", Integer, primary_key=True),
)
role_skill_scope = Table(
"role_skill_scope",
Base.metadata,
Column("role_id", Integer, ForeignKey("role.id", ondelete="CASCADE"), primary_key=True),
Column("skill_id", Integer, primary_key=True),
)
role_account_scope = Table(
"role_account_scope",
Base.metadata,
Column("role_id", Integer, ForeignKey("role.id", ondelete="CASCADE"), primary_key=True),
Column("account_id", Integer, primary_key=True),
)
class Role(Base, TimestampMixin):
__tablename__ = "role"
__table_args__ = (UniqueConstraint("dept_id", "code", name="uq_role_dept_code"),)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
# 角色归属部门;null 表示全局角色(如超管)
dept_id: Mapped[int | None] = mapped_column(
ForeignKey("organization.id", ondelete="SET NULL"), nullable=True, index=True
)
name: Mapped[str] = mapped_column(String(64), nullable=False)
code: Mapped[str] = mapped_column(String(64), nullable=False)
description: Mapped[str | None] = mapped_column(String(255), nullable=True)
status: Mapped[str] = mapped_column(String(16), default="ACTIVE", nullable=False)
# 系统内置角色(如 super_admin)不允许用户删除
is_builtin: Mapped[bool] = mapped_column(default=False, nullable=False)
menus: Mapped[list["Menu"]] = relationship( # type: ignore[name-defined] # noqa: F821
"Menu", secondary=role_menu, lazy="selectin"
)