forked from Loopers-dev-lab/loop-pack-be-l2-vol2-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRankingFacade.java
More file actions
154 lines (130 loc) · 5.18 KB
/
Copy pathRankingFacade.java
File metadata and controls
154 lines (130 loc) · 5.18 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package com.loopers.application.ranking;
import com.loopers.application.product.ProductInfo;
import com.loopers.domain.product.Product;
import com.loopers.domain.product.ProductService;
import com.loopers.domain.ranking.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
@RequiredArgsConstructor
public class RankingFacade {
private final RankingService rankingService;
private final PeriodRankingService periodRankingService;
private final ProductService productService;
/**
* TOP N 랭킹 조회 (상품 정보 포함)
*/
@Transactional(readOnly = true)
public List<RankingInfo> getTopRanking(
RankingType rankingType,
PeriodType periodType,
LocalDate date,
int limit
) {
// period가 null이면 DAILY로 처리
PeriodType period = periodType != null ? periodType : PeriodType.DAILY;
List<Ranking> entries = switch (period) {
case DAILY -> rankingService.getTopRanking(rankingType, LocalDate.now(), limit);
case WEEKLY -> periodRankingService.getTopWeeklyRanking(rankingType, date, limit);
case MONTHLY -> periodRankingService.getTopMonthlyRanking(rankingType, date, limit);
};
if (entries.isEmpty()) {
return List.of();
}
return enrichWithProductInfo(entries);
}
/**
* 페이지네이션 랭킹 조회
*/
@Transactional(readOnly = true)
public List<RankingInfo> getRankingWithPaging(
RankingType rankingType,
PeriodType periodType,
LocalDate date,
int page,
int size
) {
PeriodType period = periodType != null ? periodType : PeriodType.DAILY;
List<Ranking> entries = switch (period) {
case DAILY -> rankingService.getRankingWithPaging(rankingType, LocalDate.now(), page, size);
case WEEKLY -> periodRankingService.getWeeklyRankingWithPaging(rankingType, date, page, size);
case MONTHLY -> periodRankingService.getMonthlyRankingWithPaging(rankingType, date, page, size);
};
if (entries.isEmpty()) {
return List.of();
}
return enrichWithProductInfo(entries);
}
/**
* 특정 상품의 특정 랭킹 조회
*/
@Transactional(readOnly = true)
public RankingInfo getProductRanking(
RankingType rankingType,
LocalDate date,
Long productId
) {
Ranking entry = rankingService.getProductRanking(rankingType, date, productId);
if (entry == null) {
return null;
}
Product product = productService.getProductById(productId);
return RankingInfo.of(entry, ProductInfo.from(product));
}
/**
* 특정 상품의 모든 타입 랭킹 조회 (LIKE, VIEW, ORDER, ALL)
*
* @param productId 조회할 상품 ID
* @param date 조회 날짜 (null이면 오늘)
* @return ProductRankings (랭킹 정보가 하나도 없으면 null)
*/
@Transactional(readOnly = true)
public RankingInfo.ProductRankings getAllRankingsForProduct(Long productId, LocalDate date) {
LocalDate targetDate = date != null ? date : LocalDate.now();
// 4가지 타입의 랭킹을 조회
Ranking likeRanking =
rankingService.getProductRanking(RankingType.LIKE, targetDate, productId);
Ranking viewRanking =
rankingService.getProductRanking(RankingType.VIEW, targetDate, productId);
Ranking orderRanking =
rankingService.getProductRanking(RankingType.ORDER, targetDate, productId);
Ranking allRanking =
rankingService.getProductRanking(RankingType.ALL, targetDate, productId);
return RankingInfo.ProductRankings.of(
likeRanking,
viewRanking,
orderRanking,
allRanking
);
}
/**
* RankingEntry 리스트에 상품 정보 결합
*/
private List<RankingInfo> enrichWithProductInfo(List<Ranking> entries) {
List<Long> productIds = entries.stream()
.map(Ranking::getProductId)
.collect(Collectors.toList());
Map<Long, Product> productMap = productService.getAllByIdIn(productIds).stream()
.collect(Collectors.toMap(Product::getId, product -> product));
return entries.stream()
.map(entry -> {
Product product = productMap.get(entry.getProductId());
ProductInfo productInfo = product != null
? ProductInfo.from(product)
: null;
return RankingInfo.of(entry, productInfo);
})
.collect(Collectors.toList());
}
/**
* 전체 랭킹 개수 조회
*/
public long getTotalRankingCount(RankingType rankingType, LocalDate date) {
return rankingService.getTotalRankingCount(rankingType, date);
}
}