Skip to content

Commit

Permalink
Merge pull request #155 from sharemindteam/feature/152-post-like
Browse files Browse the repository at this point in the history
feat: 일대다 상담 좋아요 기능 구현
  • Loading branch information
letskuku authored Mar 25, 2024
2 parents 530a163 + 9b9f036 commit e889f25
Show file tree
Hide file tree
Showing 27 changed files with 641 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.sharemind.comment.application;

import com.example.sharemind.comment.domain.Comment;
import com.example.sharemind.comment.dto.request.CommentCreateRequest;
import com.example.sharemind.comment.dto.response.CommentGetResponse;

Expand All @@ -9,4 +10,6 @@ public interface CommentService {
List<CommentGetResponse> getCommentsByPost(Long postId, Long customerId);

void createComment(CommentCreateRequest commentCreateRequest, Long customerId);

Comment getCommentByCommentId(Long commentId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
import com.example.sharemind.comment.exception.CommentErrorCode;
import com.example.sharemind.comment.exception.CommentException;
import com.example.sharemind.comment.repository.CommentRepository;
import com.example.sharemind.commentLike.repository.CommentLikeRepository;
import com.example.sharemind.counselor.application.CounselorService;
import com.example.sharemind.counselor.domain.Counselor;
import com.example.sharemind.customer.application.CustomerService;
import com.example.sharemind.customer.domain.Customer;
import com.example.sharemind.post.application.PostService;
import com.example.sharemind.post.content.PostStatus;
import com.example.sharemind.post.domain.Post;
Expand All @@ -22,35 +25,51 @@
@RequiredArgsConstructor
public class CommentServiceImpl implements CommentService {

private static final Integer MAX_COMMENTS = 5;

private final PostService postService;
private final CounselorService counselorService;
private final CustomerService customerService;
private final CommentRepository commentRepository;

private static final Integer MAX_COMMENTS = 5;
private final CommentLikeRepository commentLikeRepository;

@Override
public List<CommentGetResponse> getCommentsByPost(Long postId, Long customerId) {
Post post = postService.checkAndGetCounselorPost(postId, customerId);
Customer customer = customerService.getCustomerByCustomerId(customerId);

List<Comment> comments = commentRepository.findByPostAndIsActivatedIsTrue(post);
return comments.stream()
.map(CommentGetResponse::of)
.map(comment -> CommentGetResponse.of(comment,
commentLikeRepository.existsByCommentAndCustomerAndIsActivatedIsTrue(
comment, customer)))
.toList();
}

@Transactional
@Override
public void createComment(CommentCreateRequest commentCreateRequest, Long customerId) {
Post post = postService.checkAndGetCounselorPost(commentCreateRequest.getPostId(), customerId);
Post post = postService.checkAndGetCounselorPost(commentCreateRequest.getPostId(),
customerId);
Counselor counselor = counselorService.getCounselorByCustomerId(customerId);

if (commentRepository.findByPostAndCounselorAndIsActivatedIsTrue(post, counselor) != null)
throw new CommentException(CommentErrorCode.COMMENT_ALREADY_REGISTERED, counselor.getNickname());
if (commentRepository.findByPostAndCounselorAndIsActivatedIsTrue(post, counselor) != null) {
throw new CommentException(CommentErrorCode.COMMENT_ALREADY_REGISTERED,
counselor.getNickname());
}

commentRepository.save(commentCreateRequest.toEntity(post, counselor));

List<Comment> comments = commentRepository.findByPostAndIsActivatedIsTrue(post);
if (comments.size() == MAX_COMMENTS)
if (comments.size() == MAX_COMMENTS) {
post.updatePostStatus(PostStatus.COMPLETED);
}
}

@Override
public Comment getCommentByCommentId(Long commentId) {
return commentRepository.findByCommentIdAndIsActivatedIsTrue(commentId).orElseThrow(
() -> new CommentException(CommentErrorCode.COMMENT_NOT_FOUND,
commentId.toString()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,12 @@ public Comment(Post post, Counselor counselor, String content) {
isChosen = false;
totalLike = 0L;
}

public void increaseTotalLike() {
this.totalLike++;
}

public void decreaseTotalLike() {
this.totalLike--;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,34 @@ public class CommentGetResponse {
@Schema(description = "답변 내용")
private final String content;

@Schema(description = "조회한 회원의 좋아요 여부")
private final Boolean isLiked;

@Schema(description = "좋아요 수")
private final Long totalLike;

@Schema(description = "마지막 업데이트 일시", example = "오전 11:10")
private final String updatedAt;

@Schema(description = "채택 여부", example="true")
@Schema(description = "채택 여부", example = "true")
private final Boolean isChosen;

@Builder
public CommentGetResponse(String nickName, String content, Long totalLike, String updatedAt, Boolean isChosen) {
public CommentGetResponse(String nickName, String content, Boolean isLiked, Long totalLike,
String updatedAt, Boolean isChosen) {
this.nickName = nickName;
this.content = content;
this.isLiked = isLiked;
this.totalLike = totalLike;
this.updatedAt = updatedAt;
this.isChosen = isChosen;
}

public static CommentGetResponse of(Comment comment) {
public static CommentGetResponse of(Comment comment, Boolean isLiked) {
return CommentGetResponse.builder()
.nickName(comment.getCounselor().getNickname())
.content(comment.getContent())
.isLiked(isLiked)
.totalLike(comment.getTotalLike())
.updatedAt(TimeUtil.getUpdatedAt(comment.getUpdatedAt()))
.isChosen(comment.getIsChosen())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@Getter
public enum CommentErrorCode {

COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "일대다 상담 댓글이 존재하지 않습니다."),
COMMENT_ALREADY_REGISTERED(HttpStatus.BAD_REQUEST, "상담사 당 댓글은 한 번만 작성할 수 있습니다.");

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
import com.example.sharemind.comment.domain.Comment;
import com.example.sharemind.counselor.domain.Counselor;
import com.example.sharemind.post.domain.Post;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {

List<Comment> findByPostAndIsActivatedIsTrue(Post post);

Comment findByPostAndCounselorAndIsActivatedIsTrue(Post post, Counselor counselor);

Optional<Comment> findByCommentIdAndIsActivatedIsTrue(Long commentId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.sharemind.commentLike.application;

public interface CommentLikeService {

void createCommentLike(Long commentId, Long customerId);

void deleteCommentLike(Long commentId, Long customerId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.example.sharemind.commentLike.application;

import com.example.sharemind.comment.application.CommentService;
import com.example.sharemind.comment.domain.Comment;
import com.example.sharemind.commentLike.domain.CommentLike;
import com.example.sharemind.commentLike.exception.CommentLikeErrorCode;
import com.example.sharemind.commentLike.exception.CommentLikeException;
import com.example.sharemind.commentLike.repository.CommentLikeRepository;
import com.example.sharemind.customer.application.CustomerService;
import com.example.sharemind.customer.domain.Customer;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CommentLikeServiceImpl implements CommentLikeService {

private final CustomerService customerService;
private final CommentService commentService;
private final CommentLikeRepository commentLikeRepository;

@Transactional
@Override
public void createCommentLike(Long commentId, Long customerId) {
Comment comment = commentService.getCommentByCommentId(commentId);
Customer customer = customerService.getCustomerByCustomerId(customerId);

if (commentLikeRepository.existsByCommentAndCustomer(comment, customer)) {
CommentLike commentLike = commentLikeRepository.findByCommentAndCustomer(comment,
customer).orElseThrow(
() -> new CommentLikeException(CommentLikeErrorCode.COMMENT_LIKE_NOT_FOUND));

commentLike.updateIsActivatedTrue();
} else {
CommentLike commentLike = CommentLike.builder()
.comment(comment)
.customer(customer)
.build();

commentLikeRepository.save(commentLike);
}
}

@Transactional
@Override
public void deleteCommentLike(Long commentId, Long customerId) {
Comment comment = commentService.getCommentByCommentId(commentId);
Customer customer = customerService.getCustomerByCustomerId(customerId);

CommentLike commentLike = commentLikeRepository.findByCommentAndCustomerAndIsActivatedIsTrue(
comment, customer).orElseThrow(
() -> new CommentLikeException(CommentLikeErrorCode.COMMENT_LIKE_NOT_FOUND));

commentLike.updateIsActivatedFalse();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.example.sharemind.commentLike.domain;

import com.example.sharemind.comment.domain.Comment;
import com.example.sharemind.commentLike.exception.CommentLikeErrorCode;
import com.example.sharemind.commentLike.exception.CommentLikeException;
import com.example.sharemind.customer.domain.Customer;
import com.example.sharemind.global.common.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
public class CommentLike extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "comment_like_id")
private Long commentLikeId;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "customer_id")
private Customer customer;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "comment_id")
private Comment comment;

@Builder
public CommentLike(Customer customer, Comment comment) {
this.customer = customer;
this.comment = comment;

this.comment.increaseTotalLike();
}

public void updateIsActivatedTrue() {
checkIsActivatedFalse();

super.updateIsActivatedTrue();
this.comment.increaseTotalLike();
}

public void updateIsActivatedFalse() {
super.updateIsActivatedFalse();

this.comment.decreaseTotalLike();
}

private void checkIsActivatedFalse() {
if (this.isActivated()) {
throw new CommentLikeException(CommentLikeErrorCode.COMMENT_ALREADY_LIKED);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.sharemind.commentLike.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum CommentLikeErrorCode {

COMMENT_LIKE_NOT_FOUND(HttpStatus.NOT_FOUND, "일대다 상담 댓글 좋아요 정보가 존재하지 않습니다."),
COMMENT_ALREADY_LIKED(HttpStatus.BAD_REQUEST, "이미 좋아요를 누른 일대다 상담 댓글입니다.");

private final HttpStatus httpStatus;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.sharemind.commentLike.exception;

import lombok.Getter;

@Getter
public class CommentLikeException extends RuntimeException {

private final CommentLikeErrorCode errorCode;

public CommentLikeException(CommentLikeErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}
Loading

0 comments on commit e889f25

Please sign in to comment.