39 lines
1.7 KiB
Python
39 lines
1.7 KiB
Python
"""用户 + 用户-角色关联。"""
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import Column, ForeignKey, Integer, String, Table
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.db.base import Base, TimestampMixin
|
|
|
|
user_role = Table(
|
|
"user_role",
|
|
Base.metadata,
|
|
Column("user_id", Integer, ForeignKey("user.id", ondelete="CASCADE"), primary_key=True),
|
|
Column("role_id", Integer, ForeignKey("role.id", ondelete="CASCADE"), primary_key=True),
|
|
)
|
|
|
|
|
|
class User(Base, TimestampMixin):
|
|
__tablename__ = "user"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
username: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
|
|
password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
nickname: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
email: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
avatar: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
dept_id: Mapped[int | None] = mapped_column(
|
|
ForeignKey("organization.id", ondelete="SET NULL"), nullable=True, index=True
|
|
)
|
|
status: Mapped[str] = mapped_column(String(16), default="ACTIVE", nullable=False)
|
|
# 是否超级管理员(绕过菜单权限校验,仅用于系统初始账号)
|
|
is_superuser: Mapped[bool] = mapped_column(default=False, nullable=False)
|
|
|
|
roles: Mapped[list["Role"]] = relationship( # type: ignore[name-defined] # noqa: F821
|
|
"Role", secondary=user_role, lazy="selectin"
|
|
)
|
|
dept: Mapped["Organization | None"] = relationship( # type: ignore[name-defined] # noqa: F821
|
|
"Organization", lazy="selectin"
|
|
)
|