From b3b3d46696d693385ef07b1e3b8aca8069d2adbe Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 18 Mar 2025 14:42:04 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=ED=99=88,=20=EB=AA=A8=EB=8B=9D=EC=BD=9C,=20asmr,?= =?UTF-8?q?=20=EB=8B=A8=ED=8E=B8,=20=EB=AC=B4=EB=A3=8C,=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=EB=93=A3=EA=B8=B0,=20=EC=8B=9C=EB=A6=AC=EC=A6=88=20-?= =?UTF-8?q?=2019=EA=B8=88=20=EC=BD=98=ED=85=90=EC=B8=A0=20(=EC=95=88)?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20=EC=84=A4=EC=A0=95=20-=20=EB=82=A8?= =?UTF-8?q?=EC=84=B1=ED=96=A5,=20=EC=97=AC=EC=84=B1=ED=96=A5=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=EB=A7=8C=20=EB=B3=B4=EA=B8=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/AudioContentRepository.kt | 44 +++++- .../main/AudioContentMainController.kt | 9 +- .../content/main/AudioContentMainService.kt | 29 ++-- .../main/tab/AudioContentMainTabRepository.kt | 48 ++++++- .../main/tab/RecommendSeriesRepository.kt | 23 +++- .../AudioContentMainTabAlarmController.kt | 15 +- .../alarm/AudioContentMainTabAlarmService.kt | 23 +++- .../asmr/AudioContentMainTabAsmrController.kt | 16 ++- .../asmr/AudioContentMainTabAsmrService.kt | 26 +++- .../AudioContentMainTabContentController.kt | 17 ++- .../AudioContentMainTabContentService.kt | 68 +++++---- .../ContentMainTabTagCurationRepository.kt | 35 ++++- .../ContentMainTabTagCurationService.kt | 13 +- .../free/AudioContentMainTabFreeController.kt | 19 ++- .../free/AudioContentMainTabFreeService.kt | 113 +++++++++------ .../home/AudioContentMainTabHomeController.kt | 16 ++- .../home/AudioContentMainTabHomeService.kt | 32 +++-- ...AudioContentMainTabLiveReplayController.kt | 16 ++- .../AudioContentMainTabLiveReplayService.kt | 26 +++- .../AudioContentMainTabSeriesController.kt | 31 ++++- .../AudioContentMainTabSeriesService.kt | 46 +++++-- .../content/series/ContentSeriesRepository.kt | 80 +++++++++-- .../content/series/ContentSeriesService.kt | 21 ++- .../theme/AudioContentThemeQueryRepository.kt | 13 +- .../sodalive/rank/RankingRepository.kt | 130 +++++++++++++++++- .../vividnext/sodalive/rank/RankingService.kt | 53 +++++-- 26 files changed, 777 insertions(+), 185 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 46a2a22..048a1b8 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -77,6 +77,7 @@ interface AudioContentQueryRepository { memberId: Long, theme: List, isAdult: Boolean = false, + contentType: ContentType, offset: Long = 0, limit: Long = 20 ): List @@ -84,7 +85,8 @@ interface AudioContentQueryRepository { fun totalAlarmCountByTheme( memberId: Long, theme: List, - isAdult: Boolean = false + isAdult: Boolean = false, + contentType: ContentType ): Int fun totalCountByTheme( @@ -130,6 +132,7 @@ interface AudioContentQueryRepository { curationId: Long, memberId: Long, isAdult: Boolean, + contentType: ContentType, offset: Long = 0, limit: Long = 20 ): List @@ -444,6 +447,7 @@ class AudioContentQueryRepositoryImpl( memberId: Long, theme: List, isAdult: Boolean, + contentType: ContentType, offset: Long, limit: Long ): List { @@ -464,6 +468,18 @@ class AudioContentQueryRepositoryImpl( 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.isNotEmpty()) { @@ -494,7 +510,12 @@ class AudioContentQueryRepositoryImpl( .fetch() } - override fun totalAlarmCountByTheme(memberId: Long, theme: List, isAdult: Boolean): Int { + override fun totalAlarmCountByTheme( + memberId: Long, + theme: List, + isAdult: Boolean, + contentType: ContentType + ): Int { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -510,6 +531,18 @@ class AudioContentQueryRepositoryImpl( 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.isNotEmpty()) { @@ -783,6 +816,7 @@ class AudioContentQueryRepositoryImpl( curationId: Long, memberId: Long, isAdult: Boolean, + contentType: ContentType, offset: Long, limit: Long ): List { @@ -801,6 +835,12 @@ class AudioContentQueryRepositoryImpl( 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) + ) + } } return queryFactory diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt index de06c18..3ff5f8d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt @@ -83,11 +83,18 @@ class AudioContentMainController( @GetMapping("/theme") fun getThemeList( + @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.getThemeList(isAdult = member.auth != null)) + ApiResponse.ok( + service.getThemeList( + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL + ) + ) } @GetMapping("/new/all") 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 f704c00..27add7d 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 @@ -26,8 +26,8 @@ class AudioContentMainService( ) { @Transactional(readOnly = true) @Cacheable(cacheNames = ["default"], key = "'themeList:' + ':' + #isAdult") - fun getThemeList(isAdult: Boolean): List { - return audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult) + fun getThemeList(isAdult: Boolean, contentType: ContentType): List { + return audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, contentType = contentType) .filter { it != "모닝콜" && it != "알람" && @@ -73,17 +73,20 @@ class AudioContentMainService( ): GetNewContentAllResponse { val isAdult = member.auth != null && isAdultContentVisible val themeList = if (theme.isBlank()) { - audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, isFree = isFree) - .filter { - it != "모닝콜" && - it != "알람" && - it != "슬립콜" && - it != "다시듣기" && - it != "ASMR" && - it != "릴레이" && - it != "챌린지" && - it != "자기소개" - } + audioContentThemeRepository.getActiveThemeOfContent( + isAdult = isAdult, + isFree = isFree, + contentType = contentType + ).filter { + it != "모닝콜" && + it != "알람" && + it != "슬립콜" && + it != "다시듣기" && + it != "ASMR" && + it != "릴레이" && + it != "챌린지" && + it != "자기소개" + } } else { listOf(theme) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt index 3604c0e..380158e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.main.tab 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.main.ContentCreatorResponse import kr.co.vividnext.sodalive.content.main.QContentCreatorResponse @@ -22,13 +23,15 @@ class AudioContentMainTabRepository( fun findCreatorByThemeContent( memberId: Long, theme: String, - minCount: Int + minCount: Int, + isAdult: Boolean, + contentType: ContentType ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) - val where = member.isActive.isTrue + var where = member.isActive.isTrue .and(member.role.eq(MemberRole.CREATOR)) .and(audioContent.isActive.isTrue) .and(audioContent.price.gt(0)) @@ -38,6 +41,22 @@ class AudioContentMainTabRepository( .and(audioContentTheme.theme.eq(theme)) .and(blockMember.id.isNull) + 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 + } + ) + ) + } + } + return queryFactory .select( QContentCreatorResponse( @@ -61,12 +80,17 @@ class AudioContentMainTabRepository( .fetch() } - fun findCreatorWithHasFreeContent(memberId: Long, minCount: Int): List { + fun findCreatorWithHasFreeContent( + memberId: Long, + minCount: Int, + isAdult: Boolean, + contentType: ContentType + ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) - val where = member.isActive.isTrue + var where = member.isActive.isTrue .and(member.role.eq(MemberRole.CREATOR)) .and(audioContent.isActive.isTrue) .and(audioContent.price.loe(0)) @@ -74,6 +98,22 @@ class AudioContentMainTabRepository( .and(audioContent.limited.isNull) .and(blockMember.id.isNull) + 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 + } + ) + ) + } + } + return queryFactory .select( QContentCreatorResponse( diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt index 97e5975..9ea6864 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.content.main.tab import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.main.tab.QRecommendSeries.recommendSeries import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.member.QMember.member @@ -14,13 +15,19 @@ class RecommendSeriesRepository( @Value("\${cloud.aws.cloud-front.host}") private val imageHost: String ) { - fun getNewSeriesList(isAdult: Boolean): List { + fun getNewSeriesList(isAdult: Boolean, contentType: ContentType): List { var where = recommendSeries.isActive.isTrue .and(recommendSeries.isFree.isFalse) .and(series.isActive.isTrue) if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + ) + } } return queryFactory @@ -42,13 +49,25 @@ class RecommendSeriesRepository( .fetch() } - fun getRecommendSeriesList(isAdult: Boolean): List { + fun getRecommendSeriesList(isAdult: Boolean, contentType: ContentType): List { var where = recommendSeries.isActive.isTrue .and(recommendSeries.isFree.isTrue) .and(series.isActive.isTrue) if (!isAdult) { where = where.and(series.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/main/tab/alarm/AudioContentMainTabAlarmController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmController.kt index 23b03bd..395ffb9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmController.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.main.tab.alarm 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.member.Member import org.springframework.data.domain.Pageable import org.springframework.security.core.annotation.AuthenticationPrincipal @@ -15,16 +16,26 @@ import org.springframework.web.bind.annotation.RestController class AudioContentMainTabAlarmController(private val service: AudioContentMainTabAlarmService) { @GetMapping fun fetchContentMainTabAlarm( + @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.fetchData(member)) + ApiResponse.ok( + service.fetchData( + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, + member + ) + ) } @GetMapping("/all") fun fetchAlarmContentByTheme( @RequestParam("theme") theme: String, + @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 { @@ -34,6 +45,8 @@ class AudioContentMainTabAlarmController(private val service: AudioContentMainTa service.fetchAlarmContentByTheme( theme, member, + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, offset = pageable.offset, limit = pageable.pageSize.toLong() ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmService.kt index 53e9eb2..b0d2061 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/alarm/AudioContentMainTabAlarmService.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.content.main.tab.alarm import kr.co.vividnext.sodalive.content.AudioContentRepository +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.main.GetNewContentAllResponse import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository @@ -21,8 +22,12 @@ class AudioContentMainTabAlarmService( private val eventService: EventService, private val curationRepository: AudioContentCurationQueryRepository ) { - fun fetchData(member: Member): GetContentMainTabAlarmResponse { - val isAdult = member.auth != null + fun fetchData( + isAdultContentVisible: Boolean, + contentType: ContentType, + member: Member + ): GetContentMainTabAlarmResponse { + val isAdult = member.auth != null && isAdultContentVisible val memberId = member.id!! val contentBannerList = bannerService.getBannerList( @@ -36,6 +41,7 @@ class AudioContentMainTabAlarmService( memberId = memberId, theme = alarmThemeList, isAdult = isAdult, + contentType = contentType, limit = 10 ) @@ -53,6 +59,7 @@ class AudioContentMainTabAlarmService( val rankAlarmContentList = rankingService.getContentRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = startDate, endDate = endDate, theme = alarmThemeList[0] @@ -66,10 +73,12 @@ class AudioContentMainTabAlarmService( items = contentRepository.findAudioContentByCurationIdV2( curationId = it.id!!, memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) ) } + .filter { it.items.isNotEmpty() } return GetContentMainTabAlarmResponse( contentBannerList = contentBannerList, @@ -84,6 +93,8 @@ class AudioContentMainTabAlarmService( fun fetchAlarmContentByTheme( theme: String, member: Member, + isAdultContentVisible: Boolean, + contentType: ContentType, offset: Long, limit: Long ): GetNewContentAllResponse { @@ -94,18 +105,20 @@ class AudioContentMainTabAlarmService( } val memberId = member.id!! - val isAdult = member.auth != null + val isAdult = member.auth != null && isAdultContentVisible val totalCount = contentRepository.totalAlarmCountByTheme( memberId = memberId, theme = alarmThemeList, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) val items = contentRepository.findAlarmContentByTheme( memberId = memberId, theme = alarmThemeList, isAdult = isAdult, + contentType = contentType, offset = offset, limit = limit ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrController.kt index 7714934..13a595f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrController.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.main.tab.asmr 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.member.Member import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.GetMapping @@ -14,16 +15,26 @@ import org.springframework.web.bind.annotation.RestController class AudioContentMainTabAsmrController(private val service: AudioContentMainTabAsmrService) { @GetMapping fun fetchContentMainTabAsmr( + @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.fetchData(member)) + ApiResponse.ok( + service.fetchData( + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, + member + ) + ) } @GetMapping("/popular-content-by-creator") fun getPopularContentByCreator( @RequestParam creatorId: Long, + @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("로그인 정보를 확인해주세요.") @@ -31,7 +42,8 @@ class AudioContentMainTabAsmrController(private val service: AudioContentMainTab ApiResponse.ok( service.getPopularContentByCreator( creatorId = creatorId, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrService.kt index b3094ac..0ddefb7 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/asmr/AudioContentMainTabAsmrService.kt @@ -21,8 +21,12 @@ class AudioContentMainTabAsmrService( private val eventService: EventService, private val curationRepository: AudioContentCurationQueryRepository ) { - fun fetchData(member: Member): GetContentMainTabAsmrResponse { - val isAdult = member.auth != null + fun fetchData( + isAdultContentVisible: Boolean, + contentType: ContentType, + member: Member + ): GetContentMainTabAsmrResponse { + val isAdult = member.auth != null && isAdultContentVisible val memberId = member.id!! val theme = "ASMR" val tabId = 5L @@ -37,20 +41,23 @@ class AudioContentMainTabAsmrService( memberId = memberId, theme = listOf(theme), isAdult = isAdult, - contentType = ContentType.ALL, + contentType = contentType, limit = 10 ) val creatorList = repository.findCreatorByThemeContent( memberId = memberId, theme = theme, - minCount = 4 + minCount = 4, + isAdult = isAdult, + contentType = contentType ) val salesCountRankContentList = if (creatorList.isNotEmpty()) { rankingService.fetchCreatorContentBySalesCountTop4( creatorId = creatorList[0].creatorId, isAdult = isAdult, + contentType = contentType, theme = theme ) } else { @@ -66,10 +73,12 @@ class AudioContentMainTabAsmrService( items = contentRepository.findAudioContentByCurationIdV2( curationId = it.id!!, memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) ) } + .filter { it.items.isNotEmpty() } return GetContentMainTabAsmrResponse( contentBannerList = contentBannerList, @@ -81,10 +90,15 @@ class AudioContentMainTabAsmrService( ) } - fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List { + fun getPopularContentByCreator( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { return rankingService.fetchCreatorContentBySalesCountTop4( creatorId = creatorId, isAdult = isAdult, + contentType = contentType, theme = "ASMR" ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentController.kt index 513bedb..d8209f4 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentController.kt @@ -34,6 +34,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain @GetMapping("/ranking") fun getAudioContentRanking( @RequestParam("sort-type", required = false) sortType: String?, + @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 { @@ -42,7 +44,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain ApiResponse.ok( service.getAudioContentRanking( memberId = member.id!!, - isAdult = member.auth != null, + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL, sortType = sortType ?: "매출" ) ) @@ -71,6 +74,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain @GetMapping("/popular-content-by-creator") fun getPopularContentByCreator( @RequestParam creatorId: Long, + @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("로그인 정보를 확인해주세요.") @@ -78,7 +83,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain ApiResponse.ok( service.getPopularContentByCreator( creatorId = creatorId, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } @@ -86,11 +92,16 @@ class AudioContentMainTabContentController(private val service: AudioContentMain @GetMapping("/recommend-content-by-tag") fun getRecommendedContentByTag( @RequestParam tag: String, + @RequestParam("contentType", required = false) contentType: ContentType? = null, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? ) = run { if (member == null) throw SodaException("로그인 정보를 확인해주세요.") ApiResponse.ok( - service.getRecommendedContentByTag(memberId = member.id!!, tag = tag) + service.getRecommendedContentByTag( + memberId = member.id!!, + tag = tag, + contentType = contentType ?: ContentType.ALL + ) ) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentService.kt index f84b518..9d8fd17 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/AudioContentMainTabContentService.kt @@ -30,7 +30,7 @@ class AudioContentMainTabContentService( member: Member ): GetContentMainTabContentResponse { val memberId = member.id!! - val isAdult = member.auth != null + val isAdult = member.auth != null && isAdultContentVisible val tabId = 3L // 단편 배너 @@ -41,24 +41,26 @@ class AudioContentMainTabContentService( ) // 새로운 단편 테마 - val themeOfContentList = audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult) - .filter { - it != "모닝콜" && - it != "알람" && - it != "슬립콜" && - it != "다시듣기" && - it != "ASMR" && - it != "릴레이" && - it != "챌린지" && - it != "자기소개" - } + val themeOfContentList = audioContentThemeRepository.getActiveThemeOfContent( + isAdult = isAdult, + contentType = contentType + ).filter { + it != "모닝콜" && + it != "알람" && + it != "슬립콜" && + it != "다시듣기" && + it != "ASMR" && + it != "릴레이" && + it != "챌린지" && + it != "자기소개" + } // 새로운 단편 val newContentList = audioContentRepository.findByTheme( memberId = member.id!!, theme = themeOfContentList, - isAdult = member.auth != null, - contentType = ContentType.ALL, + isAdult = isAdult, + contentType = contentType, offset = 0, limit = 10 ) @@ -76,6 +78,7 @@ class AudioContentMainTabContentService( val rankContentList = rankingService.getContentRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = dailyRankingStartDate, endDate = dailyRankingEndDate ) @@ -85,6 +88,7 @@ class AudioContentMainTabContentService( val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20( memberId = member.id!!, + contentType = contentType, startDate = dailyRankingStartDate, endDate = dailyRankingEndDate ) @@ -92,20 +96,25 @@ class AudioContentMainTabContentService( val likeCountRankContentList = if (contentRankCreatorList.isNotEmpty()) { rankingService.fetchCreatorContentByLikeCountTop4( creatorId = contentRankCreatorList[0].creatorId, - isAdult = member.auth != null + isAdult = isAdult, + contentType = contentType ) } else { emptyList() } val tagList = if (isAdult) { - tagCurationService.getTagList(isAdult = isAdult) + tagCurationService.getTagList(isAdult = isAdult, contentType = contentType) } else { emptyList() } val tagCurationContentList = if (tagList.isNotEmpty()) { - tagCurationService.getTagCurationContentList(memberId = memberId, tag = tagList[0]) + tagCurationService.getTagCurationContentList( + memberId = memberId, + tag = tagList[0], + contentType = contentType + ) } else { emptyList() } @@ -117,10 +126,12 @@ class AudioContentMainTabContentService( items = audioContentRepository.findAudioContentByCurationIdV2( curationId = it.id!!, memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) ) } + .filter { it.items.isNotEmpty() } return GetContentMainTabContentResponse( bannerList = contentBannerList, @@ -141,6 +152,7 @@ class AudioContentMainTabContentService( fun getAudioContentRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, sortType: String ): List { val currentDateTime = LocalDateTime.now() @@ -155,6 +167,7 @@ class AudioContentMainTabContentService( return rankingService.getContentRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = dailyRankingStartDate, endDate = dailyRankingEndDate, sortType = sortType @@ -170,7 +183,7 @@ class AudioContentMainTabContentService( val isAdult = member.auth != null && isAdultContentVisible val themeList = if (theme.isBlank()) { - audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult) + audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, contentType = contentType) .filter { it != "모닝콜" && it != "알람" && @@ -195,14 +208,23 @@ class AudioContentMainTabContentService( ) } - fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List { + fun getPopularContentByCreator( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { return rankingService.fetchCreatorContentByLikeCountTop4( creatorId = creatorId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) } - fun getRecommendedContentByTag(memberId: Long, tag: String): List { - return tagCurationService.getTagCurationContentList(memberId = memberId, tag = tag) + fun getRecommendedContentByTag( + memberId: Long, + tag: String, + contentType: ContentType + ): List { + return tagCurationService.getTagCurationContentList(memberId = memberId, tag = tag, contentType = contentType) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt index 3e7b85e..46b1501 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.content.main.tab.content 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.main.GetAudioContentMainItem import kr.co.vividnext.sodalive.content.main.QGetAudioContentMainItem @@ -18,7 +19,7 @@ class ContentMainTabTagCurationRepository( @Value("\${cloud.aws.cloud-front.host}") private val imageHost: String ) { - fun getTagList(isAdult: Boolean): List { + fun getTagList(isAdult: Boolean, contentType: ContentType): List { var where = contentHashTagCuration.isActive.isTrue .and(audioContent.isActive.isTrue) .and(audioContent.duration.isNotNull) @@ -27,6 +28,18 @@ class ContentMainTabTagCurationRepository( if (!isAdult) { where = where.and(contentHashTagCuration.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } } return queryFactory @@ -42,18 +55,34 @@ class ContentMainTabTagCurationRepository( .fetch() } - fun getTagCurationContentList(memberId: Long, tag: String): List { + fun getTagCurationContentList( + memberId: Long, + tag: String, + contentType: ContentType + ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) - val where = audioContent.isActive.isTrue + var where = audioContent.isActive.isTrue .and(audioContent.duration.isNotNull) .and(audioContent.limited.isNull) .and(blockMember.id.isNull) .and(contentHashTagCurationItem.isActive.isTrue) .and(contentHashTagCuration.tag.eq(tag)) + if (contentType != ContentType.ALL) { + where = where.and( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } + return queryFactory .select( QGetAudioContentMainItem( diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationService.kt index f95134d..4a73e88 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationService.kt @@ -1,15 +1,20 @@ package kr.co.vividnext.sodalive.content.main.tab.content +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem import org.springframework.stereotype.Service @Service class ContentMainTabTagCurationService(private val repository: ContentMainTabTagCurationRepository) { - fun getTagList(isAdult: Boolean): List { - return repository.getTagList(isAdult = isAdult) + fun getTagList(isAdult: Boolean, contentType: ContentType): List { + return repository.getTagList(isAdult = isAdult, contentType = contentType) } - fun getTagCurationContentList(memberId: Long, tag: String): List { - return repository.getTagCurationContentList(memberId = memberId, tag = tag) + fun getTagCurationContentList( + memberId: Long, + tag: String, + contentType: ContentType + ): List { + return repository.getTagCurationContentList(memberId = memberId, tag = tag, contentType = contentType) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeController.kt index 2547d48..e25411c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeController.kt @@ -16,15 +16,25 @@ import org.springframework.web.bind.annotation.RestController class AudioContentMainTabFreeController(private val service: AudioContentMainTabFreeService) { @GetMapping fun fetchContentMainFree( + @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.fetchData(member)) + ApiResponse.ok( + service.fetchData( + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, + member + ) + ) } @GetMapping("/introduce-creator") fun getIntroduceCreator( + @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 { @@ -33,6 +43,8 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab ApiResponse.ok( service.getIntroduceCreator( member, + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, offset = pageable.offset, limit = pageable.pageSize.toLong() ) @@ -64,6 +76,8 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab @GetMapping("/popular-content-by-creator") fun getPopularContentByCreator( @RequestParam creatorId: Long, + @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("로그인 정보를 확인해주세요.") @@ -71,7 +85,8 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab ApiResponse.ok( service.getPopularContentByCreator( creatorId = creatorId, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeService.kt index e9386b8..bbc8651 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/free/AudioContentMainTabFreeService.kt @@ -25,8 +25,12 @@ class AudioContentMainTabFreeService( private val audioContentRepository: AudioContentRepository, private val audioContentThemeRepository: AudioContentThemeQueryRepository ) { - fun fetchData(member: Member): GetContentMainTabFreeResponse { - val isAdult = member.auth != null + fun fetchData( + isAdultContentVisible: Boolean, + contentType: ContentType, + member: Member + ): GetContentMainTabFreeResponse { + val isAdult = member.auth != null && isAdultContentVisible val memberId = member.id!! val tabId = 7L @@ -40,37 +44,43 @@ class AudioContentMainTabFreeService( tabId = tabId, title = "크리에이터 소개", isAdult = isAdult - ) - .map { - GetContentCurationResponse( - title = it.title, - items = contentRepository.findAudioContentByCurationIdV2( - curationId = it.id!!, - memberId = memberId, - isAdult = isAdult - ) + ).map { + GetContentCurationResponse( + title = it.title, + items = contentRepository.findAudioContentByCurationIdV2( + curationId = it.id!!, + memberId = memberId, + isAdult = isAdult, + contentType = contentType ) - } + ) + }.filter { it.items.isNotEmpty() } - val recommendSeriesList = recommendSeriesRepository.getRecommendSeriesList(isAdult = isAdult) + val recommendSeriesList = recommendSeriesRepository.getRecommendSeriesList( + isAdult = isAdult, + contentType = contentType + ) - val themeList = audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, isFree = true) - .filter { - it != "모닝콜" && - it != "알람" && - it != "슬립콜" && - it != "다시듣기" && - it != "ASMR" && - it != "릴레이" && - it != "챌린지" && - it != "자기소개" - } + val themeList = audioContentThemeRepository.getActiveThemeOfContent( + isAdult = isAdult, + isFree = true, + contentType = contentType + ).filter { + it != "모닝콜" && + it != "알람" && + it != "슬립콜" && + it != "다시듣기" && + it != "ASMR" && + it != "릴레이" && + it != "챌린지" && + it != "자기소개" + } val newFreeContentList = if (themeList.isNotEmpty()) { audioContentRepository.findByTheme( memberId = member.id!!, theme = themeList, - isAdult = member.auth != null, - contentType = ContentType.ALL, + isAdult = isAdult, + contentType = contentType, offset = 0, limit = 10, isFree = true @@ -79,9 +89,9 @@ class AudioContentMainTabFreeService( emptyList() } - val creatorList = repository.findCreatorWithHasFreeContent(memberId, 4) + val creatorList = repository.findCreatorWithHasFreeContent(memberId, 4, isAdult, contentType) val playCountRankContentList = if (creatorList.isNotEmpty()) { - rankingService.fetchFreeContentByCreatorIdTop4(creatorList[0].creatorId, isAdult) + rankingService.fetchFreeContentByCreatorIdTop4(creatorList[0].creatorId, isAdult, contentType) } else { emptyList() } @@ -94,10 +104,12 @@ class AudioContentMainTabFreeService( items = contentRepository.findAudioContentByCurationIdV2( curationId = it.id!!, memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) ) } + .filter { it.items.isNotEmpty() } return GetContentMainTabFreeResponse( contentBannerList = contentBannerList, @@ -115,8 +127,14 @@ class AudioContentMainTabFreeService( ) } - fun getIntroduceCreator(member: Member, offset: Long, limit: Long): List { - val isAdult = member.auth != null + fun getIntroduceCreator( + member: Member, + isAdultContentVisible: Boolean, + contentType: ContentType, + offset: Long, + limit: Long + ): List { + val isAdult = member.auth != null && isAdultContentVisible val memberId = member.id!! val introduceCreatorCuration = curationRepository.findByContentMainTabIdAndTitle( @@ -130,6 +148,7 @@ class AudioContentMainTabFreeService( curationId = introduceCreatorCuration[0].id!!, memberId = memberId, isAdult = isAdult, + contentType = contentType, offset = offset, limit = limit ) @@ -153,18 +172,18 @@ class AudioContentMainTabFreeService( } else { audioContentThemeRepository.getActiveThemeOfContent( isAdult = member.auth != null && isAdultContentVisible, - isFree = true - ) - .filter { - it != "모닝콜" && - it != "알람" && - it != "슬립콜" && - it != "다시듣기" && - it != "ASMR" && - it != "릴레이" && - it != "챌린지" && - it != "자기소개" - } + isFree = true, + contentType = contentType + ).filter { + it != "모닝콜" && + it != "알람" && + it != "슬립콜" && + it != "다시듣기" && + it != "ASMR" && + it != "릴레이" && + it != "챌린지" && + it != "자기소개" + } }, isAdult = member.auth != null && isAdultContentVisible, contentType = contentType, @@ -174,7 +193,11 @@ class AudioContentMainTabFreeService( ) } - fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List { - return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult) + fun getPopularContentByCreator( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { + return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult, contentType) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeController.kt index 20d0bea..b2ca129 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeController.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.main.tab.home 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.member.Member import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.GetMapping @@ -14,16 +15,26 @@ import org.springframework.web.bind.annotation.RestController class AudioContentMainTabHomeController(private val service: AudioContentMainTabHomeService) { @GetMapping fun fetchContentMainHome( + @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.fetchData(member)) + ApiResponse.ok( + service.fetchData( + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, + member + ) + ) } @GetMapping("/popular-content-by-creator") fun getPopularContentByCreator( @RequestParam creatorId: Long, + @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("로그인 정보를 확인해주세요.") @@ -31,7 +42,8 @@ class AudioContentMainTabHomeController(private val service: AudioContentMainTab ApiResponse.ok( service.getPopularContentByCreator( creatorId = creatorId, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeService.kt index dd881b3..a748425 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/home/AudioContentMainTabHomeService.kt @@ -1,5 +1,6 @@ package kr.co.vividnext.sodalive.content.main.tab.home +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService import kr.co.vividnext.sodalive.event.EventService @@ -19,7 +20,11 @@ class AudioContentMainTabHomeService( private val rankingService: RankingService, private val eventService: EventService ) { - fun fetchData(member: Member): GetContentMainTabHomeResponse { + fun fetchData( + isAdultContentVisible: Boolean, + contentType: ContentType, + member: Member + ): GetContentMainTabHomeResponse { // 주간 랭킹 기간 val currentDateTime = LocalDateTime.now() val startDate = currentDateTime @@ -37,6 +42,8 @@ class AudioContentMainTabHomeService( val formattedLastMonday = startDate.format(startDateFormatter) val formattedLastSunday = endDate.format(endDateFormatter) + val isAdult = member.auth != null && isAdultContentVisible + // 최근 공지사항 val latestNotice = noticeService.getLatestNotice() @@ -44,7 +51,7 @@ class AudioContentMainTabHomeService( val contentBannerList = bannerService.getBannerList( tabId = 1, memberId = member.id!!, - isAdult = member.auth != null + isAdult = isAdult ) // 인기 크리에이터 @@ -56,7 +63,8 @@ class AudioContentMainTabHomeService( // 인기 시리즈 val rankSeriesList = rankingService.getSeriesRanking( memberId = member.id!!, - isAdult = member.auth != null, + isAdult = isAdult, + contentType = contentType, startDate = startDate.minusDays(1), endDate = endDate ) @@ -64,16 +72,18 @@ class AudioContentMainTabHomeService( // 인기 콘텐츠 val rankContentList = rankingService.getContentRanking( memberId = member.id!!, - isAdult = member.auth != null, + isAdult = isAdult, + contentType = contentType, startDate = startDate.minusDays(1), endDate = endDate ) // 이벤트 배너 - val eventBannerList = eventService.getEventList(isAdult = member.auth != null) + val eventBannerList = eventService.getEventList(isAdult = isAdult) val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20( memberId = member.id!!, + contentType = contentType, startDate = startDate.minusDays(1), endDate = endDate ) @@ -81,7 +91,8 @@ class AudioContentMainTabHomeService( val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) { rankingService.fetchCreatorContentBySalesCountTop4( creatorId = contentRankCreatorList[0].creatorId, - isAdult = member.auth != null + isAdult = isAdult, + contentType = contentType ) } else { emptyList() @@ -100,10 +111,15 @@ class AudioContentMainTabHomeService( ) } - fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List { + fun getPopularContentByCreator( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { return rankingService.fetchCreatorContentBySalesCountTop4( creatorId = creatorId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayController.kt index 17b7e38..5dbc6f9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayController.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.main.tab.replay 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.member.Member import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.GetMapping @@ -14,16 +15,26 @@ import org.springframework.web.bind.annotation.RestController class AudioContentMainTabLiveReplayController(private val service: AudioContentMainTabLiveReplayService) { @GetMapping fun fetchContentMainTabLiveReplay( + @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.fetchData(member)) + ApiResponse.ok( + service.fetchData( + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, + member + ) + ) } @GetMapping("/popular-content-by-creator") fun getPopularContentByCreator( @RequestParam creatorId: Long, + @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("로그인 정보를 확인해주세요.") @@ -31,7 +42,8 @@ class AudioContentMainTabLiveReplayController(private val service: AudioContentM ApiResponse.ok( service.getPopularContentByCreator( creatorId = creatorId, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayService.kt index 1be2c4a..77b4493 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/replay/AudioContentMainTabLiveReplayService.kt @@ -21,8 +21,12 @@ class AudioContentMainTabLiveReplayService( private val eventService: EventService, private val curationRepository: AudioContentCurationQueryRepository ) { - fun fetchData(member: Member): GetContentMainTabLiveReplayResponse { - val isAdult = member.auth != null + fun fetchData( + isAdultContentVisible: Boolean, + contentType: ContentType, + member: Member + ): GetContentMainTabLiveReplayResponse { + val isAdult = member.auth != null && isAdultContentVisible val memberId = member.id!! val theme = "다시듣기" val tabId = 6L @@ -37,20 +41,23 @@ class AudioContentMainTabLiveReplayService( memberId = memberId, theme = listOf(theme), isAdult = isAdult, - contentType = ContentType.ALL, + contentType = contentType, limit = 10 ) val creatorList = repository.findCreatorByThemeContent( memberId = memberId, theme = theme, - minCount = 4 + minCount = 4, + isAdult = isAdult, + contentType = contentType ) val salesCountRankContentList = if (creatorList.isNotEmpty()) { rankingService.fetchCreatorContentBySalesCountTop4( creatorId = creatorList[0].creatorId, isAdult = isAdult, + contentType = contentType, theme = theme ) } else { @@ -66,10 +73,12 @@ class AudioContentMainTabLiveReplayService( items = contentRepository.findAudioContentByCurationIdV2( curationId = it.id!!, memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) ) } + .filter { it.items.isNotEmpty() } return GetContentMainTabLiveReplayResponse( contentBannerList = contentBannerList, @@ -81,10 +90,15 @@ class AudioContentMainTabLiveReplayService( ) } - fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List { + fun getPopularContentByCreator( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { return rankingService.fetchCreatorContentBySalesCountTop4( creatorId = creatorId, isAdult = isAdult, + contentType = contentType, theme = "다시듣기" ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesController.kt index df62807..753e11b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesController.kt @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.content.main.tab.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.member.Member import org.springframework.data.domain.Pageable import org.springframework.security.core.annotation.AuthenticationPrincipal @@ -15,15 +16,25 @@ import org.springframework.web.bind.annotation.RestController class AudioContentMainTabSeriesController(private val service: AudioContentMainTabSeriesService) { @GetMapping fun fetchContentMainSeries( + @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.fetchData(member)) + ApiResponse.ok( + service.fetchData( + isAdultContentVisible = isAdultContentVisible ?: true, + contentType = contentType ?: ContentType.ALL, + member + ) + ) } @GetMapping("/original") fun getOriginalAudioDramaList( + @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 { @@ -32,7 +43,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT ApiResponse.ok( service.getOriginalAudioDramaList( memberId = member.id!!, - isAdult = member.auth != null, + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL, offset = pageable.offset, limit = pageable.pageSize.toLong() ) @@ -41,6 +53,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT @GetMapping("/completed-rank") fun getRank10DaysCompletedSeriesList( + @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 { @@ -49,7 +63,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT ApiResponse.ok( service.getRank10DaysCompletedSeriesList( memberId = member.id!!, - isAdult = member.auth != null, + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL, offset = pageable.offset, limit = pageable.pageSize.toLong() ) @@ -59,6 +74,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT @GetMapping("/recommend-by-genre") fun getRecommendSeriesListByGenre( @RequestParam genreId: Long, + @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("로그인 정보를 확인해주세요.") @@ -67,7 +84,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT service.getRecommendSeriesListByGenre( genreId, memberId = member.id!!, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } @@ -75,6 +93,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT @GetMapping("/recommend-series-by-creator") fun getRecommendSeriesByCreator( @RequestParam creatorId: Long, + @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("로그인 정보를 확인해주세요.") @@ -82,7 +102,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT ApiResponse.ok( service.getRecommendSeriesByCreator( creatorId = creatorId, - isAdult = member.auth != null + isAdult = member.auth != null && (isAdultContentVisible ?: true), + contentType = contentType ?: ContentType.ALL ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesService.kt index 3b29ee0..692f04d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/series/AudioContentMainTabSeriesService.kt @@ -1,5 +1,6 @@ package kr.co.vividnext.sodalive.content.main.tab.series +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository import kr.co.vividnext.sodalive.content.main.tab.RecommendSeriesRepository @@ -24,8 +25,12 @@ class AudioContentMainTabSeriesService( private val eventService: EventService, private val curationRepository: AudioContentCurationQueryRepository ) { - fun fetchData(member: Member): GetContentMainTabSeriesResponse { - val isAdult = member.auth != null + fun fetchData( + isAdultContentVisible: Boolean, + contentType: ContentType, + member: Member + ): GetContentMainTabSeriesResponse { + val isAdult = member.auth != null && isAdultContentVisible val memberId = member.id!! // 메인 배너 (시리즈) @@ -38,6 +43,7 @@ class AudioContentMainTabSeriesService( val originalAudioDrama = seriesService.getOriginalAudioDramaList( memberId = memberId, isAdult = isAdult, + contentType = contentType, offset = 0, limit = 20 ) @@ -55,18 +61,20 @@ class AudioContentMainTabSeriesService( val rankSeriesList = rankingService.getSeriesRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = dailyRankingStartDate, endDate = dailyRankingEndDate ) // 시리즈 장르 - val genreList = seriesService.getGenreList(memberId = memberId, isAdult = isAdult) + val genreList = seriesService.getGenreList(memberId = memberId, isAdult = isAdult, contentType = contentType) // 장르별 추천 시리즈 val recommendSeriesList = if (genreList.isNotEmpty()) { rankingService.getSeriesAllRankingByGenre( memberId = memberId, isAdult = isAdult, + contentType = contentType, genreId = genreList[0].id ) } else { @@ -74,13 +82,14 @@ class AudioContentMainTabSeriesService( } // 새로운 시리즈 - val newSeriesList = recommendSeriesRepository.getNewSeriesList(isAdult = isAdult) + val newSeriesList = recommendSeriesRepository.getNewSeriesList(isAdult = isAdult, contentType = contentType) val (completedRankStartDate, completedRankEndDate) = calculateStartAndEndDate() val rankCompleteSeriesList = rankingService.getCompleteSeriesRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = completedRankStartDate, endDate = completedRankEndDate ) @@ -96,6 +105,7 @@ class AudioContentMainTabSeriesService( val seriesRankCreatorList = rankingService.fetchCreatorBySeriesRevenueRankTop20( memberId = memberId, + contentType = contentType, startDate = startDate.minusDays(1), endDate = endDate ) @@ -103,7 +113,8 @@ class AudioContentMainTabSeriesService( val salesRankContentList = if (seriesRankCreatorList.isNotEmpty()) { rankingService.fetchCreatorSeriesBySales( creatorId = seriesRankCreatorList[0].creatorId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) } else { emptyList() @@ -120,7 +131,8 @@ class AudioContentMainTabSeriesService( items = seriesService.fetchSeriesByCurationId( curationId = it.id!!, memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) ) } @@ -148,13 +160,15 @@ class AudioContentMainTabSeriesService( fun getOriginalAudioDramaList( memberId: Long, isAdult: Boolean, + contentType: ContentType, offset: Long, limit: Long ): GetSeriesListResponse { - val totalCount = seriesService.getOriginalAudioDramaTotalCount(memberId, isAdult) + val totalCount = seriesService.getOriginalAudioDramaTotalCount(memberId, isAdult, contentType) val items = seriesService.getOriginalAudioDramaList( memberId = memberId, isAdult = isAdult, + contentType = contentType, offset = offset, limit = limit ) @@ -165,6 +179,7 @@ class AudioContentMainTabSeriesService( fun getRank10DaysCompletedSeriesList( memberId: Long, isAdult: Boolean, + contentType: ContentType, offset: Long, limit: Long ): GetSeriesListResponse { @@ -172,12 +187,14 @@ class AudioContentMainTabSeriesService( val totalCount = rankingService.getCompleteSeriesRankingTotalCount( memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) val items = rankingService.getCompleteSeriesRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = startDate, endDate = endDate, offset = offset, @@ -190,19 +207,26 @@ class AudioContentMainTabSeriesService( fun getRecommendSeriesListByGenre( genreId: Long, memberId: Long, - isAdult: Boolean + isAdult: Boolean, + contentType: ContentType ): List { return rankingService.getSeriesAllRankingByGenre( memberId = memberId, isAdult = isAdult, + contentType = contentType, genreId = genreId ) } - fun getRecommendSeriesByCreator(creatorId: Long, isAdult: Boolean): List { + fun getRecommendSeriesByCreator( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { return rankingService.fetchCreatorSeriesBySales( creatorId = creatorId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) } 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 0dd3803..0d09e67 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 @@ -35,10 +35,17 @@ interface ContentSeriesQueryRepository { fun getKeywordList(seriesId: Long): List fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse fun getRecommendSeriesList(isAuth: Boolean, contentType: ContentType, limit: Long): List - fun getOriginalAudioDramaList(memberId: Long, isAdult: Boolean, offset: Long = 0, limit: Long = 20): List - fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean): Int - fun getGenreList(isAdult: Boolean, memberId: Long): List - fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean): List + fun getOriginalAudioDramaList( + memberId: Long, + isAdult: Boolean, + contentType: ContentType, + offset: Long = 0, + limit: Long = 20 + ): List + + fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean, contentType: ContentType): Int + fun getGenreList(isAdult: Boolean, memberId: Long, contentType: ContentType): List + fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean, contentType: ContentType): List } class ContentSeriesQueryRepositoryImpl( @@ -144,7 +151,13 @@ class ContentSeriesQueryRepositoryImpl( .fetch() } - override fun getOriginalAudioDramaList(memberId: Long, isAdult: Boolean, offset: Long, limit: Long): List { + override fun getOriginalAudioDramaList( + memberId: Long, + isAdult: Boolean, + contentType: ContentType, + offset: Long, + limit: Long + ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -155,6 +168,18 @@ class ContentSeriesQueryRepositoryImpl( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } } return queryFactory @@ -168,7 +193,7 @@ class ContentSeriesQueryRepositoryImpl( .fetch() } - override fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean): Int { + override fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean, contentType: ContentType): Int { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -179,6 +204,18 @@ class ContentSeriesQueryRepositoryImpl( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } } return queryFactory @@ -191,7 +228,11 @@ class ContentSeriesQueryRepositoryImpl( .size } - override fun getGenreList(isAdult: Boolean, memberId: Long): List { + override fun getGenreList( + isAdult: Boolean, + memberId: Long, + contentType: ContentType + ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -209,6 +250,18 @@ class ContentSeriesQueryRepositoryImpl( if (!isAdult) { where = where.and(seriesGenre.isAdult.isFalse) .and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } } return queryFactory @@ -225,7 +278,12 @@ class ContentSeriesQueryRepositoryImpl( .fetch() } - override fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean): List { + override fun findByCurationId( + curationId: Long, + memberId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -239,6 +297,12 @@ class ContentSeriesQueryRepositoryImpl( if (!isAdult) { where = where.and(series.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 c0409d8..6ff5ae9 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 @@ -30,22 +30,23 @@ class ContentSeriesService( @Value("\${cloud.aws.cloud-front.host}") private val coverImageHost: String ) { - fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean): Int { - return repository.getOriginalAudioDramaTotalCount(memberId, isAdult) + fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean, contentType: ContentType): Int { + return repository.getOriginalAudioDramaTotalCount(memberId, isAdult, contentType) } fun getOriginalAudioDramaList( memberId: Long, isAdult: Boolean, + contentType: ContentType, offset: Long = 0, limit: Long = 20 ): List { - val originalAudioDramaList = repository.getOriginalAudioDramaList(memberId, isAdult, offset, limit) + val originalAudioDramaList = repository.getOriginalAudioDramaList(memberId, isAdult, contentType, offset, limit) return seriesToSeriesListItem(originalAudioDramaList, isAdult) } - fun getGenreList(memberId: Long, isAdult: Boolean): List { - return repository.getGenreList(memberId = memberId, isAdult = isAdult) + fun getGenreList(memberId: Long, isAdult: Boolean, contentType: ContentType): List { + return repository.getGenreList(memberId = memberId, isAdult = isAdult, contentType = contentType) } fun getSeriesList( @@ -191,9 +192,15 @@ class ContentSeriesService( fun fetchSeriesByCurationId( curationId: Long, memberId: Long, - isAdult: Boolean + isAdult: Boolean, + contentType: ContentType ): List { - val seriesList = repository.findByCurationId(curationId = curationId, memberId = memberId, isAdult = isAdult) + val seriesList = repository.findByCurationId( + curationId = curationId, + memberId = memberId, + isAdult = isAdult, + contentType = contentType + ) return seriesToSeriesListItem(seriesList, isAdult) } 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 c95f4c4..a3e1d1f 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 @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.content.theme 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.theme.QAudioContentTheme.audioContentTheme import org.springframework.beans.factory.annotation.Value @@ -27,12 +28,22 @@ class AudioContentThemeQueryRepository( .fetch() } - fun getActiveThemeOfContent(isAdult: Boolean = false, isFree: Boolean = false): List { + fun getActiveThemeOfContent( + isAdult: Boolean = false, + isFree: Boolean = false, + contentType: ContentType + ): List { var where = audioContent.isActive.isTrue .and(audioContentTheme.isActive.isTrue) 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) + ) + } } where = if (isFree) { diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt index 9f4ff0f..89fb7a9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt @@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.rank import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike @@ -44,6 +45,7 @@ class RankingRepository( fun getAudioContentRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime, offset: Long, @@ -66,6 +68,18 @@ class RankingRepository( 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()) { @@ -167,6 +181,7 @@ class RankingRepository( fun getSeriesRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime ): List { @@ -188,6 +203,18 @@ class RankingRepository( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } } return queryFactory @@ -209,7 +236,7 @@ class RankingRepository( .fetch() } - fun getCompleteSeriesRankingTotalCount(memberId: Long, isAdult: Boolean): Int { + fun getCompleteSeriesRankingTotalCount(memberId: Long, isAdult: Boolean, contentType: ContentType): Int { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -226,6 +253,18 @@ class RankingRepository( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } } return queryFactory @@ -244,6 +283,7 @@ class RankingRepository( fun getCompleteSeriesRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime, offset: Long, @@ -270,6 +310,12 @@ class RankingRepository( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + ) + } } return queryFactory @@ -288,7 +334,12 @@ class RankingRepository( .fetch() } - fun getSeriesAllRankingByGenre(memberId: Long, isAdult: Boolean, genreId: Long): List { + fun getSeriesAllRankingByGenre( + memberId: Long, + isAdult: Boolean, + contentType: ContentType, + genreId: Long + ): List { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.isActive.isTrue) .and(blockMember.blockedMember.id.eq(memberId)) @@ -306,6 +357,12 @@ class RankingRepository( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + ) + } } return queryFactory @@ -330,6 +387,7 @@ class RankingRepository( fun fetchCreatorBySellContentCountRankTop20( memberId: Long, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime ): List { @@ -342,10 +400,22 @@ class RankingRepository( .and(order.createdAt.goe(startDate)) .and(order.createdAt.lt(endDate)) - val memberCondition = member.isActive.isTrue + var memberCondition = member.isActive.isTrue .and(member.role.eq(MemberRole.CREATOR)) .and(member.id.eq(audioContent.member.id)) + if (contentType != ContentType.ALL) { + memberCondition = memberCondition.and( + member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) + } + val where = audioContent.isActive.isTrue .and(audioContent.price.gt(0)) .and(audioContent.duration.isNotNull) @@ -376,6 +446,7 @@ class RankingRepository( fun fetchCreatorContentBySalesCountTop4( creatorId: Long, isAdult: Boolean, + contentType: ContentType, theme: String ): List { var where = member.isActive.isTrue @@ -389,6 +460,12 @@ class RankingRepository( 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()) { @@ -423,6 +500,7 @@ class RankingRepository( fun fetchCreatorBySeriesRevenueRankTop20( memberId: Long, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime ): List { @@ -435,7 +513,7 @@ class RankingRepository( .and(order.createdAt.goe(startDate)) .and(order.createdAt.lt(startDate)) - val where = member.isActive.isTrue + var where = member.isActive.isTrue .and(member.role.eq(MemberRole.CREATOR)) .and(series.isActive.isTrue) .and(audioContent.isActive.isTrue) @@ -443,6 +521,12 @@ class RankingRepository( .and(audioContent.limited.isNull) .and(blockMember.id.isNull) + if (contentType != ContentType.ALL) { + where = where.and( + audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + ) + } + return queryFactory .select( QContentCreatorResponse( @@ -469,7 +553,7 @@ class RankingRepository( .fetch() } - fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List { + fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean, contentType: ContentType): List { var where = member.isActive.isTrue .and(member.role.eq(MemberRole.CREATOR)) .and(series.isActive.isTrue) @@ -481,6 +565,12 @@ class RankingRepository( if (!isAdult) { where = where.and(series.isAdult.isFalse) + } else { + if (contentType != ContentType.ALL) { + where = where.and( + series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + ) + } } return queryFactory @@ -501,7 +591,11 @@ class RankingRepository( .fetch() } - fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List { + fun fetchFreeContentByCreatorIdTop4( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { var where = member.isActive.isTrue .and(member.id.eq(creatorId)) .and(member.role.eq(MemberRole.CREATOR)) @@ -512,6 +606,18 @@ class RankingRepository( 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 + } + ) + ) + } } return queryFactory @@ -538,7 +644,11 @@ class RankingRepository( .fetch() } - fun fetchCreatorContentByLikeCountTop4(creatorId: Long, isAdult: Boolean): List { + fun fetchCreatorContentByLikeCountTop4( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { var where = member.isActive.isTrue .and(member.id.eq(creatorId)) .and(member.role.eq(MemberRole.CREATOR)) @@ -550,6 +660,12 @@ class RankingRepository( 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) + ) + } } return queryFactory diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingService.kt index b114ae9..e921c34 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingService.kt @@ -1,5 +1,6 @@ package kr.co.vividnext.sodalive.rank +import kr.co.vividnext.sodalive.content.ContentType import kr.co.vividnext.sodalive.content.main.ContentCreatorResponse import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse @@ -40,6 +41,7 @@ class RankingService( fun getContentRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime, offset: Long = 0, @@ -50,6 +52,7 @@ class RankingService( return repository.getAudioContentRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = startDate, endDate = endDate, offset = offset, @@ -62,21 +65,24 @@ class RankingService( fun getSeriesRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime ): List { - val seriesList = repository.getSeriesRanking(memberId, isAdult, startDate, endDate) + val seriesList = repository.getSeriesRanking(memberId, isAdult, contentType, startDate, endDate) return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult) } fun getSeriesAllRankingByGenre( memberId: Long, isAdult: Boolean, + contentType: ContentType, genreId: Long ): List { val seriesList = repository.getSeriesAllRankingByGenre( memberId = memberId, isAdult = isAdult, + contentType = contentType, genreId = genreId ) return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult) @@ -84,17 +90,20 @@ class RankingService( fun getCompleteSeriesRankingTotalCount( memberId: Long, - isAdult: Boolean + isAdult: Boolean, + contentType: ContentType ): Int { return repository.getCompleteSeriesRankingTotalCount( memberId = memberId, - isAdult = isAdult + isAdult = isAdult, + contentType = contentType ) } fun getCompleteSeriesRanking( memberId: Long, isAdult: Boolean, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime, offset: Long = 0, @@ -103,6 +112,7 @@ class RankingService( val seriesList = repository.getCompleteSeriesRanking( memberId = memberId, isAdult = isAdult, + contentType = contentType, startDate = startDate, endDate = endDate, offset = offset, @@ -179,38 +189,57 @@ class RankingService( fun fetchCreatorBySellContentCountRankTop20( memberId: Long, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime ): List { - return repository.fetchCreatorBySellContentCountRankTop20(memberId, startDate, endDate) + return repository.fetchCreatorBySellContentCountRankTop20(memberId, contentType, startDate, endDate) } fun fetchCreatorContentBySalesCountTop4( creatorId: Long, isAdult: Boolean, + contentType: ContentType, theme: String = "" ): List { - return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, theme) + return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, contentType, theme) } - fun fetchCreatorContentByLikeCountTop4(creatorId: Long, isAdult: Boolean): List { - return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult) + fun fetchCreatorContentByLikeCountTop4( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { + return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult, contentType) } fun fetchCreatorBySeriesRevenueRankTop20( memberId: Long, + contentType: ContentType, startDate: LocalDateTime, endDate: LocalDateTime ): List { - return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, startDate, endDate) + return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, contentType, startDate, endDate) } - fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List { - val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult) + fun fetchCreatorSeriesBySales( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { + val seriesList = repository.fetchCreatorSeriesBySales( + creatorId = creatorId, + isAdult = isAdult, + contentType = contentType + ) return seriesToSeriesListItem(seriesList, isAdult) } - fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List { - return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult) + fun fetchFreeContentByCreatorIdTop4( + creatorId: Long, + isAdult: Boolean, + contentType: ContentType + ): List { + return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult, contentType) } } From c7eae53b22fbc25a004ef3df0d12946ca00496d6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 18 Mar 2025 17:10:19 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=ED=99=88,=20=EB=AA=A8=EB=8B=9D=EC=BD=9C,=20asmr,?= =?UTF-8?q?=20=EB=8B=A8=ED=8E=B8,=20=EB=AC=B4=EB=A3=8C,=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=EB=93=A3=EA=B8=B0,=20=EC=8B=9C=EB=A6=AC=EC=A6=88=20-?= =?UTF-8?q?=20=EB=82=A8=EC=84=B1=ED=96=A5,=20=EC=97=AC=EC=84=B1=ED=96=A5?= =?UTF-8?q?=20=EC=84=A0=ED=83=9D=ED=95=9C=20=EC=9C=A0=EC=A0=80=EC=9D=98=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=ED=95=B4=EB=8B=B9=20=EC=84=B1=ED=96=A5?= =?UTF-8?q?=EC=9D=98=20=EC=BD=98=ED=85=90=EC=B8=A0=20+=20=EB=AF=B8?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EC=9D=98=20=EC=BD=98=ED=85=90=EC=B8=A0=EB=A5=BC=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/AudioContentRepository.kt | 88 +++++++++--- .../AudioContentCurationQueryRepository.kt | 21 ++- .../main/tab/AudioContentMainTabRepository.kt | 28 ++-- .../main/tab/RecommendSeriesRepository.kt | 24 +++- .../ContentMainTabTagCurationRepository.kt | 28 ++-- .../content/series/ContentSeriesRepository.kt | 62 ++++++--- .../theme/AudioContentThemeQueryRepository.kt | 12 +- .../sodalive/rank/RankingRepository.kt | 130 +++++++++++++----- 8 files changed, 285 insertions(+), 108 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 048a1b8..1e785f2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -404,7 +404,15 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -471,12 +479,14 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -534,12 +544,14 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -579,7 +591,15 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -619,7 +639,15 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -666,7 +694,15 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -784,7 +820,15 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -838,7 +882,15 @@ class AudioContentQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } 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 17b31df..f7e76a2 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 @@ -23,7 +23,15 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -31,6 +39,7 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact return queryFactory .select(audioContent.id) .from(audioContent) + .innerJoin(audioContent.member, member) .where(where) .fetch() .size @@ -62,7 +71,15 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt index 380158e..73d8589 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/AudioContentMainTabRepository.kt @@ -46,12 +46,14 @@ class AudioContentMainTabRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -103,12 +105,14 @@ class AudioContentMainTabRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt index 9ea6864..0c3275f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/RecommendSeriesRepository.kt @@ -25,7 +25,15 @@ class RecommendSeriesRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -59,12 +67,14 @@ class RecommendSeriesRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt index 46b1501..13ca6a4 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/tab/content/ContentMainTabTagCurationRepository.kt @@ -31,12 +31,14 @@ class ContentMainTabTagCurationRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -73,12 +75,14 @@ class ContentMainTabTagCurationRepository( if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } 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 0d09e67..fbb16c9 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 @@ -137,7 +137,15 @@ class ContentSeriesQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -171,12 +179,14 @@ class ContentSeriesQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -207,12 +217,14 @@ class ContentSeriesQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -253,12 +265,14 @@ class ContentSeriesQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -300,7 +314,15 @@ class ContentSeriesQueryRepositoryImpl( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } 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 a3e1d1f..d637431 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 @@ -4,6 +4,7 @@ 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.theme.QAudioContentTheme.audioContentTheme +import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Repository @@ -41,7 +42,15 @@ class AudioContentThemeQueryRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -55,6 +64,7 @@ class AudioContentThemeQueryRepository( return queryFactory .select(audioContentTheme.theme) .from(audioContent) + .innerJoin(audioContent.member, member) .innerJoin(audioContent.theme, audioContentTheme) .where(where) .groupBy(audioContentTheme.id) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt index 89fb7a9..22153f2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt @@ -71,12 +71,14 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -206,12 +208,14 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -256,12 +260,14 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -313,7 +319,15 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -360,7 +374,15 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -406,12 +428,14 @@ class RankingRepository( if (contentType != ContentType.ALL) { memberCondition = memberCondition.and( - member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + member.auth.isNull.or( + member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -463,7 +487,15 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -523,7 +555,15 @@ class RankingRepository( if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } @@ -568,7 +608,15 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - series.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + series.member.isNull.or( + series.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } @@ -609,12 +657,14 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq( - if (contentType == ContentType.MALE) { - 0 - } else { - 1 - } + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) ) ) } @@ -663,7 +713,15 @@ class RankingRepository( } else { if (contentType != ContentType.ALL) { where = where.and( - audioContent.member.auth.gender.eq(if (contentType == ContentType.MALE) 0 else 1) + audioContent.member.isNull.or( + audioContent.member.auth.gender.eq( + if (contentType == ContentType.MALE) { + 0 + } else { + 1 + } + ) + ) ) } } From dc1c29b69d21cf4ca65fadc71f531527bb87072b Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 18 Mar 2025 17:27:11 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=ED=99=88,=20=EB=AA=A8=EB=8B=9D=EC=BD=9C,=20asmr,?= =?UTF-8?q?=20=EB=8B=A8=ED=8E=B8,=20=EB=AC=B4=EB=A3=8C,=20=EB=8B=A4?= =?UTF-8?q?=EC=8B=9C=EB=93=A3=EA=B8=B0,=20=EC=8B=9C=EB=A6=AC=EC=A6=88=20-?= =?UTF-8?q?=20=EB=82=A8=EC=84=B1=ED=96=A5,=20=EC=97=AC=EC=84=B1=ED=96=A5?= =?UTF-8?q?=20=EC=84=A0=ED=83=9D=ED=95=9C=20=EC=9C=A0=EC=A0=80=EC=9D=98=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=ED=95=B4=EB=8B=B9=20=EC=84=B1=ED=96=A5?= =?UTF-8?q?=EC=9D=98=20=EC=BD=98=ED=85=90=EC=B8=A0=20+=20=EB=AF=B8?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EC=9D=98=20=EC=BD=98=ED=85=90=EC=B8=A0=EB=A5=BC=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/rank/RankingRepository.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt index 22153f2..611f595 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingRepository.kt @@ -426,10 +426,16 @@ class RankingRepository( .and(member.role.eq(MemberRole.CREATOR)) .and(member.id.eq(audioContent.member.id)) + var where = audioContent.isActive.isTrue + .and(audioContent.price.gt(0)) + .and(audioContent.duration.isNotNull) + .and(audioContent.limited.isNull) + .and(blockMember.id.isNull) + if (contentType != ContentType.ALL) { - memberCondition = memberCondition.and( - member.auth.isNull.or( - member.auth.gender.eq( + where = where.and( + audioContent.member.auth.isNull.or( + audioContent.member.auth.gender.eq( if (contentType == ContentType.MALE) { 0 } else { @@ -440,12 +446,6 @@ class RankingRepository( ) } - val where = audioContent.isActive.isTrue - .and(audioContent.price.gt(0)) - .and(audioContent.duration.isNotNull) - .and(audioContent.limited.isNull) - .and(blockMember.id.isNull) - return queryFactory .select( QContentCreatorResponse(