From 5ef8c7357e5a4673221a50a8be80ca98c963005f Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 25 Jul 2025 21:15:35 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactor(Store):=20notice,=20openTime=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nowait/applicationuser/store/dto/StorePageReadDto.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 2d25e23e..bae989be 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 @@ -21,6 +21,8 @@ public class StorePageReadDto { private String name; private String location; private String description; + private String notice; + private String openTime; private StoreImageUploadResponse profileImage; private List bannerImages; private Boolean isActive; @@ -48,6 +50,8 @@ public static StorePageReadDto fromEntity(Store store, List Date: Fri, 25 Jul 2025 21:36:22 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor(Store):=20Store=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?StoreDetailReadResponse=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/dto/StoreDetailReadResponse.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDetailReadResponse.java 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 new file mode 100644 index 00000000..3ccf1674 --- /dev/null +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreDetailReadResponse.java @@ -0,0 +1,97 @@ +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 StoreDetailReadResponse { + private Long storeId; + private Long waitingCount; + private Boolean isWaiting; + 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; + private Boolean isBookmarked; + + public static StoreDetailReadResponse fromEntity(Store store, List allImages, String departmentName, Long waitingCount, 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(false) + .build(); + } + + public static StoreDetailReadResponse fromEntityWithBookmark( + 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) + .build(); + } +} From f29905194417b4e0c11e61b11ea2856621ed206a Mon Sep 17 00:00:00 2001 From: Jihun Kim Date: Fri, 25 Jul 2025 21:36:35 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor(Store):=20isWaiting=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/WaitingUserRedisRepository.java | 12 +++++++++++- .../store/service/StoreService.java | 3 ++- .../store/service/StoreServiceImpl.java | 17 ++++++++--------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java index 2b74fd1d..16c84901 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingUserRedisRepository.java @@ -35,17 +35,20 @@ public boolean addToWaitingQueue(Long storeId, String userId, Integer partySize, } return Boolean.TRUE.equals(added); } + // 예약한 사람이 등록한 동반인원(partySize) 조회 public Integer getPartySize(Long storeId, String userId) { String partyKey = RedisKeyUtils.buildWaitingPartySizeKeyPrefix() + storeId; Object value = redisTemplate.opsForHash().get(partyKey, userId); return Integer.valueOf(value.toString()); } + // 예약자 대기순위 조회 public Long getRank(Long storeId, String userId) { String key = RedisKeyUtils.buildWaitingKeyPrefix() + storeId; return redisTemplate.opsForZSet().rank(key, userId); } + // 예약 취소 public boolean removeWaiting(Long storeId, String userId) { String key = RedisKeyUtils.buildWaitingKeyPrefix() + storeId; @@ -56,6 +59,7 @@ public boolean removeWaiting(Long storeId, String userId) { redisTemplate.opsForHash().delete(statusKey, userId); return true; } + // 예약 등록 시간 public Long getWaitingTimestamp(Long storeId, String userId) { String key = RedisKeyUtils.buildWaitingKeyPrefix() + storeId; @@ -67,7 +71,8 @@ public Long getWaitingTimestamp(Long storeId, String userId) { public List getUserWaitingStoreIds(String userId) { // key pattern으로 모든 매장 대기열 조회 (keys: waiting:*) Set keys = redisTemplate.keys(RedisKeyUtils.buildWaitingKeyPrefix() + "*"); - if (keys == null) return List.of(); + if (keys == null) + return List.of(); List result = new ArrayList<>(); for (String key : keys) { @@ -84,6 +89,7 @@ public List getUserWaitingStoreIds(String userId) { } return result; } + // 상태값 조회 public String getWaitingStatus(Long storeId, String userId) { String statusKey = RedisKeyUtils.buildWaitingStatusKeyPrefix() + storeId; @@ -91,6 +97,10 @@ public String getWaitingStatus(Long storeId, String userId) { return value == null ? null : value.toString(); } + // 사용자가 해당 스토어 대기열에 있는지 여부 반환 + public boolean isUserWaiting(Long storeId, String userId) { + return getRank(storeId, userId) != null; + } } 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 2f7cdab1..d7b450d7 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 @@ -5,6 +5,7 @@ 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; @@ -15,7 +16,7 @@ public interface StoreService { StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable pageable); - StorePageReadDto getStoreByStoreId(Long storeId, CustomOAuth2User customOAuth2User); + StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User customOAuth2User); List searchByKeywordNative(String name); 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 ec246e03..408c18d3 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 @@ -20,7 +20,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.nowait.applicationuser.reservation.repository.WaitingUserRedisRepository; import com.nowait.applicationuser.store.dto.StoreDepartmentReadResponse; +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.StoreWaitingInfo; @@ -52,6 +54,7 @@ public class StoreServiceImpl implements StoreService { private final StringRedisTemplate redisTemplate; private final BookmarkRepository bookmarkRepository; private final UserRepository userRepository; + private final WaitingUserRedisRepository waitingRepo; @Override @Transactional(readOnly = true) @@ -121,7 +124,7 @@ public StoreDepartmentReadResponse getAllStoresByPageAndDeparments(Pageable page @Override @Transactional(readOnly = true) - public StorePageReadDto getStoreByStoreId(Long storeId, CustomOAuth2User customOAuth2User) { + public StoreDetailReadResponse getStoreByStoreId(Long storeId, CustomOAuth2User customOAuth2User) { if (storeId == null) throw new StoreParamEmptyException(); User user = userRepository.findById(customOAuth2User.getUserId()) .orElseThrow(UserNotFoundException::new); @@ -135,12 +138,8 @@ public StorePageReadDto getStoreByStoreId(Long storeId, CustomOAuth2User customO // 2-1) Redis에서 각 Store의 웨이팅 사이즈 조회 String key = "waiting:" + storeId; - Long waitingSize = 0L; - try { - redisTemplate.opsForZSet().zCard(key); - } catch (Exception e) { - waitingSize = 0L; // Redis 접근 실패 시 0으로 처리 - } + long waitingSize = redisTemplate.opsForZSet().zCard(key); + boolean userWaiting = waitingRepo.isUserWaiting(storeId, String.valueOf(customOAuth2User.getUserId())); List images = storeImageRepository.findByStore(store); List imageDto = images.stream() @@ -148,9 +147,9 @@ public StorePageReadDto getStoreByStoreId(Long storeId, CustomOAuth2User customO .toList(); if (bookmarkRepository.existsByUserAndStore(user, store)) { - return StorePageReadDto.fromEntityWithBookmark(store, imageDto, departmentName, waitingSize, true); + return StoreDetailReadResponse.fromEntityWithBookmark(store, imageDto, departmentName, waitingSize, true, userWaiting); } else { - return StorePageReadDto.fromEntity(store, imageDto, departmentName, waitingSize); + return StoreDetailReadResponse.fromEntity(store, imageDto, departmentName, waitingSize, userWaiting); } }