1aafc28621
引入 JWT 认证、极光一键登录、短信 mock 登录与用户表,并补充技术实施文档与部署配置。 Co-authored-by: Cursor <cursoragent@cursor.com>
49 lines
1.2 KiB
Python
49 lines
1.2 KiB
Python
"""user 表的 CRUD 工具函数。
|
|
|
|
业务策略 = "注册即登录":phone 不存在则 insert,存在则更新 last_login_at。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.user import User
|
|
|
|
|
|
def get_user_by_id(db: Session, user_id: int) -> User | None:
|
|
return db.get(User, user_id)
|
|
|
|
|
|
def get_user_by_phone(db: Session, phone: str) -> User | None:
|
|
stmt = select(User).where(User.phone == phone)
|
|
return db.execute(stmt).scalar_one_or_none()
|
|
|
|
|
|
def upsert_user_for_login(
|
|
db: Session,
|
|
*,
|
|
phone: str,
|
|
register_channel: str,
|
|
) -> User:
|
|
"""登录入口统一调:有则更新 last_login_at,无则新建。
|
|
|
|
返回 commit 后的 user。调用方拿到 user.id 直接签 JWT。
|
|
"""
|
|
user = get_user_by_phone(db, phone)
|
|
now = datetime.now(timezone.utc)
|
|
if user is None:
|
|
user = User(
|
|
phone=phone,
|
|
register_channel=register_channel,
|
|
last_login_at=now,
|
|
)
|
|
db.add(user)
|
|
else:
|
|
user.last_login_at = now
|
|
# 被禁用的账号被尝试登录时,不自动启用,直接抛(在调用方处理)
|
|
db.commit()
|
|
db.refresh(user)
|
|
return user
|