From c840f5d0aaa328ac0b0421d69d3fc32f95fd3659 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Sat, 25 May 2024 17:33:52 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat=20:=20=EA=B0=80=EA=B2=8C=20=EB=8C=80?= =?UTF-8?q?=ED=91=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=8A=A4=EC=BC=80?= =?UTF-8?q?=EC=A4=84=EB=A7=81=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gusto/.idea/uiDesigner.xml | 124 ++++++++++++++++++ .../java/com/umc/gusto/GustoApplication.java | 2 + .../response/PinByMyCategoryResponse.java | 4 +- .../service/MyCategoryServiceImpl.java | 16 ++- .../domain/review/entity/ReviewImages.java | 34 +++++ .../repository/ReviewImagesRepository.java | 9 ++ .../review/repository/ReviewRepository.java | 4 +- .../service/ReviewImageServiceImpl.java | 48 +++++++ .../store/service/StoreServiceImpl.java | 21 ++- 9 files changed, 241 insertions(+), 21 deletions(-) create mode 100644 gusto/.idea/uiDesigner.xml create mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java create mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java create mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java diff --git a/gusto/.idea/uiDesigner.xml b/gusto/.idea/uiDesigner.xml new file mode 100644 index 000000000..2b63946d5 --- /dev/null +++ b/gusto/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gusto/src/main/java/com/umc/gusto/GustoApplication.java b/gusto/src/main/java/com/umc/gusto/GustoApplication.java index a2c8fd69e..2293b6ac7 100644 --- a/gusto/src/main/java/com/umc/gusto/GustoApplication.java +++ b/gusto/src/main/java/com/umc/gusto/GustoApplication.java @@ -3,8 +3,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableScheduling; @EnableJpaAuditing +@EnableScheduling @SpringBootApplication public class GustoApplication { diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java index d49d8808d..882cddd2a 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java @@ -5,6 +5,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + @Builder @Getter @NoArgsConstructor @@ -14,6 +16,6 @@ public class PinByMyCategoryResponse{ Long storeId; String storeName; String address; - String reviewImg; + List reviewImg3; Integer reviewCnt; } \ No newline at end of file diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index 9dd458aac..be4b43946 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -9,7 +9,8 @@ import com.umc.gusto.domain.myCategory.model.response.PinByMyCategoryResponse; import com.umc.gusto.domain.myCategory.repository.MyCategoryRepository; import com.umc.gusto.domain.myCategory.repository.PinRepository; -import com.umc.gusto.domain.review.entity.Review; +import com.umc.gusto.domain.review.entity.ReviewImages; +import com.umc.gusto.domain.review.repository.ReviewImagesRepository; import com.umc.gusto.domain.review.repository.ReviewRepository; import com.umc.gusto.domain.store.entity.Store; import com.umc.gusto.domain.user.entity.User; @@ -20,6 +21,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service; @@ -29,12 +31,14 @@ @Service @RequiredArgsConstructor +@EnableScheduling public class MyCategoryServiceImpl implements MyCategoryService { private final MyCategoryRepository myCategoryRepository; private final PinRepository pinRepository; private final ReviewRepository reviewRepository; private final UserRepository userRepository; + private final ReviewImagesRepository reviewImagesRepository; private static final int MY_CATEGORY_PAGE_SIZE = 7; private static final int PIN_PAGE_SIZE = 5; @@ -163,16 +167,17 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC List result = pinList.stream() // townName을 기준으로 보일 수 있는 store가 포함된 pin만 보이기 .map(pin -> { Store store = pin.getStore(); - Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(store); // 가장 좋아요가 많은 review - String reviewImg = topReviewOptional.map(Review::getImg1).orElse(""); // 가장 좋아요가 많은 review 이미지(TO DO: 3개 출력으로 변경) - Integer reviewCnt = reviewRepository.countByStoreAndUserNickname(store, finalUser.getNickname()); // 내가 작성한 리뷰의 개수 == 방문 횟수 + // 가장 좋아요가 많은 review + ReviewImages reviewImages = reviewImagesRepository.findByStore(store); // 가장 좋아요가 많은 review 이미지 3개 + List top3ReviewImages = reviewImages.getReviewImgList().subList(0, Math.min(3, reviewImages.getReviewImgList().size())); // 리뷰 이미지 리스트의 크기가 3개보다 작을 경우에도 인덱스 오류를 방지하 + Integer reviewCnt = reviewRepository.countByStoreAndUserNickname(store, finalUser.getNickname()); // 내가 작성한 리뷰의 개수 == 방문 횟수 return PinByMyCategoryResponse.builder() .pinId(pin.getPinId()) .storeId(store.getStoreId()) .storeName(store.getStoreName()) .address(store.getAddress()) - .reviewImg(reviewImg) + .reviewImg3(top3ReviewImages) .reviewCnt(reviewCnt) .build(); }) @@ -184,6 +189,7 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC .build(); } + @Transactional public void createMyCategory(User user, CreateMyCategoryRequest createMyCategory) { // 중복 이름 체크 diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java b/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java new file mode 100644 index 000000000..45ae373dc --- /dev/null +++ b/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java @@ -0,0 +1,34 @@ +package com.umc.gusto.domain.review.entity; + +import com.umc.gusto.domain.store.entity.Store; +import com.umc.gusto.global.common.BaseTime; +import jakarta.persistence.*; +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class ReviewImages extends BaseTime { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "reviewImagesId") + private Long id; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "storeId") + private Store store; + + @ElementCollection(fetch = FetchType.LAZY) + @JoinTable(name = "reviewImgList", joinColumns = @JoinColumn(name = "reviewImgListId")) + private List reviewImgList = new ArrayList<>(); + + public void updateReviewImgList(List reviewImgList) { + this.reviewImgList = reviewImgList; + } + +} diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java new file mode 100644 index 000000000..9e4c1772b --- /dev/null +++ b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java @@ -0,0 +1,9 @@ +package com.umc.gusto.domain.review.repository; + +import com.umc.gusto.domain.review.entity.ReviewImages; +import com.umc.gusto.domain.store.entity.Store; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReviewImagesRepository extends JpaRepository { + ReviewImages findByStore(Store store); +} diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java index f358010c7..44ccf99c6 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java @@ -19,8 +19,8 @@ public interface ReviewRepository extends JpaRepository { @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC LIMIT 1") Optional findFirstByStoreOrderByLikedDesc(Store store); - @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 3") - List findFirst3ByStoreOrderByLikedDesc(Store store); +// @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 3") +// List findFirst3ByStoreOrderByLikedDesc(Store store); @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 4") List findFirst4ByStoreOrderByLikedDesc(Store store); @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.visitedAt DESC, r.reviewId DESC") diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java new file mode 100644 index 000000000..dd4cc29c9 --- /dev/null +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java @@ -0,0 +1,48 @@ +package com.umc.gusto.domain.review.service; + +import com.umc.gusto.domain.review.entity.Review; +import com.umc.gusto.domain.review.entity.ReviewImages; +import com.umc.gusto.domain.review.repository.ReviewImagesRepository; +import com.umc.gusto.domain.review.repository.ReviewRepository; +import com.umc.gusto.domain.store.entity.Store; +import com.umc.gusto.domain.store.repository.StoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ReviewImageServiceImpl { + private final StoreRepository storeRepository; + private final ReviewRepository reviewRepository; + private final ReviewImagesRepository reviewImagesRepository; + + @Transactional + @Scheduled(cron = "0 0 0 * * MON") + public void updateStoreReviewImages() { + List stores = storeRepository.findAll(); + + for (Store store : stores) { + List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); + List reviewImages = top4Reviews.stream() + .map(Review::getImg1) + .collect(Collectors.toList()); + + ReviewImages storeReviewImages = reviewImagesRepository.findByStore(store); + + if (storeReviewImages == null) { + storeReviewImages = ReviewImages.builder() + .store(store) + .reviewImgList(reviewImages) + .build(); + } else { + storeReviewImages.updateReviewImgList(reviewImages); + } + reviewImagesRepository.save(storeReviewImages); + } + } +} diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index ee83a0990..f306e6aae 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -3,6 +3,8 @@ import com.umc.gusto.domain.myCategory.entity.Pin; import com.umc.gusto.domain.myCategory.repository.PinRepository; import com.umc.gusto.domain.review.entity.Review; +import com.umc.gusto.domain.review.entity.ReviewImages; +import com.umc.gusto.domain.review.repository.ReviewImagesRepository; import com.umc.gusto.domain.review.repository.ReviewRepository; import com.umc.gusto.domain.store.entity.OpeningHours; import com.umc.gusto.domain.store.entity.Store; @@ -30,6 +32,7 @@ public class StoreServiceImpl implements StoreService{ private final ReviewRepository reviewRepository; private final PinRepository pinRepository; private final OpeningHoursRepository openingHoursRepository; + private final ReviewImagesRepository reviewImagesRepository; private static final int PAGE_SIZE_FIRST = 3; private static final int PAGE_SIZE = 6; @@ -39,6 +42,8 @@ public List getStores(User user, List storeIds) { for (Long storeId : storeIds) { Store store = storeRepository.findById(storeId) .orElseThrow(() -> new GeneralException(Code.STORE_NOT_FOUND)); + ReviewImages reviewImages = reviewImagesRepository.findByStore(store); + List top3ReviewImages = reviewImages.getReviewImgList().subList(0, Math.min(3, reviewImages.getReviewImgList().size())); Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); List openingHoursList = openingHoursRepository.findByStoreStoreId(storeId); @@ -50,12 +55,6 @@ public List getStores(User user, List storeIds) { ); businessDays.put(openingHours.getBusinessDay(), timing); } - - List top3Reviews = reviewRepository.findFirst3ByStoreOrderByLikedDesc(store); - - List reviewImg = top3Reviews.stream() - .map(review -> Optional.ofNullable(review.getImg1()).orElse("")) - .collect(Collectors.toList()); boolean isPinned = pinRepository.existsByUserAndStoreStoreId(user, storeId); @@ -67,7 +66,7 @@ public List getStores(User user, List storeIds) { .longitude(store.getLongitude()) .latitude(store.getLatitude()) .businessDay(businessDays) - .reviewImg3(reviewImg) + .reviewImg3(top3ReviewImages) .pin(isPinned) .build()); } @@ -85,11 +84,7 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate // .orElseThrow(() -> new GeneralException(Code.CATEGORY_NOT_FOUND)); Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); - List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); - - List reviewImg = top4Reviews.stream() - .map(review -> Optional.ofNullable(review.getImg1()).orElse("")) - .collect(Collectors.toList()); + ReviewImages reviewImages = reviewImagesRepository.findByStore(store); // reviews 페이징 처리 (3,6,6...) int pageSize; @@ -129,7 +124,7 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate .categoryString(store.getCategoryString()) .storeName(store.getStoreName()) .address(store.getAddress()) - .reviewImg4(reviewImg) + .reviewImg4(reviewImages.getReviewImgList()) .pin(isPinned) .reviews(PagingResponse.builder() .hasNext(reviews.hasNext()) From aef5c8f4671cd00871fd7c22ee737a182283a5f4 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Wed, 26 Jun 2024 02:34:00 +0900 Subject: [PATCH 2/7] =?UTF-8?q?refactor=20:=20@Builder.Default=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=B4=20=EC=B4=88=EA=B8=B0=ED=99=94=20?= =?UTF-8?q?=ED=91=9C=ED=98=84=EC=8B=9D=20=EA=B8=B0=EB=B3=B8=EA=B0=92?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/umc/gusto/domain/review/entity/ReviewImages.java | 1 + 1 file changed, 1 insertion(+) diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java b/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java index 45ae373dc..c013a9f6c 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java @@ -23,6 +23,7 @@ public class ReviewImages extends BaseTime { @JoinColumn(name = "storeId") private Store store; + @Builder.Default @ElementCollection(fetch = FetchType.LAZY) @JoinTable(name = "reviewImgList", joinColumns = @JoinColumn(name = "reviewImgListId")) private List reviewImgList = new ArrayList<>(); From 0f6644f1b04e2df26427cc3a79478acc7fff7e55 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Thu, 27 Jun 2024 02:37:42 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor=20:=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EA=B3=BC=EB=B6=80=ED=99=94=EB=A5=BC=20=EB=A7=89=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=20=EC=8A=A4=EC=BC=80=EC=A5=B4=EB=A7=81=20?= =?UTF-8?q?=EB=A7=A4=EC=9B=94=201,16=EC=9D=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/gusto/domain/review/service/ReviewImageServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java index dd4cc29c9..083060408 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java @@ -22,7 +22,7 @@ public class ReviewImageServiceImpl { private final ReviewImagesRepository reviewImagesRepository; @Transactional - @Scheduled(cron = "0 0 0 * * MON") + @Scheduled(cron = "0 0 0 1,16 * ?") public void updateStoreReviewImages() { List stores = storeRepository.findAll(); From cbaa539ee72c1b54992fbe9ad3814456375010af Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Thu, 27 Jun 2024 03:34:44 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refactor=20:=20ReviewImages=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=ED=9B=84=20store=EC=97=90=EC=84=9C=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/PinByMyCategoryResponse.java | 3 ++ .../service/MyCategoryServiceImpl.java | 10 ++-- .../domain/review/entity/ReviewImages.java | 35 -------------- .../repository/ReviewImagesRepository.java | 9 ---- .../service/ReviewImageServiceImpl.java | 48 ------------------- .../umc/gusto/domain/store/entity/Store.java | 27 +++++++++++ .../response/GetStoreDetailResponse.java | 5 +- .../model/response/GetStoreResponse.java | 4 +- .../store/service/StoreServiceImpl.java | 34 +++++++++---- 9 files changed, 66 insertions(+), 109 deletions(-) delete mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java delete mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java delete mode 100644 gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java index 882cddd2a..2789b3be7 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/model/response/PinByMyCategoryResponse.java @@ -17,5 +17,8 @@ public class PinByMyCategoryResponse{ String storeName; String address; List reviewImg3; + String img1; + String img2; + String img3; Integer reviewCnt; } \ No newline at end of file diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index be4b43946..95fa7e46a 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -9,8 +9,6 @@ import com.umc.gusto.domain.myCategory.model.response.PinByMyCategoryResponse; import com.umc.gusto.domain.myCategory.repository.MyCategoryRepository; import com.umc.gusto.domain.myCategory.repository.PinRepository; -import com.umc.gusto.domain.review.entity.ReviewImages; -import com.umc.gusto.domain.review.repository.ReviewImagesRepository; import com.umc.gusto.domain.review.repository.ReviewRepository; import com.umc.gusto.domain.store.entity.Store; import com.umc.gusto.domain.user.entity.User; @@ -38,7 +36,6 @@ public class MyCategoryServiceImpl implements MyCategoryService { private final PinRepository pinRepository; private final ReviewRepository reviewRepository; private final UserRepository userRepository; - private final ReviewImagesRepository reviewImagesRepository; private static final int MY_CATEGORY_PAGE_SIZE = 7; private static final int PIN_PAGE_SIZE = 5; @@ -168,8 +165,7 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC .map(pin -> { Store store = pin.getStore(); // 가장 좋아요가 많은 review - ReviewImages reviewImages = reviewImagesRepository.findByStore(store); // 가장 좋아요가 많은 review 이미지 3개 - List top3ReviewImages = reviewImages.getReviewImgList().subList(0, Math.min(3, reviewImages.getReviewImgList().size())); // 리뷰 이미지 리스트의 크기가 3개보다 작을 경우에도 인덱스 오류를 방지하 + Integer reviewCnt = reviewRepository.countByStoreAndUserNickname(store, finalUser.getNickname()); // 내가 작성한 리뷰의 개수 == 방문 횟수 return PinByMyCategoryResponse.builder() @@ -177,7 +173,9 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC .storeId(store.getStoreId()) .storeName(store.getStoreName()) .address(store.getAddress()) - .reviewImg3(top3ReviewImages) + .img1(store.getImg1()) + .img2(store.getImg2()) + .img3(store.getImg3()) .reviewCnt(reviewCnt) .build(); }) diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java b/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java deleted file mode 100644 index c013a9f6c..000000000 --- a/gusto/src/main/java/com/umc/gusto/domain/review/entity/ReviewImages.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.umc.gusto.domain.review.entity; - -import com.umc.gusto.domain.store.entity.Store; -import com.umc.gusto.global.common.BaseTime; -import jakarta.persistence.*; -import lombok.*; - -import java.util.ArrayList; -import java.util.List; - -@Entity -@Getter -@Builder -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor -public class ReviewImages extends BaseTime { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "reviewImagesId") - private Long id; - - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "storeId") - private Store store; - - @Builder.Default - @ElementCollection(fetch = FetchType.LAZY) - @JoinTable(name = "reviewImgList", joinColumns = @JoinColumn(name = "reviewImgListId")) - private List reviewImgList = new ArrayList<>(); - - public void updateReviewImgList(List reviewImgList) { - this.reviewImgList = reviewImgList; - } - -} diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java deleted file mode 100644 index 9e4c1772b..000000000 --- a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewImagesRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.umc.gusto.domain.review.repository; - -import com.umc.gusto.domain.review.entity.ReviewImages; -import com.umc.gusto.domain.store.entity.Store; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ReviewImagesRepository extends JpaRepository { - ReviewImages findByStore(Store store); -} diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java deleted file mode 100644 index 083060408..000000000 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewImageServiceImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.umc.gusto.domain.review.service; - -import com.umc.gusto.domain.review.entity.Review; -import com.umc.gusto.domain.review.entity.ReviewImages; -import com.umc.gusto.domain.review.repository.ReviewImagesRepository; -import com.umc.gusto.domain.review.repository.ReviewRepository; -import com.umc.gusto.domain.store.entity.Store; -import com.umc.gusto.domain.store.repository.StoreRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class ReviewImageServiceImpl { - private final StoreRepository storeRepository; - private final ReviewRepository reviewRepository; - private final ReviewImagesRepository reviewImagesRepository; - - @Transactional - @Scheduled(cron = "0 0 0 1,16 * ?") - public void updateStoreReviewImages() { - List stores = storeRepository.findAll(); - - for (Store store : stores) { - List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); - List reviewImages = top4Reviews.stream() - .map(Review::getImg1) - .collect(Collectors.toList()); - - ReviewImages storeReviewImages = reviewImagesRepository.findByStore(store); - - if (storeReviewImages == null) { - storeReviewImages = ReviewImages.builder() - .store(store) - .reviewImgList(reviewImages) - .build(); - } else { - storeReviewImages.updateReviewImgList(reviewImages); - } - reviewImagesRepository.save(storeReviewImages); - } - } -} diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/entity/Store.java b/gusto/src/main/java/com/umc/gusto/domain/store/entity/Store.java index 6cdc5cba9..e1a108c87 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/entity/Store.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/entity/Store.java @@ -7,6 +7,8 @@ import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; +import java.util.List; + @Entity @Getter @Builder @@ -58,6 +60,14 @@ public class Store extends BaseTime { @Column(columnDefinition = "VARCHAR(20)") private String contact; + private String img1; + + private String img2; + + private String img3; + + private String img4; + @Builder.Default @Enumerated(EnumType.STRING) @Column(name = "status", nullable = false, length = 10) @@ -66,5 +76,22 @@ public class Store extends BaseTime { public enum StoreStatus { ACTIVE, INACTIVE, CLOSED } + + public void updateImages(List reviewImages) { + // reviewImages 리스트에서 이미지를 가져와 각 필드에 할당 + if (!reviewImages.isEmpty()) { + this.img1 = reviewImages.get(0); + } + if (reviewImages.size() > 1) { + this.img2 = reviewImages.get(1); + } + if (reviewImages.size() > 2) { + this.img3 = reviewImages.get(2); + } + if (reviewImages.size() > 3) { + this.img4 = reviewImages.get(3); + } + } + } diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreDetailResponse.java b/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreDetailResponse.java index b86c9690e..276bfc6a6 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreDetailResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreDetailResponse.java @@ -20,7 +20,10 @@ public class GetStoreDetailResponse{ String storeName; String address; Boolean pin; // 찜 여부 - List reviewImg4; + String img1; + String img2; + String img3; + String img4; PagingResponse reviews; } diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreResponse.java b/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreResponse.java index f84760437..e217f367b 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreResponse.java @@ -25,7 +25,9 @@ public class GetStoreResponse{ Double latitude; Map businessDay; String contact; - List reviewImg3; + String img1; + String img2; + String img3; Boolean pin; // 찜 여부 // 하루 영업 시간을 나타내는 내부 클래스 diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index f306e6aae..356d3cb6f 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -3,8 +3,6 @@ import com.umc.gusto.domain.myCategory.entity.Pin; import com.umc.gusto.domain.myCategory.repository.PinRepository; import com.umc.gusto.domain.review.entity.Review; -import com.umc.gusto.domain.review.entity.ReviewImages; -import com.umc.gusto.domain.review.repository.ReviewImagesRepository; import com.umc.gusto.domain.review.repository.ReviewRepository; import com.umc.gusto.domain.store.entity.OpeningHours; import com.umc.gusto.domain.store.entity.Store; @@ -17,7 +15,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.PageRequest; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -32,7 +30,6 @@ public class StoreServiceImpl implements StoreService{ private final ReviewRepository reviewRepository; private final PinRepository pinRepository; private final OpeningHoursRepository openingHoursRepository; - private final ReviewImagesRepository reviewImagesRepository; private static final int PAGE_SIZE_FIRST = 3; private static final int PAGE_SIZE = 6; @@ -42,8 +39,6 @@ public List getStores(User user, List storeIds) { for (Long storeId : storeIds) { Store store = storeRepository.findById(storeId) .orElseThrow(() -> new GeneralException(Code.STORE_NOT_FOUND)); - ReviewImages reviewImages = reviewImagesRepository.findByStore(store); - List top3ReviewImages = reviewImages.getReviewImgList().subList(0, Math.min(3, reviewImages.getReviewImgList().size())); Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); List openingHoursList = openingHoursRepository.findByStoreStoreId(storeId); @@ -66,7 +61,9 @@ public List getStores(User user, List storeIds) { .longitude(store.getLongitude()) .latitude(store.getLatitude()) .businessDay(businessDays) - .reviewImg3(top3ReviewImages) + .img1(store.getImg1()) + .img2(store.getImg2()) + .img3(store.getImg3()) .pin(isPinned) .build()); } @@ -84,7 +81,7 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate // .orElseThrow(() -> new GeneralException(Code.CATEGORY_NOT_FOUND)); Long pinId = pinRepository.findByUserAndStoreStoreId(user, storeId); - ReviewImages reviewImages = reviewImagesRepository.findByStore(store); + // reviews 페이징 처리 (3,6,6...) int pageSize; @@ -124,7 +121,10 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate .categoryString(store.getCategoryString()) .storeName(store.getStoreName()) .address(store.getAddress()) - .reviewImg4(reviewImages.getReviewImgList()) + .img1(store.getImg1()) + .img2(store.getImg2()) + .img3(store.getImg3()) + .img4(store.getImg4()) .pin(isPinned) .reviews(PagingResponse.builder() .hasNext(reviews.hasNext()) @@ -237,4 +237,20 @@ public List searchStore(String keyword) { }) .collect(Collectors.toList()); } + + @Transactional + @Scheduled(cron = "0 0 0 1,16 * ?") + public void updateStoreReviewImages() { + List stores = storeRepository.findAll(); + + for (Store store : stores) { + List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); + List reviewImages = top4Reviews.stream() + .map(Review::getImg1) + .collect(Collectors.toList()); + + store.updateImages(reviewImages); + storeRepository.save(store); + } + } } From 816921279b5d5a4bd13b466463ac78501e9b4fc2 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Thu, 27 Jun 2024 03:48:23 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor=20:=20img=EA=B0=80=20null=EC=9D=B8?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=20=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/MyCategoryServiceImpl.java | 6 ++--- .../store/service/StoreServiceImpl.java | 22 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java index 95fa7e46a..b96aed382 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/myCategory/service/MyCategoryServiceImpl.java @@ -173,9 +173,9 @@ public PagingResponse getAllPinByMyCategory(User user, String nickname, Long myC .storeId(store.getStoreId()) .storeName(store.getStoreName()) .address(store.getAddress()) - .img1(store.getImg1()) - .img2(store.getImg2()) - .img3(store.getImg3()) + .img1(store.getImg1() != null ? store.getImg1() : "") + .img2(store.getImg2() != null ? store.getImg2() : "") + .img3(store.getImg3() != null ? store.getImg3() : "") .reviewCnt(reviewCnt) .build(); }) diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index 356d3cb6f..cc203954b 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -61,9 +61,9 @@ public List getStores(User user, List storeIds) { .longitude(store.getLongitude()) .latitude(store.getLatitude()) .businessDay(businessDays) - .img1(store.getImg1()) - .img2(store.getImg2()) - .img3(store.getImg3()) + .img1(store.getImg1() != null ? store.getImg1() : "") + .img2(store.getImg2() != null ? store.getImg2() : "") + .img3(store.getImg3() != null ? store.getImg3() : "") .pin(isPinned) .build()); } @@ -105,10 +105,10 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate .nickname(reviewer.getNickname()) .liked(review.getLiked()) .comment(review.getComment()) - .img1(review.getImg1()) - .img2(review.getImg2()) - .img3(review.getImg3()) - .img4(review.getImg4()) + .img1(review.getImg1() != null ? review.getImg1() : "") + .img2(review.getImg2() != null ? review.getImg2() : "") + .img3(review.getImg3() != null ? review.getImg1() : "") + .img4(review.getImg4() != null ? review.getImg1() : "") .build(); }) .toList(); @@ -121,10 +121,10 @@ public GetStoreDetailResponse getStoreDetail(User user, Long storeId, LocalDate .categoryString(store.getCategoryString()) .storeName(store.getStoreName()) .address(store.getAddress()) - .img1(store.getImg1()) - .img2(store.getImg2()) - .img3(store.getImg3()) - .img4(store.getImg4()) + .img1(store.getImg1() != null ? store.getImg1() : "") + .img2(store.getImg2() != null ? store.getImg2() : "") + .img3(store.getImg3() != null ? store.getImg3() : "") + .img4(store.getImg4() != null ? store.getImg4() : "") .pin(isPinned) .reviews(PagingResponse.builder() .hasNext(reviews.hasNext()) From e203ce63b32bfbb0b9715b8822ed7cd346a853b7 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Sat, 6 Jul 2024 14:37:08 +0900 Subject: [PATCH 6/7] =?UTF-8?q?refactor=20:=20=EA=B0=80=EA=B2=8C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=8A=A4=EC=BC=80=EC=A4=84?= =?UTF-8?q?=EB=A7=81=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20=EA=B7=B8?= =?UTF-8?q?=EB=A3=B9,=20=EA=B0=80=EA=B2=8C=20service=20=EB=B3=80=EA=B2=BD(?= =?UTF-8?q?reviewImg=20->=20img1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/gusto/domain/group/service/GroupServiceImpl.java | 4 +--- .../gusto/domain/review/repository/ReviewRepository.java | 4 ++-- .../domain/store/model/response/GetStoreInfoResponse.java | 2 +- .../umc/gusto/domain/store/service/StoreServiceImpl.java | 8 ++------ 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java index 798abf885..d1681a7bc 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/group/service/GroupServiceImpl.java @@ -360,13 +360,11 @@ public PagingResponse getAllGroupList(Long groupId, Long groupListId) { // 그룹 리스트에 해당하는 각 상점 정보 조회 List list = groupLists.stream().map(gl -> { - Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(gl.getStore()); // 가장 좋아요가 많은 review - String reviewImg = topReviewOptional.map(Review::getImg1).orElse(""); return GroupListResponse.builder() .groupListId(gl.getGroupListId()) .storeId(gl.getStore().getStoreId()) .storeName(gl.getStore().getStoreName()) - .storeProfileImg(reviewImg) + .storeProfileImg(gl.getStore().getImg1() != null ? gl.getStore().getImg1() : "") .userProfileImg(gl.getUser().getProfileImage()) .address(gl.getStore().getAddress()) .build(); diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java index 44ccf99c6..f358010c7 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/repository/ReviewRepository.java @@ -19,8 +19,8 @@ public interface ReviewRepository extends JpaRepository { @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC LIMIT 1") Optional findFirstByStoreOrderByLikedDesc(Store store); -// @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 3") -// List findFirst3ByStoreOrderByLikedDesc(Store store); + @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 3") + List findFirst3ByStoreOrderByLikedDesc(Store store); @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.liked DESC, r.reviewId DESC LIMIT 4") List findFirst4ByStoreOrderByLikedDesc(Store store); @Query("SELECT r FROM Review r WHERE r.status = 'ACTIVE' AND r.user.publishReview = 'PUBLIC' AND r.store = :store ORDER BY r.visitedAt DESC, r.reviewId DESC") diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreInfoResponse.java b/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreInfoResponse.java index d7539ba5c..a0982abe6 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreInfoResponse.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/model/response/GetStoreInfoResponse.java @@ -14,5 +14,5 @@ public class GetStoreInfoResponse { String categoryString; String storeName; String address; - String reviewImg; + String img1; } \ No newline at end of file diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index cc203954b..47d0ec452 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -178,8 +178,6 @@ public List getPinStoresByCategoryAndLocation(User user, Lo for (Pin pin : pins){ Store store = pin.getStore(); - Optional topReviewOptional = reviewRepository.findFirstByStoreOrderByLikedDesc(store); - String reviewImg = topReviewOptional.map(Review::getImg1).orElse(""); boolean hasVisited = reviewRepository.existsByStoreAndUserNickname(store, user.getNickname()); GetStoreInfoResponse getStoreInfoResponse = GetStoreInfoResponse.builder() @@ -187,7 +185,7 @@ public List getPinStoresByCategoryAndLocation(User user, Lo .categoryString(store.getCategoryString()) .storeName(store.getStoreName()) .address(store.getAddress()) - .reviewImg(reviewImg) + .img1(store.getImg1() != null ? store.getImg1() : "") .build(); if(!hasVisited){ @@ -225,14 +223,12 @@ public List searchStore(String keyword) { return searchResult.stream() .map(result -> { - Optional review = reviewRepository.findFirstByStoreOrderByLikedDesc(result); - String reviewImg = review.map(Review::getImg1).orElse(""); return GetStoreInfoResponse.builder() .storeId(result.getStoreId()) .storeName(result.getStoreName()) .categoryString(result.getCategoryString()) .address(result.getAddress()) - .reviewImg(reviewImg) + .img1(result.getImg1() != null ? result.getImg1() : "") .build(); }) .collect(Collectors.toList()); From eb81773994d9efed642f8a60efbf8a2db198fd84 Mon Sep 17 00:00:00 2001 From: kchaeeun Date: Wed, 10 Jul 2024 00:29:46 +0900 Subject: [PATCH 7/7] =?UTF-8?q?refactor=20:=20=EA=B0=80=EA=B2=8C=20?= =?UTF-8?q?=EB=8C=80=ED=91=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=95=9C?= =?UTF-8?q?=EA=B0=9C=20=EA=B0=B1=EC=8B=A0=20=EB=8B=B9=20=ED=95=98=EB=82=98?= =?UTF-8?q?=EC=9D=98=20=ED=8A=B8=EB=9E=9C=EC=9E=AD=EC=85=98=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/service/ReviewService.java | 2 ++ .../domain/review/service/ReviewServiceImpl.java | 15 ++++++++++++++- .../domain/store/service/StoreServiceImpl.java | 16 +++++++--------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewService.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewService.java index cfd7e8134..e9e293f7c 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewService.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewService.java @@ -3,6 +3,7 @@ import com.umc.gusto.domain.review.model.request.CreateReviewRequest; import com.umc.gusto.domain.review.model.request.UpdateReviewRequest; import com.umc.gusto.domain.review.model.response.ReviewDetailResponse; +import com.umc.gusto.domain.store.entity.Store; import com.umc.gusto.domain.user.entity.User; import org.springframework.web.multipart.MultipartFile; @@ -16,4 +17,5 @@ public interface ReviewService { ReviewDetailResponse getReview(Long reviewId); void likeReview(User user, Long reviewId); void unlikeReview(User user, Long reviewId); + void updateStoreImages(Store store); } diff --git a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java index be947273a..6859c14c9 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/review/service/ReviewServiceImpl.java @@ -22,15 +22,17 @@ import com.umc.gusto.global.exception.customException.NotFoundException; import com.umc.gusto.global.exception.customException.PrivateItemException; import com.umc.gusto.global.util.S3Service; -import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import org.springframework.transaction.annotation.Propagation; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -216,4 +218,15 @@ private void updateImages(List images, Review review){ if(imageUrls.size()>3) review.updateImg4(imageUrls.get(3)); } + @Transactional(propagation = Propagation.REQUIRES_NEW) // 메소드가 호출될 때마다 새로운 트랜잭션이 시작됨을 의미 + public void updateStoreImages(Store store) { + List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); + List reviewImages = top4Reviews.stream() + .map(Review::getImg1) + .collect(Collectors.toList()); + + store.updateImages(reviewImages); + storeRepository.save(store); + } + } diff --git a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java index 47d0ec452..ea4239e9a 100644 --- a/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java +++ b/gusto/src/main/java/com/umc/gusto/domain/store/service/StoreServiceImpl.java @@ -4,6 +4,7 @@ import com.umc.gusto.domain.myCategory.repository.PinRepository; import com.umc.gusto.domain.review.entity.Review; import com.umc.gusto.domain.review.repository.ReviewRepository; +import com.umc.gusto.domain.review.service.ReviewService; import com.umc.gusto.domain.store.entity.OpeningHours; import com.umc.gusto.domain.store.entity.Store; import com.umc.gusto.domain.store.model.response.*; @@ -30,6 +31,8 @@ public class StoreServiceImpl implements StoreService{ private final ReviewRepository reviewRepository; private final PinRepository pinRepository; private final OpeningHoursRepository openingHoursRepository; + private final ReviewService reviewService; + private static final int PAGE_SIZE_FIRST = 3; private static final int PAGE_SIZE = 6; @@ -234,19 +237,14 @@ public List searchStore(String keyword) { .collect(Collectors.toList()); } - @Transactional + // @Scheduled(cron = "0 0 0 1,16 * ?") - public void updateStoreReviewImages() { + public void updateAllStoreImages() { List stores = storeRepository.findAll(); for (Store store : stores) { - List top4Reviews = reviewRepository.findFirst4ByStoreOrderByLikedDesc(store); - List reviewImages = top4Reviews.stream() - .map(Review::getImg1) - .collect(Collectors.toList()); - - store.updateImages(reviewImages); - storeRepository.save(store); + reviewService.updateStoreImages(store); } } + }