Skip to content

Commit

Permalink
Merge pull request #29 from Leets-Official/feat/#22/reply-dev
Browse files Browse the repository at this point in the history
Feat/#22/reply 기능 개발
  • Loading branch information
seokjun01 authored Nov 10, 2024
2 parents b2653cb + a6a3113 commit 52b2e64
Show file tree
Hide file tree
Showing 13 changed files with 268 additions and 163 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package com.leets.X.domain.post.controller;

import com.leets.X.domain.post.domain.Post;

import com.leets.X.domain.post.dto.request.PostRequestDTO;
import com.leets.X.domain.post.dto.response.ParentPostResponseDto;
import com.leets.X.domain.post.dto.response.PostResponseDto;
import com.leets.X.domain.post.service.PostService;
import com.leets.X.global.common.response.ResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
//컨트롤러에서 ResponseDto만들게끔

@Tag(name = "POST")
@RestController
@RequestMapping("/api/v1/posts")
Expand All @@ -23,27 +22,35 @@ public class PostController {

private final PostService postService;


// 게시물 상세 조회(자식 게시물 까지 함께 조회됨)
@GetMapping("/{id}")
@Operation(summary = "게시물 ID로 조회")
public ResponseDto<PostResponseDto> getPost(@PathVariable Long id) {
PostResponseDto postResponseDto = postService.getPostResponse(id);
@Operation(summary = "게시물 ID로 상세 조회")
public ResponseDto<PostResponseDto> getPost(@PathVariable Long id, @AuthenticationPrincipal String email) {
PostResponseDto postResponseDto = postService.getPostResponse(id, email);
return ResponseDto.response(ResponseMessage.GET_POST_SUCCESS.getCode(), ResponseMessage.GET_POST_SUCCESS.getMessage(), postResponseDto);
}

// 모든 부모게시물 조회
@GetMapping("/all")
@Operation(summary = "전체 부모 글 조회")
public ResponseDto<List<ParentPostResponseDto>> getAllParentPosts(@AuthenticationPrincipal String email) {
List<ParentPostResponseDto> posts = postService.getAllParentPosts(email);
return ResponseDto.response(ResponseMessage.GET_ALL_PARENT_POSTS_SUCCESS.getCode(), ResponseMessage.GET_ALL_PARENT_POSTS_SUCCESS.getMessage(), posts);
}


@GetMapping("/likes")
@Operation(summary = "좋아요 수로 정렬한 게시물 조회")
public ResponseDto<List<PostResponseDto>> getPostsSortedByLikes() {
List<PostResponseDto> posts = postService.getPostsSortedByLikes();
public ResponseDto<List<PostResponseDto>> getPostsSortedByLikes(@AuthenticationPrincipal String email) {
List<PostResponseDto> posts = postService.getPostsSortedByLikes(email);
return ResponseDto.response(ResponseMessage.GET_SORTED_BY_LIKES_SUCCESS.getCode(), ResponseMessage.GET_SORTED_BY_LIKES_SUCCESS.getMessage(), posts);
}


@GetMapping("/latest")
@Operation(summary = "최신 게시물 조회")
public ResponseDto<List<PostResponseDto>> getLatestPosts() {
List<PostResponseDto> posts = postService.getLatestPosts();
public ResponseDto<List<ParentPostResponseDto>> getLatestPosts(@AuthenticationPrincipal String email) {
List<ParentPostResponseDto> posts = postService.getLatestParentPosts(email);
return ResponseDto.response(ResponseMessage.GET_LATEST_POST_SUCCESS.getCode(), ResponseMessage.GET_LATEST_POST_SUCCESS.getMessage(), posts);
}

Expand All @@ -63,12 +70,20 @@ public ResponseDto<String> addLike(@PathVariable Long postId, @AuthenticationPri
return ResponseDto.response(ResponseMessage.ADD_LIKE_SUCCESS.getCode(), responseMessage);
}

@PostMapping("/{postId}/reply")
@Operation(summary = "답글 생성")
public ResponseDto<PostResponseDto> createReply(@PathVariable Long postId, @RequestBody PostRequestDTO postRequestDTO, @AuthenticationPrincipal String email) {
// 답글 생성 서비스 호출 (부모 ID를 직접 전달)
PostResponseDto postResponseDto = postService.createReply(postId, postRequestDTO, email);
return ResponseDto.response(ResponseMessage.REPLY_SUCCESS.getCode(), ResponseMessage.REPLY_SUCCESS.getMessage(), postResponseDto);
}


@DeleteMapping("/{postId}")
@Operation(summary = "게시물 삭제")
public ResponseDto<String> deletePost(@PathVariable Long postId, @AuthenticationPrincipal String email) {
String responseMessage = postService.deletePost(postId, email);
return ResponseDto.response(ResponseMessage.POST_DELETED_SUCCESS.getCode(), responseMessage);
postService.deletePost(postId, email);
return ResponseDto.response(ResponseMessage.POST_DELETED_SUCCESS.getCode(), ResponseMessage.POST_DELETED_SUCCESS.getMessage());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public enum ResponseMessage {
GET_LATEST_POST_SUCCESS(200, "최신 게시물 조회에 성공했습니다."),
ADD_LIKE_SUCCESS(201, "좋아요가 추가되었습니다."),
POST_DELETED_SUCCESS(200, "게시물이 성공적으로 삭제되었습니다."),
LIKE_CANCEL_SUCCESS(200, "좋아요가 성공적으로 취소되었습니다.");
LIKE_CANCEL_SUCCESS(200, "좋아요가 성공적으로 취소되었습니다."),
REPLY_SUCCESS(201, "답글이 생성되었습니다."),
GET_ALL_PARENT_POSTS_SUCCESS(200, "모든 게시글 조회에 성공하였습니다.");

private final int code;
private final String message;
Expand Down
56 changes: 32 additions & 24 deletions src/main/java/com/leets/X/domain/post/domain/Post.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.leets.X.domain.post.domain;

import com.leets.X.domain.comment.domain.Comment;

import com.leets.X.domain.image.domain.Image;
import com.leets.X.domain.like.domain.Like;
import com.leets.X.domain.post.domain.enums.IsDeleted;
Expand Down Expand Up @@ -29,6 +29,14 @@ public class Post extends BaseTimeEntity {
@JoinColumn(name = "user_id")
private User user;

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

@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Post> replies = new ArrayList<>(); //답글 리스트


@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Like> likes = new ArrayList<>();

Expand All @@ -46,32 +54,19 @@ public class Post extends BaseTimeEntity {
private LocalDateTime deletedAt;

// 좋아요 수를 관리하기 위한 필드

@Column(name = "like_count")
private Long likeCount = 0L; // 기본값을 0L로 초기화하여 null을 방지

public void incrementLikeCount() {
if (this.likeCount == null) {
this.likeCount = 1L; // null인 경우 1로 초기화
} else {
this.likeCount++;
}
public void updateLikeCount(long newLikeCount) {
this.likeCount = newLikeCount;
}

public void decrementLikeCount() {
if (this.likeCount == null || this.likeCount == 0) {
this.likeCount = 0L; // null이거나 0일 경우 0으로 유지
} else {
this.likeCount--;
}
}

public long getLikesCount() {
return likeCount != null ? likeCount : 0; // null일 경우 0 반환
}



// 서비스에서 글의 상태를 삭제 상태로 바꾸기 위한 메서드
public void delete() {
if (this.isDeleted == IsDeleted.ACTIVE) { // 이미 삭제 상태가 아닐 때만 변경
Expand All @@ -82,13 +77,26 @@ public void delete() {
// 정적 메서드로 글 생성
public static Post create(User user, String content) {
return Post.builder()
.user(user)
.content(content)
.views(0) // 기본 조회 수
.likeCount(0L) // 좋아요 갯수 추가
.isDeleted(IsDeleted.ACTIVE) // 기본값 ACTIVE로 설정
.images(new ArrayList<>()) // 빈 리스트로 초기화
.build();
}
.user(user)
.content(content)
.views(0) // 기본 조회 수
.likeCount(0L) // 좋아요 갯수 추가
.isDeleted(IsDeleted.ACTIVE) // 기본값 ACTIVE로 설정
.images(new ArrayList<>()) // 빈 리스트로 초기화
.build();
}

// 정적 팩토리 메서드
public static Post create(User user, String content, Post parent) {
return Post.builder()
.user(user)
.content(content)
.views(0) // 기본값 설정
.likeCount(0L) // 기본값 설정
.isDeleted(IsDeleted.ACTIVE) // 기본값 설정
.parent(parent) // 부모 글 설정
.build();

}
}

Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package com.leets.X.domain.post.dto.response;

import com.leets.X.domain.comment.domain.Comment;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class CommentResponseDto {
private Long commentId;
private String content;

public record CommentResponseDto(
Long commentId,
String content
) {
public static CommentResponseDto from(Comment comment) {
return new CommentResponseDto(comment.getId(), comment.getContent());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package com.leets.X.domain.post.dto.response;

import com.leets.X.domain.image.domain.Image;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ImageResponseDto {

private Long imageId;
private String url;

public record ImageResponseDto(
Long imageId,
String url
) {
public static ImageResponseDto from(Image image) {
return new ImageResponseDto(image.getId(), image.getUrl());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.leets.X.domain.post.dto.response;

import com.leets.X.domain.post.domain.Post;
import com.leets.X.domain.post.domain.enums.IsDeleted;
import com.leets.X.domain.user.domain.User;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public record ParentPostResponseDto(
Long id,
String content,
Integer views,
IsDeleted isDeleted,
LocalDateTime createdAt,
PostUserResponse user,
List<ImageResponseDto> images,
Long likeCount,
Boolean isLikedByUser
) {
public static ParentPostResponseDto from(Post post, boolean isLikedByUser) {
return new ParentPostResponseDto(
post.getId(),
post.getContent(),
post.getViews(),
post.getIsDeleted(),
post.getCreatedAt(),
convertUser(post.getUser()), // User 변환
convertImagesToDtoList(post), // Images 변환
post.getLikesCount(),
isLikedByUser // 좋아요 여부 설정
);
}

private static PostUserResponse convertUser(User user) {
return user != null ? PostUserResponse.from(user) : null;
}

private static List<ImageResponseDto> convertImagesToDtoList(Post post) {
return post.getImages() != null ? post.getImages().stream()
.map(ImageResponseDto::from)
.collect(Collectors.toList()) : Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
package com.leets.X.domain.post.dto.response;


import com.leets.X.domain.comment.domain.Comment;
import com.leets.X.domain.image.domain.Image;
import com.leets.X.domain.like.repository.LikeRepository;
import com.leets.X.domain.post.domain.Post;
import com.leets.X.domain.post.domain.enums.IsDeleted;
import com.leets.X.domain.user.domain.User;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;


import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


public record PostResponseDto(
Long id,
String content,
Integer views,
IsDeleted isDeleted,
LocalDateTime createdAt,
PostUserResponse user,
List<ImageResponseDto> images,
Long likeCount,
List<PostResponseDto> replies,
Boolean isLikedByUser // 좋아요 여부 확인
) {


@Getter
@NoArgsConstructor
@AllArgsConstructor
public class PostResponseDto {
private Long id;
private String content;
private Integer views;
private IsDeleted isDeleted;
private LocalDateTime createdAt;
private PostUserResponse user; // 작성자 정보
private List<ImageResponseDto> images; // 관련 이미지 리스트
private Long likeCount; // 좋아요 개수 추가

public static PostResponseDto from(Post post) {
public static PostResponseDto from(Post post, boolean isLikedByUser) {
return new PostResponseDto(
post.getId(),
post.getContent(),
Expand All @@ -37,22 +36,44 @@ public static PostResponseDto from(Post post) {
post.getCreatedAt(),
convertUser(post.getUser()),
convertImagesToDtoList(post),
post.getLikesCount() // 좋아요 개수 추가
post.getLikesCount(),
convertRepliesToDtoList(post.getReplies()),
isLikedByUser // 서비스에서 전달된 boolean 값 사용
);
}


// 좋아요 여부를 확인하기 위한 메서드 오버로딩
public static PostResponseDto from(Post post, User user, LikeRepository likeRepository) {
boolean isLikedByUser = user != null && likeRepository.existsByPostAndUser(post, user); // 좋아요 여부 확인

return new PostResponseDto(
post.getId(),
post.getContent(),
post.getViews(),
post.getIsDeleted(),
post.getCreatedAt(),
convertUser(post.getUser()),
convertImagesToDtoList(post),
post.getLikesCount(),
convertRepliesToDtoList(post.getReplies()),
isLikedByUser // 좋아요 여부를 동적으로 설정
);
}


private static List<PostResponseDto> convertRepliesToDtoList(List<Post> replies) {
return replies != null ? replies.stream()
.map(reply -> PostResponseDto.from(reply, false)) // 기본적으로 isLikedByUser를 false로 설정
.collect(Collectors.toList()) : Collections.emptyList();
}
private static PostUserResponse convertUser(User user) {
return user != null ? PostUserResponse.from(user) : null;
}

private static List<ImageResponseDto> convertImagesToDtoList(Post post) {
return post.getImages().stream()
return post.getImages() != null ? post.getImages().stream()
.map(ImageResponseDto::from)
.toList();
.collect(Collectors.toList()) : Collections.emptyList();
}


}


Loading

0 comments on commit 52b2e64

Please sign in to comment.