게으른 완벽주의자의 개발자 도전기
[shop] 장바구니에서 구매하기 구현 본문
장바구니에서 선택 구매 후 구매확정을 위한 화면을 구현하고자 한다.
구매확정 시
장바구니에서 구매했다면 구매 테이블과 구매상세테이블에 데이터가 들어간 후
장바구니에 담겨 있던 상품들은 삭제되도록 mapper를 구성한다
또한, 단일구매의 경우 장바구니에 담겼던 것이 아니기 때문에
장바구니 상품삭제는 필요하지 않기 때문에 if로 두가지 케이스를 구분하여
구현되도록 하고자 한다.
1. mapper
<mapper namespace="buyMapper">
<resultMap type="kh.study.shop.buy.vo.BuyVO" id="buy">
<id column="BUY_CODE" property="buyCode"/>
<result column="MEMBER_ID" property="memberId"/>
<result column="BUY_DATE" property="buyDate"/>
<result column="TOTAL_PRICE" property="totalPrice"/>
<result column="BUY_CNT" property="buyCnt"/>
<collection property="buyDetailList" resultMap="buyDetail"/>
</resultMap>
<resultMap type="kh.study.shop.buy.vo.BuyDetailVO" id="buyDetail">
<id column="BUY_DETAIL_CODE" property="buyDetailCode"/>
<result column="ITEM_CODE" property="itemCode"/>
<result column="BUY_CODE" property="buyCode"/>
<result column="BUY_AMOUNT" property="buyAmount"/>
<result column="BUY_PRICE" property="buyPrice"/>
<association property="itemInfo" resultMap="itemMapper.item"/>
</resultMap>
선택 구매하기 (shop_buy 테이블에 데이터 넣기)
<insert id="cartBuy">
INSERT INTO SHOP_BUY(
BUY_CODE
, MEMBER_ID
, TOTAL_PRICE
)VALUES(
#{buyCode}
, #{memberId}
, #{totalPrice}
)
</insert>
buy_detail에 데이터 넣기
<insert id="cartBuyDetail">
INSERT INTO SHOP_BUY_DETAIL (
BUY_DETAIL_CODE
, ITEM_CODE
, BUY_CODE
, BUY_AMOUNT
)
<foreach collection="buyDetailList" item="BuyDetailVO" separator="UNION ALL" index="status">
SELECT #{buyCode}||'_'||LPAD(#{status} + 1, 2, 0)
, #{BuyDetailVO.itemCode}
, #{buyCode}
, #{BuyDetailVO.buyAmount}
FROM DUAL
</foreach>
</insert>
선택 구매한 CART_CODE가 cart_001, cart_002인 장바구니 데이터의 조회
<select id="cartBuyInfo" resultMap="cartMapper.cart">
SELECT ITEM_CODE
, CART_AMOUNT
, TOTAL_PRICE
FROM SHOP_CART
WHERE CART_CODE IN
<foreach collection="cartCodeList" item="cartCode" open="(" close=")" separator=",">
#{cartCode}
</foreach>
</select>
다음에 들어갈 buyCode
<select id="buyCode" resultType="String">
SELECT 'BUY_' || LPAD(NVL(MAX(TO_NUMBER(SUBSTR(BUY_CODE, 5))), 0) +1, 3, 0)
FROM SHOP_BUY
</select>
장바구니 구매확정
@Override
@Transactional(rollbackFor = Exception.class)
public void buyCart(BuyVO buyVO, CartVO cartVO) {
sqlSession.insert("buyMapper.cartBuy", buyVO);
sqlSession.insert("buyMapper.cartBuyDetail", buyVO);
단일구매 확정을 클릭했을 때는 구현되지 않도록 설정
if(cartVO != null) {
sqlSession.delete("cartMapper.deleteCart", cartVO);
}
}
buyCode 가져오기
@Override
public String buyCode() {
return sqlSession.selectOne("buyMapper.buyCode");
}
장바구니 데이터의 조회
@Override
public List<CartVO> cartBuyInfo(CartVO cartVO) {
return sqlSession.selectList("buyMapper.cartBuyInfo", cartVO);
}
2. controller
buyInfo에서 구매확정 클릭
(totalPrice, itemCode, cartAmount 데이터 필요해-> cartCode만 가져오면 해결)
@PostMapping("/buyCart")
public String buyCart(CartVO cartVO, BuyVO buyVO, String[] cartCodes
, Authentication authentication
, ArrayList<BuyDetailVO> buyDetailList) {
insert 되어야 하는 buyCode 조회
String buyCode = buyService.buyCode();
totalPrice, itemCode들, cartAmount들
List<String> cartCodeList = Arrays.asList(cartCodes);
cartVO.setCartCodeList(cartCodeList);
장바구니에 담았던 목록
List<CartVO> cartList = buyService.cartBuyInfo(cartVO);
memberId
User user = (User)authentication.getPrincipal();
String memberId = user.getUsername();
totalPrice
int totalPrice = 0;
for(CartVO e : cartList) {
totalPrice = totalPrice +e.getTotalPrice();
새로운 통 만들어 줘야 함 (buy_001_01,buy_001_02 이런식으로 데이터 들어가니까)
BuyDetailVO vo = new BuyDetailVO();
vo.setItemCode(e.getItemCode());
vo.setBuyAmount(e.getCartAmount());
buyDetailList.add(vo);
}
buyVO (buyVODetail도 같이 사용)
buyVO.setBuyCode(buyCode);
buyVO.setMemberId(memberId);
buyVO.setTotalPrice(totalPrice);
buyVO.setBuyDetailList(buyDetailList); //buyDetailVO -> itemCode, cartAmount
쿼리 실행
buyService.buyCart(buyVO,cartVO);
return "redirect:/item/list";
}
3. html (th:attr 사용하기)
<div class="row justify-content-center mt-3">
<div class="col-10 mb-5">
<h4>구매 상품 정보</h4>
<table class="table align-middle">
<colgroup>
<col width="10%">
<col width="30%">
<col width="30%">
<col width="15%">
<col width="15%">
</colgroup>
<thead>
<tr>
<td>No</td>
<td colspan="2">상품정보</td>
<td>수량</td>
<td>가격</td>
</tr>
</thead>
<tbody>
<!-- 단일상품 구매하기 -->
<th:block th:if="${#lists.isEmpty(cartInfo)}">
<tr>
<td>1</td>
<td><img th:src="|@{/image/}${item.imgList[0].attachedName}|"
width="100px" height="100px"></td>
<td th:text="${item.itemName}"></td>
<td th:text="${buyAmount}"></td>
<td th:text="${#numbers.formatCurrency(item.itemPrice)}"></td>
</tr>
</th:block>
<!-- 장바구니에서 구매하기 -->
<th:block th:unless="${#lists.isEmpty(cartInfo)}">
<tr th:each="cart, status :${cartInfo}">
<td th:text="${#lists.size(cartInfo) - status.index}"></td>
<td><img th:src="|@{/image/}${cart.itemList.imgList[0].attachedName}|"
width="100px" height="100px"></td>
<td th:text="${cart.itemList.itemName}"></td>
<td th:text="${cart.cartAmount}"></td>
<td th:text="${#numbers.formatCurrency(cart.itemList.itemPrice)}"></td>
</tr>
</th:block>
</tbody>
</table>
<div class="row mt-4" >
<div class="col-12 mb-3">
<div class="row">
<div class="offset-9 col-1 text-center" style=" height: 2.5rem;
font-size: 1.3rem; padding-top: 0.2rem; border-bottom: 1.5px solid; color: block;">
총 가격
</div>
<div class="col-2 text-end" style="border-bottom: 1.5px solid; padding-top: 0.2rem;
height: 2.5rem; font-size: 1.2rem;">
<span th:text="${#numbers.formatCurrency(totalPrice)}"
th:data-total-price="${totalPrice}"> </span>
</div>
</div>
</div>
</div>
<div class="row justify-content-center mt-4">
<h4>주문자 정보</h4>
<div class="col-12 mt-4">
<table class="table" style="text-align: left;">
<colgroup>
<col width="10%">
<col width="90%">
</colgroup>
<tbody id="detail">
<tr>
<th>회원ID</th>
<td th:text="${memberInfo.memberId}"></td>
</tr>
<tr>
<th>회원이름</th>
<td th:text="${memberInfo.memberName}"></td>
</tr>
<tr>
<th>주소</th>
<td th:text="${memberInfo.memberAddr}"></td>
</tr>
<tr>
<th>연락처</th>
<td th:text="${memberInfo.memberEmail}"></td>
</tr>
</tbody>
</table>
<div class="row mt-4 mb-4" style="text-align: center;">
<div class="col-12">
<!-- <form th:action="@{/buy/buyCart}" method="post"> -->
<form th:attr="action=${#lists.isEmpty(cartInfo) ? '/buy/directBuy' : '/buy/buyCart'}" method="post" >
<!-- 체크박스가 없기 때문에 아래와 같이 사용 가능 -->
<th:block th:unless="${#lists.isEmpty(cartInfo)}">
<th:block th:each="cart : ${cartInfo}">
<input type="hidden" name="cartCodes" th:value="${cart.cartCode}">
</th:block>
</th:block>
<!-- 상세페이지에서 구매하기 -> 구매확정 -->
<th:block th:if="${#lists.isEmpty(cartInfo)}">
<input type="hidden" name="itemCode" th:value="${item.itemCode}">
<input type="hidden" name="buyAmount" th:value="${buyAmount}">
<input type="hidden" name="totalPrice" th:value="${totalPrice}">
</th:block>
<button type="submit" class="btn btn-outline-dark" id="finalBuyBtn" >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box2-heart" viewBox="0 0 16 16">
<path d="M8 7.982C9.664 6.309 13.825 9.236 8 13 2.175 9.236 6.336 6.31 8 7.982Z"/>
<path d="M3.75 0a1 1 0 0 0-.8.4L.1 4.2a.5.5 0 0 0-.1.3V15a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V4.5a.5.5 0 0 0-.1-.3L13.05.4a1
1 0 0 0-.8-.4h-8.5Zm0 1H7.5v3h-6l2.25-3ZM8.5 4V1h3.75l2.25 3h-6ZM15 5v10H1V5h14Z"/>
</svg> 구매확정 </button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
'Spring Boot' 카테고리의 다른 글
[chart] ApexChart.js를 활용하여 차트 만들기 (쿼리 데이터 넣기) (0) | 2022.12.04 |
---|---|
[shop] 구매내역조회 화면 구현하기 (1) | 2022.10.23 |
[shop]상품 상세페이지 총가격 구현하기 (0) | 2022.10.23 |
[shop]장바구니 구현하기3 (선택 삭제, 선택 구매) (0) | 2022.10.23 |
[shop] 장바구니 구현하기2(장바구니 리스트, 수량 변경) (0) | 2022.10.23 |