Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#324 Refactor 댓글 entity 수정 및 로직 수정 #353

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,39 @@ public ApiResponse<String> createComment(
return ApiResponse.onSuccess("댓글 생성 완료");
}

@PatchMapping("/{commentId}")
@Operation(summary = "댓글 내용 수정", description = "댓글 수정 API")
public ApiResponse<String> updateComment(
@AuthenticationPrincipal PrincipalDetail principalDetail,
@PathVariable("commentId") Long commentId,
@RequestBody String newContent
) {
commentService.updateComment(principalDetail, commentId, newContent);
return ApiResponse.onSuccess("댓글 수정 완료");
}



// 댓글 삭제 (대댓글 O)
@PatchMapping("/{commentId}")
@Operation(summary = "댓글 소프트 삭제", description = "댓글 id로 대댓글이 있는 댓글에 대해 소프트삭제(isDelete변경)")
@PatchMapping("/{commentId}/soft-delete")
@Operation(summary = "댓글 소프트 삭제", description = "댓글 소프트삭제(isDelete변경)")
public ApiResponse<String> updateCommentStatus(
@AuthenticationPrincipal PrincipalDetail principalDetail,
@PathVariable("commentId") Long commentId) {

commentService.updateCommentStatus(principalDetail, commentId);
commentService.softDeleteComment(principalDetail, commentId);

return ApiResponse.onSuccess("댓글 삭제 완료");
return ApiResponse.onSuccess("댓글 소프트 삭제 완료");
}


// 댓글 삭제 (대댓글 X)
@DeleteMapping("/{commentId}")
@Operation(summary = "댓글 하드 삭제", description = "댓글 id로 하드삭제 - 대댓글이 없는 경우 사용")
public ApiResponse<String> deleteComment(
@Operation(summary = "댓글 하드 삭제", description = "댓글 하드삭제 - 사용 X")
public ApiResponse<String> hardDeleteComment(
@AuthenticationPrincipal PrincipalDetail principalDetail,
@PathVariable("commentId") Long commentId) {

commentService.deleteComment(principalDetail, commentId);
commentService.hardDeleteComment(principalDetail, commentId);

return ApiResponse.onSuccess("댓글 삭제 완료");
return ApiResponse.onSuccess("댓글 하드 삭제 완료");
}


Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orphanRemoval 제거가 필요합니다.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.drinkeg.drinkeg.domain.model.BaseEntity;
import com.drinkeg.drinkeg.domain.member.domain.Member;
import com.drinkeg.drinkeg.domain.party.domain.Party;
import com.drinkeg.drinkeg.domain.recomment.domain.Recomment;
import jakarta.persistence.*;
import lombok.*;

Expand All @@ -20,6 +19,13 @@ public class Comment extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Comment parent;

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> children = new ArrayList<>();

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "party_id")
private Party party;
Expand All @@ -30,8 +36,6 @@ public class Comment extends BaseEntity {

private String content;

@OneToMany(mappedBy = "comment", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Recomment> recomments;

private boolean isDeleted = false;

Expand All @@ -40,25 +44,30 @@ public static Comment create(Member member, Party party, String content) {
.member(member)
.party(party)
.content(content)
.isDeleted(false)
.build();
}

@Builder
public Comment(Party party, Member member, String content, List<Recomment> recomments) {
public Comment(Comment parent, Party party, Member member, String content, boolean isDeleted) {
this.parent = parent;
this.party = party;
this.member = member;
this.content = content;
this.recomments = recomments != null ? recomments : new ArrayList<>();
this.isDeleted = false;
}

public void addRecomment(Recomment recomment) {
this.recomments.add(recomment);
recomment.setParentComment(this); // 자식의 참조도 설정

public void addChild(Comment child) {
this.children.add(child);
child.parent = this;
}

public void softDelete() {
this.isDeleted = true;
}

public void removeRecomment(Recomment recomment) {
this.recomments.remove(recomment);
recomment.setParentComment(null); // 자식의 부모 참조 제거
public void updateContent(String newContent) {
this.content = newContent;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dto 접미사 제거해서 파일 형식 맞춰주는게 좋아보입니다.

Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
public class CommentRequestDTO {
private Long partyId;
private String content;
private Long parentCommentId;


public static Comment toEntity(CommentRequestDTO commentRequest, Party party, Member member) {
return Comment.create(member, party, commentRequest.getContent());
public static Comment toEntity(CommentRequestDTO request, Party party, Member member, Comment parent) {
Comment newComment = Comment.create(member, party, request.getContent());
if (parent != null) {
parent.addChild(newComment);
}
return newComment;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter
Expand All @@ -19,7 +20,7 @@ public class CommentResponseDTO {
private String memberName;
private String content;
private boolean isDeleted;
private List<RecommentResponseDTO> recomments;
private List<CommentResponseDTO> children = new ArrayList<>();
private String timeAgo;
private String createdDate;
//private String url;
Expand All @@ -33,25 +34,21 @@ public CommentResponseDTO(Long id, Long memberId, String memberName, String cont
this.isDeleted = isDeleted;
}

public static CommentResponseDTO fromEntity(Comment comment, String timeAgo, String createdDate, List<RecommentResponseDTO> recommentDTOs) {
public static CommentResponseDTO fromEntity(Comment comment, String timeAgo, String createdDate) {
// isDeleted일시 content로 삭제된 댓글입니다 전달
String finalContent = comment.isDeleted() ? "삭제된 댓글입니다." : comment.getContent();

return CommentResponseDTO.builder()
.id(comment.getId())
.memberId(comment.getMember().getId())
.memberName(comment.getMember().getUsername())
.content(comment.getContent())
.memberId(comment.getMember() != null ? comment.getMember().getId() : null)
.memberName(comment.getMember() != null ? comment.getMember().getUsername() : null)
.content(finalContent)
.isDeleted(comment.isDeleted())
.timeAgo(timeAgo)
.createdDate(createdDate)
.recomments(recommentDTOs)
.children(new ArrayList<>())
.build();
}

public static Comment setDeleted(Comment comment) {
comment = Comment.builder()
.party(comment.getParty())
.member(comment.getMember())
.content("삭제된 댓글입니다.")
.build();
return comment;
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.drinkeg.drinkeg.domain.comment.repository;

import com.drinkeg.drinkeg.domain.comment.domain.Comment;
import com.drinkeg.drinkeg.domain.comment.domain.QComment;
import com.drinkeg.drinkeg.domain.recomment.domain.QRecomment;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand All @@ -19,36 +17,40 @@ public class CommentRepositoryImpl implements CommentRepositoryCustom {
@Override
public long countCommentsAndRecommentsByPartyId(Long partyId) {
QComment comment = QComment.comment;
QRecomment recomment = QRecomment.recomment;

// 댓글 수 카운트 (삭제되지 않은 댓글만)
Long commentCount = queryFactory.select(comment.count())
Long count = queryFactory
.select(comment.count())
.from(comment)
.where(comment.party.id.eq(partyId)
.and(comment.isDeleted.isFalse()))
.fetchOne();

// 대댓글 수 카운트 (부모 댓글의 삭제 여부와 관계없이 모든 대댓글)
Long recommentCount = queryFactory.select(recomment.count())
.from(recomment)
.where(recomment.comment.party.id.eq(partyId))
.where(
comment.party.id.eq(partyId),
comment.isDeleted.isFalse()
)
.fetchOne();

// null 방지
commentCount = commentCount != null ? commentCount : 0L;
recommentCount = recommentCount != null ? recommentCount : 0L;

return commentCount + recommentCount;
return count != null ? count : 0L;
}


// @Override
// public List<Comment> findCommentsWithRecomments(Long partyId) {
// QComment comment = QComment.comment;
// QRecomment recomment = QRecomment.recomment;
//
// return queryFactory.selectFrom(comment)
// .leftJoin(recomment).on(comment.id.eq(recomment.comment.id))
// .fetchJoin()
// .distinct()
// .fetch();
// }
@Override
public List<Comment> findCommentsWithRecomments(Long partyId) {
QComment comment = QComment.comment;
QRecomment recomment = QRecomment.recomment;

return queryFactory.selectFrom(comment)
.leftJoin(recomment).on(comment.id.eq(recomment.comment.id))
.fetchJoin()
return queryFactory
.selectFrom(comment)
.leftJoin(comment.children, comment).fetchJoin()
.leftJoin(comment.member).fetchJoin()
.where(
comment.party.id.eq(partyId),
comment.parent.isNull() // 루트댓글ㄹ
)
.distinct()
.fetch();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ public interface CommentService {

Comment findByIdOrThrow(Long commentId);

List<CommentResponseDTO> getCommentsByPartyId(Long partyId);

long countCommentsAndRecommentsByPartyId(Long partyId);

void createComment(PrincipalDetail principalDetail, CommentRequestDTO commentRequest);

List<CommentResponseDTO> getCommentsByPartyId(Long partyId);
void updateComment(PrincipalDetail principalDetail, Long commentId, String newContent);

void deleteComment(PrincipalDetail principalDetail, Long commentId);
void softDeleteComment(PrincipalDetail principalDetail, Long commentId);

void updateCommentStatus(PrincipalDetail principalDetail, Long commentId);
void hardDeleteComment(PrincipalDetail principalDetail, Long commentId);

String calculateTimeAgo(LocalDateTime createdAt);

Expand Down
Loading