http://localhost:8080/shopping/cart/delete/?index=44
삭제를 누르면 이 주소로 넘어간다.
-> ShoppingController
-> ShoppingService
-> ShoppingController
-> IShoppinMapper
-> ShoppinMapper.xml
-> ShoppingService
-> check
- 삭제버튼 클릭 시 삭제가 되면 된다.
: 구매버튼누르면 구매가 바로 되도록 하자.
- Mapping ->
/shopping/order
: 구매를 위한 페이지detail
페이지에도 바로 구매하기가 있어서order
로 처리를 할 것이다.confirm
띄우고 확인 누르면 바로 구매가 되도록 구현하자.
/shopping/order?pid=14&count=3
:pid
와count
가 붙으면 그 상품만 구매하는 Mapping
/shopping/order
: 사용자의 장바구니에 있는 것 모두 구매하는 Mapping
<a class="button order" th:href="@{/shopping/order}">구매하기</a>
<a class="button order" href="#" th:if="${productDto.getCount() > 0}">바로 구매하기</a>
-> 수정 전 detail.html
- 바로 구매하기 버튼을 누르면 이 주소로 매핑이 된다.
-> 수정 후 detail.html
<form class="order-container" method="get" th:action="@{/shopping/order}">
- form태그에 이것을 추가하고 구매하기 버튼을 클릭 해보자.
- 수량을 3개 선택하고 바로 구매하기 하면 주소에 구매 갯수와 상품의 남은 갯수가 뜬다.
-> 수정 완료 detail.html
<form class="order-container" method="get" onsubmit="return confirm('정말로 해당 상품을 구매할까요?')" th:action="@{/shopping/order}"> <label class="quantity-container" th:if="${productDto.getCount() > 0}"> <span hidden>개수</span> <input class="quantity-input" id="quantityInput" max="99" min="1" name="count" type="number" value="1"> </label> <input id="productIndexInput" type="hidden" name="pid" th:value="${productDto.getIndex()}"> <a class="button cart" href="#" id="cartButton" th:if="${productDto.getCount() > 0}">장바구니 넣기</a> <input class="button order" type="submit" value="바로 구매하기" th:if="${productDto.getCount() > 0}"> <a class="button sold-out" href="#" th:if="${productDto.getCount() == 0}">일시 품절</a> </form>
-> cart.html
-> ShoppingController
- 이렇게 되면
productIndex
와count
는 잘넘어온다. 그런데 int타입인데 null이 뜨면 오류이기 때문에 예외를 잡아줘야한다.
그래서 int를Optional<Integer>
로 변경해주고orElse(0)
사용해주자.
- 이렇게 수정헤준다.
- sout productIndex.orElse(0) == 0 찍힘
count.orElse(0)
-> ShoppingController
-> ShoppingService orderAll
-> ShoppingController getOrder
-> ShoppingService orderAll
-> 배송상태를 담는 order_statues
테이블 생성
-> 구매내역을 담을 수 있는 orders
테이블 생성
-> OrderEntity
-> ShoppingService orderAll
-> IShoppinMapper insertOrder
-> ShoppinMapper.xml insertOrder
-> ShoppingService
- 장바구니 내역이 삭제가 된다. 녹음 확인
-> ShoppingService orderSpecific
-> -> ShoppingService orderAll
@Transactinal
어노테이션 추가
이유 :
- stock 재고에 대해서도 추가
-> ShoppingService orderSpecific
- stock 재고에 대해서도 추가
-> ShoppingController getOrder
- else추가
-> order.html
-> order.css
<style> @charset "UTF-8"; body > .title { font-size: 2rem; font-weight: 600; margin-top: 3rem; margin-bottom: 1.5rem; } body > .subtitle { font-size: 1.125rem; margin-bottom: 3rem; } body > .buttons { align-items: center; display: flex; flex-direction: row; justify-content: center; margin: 3rem 0; } body > .buttons > .button { width: 10rem; border-radius: 0.5rem; font-size: 1.5rem; padding: 1rem 2rem; text-align: center; } body > .buttons > .button + .button { margin-left: 0.75rem; } body > .buttons > .button.back { border: 0.125rem solid rgb(66, 132, 243); color: rgb(66, 132, 243); } body > .buttons > .button.order { background-color: rgb(66, 132, 243); border: 0.125rem solid rgb(66, 132, 243); color: rgb(255, 255, 255); } </style>
-> 결과
- 구매하기 버튼 클릭시 나타나는 페이지
그런데! 이 페이지에서 새로고침을 누르면 구매가 계속되어서 orders 테이블에 데이터가 계속 쌓이게 된다. 한번만 구매가 되도록 하자.
-> detail.html
get
→post
로 변경
-> cart.html
div
→form
/a
→input
-> ShoppingController getOrder
POST로 변경
get
→Post
로 변경setViewNames
경로 변경
-> ShoppingController getOrder
새롭게 추가
-> cheak
- 구매하기를 누르면 order 페이지로 넘어가며 구매가 되며
orders
테이블에 값이 들어온 것을 확인 할 수 있고 새로고침시 중복 값이 들어오지 않게 되었다.
- 당연히
carts
테이블의 값은 사라진다.
-> Orders
테이블 수정
`product_index` INT UNSIGNED NOT NULL
장바구니에 담을시 / 구매할시 / 미래의 가격이 다 다르기 때문에 수정하자.
- 원래 있던 테이블 drop 후
price_product
,price_shipping
추가ShoppingEntity
,ShoppingMapper.xml
도 추가 수정
-> ShoppingService
여기 서비스 추가 해야함 많이..
-> UserController getMy
-> ShoppingService getOrderOf
-> IShoppingMapper selectOrderByEmail
-> ShoppingMapper.xml selectOrderByEmail
-> ShoppingService getOrderOf
-> UserContorller
-> UserController getMy
- 어떤 상품이 발송 처리가됐는지 는 관리자가 하는 것이다. 모든 사용자의 상품이 다 보여야한다.
-> selectOrders
- selectOrdersByEmail에서 where만 삭제
-> OrderStatusEntity
-> IShoppingMapper selectOrderStatuses
-> ShoppingMapper.xml selectOrderStatuses
-> ShoppingService getOrderStatuses
-> UserController
-> my.html
<body> <th:block th:replace="~{fragments/header.html :: content}"></th:block> <table class="table order-table"> <caption>구매내역</caption> <thead> <tr> <th>주문번호</th> <th th:if="${userEntity.isAdmin()}">주문자</th> <th class="info" colspan="2">상품정보</th> <th>주문금액</th> <th>배송비</th> <th>배송현황</th> <th></th> </tr> </thead> <tbody> <tr th:each="pair : ${pairList}" th:with="orderEntity=${pair.getLeft()}, productEntity=${pair.getRight()}"> <td class="index" th:text="${orderEntity.getIndex()}"></td> <td th:if="${userEntity.isAdmin()}" th:text="${userEntity.getEmail()}"></td> <td class="thumbnail-container"> <img alt="상품이미지" class="thumbnail" th:src="@{/product/detail/thumbnail (id=${productEntity.getThumbnailId()})}"> </td> <td> <div class="datetime" th:text="${#dates.format(orderEntity.getCreatedAt(), 'yyyy-MM-dd mm:HH:ss') + '구매'}"></div> <div class="title" th:text="${productEntity.getTitle()}"></div> </td> <td class="nowrap centered" th:text="${#numbers.formatInteger(orderEntity.getPriceProduct(), 0, 'COMMA') + '원'}"></td> <td class="nowrap centered" th:text="${orderEntity.getPriceShipping() == 0 ? '무료' : #numbers.formatInteger(orderEntity.getPriceShipping(), 0, 'COMMA') + '원'}"></td> <td class="centered " th:text="${orderStatuses.get(orderEntity.getOrderStatusIndex())}"></td> <td> <div class="delivery-container" th:if="${userEntity.isAdmin()}"> <select class="delivery-select" rel="deliverySelect" th:data-oid="${orderEntity.getIndex()}"> <option th:each="key : ${orderStatuses.keySet()}" th:value="${key}" th:text="${orderStatuses.get(key)}" th:selected="${orderEntity.getOrderStatusIndex() == key}"></option> </select> </div> <div class="button-container"> <a class="button" th:if="${orderEntity.getOrderStatusIndex() == 4 && userEntity.getEmail().equals(orderEntity.getUserEmail())}">리뷰쓰기</a> <a class="button" th:if="${orderEntity.getOrderStatusIndex() == 1 || orderEntity.getOrderStatusIndex() ==2 || orderEntity.getOrderStatusIndex() == 3}">구매취소</a> <a class="button" th:if="${orderEntity.getOrderStatusIndex() == 4}">반품신청</a> </div> </td> </tr> </tbody> </table> </body>
-> my.css
<style> body > .table { width: var(--content-max-width); border-collapse: collapse; margin-top: 1.5rem; } body > .table > caption { background-color: rgb(250, 250, 250); border-top: 0.125rem solid rgb(221,221,221); border-bottom: 0.125rem solid rgb(221,221,221); font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem; padding: 0.625rem 1rem; text-align: left; } body > .table > thead th { background-color: rgb(250, 250, 250); border-top: 0.125rem solid rgb(221,221,221); border-bottom: 0.125rem solid rgb(221,221,221); font-weight: 500; padding: 0.425rem 0.75rem; white-space: nowrap; } body > .table > thead th.info { width: 100%; } body > .table > tbody td { border-bottom: 0.0625rem solid rgb(221,221,221); padding: 0.5rem 1rem; } body > .table > tbody td:not(:last-child) { border-right: 0.0625rem solid rgb(221,221,221); } body > .table > tbody td.index { text-align: center; } body > .table > tbody td.nowrap { white-space: nowrap; } body > .table > tbody td.centered { text-align: center; } body > .table > tbody td.thumbnail-container { border-right: none; padding-right: 0; } body > .table > tbody .thumbnail { height: 5rem; } body > .table > tbody .datetime { color: rgb(160,160,160); font-size: 0.8rem; margin-bottom: 0.375rem; } body > .table > tbody .title { font-weight: 500; } body > .table > tbody .delivery-select { width: auto; border: 0.0625rem solid rgb(221,221,221); border-radius: 0.25rem; margin-bottom: 0.5rem; padding: 0.25rem 0.5rem; } body > .table > tbody .button-container { align-items: stretch; display: flex; flex-direction: column; justify-content: flex-start; } body > .table > tbody .button-container > .button { border: 0.0625rem solid rgb(221,221,221); border-radius: 0.25rem; cursor: pointer; padding: 0.25rem 0.5rem; text-align: center; } body > .table > tbody .button-container > .button + .button { margin-top: 0.395rem; } </style>
-> 결과