Skip to content

Commit 01a1033

Browse files
authored
Feat 게시글 상세 페이지 구현 (#88)
* DTO record -> Class * Feat 게시글 상세 페이지 구현 * Feat 게시글 상세 페이지 TC 작성
1 parent 17f5ff2 commit 01a1033

File tree

9 files changed

+222
-43
lines changed

9 files changed

+222
-43
lines changed

back/src/main/java/com/back/domain/post/like/service/PostLikeService.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
import com.back.domain.post.like.repository.PostLikeRepository;
66
import com.back.domain.post.post.entity.Post;
77
import com.back.domain.post.post.service.PostService;
8+
import com.back.domain.post.rq.PostDetailFacade;
89
import com.back.global.rq.Rq;
910
import jakarta.transaction.Transactional;
1011
import lombok.RequiredArgsConstructor;
12+
import org.springframework.context.annotation.Lazy;
1113
import org.springframework.stereotype.Service;
1214

1315
import java.util.Optional;
@@ -16,8 +18,8 @@
1618
public class PostLikeService {
1719
private final Rq rq;
1820
private final PostLikeRepository postLikeRepository;
19-
private final PostService postService;
20-
21+
//private final PostDetailFacade postDetailFacade;
22+
private final PostService postService; // 리팩토링 대상
2123

2224
@Transactional
2325
public void likePost(long postId) {
@@ -70,11 +72,25 @@ public void disLikePost(long postId) {
7072
}
7173
}
7274

73-
public int showDisLikeCount(Long postId) {
75+
public int getDisLikeCount(Long postId) {
7476
return postLikeRepository.countDislikesByPostId(postId);
7577
}
7678

77-
public int showLikeCount(Long postId) {
79+
public int getLikeCount(Long postId) {
7880
return postLikeRepository.countLikesByPostId(postId);
7981
}
82+
83+
public String getPresentStatus(Long postId) {
84+
Member member = rq.getActor();
85+
Post post = postService.findById(postId);
86+
87+
Optional<PostLike> existingLike = postLikeRepository.findByMemberAndPost(member, post);
88+
89+
if (existingLike.isPresent()) {
90+
PostLike postLike = existingLike.get();
91+
return postLike.getStatus().name();
92+
}
93+
94+
return "NONE"; // 좋아요/싫어요 안한 상태
95+
}
8096
}

back/src/main/java/com/back/domain/post/post/controller/InformationPostController.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@
55
import com.back.domain.post.post.dto.*;
66
import com.back.domain.post.post.entity.Post;
77
import com.back.domain.post.post.service.PostService;
8+
import com.back.domain.post.rq.PostDetailFacade;
89
import com.back.global.rq.Rq;
910
import com.back.global.rsData.RsData;
1011
import io.swagger.v3.oas.annotations.Operation;
1112
import jakarta.validation.Valid;
12-
import lombok.Getter;
1313
import lombok.RequiredArgsConstructor;
1414
import org.springframework.data.domain.Page;
15-
import org.springframework.data.domain.Pageable;
16-
import org.springframework.data.domain.Sort;
17-
import org.springframework.data.web.PageableDefault;
1815
import org.springframework.web.bind.annotation.*;
1916

2017
import java.util.List;
@@ -26,6 +23,7 @@ public class InformationPostController {
2623
private final PostLikeService postLikeService;
2724
private final PostService postService;
2825
private final Rq rq;
26+
private final PostDetailFacade postDetailFacade;
2927

3028

3129
@Operation(summary = "게시글 조회 - 페이징 처리")
@@ -103,7 +101,7 @@ public RsData<Void> likePost(@PathVariable Long post_id) {
103101
@Operation(summary = "게시글 좋아요 (Show)")
104102
@GetMapping("/{post_id}/liked")
105103
public RsData<PostLikedResponse> getLike(@PathVariable Long post_id) {
106-
int likeCount = postLikeService.showLikeCount(post_id);
104+
int likeCount = postLikeService.getLikeCount(post_id);
107105
PostLikedResponse postLikedResponse = new PostLikedResponse(likeCount);
108106

109107
return new RsData<>("200", "게시글 좋아요 조회 성공", postLikedResponse);
@@ -112,7 +110,7 @@ public RsData<PostLikedResponse> getLike(@PathVariable Long post_id) {
112110
@Operation(summary = "게시글 싫어요 (Show)")
113111
@GetMapping("/{post_id}/Disliked")
114112
public RsData<PostLikedResponse> getDisLike(@PathVariable Long post_id) {
115-
int likeCount = postLikeService.showDisLikeCount(post_id);
113+
int likeCount = postLikeService.getDisLikeCount(post_id);
116114
PostLikedResponse postLikedResponse = new PostLikedResponse(likeCount);
117115

118116
return new RsData<>("200", "게시글 싫어요 조회 성공", postLikedResponse);
@@ -125,4 +123,12 @@ public RsData<PostLikedResponse> disLikePost(@PathVariable Long post_id) {
125123

126124
return new RsData<>("200", "게시글 싫어요 성공", null);
127125
}
126+
127+
@GetMapping("/Detail/{post_id}")
128+
public RsData<PostDetailResponse> getPostDetail(@PathVariable Long post_id) {
129+
130+
PostDetailResponse response = postDetailFacade.getDetailWithViewIncrement(post_id);
131+
132+
return new RsData<>("200", "게시글 상세 조회 성공", response);
133+
}
128134
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.back.domain.post.post.dto;
2+
3+
import com.back.domain.post.comment.dto.CommentAllResponse;
4+
import com.back.domain.post.post.entity.Post;
5+
import lombok.Data;
6+
7+
import java.time.LocalDateTime;
8+
import java.util.List;
9+
@Data
10+
public class PostDetailResponse {
11+
12+
private Long id;
13+
private String title;
14+
private String content;
15+
private String authorName;
16+
private LocalDateTime createdAt;
17+
private int viewCount;
18+
19+
private int likeCount;
20+
private int dislikeCount;
21+
private String userLikeStatus;
22+
23+
private List<CommentAllResponse> comments;
24+
25+
26+
27+
public static PostDetailResponse from(Post post, List<CommentAllResponse> comments, int likeCount, int dislikeCount, String userLikeStatus) {
28+
PostDetailResponse postDetailResponse = new PostDetailResponse();
29+
30+
postDetailResponse.setId(post.getId());
31+
postDetailResponse.setTitle(post.getTitle());
32+
postDetailResponse.setContent(post.getContent());
33+
postDetailResponse.setAuthorName(post.getAuthorName());
34+
postDetailResponse.setCreatedAt(post.getCreateDate());
35+
postDetailResponse.setViewCount(post.getViewCount());
36+
37+
postDetailResponse.setLikeCount(likeCount);
38+
postDetailResponse.setDislikeCount(dislikeCount);
39+
postDetailResponse.setUserLikeStatus(userLikeStatus);
40+
41+
postDetailResponse.setComments(comments);
42+
43+
44+
45+
return postDetailResponse;
46+
}
47+
48+
}

back/src/main/java/com/back/domain/post/post/dto/PostDto.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22

33

44
import com.back.domain.post.post.entity.Post;
5+
import lombok.Data;
6+
7+
@Data
8+
public class PostDto {
9+
private Long postId;
10+
private String title;
11+
private String content;
512

6-
public record PostDto(
7-
Long postId,
8-
String title,
9-
String content
10-
) {
1113
public static PostDto from(Post post) {
12-
return new PostDto(
13-
post.getId(),
14-
post.getTitle(),
15-
post.getContent()
16-
);
14+
PostDto postDto = new PostDto();
15+
postDto.setPostId(post.getId());
16+
postDto.setTitle(post.getTitle());
17+
postDto.setContent(post.getContent());
18+
19+
return postDto;
1720
}
1821
}

back/src/main/java/com/back/domain/post/post/dto/PostPagingResponse.java

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
package com.back.domain.post.post.dto;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.Data;
45
import org.springframework.data.domain.Page;
6+
import org.springframework.security.core.parameters.P;
57

68
import java.util.List;
79

8-
public record PostPagingResponse(
9-
@Schema(description = "게시글 목록")
10-
List<PostDto> posts,
11-
@Schema(description = "현재 페이지 (0부터 시작)")
12-
int currentPage,
13-
@Schema(description = "총 페이지")
14-
int totalPage,
15-
@Schema(description = "총 개수")
16-
long totalElements,
17-
@Schema(description = "다음 페이지 존재 여부")
18-
boolean hasNext
19-
) {
10+
@Data
11+
public class PostPagingResponse{
12+
13+
@Schema(description = "게시글 목록")
14+
List<PostDto> posts;
15+
@Schema(description = "현재 페이지 (0부터 시작)")
16+
int currentPage;
17+
@Schema(description = "총 페이지")
18+
int totalPage;
19+
@Schema(description = "총 개수")
20+
long totalElements;
21+
@Schema(description = "다음 페이지 존재 여부")
22+
boolean hasNext;
2023

2124
public static PostPagingResponse from(Page<PostDto> page) {
22-
return new PostPagingResponse(
23-
page.getContent(),
24-
page.getNumber(),
25-
page.getTotalPages(),
26-
page.getTotalElements(),
27-
page.hasNext()
28-
);
25+
PostPagingResponse postPagingResponse = new PostPagingResponse();
26+
postPagingResponse.setPosts(page.getContent());
27+
postPagingResponse.setCurrentPage(page.getNumber());
28+
postPagingResponse.setTotalPage(page.getTotalPages());
29+
postPagingResponse.setTotalElements(page.getTotalElements());
30+
postPagingResponse.setHasNext(page.hasNext());
31+
32+
return postPagingResponse;
2933
}
3034

3135
}

back/src/main/java/com/back/domain/post/post/repository/PostRepository.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55
import org.springframework.data.domain.Pageable;
66
import org.springframework.data.jpa.repository.JpaRepository;
77
import org.springframework.data.jpa.repository.Query;
8+
import org.springframework.data.repository.query.Param;
89
import org.springframework.stereotype.Repository;
910

1011
import java.util.List;
12+
import java.util.Optional;
1113

1214
@Repository
1315
public interface PostRepository extends JpaRepository<Post, Long> , PostRepositoryCustom{
1416
@Query("SELECT p FROM Post p JOIN FETCH p.member")
1517
List<Post> findAllWithMember();
18+
19+
@Query("SELECT p FROM Post p JOIN FETCH p.member WHERE p.id = :postId")
20+
Optional<Post> findByIdWithMember(@Param("postId") Long postId);
21+
1622
}

back/src/main/java/com/back/domain/post/post/service/PostService.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
package com.back.domain.post.post.service;
22

33
import com.back.domain.member.member.entity.Member;
4-
import com.back.domain.post.like.repository.PostLikeRepository;
54
import com.back.domain.post.post.dto.PostAllResponse;
65
import com.back.domain.post.post.dto.PostCreateRequest;
76
import com.back.domain.post.post.dto.PostDto;
87
import com.back.domain.post.post.entity.Post;
98
import com.back.domain.post.post.repository.PostRepository;
109
import com.back.global.exception.ServiceException;
11-
import com.back.global.rq.Rq;
12-
import jakarta.transaction.Transactional;
1310
import jakarta.validation.Valid;
1411
import lombok.RequiredArgsConstructor;
1512
import org.springframework.data.domain.Page;
1613
import org.springframework.data.domain.PageRequest;
1714
import org.springframework.data.domain.Pageable;
1815
import org.springframework.stereotype.Service;
16+
import org.springframework.transaction.annotation.Transactional;
1917

2018
import java.util.List;
2119

2220
@Service
2321
@RequiredArgsConstructor
2422
public class PostService {
2523

26-
private final PostRepository postRepository;
24+
private final PostRepository postRepository;;
2725

2826
public List<Post> getAllPosts() {
2927
List<Post> posts = postRepository.findAll();
@@ -67,6 +65,14 @@ public void updatePost(long postId, Member member, @Valid PostCreateRequest post
6765
postRepository.save(post);
6866
}
6967

68+
public Post getPostDetailWithViewIncrement(Long postId) {
69+
Post post = postRepository.findByIdWithMember(postId)
70+
.orElseThrow(()-> new ServiceException("400","해당 Id의 게시글이 없습니다."));
71+
post.setViewCount(post.getViewCount() + 1);
72+
73+
return post;
74+
}
75+
7076

7177
public Page<PostDto> getPosts(String keyword, int page, int size) {
7278
Pageable pageable = PageRequest.of(page, size);
@@ -86,4 +92,6 @@ public List<PostAllResponse> getAllPostResponse() {
8692
.map(PostAllResponse::new)
8793
.toList();
8894
}
95+
96+
8997
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.back.domain.post.rq;
2+
3+
import com.back.domain.post.comment.dto.CommentAllResponse;
4+
import com.back.domain.post.comment.service.PostCommentService;
5+
import com.back.domain.post.like.service.PostLikeService;
6+
import com.back.domain.post.post.dto.PostDetailResponse;
7+
import com.back.domain.post.post.entity.Post;
8+
import com.back.domain.post.post.service.PostService;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.stereotype.Service;
11+
import org.springframework.transaction.annotation.Transactional;
12+
13+
import java.util.List;
14+
15+
@Service
16+
@RequiredArgsConstructor
17+
public class PostDetailFacade {
18+
19+
private final PostService postService;
20+
private final PostLikeService postLikeService;
21+
private final PostCommentService postCommentService;
22+
23+
@Transactional
24+
public PostDetailResponse getDetailWithViewIncrement(Long postId) {
25+
// 조회수 증가와 상세정보 조회를 한 번에
26+
Post post = postService.getPostDetailWithViewIncrement(postId);
27+
28+
List<CommentAllResponse> comments = postCommentService.getAllPostCommentResponse(postId);
29+
int likeCount = postLikeService.getLikeCount(postId);
30+
int dislikeCount = postLikeService.getDisLikeCount(postId);
31+
String userStatus = postLikeService.getPresentStatus(postId);
32+
33+
return PostDetailResponse.from(post, comments, likeCount, dislikeCount, userStatus);
34+
}
35+
36+
// public Post findById(Long postId) {
37+
// return postService.findById(postId);
38+
// }
39+
40+
41+
}

0 commit comments

Comments
 (0)