장바구니 담기 기능 구현

루민 ·2023년 4월 24일
0

📝상품 상세 페이지

<!-- Product section-->
<section class="py-5">
    <div class="container px-4 px-lg-5 my-5" th:object="${item}">
        <div class="row gx-4 gx-lg-5 align-items-center" >
            <div class="col-md-6"><img class="card-img-top mb-5 mb-md-0" th:src="|/images/${item.getItemImageListDto().get(0).getStoreName()}|" alt="..." /></div>
            <div class="col-md-6">
                <h1 class="display-5 fw-bolder" th:text="${item.getName()}">Shop item template</h1>
                <input type="hidden" th:value="${item.itemId}" id="id" name="id">
                <div class="fs-5 mb-5">
                    <input type="hidden" th:value="${item.price}" id="price" name="price">
                    <span class="text-decoration-none" th:text="${item.getPrice()}"></span></div>
                <hr class="my-4">


                <div class="input-group fs-5 mb-5">
                    <div class="input-group-prepend">
                        <input type="hidden" th:value="${item.stockQuantity}" id="stockQuantity" name="stockQuantity">
                        <span class="input-group-text">주문 수량</span>
                    </div>
                    <input class="form-control text-center me-3" id="count" name="count" type="number" value="1" style=" max-width: 5rem" />
                </div>


                <div class="container bg-light">
                    <h6>총 상품 금액</h6>
                    <h4 name="totalPrice" id="totalPrice" class="font-weight-bold" ></h4>
                </div>
                <br>

                <div class="d-flex">
                    <form th:action="@{/logout}" class="d-flex" method="post">
                        <button class="btn btn-outline-dark"
                                type="submit">
                            바로 구매하기
                        </button>
                    </form>
                    &nbsp
                    <button class="btn btn-outline-dark flex-shrink-0" type="button" th:onclick="addCart()">
                        <i class="bi-cart-fill me-1"></i>
                        장바구니 담기
                    </button>
                </div>
            </div>
        </div>

    </div>
</section>


<script th:inline="javascript">
  
    <!-- 장바구니 담기 -->
    function addCart() {

        var count = $("#count").val();
        var itemId = $("#id").val();
        var cartForm = {
            itemId : itemId,
            count : count
        };

       $.ajax({
           url: "/cart",
           data: cartForm,
           type: 'POST',
           success: function(result) {
               alert("상품을 담았습니다.");
               location.href = "/";
           },

           error: function (jqXHR, textStatus, errorThrown) {
               alert(jqXHR.responseText);
               location.href="/members"
           }
       })
    }
</script>
  • 장바구니 담기 버튼을 클릭하면 addCart 함수가 호출됩니다.
  • addCart() : $("#count").val()를 사용하여 구매자가 선택한 수량을 변수에 저장하고, $("#id").val()로 상품 아이디를 변수에 저장한 후 cartForm에 매치하였습니다.
  • 서버와의 통신은 자바스크립트를 이용해서 비동기식으로 XML을 이용하여 서버와 통신하는 방식인 Ajax를 이용하였습니다.


📝Controller

 //장바구니 담기
    @PostMapping("/cart")
    public ResponseEntity<String> addCart(@ModelAttribute CartForm cartForm, HttpServletRequest request) {

        Member member = getMember(request);
        //비로그인 회원은 장바구니를 가질 수 없다.
        if (member == null) {
            return new ResponseEntity<String>("로그인이 필요합니다.", HttpStatus.BAD_REQUEST);
        }

        cartService.addCart(member.getId(), cartForm.getItemId(), cartForm.getCount());
        return ResponseEntity.ok("success");
    }
    
    
        private Member getMember(HttpServletRequest request) {

		//세션 가져오기 
        HttpSession session = request.getSession(false);

        //비로그인 사용자
        if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
            return null;
        }
        
		//세션에 저장되어있는 회원정보 가져오기
        Member member = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
        return member;
    }
  • 비로그인 회원은 장바구니를 가질 수 없도록 구현하였습니다.
  • 세션을 조회해서 회원 정보를 얻어와서 회원이 없으면 400 bad request로 응답하고, 회원 정보가 있으면 장바구니 담기 서비스를 호출합니다.

cartForm

@Getter
@Setter
public class CartForm {

    private Long itemId;
    private int count;
}


📝cartService

 	/**
     * 장바구니 담기(추가)
     */
    public Long addCart(Long memberId, Long itemId, int count) {

        //엔티티 조회
        Member member = memberRepository.findById(memberId).get();
        Cart cart = cartRepository.findByMemberId(memberId).orElse(null);
        Item item = itemRepository.findById(itemId).get();

        //장바구니 없으면 생성
        if (cart == null) {
            log.info("장바구니 신규 생성");
            cart = Cart.createCart(member);
            cartRepository.save(cart);
        }

        //장바구니안에 장바구니 상품 조회
        CartItem cartItem = cartItemRepository.findByCartIdAndItemId(cart.getId(), item.getId()).orElse(null);



        //장바구니 상품이 없으면 생성
        if (cartItem == null) {
            cartItem = CartItem.createCartItem(count, cart, item);
            CartItem savedCartItem = cartItemRepository.save(cartItem);
            log.info("cartItemId={}", cartItem.getId());
            return savedCartItem.getId();
        }

        //장바구니 상품이 존재하면 수량 변경 (Dirty checking)
        cartItem.changeCount(count);
        return cartItem.getId();

    }
  • 조회한 회원이 장바구니를 가지고 있지 않으면 새로 생성합니다.
  • 장바구니 상품이 없으면 새로 생성하고 이미 존재한다면 수량만 변경해주도록 하였습니다.


📝결과화면


장바구니 담기 성공시


장바구니 담기 실패(비로그인 회원)

0개의 댓글