상품 상세 페이지

루민 ·2023년 4월 14일
0

📝상품 상세 페이지

  • 상품 상세 페이지는 Bootstrap의 쇼핑몰 무료 템플릿을 참고하였습니다.

ItemController

 	/**
     * 상품 상세 조회
     */
    @GetMapping("items/{itemId}")
    public String itemView(@PathVariable(name = "itemId") Long itemId, Model model) {
        Item item = itemService.findItem(itemId);
        List<ItemImage> itemImageList = itemImageService.findItemImageDetail(itemId, "N");

        //엔티티 -> DTO
        List<ItemImageDto> itemImageDtoList = itemImageList.stream()
                .map(ItemImageDto::new)
                .collect(Collectors.toList());

        ItemForm itemform = new ItemForm(
                item.getId(),
                item.getName(),
                item.getPrice(),
                item.getStockQuantity(),
                item.getDescription(),
                itemImageDtoList
        );

        model.addAttribute("item", itemform);

        return "item/itemView";

    }
  • 메인 페이지의 View Option을 클릭하면 상세화면으로 이동합니다.
  • 메인 페이지에서 넘어오는 itemId를 이용하여 상품 정보와 상품 이미지를 데이터베이스에서 가져옵니다.
  • itemImageService.findItemImageDetail(itemId, "N"); : 삭제 처리된 이미지는 화면에 반환하면 안되기 때문에 삭제 처리되지 않은 이미지들만 가져오도록 하였습니다.
  • 엔티티를 View에 반환하지 않기 위해 DTO로 변환해주고 View에 전달하였습니다.
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ItemForm {


    private Long itemId;
    @NotEmpty(message = "상품 이름은 필수입니다.")
    private String name;  //상품명
    @NotNull(message = "상품 가격은 필수입니다.")
    private int price; //상품 가격
    @NotNull(message = "상품 재고 수량은 필수입니다.")
    private int stockQuantity;  //재고 수량
    private String description;  //상품 설명

    //상품 수정, 장바구니,상품 상세에 사용
    private List<ItemImageDto> itemImageListDto = new ArrayList<>();

    public ItemServiceDTO toServiceDTO() {
        return ItemServiceDTO.builder()
                .id(itemId)
                .name(name)
                .price(price)
                .stockQuantity(stockQuantity)
                .description(description)
                .build();
    }
}


상품 상세 페이지

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <meta name="description" content="" />
    <meta name="author" content="" />
    <title>Roominis</title>
    <!-- Favicon-->
    <link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
    <!-- Bootstrap icons-->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet" />
    <!-- Core theme CSS (includes Bootstrap)-->
    <link href="/css/styles.css" rel="stylesheet" />

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>


<script th:inline="javascript">
    <!-- 처음 웹페이지 로딩시 호출 -->
    $(document).ready(function(){

        $("#description").val().replace()

        calculateTotalPrice();

        <!-- count 값이 변경될때마다 호출 -->
        $("#count").change(function(){
            calculateTotalPrice();
        });
    });

    <!-- 총 상품 금액 계산 -->
    function calculateTotalPrice(){

        var quantity = $("#stockQuantity").val()*1;
        var count = $("#count").val();
        var price = $("#price").val();


        <!-- 재고 부족 -->
        if (quantity < count) {
            alert("샹품 재고가 부족합니다. 재고:" + quantity + "개")
            return;
        }

        var totalPrice = price*count;
        $("#totalPrice").html(totalPrice + '원');
    }
</script>

<body>
<!-- Navigation-->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" style="background-color: #e3f2fd;">
    <div class="container px-4 px-lg-5">
        <a class="navbar-brand" th:href="@{/}">Home</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0 ms-lg-4">

            </ul>
            <form class="d-flex">
                <button class="btn btn-light btn-outline-secondary" type="submit">
                    <i class="bi-cart-fill me-1"></i>
                    Cart
                    <span class="badge bg-dark text-white ms-1 rounded-pill">0</span>
                </button>
            </form>
        </div>
    </div>
</nav>
<!-- Product section-->
<section class="py-5">
    <div class="container px-4 px-lg-5 my-5" th:object="${item}">
        <div class="row gx-4 gx-lg-5 align-items-center" >
            <div class="col-md-6"><img class="card-img-top mb-5 mb-md-0" th:src="|/images/${item.getItemImageListDto().get(0).getStoreName()}|" alt="..." /></div>
            <div class="col-md-6">
                <h1 class="display-5 fw-bolder" th:text="${item.getName()}">Shop item template</h1>
                <div class="fs-5 mb-5">
                    <input type="hidden" th:value="${item.price}" id="price" name="price">
                    <span class="text-decoration-none" th:text="${item.getPrice()}"></span></div>
                <hr class="my-4">


                <div class="input-group fs-5 mb-5">
                    <div class="input-group-prepend">
                        <input type="hidden" th:value="${item.stockQuantity}" id="stockQuantity" name="stockQuantity">
                        <span class="input-group-text">주문 수량</span>
                    </div>
                    <input class="form-control text-center me-3" id="count" name="count" type="number" value="1" style=" max-width: 5rem" />
                </div>


                <div class="container bg-light">
                    <h6>총 상품 금액</h6>
                    <h4 name="totalPrice" id="totalPrice" class="font-weight-bold" ></h4>
                </div>
                <br>

                <div class="d-flex">
                    <form th:action="@{/logout}" class="d-flex" method="post">
                        <button class="btn btn-outline-dark"
                                type="submit">
                            바로 구매하기
                        </button>
                    </form>
                    &nbsp
                    <button class="btn btn-outline-dark flex-shrink-0" type="button">
                        <i class="bi-cart-fill me-1"></i>
                        장바구니 담기
                    </button>
                </div>
            </div>
        </div>

    </div>
</section>
<!-- Related items section-->
<section class="py-5 bg-light">
    <div class="container">
        <p class="lead" id="description" style="text-align: center" th:text="${item.getDescription()}">Lorem ipsum dolor sit amet consectetur adipisicing?</p>
    </div>
    <hr class="my-4">
    <div class="container px-4 px-lg-5 mt-5"  >
        <div th:each="itemImage : ${item.getItemImageListDto()}" class="text-center">
            <img class="card-img-top rounded mb-5 mb-md-0" style="padding-bottom: 50px; width: 550px; height:700px" th:src="|/images/${itemImage.getStoreName()}|" >
        </div>
    </div>
</section>
<!-- Footer-->
<footer class="py-5 bg-dark">
    <div class="container"><p class="m-0 text-center text-white">Copyright &copy; Roominis</p></div>
</footer>
<!-- Bootstrap core JS-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Core theme JS-->
<script src="js/scripts.js"></script>
</body>
</html>
  • 컨트롤러에서 넘어온 상품 정보와 이미지를 이용해 화면에 표시되도록 하였습니다.
  • JQuery를 이용하여 주문 수량이 변경(.change())되면 총 상품 금액도 그에 맞게 계산되도록 구현하였습니다.
  • 주문 수량이 상품 재고를 초과하면 경고 메세지를 출력하도록 하였습니다.


결과 화면



📝참고

https://startbootstrap.com/template/shop-item

0개의 댓글