@ControllerAdvice
public class Common {
@Autowired
private PageRepository pageRepo;
@Autowired
private CategoryRepository categoryRepo;
@ModelAttribute
public void sharedData(Model model, HttpSession session) {
// cpages에 모든 페이지들을 순서대로 담아서 전달
List<Page> cpages = pageRepo.findAllByOrderBySortingAsc();
List<Category> categories = categoryRepo.findAll();
// 현재 Cart 상태
boolean cartActive = false; // Cart가 존재하지 않을 때 false
if (session.getAttribute("cart") != null) {
@SuppressWarnings("unchecked")
HashMap<Integer, Cart> cart = (HashMap<Integer, Cart>) session.getAttribute("cart");
int size = 0; // Cart에 담긴 상품의 갯수
int total = 0; // 총 가격
for (Cart item : cart.values()) {// 장바구니 cart 객체들을 반복, cart.values()는 key값을 빼고 데이터만 반복
size += item.getQuantity();
total += item.getQuantity() * Integer.parseInt(item.getPrice()); // 상품 수량 * 가격 = 총 가격
}
model.addAttribute("csize", size);
model.addAttribute("ctotal", total);
cartActive = true; // Cart가 존재함
}
model.addAttribute("cpages", cpages);
model.addAttribute("ccategories", categories);
model.addAttribute("cartActive", cartActive); // Cart가 존재하면 true, 없으면 false
}
}
<div th:replace="/fragments/cart_partial"></div>
/**
* 제품의 id를 입력받아 Session에 CartList를 저장한다.
* @param id
* @param session
* @return
*/
@GetMapping("/add/{id}")
public String add(@PathVariable("id") int id, HttpSession session, Model model, @RequestParam(required = false) String cartPage) {
//0. 상품을 DB에서 검색
Product product = productRepo.getById(id);
//1. Session에 상품 저장 (Map<id,cart>로 그룹을 만든다.
if (session.getAttribute("cart") == null) { // Session에 Cart가 없으면
HashMap<Integer, Cart> cart = new HashMap<>();
cart.put(id, new Cart(id, product.getName(), product.getPrice(), 1, product.getImage()));
session.setAttribute("cart", cart);
} else {//2. 이미 Cart가 있을경우 ((1) 그 상품이 이미 담겨져 있을 경우, (2) 없을 경우
HashMap<Integer, Cart> cart = (HashMap<Integer, Cart>) session.getAttribute("cart");
if(cart.containsKey(id)) { // Cart에 그 상품이 있을 경우
int qty = cart.get(id).getQuantity(); // 현재 Cart에 담긴 상품의 수량
cart.put(id, new Cart(id, product.getName(), product.getPrice(), ++qty, product.getImage())); // session에서 참조변수를 불러오는 것이라 call by reference로 인행 원본데이터에도 영향을 줌
} else {
cart.put(id, new Cart(id, product.getName(), product.getPrice(), 1, product.getImage()));
session.setAttribute("cart", cart); // 새로 생성하는 것이기 때문에 session에 저장해야할 필요가 있다.
}
}
HashMap<Integer, Cart> cart = (HashMap<Integer, Cart>) session.getAttribute("cart");
int size = 0; // Cart에 담긴 상품의 갯수
int total = 0; // 총 가격
for (Cart item : cart.values()) {// 장바구니 cart 객체들을 반복, cart.values()는 key값을 빼고 데이터만 반복
size += item.getQuantity();
total += item.getQuantity() * Integer.parseInt(item.getPrice()); // 상품 수량 * 가격 = 총 가격
}
model.addAttribute("csize", size);
model.addAttribute("ctotal", total);
if(cartPage != null) { // cart.html 페이지에서 (+)버튼을 눌렀을 때는 다시 Cart페이지로 새로고침
return "redirect:/cart/view";
}
return "cart_view";
}
<div style="position: relative">
<p>
<a class="btn btn-primary addToCart" th:attr="data-id=${product.id}" th:href="@{'/cart/add/' + ${product.id}}">장바구니추가</a>
</p>
<div class="btn btn-sm btn-success hide productAdded">추가됨!</div>
</div>
<script>
// 장바구니추가버튼을 눌렀을 때 이벤트 추가
$('a.addToCart').click(function (e) {
e.preventDefault(); // 원래 a 태그의 기능인 주소이동을 멈춤
let $this = $(this); // JQuery 변수, $변수명, 클릭한 장바구니추가버튼
let id = $this.attr('data-id'); // 상품 id 값
let url = '/cart/add/' + id;
// Ajax get 메소드, 주소는 url, 보내는 데이터 없음 {}, 결과는 data
$.get(url, {}, function (data) {
$('div.cart').html(data); // Cart화면 덮어쓰기
}).done(function () {
$this.parent().parent().find('div.productAdded').fadeIn(); // parent()는 상위태그로 이동, find()는 자식태그들 중에서 찾음, 희마하게 보여주기
setTimeout(function () {
$this.parent().parent().find('div.productAdded').fadeOut(); // 1초뒤에 사라짐
}, 1000);
});
});
</script>
<p>장바구니에 <span th:text="${csize}"></span> 개 상품이 있습니다.</p>
<p>총 가격은 <span th:text="${ctotal}"></span> 원 입니다.</p>
<p>
<a href="/cart/view" class="btn btn-success">카트 보기</a>
<a href="/cart/clear" class="btn btn-danger float-right">비우기</a>
</p>
cart에 상품 추가 전
cart에 상품 추가
@GetMapping("/view")
public String view(HttpSession session, Model model) {
if (session.getAttribute("cart") == null) {
return "redirect:/"; // Cart가 없을 경우 홈페이지로 이동
}
HashMap<Integer, Cart> cart = (HashMap<Integer, Cart>) session.getAttribute("cart");
model.addAttribute("cart", cart);
model.addAttribute("noCartView", true); // 왼쪽 Cart_view는 필요없음
return "cart";
}
@GetMapping("/subtract/{id}")
public String subtract(@PathVariable("id") int id, HttpSession session, Model model, HttpServletRequest httpServletRequest) {
HashMap<Integer, Cart> cart = (HashMap<Integer, Cart>) session.getAttribute("cart");
// 현재 cart에 담긴 상품의 갯수를 가져오기
int qty = cart.get(id).getQuantity();
if (qty == 1) { // 1에서 빼면 0 => cart에서 없어져야함
cart.remove(id); // key값으로 삭제
if(cart.size() == 0) { // cart에 상품이 담겨있지 않으면
session.removeAttribute("cart"); // session에서 삭제
}
} else {
cart.get(id).setQuantity(--qty);
}
String referenLink = httpServletRequest.getHeader("Referer"); // 요청된 이전주소의 정보가 들어있음
return "redirect:" + referenLink; // 다시 이전페이지로 이동
}
@GetMapping("/remove/{id}")
public String remove(@PathVariable("id") int id, HttpSession session, Model model, HttpServletRequest httpServletRequest) {
HashMap<Integer, Cart> cart = (HashMap<Integer, Cart>) session.getAttribute("cart");
cart.remove(id); // id로 삭제
if(cart.size() == 0) { // cart에 상품이 담겨있지 않으면
session.removeAttribute("cart"); // session에서 삭제
}
String referenLink = httpServletRequest.getHeader("Referer"); // 요청된 이전주소의 정보가 들어있음
return "redirect:" + referenLink; // 다시 이전페이지로 이동
}
@GetMapping("/clear")
public String clear(HttpSession session, Model model, HttpServletRequest httpServletRequest) {
session.removeAttribute("cart"); // session에서 삭제
String referenLink = httpServletRequest.getHeader("Referer"); // 요청된 이전주소의 정보가 들어있음
return "redirect:" + referenLink; // 다시 이전페이지로 이동
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/fragments/head :: head-front"></head>
<body>
<nav th:replace="/fragments/nav :: nav-front"></nav>
<main role="main" class="container-fluid mt-5">
<div class="row">
<div th:replace="/fragments/categories :: categories"></div>
<div class="col"></div>
<div class="col-7">
<h2 class="display-4">장바구니</h2>
<table class="table">
<tr>
<th>상품</th>
<th>이미지</th>
<th>수량</th>
<th>가격</th>
<th>합계</th>
</tr>
<!-- item은 HashMap cart의 한개의 item-->
<!-- 이 때 key값은 제품 id, value는 cart 객체이므로 item.value.name 제품이름-->
<tr th:each="item : ${cart}">
<td th:text="${item.value.name}"></td>
<td>
<img th:src="@{'/media/'+${item.value.image}}" style="height: 2em" />
</td>
<td>
<span th:text="${item.value.quantity}"></span>
<a th:href="@{'/cart/add/'+${item.value.id}} + '?cartPage=true'" class="btn btn-success btn-sm">+</a>
<a th:href="@{'/cart/subtract/'+${item.value.id}}" class="btn btn-primary btn-sm">-</a>
<a th:href="@{'/cart/remove/'+${item.value.id}}" class="btn btn-danger btn-sm">삭제</a>
</td>
<td th:text="${item.value.price} + ' 원'"></td>
<td th:with="totalPrice = ${item.value.price}*${item.value.quantity}" th:text="${totalPrice} + ' 원'"></td>
</tr>
<tr>
<th colspan="5" class="text-right pr-5" th:text="'총 합계 : ' + ${ctotal} + ' 원'"></th>
</tr>
<tr>
<td>
<a href="/cart/clear" class="btn btn-danger">비우기</a>
</td>
<td colspan="4" class="text-right">
<a href="#" class="btn btn-success checkout">체크아웃</a>
</td>
</tr>
</table>
</div>
<div class="col"></div>
</div>
</main>
<footer th:replace="/fragments/footer :: footer"></footer>
<script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-1.2.0.js"></script>
<script>
$(function () {
$('a.checkout').click(function (e) {
e.preventDefault();
$.get('/cart/clear', {}, function () {}); // ajax로 cart clear 요청
//$("form#paypalform").submit();
kakaoPay();
});
});
</script>
<script th:inline="javascript">
function kakaoPay() {
var IMP = window.IMP; // 생략 가능
IMP.init('imp97492501'); // 예: imp00000000
IMP.request_pay(
{
pg: 'kakaopay',
//pay_method : 'card', //생략 가능
merchant_uid: 'order_no_0015', // 상점에서 관리하는 주문 번호(중복안되어야 됨)
name: '주문명:결제테스트',
amount: [[${ctotal}]],
buyer_email: 'iamport@siot.do',
buyer_name: '구매자이름',
buyer_tel: '010-1234-5678',
buyer_addr: '서울특별시 강남구 삼성동',
buyer_postcode: '123-456',
},
function (rsp) {
if (rsp.success) {
let msg = '결제가 완료되었습니다.';
msg += '고유ID : ' + rsp.imp_uid;
msg += '상점 거래ID : ' + rsp.merchant_uid;
msg += '결제 금액 : ' + rsp.paid_amount;
msg += '카드 승인번호 : ' + rsp.apply_num;
if (!alert(msg)) location.reload();
} else {
let msg = '결제에 실패하였습니다.';
msg += '에러내용 : ' + rsp.error_msg;
alert(msg);
}
}
);
}
</script>