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