diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/controller/GetUserPickPopularPostsController.java b/src/main/java/com/ftm/server/adapter/in/web/post/controller/GetUserPickPopularPostsController.java index 7857196..10667be 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/controller/GetUserPickPopularPostsController.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/controller/GetUserPickPopularPostsController.java @@ -2,12 +2,15 @@ import com.ftm.server.adapter.in.web.post.dto.response.GetUserPickPopularPostsResponse; import com.ftm.server.application.port.in.post.GetUserPickPopularPostsUseCase; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.common.response.ApiResponse; import com.ftm.server.common.response.enums.SuccessResponseCode; +import com.ftm.server.infrastructure.security.UserPrincipal; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -19,9 +22,14 @@ public class GetUserPickPopularPostsController { private final GetUserPickPopularPostsUseCase userPickPopularPostsUseCase; @GetMapping("/api/posts/userpick/popular") - public ResponseEntity getUserPickPopularPosts() { + public ResponseEntity getUserPickPopularPosts( + @AuthenticationPrincipal UserPrincipal userPrincipal) { List userPickPopularPostsResponses = - userPickPopularPostsUseCase.execute().stream() + userPickPopularPostsUseCase + .execute( + FindByUserIdQuery.of( + userPrincipal == null ? null : userPrincipal.getId())) + .stream() .map(GetUserPickPopularPostsResponse::from) .toList(); diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickBiblePostsController.java b/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickBiblePostsController.java index 7bc1155..47cfc8a 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickBiblePostsController.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickBiblePostsController.java @@ -2,11 +2,14 @@ import com.ftm.server.adapter.in.web.post.dto.response.LoadUserPickBiblePostsResponse; import com.ftm.server.application.port.in.post.LoadUserPickBiblePostsUseCase; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.common.response.ApiResponse; import com.ftm.server.common.response.enums.SuccessResponseCode; +import com.ftm.server.infrastructure.security.UserPrincipal; import java.util.List; import lombok.AllArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -17,9 +20,14 @@ public class LoadUserPickBiblePostsController { private final LoadUserPickBiblePostsUseCase userPickBiblePostsUseCase; @GetMapping("/api/posts/userpick/bible") - public ResponseEntity loadUserPickGroomingBiblePosts() { + public ResponseEntity loadUserPickGroomingBiblePosts( + @AuthenticationPrincipal UserPrincipal userPrincipal) { List result = - userPickBiblePostsUseCase.execute().stream() + userPickBiblePostsUseCase + .execute( + FindByUserIdQuery.of( + userPrincipal == null ? null : userPrincipal.getId())) + .stream() .map(LoadUserPickBiblePostsResponse::from) .toList(); return ResponseEntity.ok(ApiResponse.success(SuccessResponseCode.OK, result)); diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickTopBookmarkPostsController.java b/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickTopBookmarkPostsController.java index d0421ac..41ed83c 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickTopBookmarkPostsController.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/controller/LoadUserPickTopBookmarkPostsController.java @@ -2,11 +2,14 @@ import com.ftm.server.adapter.in.web.post.dto.response.LoadUserPickTopBookmarkPostsResponse; import com.ftm.server.application.port.in.post.LoadUserPickTopBookmarkPostsUseCase; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.common.response.ApiResponse; import com.ftm.server.common.response.enums.SuccessResponseCode; +import com.ftm.server.infrastructure.security.UserPrincipal; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -17,9 +20,16 @@ public class LoadUserPickTopBookmarkPostsController { private final LoadUserPickTopBookmarkPostsUseCase useCase; @GetMapping("/api/posts/userpick/top-bookmarks") - public ResponseEntity loadTopBookmarkPosts() { + public ResponseEntity loadTopBookmarkPosts( + @AuthenticationPrincipal UserPrincipal userPrincipal) { List result = - useCase.execute().stream().map(LoadUserPickTopBookmarkPostsResponse::from).toList(); + useCase + .execute( + FindByUserIdQuery.of( + userPrincipal == null ? null : userPrincipal.getId())) + .stream() + .map(LoadUserPickTopBookmarkPostsResponse::from) + .toList(); return ResponseEntity.ok(ApiResponse.success(SuccessResponseCode.OK, result)); } } diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/GetUserPickPopularPostsResponse.java b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/GetUserPickPopularPostsResponse.java index 8452798..735c2fb 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/GetUserPickPopularPostsResponse.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/GetUserPickPopularPostsResponse.java @@ -17,6 +17,7 @@ public class GetUserPickPopularPostsResponse { private final Long scrapCount; private final String imageUrl; private final List hashtags; + private final Boolean userBookmarkYn; public static GetUserPickPopularPostsResponse from(UserPickPopularPostsVo vo) { return new GetUserPickPopularPostsResponse( @@ -29,6 +30,7 @@ public static GetUserPickPopularPostsResponse from(UserPickPopularPostsVo vo) { vo.getLikeCount(), vo.getScrapCount(), vo.getImageUrl(), - vo.getHashtags()); + vo.getHashtags(), + vo.getUserBookmarkYn()); } } diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickBiblePostsResponse.java b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickBiblePostsResponse.java index cad4016..1db15d1 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickBiblePostsResponse.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickBiblePostsResponse.java @@ -18,6 +18,7 @@ public class LoadUserPickBiblePostsResponse { private final Long scrapCount; private final String imageUrl; private final List hashtags; + private final Boolean userBookmarkYn; public static LoadUserPickBiblePostsResponse from(UserPickBiblePostsVo vo) { return new LoadUserPickBiblePostsResponse( @@ -30,6 +31,7 @@ public static LoadUserPickBiblePostsResponse from(UserPickBiblePostsVo vo) { vo.getLikeCount(), vo.getScrapCount(), vo.getImageUrl(), - vo.getHashtags()); + vo.getHashtags(), + vo.getUserBookmarkYn()); } } diff --git a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickTopBookmarkPostsResponse.java b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickTopBookmarkPostsResponse.java index 9735cbd..9460344 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickTopBookmarkPostsResponse.java +++ b/src/main/java/com/ftm/server/adapter/in/web/post/dto/response/LoadUserPickTopBookmarkPostsResponse.java @@ -19,6 +19,7 @@ public class LoadUserPickTopBookmarkPostsResponse { private final Long scrapCount; private final String imageUrl; private final List hashtags; + private final Boolean userBookmarkYn; public static LoadUserPickTopBookmarkPostsResponse from(LoadUserPickTopBookmarkPostsVo vo) { return new LoadUserPickTopBookmarkPostsResponse( @@ -31,6 +32,7 @@ public static LoadUserPickTopBookmarkPostsResponse from(LoadUserPickTopBookmarkP vo.getLikeCount(), vo.getScrapCount(), vo.getImageUrl(), - vo.getHashtags()); + vo.getHashtags(), + vo.getUserBookmarkYn()); } } diff --git a/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickBiblePostsWithCacheAdapter.java b/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickBiblePostsWithCacheAdapter.java index 853b10c..91b67fa 100644 --- a/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickBiblePostsWithCacheAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickBiblePostsWithCacheAdapter.java @@ -5,7 +5,6 @@ import com.ftm.server.application.port.out.cache.LoadUserPickBiblePostsWithCachePort; import com.ftm.server.application.port.out.persistence.post.LoadPostPort; import com.ftm.server.application.query.FindUserPickBiblePostsQuery; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import com.ftm.server.common.annotation.Adapter; import java.util.List; import lombok.RequiredArgsConstructor; @@ -22,7 +21,7 @@ public class LoadUserPickBiblePostsWithCacheAdapter implements LoadUserPickBible @Cacheable( cacheNames = USER_PICK_BIBLE_POSTS_CACHE_NAME, key = USER_PICK_BIBLE_POSTS_CACHE_KEY_ALL) - public List getUserPickBiblePost() { + public List getUserPickBiblePost() { return execute(); } @@ -30,14 +29,14 @@ public List getUserPickBiblePost() { @CachePut( cacheNames = USER_PICK_BIBLE_POSTS_CACHE_NAME, key = USER_PICK_BIBLE_POSTS_CACHE_KEY_ALL) - public List getUserPickBiblePostCachePut() { + public List getUserPickBiblePostCachePut() { return execute(); } - public List execute() { + public List execute() { // 최근 1개월 상위 4개 post id를 조회 - List postList = + List postList = loadPostPort.loadUserPickBiblePosts(FindUserPickBiblePostsQuery.of(4)); if (postList.isEmpty()) return List.of(); diff --git a/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickPopularPostsWithCacheAdapter.java b/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickPopularPostsWithCacheAdapter.java index ebf9376..616ce8d 100644 --- a/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickPopularPostsWithCacheAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickPopularPostsWithCacheAdapter.java @@ -7,7 +7,6 @@ import com.ftm.server.application.port.out.persistence.post.LoadPostPort; import com.ftm.server.application.query.FindUserPickPopularPostsQuery; import com.ftm.server.common.annotation.Adapter; -import com.ftm.server.domain.entity.Post; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -29,7 +28,7 @@ public class LoadUserPickPopularPostsWithCacheAdapter implements LoadUserPickPop @CachePut( cacheNames = USER_PICK_POPULAR_POSTS_CACHE_NAME, key = USER_PICK_POPULAR_POSTS_CACHE_KEY_ALL) - public List getUserPickPopularPostCachePut() { + public List getUserPickPopularPostCachePut() { return execute(); } @@ -37,14 +36,14 @@ public List getUserPickPopularPostCachePut() { @Cacheable( cacheNames = USER_PICK_POPULAR_POSTS_CACHE_NAME, key = USER_PICK_POPULAR_POSTS_CACHE_KEY_ALL) - public List getUserPickPopularPost() { + public List getUserPickPopularPost() { return execute(); } - public List execute() { + public List execute() { // 최근 1개월 상위 4개 post id를 조회 LocalDateTime since = LocalDate.now().minusMonths(1).atStartOfDay(); - List postList = + List postList = loadPostPort.loadUserPickPopularPosts(FindUserPickPopularPostsQuery.of(since, 4)); if (postList.isEmpty()) return List.of(); diff --git a/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickTopBookmarkPostsWithCacheAdapter.java b/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickTopBookmarkPostsWithCacheAdapter.java index b9268cd..7c359f7 100644 --- a/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickTopBookmarkPostsWithCacheAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/cache/LoadUserPickTopBookmarkPostsWithCacheAdapter.java @@ -6,7 +6,6 @@ import com.ftm.server.application.port.out.cache.LoadUserPickTopBookmarkPostsWithCachePort; import com.ftm.server.application.port.out.persistence.post.LoadPostPort; import com.ftm.server.application.query.FindTopPostsByBookmarkCountQuery; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import com.ftm.server.common.annotation.Adapter; import java.util.List; import lombok.RequiredArgsConstructor; @@ -26,7 +25,7 @@ public class LoadUserPickTopBookmarkPostsWithCacheAdapter @Cacheable( cacheNames = USER_PICK_TOP_BOOKMARK_POSTS_CACHE_NAME, key = USER_PICK_TOP_BOOKMARK_POSTS_CACHE_KEY_ALL) - public List getTopBookmarkPosts() { + public List getTopBookmarkPosts() { return execute(); } @@ -34,12 +33,12 @@ public List getTopBookmarkPosts() { @CachePut( cacheNames = USER_PICK_TOP_BOOKMARK_POSTS_CACHE_NAME, key = USER_PICK_TOP_BOOKMARK_POSTS_CACHE_KEY_ALL) - public List getTopBookmarkPostsCachePut() { + public List getTopBookmarkPostsCachePut() { return execute(); } - private List execute() { - List posts = + private List execute() { + List posts = loadPostPort.loadTopPostsByBookmarkCount(FindTopPostsByBookmarkCountQuery.of(4)); if (posts.isEmpty()) return List.of(); return posts; diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java index 37616f7..7b0ef71 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/post/PostDomainPersistenceAdapter.java @@ -149,22 +149,18 @@ public List loadPostsByDeleteOption(FindPostByDeleteOptionQuery query) { } @Override - public List loadUserPickPopularPosts(FindUserPickPopularPostsQuery query) { - return postRepository - .findTopNPostsByViewCountAndLikeCount(query.getSince(), query.getLimit()) - .stream() - .map(postMapper::toDomainEntity) - .toList(); + public List loadUserPickPopularPosts(FindUserPickPopularPostsQuery query) { + return postRepository.findTopNPostsByViewCountAndLikeCount( + query.getSince(), query.getLimit()); } @Override - public List loadUserPickBiblePosts(FindUserPickBiblePostsQuery query) { + public List loadUserPickBiblePosts(FindUserPickBiblePostsQuery query) { return postRepository.findTopNPostsByLikeCount(query.getLimit()); } @Override - public List loadTopPostsByBookmarkCount( - FindTopPostsByBookmarkCountQuery query) { + public List loadTopPostsByBookmarkCount(FindTopPostsByBookmarkCountQuery query) { return postRepository.findTopNPostsByBookmarkCount(query.getLimit()); } @@ -180,6 +176,11 @@ public List loadUserPickAllPostsByLatest( .toList(); } + @Override + public List loadPostIdAndBookmarkYn(FindByPostIdsAndUserQuery query) { + return postRepository.findPostIdWithBookmarkYn(query); + } + @Override public List loadPostWithUserAndBookmarkCount( FindByIdsQuery query) { diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepository.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepository.java index afb1f62..6e6d5b5 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepository.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepository.java @@ -1,11 +1,9 @@ package com.ftm.server.adapter.out.persistence.repository; import com.ftm.server.adapter.out.persistence.model.PostJpaEntity; -import com.ftm.server.application.query.FindPostByDeleteOptionQuery; -import com.ftm.server.application.query.FindPostsByCreatedDateQuery; -import com.ftm.server.application.query.FindPostsByPagingQuery; -import com.ftm.server.application.query.FindUserPickLatestPostsByCursorQuery; +import com.ftm.server.application.query.*; import com.ftm.server.application.vo.post.BookmarkYnWrapperVo; +import com.ftm.server.application.vo.post.PostIdAndBookmarkYnVo; import com.querydsl.core.Tuple; import java.util.List; import org.springframework.data.domain.Slice; @@ -19,4 +17,6 @@ public interface PostCustomRepository { List findAllByCreatedDateInOneWeekAndUserGrouping(FindPostsByCreatedDateQuery query); List findPostsByLatestCursor(FindUserPickLatestPostsByCursorQuery query); + + List findPostIdWithBookmarkYn(FindByPostIdsAndUserQuery query); } diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepositoryImpl.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepositoryImpl.java index 9100f38..2ceb80d 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepositoryImpl.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostCustomRepositoryImpl.java @@ -4,11 +4,9 @@ import static com.ftm.server.adapter.out.persistence.model.QPostJpaEntity.postJpaEntity; import com.ftm.server.adapter.out.persistence.model.PostJpaEntity; -import com.ftm.server.application.query.FindPostByDeleteOptionQuery; -import com.ftm.server.application.query.FindPostsByCreatedDateQuery; -import com.ftm.server.application.query.FindPostsByPagingQuery; -import com.ftm.server.application.query.FindUserPickLatestPostsByCursorQuery; +import com.ftm.server.application.query.*; import com.ftm.server.application.vo.post.BookmarkYnWrapperVo; +import com.ftm.server.application.vo.post.PostIdAndBookmarkYnVo; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.Tuple; import com.querydsl.core.types.Projections; @@ -129,4 +127,27 @@ public List findPostsByLatestCursor( .limit(query.getLimit() + 1) // hasNext 체크를 위해 +1 .fetch(); } + + @Override + public List findPostIdWithBookmarkYn(FindByPostIdsAndUserQuery query) { + + return queryFactory + .select( + Projections.constructor( + PostIdAndBookmarkYnVo.class, + postJpaEntity.id, + bookmarkJpaEntity.id.isNotNull())) + .from(postJpaEntity) + .leftJoin(bookmarkJpaEntity) + .on( + bookmarkJpaEntity + .post + .eq(postJpaEntity) + .and( + bookmarkJpaEntity.user.id.eq( + query.getUserId())) // 특정 user 북마크 여부 확인 + ) + .where(postJpaEntity.id.in(query.getPostIds())) + .fetch(); + } } diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostRepository.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostRepository.java index 01e88a7..0b2fba6 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostRepository.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostRepository.java @@ -2,7 +2,6 @@ import com.ftm.server.adapter.out.persistence.model.PostJpaEntity; import com.ftm.server.application.vo.post.PostAndBookmarkCountVo; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import java.time.LocalDateTime; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; @@ -29,7 +28,7 @@ public interface PostRepository @Query( value = """ - SELECT * + SELECT id FROM post p WHERE p.created_at >= :since ORDER BY @@ -39,12 +38,11 @@ public interface PostRepository LIMIT :limit """, nativeQuery = true) - List findTopNPostsByViewCountAndLikeCount( + List findTopNPostsByViewCountAndLikeCount( @Param("since") LocalDateTime since, @Param("limit") int limit); - @Query( - "select new com.ftm.server.application.vo.post.PostWithIdAndAuthorVo(p.id) from PostJpaEntity p order by p.likeCount DESC") - List findTopNPostsByLikeCount(@Param("limit") int limit); + @Query("select p.id from PostJpaEntity p order by p.likeCount DESC") + List findTopNPostsByLikeCount(@Param("limit") int limit); @Query( """ diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepository.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepository.java index c3d47bd..464094c 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepository.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepository.java @@ -3,7 +3,6 @@ import com.ftm.server.application.query.FindByIdsQuery; import com.ftm.server.application.query.FindPostsByCreatedDateQuery; import com.ftm.server.application.vo.post.PostWithBookmarkCountVo; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import com.ftm.server.application.vo.post.PostWithUserAndBookmarkCountVo; import com.ftm.server.application.vo.post.UserWithPostCountVo; import java.util.List; @@ -17,5 +16,5 @@ List findAllPostsWithUserAndBookmarkCount( List findAllPostsWithUserAndBookmarkCount(FindByIdsQuery query); - List findTopNPostsByBookmarkCount(int limit); + List findTopNPostsByBookmarkCount(int limit); } diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepositoryImpl.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepositoryImpl.java index 1452704..04e6a34 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepositoryImpl.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/PostWithBookmarkCustomRepositoryImpl.java @@ -6,7 +6,6 @@ import com.ftm.server.application.query.FindByIdsQuery; import com.ftm.server.application.query.FindPostsByCreatedDateQuery; import com.ftm.server.application.vo.post.PostWithBookmarkCountVo; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import com.ftm.server.application.vo.post.PostWithUserAndBookmarkCountVo; import com.ftm.server.application.vo.post.UserWithPostCountVo; import com.ftm.server.domain.enums.UserRole; @@ -118,9 +117,9 @@ public List findAllPostsWithUserAndBookmarkCount } @Override - public List findTopNPostsByBookmarkCount(int limit) { + public List findTopNPostsByBookmarkCount(int limit) { return queryFactory - .select(Projections.constructor(PostWithIdAndAuthorVo.class, postJpaEntity.id)) + .select(postJpaEntity.id) .from(postJpaEntity) .leftJoin(bookmarkJpaEntity) .on(bookmarkJpaEntity.post.eq(postJpaEntity)) diff --git a/src/main/java/com/ftm/server/application/port/in/post/GetUserPickPopularPostsUseCase.java b/src/main/java/com/ftm/server/application/port/in/post/GetUserPickPopularPostsUseCase.java index 8274abd..3036cc5 100644 --- a/src/main/java/com/ftm/server/application/port/in/post/GetUserPickPopularPostsUseCase.java +++ b/src/main/java/com/ftm/server/application/port/in/post/GetUserPickPopularPostsUseCase.java @@ -1,10 +1,11 @@ package com.ftm.server.application.port.in.post; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.application.vo.post.UserPickPopularPostsVo; import com.ftm.server.common.annotation.UseCase; import java.util.List; @UseCase public interface GetUserPickPopularPostsUseCase { - List execute(); + List execute(FindByUserIdQuery query); } diff --git a/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickBiblePostsUseCase.java b/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickBiblePostsUseCase.java index 7747141..a03733a 100644 --- a/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickBiblePostsUseCase.java +++ b/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickBiblePostsUseCase.java @@ -1,10 +1,11 @@ package com.ftm.server.application.port.in.post; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.application.vo.post.UserPickBiblePostsVo; import com.ftm.server.common.annotation.UseCase; import java.util.List; @UseCase public interface LoadUserPickBiblePostsUseCase { - List execute(); + List execute(FindByUserIdQuery query); } diff --git a/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickTopBookmarkPostsUseCase.java b/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickTopBookmarkPostsUseCase.java index a5052a5..dec8c6f 100644 --- a/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickTopBookmarkPostsUseCase.java +++ b/src/main/java/com/ftm/server/application/port/in/post/LoadUserPickTopBookmarkPostsUseCase.java @@ -1,8 +1,9 @@ package com.ftm.server.application.port.in.post; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.application.vo.post.LoadUserPickTopBookmarkPostsVo; import java.util.List; public interface LoadUserPickTopBookmarkPostsUseCase { - List execute(); + List execute(FindByUserIdQuery query); } diff --git a/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickBiblePostsWithCachePort.java b/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickBiblePostsWithCachePort.java index 23fa040..dd2a955 100644 --- a/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickBiblePostsWithCachePort.java +++ b/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickBiblePostsWithCachePort.java @@ -1,11 +1,10 @@ package com.ftm.server.application.port.out.cache; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import java.util.List; public interface LoadUserPickBiblePostsWithCachePort { - List getUserPickBiblePost(); + List getUserPickBiblePost(); - List getUserPickBiblePostCachePut(); + List getUserPickBiblePostCachePut(); } diff --git a/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickPopularWithCachePort.java b/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickPopularWithCachePort.java index dd3b797..56a9991 100644 --- a/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickPopularWithCachePort.java +++ b/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickPopularWithCachePort.java @@ -1,13 +1,12 @@ package com.ftm.server.application.port.out.cache; import com.ftm.server.common.annotation.Port; -import com.ftm.server.domain.entity.Post; import java.util.List; @Port public interface LoadUserPickPopularWithCachePort { - List getUserPickPopularPost(); + List getUserPickPopularPost(); - List getUserPickPopularPostCachePut(); + List getUserPickPopularPostCachePut(); } diff --git a/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickTopBookmarkPostsWithCachePort.java b/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickTopBookmarkPostsWithCachePort.java index eb7e1ff..619786c 100644 --- a/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickTopBookmarkPostsWithCachePort.java +++ b/src/main/java/com/ftm/server/application/port/out/cache/LoadUserPickTopBookmarkPostsWithCachePort.java @@ -1,11 +1,10 @@ package com.ftm.server.application.port.out.cache; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; import java.util.List; public interface LoadUserPickTopBookmarkPostsWithCachePort { - List getTopBookmarkPosts(); + List getTopBookmarkPosts(); - List getTopBookmarkPostsCachePut(); + List getTopBookmarkPostsCachePut(); } diff --git a/src/main/java/com/ftm/server/application/port/out/persistence/post/LoadPostPort.java b/src/main/java/com/ftm/server/application/port/out/persistence/post/LoadPostPort.java index b500d78..905d00e 100644 --- a/src/main/java/com/ftm/server/application/port/out/persistence/post/LoadPostPort.java +++ b/src/main/java/com/ftm/server/application/port/out/persistence/post/LoadPostPort.java @@ -2,7 +2,7 @@ import com.ftm.server.application.query.*; import com.ftm.server.application.vo.post.BookmarkYnWrapperVo; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; +import com.ftm.server.application.vo.post.PostIdAndBookmarkYnVo; import com.ftm.server.common.annotation.Port; import com.ftm.server.domain.entity.Post; import java.util.List; @@ -17,12 +17,14 @@ public interface LoadPostPort { List loadPostsByDeleteOption(FindPostByDeleteOptionQuery query); - List loadUserPickPopularPosts(FindUserPickPopularPostsQuery query); + List loadUserPickPopularPosts(FindUserPickPopularPostsQuery query); - List loadUserPickBiblePosts(FindUserPickBiblePostsQuery query); + List loadUserPickBiblePosts(FindUserPickBiblePostsQuery query); - List loadTopPostsByBookmarkCount(FindTopPostsByBookmarkCountQuery query); + List loadTopPostsByBookmarkCount(FindTopPostsByBookmarkCountQuery query); List loadUserPickAllPostsByLatest( FindUserPickLatestPostsByCursorQuery query); + + List loadPostIdAndBookmarkYn(FindByPostIdsAndUserQuery query); } diff --git a/src/main/java/com/ftm/server/application/query/FindByPostIdsAndUserQuery.java b/src/main/java/com/ftm/server/application/query/FindByPostIdsAndUserQuery.java new file mode 100644 index 0000000..3e2f28c --- /dev/null +++ b/src/main/java/com/ftm/server/application/query/FindByPostIdsAndUserQuery.java @@ -0,0 +1,16 @@ +package com.ftm.server.application.query; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class FindByPostIdsAndUserQuery { + List postIds; + Long userId; + + public static FindByPostIdsAndUserQuery of(List postIds, Long userId) { + return new FindByPostIdsAndUserQuery(postIds, userId); + } +} diff --git a/src/main/java/com/ftm/server/application/service/post/GetUserPickPopularPostsService.java b/src/main/java/com/ftm/server/application/service/post/GetUserPickPopularPostsService.java index 05b20c6..70cc9cd 100644 --- a/src/main/java/com/ftm/server/application/service/post/GetUserPickPopularPostsService.java +++ b/src/main/java/com/ftm/server/application/service/post/GetUserPickPopularPostsService.java @@ -1,21 +1,24 @@ package com.ftm.server.application.service.post; +import static java.util.stream.Collectors.toMap; + import com.ftm.server.application.port.in.post.GetUserPickPopularPostsUseCase; import com.ftm.server.application.port.out.cache.LoadUserPickPopularWithCachePort; import com.ftm.server.application.port.out.persistence.post.LoadPostImagePort; +import com.ftm.server.application.port.out.persistence.post.LoadPostPort; import com.ftm.server.application.port.out.persistence.post.LoadPostWithBookmarkCountPort; -import com.ftm.server.application.port.out.persistence.post.LoadUserForPostDomainPort; -import com.ftm.server.application.query.FindBookmarkCountByPostIdsQuery; import com.ftm.server.application.query.FindByIdsQuery; -import com.ftm.server.application.vo.post.PostAndBookmarkCountVo; -import com.ftm.server.application.vo.post.UserIdAndNameVo; -import com.ftm.server.application.vo.post.UserPickPopularPostsVo; +import com.ftm.server.application.query.FindByPostIdsAndUserQuery; +import com.ftm.server.application.query.FindByUserIdQuery; +import com.ftm.server.application.vo.post.*; import com.ftm.server.common.consts.PropertiesHolder; -import com.ftm.server.domain.entity.Post; import com.ftm.server.domain.entity.PostImage; import com.ftm.server.domain.enums.PostHashtag; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -28,81 +31,73 @@ public class GetUserPickPopularPostsService implements GetUserPickPopularPostsUs private final LoadPostWithBookmarkCountPort loadPostWithBookmarkCountPort; private final LoadPostImagePort loadPostImagePort; - private final LoadUserForPostDomainPort loadUserForPostDomainPort; + private final LoadPostPort loadPostPort; @Override - public List execute() { - - // 1) 상위 4개 게시물의 id 를 cache 에서 조회 - List postList = loadUserPickPopularWithCachePort.getUserPickPopularPost(); + public List execute(FindByUserIdQuery query) { - // 2) id 목록 - List postIds = postList.stream().map(Post::getId).toList(); - List authorIds = postList.stream().map(Post::getUserId).toList(); + // 상위 4개 게시물의 id 를 cache 에서 조회 + List postIdList = loadUserPickPopularWithCachePort.getUserPickPopularPost(); + if (postIdList.isEmpty()) return List.of(); + return convertToVo(postIdList, query.getUserId()); + } - // 3) 북마크(스크랩) 수 - List postAndBookmarkCountVos = - loadPostWithBookmarkCountPort.getPostAndBookmarkCount( - FindBookmarkCountByPostIdsQuery.of(postIds)); + private List convertToVo(List postIds, Long userId) { - var scrapCountMap = - postAndBookmarkCountVos.stream() - .collect( - java.util.stream.Collectors.toMap( - PostAndBookmarkCountVo::getPostId, - PostAndBookmarkCountVo::getBookmarkCount)); + // post 상세 조회 + Map detailPostMap = + loadPostWithBookmarkCountPort + .loadPostWithUserAndBookmarkCount(FindByIdsQuery.from(postIds)) + .stream() + .collect(toMap(PostWithUserAndBookmarkCountVo::getId, vo -> vo)); - // 4) 작성자 이름 - List userIdAndNameVos = - loadUserForPostDomainPort.loadPostAndAuthorName(FindByIdsQuery.from(authorIds)); - var authorNameMap = - userIdAndNameVos.stream() - .collect( - java.util.stream.Collectors.toMap( - UserIdAndNameVo::getUserId, - UserIdAndNameVo::getAuthorName, - (a, b) -> a // 중복 authorId 있을 경우 첫 값 사용 - )); + Map userBookmarkMap; + if (userId != null) { + userBookmarkMap = + loadPostPort + .loadPostIdAndBookmarkYn(FindByPostIdsAndUserQuery.of(postIds, userId)) + .stream() + .collect( + toMap( + PostIdAndBookmarkYnVo::getPostId, + PostIdAndBookmarkYnVo::getBookmarkYn)); + ; + } else { + userBookmarkMap = + postIds.stream().collect(Collectors.toMap(Function.identity(), id -> false)); + } - // 5) 대표 이미지 - List postImages = - loadPostImagePort.loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)); - var imageUrlMap = - postImages.stream() - .collect( - java.util.stream.Collectors.toMap( - PostImage::getPostId, - PostImage::getObjectKey, - (a, b) -> a // 중복 시 첫 이미지 - )); + // post 대표 이미지 조회 + Map imageUrlMap = + loadPostImagePort + .loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)) + .stream() + .collect(toMap(PostImage::getPostId, PostImage::getObjectKey, (a, b) -> a)); - // 6) 합치기 (postList 순서 = 랭킹) - return IntStream.range(0, postList.size()) + // 합치기 (postList 순서 = 랭킹) + return IntStream.range(0, postIds.size()) .mapToObj( i -> { - Post p = postList.get(i); + Long postId = postIds.get(i); + PostWithUserAndBookmarkCountVo p = detailPostMap.get(postId); int ranking = i + 1; - - long scrapCount = scrapCountMap.getOrDefault(p.getId(), 0L); - String authorName = authorNameMap.getOrDefault(p.getUserId(), ""); String imageUrl = imageUrlMap.getOrDefault( p.getId(), PropertiesHolder.POST_DEFAULT_IMAGE); // 없으면 null - List hashtags = - p.getHashtags() == null || p.getHashtags().length == 0 - ? List.of() - : Arrays.stream(p.getHashtags()) - .map(PostHashtag::getTag) - .toList(); return UserPickPopularPostsVo.of( ranking, p, - authorName, - scrapCount, PropertiesHolder.CDN_PATH + "/" + imageUrl, - hashtags); + toHashtagList(p.getHashtags()), + userBookmarkMap.get(postId)); }) .toList(); } + + private List toHashtagList(PostHashtag[] hashtags) { + return (hashtags == null || hashtags.length == 0) + ? List.of() + : Arrays.stream(hashtags).map(PostHashtag::getTag).toList(); + } } diff --git a/src/main/java/com/ftm/server/application/service/post/LoadUserPickBiblePostsService.java b/src/main/java/com/ftm/server/application/service/post/LoadUserPickBiblePostsService.java index 98029d3..c9ada7e 100644 --- a/src/main/java/com/ftm/server/application/service/post/LoadUserPickBiblePostsService.java +++ b/src/main/java/com/ftm/server/application/service/post/LoadUserPickBiblePostsService.java @@ -1,10 +1,15 @@ package com.ftm.server.application.service.post; +import static java.util.stream.Collectors.toMap; + import com.ftm.server.application.port.in.post.LoadUserPickBiblePostsUseCase; import com.ftm.server.application.port.out.cache.LoadUserPickBiblePostsWithCachePort; import com.ftm.server.application.port.out.persistence.post.LoadPostImagePort; +import com.ftm.server.application.port.out.persistence.post.LoadPostPort; import com.ftm.server.application.port.out.persistence.post.LoadPostWithBookmarkCountPort; import com.ftm.server.application.query.FindByIdsQuery; +import com.ftm.server.application.query.FindByPostIdsAndUserQuery; +import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.application.vo.post.*; import com.ftm.server.common.consts.PropertiesHolder; import com.ftm.server.domain.entity.PostImage; @@ -12,6 +17,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; @@ -25,36 +31,51 @@ public class LoadUserPickBiblePostsService implements LoadUserPickBiblePostsUseC private final LoadPostWithBookmarkCountPort loadPostWithBookmarkCountPort; private final LoadPostImagePort loadPostImagePort; + private final LoadPostPort loadPostPort; @Override - public List execute() { - // 1. 좋아요 누적 순으로 상위 4개의 게시물을 cache 에서 조회 - List postList = - loadUserPickBibleWithCachePort.getUserPickBiblePost(); + public List execute(FindByUserIdQuery query) { + // 좋아요 누적 순으로 상위 4개의 게시물을 cache 에서 조회 + List postIds = loadUserPickBibleWithCachePort.getUserPickBiblePost(); + + if (postIds.isEmpty()) return List.of(); + + return convertToVo(postIds, query.getUserId()); + } - // 2) id 목록 - List postIds = postList.stream().map(PostWithIdAndAuthorVo::getPostId).toList(); + private List convertToVo(List postIds, Long userId) { - // 3) post 상세 조회 + // post 상세 조회 Map detailPostMap = loadPostWithBookmarkCountPort .loadPostWithUserAndBookmarkCount(FindByIdsQuery.from(postIds)) .stream() - .collect(Collectors.toMap(PostWithUserAndBookmarkCountVo::getId, vo -> vo)); + .collect(toMap(PostWithUserAndBookmarkCountVo::getId, vo -> vo)); - // 4) 대표 이미지 - List postImages = - loadPostImagePort.loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)); - var imageUrlMap = - postImages.stream() - .collect( - java.util.stream.Collectors.toMap( - PostImage::getPostId, - PostImage::getObjectKey, - (a, b) -> a // 중복 시 첫 이미지 - )); + Map userBookmarkMap; + if (userId != null) { + userBookmarkMap = + loadPostPort + .loadPostIdAndBookmarkYn(FindByPostIdsAndUserQuery.of(postIds, userId)) + .stream() + .collect( + toMap( + PostIdAndBookmarkYnVo::getPostId, + PostIdAndBookmarkYnVo::getBookmarkYn)); + ; + } else { + userBookmarkMap = + postIds.stream().collect(Collectors.toMap(Function.identity(), id -> false)); + } - // 5) 합치기 (postList 순서 = 랭킹) + // post 대표 이미지 조회 + Map imageUrlMap = + loadPostImagePort + .loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)) + .stream() + .collect(toMap(PostImage::getPostId, PostImage::getObjectKey, (a, b) -> a)); + + // 합치기 (postList 순서 = 랭킹) return IntStream.range(0, postIds.size()) .mapToObj( i -> { @@ -65,18 +86,19 @@ public List execute() { imageUrlMap.getOrDefault( p.getId(), PropertiesHolder.POST_DEFAULT_IMAGE); // 없으면 null - List hashtags = - p.getHashtags() == null || p.getHashtags().length == 0 - ? List.of() - : Arrays.stream(p.getHashtags()) - .map(PostHashtag::getTag) - .toList(); return UserPickBiblePostsVo.of( ranking, p, PropertiesHolder.CDN_PATH + "/" + imageUrl, - hashtags); + toHashtagList(p.getHashtags()), + userBookmarkMap.get(postId)); }) .toList(); } + + private List toHashtagList(PostHashtag[] hashtags) { + return (hashtags == null || hashtags.length == 0) + ? List.of() + : Arrays.stream(hashtags).map(PostHashtag::getTag).toList(); + } } diff --git a/src/main/java/com/ftm/server/application/service/post/LoadUserPickTopBookmarkPostsService.java b/src/main/java/com/ftm/server/application/service/post/LoadUserPickTopBookmarkPostsService.java index d5558f7..acea0c4 100644 --- a/src/main/java/com/ftm/server/application/service/post/LoadUserPickTopBookmarkPostsService.java +++ b/src/main/java/com/ftm/server/application/service/post/LoadUserPickTopBookmarkPostsService.java @@ -1,17 +1,21 @@ package com.ftm.server.application.service.post; +import static java.util.stream.Collectors.toMap; + import com.ftm.server.application.port.in.post.LoadUserPickTopBookmarkPostsUseCase; import com.ftm.server.application.port.out.cache.LoadUserPickTopBookmarkPostsWithCachePort; import com.ftm.server.application.port.out.persistence.post.LoadPostImagePort; +import com.ftm.server.application.port.out.persistence.post.LoadPostPort; import com.ftm.server.application.port.out.persistence.post.LoadPostWithBookmarkCountPort; import com.ftm.server.application.query.FindByIdsQuery; -import com.ftm.server.application.vo.post.LoadUserPickTopBookmarkPostsVo; -import com.ftm.server.application.vo.post.PostWithIdAndAuthorVo; -import com.ftm.server.application.vo.post.PostWithUserAndBookmarkCountVo; +import com.ftm.server.application.query.FindByPostIdsAndUserQuery; +import com.ftm.server.application.query.FindByUserIdQuery; +import com.ftm.server.application.vo.post.*; import com.ftm.server.common.consts.PropertiesHolder; import com.ftm.server.domain.entity.PostImage; import com.ftm.server.domain.enums.PostHashtag; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; @@ -24,35 +28,51 @@ public class LoadUserPickTopBookmarkPostsService implements LoadUserPickTopBookm private final LoadUserPickTopBookmarkPostsWithCachePort cachePort; private final LoadPostWithBookmarkCountPort loadPostWithBookmarkCountPort; private final LoadPostImagePort loadPostImagePort; + private final LoadPostPort loadPostPort; @Override - public List execute() { + public List execute(FindByUserIdQuery query) { // 1) 캐시에서 상위 id 목록 조회 (4개) - List postList = cachePort.getTopBookmarkPosts(); - if (postList.isEmpty()) return List.of(); + List postIds = cachePort.getTopBookmarkPosts(); + + if (postIds.isEmpty()) return List.of(); + + return convertToVo(postIds, query.getUserId()); + } - // 2) id 목록 - List postIds = postList.stream().map(PostWithIdAndAuthorVo::getPostId).toList(); + private List convertToVo(List postIds, Long userId) { - // 3) 상세 조회 (유저/북마크 수 포함) + // post 상세 조회 Map detailPostMap = loadPostWithBookmarkCountPort .loadPostWithUserAndBookmarkCount(FindByIdsQuery.from(postIds)) .stream() - .collect(Collectors.toMap(PostWithUserAndBookmarkCountVo::getId, vo -> vo)); + .collect(toMap(PostWithUserAndBookmarkCountVo::getId, vo -> vo)); - // 4) 대표 이미지 - List postImages = - loadPostImagePort.loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)); + Map userBookmarkMap; + if (userId != null) { + userBookmarkMap = + loadPostPort + .loadPostIdAndBookmarkYn(FindByPostIdsAndUserQuery.of(postIds, userId)) + .stream() + .collect( + toMap( + PostIdAndBookmarkYnVo::getPostId, + PostIdAndBookmarkYnVo::getBookmarkYn)); + ; + } else { + userBookmarkMap = + postIds.stream().collect(Collectors.toMap(Function.identity(), id -> false)); + } + + // post 대표 이미지 조회 Map imageUrlMap = - postImages.stream() - .collect( - java.util.stream.Collectors.toMap( - PostImage::getPostId, - PostImage::getObjectKey, - (a, b) -> a)); + loadPostImagePort + .loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)) + .stream() + .collect(toMap(PostImage::getPostId, PostImage::getObjectKey, (a, b) -> a)); - // 5) 합치기 (postList 순서 = 랭킹) + // 합치기 (postList 순서 = 랭킹) return IntStream.range(0, postIds.size()) .mapToObj( i -> { @@ -61,19 +81,21 @@ public List execute() { int ranking = i + 1; String imageUrl = imageUrlMap.getOrDefault( - p.getId(), PropertiesHolder.POST_DEFAULT_IMAGE); - List hashtags = - p.getHashtags() == null || p.getHashtags().length == 0 - ? List.of() - : Arrays.stream(p.getHashtags()) - .map(PostHashtag::getTag) - .toList(); + p.getId(), + PropertiesHolder.POST_DEFAULT_IMAGE); // 없으면 null return LoadUserPickTopBookmarkPostsVo.of( ranking, p, PropertiesHolder.CDN_PATH + "/" + imageUrl, - hashtags); + toHashtagList(p.getHashtags()), + userBookmarkMap.get(postId)); }) .toList(); } + + private List toHashtagList(PostHashtag[] hashtags) { + return (hashtags == null || hashtags.length == 0) + ? List.of() + : Arrays.stream(hashtags).map(PostHashtag::getTag).toList(); + } } diff --git a/src/main/java/com/ftm/server/application/vo/post/LoadUserPickTopBookmarkPostsVo.java b/src/main/java/com/ftm/server/application/vo/post/LoadUserPickTopBookmarkPostsVo.java index 1354e0e..26c3f03 100644 --- a/src/main/java/com/ftm/server/application/vo/post/LoadUserPickTopBookmarkPostsVo.java +++ b/src/main/java/com/ftm/server/application/vo/post/LoadUserPickTopBookmarkPostsVo.java @@ -17,12 +17,14 @@ public class LoadUserPickTopBookmarkPostsVo { private final Long scrapCount; private final String imageUrl; private final List hashtags; + private final Boolean userBookmarkYn; public static LoadUserPickTopBookmarkPostsVo of( Integer ranking, PostWithUserAndBookmarkCountVo post, String imageUrl, - List hashtags) { + List hashtags, + Boolean userBookmarkYn) { return new LoadUserPickTopBookmarkPostsVo( ranking, post.getId(), @@ -33,6 +35,7 @@ public static LoadUserPickTopBookmarkPostsVo of( post.getLikeCount(), post.getScrapCount(), imageUrl, - hashtags); + hashtags, + userBookmarkYn); } } diff --git a/src/main/java/com/ftm/server/application/vo/post/PostIdAndBookmarkYnVo.java b/src/main/java/com/ftm/server/application/vo/post/PostIdAndBookmarkYnVo.java new file mode 100644 index 0000000..81a5433 --- /dev/null +++ b/src/main/java/com/ftm/server/application/vo/post/PostIdAndBookmarkYnVo.java @@ -0,0 +1,11 @@ +package com.ftm.server.application.vo.post; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PostIdAndBookmarkYnVo { + private final Long postId; + private final Boolean bookmarkYn; +} diff --git a/src/main/java/com/ftm/server/application/vo/post/UserPickBiblePostsVo.java b/src/main/java/com/ftm/server/application/vo/post/UserPickBiblePostsVo.java index 73fb3b7..0c6ea1c 100644 --- a/src/main/java/com/ftm/server/application/vo/post/UserPickBiblePostsVo.java +++ b/src/main/java/com/ftm/server/application/vo/post/UserPickBiblePostsVo.java @@ -17,12 +17,14 @@ public class UserPickBiblePostsVo { private final Long scrapCount; private final String imageUrl; private final List hashtags; + private final Boolean userBookmarkYn; public static UserPickBiblePostsVo of( Integer ranking, PostWithUserAndBookmarkCountVo post, String imageUrl, - List hashtags) { + List hashtags, + Boolean userBookmarkYn) { return new UserPickBiblePostsVo( ranking, post.getId(), @@ -33,6 +35,7 @@ public static UserPickBiblePostsVo of( post.getLikeCount(), post.getScrapCount(), imageUrl, - hashtags); + hashtags, + userBookmarkYn); } } diff --git a/src/main/java/com/ftm/server/application/vo/post/UserPickPopularPostsVo.java b/src/main/java/com/ftm/server/application/vo/post/UserPickPopularPostsVo.java index 3a524f8..35686a3 100644 --- a/src/main/java/com/ftm/server/application/vo/post/UserPickPopularPostsVo.java +++ b/src/main/java/com/ftm/server/application/vo/post/UserPickPopularPostsVo.java @@ -1,6 +1,5 @@ package com.ftm.server.application.vo.post; -import com.ftm.server.domain.entity.Post; import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; @@ -21,24 +20,25 @@ public class UserPickPopularPostsVo { private final Long scrapCount; private final String imageUrl; private final List hashtags; + private final Boolean userBookmarkYn; public static UserPickPopularPostsVo of( Integer ranking, - Post post, - String authorName, - Long scrapCount, + PostWithUserAndBookmarkCountVo post, String imageUrl, - List hashtags) { + List hashtags, + Boolean userBookmarkYn) { return new UserPickPopularPostsVo( ranking, post.getId(), post.getTitle(), post.getUserId(), - authorName, + post.getUserName(), post.getViewCount(), post.getLikeCount(), - scrapCount, + post.getScrapCount(), imageUrl, - hashtags); + hashtags, + userBookmarkYn); } } diff --git a/src/test/java/com/ftm/server/post/LoadUserPickBiblePostsTest.java b/src/test/java/com/ftm/server/post/LoadUserPickBiblePostsTest.java index 000ac57..ceea53c 100644 --- a/src/test/java/com/ftm/server/post/LoadUserPickBiblePostsTest.java +++ b/src/test/java/com/ftm/server/post/LoadUserPickBiblePostsTest.java @@ -56,7 +56,10 @@ public class LoadUserPickBiblePostsTest extends BaseTest { fieldWithPath("data[].imageUrl").type(STRING).description("이미지 url"), fieldWithPath("data[].hashtags") .type(ARRAY) - .description("게시글 해시태그 : 한글 태그 표시. 없는 경우 빈 배열([])로 표시")); + .description("게시글 해시태그 : 한글 태그 표시. 없는 경우 빈 배열([])로 표시"), + fieldWithPath("data[].userBookmarkYn") + .type(BOOLEAN) + .description("사용자 북마크 등록 여부")); private ResultActions getResultActions() throws Exception { return mockMvc.perform(RestDocumentationRequestBuilders.get("/api/posts/userpick/bible")); diff --git a/src/test/java/com/ftm/server/post/LoadUserPickPopularPostsTest.java b/src/test/java/com/ftm/server/post/LoadUserPickPopularPostsTest.java index c256451..3b06e73 100644 --- a/src/test/java/com/ftm/server/post/LoadUserPickPopularPostsTest.java +++ b/src/test/java/com/ftm/server/post/LoadUserPickPopularPostsTest.java @@ -55,7 +55,10 @@ public class LoadUserPickPopularPostsTest extends BaseTest { fieldWithPath("data[].imageUrl").type(STRING).description("이미지 url"), fieldWithPath("data[].hashtags") .type(ARRAY) - .description("게시글 해시태그 : 한글 태그 표시. 없는 경우 빈 배열([])로 표시")); + .description("게시글 해시태그 : 한글 태그 표시. 없는 경우 빈 배열([])로 표시"), + fieldWithPath("data[].userBookmarkYn") + .type(BOOLEAN) + .description("사용자 북마크 등록 여부")); private ResultActions getResultActions() throws Exception { return mockMvc.perform(RestDocumentationRequestBuilders.get("/api/posts/userpick/popular")); diff --git a/src/test/java/com/ftm/server/post/LoadUserPickTopBookmarkPostsTest.java b/src/test/java/com/ftm/server/post/LoadUserPickTopBookmarkPostsTest.java index 4b9e1a7..6aa758b 100644 --- a/src/test/java/com/ftm/server/post/LoadUserPickTopBookmarkPostsTest.java +++ b/src/test/java/com/ftm/server/post/LoadUserPickTopBookmarkPostsTest.java @@ -56,7 +56,10 @@ public class LoadUserPickTopBookmarkPostsTest extends BaseTest { fieldWithPath("data[].imageUrl").type(STRING).description("이미지 url"), fieldWithPath("data[].hashtags") .type(ARRAY) - .description("게시글 해시태그 : 한글 태그 표시. 없는 경우 빈 배열([])로 표시")); + .description("게시글 해시태그 : 한글 태그 표시. 없는 경우 빈 배열([])로 표시"), + fieldWithPath("data[].userBookmarkYn") + .type(BOOLEAN) + .description("사용자 북마크 등록 여부")); private ResultActions getResultActions() throws Exception { return mockMvc.perform(