From ec83a1745a5b6860da9ee9caf77570305d744d89 Mon Sep 17 00:00:00 2001 From: Bulgogi-Pizza Date: Mon, 24 Feb 2025 17:09:26 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat=20[#30]=20:=20Payment=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=99=84=EC=84=B1,=20Order=EC=99=80=20Pay?= =?UTF-8?q?ment=20=EC=97=B0=EA=B2=B0,=20User=20Merge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../restaurant/RestaurantAdminController.java | 12 ++--- .../admin/user/UserAdminController.java | 12 ++--- .../address/controller/AddressController.java | 12 ++--- .../_delivery/domain/menu/MenuController.java | 18 +------ .../_delivery/domain/order/Order.java | 6 ++- .../_delivery/domain/order/OrderService.java | 19 ++++++- .../domain/order/OrderStatusEnum.java | 1 + .../_delivery/domain/payment/Payment.java | 6 +-- .../domain/payment/PaymentController.java | 32 ++++++------ .../domain/payment/PaymentResponseDto.java | 28 +++++++++++ .../domain/payment/PaymentService.java | 49 +++++++++++++++---- .../restaurant/RestaurantController.java | 10 ++-- .../restaurant/RestaurantRequestDto.java | 2 + .../_delivery/domain/review/Review.java | 2 - .../user/controller/UserController.java | 20 ++++---- .../domain/user/service/UserService.java | 27 +++++----- 16 files changed, 159 insertions(+), 97 deletions(-) create mode 100644 src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentResponseDto.java diff --git a/src/main/java/com/sparta/spring_deep/_delivery/admin/restaurant/RestaurantAdminController.java b/src/main/java/com/sparta/spring_deep/_delivery/admin/restaurant/RestaurantAdminController.java index 1ca2de4..06c9acb 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/admin/restaurant/RestaurantAdminController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/admin/restaurant/RestaurantAdminController.java @@ -23,7 +23,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/admin/restaurants") +@RequestMapping("/admin") @Slf4j(topic = "RestaurantAdminController") public class RestaurantAdminController { @@ -31,7 +31,7 @@ public class RestaurantAdminController { private final RestaurantAdminService restaurantAdminService; // 음식점 상세 조회 - @GetMapping("/{restaurantId}") + @GetMapping("/restaurants/{restaurantId}") public ResponseEntity getRestaurant( @PathVariable UUID restaurantId) { log.info("음식점 상세 조회"); @@ -43,7 +43,7 @@ public ResponseEntity getRestaurant( } // 음식점 생성 - @PostMapping + @PostMapping("/restaurants") public ResponseEntity addRestaurant( @RequestBody RestaurantAdminCreateRequestDto restaurantAdminCreateRequestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -55,7 +55,7 @@ public ResponseEntity addRestaurant( } // 음식점 정보 수정 - @PutMapping("/{restaurantId}") + @PutMapping("/restaurants/{restaurantId}") public ResponseEntity updateRestaurant( @RequestBody RestaurantAdminRequestDto restaurantAdminRequestDto, @PathVariable UUID restaurantId, @@ -68,7 +68,7 @@ public ResponseEntity updateRestaurant( } // 음식점 삭제 - @DeleteMapping("/{restaurantId}") + @DeleteMapping("/restaurants/{restaurantId}") public ResponseEntity deleteRestaurant( @PathVariable UUID restaurantId, @AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -78,7 +78,7 @@ public ResponseEntity deleteRestaurant( return ResponseEntity.status(HttpStatus.OK).body(null); } - @GetMapping("/search") + @GetMapping("/restaurants/search") public ResponseEntity> searchRestaurant( @ModelAttribute RestaurantAdminSearchDto restaurantAdminSearchDto, @PageableDefault(sort = "name", direction = Sort.Direction.ASC) Pageable pageable) { diff --git a/src/main/java/com/sparta/spring_deep/_delivery/admin/user/UserAdminController.java b/src/main/java/com/sparta/spring_deep/_delivery/admin/user/UserAdminController.java index cf87c57..0391ed8 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/admin/user/UserAdminController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/admin/user/UserAdminController.java @@ -22,13 +22,13 @@ @RestController @RequiredArgsConstructor @Slf4j(topic = "UserAdminService") -@RequestMapping("/admin/users") +@RequestMapping("/admin") public class UserAdminController { private final UserAdminService userAdminService; // 사용자 전체 조회 + 페이징 기능 - @GetMapping("/search") // search?page=0&size=2로 요청하면 2개만 조회 + @GetMapping("/users/search") // search?page=0&size=2로 요청하면 2개만 조회 public ResponseEntity> searchUsers( @ModelAttribute UserAdminSearchDto searchDto, @PageableDefault(sort = "username", direction = Sort.Direction.ASC) Pageable pageable) { @@ -40,7 +40,7 @@ public ResponseEntity> searchUsers( } // 사용자 상세 조회 - @GetMapping("/{userId}") + @GetMapping("/users/{userId}") public ResponseEntity getUser( @PathVariable String userId) { log.info("getUser"); @@ -51,7 +51,7 @@ public ResponseEntity getUser( } // 사용자 등록 - @PostMapping + @PostMapping("/users") public ResponseEntity createUser( @RequestBody UserCreateRequestDto userCreateRequestDto, @AuthenticationPrincipal UserDetails userDetails) { @@ -64,7 +64,7 @@ public ResponseEntity createUser( } // 사용자 수정 - @PutMapping("/{userId}") + @PutMapping("/users/{userId}") public ResponseEntity updateUser( @PathVariable String userId, @RequestBody UserUpdateRequestDto userUpdateRequestDto, @@ -78,7 +78,7 @@ public ResponseEntity updateUser( } // 사용자 삭제 - @DeleteMapping("/{userId}") + @DeleteMapping("/users/{userId}") public ResponseEntity deleteUser( @PathVariable String userId, @AuthenticationPrincipal UserDetails userDetails) { diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/address/controller/AddressController.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/address/controller/AddressController.java index 5f18f3b..aa82fa2 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/address/controller/AddressController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/address/controller/AddressController.java @@ -26,14 +26,14 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/addresses") +@RequestMapping("/api") @Slf4j(topic = "Address Controller") public class AddressController { private final AddressService addressService; // 배송지 추가 - @PostMapping + @PostMapping("/addresses") public ResponseEntity createAddress( @RequestBody AddressRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -45,7 +45,7 @@ public ResponseEntity createAddress( } // 배송지 조회 - @GetMapping("/search") + @GetMapping("/addresses/search") public ResponseEntity> searchMyAddresses( @ModelAttribute AddressSearchDto searchDto, @AuthenticationPrincipal UserDetailsImpl userDetails, @@ -60,7 +60,7 @@ public ResponseEntity> searchMyAddresses( // 개별 배송지 조회 - @GetMapping("/{addressId}") + @GetMapping("/addresses/{addressId}") public ResponseEntity getAddress( @PathVariable UUID addressId, @AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -72,7 +72,7 @@ public ResponseEntity getAddress( } // 배송지 수정 - @PutMapping("/{addressId}") + @PutMapping("/addresses/{addressId}") public ResponseEntity updateAddress( @PathVariable UUID addressId, @RequestBody AddressRequestDto requestDto, @@ -86,7 +86,7 @@ public ResponseEntity updateAddress( } // 배송지 삭제 - @DeleteMapping("/{addressId}") + @DeleteMapping("/addresses/{addressId}") public ResponseEntity deleteAddress( @PathVariable UUID addressId, @AuthenticationPrincipal UserDetailsImpl userDetails) { diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/menu/MenuController.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/menu/MenuController.java index 50edd4b..a061469 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/menu/MenuController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/menu/MenuController.java @@ -41,21 +41,7 @@ public ResponseEntity addMenu( MenuResponseDto responseDto = menuService.addMenu(restaurantId, requestDto, userDetails); return ResponseEntity.status(HttpStatus.CREATED).body(responseDto); } - -// // restaurant_id 기반 모든 메뉴 조회 -// @GetMapping("/menus/{restaurantId}") -// public ResponseEntity> getRestaurantAllMenus( -// @PathVariable(name = "restaurantId") Restaurant restaurantId, -// @RequestParam(required = false) String name, -// @RequestParam(defaultValue = "createdAt") String sortBy, -// @RequestParam(defaultValue = "0") int page, -// @RequestParam(defaultValue = "10") int size -// ) { -// Page responseDtoPage = menuService.getAllMenus(restaurantId, name, sortBy, -// page, size); -// return ResponseEntity.status(HttpStatus.OK).body(responseDtoPage); -// } - + // restaurant_id 기반 메뉴 검색 및 조회 @GetMapping("/menus/{restaurantId}/search") public ResponseEntity> searchMenus( @@ -102,7 +88,7 @@ public ResponseEntity aiDescription( @AuthenticationPrincipal UserDetailsImpl userDetails ) { log.info("aiDescription"); - + MenuAiResponseDto responseDto = menuService.aiDescription(menuId, userDetails); return ResponseEntity.status(HttpStatus.CREATED).body(responseDto); } diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/order/Order.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/order/Order.java index ddae71c..1227913 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/order/Order.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/order/Order.java @@ -22,13 +22,11 @@ import java.util.UUID; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; @Entity @Getter -@Setter @RequiredArgsConstructor @Table(name = "p_order") public class Order extends BaseEntity { @@ -73,9 +71,13 @@ public Order(User customer, Restaurant restaurant, Address address, this.request = request; } + public void updateTotalPrice(BigDecimal totalPrice) { + this.totalPrice = totalPrice; + } public void updateOrderStatus(User user, OrderStatusEnum status) { super.update(user.getUsername()); // user -> username으로 변경 예정 (*baseEntity) this.status = status; } + } \ No newline at end of file diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderService.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderService.java index c8371da..bbf7205 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderService.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderService.java @@ -10,6 +10,9 @@ import com.sparta.spring_deep._delivery.domain.order.orderDetails.OrderDetailsResponseDto; import com.sparta.spring_deep._delivery.domain.order.orderItem.OrderItem; import com.sparta.spring_deep._delivery.domain.order.orderItem.OrderItemRepository; +import com.sparta.spring_deep._delivery.domain.payment.Payment.PaymentStatusEnum; +import com.sparta.spring_deep._delivery.domain.payment.PaymentResponseDto; +import com.sparta.spring_deep._delivery.domain.payment.PaymentService; import com.sparta.spring_deep._delivery.domain.restaurant.Restaurant; import com.sparta.spring_deep._delivery.domain.restaurant.RestaurantRepository; import com.sparta.spring_deep._delivery.domain.review.Review; @@ -48,6 +51,7 @@ public class OrderService { private final AddressRepository addressRepository; private final MenuRepository menuRepository; private final ReviewRepository reviewRepository; + private final PaymentService paymentService; private LocalDateTime lastCheckedTime = LocalDateTime.now().minusMinutes(5); @@ -90,8 +94,19 @@ public OrderDetailsResponseDto createOrder(OrderDetailsRequestDto requestDto, Us orderItemList.add(orderItem); }); - - order.setTotalPrice(sumPrice.get()); + order.updateTotalPrice(sumPrice.get()); + + // 결제 요청 + PaymentResponseDto paymentResponseDto = paymentService.createPayment(user.getUsername(), + order.getId(), sumPrice.get()); + + if (paymentResponseDto.getPaymentStatus() == PaymentStatusEnum.COMPLETED) { + order.updateOrderStatus(user, OrderStatusEnum.CONFIRMED); + + } else if (paymentResponseDto.getPaymentStatus() == PaymentStatusEnum.FAILED) { + order.updateOrderStatus(user, OrderStatusEnum.FAILED); + order.delete(user.getUsername()); + } return new OrderDetailsResponseDto(order, orderItemList); } diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderStatusEnum.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderStatusEnum.java index 13a99ef..22de37d 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderStatusEnum.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/order/OrderStatusEnum.java @@ -4,5 +4,6 @@ public enum OrderStatusEnum { PENDING, CONFIRMED, DELIVERED, + FAILED, CANCELLED } \ No newline at end of file diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/Payment.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/Payment.java index 5760cec..82c3180 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/Payment.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/Payment.java @@ -11,19 +11,19 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; import jakarta.validation.constraints.Digits; import java.math.BigDecimal; import java.util.UUID; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; @Entity @Getter -@Setter @RequiredArgsConstructor +@Table(name = "p_payment") public class Payment extends BaseEntity { @Id @@ -44,7 +44,7 @@ public class Payment extends BaseEntity { private PaymentMethodEnum paymentMethod; @Enumerated(EnumType.STRING) - @Column(name = "payment_status", nullable = false, columnDefinition = "p_payment_method_enum") + @Column(name = "status", nullable = false, columnDefinition = "p_payment_method_enum") @JdbcTypeCode(SqlTypes.NAMED_ENUM) private PaymentStatusEnum paymentStatus; diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentController.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentController.java index 112eb74..d869385 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentController.java @@ -26,52 +26,54 @@ public class PaymentController { // 결제 생성 @PostMapping("/payment") - public ResponseEntity createPayment(@RequestBody PaymentRequestDto requestDto + public ResponseEntity createPayment( + @RequestBody PaymentRequestDto requestDto , @AuthenticationPrincipal UserDetailsImpl userDetails) { log.info("createPayment"); - Payment payment = paymentService.createPayment(userDetails.getUsername(), + PaymentResponseDto responseDto = paymentService.createPayment(userDetails.getUsername(), UUID.fromString(requestDto.orderId), requestDto.amount); - return ResponseEntity.status(HttpStatus.OK).body(payment); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); } // 결제 완료 처리 @PutMapping("/payment/complete") - public ResponseEntity completePayment(@RequestParam String paymentId) { + public ResponseEntity completePayment(@RequestParam String paymentId) { log.info("completePayment"); - Payment payment = paymentService.completePayment(UUID.fromString(paymentId)); - return ResponseEntity.status(HttpStatus.OK).body(payment); + PaymentResponseDto responseDto = paymentService.completePayment(UUID.fromString(paymentId)); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); } // 결제 취소 처리 @PutMapping("/payment/cancel") - public ResponseEntity cancelPayment(@RequestParam String paymentId) { + public ResponseEntity cancelPayment(@RequestParam String paymentId) { log.info("cancelPayment"); - Payment payment = paymentService.cancelPayment(UUID.fromString(paymentId)); - return ResponseEntity.status(HttpStatus.OK).body(payment); + PaymentResponseDto responseDto = paymentService.cancelPayment(UUID.fromString(paymentId)); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); } // 결제 실패 처리 @PutMapping("/payment/fail") - public ResponseEntity failPayment(@RequestParam String paymentId) { + public ResponseEntity failPayment(@RequestParam String paymentId) { log.info("failPayment"); - Payment payment = paymentService.failPayment(UUID.fromString(paymentId)); - return ResponseEntity.status(HttpStatus.OK).body(payment); + PaymentResponseDto responseDto = paymentService.failPayment(UUID.fromString(paymentId)); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); } // 결제 조회 @GetMapping("/payment") - public ResponseEntity getPayment(@AuthenticationPrincipal UserDetailsImpl userDetails, + public ResponseEntity getPayment( + @AuthenticationPrincipal UserDetailsImpl userDetails, @RequestParam String paymentId) { log.info("getPayment"); - Payment payment = paymentService.getPayment(userDetails.getUser(), + PaymentResponseDto responseDto = paymentService.getPayment(userDetails.getUser(), UUID.fromString(paymentId)); - return ResponseEntity.status(HttpStatus.OK).body(payment); + return ResponseEntity.status(HttpStatus.OK).body(responseDto); } // 결제 내역 삭제 diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentResponseDto.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentResponseDto.java new file mode 100644 index 0000000..a7a7ce0 --- /dev/null +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentResponseDto.java @@ -0,0 +1,28 @@ +package com.sparta.spring_deep._delivery.domain.payment; + +import com.sparta.spring_deep._delivery.domain.payment.Payment.PaymentMethodEnum; +import com.sparta.spring_deep._delivery.domain.payment.Payment.PaymentStatusEnum; +import java.math.BigDecimal; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PaymentResponseDto { + + private UUID id; + private UUID orderId; + private BigDecimal amount; + private PaymentMethodEnum paymentMethod; + private PaymentStatusEnum paymentStatus; + + public PaymentResponseDto(Payment payment) { + this.id = payment.getId(); + this.orderId = payment.getOrder().getId(); + this.amount = payment.getAmount(); + this.paymentMethod = payment.getPaymentMethod(); + this.paymentStatus = payment.getPaymentStatus(); + } + +} diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentService.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentService.java index cf2e2c2..8fcbf89 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentService.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/payment/PaymentService.java @@ -6,6 +6,7 @@ import com.sparta.spring_deep._delivery.domain.order.OrderRepository; import com.sparta.spring_deep._delivery.domain.user.entity.User; import com.sparta.spring_deep._delivery.domain.user.entity.UserRole; +import com.sparta.spring_deep._delivery.exception.InternalServerException; import com.sparta.spring_deep._delivery.exception.ResourceNotFoundException; import java.math.BigDecimal; import java.util.UUID; @@ -26,55 +27,83 @@ public class PaymentService { // 결제 생성 @Transactional - public Payment createPayment(String username, UUID orderId, BigDecimal amount) { + public PaymentResponseDto createPayment(String username, UUID orderId, BigDecimal amount) { log.info("Creating Payment for username {} and order id {}", username, orderId); Order order = orderRepository.findById(orderId) .orElseThrow(ResourceNotFoundException::new); Payment payment = new Payment(username, order, amount); - return paymentRepository.save(payment); + + // 카드사 요청 대기 + try { + Thread.sleep(1000); + boolean paymentSuccess; + + // 90% 확률로 COMPLETE + // 10% 확률로 FAILED + if (Math.random() <= 0.9) { + paymentSuccess = true; + } else { + paymentSuccess = false; + } + + if (paymentSuccess) { + // complete + payment.completePayment(); + } else { + // failed + payment.failPayment(); + } + + } catch (InterruptedException e) { + throw new InternalServerException(); + } + + paymentRepository.save(payment); + return new PaymentResponseDto(payment); } // 결제 완료 처리 @Transactional - public Payment completePayment(UUID paymentId) { + public PaymentResponseDto completePayment(UUID paymentId) { log.info("Completing Payment for payment id {}", paymentId); Payment payment = paymentRepository.findById(paymentId) .orElseThrow(ResourceNotFoundException::new); payment.completePayment(); - return payment; + + return new PaymentResponseDto(payment); } // 결제 취소 처리 @Transactional - public Payment cancelPayment(UUID paymentId) { + public PaymentResponseDto cancelPayment(UUID paymentId) { log.info("Canceling Payment for payment id {}", paymentId); Payment payment = paymentRepository.findById(paymentId) .orElseThrow(ResourceNotFoundException::new); payment.cancelPayment(); - return payment; + return new PaymentResponseDto(payment); } // 결제 실패 처리 @Transactional - public Payment failPayment(UUID paymentId) { + public PaymentResponseDto failPayment(UUID paymentId) { log.info("Failing Payment for payment id {}", paymentId); Payment payment = paymentRepository.findById(paymentId) .orElseThrow(ResourceNotFoundException::new); payment.failPayment(); - return payment; + return new PaymentResponseDto(payment); } // 결제 조회 @Transactional(readOnly = true) - public Payment getPayment(User user, UUID paymentId) { + public PaymentResponseDto getPayment(User user, UUID paymentId) { log.info("Getting Payment for payment id {}", paymentId); Payment payment = paymentRepository.findById(paymentId) @@ -85,7 +114,7 @@ public Payment getPayment(User user, UUID paymentId) { ownerCheck(user, payment.getOrder().getCustomer()); } - return payment; + return new PaymentResponseDto(payment); } // 결제 내역 삭제 diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantController.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantController.java index 34daa7f..43104e0 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantController.java @@ -22,14 +22,14 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/restaurants") +@RequestMapping("/api") @Slf4j(topic = "Restaurant Controller") public class RestaurantController { private final RestaurantManageService restaurantManageService; // 음식점 수정 - @PutMapping("/{restaurantId}") + @PutMapping("/restaurants/{restaurantId}") public ResponseEntity updateRestaurant( @RequestBody RestaurantRequestDto restaurantRequestDto, @PathVariable UUID restaurantId, @@ -42,7 +42,7 @@ public ResponseEntity updateRestaurant( } // 음식점 삭제 - @DeleteMapping("/{restaurantId}") + @DeleteMapping("/restaurants/{restaurantId}") public ResponseEntity deleteRestaurant( @PathVariable UUID restaurantId, @AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -54,7 +54,7 @@ public ResponseEntity deleteRestaurant( } // 음식점 조회 - @GetMapping(value = "/{restaurantId}") + @GetMapping(value = "/restaurants/{restaurantId}") public ResponseEntity getRestaurant(@PathVariable UUID restaurantId) { log.info("음식점 조회"); @@ -63,7 +63,7 @@ public ResponseEntity getRestaurant(@PathVariable UUID re } // 음식점 검색 - @GetMapping("/search") + @GetMapping("/restaurants/search") public ResponseEntity> searchRestaurant( @ModelAttribute RestaurantSearchDto searchDto, @PageableDefault(page = 0, size = 10, sort = "name", direction = Sort.Direction.ASC) Pageable pageable) { diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantRequestDto.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantRequestDto.java index 5f74997..c16235b 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantRequestDto.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/restaurant/RestaurantRequestDto.java @@ -1,9 +1,11 @@ package com.sparta.spring_deep._delivery.domain.restaurant; import com.sparta.spring_deep._delivery.domain.restaurant.Restaurant.CategoryEnum; +import lombok.AllArgsConstructor; import lombok.Getter; @Getter +@AllArgsConstructor public class RestaurantRequestDto { String name; diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/review/Review.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/review/Review.java index e2c53a8..a751dfc 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/review/Review.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/review/Review.java @@ -15,11 +15,9 @@ import java.util.UUID; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; @Entity @Getter -@Setter @NoArgsConstructor @Table(name = "p_review") public class Review extends BaseEntity { diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/user/controller/UserController.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/user/controller/UserController.java index 673a4fe..1478176 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/user/controller/UserController.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/user/controller/UserController.java @@ -1,13 +1,11 @@ package com.sparta.spring_deep._delivery.domain.user.controller; import com.sparta.spring_deep._delivery.domain.user.details.UserDetailsImpl; -import com.sparta.spring_deep._delivery.domain.user.dto.LoginRequestDto; -import com.sparta.spring_deep._delivery.domain.user.dto.LoginResponseDto; import com.sparta.spring_deep._delivery.domain.user.dto.PasswordChangeDto; import com.sparta.spring_deep._delivery.domain.user.dto.UserDto; import com.sparta.spring_deep._delivery.domain.user.entity.User; -import com.sparta.spring_deep._delivery.domain.user.service.UserService; import com.sparta.spring_deep._delivery.domain.user.jwt.JwtUtil; +import com.sparta.spring_deep._delivery.domain.user.service.UserService; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -30,16 +28,16 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/api/users") +@RequestMapping("/api") @RequiredArgsConstructor -@Slf4j(topic = "User Controller") +@Slf4j(topic = "UserController") public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); private final UserService userService; private final JwtUtil jwtUtil; - @PostMapping("/signup") + @PostMapping("/users/signup") public ResponseEntity signup(@Valid @RequestBody UserDto userDto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { @@ -54,7 +52,7 @@ public ResponseEntity signup(@Valid @RequestBody UserDto userDto, return new ResponseEntity<>(newUser, HttpStatus.CREATED); } - @PostMapping("/logout") + @PostMapping("/users/logout") public ResponseEntity logout(@RequestHeader(value = "Authorization") String token) { // 클라이언트쪽에서 JWT 토큰 무효화해야 함! if (token != null && token.startsWith("Bearer ")) { @@ -67,7 +65,7 @@ public ResponseEntity logout(@RequestHeader(value = "Authorization") String t return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid Token"); } - @GetMapping("/me") + @GetMapping("/users/me") public ResponseEntity getCurrentUser( @AuthenticationPrincipal UserDetailsImpl userDetails) { User user = userDetails.getUser(); @@ -76,7 +74,7 @@ public ResponseEntity getCurrentUser( } @PreAuthorize("authentication.name == #username") - @PutMapping("/{username}") + @PutMapping("/users/{username}") public ResponseEntity updateUser(@PathVariable String username, @Valid @RequestBody UserDto userDto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { @@ -91,7 +89,7 @@ public ResponseEntity updateUser(@PathVariable String username, } @PreAuthorize("authentication.name == #username") - @PutMapping("/{username}/password") + @PutMapping("/users/{username}/password") public ResponseEntity changePassword(@PathVariable String username, @RequestBody PasswordChangeDto passwordChangeDto) { userService.changePassword(username, passwordChangeDto); @@ -99,7 +97,7 @@ public ResponseEntity changePassword(@PathVariable String username, } @PreAuthorize("authentication.name == #username") - @DeleteMapping("/{username}") + @DeleteMapping("/users/{username}") public ResponseEntity deleteUser(@PathVariable String username) { userService.deleteUser(username); // Soft delete logger.info("User soft deleted successfully: {}", username); diff --git a/src/main/java/com/sparta/spring_deep/_delivery/domain/user/service/UserService.java b/src/main/java/com/sparta/spring_deep/_delivery/domain/user/service/UserService.java index e0ee7d5..ae1949b 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/domain/user/service/UserService.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/domain/user/service/UserService.java @@ -1,24 +1,18 @@ package com.sparta.spring_deep._delivery.domain.user.service; -import com.sparta.spring_deep._delivery.domain.user.details.UserDetailsImpl; -import com.sparta.spring_deep._delivery.domain.user.dto.LoginRequestDto; -import com.sparta.spring_deep._delivery.domain.user.dto.LoginResponseDto; import com.sparta.spring_deep._delivery.domain.user.dto.PasswordChangeDto; import com.sparta.spring_deep._delivery.domain.user.dto.UserDto; -import com.sparta.spring_deep._delivery.domain.user.entity.IsPublic; import com.sparta.spring_deep._delivery.domain.user.entity.User; -import com.sparta.spring_deep._delivery.domain.user.entity.UserRole; +import com.sparta.spring_deep._delivery.domain.user.jwt.JwtUtil; import com.sparta.spring_deep._delivery.domain.user.repository.UserRepository; import com.sparta.spring_deep._delivery.exception.DuplicateResourceException; -import com.sparta.spring_deep._delivery.domain.user.jwt.JwtUtil; +import com.sparta.spring_deep._delivery.exception.OwnershipMismatchException; +import com.sparta.spring_deep._delivery.exception.ResourceNotFoundException; import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -39,6 +33,7 @@ public class UserService { @Transactional public User registerUser(UserDto userDto) { + if (userRepository.existsByUsername(userDto.getUsername())) { throw new DuplicateResourceException(); } @@ -70,13 +65,15 @@ public User registerUser(UserDto userDto) { } public User updateUser(String userName, UserDto userDto) { + User user = userRepository.findByUsernameAndIsDeletedFalse(userName) - .orElseThrow(() -> new RuntimeException("User not found!")); + .orElseThrow(ResourceNotFoundException::new); // Check if the email was updated to a new one that already exists if (!user.getEmail().equals(userDto.getEmail()) && userRepository.existsByEmail( userDto.getEmail())) { - throw new RuntimeException("Email is already in use!"); + log.info("Check if the email was updated to a new one that already exists"); + throw new OwnershipMismatchException(); } user.setEmail(userDto.getEmail()); @@ -87,16 +84,20 @@ public User updateUser(String userName, UserDto userDto) { } public void deleteUser(String userName) { + log.info("delete user " + userName); + User user = userRepository.findByUsernameAndIsDeletedFalse(userName) - .orElseThrow(() -> new RuntimeException("User not found!")); + .orElseThrow(ResourceNotFoundException::new); user.setIsDeleted(true); // Assuming there's an isActive flag for soft delete user.delete(userName); userRepository.save(user); } public void changePassword(String userName, PasswordChangeDto passwordChangeDto) { + log.info("change password " + userName); + User user = userRepository.findByUsernameAndIsDeletedFalse(userName) - .orElseThrow(() -> new RuntimeException("User not found!")); + .orElseThrow(ResourceNotFoundException::new); user.setPassword(passwordEncoder.encode(passwordChangeDto.getNewPassword())); user.update(userName); userRepository.save(user);