Skip to content
Merged
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 @@ -53,4 +53,8 @@ public boolean hasNickName() {
public void changeNickname(String nickname) {
this.nickname = nickname;
}

public boolean isEqualsId(Long id) {
return this.id.equals(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,11 @@ public boolean isDeleted() {
}

public boolean isDeletedByMember() {
return this.deletedBy != null;
return this.deletedBy != null && this.deletedAnonymousBy == null;
}

public boolean isDeletedByAnonymousMember() {
return this.deletedAnonymousBy != null;
return this.deletedBy == null && this.deletedAnonymousBy != null;
}

public boolean isEqualsId(Long id) {
Expand Down Expand Up @@ -273,4 +273,12 @@ public boolean isCreatedAnonymousMember() {
public boolean isCreatedMember() {
return this.createdBy != null && this.createdAnonymousBy == null;
}

public boolean isDeletedMemberByMySelf() {
return this.createdBy.isEqualsId(this.deletedBy.getId());
}

public boolean isDeletedAnonymousMemberByMySelf() {
return this.createdAnonymousBy.isEqualsId(this.deletedAnonymousBy.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@

import com.dreamypatisiel.devdevdev.domain.entity.embedded.CommentContents;
import com.dreamypatisiel.devdevdev.domain.entity.embedded.Count;
import jakarta.persistence.*;

import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand Down Expand Up @@ -53,23 +64,31 @@ public class TechComment extends BasicTime {
private LocalDateTime contentsLastModifiedAt;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", referencedColumnName = "id")
@JoinColumn(name = "parent_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "fk_tech_comment_01"))
private TechComment parent;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "origin_parent_id", referencedColumnName = "id")
@JoinColumn(name = "origin_parent_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "fk_tech_comment_02"))
private TechComment originParent;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "created_by", nullable = false)
@JoinColumn(name = "created_by", foreignKey = @ForeignKey(name = "fk_tech_comment_03"))
private Member createdBy;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "deleted_by")
@JoinColumn(name = "deleted_by", foreignKey = @ForeignKey(name = "fk_tech_comment_04"))
private Member deletedBy;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tech_article_id", nullable = false)
@JoinColumn(name = "created_anonymous_by", foreignKey = @ForeignKey(name = "fk_tech_comment_05"))
private AnonymousMember createdAnonymousBy;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "deleted_anonymous_by", foreignKey = @ForeignKey(name = "fk_tech_comment_06"))
private AnonymousMember deletedAnonymousBy;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tech_article_id", nullable = false, foreignKey = @ForeignKey(name = "fk_tech_comment_07"))
private TechArticle techArticle;

@OneToMany(mappedBy = "techComment")
Expand All @@ -78,7 +97,8 @@ public class TechComment extends BasicTime {
@Builder
private TechComment(CommentContents contents, Count blameTotalCount, Count recommendTotalCount, Count replyTotalCount,
TechComment parent, TechComment originParent, Member createdBy, Member deletedBy,
TechArticle techArticle, LocalDateTime deletedAt) {
AnonymousMember createdAnonymousBy, AnonymousMember deletedAnonymousBy, TechArticle techArticle,
LocalDateTime deletedAt) {
this.contents = contents;
this.blameTotalCount = blameTotalCount;
this.recommendTotalCount = recommendTotalCount;
Expand All @@ -87,6 +107,8 @@ private TechComment(CommentContents contents, Count blameTotalCount, Count recom
this.originParent = originParent;
this.createdBy = createdBy;
this.deletedBy = deletedBy;
this.createdAnonymousBy = createdAnonymousBy;
this.deletedAnonymousBy = deletedAnonymousBy;
this.techArticle = techArticle;
this.deletedAt = deletedAt;
}
Expand Down Expand Up @@ -159,4 +181,12 @@ public void incrementBlameTotalCount() {
public boolean isEqualsId(Long id) {
return this.id.equals(id);
}

public boolean isCreatedAnonymousMember() {
return this.createdBy == null && this.createdAnonymousBy != null;
}

public boolean isCreatedMember() {
return this.createdBy != null && this.createdAnonymousBy == null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ Optional<TechComment> findByIdAndTechArticleIdAndCreatedByIdAndDeletedAtIsNull(L

Optional<TechComment> findByIdAndTechArticleIdAndDeletedAtIsNull(Long id, Long techArticleId);

@EntityGraph(attributePaths = {"createdBy", "deletedBy", "techArticle"})
List<TechComment> findWithMemberWithTechArticleByOriginParentIdInAndParentIsNotNullAndOriginParentIsNotNull(
Set<Long> originParentIds);
@EntityGraph(attributePaths = {"createdBy", "deletedBy", "createdAnonymousBy", "deletedAnonymousBy", "techArticle"})
List<TechComment> findWithDetailsByOriginParentIdInAndParentIsNotNullAndOriginParentIsNotNull(Set<Long> originParentIds);

Long countByTechArticleIdAndOriginParentIsNullAndParentIsNullAndDeletedAtIsNull(Long techArticleId);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dreamypatisiel.devdevdev.domain.repository.techArticle.custom;

import static com.dreamypatisiel.devdevdev.domain.entity.QAnonymousMember.anonymousMember;
import static com.dreamypatisiel.devdevdev.domain.entity.QMember.member;
import static com.dreamypatisiel.devdevdev.domain.entity.QTechArticle.techArticle;
import static com.dreamypatisiel.devdevdev.domain.entity.QTechComment.techComment;
Expand Down Expand Up @@ -34,7 +35,8 @@ public Slice<TechComment> findOriginParentTechCommentsByCursor(Long techArticleI
TechCommentSort techCommentSort, Pageable pageable) {
List<TechComment> contents = query.selectFrom(techComment)
.innerJoin(techComment.techArticle, techArticle).on(techArticle.id.eq(techArticleId))
.innerJoin(techComment.createdBy, member).fetchJoin()
.leftJoin(techComment.createdBy, member).fetchJoin()
.leftJoin(techComment.createdAnonymousBy, anonymousMember).fetchJoin()
.where(techComment.parent.isNull()
.and(techComment.originParent.isNull())
.and(getCursorCondition(techCommentSort, techCommentId))
Expand All @@ -51,7 +53,8 @@ public List<TechComment> findOriginParentTechBestCommentsByTechArticleIdAndOffse

return query.selectFrom(techComment)
.innerJoin(techComment.techArticle, techArticle).on(techArticle.id.eq(techArticleId))
.innerJoin(techComment.createdBy, member).fetchJoin()
.leftJoin(techComment.createdBy, member).fetchJoin()
.leftJoin(techComment.createdAnonymousBy, anonymousMember).fetchJoin()
.where(techComment.parent.isNull()
.and(techComment.originParent.isNull())
.and(techComment.deletedAt.isNull())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import com.dreamypatisiel.devdevdev.domain.policy.TechBestCommentsPolicy;
import com.dreamypatisiel.devdevdev.domain.repository.techArticle.TechCommentRepository;
import com.dreamypatisiel.devdevdev.domain.repository.techArticle.TechCommentSort;
import com.dreamypatisiel.devdevdev.domain.service.member.AnonymousMemberService;
import com.dreamypatisiel.devdevdev.global.utils.AuthenticationMemberUtils;
import com.dreamypatisiel.devdevdev.web.dto.SliceCommentCustom;
import com.dreamypatisiel.devdevdev.web.dto.SliceCustom;
import com.dreamypatisiel.devdevdev.web.dto.request.techArticle.ModifyTechCommentRequest;
import com.dreamypatisiel.devdevdev.web.dto.request.techArticle.RegisterTechCommentRequest;
import com.dreamypatisiel.devdevdev.web.dto.response.techArticle.TechCommentRecommendResponse;
Expand All @@ -24,9 +24,13 @@
@Transactional(readOnly = true)
public class GuestTechCommentService extends TechCommentCommonService implements TechCommentService {

private final AnonymousMemberService anonymousMemberService;

public GuestTechCommentService(TechCommentRepository techCommentRepository,
TechBestCommentsPolicy techBestCommentsPolicy) {
TechBestCommentsPolicy techBestCommentsPolicy,
AnonymousMemberService anonymousMemberService) {
super(techCommentRepository, techBestCommentsPolicy);
this.anonymousMemberService = anonymousMemberService;
}

@Override
Expand Down Expand Up @@ -60,12 +64,12 @@ public TechCommentResponse deleteTechComment(Long techArticleId, Long techCommen
@Override
public SliceCommentCustom<TechCommentsResponse> getTechComments(Long techArticleId, Long techCommentId,
TechCommentSort techCommentSort, Pageable pageable,
Authentication authentication) {
String anonymousMemberId, Authentication authentication) {
// 익명 회원인지 검증
AuthenticationMemberUtils.validateAnonymousMethodCall(authentication);

// 기술블로그 댓글/답글 조회
return super.getTechComments(techArticleId, techCommentId, techCommentSort, pageable, null);
return super.getTechComments(techArticleId, techCommentId, techCommentSort, pageable, null, null);
}

@Override
Expand All @@ -80,12 +84,12 @@ public TechCommentRecommendResponse recommendTechComment(Long techArticleId, Lon
* @Since: 2024.10.27
*/
@Override
public List<TechCommentsResponse> findTechBestComments(int size, Long techArticleId,
public List<TechCommentsResponse> findTechBestComments(int size, Long techArticleId, String anonymousMemberId,
Authentication authentication) {

// 익명 회원인지 검증
AuthenticationMemberUtils.validateAnonymousMethodCall(authentication);

return super.findTechBestComments(size, techArticleId, null);
return super.findTechBestComments(size, techArticleId, null, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.dreamypatisiel.devdevdev.domain.service.techArticle.techComment;

import static com.dreamypatisiel.devdevdev.domain.exception.GuestExceptionMessage.INVALID_ANONYMOUS_CAN_NOT_USE_THIS_FUNCTION_MESSAGE;

import com.dreamypatisiel.devdevdev.domain.entity.AnonymousMember;
import com.dreamypatisiel.devdevdev.domain.policy.TechBestCommentsPolicy;
import com.dreamypatisiel.devdevdev.domain.repository.techArticle.TechCommentRepository;
import com.dreamypatisiel.devdevdev.domain.repository.techArticle.TechCommentSort;
import com.dreamypatisiel.devdevdev.domain.service.member.AnonymousMemberService;
import com.dreamypatisiel.devdevdev.global.utils.AuthenticationMemberUtils;
import com.dreamypatisiel.devdevdev.web.dto.SliceCommentCustom;
import com.dreamypatisiel.devdevdev.web.dto.request.techArticle.ModifyTechCommentRequest;
import com.dreamypatisiel.devdevdev.web.dto.request.techArticle.RegisterTechCommentRequest;
import com.dreamypatisiel.devdevdev.web.dto.response.techArticle.TechCommentRecommendResponse;
import com.dreamypatisiel.devdevdev.web.dto.response.techArticle.TechCommentResponse;
import com.dreamypatisiel.devdevdev.web.dto.response.techArticle.TechCommentsResponse;
import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class GuestTechCommentServiceV2 extends TechCommentCommonService implements TechCommentService {

private final AnonymousMemberService anonymousMemberService;

public GuestTechCommentServiceV2(TechCommentRepository techCommentRepository,
TechBestCommentsPolicy techBestCommentsPolicy,
AnonymousMemberService anonymousMemberService) {
super(techCommentRepository, techBestCommentsPolicy);
this.anonymousMemberService = anonymousMemberService;
}

@Override
public TechCommentResponse registerMainTechComment(Long techArticleId,
RegisterTechCommentRequest registerTechCommentRequest,
Authentication authentication) {
throw new AccessDeniedException(INVALID_ANONYMOUS_CAN_NOT_USE_THIS_FUNCTION_MESSAGE);
}

@Override
public TechCommentResponse registerRepliedTechComment(Long techArticleId, Long originParentTechCommentId,
Long parentTechCommentId,
RegisterTechCommentRequest registerRepliedTechCommentRequest,
Authentication authentication) {
throw new AccessDeniedException(INVALID_ANONYMOUS_CAN_NOT_USE_THIS_FUNCTION_MESSAGE);
}

@Override
public TechCommentResponse modifyTechComment(Long techArticleId, Long techCommentId,
ModifyTechCommentRequest modifyTechCommentRequest,
Authentication authentication) {
throw new AccessDeniedException(INVALID_ANONYMOUS_CAN_NOT_USE_THIS_FUNCTION_MESSAGE);
}

@Override
public TechCommentResponse deleteTechComment(Long techArticleId, Long techCommentId,
Authentication authentication) {
throw new AccessDeniedException(INVALID_ANONYMOUS_CAN_NOT_USE_THIS_FUNCTION_MESSAGE);
}

/**
* @Note: 익명 회원이 기술블로그 댓글/답글을 조회한다.
* @Author: 장세웅
* @Since: 2025.07.20
*/
@Override
public SliceCommentCustom<TechCommentsResponse> getTechComments(Long techArticleId, Long techCommentId,
TechCommentSort techCommentSort, Pageable pageable,
String anonymousMemberId,
Authentication authentication) {
// 익명 회원인지 검증
AuthenticationMemberUtils.validateAnonymousMethodCall(authentication);

// 익명회원 추출
AnonymousMember anonymousMember = anonymousMemberService.findOrCreateAnonymousMember(anonymousMemberId);

// 기술블로그 댓글/답글 조회
return super.getTechComments(techArticleId, techCommentId, techCommentSort, pageable, null, anonymousMember);
}

@Override
public TechCommentRecommendResponse recommendTechComment(Long techArticleId, Long techCommentId,
Authentication authentication) {
throw new AccessDeniedException(INVALID_ANONYMOUS_CAN_NOT_USE_THIS_FUNCTION_MESSAGE);
}

/**
* @Note: 익명 회원이 기술블로그 베스트 댓글을 조회한다.
* @Author: 장세웅
* @Since: 2025.07.20
*/
@Override
public List<TechCommentsResponse> findTechBestComments(int size, Long techArticleId,
String anonymousMemberId, Authentication authentication) {

// 익명 회원인지 검증
AuthenticationMemberUtils.validateAnonymousMethodCall(authentication);

// 익명회원 추출
AnonymousMember anonymousMember = anonymousMemberService.findOrCreateAnonymousMember(anonymousMemberId);

return super.findTechBestComments(size, techArticleId, null, anonymousMember);
}
}
Loading