-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FIX] Admin 게임 점수 수정 시 승패 카운트 오류 수정 (#402)
- Loading branch information
Showing
3 changed files
with
177 additions
and
171 deletions.
There are no files selected for viewing
307 changes: 156 additions & 151 deletions
307
src/main/java/com/gg/server/admin/game/service/GameAdminService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,152 +1,157 @@ | ||
package com.gg.server.admin.game.service; | ||
|
||
import com.gg.server.admin.game.dto.GameLogAdminDto; | ||
import com.gg.server.admin.game.dto.GameLogListAdminResponseDto; | ||
import com.gg.server.admin.game.data.GameAdminRepository; | ||
import com.gg.server.admin.game.dto.RankGamePPPModifyReqDto; | ||
import com.gg.server.admin.game.exception.NotRecentlyGameException; | ||
import com.gg.server.admin.pchange.data.PChangeAdminRepository; | ||
import com.gg.server.admin.season.data.SeasonAdminRepository; | ||
import com.gg.server.admin.team.data.TeamUserAdminRepository; | ||
import com.gg.server.admin.user.data.UserAdminRepository; | ||
import com.gg.server.domain.game.data.Game; | ||
import com.gg.server.domain.game.dto.GameTeamUser; | ||
import com.gg.server.domain.game.exception.GameNotExistException; | ||
import com.gg.server.domain.game.type.StatusType; | ||
import com.gg.server.domain.match.data.RedisMatchUserRepository; | ||
import com.gg.server.domain.pchange.data.PChange; | ||
import com.gg.server.domain.pchange.data.PChangeRepository; | ||
|
||
import com.gg.server.domain.rank.redis.RankRedisService; | ||
import com.gg.server.domain.season.data.Season; | ||
import com.gg.server.domain.season.exception.SeasonNotFoundException; | ||
import com.gg.server.domain.team.data.TeamUser; | ||
import com.gg.server.domain.user.data.User; | ||
import com.gg.server.domain.user.exception.UserNotFoundException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.cache.annotation.CacheEvict; | ||
import org.springframework.cache.annotation.Caching; | ||
import org.springframework.data.domain.*; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class GameAdminService { | ||
|
||
private final GameAdminRepository gameAdminRepository; | ||
private final SeasonAdminRepository seasonAdminRepository; | ||
private final UserAdminRepository userAdminRepository; | ||
private final PChangeRepository pChangeRepository; | ||
private final PChangeAdminRepository pChangeAdminRepository; | ||
private final RankRedisService rankRedisService; | ||
private final TeamUserAdminRepository teamUserAdminRepository; | ||
private final RedisMatchUserRepository redisMatchUserRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public GameLogListAdminResponseDto findAllGamesByAdmin(Pageable pageable) { | ||
Page<Game> gamePage = gameAdminRepository.findAll(pageable); //모든 게임 정보 가져오기 | ||
return new GameLogListAdminResponseDto(getGameLogList(gamePage.getContent().stream().map(Game::getId).collect(Collectors.toList())), gamePage.getTotalPages()); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public GameLogListAdminResponseDto findGamesBySeasonId(Long seasonId, Pageable pageable){ | ||
Season season = seasonAdminRepository.findById(seasonId).orElseThrow(()-> new SeasonNotFoundException()); | ||
Page<Game> games = gameAdminRepository.findBySeason(pageable, season); //시즌 id로 게임들 찾아오기 | ||
return new GameLogListAdminResponseDto(getGameLogList(games.getContent().stream().map(Game::getId).collect(Collectors.toList())), games.getTotalPages()); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public List<GameLogAdminDto> getGameLogList(List<Long> gameIdList){ | ||
List<GameTeamUser> teamViews = gameAdminRepository.findTeamsByGameIsIn(gameIdList); | ||
return teamViews.stream().map(GameLogAdminDto::new).collect(Collectors.toList()); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public GameLogListAdminResponseDto findGamesByIntraId(String intraId, Pageable pageable){ | ||
User user = userAdminRepository.findByIntraId(intraId).orElseThrow(() -> new UserNotFoundException()); | ||
List<PChange> pChangeList = pChangeRepository.findAllByUserId(user.getId()); | ||
List<Game> gameList = new ArrayList<>(); | ||
|
||
for(PChange pChange : pChangeList) | ||
gameList.add(pChange.getGame()); | ||
|
||
int start = (int)pageable.getOffset(); | ||
int end = Math.min((start + pageable.getPageSize()), gameList.size()); | ||
Page<Game> games = new PageImpl<>(gameList.subList(start, end), pageable, gameList.size()); | ||
return new GameLogListAdminResponseDto(getGameLogList(games.getContent().stream().map(Game::getId).collect(Collectors.toList())), games.getTotalPages()); | ||
} | ||
|
||
@Transactional | ||
@Caching(evict = { | ||
@CacheEvict(value = "rankGameListByIntra", allEntries = true), | ||
@CacheEvict(value = "rankGameList", allEntries = true), | ||
@CacheEvict(value = "allGameList", allEntries = true), | ||
@CacheEvict(value = "allGameListByUser", allEntries = true) | ||
}) | ||
public void rankResultEdit(RankGamePPPModifyReqDto reqDto, Long gameId) { | ||
// 게임이 두명 다 가장 마지막 게임인지 확인 (그 game에 해당하는 팀이 맞는지 확인) | ||
List<TeamUser> teamUsers = teamUserAdminRepository.findUsersByTeamIdIn(List.of(reqDto.getTeam1Id(), reqDto.getTeam2Id())); | ||
Game game = gameAdminRepository.findById(gameId) | ||
.orElseThrow(GameNotExistException::new); | ||
Season season = seasonAdminRepository.findById(game.getSeason().getId()) | ||
.orElseThrow(SeasonNotFoundException::new); | ||
if (!isRecentlyGame(teamUsers, gameId) || EnrollSlots(teamUsers)) { | ||
throw new NotRecentlyGameException(); | ||
} | ||
// pchange 가져와서 rank ppp 이전 값을 가지고 새 점수를 바탕으로 다시 계산 | ||
for (TeamUser teamUser : | ||
teamUsers) { | ||
List<PChange> pChanges = pChangeAdminRepository.findByTeamUser(teamUser.getUser().getId()); | ||
rollbackGameResult(reqDto, season, teamUser, pChanges); | ||
pChangeAdminRepository.delete(pChanges.get(0)); | ||
} | ||
rankRedisService.updateRankRedis(teamUsers.get(0), teamUsers.get(1), game); | ||
} | ||
|
||
private void rollbackGameResult(RankGamePPPModifyReqDto reqDto, Season season, TeamUser teamUser, List<PChange> pChanges) { | ||
// pchange ppp도 update | ||
// rankredis 에 ppp 다시 반영 | ||
// rank zset 도 update | ||
// 이전 ppp, exp 되돌리기 | ||
// rank data 에 있는 ppp 되돌리기 | ||
if (pChanges.size() == 1) { | ||
rankRedisService.rollbackRank(teamUser, season.getStartPpp(), season.getId()); | ||
teamUser.getUser().updateExp(0); | ||
} else { | ||
rankRedisService.rollbackRank(teamUser, pChanges.get(1).getPppResult(), season.getId()); | ||
teamUser.getUser().updateExp(pChanges.get(1).getExp()); | ||
} | ||
if (teamUser.getTeam().getId().equals(reqDto.getTeam1Id())) { | ||
teamUser.getTeam().updateScore(reqDto.getTeam1Score(), reqDto.getTeam1Score() > reqDto.getTeam2Score()); | ||
} else if (teamUser.getTeam().getId().equals(reqDto.getTeam2Id())) { | ||
teamUser.getTeam().updateScore(reqDto.getTeam2Score(), reqDto.getTeam2Score() > reqDto.getTeam1Score()); | ||
} | ||
} | ||
|
||
private Boolean isRecentlyGame(List<TeamUser> teamUsers, Long gameId) { | ||
for (TeamUser teamUser : teamUsers) { | ||
List<PChange> pChanges = pChangeAdminRepository.findByTeamUser(teamUser.getUser().getId()); | ||
if (!pChanges.get(0).getGame().getId().equals(gameId)) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
private Boolean EnrollSlots(List<TeamUser> teamUsers) { | ||
for (TeamUser teamUser : teamUsers) { | ||
Long userId = teamUser.getUser().getId(); | ||
if (redisMatchUserRepository.countMatchTime(userId) > 0) { | ||
return true; | ||
} | ||
if (gameAdminRepository.findByStatusTypeAndUserId(StatusType.BEFORE, userId).isPresent()) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
package com.gg.server.admin.game.service; | ||
|
||
import com.gg.server.admin.game.dto.GameLogAdminDto; | ||
import com.gg.server.admin.game.dto.GameLogListAdminResponseDto; | ||
import com.gg.server.admin.game.data.GameAdminRepository; | ||
import com.gg.server.admin.game.dto.RankGamePPPModifyReqDto; | ||
import com.gg.server.admin.game.exception.NotRecentlyGameException; | ||
import com.gg.server.admin.pchange.data.PChangeAdminRepository; | ||
import com.gg.server.admin.pchange.exception.PChangeNotExistException; | ||
import com.gg.server.admin.season.data.SeasonAdminRepository; | ||
import com.gg.server.admin.team.data.TeamUserAdminRepository; | ||
import com.gg.server.admin.user.data.UserAdminRepository; | ||
import com.gg.server.domain.game.data.Game; | ||
import com.gg.server.domain.game.dto.GameTeamUser; | ||
import com.gg.server.domain.game.exception.GameNotExistException; | ||
import com.gg.server.domain.game.type.StatusType; | ||
import com.gg.server.domain.match.data.RedisMatchUserRepository; | ||
import com.gg.server.domain.pchange.data.PChange; | ||
import com.gg.server.domain.pchange.data.PChangeRepository; | ||
|
||
import com.gg.server.domain.rank.redis.RankRedisService; | ||
import com.gg.server.domain.season.data.Season; | ||
import com.gg.server.domain.season.exception.SeasonNotFoundException; | ||
import com.gg.server.domain.team.data.TeamUser; | ||
import com.gg.server.domain.user.data.User; | ||
import com.gg.server.domain.user.exception.UserNotFoundException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.cache.annotation.CacheEvict; | ||
import org.springframework.cache.annotation.Caching; | ||
import org.springframework.data.domain.*; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class GameAdminService { | ||
|
||
private final GameAdminRepository gameAdminRepository; | ||
private final SeasonAdminRepository seasonAdminRepository; | ||
private final UserAdminRepository userAdminRepository; | ||
private final PChangeRepository pChangeRepository; | ||
private final PChangeAdminRepository pChangeAdminRepository; | ||
private final RankRedisService rankRedisService; | ||
private final TeamUserAdminRepository teamUserAdminRepository; | ||
private final RedisMatchUserRepository redisMatchUserRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public GameLogListAdminResponseDto findAllGamesByAdmin(Pageable pageable) { | ||
Page<Game> gamePage = gameAdminRepository.findAll(pageable); //모든 게임 정보 가져오기 | ||
return new GameLogListAdminResponseDto(getGameLogList(gamePage.getContent().stream().map(Game::getId).collect(Collectors.toList())), gamePage.getTotalPages()); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public GameLogListAdminResponseDto findGamesBySeasonId(Long seasonId, Pageable pageable){ | ||
Season season = seasonAdminRepository.findById(seasonId).orElseThrow(()-> new SeasonNotFoundException()); | ||
Page<Game> games = gameAdminRepository.findBySeason(pageable, season); //시즌 id로 게임들 찾아오기 | ||
return new GameLogListAdminResponseDto(getGameLogList(games.getContent().stream().map(Game::getId).collect(Collectors.toList())), games.getTotalPages()); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public List<GameLogAdminDto> getGameLogList(List<Long> gameIdList){ | ||
List<GameTeamUser> teamViews = gameAdminRepository.findTeamsByGameIsIn(gameIdList); | ||
return teamViews.stream().map(GameLogAdminDto::new).collect(Collectors.toList()); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public GameLogListAdminResponseDto findGamesByIntraId(String intraId, Pageable pageable){ | ||
User user = userAdminRepository.findByIntraId(intraId).orElseThrow(UserNotFoundException::new); | ||
List<PChange> pChangeList = pChangeRepository.findAllByUserId(user.getId()); | ||
List<Game> gameList = new ArrayList<>(); | ||
|
||
for(PChange pChange : pChangeList) | ||
gameList.add(pChange.getGame()); | ||
|
||
int start = (int)pageable.getOffset(); | ||
int end = Math.min((start + pageable.getPageSize()), gameList.size()); | ||
Page<Game> games = new PageImpl<>(gameList.subList(start, end), pageable, gameList.size()); | ||
return new GameLogListAdminResponseDto(getGameLogList(games.getContent().stream().map(Game::getId).collect(Collectors.toList())), games.getTotalPages()); | ||
} | ||
|
||
@Transactional | ||
@Caching(evict = { | ||
@CacheEvict(value = "rankGameListByIntra", allEntries = true), | ||
@CacheEvict(value = "rankGameList", allEntries = true), | ||
@CacheEvict(value = "allGameList", allEntries = true), | ||
@CacheEvict(value = "allGameListByUser", allEntries = true) | ||
}) | ||
public void rankResultEdit(RankGamePPPModifyReqDto reqDto, Long gameId) { | ||
// 게임이 두명 다 가장 마지막 게임인지 확인 (그 game에 해당하는 팀이 맞는지 확인) | ||
List<TeamUser> teamUsers = teamUserAdminRepository.findUsersByTeamIdIn(List.of(reqDto.getTeam1Id(), reqDto.getTeam2Id())); | ||
Game game = gameAdminRepository.findById(gameId) | ||
.orElseThrow(GameNotExistException::new); | ||
Season season = seasonAdminRepository.findById(game.getSeason().getId()) | ||
.orElseThrow(SeasonNotFoundException::new); | ||
if (!isRecentlyGame(teamUsers, gameId) || EnrollSlots(teamUsers)) { | ||
throw new NotRecentlyGameException(); | ||
} | ||
// pchange 가져와서 rank ppp 이전 값을 가지고 새 점수를 바탕으로 다시 계산 | ||
for (TeamUser teamUser : | ||
teamUsers) { | ||
List<PChange> pChanges = pChangeAdminRepository.findByTeamUser(teamUser.getUser().getId()); | ||
if (!pChanges.get(0).getGame().getId().equals(gameId)) { | ||
throw new PChangeNotExistException(); | ||
} | ||
rollbackGameResult(reqDto, season, teamUser, pChanges); | ||
teamUserAdminRepository.flush(); | ||
pChangeAdminRepository.delete(pChanges.get(0)); | ||
} | ||
rankRedisService.updateRankRedis(teamUsers.get(0), teamUsers.get(1), game); | ||
} | ||
|
||
private void rollbackGameResult(RankGamePPPModifyReqDto reqDto, Season season, TeamUser teamUser, List<PChange> pChanges) { | ||
// pchange ppp도 update | ||
// rankredis 에 ppp 다시 반영 | ||
// rank zset 도 update | ||
// 이전 ppp, exp 되돌리기 | ||
// rank data 에 있는 ppp 되돌리기 | ||
if (pChanges.size() == 1) { | ||
rankRedisService.rollbackRank(teamUser, season.getStartPpp(), season.getId()); | ||
teamUser.getUser().updateExp(0); | ||
} else { | ||
rankRedisService.rollbackRank(teamUser, pChanges.get(1).getPppResult(), season.getId()); | ||
teamUser.getUser().updateExp(pChanges.get(1).getExp()); | ||
} | ||
if (teamUser.getTeam().getId().equals(reqDto.getTeam1Id())) { | ||
teamUser.getTeam().updateScore(reqDto.getTeam1Score(), reqDto.getTeam1Score() > reqDto.getTeam2Score()); | ||
} else if (teamUser.getTeam().getId().equals(reqDto.getTeam2Id())) { | ||
teamUser.getTeam().updateScore(reqDto.getTeam2Score(), reqDto.getTeam2Score() > reqDto.getTeam1Score()); | ||
} | ||
} | ||
|
||
private Boolean isRecentlyGame(List<TeamUser> teamUsers, Long gameId) { | ||
for (TeamUser teamUser : teamUsers) { | ||
List<PChange> pChanges = pChangeAdminRepository.findByTeamUser(teamUser.getUser().getId()); | ||
if (!pChanges.get(0).getGame().getId().equals(gameId)) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
private Boolean EnrollSlots(List<TeamUser> teamUsers) { | ||
for (TeamUser teamUser : teamUsers) { | ||
Long userId = teamUser.getUser().getId(); | ||
if (redisMatchUserRepository.countMatchTime(userId) > 0) { | ||
return true; | ||
} | ||
if (gameAdminRepository.findByStatusTypeAndUserId(StatusType.BEFORE, userId).isPresent()) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 20 additions & 20 deletions
40
src/main/java/com/gg/server/domain/team/data/TeamUserRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
package com.gg.server.domain.team.data; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
public interface TeamUserRepository extends JpaRepository<TeamUser, Long> { | ||
@Query(value = "select team_user.id, team_user.team_id, team_user.user_id from team, team_user " + | ||
"where team.game_id =:gid and team.id = team_user.team_id", nativeQuery = true) | ||
List<TeamUser> findAllByGameId(@Param("gid")Long gid); | ||
|
||
@Query(value = "select count(*) from game, team, team_user " + | ||
"where game.start_time >= :today and team_user.team_id = team.id and team_user.user_id = :userId " + | ||
"and team.game_id = game.id and game.status = 'END'", nativeQuery = true) | ||
Integer findByDateAndUser(@Param("today")LocalDateTime today, @Param("userId") Long userId); | ||
|
||
} | ||
package com.gg.server.domain.team.data; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
public interface TeamUserRepository extends JpaRepository<TeamUser, Long> { | ||
@Query(value = "select team_user.id, team_user.team_id, team_user.user_id from team, team_user " + | ||
"where team.game_id =:gid and team.id = team_user.team_id", nativeQuery = true) | ||
List<TeamUser> findAllByGameId(@Param("gid")Long gid); | ||
|
||
@Query(value = "select count(*) from game, team, team_user " + | ||
"where game.start_time >= :today and team_user.team_id = team.id and team_user.user_id = :userId " + | ||
"and team.game_id = game.id and game.status = 'END'", nativeQuery = true) | ||
Integer findByDateAndUser(@Param("today")LocalDateTime today, @Param("userId") Long userId); | ||
|
||
} |