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

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"
)