fix(score): return failed score which read from cache & remove legacy score error

This commit is contained in:
MingxuanGame
2025-08-25 08:40:16 +00:00
parent 81a07b5544
commit d11303b562
3 changed files with 22 additions and 10 deletions

View File

@@ -316,8 +316,6 @@ async def get_user_beatmap_score(
mods: str = Query(None, description="筛选使用的 Mods (暂未实现)"), mods: str = Query(None, description="筛选使用的 Mods (暂未实现)"),
current_user: User = Security(get_current_user, scopes=["public"]), current_user: User = Security(get_current_user, scopes=["public"]),
): ):
if legacy_only:
raise HTTPException(status_code=404, detail="This server only contains non-legacy scores")
user_score = ( user_score = (
await db.exec( await db.exec(
select(Score) select(Score)
@@ -325,8 +323,10 @@ async def get_user_beatmap_score(
Score.gamemode == mode if mode is not None else True, Score.gamemode == mode if mode is not None else True,
Score.beatmap_id == beatmap_id, Score.beatmap_id == beatmap_id,
Score.user_id == user_id, Score.user_id == user_id,
col(Score.passed).is_(True),
) )
.order_by(col(Score.total_score).desc()) .order_by(col(Score.total_score).desc())
.limit(1)
) )
).first() ).first()
@@ -358,8 +358,6 @@ async def get_user_all_beatmap_scores(
ruleset: GameMode | None = Query(None, description="指定 ruleset (可选)"), ruleset: GameMode | None = Query(None, description="指定 ruleset (可选)"),
current_user: User = Security(get_current_user, scopes=["public"]), current_user: User = Security(get_current_user, scopes=["public"]),
): ):
if legacy_only:
raise HTTPException(status_code=404, detail="This server only contains non-legacy scores")
all_user_scores = ( all_user_scores = (
await db.exec( await db.exec(
select(Score) select(Score)
@@ -367,8 +365,9 @@ async def get_user_all_beatmap_scores(
Score.gamemode == ruleset if ruleset is not None else True, Score.gamemode == ruleset if ruleset is not None else True,
Score.beatmap_id == beatmap_id, Score.beatmap_id == beatmap_id,
Score.user_id == user_id, Score.user_id == user_id,
col(Score.passed).is_(True),
) )
.order_by(col(Score.classic_total_score).desc()) .order_by(col(Score.total_score).desc())
) )
).all() ).all()

View File

@@ -331,7 +331,7 @@ async def get_user_scores(
# 先尝试从缓存获取对于recent类型使用较短的缓存时间 # 先尝试从缓存获取对于recent类型使用较短的缓存时间
cache_expire = 30 if type == "recent" else settings.user_scores_cache_expire_seconds cache_expire = 30 if type == "recent" else settings.user_scores_cache_expire_seconds
cached_scores = await cache_service.get_user_scores_from_cache(user_id, type, mode, limit, offset) cached_scores = await cache_service.get_user_scores_from_cache(user_id, type, include_fails, mode, limit, offset)
if cached_scores is not None: if cached_scores is not None:
return cached_scores return cached_scores
@@ -373,7 +373,15 @@ async def get_user_scores(
# 异步缓存结果 # 异步缓存结果
background_task.add_task( background_task.add_task(
cache_service.cache_user_scores, user_id, type, score_responses, mode, limit, offset, cache_expire cache_service.cache_user_scores,
user_id,
type,
score_responses,
include_fails,
mode,
limit,
offset,
cache_expire,
) )
return score_responses return score_responses

View File

@@ -107,13 +107,16 @@ class UserCacheService:
self, self,
user_id: int, user_id: int,
score_type: str, score_type: str,
include_fail: bool,
mode: GameMode | None = None, mode: GameMode | None = None,
limit: int = 100, limit: int = 100,
offset: int = 0, offset: int = 0,
) -> str: ) -> str:
"""生成用户成绩缓存键""" """生成用户成绩缓存键"""
mode_part = f":{mode}" if mode else "" mode_part = f":{mode}" if mode else ""
return f"user:{user_id}:scores:{score_type}{mode_part}:limit:{limit}:offset:{offset}" return (
f"user:{user_id}:scores:{score_type}{mode_part}:limit:{limit}:offset:{offset}:include_fail:{include_fail}"
)
def _get_user_beatmapsets_cache_key( def _get_user_beatmapsets_cache_key(
self, user_id: int, beatmapset_type: str, limit: int = 100, offset: int = 0 self, user_id: int, beatmapset_type: str, limit: int = 100, offset: int = 0
@@ -159,13 +162,14 @@ class UserCacheService:
self, self,
user_id: int, user_id: int,
score_type: str, score_type: str,
include_fail: bool,
mode: GameMode | None = None, mode: GameMode | None = None,
limit: int = 100, limit: int = 100,
offset: int = 0, offset: int = 0,
) -> list[ScoreResp] | None: ) -> list[ScoreResp] | None:
"""从缓存获取用户成绩""" """从缓存获取用户成绩"""
try: try:
cache_key = self._get_user_scores_cache_key(user_id, score_type, mode, limit, offset) cache_key = self._get_user_scores_cache_key(user_id, score_type, include_fail, mode, limit, offset)
cached_data = await self.redis.get(cache_key) cached_data = await self.redis.get(cache_key)
if cached_data: if cached_data:
logger.debug(f"User scores cache hit for user {user_id}, type {score_type}") logger.debug(f"User scores cache hit for user {user_id}, type {score_type}")
@@ -181,6 +185,7 @@ class UserCacheService:
user_id: int, user_id: int,
score_type: str, score_type: str,
scores: list[ScoreResp], scores: list[ScoreResp],
include_fail: bool,
mode: GameMode | None = None, mode: GameMode | None = None,
limit: int = 100, limit: int = 100,
offset: int = 0, offset: int = 0,
@@ -190,7 +195,7 @@ class UserCacheService:
try: try:
if expire_seconds is None: if expire_seconds is None:
expire_seconds = settings.user_scores_cache_expire_seconds expire_seconds = settings.user_scores_cache_expire_seconds
cache_key = self._get_user_scores_cache_key(user_id, score_type, mode, limit, offset) cache_key = self._get_user_scores_cache_key(user_id, score_type, include_fail, mode, limit, offset)
# 使用 model_dump_json() 而不是 model_dump() + json.dumps() # 使用 model_dump_json() 而不是 model_dump() + json.dumps()
scores_json_list = [score.model_dump_json() for score in scores] scores_json_list = [score.model_dump_json() for score in scores]
cached_data = f"[{','.join(scores_json_list)}]" cached_data = f"[{','.join(scores_json_list)}]"