Jin's Dev Story

[스프링 부트 쇼핑몰 프로젝트 with JPA] 16.장바구니 상품 삭제 & 주문 본문

Web & Android/스프링 부트 쇼핑몰 프로젝트 with JPA

[스프링 부트 쇼핑몰 프로젝트 with JPA] 16.장바구니 상품 삭제 & 주문

woojin._. 2023. 10. 16. 20:06
이 내용은 스프링 부트 쇼핑몰 프로젝트 with JPA 책을 학습한 내용입니다.

Section 1. 장바구니 상품 삭제

1. CartService

  • 장바구니 상품 번호를 파라미터로 받아서 삭제하는 로직 추가
// 장바구니 상품 삭제
    public void deleteCartItem(Long cartItemId) {
        CartItem cartItem = cartItemRepository.findById(cartItemId).orElseThrow(EntityNotFoundException::new);
        cartItemRepository.delete(cartItem);
    }

2. CartController

  • 장바구니 상품 삭제 요청을 처리하는 Controller
  • 삭제 요청이므로 DeleteMapping 어노테이션 지정
  • 상품 삭제 요청을 하는 유저와 해당 장바구니 상품의 유저가 일치하는지 검증
@DeleteMapping("/cartItem/{cartItemId}")
    public @ResponseBody ResponseEntity deleteCartItem(@PathVariable("cartItemId") Long cartItemId, Principal principal) {

        if(!cartService.validateCartItem(cartItemId, principal.getName())) {
            return new ResponseEntity<String>("수정 권한이 없습니다.", HttpStatus.FORBIDDEN);
        }

        cartService.deleteCartItem(cartItemId);
        return new ResponseEntity<Long>(cartItemId, HttpStatus.OK);
    }

3. 장바구니 상품 삭제 요청

  • 장바구니 페이지에서 상품의 X 버튼을 클릭하면 삭제 요청
<button type="button" class="close" aria-label="Close">
   <span aria-hidden="true" th:data-id="${cartItem.cartItemId}" onclick="deleteCartItem(this)">&times;</span>
</button>
function deleteCartItem(obj){
      var cartItemId = obj.dataset.id;
      var token = $("meta[name='_csrf']").attr("content");
      var header = $("meta[name='_csrf_header']").attr("content");

      var url = "/cartItem/" + cartItemId;

      $.ajax({
        url      : url,
        type     : "DELETE",
        beforeSend : function(xhr){
          /* 데이터를 전송하기 전에 헤더에 csrf값을 설정 */
          xhr.setRequestHeader(header, token);
        },
        dataType : "json",
        cache   : false,
        success  : function(result, status){
          location.href='/cart';
        },
        error : function(jqXHR, status, error){

          if(jqXHR.status == '401'){
            alert('로그인 후 이용해주세요');
            location.href='/members/login';
          } else{
            alert(jqXHR.responseJSON.message);
          }

        }
      });
    }

 


Section 2. 장바구니 상품 주문

1. CartOrderDto

  • 장바구니 페이지에서 주문할 상품의 데이터를 위한 Dto
  • 자기 자신을 List로 가짐
@Getter
@Setter
public class CartOrderDto {

    private Long cartItemId;

    private List<CartOrderDto> cartOrderDtoList;

}

2. OrderService

  • 장바구니 페이지에서 전달 받은 구매 상품으로 주문을 생성하는 로직 추가
  • Order.createOrder() 메소드 호출
// 장바구니에서 주문할 상품 데이터를 전달받아 주문을 생성
    public Long orders(List<OrderDto> orderDtoList, String email) {

        Member member = memberRepository.findByEmail(email);
        List<OrderItem> orderItemList = new ArrayList<>();

        for(OrderDto orderDto : orderDtoList) {
            Item item = itemRepository.findById(orderDto.getItemId()).orElseThrow(EntityNotFoundException::new);

            OrderItem orderItem = OrderItem.createOrderItem(item, orderDto.getCount());
            orderItemList.add(orderItem);
        }

        Order order = Order.createOrder(member, orderItemList);
        orderRepository.save(order);

        return order.getId();
    }

3. CartService

  • OrderDtoList 생성 및 OrderService.orders() 메소드 호출 로직 추가
  • 주문한 상품은 장바구니에서 제거하는 로직 추가
// 주문 로직으로 전달한 orderDto 리스트 생성 및 주문 로직 호출, 주문한 상품은 장바구니에서 제거
    public Long orderCartItem(List<CartOrderDto> cartOrderDtoList, String email) {
        List<OrderDto> orderDtoList = new ArrayList<>();

        for(CartOrderDto cardOrderDto : cartOrderDtoList) {
            CartItem cartItem = cartItemRepository.findById(cardOrderDto.getCartItemId()).orElseThrow(EntityNotFoundException::new);

            OrderDto orderDto = new OrderDto();
            orderDto.setItemId(cartItem.getItem().getId());
            orderDto.setCount(cartItem.getCount());
            orderDtoList.add(orderDto);
        }

        Long orderId = orderService.orders(orderDtoList, email);

        for (CartOrderDto cartOrderDto : cartOrderDtoList) {
            CartItem cartItem = cartItemRepository.findById(cartOrderDto.getCartItemId()).orElseThrow(EntityNotFoundException::new);
            cartItemRepository.delete(cartItem);
        }

        return orderId;
    }

4. CartController

  • 장바구니 주문 상품이 로그인한 유저의 것이 맞는지 검증
  • CartService.orderCartItem() 메소드 호출
// 장바구니 상품의 수량을 업데이트하는 요청 처리
    @PostMapping("/cart/orders")
    public @ResponseBody ResponseEntity orderCartItem(@RequestBody CartOrderDto cartOrderDto, Principal principal) {
        List<CartOrderDto> cartOrderDtoList = cartOrderDto.getCartOrderDtoList();

        if(cartOrderDtoList == null || cartOrderDtoList.size() == 0) {
            return new ResponseEntity<String>("주문할 상품을 선택해주세요", HttpStatus.FORBIDDEN);
        }

        for(CartOrderDto cartOrder : cartOrderDtoList) {
            if (!cartService.validateCartItem(cartOrder.getCartItemId(), principal.getName())){
                return new ResponseEntity<String>("주문 권한이 없습니다.", HttpStatus.FORBIDDEN);
            }
        }

        Long orderId = cartService.orderCartItem(cartOrderDtoList, principal.getName());

        return new ResponseEntity<Long>(orderId, HttpStatus.OK);
    }

5. 장바구니 페이지 상품 주문

  • 자바스크립트의 Array 와 Object 를 이용하여 Json 데이터 전송
function orders(){
      var token = $("meta[name='_csrf']").attr("content");
      var header = $("meta[name='_csrf_header']").attr("content");

      var url = "/cart/orders";

      var dataList = new Array();
      var paramData = new Object();

      $("input[name=cartChkBox]:checked").each(function() {
        var cartItemId = $(this).val();
        var data = new Object();
        data["cartItemId"] = cartItemId;
        dataList.push(data);
      });

      paramData['cartOrderDtoList'] = dataList;

      var param = JSON.stringify(paramData);

      $.ajax({
        url      : url,
        type     : "POST",
        contentType : "application/json",
        data     : param,
        beforeSend : function(xhr){
          /* 데이터를 전송하기 전에 헤더에 csrf값을 설정 */
          xhr.setRequestHeader(header, token);
        },
        dataType : "json",
        cache   : false,
        success  : function(result, status){
          alert("주문이 완료 되었습니다.");
          location.href='/orders';
        },
        error : function(jqXHR, status, error){

          if(jqXHR.status == '401'){
            alert('로그인 후 이용해주세요');
            location.href='/members/login';
          } else{
            alert(jqXHR.responseJSON.message);
          }

        }
      });
    }

6. 장바구니 상품 주문 동작 원리

  • 계층을 이동할 때는 Dto 객체로 데이터를 넘기고, 해당 계층에서 Dto 객체를 이용하여 Entity 객체를 조회, 해당 Entity 객체를 이용하여 자신의 로직을 수행
  • Controller
    • ① CartOrderDto 에서 CartOrderList 를 가져온 뒤 cartService.orderCartItem() 메소드 수행
  • CartService
    • ② cartOrderDto 에 존재하는 cartItemId 를 이용하여 CartItem 객체 조회
    • ③ cartItem 에 존재하는 ItemId 와 count 값을 얻은 뒤에 이를 이용하여 OrderDto 객체 생성
    • ④ OrderDtoList 를 orderService.orders() 메소드 파라미터로 넘겨 호출
  • OrderService
    • ⑤ OrderDto 에 존재하는 ItemId 와 count 값을 얻은 뒤에 이를 이용하여 OrderItem 객체 생성 
    • ⑥ Order.createOrder() 메소드 호출하여 Order 객체 생성후 save
      • - 이때, 파라미터는 member, orderItemList