11package com .backend .global .scheduler ;
22
3+ import com .backend .domain .bid .entity .Bid ;
34import com .backend .domain .bid .repository .BidRepository ;
45import com .backend .domain .notification .service .AuctionNotificationService ;
6+ import com .backend .domain .notification .service .BidNotificationService ;
57import com .backend .domain .product .entity .Product ;
68import com .backend .domain .product .enums .AuctionStatus ;
79import com .backend .domain .product .event .helper .ProductChangeTracker ;
@@ -26,6 +28,7 @@ public class AuctionSchedulerService {
2628 private final BidRepository bidRepository ;
2729 private final WebSocketService webSocketService ;
2830 private final AuctionNotificationService auctionNotificationService ;
31+ private final BidNotificationService bidNotificationService ;
2932 private final ApplicationEventPublisher eventPublisher ;
3033
3134 // 매분마다 실행되어 종료된 경매들을 확인하고 낙찰 처리
@@ -118,15 +121,18 @@ private void processAuctionEnd(Product product) {
118121 log .info ("상품 ID: {}, 낙찰가: {}원으로 낙찰 처리되었습니다." ,
119122 product .getId (), highestBidPrice );
120123
121- // 구독자들에게 낙찰 알림 전송
124+ // 구독자들에게 낙찰 알림 전송 (브로드캐스트)
122125 webSocketService .broadcastAuctionEnd (product .getId (), true , highestBidPrice );
123126
127+ // 개인 알림 전송
128+ sendAuctionEndNotifications (product , highestBidPrice );
129+
124130 } else {
125131 // 입찰이 없었던 경우 - 유찰 처리
126132 updateProduct (product , AuctionStatus .FAILED , null );
127133 log .info ("상품 ID: {}, 입찰이 없어 유찰 처리되었습니다." , product .getId ());
128134
129- // 구독자들에게 유찰 알림 전송
135+ // 구독자들에게 유찰 알림 전송 (브로드캐스트)
130136 webSocketService .broadcastAuctionEnd (product .getId (), false , 0L );
131137 }
132138
@@ -138,6 +144,41 @@ private void processAuctionEnd(Product product) {
138144 }
139145 }
140146
147+ // 경매 종료 시 개인 알림 전송
148+ private void sendAuctionEndNotifications (Product product , Long finalPrice ) {
149+ try {
150+ List <Bid > bids = bidRepository .findAllBidsByProductOrderByPriceDesc (product .getId ());
151+
152+ if (bids .isEmpty ()) {
153+ return ;
154+ }
155+
156+ // 낙찰자
157+ Bid winningBid = bids .get (0 );
158+
159+ // 낙찰자에게 낙찰 알림
160+ bidNotificationService .notifyAuctionWon (winningBid .getMember ().getId (), product , finalPrice );
161+
162+ // 나머지 입찰자들에게 낙찰 실패 알림
163+ for (int i = 1 ; i < bids .size (); i ++) {
164+ Bid losingBid = bids .get (i );
165+ bidNotificationService .notifyAuctionLost (
166+ losingBid .getMember ().getId (),
167+ product ,
168+ finalPrice ,
169+ losingBid .getBidPrice ()
170+ );
171+ }
172+
173+ log .info ("상품 ID: {}에 대한 경매 종료 개인 알림 전송 완료. 낙찰자: {}, 탈락자: {}명" ,
174+ product .getId (), winningBid .getMember ().getId (), bids .size () - 1 );
175+
176+ } catch (Exception e ) {
177+ log .error ("경매 종료 개인 알림 전송 중 오류 발생. 상품 ID: {}, 오류: {}" ,
178+ product .getId (), e .getMessage (), e );
179+ }
180+ }
181+
141182 // 개별 경매 시작 처리
142183 private void processAuctionStart (Product product ) {
143184 try {
0 commit comments