33import com .waitit .capstone .domain .dashboard .dto .*;
44import com .waitit .capstone .domain .dashboard .entity .QueueLog ;
55import com .waitit .capstone .domain .dashboard .entity .Review ;
6- import com .waitit .capstone .domain .dashboard .repository .QueueLogRepository ;
6+ import com .waitit .capstone .domain .dashboard .repository .QueueLogRepositoryV2 ; // V2로 변경
77import com .waitit .capstone .domain .dashboard .repository .ReviewRepository ;
88import lombok .RequiredArgsConstructor ;
99import org .springframework .stereotype .Service ;
2222@ Transactional (readOnly = true )
2323public class DashboardServiceV2 {
2424
25- private final QueueLogRepository queueLogRepository ;
25+ private final QueueLogRepositoryV2 queueLogRepository ; // V2로 변경
2626 private final ReviewRepository reviewRepository ;
2727
28- /**
29- * 1. 전체 스토어 지표 조회
30- */
3128 public StoreMetricsResponse getStoreMetrics (Long storeId , String dateRange ) {
3229 String [] dates = dateRange .split ("~" );
3330 LocalDateTime startDate = LocalDate .parse (dates [0 ], DateTimeFormatter .ISO_LOCAL_DATE ).atStartOfDay ();
3431 LocalDateTime endDate = LocalDate .parse (dates [1 ], DateTimeFormatter .ISO_LOCAL_DATE ).atTime (LocalTime .MAX );
3532
36- // 1. 전체 요약 통계 계산
3733 long totalWaitlistCount = queueLogRepository .countByHostIdAndRegisteredAtBetween (storeId , startDate , endDate );
3834 long totalActualUsers = queueLogRepository .countByHostIdAndStatusAndEnteredAtBetween (storeId , QueueLog .Status .ENTERED , startDate , endDate );
3935 long totalDropouts = queueLogRepository .countByHostIdAndStatusAndCancelledAtBetween (storeId , QueueLog .Status .CANCELLED , startDate , endDate );
@@ -48,49 +44,50 @@ public StoreMetricsResponse getStoreMetrics(Long storeId, String dateRange) {
4844 .averageWaitTimeSeconds (avgWaitTime != null ? avgWaitTime : 0.0 )
4945 .build ();
5046
51- // 2. 시간대별 세부 통계 계산
52- List <HourlyMetricsQueryResult > hourlyResults = queueLogRepository .findHourlyMetrics (storeId , startDate , endDate );
47+ List <Object []> hourlyResults = queueLogRepository .findHourlyMetricsRaw (storeId , startDate , endDate );
5348 List <HourlyStoreMetricsDto > hourlyData = hourlyResults .stream ()
54- .map (result -> HourlyStoreMetricsDto .builder ()
55- .timeSlot (String .format ("%02d:00 - %02d:00" , result .getHour (), result .getHour () + 1 ))
56- .waitlistCount (result .getTotalCount ())
57- .actualUsers (result .getEnteredCount ())
58- .dropouts (result .getCancelledCount ())
59- .build ())
49+ .map (result -> {
50+ Integer hour = ((Number ) result [0 ]).intValue ();
51+ long totalCount = ((Number ) result [1 ]).longValue ();
52+ long enteredCount = ((Number ) result [2 ]).longValue ();
53+ long cancelledCount = ((Number ) result [3 ]).longValue ();
54+ return HourlyStoreMetricsDto .builder ()
55+ .timeSlot (String .format ("%02d:00 - %02d:00" , hour , hour + 1 ))
56+ .waitlistCount (totalCount )
57+ .actualUsers (enteredCount )
58+ .dropouts (cancelledCount )
59+ .build ();
60+ })
6061 .collect (Collectors .toList ());
6162
62- // 3. 최종 응답 조합
6363 return StoreMetricsResponse .builder ()
6464 .summary (summary )
6565 .hourlyData (hourlyData )
6666 .build ();
6767 }
6868
69- /**
70- * 4. 예상 대기인원 추이 조회
71- */
7269 public List <WaitlistTrendHourlyData > getWaitlistTrend (Long storeId , String dateRange ) {
7370 String [] dates = dateRange .split ("~" );
7471 LocalDateTime startDate = LocalDate .parse (dates [0 ], DateTimeFormatter .ISO_LOCAL_DATE ).atStartOfDay ();
7572 LocalDateTime endDate = LocalDate .parse (dates [1 ], DateTimeFormatter .ISO_LOCAL_DATE ).atTime (LocalTime .MAX );
7673
77- List <HourlyMetricsQueryResult > hourlyResults = queueLogRepository .findHourlyMetrics (storeId , startDate , endDate );
74+ List <Object [] > hourlyResults = queueLogRepository .findHourlyMetricsRaw (storeId , startDate , endDate );
7875
7976 return hourlyResults .stream ()
8077 .map (result -> {
81- double utilizationRate = (result .getTotalCount () > 0 ) ? (double ) result .getEnteredCount () / result .getTotalCount () : 0.0 ;
78+ Integer hour = ((Number ) result [0 ]).intValue ();
79+ long totalCount = ((Number ) result [1 ]).longValue ();
80+ long enteredCount = ((Number ) result [2 ]).longValue ();
81+ double utilizationRate = (totalCount > 0 ) ? (double ) enteredCount / totalCount : 0.0 ;
8282 return WaitlistTrendHourlyData .builder ()
83- .timeSlot (String .format ("%02d:00 - %02d:00" , result . getHour (), result . getHour () + 1 ))
84- .waitlistCount (result . getTotalCount () )
83+ .timeSlot (String .format ("%02d:00 - %02d:00" , hour , hour + 1 ))
84+ .waitlistCount (totalCount )
8585 .utilizationRate (utilizationRate )
8686 .build ();
8787 })
8888 .collect (Collectors .toList ());
8989 }
9090
91- /**
92- * 3. 재방문율 조회
93- */
9491 public ReturnRateResponse getReturnRate (Long storeId , String dateRange ) {
9592 String [] dates = dateRange .split ("~" );
9693 LocalDateTime startDate = LocalDate .parse (dates [0 ], DateTimeFormatter .ISO_LOCAL_DATE ).atStartOfDay ();
@@ -118,16 +115,12 @@ public ReturnRateResponse getReturnRate(Long storeId, String dateRange) {
118115 .build ();
119116 }
120117
121- /**
122- * 5. 리뷰 및 대기 취소 사유 조회
123- */
124118 public ReviewAndCancelStatsResponse getReviewAndCancelStats (Long storeId , String dateRange , Integer ratingMin ) {
125119 String [] dates = dateRange .split ("~" );
126120 LocalDateTime startDate = LocalDate .parse (dates [0 ], DateTimeFormatter .ISO_LOCAL_DATE ).atStartOfDay ();
127121 LocalDateTime endDate = LocalDate .parse (dates [1 ], DateTimeFormatter .ISO_LOCAL_DATE ).atTime (LocalTime .MAX );
128122 int minRating = (ratingMin != null ) ? ratingMin : 0 ;
129123
130- // 1. 취소 사유 통계 계산
131124 List <CancelReasonCountDto > reasonCounts = queueLogRepository .findCancelReasonStats (storeId , startDate , endDate );
132125 long totalCancellations = reasonCounts .stream ().mapToLong (CancelReasonCountDto ::getCount ).sum ();
133126
@@ -141,7 +134,6 @@ public ReviewAndCancelStatsResponse getReviewAndCancelStats(Long storeId, String
141134 })
142135 .collect (Collectors .toList ());
143136
144- // 2. 리뷰 목록 조회
145137 List <Review > reviewEntities = reviewRepository .findReviews (storeId , startDate , endDate , minRating );
146138 List <ReviewSummaryDto > reviews = reviewEntities .stream ()
147139 .map (ReviewSummaryDto ::from )
0 commit comments