diff --git a/src/main/java/com/gamegoo/controller/mannner/MannerController.java b/src/main/java/com/gamegoo/controller/mannner/MannerController.java index 1bf8ec09..c2c55004 100644 --- a/src/main/java/com/gamegoo/controller/mannner/MannerController.java +++ b/src/main/java/com/gamegoo/controller/mannner/MannerController.java @@ -119,7 +119,7 @@ public ApiResponse getBadMannerKeywo } @GetMapping() - @Operation(summary = "내가 받은 매너 평가 조회 API", description = "회원의 매너레벨과 회원이 받은 매너 평가를 조회하는 API 입니다.") + @Operation(summary = "내가 받은 매너 평가 조회 API", description = "회원의 매너레벨과 회원이 받은 키워드를 조회하는 API 입니다.") public ApiResponse getMyManner(){ Long memberId = JWTUtil.getCurrentUserId(); @@ -128,4 +128,14 @@ public ApiResponse getMyManner(){ return ApiResponse.onSuccess(result); } + + @GetMapping("/{memberId}") + @Operation(summary = "다른 유저의 매너 평가 조회 API", description = "다른 유저의 매너레벨과 키워드를 조회하는 API 입니다.") + @Parameter(name = "memberId", description = "매너 평가 조회 대상의 id 입니다.") + public ApiResponse getMannerById(@PathVariable(name = "memberId") Long targetMemberId){ + + MannerResponse.mannerByIdResponseDTO result = mannerService.getMannerById(targetMemberId); + + return ApiResponse.onSuccess(result); + } } diff --git a/src/main/java/com/gamegoo/dto/board/BoardResponse.java b/src/main/java/com/gamegoo/dto/board/BoardResponse.java index 408c2c06..09f78810 100644 --- a/src/main/java/com/gamegoo/dto/board/BoardResponse.java +++ b/src/main/java/com/gamegoo/dto/board/BoardResponse.java @@ -3,6 +3,8 @@ import com.gamegoo.domain.member.Tier; import java.time.LocalDateTime; import java.util.List; + +import com.gamegoo.dto.manner.MannerResponse; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -123,6 +125,7 @@ public static class boardByIdResponseForMemberDTO { String gameName; String tag; Integer mannerLevel; + List mannerKeywords; Tier tier; Boolean mike; List championList; diff --git a/src/main/java/com/gamegoo/dto/manner/MannerResponse.java b/src/main/java/com/gamegoo/dto/manner/MannerResponse.java index 5d814cf6..c77f7459 100644 --- a/src/main/java/com/gamegoo/dto/manner/MannerResponse.java +++ b/src/main/java/com/gamegoo/dto/manner/MannerResponse.java @@ -53,6 +53,17 @@ public static class myMannerResponseDTO{ Integer mannerLevel; List mannerKeywords; } + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class mannerByIdResponseDTO{ + Long memberId; + Integer mannerLevel; + List mannerKeywords; + } + @Getter @Builder @NoArgsConstructor diff --git a/src/main/java/com/gamegoo/service/board/BoardService.java b/src/main/java/com/gamegoo/service/board/BoardService.java index 038f8790..1b71b56d 100644 --- a/src/main/java/com/gamegoo/service/board/BoardService.java +++ b/src/main/java/com/gamegoo/service/board/BoardService.java @@ -12,16 +12,15 @@ import com.gamegoo.domain.member.Tier; import com.gamegoo.dto.board.BoardRequest; import com.gamegoo.dto.board.BoardResponse; +import com.gamegoo.dto.manner.MannerResponse; import com.gamegoo.repository.board.BoardGameStyleRepository; import com.gamegoo.repository.board.BoardRepository; import com.gamegoo.repository.member.GameStyleRepository; import com.gamegoo.repository.member.MemberRepository; +import com.gamegoo.service.manner.MannerService; import com.gamegoo.service.member.FriendService; import com.gamegoo.util.MemberUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; @@ -37,6 +36,8 @@ public class BoardService { @Autowired private FriendService friendService; + @Autowired + private MannerService mannerService; private final MemberRepository memberRepository; private final BoardRepository boardRepository; private final GameStyleRepository gameStyleRepository; @@ -335,6 +336,10 @@ public BoardResponse.boardByIdResponseForMemberDTO getBoardByIdForMember(Long bo Member poster = board.getMember(); + List mannerKeywordDTOs = mannerService.mannerKeyword(poster); + + List mannerKeywords = mannerService.sortMannerKeywordDTOs(mannerKeywordDTOs); + return BoardResponse.boardByIdResponseForMemberDTO.builder() .boardId(board.getId()) .memberId(poster.getId()) @@ -346,6 +351,7 @@ public BoardResponse.boardByIdResponseForMemberDTO getBoardByIdForMember(Long bo .gameName(poster.getGameName()) .tag(poster.getTag()) .mannerLevel(poster.getMannerLevel()) + .mannerKeywords(mannerKeywords) .tier(poster.getTier()) .championList(poster.getMemberChampionList().stream().map(MemberChampion::getId) .collect(Collectors.toList())) diff --git a/src/main/java/com/gamegoo/service/manner/MannerService.java b/src/main/java/com/gamegoo/service/manner/MannerService.java index 3c37a502..053554d5 100644 --- a/src/main/java/com/gamegoo/service/manner/MannerService.java +++ b/src/main/java/com/gamegoo/service/manner/MannerService.java @@ -310,7 +310,7 @@ public MannerRating update(MannerRequest.mannerUpdateDTO request, Long memberId, } // 매너점수를 산정하고 업데이트. - private int updateMannerScore(Member targetMember){ + private int updateMannerScore(Member targetMember) { // 매너평가 ID 조회 List mannerRatings = targetMember.getMannerRatingList(); @@ -318,11 +318,11 @@ private int updateMannerScore(Member targetMember){ int totalCount; // 매너 평가 + 비매너 평가를 처음 받은 회원 - if (mannerRatings.size()==1){ + if (mannerRatings.size() == 1) { if (mannerRatings.get(0).getIsPositive()) { totalCount = mannerRatings.get(0).getMannerRatingKeywordList().size(); } else { - totalCount = (mannerRatings.get(0).getMannerRatingKeywordList().size())*-2; + totalCount = (mannerRatings.get(0).getMannerRatingKeywordList().size()) * -2; } } else { int positiveCount = mannerRatings.stream() @@ -331,20 +331,20 @@ private int updateMannerScore(Member targetMember){ .collect(Collectors.toList()) .size(); - int negativeCount = mannerRatings.stream() + int negativeCount = mannerRatings.stream() .filter(mannerRating -> !mannerRating.getIsPositive()) .flatMap(mannerRating -> mannerRating.getMannerRatingKeywordList().stream()) .collect(Collectors.toList()) .size(); - totalCount = positiveCount + (negativeCount*-2); + totalCount = positiveCount + (negativeCount * -2); } return totalCount; } // 매너레벨 결정 - private int mannerLevel(int mannerCount){ + private int mannerLevel(int mannerCount) { if (mannerCount < 10) { return 1; } else if (mannerCount < 20) { @@ -360,7 +360,7 @@ private int mannerLevel(int mannerCount){ // 매너평가 조회 @Transactional(readOnly = true) - public MannerResponse.mannerKeywordResponseDTO getMannerKeyword(Long memberId, Long targetMemberId){ + public MannerResponse.mannerKeywordResponseDTO getMannerKeyword(Long memberId, Long targetMemberId) { Member member = memberRepository.findById(memberId).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); @@ -412,7 +412,7 @@ public MannerResponse.mannerKeywordResponseDTO getMannerKeyword(Long memberId, L // 비매너평가 조회 @Transactional(readOnly = true) - public MannerResponse.badMannerKeywordResponseDTO getBadMannerKeyword(Long memberId, Long targetMemberId){ + public MannerResponse.badMannerKeywordResponseDTO getBadMannerKeyword(Long memberId, Long targetMemberId) { Member member = memberRepository.findById(memberId).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); @@ -458,7 +458,7 @@ public MannerResponse.badMannerKeywordResponseDTO getBadMannerKeyword(Long membe // 내가 받은 매너 평가 조회 @Transactional(readOnly = true) - public MannerResponse.myMannerResponseDTO getMyManner(Long memberId){ + public MannerResponse.myMannerResponseDTO getMyManner(Long memberId) { Member member = memberRepository.findById(memberId).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); @@ -524,10 +524,150 @@ public MannerResponse.myMannerResponseDTO getMyManner(Long memberId){ mannerKeywordDTOs.add(new MannerResponse.mannerKeywordDTO(false, i, count)); } + List mannerKeywords = sortMannerKeywordDTOs(mannerKeywordDTOs); + Integer mannerLevel = member.getMannerLevel(); return MannerResponse.myMannerResponseDTO.builder() .mannerLevel(mannerLevel) - .mannerKeywords(mannerKeywordDTOs) + .mannerKeywords(mannerKeywords) .build(); } + + // 대상 회원의 매너 평가 조회 + @Transactional(readOnly = true) + public MannerResponse.mannerByIdResponseDTO getMannerById(Long targetMemberId) { + + Member targetMember = memberRepository.findById(targetMemberId).orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND)); + + List mannerKeywordDTOs = mannerKeyword(targetMember); + + List mannerKeywords = sortMannerKeywordDTOs(mannerKeywordDTOs); + + Integer mannerLevel = targetMember.getMannerLevel(); + return MannerResponse.mannerByIdResponseDTO.builder() + .memberId(targetMember.getId()) + .mannerLevel(mannerLevel) + .mannerKeywords(mannerKeywords) + .build(); + } + + public List mannerKeyword(Member targetMember) { + // 매너평가 ID 조회 + List mannerRatings = targetMember.getMannerRatingList(); + + // 매너키워드 조회 + List positiveMannerRatings = mannerRatings.stream() + .filter(MannerRating::getIsPositive) + .collect(Collectors.toList()); + + // 각 매너키워드(1~6) 별 count 집계 + List mannerKeywordIds = new ArrayList<>(); + + for (MannerRating positiveRating : positiveMannerRatings) { + List mannerRatingKeywords = positiveRating.getMannerRatingKeywordList(); + for (MannerRatingKeyword mannerRatingKeyword : mannerRatingKeywords) { + mannerKeywordIds.add(mannerRatingKeyword.getMannerKeyword().getId()); + } + } + + Map mannerKeywordCountMap = new HashMap<>(); + for (long i = 1; i <= 6; i++) { + mannerKeywordCountMap.put((int) i, 0); // 초기화 + } + for (Long keywordId : mannerKeywordIds) { + mannerKeywordCountMap.put(keywordId.intValue(), mannerKeywordCountMap.getOrDefault(keywordId.intValue(), 0) + 1); + } + + // 비매너키워드 조회 + List negativeMannerRatings = mannerRatings.stream() + .filter(mannerRating -> !mannerRating.getIsPositive()) + .collect(Collectors.toList()); + + // 각 비매너키워드(7~12) 별 count 집계 + List badMannerKeywordIds = new ArrayList<>(); + + for (MannerRating negativeRating : negativeMannerRatings) { + List badMannerRatingKeywords = negativeRating.getMannerRatingKeywordList(); + for (MannerRatingKeyword badMannerRatingKeyword : badMannerRatingKeywords) { + badMannerKeywordIds.add(badMannerRatingKeyword.getMannerKeyword().getId()); + } + } + + Map badMannerKeywordCountMap = new HashMap<>(); + for (long i = 7; i <= 12; i++) { + badMannerKeywordCountMap.put((int) i, 0); // 초기화 + } + for (Long keywordId : badMannerKeywordIds) { + badMannerKeywordCountMap.put(keywordId.intValue(), badMannerKeywordCountMap.getOrDefault(keywordId.intValue(), 0) + 1); + } + + // 매너 키워드 DTO 생성 + List mannerKeywordDTOs = new ArrayList<>(); + for (int i = 1; i <= 6; i++) { + int count = mannerKeywordCountMap.getOrDefault(i, 0); + mannerKeywordDTOs.add(new MannerResponse.mannerKeywordDTO(true, i, count)); + } + + // 비매너 키워드 DTO 생성 + for (int i = 7; i <= 12; i++) { + int count = badMannerKeywordCountMap.getOrDefault(i, 0); + mannerKeywordDTOs.add(new MannerResponse.mannerKeywordDTO(false, i, count)); + } + + return mannerKeywordDTOs; + } + + // mannerKeywordDTOs(매너키워드,비매너키워드) 정렬 + public List sortMannerKeywordDTOs(List mannerKeywordDTOs) { + + // mannerKeywordId와 contents 값을 매핑 + Map content = mannerKeywordRepository.findAll().stream() + .collect(Collectors.toMap(MannerKeyword::getId, MannerKeyword::getContents)); + + // Comparator 생성 + // 우선 순위) 1. count 기준 내림차순, 2.contents 기준 숫자, 3.contents 기준 한글(ㄱㄴㄷ순) 정렬 + Comparator comparator = Comparator + .comparingInt(MannerResponse.mannerKeywordDTO::getCount).reversed() // count 내림차순 + .thenComparing(dto -> { + String contents = content.get((long) dto.getMannerKeywordId()); + return sortByContents(contents); + }); // contents 기준 정렬 + + // 매너키워드와 비매너키워드를 분리하여 각각 정렬 + List positiveKeywords = mannerKeywordDTOs.stream() + .filter(MannerResponse.mannerKeywordDTO::getIsPositive) + .sorted(comparator) + .collect(Collectors.toList()); + + List negativeKeywords = mannerKeywordDTOs.stream() + .filter(dto -> !dto.getIsPositive()) + .sorted(comparator) + .collect(Collectors.toList()); + + // 정렬된 매너키워드와 비매너키워드를 합치기 + List sortedKeywordDTOs = new ArrayList<>(); + sortedKeywordDTOs.addAll(positiveKeywords); + sortedKeywordDTOs.addAll(negativeKeywords); + + return sortedKeywordDTOs; + } + + // contents를 숫자 우선, 한글로 정렬하는 메서드 + public String sortByContents(String contents) { + if (contents == null || contents.isEmpty()) { + // contents가 null이거나 빈 문자열인 경우 가장 낮은 우선순위로 처리 + return "\uFFFF"; // ASCII의 가장 큰 값 + } + + // 첫 글자 가져오기 + char firstChar = contents.charAt(0); + + if (Character.isDigit(firstChar)) { + // 숫자일 경우, 우선순위 높음 (숫자를 기준으로 정렬) + return "0" + contents; // 숫자로 시작하는 경우를 우선순위가 높은 것으로 설정 + } else { + // 한글일 경우, 한글 정렬을 위해 `contents` 자체를 반환 + return contents; + } + } }