추천하기 기능을 구현하되, 같은 ip에서는 한 번만 추천할 수 있도록 구현하고 싶었다.
추천하기 버튼을 누르는 순간 새로고침하지 않고 해당 내용을 반영해야 하기 때문에 AJAX를 사용하였다.
일단 추천한 유저의 IP정보를 가지고 있을 THUMBUPS 테이블을 정의했다.
POST_ID에는 해당 글의 ID가 들어가고, USER_IP테이블에는 추천한 유저의 IP가 담긴다.
var thumbup = function(id,ip,callback){
// 추천수 카운트 변수
var count;
// 해당 글의 추천 수를 새로운 DB에서 카운트 해서 가져오기
db.query('SELECT COUNT(*) AS COUNT FROM THUMBUPS WHERE POST_ID=?',[id],(err,result)=>{
if (err){
errcode = 1
callback(false,errcode);
console.log(err);
return;
}
count = result[0].COUNT;
});
// 해당 글을 추천한 ip리스트 가져오기
db.query('SELECT USER_IP FROM THUMBUPS WHERE POST_ID=?',[id],(err,result)=>{
if (err){
errcode = 2
callback(false,errcode);
console.log(err);
return;
}
// 해당 ip가 이미 추천한 ip인지 확인
for (let savedIp of result)
if (savedIp.USER_IP == ip)
var forDelete = true;
if (forDelete){
// 추천 취소
db.query('DELETE FROM THUMBUPS WHERE POST_ID=? AND USER_IP=?',[id,ip],(err,hi)=>{
if (err){
errcode = 3
console.log(err);
callback(false,errcode);
return;
}
count--;
// 해당 글의 추천수 조정
db.query('UPDATE POST SET THUMBUP=? WHERE ID=?',[count,id],()=>{});
callback('deleted',count);
});
} else{
// 추천 진행
db.query('INSERT INTO THUMBUPS (`POST_ID`, `USER_IP`) VALUES (?,?)',[id,ip],(err)=>{
if (err){
errcode = 4
callback(false,errcode);
console.log(err);
return;
}
count++;
// 해당 글의 추천수 조정
db.query('UPDATE POST SET THUMBUP=? WHERE ID=?',[count,id],()=>{});
callback('success',count);
});
}
});
}
먼저 db-query.js의 thumbup 함수이다. 추천 수를 해당 글의 THUMBUP에서 가져오지 않고 THUMBUPS 테이블에서 직접 카운트하여 가져온 것은 추천 과정 중 혹시 오류가 발생하여 THUMBUPS테이블에는 변화가 생겼지만 POST테이블에는 적용되지 않는 경우도 있을 것 같아서 일부러 이렇게 작성했다.
만약 실행 도중 오류가 발생한다면 콜백함수에 false와 오류 코드를 전송하고, 성공했다면 true와 추천수를 반환한다.
router.post('/thumbup',function(req,res,next){
db.thumbup(req.body.id,req.ip,(response,count)=>{
res.send({result: response, count: count})
});
});
view.js에서는 단순히 AJAX에서 요청을 받은 뒤 db의 thumbup함수를 호출하고 결괏값을 넘겨주면 된다. 이때 요청으로부터 ip를 얻어서 함께 함수로 넘긴다.
<div id="post-thumbuparea">
<span id="thumbup-count"><%=thumbup%></span><br>
<a onclick="thumbup(<%=id%>)" onmouseover="this.style.cursor='pointer'"><img src="/images/thumbup.svg" alt="추천하기"></a>
</div>
view.ejs의 변화한 점은 thumbuparea에서 추천하기 버튼에 사진을 적용하고 functions.js의 thumbup함수와 연결해 준 것이다.
function thumbup(id){
$.ajax({
url: '/view/thumbup',
datatype: 'json',
type: 'POST',
data: {id:id},
success: function(result){
if (result.result)
$('#thumbup-count').text(result.count);
else
alert('에러가 발생했습니다. ERRORCODE : '+result.count);
}
})
};
functions.js의 thumbup함수이다. 해당 글의 id를 인자로 받아서, /view/thumbup으로 POST요청을 보낸다. 그리고 결과를 받아서 새로고침 없이 추천수를 반영한다. 오류가 발생했다면 경고창과 오류번호를 띄운다.
현재 조회 부분은 이렇다. 여기서 따봉 이미지를 클릭하면
바로 추천수가 반영되어 갱신되고 DB에도 잘 들어간다. 지금은 localhost상황이라 제대로 ip가 나오진 않지만(같은 망의 다른 PC로 해도 내부 ip가 저장된다) 후에 배포하고 다시 테스트해야할 기능이다.
'Projects > NodeBoard' 카테고리의 다른 글
댓글 답글 기능 구현 (0) | 2021.03.09 |
---|---|
AJAX로 댓글달기 기능 구현 (5) | 2021.03.06 |
글 검색 기능과 페이징 개선 (1) | 2021.03.02 |
글 수정 기능과 글 리스트 페이징 (0) | 2021.02.27 |
글 삭제 기능 제작 (0) | 2021.02.26 |
댓글