From 7eeb91a02a8cf95fee660cfe8c996f7974cd599e Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Tue, 29 Jul 2025 12:07:39 +0900 Subject: [PATCH 1/6] =?UTF-8?q?refactor(Reservation):=20bookmarkedSet=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applicationuser/bookmark/service/BookmarkService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/bookmark/service/BookmarkService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/bookmark/service/BookmarkService.java index 63436967..e5fe86c8 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/bookmark/service/BookmarkService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/bookmark/service/BookmarkService.java @@ -1,7 +1,9 @@ package com.nowait.applicationuser.bookmark.service; +import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -60,7 +62,9 @@ public List getBookmarks(CustomOAuth2User customOAuth2User) { .map(Store::getStoreId) .toList(); - return storeService.getAllStoresByPageAndDeparments(storeIds); + Set bookmarkedSet = new HashSet<>(storeIds); + + return storeService.getAllStoresByPageAndDeparments(storeIds, bookmarkedSet); } @Transactional From 264fd3d5d28832ec4de67ad6e367b2a37cacfdc0 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Tue, 29 Jul 2025 12:09:33 +0900 Subject: [PATCH 2/6] =?UTF-8?q?refactor(Reservation):=20StorePageReadDto?= =?UTF-8?q?=EB=A5=BC=20StorePageReadResponse=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/dto/StoreDepartmentReadResponse.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java index fe04584f..e052524b 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDepartmentReadResponse.java @@ -11,12 +11,12 @@ @Builder public class StoreDepartmentReadResponse { - private List storePageReadDtos; + private List storePageReadDtos; private boolean hasNext; - public static StoreDepartmentReadResponse of(List storePageReadDtos, boolean hasNext) { + public static StoreDepartmentReadResponse of(List storePageReadResponses, boolean hasNext) { return StoreDepartmentReadResponse.builder() - .storePageReadDtos(storePageReadDtos) + .storePageReadDtos(storePageReadResponses) .hasNext(hasNext) .build(); } From dcea2a4ab72f0d17dd8adb72d5453f8e9333510f Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Tue, 29 Jul 2025 12:10:37 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor(Reservation):=20fromEntity?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/dto/StoreDetailReadResponse.java | 43 +++---------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDetailReadResponse.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDetailReadResponse.java index 3ccf1674..c40550e7 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDetailReadResponse.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDetailReadResponse.java @@ -15,6 +15,7 @@ @Builder public class StoreDetailReadResponse { private Long storeId; + private Boolean isBookmark; private Long waitingCount; private Boolean isWaiting; private Long departmentId; @@ -29,9 +30,10 @@ public class StoreDetailReadResponse { private Boolean isActive; private Boolean deleted; private LocalDateTime createdAt; - private Boolean isBookmarked; - public static StoreDetailReadResponse fromEntity(Store store, List allImages, String departmentName, Long waitingCount, Boolean isWaiting) { + public static StoreDetailReadResponse fromEntity( + Store store, List allImages, String departmentName, Long waitingCount, Boolean isBookmark, Boolean isWaiting + ) { StoreImageUploadResponse profile = allImages.stream() .filter(image -> image.getImageType() == ImageType.PROFILE) @@ -43,8 +45,8 @@ public static StoreDetailReadResponse fromEntity(Store store, List allImages, String departmentName, Long waitingCount, Boolean isBookmarked, Boolean isWaiting - ) { - - StoreImageUploadResponse profile = allImages.stream() - .filter(image -> image.getImageType() == ImageType.PROFILE) - .findFirst() - .orElse(null); - - List banners = allImages.stream() - .filter(image -> image.getImageType() == ImageType.BANNER) - .toList(); - - return StoreDetailReadResponse.builder() - .createdAt(store.getCreatedAt()) - .storeId(store.getStoreId()) - .waitingCount(waitingCount) - .isWaiting(isWaiting) - .departmentId(store.getDepartmentId()) - .departmentName(departmentName) - .name(store.getName()) - .location(store.getLocation()) - .description(store.getDescription()) - .notice(store.getNotice()) - .openTime(store.getOpenTime()) .isActive(store.getIsActive()) .deleted(store.getDeleted()) - .profileImage(profile) - .bannerImages(banners) - .isBookmarked(isBookmarked) + .createdAt(store.getCreatedAt()) .build(); } } From 6c6c0a494e5f7050a0c20ae7106498e589bfa9a7 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Tue, 29 Jul 2025 12:10:43 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor(Reservation):=20fromEntity?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/dto/StorePageReadDto.java | 40 ++----------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java index bae989be..05b3b280 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadDto.java @@ -15,6 +15,7 @@ @Builder public class StorePageReadDto { private Long storeId; + private Boolean isBookmark; private Long waitingCount; private Long departmentId; private String departmentName; @@ -28,9 +29,8 @@ public class StorePageReadDto { private Boolean isActive; private Boolean deleted; private LocalDateTime createdAt; - private Boolean isBookmarked; - public static StorePageReadDto fromEntity(Store store, List allImages, String departmentName, Long waitingCount) { + public static StorePageReadDto fromEntity(Store store, List allImages, String departmentName, Long waitingCount, Boolean isBookmark) { StoreImageUploadResponse profile = allImages.stream() .filter(image -> image.getImageType() == ImageType.PROFILE) @@ -42,8 +42,8 @@ public static StorePageReadDto fromEntity(Store store, List allImages, String departmentName, Long waitingCount, Boolean isBookmarked - ) { - - StoreImageUploadResponse profile = allImages.stream() - .filter(image -> image.getImageType() == ImageType.PROFILE) - .findFirst() - .orElse(null); - - List banners = allImages.stream() - .filter(image -> image.getImageType() == ImageType.BANNER) - .toList(); - - return StorePageReadDto.builder() - .createdAt(store.getCreatedAt()) - .storeId(store.getStoreId()) - .waitingCount(waitingCount) - .departmentId(store.getDepartmentId()) - .departmentName(departmentName) - .name(store.getName()) - .location(store.getLocation()) - .description(store.getDescription()) - .notice(store.getNotice()) - .openTime(store.getOpenTime()) .isActive(store.getIsActive()) .deleted(store.getDeleted()) - .profileImage(profile) - .bannerImages(banners) - .isBookmarked(isBookmarked) + .createdAt(store.getCreatedAt()) .build(); } } From 42743741ea05ff81ad61263f9f3d25d2ffd6a960 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Tue, 29 Jul 2025 12:10:54 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor(Reservation):=20StorePageReadRespo?= =?UTF-8?q?nse=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/dto/StorePageReadResponse.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadResponse.java diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadResponse.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadResponse.java new file mode 100644 index 00000000..6066f75e --- /dev/null +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StorePageReadResponse.java @@ -0,0 +1,60 @@ +package com.nowait.applicationuser.store.dto; + +import java.time.LocalDateTime; +import java.util.List; + +import com.nowait.domaincorerdb.store.entity.ImageType; +import com.nowait.domaincorerdb.store.entity.Store; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@AllArgsConstructor +@Builder +public class StorePageReadResponse { + private Long storeId; + private Long waitingCount; + private Long departmentId; + private String departmentName; + private String name; + private String location; + private String description; + private String notice; + private String openTime; + private StoreImageUploadResponse profileImage; + private List bannerImages; + private Boolean isActive; + private Boolean deleted; + private LocalDateTime createdAt; + + public static StorePageReadResponse fromEntity(Store store, List allImages, String departmentName, Long waitingCount) { + + StoreImageUploadResponse profile = allImages.stream() + .filter(image -> image.getImageType() == ImageType.PROFILE) + .findFirst() + .orElse(null); + + List banners = allImages.stream() + .filter(image -> image.getImageType() == ImageType.BANNER) + .toList(); + + return StorePageReadResponse.builder() + .storeId(store.getStoreId()) + .waitingCount(waitingCount) + .departmentId(store.getDepartmentId()) + .departmentName(departmentName) + .name(store.getName()) + .location(store.getLocation()) + .description(store.getDescription()) + .notice(store.getNotice()) + .openTime(store.getOpenTime()) + .profileImage(profile) + .bannerImages(banners) + .isActive(store.getIsActive()) + .deleted(store.getDeleted()) + .createdAt(store.getCreatedAt()) + .build(); + } +} From 0340240a0e7d22a38677f924df3b00ded49a3549 Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Tue, 29 Jul 2025 12:11:47 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor(Reservation):=20getAllStoresByPage?= =?UTF-8?q?AndDeparments=20=EB=82=B4=20Set=20bookmarkedSet=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/service/StoreService.java | 8 +++--- .../store/service/StoreServiceImpl.java | 27 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java index d7b450d7..7900d032 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreService.java @@ -1,14 +1,14 @@ package com.nowait.applicationuser.store.service; import java.util.List; +import java.util.Set; import org.springframework.data.domain.Pageable; import com.nowait.applicationuser.store.dto.StoreDepartmentReadResponse; import com.nowait.applicationuser.store.dto.StoreDetailReadResponse; import com.nowait.applicationuser.store.dto.StorePageReadDto; -import com.nowait.applicationuser.store.dto.StoreReadDto; -import com.nowait.applicationuser.store.dto.StoreReadResponse; +import com.nowait.applicationuser.store.dto.StorePageReadResponse; import com.nowait.applicationuser.store.dto.StoreWaitingInfo; import com.nowait.domainuserrdb.oauth.dto.CustomOAuth2User; @@ -18,9 +18,9 @@ public interface StoreService { StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User customOAuth2User); - List searchByKeywordNative(String name); + List searchByKeywordNative(String name); List getStoresByWaitingCount(boolean desc); - List getAllStoresByPageAndDeparments(List storeIds); + List getAllStoresByPageAndDeparments(List storeIds, Set bookmarkedSet); } diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java index 408c18d3..4743feb2 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/service/StoreServiceImpl.java @@ -5,6 +5,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -16,7 +17,6 @@ import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -25,6 +25,7 @@ import com.nowait.applicationuser.store.dto.StoreDetailReadResponse; import com.nowait.applicationuser.store.dto.StoreImageUploadResponse; import com.nowait.applicationuser.store.dto.StorePageReadDto; +import com.nowait.applicationuser.store.dto.StorePageReadResponse; import com.nowait.applicationuser.store.dto.StoreWaitingInfo; import com.nowait.domaincorerdb.department.entity.Department; import com.nowait.domaincorerdb.department.repository.DepartmentRepository; @@ -105,7 +106,7 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page )); // 5) Dto 매핑 - List content = stores.stream() + List content = stores.stream() .map(store -> { List imgs = imageMap .getOrDefault(store.getStoreId(), List.of()); @@ -113,7 +114,7 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page .getOrDefault(store.getDepartmentId(), "Unknown Department"); Long waitingCount = waitingSizeMap.getOrDefault(store.getStoreId(), 0L); - return StorePageReadDto.fromEntity(store, imgs, departmentName, waitingCount); + return StorePageReadResponse.fromEntity(store, imgs, departmentName, waitingCount); }) .toList(); @@ -136,6 +137,8 @@ public StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User .map(Department::getName) .orElse("Unknown Department"); + boolean isBookmark = bookmarkRepository.existsByUserAndStore(user, store); + // 2-1) Redis에서 각 Store의 웨이팅 사이즈 조회 String key = "waiting:" + storeId; long waitingSize = redisTemplate.opsForZSet().zCard(key); @@ -146,22 +149,16 @@ public StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User .map(StoreImageUploadResponse::fromEntity) .toList(); - if (bookmarkRepository.existsByUserAndStore(user, store)) { - return StoreDetailReadResponse.fromEntityWithBookmark(store, imageDto, departmentName, waitingSize, true, userWaiting); - } else { - return StoreDetailReadResponse.fromEntity(store, imageDto, departmentName, waitingSize, userWaiting); - } + return StoreDetailReadResponse.fromEntity(store, imageDto, departmentName, waitingSize, isBookmark, userWaiting); } @Override - public List searchByKeywordNative(String keyword) { + public List searchByKeywordNative(String keyword) { if (keyword == null || keyword.isBlank()) { throw new StoreParamEmptyException(); } // 1) 페이징된 Store 스냅샷 조회 - // Like 사용 - // List stores = storeRepository.findByNameContainingIgnoreCaseAndDeletedFalse(keyword); // 풀텍스트인덱스 사용 List stores = storeRepository.searchByKeywordNative(keyword); @@ -213,7 +210,7 @@ public List searchByKeywordNative(String keyword) { .getOrDefault(store.getDepartmentId(), "Unknown Department"); Long waitingCount = waitingSizeMap.getOrDefault(store.getStoreId(), 0L); - return StorePageReadDto.fromEntity(store, imgs, departmentName, waitingCount); + return StorePageReadResponse.fromEntity(store, imgs, departmentName, waitingCount); }) .toList(); } @@ -288,7 +285,7 @@ private RedisConnection getSafeConnection() { @Override @Transactional(readOnly = true) - public List getAllStoresByPageAndDeparments(List storeIds) { + public List getAllStoresByPageAndDeparments(List storeIds, Set bookmarkedSet) { // 1) 페이징된 Store 스냅샷 조회 List stores = storeRepository.findAllByStoreIdInOrderByStoreIdAsc(storeIds); @@ -339,7 +336,9 @@ public List getAllStoresByPageAndDeparments(List storeId .getOrDefault(store.getDepartmentId(), "Unknown Department"); Long waitingCount = waitingSizeMap.getOrDefault(store.getStoreId(), 0L); - return StorePageReadDto.fromEntity(store, imgs, departmentName, waitingCount); + boolean isBookmark = bookmarkedSet.contains(store.getStoreId()); + + return StorePageReadDto.fromEntity(store, imgs, departmentName, waitingCount, isBookmark); }) .toList();