API响应条目重复且未返回足够游戏用户积分问题求助
API响应重复且积分返回不全的修复方案
问题根源分析
重复条目问题:
- 原代码按
game_id+version_id+user_id分组,当同一个游戏存在多个版本时,会生成多条仅版本不同的记录,而响应中仅展示游戏基础信息,导致视觉上出现重复条目。 - 分组后直接使用
$score->created_at是错误的:分组聚合后,该字段并非对应最高分记录的创建时间,而是分组中任意一条记录的时间,属于无效数据。
- 原代码按
积分返回不全问题:
- 原代码仅查询了每个(游戏+版本)分组的最高分,而非用户的所有积分记录,自然无法返回更多积分数据。
修复方案
根据你的需求选择对应方案:
方案1:返回每个游戏的最高分(无重复,单游戏单条记录)
如果需求是每个游戏仅返回用户的最高分,同时确保数据准确:
public function toArray($request) { // 先获取每个游戏的最高分 $highestScoreAggregates = Score::where('user_id', $this->user->id) ->select('game_id', DB::raw('MAX(score) as max_score')) ->groupBy('game_id') ->get(); // 关联回原表,找到对应最高分的完整记录(包含正确的created_at) $scoreRecords = Score::where('user_id', $this->user->id) ->whereIn( ['game_id', 'score'], $highestScoreAggregates->map(fn($item) => [$item->game_id, $item->max_score])->toArray() ) ->with('game') // 预加载游戏,避免N+1查询 ->get(); return $scoreRecords->map(function ($score) { return [ 'game' => new UserGamesResource($score->game), 'score' => $score->score, 'timestamp' => Carbon::parse($score->created_at)->toIso8601String(), ]; })->toArray(); }
方案2:返回用户的所有积分记录(无遗漏)
如果需求是返回该用户在游戏中的所有积分记录,直接去掉分组聚合逻辑:
public function toArray($request) { // 获取用户所有积分记录,预加载关联的游戏模型 $allScores = Score::where('user_id', $this->user->id) ->with('game') ->get(); return $allScores->map(function ($score) { return [ 'game' => new UserGamesResource($score->game), 'score' => $score->score, 'timestamp' => Carbon::parse($score->created_at)->toIso8601String(), ]; })->toArray(); }
额外优化:保留版本维度的最高分
如果需要按游戏版本区分最高分,仅需调整分组字段,同时在响应中加入版本信息避免视觉重复:
public function toArray($request) { $highestScoreAggregates = Score::where('user_id', $this->user->id) ->select('game_id', 'version_id', DB::raw('MAX(score) as max_score')) ->groupBy('game_id', 'version_id') ->get(); $scoreRecords = Score::where('user_id', $this->user->id) ->whereIn( ['game_id', 'version_id', 'score'], $highestScoreAggregates->map(fn($item) => [$item->game_id, $item->version_id, $item->max_score])->toArray() ) ->with('game') ->get(); return $scoreRecords->map(function ($score) { return [ 'game' => new UserGamesResource($score->game), 'version_id' => $score->version_id, // 加入版本信息区分 'score' => $score->score, 'timestamp' => Carbon::parse($score->created_at)->toIso8601String(), ]; })->toArray(); }
内容的提问来源于stack exchange,提问作者Данил Грицан
相关产品推荐
相关产品推荐

