coupang Day09

김지원·2022년 7월 11일
0

WebDevelop

목록 보기
20/21

오늘 할 것 : 리뷰 장바구니 구매
GCP에 배포

장바구니
로컬저장소(로컬스토리즈) 브라우저 저장소에 저장이 된다.
Js로 구현한다. 잘 사용하지 않느다.
로그인하고 장바구니에 담았다고 치자.

DB화 해야한다.

장바구니 구매 리뷰는 프로덕트와 멤버에 종송적이지 않다.

이 세개를 묶자.(장바구니 구매 리뷰)
carts 로 (스키마 하나 더 만든다.)

-> 장바구니 테이블 생성 carts

-> shopping 패키지 -> CartEntity

-> ShoppingController postCartAdd

-> AddResult

-> AddVo

-> ShoppingController postCartAdd

-> IShoppingMapper insertCart

-> ShoppingMapper.xml insertCart

-> ShoppingService 생성후 ShoppingController

-> ShoppingService

-> ShoppingController

-> detal.html 추가

-> detail.js 추가

-> 장바구니에 상품을 담아보자.

-> ShoppingController getCart

Tuple & Triple

Tuple과 HashMap의 차이점

  • 해쉬맵은 키와 값쌍으로 이루어진 것들의 나열이다.
    [K-V] -> 키가 겹치면 안된다.
  • pair는 그냥 두 타입의 쌍이다. 이거 단 하나만 가진다. ->[L-R]
    누가 키고 값이고가 아니라 둘 다 값이다. (getLight, getLeft로 사용.)

Triple 사용예시


Dto를 만들지 않고 Tuple(튜플)로 하자.

-> ShoppingController getCart

  • apache.commons.lang3 로 추가
  • List로 수정. List로 사용하자.

-> ShoppingService getCartOf

-> IShoppingMapper selectCartByEmail

-> ShoppingMapper.xml selectCartByEmail

  • 장바구니에 담았던 상품을 또 담으면 리스트가 중복으로 생기지 않고 사려고 하는 갯수만 올라간다. 어떻게 하면 좋을까?
  • count를 모두 합해주고 ORDER BY를 걸어주자.

-> ShoppingController getCart

  • 향상된 for문 사용.

-> ShoppingController productService 상수 추가

-> ProductService getProductByIndex 추가

  • IProductMapper에 이미 getProductByIndex 있으니깐 바로 적어주자 .

-> ShoppingController getCart

  • ImmutablePair가 붙은 객체들은 보통 final 이다.

-> cart.html

  • 장바구니를 누르면 장바구니에 담은 상품의 사진이 나온다.
<tr th:each="pair : ${pairList}"
        th:with="cartEntity=${pair.getLeft()}, productEntity=${pair.getRight()}">
        <td>
            <img th:src="@{/product/detail/thumbnail (id=${productEntity.getThumbnailId()})}">
        </td>
</tr>
  • 설명

-> ShoppingController getCart

-> ShoppingController getCart

-> cart.html

<body>
<div class="logo-container">
    <img alt="Coupang" class="logo" th:src="@{/resources/images/logo.png}">
</div>
<table>
    <thead>
    <tr>
        <th></th>
        <th>상품정보</th>
        <th>상품금액</th>
        <th>배송비</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="pair : ${pairList}"
        th:with="cartEntity=${pair.getLeft()}, productEntity=${pair.getRight()}">
        <td>
            <img class="thumbnail" th:src="@{/product/detail/thumbnail (id=${productEntity.getThumbnailId()})}">
        </td>
        <td>
            <div class="title" th:text="${productEntity.getTitle()}"></div>
            <div class="detail" th:with="dt = ${#dates.createNow()}">
                <span class="due" style="color: black;"
                      th:if="${productEntity.getDelivery().equals('normal')}"
                      th:with="tomorrow = ${T(org.apache.commons.lang3.time.DateUtils).addDays(dt, 2)}"
                      th:text="${#dates.format(tomorrow, 'M/d') + '(' + #dates.dayOfWeekName(tomorrow).substring(0, 1) + ') 도착 예정'}"></span>
                <span class="due"
                      th:if="${productEntity.getDelivery().equals('rocket')}"
                      th:with="tomorrow = ${T(org.apache.commons.lang3.time.DateUtils).addDays(dt, 1)}"
                      th:text="${#dates.format(tomorrow, 'M/d') + '(' + #dates.dayOfWeekName(tomorrow).substring(0, 1) + ') 도착 보장'}"></span>
                <span class="due"
                      th:if="${productEntity.getDelivery().equals('rocketFresh')}"
                      th:with="tomorrow = ${T(org.apache.commons.lang3.time.DateUtils).addDays(dt, 1)}"
                      th:text="${#dates.format(tomorrow, 'M/d') + '(' + #dates.dayOfWeekName(tomorrow).substring(0, 1) + ') 새벽 도착 보장'}"></span>
                <span class="spring"></span>
                <span th:text="${#numbers.formatInteger(productEntity.getPrice(), 0, 'COMMA')+'원'}"></span>
                <span th:text="${cartEntity.getCount() + '개'}"></span>
                <span th:text="${#numbers.formatInteger(productEntity.getPrice() + cartEntity.getCount(), 0, 'COMMA') + '원'}"></span>
                <a th:href="@{/shopping/cart/delete/ (index=${productEntity.getIndex()})}"
                   onclick="return confirm('정말로 해당 삼품을 장바구니에서 삭제할까요?')">삭제</a>
            </div>
        </td>
        <td class="spaced">
            <div th:text="${#numbers.formatInteger(productEntity.getPrice() + cartEntity.getCount(), 0, 'COMMA') + '원'}"></div>
            <img alt="로켓배송" class="rocket" th:src="@{/resources/images/rocket.png}"
                 th:if="${productEntity.getDelivery().equals('rocket')}">
            <img alt="로켓프레시" class="rocket" th:src="@{/resources/images/rocket-fresh.png}"
                 th:if="${productEntity.getDelivery().equals('rocketFresh')}">
        </td>
        <td class="spaced">
            <!--/*@thymesVar id="getDelivery" type="dev.jwkim.coupang.entities.product.ProductEntity"*/-->
            <span class="fee" th:if="${productEntity.getDelivery().equals('normal')}">배송비 3,000원</span>
            <span class="fee"
                  th:if="${productEntity.getDelivery().equals('rocket') || productEntity.getDelivery().equals('rocketFresh')}">무료</span>
        </td>
    </tr>
    </tbody>
    <tfoot>
    <tr>
        <td colspan="4">
           <div class="wrapper">
               <span>상품가격</span>
               <span class="value" th:text="${#numbers.formatInteger(totalProduct, 0, 'COMMA') + '원'}"></span>
               <span class="sign">+</span>
               <span>배송비</span>
               <span class="value" th:text="${#numbers.formatInteger(totalShopping, 0, 'COMMA') + '원'}"></span>
               <span class="sign">=</span>
               <span>주문금액</span>
               <span class="value" th:text="${#numbers.formatInteger(total, 0, 'COMMA') + '원'}"></span>
           </div>
        </td>
    </tr>
    </tfoot>
</table>
<div class="buttons">
    <a class="button back" th:href="@{/}">계속 쇼핑하기</a>
    <a class="button order" th:href="@{/shopping/order}">구매하기</a>
</div>
</body>

-> cart.css

<style>
@charset "UTF-8";
body > .logo-container {
    width: var(--content-max-width);
    margin: 2rem 0 1rem 0;
}
body > .logo-container > .logo {
    height: 2.5rem;
}
body > table {
    width: var(--content-max-width);
    border-collapse: collapse;
}
body > table > thead th,
body > table > tfoot td {
    background-color: rgb(250, 250, 250);
    border-top: 0.0625rem solid rgb(221, 221, 221);
    border-bottom: 0.0625rem solid rgb(221, 221, 221);
    padding: 0.75rem;
    white-space: nowrap;
}
body > table > tbody .thumbnail {
    height: 6rem;
    margin: 1rem 2rem 1rem 0;
}
body > table > tbody .title {
    border-bottom: 0.0625rem solid rgb(221, 221, 221);
    font-size: 1.125rem;
    font-weight: 500;
    margin-bottom: 0.625rem;
    padding-bottom: 0.625rem;
}
body > table > tbody .detail {
    align-items: center;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    margin-right: 0.5rem;
}
body > table > tbody .detail > * + * {
    margin-left: 0.5rem;
}
body > table > tbody .detail > .spring {
    flex: 1;
}
body > table > tbody .rocket {
    height: 1.125rem;
    margin-top: 0.25rem;
}
body > table > tbody td {
    border-bottom: 0.0625rem solid rgb(221, 221, 221);
}
body > table > tbody td.spaced {
    border: 0.0625rem solid rgb(221, 221, 221);
    border-right: none;
    padding: 0.5rem 1rem;
    text-align: center;
}
body > table > tfoot td {
    padding: 1.5rem;
}
body > table > tfoot .wrapper {
    align-items: center;
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
}
body > table > tfoot .value {
    font-weight: 600;
    margin-left: 0.5rem;
}
body > table > tfoot .sign {
    top: 0.0625rem;
    width: 1.5rem;
    height: 1.5rem;
    align-items: center;
    background-color: rgb(200, 200, 200);
    border-radius: 50%;
    box-sizing: border-box;
    color: rgb(255, 255, 255);
    display: flex;
    flex-direction: row;
    font-size: 1.25rem;
    font-weight: 800;
    justify-content: center;
    margin: 0 0.5rem;
    padding-bottom: 0.3rem;
    position: relative;
}
body > table > tfoot .value:last-child {
    font-size: 1.125rem;
}
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>

-> 최종결과

0개의 댓글