Files
test/app/model/account.py
T
2026-09-21 19:03:31 +08:00

36 lines
1.6 KiB
Python

"""登录账号表(需求第 5 节的"用户认证模块",这版直接做进来了)。"""
from __future__ import annotations
from datetime import datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, String
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.model.base import Base, SoftDeleteMixin, TimestampMixin
from app.model.constants import ROLE_TEXT, Role
class Account(Base, TimestampMixin, SoftDeleteMixin):
__tablename__ = "account"
__table_args__ = {"comment": "登录账号表"}
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
username: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, comment="登录名")
hashed_password: Mapped[str] = mapped_column(String(120), nullable=False, comment="bcrypt 哈希后的密码")
real_name: Mapped[str] = mapped_column(String(30), nullable=False, comment="姓名")
role: Mapped[str] = mapped_column(String(20), default=Role.ADVISOR.value, nullable=False, comment="角色 admin/advisor/viewer")
advisor_id: Mapped[int | None] = mapped_column(ForeignKey("advisor.id"), comment="关联顾问(顾问账号专用)")
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, comment="是否启用")
last_login_at: Mapped[datetime | None] = mapped_column(DateTime, comment="最近登录时间")
advisor: Mapped["Advisor"] = relationship(lazy="joined") # noqa: F821
@property
def role_text(self) -> str:
return ROLE_TEXT.get(self.role, self.role)
@property
def is_admin(self) -> bool:
return self.role == Role.ADMIN.value