From 43662738fc7488ddcde03417599a7fc2c5eb9a1f Mon Sep 17 00:00:00 2001
From: Klaus <klaus@vividnext.co.kr>
Date: Mon, 14 Oct 2024 01:17:47 +0900
Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?=
 =?UTF-8?q?=EC=9D=B8=20-=20=EC=B6=94=EC=B2=9C=EC=8B=9C=EB=A6=AC=EC=A6=88,?=
 =?UTF-8?q?=20=EC=83=88=EB=A1=9C=EC=9A=B4=20=EC=BD=98=ED=85=90=EC=B8=A0,?=
 =?UTF-8?q?=20=ED=81=90=EB=A0=88=EC=9D=B4=EC=85=98=20-=20=EB=82=A8?=
 =?UTF-8?q?=EC=84=B1=ED=96=A5=EC=9D=B4=EB=A9=B4=20=EC=97=AC=EC=84=B1=20?=
 =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0,=20=EC=97=AC?=
 =?UTF-8?q?=EC=84=B1=ED=96=A5=EC=9D=B4=EB=A9=B4=20=EB=82=A8=EC=84=B1=20?=
 =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20=EC=9E=91?=
 =?UTF-8?q?=ED=92=88=EC=9D=B4=20=EC=A1=B0=ED=9A=8C=EB=90=98=EB=8F=84?=
 =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../content/AudioContentRepository.kt         | 23 +++++++++++--------
 .../content/main/AudioContentMainService.kt   |  3 ++-
 .../content/series/ContentSeriesController.kt | 11 ++++++++-
 .../content/series/ContentSeriesRepository.kt | 13 ++++++++---
 .../content/series/ContentSeriesService.kt    | 11 ++++++---
 .../theme/AudioContentThemeController.kt      |  5 ++++
 .../content/theme/AudioContentThemeService.kt |  9 ++++++--
 7 files changed, 55 insertions(+), 20 deletions(-)

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 a11b3be..e417a61 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt
@@ -64,7 +64,7 @@ interface AudioContentQueryRepository {
         theme: String = "",
         sortType: SortType = SortType.NEWEST,
         isAdult: Boolean = false,
-        contentType: ContentType = ContentType.ALL,
+        contentType: ContentType,
         offset: Long = 0,
         limit: Long = 20
     ): List<GetAudioContentMainItem>
@@ -72,7 +72,8 @@ interface AudioContentQueryRepository {
     fun totalCountByTheme(
         memberId: Long,
         theme: String = "",
-        isAdult: Boolean = false
+        isAdult: Boolean = false,
+        contentType: ContentType
     ): Int
 
     fun findByThemeFor2Weeks(
@@ -80,7 +81,7 @@ interface AudioContentQueryRepository {
         memberId: Long,
         theme: String = "",
         isAdult: Boolean = false,
-        contentType: ContentType = ContentType.ALL,
+        contentType: ContentType,
         offset: Long = 0,
         limit: Long = 20
     ): List<GetAudioContentMainItem>
@@ -89,7 +90,7 @@ interface AudioContentQueryRepository {
         theme: String,
         memberId: Long,
         isAdult: Boolean,
-        contentType: ContentType = ContentType.ALL
+        contentType: ContentType
     ): Int
 
     fun getNewContentUploadCreatorList(
@@ -103,7 +104,7 @@ interface AudioContentQueryRepository {
         curationId: Long,
         cloudfrontHost: String,
         isAdult: Boolean,
-        contentType: ContentType = ContentType.ALL
+        contentType: ContentType
     ): List<GetAudioContentMainItem>
 
     fun getAudioContentRanking(
@@ -374,7 +375,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
             if (contentType != ContentType.ALL) {
                 where = where.and(
                     audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1)
-                        .or(audioContent.isAdult.isFalse)
                 )
             }
         }
@@ -406,7 +406,7 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
             .fetch()
     }
 
-    override fun totalCountByTheme(memberId: Long, theme: String, isAdult: Boolean): Int {
+    override fun totalCountByTheme(memberId: Long, theme: String, isAdult: Boolean, contentType: ContentType): Int {
         var where = audioContent.isActive.isTrue
             .and(audioContent.duration.isNotNull)
             .and(
@@ -417,6 +417,12 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
 
         if (!isAdult) {
             where = where.and(audioContent.isAdult.isFalse)
+        } else {
+            if (contentType != ContentType.ALL) {
+                where = where.and(
+                    audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1)
+                )
+            }
         }
 
         if (theme.isNotBlank()) {
@@ -454,7 +460,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
             if (contentType != ContentType.ALL) {
                 where = where.and(
                     audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1)
-                        .or(audioContent.isAdult.isFalse)
                 )
             }
         }
@@ -497,7 +502,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
             if (contentType != ContentType.ALL) {
                 where = where.and(
                     audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1)
-                        .or(audioContent.isAdult.isFalse)
                 )
             }
         }
@@ -611,7 +615,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
             if (contentType != ContentType.ALL) {
                 where = where.and(
                     audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1)
-                        .or(audioContent.isAdult.isFalse)
                 )
             }
         }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt
index 73be372..db2c22a 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt
@@ -143,7 +143,8 @@ class AudioContentMainService(
     @Transactional(readOnly = true)
     @Cacheable(
         cacheNames = ["default"],
-        key = "'getAudioContentCurationListWithPaging:' + #memberId + ':' + #isAdult + ':' + #offset + ':' + #limit"
+        key = "'getAudioContentCurationListWithPaging:' + #memberId + ':' + #isAdult + ':' + #contentType" +
+            "+ ':' + #offset + ':' + #limit"
     )
     fun getAudioContentCurationListWithPaging(
         memberId: Long,
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt
index 9dffcfc..365e90d 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesController.kt
@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.series
 
 import kr.co.vividnext.sodalive.common.ApiResponse
 import kr.co.vividnext.sodalive.common.SodaException
+import kr.co.vividnext.sodalive.content.ContentType
 import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType
 import kr.co.vividnext.sodalive.member.Member
 import org.springframework.data.domain.Pageable
@@ -69,10 +70,18 @@ class ContentSeriesController(private val service: ContentSeriesService) {
 
     @GetMapping("/recommend")
     fun getRecommendSeriesList(
+        @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.getRecommendSeriesList(member = member))
+        ApiResponse.ok(
+            service.getRecommendSeriesList(
+                isAdultContentVisible = isAdultContentVisible ?: true,
+                contentType = contentType ?: ContentType.ALL,
+                member = member
+            )
+        )
     }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt
index cae0c84..7512aac 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesRepository.kt
@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.series
 
 import com.querydsl.core.types.dsl.Expressions
 import com.querydsl.jpa.impl.JPAQueryFactory
+import kr.co.vividnext.sodalive.content.ContentType
 import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
 import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag
 import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentMinMaxPriceResponse
@@ -27,7 +28,7 @@ interface ContentSeriesQueryRepository {
     fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series?
     fun getKeywordList(seriesId: Long): List<String>
     fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
-    fun getRecommendSeriesList(memberId: Long, isAuth: Boolean, limit: Long): List<Series>
+    fun getRecommendSeriesList(isAuth: Boolean, contentType: ContentType, limit: Long): List<Series>
 }
 
 class ContentSeriesQueryRepositoryImpl(
@@ -111,11 +112,17 @@ class ContentSeriesQueryRepositoryImpl(
             .fetchFirst()
     }
 
-    override fun getRecommendSeriesList(memberId: Long, isAuth: Boolean, limit: Long): List<Series> {
+    override fun getRecommendSeriesList(isAuth: Boolean, contentType: ContentType, limit: Long): List<Series> {
         var where = series.isActive.isTrue
 
         if (!isAuth) {
-            where = where.and(series.isAdult.isFalse)
+            where = where.and(audioContent.isAdult.isFalse)
+        } else {
+            if (contentType != ContentType.ALL) {
+                where = where.and(
+                    series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1)
+                )
+            }
         }
 
         return queryFactory
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt
index d9a1398..fb00156 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/ContentSeriesService.kt
@@ -1,6 +1,7 @@
 package kr.co.vividnext.sodalive.content.series
 
 import kr.co.vividnext.sodalive.common.SodaException
+import kr.co.vividnext.sodalive.content.ContentType
 import kr.co.vividnext.sodalive.content.order.OrderRepository
 import kr.co.vividnext.sodalive.content.order.OrderType
 import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository
@@ -155,10 +156,14 @@ class ContentSeriesService(
         return GetSeriesContentListResponse(totalCount, contentList)
     }
 
-    fun getRecommendSeriesList(member: Member): List<GetSeriesListResponse.SeriesListItem> {
+    fun getRecommendSeriesList(
+        isAdultContentVisible: Boolean,
+        contentType: ContentType,
+        member: Member
+    ): List<GetSeriesListResponse.SeriesListItem> {
         val seriesList = repository.getRecommendSeriesList(
-            memberId = member.id!!,
-            isAuth = member.auth != null,
+            isAuth = member.auth != null && isAdultContentVisible,
+            contentType = contentType,
             limit = 10
         ).filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!) }
 
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 a17ddfe..698985c 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
@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.theme
 
 import kr.co.vividnext.sodalive.common.ApiResponse
 import kr.co.vividnext.sodalive.common.SodaException
+import kr.co.vividnext.sodalive.content.ContentType
 import kr.co.vividnext.sodalive.content.SortType
 import kr.co.vividnext.sodalive.member.Member
 import org.springframework.data.domain.Pageable
@@ -30,6 +31,8 @@ class AudioContentThemeController(private val service: AudioContentThemeService)
     fun getContentByTheme(
         @PathVariable id: Long,
         @RequestParam("sort-type", required = false) sortType: SortType? = SortType.NEWEST,
+        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
+        @RequestParam("contentType", required = false) contentType: ContentType? = null,
         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
         pageable: Pageable
     ) = run {
@@ -39,6 +42,8 @@ class AudioContentThemeController(private val service: AudioContentThemeService)
             service.getContentByTheme(
                 themeId = id,
                 sortType = sortType ?: SortType.NEWEST,
+                isAdultContentVisible = isAdultContentVisible ?: true,
+                contentType = contentType ?: ContentType.ALL,
                 member = member,
                 offset = pageable.offset,
                 limit = pageable.pageSize.toLong()
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 64f600b..5a3c6a9 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
@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.theme
 
 import kr.co.vividnext.sodalive.common.SodaException
 import kr.co.vividnext.sodalive.content.AudioContentRepository
+import kr.co.vividnext.sodalive.content.ContentType
 import kr.co.vividnext.sodalive.content.SortType
 import kr.co.vividnext.sodalive.content.theme.content.GetContentByThemeResponse
 import kr.co.vividnext.sodalive.member.Member
@@ -28,6 +29,8 @@ class AudioContentThemeService(
     fun getContentByTheme(
         themeId: Long,
         sortType: SortType,
+        isAdultContentVisible: Boolean,
+        contentType: ContentType,
         member: Member,
         offset: Long,
         limit: Long
@@ -38,7 +41,8 @@ class AudioContentThemeService(
         val totalCount = contentRepository.totalCountByTheme(
             memberId = member.id!!,
             theme = theme.theme,
-            isAdult = member.auth != null
+            isAdult = member.auth != null && isAdultContentVisible,
+            contentType = contentType
         )
 
         val items = contentRepository.findByTheme(
@@ -46,7 +50,8 @@ class AudioContentThemeService(
             memberId = member.id!!,
             theme = theme.theme,
             sortType = sortType,
-            isAdult = member.auth != null,
+            isAdult = member.auth != null && isAdultContentVisible,
+            contentType = contentType,
             offset = offset,
             limit = limit
         )