์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ(11) ํšŒ์› MY PAGE - ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก

2023. 4. 5. 16:24ใ†Spring

ํ™”๋ฉด ์ƒ๋‹จ์˜ MY PAGE ๋ˆŒ๋ €์„ ๋•Œ ํšŒ์›์ด ๋ณด๋ฉด ํ™”๋ฉด์ฐฝ ๊ตฌ์„ฑ

personal_layout.html ์ƒ์„ฑ

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
   xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<!-- bootstrap css ๋กœ๋”ฉ -->
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<!-- admin_layout๊ณผ ์—ด๋ฆฌ๋Š” ๋ชจ๋“  ํŽ˜์ด์ง€์— ์—ด๋ฆฌ๋Š” ๊ณตํ†ต ์ ์šฉ๋˜๋Š” css ๋กœ๋”ฉ -->
<link rel="stylesheet" href="/css/common.css">
<!-- header์— ์ ์šฉ๋˜๋Š” css -->
<link rel="stylesheet" href="/css/fragment/header.css">
<!-- content ํŽ˜์ด์ง€๊ฐ€ ์—ด๋ฆด ๋•Œ ๊ฐ™์ด ์—ด๋ฆฌ๋Š” css (ํŽ˜์ด์ง€๋งˆ๋‹ค ๋ฐ”๋€Œ๋Š” css) -->
<th:block layout:fragment="content_css"></th:block>
</head>
<body>
<div class="container">
			<!-- ํ–‰ -->
	<div class="row" style="margin-bottom: 30px;">
				<!-- ์—ด -->
		<div class="col">
			 <!-- headerFragment๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ง€์ •๋œ layout ํŽ˜์ด์ง€๋กœ ๋Œ€์ฒด๋จ -->
      		<th:block th:replace="~{fragment/header::headerFragment}"></th:block>
		</div>
	</div>
	<div class="row">
		<div class="col-3"> <!-- ํ–‰์€ 12 ๋ถ€๋ถ„์ž„ ์‚ฌ์ด์ฆˆ ์ง€์ • ๊ฐ€๋Šฅ  -->
			 <!-- adminSideFragment๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ง€์ •๋œ layout ํŽ˜์ด์ง€๋กœ ๋Œ€์ฒด๋จ -->
      		<th:block th:replace="~{fragment/personal_side::personalSideFragment}"></th:block>
		</div>
		<div class="col-9">	   
   			<!-- content๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ง€์ •๋œ layout ํŽ˜์ด์ง€ ์—ด๋ฆผ (๋ฐ”๋€Œ๋Š” ํ™”๋ฉด) -->
     		 <th:block layout:fragment="content"></th:block>
		</div>
	</div>
</div>

<!-- Jquery ๋ฌธ๋ฒ• ๋กœ๋”ฉ -->
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<!-- bootstrap js ๋กœ๋”ฉ  -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<!-- header.js ๋กœ๋”ฉ -->
<script type="text/javascript" src="/js/fragment/header.js"></script>
<!-- ์šฐํŽธ๋ฒˆํ˜ธ api -->
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<!-- content ํŽ˜์ด์ง€๊ฐ€ ์—ด๋ฆด ๋•Œ ๊ฐ™์ด ์—ด๋ฆฌ๋Š” js  -->
<th:block layout:fragment="content_js"></th:block>
</body>
</html>

personal_side.html ์ƒ์„ฑ ๋‘ html ์—ฐ๊ฒฐ fragment๋กœ ํ™”๋ฉด ๊ตฌ์„ฑ

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">


<th:block th:fragment="personalSideFragment">
	<div class="row">
		<div class="col">    <!-- active -->
			<div class="list-group">
					<!-- ํšŒ์› ์‚ฌ์ด๋“œ ๋ฉ”๋‰ด --> 
					<a href="" 
					class="list-group-item list-group-item-action">
						์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก
					</a>
					<a href="" 
					class="list-group-item list-group-item-action">
						๊ตฌ๋งค ๋‚ด์—ญ
					</a>
					<a href="" 
					class="list-group-item list-group-item-action">
						๊ฐœ์ธ์ •๋ณด์ˆ˜์ •
					</a>
			</div>
		</div>
	</div>
</th:block>	
</html>

 

MY PAGE ๋ˆ„๋ฅด๋ฉด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ํ™”๋ฉด์œผ๋กœ ์ด๋™

header.html์˜ MY PAGE aํƒœ๊ทธ ๊ฐ์‹ธ์„œ controller ์ด๋™

<a th:href="@{/cart/cartList}">MY PAGE</a>

 

controller ์ž‘์„ฑ. ํŽ˜์ด์ง€ ์ด๋™ ๊ฒฝ๋กœ ์„ค์ •

	//์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€
	@GetMapping("/cartList")
	public String cartList() {
		
		return "content/cart/cart_list";
	}

cart_list.html ์ƒ์„ฑ

personal_layout๊ณผ ๊ฐ™์ด ์—ด๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— fragment ์„ค์ •

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
   xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
   layout:decorate="~{fragment/personal_layout}">

<!-- ์—ฐ๊ฒฐํ•ด์•ผ ํ•  ์™ธ๋ถ€ css ํŒŒ์ผ -->
<th:block layout:fragment="content_css">
	<!--<link rel="stylesheet" href="/css/test.css(๋ณ€๊ฒฝ)">--> <!-- ์™ธ๋ถ€ css ์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ๋ฅผ block ์•ˆ์— ์ž‘์„ฑ layout์—์„œ ๊ฐ™์ด ์—ด์–ด์คŒ -->
</th:block>


<th:block layout:fragment="content">
	์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก
</th:block>

<!-- ์—ฐ๊ฒฐํ•ด์•ผ ํ•  ์™ธ๋ถ€ js ํŒŒ์ผ-->
<th:block layout:fragment="content_js">
	<!--<script type="text/javascript" src="/js/test.js(๋ณ€๊ฒฝ)"></script> --> <!-- ์™ธ๋ถ€ js ์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ๋ฅผ block ์•ˆ์— ์ž‘์„ฑ layout์—์„œ ๊ฐ™์ด ์—ด์–ด์คŒ -->
</th:block>


</html>

MY PAGE ํด๋ฆญ ์‹œ ์œ„์ฒ˜๋Ÿผ personal_side ๋œจ๊ณ  ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€๋กœ ์ด๋™

 

๋ฉ”๋‰ด์— ์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์•ˆ ๋œธ. > ๋งค๋ฒˆ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ชฉ๋ก ์กฐํšŒ ์ฟผ๋ฆฌ ๋ฐ˜๋ณต ํ•ด์•ผํ•จ.

์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒํ•˜๋Š” ์ธํ„ฐ์…‰ํŠธ ์ƒ์„ฑํ•˜์—ฌ ์ฒ˜๋ฆฌ

CategoryInterceptor ํด๋ž˜์Šค ์ƒ์„ฑํ•˜์—ฌ HandlerInterceptor ๊ตฌํ˜„ 

๋ฉ”์†Œ๋“œ ์‹คํ–‰์„ ์œ„ํ•ด ๊ทธ ์ „์— itemService ์˜์กด์„ฑ ์ฃผ์ž….

postHandle ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์—ฌ ์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ ๋ฉ”์†Œ๋“œ ์‹คํ–‰.

//์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ 
public class CategoryInterceptor implements HandlerInterceptor{
	
	//์˜์กด์„ฑ ์ฃผ์ž…
	@Resource(name = "itemService")
	private ItemService itemService;

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		//์‚ฌ์šฉ์ค‘์ธ ์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ
		modelAndView.addObject("categoryList", itemService.getCateListInUse());
	}

}

IntercepterConfig ํด๋ž˜์Šค์—์„œ ์ธํ„ฐ์…‰ํ„ฐ ์–ธ์ œ ์“ธ ์ง€ ์„ค์ •.

์ƒํ’ˆ ๋ชฉ๋ก, ์ƒํ’ˆ ์ƒ์„ธ ์กฐํšŒ, ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€ ์ด๋™ํ•  ๋•Œ ์ธํ„ฐ์…‰ํ„ฐ ํ•„์š”.

 

์นดํ…Œ๊ณ ๋ฆฌ ์ธํ„ฐ์…‰ํ„ฐ์— ๋Œ€ํ•œ ๊ฐ์ฒด ์ƒ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ฆฌํ„ด

@Bean
public CategoryInterceptor getCategoryInterceptor() {
    return new CategoryInterceptor();
}

 

์ธํ„ฐ์…‰ํ„ฐ ์–ธ์ œ ์‹คํ–‰๋  ์ง€ ์„ค์ •

//์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ
registry.addInterceptor(getCategoryInterceptor())
        .addPathPatterns("/item/**") //์ƒํ’ˆ ๊ด€๋ จ ํŽ˜์ด์ง€ ๋“ค์–ด๊ฐˆ ๋•Œ๋งˆ๋‹ค
        .addPathPatterns("/cart/**") //์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ด€๋ จ 
        .excludePathPatterns("/**/*Ajax"); //๋ชจ๋“  ์ปจํŠธ๋กค๋Ÿฌ์˜ Ajax๋กœ ๋๋‚˜๋Š” ์ด๋™๊ฒฝ๋กœ ์ œ์™ธ

์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์‚ฌ์šฉ์ค‘์ธ ์ƒํ’ˆ ๋ชฉ๋ก ์กฐํšŒํ•˜๋Š” ๋ฉ”์†Œ๋“œ ์‚ญ์ œํ•ด์ฃผ๊ณ  ์ธํ„ฐ์…‰ํ„ฐ๋กœ ๋‹ค ์ฒ˜๋ฆฌ๋˜๊ฒŒ ํ•จ.

 

 

 

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ํ™”๋ฉด ๊ทธ๋ฆฌ๊ธฐ

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ ๊ธฐ๋Šฅ.

์กฐ์ธ ์‚ฌ์šฉํ•˜์—ฌ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ ์ฟผ๋ฆฌ ์ž‘์„ฑ

	<!-- ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ -->
	<select id="getCartList" resultMap="cart">
		SELECT CART_CODE 
			, ITEM.ITEM_CODE
			, ITEM_NAME
			, ITEM_PRICE
			, CART_CNT
			, ATTACHED_FILE_NAME
			, CART_CNT * ITME_PRICE AS TOTAL_PRICE
		FROM SHOP_ITEM ITEM, SHOP_CART CART, ITEM_IMG IMG
		WHERE ITEM.ITEM_CODE = IMG.ITEM_CODE
		AND ITEM.ITEM_CODE = CART.ITEM_CODE
		WHERE IS_MAIN = 'Y'
		AND MEM_ID = #{memId}
		
			
	</select>

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ ์‹œ ์ƒํ’ˆ ์ •๋ณด์™€ ์ด๊ฐ€๊ฒฉ ๋ฐ์ดํ„ฐ ๋‹ด์•„์˜ฌ ๊ณณ์ด ํ•„์š”.

CartVO์— ๋ณ€์ˆ˜ ์ถ”๊ฐ€

private int totalPrice;
private ItemVO itemVO; //CartVO๋Š” ์ƒํ’ˆ ์ •๋ณด ํ•˜๋‚˜๋ฅผ ๊ฐ€์ง.

 

CartMapper resultMap ์ž‘์„ฑ ์‹œ ์ฃผ์˜!

itemVO๋Š” association์‚ฌ์šฉํ•˜์—ฌ resultMap ์ž‘์„ฑ

itemVO๋Š” imgList ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋‹ค ๋ฐ›์•„์˜ด.

TOTAL_PRICE๋Š” ์–ด๋–ค resultMap์—๋„ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€ ์ž‘์„ฑ.

<mapper namespace="cartMapper">
	<resultMap type="com.study.shop.cart.vo.CartVO" id="cart">
		<id column="CART_CODE" property="cartCode"/>
		<result column="ITEM_CODE" property="itemCode"/>
		<result column="MEM_ID" property="memId"/>
		<result column="REG_DATE" property="regDate"/>
		<result column="CART_CNT" property="cartCnt"/>
		<result column="TOTAL_PRICE" property="totalPrice"/>
		<association property="itemVO" resultMap="itemMapper.item"></association>
	</resultMap>

 

CartService ์ž‘์„ฑ

//์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ
List<CartVO> getCartList(String memId);

CartServiceImpl ์ž‘์„ฑ

//์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ
@Override
public List<CartVO> getCartList(String memId) {
    return sqlSession.selectList("cartMapper.getCartList", memId);
}

CartController ์ž‘์„ฑ

//์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€
@GetMapping("/cartList")
public String cartList(Model model, HttpSession session) {
    //์„ธ์…˜์—์„œ memId ๋นผ๊ธฐ
    MemberVO loginInfo = (MemberVO)session.getAttribute("loginInfo");

    //์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก ์กฐํšŒ
    List<CartVO> cartList = cartService.getCartList(loginInfo.getMemId());
    model.addAttribute("cartList", cartList);

    //์ด ๊ตฌ๋งค๊ธˆ์•ก ๊ณ„์‚ฐ
    int finalPrice = 0;
    for(CartVO cart : cartList) {
        finalPrice += cart.getTotalPrice();
    }

    model.addAttribute("finalPrice", finalPrice);

    return "content/cart/cart_list";
	}
}

 

 

๊ตฌ๋งค๊ธˆ์•ก์€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ๋“ค์— ์ฒดํฌ๋ฐ•์Šค๋ฅผ ์ฒดํฌํ•œ ๊ฒƒ๋“ค์˜ ๊ฐ€๊ฒฉ ํ•ฉ์ด ๋“ค์–ด์˜ด.

controller์—์„œ ์ด ๊ตฌ๋งค๊ธˆ์•ก ๊ณ„์‚ฐํ•˜์—ฌ html์— ์ „๋‹ฌ

 

cart_list.html์— ๋ฐ์ดํ„ฐ ๋ฟŒ๋ ค์ฃผ๊ธฐ.

๋ฐ์ดํ„ฐ ๋ฟŒ๋ฆด ๋•Œ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ฝ”๋“œ ์ฃผ์˜!

cartVO ์•ˆ์˜ itemVO ์•ˆ์˜ itemList์˜ 0๋ฒˆ์งธ ๋ฐ์ดํ„ฐ์˜ attachedFileName ๋ถˆ๋Ÿฌ์™€์•ผ ํ•จ.

0๋ฒˆ์งธ ๋ฐ์ดํ„ฐ์ธ ์ด์œ  : IS_MIAN = 'Y'์ธ ๊ฒƒ ํ•˜๋‚˜๋ฟ์ž„.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
   xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
   layout:decorate="~{fragment/personal_layout}">

<!-- ์—ฐ๊ฒฐํ•ด์•ผ ํ•  ์™ธ๋ถ€ css ํŒŒ์ผ -->
<th:block layout:fragment="content_css">
	<!--<link rel="stylesheet" href="/css/test.css(๋ณ€๊ฒฝ)">--> <!-- ์™ธ๋ถ€ css ์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ๋ฅผ block ์•ˆ์— ์ž‘์„ฑ layout์—์„œ ๊ฐ™์ด ์—ด์–ด์คŒ -->
</th:block>


<th:block layout:fragment="content">
	<div class="row">
		<div class="col">
			<div class="row mb-3">
				<div class="col">
						<table class="table table-hover text-center align-middle">
						<colgroup>
							<col width="7%">
							<col width="15%">
							<col width="*">
							<col width="15%">
							<col width="15%">
							<col width="15%">
							<col width="7%">
						</colgroup>
						<thead class="table-head">
							<tr>
								<td>
									<input type="checkbox" class="form-check-input" checked>
								</td>
								<td>์ƒํ’ˆ ์ด๋ฏธ์ง€</td>
								<td>์ƒํ’ˆ๋ช…</td>
								<td>๊ฐ€ ๊ฒฉ</td>
								<td>์ˆ˜ ๋Ÿ‰</td>
								<td>์ด ๊ฐ€๊ฒฉ</td>
								<td></td>
							</tr>
						</thead>
						<tbody>
							<th:block th:if="${#lists.size(cartList) == 0}">
								<tr>
									<td colspan="7">์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธด ์ƒํ’ˆ์ด ์—†์Šต๋‹ˆ๋‹ค.</td>
								</tr>
							</th:block>
							<th:block th:if="${#lists.size(cartList) != 0}">
							
							<tr th:each="cart : ${cartList}">
								<td>
									<input type="checkbox" class="form-check-input" checked>
								</td>
								<td>
									<img width="70px;" th:src="${'/upload/' + cart.itemVO.imgList[0].attachedFileName}">
								</td>   <!-- ์™ผ์ชฝ ์ •๋ ฌ  -->
								<td class="text-start">[[${cart.itemVO.itemName}]]</td>
								<td>[[${#numbers.formatCurrency(cart.itemVO.itemPrice)}]]</td>
								<td>
									<div class="row">
										<div class="col-7">
											<input type="number" class="form-control" min="1" th:value="${cart.cartCnt}">
										</div>
										<div class="col-5 d-grid">
											<input type="button" class="btn btn-secondary" value="์ˆ˜์ •">
										</div>
									</div>
								</td>
								<td>[[${#numbers.formatCurrency(cart.totalPrice)}]]</td>
								<td>
									<div class="row">
										<div class="col d-grid">
											<input type="button"  class="btn btn-secondary" value="์‚ญ์ œ">
										</div>
									</div>
								</td>
							</tr>
							</th:block>
						</tbody>
					</table>
				</div>
			</div>
			<div class="row mb-3">
						<!--offset-10 : 12๋“ฑ๋ถ„ 10๋“ฑ๋ถ„ ๋น„์šฐ๊ณ  ์‹œ์ž‘ -->
				<div class="offset-9 col-2">๊ตฌ๋งค๊ธˆ์•ก</div>
				<div class="col-1">[[${#numbers.formatCurrency(finalPrice)}]]</div>
			</div>
			<div class="row mb-3">
				<div class="offset-5 col-1 d-grid">
					<input type="button" class="btn btn-primary" value="์„ ํƒ๊ตฌ๋งค">
				</div>
				<div class="col-1 d-grid">
					<input type="button" class="btn btn-primary" value="์„ ํƒ์‚ญ์ œ">
				</div>
				
			</div>
		</div>
	</div>
</th:block>

<!-- ์—ฐ๊ฒฐํ•ด์•ผ ํ•  ์™ธ๋ถ€ js ํŒŒ์ผ-->
<th:block layout:fragment="content_js">
	<!--<script type="text/javascript" src="/js/test.js(๋ณ€๊ฒฝ)"></script> --> <!-- ์™ธ๋ถ€ js ์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ๋ฅผ block ์•ˆ์— ์ž‘์„ฑ layout์—์„œ ๊ฐ™์ด ์—ด์–ด์คŒ -->
</th:block>


</html>