diff --git a/src/main/java/treehouse/server/api/comment/business/CommentMapper.java b/src/main/java/treehouse/server/api/comment/business/CommentMapper.java index 8b6148a..975928a 100644 --- a/src/main/java/treehouse/server/api/comment/business/CommentMapper.java +++ b/src/main/java/treehouse/server/api/comment/business/CommentMapper.java @@ -3,6 +3,7 @@ import treehouse.server.api.comment.presentation.dto.CommentResponseDTO; import treehouse.server.api.member.business.MemberMapper; import treehouse.server.api.reaction.presentation.dto.ReactionResponseDTO; +import treehouse.server.global.common.util.TimeFormatter; import treehouse.server.global.entity.comment.Comment; import treehouse.server.global.entity.comment.CommentType; import treehouse.server.global.entity.member.Member; @@ -16,7 +17,7 @@ public class CommentMapper { public static CommentResponseDTO.CommentInfoDto toCommentInfoDto(Comment comment, ReactionResponseDTO.getReactionList reactionList, List replyInfoDtoList) { return CommentResponseDTO.CommentInfoDto.builder() - .commentedAt(comment.getCreatedAt().toString()) + .commentedAt(TimeFormatter.format(comment.getCreatedAt())) .commentId(comment.getId()) .context(comment.getContent()) .reactionList(reactionList) @@ -28,7 +29,7 @@ public static CommentResponseDTO.CommentInfoDto toCommentInfoDto(Comment comment public static CommentResponseDTO.ReplyInfoDto toReplyInfoDto(Comment comment, ReactionResponseDTO.getReactionList reactionList) { return CommentResponseDTO.ReplyInfoDto.builder() - .commentedAt(comment.getCreatedAt().toString()) + .commentedAt(TimeFormatter.format(comment.getCreatedAt())) .commentId(comment.getId()) .context(comment.getContent()) .reactionList(reactionList) diff --git a/src/main/java/treehouse/server/api/comment/business/CommentService.java b/src/main/java/treehouse/server/api/comment/business/CommentService.java index 06f8699..1ad8cd7 100644 --- a/src/main/java/treehouse/server/api/comment/business/CommentService.java +++ b/src/main/java/treehouse/server/api/comment/business/CommentService.java @@ -116,13 +116,8 @@ public CommentResponseDTO.CommentListDto getCommentResponseList(User user, Long )); ReactionResponseDTO.getReactionList reactionDtoList = ReactionMapper.toGetReactionList(reactionMap); - // 여기서 comment 에 대한 reply 목록을 조회해서 List 를 만든 다음, mapper에 매개변수로 넣고, mapper 코드 업데이트 하자. - - // 1. queryAdapter 에 parentId 가지고 childList 조회하는 메서드 만들기 List childCommentList = commentQueryAdapter.getChildCommentListByPostIdAndParentId(postId, comment.getId(), pageable); - // 2. mapper 에 childList를 각각 comment 에서 ReplyInfoDto 로 바꾸는 메서드 만들기 - // 각 답글마다 reactionList를 생성 List replyInfoDtoList = childCommentList.stream() .map(reply -> { List replyReactions = reactionQueryAdapter.findAllByComment(reply); @@ -143,9 +138,6 @@ public CommentResponseDTO.CommentListDto getCommentResponseList(User user, Long }) .collect(Collectors.toList()); - - // 3. mapper 에 이렇게 만든 childList 를 포함해서 최종 응답 형태인 CommentList 로 바꾸는 메서드 만들고 호출하기 - return CommentMapper.toCommentInfoDto(comment, reactionDtoList,replyInfoDtoList); }) .collect(Collectors.toList()); diff --git a/src/main/java/treehouse/server/api/member/business/MemberMapper.java b/src/main/java/treehouse/server/api/member/business/MemberMapper.java index 543187a..c914ecb 100644 --- a/src/main/java/treehouse/server/api/member/business/MemberMapper.java +++ b/src/main/java/treehouse/server/api/member/business/MemberMapper.java @@ -60,6 +60,19 @@ public static MemberResponseDTO.getProfile toGetProfile(List branches, M .build(); } + public static MemberResponseDTO.getProfile toGetMemberProfile(List branches, Member member, Member targetMember) { + return MemberResponseDTO.getProfile.builder() + .memberId(targetMember.getId()) + .memberName(targetMember.getName()) + .userName(targetMember.getUser().getName()) + .closestMemberCount(BranchUtil.countClosestMembers(branches, targetMember.getId())) // ClosestMember 기능 개발 이후 변경 예정 + .treehouseCount(targetMember.getUser().getMemberList().size()) // TreehouseCount 기능 개발 이후 변경 예정 + .fromMe(BranchUtil.calculateBranchDegree(branches, member.getId(), targetMember.getId())) + .profileImageUrl(targetMember.getProfileImageUrl()) + .bio(targetMember.getBio()) + .build(); + } + public static MemberResponseDTO.updateProfile toUpdateProfile(Member member) { return MemberResponseDTO.updateProfile.builder() .memberId(member.getId()) diff --git a/src/main/java/treehouse/server/api/member/business/MemberService.java b/src/main/java/treehouse/server/api/member/business/MemberService.java index 1e9488a..c21e358 100644 --- a/src/main/java/treehouse/server/api/member/business/MemberService.java +++ b/src/main/java/treehouse/server/api/member/business/MemberService.java @@ -54,6 +54,16 @@ public MemberResponseDTO.getProfile getMyProfile(User user, Long treehouseId){ return MemberMapper.toGetProfile(branches, member, member); } + public MemberResponseDTO.getProfile getMemberProfile(User user, Long memberId, Long treehouseId){ + TreeHouse treeHouse = treehouseQueryAdapter.getTreehouseById(treehouseId); + Member member = memberQueryAdapter.findByUserAndTreehouse(user, treeHouse); + Member targetMember = memberQueryAdapter.findById(memberId); + List branches = branchQueryAdapter.findAllByTreeHouse(treeHouse); // 트리하우스 내 모든 브랜치 조회 + return MemberMapper.toGetMemberProfile(branches, member, targetMember); + } + + + @Transactional public MemberResponseDTO.updateProfile updateProfile(User user, Long treehouseId, MemberRequestDTO.updateProfile request){ TreeHouse treeHouse = treehouseQueryAdapter.getTreehouseById(treehouseId); diff --git a/src/main/java/treehouse/server/api/member/presentation/MemberApi.java b/src/main/java/treehouse/server/api/member/presentation/MemberApi.java index c1dd034..9f789c5 100644 --- a/src/main/java/treehouse/server/api/member/presentation/MemberApi.java +++ b/src/main/java/treehouse/server/api/member/presentation/MemberApi.java @@ -10,6 +10,8 @@ import treehouse.server.api.member.business.MemberService; import treehouse.server.api.member.presentation.dto.MemberRequestDTO; import treehouse.server.api.member.presentation.dto.MemberResponseDTO; +import treehouse.server.api.post.business.PostService; +import treehouse.server.api.post.presentation.dto.PostResponseDTO; import treehouse.server.global.common.CommonResponse; import treehouse.server.global.entity.User.User; import treehouse.server.global.security.handler.annotation.AuthMember; @@ -22,13 +24,14 @@ public class MemberApi { private final MemberService memberService; + private final PostService postService; @PostMapping("/members/register") @Operation(summary = "트리하우스 회원가입 \uD83D\uDD11✅", description = "트리하우스 멤버로 가입합니다.") public CommonResponse registerTreehouseMember( @RequestBody final MemberRequestDTO.registerMember request, @AuthMember @Parameter(hidden = true) User user - ){ + ) { return CommonResponse.onSuccess(memberService.register(user, request)); } @@ -37,17 +40,39 @@ public CommonResponse registerTreehouseMember( public CommonResponse getMyProfile( @PathVariable final Long treehouseId, @AuthMember @Parameter(hidden = true) User user - ){ + ) { return CommonResponse.onSuccess(memberService.getMyProfile(user, treehouseId)); } + @GetMapping("/treehouses/{treehouseId}/profiles/{memberId}") + @Operation(summary = "멤버 프로필 조회 \uD83D\uDC64 ✅", description = "특정 트리하우스에서 특정 멤버의 프로필을 조회합니다.") + public CommonResponse getMemberProfile( + @PathVariable(name = "treehouseId") Long treehouseId, + @PathVariable(name = "memberId") Long memberId, + @AuthMember @Parameter(hidden = true) User user + ) { + return CommonResponse.onSuccess(memberService.getMemberProfile(user, memberId, treehouseId)); + } + + @PatchMapping("/treehouses/{treehouseId}/profiles/myProfile") @Operation(summary = "내 프로필 수정 \uD83D\uDC64 ✅", description = "특정 트리하우스에서 내 프로필을 수정합니다.") public CommonResponse updateProfile( @PathVariable final Long treehouseId, @RequestBody final MemberRequestDTO.updateProfile request, @AuthMember @Parameter(hidden = true) User user - ){ + ) { return CommonResponse.onSuccess(memberService.updateProfile(user, treehouseId, request)); } + + @GetMapping("/treehouses/{treehouseId}/profiles/{memberId}/posts") + @Operation(summary = "멤버가 작성한 게시글 조회 \uD83D\uDC64 ✅", description = "특정 트리하우스에서 특정 멤버가 작성한 게시글 목록을 조회합니다.") + public CommonResponse getPosts( + @PathVariable(name = "treehouseId") Long treehouseId, + @PathVariable(name = "memberId") Long memberId, + @RequestParam(defaultValue = "0") int page, + @AuthMember @Parameter(hidden = true) User user + ) { + return CommonResponse.onSuccess(postService.getMemberPosts(user, memberId, treehouseId, page)); + } } diff --git a/src/main/java/treehouse/server/api/member/presentation/dto/MemberResponseDTO.java b/src/main/java/treehouse/server/api/member/presentation/dto/MemberResponseDTO.java index 0e9128e..a73d75d 100644 --- a/src/main/java/treehouse/server/api/member/presentation/dto/MemberResponseDTO.java +++ b/src/main/java/treehouse/server/api/member/presentation/dto/MemberResponseDTO.java @@ -47,4 +47,5 @@ public static class getProfile { public static class updateProfile { private Long memberId; } + } diff --git a/src/main/java/treehouse/server/api/post/business/PostMapper.java b/src/main/java/treehouse/server/api/post/business/PostMapper.java index 59f2b43..b565b4a 100644 --- a/src/main/java/treehouse/server/api/post/business/PostMapper.java +++ b/src/main/java/treehouse/server/api/post/business/PostMapper.java @@ -31,6 +31,24 @@ public static PostResponseDTO.getPostDetails toGetPostDetails(Post post, List postImageUrlList, ReactionResponseDTO.getReactionList reactionList) { + return PostResponseDTO.getOnlyPostDetail.builder() + .postId(post.getId()) + .context(post.getContent()) + .pictureUrlList(postImageUrlList) + .commentCount(post.getCommentList().size()) + .reactionList(reactionList) + .postedAt(TimeFormatter.format(post.getCreatedAt())) + .build(); + } + + public static PostResponseDTO.getMemberPostList toGetMemberPostList(Member targetMember, List onlyPostDetailList) { + return PostResponseDTO.getMemberPostList.builder() + .memberProfile(MemberMapper.toGetWriterProfile(targetMember)) + .postList(onlyPostDetailList) + .build(); + } + public static Post toPost(PostRequestDTO.createPost request, Member member, TreeHouse treeHouse){ return Post.builder() .content(request.getContext()) diff --git a/src/main/java/treehouse/server/api/post/business/PostService.java b/src/main/java/treehouse/server/api/post/business/PostService.java index 14fdc45..dec842f 100644 --- a/src/main/java/treehouse/server/api/post/business/PostService.java +++ b/src/main/java/treehouse/server/api/post/business/PostService.java @@ -177,6 +177,44 @@ public List getPosts (User user, Long treehouseI return postDtoList; } + public PostResponseDTO.getMemberPostList getMemberPosts(User user, Long targetMemberId, Long treehouseId, int page) { + + Pageable pageable = PageRequest.of(page, 10, Sort.by(Sort.Direction.DESC, "createdAt")); + TreeHouse treehouse = treehouseQueryAdapter.getTreehouseById(treehouseId); + Member member = memberQueryAdapter.findByUserAndTreehouse(user, treehouse); + Member targetMember = memberQueryAdapter.findById(targetMemberId); + + List postListByMember = postQueryAdapter.findAllByTreeHouseAndWriter(treehouse, targetMember, pageable); + + + List postDtoList = postListByMember.stream() + .map(post -> { + List postImageList = post.getPostImageList(); + List postImageUrlList= postImageList.stream() + .map(PostImage::getImageUrl) + .toList(); + List reactions = reactionQueryAdapter.findAllByPost(post); + Map reactionMap = reactions.stream() + .collect(Collectors.toMap( + Reaction::getReactionName, + reaction -> { + String reactionName = reaction.getReactionName(); + Integer reactionCount = reactionQueryAdapter.countReactionsByReactionNameAndPostId(reactionName, post.getId()); + Boolean isPushed = reactionQueryAdapter.existByMemberAndPostAndReactionName(member, post, reactionName); + return ReactionMapper.toGetReaction(reaction, reactionCount, isPushed); + }, + (existing, replacement) -> existing // 중복되는 경우 기존 값을 사용 + )); + + ReactionResponseDTO.getReactionList reactionDtoList = ReactionMapper.toGetReactionList(reactionMap); + return PostMapper.toGetOnlyPostDetails(post, postImageUrlList, reactionDtoList); + }) + .collect(Collectors.toList()); + + return PostMapper.toGetMemberPostList(targetMember, postDtoList); + } + + @Transactional public PostResponseDTO.updatePostResult updatePost(User user, Long treehouseId, Long postId, PostRequestDTO.updatePost request) { //TODO 현재 로그인 한 사용자가 게시글 작성자인지 확인하는 로직 개선 diff --git a/src/main/java/treehouse/server/api/post/implement/PostQueryAdapter.java b/src/main/java/treehouse/server/api/post/implement/PostQueryAdapter.java index 82f83dc..72da6c8 100644 --- a/src/main/java/treehouse/server/api/post/implement/PostQueryAdapter.java +++ b/src/main/java/treehouse/server/api/post/implement/PostQueryAdapter.java @@ -6,6 +6,7 @@ import org.springframework.data.domain.Pageable; import treehouse.server.api.post.persistence.PostRepository; import treehouse.server.global.annotations.Adapter; +import treehouse.server.global.entity.member.Member; import treehouse.server.global.entity.post.Post; import treehouse.server.global.entity.treeHouse.TreeHouse; import treehouse.server.global.exception.GlobalErrorCode; @@ -27,4 +28,8 @@ public Post findById(Long postId) { public List findAllByTreehouse(TreeHouse treehouse, Pageable pageable) { return postRepository.findAllByTreeHouse(treehouse, pageable); } + + public List findAllByTreeHouseAndWriter(TreeHouse treeHouse, Member writer, Pageable pageable) { + return postRepository.findAllByTreeHouseAndWriter(treeHouse, writer, pageable); + } } diff --git a/src/main/java/treehouse/server/api/post/persistence/PostRepository.java b/src/main/java/treehouse/server/api/post/persistence/PostRepository.java index 67cc071..9e5a174 100644 --- a/src/main/java/treehouse/server/api/post/persistence/PostRepository.java +++ b/src/main/java/treehouse/server/api/post/persistence/PostRepository.java @@ -4,6 +4,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import treehouse.server.global.entity.member.Member; import treehouse.server.global.entity.post.Post; import treehouse.server.global.entity.treeHouse.TreeHouse; @@ -13,4 +14,6 @@ public interface PostRepository extends JpaRepository { List findAllByTreeHouse(TreeHouse treehouse, Pageable pageable); + + List findAllByTreeHouseAndWriter(TreeHouse treeHouse, Member writer, Pageable pageable); } diff --git a/src/main/java/treehouse/server/api/post/presentation/dto/PostResponseDTO.java b/src/main/java/treehouse/server/api/post/presentation/dto/PostResponseDTO.java index bc4c651..f2ab344 100644 --- a/src/main/java/treehouse/server/api/post/presentation/dto/PostResponseDTO.java +++ b/src/main/java/treehouse/server/api/post/presentation/dto/PostResponseDTO.java @@ -27,6 +27,28 @@ public static class getPostDetails { private String postedAt; } + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class getOnlyPostDetail { + private Long postId; + private String context; + private List pictureUrlList; + private Integer commentCount; + private ReactionResponseDTO.getReactionList reactionList; + private String postedAt; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class getMemberPostList { + private MemberResponseDTO.getWriterProfile memberProfile; + List postList; + } + @Builder @Getter @NoArgsConstructor