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-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()) 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..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 @@ -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,30 @@ 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) -> desc ? + b.getWaitingCount().compareTo(a.getWaitingCount()) : + a.getWaitingCount().compareTo(b.getWaitingCount())) + .toList(); + + return result; + } }