# ============================================================================= # 用户角色关联模型 — user_roles 表 # ============================================================================= # 说明:用户与角色的多对多关联表,记录角色来源和分配信息 # ============================================================================= import uuid from datetime import datetime from typing import Optional from sqlalchemy import String, DateTime, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import Mapped, mapped_column from app.database import Base class UserRole(Base): """用户角色关联模型 — 对应 user_roles 表。 记录用户拥有的角色,支持以下来源: - auto: 系统自动分配(所有员工默认 user 角色) - tag: 企微标签映射 - ehr: eHR 字段映射 - manual: 管理后台手动分配 """ __tablename__ = "user_roles" __table_args__ = ( # 同一用户同一角色只能有一条记录 UniqueConstraint("employee_id", "role_id", name="uq_user_role"), # 按 employee_id 查询优化 Index("idx_user_roles_employee_id", "employee_id"), # 按 role_id 查询优化 Index("idx_user_roles_role_id", "role_id"), ) # 主键:UUID id: Mapped[str] = mapped_column( String(36), primary_key=True, default=lambda: str(uuid.uuid4()), ) # 企微 UserID employee_id: Mapped[str] = mapped_column( String(100), nullable=False, comment="企微 UserID", ) # 角色 ID(外键) role_id: Mapped[str] = mapped_column( String(36), ForeignKey("roles.id", ondelete="CASCADE"), nullable=False, comment="角色 ID", ) # 角色来源:auto/tag/ehr/manual source: Mapped[str] = mapped_column( String(50), nullable=False, comment="角色来源:auto/tag/ehr/manual", ) # 分配者(手动分配时记录操作人) assigned_by: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="分配者(手动分配时记录操作人)", ) # 分配时间 assigned_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, default=datetime.now, comment="分配时间", ) # 过期时间(可选,用于临时角色) expires_at: Mapped[Optional[datetime]] = mapped_column( DateTime(timezone=True), nullable=True, comment="过期时间(可选,用于临时角色)", ) def __repr__(self) -> str: return f""