Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

게으른 완벽주의자의 개발자 도전기

[shop]상세페이지 구매하기(단일 구매) 구현 본문

Spring Boot

[shop]상세페이지 구매하기(단일 구매) 구현

머리방울 2022. 10. 23. 13:19

1. html

<div class="row g-4">
<div class="col-4 mr-3" > 
    <form th:action="@{/cart/detailBuy}" method="post" id="buyDetailForm">
    	<input type="hidden" name="itemCode" th:value="${item.itemCode}">
    	<input type="hidden" name="buyAmount" value="" id="buyAmountInput">								
    </form>
    <button type="button" class="btn btn-outline-dark" th:onclick="detailBuy();"> 
    <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>
</div>

 

2. js

function detailBuy(){
	//수량 데이터 넘기기
	const buyAmount = document.querySelector('#cartAmount').value;
	document.querySelector('#buyAmountInput').value = buyAmount;
	
	document.querySelector('#buyDetailForm').submit();

}

 

3. mapper

<select id="detailBuy" resultMap="itemMapper.item">
SELECT ITEM_CODE
   	 , ITEM_NAME
   	 , ITEM_PRICE
     , (SELECT ATTACHED_NAME
        FROM ITEM_IMG
        WHERE ITEM_CODE = S.ITEM_CODE AND IS_MAIN = 'Y') AS ATTACHED_NAME
FROM SHOP_ITEM S
WHERE ITEM_CODE = #{itemCode} 
   
</select>

 

4. controller

@PostMapping("/detailBuy")
public String detailBuy(Authentication authentication, Model model, 
       	    		 int buyAmount, String itemCode) {
		
    //멤버정보
    User user = (User)authentication.getPrincipal();
    String memberId = user.getUsername();

    model.addAttribute("memberInfo", memberService.memberDetail(memberId));

    //itemCode(이미지, 상품명, 가격)
    ItemVO itemVO = cartService.detailBuy(itemCode);

    model.addAttribute("item", itemVO);

    //수량데이터
    model.addAttribute("buyAmount", buyAmount);

    int finalPrice = 0;
    finalPrice = finalPrice + (buyAmount * itemVO.getItemPrice());
    model.addAttribute("totalPrice", finalPrice);

    return "content/buy/buy_info";

}

Buy_Info 

<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>
  </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:attr="action=${#lists.isEmpty(cartInfo) ? '/buy/directBuy' : '/buy/buyCart'}" method="post" >
   <!-- 상세페이지에서 구매하기 -> 구매확정 -->
    <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>
</div>

mapper

선택상품 주문하기
<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);
    }

}

구매확정 눌렀을 때 실행될 controller

단일메뉴 구매확정 버튼
@PostMapping("/directBuy")
public String directBuy(String itemCode, int buyAmount, int totalPrice
                        , BuyVO buyVO, Authentication authentication
                        , BuyDetailVO buyDetailVO, ArrayList<BuyDetailVO> buyDetailList) {
    memberId
    User user = (User)authentication.getPrincipal();
    String memberId = user.getUsername();

    insert 되어야 하는 buyCode 조회
    String buyCode = buyService.buyCode();

   /buyVO
    buyVO.setBuyCode(buyCode);
    buyVO.setTotalPrice(totalPrice);
    buyVO.setMemberId(memberId);

    buyDetailVO
    buyDetailVO.setBuyCode(buyCode);
    buyDetailVO.setItemCode(itemCode);
    buyDetailVO.setBuyAmount(buyAmount);
    buyDetailList.add(buyDetailVO);

    buyVO의 detailList에 집어 넣기
    buyVO.setBuyDetailList(buyDetailList);

    buyService.buyDirect(buyVO);
    단일구매에서는 장바구니 삭제 mapper 실행이 불필요하기 때문에 null 넣어준다.
    buyService.buyCart(buyVO, null);

    return "redirect:/item/list";
}