본문 바로가기
SPRING/SPRING 프로젝트

SPRING 프로젝트 - 펀딩 사이트 (5) : 찜하기와 공유하기

by 스노위13 2022. 9. 6.

1. 내용 :  펀딩 리스트에서 사진이나 제목을 클릭하면 그 펀딩의 내용에 대해서 간단하게 알려주는 페이지이다. 찜과 공유하기, 더 알아보기를 할 수 있다.

2. 과정 중 특이점 : 수업시간에는 찜하기를 배우지 않았기 때문에 스스로 어떤 식으로 짜야할지 하나씩 생각하면서 만드는게 어렵지만 재미있었다. 찜을 하는 순간 하트 색깔과 찜한 갯수가 바뀔 때 새로고침하게 만들었는데 그냥 요소가 바뀌게 했어도 좋았을 것 같다. 

3. 화면 및 코드 

1) 펀딩 세부 화면

펀딩 세부 화면에서는 펀딩의 카테고리, 제목, 사진, 달성현황과 퍼센트, 남은 시간, 창작자, 키워드를 정보로 보여준다. 더 알아보기를 클릭하면 크롤링해온 기존 펀딩 사이트가 새 탭으로 뜬다. (키워드는 이후에 진행된 파이썬 프로젝트의 결과물이라 현재 코드에는 없음. )

하트를 누르면 찜하기가 되어서 DB에 저장되며 '나의 펀딩'에서 확인할 수 있다. 이미 찜한 펀딩이라면 취소하기가 된다. 찜하기는 로그인 했을 때만 가능하다. 공유하기를 클릭하면 현재 페이지가 복사된다. 

2) JSP (전체 코드는 아래에서 더보기를 찾아 눌러주세요)

<!-- 찜하기 부분 -->
<c:if test="${USER_INFO eq null }">
<button type="button" class="btn btn-secondary disabled">
<ion-icon name="heart-outline" size="large"></ion-icon> ${funding.fuLike }</button> 
</c:if>
<c:if test="${USER_INFO ne null }">
    <form id="addLike" name="addLike" >					
        <input type="hidden" id="fuNo" name="fuNo" value="${funding.fuNo }">
        <input type="hidden" id="memId" name="memId" value="${USER_INFO.userId }">
        <!-- 사용자가 '좋아요' 안 한 글일 때 -->
        <c:if test="${checklike eq 0 }">
        <div id="emptyheart">
            <button type="button" class="btn" id="heartClick">
            <ion-icon name="heart-outline"size="large">	</ion-icon> 
            ${funding.fuLike }</button>
        </div>	
        </c:if>
        <!-- 사용자가 '좋아요'한 글일 때 -->
        <c:if test="${checklike eq 1 }">
        <div id="fillheart">
            <button type="button" class="btn" id="heartClick">
            <ion-icon name="heart"  size="large"></ion-icon> 
            ${funding.fuLike }</button>
        </div>	
        </c:if>
    </form>					
</c:if>
<!-- 찜하기 부분 끝 -->

찜하기 부분에서는 USER_INFO가 없으면 아예 클릭하지 못하게 만들었다. 그리고 checklike를 통해 사용자가 좋아요 한 글인지 좋아요 하지 않은 글인지를 판단하여 하트 모양을 바꾸었다. 

$(function(){
	$("#heartClick").click(function(){
		let fuNo = $("form[name='addLike']").find('#fuNo').val();
		let memId = $("form[name='addLike']").find('#memId').val();
		$.ajax({
			url: "saveLike.wow"
			,type : 'POST'
			,data : {memId : memId, fuNo : fuNo}
			,success : function(data){
				alert(data);
				if(data == 0){						
					alert("찜하였습니다");					
					document.location.href = document.location.href;
				}else if(data == 1){
					alert("찜을 취소하였습니다");					
					document.location.href = document.location.href;
				}				
			},
			error : function() {
                alert('error');
            }
		}); 				
	});
});

찜하기 버튼을 클릭했을 때의 Javascript 부분!  펀딩번호와 아이디 값을 받아서 ajax를 이용하여 컨트롤러에 보낸다. 컨트롤러에서는 이를 받아서 특정 동작을 수행 후 숫자를 보내는데 이 숫자에 따라 alert창의 내용이 다르다. 

전체 코드가 궁금하시면 아래 더보기를 눌러 주세요.

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<%@include file="/WEB-INF/inc/header.jsp" %>

<meta charset="UTF-8">
<title>펀딩 상세보기</title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/resources/css/funding/fundingView.css" />
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
</head>
<body>
<%@include file="/WEB-INF/inc/top.jsp" %>
<div class="row mt-5">
</div>
<div class = "container">
	<div class="fu_header">	
		<h5>${funding.fuCate }</h5>
		<h2>${funding.fuTitle }</h2> 
	</div>
	<div class="row" id="fu_item">
		<div class="col-6" id="fu_img">
			<img class="align-items-center" alt="" src="${funding.fuImg }">
		</div>
		<div class="col-6" id="fu_introduction">
			<div class="introduction">달성 현황</div>
			<div class="fu_detail">
				<h3>${funding.fuAmount }</h3><div class="fuPercent">${funding.fuPercent }</div>
			</div>
			<div class="fu_title">남은 시간</div>
			<div class="fu_detail"><h3>${funding.fuDday } ${funding.fuDday eq "오늘마감" ? "" : "남음"}</h3></div>
			<div class="fu_title">크라우드 펀딩 사이트</div>
			<div class="fu_detail"><h4>${funding.fuSite }</h4></div>
			<div class="fu_title">창작자</div>
			<div class="fu_detail"><h4>${funding.fuEnter }</h4></div>
			
			<div class="option">
				<!-- 찜하기 부분 -->
				<c:if test="${USER_INFO eq null }">
				<button type="button" class="btn btn-secondary disabled">
				<ion-icon name="heart-outline" size="large"></ion-icon> ${funding.fuLike }</button> 
				</c:if>
				<c:if test="${USER_INFO ne null }">
					<form id="addLike" name="addLike" >					
						<input type="hidden" id="fuNo" name="fuNo" value="${funding.fuNo }">
						<input type="hidden" id="memId" name="memId" value="${USER_INFO.userId }">
						<!-- 사용자가 좋아요 안 한 글일 때 -->
						<c:if test="${checklike eq 0 }">
						<div id="emptyheart">
							<button type="button" class="btn" id="heartClick">
							<ion-icon name="heart-outline"size="large">	</ion-icon> 
							${funding.fuLike }</button>
						</div>	
						</c:if>
						<!-- 사용자가 좋아요 한 글일 때 -->
						<c:if test="${checklike eq 1 }">
						<div id="fillheart">
							<button type="button" class="btn" id="heartClick">
							<ion-icon name="heart"  size="large"></ion-icon> 
							${funding.fuLike }</button>
						</div>	
						</c:if>
					</form>					
				</c:if>
				<!-- 찜하기 부분 끝 -->
				<button type="button" class="btn" onclick="clip(); return false;">
				<ion-icon name="share-social-outline"  size="large"></ion-icon></button>
			</div>			
				<button type="button" class="btn btn-primary btn-lg" onclick="window.open('${funding.fuUrl}')">&nbsp;&nbsp;더 알아보기&nbsp;&nbsp;</button>		
		</div>
	</div>
</div>

<script type="text/javascript">

$(function(){
	$("#heartClick").click(function(){
		let fuNo = $("form[name='addLike']").find('#fuNo').val();
		let memId = $("form[name='addLike']").find('#memId').val();
		$.ajax({
			url: "saveLike.wow"
			,type : 'POST'
			,data : {memId : memId, fuNo : fuNo}
			,success : function(data){
				alert(data);
				if(data == 0){						
					alert("찜하였습니다");					
					document.location.href = document.location.href;
				}else if(data == 1){
					alert("찜을 취소하였습니다");					
					document.location.href = document.location.href;
				}				
			},
			error : function() {
                alert('error');
            }
		}); 				
	});
});
</script>

</body>
</html>

3) Controller + XML

@RequestMapping(value = "fundingView.wow")
public String fundingdView(Model model, LikeVO like) {
    FundingVO funding = fuService.getfunding(like.getFuNo());
    int checklike = likeService.checkLike(like);

    model.addAttribute("funding", funding);
    model.addAttribute("checklike", checklike);
    return "funding/fundingView";
}

펀딩 세부 화면을 가지고 오기 위해서는 funding 테이블에 있는 정보와 like 테이블에 있는 정보를 가져와 View에 보내주었다. checklike를 이용하여 하트 아이콘의 모양을 결정한다. 

<select id="getfunding" resultType="com.study.funding.vo.FundingVO" parameterType="int">
SELECT
    fu_no	   			 , fu_site	    , fu_title
    , fu_cate       , fu_enter	    , fu_img
    , fu_percent	 , fu_amount	    , fu_dday
    , fu_url  	    , fu_like
FROM    funding
WHERE fu_no =#{fuNo}
</select>

<select id="checkLike" resultType="int">
	SELECT count(*)
	FROM    mem_like
	where fu_no = #{fuNo}
	and mem_id = #{memId}
</select>

위의 컨트롤러와 연결된 XML은 다음과 같다. checklike에서는 count(*)을 사용해서 1인지 0인지에 따라 사용자가 찜을 했는지 하지 않았는지를 구분할 수 있다.

@RequestMapping(value = "saveLike.wow")
@ResponseBody
public int saveLike(Model model, LikeVO like) {
    int likeyn = likeservice.checkLike(like);
    if(likeyn == 0) {
        likeservice.insertLike(like);
        fundingService.addLike(like.getFuNo());
        return 0;		
    }else if(likeyn == 1) {
        likeservice.deleteLike(like);
        fundingService.subLike(like.getFuNo());
        return 1;
    }else {
        return 2;
    }
}

실질적으로 찜하기를 하는 컨트롤러는 위와 같다. view에서 ajax로 saveLike를 요청하면 위의 내용이 실행되는데 여기서도 checklike를 활용한다. 사용자가 찜한 펀딩이 아니라면 xml에서 insertLike와 addLike를 하고 사용자가 찜한 펀딩이라면 deleteLike와 subLike를 한다.

<update id="insertLike" parameterType="com.study.like.vo.LikeVO">
	INSERT INTO mem_like (
	    like_no,	    mem_id,	    fu_no
	) VALUES (
	    like_seq.nextval,
	    #{memId},
	    #{fuNo}
	)
</update>

<update id="deleteLike" parameterType="com.study.like.vo.LikeVO">
	DELETE FROM mem_like
	WHERE mem_id = #{memId}
	AND fu_no = #{fuNo}
</update>

<update id="addLike" parameterType="int">
    UPDATE funding SET
    FU_LIKE = FU_LIKE + 1
    WHERE fu_no=#{fuNo}	
</update>

<update id="subLike" parameterType="int">
    UPDATE funding SET
    FU_LIKE = FU_LIKE - 1
    WHERE fu_no=#{fuNo}	
</update>

 insertLike, addLike, deleteLike, subLike는 위와 같다. 컨트롤러와 xml로 DB가 바뀌면 화면이 새로고침 되면서 변경된 내용이 적용되게 하였다. 

댓글