Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/160] 매너평가 관련 추가 구현 #162

Merged
merged 7 commits into from
Aug 13, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public ApiResponse<MannerResponse.badMannerKeywordResponseDTO> getBadMannerKeywo
}

@GetMapping()
@Operation(summary = "내가 받은 매너 평가 조회 API", description = "회원의 매너레벨과 회원이 받은 매너 평가를 조회하는 API 입니다.")
@Operation(summary = "내가 받은 매너 평가 조회 API", description = "회원의 매너레벨과 회원이 받은 키워드를 조회하는 API 입니다.")
public ApiResponse<MannerResponse.myMannerResponseDTO> getMyManner(){

Long memberId = JWTUtil.getCurrentUserId();
Expand All @@ -128,4 +128,14 @@ public ApiResponse<MannerResponse.myMannerResponseDTO> getMyManner(){

return ApiResponse.onSuccess(result);
}

@GetMapping("/{memberId}")
@Operation(summary = "다른 유저의 매너 평가 조회 API", description = "다른 유저의 매너레벨과 키워드를 조회하는 API 입니다.")
@Parameter(name = "memberId", description = "매너 평가 조회 대상의 id 입니다.")
public ApiResponse<MannerResponse.mannerByIdResponseDTO> getMannerById(@PathVariable(name = "memberId") Long targetMemberId){

MannerResponse.mannerByIdResponseDTO result = mannerService.getMannerById(targetMemberId);

return ApiResponse.onSuccess(result);
}
}
3 changes: 3 additions & 0 deletions src/main/java/com/gamegoo/dto/board/BoardResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -123,6 +125,7 @@ public static class boardByIdResponseForMemberDTO {
String gameName;
String tag;
Integer mannerLevel;
List<MannerResponse.mannerKeywordDTO> mannerKeywords;
Tier tier;
Boolean mike;
List<Long> championList;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/gamegoo/dto/manner/MannerResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ public static class myMannerResponseDTO{
Integer mannerLevel;
List<mannerKeywordDTO> mannerKeywords;
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class mannerByIdResponseDTO{
Long memberId;
Integer mannerLevel;
List<mannerKeywordDTO> mannerKeywords;
}

@Getter
@Builder
@NoArgsConstructor
Expand Down
14 changes: 10 additions & 4 deletions src/main/java/com/gamegoo/service/board/BoardService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -335,6 +336,10 @@ public BoardResponse.boardByIdResponseForMemberDTO getBoardByIdForMember(Long bo

Member poster = board.getMember();

List<MannerResponse.mannerKeywordDTO> mannerKeywordDTOs = mannerService.mannerKeyword(poster);

List<MannerResponse.mannerKeywordDTO> mannerKeywords = mannerService.sortMannerKeywordDTOs(mannerKeywordDTOs);

return BoardResponse.boardByIdResponseForMemberDTO.builder()
.boardId(board.getId())
.memberId(poster.getId())
Expand All @@ -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()))
Expand Down
160 changes: 150 additions & 10 deletions src/main/java/com/gamegoo/service/manner/MannerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -310,19 +310,19 @@ public MannerRating update(MannerRequest.mannerUpdateDTO request, Long memberId,
}

// 매너점수를 산정하고 업데이트.
private int updateMannerScore(Member targetMember){
private int updateMannerScore(Member targetMember) {

// 매너평가 ID 조회
List<MannerRating> mannerRatings = targetMember.getMannerRatingList();

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()
Expand All @@ -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) {
Expand All @@ -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));

Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -524,10 +524,150 @@ public MannerResponse.myMannerResponseDTO getMyManner(Long memberId){
mannerKeywordDTOs.add(new MannerResponse.mannerKeywordDTO(false, i, count));
}

List<MannerResponse.mannerKeywordDTO> 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<MannerResponse.mannerKeywordDTO> mannerKeywordDTOs = mannerKeyword(targetMember);

List<MannerResponse.mannerKeywordDTO> mannerKeywords = sortMannerKeywordDTOs(mannerKeywordDTOs);

Integer mannerLevel = targetMember.getMannerLevel();
return MannerResponse.mannerByIdResponseDTO.builder()
.memberId(targetMember.getId())
.mannerLevel(mannerLevel)
.mannerKeywords(mannerKeywords)
.build();
}

public List<MannerResponse.mannerKeywordDTO> mannerKeyword(Member targetMember) {
// 매너평가 ID 조회
List<MannerRating> mannerRatings = targetMember.getMannerRatingList();

// 매너키워드 조회
List<MannerRating> positiveMannerRatings = mannerRatings.stream()
.filter(MannerRating::getIsPositive)
.collect(Collectors.toList());

// 각 매너키워드(1~6) 별 count 집계
List<Long> mannerKeywordIds = new ArrayList<>();

for (MannerRating positiveRating : positiveMannerRatings) {
List<MannerRatingKeyword> mannerRatingKeywords = positiveRating.getMannerRatingKeywordList();
for (MannerRatingKeyword mannerRatingKeyword : mannerRatingKeywords) {
mannerKeywordIds.add(mannerRatingKeyword.getMannerKeyword().getId());
}
}

Map<Integer, Integer> 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<MannerRating> negativeMannerRatings = mannerRatings.stream()
.filter(mannerRating -> !mannerRating.getIsPositive())
.collect(Collectors.toList());

// 각 비매너키워드(7~12) 별 count 집계
List<Long> badMannerKeywordIds = new ArrayList<>();

for (MannerRating negativeRating : negativeMannerRatings) {
List<MannerRatingKeyword> badMannerRatingKeywords = negativeRating.getMannerRatingKeywordList();
for (MannerRatingKeyword badMannerRatingKeyword : badMannerRatingKeywords) {
badMannerKeywordIds.add(badMannerRatingKeyword.getMannerKeyword().getId());
}
}

Map<Integer, Integer> 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<MannerResponse.mannerKeywordDTO> 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<MannerResponse.mannerKeywordDTO> sortMannerKeywordDTOs(List<MannerResponse.mannerKeywordDTO> mannerKeywordDTOs) {

// mannerKeywordId와 contents 값을 매핑
Map<Long, String> content = mannerKeywordRepository.findAll().stream()
.collect(Collectors.toMap(MannerKeyword::getId, MannerKeyword::getContents));

// Comparator 생성
// 우선 순위) 1. count 기준 내림차순, 2.contents 기준 숫자, 3.contents 기준 한글(ㄱㄴㄷ순) 정렬
Comparator<MannerResponse.mannerKeywordDTO> comparator = Comparator
.comparingInt(MannerResponse.mannerKeywordDTO::getCount).reversed() // count 내림차순
.thenComparing(dto -> {
String contents = content.get((long) dto.getMannerKeywordId());
return sortByContents(contents);
}); // contents 기준 정렬

// 매너키워드와 비매너키워드를 분리하여 각각 정렬
List<MannerResponse.mannerKeywordDTO> positiveKeywords = mannerKeywordDTOs.stream()
.filter(MannerResponse.mannerKeywordDTO::getIsPositive)
.sorted(comparator)
.collect(Collectors.toList());

List<MannerResponse.mannerKeywordDTO> negativeKeywords = mannerKeywordDTOs.stream()
.filter(dto -> !dto.getIsPositive())
.sorted(comparator)
.collect(Collectors.toList());

// 정렬된 매너키워드와 비매너키워드를 합치기
List<MannerResponse.mannerKeywordDTO> 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;
}
}
}
Loading