diff --git a/src/main/java/com/kt/integration/eventlistener/DiscountEventListener.java b/src/main/java/com/kt/integration/eventlistener/DiscountEventListener.java new file mode 100644 index 00000000..f4d21d81 --- /dev/null +++ b/src/main/java/com/kt/integration/eventlistener/DiscountEventListener.java @@ -0,0 +1,50 @@ +package com.kt.integration.eventlistener; + +import com.kt.event.ProductDiscountEvent; +import com.kt.notification.MailSendRequest; +import com.kt.notification.MailSendService; +import com.kt.repository.cart.CartRepository; +import com.kt.repository.wishlist.WishlistRepository; +import com.kt.service.discount.DiscountService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Component +@RequiredArgsConstructor +public class DiscountEventListener { + + private final DiscountService discountService; + private final MailSendService mailSendService; + private final WishlistRepository wishlistRepository; + private final CartRepository cartRepository; + + @EventListener + public void sendMail(ProductDiscountEvent event) { + + List wishlistEmails = + wishlistRepository.findDistinctEmailsByProductId(event.productId()); + List cartEmails = + cartRepository.findDistinctEmailsByProductId(event.productId()); + + Set distinct_Emails = new HashSet<>(wishlistEmails); + distinct_Emails.addAll(cartEmails); + + if (distinct_Emails.isEmpty()) return; + + for (String email : distinct_Emails) { + MailSendRequest request = new MailSendRequest( + email, + "현재 상품 " + event.productName() + " 이(가) 할인중입니다.", + "상품명: " + event.productName() + "\n할인금액: " + event.discountValue() + "\n할인가: 289,000원\n링크: https://your-shop.com/products/" + event.productId() + "\n\n지금 구매하면 혜택 적용됩니다." + ); + mailSendService.sendEmail(request); + } + } +} + diff --git a/src/main/java/com/kt/notification/FakeMailSendService.java b/src/main/java/com/kt/notification/FakeMailSendService.java new file mode 100644 index 00000000..e584ac25 --- /dev/null +++ b/src/main/java/com/kt/notification/FakeMailSendService.java @@ -0,0 +1,18 @@ +package com.kt.notification; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@Profile("test") +public class FakeMailSendService implements MailSendService { + + @Override + public void sendEmail(MailSendRequest mailSendRequest) { + log.info("[TEST] skip email send: to={}, subject={}", + mailSendRequest.email(), mailSendRequest.title()); + } +} + diff --git a/src/main/java/com/kt/repository/cart/CartRepository.java b/src/main/java/com/kt/repository/cart/CartRepository.java index c2cb9559..07d217e3 100644 --- a/src/main/java/com/kt/repository/cart/CartRepository.java +++ b/src/main/java/com/kt/repository/cart/CartRepository.java @@ -10,6 +10,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; public interface CartRepository extends JpaRepository { default Cart findByIdOrThrow(Long id, ErrorCode errorCode) { @@ -20,4 +21,15 @@ default Cart findByIdOrThrow(Long id, ErrorCode errorCode) { @EntityGraph(attributePaths = {"user", "product", "user.membership"}) Page findByUserId(Long userId, Pageable pageable); + + //상품을 찜한 유저 이메일만 뽑는 쿼리, jpa는 비효율적이라 사용x + @Query(""" + select distinct u.email + from Wishlist w + join w.user u + where w.product.id = :productId + and u.isDeleted = false + and u.email is not null + """) + List findDistinctEmailsByProductId(Long productId); } diff --git a/src/main/java/com/kt/repository/wishlist/WishlistRepository.java b/src/main/java/com/kt/repository/wishlist/WishlistRepository.java index d349d1fb..258924ae 100644 --- a/src/main/java/com/kt/repository/wishlist/WishlistRepository.java +++ b/src/main/java/com/kt/repository/wishlist/WishlistRepository.java @@ -3,17 +3,29 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import com.kt.domain.wishlist.Wishlist; @Repository public interface WishlistRepository extends JpaRepository { - boolean existsByUserIdAndProductId(Long userId, Long productId); - List findByUserId(Long userId); - List findByProductId(Long productId); + boolean existsByUserIdAndProductId(Long userId, Long productId); + List findByUserId(Long userId); + List findByProductId(Long productId); - void deleteByUserIdAndProductId(Long userId, Long productId); + void deleteByUserIdAndProductId(Long userId, Long productId); - void deleteByUserId(Long userId); + void deleteByUserId(Long userId); + + //상품을 찜한 유저 이메일만 뽑는 쿼리, jpa는 비효율적이라 사용x + @Query(""" + select distinct u.email + from Wishlist w + join w.user u + where w.product.id = :productId + and u.isDeleted = false + and u.email is not null + """) + List findDistinctEmailsByProductId(Long productId); }