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

Feat #22 Reply-기능-개발 #24

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5fed2ca
Feat: 답글 기능 컨트롤러 구현
seokjun01 Nov 7, 2024
02075a2
Feat: 답글 생성 성공 응답 메시지 추가
seokjun01 Nov 7, 2024
bc7578c
Feat : parent 필드와 답글들을 담는 리스트 추가
seokjun01 Nov 7, 2024
b5205bd
Feat: Dto타입 리스트로 replies 필드 생성
seokjun01 Nov 7, 2024
f35ff13
Feat : 답글 생성 로직 구현
seokjun01 Nov 7, 2024
df893d2
Refactor : dto 타입 통일 class --> record
seokjun01 Nov 7, 2024
6471c8d
fix : Dto 타입변환으로 인한 메서드 호출 방식 수정
seokjun01 Nov 7, 2024
7f762c4
Refactor : 최신 게시물 조회 로직 중복제거
seokjun01 Nov 8, 2024
cecdbf2
Refactor : 좋아요 여부를 나타내는 메소드 오버로딩
seokjun01 Nov 8, 2024
a32f6e3
Refactor: 조회 로직에 매개변수 추가 + 사용자 정보 저장
seokjun01 Nov 8, 2024
c1ca103
Refactor: 조회 컨트롤러 매개변수 추가
seokjun01 Nov 8, 2024
d0ffeeb
Refactor: 조회 로직에 좋아요 눌렀는지 여부 추가
seokjun01 Nov 8, 2024
644fa50
Refacor: 삭제 로직 단편화
seokjun01 Nov 8, 2024
18221a5
Refactor: 좋아요 객체 수로 갯수 계산
seokjun01 Nov 8, 2024
a788ca1
Refactor: 엔티티 내 메서드를 통해 좋아요 수 갱신 후 DB 반영
seokjun01 Nov 8, 2024
301b23d
Refactor : 들여쓰기 수장
seokjun01 Nov 8, 2024
5d3ac81
Feat : 모든 글 조회 및 상세 조회 로직 구현
seokjun01 Nov 8, 2024
1ca3a61
Feat : 모든 게시글 조회 성공 메시지 추가
seokjun01 Nov 8, 2024
31ed1a2
Feat : 전체조회와, 상세조회를 위한 메서드 추가
seokjun01 Nov 8, 2024
52b8fc9
Feat: Replies를 반환안하는 메서드 오버로딩
seokjun01 Nov 8, 2024
1493609
Merge branch 'main' of https://github.com/Leets-Official/X-BE into fe…
seokjun01 Nov 8, 2024
d6b3ac8
Refactor: post 객체에 메서드 캡슐화
seokjun01 Nov 9, 2024
02ea5cc
Feat : 역할 분리를 위한, 부모글만 조회하는 dto 생성
seokjun01 Nov 9, 2024
a10a37d
Refactor: withOutReplies메서드 Dto로 추출
seokjun01 Nov 9, 2024
03d3636
Refactor : 부모글만 반환하는 Dto는 반환타입 변경
seokjun01 Nov 9, 2024
330b7f6
Refactor: 좋아요 체크 여부 서비스계층에서 구현, 반환타입, 매개변수 수정
seokjun01 Nov 9, 2024
4bb0652
fix : 깃 커밋 수정
seokjun01 Nov 9, 2024
5fae1e0
fix : 깃 커밋 수정
seokjun01 Nov 9, 2024
c395976
fix :로컬 원격 커밋 수정
seokjun01 Nov 9, 2024
a6a3113
fix : 환경변수 설정
seokjun01 Nov 9, 2024
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
@@ -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
Loading