Skip to content

Commit 6ea7a2f

Browse files
committed
feat: 팔로잉한 포스트 목록 및 인기 포스트 목록 조회 기능 구현
1 parent 09bc8a8 commit 6ea7a2f

4 files changed

Lines changed: 71 additions & 9 deletions

File tree

src/main/java/hanium/modic/backend/domain/post/enums/PostType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
public enum PostType {
44
ALL, // 모든 포스트 (기본값)
55
ORIGINAL, // 원본 포스트만
6-
AI_DERIVED // AI 파생 포스트만
6+
AI_DERIVED, // AI 파생 포스트만
7+
HOTTEST // 인기 포스트만
78
}

src/main/java/hanium/modic/backend/domain/post/repository/PostEntityRepository.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,30 @@ WITH RECURSIVE post_tree AS (
6565
List<PostEntity> findAllDescendantsByPostId(@Param("postId") Long postId);
6666

6767
boolean existsByParentPostIdAndThumbnailImageId(Long postId, Long createdAiImageId);
68+
69+
@Query("""
70+
SELECT p
71+
FROM PostEntity p
72+
LEFT JOIN PostStatisticsEntity ps
73+
ON p.id = ps.postId
74+
WHERE p.postStatus IN (hanium.modic.backend.domain.post.enums.PostStatus.ORIGINAL
75+
, hanium.modic.backend.domain.post.enums.PostStatus.DERIVED_APPROVED)
76+
ORDER BY ps.likeCount DESC NULLS LAST, p.createAt DESC
77+
""")
78+
Page<PostEntity> findHottestPosts(Pageable pageable);
79+
80+
@Query("""
81+
SELECT p
82+
FROM PostEntity p
83+
WHERE p.postStatus IN (hanium.modic.backend.domain.post.enums.PostStatus.ORIGINAL
84+
, hanium.modic.backend.domain.post.enums.PostStatus.DERIVED_APPROVED)
85+
AND
86+
p.userId IN (
87+
SELECT f.followingId
88+
FROM FollowEntity f
89+
WHERE f.myId = :myId
90+
)
91+
ORDER BY p.createAt DESC
92+
""")
93+
Page<PostEntity> findPostsByFollowedUsers(@Param("myId") Long myId, Pageable pageable);
6894
}

src/main/java/hanium/modic/backend/domain/post/service/PostService.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,18 @@ public Page<GetPostsResponse> getPosts(
237237
return createGetPostsResponse(posts);
238238
}
239239

240+
// 팔로우한 포스트 목록 조회
241+
@Transactional(readOnly = true)
242+
public Page<GetPostsResponse> getFollowingPosts(
243+
final long userId,
244+
final int page,
245+
final int size
246+
) {
247+
Pageable pageable = PageRequest.of(page, size, SORT_DIRECTION, SORT_CRITERIA);
248+
Page<PostEntity> posts = postEntityRepository.findPostsByFollowedUsers(userId, pageable);
249+
return createGetPostsResponse(posts);
250+
}
251+
240252
// 검색어로 포스트 목록 조회
241253

242254
/**
@@ -416,6 +428,7 @@ private Page<PostEntity> getPostsByType(Pageable pageable, PostType postType) {
416428
case ORIGINAL -> postEntityRepository.findAllByPostStatus(ORIGINAL, pageable);
417429
case AI_DERIVED -> postEntityRepository.findAllByPostStatus(DERIVED_APPROVED, pageable);
418430
case ALL -> postEntityRepository.findAllByPostStatusIn(List.of(ORIGINAL, DERIVED_APPROVED), pageable);
431+
case HOTTEST -> postEntityRepository.findHottestPosts(pageable);
419432
};
420433
}
421434

@@ -462,6 +475,7 @@ private List<PostStatus> resolveSearchTargetStatuses(PostType postType) {
462475
case ORIGINAL -> List.of(ORIGINAL);
463476
case AI_DERIVED -> List.of(DERIVED_APPROVED);
464477
case ALL -> List.of(ORIGINAL, DERIVED_APPROVED);
478+
case HOTTEST -> List.of(ORIGINAL, DERIVED_APPROVED);
465479
};
466480
}
467481

src/main/java/hanium/modic/backend/web/post/controller/PostController.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package hanium.modic.backend.web.post.controller;
22

3+
import static hanium.modic.backend.common.error.ErrorCode.*;
34
import static org.springframework.http.HttpStatus.*;
45

56
import java.util.List;
@@ -20,6 +21,7 @@
2021
import hanium.modic.backend.common.annotation.user.CurrentUser;
2122
import hanium.modic.backend.common.response.AppResponse;
2223
import hanium.modic.backend.common.response.PageResponse;
24+
import hanium.modic.backend.common.swagger.ApiErrorMapping;
2325
import hanium.modic.backend.domain.post.enums.PostType;
2426
import hanium.modic.backend.domain.post.service.PostService;
2527
import hanium.modic.backend.domain.postReview.service.PostReviewAuthorizationService;
@@ -95,12 +97,12 @@ public ResponseEntity<AppResponse<GetPostResponse>> getPost(@PathVariable Long i
9597
summary = "게시글 목록 조회 API",
9698
description = """
9799
게시글 목록을 조회합니다. 정렬 기준, 페이지 번호, 페이지 크기, 포스트 타입을 입력받습니다.
98-
postType은 (ALL, ORIGINAL, AI_DERIVED)가 존재한다.
99-
""",
100-
responses = {
101-
@ApiResponse(responseCode = "400", description = "사용자 입력 오류[C-001]")
102-
}
100+
postType은 (ALL, ORIGINAL, AI_DERIVED, HOTTEST)가 존재한다.
101+
"""
103102
)
103+
@ApiErrorMapping({
104+
USER_INPUT_EXCEPTION
105+
})
104106
public ResponseEntity<AppResponse<PageResponse<GetPostsResponse>>> getPosts(
105107
@RequestParam(required = false, defaultValue = "0") @Min(value = 0, message = "페이지 번호는 0 이상이어야 합니다") Integer page,
106108
@RequestParam(required = false, defaultValue = "10") @Min(value = 10, message = "페이지 크기는 10 이상이어야 합니다.") @Max(value = 20, message = "페이지 크기는 20 이하여야 합니다.") Integer size,
@@ -110,13 +112,32 @@ public ResponseEntity<AppResponse<PageResponse<GetPostsResponse>>> getPosts(
110112
return ResponseEntity.ok(AppResponse.ok(PageResponse.of(response)));
111113
}
112114

115+
@GetMapping("/following")
116+
@Operation(
117+
summary = "팔로우한 사용자의 게시글 목록 조회 API",
118+
description = """
119+
팔로우한 사용자의 게시글 목록을 조회합니다. 페이지 번호, 페이지 크기, 포스트 타입을 입력받습니다.
120+
"""
121+
)
122+
@ApiErrorMapping({
123+
USER_INPUT_EXCEPTION
124+
})
125+
public ResponseEntity<AppResponse<PageResponse<GetPostsResponse>>> getFollowingPosts(
126+
@RequestParam(required = false, defaultValue = "0") @Min(value = 0, message = "페이지 번호는 0 이상이어야 합니다") Integer page,
127+
@RequestParam(required = false, defaultValue = "10") @Min(value = 10, message = "페이지 크기는 10 이상이어야 합니다.") @Max(value = 20, message = "페이지 크기는 20 이하여야 합니다.") Integer size,
128+
@CurrentUser UserEntity user
129+
) {
130+
Page<GetPostsResponse> response = postService.getFollowingPosts(user.getId(), page, size);
131+
return ResponseEntity.ok(AppResponse.ok(PageResponse.of(response)));
132+
}
133+
113134
@GetMapping("/search")
114135
@Operation(
115136
summary = "게시글 검색 API",
116137
description = """
117-
제목 또는 설명에 검색어가 포함된 게시글을 조회합니다.
118-
검색 대상은 postType(ALL, ORIGINAL, AI_DERIVED)에 따라 달라집니다.
119-
""",
138+
제목 또는 설명에 검색어가 포함된 게시글을 조회합니다.
139+
검색 대상은 postType(ALL, ORIGINAL, AI_DERIVED)에 따라 달라집니다.
140+
""",
120141
responses = {
121142
@ApiResponse(responseCode = "400", description = "사용자 입력 오류[C-001]")
122143
}

0 commit comments

Comments
 (0)