SpringBoot 프로젝트

Spring Boot - 댓글 CRUD기능 구현하기 (3)

orin602 2024. 11. 22. 16:21

이번 글에서는 댓글 삭제 및 댓글 좋아요 기능에 대해 써보려고 합니다..

저번 글에서 하려고 했느데 오류가 많아서 수정하다보니 깜빡했어요;;  부족하지만 좋게 봐주세요 :)

1. 삭제 버튼 Html

<button type="button" th:data-reply-seq="${reply.replySeq}" th:data-reply-member-id="${reply.member.id}" 
    th:data-login-user-id="${loginUser.id}" class="detail-replydelete-btn"
    onclick="replyDelete(this)">댓글삭제</button>
  • data-* 속성은 HTML5에서 표준화된 커스텀 데이터 속성으로, 자바스크립트에서 데이터를 전송하거나 스타일링을 위해 데이터를 HTML 요소에 저장할 때 유용하게 사용됩니다.
  • th:data-reply-seq속성에 reply.replySeq 값이, th:data-reply-member-id 속성에 댓글 작성자 ID인 reply.member.id 값이, th:data-login-user-id속성에 로그인한 사용자 ID인 loginUser.id 값
  • JavaScript에서 버튼을 클릭할 때 이러한 data-* 속성에 저장된 값을 쉽게 추출하여 사용할 수 있습니다.

 

 

2. 버튼 클릭 시 호출 함수 JavaScript

// 댓글 삭제
function replyDelete(buttonElement) {
	// 버튼에서 댓글 정보와 사용자 ID 가져오기
	var replySeq = $(buttonElement).data('reply-seq'); // 댓글 시퀀스
	var replyMemberId = $(buttonElement).data('reply-member-id'); // 댓글 작성자 ID
	var loginUserId = $(buttonElement).data('login-user-id'); // 현재 로그인한 사용자 ID
	
	if(replyMemberId === loginUserId) { // 작성자와 로그인한 사용자가 일치할 경우
		swal.fire({
			title: '댓글 삭제 확인',
			text: '정말로 이 댓글을 삭제하시겠습니까?',
			icon: 'warning',
			showCancelButton: true,
			confirmButtonText: '삭제',
			cancelButtonText: '취소',
			reverseButtons: true
		}).then((result) => {
			if(result.isConfirmed) {
				$.ajax({
					url: `/replies/{replySeq}/delete`,
					method: 'POST',
					success: function(response) {
						swal.fire({
							title: '삭제 성공',
							text: '댓글을 성공적으로 삭제하였습니다.',
							icon: 'success',
							confirmButtonText: '확인'
						}).then(() => {
							location.reload();
						});
					},
					error: function(xhr, status, error) {
						let errorMessage = '댓글 삭제에 실패했습니다.';
						
						// 서버에서 반환한 에러 메시지 처리
						if (xhr.responseJSON && xhr.responseJSON.message) {
						    errorMessage = xhr.responseJSON.message;
						}
						
						swal.fire({
						    title: '삭제 실패',
						    text: errorMessage,
						    icon: 'error',
						    confirmButtonText: '확인'
						});
					}
				});
			}
		});
	} else {
		swal.fire({
		    title: '삭제 불가',
		    text: '댓글 작성자만 삭제할 수 있습니다.',
		    icon: 'warning',
		    confirmButtonText: '확인'
		});
	}
}

+++ JavaScript 수정 : url: `/replies/{replySeq}/delete`,에서 url: `/replies/${replySeq}/delete` 로 $ 추가 +++

 

3. Controller 구현 및 Service

@PostMapping("/replies/{replySeq}/delete")
public ResponseEntity<Map<String, String>> deleteReply(@PathVariable int replySeq, HttpSession session) {
    // 로그인한 사용자 확인
    Member loginUser = (Member) session.getAttribute("loginUser");

    if (loginUser == null) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Collections.singletonMap("message", "로그인 후 이용할 수 있습니다."));
    }

    // 댓글 정보 가져오기
    Reply replyUser = replyService.getReplyBySeq(replySeq);
    if (replyUser == null) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Collections.singletonMap("message", "해당 댓글을 찾을 수 없습니다."));
    }

    // 댓글 작성자와 로그인한 사용자 확인
    if (!replyUser.getMember().getId().equals(loginUser.getId())) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(Collections.singletonMap("message", "작성자만 댓글을 삭제할 수 있습니다."));
    }

    // 댓글 삭제 처리
    try {
        replyService.deleteReply(replySeq);
        return ResponseEntity.ok(Collections.singletonMap("message", "댓글이 성공적으로 삭제되었습니다."));
    } catch (Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Collections.singletonMap("message", "댓글 삭제 중 오류가 발생했습니다."));
    }
}
// 댓글 삭제
@Override
public void deleteReply(int replySeq) {
    replyRepo.deleteById(replySeq);
}

 

테스트

작성자와 로그인한 사용자가 다를 때
id가 일치하고, 삭제 성공 alert2창
삭제 반영

 

다음 포스팅에서는 댓글 좋아요 기능에 대해 설명할 예정입니다. 이를 통해 사용자가 댓글에 좋아요를 추가하거나 취소하는 기능을 구현하고, 댓글에 대한 상호작용을 더욱 풍부하게 만들 수 있습니다. 댓글 좋아요 기능 구현에 대해 자세히 다루는 글을 기대해 주세요!