[패스트캠퍼스X야놀자 : 미니 프로젝트] 마이페이지 조회 기능 구현

꼬마요리사레미·2023년 12월 9일

ReviewStatus enum class

public enum ReviewStatus {
     NOT_WRITABLE, WRITABLE, WRITTEN, DELETED
}
  1. ReviewStatus 열거형은 다음과 같이 네 가지 상태를 표현할 수 있다.
  • NOT_WRITABLE: 체크아웃 전이라 리뷰 작성이 불가능한 상태를 나타낸다.
  • WRITABLE: 체크아웃 이후라 리뷰 작성이 가능한 상태를 나타낸다.
  • WRITTEN: 리뷰가 작성된 상태를 나타낸다. 수정이 가능한 상태이다.
  • DELETED: 리뷰가 삭제된 상태를 나타낸다. 더이상 재작성은 불가능한 상태이다.
  1. 주문 상세 조회에서는 이러한 리뷰 상태를 이용하여 각 주문 상품의 리뷰 작성 여부를 확인할 수 있다.

1️⃣ 마이페이지 조회

Mypage Read API

  1. 요청 메서드 : GET
  2. 엔드 포인트 : /user
  3. 요청 데이터 : 없음
  4. 응답 데이터
  • 성공 시 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": [
                "일반실(한실)"
            ]
        }
    }
]

Mypage Read Resposne DTO

ReviewCreateRequest

@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();
    }
}

User Controller & Service Class

UserController - getMyPage

@GetMapping
public ResponseEntity<List<MyPageResponse>> getMyPage() {
    List<MyPageResponse> myPageResponse = userService.getMyPage();
    return ResponseEntity.ok(myPageResponse);
}

UserService - getMyPage

@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;
}

2️⃣ 마이페이지 상세 조회

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"
        }
    ]
}

Mypage Detail Read Resposne DTO

MyPageDetailResponse

@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();
    }
}

OrderItemResponse

@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 일 때 재작성을 막기 위해 )

User Controller & Service Class

UserController - getMyPageDetails

@GetMapping("/details/{orderId}")
public ResponseEntity<MyPageDetailResponse> getMyPageDetails(@PathVariable Long orderId) {
    MyPageDetailResponse myPageDetailResponse = userService.getMyPageDetails(orderId);
    return ResponseEntity.ok(myPageDetailResponse);
}

UserService - getMyPageDetails

@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;
}

0개의 댓글