-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: (#515) 모든 멤버의 게시글 작성 개수 불러오기 메서드 추가 * feat: (#515) 모든 멤버의 투표 수 불러오기 메서드 추가 * feat: (#515) 랭킹 순위 구하는 클래스 구현 * feat: (#515) 내 랭킹 정보 조회 API 구현 * style: (#515) 주석 수정 * feat: (#515) swagger 추가 * style: (#515) final 키워드 추가 * refactor: (#515) 응답 변수 추출 * refactor: (#515) 메서드 이름 수정 및 순서 변경 * refactor: (#515) 클래스와 메서드 이름 수정 및 상수 추출 * refactor: (#515) 테스트 응답 검증 추가 및 변수 이름 수정 * refactor: (#515) 트랜잭션 어노테이션 추가 * refactor: (#515) score 반환 long으로 변환 * refactor: (#515) getter 메서드 명 수정 * test: (#515) assertAll 로 수정 * refactor: (#515) ranking 도메인 패키지로 변경 * refactor: (#515) 클래스 이름 및 메서드 이름 수정 * refactor: (#515) 클래스,메서드,변수명 수정 * refactor: (#515) 패키지 수정 * refactor: (#515) swagger 어노테이션 명세 수정 * refactor: (#515) uri 수정 * fix: (#515) uri 테스트 수정
- Loading branch information
Showing
16 changed files
with
490 additions
and
2 deletions.
There are no files selected for viewing
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
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
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
24 changes: 24 additions & 0 deletions
24
backend/src/main/java/com/votogether/domain/ranking/controller/RankingController.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 |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.votogether.domain.ranking.controller; | ||
|
||
import com.votogether.domain.member.entity.Member; | ||
import com.votogether.domain.ranking.dto.response.RankingResponse; | ||
import com.votogether.domain.ranking.service.RankingService; | ||
import com.votogether.global.jwt.Auth; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
public class RankingController implements RankingControllerDocs { | ||
|
||
private final RankingService rankingService; | ||
|
||
@GetMapping("/members/me/ranking/passion") | ||
public ResponseEntity<RankingResponse> getRanking(@Auth final Member member) { | ||
final RankingResponse response = rankingService.getPassionRanking(member); | ||
return ResponseEntity.ok(response); | ||
} | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
backend/src/main/java/com/votogether/domain/ranking/controller/RankingControllerDocs.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 |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.votogether.domain.ranking.controller; | ||
|
||
import com.votogether.domain.member.entity.Member; | ||
import com.votogether.domain.ranking.dto.response.RankingResponse; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import org.springframework.http.ResponseEntity; | ||
|
||
@Tag(name = "랭킹", description = "랭킹 API") | ||
public interface RankingControllerDocs { | ||
|
||
@Operation(summary = "나의 열정 랭킹 조회", description = "나의 열정 랭킹 정보를 조회한다.") | ||
@ApiResponse(responseCode = "200", description = "나의 열정 랭킹 정보 조회 성공") | ||
ResponseEntity<RankingResponse> getRanking(final Member member); | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
backend/src/main/java/com/votogether/domain/ranking/dto/response/RankingResponse.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 |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.votogether.domain.ranking.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
@Schema(description = "랭킹 정보 응답") | ||
public record RankingResponse( | ||
@Schema(description = "랭킹", example = "2") | ||
int ranking, | ||
|
||
@Schema(description = "닉네임", example = "유저") | ||
String nickname, | ||
|
||
@Schema(description = "게시글 수", example = "5") | ||
int postCount, | ||
|
||
@Schema(description = "투표 수", example = "6") | ||
int voteCount, | ||
|
||
@Schema(description = "점수", example = "31") | ||
long score | ||
) { | ||
} | ||
|
53 changes: 53 additions & 0 deletions
53
backend/src/main/java/com/votogether/domain/ranking/entity/PassionRankings.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 |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.votogether.domain.ranking.entity; | ||
|
||
import com.votogether.domain.member.entity.Member; | ||
import com.votogether.domain.ranking.entity.vo.PassionRecord; | ||
import java.util.Comparator; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class PassionRankings { | ||
|
||
private final Map<Member, Integer> rankings = new HashMap<>(); | ||
private final Map<Member, PassionRecord> passionBoard; | ||
|
||
public PassionRankings(final Map<Member, PassionRecord> passionBoard) { | ||
this.passionBoard = passionBoard; | ||
calculateRanking(); | ||
} | ||
|
||
private void calculateRanking() { | ||
final List<Member> members = passionBoard.entrySet().stream() | ||
.sorted(Comparator.comparingLong(entry -> -entry.getValue().calculateScore())) | ||
.map(s -> s.getKey()) | ||
.toList(); | ||
|
||
int currentRanking = 1; | ||
int previousRanking = -1; | ||
long previousScore = -1; | ||
for (Member member : members) { | ||
long currentScore = passionBoard.get(member).calculateScore(); | ||
int ranking = (currentScore == previousScore) ? previousRanking : currentRanking; | ||
|
||
this.rankings.put(member, ranking); | ||
|
||
previousRanking = ranking; | ||
previousScore = currentScore; | ||
currentRanking++; | ||
} | ||
} | ||
|
||
public long getScore(Member member) { | ||
return passionBoard.get(member).calculateScore(); | ||
} | ||
|
||
public int getRanking(Member member) { | ||
return rankings.get(member); | ||
} | ||
|
||
public PassionRecord getActivityRecord(Member member) { | ||
return passionBoard.get(member); | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
backend/src/main/java/com/votogether/domain/ranking/entity/vo/PassionRecord.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 |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.votogether.domain.ranking.entity.vo; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class PassionRecord { | ||
|
||
private static final int POST_WEIGHT = 5; | ||
private static final int VOTE_WEIGHT = 1; | ||
|
||
private final int postCount; | ||
private final int voteCount; | ||
|
||
public PassionRecord(int postCount, int voteCount) { | ||
this.postCount = postCount; | ||
this.voteCount = voteCount; | ||
} | ||
|
||
public long calculateScore() { | ||
return postCount * POST_WEIGHT + voteCount * VOTE_WEIGHT; | ||
} | ||
|
||
} |
51 changes: 51 additions & 0 deletions
51
backend/src/main/java/com/votogether/domain/ranking/service/RankingService.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 |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.votogether.domain.ranking.service; | ||
|
||
import com.votogether.domain.member.entity.Member; | ||
import com.votogether.domain.member.repository.MemberRepository; | ||
import com.votogether.domain.post.repository.PostRepository; | ||
import com.votogether.domain.ranking.dto.response.RankingResponse; | ||
import com.votogether.domain.ranking.entity.PassionRankings; | ||
import com.votogether.domain.ranking.entity.vo.PassionRecord; | ||
import com.votogether.domain.vote.repository.VoteRepository; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class RankingService { | ||
|
||
private final MemberRepository memberRepository; | ||
private final PostRepository postRepository; | ||
private final VoteRepository voteRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public RankingResponse getPassionRanking(final Member member) { | ||
final PassionRankings passionRankings = getPassionRankings(); | ||
return new RankingResponse( | ||
passionRankings.getRanking(member), | ||
member.getNickname(), | ||
passionRankings.getActivityRecord(member).getPostCount(), | ||
passionRankings.getActivityRecord(member).getVoteCount(), | ||
passionRankings.getScore(member) | ||
); | ||
} | ||
|
||
private PassionRankings getPassionRankings() { | ||
final List<Member> members = memberRepository.findAll(); | ||
final List<Integer> postCounts = postRepository.findCountsByMembers(members); | ||
final List<Integer> voteCounts = voteRepository.findCountsByMembers(members); | ||
|
||
final Map<Member, PassionRecord> passionBoard = new HashMap<>(); | ||
|
||
for (int i = 0; i < members.size(); i++) { | ||
passionBoard.put(members.get(i), new PassionRecord(postCounts.get(i), voteCounts.get(i))); | ||
} | ||
|
||
return new PassionRankings(passionBoard); | ||
} | ||
|
||
} |
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
85 changes: 85 additions & 0 deletions
85
backend/src/test/java/com/votogether/domain/member/entity/PassionRankingsTest.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 |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package com.votogether.domain.member.entity; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertAll; | ||
|
||
import com.votogether.domain.ranking.entity.PassionRankings; | ||
import com.votogether.domain.ranking.entity.vo.PassionRecord; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.test.util.ReflectionTestUtils; | ||
|
||
class PassionRankingsTest { | ||
|
||
@Nested | ||
@DisplayName("랭킹") | ||
class Ranking { | ||
|
||
@Test | ||
@DisplayName("랭킹 순위와 점수를 계산한다.") | ||
void calculateRank() { | ||
//given | ||
Member memberA = Member.builder().nickname("00").build(); | ||
Member memberB = Member.builder().nickname("11").build(); | ||
Member memberC = Member.builder().nickname("22").build(); | ||
ReflectionTestUtils.setField(memberA, "id", 1L); | ||
ReflectionTestUtils.setField(memberB, "id", 2L); | ||
ReflectionTestUtils.setField(memberC, "id", 3L); | ||
|
||
Map<Member, PassionRecord> board = new HashMap<>(); | ||
board.put(memberA, new PassionRecord(1, 1)); | ||
board.put(memberB, new PassionRecord(1, 2)); | ||
board.put(memberC, new PassionRecord(1, 3)); | ||
|
||
PassionRankings passionRankings = new PassionRankings(board); | ||
|
||
//when, then | ||
assertAll( | ||
() -> assertThat(passionRankings.getScore(memberA)).isEqualTo(6), | ||
() -> assertThat(passionRankings.getScore(memberB)).isEqualTo(7), | ||
() -> assertThat(passionRankings.getScore(memberC)).isEqualTo(8), | ||
() -> assertThat(passionRankings.getRanking(memberA)).isEqualTo(3), | ||
() -> assertThat(passionRankings.getRanking(memberB)).isEqualTo(2), | ||
() -> assertThat(passionRankings.getRanking(memberC)).isEqualTo(1) | ||
); | ||
} | ||
|
||
@Test | ||
@DisplayName("동순위가 존재하는 랭킹 순위와 점수를 계산한다.") | ||
void calculateRank1() { | ||
//given | ||
Member memberA = Member.builder().nickname("00").build(); | ||
Member memberB = Member.builder().nickname("11").build(); | ||
Member memberC = Member.builder().nickname("22").build(); | ||
Member memberD = Member.builder().nickname("33").build(); | ||
ReflectionTestUtils.setField(memberA, "id", 1L); | ||
ReflectionTestUtils.setField(memberB, "id", 2L); | ||
ReflectionTestUtils.setField(memberC, "id", 3L); | ||
ReflectionTestUtils.setField(memberD, "id", 4L); | ||
|
||
Map<Member, PassionRecord> board = new HashMap<>(); | ||
board.put(memberA, new PassionRecord(1, 1)); | ||
board.put(memberB, new PassionRecord(1, 3)); | ||
board.put(memberC, new PassionRecord(1, 3)); | ||
board.put(memberD, new PassionRecord(1, 3)); | ||
|
||
PassionRankings passionRankings = new PassionRankings(board); | ||
|
||
//when, then | ||
assertAll( | ||
() -> assertThat(passionRankings.getScore(memberA)).isEqualTo(6), | ||
() -> assertThat(passionRankings.getScore(memberB)).isEqualTo(8), | ||
() -> assertThat(passionRankings.getScore(memberC)).isEqualTo(8), | ||
() -> assertThat(passionRankings.getRanking(memberA)).isEqualTo(4), | ||
() -> assertThat(passionRankings.getRanking(memberB)).isEqualTo(1), | ||
() -> assertThat(passionRankings.getRanking(memberC)).isEqualTo(1), | ||
() -> assertThat(passionRankings.getRanking(memberD)).isEqualTo(1) | ||
); | ||
} | ||
|
||
} | ||
|
||
} |
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
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
Oops, something went wrong.