본문 바로가기
Projects/쇼핑몰 프로젝트

[장바구니] 장바구니 기능구현(상품추가, 수량변경)

by 젊은오리 2023. 1. 13.
728x90

장바구니의 기능들을 구현한 것을 정리해보자.

1. 상품추가

상품상세페이지에서 장바구니를 누르면 장바구니에 추가가 되도록 구현하는 것이 목표이다. 로그인한 유저에 한해서 장바구니 이용을 제한했고, ajax로 상품데이터를 서버에 전송했다. ajax통신 시에 url에 파라미터를 주어서 넘기는 방식은 파라미터에 특수문자같은 문자가 들어올 경우 문제가 발생할 수 있어서 위험한 방법이라고는 했지만 데이터와 같이 같이 넘겨보았다. 

상품추가 로직

  • 기존 장바구니에 없는 상품이라면 새롭게 장바구니를 만들어서 저장
  • 기존 장바구니에 있는 상품이라면 기존 장바구니에 수량을 더해주고 저장

 

JS

function onCart(){
    var productId = $("#productId").val();
    var principalId = $("#principalId").val();
    var amount = document.getElementById('amount_input').value;

    if(principalId == ""){
        alert("로그인 후 이용가능합니다.");
        location.href="http://localhost:8080/auth/login"
    }
    else{
        if(amount<1){
            alert("1개 이상 선택해야 합니다.");
        }else{
            var data={
                p: principalId,
                amount: amount
            };

            $.ajax({
                type: "post",
                url: `/api/cart/${productId}/${amount}`,
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            }).done(res => {
                alert("상품을 장바구니에 담았습니다.");
                location.href="http://localhost:8080/cart/"+principalId;
            }).fail(error => {
                alert("실패");
            });
        }
    }
}

 

Service

@Transactional
public void addCart(User user, int productId, int amount){
    Cart cart = cartRepository.findByUserIdAndProductId(user.getId(),productId);
    
    //새로 만든 cart라면 product_count를 amount로 하는 장바구니 생성
    if(cart == null){
        Product product = productRepository.findById(productId).orElseThrow(()->{
            return new CustomException("상품을 찾을 수 없습니다.");
        });
        Cart newCart = new Cart();
        newCart.setUser(user);
        newCart.setProduct(product);
        newCart.setProduct_count(amount);
        cartRepository.save(newCart);
    }else{ //원래 있다면 product_count + amount해주고 저장
        int prev = cart.getProduct_count();
        cart.setProduct_count(prev+amount);
        cartRepository.save(cart);
    }
}

 

View

 

 

 

2. 수량변경

장바구니페이지에서 수량을 변경하면, 데이터베이스에 반영되면서 동시에 화면에서 바뀌게 하는 것이 목표이다. 장바구니 아이디(cartId)를 파라미터로 받아서 서버에 전해주었다. 통신이 완료되었을 때 서버에서 프론트로 유저의 모든 장바구니 객체를 json으로 주게 했는데, 이는 장바구니의 Total금액을 화면에 렌더링하기 위함이다.  

수량변경 로직

  • 수량감소의 경우 수량0개가 아닌 경우에 한해서 장바구니객체의 수량을 감소한다. 이때 장바구니객체의 totalPrice를 갱신해주고 commit한다.
  • 수량증가의 경우 감소와 마찬가지로 장바구니객체의 totalPrice를 갱신해주고 commit해준다.

 

JS

//물건 수량 감소
function count_down(cartId){
    if($('#count_' + cartId).text() == "0개") {
        alert("최소 갯수입니다.");
    }else if($('#count_' + cartId).text() == "1개"){
        delete_cart(cartId);
    }else{

        $.ajax({
            type: "post",
            url: `/api/cart/${cartId}/down`,
            contentType: "application/json; charset=utf-8",   //보낼 데이터의 형식
            dataType: "json" //응답받을 데이터의 형식
        }).done(res => {
            //해당 cart찾기
            var index = -1;
            for(var i=0; i<res.data.length;i++){
                if(res.data[i].id == cartId){
                    index = i;
                }
            }

            //수량 갱신
            $('#count_' + cartId).text(res.data[index].product_count+"개");

            //가격 갱신
            $('#total_price_'+cartId).text(res.data[index].total_price+"원");

            //장바구니 총 가격 갱신
            var sum = 0;
            for(var i=0; i<res.data.length; i++){
                sum += parseInt($('#total_price_'+res.data[i].id).text());
            }
            $('#summary').text(sum+"원");


        }).fail(error => {
            alert("수량 감소 실패");
        });
    }
}

//물건 수량 증가
function count_up(cartId){
    $.ajax({
        type: "post",
        url: `/api/cart/${cartId}/up`,
        contentType: "application/json; charset=utf-8",   //보낼 데이터의 형식
        dataType: "json" //응답받을 데이터의 형식
    }).done(res => {
        //해당 cart찾기
        var index = -1;
        for(var i=0; i<res.data.length;i++){
            if(res.data[i].id == cartId){
                index = i;
            }
        }

        //수량 갱신
        $('#count_' + cartId).text(res.data[index].product_count+"개");

        //가격 갱신
        $('#total_price_'+cartId).text(res.data[index].total_price+"원");

        //장바구니 총 가격 갱신
        var sum = 0;
        for(var i=0; i<res.data.length; i++){
            sum += parseInt($('#total_price_'+res.data[i].id).text());
        }
        $('#summary').text(sum+"원");

    }).fail(error => {
        alert("수량 증가 실패");
    });
}

 

Service

@Transactional
public Cart downCart(int cartId){
    Cart cart = cartRepository.findById(cartId).orElseThrow(()->{
        return new CustomException("찾을 수 없는 장바구니 입니다.");
    });

    //수량 0개가 아닐때 감소시킴.
    if(cart.getProduct_count() != 0) {
        int prev = cart.getProduct_count();
        cart.setProduct_count(prev - 1);

        //계산을 해주고 commit해야함.
        cart.calculateTotalPrice();
        cartRepository.save(cart);
    }
    return cart;
}

@Transactional
public Cart upCart(int cartId){
    Cart cart = cartRepository.findById(cartId).orElseThrow(()->{
        return new CustomException("찾을 수 없는 장바구니 입니다.");
    });

    int prev = cart.getProduct_count();
    cart.setProduct_count(prev + 1);

    //계산을 해주고 commit해야함.
    cart.calculateTotalPrice();
    cartRepository.save(cart);

    return cart;
}

 

 

728x90

댓글