-
Notifications
You must be signed in to change notification settings - Fork 0
매치 전적 구현 #39
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
Merged
Merged
매치 전적 구현 #39
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
3b762d3
feat: 전적 로직 구현 및 예외 처리 수정
hojooo 9c64857
fix: matchuser 생성 로직 변경
hojooo eeb4db5
fix: 전적 풋살, 축구, 통합으로 나누어서 관리하도록 로직 수정
hojooo bf05838
Merge branch 'develop' into feat/#30-club-statistics
hojooo c443658
fix: 매치 테스트에 전적 mock 주입
hojooo 665248e
fix: 전적 관련 수정
hojooo cf79f4b
Merge branch 'develop' into feat/#30-club-statistics
hojooo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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
21 changes: 21 additions & 0 deletions
21
src/main/java/com/example/moim/statistic/controller/StatisticController.java
This file contains hidden or 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,21 @@ | ||
| package com.example.moim.statistic.controller; | ||
|
|
||
| import com.example.moim.global.exception.BaseResponse; | ||
| import com.example.moim.global.exception.ResponseCode; | ||
| import com.example.moim.statistic.dto.StatisticDTO; | ||
| import com.example.moim.statistic.service.StatisticService; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| public class StatisticController { | ||
| private StatisticService statisticService; | ||
|
|
||
| // 전적 조회(전적 메인) | ||
| @GetMapping("/statistic/{clubId}") | ||
| public BaseResponse<StatisticDTO.StatisticResponse> getStatistic(@PathVariable Long clubId, | ||
| @RequestBody StatisticDTO.StatisticRequest request) { | ||
| return BaseResponse.onSuccess(statisticService.getStatistic(clubId, request.getTargetSeason(), request.getTargetType()), ResponseCode.OK); | ||
| } | ||
| } |
47 changes: 47 additions & 0 deletions
47
src/main/java/com/example/moim/statistic/dto/StatisticDTO.java
This file contains hidden or 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,47 @@ | ||
| package com.example.moim.statistic.dto; | ||
|
|
||
| import com.example.moim.statistic.entity.Statistic; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Data; | ||
|
|
||
| public class StatisticDTO { | ||
| @Data | ||
| @AllArgsConstructor | ||
| public static class StatisticRequest { | ||
|
||
| private String targetSeason; | ||
| private String targetType; | ||
| } | ||
|
|
||
| @Data | ||
| @AllArgsConstructor | ||
| public static class StatisticResponse { | ||
| private String season; | ||
| private String rank; | ||
| private int point; | ||
| private float winRate; | ||
| private int winCount; | ||
| private int defeatCount; | ||
| private int drawCount; | ||
| private String mvpName; | ||
| private int mvpGoalCount; | ||
|
|
||
| public StatisticResponse(Statistic statistic) { | ||
| this.season = statistic.getSeason(); | ||
| this.point = statistic.getPoint(); | ||
| this.winRate = statistic.getWinRate(); | ||
| this.winCount = statistic.getWinCount(); | ||
| this.defeatCount = statistic.getDefeatCount(); | ||
| this.drawCount = statistic.getDrawCount(); | ||
| this.mvpName = statistic.getMvpName(); | ||
| this.mvpGoalCount = statistic.getMvpScore(); | ||
| this.rank = statistic.getTier().toString(); | ||
| } | ||
| } | ||
|
|
||
| @Data | ||
| @AllArgsConstructor | ||
| public static class mvpDTO { | ||
| private String name; | ||
| private Long goalCount; | ||
| } | ||
| } | ||
156 changes: 156 additions & 0 deletions
156
src/main/java/com/example/moim/statistic/entity/Statistic.java
This file contains hidden or 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,156 @@ | ||
| package com.example.moim.statistic.entity; | ||
|
|
||
| import com.example.moim.club.entity.Club; | ||
| import com.example.moim.club.entity.UserClub; | ||
| import com.example.moim.global.entity.BaseEntity; | ||
| import com.example.moim.global.enums.SportsType; | ||
| import jakarta.persistence.*; | ||
| import lombok.Getter; | ||
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| import static com.example.moim.statistic.entity.Tier.ROOKIE; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| public class Statistic extends BaseEntity { | ||
| @Id @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "club_id") | ||
| private Club club; | ||
|
|
||
| private SportsType sportsType; | ||
| private String season; // -년 전반기 / 후반기 | ||
| private Tier tier; | ||
| private int point; | ||
|
|
||
| private float winRate; // 소수점 한 자리 수까지 표기 | ||
| private int winCount; | ||
| private int drawCount; | ||
| private int defeatCount; | ||
|
|
||
| private int winStreak; | ||
| private int defeatStreak; | ||
|
|
||
| private int mvpScore; | ||
| private String mvpName; | ||
|
|
||
| public static String getCurrentSeason() { | ||
| LocalDate now = LocalDate.now(); | ||
| int year = now.getYear(); | ||
| int month = now.getMonthValue(); | ||
| String half = (month <= 6) ? "상반기" : "하반기"; | ||
|
|
||
| return year + " " + half + "전적"; | ||
| } | ||
|
|
||
| // 모임 만들때 기본적으로 하나 생성, 반기별로 하나씩 생성 | ||
| public static Statistic createStatistic(Club club, SportsType sportsType) { | ||
| Statistic statistic = new Statistic(); | ||
|
|
||
| statistic.club = club; | ||
| statistic.sportsType = sportsType; | ||
| statistic.season = Statistic.getCurrentSeason(); | ||
| statistic.tier = ROOKIE; | ||
| statistic.point = 305; | ||
| statistic.winRate = 0f; | ||
| statistic.winCount = 0; | ||
| statistic.drawCount = 0; | ||
| statistic.defeatCount = 0; | ||
| statistic.winStreak = 0; | ||
| statistic.defeatStreak = 0; | ||
| statistic.mvpScore = 0; | ||
| statistic.mvpName = null; | ||
|
|
||
| return statistic; | ||
| } | ||
|
|
||
| public void updateStatistic(int homeScore, int awayScore, int opponentRank, String mvpName, int mvpScore) { | ||
| int currentMatches = this.winCount + this.drawCount + this.defeatCount; // 배치고사 단계: 3경기 미만, 이후 경기부터는 정식 랭크 적용 | ||
| int pointsChange = 0; | ||
|
|
||
| int ourRankLevel = this.tier.getLevel(); | ||
| int diff = opponentRank - ourRankLevel; | ||
|
|
||
| if (homeScore > awayScore) { | ||
| this.winCount++; | ||
| this.winStreak += this.winStreak + 1; | ||
| this.defeatStreak = 0; | ||
|
|
||
| if (this.tier == ROOKIE) { | ||
| pointsChange += 125; | ||
| } else { | ||
| pointsChange += 128; | ||
| // 3연승 이상이면 연승 보너스: 현재 연승 수 × 10점을 추가 | ||
| if (this.winStreak >= 3) { | ||
| pointsChange += this.winStreak * 10; | ||
| } | ||
| // 랭크 차이 보너스: 우리 팀의 랭크와 상대팀의 랭크 차이에 따라 추가 점수를 부여 | ||
| if (diff == 2) { | ||
| pointsChange += 100; | ||
| } else if (diff >= 3) { | ||
| pointsChange += 150; | ||
| } | ||
| } | ||
| } else if (homeScore < awayScore) { | ||
| this.defeatCount++; | ||
| this.defeatStreak += this.defeatStreak + 1; | ||
| this.winStreak = 0; | ||
|
|
||
| if (this.tier == ROOKIE) { | ||
| pointsChange -= 75; | ||
| } else { | ||
| // 기본 패배 페널티는 -72점 | ||
| // 단, 연패 완화 로직: 3연패 시에는 -30점, 4연패 이상이면 페널티가 0점 | ||
| if (this.defeatStreak == 3) { | ||
| pointsChange += -30; | ||
| } else if (this.defeatStreak >= 4) { | ||
| pointsChange += 0; | ||
| } else { | ||
| pointsChange += -72; | ||
| } | ||
| } | ||
| } else { | ||
| this.drawCount++; | ||
| this.winStreak = 0; | ||
| this.defeatStreak = 0; | ||
|
|
||
| if (this.tier == ROOKIE) { | ||
| pointsChange += 50; | ||
| } else { | ||
| pointsChange += 47; | ||
| } | ||
| } | ||
|
|
||
| this.point += pointsChange; | ||
|
|
||
| boolean isRookie = (currentMatches < 3); | ||
| if (!isRookie) { | ||
| if (this.point >= 1600) { | ||
| this.tier = Tier.M1; | ||
| } else if (this.point >= 1300) { | ||
| this.tier = Tier.M2; | ||
| } else if (this.point >= 875) { | ||
| this.tier = Tier.M3; | ||
| } else if (this.point >= 500) { | ||
| this.tier = Tier.M4; | ||
| } else { | ||
| this.tier = Tier.M5; | ||
| } | ||
| } | ||
|
|
||
| this.mvpName = mvpName; | ||
| this.mvpScore = mvpScore; | ||
|
|
||
| // 총 경기수 계산 후 승률 업데이트 (승률 = (승리수/총경기수)*100) | ||
| int totalMatches = this.winCount + this.drawCount + this.defeatCount; | ||
| this.winRate = totalMatches > 0 ? ((float) this.winCount / totalMatches) * 100 : 0; | ||
| } | ||
|
|
||
| public void updateMvp(UserClub userClub) { | ||
| this.mvpName = userClub.getUser().getName(); | ||
| this.mvpScore = userClub.getScore(); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StatisticDTO에 Request, Response 모아서 구현하신 이유가 궁금합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DTO들이 많아지면 관리하기가 힘들어진다고 생각이 들어서 이너 클래스로 관련된 DTO들을 모아서 구현했습니다!