Skip to content

Commit

Permalink
🔨 Refactor: 커뮤니티 중 게시글 목록 반환과 게시글 이미지 관련 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhacandy authored Sep 19, 2024
2 parents a049bf3 + 6c2140a commit 81d01e5
Show file tree
Hide file tree
Showing 24 changed files with 205 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package cotato.growingpain.comment.controller;

import cotato.growingpain.comment.domain.entity.Comment;
import cotato.growingpain.comment.dto.response.CommentListResponse;
import cotato.growingpain.comment.service.CommentLikeService;
import cotato.growingpain.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -21,15 +25,15 @@
@Tag(name = "댓글 좋아요", description = "댓글 좋아요 관련된 api")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/comment/likes/{commentId}")
@RequestMapping("/api/comment/likes")
@Slf4j
public class CommentLikeController {

private final CommentLikeService commentLikeService;

@Operation(summary = "댓글 좋아요 등록", description = "댓글 좋아요 등록을 위한 메소드")
@ApiResponse(content = @Content(schema = @Schema(implementation = Response.class)))
@PostMapping("")
@PostMapping("/{commentId}")
@ResponseStatus(HttpStatus.OK)
public Response<?> registerLike(@PathVariable Long commentId,
@AuthenticationPrincipal Long memberId) {
Expand All @@ -41,12 +45,24 @@ public Response<?> registerLike(@PathVariable Long commentId,

@Operation(summary = "댓글 좋아요 취소", description = "댓글 좋아요 취소를 위한 메소드")
@ApiResponse(content = @Content(schema = @Schema(implementation = Response.class)))
@DeleteMapping("")
@DeleteMapping("/{commentId}")
@ResponseStatus(HttpStatus.OK)
public Response<?> deleteLike(@PathVariable Long commentId,
@AuthenticationPrincipal Long memberId) {

commentLikeService.deleteLike(commentId, memberId);
return Response.createSuccessWithNoData("댓글 좋아요 취소 완료");
}


@Operation(summary = "좋아요 누른 댓글 목록 조회", description = "사용자가 좋아요를 누른 댓글의 목록을 조회하기 위한 메소드")
@ApiResponse(content = @Content(schema = @Schema(implementation = Response.class)))
@GetMapping("/{memberId}/list")
@ResponseStatus(HttpStatus.OK)
public Response<CommentListResponse> getLikeComments(@AuthenticationPrincipal Long memberId) {
log.info("사용자가 좋아요를 누른 댓글 목록 요청: memberId {}", memberId);
List<Comment> likedComments = commentLikeService.getLikedComments(memberId);
CommentListResponse commentListResponse = CommentListResponse.from(likedComments);
return Response.createSuccess("좋아요를 누른 댓글 목록 조회 완료", commentListResponse);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package cotato.growingpain.comment.dto.response;

import cotato.growingpain.comment.domain.entity.Comment;
import java.util.List;

public record CommentListResponse(
List<CommentResponse> commentList
) {
public static CommentListResponse from(List<Comment> comments) {
List<CommentResponse> commentResponses = comments.stream()
.map(CommentResponse::from)
.toList();
return new CommentListResponse(commentResponses);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cotato.growingpain.comment.domain.entity.Comment;
import cotato.growingpain.comment.domain.entity.CommentLike;
import cotato.growingpain.member.domain.entity.Member;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
Expand All @@ -15,5 +16,6 @@ public interface CommentLikeRepository extends JpaRepository<CommentLike, Long>
@Query(value = "delete from CommentLike c where c.comment.id=:commentId")
void deleteByCommentId(Long commentId);

Optional<CommentLike> findByMemberAndComment(Member member, Comment comment);
Optional<CommentLike> findAllByMemberAndComment(Member member, Comment comment);
List<CommentLike> findAllByMemberId(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public interface CommentRepository extends JpaRepository<Comment, Long> {
@Query("SELECT new cotato.growingpain.comment.dto.response.CommentResponse(c.post.id, c.id, c.createdAt, c.modifiedAt, c.content, c.likeCount, c.isDeleted, c.member.id, c.member.profileImageUrl, c.member.name, c.member.field) FROM Comment c WHERE c.post.id = :postId AND c.isDeleted = false")
List<CommentResponse> findByPostIdAndIsDeletedFalse(@Param("postId") Long postId);

List<Comment> findCommentsByPostIdAndIsDeletedFalse(Long postId);
List<Comment> findAllByPostIdAndIsDeletedFalse(Long postId);

Optional<Comment> findByIdAndMemberIdAndIsDeletedFalse(Long commentId, Long memberId);
Optional<Comment> findAllByIdAndMemberIdAndIsDeletedFalse(Long commentId, Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import cotato.growingpain.common.exception.ErrorCode;
import cotato.growingpain.member.domain.entity.Member;
import cotato.growingpain.member.repository.MemberRepository;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -44,13 +46,23 @@ public void deleteLike(Long commentId, Long memberId) {

Comment comment = findCommentId(commentId);
Member member = findMemberById(memberId);
CommentLike commentLike = commentLikeRepository.findByMemberAndComment(member, comment)
CommentLike commentLike = commentLikeRepository.findAllByMemberAndComment(member, comment)
.orElseThrow(() -> new AppException(ErrorCode.COMMENT_LIKE_NOT_FOUND));

commentLike.decreaseCommentLikeCount(member, comment);
commentLikeRepository.delete(commentLike);
}

@Transactional
public List<Comment> getLikedComments(Long memberId) {
List<CommentLike> commentLikes = commentLikeRepository.findAllByMemberId(memberId);

return commentLikes.stream()
.map(CommentLike::getComment)
.collect(Collectors.toList());
}


private Comment findCommentId(Long commentId) {
return commentRepository.findById(commentId)
.orElseThrow(() -> new AppException(ErrorCode.COMMENT_NOT_FOUND));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public CommentListResponse getCommentsByPostId(Long postId) {
@Transactional(readOnly = true)
public CommentListResponse getAllPostsAndCommentsByMemberId(Long memberId) {
// 사용자가 작성한 모든 포스트 조회
List<Post> posts = postRepository.findByMemberIdAndIsDeletedFalse(memberId);
List<Post> posts = postRepository.findAllByMemberIdAndIsDeletedFalse(memberId);
List<CommentResponse> commentList = new ArrayList<>();

// 각 포스트의 댓글 조회
Expand All @@ -73,7 +73,7 @@ public CommentListResponse getAllPostsAndCommentsByMemberId(Long memberId) {

@Transactional
public void deleteComment(Long commentId, Long memberId) {
Comment comment = commentRepository.findByIdAndMemberIdAndIsDeletedFalse(commentId, memberId)
Comment comment = commentRepository.findAllByIdAndMemberIdAndIsDeletedFalse(commentId, memberId)
.orElseThrow(() -> new AppException(ErrorCode.COMMENT_NOT_FOUND));

if(comment.isDeleted()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import cotato.growingpain.common.Response;
import cotato.growingpain.post.PostCategory;
import cotato.growingpain.post.domain.entity.Post;
import cotato.growingpain.post.domain.entity.PostImage;
import cotato.growingpain.post.dto.request.PostRequest;
import cotato.growingpain.post.dto.response.PostImageListResponse;
import cotato.growingpain.post.dto.response.PostListResponse;
import cotato.growingpain.post.service.PostService;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -21,6 +23,7 @@
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -88,13 +91,24 @@ public Response<?> deletePost(@PathVariable Long postId,

@Operation(summary = "게시글 수정", description = "게시글 수정을 위한 메소드")
@ApiResponse(content = @Content(schema = @Schema(implementation = Response.class)))
@PostMapping(value = "/{postId}/update")
@PatchMapping(value = "/{postId}/update")
@ResponseStatus(HttpStatus.CREATED)
public Response<?> registerPost(@PathVariable Long postId,
public Response<?> updatePost(@PathVariable Long postId,
@ModelAttribute @Valid PostRequest request,
@AuthenticationPrincipal Long memberId) throws IOException {
log.info("게시글 {} 수정한 memberId: {}", postId, memberId);
postService.updatePost(postId, request,memberId);
return Response.createSuccessWithNoData("포스트 수정 완료");
}
}

@Operation(summary = "게시글별 이미지 목록 조회", description = "게시글별로 이미지 목록 조회 위한 메소드")
@ApiResponse(content = @Content(schema = @Schema(implementation = PostImageListResponse.class)))
@GetMapping("/{postId}/image")
@ResponseStatus(HttpStatus.OK)
public Response<PostImageListResponse> getPostImageByPostId(@PathVariable Long postId) {
List<PostImage> postImages = postService.getPostImageByPostId(postId);
log.info("{}에 있는 이미지 목록", postId);
PostImageListResponse postImageListResponse = PostImageListResponse.from(postImages);
return Response.createSuccess("게시글의 이미지 목록 조회 완료", postImageListResponse);
}
}
18 changes: 9 additions & 9 deletions src/main/java/cotato/growingpain/post/domain/entity/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import cotato.growingpain.comment.domain.entity.Comment;
import cotato.growingpain.common.domain.BaseTimeEntity;
import cotato.growingpain.common.exception.AppException;
import cotato.growingpain.common.exception.ErrorCode;
Expand Down Expand Up @@ -42,9 +43,6 @@ public class Post extends BaseTimeEntity {

private String content;

@Column(name = "post_image_url")
private String imageUrl;

@Enumerated(EnumType.STRING)
@Column(name = "parent_post_category")
private PostCategory parentCategory;
Expand All @@ -70,17 +68,20 @@ public class Post extends BaseTimeEntity {
@JsonIgnore
private List<PostSave> postSaves = new ArrayList<>();

private Post(Member member, String title, String content, String imageUrl, PostCategory parentCategory, PostCategory subCategory) {
@OneToMany(mappedBy = "post")
@JsonIgnore
private List<Comment> comments = new ArrayList<>();

private Post(Member member, String title, String content, PostCategory parentCategory, PostCategory subCategory) {
this.member = member;
this.title = title;
this.content = content;
this.imageUrl = imageUrl;
this.parentCategory = parentCategory;
this.subCategory = subCategory;
}

public static Post of(Member member, String title, String content, String imageUrl, PostCategory parentCategory, PostCategory subCategory) {
return new Post(member, title, content, imageUrl, parentCategory, subCategory);
public static Post of(Member member, String title, String content, PostCategory parentCategory, PostCategory subCategory) {
return new Post(member, title, content, parentCategory, subCategory);
}

public void increaseLikeCount(){
Expand All @@ -104,10 +105,9 @@ public void deletePost() {
likeCount = 0;
}

public void updatePost(String title, String content, String imageUrl, PostCategory category) {
public void updatePost(String title, String content, PostCategory category) {
this.title = title;
this.content = content;
this.imageUrl = imageUrl;
this.subCategory = category;
this.parentCategory = category.getParent();
this.modifiedAt = LocalDateTime.now();
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/cotato/growingpain/post/domain/entity/PostImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cotato.growingpain.post.domain.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PostImage {

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


@Column(name = "post_id", nullable = false)
private Long postId;

@Column(name = "post_image_url", nullable = false)
private String imageUrl;

public PostImage(Long postId, String imageUrl) {
this.postId = postId;
this.imageUrl = imageUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cotato.growingpain.post.PostCategory;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;

public record PostRequest(
Expand All @@ -15,7 +16,7 @@ public record PostRequest(
@Size(max = 3000)
String content,

MultipartFile postImage,
List<MultipartFile> postImages,

PostCategory category
){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cotato.growingpain.post.dto.response;

import cotato.growingpain.post.domain.entity.PostImage;
import java.util.List;

public record PostImageListResponse (
List <PostImageResponse> postImages
) {
public static PostImageListResponse from(List<PostImage> postImages) {
List <PostImageResponse> postImageResponses = postImages.stream()
.map(PostImageResponse::from)
.toList();
return new PostImageListResponse(postImageResponses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package cotato.growingpain.post.dto.response;

import cotato.growingpain.post.domain.entity.PostImage;

public record PostImageResponse(

Long postImageId,
String imageUrl
) {
public static PostImageResponse from(PostImage postImage) {
return new PostImageResponse(
postImage.getId(),
postImage.getImageUrl()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ public record PostResponse(
LocalDateTime modifiedAt,
String title,
String content,
String postImageUrl,
//String postImageUrl,
String parentCategory,
String subCategory,
Integer likeCount,
int likeCount,
int commentCount,
Boolean isDeleted,
String memberNickname,
String profileImageUrl,
Expand All @@ -27,10 +28,11 @@ public static PostResponse from(Post post) {
post.getModifiedAt(),
post.getTitle(),
post.getContent(),
post.getImageUrl(),
//post.getImageUrl(),
post.getParentCategory() != null ? post.getParentCategory().name() : null,
post.getSubCategory() != null ? post.getSubCategory().name() : null,
post.getLikeCount(),
post.getComments().size(),
post.isDeleted(),
post.getMember().getName(),
post.getMember().getProfileImageUrl(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cotato.growingpain.post.repository;

import cotato.growingpain.post.domain.entity.PostImage;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PostImageRepository extends JpaRepository<PostImage, Long> {
void deleteAllByPostId(Long postId);

List<PostImage> findAllByPostId(Long postId);
}
Loading

0 comments on commit 81d01e5

Please sign in to comment.