refactor(user): refactor user database

**Breaking Change**

用户表变为 lazer_users

建议删除与用户关联的表进行迁移
This commit is contained in:
MingxuanGame
2025-07-30 16:17:09 +00:00
parent 3900babe3d
commit 9ce99398ab
37 changed files with 994 additions and 2073 deletions

View File

@@ -1,12 +1,8 @@
from __future__ import annotations
from typing import Literal
from app.database import User as DBUser
from app.database import User, UserResp
from app.dependencies.database import get_db
from app.models.score import INT_TO_MODE
from app.models.user import User as ApiUser
from app.utils import convert_db_user_to_api_user
from app.models.score import GameMode
from .api_router import router
@@ -17,28 +13,17 @@ from sqlmodel.ext.asyncio.session import AsyncSession
from sqlmodel.sql.expression import col
# ---------- Shared Utility ----------
async def get_user_by_lookup(
db: AsyncSession, lookup: str, key: str = "id"
) -> DBUser | None:
"""根据查找方式获取用户"""
if key == "id":
try:
user_id = int(lookup)
result = await db.exec(select(DBUser).where(DBUser.id == user_id))
return result.first()
except ValueError:
return None
elif key == "username":
result = await db.exec(select(DBUser).where(DBUser.name == lookup))
return result.first()
else:
return None
# ---------- Batch Users ----------
class BatchUserResponse(BaseModel):
users: list[ApiUser]
users: list[UserResp]
SEARCH_INCLUDE = [
"team",
"daily_challenge_user_stats",
"statistics",
"statistics_rulesets",
"achievements",
]
@router.get("/users", response_model=BatchUserResponse)
@@ -52,74 +37,54 @@ async def get_users(
if user_ids:
searched_users = (
await session.exec(
DBUser.all_select_clause().limit(50).where(col(DBUser.id).in_(user_ids))
select(User)
.options(*User.all_select_option())
.limit(50)
.where(col(User.id).in_(user_ids))
)
).all()
else:
searched_users = (
await session.exec(DBUser.all_select_clause().limit(50))
await session.exec(
select(User).options(*User.all_select_option()).limit(50)
)
).all()
return BatchUserResponse(
users=[
await convert_db_user_to_api_user(
searched_user, ruleset=INT_TO_MODE[searched_user.preferred_mode].value
await UserResp.from_db(
searched_user,
session,
include=SEARCH_INCLUDE,
)
for searched_user in searched_users
]
)
# # ---------- Individual User ----------
# @router.get("/users/{user_lookup}/{mode}", response_model=ApiUser)
# @router.get("/users/{user_lookup}/{mode}/", response_model=ApiUser)
# async def get_user_with_mode(
# user_lookup: str,
# mode: Literal["osu", "taiko", "fruits", "mania"],
# key: Literal["id", "username"] = Query("id"),
# current_user: DBUser = Depends(get_current_user),
# db: AsyncSession = Depends(get_db),
# ):
# """获取指定游戏模式的用户信息"""
# user = await get_user_by_lookup(db, user_lookup, key)
# if not user:
# raise HTTPException(status_code=404, detail="User not found")
# return await convert_db_user_to_api_user(user, mode)
# @router.get("/users/{user_lookup}", response_model=ApiUser)
# @router.get("/users/{user_lookup}/", response_model=ApiUser)
# async def get_user_default(
# user_lookup: str,
# key: Literal["id", "username"] = Query("id"),
# current_user: DBUser = Depends(get_current_user),
# db: AsyncSession = Depends(get_db),
# ):
# """获取用户信息默认使用osu模式但包含所有模式的统计信息"""
# user = await get_user_by_lookup(db, user_lookup, key)
# if not user:
# raise HTTPException(status_code=404, detail="User not found")
# return await convert_db_user_to_api_user(user, "osu")
@router.get("/users/{user}/{ruleset}", response_model=ApiUser)
@router.get("/users/{user}/", response_model=ApiUser)
@router.get("/users/{user}", response_model=ApiUser)
@router.get("/users/{user}/{ruleset}", response_model=UserResp)
@router.get("/users/{user}/", response_model=UserResp)
@router.get("/users/{user}", response_model=UserResp)
async def get_user_info(
user: str,
ruleset: Literal["osu", "taiko", "fruits", "mania"] = "osu",
ruleset: GameMode | None = None,
session: AsyncSession = Depends(get_db),
):
searched_user = (
await session.exec(
DBUser.all_select_clause().where(
DBUser.id == int(user)
select(User)
.options(*User.all_select_option())
.where(
User.id == int(user)
if user.isdigit()
else DBUser.name == user.removeprefix("@")
else User.username == user.removeprefix("@")
)
)
).first()
if not searched_user:
raise HTTPException(404, detail="User not found")
return await convert_db_user_to_api_user(searched_user, ruleset=ruleset)
return await UserResp.from_db(
searched_user,
session,
include=SEARCH_INCLUDE,
ruleset=ruleset,
)