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] #31 repost 기능 구현 및 코드 통합 #31

Merged
merged 17 commits into from
Nov 11, 2024
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 @@ -5,6 +5,7 @@
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.domain.post.service.RepostService;
import com.leets.X.global.common.response.ResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -26,6 +27,7 @@
public class PostController {

private final PostService postService;
private final RepostService repostService;

// 게시물 상세 조회(자식 게시물 까지 함께 조회됨)
@GetMapping("/{id}")
Expand All @@ -37,37 +39,51 @@ public ResponseDto<PostResponseDto> getPost(@PathVariable Long id, @Authenticati

// 모든 부모게시물 조회
@GetMapping("/all")
@Operation(summary = "전체 부모 글 조회")
@Operation(summary = "[Home] 추천 게시글")
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("/user/{userId}")
@Operation(summary = "[Profile] 유저 게시글 조회")
public ResponseDto<List<ParentPostResponseDto>> getAllUserPosts(@PathVariable Long userId) {
List<ParentPostResponseDto> posts = repostService.getUserFeed(userId);
return ResponseDto.response(ResponseMessage.GET_USER_POST.getCode(), ResponseMessage.GET_USER_POST.getMessage(), posts);
}

@GetMapping("/likes")
@Operation(summary = "좋아요 수로 정렬한 게시물 조회")
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("/following")
@Operation(summary = "[Home] 팔로잉 게시글 조회")
public ResponseDto<List<ParentPostResponseDto>> getAllFollowingPosts(@AuthenticationPrincipal String email) {
List<ParentPostResponseDto> posts = repostService.getFollowingPost(email);
return ResponseDto.response(ResponseMessage.GET_FOLLOWING_POST.getCode(), ResponseMessage.GET_FOLLOWING_POST.getMessage(), posts);
}


@GetMapping("/latest")
@Operation(summary = "최신 게시물 조회")
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);
}
// @GetMapping("/likes")
// @Operation(summary = "좋아요 수로 정렬한 게시물 조회")
// 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<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);
// }


@PostMapping(value = "/post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "글 생성")
public ResponseDto<PostResponseDto> createPost(@RequestPart PostRequestDTO postRequestDTO,
public ResponseDto<String> createPost(@RequestPart PostRequestDTO postRequestDTO,
@RequestPart(value = "files", required = false) List<MultipartFile> files,
@AuthenticationPrincipal String email) throws IOException {
// 인증된 사용자의 이메일을 `@AuthenticationPrincipal`을 통해 주입받음
PostResponseDto postResponseDto = postService.createPost(postRequestDTO, files , email);
return ResponseDto.response(ResponseMessage.POST_SUCCESS.getCode(), ResponseMessage.POST_SUCCESS.getMessage(), postResponseDto);
postService.createPost(postRequestDTO, files , email);
return ResponseDto.response(ResponseMessage.POST_SUCCESS.getCode(), ResponseMessage.POST_SUCCESS.getMessage());
}

@PostMapping("/{postId}/like")
Expand All @@ -79,13 +95,13 @@ public ResponseDto<String> addLike(@PathVariable Long postId, @AuthenticationPri

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


Expand All @@ -104,4 +120,11 @@ public ResponseDto<String> cancelLike(@PathVariable Long postId, @Authentication
return ResponseDto.response(ResponseMessage.LIKE_CANCEL_SUCCESS.getCode(), responseMessage);
}

@PostMapping("/repost/{postId}")
@Operation(summary = "Repost 하기")
public ResponseDto<String> repost(@PathVariable Long postId, @AuthenticationPrincipal String email) {
repostService.rePost(postId, email);
return ResponseDto.response(ResponseMessage.REPOST_SUCCESS.getCode(), ResponseMessage.REPOST_SUCCESS.getMessage());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ public enum ResponseMessage {
POST_DELETED_SUCCESS(200, "게시물이 성공적으로 삭제되었습니다."),
LIKE_CANCEL_SUCCESS(200, "좋아요가 성공적으로 취소되었습니다."),
REPLY_SUCCESS(201, "답글이 생성되었습니다."),
GET_ALL_PARENT_POSTS_SUCCESS(200, "모든 게시글 조회에 성공하였습니다.");
GET_ALL_PARENT_POSTS_SUCCESS(200, "모든 게시글 조회에 성공하였습니다."),
REPOST_SUCCESS(200, "리포스트에 성공했습니다."),
GET_USER_POST(200, "해당 유저의 게시글 조회에 성공했습니다."),
GET_FOLLOWING_POST(200, "팔로우 하는 게시글 조회에 성공했습니다.");

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

import com.leets.X.domain.user.domain.User;
import jakarta.persistence.*;
import lombok.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
@Getter
public class Repost {

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;

public static Repost of(User user, Post post) {
return Repost.builder()
.user(user)
.post(post)
.build();
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/leets/X/domain/post/domain/enums/Type.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.leets.X.domain.post.domain.enums;

public enum Type {
POST, REPOST
}
87 changes: 87 additions & 0 deletions src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.leets.X.domain.post.dto.mapper;

import com.leets.X.domain.image.dto.response.ImageResponse;
import com.leets.X.domain.like.repository.LikeRepository;
import com.leets.X.domain.post.domain.Post;
import com.leets.X.domain.post.domain.enums.Type;
import com.leets.X.domain.post.dto.response.ParentPostResponseDto;
import com.leets.X.domain.post.dto.response.PostResponseDto;
import com.leets.X.domain.post.dto.response.PostUserResponse;
import com.leets.X.domain.user.domain.User;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

@Component
public class PostMapper {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에는 dto의 from이나 entity의 of 정적 메서드를 사용했다면,
post와 repost를 공통으로 사용하는 dto 변환과 관련 로직을 위해 Mapper를 두어 관심사를 분리한건가요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 PostResponseDto 내부 로직이 많아짐에 따라 dto의 역할을 넘어서는 책임이 생긴다고 판단해 dto를 만드는 커스텀 매퍼를 구현했습니다
또 post의 경우 자기 참조를 진행 중이라 dto로 만들어 반환하는 과정에 재귀적인 로직이 필요해 책임을 이전했습니다!


public PostResponseDto toPostResponseDto(Post post, User user, LikeRepository likeRepository, Type postType) {
return PostResponseDto.builder()
.id(post.getId())
.content(post.getContent())
.views(post.getViews())
.isDeleted(post.getIsDeleted())
.createdAt(post.getCreatedAt())
.user(toPostUserResponse(post.getUser()))
.likeCount(post.getLikeCount())
.isLikedByUser(isLikedByUser(post, user, likeRepository))
.postType(postType)
.myPost(isMyPost(post, user))
// .replyTo(getCustomId(post))
.images(toImageResponse(post))
.replies(toReplies(post.getReplies(), user, likeRepository, postType))
.build();
}

public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeRepository likeRepository, Type postType, Long repostingUserId) {
return ParentPostResponseDto.builder()
.id(post.getId())
.content(post.getContent())
.views(post.getViews())
.isDeleted(post.getIsDeleted())
.createdAt(post.getCreatedAt())
.user(toPostUserResponse(post.getUser()))
.likeCount(post.getLikeCount())
.isLikedByUser(isLikedByUser(post, user, likeRepository))
.repostingUserId(repostingUserId)
.postType(postType)
.myPost(isMyPost(post, user))
// .replyTo(getCustomId(post))
.images(toImageResponse(post))
.build();
}

public PostUserResponse toPostUserResponse(User user) {
return PostUserResponse.from(user);
}

public List<ImageResponse> toImageResponse(Post post) {
return post.getImages().stream()
.map(ImageResponse::from)
.toList();
}

private List<PostResponseDto> toReplies(List<Post> replies, User user, LikeRepository likeRepository, Type postType) {
return replies.stream()
.map(reply -> toPostResponseDto(reply, user, likeRepository, postType))
.collect(Collectors.toList());

}

private boolean isLikedByUser(Post post, User user, LikeRepository likeRepository) {
return likeRepository.existsByPostAndUser(post, user);
}

private boolean isMyPost(Post post, User user) {
return post.getUser().equals(user);
}

private String getCustomId(Post post) {
if(post.getParent() == null){
return null;
}
return post.getParent().getUser().getCustomId();
}

}

This file was deleted.

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

import com.leets.X.domain.post.domain.Post;
import com.leets.X.domain.image.dto.response.ImageResponse;
import com.leets.X.domain.post.domain.enums.IsDeleted;
import com.leets.X.domain.user.domain.User;
import com.leets.X.domain.post.domain.enums.Type;
import lombok.Builder;

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

@Builder
public record ParentPostResponseDto(
Long id,
String content,
Expand All @@ -17,30 +17,12 @@ public record ParentPostResponseDto(
LocalDateTime createdAt,
PostUserResponse user,
Long likeCount,
Long repostingUserId,
Type postType,
Boolean myPost,
Boolean isLikedByUser,
List<ImageResponseDto> images
// String replyTo,
List<ImageResponse> images
) {
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 변환
post.getLikesCount(),
isLikedByUser, // 좋아요 여부 설정
convertImagesToDtoList(post) // Images 변환
);
}

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();
}
}
Loading
Loading