I T H

[프로젝트] 17. 상품상세 페이지 - 슬라이드 이미지 (Week 4) 본문

Spring ArtGallery Project

[프로젝트] 17. 상품상세 페이지 - 슬라이드 이미지 (Week 4)

thdev 2024. 1. 24. 09:45

메인화면의 상품 이미지들 중 1개를 클릭하여 링크를 통해 상품상세 페이지로 이동하도록 구현함.

URL 링크 호출 시 파라미터 값으로 상품의 아이디를 전달한 후 

상품상세 페이지에서 해당 아이디 값을 통해 

상세 정보를 조회 후 화면에 출력하도록 함.

 

상품에 대한 이미지들을 통해 슬라이드 이미지 효과도 적용.

 

[ product.jsp ]

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
	
<!DOCTYPE html>
<html lang="kr">

<head>
    <meta charset="UTF-8">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- The above 4 meta tags *must* come first in the head; any other head content must come *after* these tags -->

    <!-- Title  -->
    <title>ART - 상품 상세</title>

	<!-- import CSS -->
	<%@include file="/resources/inc/incCss.jsp"%>
</head>

<body>

    <!-- ##### Main Content Wrapper Start ##### -->
    <div class="main-content-wrapper d-flex clearfix">

        <!-- import Header -->
		<%@include file="/resources/inc/incHeader.jsp"%>

        <div class="single-product-area section-padding-100 clearfix">
            <div class="container-fluid">

                <div class="row">
                    <div class="col-12">
                        <nav aria-label="breadcrumb">
                            <ol class="breadcrumb mt-50">
                                <li class="breadcrumb-item"><a href="#">상품</a></li>
                                <li class="breadcrumb-item active txtProdName" aria-current="page">white modern chair</li>
                            </ol>
                        </nav>
                    </div>
                </div>

                <div class="row">
                    <div class="col-12 col-lg-7">
                        <div class="single_product_thumb">
                            <div id="product_details_slider" class="carousel slide" data-ride="carousel">
                            	<!-- 하단에 작은 이미지들 영역 -->
                                <ol class="carousel-indicators">
                                </ol>
                                <!-- 메인 이미지 영역 -->
                                <div class="carousel-inner">
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="col-12 col-lg-5">
                        <div class="single_product_desc">
                            <!-- Product Meta Data -->
                            <div class="product-meta-data">
                                <div class="line"></div>
                                <p class="product-price">$180</p>
                                <a>
                                    <h6 class="txtProdName">White Modern Chair</h6>
                                </a>
                                <!-- Ratings & Review -->
                                <div class="ratings-review mb-15 d-flex align-items-center justify-content-between">
                                    <div class="ratings">
                                        <i class="fa fa-star" aria-hidden="true"></i>
                                        <i class="fa fa-star" aria-hidden="true"></i>
                                        <i class="fa fa-star" aria-hidden="true"></i>
                                        <i class="fa fa-star" aria-hidden="true"></i>
                                        <i class="fa fa-star" aria-hidden="true"></i>
                                    </div>
                                    <div class="review">
                                        <a href="#">Write A Review</a>
                                    </div>
                                </div>
                                <!-- Avaiable -->
                                <p class="avaibility"><i class="fa fa-circle"></i> 판매중</p>
                            </div>

                            <div class="short_overview my-5">
                                <pre class="txtProdDesc"></pre>
                            </div>

                            <!-- Add to Cart Form -->
                            <form class="cart clearfix" method="post">
                                <div class="cart-btn d-flex mb-50">
                                    <p><small>수량</small></p>
                                    <select class="w-50" id="cmbCnt">
                                   	</select>
                                </div>
                                <button type="submit" name="addtocart" value="5" class="btn amado-btn">장바구니 담기</button>
                            </form>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- ##### Main Content Wrapper End ##### -->

    <!-- import Footer -->
	<%@include file="/resources/inc/incFooter.jsp"%>

    <!-- import JS -->
	<%@include file="/resources/inc/incJs.jsp"%>
	
	<!-- page script -->
	<script src="/resources/views/product.js"></script>

</body>

</html>

 

[ product.js ]

/*******************************************************************************
 * product.js
 * @author thkim
 * @since 2022
 * @DESC 상품상세조회 화면 스크립트
 ******************************************************************************/
(function() {
	
	function Product() {
		
		/* 
		 * private variables
		 */
		var prodId = "";
		
		/* 
		 * 초기화 메소드
		 */
		function _init() {
			// 이벤트 처리 함수 호출 
			bindEvent();
			
			// url 파라미터로 넘어온 상품 아이디를 통해 상품 정보를 조회한다.
			var url = window.location.href;
			if(url.indexOf("prodId=") > -1) {
				
				prodId = getParameterByName("prodId");
				
				// 상품 상세 조회 (1개)
				findProductInfo();
			}
		}
		
		function bindEvent() {
			
		}
		
		/*
		 * URL에서 파라미터 추출
		 */
		function getParameterByName(name) {
	        name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
	        var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
	                results = regex.exec(location.search);
	        return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
	    }
		
		/*
		 * 상품 상세 조회 (1개)
		 */
		function findProductInfo() {
			
			var obj = {
				prodId: prodId
			};
			
			cfFind("/product/findProductInfo", obj, function(data) {
				if(data.length > 0) {
					// 조회한 상품 정보 화면에 세팅 
					$(".product-price").html(data[0].PROD_PRICE + "원 부터");
					$(".txtProdDesc").html(data[0].PROD_DESC);
					$(".txtProdName").html(data[0].PROD_NAME);
					var cnt = Number(data[0].PROD_CNT);
					var cmbHtml = "";
					for(var i = 1; i <= cnt; i++) {
						cmbHtml += "<option value='" + i + "'>" + i + "</option>";
					}
					$('#cmbCnt').html(cmbHtml);
					$('#cmbCnt').val(data[0].PROD_CNT).niceSelect('update');
					
					// 이미지 세팅
					var activeCls = "";
					var mainImgHtml = "";
					var subImgHtml = "";
					$.each(data, function(idx, node) {
						// 메인 이미지이면 active 설정
						if(idx == 0) {
							activeCls = "active";
						} else {
							activeCls = "";
						}
						
						mainImgHtml += "<div class='carousel-item " + activeCls + "'>";
                        mainImgHtml += "            <a class='gallery_img' href='/resources/upload/" + node["PROD_IMG"] + "'>";
                        mainImgHtml += "                <img class='d-block w-100' src='/resources/upload/" + node["PROD_IMG"] + "'>";
                        mainImgHtml += "            </a>";
                        mainImgHtml += "</div>";
						subImgHtml += "<li class='" + activeCls + "' data-target='#product_details_slider' data-slide-to='" + idx + "' style='background-image: url(/resources/upload/" + node["PROD_IMG"] + ");'></li>";
					});
					
					$(".carousel-inner").html(mainImgHtml);
					$(".carousel-indicators").html(subImgHtml);
				} 
			}, true, "POST");
		}
		
		function _finalize() {
		}
		
		return {
            init : _init,
            finalize : _finalize
        };
    };
    
    var product = new Product();
    product.init();
    
})();

//# sourceURL=product.js

 

[ ProductController.java ]

package kr.co.art.biz.product.web;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.co.art.biz.product.persistence.ProductMapper;

@Controller
@RequestMapping("/product")
public class ProductController {
	
	@Autowired
	private ProductMapper productMapper;
	
	@RequestMapping("")
	public String main() {
		return "product";
	}
	
	/**
	 * 상품상세 조회
	 * (/product/findProductInfo)
	 * @return
	 */
	@RequestMapping("/findProductInfo")
	@ResponseBody
	public List<Map<String, Object>> findProductInfo(@RequestBody Map<String, Object> param) {
		List<Map<String, Object>> list = productMapper.findProductInfo(param);
		
		return list;
	}
	
}

 

[ ProductMapper.java ]

package kr.co.art.biz.product.persistence;

import java.util.List;
import java.util.Map;

public interface ProductMapper {
	
	// 상품 상세 조회
	List<Map<String, Object>> findProductInfo(Map<String, Object> params);
	
}

 

[ ProductMapper.xml ]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="kr.co.art.biz.product.persistence.ProductMapper">

	<select id="findProductInfo" resultType="hashmap" parameterType="hashmap">
		SELECT A.PROD_NAME 
		     , A.PROD_PRICE 
		     , A.PROD_CNT 
		     , A.PROD_DESC 
		     , B.PROD_IMG 
		     , B.MAIN_IMG 
		  FROM ART.ART_PROD A
		  LEFT OUTER JOIN ART.ART_PROD_DETAIL B 
		    ON A.PROD_ID = B.PROD_ID 
		 WHERE 1=1
		   AND A.PROD_ID = #{prodId}
		 ORDER BY B.MAIN_IMG DESC
		 LIMIT 4
	</select>
	
</mapper>

 

[ 결과 화면 ]