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 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(); } 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(); } } 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(); } } 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(); + } +} 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();