From d11303b562c9ffb1c6cab9fb5fe2ceda2d645721 Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Mon, 25 Aug 2025 08:40:16 +0000 Subject: [PATCH] fix(score): return failed score which read from cache & remove legacy score error --- app/router/v2/score.py | 9 ++++----- app/router/v2/user.py | 12 ++++++++++-- app/service/user_cache_service.py | 11 ++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/router/v2/score.py b/app/router/v2/score.py index cf3aa32..6077ed7 100644 --- a/app/router/v2/score.py +++ b/app/router/v2/score.py @@ -316,8 +316,6 @@ async def get_user_beatmap_score( mods: str = Query(None, description="筛选使用的 Mods (暂未实现)"), 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 = ( await db.exec( select(Score) @@ -325,8 +323,10 @@ async def get_user_beatmap_score( Score.gamemode == mode if mode is not None else True, Score.beatmap_id == beatmap_id, Score.user_id == user_id, + col(Score.passed).is_(True), ) .order_by(col(Score.total_score).desc()) + .limit(1) ) ).first() @@ -358,8 +358,6 @@ async def get_user_all_beatmap_scores( ruleset: GameMode | None = Query(None, description="指定 ruleset (可选)"), 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 = ( await db.exec( select(Score) @@ -367,8 +365,9 @@ async def get_user_all_beatmap_scores( Score.gamemode == ruleset if ruleset is not None else True, Score.beatmap_id == beatmap_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() diff --git a/app/router/v2/user.py b/app/router/v2/user.py index 8472a8d..d3861b0 100644 --- a/app/router/v2/user.py +++ b/app/router/v2/user.py @@ -331,7 +331,7 @@ async def get_user_scores( # 先尝试从缓存获取(对于recent类型使用较短的缓存时间) 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: return cached_scores @@ -373,7 +373,15 @@ async def get_user_scores( # 异步缓存结果 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 diff --git a/app/service/user_cache_service.py b/app/service/user_cache_service.py index 7e05892..a7c2817 100644 --- a/app/service/user_cache_service.py +++ b/app/service/user_cache_service.py @@ -107,13 +107,16 @@ class UserCacheService: self, user_id: int, score_type: str, + include_fail: bool, mode: GameMode | None = None, limit: int = 100, offset: int = 0, ) -> str: """生成用户成绩缓存键""" 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( self, user_id: int, beatmapset_type: str, limit: int = 100, offset: int = 0 @@ -159,13 +162,14 @@ class UserCacheService: self, user_id: int, score_type: str, + include_fail: bool, mode: GameMode | None = None, limit: int = 100, offset: int = 0, ) -> list[ScoreResp] | None: """从缓存获取用户成绩""" 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) if cached_data: logger.debug(f"User scores cache hit for user {user_id}, type {score_type}") @@ -181,6 +185,7 @@ class UserCacheService: user_id: int, score_type: str, scores: list[ScoreResp], + include_fail: bool, mode: GameMode | None = None, limit: int = 100, offset: int = 0, @@ -190,7 +195,7 @@ class UserCacheService: try: if expire_seconds is None: 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() scores_json_list = [score.model_dump_json() for score in scores] cached_data = f"[{','.join(scores_json_list)}]"