From a7236fde562f3304d00e17bcff33fb4b72030b3c Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:13:01 +0900 Subject: [PATCH 01/27] =?UTF-8?q?feat:=20repost=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/post/service/RepostService.java | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/main/java/com/leets/X/domain/post/service/RepostService.java diff --git a/src/main/java/com/leets/X/domain/post/service/RepostService.java b/src/main/java/com/leets/X/domain/post/service/RepostService.java new file mode 100644 index 0000000..9140bf3 --- /dev/null +++ b/src/main/java/com/leets/X/domain/post/service/RepostService.java @@ -0,0 +1,120 @@ +package com.leets.X.domain.post.service; + +import com.leets.X.domain.follow.domain.Follow; +import com.leets.X.domain.post.domain.Post; +import com.leets.X.domain.post.domain.Repost; +import com.leets.X.domain.post.domain.enums.Status; +import com.leets.X.domain.post.dto.response.PostResponseDto; +import com.leets.X.domain.post.exception.AlreadyRepostException; +import com.leets.X.domain.post.repository.PostRepository; +import com.leets.X.domain.post.repository.RepostRepository; +import com.leets.X.domain.user.domain.User; +import com.leets.X.domain.user.service.UserService; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class RepostService { + private final RepostRepository repostRepository; + private final PostRepository postRepository; + private final PostService postService; + private final UserService userService; + + @Transactional + public void rePost(Long postId, String email) { + User user = userService.find(email); + Post post = postService.findPost(postId); + + check(user.getId(), post.getId()); + + Repost repost = repostRepository.save(Repost.of(user, post)); + user.addRepost(repost); + } + + public List getPosts(String email) { + User user = userService.find(email); + + // 자신의 게시물과 리포스트 가져오기 + List myPosts = getUserPosts(user, true); + List myReposts = getUserReposts(user, true); + + // 팔로잉한 사용자들의 게시물과 리포스트 가져오기 + List followingPosts = getFollowingUsersPosts(user); + List followingReposts = getFollowingUsersReposts(user); + + // 모든 게시물 합치고 정렬 + List allPosts = mergeAndSortPosts(myPosts, myReposts, followingPosts, followingReposts); + + return allPosts; + } + + public List getUserFeed(Long userId) { + User user = userService.find(userId); + + // 해당 사용자의 게시물과 리포스트 가져오기 + List userPosts = getUserPosts(user, false); + List userReposts = getUserReposts(user, false); + + // 모든 게시물 합치고 정렬 + List allPosts = mergeAndSortPosts(userPosts, userReposts); + + return allPosts; + } + + private void check(Long userId, Long postId){ + if(repostRepository.existsByUserIdAndPostId(userId, postId)) { + throw new AlreadyRepostException(); + } + } + + // 사용자 자신의 게시물을 가져오는 메서드 + private List getUserPosts(User user, boolean isOwner) { + return user.getPosts().stream() + .map(post -> PostResponseDto.from(post, Status.POST, isOwner)) + .collect(Collectors.toList()); + } + + // 사용자 자신의 리포스트를 가져오는 메서드 + private List getUserReposts(User user, boolean isOwner) { + return user.getReposts().stream() + .map(repost -> PostResponseDto.from(repost.getPost(), Status.REPOST, isOwner)) + .collect(Collectors.toList()); + } + + // 팔로잉한 사용자들의 게시물을 가져오는 메서드 + private List getFollowingUsersPosts(User user) { + return user.getFollowingList().stream() + .map(Follow::getFollowed) + .flatMap(followedUser -> followedUser.getPosts().stream()) + .map(post -> PostResponseDto.from(post, Status.POST, false)) + .collect(Collectors.toList()); + } + + // 팔로잉한 사용자들의 리포스트를 가져오는 메서드 + private List getFollowingUsersReposts(User user) { + return user.getFollowingList().stream() + .map(Follow::getFollowed) + .flatMap(followedUser -> followedUser.getReposts().stream()) + .map(repost -> PostResponseDto.from(repost.getPost(), Status.REPOST, false)) + .collect(Collectors.toList()); + } + + // 여러 리스트의 게시물을 합치고 정렬하는 메서드 + private List mergeAndSortPosts(List... postLists) { + List allPosts = new ArrayList<>(); + for (List posts : postLists) { + allPosts.addAll(posts); + } + return allPosts.stream() + .sorted(Comparator.comparing(PostResponseDto::getCreatedAt).reversed()) + .collect(Collectors.toList()); + } + +} From 8021d849b1b996025f78e82076f304293b6d60fc Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:13:23 +0900 Subject: [PATCH 02/27] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=20=EB=A6=AC?= =?UTF-8?q?=ED=8F=AC=EC=8A=A4=ED=8A=B8=20=ED=95=9C=20=EA=B8=80=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=98=88=EC=99=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/exception/AlreadyRepostException.java | 16 ++++++++++++++++ .../X/domain/post/exception/ErrorMessage.java | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leets/X/domain/post/exception/AlreadyRepostException.java diff --git a/src/main/java/com/leets/X/domain/post/exception/AlreadyRepostException.java b/src/main/java/com/leets/X/domain/post/exception/AlreadyRepostException.java new file mode 100644 index 0000000..e41077e --- /dev/null +++ b/src/main/java/com/leets/X/domain/post/exception/AlreadyRepostException.java @@ -0,0 +1,16 @@ +package com.leets.X.domain.post.exception; + +import com.leets.X.global.common.exception.BaseException; + +import static com.leets.X.domain.post.exception.ErrorMessage.ALREADY_REPOST; + +public class AlreadyRepostException extends BaseException { + + public AlreadyRepostException() { + super(ALREADY_REPOST.getCode(), ALREADY_REPOST.getMessage()); + } + + + + +} diff --git a/src/main/java/com/leets/X/domain/post/exception/ErrorMessage.java b/src/main/java/com/leets/X/domain/post/exception/ErrorMessage.java index f70d6b5..fe57d0b 100644 --- a/src/main/java/com/leets/X/domain/post/exception/ErrorMessage.java +++ b/src/main/java/com/leets/X/domain/post/exception/ErrorMessage.java @@ -10,7 +10,8 @@ public enum ErrorMessage { POST_NOT_FOUND(404, "존재하지 않는 게시글입니다."), UNAUTHORIZED_POST_DELETION(403, "게시물을 삭제할 권한이 없습니다."), ALREADY_LIKED(400, "이미 좋아요를 누른 게시물입니다."), - NOT_LIKED(400, "좋아요가 눌려 있지 않은 게시물입니다."); + NOT_LIKED(400, "좋아요가 눌려 있지 않은 게시물입니다."), + ALREADY_REPOST(400, "이미 repost 한 게시물입니다."); private final int code; private final String message; From 0683ac1c2fdb64a69644580adc8c999c06fc78f5 Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:14:02 +0900 Subject: [PATCH 03/27] =?UTF-8?q?feat:=20=EB=A6=AC=ED=8F=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leets/X/domain/post/domain/Repost.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/com/leets/X/domain/post/domain/Repost.java diff --git a/src/main/java/com/leets/X/domain/post/domain/Repost.java b/src/main/java/com/leets/X/domain/post/domain/Repost.java new file mode 100644 index 0000000..f26d7e1 --- /dev/null +++ b/src/main/java/com/leets/X/domain/post/domain/Repost.java @@ -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(); + } +} From d1b487afa4ab7c8259d78c8cd07bb65ab040cdbf Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:14:09 +0900 Subject: [PATCH 04/27] =?UTF-8?q?feat:=20=EB=A6=AC=ED=8F=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=80=EC=9E=A5=EC=86=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leets/X/domain/post/repository/RepostRepository.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/com/leets/X/domain/post/repository/RepostRepository.java diff --git a/src/main/java/com/leets/X/domain/post/repository/RepostRepository.java b/src/main/java/com/leets/X/domain/post/repository/RepostRepository.java new file mode 100644 index 0000000..d3ace8c --- /dev/null +++ b/src/main/java/com/leets/X/domain/post/repository/RepostRepository.java @@ -0,0 +1,9 @@ +package com.leets.X.domain.post.repository; + +import com.leets.X.domain.post.domain.Repost; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RepostRepository extends JpaRepository { + boolean existsByUserIdAndPostId(Long userId, Long postId); + +} From 6bc2d261525115b6688f4ea9815b5df4d773b4e8 Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:14:44 +0900 Subject: [PATCH 05/27] =?UTF-8?q?feat:=20=ED=8F=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EA=B5=AC=EB=B6=84=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20enum=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/leets/X/domain/post/domain/enums/Type.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/com/leets/X/domain/post/domain/enums/Type.java diff --git a/src/main/java/com/leets/X/domain/post/domain/enums/Type.java b/src/main/java/com/leets/X/domain/post/domain/enums/Type.java new file mode 100644 index 0000000..5232862 --- /dev/null +++ b/src/main/java/com/leets/X/domain/post/domain/enums/Type.java @@ -0,0 +1,5 @@ +package com.leets.X.domain.post.domain.enums; + +public enum Type { + POST, REPOST +} From 7944bcef0431a11586d4f375c6cfa7f822361e6d Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:15:02 +0900 Subject: [PATCH 06/27] =?UTF-8?q?feat:=20=EB=A6=AC=ED=8F=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=96=91=EB=B0=A9=ED=96=A5=20=EB=A7=A4=ED=95=91=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/leets/X/domain/user/domain/User.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/leets/X/domain/user/domain/User.java b/src/main/java/com/leets/X/domain/user/domain/User.java index 89a3001..1a04422 100644 --- a/src/main/java/com/leets/X/domain/user/domain/User.java +++ b/src/main/java/com/leets/X/domain/user/domain/User.java @@ -3,6 +3,7 @@ import com.leets.X.domain.follow.domain.Follow; import com.leets.X.domain.like.domain.Like; import com.leets.X.domain.post.domain.Post; +import com.leets.X.domain.post.domain.Repost; import com.leets.X.domain.user.dto.request.UserInitializeRequest; import com.leets.X.domain.user.dto.request.UserUpdateRequest; import com.leets.X.global.common.domain.BaseTimeEntity; @@ -62,6 +63,9 @@ public class User extends BaseTimeEntity { @OneToMany(mappedBy = "follower", cascade = CascadeType.REMOVE, orphanRemoval = true) private List followingList = new ArrayList<>(); + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE, orphanRemoval = true) + private List reposts = new ArrayList<>(); + public void initProfile(UserInitializeRequest dto){ this.birth = dto.birth(); this.customId = dto.customId(); @@ -90,6 +94,8 @@ public void removeFollowing(Follow follow) { this.followingList.remove(follow); } - + public void addRepost(Repost repost) { + this.reposts.add(repost); + } } From 57f1c9dfb5d986790566c357e0b894e647897ac3 Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 17:15:33 +0900 Subject: [PATCH 07/27] =?UTF-8?q?refactor:=20enum=20=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/leets/X/domain/post/service/RepostService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/service/RepostService.java b/src/main/java/com/leets/X/domain/post/service/RepostService.java index 9140bf3..167bcb7 100644 --- a/src/main/java/com/leets/X/domain/post/service/RepostService.java +++ b/src/main/java/com/leets/X/domain/post/service/RepostService.java @@ -3,7 +3,7 @@ import com.leets.X.domain.follow.domain.Follow; import com.leets.X.domain.post.domain.Post; import com.leets.X.domain.post.domain.Repost; -import com.leets.X.domain.post.domain.enums.Status; +import com.leets.X.domain.post.domain.enums.Type; import com.leets.X.domain.post.dto.response.PostResponseDto; import com.leets.X.domain.post.exception.AlreadyRepostException; import com.leets.X.domain.post.repository.PostRepository; @@ -77,14 +77,14 @@ private void check(Long userId, Long postId){ // 사용자 자신의 게시물을 가져오는 메서드 private List getUserPosts(User user, boolean isOwner) { return user.getPosts().stream() - .map(post -> PostResponseDto.from(post, Status.POST, isOwner)) + .map(post -> PostResponseDto.from(post, Type.POST, isOwner)) .collect(Collectors.toList()); } // 사용자 자신의 리포스트를 가져오는 메서드 private List getUserReposts(User user, boolean isOwner) { return user.getReposts().stream() - .map(repost -> PostResponseDto.from(repost.getPost(), Status.REPOST, isOwner)) + .map(repost -> PostResponseDto.from(repost.getPost(), Type.REPOST, isOwner)) .collect(Collectors.toList()); } @@ -93,7 +93,7 @@ private List getFollowingUsersPosts(User user) { return user.getFollowingList().stream() .map(Follow::getFollowed) .flatMap(followedUser -> followedUser.getPosts().stream()) - .map(post -> PostResponseDto.from(post, Status.POST, false)) + .map(post -> PostResponseDto.from(post, Type.POST, false)) .collect(Collectors.toList()); } @@ -102,7 +102,7 @@ private List getFollowingUsersReposts(User user) { return user.getFollowingList().stream() .map(Follow::getFollowed) .flatMap(followedUser -> followedUser.getReposts().stream()) - .map(repost -> PostResponseDto.from(repost.getPost(), Status.REPOST, false)) + .map(repost -> PostResponseDto.from(repost.getPost(), Type.REPOST, false)) .collect(Collectors.toList()); } From 67e36163e5bc233fbd188bc2bd539df32d1f0a4b Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:05:10 +0900 Subject: [PATCH 08/27] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20dto=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/post/dto/response/ImageResponseDto.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/main/java/com/leets/X/domain/post/dto/response/ImageResponseDto.java diff --git a/src/main/java/com/leets/X/domain/post/dto/response/ImageResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/ImageResponseDto.java deleted file mode 100644 index 46d9266..0000000 --- a/src/main/java/com/leets/X/domain/post/dto/response/ImageResponseDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.leets.X.domain.post.dto.response; - -import com.leets.X.domain.image.domain.Image; - - -public record ImageResponseDto( - Long imageId, - String url -) { - public static ImageResponseDto from(Image image) { - return new ImageResponseDto(image.getId(), image.getUrl()); - } -} From 3f91bba48a1ea4350395410b2ba3c52b3887a4ff Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:05:39 +0900 Subject: [PATCH 09/27] =?UTF-8?q?refactor:=20=EB=A6=AC=ED=8F=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B4=80=EB=A0=A8=20=EC=A0=95=EB=B3=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/ParentPostResponseDto.java | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java index 72761dd..f7103d9 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java @@ -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, @@ -17,30 +17,12 @@ public record ParentPostResponseDto( LocalDateTime createdAt, PostUserResponse user, Long likeCount, + Long repostingUserId, + Type postType, + Boolean myPost, Boolean isLikedByUser, - List images + String replyTo, + List 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 convertImagesToDtoList(Post post) { - return post.getImages() != null ? post.getImages().stream() - .map(ImageResponseDto::from) - .collect(Collectors.toList()) : Collections.emptyList(); - } } From 5e3f77177bf4079d229ef38b83b26d09d6eab2da Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:06:09 +0900 Subject: [PATCH 10/27] =?UTF-8?q?refactor:=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=B0=8F=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=B1=85=EC=9E=84=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/dto/response/PostResponseDto.java | 64 ++----------------- 1 file changed, 6 insertions(+), 58 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java index 0aad551..d45b35e 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java @@ -2,18 +2,14 @@ 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.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 PostResponseDto( Long id, String content, @@ -23,61 +19,13 @@ public record PostResponseDto( PostUserResponse user, Long likeCount, Boolean isLikedByUser, // 좋아요 여부 확인 + Type postType, + Boolean myPost, + String replyTo, List images, List replies ) { - - public static PostResponseDto from(Post post, boolean isLikedByUser) { - return new PostResponseDto( - post.getId(), - post.getContent(), - post.getViews(), - post.getIsDeleted(), - post.getCreatedAt(), - convertUser(post.getUser()), - post.getLikesCount(), - isLikedByUser, // 서비스에서 전달된 boolean 값 사용 - convertImagesToDtoList(post), - convertRepliesToDtoList(post.getReplies()) - ); - } - - - // 좋아요 여부를 확인하기 위한 메서드 오버로딩 - 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()), - post.getLikesCount(), - isLikedByUser, // 좋아요 여부를 동적으로 설정 - convertImagesToDtoList(post), - convertRepliesToDtoList(post.getReplies()) - ); - } - - - private static List convertRepliesToDtoList(List 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 convertImagesToDtoList(Post post) { - return post.getImages().stream() - .map(ImageResponse::from) - .toList(); - } - } From 967597316d8a41c9526df203d20cd0068369463a Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:07:08 +0900 Subject: [PATCH 11/27] =?UTF-8?q?feat:=20post=20=EA=B4=80=EB=A0=A8=20dto?= =?UTF-8?q?=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8A=94=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=EB=A7=A4=ED=8D=BC=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/post/dto/mapper/PostMapper.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java diff --git a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java new file mode 100644 index 0000000..46b43b4 --- /dev/null +++ b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java @@ -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 { + + 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 toImageResponse(Post post) { + return post.getImages().stream() + .map(ImageResponse::from) + .toList(); + } + + private List toReplies(List 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(); + } + +} From ddd32f23b930c952a3bc643ca69ddca063b3eb61 Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:09:06 +0900 Subject: [PATCH 12/27] =?UTF-8?q?refactor:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=EC=97=90=20=EB=A7=9E=EB=8A=94=20API=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/controller/PostController.java | 59 +++++++++++++------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/controller/PostController.java b/src/main/java/com/leets/X/domain/post/controller/PostController.java index 6bec614..9d9fd9e 100644 --- a/src/main/java/com/leets/X/domain/post/controller/PostController.java +++ b/src/main/java/com/leets/X/domain/post/controller/PostController.java @@ -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; @@ -26,6 +27,7 @@ public class PostController { private final PostService postService; + private final RepostService repostService; // 게시물 상세 조회(자식 게시물 까지 함께 조회됨) @GetMapping("/{id}") @@ -37,37 +39,51 @@ public ResponseDto getPost(@PathVariable Long id, @Authenticati // 모든 부모게시물 조회 @GetMapping("/all") - @Operation(summary = "전체 부모 글 조회") + @Operation(summary = "[Home] 추천 게시글") public ResponseDto> getAllParentPosts(@AuthenticationPrincipal String email) { List 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> getAllUserPosts(@PathVariable Long userId) { + List posts = repostService.getUserFeed(userId); + return ResponseDto.response(ResponseMessage.GET_USER_POST.getCode(), ResponseMessage.GET_USER_POST.getMessage(), posts); + } - @GetMapping("/likes") - @Operation(summary = "좋아요 수로 정렬한 게시물 조회") - public ResponseDto> getPostsSortedByLikes(@AuthenticationPrincipal String email) { - List 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> getAllFollowingPosts(@AuthenticationPrincipal String email) { + List posts = repostService.getFollowingPost(email); + return ResponseDto.response(ResponseMessage.GET_FOLLOWING_POST.getCode(), ResponseMessage.GET_FOLLOWING_POST.getMessage(), posts); } - @GetMapping("/latest") - @Operation(summary = "최신 게시물 조회") - public ResponseDto> getLatestPosts(@AuthenticationPrincipal String email) { - List 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> getPostsSortedByLikes(@AuthenticationPrincipal String email) { +// List 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> getLatestPosts(@AuthenticationPrincipal String email) { +// List 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 createPost(@RequestPart PostRequestDTO postRequestDTO, + public ResponseDto createPost(@RequestPart PostRequestDTO postRequestDTO, @RequestPart(value = "files", required = false) List 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") @@ -79,13 +95,13 @@ public ResponseDto addLike(@PathVariable Long postId, @AuthenticationPri @PostMapping(value = "/{postId}/reply", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation(summary = "답글 생성") - public ResponseDto createReply(@PathVariable Long postId, + public ResponseDto createReply(@PathVariable Long postId, @RequestPart PostRequestDTO postRequestDTO, @RequestPart(value = "files", required = false) List 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()); } @@ -104,4 +120,11 @@ public ResponseDto cancelLike(@PathVariable Long postId, @Authentication return ResponseDto.response(ResponseMessage.LIKE_CANCEL_SUCCESS.getCode(), responseMessage); } + @PostMapping("/repost/{postId}") + @Operation(summary = "Repost 하기") + public ResponseDto repost(@PathVariable Long postId, @AuthenticationPrincipal String email) { + repostService.rePost(postId, email); + return ResponseDto.response(ResponseMessage.REPOST_SUCCESS.getCode(), ResponseMessage.REPOST_SUCCESS.getMessage()); + } + } From bda584a91ffa35bed8297173b7612a015fabfbfd Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:09:21 +0900 Subject: [PATCH 13/27] =?UTF-8?q?refactor:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=EC=97=90=20=EB=A7=9E=EB=8A=94=20API=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/post/service/PostService.java | 90 ++++++++++--------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/service/PostService.java b/src/main/java/com/leets/X/domain/post/service/PostService.java index 25f9fa4..1c8609d 100644 --- a/src/main/java/com/leets/X/domain/post/service/PostService.java +++ b/src/main/java/com/leets/X/domain/post/service/PostService.java @@ -6,6 +6,8 @@ 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.post.domain.enums.Type; +import com.leets.X.domain.post.dto.mapper.PostMapper; 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; @@ -24,7 +26,6 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; -import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -36,67 +37,71 @@ public class PostService { private final UserService userService; private final LikeRepository likeRepository; private final ImageService imageService; + private final PostMapper postMapper; - // 모든 부모 글만 조회 (자식 글 제외) + // 추천 게시글 조회. following 되지 않은 글만 반환 public List getAllParentPosts(String email) { User user = userService.find(email); + List followedUserIds = user.getFollowingList().stream() + .map(follow -> follow.getFollowed().getId()) + .toList(); + List posts = postRepository.findByParentIsNullAndIsDeletedOrderByCreatedAtDesc(IsDeleted.ACTIVE); return posts.stream() + .filter(post -> !followedUserIds.contains(post.getUser().getId())) .map(post -> { - boolean isLikedByUser = likeRepository.existsByPostAndUser(post, user); - return ParentPostResponseDto.from(post, isLikedByUser); + return postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null); }) .collect(Collectors.toList()); } - // 전체 게시물 조회 (자식 글 포함) + // 상세조회 public PostResponseDto getPostResponse(Long id, String email) { Post post = postRepository.findWithRepliesByIdAndIsDeleted(id, IsDeleted.ACTIVE) .orElseThrow(PostNotFoundException::new); User user = userService.find(email); - boolean isLikedByUser = likeRepository.existsByPostAndUser(post, user); - return PostResponseDto.from(post, isLikedByUser); + return postMapper.toPostResponseDto(post, user, likeRepository, Type.POST); } - // 좋아요 순으로 게시물 조회 - public List getPostsSortedByLikes(String email) { - User user = userService.find(email); - List posts = postRepository.findAll(); - - return posts.stream() - .filter(post -> post.getIsDeleted() == IsDeleted.ACTIVE) - .sorted(Comparator.comparing(Post::getLikesCount).reversed()) - .map(post -> { - boolean isLikedByUser = likeRepository.existsByPostAndUser(post, user); - return PostResponseDto.from(post, isLikedByUser); - }) - .collect(Collectors.toList()); - } - - // 최신 부모 글 10개 조회 (자식 글 제외) - public List getLatestParentPosts(String email) { - User user = userService.find(email); - - List posts = postRepository.findByParentIsNullAndIsDeletedOrderByCreatedAtDesc(IsDeleted.ACTIVE) - .stream() - .limit(10) - .collect(Collectors.toList()); - - return posts.stream() - .map(post -> { - boolean isLikedByUser = likeRepository.existsByPostAndUser(post, user); - return ParentPostResponseDto.from(post, isLikedByUser); - }) - .collect(Collectors.toList()); - } +// // 좋아요 순으로 게시물 조회 +// public List getPostsSortedByLikes(String email) { +// User user = userService.find(email); +// List posts = postRepository.findAll(); +// +// return posts.stream() +// .filter(post -> post.getIsDeleted() == IsDeleted.ACTIVE) +// .sorted(Comparator.comparing(Post::getLikesCount).reversed()) +// .map(post -> { +// boolean isLikedByUser = likeRepository.existsByPostAndUser(post, user); +// return PostResponseDto.from(post, isLikedByUser); +// }) +// .collect(Collectors.toList()); +// } +// +// // 최신 부모 글 10개 조회 (자식 글 제외) +// public List getLatestParentPosts(String email) { +// User user = userService.find(email); +// +// List posts = postRepository.findByParentIsNullAndIsDeletedOrderByCreatedAtDesc(IsDeleted.ACTIVE) +// .stream() +// .limit(10) +// .collect(Collectors.toList()); +// +// return posts.stream() +// .map(post -> { +// boolean isLikedByUser = likeRepository.existsByPostAndUser(post, user); +// return ParentPostResponseDto.from(post, isLikedByUser); +// }) +// .collect(Collectors.toList()); +// } // 글 생성 @Transactional - public PostResponseDto createPost(PostRequestDTO postRequestDTO,List files, String email) throws IOException { + public void createPost(PostRequestDTO postRequestDTO,List files, String email) throws IOException { User user = userService.find(email); if (user == null) { throw new UserNotFoundException(); @@ -109,8 +114,6 @@ public PostResponseDto createPost(PostRequestDTO postRequestDTO,List images = imageService.save(files, savedPost); savedPost.addImage(images); } - - return PostResponseDto.from(savedPost, false); } // 좋아요 추가 @@ -131,7 +134,7 @@ public String addLike(Long postId, String email) { // 답글 생성 @Transactional - public PostResponseDto createReply(Long parentId, PostRequestDTO postRequestDTO, List files, String email) throws IOException { + public void createReply(Long parentId, PostRequestDTO postRequestDTO, List files, String email) throws IOException { User user = userService.find(email); Post parentPost = findPost(parentId); @@ -142,8 +145,6 @@ public PostResponseDto createReply(Long parentId, PostRequestDTO postRequestDTO, List images = imageService.save(files, savedReply); savedReply.addImage(images); } - - return PostResponseDto.from(savedReply, false); } // 게시물 삭제 @@ -194,4 +195,5 @@ public PostUserResponse findUser(String email) { return PostUserResponse.from(user); } + } From 15525c049bb6e4a6d3ab7c1313d087e99d9b808d Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:09:43 +0900 Subject: [PATCH 14/27] =?UTF-8?q?refactor:=20=20repost=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/post/service/RepostService.java | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/service/RepostService.java b/src/main/java/com/leets/X/domain/post/service/RepostService.java index 167bcb7..e03e971 100644 --- a/src/main/java/com/leets/X/domain/post/service/RepostService.java +++ b/src/main/java/com/leets/X/domain/post/service/RepostService.java @@ -1,10 +1,12 @@ package com.leets.X.domain.post.service; import com.leets.X.domain.follow.domain.Follow; +import com.leets.X.domain.like.repository.LikeRepository; import com.leets.X.domain.post.domain.Post; import com.leets.X.domain.post.domain.Repost; import com.leets.X.domain.post.domain.enums.Type; -import com.leets.X.domain.post.dto.response.PostResponseDto; +import com.leets.X.domain.post.dto.mapper.PostMapper; +import com.leets.X.domain.post.dto.response.ParentPostResponseDto; import com.leets.X.domain.post.exception.AlreadyRepostException; import com.leets.X.domain.post.repository.PostRepository; import com.leets.X.domain.post.repository.RepostRepository; @@ -24,96 +26,99 @@ public class RepostService { private final RepostRepository repostRepository; private final PostRepository postRepository; + private final LikeRepository likeRepository; private final PostService postService; private final UserService userService; + private final PostMapper postMapper; @Transactional public void rePost(Long postId, String email) { User user = userService.find(email); Post post = postService.findPost(postId); - check(user.getId(), post.getId()); - Repost repost = repostRepository.save(Repost.of(user, post)); user.addRepost(repost); } - public List getPosts(String email) { + public List getFollowingPost(String email) { User user = userService.find(email); // 자신의 게시물과 리포스트 가져오기 - List myPosts = getUserPosts(user, true); - List myReposts = getUserReposts(user, true); + List myPosts = getUserPosts(user, true); + List myReposts = getUserReposts(user, true); // 팔로잉한 사용자들의 게시물과 리포스트 가져오기 - List followingPosts = getFollowingUsersPosts(user); - List followingReposts = getFollowingUsersReposts(user); + List followingPosts = getFollowingUsersPosts(user); + List followingReposts = getFollowingUsersReposts(user); // 모든 게시물 합치고 정렬 - List allPosts = mergeAndSortPosts(myPosts, myReposts, followingPosts, followingReposts); + List allPosts = mergeAndSortPosts(myPosts, myReposts, followingPosts, followingReposts); return allPosts; } - public List getUserFeed(Long userId) { + public List getUserFeed(Long userId) { User user = userService.find(userId); // 해당 사용자의 게시물과 리포스트 가져오기 - List userPosts = getUserPosts(user, false); - List userReposts = getUserReposts(user, false); + List userPosts = getUserPosts(user, false); + List userReposts = getUserReposts(user, false); // 모든 게시물 합치고 정렬 - List allPosts = mergeAndSortPosts(userPosts, userReposts); + List allPosts = mergeAndSortPosts(userPosts, userReposts); return allPosts; } + // 내 글을 리포스트 하는 것도 가능하기에 제거 private void check(Long userId, Long postId){ if(repostRepository.existsByUserIdAndPostId(userId, postId)) { throw new AlreadyRepostException(); } } - // 사용자 자신의 게시물을 가져오는 메서드 - private List getUserPosts(User user, boolean isOwner) { + // 사용자의 게시물을 가져오는 메서드 + private List getUserPosts(User user, boolean isOwner) { return user.getPosts().stream() - .map(post -> PostResponseDto.from(post, Type.POST, isOwner)) + .filter(post -> post.getParent() == null) + .map(post -> postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null)) .collect(Collectors.toList()); } - // 사용자 자신의 리포스트를 가져오는 메서드 - private List getUserReposts(User user, boolean isOwner) { + // 사용자의 리포스트를 가져오는 메서드 + private List getUserReposts(User user, boolean isOwner) { return user.getReposts().stream() - .map(repost -> PostResponseDto.from(repost.getPost(), Type.REPOST, isOwner)) + .map(repost -> postMapper.toParentPostResponseDto(repost.getPost(), user, likeRepository, Type.REPOST, repost.getUser().getId())) .collect(Collectors.toList()); } // 팔로잉한 사용자들의 게시물을 가져오는 메서드 - private List getFollowingUsersPosts(User user) { + private List getFollowingUsersPosts(User user) { return user.getFollowingList().stream() .map(Follow::getFollowed) .flatMap(followedUser -> followedUser.getPosts().stream()) - .map(post -> PostResponseDto.from(post, Type.POST, false)) + .filter(post -> post.getParent() == null) + .map(post -> postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null)) .collect(Collectors.toList()); } // 팔로잉한 사용자들의 리포스트를 가져오는 메서드 - private List getFollowingUsersReposts(User user) { + private List getFollowingUsersReposts(User user) { return user.getFollowingList().stream() .map(Follow::getFollowed) .flatMap(followedUser -> followedUser.getReposts().stream()) - .map(repost -> PostResponseDto.from(repost.getPost(), Type.REPOST, false)) + .map(repost -> postMapper.toParentPostResponseDto(repost.getPost(), user, likeRepository, Type.REPOST, repost.getUser().getId())) .collect(Collectors.toList()); } // 여러 리스트의 게시물을 합치고 정렬하는 메서드 - private List mergeAndSortPosts(List... postLists) { - List allPosts = new ArrayList<>(); - for (List posts : postLists) { + private List mergeAndSortPosts(List... postLists) { + List allPosts = new ArrayList<>(); + for (List posts : postLists) { allPosts.addAll(posts); } return allPosts.stream() - .sorted(Comparator.comparing(PostResponseDto::getCreatedAt).reversed()) + .sorted(Comparator.comparing(ParentPostResponseDto::createdAt).reversed()) .collect(Collectors.toList()); } From 6cf2a0405d1e3d014288d268a4323ffc4a150e1c Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:10:00 +0900 Subject: [PATCH 15/27] =?UTF-8?q?feat:=20=EC=9D=91=EB=8B=B5=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/leets/X/domain/post/controller/ResponseMessage.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/leets/X/domain/post/controller/ResponseMessage.java b/src/main/java/com/leets/X/domain/post/controller/ResponseMessage.java index d32c59d..6c74090 100644 --- a/src/main/java/com/leets/X/domain/post/controller/ResponseMessage.java +++ b/src/main/java/com/leets/X/domain/post/controller/ResponseMessage.java @@ -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; From ec472e6463539f22077510daacdc141cec3dc3cd Mon Sep 17 00:00:00 2001 From: hyxklee Date: Sun, 10 Nov 2024 23:29:05 +0900 Subject: [PATCH 16/27] =?UTF-8?q?refactor:=20replyTo=20=ED=95=AD=EB=AA=A9?= =?UTF-8?q?=20=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/leets/X/domain/post/dto/mapper/PostMapper.java | 4 ++-- .../X/domain/post/dto/response/ParentPostResponseDto.java | 2 +- .../com/leets/X/domain/post/dto/response/PostResponseDto.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java index 46b43b4..8e553f1 100644 --- a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java +++ b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java @@ -28,7 +28,7 @@ public PostResponseDto toPostResponseDto(Post post, User user, LikeRepository li .isLikedByUser(isLikedByUser(post, user, likeRepository)) .postType(postType) .myPost(isMyPost(post, user)) - .replyTo(getCustomId(post)) +// .replyTo(getCustomId(post)) .images(toImageResponse(post)) .replies(toReplies(post.getReplies(), user, likeRepository, postType)) .build(); @@ -47,7 +47,7 @@ public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeR .repostingUserId(repostingUserId) .postType(postType) .myPost(isMyPost(post, user)) - .replyTo(getCustomId(post)) +// .replyTo(getCustomId(post)) .images(toImageResponse(post)) .build(); } diff --git a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java index f7103d9..37ac13d 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java @@ -21,7 +21,7 @@ public record ParentPostResponseDto( Type postType, Boolean myPost, Boolean isLikedByUser, - String replyTo, +// String replyTo, List images ) { diff --git a/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java index d45b35e..45dea72 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java @@ -21,7 +21,7 @@ public record PostResponseDto( Boolean isLikedByUser, // 좋아요 여부 확인 Type postType, Boolean myPost, - String replyTo, +// String replyTo, List images, List replies ) { From b56a8b9c1f8c7bd1fd07007f5856c74b5dae72bb Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:21:25 +0900 Subject: [PATCH 17/27] =?UTF-8?q?feat:=20=EC=B5=9C=EB=8C=80=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=9A=A9=EB=9F=89=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e894830..91b55a9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,11 @@ spring: profiles: active: local + servlet: + multipart: + enabled: true + max-file-size: 10MB + max-request-size: 10MB springdoc: swagger-ui: From c0f5cb7200b48b174dac18fbd4f424a13345404d Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:21:55 +0900 Subject: [PATCH 18/27] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EB=A7=A4=ED=95=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/leets/X/domain/image/domain/Image.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/leets/X/domain/image/domain/Image.java b/src/main/java/com/leets/X/domain/image/domain/Image.java index 12ba864..ffc7470 100644 --- a/src/main/java/com/leets/X/domain/image/domain/Image.java +++ b/src/main/java/com/leets/X/domain/image/domain/Image.java @@ -2,6 +2,7 @@ import com.leets.X.domain.image.dto.request.ImageDto; import com.leets.X.domain.post.domain.Post; +import com.leets.X.domain.user.domain.User; import com.leets.X.global.common.domain.BaseTimeEntity; import jakarta.persistence.*; import lombok.*; @@ -22,6 +23,10 @@ public class Image extends BaseTimeEntity { private String url; + @OneToOne + @JoinColumn(name = "user_id") + private User user; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "post_Id") private Post post; @@ -34,5 +39,12 @@ public static Image from(ImageDto dto, Post post) { .build(); } + public static Image from(ImageDto dto, User user) { + return Image.builder() + .name(dto.name()) + .url(dto.url()) + .user(user) + .build(); + } } From 6fede45d6119842d323f62d21de5d0bdeb4ca06f Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:22:14 +0900 Subject: [PATCH 19/27] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=82=AC=EC=A0=84=201=EA=B0=9C=20=EC=94=A9=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=ED=95=98=EB=8A=94=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/image/service/ImageService.java | 7 ++++ .../image/service/ImageUploadService.java | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/main/java/com/leets/X/domain/image/service/ImageService.java b/src/main/java/com/leets/X/domain/image/service/ImageService.java index ad7cf2c..8e60931 100644 --- a/src/main/java/com/leets/X/domain/image/service/ImageService.java +++ b/src/main/java/com/leets/X/domain/image/service/ImageService.java @@ -4,6 +4,7 @@ import com.leets.X.domain.image.dto.request.ImageDto; import com.leets.X.domain.image.repository.ImageRepository; import com.leets.X.domain.post.domain.Post; +import com.leets.X.domain.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,4 +31,10 @@ public List save(List file, Post post) throws IOException return imageRepository.saveAll(imageList); } + @Transactional + public Image save(MultipartFile image, User user) throws IOException { + ImageDto imageDto = imageUploadService.uploadImage(image); + return imageRepository.save(Image.from(imageDto, user)); + } + } diff --git a/src/main/java/com/leets/X/domain/image/service/ImageUploadService.java b/src/main/java/com/leets/X/domain/image/service/ImageUploadService.java index eba5bc8..b061c9a 100644 --- a/src/main/java/com/leets/X/domain/image/service/ImageUploadService.java +++ b/src/main/java/com/leets/X/domain/image/service/ImageUploadService.java @@ -63,6 +63,39 @@ public List uploadImages(List files) throws IOException return images; } + + public ImageDto uploadImage(MultipartFile image) throws IOException { + + String originalName = image.getOriginalFilename(); + String fileName = generateFileName(originalName); + + try { + // PutObjectRequest 생성 및 설정 + PutObjectRequest putObjectRequest = PutObjectRequest.builder() + .bucket(bucketName) + .key(fileName) + .contentType(image.getContentType()) + .build(); + + // S3에 파일 업로드 + PutObjectResponse response = s3Client.putObject( + putObjectRequest, + RequestBody.fromInputStream(image.getInputStream(), image.getSize()) + ); + + // 업로드 성공 여부 확인 + if (response.sdkHttpResponse().isSuccessful()) { + // 업로드된 파일의 URL을 ImageDto로 추가 + return ImageDto.of(originalName, generateFileUrl(fileName)); + } else { + throw new S3UploadException(); + } + } catch (S3Exception e) { + throw new S3UploadException(); + } + } + + // S3에 저장된 파일 URL 생성 private String generateFileUrl(String fileName) { return String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, fileName); From 2ddee1830f663fbcae5581979a133cdfe01d692a Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:22:25 +0900 Subject: [PATCH 20/27] =?UTF-8?q?feat:=20image=EC=99=80=20=EB=A7=A4?= =?UTF-8?q?=ED=95=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/leets/X/domain/user/domain/User.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/leets/X/domain/user/domain/User.java b/src/main/java/com/leets/X/domain/user/domain/User.java index 24e1f44..7da6d64 100644 --- a/src/main/java/com/leets/X/domain/user/domain/User.java +++ b/src/main/java/com/leets/X/domain/user/domain/User.java @@ -1,6 +1,7 @@ package com.leets.X.domain.user.domain; import com.leets.X.domain.follow.domain.Follow; +import com.leets.X.domain.image.domain.Image; import com.leets.X.domain.like.domain.Like; import com.leets.X.domain.post.domain.Post; import com.leets.X.domain.user.dto.request.UserInitializeRequest; @@ -53,6 +54,9 @@ public class User extends BaseTimeEntity { private long followingCount = 0L; + @OneToOne(mappedBy = "user") + private Image image; + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE, orphanRemoval = true) private List posts = new ArrayList<>(); @@ -70,11 +74,12 @@ public void initProfile(UserInitializeRequest dto){ this.customId = dto.customId(); } - public void update(UserUpdateRequest dto){ + public void update(UserUpdateRequest dto, Image image){ this.name = dto.name(); this.introduce = dto.introduce(); this.location = dto.location(); this.webSite = dto.webSite(); + this.image = image; } public void addFollower(Follow follow) { From b2cf446b19802a25b46788bccd8ed06dfc7a221d Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:39:03 +0900 Subject: [PATCH 21/27] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leets/X/domain/image/domain/Image.java | 5 ++++ .../X/domain/image/service/ImageService.java | 9 ++++++ .../X/domain/user/service/UserService.java | 30 ++++++++++++++++--- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/leets/X/domain/image/domain/Image.java b/src/main/java/com/leets/X/domain/image/domain/Image.java index ffc7470..6a9c054 100644 --- a/src/main/java/com/leets/X/domain/image/domain/Image.java +++ b/src/main/java/com/leets/X/domain/image/domain/Image.java @@ -47,4 +47,9 @@ public static Image from(ImageDto dto, User user) { .build(); } + public void update(ImageDto dto) { + this.name = dto.name(); + this.url = dto.url(); + } + } diff --git a/src/main/java/com/leets/X/domain/image/service/ImageService.java b/src/main/java/com/leets/X/domain/image/service/ImageService.java index 8e60931..4c98498 100644 --- a/src/main/java/com/leets/X/domain/image/service/ImageService.java +++ b/src/main/java/com/leets/X/domain/image/service/ImageService.java @@ -37,4 +37,13 @@ public Image save(MultipartFile image, User user) throws IOException { return imageRepository.save(Image.from(imageDto, user)); } + public ImageDto getImage(MultipartFile image) throws IOException { + return imageUploadService.uploadImage(image); + } + + @Transactional + public void delete(Image image) { + imageRepository.delete(image); + } + } diff --git a/src/main/java/com/leets/X/domain/user/service/UserService.java b/src/main/java/com/leets/X/domain/user/service/UserService.java index 88f7966..6045138 100644 --- a/src/main/java/com/leets/X/domain/user/service/UserService.java +++ b/src/main/java/com/leets/X/domain/user/service/UserService.java @@ -1,6 +1,9 @@ package com.leets.X.domain.user.service; import com.leets.X.domain.follow.domain.Follow; +import com.leets.X.domain.image.domain.Image; +import com.leets.X.domain.image.dto.request.ImageDto; +import com.leets.X.domain.image.service.ImageService; import com.leets.X.domain.user.domain.User; import com.leets.X.domain.user.dto.request.UserInitializeRequest; import com.leets.X.domain.user.dto.request.UserUpdateRequest; @@ -17,7 +20,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; import java.util.List; import static com.leets.X.domain.user.domain.enums.LoginStatus.LOGIN; @@ -29,6 +34,7 @@ public class UserService { private final AuthService authService; + private final ImageService imageService; private final JwtProvider jwtProvider; private final UserRepository userRepository; @@ -64,10 +70,18 @@ public void initProfile(UserInitializeRequest dto, String email){ * 프로필 수정 */ @Transactional - public void updateProfile(UserUpdateRequest dto, String email){ + public void updateProfile(UserUpdateRequest dto, MultipartFile image, String email) throws IOException { User user = find(email); - - user.update(dto); + Image savedImage = user.getImage(); + // 이미지가 없다면 새로 생성해서 저장 + if(savedImage== null){ + savedImage = imageService.save(image, user); + } else if (image != null) { + ImageDto imageDto = imageService.getImage(image); + savedImage.update(imageDto); + } + // 기존 이미지가 있다면 ImageDto를 생성해서 기존 이미지를 업데이트 + user.update(dto, savedImage); } public UserProfileResponse getProfile(Long userId, String email){ @@ -75,7 +89,7 @@ public UserProfileResponse getProfile(Long userId, String email){ .orElseThrow(UserNotFoundException::new); boolean isMyProfile = user.getEmail().equals(email); boolean isFollowing = checkFollowing(user, email); - return UserProfileResponse.from(user, isMyProfile, isFollowing); + return UserProfileResponse.from(user, isMyProfile, isFollowing, getImage(user)); } // // @Transactional @@ -116,6 +130,14 @@ private boolean checkFollowing(User target, String email){ .anyMatch(follow -> follow.getFollower().getId().equals(source.getId())); } + private ImageDto getImage(User user){ + if(user.getImage() != null){ + Image image = user.getImage(); + return ImageDto.of(image.getName(), image.getUrl()); + } + return null; + } + /* * userRepository에서 사용자를 검색하는 메서드 * 공통으로 사용되는 부분이 많기 때문에 별도로 분리 From 7a7c6e8be44811cc9adeb4b6a7433570c057ad38 Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:39:21 +0900 Subject: [PATCH 22/27] =?UTF-8?q?feat:=20multiPartForm=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/user/controller/UserController.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/leets/X/domain/user/controller/UserController.java b/src/main/java/com/leets/X/domain/user/controller/UserController.java index b021151..3bd8a9d 100644 --- a/src/main/java/com/leets/X/domain/user/controller/UserController.java +++ b/src/main/java/com/leets/X/domain/user/controller/UserController.java @@ -1,11 +1,11 @@ package com.leets.X.domain.user.controller; +import com.leets.X.domain.user.domain.enums.LoginStatus; import com.leets.X.domain.user.dto.request.UserInitializeRequest; import com.leets.X.domain.user.dto.request.UserSocialLoginRequest; import com.leets.X.domain.user.dto.request.UserUpdateRequest; import com.leets.X.domain.user.dto.response.UserProfileResponse; import com.leets.X.domain.user.dto.response.UserSocialLoginResponse; -import com.leets.X.domain.user.domain.enums.LoginStatus; import com.leets.X.domain.user.service.UserService; import com.leets.X.global.common.response.ResponseDto; import io.swagger.v3.oas.annotations.Operation; @@ -13,8 +13,12 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; import static com.leets.X.domain.user.controller.ResponseMessage.*; @@ -55,10 +59,12 @@ public ResponseDto getUserProfile(@PathVariable Long userId return ResponseDto.response(GET_PROFILE_SUCCESS.getCode(), GET_PROFILE_SUCCESS.getMessage(), userService.getProfile(userId, email)); } - @PatchMapping("/profile") + @PatchMapping(value="/profile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation(summary = "유저 프로필 수정") - public ResponseDto updateProfile(@RequestBody @Valid UserUpdateRequest request, @AuthenticationPrincipal @Parameter(hidden = true) String email){ - userService.updateProfile(request, email); + public ResponseDto updateProfile(@RequestPart @Valid UserUpdateRequest request, + @RequestPart(value = "image", required = false) MultipartFile image, + @AuthenticationPrincipal @Parameter(hidden = true) String email) throws IOException { + userService.updateProfile(request, image, email); return ResponseDto.response(PROFILE_UPDATE_SUCCESS.getCode(), PROFILE_UPDATE_SUCCESS.getMessage()); } From 8eede992c50381ed8a437648e558d25410bedcae Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:39:40 +0900 Subject: [PATCH 23/27] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20image=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../X/domain/user/dto/response/UserProfileResponse.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/leets/X/domain/user/dto/response/UserProfileResponse.java b/src/main/java/com/leets/X/domain/user/dto/response/UserProfileResponse.java index 8352d48..eb2d74f 100644 --- a/src/main/java/com/leets/X/domain/user/dto/response/UserProfileResponse.java +++ b/src/main/java/com/leets/X/domain/user/dto/response/UserProfileResponse.java @@ -1,5 +1,6 @@ package com.leets.X.domain.user.dto.response; +import com.leets.X.domain.image.dto.request.ImageDto; import com.leets.X.domain.user.domain.User; import lombok.Builder; @@ -16,10 +17,11 @@ public record UserProfileResponse( Long followingCount, Boolean isFollowing, LocalDateTime createdAt, - LocalDateTime updatedAt + LocalDateTime updatedAt, + ImageDto profileImage ) { // 정적 팩토리 메서드 - public static UserProfileResponse from(User user, Boolean isMyProfile, Boolean isFollowing) { + public static UserProfileResponse from(User user, Boolean isMyProfile, Boolean isFollowing, ImageDto image) { return UserProfileResponse.builder() .userId(user.getId()) .isMyProfile(isMyProfile) @@ -31,6 +33,7 @@ public static UserProfileResponse from(User user, Boolean isMyProfile, Boolean i .isFollowing(isFollowing) .createdAt(user.getCreatedAt()) .updatedAt(user.getUpdatedAt()) + .profileImage(image) .build(); } } From 660c8acd2d773b91e467152ddb4d574442d9555c Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 22:55:45 +0900 Subject: [PATCH 24/27] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EC=9E=91=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=ED=95=A8=EA=BB=98=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/leets/X/domain/post/dto/mapper/PostMapper.java | 9 ++++++++- .../X/domain/post/dto/response/PostUserResponse.java | 10 +++++++--- .../com/leets/X/domain/post/service/PostService.java | 9 ++++----- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java index 8e553f1..0b8dddd 100644 --- a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java +++ b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java @@ -1,5 +1,7 @@ package com.leets.X.domain.post.dto.mapper; +import com.leets.X.domain.image.domain.Image; +import com.leets.X.domain.image.dto.request.ImageDto; 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; @@ -53,7 +55,12 @@ public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeR } public PostUserResponse toPostUserResponse(User user) { - return PostUserResponse.from(user); + ImageDto dto = null; + Image image = user.getImage(); + if(image != null){ + dto = ImageDto.of(image.getName(), image.getUrl()); + } + return PostUserResponse.from(user, dto); } public List toImageResponse(Post post) { diff --git a/src/main/java/com/leets/X/domain/post/dto/response/PostUserResponse.java b/src/main/java/com/leets/X/domain/post/dto/response/PostUserResponse.java index 9e303fb..5b59bc6 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/PostUserResponse.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/PostUserResponse.java @@ -1,18 +1,22 @@ package com.leets.X.domain.post.dto.response; +import com.leets.X.domain.image.dto.request.ImageDto; import com.leets.X.domain.user.domain.User; public record PostUserResponse( Long userId, String name, - String customId + String customId, + ImageDto profileImage + ) { - public static PostUserResponse from(User user) { + public static PostUserResponse from(User user, ImageDto profileImage) { return new PostUserResponse( user.getId(), user.getName(), - user.getCustomId() + user.getCustomId(), + profileImage ); } } diff --git a/src/main/java/com/leets/X/domain/post/service/PostService.java b/src/main/java/com/leets/X/domain/post/service/PostService.java index 1c8609d..4c9652f 100644 --- a/src/main/java/com/leets/X/domain/post/service/PostService.java +++ b/src/main/java/com/leets/X/domain/post/service/PostService.java @@ -11,7 +11,6 @@ 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.dto.response.PostUserResponse; import com.leets.X.domain.post.exception.AlreadyLikedException; import com.leets.X.domain.post.exception.NotLikedException; import com.leets.X.domain.post.exception.PostNotFoundException; @@ -190,10 +189,10 @@ public Post findPost(Long postId) { .orElseThrow(PostNotFoundException::new); } - public PostUserResponse findUser(String email) { - User user = userService.find(email); - return PostUserResponse.from(user); - } +// public PostUserResponse findUser(String email) { +// User user = userService.find(email); +// return PostUserResponse.from(user); +// } } From 518798c708248d1389893ac1b7a90cf3888a347c Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 23:29:34 +0900 Subject: [PATCH 25/27] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20reply=20count,=20repost=20coun?= =?UTF-8?q?t=EB=A5=BC=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/leets/X/domain/post/domain/Post.java | 24 +++++++++++++++++++ .../X/domain/post/dto/mapper/PostMapper.java | 4 ++++ .../dto/response/ParentPostResponseDto.java | 2 ++ .../post/dto/response/PostResponseDto.java | 2 ++ .../X/domain/post/service/PostService.java | 3 +++ .../X/domain/post/service/RepostService.java | 1 + 6 files changed, 36 insertions(+) diff --git a/src/main/java/com/leets/X/domain/post/domain/Post.java b/src/main/java/com/leets/X/domain/post/domain/Post.java index 9721497..d16ebe1 100644 --- a/src/main/java/com/leets/X/domain/post/domain/Post.java +++ b/src/main/java/com/leets/X/domain/post/domain/Post.java @@ -48,10 +48,15 @@ public class Post extends BaseTimeEntity { private Integer views; + @Enumerated(EnumType.STRING) private IsDeleted isDeleted; private LocalDateTime deletedAt; + private Long replyCount; + + private Long repostCount; + // 좋아요 수를 관리하기 위한 필드 @Column(name = "like_count") @@ -111,5 +116,24 @@ public static Post create(User user, String content, Post parent) { public void addImage(List images) { this.images.addAll(images); // 기존 리스트에 이미지 추가 } + + public void increaseReplyCount() { + this.replyCount++; + } + + public void decreaseReplyCount() { + if(this.replyCount > 0L) { + this.replyCount--; + } + } + + public void increaseRepostCount(){ + this.repostCount++; + } + public void decreaseRepostCount() { + if(this.repostCount > 0L) { + this.repostCount--; + } + } } diff --git a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java index 0b8dddd..e834abe 100644 --- a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java +++ b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java @@ -26,6 +26,8 @@ public PostResponseDto toPostResponseDto(Post post, User user, LikeRepository li .isDeleted(post.getIsDeleted()) .createdAt(post.getCreatedAt()) .user(toPostUserResponse(post.getUser())) + .replyCount(post.getReplyCount()) + .repostCount(post.getRepostCount()) .likeCount(post.getLikeCount()) .isLikedByUser(isLikedByUser(post, user, likeRepository)) .postType(postType) @@ -44,6 +46,8 @@ public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeR .isDeleted(post.getIsDeleted()) .createdAt(post.getCreatedAt()) .user(toPostUserResponse(post.getUser())) + .replyCount(post.getReplyCount()) + .repostCount(post.getRepostCount()) .likeCount(post.getLikeCount()) .isLikedByUser(isLikedByUser(post, user, likeRepository)) .repostingUserId(repostingUserId) diff --git a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java index 37ac13d..ae86c4e 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java @@ -16,6 +16,8 @@ public record ParentPostResponseDto( IsDeleted isDeleted, LocalDateTime createdAt, PostUserResponse user, + Long replyCount, + Long repostCount, Long likeCount, Long repostingUserId, Type postType, diff --git a/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java index 45dea72..b078424 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/PostResponseDto.java @@ -17,6 +17,8 @@ public record PostResponseDto( IsDeleted isDeleted, LocalDateTime createdAt, PostUserResponse user, + Long replyCount, + Long repostCount, Long likeCount, Boolean isLikedByUser, // 좋아요 여부 확인 Type postType, diff --git a/src/main/java/com/leets/X/domain/post/service/PostService.java b/src/main/java/com/leets/X/domain/post/service/PostService.java index 4c9652f..a4123b7 100644 --- a/src/main/java/com/leets/X/domain/post/service/PostService.java +++ b/src/main/java/com/leets/X/domain/post/service/PostService.java @@ -140,6 +140,8 @@ public void createReply(Long parentId, PostRequestDTO postRequestDTO, List images = imageService.save(files, savedReply); savedReply.addImage(images); @@ -158,6 +160,7 @@ public void deletePost(Long postId, String email) { } post.delete(); + post.getParent().decreaseReplyCount(); } // 좋아요 취소 diff --git a/src/main/java/com/leets/X/domain/post/service/RepostService.java b/src/main/java/com/leets/X/domain/post/service/RepostService.java index e03e971..423e6f9 100644 --- a/src/main/java/com/leets/X/domain/post/service/RepostService.java +++ b/src/main/java/com/leets/X/domain/post/service/RepostService.java @@ -38,6 +38,7 @@ public void rePost(Long postId, String email) { Repost repost = repostRepository.save(Repost.of(user, post)); user.addRepost(repost); + post.increaseReplyCount(); } public List getFollowingPost(String email) { From 85fce009468e77bca7fbfedd213d4becfc7dd2c2 Mon Sep 17 00:00:00 2001 From: hyxklee Date: Mon, 11 Nov 2024 23:39:58 +0900 Subject: [PATCH 26/27] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20repost=ED=95=9C=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EC=9D=98=20name=EB=8F=84=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/leets/X/domain/post/dto/mapper/PostMapper.java | 3 ++- .../X/domain/post/dto/response/ParentPostResponseDto.java | 1 + .../java/com/leets/X/domain/post/service/PostService.java | 2 +- .../com/leets/X/domain/post/service/RepostService.java | 8 ++++---- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java index e834abe..247e258 100644 --- a/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java +++ b/src/main/java/com/leets/X/domain/post/dto/mapper/PostMapper.java @@ -38,7 +38,7 @@ public PostResponseDto toPostResponseDto(Post post, User user, LikeRepository li .build(); } - public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeRepository likeRepository, Type postType, Long repostingUserId) { + public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeRepository likeRepository, Type postType, Long repostingUserId, String reposingUserName) { return ParentPostResponseDto.builder() .id(post.getId()) .content(post.getContent()) @@ -50,6 +50,7 @@ public ParentPostResponseDto toParentPostResponseDto(Post post, User user, LikeR .repostCount(post.getRepostCount()) .likeCount(post.getLikeCount()) .isLikedByUser(isLikedByUser(post, user, likeRepository)) + .repostingUserName(reposingUserName) .repostingUserId(repostingUserId) .postType(postType) .myPost(isMyPost(post, user)) diff --git a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java index ae86c4e..828363e 100644 --- a/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java +++ b/src/main/java/com/leets/X/domain/post/dto/response/ParentPostResponseDto.java @@ -19,6 +19,7 @@ public record ParentPostResponseDto( Long replyCount, Long repostCount, Long likeCount, + String repostingUserName, Long repostingUserId, Type postType, Boolean myPost, diff --git a/src/main/java/com/leets/X/domain/post/service/PostService.java b/src/main/java/com/leets/X/domain/post/service/PostService.java index a4123b7..ceab5db 100644 --- a/src/main/java/com/leets/X/domain/post/service/PostService.java +++ b/src/main/java/com/leets/X/domain/post/service/PostService.java @@ -51,7 +51,7 @@ public List getAllParentPosts(String email) { return posts.stream() .filter(post -> !followedUserIds.contains(post.getUser().getId())) .map(post -> { - return postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null); + return postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null, null); }) .collect(Collectors.toList()); } diff --git a/src/main/java/com/leets/X/domain/post/service/RepostService.java b/src/main/java/com/leets/X/domain/post/service/RepostService.java index 423e6f9..0e52367 100644 --- a/src/main/java/com/leets/X/domain/post/service/RepostService.java +++ b/src/main/java/com/leets/X/domain/post/service/RepostService.java @@ -82,14 +82,14 @@ private void check(Long userId, Long postId){ private List getUserPosts(User user, boolean isOwner) { return user.getPosts().stream() .filter(post -> post.getParent() == null) - .map(post -> postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null)) + .map(post -> postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null, null)) .collect(Collectors.toList()); } // 사용자의 리포스트를 가져오는 메서드 private List getUserReposts(User user, boolean isOwner) { return user.getReposts().stream() - .map(repost -> postMapper.toParentPostResponseDto(repost.getPost(), user, likeRepository, Type.REPOST, repost.getUser().getId())) + .map(repost -> postMapper.toParentPostResponseDto(repost.getPost(), user, likeRepository, Type.REPOST, repost.getUser().getId(), repost.getUser().getName())) .collect(Collectors.toList()); } @@ -99,7 +99,7 @@ private List getFollowingUsersPosts(User user) { .map(Follow::getFollowed) .flatMap(followedUser -> followedUser.getPosts().stream()) .filter(post -> post.getParent() == null) - .map(post -> postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null)) + .map(post -> postMapper.toParentPostResponseDto(post, user, likeRepository, Type.POST, null, null)) .collect(Collectors.toList()); } @@ -108,7 +108,7 @@ private List getFollowingUsersReposts(User user) { return user.getFollowingList().stream() .map(Follow::getFollowed) .flatMap(followedUser -> followedUser.getReposts().stream()) - .map(repost -> postMapper.toParentPostResponseDto(repost.getPost(), user, likeRepository, Type.REPOST, repost.getUser().getId())) + .map(repost -> postMapper.toParentPostResponseDto(repost.getPost(), user, likeRepository, Type.REPOST, repost.getUser().getId(), repost.getUser().getName())) .collect(Collectors.toList()); } From fab2a6f2dd2061846d0e48d19f3c86b7ea9557de Mon Sep 17 00:00:00 2001 From: hyxklee Date: Tue, 12 Nov 2024 00:27:10 +0900 Subject: [PATCH 27/27] =?UTF-8?q?HOTFIX:=20post=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=8B=9C=200=EC=9C=BC=EB=A1=9C=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/leets/X/domain/post/domain/Post.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/leets/X/domain/post/domain/Post.java b/src/main/java/com/leets/X/domain/post/domain/Post.java index d16ebe1..f06454f 100644 --- a/src/main/java/com/leets/X/domain/post/domain/Post.java +++ b/src/main/java/com/leets/X/domain/post/domain/Post.java @@ -62,6 +62,13 @@ public class Post extends BaseTimeEntity { @Column(name = "like_count") private Long likeCount = 0L; // 기본값을 0L로 초기화하여 null을 방지 + @PrePersist + public void init() { + replyCount = 0L; + repostCount = 0L; + likeCount = 0L; + } + public void updateLikeCount(long newLikeCount) { this.likeCount = newLikeCount; }