From 5dbb4bcebb6d6af316a1e8bf32e9447240d41d36 Mon Sep 17 00:00:00 2001 From: jeonghyemin Date: Thu, 24 Jul 2025 10:51:10 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat(Store):=20=EC=A3=BC=EC=A0=90=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ReservationController.java | 4 +-- .../store/controller/StoreController.java | 17 +++++++++++ .../store/dto/StoreWaitingInfo.java | 19 +++++++++++++ .../store/service/StoreService.java | 3 ++ .../store/service/StoreServiceImpl.java | 28 +++++++++++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreWaitingInfo.java diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/controller/ReservationController.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/controller/ReservationController.java index a6871ed0..97920fb8 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/controller/ReservationController.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/controller/ReservationController.java @@ -33,7 +33,7 @@ public class ReservationController { private final ReservationService reservationService; @GetMapping("/admin/{storeId}/waiting/users") - @Operation(summary = "주점별 전체 대기 리스트 조회", description = "주점에 대한 대기 리스트 조회(WAITING,CALLING)") + @Operation(summary = "주점별 전체 대기/호출중 리스트 조회", description = "주점에 대한 대기 리스트 조회(WAITING,CALLING)") @ApiResponse(responseCode = "200", description = "주점별 전체 대기 리스트 조회") public ResponseEntity> getWaitingUsersWithScore(@PathVariable Long storeId) { List response = reservationService.getAllWaitingUserDetails(storeId); @@ -41,7 +41,7 @@ public ResponseEntity> getWaitingUsersWithScore(@PathV } @GetMapping("/admin/{storeId}/completed") - @Operation(summary = "주점별 전체 완료 리스트 조회", description = "주점에 대한 완료/취소 리스트 조회(CANCELED,CONFIRMED)") + @Operation(summary = "주점별 전체 취소/완료 리스트 조회", description = "주점에 대한 완료/취소 리스트 조회(CANCELED,CONFIRMED)") @ApiResponse(responseCode = "200", description = "주점별 전체 완료/취소 리스트 조회") public ResponseEntity getCompletedReservationList( @PathVariable Long storeId, diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java index b39a53a8..b495ca0b 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/controller/StoreController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.nowait.applicationuser.store.dto.StoreWaitingInfo; import com.nowait.applicationuser.store.service.StoreService; import com.nowait.common.api.ApiUtils; @@ -97,4 +98,20 @@ public ResponseEntity searchStores(@RequestParam("name") String name) { ) ); } + + @GetMapping("/waiting-list") + @Operation(summary = "예약 많은순/적은순 주점 리스트 조회", description = "desc(대기 많은순) , asc(대기 적은순)") + @ApiResponse(responseCode = "200", description = "주점 대기순 정렬") + public ResponseEntity getStoreWaitingList( + @RequestParam(defaultValue = "desc") String order) { + boolean desc = !"asc".equalsIgnoreCase(order); // 기본: 대기 많은 순 + + return ResponseEntity + .ok() + .body( + ApiUtils.success( + storeService.getStoresByWaitingCount(desc) + ) + ); + } } diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreWaitingInfo.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreWaitingInfo.java new file mode 100644 index 00000000..56249932 --- /dev/null +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/store/dto/StoreWaitingInfo.java @@ -0,0 +1,19 @@ +package com.nowait.applicationuser.store.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +@Schema(description = "주점 대기 현황 정보 DTO") +public class StoreWaitingInfo { + @Schema(description = "주점 ID", example = "1") + private String storeId; + + @Schema(description = "주점명", example = "노웨이팅 치킨") + private String storeName; + + @Schema(description = "대기 인원 수", example = "12") + private Long waitingCount; +} 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 3df99912..1e85f7c0 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 @@ -8,6 +8,7 @@ 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.StoreWaitingInfo; public interface StoreService { @@ -21,4 +22,6 @@ public interface StoreService { List searchStoresByName(String name); + List getStoresByWaitingCount(boolean desc); + } 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 8b9a5a5e..9048a18d 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 @@ -2,10 +2,12 @@ import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,6 +16,7 @@ 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.StoreWaitingInfo; import com.nowait.domaincorerdb.department.entity.Department; import com.nowait.domaincorerdb.department.repository.DepartmentRepository; import com.nowait.domaincorerdb.store.entity.Store; @@ -32,6 +35,7 @@ public class StoreServiceImpl implements StoreService { private final StoreRepository storeRepository; private final StoreImageRepository storeImageRepository; private final DepartmentRepository departmentRepository; + private final StringRedisTemplate redisTemplate; @Override @@ -188,4 +192,28 @@ public List searchStoresByName(String name) { }) .toList(); } + + // 주점 대기 리스트 반환 (많은 순/적은 순) + @Transactional(readOnly = true) + public List getStoresByWaitingCount(boolean desc) { + // 1. 모든 waiting:{storeId} key 조회 (패턴 탐색) + Set keys = redisTemplate.keys("waiting:*"); + if (keys == null) return List.of(); + + List result = keys.stream() + .filter(key -> key.startsWith("waiting:") && !key.startsWith("waiting:party:")) + .filter(key -> "zset".equals(redisTemplate.type(key).code())) // 타입 확인 확실히! + .map(key -> { + Long count = redisTemplate.opsForZSet().zCard(key); + String storeId = key.replace("waiting:", ""); + String storeName = storeRepository.findById(Long.valueOf(storeId)) + .map(Store::getName) + .orElse("UNKNOWN"); + return new StoreWaitingInfo(storeId, storeName, count != null ? count : 0); + }) + .sorted((a, b) -> b.getWaitingCount().compareTo(a.getWaitingCount())) + .toList(); + + return result; + } } From 5b61099fa7834fbb2377f7cb8c62e610184dd7c6 Mon Sep 17 00:00:00 2001 From: jeonghyemin Date: Thu, 24 Jul 2025 10:58:58 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat(Store):=20=EC=A3=BC=EC=A0=90=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applicationuser/store/service/StoreServiceImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 9048a18d..0eb1538b 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 @@ -202,7 +202,7 @@ public List getStoresByWaitingCount(boolean desc) { List result = keys.stream() .filter(key -> key.startsWith("waiting:") && !key.startsWith("waiting:party:")) - .filter(key -> "zset".equals(redisTemplate.type(key).code())) // 타입 확인 확실히! + .filter(key -> "zset".equals(redisTemplate.type(key).code())) .map(key -> { Long count = redisTemplate.opsForZSet().zCard(key); String storeId = key.replace("waiting:", ""); @@ -211,7 +211,9 @@ public List getStoresByWaitingCount(boolean desc) { .orElse("UNKNOWN"); return new StoreWaitingInfo(storeId, storeName, count != null ? count : 0); }) - .sorted((a, b) -> b.getWaitingCount().compareTo(a.getWaitingCount())) + .sorted((a, b) -> desc ? + b.getWaitingCount().compareTo(a.getWaitingCount()) : + a.getWaitingCount().compareTo(b.getWaitingCount())) .toList(); return result; From 7eb9608e4f6c33584e009a8388dda8ea6073dc7b Mon Sep 17 00:00:00 2001 From: jeonghyemin Date: Thu, 24 Jul 2025 22:58:19 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat(Reservation):=20=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EB=B0=98=ED=99=98=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reservation/dto/WaitingUserResponse.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java index eb8d3d37..71c1c490 100644 --- a/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java +++ b/nowait-app-admin-api/src/main/java/com/nowait/applicationadmin/reservation/dto/WaitingUserResponse.java @@ -16,8 +16,11 @@ @Schema(description = "대기 사용자 응답 DTO") public class WaitingUserResponse { - @Schema(description = "유저 ID", example = "1201") - private String id; // userId + @Schema(description = "예약 ID", example = "1201") + private String id; // reservationId + + @Schema(description = "유저 ID", example = "16") + private String userId; @Schema(description = "파티 인원", example = "3") private Integer partySize; @@ -37,6 +40,7 @@ public class WaitingUserResponse { public static WaitingUserResponse fromEntity(Reservation reservation) { return WaitingUserResponse.builder() .id(reservation.getId().toString()) + .userId(reservation.getUser().getId().toString()) .partySize(reservation.getPartySize()) .userName(reservation.getUser().getNickname()) .createdAt(reservation.getRequestedAt())