Skip to content

Commit 19b7bb6

Browse files
committed
feat : 메인 or 랭킹화면 랭킹 구현(지난주,이번주,역대 TOP10)
1 parent c847375 commit 19b7bb6

File tree

13 files changed

+310
-0
lines changed

13 files changed

+310
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.ezcode.codetest.application.ranking.dto;
2+
3+
import lombok.Builder;
4+
5+
@Builder
6+
public record RankingResponse(
7+
Long userId,
8+
String nickname, // 사용자 이름
9+
int rank,
10+
int score
11+
) {}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.ezcode.codetest.application.ranking.service;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.ezcode.codetest.application.ranking.dto.RankingResponse;
5+
import org.ezcode.codetest.infrastructure.ranking.redis.RedisRankingService;
6+
import org.springframework.stereotype.Service;
7+
8+
import java.time.DayOfWeek;
9+
import java.time.LocalDate;
10+
import java.util.List;
11+
12+
@Service
13+
@RequiredArgsConstructor
14+
public class RankingFacadeService {
15+
16+
private final RedisRankingService redisRankingService;
17+
18+
public List<RankingResponse> getWeeklyRanking() {
19+
LocalDate thisMonday = LocalDate.now().with(DayOfWeek.MONDAY);
20+
return redisRankingService.getTopRankings("ranking:weekly:" + thisMonday, 10);
21+
}
22+
23+
public List<RankingResponse> getLastWeekRanking() {
24+
LocalDate lastMonday = LocalDate.now().with(DayOfWeek.MONDAY).minusWeeks(1);
25+
return redisRankingService.getTopRankings("ranking:weekly:" + lastMonday, 10);
26+
}
27+
28+
public List<RankingResponse> getAllTimeRanking() {
29+
return redisRankingService.getTopRankings("ranking:all", 10);
30+
}
31+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.ezcode.codetest.domain.ranking.model.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.AccessLevel;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
8+
import org.ezcode.codetest.common.base.entity.BaseEntity;
9+
import org.ezcode.codetest.domain.ranking.model.enums.RankingType;
10+
11+
import java.time.LocalDate;
12+
13+
@Entity
14+
@Getter
15+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
16+
public class Ranking extends BaseEntity {
17+
18+
@Id
19+
@GeneratedValue(strategy = GenerationType.IDENTITY)
20+
private Long id;
21+
22+
private Long userId;
23+
24+
@Enumerated(EnumType.STRING)
25+
private RankingType type; // WEEKLY, MONTHLY, ALL_TIME
26+
27+
private int rank;
28+
private int score;
29+
30+
private LocalDate rankingDate; // 기준 날짜
31+
32+
@Builder
33+
public Ranking(Long userId, RankingType type, int rank, int score, LocalDate rankingDate) {
34+
this.userId = userId;
35+
this.type = type;
36+
this.rank = rank;
37+
this.score = score;
38+
this.rankingDate = rankingDate;
39+
}
40+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.ezcode.codetest.domain.ranking.model.enums;
2+
3+
public enum RankingType {
4+
WEEKLY, MONTHLY, ALL_TIME
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.ezcode.codetest.domain.ranking.repository;
2+
3+
import org.ezcode.codetest.domain.ranking.model.entity.Ranking;
4+
import org.ezcode.codetest.domain.ranking.model.enums.RankingType;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
7+
import java.time.LocalDate;
8+
import java.util.List;
9+
10+
public interface RankingRepository extends JpaRepository<Ranking, Long> {
11+
12+
List<Ranking> findByTypeAndRankingDateOrderByRankAsc(RankingType type, LocalDate date);
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
package org.ezcode.codetest.domain.submission.repository;
22

3+
import java.time.LocalDateTime;
4+
import java.util.List;
35
import java.util.Optional;
46

57
import org.ezcode.codetest.domain.submission.model.entity.UserProblemResult;
8+
import org.springframework.data.jpa.repository.Query;
9+
610

711
public interface UserProblemResultRepository {
812
Optional<UserProblemResult> findUserProblemResultByUserIdAndProblemId(Long userId, Long problemId);
913

1014
void saveUserProblemResult(UserProblemResult userProblemResult);
1115

1216
void updateUserProblemResult(UserProblemResult userProblemResult, boolean isCorrect);
17+
18+
@Query("""
19+
SELECT upr.user.id, SUM(p.score)
20+
FROM UserProblemResult upr
21+
JOIN upr.problem p
22+
WHERE upr.isCorrect = true
23+
AND (:start IS NULL OR upr.createdAt >= :start)
24+
AND (:end IS NULL OR upr.createdAt < :end)
25+
GROUP BY upr.user.id
26+
""")
27+
List<Object[]> findScoresBetween(LocalDateTime start, LocalDateTime end);
1328
}

src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ public interface UserRepository {
1919

2020
boolean existsByNickname(String nickname);
2121

22+
User findById(Long id);
23+
2224
}

src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/submission/impl/UserProblemResultRepositoryImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.ezcode.codetest.infrastructure.persistence.repository.submission.impl;
22

3+
import java.time.LocalDateTime;
4+
import java.util.List;
35
import java.util.Optional;
46

57
import org.ezcode.codetest.domain.submission.model.entity.UserProblemResult;
@@ -29,4 +31,11 @@ public void saveUserProblemResult(UserProblemResult userProblemResult) {
2931
public void updateUserProblemResult(UserProblemResult userProblemResult, boolean isCorrect) {
3032
userProblemResult.updateResult(isCorrect);
3133
}
34+
35+
@Override
36+
public List<Object[]> findScoresBetween(LocalDateTime start, LocalDateTime end) {
37+
return userProblemResultJpaRepository.findScoresBetween(start, end);
38+
}
39+
40+
3241
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
package org.ezcode.codetest.infrastructure.persistence.repository.submission.jpa;
22

3+
import java.time.LocalDateTime;
4+
import java.util.List;
35
import java.util.Optional;
46

57
import org.ezcode.codetest.domain.submission.model.entity.UserProblemResult;
68
import org.springframework.data.jpa.repository.JpaRepository;
9+
import org.springframework.data.jpa.repository.Query;
710

811
public interface UserProblemResultJpaRepository extends JpaRepository<UserProblemResult, Long> {
912
Optional<UserProblemResult> findByUserIdAndProblemId(Long userId, Long problemId);
13+
14+
@Query("""
15+
SELECT upr.user.id, SUM(p.score)
16+
FROM UserProblemResult upr
17+
JOIN upr.problem p
18+
WHERE upr.isCorrect = true
19+
AND (:start IS NULL OR upr.createdAt >= :start)
20+
AND (:end IS NULL OR upr.createdAt < :end)
21+
GROUP BY upr.user.id
22+
""")
23+
List<Object[]> findScoresBetween(LocalDateTime start, LocalDateTime end);
24+
1025
}

src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ public boolean existsByNickname(String nickname) {
4343
return userJpaRepository.existsByNickname(nickname);
4444
}
4545

46+
@Override
47+
public User findById(Long id) {
48+
return userJpaRepository.findById(id).get();
49+
}
50+
4651
}

0 commit comments

Comments
 (0)