나만의 프로젝트 배포하기 10일차

박세건·2023년 9월 21일
0

개인 프로젝트

목록 보기
10/15
post-thumbnail

구매 내역 조회

주문 기능을 완료했다면 주문이 정상적으로 진행되었는지 사용자가 확인할 수 있는 구매 내역 조회 기능을 추가해보자

구매 내역 조회 기능 순서

  • 구매내역 보여주는 html 설계

  • html에 들어갈 정보와 맞는 dto설정

  • 해당 정보를 저장시켜주는 service 설계

  • 가져온 데이터를 html로 보내주는 controller 설계

  • 구매내역 보여주는 html 설계

<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/default_layout}">

<div layout:fragment="content">

    <div class="container mt-3">
        <h2>구매 내역</h2>
        <table class="table">
            <thead>
            <tr>
                <th>주문 번호</th>
                <th>구매 날짜</th>
                <th>구매 상품</th>
                <th>구매 개수</th>
                <th>가격</th>
                <th>주문 상태</th>
            </tr>
            </thead>
            <tbody>
            <th:block th:each="order:${orderList}">
                <th:block th:each="orderItem:${order.orderItemResponseDtoList}">
                    <tr>
                        <td th:text="${order.id}"></td>
                        <td th:text="${order.date}"></td>
                        <td th:text="${orderItem.itemResponseDto.name}"></td>
                        <td th:text="${orderItem.count}"></td>
                        <td th:text="${order.price}"></td>
                        <td th:text="${order.status}"></td>
                    </tr>
                </th:block>
            </th:block>

            </tbody>
        </table>
    </div>

</div>
</html>
  • html에 들어갈 정보와 맞는 dto설정
package com.qkrtprjs.happyexercise.dto;

import com.qkrtprjs.happyexercise.entitiy.order.Order;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

@Getter
@NoArgsConstructor
public class OrderListResponseDto {
    private Long id;

    private LocalDateTime date;

    private String status;

    private int price;

    private List<OrderItemResponseDto> orderItemResponseDtoList;

    @Builder
    public OrderListResponseDto(Long id, LocalDateTime date, String status, int price, List<OrderItemResponseDto> orderItemResponseDtoList) {
        this.id = id;
        this.date = date;
        this.status = status;
        this.price = price;
        this.orderItemResponseDtoList = orderItemResponseDtoList;
    }
}
//Entity이름의 ResponseDto는 해당 Entity와 알맞는 정보의 필드들을 갖고있음을 의미한다.
  • 해당 정보를 저장시켜주는 service 설계(로그인 한 사용자의 정보만 가져와야하기때문에 로그인 정보 사용)
    public List<OrderListResponseDto> orderList(SessionMember loginMember) {
        List<OrderListResponseDto> dtoList = new ArrayList<>();
        Member member = memberRepository.findByEmail(loginMember.getEmail()).orElseThrow(() -> new IllegalArgumentException("해당 이메일은 존재하지 않습니다!"));
        List<Order> orderList = orderRepository.findByMember(member);
        for (Order order : orderList) {
            List<OrderItemResponseDto> orderItemResponseDtoList =
                    orderItemRepository.findByOrder(order).stream().map(orderItem -> OrderItem.toDto(orderItem)).collect(Collectors.toList());
            dtoList.add(
                    OrderListResponseDto.builder()
                            .id(order.getId())
                            .date(order.getDate())
                            .status(order.getStatus())
                            .price(order.getPrice())
                            .orderItemResponseDtoList(orderItemResponseDtoList)
                            .build()
            );

        }
        return dtoList;
    }
  • 가져온 데이터를 model로 감싸서 html로 보내주는 controller 설계
    @GetMapping("/orderList")
    private String orderList(Model model, @LoginMember SessionMember loginMember) {
        List<OrderListResponseDto> orderListResponseDtoList = orderService.orderList(loginMember);
        model.addAttribute("loginMember", loginMember);
        model.addAttribute("orderList", orderListResponseDtoList);
        return "order/orderList";
    }

정상적으로 보여지는 것을 확인할 수 있다. 추가로 현재는 하나의 주문에 하나의 상품이 들어가있지만 장바구니 기능을 추가하면서 여러가지를 한번에 주문할 수 있는 기능을 추가할 때에는 하나의 주문에 여러가지 상품이 들어갈 수 있기때문에 dto의 필드를

    private Long id;
    private LocalDateTime date;
    private String status;
    private int price;
    private List<OrderItemResponseDto> orderItemResponseDtoList;

로 지정해주었다.

주문 취소 기능

이어서 주문 취소기능을 추가하려고 구상하던 중에 문득 주문 상세보기 페이지가 있다면 더 효율적으로 진행할 수 있다고 생각했다 무작정 구매 내역에서 주문 취소를 하는 것은 깔끔하지가 않다고 생각했고 다른 플랫폼들을 확인해본결과 하나의 주문을 상세보기를 이용해서 들어간다음 거기서 주문 취소를 하는 방식을 이용하고 있어서 비슷하게 접근해보려고한다.

그렇다면 먼저 주문 상세보기 페이지부터 수정해보자!

html에서 속성값을 이용한 데이터 전달

우선 상세보기 버튼을 만들어주고 클릭시에 id 값을 전달해준다
이 과정은

<button th:id="${order.id}" type="button"  class="btn btn-primary" name="orderDetail-btn">상세보기</button>

버튼에 id 라는 속성값을 만들어주고 거기에 id값을 저장시켜준다음에

        $("[name=orderDetail-btn]").on('click',function (){
            console.log(this.getAttribute("id"));
        });

버튼을 클릭했을때에 클릭한 버튼(this)의 id 라는 속성값을 가져오게하면 id 값을 가져올 수 있다!!

        $("[name=orderDetail-btn]").on('click',function (){
            location.href="/order/" + this.getAttribute("id");
        });

가져온 id값을 이용해서 페이지를 이동시켜준다.

  • 해당 주소를 받아주는 컨트롤러 설계
    @GetMapping("/order/{id}")
    private String orderDetail(Model model, @PathVariable Long id) {
        OrderDetailResponseDto orderDetailResponseDto = orderService.orderDetail(id);
        model.addAttribute("order", orderDetailResponseDto);
        return "order/orderDetail";
    }
  • 이전에 만들어놓았던 orderList를 가져오는 함수에서 하나의 정보만 가져오기때문에 list가 아닌 하나의 정보만 return 받는 서비스 설계
    public OrderDetailResponseDto orderDetail(Long id) {
        Order order = orderRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 id값은 존재하지 않습니다!"));
        List<OrderItemResponseDto> orderItemResponseDtoList =
                orderItemRepository.findByOrder(order).stream().map(orderItem -> OrderItem.toDto(orderItem)).collect(Collectors.toList());
        return OrderDetailResponseDto.builder()
                .id(order.getId())
                .date(order.getDate())
                .status(order.getStatus())
                .price(order.getPrice())
                .orderItemResponseDtoList(orderItemResponseDtoList)
                .build();
    }
  • 주문 상세정보 html 코드 (주문에는 상품이 여러개 들어갈 수 있기때문에 미리 반복문 사용해서 설계)
<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/default_layout}">

<div layout:fragment="content">

    <div class="container mt-3">
        <h2>주문 자세히 보기</h2>
        <button type="button" class="btn btn-danger" id="delete-item-btn">삭제</button>

        <div class="mb-3 mt-3">
            <label for="id">주문번호:</label>
            <input type="text" class="form-control" id="id" th:value="${order.id}" name="id" readonly>
        </div>

        <table class="table">
            <thead>
            <tr>
                <th>상품명</th>
                <th>개당 가격</th>
                <th>구매 개수</th>
                <th>구매 가격</th>
            </tr>
            </thead>
            <tbody>
            <th:block th:each="orderItem:${order.orderItemResponseDtoList}">
                <tr>
                    <td th:text="${orderItem.itemResponseDto.name}"></td>
                    <td th:text="${orderItem.itemResponseDto.price}"></td>
                    <td th:text="${orderItem.count}"></td>
                    <td th:text="${orderItem.price}"></td>
                </tr>
            </th:block>
            </tbody>
        </table>
        <div class="mb-3">
            <label for="orderPrice">주문 금액:</label>
            <input type="text" class="form-control" id="orderPrice" th:value="${order.price}" name="orderPrice" readonly>
        </div>
        <div class="mb-3">
            <label for="date">주문 날짜:</label>
            <input type="text" class="form-control" id="date" th:value="${order.date}" name="date" readonly>
        </div>
        <div class="mb-3">
            <label for="status">주문 상황:</label>
            <input type="text" class="form-control" id="status" th:value="${order.status}" name="status" readonly>
        </div>
    </div>
</div>
</html>


  • 이전 페이지 수정 및 주문 상세보기 페이지 완성

주문을 삭제하는 기능을 추가해보자!

profile
멋있는 사람 - 일단 하자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN