프로젝트

Node.js - 게시판 ( 게시물 및 댓글 작성 / 삭제 )

GoF9490 2022. 9. 7. 00:42

 

// 게시물 view 페이지

app.get('/view', (req, res, next)=>{
	// url쿼리의 id값을 이용해 db에서 데이터 조회
    db.query('SELECT title, content, writer, deleted FROM board WHERE id=?',
    [req.query.id], (err, results)=>{
        if (err) return next(err);
        if (results[0].deleted === 1) return res.redirect('/');

		// url쿼리값을 이용해 해당 글에 작성된 댓글 데이터 조회
        db.query(`SELECT id, writer, content, deleted FROM comment WHERE board_id=? ORDER BY id DESC LIMIT 30`,
        [req.query.id], (err2, results2)=>{
            if (err2) return next(err2);

			// html 템플릿에 보낼 댓글 내용 제작
            let comment = '<ul class="comment_box">';
            for (var i=0; i<results2.length; i++){
                comment += `
                <li class="comment_view">
                    <div class="comment_balance">${(results2[i].deleted == 0) ? results2[i].writer : ''}</div>
                    <p class="comment_content">${(results2[i].deleted == 0) ? results2[i].content : '삭제된 댓글입니다.'}</p>
                    ${((results2[i].deleted != 0)) ? '' : 
                        `<a href="/comment_delete?id=${results2[i].id}&writer=${results2[i].writer}&board_id=${req.query.id}" class="comment_balance">글삭제</a>`}
                </li>
                `;
            }
            comment += '</ul>';

            return res.send(template.view(template.check_login(req.user), req.query.id, results[0], comment));
        });
    });
    return;
});

 

url쿼리문으로 해당 글의 view페이지로 진입이 가능하다.

글수정 및 글삭제 기능은 이전 작성글에서 확인 가능하며, 해당 페이지에서 hidden값으로 되어있는 닉네임을 전송, 접속해있는 유저와 닉네임이 일치할 경우만 글수정, 글삭제 기능이 동작한다.(기본적으로 닉네임은 unique값이라 db상 중복이 생길수가 없다.)

 

작성하면서 생각난건데, 당장의 기능은 없지만 닉네임 변경 기능이 생긴다면 문제가 생길것같은 인증방식이다. writer값을 유저 닉네임이 아니라 유저 id값을 저장해놓고, 유저 닉네임은 join 으로 불러오던가 해서 쓰는게 맞는것같다.

 

// 댓글 작성 / 삭제

app.post('/comment_process', (req, res, next)=>{
    if (req.user.nickname !== req.body.nickname) return res.redirect('/');

    db.query(`INSERT INTO comment (board_id, writer, content, day) 
    VALUES (?, ?, ?, NOW())`, 
    [req.body.board_id, req.body.nickname, req.body.comment], 
    (err, results)=>{
        if (err) return next(err);
        return res.redirect(`/view?id=${req.body.board_id}`);
    });

    return;
});

app.get('/comment_delete', (req, res, next)=>{
    if (!req.user) return res.redirect(`/view?id=${req.query.board_id}`);
    if (req.user.nickname !== req.query.writer) return res.redirect(`/view?id=${req.query.board_id}`);

    db.query(`UPDATE comment SET deleted=1 WHERE id=?`, [req.query.id], (err, results)=>{
        if (err) return next(err);
        return res.redirect(`/view?id=${req.query.board_id}`);
    });
    return;
});

로그인을 했을시, html템플릿 단에서 본문과 댓글 사이에 댓글작성창이 따로 추가된다.

 

댓글은 최대 30개까지만 노출되며, 최신순으로 노출된다. 댓글도 메인페이지처럼 페이지번호를 줄까 생각했는데, 그러려면 당장 UI부터 건들여야 될것같아서 관뒀다.

 

기본적으로 메인페이지 만들때의 기능을 그대로 쓰는 방식이라 하면서 흥미가 떨어지던 파트. UI도 조잡하고, 댓글수정 버튼같은것도 넣으려다가 너무 좁아지는것같아서 뺏다. 어짜피 기능도 글쓰던 방식이랑 똑같은 기능 쓸것같고.

 

 그나마 기능에 조금 다른 느낌을 주기위해, 삭제된 댓글은 조회에서 빠지지 않고 '삭제된 댓글입니다'  라는 내용으로 노출된다.

 

// 끝으로 사족

더보기

 원래는 일요일까지 끝마치고 이번주부터 spring 강의를 들으려 했는데, 중간중간마다 보완점이 보여서 좀 더 길어졌다. 어떻게보면 html 및 css 같은 프론트 업무를 화요일에 끝마쳤고, 백엔드 업무는 수요일부터 시작했으니 백엔드만 보면 정확히 1주일 걸렸다고 할 수 있겠다.

 

 댓글 기능은 만들면서도 참 고민이 많았다. 크기가 좁아서 버튼 두개만 넣어도 외관이 망가지고, textarea 쓰려하니 또 외관이 망가진다. 처음부터 html템플릿과 css만들때 설계가 좀 잘못되서 기능이 제한적으로 되지 않았나 싶다. 리팩토링은 추후에 할 의향이 있지만, 댓글기능 개선은 html 템플릿부터 해서 건드려야 할것이 많아서 차라리 spring으로 재도전 할듯. 아마 수정을 하더라도 spring을 배운 후 나아아아중에.

 

 프로젝트를 진행하면서 다른 포털사이트나 커뮤니티의 페이지를 검사하면서 몇몇개는 응용해서 적용했고, 대부분은 배워야 할 것으로 남겨뒀다. 그래도 배워야 할 키워드를 몇개 건진것같아서 의미있는 프로젝트였지 싶다.