Showing
3 changed files
with
121 additions
and
3 deletions
... | @@ -46,6 +46,15 @@ create table board( | ... | @@ -46,6 +46,15 @@ create table board( |
46 | hit int not null, | 46 | hit int not null, |
47 | ID varchar(20) not null | 47 | ID varchar(20) not null |
48 | )engine=innodb; | 48 | )engine=innodb; |
49 | + | ||
50 | +create table comment( | ||
51 | + idx int auto_increment primary key, | ||
52 | + ID varchar(20) not null, | ||
53 | + nickname varchar(50) not null, | ||
54 | + comment mediumtext not null, | ||
55 | + bulletin_id int not null, | ||
56 | + foreign key (bulletin_id) references board(idx) on delete cascade | ||
57 | + )engine=innodb; | ||
49 | ``` | 58 | ``` |
50 | 59 | ||
51 | --- | 60 | --- |
... | @@ -61,7 +70,7 @@ create table board( | ... | @@ -61,7 +70,7 @@ create table board( |
61 | >UPDATE board SET idx = @COUNT:=@COUNT+1; | 70 | >UPDATE board SET idx = @COUNT:=@COUNT+1; |
62 | 71 | ||
63 | --- | 72 | --- |
64 | -### 최종 수정: 2021-11-25 18:48<br> | 73 | +### 최종 수정: 2021-11-26 04:42<br> |
65 | ### 수정 내용: | 74 | ### 수정 내용: |
66 | 0. 사용자-서버 채팅간 여백 | 75 | 0. 사용자-서버 채팅간 여백 |
67 | 0. 채팅 엔터키 | 76 | 0. 채팅 엔터키 |
... | @@ -73,3 +82,4 @@ create table board( | ... | @@ -73,3 +82,4 @@ create table board( |
73 | 6. 채팅(socket) 사용 중 서버 재시작 시 서버 오류 해결 | 82 | 6. 채팅(socket) 사용 중 서버 재시작 시 서버 오류 해결 |
74 | 7. 코드 다듬음 | 83 | 7. 코드 다듬음 |
75 | 8. 버그 수정 | 84 | 8. 버그 수정 |
85 | +9. 댓글 등록, 열람 기능 구현. 삭제 기능 불완전함(달린 댓글이 1개일 때만 삭제기능 동작) | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -124,12 +124,76 @@ router.get('/read/:idx', function(req,res,next){ | ... | @@ -124,12 +124,76 @@ router.get('/read/:idx', function(req,res,next){ |
124 | if(err) console.error(err) | 124 | if(err) console.error(err) |
125 | }) | 125 | }) |
126 | 126 | ||
127 | + var sql_comment = "select idx, nickname, comment from comment where bulletin_id =?" | ||
128 | + board.query(sql_comment, [idx], function(err,comment){ | ||
129 | + if (err) console.error("err : " + err); | ||
130 | + res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0], comment:comment, comment_length : comment.length, usernick:req.user.nickname}) | ||
131 | + }) | ||
127 | console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.('+ip+')') | 132 | console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.('+ip+')') |
128 | - res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0]}) | ||
129 | } | 133 | } |
130 | }) | 134 | }) |
131 | }) | 135 | }) |
132 | 136 | ||
137 | + | ||
138 | +router.post('/read/commentwrite', function(req,res,next){ | ||
139 | + var ip = requestIp.getClientIp(req); | ||
140 | + var idx = req.body.idx; | ||
141 | + var nickname = req.user.nickname // var name = req.body.name | ||
142 | + var comment = req.body.comment | ||
143 | + var ID = req.user.ID | ||
144 | + var datas = [ID, nickname, comment, idx] | ||
145 | + | ||
146 | + var sql = "insert into comment(ID, nickname, comment, bulletin_id) values(?, ?, ?, ?)" | ||
147 | + board.query(sql, datas, function(err,row){ | ||
148 | + if (err) console.error("err : " + err); | ||
149 | + }) | ||
150 | + res.redirect('/board/read/'+idx); | ||
151 | +}) | ||
152 | + | ||
153 | +router.post('/read/commentdelete', function(req,res,next){ | ||
154 | + var ip = requestIp.getClientIp(req); | ||
155 | + var idx = req.body.idxcomment; | ||
156 | + var idxbulletin = req.body.idx; | ||
157 | + var ID = req.user.ID; | ||
158 | + var datas = [ID, idx] | ||
159 | + | ||
160 | + var sql = "delete from comment where ID =? and idx=?" | ||
161 | + board.query(sql,datas,function(err,result){ | ||
162 | + if(err) console.error(err) | ||
163 | + // 삭제를 요청한 사용자가 작성자가 아닌 경우 | ||
164 | + if(result.affectedRows == 0){ | ||
165 | + // 운영자세요? | ||
166 | + var sql_ = 'select type from userdb where ID="'+ID+'"'; | ||
167 | + board.query(sql_, function(err_, result_){ | ||
168 | + if(err_) console.error(err_) | ||
169 | + | ||
170 | + if(result_[0].type == "운영자"){ // 작성자는 아니나 유저 타입이 운영자인 경우 | ||
171 | + var sqlAdmin = 'delete from comment where idx="'+idx+'"'; | ||
172 | + board.query(sqlAdmin, function(err__, result__){ | ||
173 | + if(err__) console.error(err__) | ||
174 | + | ||
175 | + var nickname = req.user.nickname; | ||
176 | + res.send("<script>alert('댓글이 운영자에 의해 삭제되었습니다.');window.location.href='/board/read/"+idxbulletin+"';</script>"); | ||
177 | + console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 댓글을 삭제했습니다.('+ip+')') | ||
178 | + }) | ||
179 | + } | ||
180 | + else{ // 작성자도, 운영자도 아니면 | ||
181 | + var nickname = req.user.nickname; | ||
182 | + console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 댓글 삭제를 거부했습니다.(권한없음 // '+ip+')') | ||
183 | + res.send("<script>alert('댓글 작성자가 아닙니다');history.back();</script>"); | ||
184 | + } | ||
185 | + }) | ||
186 | + } | ||
187 | + else{ // 작성자인 경우 | ||
188 | + var id = req.user.ID; | ||
189 | + var nickname = req.user.nickname; | ||
190 | + res.send("<script>alert('댓글이 삭제되었습니다.');window.location.href='/board/read/"+idxbulletin+"';</script>"); | ||
191 | + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 댓글을 삭제했습니다.('+ip+')') | ||
192 | + } | ||
193 | + }) | ||
194 | + | ||
195 | +}) | ||
196 | + | ||
133 | router.post('/update', function(req,res,next){ | 197 | router.post('/update', function(req,res,next){ |
134 | var ip = requestIp.getClientIp(req); | 198 | var ip = requestIp.getClientIp(req); |
135 | var ID = req.user.ID; | 199 | var ID = req.user.ID; |
... | @@ -163,7 +227,6 @@ router.post('/delete', function(req,res,next){ | ... | @@ -163,7 +227,6 @@ router.post('/delete', function(req,res,next){ |
163 | var sql = "delete from board where idx=? and ID=?" | 227 | var sql = "delete from board where idx=? and ID=?" |
164 | board.query(sql,datas, function(err,result){ | 228 | board.query(sql,datas, function(err,result){ |
165 | if(err) console.error(err) | 229 | if(err) console.error(err) |
166 | - | ||
167 | // 삭제를 요청한 사용자가 작성자가 아닌 경우 | 230 | // 삭제를 요청한 사용자가 작성자가 아닌 경우 |
168 | if(result.affectedRows == 0){ | 231 | if(result.affectedRows == 0){ |
169 | // 운영자세요? | 232 | // 운영자세요? | ... | ... |
... | @@ -77,6 +77,51 @@ | ... | @@ -77,6 +77,51 @@ |
77 | </table> | 77 | </table> |
78 | </form> | 78 | </form> |
79 | </div> | 79 | </div> |
80 | + <div class="container px-5 my-5"> | ||
81 | + <h1>댓글</h1> | ||
82 | + <script> | ||
83 | + function submit3(frm){ | ||
84 | + frm.action="/board/read/commentdelete"; | ||
85 | + frm.submit(); | ||
86 | + return true; | ||
87 | + } | ||
88 | + function deleteit(buttonID){ | ||
89 | + | ||
90 | + } | ||
91 | + </script> | ||
92 | + <form action="/board/read/commentwrite" method="post"> | ||
93 | + <table border="1"> | ||
94 | + <input type="hidden" name="idx" value="<%=row.idx%>"/> | ||
95 | + <tr> | ||
96 | + <td>닉네임</td> | ||
97 | + <td>댓글</td> | ||
98 | + </tr> | ||
99 | + <% | ||
100 | + for(var i=0; i<comment_length; i++){ | ||
101 | + var data = comment[i] | ||
102 | + %> | ||
103 | + | ||
104 | + <tr> | ||
105 | + <td><%=data.nickname%></td> | ||
106 | + <td><%=data.comment%></td> | ||
107 | + <td> | ||
108 | + <input type="hidden" name="idxcomment" value="<%=data.idx%>"/> | ||
109 | + <button type="button" id="<%=data.idx%>" onclick="return submit3(this.form);">댓글 삭제</button> | ||
110 | + </td> | ||
111 | + </tr> | ||
112 | + <% | ||
113 | + } | ||
114 | + %> | ||
115 | + <tr> | ||
116 | + <td><%=usernick%></td> | ||
117 | + <td><textarea name="comment" id="comment" cols="30" rows="2" required></textarea></td> | ||
118 | + <td colspan="2"> | ||
119 | + <button type="submit">댓글 쓰기</button> | ||
120 | + </td> | ||
121 | + </tr> | ||
122 | + </table> | ||
123 | + </form> | ||
124 | + </div> | ||
80 | <!-- Footer--> | 125 | <!-- Footer--> |
81 | <footer class="footer bg-light"> | 126 | <footer class="footer bg-light"> |
82 | <div class="container"> | 127 | <div class="container"> | ... | ... |
-
Please register or login to post a comment