Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.ezcode.codetest.application.ranking.dto;

public record TargetRankingResponse(
Long userId,
String nickname,
int ranks,
int score,
boolean isMe // 프론트에서 이걸보고 누가 특정 사람인지 파악(ex, 색 더 진하게)
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.RequiredArgsConstructor;
import org.ezcode.codetest.application.ranking.dto.RankingResponse;
import org.ezcode.codetest.application.ranking.dto.TargetRankingResponse;
import org.ezcode.codetest.infrastructure.ranking.redis.RedisRankingService;
import org.springframework.stereotype.Service;

Expand All @@ -28,4 +29,18 @@ public List<RankingResponse> getLastWeekRanking() {
public List<RankingResponse> getAllTimeRanking() {
return redisRankingService.getTopRankings("ranking:all", 10);
}

//랭킹 조회
public List<TargetRankingResponse> getRanking(String period, Long userId) {
LocalDate baseMonday = LocalDate.now().with(DayOfWeek.MONDAY);
String key = switch (period) {
case "weekly" -> "ranking:weekly:" + baseMonday;
case "last-week" -> "ranking:weekly:" + baseMonday.minusWeeks(1);
case "all-time" -> "ranking:all";
default -> throw new IllegalArgumentException("기간은 weekly, last-week, all-time 만 가능합니다.");
};

return redisRankingService.getRanking(key, userId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ezcode.codetest.application.ranking.dto.RankingResponse;
import org.ezcode.codetest.application.ranking.dto.TargetRankingResponse;
import org.ezcode.codetest.infrastructure.persistence.repository.user.UserJpaRepository;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
Expand Down Expand Up @@ -65,4 +66,38 @@ public List<RankingResponse> getTopRankings(String key, int limit) {
}).collect(Collectors.toList());
}

public List<TargetRankingResponse> getRanking(String key, Long userId) {
Long myRank = redisTemplate.opsForZSet().reverseRank(key, userId.toString());
if (myRank == null) return List.of();

long start = Math.max(0, myRank - 1);
long end = myRank + 1;

Set<ZSetOperations.TypedTuple<String>> range = redisTemplate.opsForZSet()
.reverseRangeWithScores(key, start, end);

if (range == null || range.isEmpty()) return List.of();

List<String> ids = range.stream().map(ZSetOperations.TypedTuple::getValue).toList();
Map<Long, String> nicknameMap = userJpaRepository.findAllById(
ids.stream().map(Long::parseLong).toList()
).stream().collect(Collectors.toMap(
u -> u.getId(),
u -> u.getNickname()
));

return range.stream().map(tuple -> {
Long id = Long.parseLong(tuple.getValue());
Long rank = redisTemplate.opsForZSet().reverseRank(key, tuple.getValue());

return new TargetRankingResponse(
id,
nicknameMap.getOrDefault(id, "알 수 없음"),
rank != null ? rank.intValue() + 1 : -1,
tuple.getScore() != null ? tuple.getScore().intValue() : 0,
id.equals(userId)
);
}).sorted(Comparator.comparingInt(TargetRankingResponse::ranks)).toList();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import lombok.RequiredArgsConstructor;
import org.ezcode.codetest.application.ranking.dto.PointResponse;
import org.ezcode.codetest.application.ranking.dto.RankingResponse;
import org.ezcode.codetest.application.ranking.dto.TargetRankingResponse;
import org.ezcode.codetest.application.ranking.service.RankingFacadeService;
import org.ezcode.codetest.domain.user.model.entity.AuthUser;
import org.ezcode.codetest.infrastructure.ranking.scheduler.RankingSyncScheduler;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;

Expand Down Expand Up @@ -41,4 +41,24 @@ public List<RankingResponse> getAllTime() {
public void forceRefreshRankings() {
rankingSyncScheduler.syncRankingsToRedis();
}

// 내 랭킹 조회
// weekly, last-week, all-time 3개 가능 뭘 표시할지 의논해서 쓰면 될듯
@GetMapping("/me/around")
public List<TargetRankingResponse> getMyRanking(
@RequestParam("period") String period,
@AuthenticationPrincipal AuthUser authUser
) {
return rankingService.getRanking(period, authUser.getId());
}

@GetMapping("/{userId}/around")
public List<TargetRankingResponse> getTargetAroundRanking(
@RequestParam("period") String period,
@PathVariable Long userId
) {
return rankingService.getRanking(period, userId);
}


}