提供基本前后端骨架

This commit is contained in:
hisatri
2026-01-06 23:49:23 +08:00
parent 84d4ccc226
commit 06f8176e23
89 changed files with 19293 additions and 2 deletions

141
app/models/user.py Normal file
View File

@@ -0,0 +1,141 @@
"""
用户模型
定义用户数据表结构。
"""
from datetime import datetime, timezone
from typing import TYPE_CHECKING
from uuid import uuid4
from sqlalchemy import Boolean, DateTime, String, Text, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
if TYPE_CHECKING:
from app.models.balance import UserBalance
def generate_uuid() -> str:
"""生成 UUID 字符串"""
return str(uuid4())
def utc_now() -> datetime:
"""获取当前 UTC 时间"""
return datetime.now(timezone.utc)
class User(Base):
"""用户模型"""
__tablename__ = "users"
# 主键:使用 UUID 字符串
id: Mapped[str] = mapped_column(
String(36),
primary_key=True,
default=generate_uuid,
comment="用户唯一标识",
)
# 账户信息
username: Mapped[str] = mapped_column(
String(32),
unique=True,
index=True,
nullable=False,
comment="用户名",
)
email: Mapped[str | None] = mapped_column(
String(255),
unique=True,
index=True,
nullable=True,
comment="邮箱地址",
)
hashed_password: Mapped[str | None] = mapped_column(
String(255),
nullable=True, # OAuth2 用户可能没有密码
comment="密码哈希",
)
# OAuth2 关联信息
oauth_provider: Mapped[str | None] = mapped_column(
String(32),
nullable=True,
index=True,
comment="OAuth2 提供商(如 linuxdo",
)
oauth_user_id: Mapped[str | None] = mapped_column(
String(128),
nullable=True,
index=True,
comment="OAuth2 用户 ID",
)
# 用户状态
is_active: Mapped[bool] = mapped_column(
Boolean,
default=True,
nullable=False,
comment="是否激活",
)
is_superuser: Mapped[bool] = mapped_column(
Boolean,
default=False,
nullable=False,
comment="是否为超级管理员",
)
# 个人信息
nickname: Mapped[str | None] = mapped_column(
String(64),
nullable=True,
comment="昵称",
)
avatar_url: Mapped[str | None] = mapped_column(
String(512),
nullable=True,
comment="头像 URL",
)
bio: Mapped[str | None] = mapped_column(
Text,
nullable=True,
comment="个人简介",
)
# 时间戳
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=utc_now,
server_default=func.now(),
nullable=False,
comment="创建时间",
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=utc_now,
onupdate=utc_now,
server_default=func.now(),
nullable=False,
comment="更新时间",
)
last_login_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True),
nullable=True,
comment="最后登录时间",
)
# 关系
balance_account: Mapped["UserBalance | None"] = relationship(
"UserBalance",
back_populates="user",
uselist=False,
lazy="selectin",
)
def __repr__(self) -> str:
return f"<User(id={self.id!r}, username={self.username!r})>"