ReviewStatus enum class
public enum ReviewStatus { NOT_WRITABLE, WRITABLE, WRITTEN, DELETED }
- ReviewStatus 열거형은 다음과 같이 네 가지 상태를 표현할 수 있다.
- NOT_WRITABLE: 체크아웃 전이라 리뷰 작성이 불가능한 상태를 나타낸다.
- WRITABLE: 체크아웃 이후라 리뷰 작성이 가능한 상태를 나타낸다.
- WRITTEN: 리뷰가 작성된 상태를 나타낸다. 수정이 가능한 상태이다.
- DELETED: 리뷰가 삭제된 상태를 나타낸다. 더이상 재작성은 불가능한 상태이다.
- 주문 상세 조회에서는 이러한 리뷰 상태를 이용하여 각 주문 상품의 리뷰 작성 여부를 확인할 수 있다.
Mypage Read API
- 요청 메서드 : GET
- 엔드 포인트 : /user
- 요청 데이터 : 없음
- 응답 데이터
- 성공 시 200 OK : 사용자의 주문 정보를 담은 MyPageResponse 객체의 리스트를 반환
[ { "orderId": 1, "orderCreateDate": "2023-12-07T02:17:33", "payment": "KAKAOPAY", "totalPrice": 100000, "accommodation": { "accommodationImages": [ "http://tong.visitkorea.or.kr/cms/resource/18/3046218_image2_1.jpg" ], "accommodationNames": [ "브라운도트 천안성정점" ], "productNames": [ "디럭스 스위트 룸" ] } }, { "orderId": 15, "orderCreateDate": "2023-12-27T20:02:54", "payment": "KAKAOPAY", "totalPrice": 100000, "accommodation": { "accommodationImages": [ "http://tong.visitkorea.or.kr/cms/resource/62/3039162_image2_1.jpg" ], "accommodationNames": [ "세심천온천호텔" ], "productNames": [ "일반실(한실)" ] } } ]
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MyPageResponse {
private Long orderId;
private LocalDateTime orderCreateDate;
private Payment payment;
private Integer totalPrice;
private AccommodationDetails accommodation;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class AccommodationDetails {
private List<String> accommodationImages;
private List<String> accommodationNames;
private List<String> productNames;
public static AccommodationDetails fromEntity(List<OrderItem> orderItems) {
return AccommodationDetails.builder()
.accommodationImages(orderItems.stream()
.map(orderItem -> orderItem.getProduct().getAccommodation().getAccommodationImageList().get(0).getImageUrl())
.distinct()
.collect(Collectors.toList()))
.accommodationNames(orderItems.stream()
.map(orderItem -> orderItem.getProduct().getAccommodation().getName())
.distinct()
.collect(Collectors.toList()))
.productNames(orderItems.stream()
.map(orderItem -> orderItem.getProduct().getName())
.distinct()
.collect(Collectors.toList()))
.build();
}
}
public static MyPageResponse fromEntity(Orders order) {
List<OrderItem> orderItems = order.getOrderItemList();
return MyPageResponse.builder()
.orderId(order.getId())
.orderCreateDate(order.getOrderCreateDate())
.payment(order.getPayment())
.totalPrice(order.getTotalPrice())
.accommodation(AccommodationDetails.fromEntity(orderItems))
.build();
}
}
@GetMapping
public ResponseEntity<List<MyPageResponse>> getMyPage() {
List<MyPageResponse> myPageResponse = userService.getMyPage();
return ResponseEntity.ok(myPageResponse);
}
@Transactional
public List<MyPageResponse> getMyPage() {
User user = getUser();
List<Orders> orders = orderRepository.getUserOrdersWithDetails(user);
List<MyPageResponse> myPageResponseList = orders.stream()
.map(MyPageResponse::fromEntity)
.collect(Collectors.toList());
return myPageResponseList;
}
Mypage Detail Read API
1. 요청 메서드 : GET
2. 엔드포인트 : /user/details/{orderId}
3. 요청 데이터 : orderId
4. 응답 데이터
- 성공 시 200 OK : 특정 주문의 상세 정보를 담은 MyPageDetailResponse 객체를 반환
{ "orderId": 15, "orderItemList": [ { "orderItemId": 21, "checkIn": "2023-12-26", "checkOut": "2023-12-28", "personNumber": 2, "price": 100000, "orderItemDetail": { "accommodationName": "세심천온천호텔", "accommodationAddress": "충청남도 예산군 삽교읍 수암산로 210", "productImage": "http://tong.visitkorea.or.kr/cms/resource/61/3039161_image2_1.JPG", "productName": "일반실(한실)" }, "reviewStatus": "WRITTEN" }, { "orderItemId": 22, "checkIn": "2023-12-30", "checkOut": "2024-01-01", "personNumber": 3, "price": 120000, "orderItemDetail": { "accommodationName": "예쁜곳펜션", "accommodationAddress": "경기도 가평군 북면 방림로 240", "productImage": "https://example.com/image2.jpg", "productName": "스탠다드 트윈룸" }, "reviewStatus": "NOT_WRITABLE" } ] }
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MyPageDetailResponse {
private Long orderId;
@ArraySchema(schema = @Schema(implementation = OrderItemResponse.class))
private List<OrderItemResponse> orderItemList;
public static MyPageDetailResponse fromEntity(Orders order) {
List<OrderItemResponse> orderItemResponses = order.getOrderItemList().stream()
.map(OrderItemResponse::fromEntity)
.collect(Collectors.toList());
return MyPageDetailResponse.builder()
.orderId(order.getId())
.orderItemList(orderItemResponses)
.build();
}
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class OrderItemResponse {
private Long orderItemId;
private LocalDate checkIn;
private LocalDate checkOut;
private Integer personNumber;
private Integer price;
private OrderItemDetailResponse orderItemDetail;
private ReviewStatus reviewStatus;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class OrderItemDetailResponse {
private String accommodationName;
private String accommodationAddress;
private String productImage;
private String productName;
public static OrderItemDetailResponse fromEntity(OrderItem orderItem) {
return OrderItemDetailResponse.builder()
.accommodationName(orderItem.getProduct().getAccommodation().getName())
.accommodationAddress(orderItem.getProduct().getAccommodation().getAddress())
.productImage(orderItem.getProduct().getProductImageList().get(0).getImageUrl())
.productName(orderItem.getProduct().getName())
.build();
}
}
public static OrderItemResponse fromEntity(OrderItem orderItem) {
LocalDate currentDate = LocalDate.now();
ReviewStatus reviewStatus = (currentDate.isAfter(orderItem.getEndDate())
&& orderItem.getReviewStatus() == ReviewStatus.NOT_WRITABLE)
? ReviewStatus.WRITABLE
: orderItem.getReviewStatus();
return OrderItemResponse.builder()
.orderItemId(orderItem.getId())
.checkIn(orderItem.getStartDate())
.checkOut(orderItem.getEndDate())
.personNumber(orderItem.getPersonNumber())
.price(orderItem.getPrice())
.orderItemDetail(OrderItemDetailResponse.fromEntity(orderItem))
.reviewStatus(orderItem.getReviewStatus())
.build();
}
}
- 리뷰 작성이 가능한 상태가 되기 위한 조건은 다음과 같다.
ReviewStatus reviewStatus = (currentDate.isAfter(orderItem.getEndDate()) && orderItem.getReviewStatus() == ReviewStatus.NOT_WRITABLE) ? ReviewStatus.WRITABLE : orderItem.getReviewStatus();현재 날짜가 체크아웃 날짜 이후이며, 리뷰 작성 상태가 NOT_WRITABLE 일 때
( WRITTEN 일 때 재작성을 막기 위해 )
@GetMapping("/details/{orderId}")
public ResponseEntity<MyPageDetailResponse> getMyPageDetails(@PathVariable Long orderId) {
MyPageDetailResponse myPageDetailResponse = userService.getMyPageDetails(orderId);
return ResponseEntity.ok(myPageDetailResponse);
}
@Transactional
public MyPageDetailResponse getMyPageDetails(Long orderId) {
User user = getUser();
Orders order = orderRepository.findById(orderId)
.orElseThrow(() -> new OrderException(OrderExceptionCode.ORDER_NOT_FOUND));
MyPageDetailResponse myPageDetailResponse = MyPageDetailResponse.fromEntity(order);
return myPageDetailResponse;
}