From b6eb13df065691e21611bab548d4178ca8501035 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 20 Nov 2025 00:05:33 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat(content-sort-type):=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=A0=95=EB=A0=AC=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=9D=B8=EA=B8=B0=EC=88=9C(POPULARITY)=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/vividnext/sodalive/content/AudioContent.kt | 2 +- .../vividnext/sodalive/content/AudioContentRepository.kt | 7 +++++++ .../main/curation/AudioContentCurationQueryRepository.kt | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt index f65ece2..e08a830 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt @@ -23,7 +23,7 @@ enum class PurchaseOption { } enum class SortType { - NEWEST, PRICE_HIGH, PRICE_LOW + NEWEST, PRICE_HIGH, PRICE_LOW, POPULARITY } @Entity diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt index 8dbeaf4..a2b4dc1 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -241,6 +241,7 @@ class AudioContentQueryRepositoryImpl( SortType.NEWEST -> audioContent.releaseDate.desc() SortType.PRICE_HIGH -> audioContent.price.desc() SortType.PRICE_LOW -> audioContent.price.asc() + SortType.POPULARITY -> audioContent.playCount.desc() } var where = audioContent.member.id.eq(creatorId) @@ -462,6 +463,12 @@ class AudioContentQueryRepositoryImpl( audioContent.releaseDate.asc(), audioContent.id.asc() ) + + SortType.POPULARITY -> listOf( + audioContent.playCount.desc(), + audioContent.releaseDate.asc(), + audioContent.id.asc() + ) } var where = audioContent.isActive.isTrue diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt index 71ce651..1839851 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt @@ -58,6 +58,7 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact SortType.NEWEST -> audioContent.createdAt.desc() SortType.PRICE_HIGH -> audioContent.price.desc() SortType.PRICE_LOW -> audioContent.price.asc() + SortType.POPULARITY -> audioContent.playCount.desc() } var where = audioContent.isActive.isTrue -- 2.49.1 From 88d90eec2f71906e5075483d0454cbda86172a1f Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 20 Nov 2025 00:26:24 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat(content-sort-type):=20getLatestContent?= =?UTF-8?q?ByTheme(=ED=85=8C=EB=A7=88=EB=B3=84=20=EC=BD=98=ED=85=90?= =?UTF-8?q?=EC=B8=A0=20=EC=A1=B0=ED=9A=8C)=EC=8B=9C=20=EC=A0=95=EB=A0=AC?= =?UTF-8?q?=20=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/AudioContentController.kt | 5 ++++- .../content/AudioContentRepository.kt | 19 ++++++++++++++++++- .../sodalive/content/AudioContentService.kt | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt index ff15997..5cddb91 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt @@ -243,6 +243,8 @@ class AudioContentController(private val service: AudioContentService) { @RequestParam("contentType", required = false) contentType: ContentType? = null, @RequestParam("isFree", required = false) isFree: Boolean? = null, @RequestParam("isPointAvailableOnly", required = false) isPointAvailableOnly: Boolean? = null, + @RequestParam("sort-type", required = false) sortType: SortType? = SortType.NEWEST, + @RequestParam("theme", required = false) theme: String? = null, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, pageable: Pageable ) = run { @@ -250,10 +252,11 @@ class AudioContentController(private val service: AudioContentService) { ApiResponse.ok( service.getLatestContentByTheme( - theme = emptyList(), + theme = if (theme == null) listOf() else listOf(theme), contentType = contentType ?: ContentType.ALL, offset = pageable.offset, limit = pageable.pageSize.toLong(), + sortType = sortType ?: SortType.NEWEST, isFree = isFree ?: false, isAdult = (isAdultContentVisible ?: true) && member.auth != null, isPointAvailableOnly = isPointAvailableOnly ?: false diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt index a2b4dc1..c66539b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -180,6 +180,7 @@ interface AudioContentQueryRepository { contentType: ContentType, offset: Long, limit: Long, + sortType: SortType, isFree: Boolean, isAdult: Boolean, orderByRandom: Boolean = false, @@ -1304,6 +1305,7 @@ class AudioContentQueryRepositoryImpl( contentType: ContentType, offset: Long, limit: Long, + sortType: SortType, isFree: Boolean, isAdult: Boolean, orderByRandom: Boolean, @@ -1349,7 +1351,22 @@ class AudioContentQueryRepositoryImpl( val orderBy = if (orderByRandom) { Expressions.numberTemplate(Double::class.java, "function('rand')").asc() } else { - audioContent.releaseDate.desc() + when (sortType) { + SortType.NEWEST -> audioContent.releaseDate.desc() + SortType.PRICE_HIGH -> if (isFree) { + audioContent.releaseDate.desc() + } else { + audioContent.price.desc() + } + + SortType.PRICE_LOW -> if (isFree) { + audioContent.releaseDate.asc() + } else { + audioContent.price.desc() + } + + SortType.POPULARITY -> audioContent.playCount.desc() + } } return queryFactory diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index 23bca75..dfb4a0d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -988,6 +988,7 @@ class AudioContentService( contentType: ContentType, offset: Long = 0, limit: Long = 20, + sortType: SortType = SortType.NEWEST, isFree: Boolean = false, isAdult: Boolean = false, orderByRandom: Boolean = false, @@ -998,6 +999,7 @@ class AudioContentService( contentType = contentType, offset = offset, limit = limit, + sortType = sortType, isFree = isFree, isAdult = isAdult, orderByRandom = orderByRandom, -- 2.49.1 From 60989391f684415766a7b742113f7bb13b70b178 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 20 Nov 2025 00:51:09 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat(content-sort-type):=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=EA=B0=80=20=EC=9E=88=EB=8A=94=20active=20?= =?UTF-8?q?=ED=85=8C=EB=A7=88=20=EC=A1=B0=ED=9A=8C=20API=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 --- .../theme/AudioContentThemeController.kt | 20 +++++++++++++++++++ .../theme/AudioContentThemeQueryRepository.kt | 5 +++++ .../content/theme/AudioContentThemeService.kt | 2 ++ 3 files changed, 27 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeController.kt index 698985c..ef84371 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeController.kt @@ -27,6 +27,26 @@ class AudioContentThemeController(private val service: AudioContentThemeService) ApiResponse.ok(service.getThemes()) } + @GetMapping("/active") + fun getActiveThemes( + @RequestParam("isFree", required = false) isFree: Boolean? = null, + @RequestParam("isPointAvailableOnly", required = false) isPointAvailableOnly: Boolean? = null, + @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null, + @RequestParam("contentType", required = false) contentType: ContentType? = null, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok( + service.getActiveThemeOfContent( + isAdult = member.auth != null && (isAdultContentVisible ?: true), + isFree = isFree ?: false, + isPointAvailableOnly = isPointAvailableOnly ?: false, + contentType = contentType ?: ContentType.ALL + ) + ) + } + @GetMapping("/{id}/content") fun getContentByTheme( @PathVariable id: Long, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeQueryRepository.kt index 2eeb2ad..1ad1d65 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeQueryRepository.kt @@ -32,6 +32,7 @@ class AudioContentThemeQueryRepository( fun getActiveThemeOfContent( isAdult: Boolean = false, isFree: Boolean = false, + isPointAvailableOnly: Boolean = false, contentType: ContentType ): List { var where = audioContent.isActive.isTrue @@ -59,6 +60,10 @@ class AudioContentThemeQueryRepository( where = where.and(audioContent.price.loe(0)) } + if (isPointAvailableOnly) { + where = where.and(audioContent.isPointAvailable.isTrue) + } + return queryFactory .select(audioContentTheme.theme) .from(audioContent) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeService.kt index 6bafdcf..385b270 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/theme/AudioContentThemeService.kt @@ -23,11 +23,13 @@ class AudioContentThemeService( fun getActiveThemeOfContent( isAdult: Boolean = false, isFree: Boolean = false, + isPointAvailableOnly: Boolean = false, contentType: ContentType ): List { return queryRepository.getActiveThemeOfContent( isAdult = isAdult, isFree = isFree, + isPointAvailableOnly = isPointAvailableOnly, contentType = contentType ) } -- 2.49.1