Skip to content

Commit

Permalink
🐛 [Fix] GameStyleIdList가 null일 때 예외처리
Browse files Browse the repository at this point in the history
  • Loading branch information
rimi3226 committed Oct 6, 2024
1 parent af2990a commit a3cd3a1
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import com.gamegoo.apiPayload.ApiResponse;
import com.gamegoo.apiPayload.code.status.ErrorStatus;
import com.gamegoo.apiPayload.exception.handler.MatchingHandler;
import com.gamegoo.converter.MatchingConverter;
import com.gamegoo.domain.matching.MatchingType;
import com.gamegoo.domain.member.Member;
import com.gamegoo.dto.matching.MatchingRequest;
import com.gamegoo.dto.matching.MatchingResponse;
import com.gamegoo.dto.matching.MemberPriority;
import com.gamegoo.service.chat.ChatCommandService;
import com.gamegoo.service.matching.MatchingService;
import com.gamegoo.util.JWTUtil;
Expand All @@ -14,8 +17,12 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import com.gamegoo.service.member.ProfileService;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequiredArgsConstructor
Expand All @@ -25,6 +32,8 @@ public class MatchingController {

private final MatchingService matchingService;
private final ChatCommandService chatCommandService;
private final ProfileService profileService;


@PostMapping("/priority")
@Operation(summary = "우선순위 계산 및 매칭 기록을 저장하는 API 입니다.", description =
Expand All @@ -48,13 +57,24 @@ public ApiResponse<MatchingResponse.PriorityMatchingResponseDTO> saveMatching(
throw new MatchingHandler(ErrorStatus.MATCHING_TYPE_BAD_REQUEST);
}

// 우선순위 계산
MatchingResponse.PriorityMatchingResponseDTO priorityMatchingResponseDTO = matchingService.getPriorityLists(
request, id);
// 우선순위 계산 리스트를 Service로부터 가져옴
Map<String, List<MemberPriority>> priorityLists = matchingService.calculatePriorityList(request, id);

// 각 우선순위 리스트 추출
List<MemberPriority> myPriorityList = priorityLists.get("myPriorityList");
List<MemberPriority> otherPriorityList = priorityLists.get("otherPriorityList");

// DB에 기록하기
matchingService.save(request, id);
return ApiResponse.onSuccess(priorityMatchingResponseDTO);

// gameStyleList 가져오기
Member member = profileService.findMember(id);
List<String> gameStyleList = profileService.getGameStyleList(member);


// ApiResponse로 변환하여 반환
return ApiResponse.onSuccess(MatchingConverter.toPriorityMatchingResponseDTO(
member, request, myPriorityList, otherPriorityList, gameStyleList));
}

@PatchMapping("/status")
Expand Down
46 changes: 46 additions & 0 deletions src/main/java/com/gamegoo/converter/MatchingConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.gamegoo.converter;

import com.gamegoo.dto.matching.MatchingRequest;
import com.gamegoo.dto.matching.MatchingResponse;
import com.gamegoo.domain.member.Member;
import com.gamegoo.dto.matching.MemberPriority;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class MatchingConverter {

// 매칭 요청에 대한 응답 DTO 생성
public static MatchingResponse.PriorityMatchingResponseDTO toPriorityMatchingResponseDTO(
Member member,
MatchingRequest.InitializingMatchingRequestDTO request,
List<MemberPriority> myPriorityList,
List<MemberPriority> otherPriorityList,
List<String> gameStyleList) {

// 내 매칭 기록 DTO 생성
MatchingResponse.matchingRequestResponseDTO myMatchingInfo = MatchingResponse.matchingRequestResponseDTO.builder()
.memberId(member.getId())
.gameName(member.getGameName())
.tag(member.getTag())
.tier(member.getTier())
.rank(member.getRank())
.mannerLevel(member.getMannerLevel())
.profileImg(member.getProfileImage())
.gameMode(request.getGameMode())
.mainPosition(request.getMainP())
.subPosition(request.getSubP())
.wantPosition(request.getWantP())
.mike(request.getMike())
.gameStyleList(gameStyleList)
.build();

// 최종 DTO 반환
return MatchingResponse.PriorityMatchingResponseDTO.builder()
.myPriorityList(myPriorityList)
.otherPriorityList(otherPriorityList)
.myMatchingInfo(myMatchingInfo)
.build();
}
}
1 change: 1 addition & 0 deletions src/main/java/com/gamegoo/converter/MemberConverter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gamegoo.converter;

import com.gamegoo.domain.friend.Friend;
//import com.gamegoo.domain.member.Member;
import com.gamegoo.domain.member.Member;
import com.gamegoo.dto.member.MemberResponse;
import com.gamegoo.dto.member.MemberResponse.friendInfoDTO;
Expand Down
86 changes: 31 additions & 55 deletions src/main/java/com/gamegoo/service/matching/MatchingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
import com.gamegoo.repository.member.MemberRepository;
import com.gamegoo.service.member.ProfileService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import javax.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -37,83 +36,62 @@ public class MatchingService {
*
* @param request
* @param id
* @return
* @throws MemberHandler
*/
public MatchingResponse.PriorityMatchingResponseDTO getPriorityLists(
MatchingRequest.InitializingMatchingRequestDTO request, Long id) throws MemberHandler {
// 우선순위 계산
public Map<String, List<MemberPriority>> calculatePriorityList(
MatchingRequest.InitializingMatchingRequestDTO request, Long id) {

// 게임 모드가 같고, 5분동안 매칭이 되지 않은 매칭 기록 가져오기
LocalDateTime fiveMinutesAgo = LocalDateTime.now().minusMinutes(5);
List<MatchingRecord> matchingRecords = matchingRecordRepository.findTopByCreatedAtAfterAndStatusAndGameModeGroupByMemberId(
fiveMinutesAgo, MatchingStatus.PENDING, request.getGameMode());
fiveMinutesAgo, MatchingStatus.PENDING, request.getGameMode());

Member member = profileService.findMember(id);

List<MemberPriority> otherPriorityList = new ArrayList<>();
List<MemberPriority> myPriorityList = new ArrayList<>();

MatchingRecord myMatchingRecord = MatchingRecord.builder()
.member(member)
.mike(request.getMike())
.rank(member.getRank())
.tier(member.getTier())
.winRate(member.getWinRate())
.status(MatchingStatus.PENDING)
.matchingType(MatchingType.valueOf(request.getMatchingType()))
.mainPosition(request.getMainP())
.subPosition(request.getSubP())
.wantPosition(request.getWantP())
.mannerLevel(member.getMannerLevel())
.gameMode(request.getGameMode())
.targetMember(null)
.build();
.member(member)
.mike(request.getMike())
.rank(member.getRank())
.tier(member.getTier())
.winRate(member.getWinRate())
.status(MatchingStatus.PENDING)
.matchingType(MatchingType.valueOf(request.getMatchingType()))
.mainPosition(request.getMainP())
.subPosition(request.getSubP())
.wantPosition(request.getWantP())
.mannerLevel(member.getMannerLevel())
.gameMode(request.getGameMode())
.targetMember(null)
.build();

// 우선순위 리스트 초기화
List<MemberPriority> myPriorityList = new ArrayList<>();
List<MemberPriority> otherPriorityList = new ArrayList<>();

// 우선순위 계산하기
for (MatchingRecord record : matchingRecords) {
Long otherMemberId = record.getMember().getId();

// 서로 차단한 사용자일 경우 우선순위 계산 X
if (blockRepository.existsByBlockerMemberAndBlockedMember(member, record.getMember())) {
continue;
}

if (!id.equals(otherMemberId)) {
int otherPriority = calculatePriority(myMatchingRecord, record);
myPriorityList.add(new MemberPriority(otherMemberId, otherPriority));

int myPriority = calculatePriority(record, myMatchingRecord);
otherPriorityList.add(new MemberPriority(record.getMember().getId(), myPriority));
}


}

// 내 매칭 기록 dto 생성
MatchingResponse.matchingRequestResponseDTO myMatchingInfo = matchingRequestResponseDTO.builder()
.memberId(member.getId())
.gameName(member.getGameName())
.tag(member.getTag())
.tier(member.getTier())
.rank(member.getRank())
.mannerLevel(member.getMannerLevel())
.profileImg(member.getProfileImage())
.gameMode(request.getGameMode())
.mainPosition(request.getMainP())
.subPosition(request.getSubP())
.wantPosition(request.getWantP())
.mike(request.getMike())
.gameStyleList(profileService.getGameStyleList(member))
.build();
// 두 리스트를 Map으로 반환
Map<String, List<MemberPriority>> priorityLists = new HashMap<>();
priorityLists.put("myPriorityList", myPriorityList);
priorityLists.put("otherPriorityList", otherPriorityList);

return MatchingResponse.PriorityMatchingResponseDTO.builder()
.myPriorityList(myPriorityList)
.otherPriorityList(otherPriorityList)
.myMatchingInfo(myMatchingInfo)
.build();
return priorityLists;
}



/**
* 우선순위 계산
*
Expand Down Expand Up @@ -350,9 +328,8 @@ public void save(MatchingRequest.InitializingMatchingRequestDTO request, Long id
member.updateMemberFromMatching(request.getMainP(), request.getSubP(),
request.getMike());
}
if (request.getGameStyleIdList() != null) {
profileService.addMemberGameStyles(request.getGameStyleIdList(), member.getId());
}

profileService.addMemberGameStyles(request.getGameStyleIdList(), member.getId());

matchingRecordRepository.save(matchingRecord);
memberRepository.save(member);
Expand Down Expand Up @@ -502,7 +479,6 @@ public MatchingResponse.matchingFoundResponseDTO foundMatching(Long memberId,
*
* @param memberId
* @param targetMemberId
* @return
*/
@Transactional
public void successMatching(Long memberId, Long targetMemberId, Integer gameMode) {
Expand Down
48 changes: 31 additions & 17 deletions src/main/java/com/gamegoo/service/member/ProfileService.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,32 @@ public class ProfileService {
public List<MemberGameStyle> addMemberGameStyles(List<Long> gameStyleIdList, Long memberId) {
// 회원 엔티티 조회
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));

// 요청으로 온 gameStyleId로 GameStyle 엔티티 리스트를 생성 및 검증
List<GameStyle> requestGameStyleList = new ArrayList<>();
if (gameStyleIdList != null && !gameStyleIdList.isEmpty()) {
requestGameStyleList = gameStyleIdList.stream()
.map(gameStyleId -> gameStyleRepository.findById(gameStyleId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.GAMESTYLE_NOT_FOUND)))
.toList();
}

// 현재 DB에 저장된 MemberGameStyle 목록을 가져옴
List<MemberGameStyle> currentMemberGameStyleList = new ArrayList<>(member.getMemberGameStyleList());

// 요청으로 온 gamestyleId로 GameStyle 엔티티 리스트를 생성 및 gamestyleId에 해당하는 gamestyle이 db에 존재하는지 검증
List<GameStyle> requestGameStyleList = gameStyleIdList.stream()
.map(gameStyleId -> gameStyleRepository.findById(gameStyleId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.GAMESTYLE_NOT_FOUND)))
.toList();
// 요청된 gameStyleId가 빈 리스트인 경우, 모든 MemberGameStyle을 삭제
if (requestGameStyleList.isEmpty()) {
for (MemberGameStyle memberGameStyle : currentMemberGameStyleList) {
memberGameStyle.removeMember(member); // 양방향 연관관계 제거
memberGameStyleRepository.delete(memberGameStyle);
}
return new ArrayList<>(); // 빈 리스트 반환
}

// db에는 존재하나, request에는 존재하지 않는 gameStyle을 삭제
// DB에는 존재하나, 요청에는 없는 gameStyle 삭제
List<MemberGameStyle> toRemove = new ArrayList<>();
for (MemberGameStyle memberGameStyle : member.getMemberGameStyleList()) {
for (MemberGameStyle memberGameStyle : currentMemberGameStyleList) {
if (!requestGameStyleList.contains(memberGameStyle.getGameStyle())) {
toRemove.add(memberGameStyle);
}
Expand All @@ -73,16 +88,16 @@ public List<MemberGameStyle> addMemberGameStyles(List<Long> gameStyleIdList, Lon
memberGameStyleRepository.delete(memberGameStyle);
}

// request에는 존재하나, db에는 존재하지 않는 gameStyle을 추가
List<GameStyle> currentGameStyleList = member.getMemberGameStyleList().stream()
.map(MemberGameStyle::getGameStyle)
.toList();
// 요청에는 있으나, DB에 없는 gameStyle 추가
List<GameStyle> currentGameStyleList = currentMemberGameStyleList.stream()
.map(MemberGameStyle::getGameStyle)
.toList();

for (GameStyle reqGameStyle : requestGameStyleList) {
if (!currentGameStyleList.contains(reqGameStyle)) {
MemberGameStyle memberGameStyle = MemberGameStyle.builder()
.gameStyle(reqGameStyle)
.build();
.gameStyle(reqGameStyle)
.build();
memberGameStyle.setMember(member); // 양방향 연관관계 매핑
memberGameStyleRepository.save(memberGameStyle);
}
Expand All @@ -91,6 +106,7 @@ public List<MemberGameStyle> addMemberGameStyles(List<Long> gameStyleIdList, Lon
return member.getMemberGameStyleList();
}


/**
* 회원 탈퇴 처리
*
Expand All @@ -107,9 +123,7 @@ public void deleteMember(Long userId) {
// 해당 회원이 속한 모든 채팅방에서 퇴장 처리
List<MemberChatroom> allActiveMemberChatroom = memberChatroomRepository.findAllActiveMemberChatroom(
member.getId());
allActiveMemberChatroom.forEach(memberChatroom -> {
memberChatroom.updateLastJoinDate(null);
});
allActiveMemberChatroom.forEach(memberChatroom -> memberChatroom.updateLastJoinDate(null));

// 해당 회원이 보낸 모든 친구 요청 취소 처리
List<FriendRequests> sendFriendRequestsList = friendRequestsRepository.findAllByFromMemberAndStatus(
Expand Down

0 comments on commit a3cd3a1

Please sign in to comment.