본문 바로가기
Projects/NodeBoard

추천하기 기능 구현

by DawIT 2021. 3. 3.
320x100

추천하기 기능을 구현하되, 같은 ip에서는 한 번만 추천할 수 있도록 구현하고 싶었다.

 

추천하기 버튼을 누르는 순간 새로고침하지 않고 해당 내용을 반영해야 하기 때문에 AJAX를 사용하였다.

 

일단 추천한 유저의 IP정보를 가지고 있을 THUMBUPS 테이블을 정의했다.

 

THUMBUPS 테이블 columns

 

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

댓글