-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathGeneralFeedRankingService.java
More file actions
101 lines (86 loc) · 4.36 KB
/
GeneralFeedRankingService.java
File metadata and controls
101 lines (86 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package ddingdong.ddingdongBE.domain.feed.service;
import ddingdong.ddingdongBE.domain.club.entity.Club;
import ddingdong.ddingdongBE.domain.club.service.ClubService;
import ddingdong.ddingdongBE.domain.feed.repository.FeedRepository;
import ddingdong.ddingdongBE.domain.feed.repository.dto.MonthlyFeedRankingDto;
import ddingdong.ddingdongBE.domain.feed.service.dto.query.ClubFeedRankingQuery;
import ddingdong.ddingdongBE.domain.feed.service.dto.query.ClubMonthlyStatusQuery;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class GeneralFeedRankingService implements FeedRankingService {
private static final int FEED_WEIGHT = 10;
private static final int VIEW_WEIGHT = 1;
private static final int LIKE_WEIGHT = 3;
private static final int COMMENT_WEIGHT = 5;
private final FeedRepository feedRepository;
private final ClubService clubService;
@Override
public List<ClubFeedRankingQuery> getClubFeedRanking(int year, int month) {
List<MonthlyFeedRankingDto> rawRankings = feedRepository.findMonthlyRankingByClub(year, month);
List<MonthlyFeedRankingDto> sorted = rawRankings.stream()
.sorted(Comparator.comparingLong(this::calculateScore).reversed())
.toList();
List<ClubFeedRankingQuery> result = new ArrayList<>();
long previousScore = Long.MAX_VALUE;
int rank = 1;
for (int i = 0; i < sorted.size(); i++) {
long totalScore = calculateScore(sorted.get(i));
if (i > 0 && totalScore < previousScore) {
rank = i + 1;
}
result.add(toClubFeedRankingQuery(rank, sorted.get(i)));
previousScore = totalScore;
}
return result;
}
@Override
public ClubMonthlyStatusQuery getClubMonthlyStatus(Long userId, int year, int month) {
Club club = clubService.getByUserId(userId);
List<ClubFeedRankingQuery> rankings = getClubFeedRanking(year, month);
int lastMonthRank = getLastMonthRank(club.getId(), year, month);
return rankings.stream()
.filter(rankingQuery -> rankingQuery.clubId().equals(club.getId()))
.findFirst()
.filter(rankingQuery -> rankingQuery.totalScore() > 0)
.map(rankingQuery -> toMonthlyStatus(year, month, rankingQuery, lastMonthRank))
.orElse(ClubMonthlyStatusQuery.createEmpty(year, month, lastMonthRank));
}
private ClubMonthlyStatusQuery toMonthlyStatus(int year, int month,
ClubFeedRankingQuery ranking, int lastMonthRank) {
return ClubMonthlyStatusQuery.of(year, month, ranking.rank(), lastMonthRank,
ranking.feedScore(), ranking.viewScore(), ranking.likeScore(), ranking.commentScore());
}
private int getLastMonthRank(Long clubId, int year, int month) {
int lastYear = month == 1 ? year - 1 : year;
int lastMonth = month == 1 ? 12 : month - 1;
List<ClubFeedRankingQuery> lastMonthRankings = getClubFeedRanking(lastYear, lastMonth);
return lastMonthRankings.stream()
.filter(ranking -> ranking.clubId().equals(clubId))
.filter(ranking -> ranking.totalScore() > 0)
.findFirst()
.map(ClubFeedRankingQuery::rank)
.orElse(0);
}
private ClubFeedRankingQuery toClubFeedRankingQuery(int rank, MonthlyFeedRankingDto dto) {
long feedScore = dto.getFeedCount() * FEED_WEIGHT;
long viewScore = dto.getViewCount() * VIEW_WEIGHT;
long likeScore = dto.getLikeCount() * LIKE_WEIGHT;
long commentScore = dto.getCommentCount() * COMMENT_WEIGHT;
long totalScore = feedScore + viewScore + likeScore + commentScore;
return ClubFeedRankingQuery.of(rank, dto.getClubId(), dto.getClubName(),
feedScore, viewScore, likeScore, commentScore, totalScore);
}
private long calculateScore(MonthlyFeedRankingDto dto) {
return dto.getFeedCount() * FEED_WEIGHT
+ dto.getViewCount() * VIEW_WEIGHT
+ dto.getLikeCount() * LIKE_WEIGHT
+ dto.getCommentCount() * COMMENT_WEIGHT;
}
}