From 2846432ad1e01f79b9db0befea85770f60002c1a Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Tue, 1 Oct 2024 02:38:56 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20#219=20-=20=EC=BA=90=EB=9F=AC=EC=85=80?= =?UTF-8?q?=20=EB=B2=88=ED=98=B8=EA=B0=80=20=EC=A4=91=EB=B3=B5=EB=90=9C=20?= =?UTF-8?q?=ED=95=AD=EB=AA=A9=20=EC=A4=91=EC=97=90=EC=84=9C=20promotionId?= =?UTF-8?q?=EA=B0=80=20=EB=8B=A4=EB=A5=B8=20=EA=B2=BD=EC=9A=B0=EC=97=90?= =?UTF-8?q?=EB=A7=8C=20=EC=82=AD=EC=A0=9C=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#220)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [#219] fix(AdminFacade): 중복된 캐러셀 번호 처리 및 삭제 로직 수정 - Promotion ID가 다른 중복된 캐러셀 번호만 삭제하도록 수정 - 삭제할 캐러셀 번호와 중복된 캐러셀 번호를 분리하여 처리 - 중복된 캐러셀 번호를 처리하는 로직을 메서드로 분리하여 가독성 향상 - Promotion 수정 및 생성 요청을 명확하게 분리하여 처리 * [#219] feat(AdminService): 중복된 캐러셀 번호 처리 및 프로모션 삭제 로직 추가 * [#219] refactor(AdminUseCase): 메서드 시그니처 변경 * [#219] refactor(PromotionService): 캐러셀넘버로 Promotion 객체를 찾는 메서드 구현 및 캐러셀 넘버로 삭제 시 리스트 형태로 주도록 변경 * [#219] refactor(PromotionUseCase): 메서드 시그니처 변경 및 캐러셀 넘버로 Promotion 객체를 조회하는 메서드 선언 * [#219] refactor(PromotionRepository): 캐러셀 번호 기반 프로모션 삭제 로직 변경 및 조회 기능 추가 - `deleteByCarouselNumbers` 메서드 변: 여러 캐러셀 번호에 해당하는 프로모션을 한 경에 삭제하도록 로직 변경 - `findByCarouselNumber` 메서드 추가: 캐러셀 번호로 프로모션을 조회하는 기능 구현 - JPA 쿼리 최적화를 위해 `@Modifying` 및 `@Transactional` 어노테이션 추가 --- .../beat/admin/application/AdminService.java | 24 +++++++--- .../com/beat/admin/facade/AdminFacade.java | 46 +++++++++++++++---- .../com/beat/admin/port/in/AdminUseCase.java | 2 +- .../application/PromotionService.java | 32 ++++++------- .../promotion/dao/PromotionRepository.java | 12 ++++- .../promotion/port/in/PromotionUseCase.java | 4 +- 6 files changed, 84 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/beat/admin/application/AdminService.java b/src/main/java/com/beat/admin/application/AdminService.java index cf24b939..3ded8d8d 100644 --- a/src/main/java/com/beat/admin/application/AdminService.java +++ b/src/main/java/com/beat/admin/application/AdminService.java @@ -36,11 +36,13 @@ public List findAllPromotionsSortedByCarouselNumber() { @Override @Transactional public List processPromotionsAndSortByCarouselNumber(List modifyRequests, - List generateRequests, List deleteCarouselNumbers) { + List generateRequests, List deleteCarouselNumbers, + List overlappingCarouselNumbers) { + handleOverlappingCarouselNumbersPromotionDeletion(overlappingCarouselNumbers); + handlePromotionDeletion(deleteCarouselNumbers); List modifiedPromotions = handlePromotionModification(modifyRequests); List addedPromotions = handlePromotionGeneration(generateRequests); - handlePromotionDeletion(deleteCarouselNumbers); List applyPromotionChanges = new ArrayList<>(modifiedPromotions); applyPromotionChanges.addAll(addedPromotions); @@ -48,9 +50,23 @@ public List processPromotionsAndSortByCarouselNumber(List overlappingCarouselNumbers) { + if (!overlappingCarouselNumbers.isEmpty()) { + promotionUseCase.deleteByCarouselNumber(overlappingCarouselNumbers); + } + } + + private void handlePromotionDeletion(List deleteCarouselNumbers) { + if (!deleteCarouselNumbers.isEmpty()) { + promotionUseCase.deleteByCarouselNumber(deleteCarouselNumbers); + } + } + private List handlePromotionModification(List modifyRequests) { return modifyRequests.stream().map(modifyRequest -> { + Promotion promotion = promotionUseCase.findById(modifyRequest.promotionId()); + Performance performance = Optional.ofNullable(modifyRequest.performanceId()) .map(performanceUseCase::findById) .orElse(null); @@ -70,10 +86,6 @@ private List handlePromotionGeneration(List }).toList(); } - private void handlePromotionDeletion(List deleteCarouselNumbers) { - deleteCarouselNumbers.forEach(promotionUseCase::deleteByCarouselNumber); - } - private List sortPromotionsByCarouselNumber(List promotions) { return promotions.stream() .sorted(Comparator.comparing(Promotion::getCarouselNumber, Comparator.comparingInt(Enum::ordinal))) diff --git a/src/main/java/com/beat/admin/facade/AdminFacade.java b/src/main/java/com/beat/admin/facade/AdminFacade.java index 2082cd0c..f2d67cc4 100644 --- a/src/main/java/com/beat/admin/facade/AdminFacade.java +++ b/src/main/java/com/beat/admin/facade/AdminFacade.java @@ -66,12 +66,32 @@ public CarouselFindAllResponse checkMemberAndFindAllPromotionsSortedByCarouselNu public CarouselProcessAllResponse checkMemberAndProcessAllPromotionsSortedByCarouselNumber(Long memberId, CarouselProcessRequest request) { + memberUseCase.findMemberById(memberId); List modifyRequests = new ArrayList<>(); List generateRequests = new ArrayList<>(); Set requestCarouselNumbers = new HashSet<>(); + categorizePromotionRequests(request, modifyRequests, generateRequests, requestCarouselNumbers); + + List allExistingCarouselNumbers = promotionUseCase.findAllCarouselNumbers(); + + List deleteCarouselNumbers = findDeleteCarouselNumbers(requestCarouselNumbers, + allExistingCarouselNumbers); + List overlappingCarouselNumbers = findOverlappingCarouselNumbers(requestCarouselNumbers, + allExistingCarouselNumbers, request); + + List sortedPromotions = adminUsecase.processPromotionsAndSortByCarouselNumber(modifyRequests, + generateRequests, deleteCarouselNumbers, overlappingCarouselNumbers); + + return CarouselProcessAllResponse.from(sortedPromotions); + } + + private void categorizePromotionRequests(CarouselProcessRequest request, + List modifyRequests, List generateRequests, + Set requestCarouselNumbers) { + for (PromotionHandleRequest promotionRequest : request.carousels()) { requestCarouselNumbers.add(promotionRequest.carouselNumber()); @@ -81,17 +101,27 @@ public CarouselProcessAllResponse checkMemberAndProcessAllPromotionsSortedByCaro generateRequests.add(generateRequest); } } + } - List allExistingCarouselNumbers = promotionUseCase.findAllCarouselNumbers(); - - List deleteCarouselNumbers = allExistingCarouselNumbers.stream() + private List findDeleteCarouselNumbers(Set requestCarouselNumbers, + List allExistingCarouselNumbers) { + return allExistingCarouselNumbers.stream() .filter(existingCarouselNumber -> !requestCarouselNumbers.contains(existingCarouselNumber)) .toList(); + } - List sortedPromotions = adminUsecase. - processPromotionsAndSortByCarouselNumber(modifyRequests, generateRequests, - deleteCarouselNumbers); - - return CarouselProcessAllResponse.from(sortedPromotions); + private List findOverlappingCarouselNumbers(Set requestCarouselNumbers, + List allExistingCarouselNumbers, CarouselProcessRequest request) { + return allExistingCarouselNumbers.stream() + .filter(requestCarouselNumbers::contains) + .filter(existingCarouselNumber -> { + Promotion existingPromotion = promotionUseCase.findPromotionByCarouselNumber(existingCarouselNumber); + return request.carousels() + .stream() + .filter(req -> req instanceof CarouselProcessRequest.PromotionModifyRequest) + .map(req -> (CarouselProcessRequest.PromotionModifyRequest)req) + .noneMatch(req -> req.promotionId() != null && req.promotionId().equals(existingPromotion.getId())); + }) + .toList(); } } \ No newline at end of file diff --git a/src/main/java/com/beat/admin/port/in/AdminUseCase.java b/src/main/java/com/beat/admin/port/in/AdminUseCase.java index 3abd6920..747b812f 100644 --- a/src/main/java/com/beat/admin/port/in/AdminUseCase.java +++ b/src/main/java/com/beat/admin/port/in/AdminUseCase.java @@ -11,5 +11,5 @@ public interface AdminUseCase { List findAllPromotionsSortedByCarouselNumber(); List processPromotionsAndSortByCarouselNumber(List modifyRequests, - List generateRequests, List deleteCarouselNumbers); + List generateRequests, List deleteCarouselNumbers, List overlappingCarouselNumbers); } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/application/PromotionService.java b/src/main/java/com/beat/domain/promotion/application/PromotionService.java index 7f352ec8..35ecd364 100644 --- a/src/main/java/com/beat/domain/promotion/application/PromotionService.java +++ b/src/main/java/com/beat/domain/promotion/application/PromotionService.java @@ -17,6 +17,7 @@ import java.util.List; @Service +@Transactional @RequiredArgsConstructor public class PromotionService implements PromotionUseCase { @@ -36,36 +37,22 @@ public List findAllPromotions() { } @Override - @Transactional public Promotion createPromotion(String newImageUrl, Performance performance, String redirectUrl, boolean isExternal, CarouselNumber carouselNumber) { - Promotion newPromotion = Promotion.create( - newImageUrl, - performance, - redirectUrl, - isExternal, - carouselNumber - ); + Promotion newPromotion = Promotion.create(newImageUrl, performance, redirectUrl, isExternal, carouselNumber); return promotionRepository.save(newPromotion); } @Override - @Transactional public Promotion modifyPromotion(Promotion promotion, Performance performance, PromotionModifyRequest request) { - promotion.updatePromotionDetails( - request.carouselNumber(), - request.newImageUrl(), - request.isExternal(), - request.redirectUrl(), - performance - ); + promotion.updatePromotionDetails(request.carouselNumber(), request.newImageUrl(), request.isExternal(), + request.redirectUrl(), performance); return promotionRepository.save(promotion); } @Override - @Transactional - public void deleteByCarouselNumber(CarouselNumber carouselNumber) { - promotionRepository.deleteByCarouselNumber(carouselNumber); + public void deleteByCarouselNumber(List carouselNumber) { + promotionRepository.deleteByCarouselNumbers(carouselNumber); } @Override @@ -73,4 +60,11 @@ public void deleteByCarouselNumber(CarouselNumber carouselNumber) { public List findAllCarouselNumbers() { return promotionRepository.findAllCarouselNumbers(); } + + @Override + @Transactional(readOnly = true) + public Promotion findPromotionByCarouselNumber(CarouselNumber carouselNumber) { + return promotionRepository.findByCarouselNumber(carouselNumber) + .orElseThrow(() -> new NotFoundException(PromotionErrorCode.PROMOTION_NOT_FOUND)); + } } diff --git a/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java b/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java index 06b26111..f06f0f75 100644 --- a/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java +++ b/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java @@ -3,9 +3,13 @@ import com.beat.domain.promotion.domain.CarouselNumber; import com.beat.domain.promotion.domain.Promotion; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Optional; public interface PromotionRepository extends JpaRepository { List findAll(); @@ -13,5 +17,11 @@ public interface PromotionRepository extends JpaRepository { @Query("SELECT p.carouselNumber FROM Promotion p") List findAllCarouselNumbers(); - void deleteByCarouselNumber(CarouselNumber carouselNumber); + @Modifying(clearAutomatically = true) + @Transactional + @Query("DELETE FROM Promotion p WHERE p.carouselNumber IN :carouselNumbers") + void deleteByCarouselNumbers(@Param("carouselNumbers") List carouselNumbers); + + @Query("SELECT p FROM Promotion p WHERE p.carouselNumber = :carouselNumber") + Optional findByCarouselNumber(@Param("carouselNumber") CarouselNumber carouselNumber); } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java b/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java index 663f4be7..1ad8acd6 100644 --- a/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java +++ b/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java @@ -17,7 +17,9 @@ Promotion createPromotion(String newImageUrl, Performance performance, String re Promotion modifyPromotion(Promotion promotion, Performance performance, PromotionModifyRequest request); - void deleteByCarouselNumber(CarouselNumber carouselNumber); + void deleteByCarouselNumber(List carouselNumbers); List findAllCarouselNumbers(); + + Promotion findPromotionByCarouselNumber(CarouselNumber carouselNumber); } \ No newline at end of file