3eb439b5ae
Reviewed-on: #114
51 lines
1.9 KiB
Python
51 lines
1.9 KiB
Python
"""新手引导完成标记的读写(按 user_id + device_id 去重)。
|
|
|
|
登录时 [is_completed] 判断该 (账号, 设备) 是否走过引导;走完引导时 [mark_completed] 写一条。
|
|
device_id 为空(老客户端 / 取不到 ANDROID_ID)一律按"未完成"处理,即照常走引导,不误跳过。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import delete, select
|
|
from sqlalchemy.exc import IntegrityError
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.onboarding import OnboardingCompletion
|
|
|
|
|
|
def is_completed(db: Session, *, user_id: int, device_id: str) -> bool:
|
|
"""该 (账号, 设备) 是否已完成新手引导。device_id 为空 → 一律 False。"""
|
|
if not device_id:
|
|
return False
|
|
stmt = select(OnboardingCompletion.id).where(
|
|
OnboardingCompletion.user_id == user_id,
|
|
OnboardingCompletion.device_id == device_id,
|
|
)
|
|
return db.execute(stmt).first() is not None
|
|
|
|
|
|
def mark_completed(db: Session, *, user_id: int, device_id: str) -> None:
|
|
"""走完引导时写入。device_id 为空忽略;同 (账号, 设备) 已存在则幂等(靠唯一约束兜并发)。"""
|
|
if not device_id:
|
|
return
|
|
db.add(OnboardingCompletion(user_id=user_id, device_id=device_id))
|
|
try:
|
|
db.commit()
|
|
except IntegrityError:
|
|
# 并发 / 重复提交撞唯一约束:已有行即视为成功。
|
|
db.rollback()
|
|
|
|
|
|
def delete_completion(db: Session, *, user_id: int, device_id: str) -> int:
|
|
"""删该 (账号, 设备) 的引导完成标记 → 下次登录 is_completed=False → 客户端重走。
|
|
与 [mark_completed] 互逆。device_id 为空忽略(返 0);无记录也幂等(返 0)。返回删除行数。"""
|
|
if not device_id:
|
|
return 0
|
|
result = db.execute(
|
|
delete(OnboardingCompletion).where(
|
|
OnboardingCompletion.user_id == user_id,
|
|
OnboardingCompletion.device_id == device_id,
|
|
)
|
|
)
|
|
db.commit()
|
|
return result.rowcount
|