I T H

[프로젝트] 18. 상품페이지 - 장바구니 담기 (Week 4) 본문

Spring ArtGallery Project

[프로젝트] 18. 상품페이지 - 장바구니 담기 (Week 4)

thdev 2024. 1. 24. 09:47

등록된 모든 상품 리스트를 출력하는 페이지를 구현

- 해당 화면에서는 상품을 장바구니에 담을 수 있도록 기능을 구현.

 

추후 고려해봐야 할 로직

1. 이미 동일한 상품이 장바구니에 담겨있는 경우
2. 장바구니에 담을 상품 수량이 초과된 경우

 

[ prod.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="amado_product_area section-padding-100">
            <div class="container-fluid">

                <div class="row">
                    <div class="col-12">
                        <div class="product-topbar d-xl-flex align-items-end justify-content-between">
                            <!-- Total Products -->
                            <div class="total-products">
                                <p>Showing 1-8 0f 25</p>
                                <div class="view d-flex">
                                    <a href="#"><i class="fa fa-th-large" aria-hidden="true"></i></a>
                                    <a href="#"><i class="fa fa-bars" aria-hidden="true"></i></a>
                                </div>
                            </div>
                            <!-- Sorting -->
                            <div class="product-sorting d-flex">
                                <div class="sort-by-date d-flex align-items-center mr-15">
                                    <p>Sort by</p>
                                    <form action="#" method="get">
                                        <select name="select" id="sortBydate">
                                            <option value="value">Date</option>
                                            <option value="value">Newest</option>
                                            <option value="value">Popular</option>
                                        </select>
                                    </form>
                                </div>
                                <div class="view-product d-flex align-items-center">
                                    <p>View</p>
                                    <form action="#" method="get">
                                        <select name="select" id="viewProduct">
                                            <option value="value">12</option>
                                            <option value="value">24</option>
                                            <option value="value">48</option>
                                            <option value="value">96</option>
                                        </select>
                                    </form>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

				<!-- 상품 리스트 출력할 영역 -->
                <div id="mainArea" class="row">
                    
                </div>

                <div class="row">
                    <div class="col-12">
                        <!-- Pagination -->
                        <nav aria-label="navigation">
                            <ul class="pagination justify-content-end mt-50">
                                <li class="page-item active"><a class="page-link" href="#">01.</a></li>
                                <li class="page-item"><a class="page-link" href="#">02.</a></li>
                                <li class="page-item"><a class="page-link" href="#">03.</a></li>
                                <li class="page-item"><a class="page-link" href="#">04.</a></li>
                            </ul>
                        </nav>
                    </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/prod.js"></script>

</body>

</html>

 

[ prod.js ]

/*******************************************************************************
 * prod.js
 * @author thkim
 * @since 2022
 * @DESC 상품 정보 화면 스크립트
 ******************************************************************************/
(function() {
	
	function Prod() {
		
		/* 
		 * private variables
		 */
		var userId = "";
		
		/* 
		 * 초기화 메소드
		 */
		function _init() {
			// 이벤트 처리 함수 호출 
			bindEvent();
			
			// 세션에서 로그인한 사용자 아이디 가져오기
			findSessionInfo();
			
			// 등록된 상품 리스트 조회 
			findProdInfo();
		}
		
		function bindEvent() {
		}
		
		/*
		 * 세션에서 사용자 아이디 가져오기 
		 */
		function findSessionInfo() {
			var obj = {
			};
			
			// 로그인한 세션이 존재하는지 체크 후 아이디 정보를 가져온다. 
			cfFind("/findSession", obj, function(data) {
				userId = data.sessionId;
			}, true, "POST");
		} 
		
		/*
		 * 등록된 상품 리스트 조회 
		 */
		function findProdInfo() {
			
			var obj = {
			};
			
			// 등록된 상품 모든 리스트를 조회하여 화면에 출력한다.
			cfFind("/prod/findProdInfo", obj, function(data) {
				if(data.length > 0) {
					var html = "";
					$.each(data, function(idx, node) {
						html +="<div class='col-12 col-sm-6 col-md-12 col-xl-6'>";
                        html +="<div class='single-product-wrapper'>";
                        html +="    <div class='product-img'>";
                        html +="         <img src='/resources/upload/" + node["PROD_IMG"] + "' alt=''>";
                        html +="         <img class='hover-img' src='/resources/upload/" + node["PROD_IMG"] + "' alt=''>";
                        html +="    </div>";

                        html +="    <div class='product-description d-flex align-items-center justify-content-between'>";
                        html +="        <div class='product-meta-data'>";
                        html +="            <div class='line'></div>";
                        html +="            <p class='product-price'>" + node["PROD_PRICE"] + "</p>";
                        html +="            <a href='/product?prodId=" + node["PROD_ID"] + "'>";
                        html +="                <h6>" + node["PROD_NAME"] + "</h6>";
                        html +="            </a>";
                        html +="        </div>";
                        html +="        <div class='ratings-cart text-right'>";
                        html +="            <div class='ratings'>";
                        html +="                <i class='fa fa-star' aria-hidden='true'></i>";
                        html +="                <i class='fa fa-star' aria-hidden='true'></i>";
                        html +="                <i class='fa fa-star' aria-hidden='true'></i>";
                        html +="                <i class='fa fa-star' aria-hidden='true'></i>";
                        html +="                <i class='fa fa-star' aria-hidden='true'></i>";
                        html +="            </div>";
                        html +="            <div class='cart'>";
                        html +="                <a id='" + node["PROD_ID"] + "' class='btnCart' data-toggle='tooltip' data-placement='left' title='Add to Cart'><img src='/resources/img/core-img/cart.png' alt=''></a>";
                        html +="            </div>";
                        html +="        </div>";
                        html +="    </div>";
                        html +="</div>";
                    	html +="</div>";
					});
					
					$("#mainArea").html(html);
					
					// 상품마다 우측 하단 장바구니 누를 경우 
					$(".btnCart").on("click", function() {
						// 사용자 아이디
						// 상품 아이디 
						// 수량 
						// -> 장바구니 테이블에 insert 하기 (delete 후 다시 insert) 
						var prodId = $(this)[0].id;
						var result = confirm("장바구니에 등록하시겠습니까?");
						if(result) {
							var obj = {
								userId: userId,
								prodId: prodId,
								prodCnt: '1'
							}
							
							cfSave("/prod/saveCartInfo", obj, function(data) {
								if(data.success) {
									alert("장바구니 등록이 완료되었습니다.");
								}
							});
						}
						
					});
				} else {
					alert("등록된 상품 정보가 없습니다.");
					return;
				}
			}, true, "POST");
		}
		
		function _finalize() {
		}
		
		return {
            init : _init,
            finalize : _finalize
        };
    };
    
    var prod = new Prod();
    prod.init();
    
})();

//# sourceURL=prod.js

[ ProdController.java ]

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

import java.util.HashMap;
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.prod.persistence.ProdMapper;
import kr.co.art.biz.prod.service.ProdService;

@Controller
@RequestMapping("/prod")
public class ProdController {
	
	@Autowired
	private ProdService prodService;
	
	@Autowired
	private ProdMapper prodMapper;
	
	@RequestMapping("")
	public String main() {
		return "prod";
	}
	
	/**
	 * 상품 리스트 조회
	 * (/prod/findProdInfo)
	 * @return
	 */
	@RequestMapping("/findProdInfo")
	@ResponseBody
	public List<Map<String, Object>> findProdInfo(@RequestBody Map<String, Object> param) {
		List<Map<String, Object>> list = prodMapper.findProdInfo(param);
		
		return list;
	}
	
	/**
	 * 장바구니 등록
	 * (/prod/saveCartInfo)
	 * @return
	 */
	@RequestMapping("/saveCartInfo")
	@ResponseBody
	public Map<String, Object> saveCartInfo(@RequestBody Map<String, Object> param) {
		Map<String, Object> result = new HashMap<String, Object>();
		prodService.saveCartInfo(param);
		
		result.put("success", true);
		return result;
	}
	
}

 

[ ProdService.java ] 

package kr.co.art.biz.prod.service;

import java.util.Map;

public interface ProdService {
	// 장바구니 넣기
	void saveCartInfo(Map<String, Object> map);
}

 

[ ProdServiceImpl.java ]

package kr.co.art.biz.prod.service;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.co.art.biz.prod.persistence.ProdMapper;

@Service
public class ProdServiceImpl implements ProdService {

	@Autowired
	private ProdMapper prodMapper;
	
	@Override
	public void saveCartInfo(Map<String, Object> map) {
		
		prodMapper.saveCartInfoRemove(map);
		prodMapper.saveCartInfo(map);
	}

}

 

[ ProdMapper.java ]

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

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

public interface ProdMapper {
	
	// 상품 상세 조회
	List<Map<String, Object>> findProdInfo(Map<String, Object> params);
	
	// 선택한 상품 장바구니에 담기
	void saveCartInfo(Map<String, Object> params);
	
	// 상품 장바구니 내역 삭제 
	void saveCartInfoRemove(Map<String, Object> params);
	
}

 

[ ProdMapper.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.prod.persistence.ProdMapper">

	<select id="findProdInfo" resultType="hashmap" parameterType="hashmap">
		SELECT A.PROD_ID
		     , 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
		 ORDER BY A.PROD_ID, B.MAIN_IMG DESC
	</select>
	
	<insert id="saveCartInfo" parameterType="hashmap">
		INSERT INTO ART.ART_CART (CART_ID, USER_ID, PROD_ID, CART_CNT, INPUT_DATETIME)
		 VALUES (
		 	  UUID()
		 	, #{userId}
		 	, #{prodId}
		 	, #{prodCnt}
		 	, NOW()
		 )
	</insert>
	
	<delete id="saveCartInfoRemove" parameterType="hashmap">
		DELETE FROM ART.ART_CART
		 WHERE 1=1
		   AND USER_ID = #{userId}
		   AND PROD_ID = #{prodId}
	</delete>
	
</mapper>