Back-End/Spring
[Spring] AJAX를 이용한 쇼핑몰 좋아요 구현 소스코드
09009
2023. 6. 15. 10:14
RestCustomerController
package com.yyi.shop.customer.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yyi.shop.dto.CustomerDto;
@RestController
@RequestMapping("/customer/*")
public class RestCustomerController {
// 로그인이 되어있는지 확인
@RequestMapping("getCustomerId")
public Map<String, Object> getCustomerId(HttpSession session) {
Map<String, Object> map = new HashMap<>();
CustomerDto sessionUser = (CustomerDto) session.getAttribute("sessionUser");
if (sessionUser == null) {
map.put("result", "fail");
map.put("reason", "로그인이 되어있지 않습니다.");
} else {
map.put("result", "success");
map.put("id", sessionUser.getId());
}
return map;
}
}
ProductSqlMapper.xml
<!-- 상품 좋아요 클릭 -->
<insert id="likeProduct">
INSERT INTO product_likes VALUES(
likes_seq.nextval,
#{product_id},
#{customer_id},
SYSDATE
)
</insert>
<!-- 상품 좋아요 취소 -->
<delete id="unlikeProduct">
DELETE FROM product_likes
WHERE product_id = #{product_id} AND
customer_id = #{customer_id}
</delete>
<!-- 고객 당 상품 좋아요 개수 확인 -->
<select id="checkLikeProductByCustomer" resultType="int">
SELECT COUNT(*)
FROM
product_likes
WHERE
product_id = #{product_id} AND
customer_id = #{customer_id}
</select>
<!-- 상품 당 좋아요 개수 -->
<select id="countLikeProductId" resultType="int">
SELECT COUNT(*)
FROM product_likes
WHERE product_id = #{product_id}
</select>
ProductSqlMapper
// 고객: 상품 좋아요 클릭
public void likeProduct(ProductLikesDto productLikesDto);
// 상품 좋아요 취소
public void unlikeProduct(ProductLikesDto productLikesDto);
// 고객의 상품 하나 좋아요 확인
public int checkLikeProductByCustomer(ProductLikesDto productLikesDto);
// 상품 당 좋아요 개수
public int countLikeProductId(int product_id);
ProductServiceImpl
@Service
public class ProductServiceImpl {
@Autowired
private ProductSqlMapper productSqlMapper;
@Autowired
private SellerSqlMapper sellerSqlMapper;
@Autowired
private ReviewSqlMapper reviewSqlMapper;
// 좋아요 아이콘 클릭
public void toggleLike(ProductLikesDto productLikesDto) {
if(productSqlMapper.checkLikeProductByCustomer(productLikesDto) > 0) {
productSqlMapper.unlikeProduct(productLikesDto); // 좋아요를 클릭한 상태면 취소하기
} else {
productSqlMapper.likeProduct(productLikesDto); // 좋아요를 클릭한 적이 없다면 좋아요 누르기 (색 변경)
}
}
// 고객이 하나의 상품에 대하여 좋아요를 하였는지 체크
public boolean checkLikeProductByCustomer(ProductLikesDto productLikesDto) {
return productSqlMapper.checkLikeProductByCustomer(productLikesDto) > 0;
}
// 상품 당 좋아요 개수
public int getTotalLikeProductId(int product_id) {
return productSqlMapper.countLikeProductId(product_id);
}
RestProductController
@RestController
@RequestMapping("/product/*")
public class RestProductController {
@Autowired
private ProductServiceImpl productService;
// 좋아요 클릭했다 뗐다 하기
@RequestMapping("toggleLike")
public Map<String, Object> toggleLike(HttpSession session, ProductLikesDto params) {
Map<String, Object> map = new HashMap<>();
CustomerDto sessionUser = (CustomerDto) session.getAttribute("sessionUser");
params.setCustomer_id(sessionUser.getId());
productService.toggleLike(params);
map.put("result", "success");
return map;
}
// 고객이 하나의 상품에 대하여 좋아요를 하였는지 체크
@RequestMapping("checkLikeProductByCustomer")
public Map<String, Object> checkLikeProductByCustomer(HttpSession session, ProductLikesDto params) {
Map<String, Object> map = new HashMap<>();
CustomerDto sessionUser = (CustomerDto) session.getAttribute("sessionUser");
if (sessionUser == null) {
map.put("result", "fail");
map.put("reason", "로그인이 되어있지 않습니다.");
return map;
}
params.setCustomer_id(sessionUser.getId());
map.put("result", "success");
map.put("checkLikeProductByCustomer", productService.checkLikeProductByCustomer(params));
return map;
}
// 상품 좋아요 개수 체크
@RequestMapping("getTotalLikeProductId")
public Map<String, Object> getTotalLikeProductId(int product_id) {
Map<String, Object> map = new HashMap<>();
map.put("result", "success");
map.put("count", productService.getTotalLikeProductId(product_id));
return map;
}
}
detail.jsp (좋아요 부분만)
<div class="row mt-2">
<div class="col">
<i id="heartBox" onclick="toggleLike()" class="fs-1 text-danger bi bi-heart"></i>
<span id="totalLikeCount"></span>
<input type="hidden" name="product_id" value="${productDetail.productDto.id}">
<input type="hidden" name="customer_id" value="${sessionUser.id}">
</div>
</div>
detail.js
/**
*
*/
function orderLimit() {
alert("고객 전용 서비스입니다.");
return false;
}
var path = window.location.pathname;
//경로에서 변수 부분 추출
var parts = path.split('/');
var product_id = parts[parts.length - 1];
let sessionId = null;
function getSessionId() {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200){
const response = JSON.parse(xhr.responseText);
if(response.result == "success") {
sessionId = response.id;
console.log('sessionId::', sessionId);
}
}
}
xhr.open("get", "/shop/customer/getCustomerId",false);
xhr.send();
}
function refreshTotalLikeCount() {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200){
const response = JSON.parse(xhr.responseText);
const totalLikeCountBox = document.getElementById("totalLikeCount");
totalLikeCountBox.innerHTML = response.count;
}
}
xhr.open("get", "/shop/product/getTotalLikeProductId?product_id=" + product_id);
xhr.send();
}
function toggleLike() {
if(sessionId == null) {
if(confirm("로그인 후 서비스를 이용하실 수 있습니다.")) {
location.href = "/shop/customer/loginPage";
}
return;
}
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
const response = JSON.parse(xhr.responseText);
refreshTotalLikeCount();
refreshMyHeart();
}
}
xhr.open("get", "/shop/product/toggleLike?product_id=" + product_id);
xhr.send();
}
function refreshMyHeart(){
if(sessionId == null)
return;
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
const response = JSON.parse(xhr.responseText);
// js 렌더링... 작업..
const heartBox = document.getElementById("heartBox");
if(response.checkLikeProductByCustomer){
heartBox.classList.remove("bi-heart");
heartBox.classList.add("bi-heart-fill");
}else{
heartBox.classList.remove("bi-heart-fill");
heartBox.classList.add("bi-heart");
}
}
}
//get
xhr.open("get", "/shop/product/checkLikeProductByCustomer?product_id=" + product_id);
xhr.send();
}
window.addEventListener("DOMContentLoaded", function(){
//사실상 시작 시점...
getSessionId();
refreshTotalLikeCount();
refreshMyHeart();
});
상품 좋아요 클릭 이전
상품 좋아요 클릭 후