From 67827ab488250486cb9dd66acf3c4b1ac629c738 Mon Sep 17 00:00:00 2001 From: ljy1348 Date: Wed, 17 Jun 2026 21:09:38 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[FEAT]=20=EC=86=8C=EC=84=A4=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EA=B2=80=EC=83=89=20=EC=8B=9C=20=ED=94=8C=EB=9E=AB?= =?UTF-8?q?=ED=8F=BC=20=ED=95=84=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /novels/filtered API에 platformNames(Array) 파라미터 추가 - platformNames가 존재하면 해당 플랫폼에 등록된 소설만 조회 - NovelGenre 조인을 INNER → LEFT JOIN으로 변경하여 플랫폼 없는 소설도 포함) --- .../WSSServer/controller/NovelController.java | 3 ++- .../org/websoso/WSSServer/novel/domain/Novel.java | 3 +++ .../org/websoso/WSSServer/novel/domain/Platform.java | 11 +++++++---- .../novel/repository/NovelCustomRepository.java | 2 +- .../novel/repository/NovelCustomRepositoryImpl.java | 12 ++++++++++-- .../WSSServer/novel/service/NovelServiceImpl.java | 4 ++-- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/websoso/WSSServer/controller/NovelController.java b/src/main/java/org/websoso/WSSServer/controller/NovelController.java index d44153cd..4ad848b5 100644 --- a/src/main/java/org/websoso/WSSServer/controller/NovelController.java +++ b/src/main/java/org/websoso/WSSServer/controller/NovelController.java @@ -84,12 +84,13 @@ public ResponseEntity getFilteredNovels( @RequestParam(required = false, defaultValue = "0.0") Float novelRatingStart, @RequestParam(required = false, defaultValue = "5.0") Float novelRatingEnd, @RequestParam(required = false) List keywordIds, + @RequestParam(required = false) List platformNames, @RequestParam int page, @RequestParam int size) { return ResponseEntity .status(OK) .body(searchNovelApplication.getFilteredNovels(genres, keywordIds, isCompleted, novelRating, - novelRatingStart, novelRatingEnd, page, size)); + novelRatingStart, novelRatingEnd, platformNames, page, size)); } /** diff --git a/src/main/java/org/websoso/WSSServer/novel/domain/Novel.java b/src/main/java/org/websoso/WSSServer/novel/domain/Novel.java index ab85e906..5b4d1913 100644 --- a/src/main/java/org/websoso/WSSServer/novel/domain/Novel.java +++ b/src/main/java/org/websoso/WSSServer/novel/domain/Novel.java @@ -47,6 +47,9 @@ public class Novel { @OneToMany(mappedBy = "novel", fetch = FetchType.LAZY) private List novelGenres = new ArrayList<>(); + @OneToMany(mappedBy = "novel", fetch = FetchType.LAZY) + private List novelPlatforms = new ArrayList<>(); + public String getFirstGenreName(){ return novelGenres.stream() .findFirst() diff --git a/src/main/java/org/websoso/WSSServer/novel/domain/Platform.java b/src/main/java/org/websoso/WSSServer/novel/domain/Platform.java index f397a0ee..c0ca7fe3 100644 --- a/src/main/java/org/websoso/WSSServer/novel/domain/Platform.java +++ b/src/main/java/org/websoso/WSSServer/novel/domain/Platform.java @@ -2,14 +2,14 @@ import static jakarta.persistence.GenerationType.IDENTITY; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.List; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -25,4 +25,7 @@ public class Platform { @Column(columnDefinition = "text", nullable = false) private String platformImage; + @OneToMany(mappedBy = "platform", fetch = FetchType.LAZY) + private List novelPlatforms = new ArrayList<>(); + } diff --git a/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepository.java b/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepository.java index a5a65963..34e66db2 100644 --- a/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepository.java +++ b/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepository.java @@ -11,7 +11,7 @@ public interface NovelCustomRepository { Page findSearchedNovels(Pageable pageable, String query); - Page findFilteredNovels(Pageable pageable, List genres, Boolean isCompleted, Float novelRatingStart, Float novelRatingEnd, List keywords); + Page findFilteredNovels(Pageable pageable, List genres, Boolean isCompleted, Float novelRatingStart, Float novelRatingEnd, List keywords, List platformNames); List findAutocompleteNovels(String searchQuery, int limitSize); diff --git a/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepositoryImpl.java b/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepositoryImpl.java index a745d0b6..fddac530 100644 --- a/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepositoryImpl.java +++ b/src/main/java/org/websoso/WSSServer/novel/repository/NovelCustomRepositoryImpl.java @@ -6,6 +6,8 @@ import static org.websoso.WSSServer.library.domain.QUserNovel.userNovel; import static org.websoso.WSSServer.novel.domain.QNovel.novel; import static org.websoso.WSSServer.novel.domain.QNovelGenre.novelGenre; +import static org.websoso.WSSServer.novel.domain.QNovelPlatform.novelPlatform; +import static org.websoso.WSSServer.novel.domain.QPlatform.platform; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.CaseBuilder; @@ -75,7 +77,7 @@ private StringTemplate getCleanedString(StringPath stringPath) { @Override public Page findFilteredNovels(Pageable pageable, List genres, Boolean isCompleted, Float novelRatingStart, - Float novelRatingEnd, List keywords) { + Float novelRatingEnd, List keywords, List platformNames) { NumberTemplate popularity = Expressions.numberTemplate(Long.class, "(SELECT COUNT(un) FROM UserNovel un WHERE un.novel = {0} AND (un.isInterest = true OR un.status <> 'QUIT'))", @@ -85,6 +87,8 @@ public Page findFilteredNovels(Pageable pageable, List genres, Boo .selectFrom(novel) .distinct() .join(novel.novelGenres, novelGenre) + .leftJoin(novel.novelPlatforms, novelPlatform) + .leftJoin(novelPlatform.platform, platform) .where( genres.isEmpty() ? null @@ -95,7 +99,11 @@ public Page findFilteredNovels(Pageable pageable, List genres, Boo getAverageRatingCondition(novel, novelRatingStart, novelRatingEnd), keywords.isEmpty() ? null - : getKeywordCount(novel, keywords).eq(keywords.size()) + : getKeywordCount(novel, keywords).eq(keywords.size()), + platformNames == null || platformNames.isEmpty() + ? null + : platform.platformName.in(platformNames) + ) .orderBy(popularity.desc()); diff --git a/src/main/java/org/websoso/WSSServer/novel/service/NovelServiceImpl.java b/src/main/java/org/websoso/WSSServer/novel/service/NovelServiceImpl.java index 92cea1f7..ede901ba 100644 --- a/src/main/java/org/websoso/WSSServer/novel/service/NovelServiceImpl.java +++ b/src/main/java/org/websoso/WSSServer/novel/service/NovelServiceImpl.java @@ -51,8 +51,8 @@ public List getAutocompleteNovels(String searchQuery, int getSize) { } public Page findFilteredNovels(PageRequest pageRequest, List genres, List keywords, - Boolean isCompleted, Float novelRatingStart, Float novelRatingEnd) { - return novelRepository.findFilteredNovels(pageRequest, genres, isCompleted, novelRatingStart, novelRatingEnd, keywords); + Boolean isCompleted, Float novelRatingStart, Float novelRatingEnd, List platformNames) { + return novelRepository.findFilteredNovels(pageRequest, genres, isCompleted, novelRatingStart, novelRatingEnd, keywords, platformNames); } public List getGenresByNovel(Novel novel) { From 9cd2d76e012a29b7e329c7be50517322a819d68f Mon Sep 17 00:00:00 2001 From: ljy1348 Date: Wed, 17 Jun 2026 21:26:10 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[FIX]=20SearchNovelApplication.java=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EB=B9=A0=EC=A7=84=EA=B1=B0=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 --- .../WSSServer/application/SearchNovelApplication.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/websoso/WSSServer/application/SearchNovelApplication.java b/src/main/java/org/websoso/WSSServer/application/SearchNovelApplication.java index 039587fa..dad8c894 100644 --- a/src/main/java/org/websoso/WSSServer/application/SearchNovelApplication.java +++ b/src/main/java/org/websoso/WSSServer/application/SearchNovelApplication.java @@ -100,7 +100,7 @@ public SearchedNovelsResponse searchNovels(User user, String query, int page, in //TODO: 추후 novelRating 제거 @Transactional(readOnly = true) - public FilteredNovelsResponse getFilteredNovels(List genreNames, List keywordIds, Boolean isCompleted, Float novelRating, Float novelRatingStart, Float novelRatingEnd, int page, int size) { + public FilteredNovelsResponse getFilteredNovels(List genreNames, List keywordIds, Boolean isCompleted, Float novelRating, Float novelRatingStart, Float novelRatingEnd, List platformNames, int page, int size) { PageRequest pageRequest = PageRequest.of(page, size); List genres = genreService.getGenresOrException(genreNames); @@ -110,9 +110,9 @@ public FilteredNovelsResponse getFilteredNovels(List genreNames, List novels; if (novelRating == null) { - novels = novelService.findFilteredNovels(pageRequest, genres, keywords, isCompleted, novelRatingStart, novelRatingEnd); + novels = novelService.findFilteredNovels(pageRequest, genres, keywords, isCompleted, novelRatingStart, novelRatingEnd, platformNames); } else { - novels = novelService.findFilteredNovels(pageRequest, genres, keywords, isCompleted, novelRating, novelRatingEnd); + novels = novelService.findFilteredNovels(pageRequest, genres, keywords, isCompleted, novelRating, novelRatingEnd, platformNames); } List novelGetResponsePreviews = novels.stream()