20221020_thu
실습내용
- 1.구매할 상품은 장바구니에서 삭제되어야한다.
- 2.단일 구매
: 상품상세정보페이지에서 구매버튼 클릭시 바로 구매되도록 만들기.
: 구매버튼 클릭시, 바로 구매되는 것이 아니라, buyInfo.html페이지로 바로 이동해야한다.
: 상품상세페이지에서 구매버튼 클릭시, 'item_code','수량'만 들고오도록 한다.- 3.메뉴 나오기
- 4.주문내역 조회
: 장바구니 옆에 구매내역 이라는 글자를 넣어라.
: 장바구니 목록 -> 내정보관리 로 변경하라.
: side메뉴에는 내정보관리(장바구니 목록,내정보수정,구매내역조회) 만들도록하라.- 5.매출관리
@PostMapping("/insertBuy")
public String buyCart(String[] cartCodes, BuyVO buyVO,CartVO cartVO,Authentication authentication) {
//totalPrice,itemCode(들),수량(들) -> 데이터를 가져와야한다.
// 하지만!! cartCode(들)만 들고오면 위에 데이터들도 따라오게할 수 있다!!!
// cart테이블에가면 아이템코드 수량, 토탈프라이스 모두 있기때문에 cartCode만 알면 연결되 나머지 데이터들을 들고올 수 있다.
// cartCode(들)을 들고오는 방법은?
System.out.println("!@!!!!!!!!!!!!!!!!!!!@@@@" + cartCodes);// 콘솔확인시, CART_004,CART_007 -> 자스를 사용하지않아도 이런 식으로 데이터를 들고온다.
// 매개변수에서부터 배열 자료형으로 받으면(String[] cartCodes), 굳이 위에처럼 ,쉼표로 문자열을 자를 필요가 없다.
//for문을 돌려 하나씩빼서 콘솔 출력한다.
for(String e : cartCodes) {
System.out.println("@@@@@@@@@@@@@@@@@@@ " + e);
}
// buy_code 데이터 들고오기 : insert되어야하는 buy_code 조회
String buyCode = buyService.selectNextBuyCode();
//totalPrice,itemCode(들),cartAmount(들) 데이터는 어떻게 들고오냐
//위에 알고있는 cartCode를 이용해서 위 데이터를 쿼리문을 통해 가져온다. -> buy-mapper에서 만들어주기.
// 우리가 들고온 cartCode들을 cartVO에 넣어줘야한다.
// 이미 cartVo에는 리스트형태로 cartCodeList가 있는데, 이를 배열의 형태로 바꾸어 넣어준다.
//List<String> cartCodeList = Arrays.asList(cartCodes);
cartVO.setCartCodeList(Arrays.asList(cartCodes));
List<CartVO> cartList = buyService.getCartInfoForBuy(cartVO);
List<BuyDetailVO> buyDetailList = new ArrayList<>(); //아래 데이터 넣기위해서 미리 통만들기(변수선언)
//반복해서 itemCode와 amount값,totalPrice값 모두 for문돌려서 하나씩 빼기
int totalPrice =0;
for(CartVO cart : cartList) {
totalPrice = totalPrice + cart.getTotalPrice();
//아래처럼 만들어준 것을 위에 buydetailList 통에 넣어준다.
BuyDetailVO vo = new BuyDetailVO();
vo.setItemCode(cart.getItemCode());
vo.setBuyAmount(cart.getCartAmount());
buyDetailList.add(vo);
}
//memberID 데이터가져오기
User user = (User)authentication.getPrincipal();
// 위에서 부터 가져온 모든 데이터들을 BuyVO에서 setter를 이용해 데이터 넣어주기
buyVO.setBuyCode(buyCode);
buyVO.setMemberId(user.getUsername());
buyVO.setTotalPrice(totalPrice);
buyVO.setBuyDetailList(buyDetailList);// buyDetailVO 에서 itemCode,cartAmount값 가져오기.
//실제 구매실행 쿼리문 + (상품 구매 후)장바구니삭제
buyService.insertBuy(buyVO,cartVO);
// !! 주의 !!
// 구매한 장바구니는 목록에서 삭제-> 한줄만 아래처럼 추가하면 트랜잭션 처리 안됨
//cartService.deleteCarts(cartVO);
return "content/buy/buy_list";//구매내역페이지
}
package Kh.study.shop.buy.service;
public interface BuyService {
//구매등록
void insertBuy(BuyVO buyVO,CartVO cartVO);
@Transactional(rollbackFor = Exception.class)//어떤 오류든 간에 뭐든지 롤백하겠다.
@Override
public void insertBuy(BuyVO buyVO,CartVO cartVO) {
sqlSession.insert("buyMapper.insertBuy",buyVO);
sqlSession.insert("buyMapper.insertBuyDetail",buyVO);
sqlSession.delete("cartMapper.deleteCarts",cartVO);
}
- 단일구매하기
: 상품상세페이지에서 구매버튼 클릭시, 'item_code','수량'만 들고오도록 한다.
: 구매를 누르면 상품상세조회하는 쿼리문을 띄운다.
방법은 두 가지가 있다.- 1) 상세페이지의 '구매'버튼에 form태그로 가져갈 데이터 모두 감싸서 보내주도록 한다.
- 2) 구매버튼누르면 form태그가 실행되도록 버튼form태그 위에 수량이라는 input태그를 감싸지 않은 채로 보내도록한다.눈에 보기좋게 자바스크립트안에 있는 데이터를 넣어줘서 보내기. -> 우리가 할 방법!!
// 단일구매(상세페이지에서 바로구매 클릭시)
@PostMapping("/buyInfoDirect")
public String buyInfoDirect(String itemCode, int buyAmount,Model model,Authentication authentication) {// VO로 매개변수받아도 되지만, 그냥 단순히 필요한 두개의 데이터만 매개변수로 받았다.
model.addAttribute("item",itemService.selectDetailItem(itemCode));//이전에 만든 itemServiceImpl의 상세정보를 들고온다.
model.addAttribute("buyAmount",buyAmount);//자스를 통해 매개변수로 들고온데이터 그대로 보낸다
User user = (User)authentication.getPrincipal();
model.addAttribute("memberVO",memberService.selectMemberInfo(user.getUsername()));//구매자정보조회
return "content/buy/buy_info";
}
//[함수 ] (단일구매)상세페이지에서 바로 구매 버튼 클릭 시 진행되는 함수
function buy(){
//실제 입력한 수량값 선택
const buyAmount = document.querySelector('#cartAmount').value;
// 우리가 hidden으로 데려갈 input태그에 실제 입력 수량값 넣어주기
document.querySelector('#buyAmountInput').value = buyAmount;
// 서브밋 시키기
document.querySelector('#buyForm').submit();
}
👀주의할점👀
: html에서 이미지리스트를 넘길때 그냥 imgList[0]로 넘기면 is_main = 'Y'라는 쿼리문을 상품상세조회 쿼리문 조건절에 없기때문에 이렇게 사용하면, 상세이미지가 나온다.
: 그래서 메인이미지가 출력되도록하려면 저번처럼 th:block태그를 사용해서 반복문을 돌린 후,forecah로 하나씩 빼주어야한다.
: 컨트롤러에서 던져진 item이라는 itemVO의 imgList를 하나씩 빼는데 그 중 img라는 이름의 img정보 하나씩 뺀다. 그 중 is_main이 'Y'값이면, img의 attachedName만을 추출하면된다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultra.net.nz/thymeleaf/layout"
layout:decorate="~{layout/base_layout}"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<div layout:fragment="content">
<div class="row mt-4">
<!-- 좌측 -->
<div class="col-7">
<!-- 제목줄 -->
<div class="row mb-5">
<div class="col">
<h2>✔ ORDER </h2>
</div>
</div>
<!-- 구매할 장바구니 목록 영역 -->
<div class="row mb-3">
<div class="col">
<table class="table table-hover">
<colgroup>
<col width="10%" >
<col width="25%" >
<col width="25%" >
<col width="20%" >
<col width="20%" >
</colgroup>
<thead style="font-size: 20px; font-weight: bold; color: #425F57;">
<tr >
<!-- <td >
(1)리스트 값 null인지 아는 방법
장바구니에서 선택구매했을 때
<th:block th:if="${buyingList != null}">No.</th:block>
단일구매로 상세페이지에서 바로 구매했을 때
<th:block th:if="${buyingList == null}">✔</th:block>
(2)리스트 값 null인지 아는 방법
리스트의 값이 비어있는지 -> true/false값으로 출력
[[${#lists.isEmpty(buyingList)}]]
</td> -->
<td>No.</td>
<td style="text-align: center;">상품명</td>
<td>상품이미지</td>
<td>가격</td>
<td>수량</td>
</tr>
</thead>
<tbody>
<!-- 장바구니에서 선택구매 했을 때 -->
<th:block th:if="${#lists.isEmpty(buyingList)}"><!-- if는 true값이라면 아래 데이터 보여주는 것! -->
<tr>
<td>#</td>
<!-- 단, 쿼리문에서 is_main값 y인것만 뽑으라고 안했기때문에 반복문돌려야한다. -->
<td>
<th:block th:each="img : ${item.imgList}"><!-- item하나에는 여러개의 이미지리스트가 있다. 그 중 하나의 이미지정보를 img 뺐을 때 -->
<th:block th:if="${img.isMain eq 'Y'}">
<img width="100px;" height="140px;" th:src="|@{/images/}${img.attachedName}|">
</th:block>
</th:block>
</td>
<td>[[${item.itemName}]]</td>
<td>[[${item.itemPrice}]]</td>
<td>[[${buyAmount}]]</td>
</tr>
</th:block >
<!-- 상세페이지에서 바로 구매했을 때(단일구매) -->
<th:block th:unless="${#lists.isEmpty(buyingList)}"><!-- th:uless는 false값이면 데이터 보여주겠다. -->
<tr th:each="buy : ${buyingList}"><!-- buy 자료형은 cartVO -->
<td><span th:text="${#lists.size(buyingList) - buyStat.index}"></span> </td>
<!-- 다른방법 상품명불러오기 : ${buy.itemVO.itemName} -->
<td><span th:text=" ${buy.itemName}" ></span> </td>
<!-- 다른방법 이미지 불러오기 : th:src="|@{/images/}${buy.itmeVO.imgList[0].attachedName}|" -->
<td><img width="100px;" height="140px;" th:src="|@{/images/}${buy.attachedName}|"></td>
<!-- 다른방법 가격불러오기 : [[${buy.itemVO.itemPrice}]] -->
<td><span th:text=" ${#numbers.formatCurrency(buy.itemPrice)}" ></span> </td>
<td><span th:text=" ${buy.cartAmount}" ></span> </td>
</tr>
</th:block>
</tbody>
</table>
</div>
</div>
</div>
<!-- 우측 -->
<div class="col-5">
<!-- 제목줄 영역 -->
<div class="row mb-5">
<div class="col">
<h2>✔ MEMBER INFO</h2>
</div>
</div>
<!-- 주문자 정보 영역 -->
<div class="row mb-3">
<div class="col">
<table class="table">
<thead>
<tr>
<th scope="col">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/>
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z"/>
</svg> Detail
</th>
<th scope="row">
</th>
</tr>
<tr>
<th scope="col">ID</th>
<td th:text="${#authentication.name}"></td>
</tr>
<tr>
<th scope="col">이름</th>
<td th:text="${memberVO.memberName}"></td></tr>
<tr>
<th scope="col">E-Mail</th>
<td th:text="${memberVO.memberEmail}"></td></tr>
<tr>
<th scope="col">주소</th>
<td th:text="${memberVO.memberAddr}"></td>
</tr>
</thead>
<tbody class="table-group-divider">
</tbody>
</table>
</div>
</div>
<div class="row">
<div align="center" class="col-7">
<div class="input-group mb-3 " >
<span class="input-group-text" id="inputGroup-sizing-default"> 총가격 </span>
<span id="finalPriceTag" style="text-align: right;" th:data-total-price="${finalPrice}" th:text=" ${#numbers.formatCurrency(finalPrice)}" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"></span>
</div>
</div>
<div align="center" class="col-5">
<form th:action="@{/buy/insertBuy}" method="post" >
<!-- 여기 목록조회에서 cartCode를 사용하려면 목록조회 쿼리문에 조회컬럼 추가하기! CART_CODE -->
<!-- 체크박스때문에 체크된 상품만 가져와야해서 for문으로 문자열잘라야하는 cart_list와 달리 자바스크립트 사용하지 않고 한번에 보낼수있기때문에 사용! -->
<th:block th:each="buy : ${buyingList}" >
<input type="hidden" name="cartCodes" th:value="${buy.cartCode}"><!-- 구매하기 버튼클릭시 cartCodes라는 이름으로 데이터 가져간다. -> 컨트롤러가서 받기. -->
</th:block>
<button type="submit" class="btn btn-outline-success">구매하기</button>
</form>
</div>
</div>
</div>
</div>
</div>
</html>
- 장바구니 목록 -> 내정보관리 로 변경하라.
- side메뉴에는 내정보관리(장바구니 목록,내정보수정,구매내역조회) 만들도록하라.