19금 콘텐츠 보기 설정 적용 #289
@@ -77,6 +77,7 @@ interface AudioContentQueryRepository {
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        theme: List<String>,
 | 
			
		||||
        isAdult: Boolean = false,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        offset: Long = 0,
 | 
			
		||||
        limit: Long = 20
 | 
			
		||||
    ): List<GetAudioContentMainItem>
 | 
			
		||||
@@ -84,7 +85,8 @@ interface AudioContentQueryRepository {
 | 
			
		||||
    fun totalAlarmCountByTheme(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        theme: List<String>,
 | 
			
		||||
        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<GetAudioContentMainItem>
 | 
			
		||||
@@ -401,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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -444,6 +455,7 @@ class AudioContentQueryRepositoryImpl(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        theme: List<String>,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        offset: Long,
 | 
			
		||||
        limit: Long
 | 
			
		||||
    ): List<GetAudioContentMainItem> {
 | 
			
		||||
@@ -464,6 +476,20 @@ class AudioContentQueryRepositoryImpl(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (theme.isNotEmpty()) {
 | 
			
		||||
@@ -494,7 +520,12 @@ class AudioContentQueryRepositoryImpl(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun totalAlarmCountByTheme(memberId: Long, theme: List<String>, isAdult: Boolean): Int {
 | 
			
		||||
    override fun totalAlarmCountByTheme(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        theme: List<String>,
 | 
			
		||||
        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 +541,20 @@ class AudioContentQueryRepositoryImpl(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (theme.isNotEmpty()) {
 | 
			
		||||
@@ -546,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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -586,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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -633,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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -751,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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -783,6 +860,7 @@ class AudioContentQueryRepositoryImpl(
 | 
			
		||||
        curationId: Long,
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        offset: Long,
 | 
			
		||||
        limit: Long
 | 
			
		||||
    ): List<GetAudioContentMainItem> {
 | 
			
		||||
@@ -801,6 +879,20 @@ class AudioContentQueryRepositoryImpl(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,8 @@ class AudioContentMainService(
 | 
			
		||||
) {
 | 
			
		||||
    @Transactional(readOnly = true)
 | 
			
		||||
    @Cacheable(cacheNames = ["default"], key = "'themeList:' + ':' + #isAdult")
 | 
			
		||||
    fun getThemeList(isAdult: Boolean): List<String> {
 | 
			
		||||
        return audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
 | 
			
		||||
    fun getThemeList(isAdult: Boolean, contentType: ContentType): List<String> {
 | 
			
		||||
        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)
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<ContentCreatorResponse> {
 | 
			
		||||
        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,24 @@ 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.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
            .select(
 | 
			
		||||
                QContentCreatorResponse(
 | 
			
		||||
@@ -61,12 +82,17 @@ class AudioContentMainTabRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun findCreatorWithHasFreeContent(memberId: Long, minCount: Int): List<ContentCreatorResponse> {
 | 
			
		||||
    fun findCreatorWithHasFreeContent(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        minCount: Int,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<ContentCreatorResponse> {
 | 
			
		||||
        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 +100,24 @@ 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.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
            .select(
 | 
			
		||||
                QContentCreatorResponse(
 | 
			
		||||
 
 | 
			
		||||
@@ -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,27 @@ class RecommendSeriesRepository(
 | 
			
		||||
    @Value("\${cloud.aws.cloud-front.host}")
 | 
			
		||||
    private val imageHost: String
 | 
			
		||||
) {
 | 
			
		||||
    fun getNewSeriesList(isAdult: Boolean): List<GetRecommendSeriesListResponse> {
 | 
			
		||||
    fun getNewSeriesList(isAdult: Boolean, contentType: ContentType): List<GetRecommendSeriesListResponse> {
 | 
			
		||||
        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.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -42,13 +57,27 @@ class RecommendSeriesRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getRecommendSeriesList(isAdult: Boolean): List<GetRecommendSeriesListResponse> {
 | 
			
		||||
    fun getRecommendSeriesList(isAdult: Boolean, contentType: ContentType): List<GetRecommendSeriesListResponse> {
 | 
			
		||||
        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.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
            )
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetAudioContentRankingItem> {
 | 
			
		||||
    fun getPopularContentByCreator(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return rankingService.fetchCreatorContentBySalesCountTop4(
 | 
			
		||||
            creatorId = creatorId,
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType,
 | 
			
		||||
            theme = "ASMR"
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetAudioContentRankingItem> {
 | 
			
		||||
        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<GetAudioContentRankingItem> {
 | 
			
		||||
    fun getPopularContentByCreator(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return rankingService.fetchCreatorContentByLikeCountTop4(
 | 
			
		||||
            creatorId = creatorId,
 | 
			
		||||
            isAdult = isAdult
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getRecommendedContentByTag(memberId: Long, tag: String): List<GetAudioContentMainItem> {
 | 
			
		||||
        return tagCurationService.getTagCurationContentList(memberId = memberId, tag = tag)
 | 
			
		||||
    fun getRecommendedContentByTag(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        tag: String,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentMainItem> {
 | 
			
		||||
        return tagCurationService.getTagCurationContentList(memberId = memberId, tag = tag, contentType = contentType)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String> {
 | 
			
		||||
    fun getTagList(isAdult: Boolean, contentType: ContentType): List<String> {
 | 
			
		||||
        var where = contentHashTagCuration.isActive.isTrue
 | 
			
		||||
            .and(audioContent.isActive.isTrue)
 | 
			
		||||
            .and(audioContent.duration.isNotNull)
 | 
			
		||||
@@ -27,6 +28,20 @@ class ContentMainTabTagCurationRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(contentHashTagCuration.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -42,18 +57,36 @@ class ContentMainTabTagCurationRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getTagCurationContentList(memberId: Long, tag: String): List<GetAudioContentMainItem> {
 | 
			
		||||
    fun getTagCurationContentList(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        tag: String,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentMainItem> {
 | 
			
		||||
        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.isNull.or(
 | 
			
		||||
                    audioContent.member.auth.gender.eq(
 | 
			
		||||
                        if (contentType == ContentType.MALE) {
 | 
			
		||||
                            0
 | 
			
		||||
                        } else {
 | 
			
		||||
                            1
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
            .select(
 | 
			
		||||
                QGetAudioContentMainItem(
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String> {
 | 
			
		||||
        return repository.getTagList(isAdult = isAdult)
 | 
			
		||||
    fun getTagList(isAdult: Boolean, contentType: ContentType): List<String> {
 | 
			
		||||
        return repository.getTagList(isAdult = isAdult, contentType = contentType)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getTagCurationContentList(memberId: Long, tag: String): List<GetAudioContentMainItem> {
 | 
			
		||||
        return repository.getTagCurationContentList(memberId = memberId, tag = tag)
 | 
			
		||||
    fun getTagCurationContentList(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        tag: String,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentMainItem> {
 | 
			
		||||
        return repository.getTagCurationContentList(memberId = memberId, tag = tag, contentType = contentType)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetAudioContentMainItem> {
 | 
			
		||||
        val isAdult = member.auth != null
 | 
			
		||||
    fun getIntroduceCreator(
 | 
			
		||||
        member: Member,
 | 
			
		||||
        isAdultContentVisible: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        offset: Long,
 | 
			
		||||
        limit: Long
 | 
			
		||||
    ): List<GetAudioContentMainItem> {
 | 
			
		||||
        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<GetAudioContentRankingItem> {
 | 
			
		||||
        return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult)
 | 
			
		||||
    fun getPopularContentByCreator(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult, contentType)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetAudioContentRankingItem> {
 | 
			
		||||
    fun getPopularContentByCreator(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return rankingService.fetchCreatorContentBySalesCountTop4(
 | 
			
		||||
            creatorId = creatorId,
 | 
			
		||||
            isAdult = isAdult
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetAudioContentRankingItem> {
 | 
			
		||||
    fun getPopularContentByCreator(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return rankingService.fetchCreatorContentBySalesCountTop4(
 | 
			
		||||
            creatorId = creatorId,
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType,
 | 
			
		||||
            theme = "다시듣기"
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        return rankingService.getSeriesAllRankingByGenre(
 | 
			
		||||
            memberId = memberId,
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType,
 | 
			
		||||
            genreId = genreId
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getRecommendSeriesByCreator(creatorId: Long, isAdult: Boolean): List<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
    fun getRecommendSeriesByCreator(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        return rankingService.fetchCreatorSeriesBySales(
 | 
			
		||||
            creatorId = creatorId,
 | 
			
		||||
            isAdult = isAdult
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,10 +35,17 @@ interface ContentSeriesQueryRepository {
 | 
			
		||||
    fun getKeywordList(seriesId: Long): List<String>
 | 
			
		||||
    fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
 | 
			
		||||
    fun getRecommendSeriesList(isAuth: Boolean, contentType: ContentType, limit: Long): List<Series>
 | 
			
		||||
    fun getOriginalAudioDramaList(memberId: Long, isAdult: Boolean, offset: Long = 0, limit: Long = 20): List<Series>
 | 
			
		||||
    fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean): Int
 | 
			
		||||
    fun getGenreList(isAdult: Boolean, memberId: Long): List<GetSeriesGenreListResponse>
 | 
			
		||||
    fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean): List<Series>
 | 
			
		||||
    fun getOriginalAudioDramaList(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        offset: Long = 0,
 | 
			
		||||
        limit: Long = 20
 | 
			
		||||
    ): List<Series>
 | 
			
		||||
 | 
			
		||||
    fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean, contentType: ContentType): Int
 | 
			
		||||
    fun getGenreList(isAdult: Boolean, memberId: Long, contentType: ContentType): List<GetSeriesGenreListResponse>
 | 
			
		||||
    fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean, contentType: ContentType): List<Series>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
@@ -130,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
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -144,7 +159,13 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getOriginalAudioDramaList(memberId: Long, isAdult: Boolean, offset: Long, limit: Long): List<Series> {
 | 
			
		||||
    override fun getOriginalAudioDramaList(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        offset: Long,
 | 
			
		||||
        limit: Long
 | 
			
		||||
    ): List<Series> {
 | 
			
		||||
        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
			
		||||
            .and(blockMember.isActive.isTrue)
 | 
			
		||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
			
		||||
@@ -155,6 +176,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -168,7 +203,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 +214,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -191,7 +240,11 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
            .size
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getGenreList(isAdult: Boolean, memberId: Long): List<GetSeriesGenreListResponse> {
 | 
			
		||||
    override fun getGenreList(
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetSeriesGenreListResponse> {
 | 
			
		||||
        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
			
		||||
            .and(blockMember.isActive.isTrue)
 | 
			
		||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
			
		||||
@@ -209,6 +262,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(seriesGenre.isAdult.isFalse)
 | 
			
		||||
                .and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -225,7 +292,12 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean): List<Series> {
 | 
			
		||||
    override fun findByCurationId(
 | 
			
		||||
        curationId: Long,
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<Series> {
 | 
			
		||||
        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
			
		||||
            .and(blockMember.isActive.isTrue)
 | 
			
		||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
			
		||||
@@ -239,6 +311,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        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<GetSeriesGenreListResponse> {
 | 
			
		||||
        return repository.getGenreList(memberId = memberId, isAdult = isAdult)
 | 
			
		||||
    fun getGenreList(memberId: Long, isAdult: Boolean, contentType: ContentType): List<GetSeriesGenreListResponse> {
 | 
			
		||||
        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<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
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 kr.co.vividnext.sodalive.member.QMember.member
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value
 | 
			
		||||
import org.springframework.stereotype.Repository
 | 
			
		||||
 | 
			
		||||
@@ -27,12 +29,30 @@ class AudioContentThemeQueryRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getActiveThemeOfContent(isAdult: Boolean = false, isFree: Boolean = false): List<String> {
 | 
			
		||||
    fun getActiveThemeOfContent(
 | 
			
		||||
        isAdult: Boolean = false,
 | 
			
		||||
        isFree: Boolean = false,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<String> {
 | 
			
		||||
        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.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        where = if (isFree) {
 | 
			
		||||
@@ -44,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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (theme.isNotBlank()) {
 | 
			
		||||
@@ -167,6 +183,7 @@ class RankingRepository(
 | 
			
		||||
    fun getSeriesRanking(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        startDate: LocalDateTime,
 | 
			
		||||
        endDate: LocalDateTime
 | 
			
		||||
    ): List<Series> {
 | 
			
		||||
@@ -188,6 +205,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -209,7 +240,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 +257,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -244,6 +289,7 @@ class RankingRepository(
 | 
			
		||||
    fun getCompleteSeriesRanking(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        startDate: LocalDateTime,
 | 
			
		||||
        endDate: LocalDateTime,
 | 
			
		||||
        offset: Long,
 | 
			
		||||
@@ -270,6 +316,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -288,7 +348,12 @@ class RankingRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getSeriesAllRankingByGenre(memberId: Long, isAdult: Boolean, genreId: Long): List<Series> {
 | 
			
		||||
    fun getSeriesAllRankingByGenre(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        genreId: Long
 | 
			
		||||
    ): List<Series> {
 | 
			
		||||
        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
			
		||||
            .and(blockMember.isActive.isTrue)
 | 
			
		||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
			
		||||
@@ -306,6 +371,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -330,6 +409,7 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorBySellContentCountRankTop20(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        startDate: LocalDateTime,
 | 
			
		||||
        endDate: LocalDateTime
 | 
			
		||||
    ): List<ContentCreatorResponse> {
 | 
			
		||||
@@ -342,16 +422,30 @@ 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))
 | 
			
		||||
 | 
			
		||||
        val where = audioContent.isActive.isTrue
 | 
			
		||||
        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) {
 | 
			
		||||
            where = where.and(
 | 
			
		||||
                audioContent.member.auth.isNull.or(
 | 
			
		||||
                    audioContent.member.auth.gender.eq(
 | 
			
		||||
                        if (contentType == ContentType.MALE) {
 | 
			
		||||
                            0
 | 
			
		||||
                        } else {
 | 
			
		||||
                            1
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
            .select(
 | 
			
		||||
                QContentCreatorResponse(
 | 
			
		||||
@@ -376,6 +470,7 @@ class RankingRepository(
 | 
			
		||||
    fun fetchCreatorContentBySalesCountTop4(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        theme: String
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        var where = member.isActive.isTrue
 | 
			
		||||
@@ -389,6 +484,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (theme.isNotBlank()) {
 | 
			
		||||
@@ -423,6 +532,7 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorBySeriesRevenueRankTop20(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        startDate: LocalDateTime,
 | 
			
		||||
        endDate: LocalDateTime
 | 
			
		||||
    ): List<ContentCreatorResponse> {
 | 
			
		||||
@@ -435,7 +545,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 +553,20 @@ class RankingRepository(
 | 
			
		||||
            .and(audioContent.limited.isNull)
 | 
			
		||||
            .and(blockMember.id.isNull)
 | 
			
		||||
 | 
			
		||||
        if (contentType != ContentType.ALL) {
 | 
			
		||||
            where = where.and(
 | 
			
		||||
                audioContent.member.isNull.or(
 | 
			
		||||
                    audioContent.member.auth.gender.eq(
 | 
			
		||||
                        if (contentType == ContentType.MALE) {
 | 
			
		||||
                            0
 | 
			
		||||
                        } else {
 | 
			
		||||
                            1
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
            .select(
 | 
			
		||||
                QContentCreatorResponse(
 | 
			
		||||
@@ -469,7 +593,7 @@ class RankingRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List<Series> {
 | 
			
		||||
    fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean, contentType: ContentType): List<Series> {
 | 
			
		||||
        var where = member.isActive.isTrue
 | 
			
		||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
			
		||||
            .and(series.isActive.isTrue)
 | 
			
		||||
@@ -481,6 +605,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(series.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    series.member.isNull.or(
 | 
			
		||||
                        series.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -501,7 +639,11 @@ class RankingRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
			
		||||
    fun fetchFreeContentByCreatorIdTop4(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        var where = member.isActive.isTrue
 | 
			
		||||
            .and(member.id.eq(creatorId))
 | 
			
		||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
			
		||||
@@ -512,6 +654,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
@@ -538,7 +694,11 @@ class RankingRepository(
 | 
			
		||||
            .fetch()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorContentByLikeCountTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
			
		||||
    fun fetchCreatorContentByLikeCountTop4(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        var where = member.isActive.isTrue
 | 
			
		||||
            .and(member.id.eq(creatorId))
 | 
			
		||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
			
		||||
@@ -550,6 +710,20 @@ class RankingRepository(
 | 
			
		||||
 | 
			
		||||
        if (!isAdult) {
 | 
			
		||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
			
		||||
        } else {
 | 
			
		||||
            if (contentType != ContentType.ALL) {
 | 
			
		||||
                where = where.and(
 | 
			
		||||
                    audioContent.member.isNull.or(
 | 
			
		||||
                        audioContent.member.auth.gender.eq(
 | 
			
		||||
                            if (contentType == ContentType.MALE) {
 | 
			
		||||
                                0
 | 
			
		||||
                            } else {
 | 
			
		||||
                                1
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return queryFactory
 | 
			
		||||
 
 | 
			
		||||
@@ -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<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        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<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        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<ContentCreatorResponse> {
 | 
			
		||||
        return repository.fetchCreatorBySellContentCountRankTop20(memberId, startDate, endDate)
 | 
			
		||||
        return repository.fetchCreatorBySellContentCountRankTop20(memberId, contentType, startDate, endDate)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorContentBySalesCountTop4(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        theme: String = ""
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, theme)
 | 
			
		||||
        return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, contentType, theme)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorContentByLikeCountTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult)
 | 
			
		||||
    fun fetchCreatorContentByLikeCountTop4(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult, contentType)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorBySeriesRevenueRankTop20(
 | 
			
		||||
        memberId: Long,
 | 
			
		||||
        contentType: ContentType,
 | 
			
		||||
        startDate: LocalDateTime,
 | 
			
		||||
        endDate: LocalDateTime
 | 
			
		||||
    ): List<ContentCreatorResponse> {
 | 
			
		||||
        return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, startDate, endDate)
 | 
			
		||||
        return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, contentType, startDate, endDate)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult)
 | 
			
		||||
    fun fetchCreatorSeriesBySales(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
			
		||||
        val seriesList = repository.fetchCreatorSeriesBySales(
 | 
			
		||||
            creatorId = creatorId,
 | 
			
		||||
            isAdult = isAdult,
 | 
			
		||||
            contentType = contentType
 | 
			
		||||
        )
 | 
			
		||||
        return seriesToSeriesListItem(seriesList, isAdult)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult)
 | 
			
		||||
    fun fetchFreeContentByCreatorIdTop4(
 | 
			
		||||
        creatorId: Long,
 | 
			
		||||
        isAdult: Boolean,
 | 
			
		||||
        contentType: ContentType
 | 
			
		||||
    ): List<GetAudioContentRankingItem> {
 | 
			
		||||
        return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult, contentType)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user