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}')"> 더 알아보기 </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가 바뀌면 화면이 새로고침 되면서 변경된 내용이 적용되게 하였다.
'SPRING > SPRING 프로젝트' 카테고리의 다른 글
SPRING 프로젝트 - 펀딩 사이트(7) : 페이지네이션 없이 무한스크롤 구현 (0) | 2022.09.08 |
---|---|
SPRING 프로젝트 - 펀딩 사이트 (6) : 회원가입 (0) | 2022.09.06 |
SPRING 프로젝트 - 펀딩 사이트 (4) : xml 조건 정렬과 Grid (0) | 2022.09.02 |
SPRING 프로젝트 - 펀딩 사이트 (3) : 로그인 화면 구현 (0) | 2022.08.29 |
SPRING 프로젝트 - 펀딩 사이트 (2) : DB (0) | 2022.08.24 |
댓글