From 9085d4fb753be1bcd42b13484e43eec7ad646aad Mon Sep 17 00:00:00 2001 From: jeonghyemin Date: Fri, 18 Jul 2025 18:40:29 +0900 Subject: [PATCH] =?UTF-8?q?feat(Reservation):=20=EB=8C=80=EA=B8=B0?= =?UTF-8?q?=EC=97=B4=20=EC=A1=B0=ED=9A=8C=20=EB=B0=8F=20=EC=B7=A8=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 대기열 조회 및 취소 api 추가 --- .../controller/ReservationController.java | 35 +++++++++++++++++++ .../repository/WaitingRedisRepository.java | 2 +- .../service/ReservationService.java | 17 ++++++--- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java index 0b546170..eef6a538 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/controller/ReservationController.java @@ -3,6 +3,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -63,4 +65,37 @@ public ResponseEntity createQueue( ) ); } + + @GetMapping("/get/queue/redis/{storeId}") + @Operation(summary = "본인 대기열 조회", description = "특정 주점에 대한 본인 대기열 조회") + @ApiResponse(responseCode = "200", description = "본인 대기열 조회") + public ResponseEntity getQueue( + @PathVariable Long storeId, + @AuthenticationPrincipal CustomOAuth2User customOAuth2User + ) { + WaitingResponseDto response = reservationService.myWaitingInfo(storeId,customOAuth2User); + return ResponseEntity + .ok() + .body( + ApiUtils.success( + response + ) + ); + } + + @DeleteMapping("/delete/queue/redis/{storeId}") + @Operation(summary = "내 대기열 취소", description = "특정 주점에 대한 대기열 취소") + @ApiResponse(responseCode = "200", description = "대기열 취소") + public ResponseEntity deleteQueue( + @PathVariable Long storeId, + @AuthenticationPrincipal CustomOAuth2User customOAuth2User + ) { + return ResponseEntity + .ok() + .body( + ApiUtils.success( + reservationService.cancelWaiting(storeId,customOAuth2User) + ) + ); + } } diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java index 7402b1c3..36f574db 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/repository/WaitingRedisRepository.java @@ -27,7 +27,7 @@ public boolean addToWaitingQueue(Long storeId, String userId, Integer partySize, public Integer getPartySize(Long storeId, String userId) { String partyKey = RedisKeyUtils.buildWaitingPartySizeKeyPrefix() + storeId; Object value = redisTemplate.opsForHash().get(partyKey, userId); - return value == null ? null : Integer.valueOf(value.toString()); + return Integer.valueOf(value.toString()); } public Long getRank(Long storeId, String userId) { diff --git a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java index c4fedcae..d3310e95 100644 --- a/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java +++ b/nowait-app-user-api/src/main/java/com/nowait/applicationuser/reservation/service/ReservationService.java @@ -11,6 +11,7 @@ import com.nowait.applicationuser.reservation.dto.WaitingResponseDto; import com.nowait.applicationuser.reservation.repository.WaitingRedisRepository; import com.nowait.common.enums.ReservationStatus; +import com.nowait.common.enums.Role; import com.nowait.domaincorerdb.reservation.entity.Reservation; import com.nowait.domaincorerdb.reservation.exception.DuplicateReservationException; import com.nowait.domaincorerdb.reservation.repository.ReservationRepository; @@ -42,6 +43,12 @@ public WaitingResponseDto registerWaiting( .orElseThrow(StoreNotFoundException::new); if (Boolean.FALSE.equals(store.getIsActive())) throw new StoreWaitingDisabledException(); + // User Role 검증 추가 + User user = userRepository.findById(customOAuth2User.getUserId()) + .orElseThrow(UserNotFoundException::new); + if (user.getRole() == Role.MANAGER) { + throw new IllegalArgumentException("Manager cannot register waiting"); + } String userId = customOAuth2User.getUserId().toString(); long timestamp = System.currentTimeMillis(); @@ -59,9 +66,10 @@ public WaitingResponseDto registerWaiting( .build(); } - public WaitingResponseDto myWaitingInfo(Long storeId, String userId) { + public WaitingResponseDto myWaitingInfo(Long storeId, CustomOAuth2User customOAuth2User) { + String userId = customOAuth2User.getUserId().toString(); // 입력 검증 추가 - if (storeId == null || userId == null || userId.trim().isEmpty()) { + if (storeId == null || userId.trim().isEmpty()) { throw new IllegalArgumentException("Invalid storeId or userId"); } Long rank = waitingRedisRepository.getRank(storeId, userId); @@ -72,8 +80,9 @@ public WaitingResponseDto myWaitingInfo(Long storeId, String userId) { .build(); } - public boolean cancelWaiting(Long storeId, String userId) { - if (storeId == null || userId == null || userId.trim().isEmpty()) { + public boolean cancelWaiting(Long storeId, CustomOAuth2User customOAuth2User) { + String userId = customOAuth2User.getUserId().toString(); + if (storeId == null || userId.trim().isEmpty()) { throw new IllegalArgumentException("Invalid storeId or userId"); } // 대기열에서 제거 및 결과 반환