[Spring Boot 게시판] 27일차

김정현·2022년 11월 7일
0

SPRINGBOOT게시판

목록 보기
27/36

1. 댓글삭제와 수정버튼 노출

1) 댓글 리스트에 수정/삭제 권한 데이터 업데이트

	public List<Reply> getForPrintReplies(Member actor, String relTypeCode, int relId) {
		List<Reply> replies = replyRepository.getForPrintReplies(relTypeCode, relId);

		for (Reply reply : replies) {
			updateForPrintData(actor, reply);
		}

		return replies;
	}	
  • 게시물의 수정/삭제 권한 데이터를 게시물 객체에 직접 업데이트 했던 것처럼
  • DB로부터 댓글을 List로 가져온 후
  • 댓글에 대한 수정/삭제 권한을 updateForPrintData(actor, reply)를 통해 댓글 객체에 업데이트

2) 댓글에 수정/삭제 권한 업데이트 메소드

	private void updateForPrintData(Member actor, Reply reply) {
		if (actor == null) {
			return;
		}

		ResultData actorCanDeleteRd = actorCanDelete(actor, reply);
		reply.setExtra__actorCanDelete(actorCanDeleteRd.isSuccess());

		ResultData actorCanModifyRd = actorCanModify(actor, reply);
		reply.setExtra__actorCanModify(actorCanModifyRd.isSuccess());
	}
  • 댓글객체에 수정/삭제 권한에대한 데이터를 추가

3) 댓글에 수정/삭제 권한여부 체크

	private ResultData actorCanModify(Member actor, Reply reply) {
		if (reply == null) {
			return ResultData.from("F-1", "댓글이 존재하지 않습니다");
		}

		if (reply.getMemberId() != actor.getId()) {
			return ResultData.from("F-2", "해당 게시물에 대한 권한이 없습니다");
		}

		return ResultData.from("S-1", "수정 가능");
	}

	private ResultData actorCanDelete(Member actor, Reply reply) {
		if (reply == null) {
			return ResultData.from("F-1", "댓글이 존재하지 않습니다");
		}

		if (reply.getMemberId() != actor.getId()) {
			return ResultData.from("F-2", "해당 게시물에 대한 권한이 없습니다");
		}

		return ResultData.from("S-1", "삭제 가능");
	}
  • 매개변수로 받는 actor는 로그인된 멤버이다.
  • 로그인된 멤버아이디와 댓글에 저장되있는 멤버아이디가 같다면 수정/삭제 권한 true

4) 게시물 상세보기 jsp

    <td>
        <c:if test="${reply.extra__actorCanModify }">
            <a class="btn btn-ghost" href="../reply/modify?id=${reply.id }">수정</a>
        </c:if>
        <c:if test="${reply.extra__actorCanDelete }">
            <a class="btn btn-ghost" onclick="if(confirm('삭제 하시겠습니까?') == false) return false;"
               href="../reply/doDelete?id=${reply.id }"
               >삭제</a>
        </c:if>
    </td>
  • 댓글 리스트를 테이블로 보여주고 있어 테이블에 수정/삭제 버튼을 추가
  • 위에 코드에서 로그인된 회원이 해당 댓글에 수정/삭제를 할수있는지 체크 했기때문에
  • 권한여부에따라 수정/삭제버튼 을 노출시킴

2. 댓글 삭제 구현

1) ReplyController

	@RequestMapping("/usr/reply/doDelete")
	@ResponseBody
	public String doDelete(int id, String replaceUri) {

		if (Ut.empty(id)) {
			return rq.jsHistoryBack("id가 없습니다");
		}

		Reply reply = replyService.getForPrintReply(rq.getLoginedMember(), id);

		if (reply == null) {
			return rq.jsHistoryBack(Ut.f("%d번 댓글은 존재하지 않습니다", id));
		}

		if (reply.isExtra__actorCanDelete() == false) {
			return rq.jsHistoryBack("해당 댓글을 삭제할 권한이 없습니다");
		}

		ResultData deleteReplyRd = replyService.deleteReply(id);

		if (Ut.empty(replaceUri)) {
			switch (reply.getRelTypeCode()) {
			case "article":
				replaceUri = Ut.f("../article/detail?id=%d", reply.getRelId());
				break;
			}
		}
		return rq.jsReplace(deleteReplyRd.getMsg(), replaceUri);
	}
  • 삭제버튼 클릭시 위의 메서드가 실행이 되는데
  • replyService.getForPrintReply(rq.getLoginedMember(), id) 메서드로 id에 해당하는 댓글을 가져옴
  • 댓글의 존재여부, 삭제권한 체크하고 조건이 맞지 않을시 뒤로 돌아가기
  • replyService.deleteReply(id) : 실질적으로 댓글을 삭제하는 메서드

2) ReplyRepository

	@Select("""
			<script>
				SELECT R.*,
				M.nickname AS extra__writerName
				FROM reply AS R
				LEFT JOIN `member` AS M
				ON R.memberId = M.id
				WHERE R.id = #{id}
			</script>
			""")
	Reply getForPrintReply(int id);

	@Delete("""
			DELETE FROM reply
			WHERE id = #{id}
			""")
	void deleteReply(int id);
  • 첫번째 쿼리문은 id에 해당하는 댓글을 가져오는 쿼리문
  • 두번째 쿼리문은 id에 해당하는 댓글을 삭제하는 쿼리문

3. 댓글 수정 폼 구현 (중복 발송 x, 빈 내용 발송 x)

1) ReplyController

	@RequestMapping("/usr/reply/modify")
	public String modify(Model model, int id, String replaceUri) {
		if (Ut.empty(id)) {
			return rq.jsHistoryBackOnView("id가 없습니다");
		}
		Reply reply = replyService.getForPrintReply(rq.getLoginedMember(),id);
		
		if (reply == null) {
			return rq.jsHistoryBackOnView(Ut.f("%d번 댓글은 존재하지 않습니다", id));
		}
		
		if (reply.isExtra__actorCanModify() == false) {
			return rq.jsHistoryBack("해당 댓글을 수정할 권한이 없습니다");
		}
		
		String relDataTitle = null;

		switch (reply.getRelTypeCode()) {
		case "article":
			Article article = articleService.getArticle(reply.getRelId());
			relDataTitle = article.getTitle();
			break;
		}
		model.addAttribute("reply", reply);
		model.addAttribute("relDataTitle", relDataTitle);
		
		return "usr/reply/modify";
	}
  • uri로 접근시 댓글의 존재 여부, 권한을 체크

  • 댓글 수정 페이지에 댓글과, 게시물의 제목(relDataTitle)을 넘겨준다. modify.jsp에서 보여주기 위해

  • 이때 댓글의 관련데이터(reply.getRelTypeCode()) 가 article이므로

  • articleService로부터 게시물 데이터를 가져와 게시물의 제목만 model객체에 추가

2) modify.jsp

	<script>
		var ReplyModify__submitDone = false;
		
		function ReplyModify__submitForm(form){
			if(ReplyModify__submitDone){
				alert('이미 처리중 입니다.');
				return;
			}
			form.body.value = form.body.value.trim();
			if(form.body.value.length==0){
				alert('댓글을 작성 해주세요.');
				form.body.focus();
				return;
			}
			ReplyModify__submitDone = true;
			form.submit();		
		}	
	</script>
  • 테이블로 댓글 수정 폼에서 전송시 빈내용, 중복발송 처리를 방지

0개의 댓글