19금 콘텐츠 보기 설정 적용 #289
@@ -77,6 +77,7 @@ interface AudioContentQueryRepository {
 | 
				
			|||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        theme: List<String>,
 | 
					        theme: List<String>,
 | 
				
			||||||
        isAdult: Boolean = false,
 | 
					        isAdult: Boolean = false,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long = 0,
 | 
					        offset: Long = 0,
 | 
				
			||||||
        limit: Long = 20
 | 
					        limit: Long = 20
 | 
				
			||||||
    ): List<GetAudioContentMainItem>
 | 
					    ): List<GetAudioContentMainItem>
 | 
				
			||||||
@@ -84,7 +85,8 @@ interface AudioContentQueryRepository {
 | 
				
			|||||||
    fun totalAlarmCountByTheme(
 | 
					    fun totalAlarmCountByTheme(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        theme: List<String>,
 | 
					        theme: List<String>,
 | 
				
			||||||
        isAdult: Boolean = false
 | 
					        isAdult: Boolean = false,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
    ): Int
 | 
					    ): Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun totalCountByTheme(
 | 
					    fun totalCountByTheme(
 | 
				
			||||||
@@ -130,6 +132,7 @@ interface AudioContentQueryRepository {
 | 
				
			|||||||
        curationId: Long,
 | 
					        curationId: Long,
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long = 0,
 | 
					        offset: Long = 0,
 | 
				
			||||||
        limit: Long = 20
 | 
					        limit: Long = 20
 | 
				
			||||||
    ): List<GetAudioContentMainItem>
 | 
					    ): List<GetAudioContentMainItem>
 | 
				
			||||||
@@ -401,7 +404,15 @@ class AudioContentQueryRepositoryImpl(
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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,
 | 
					        memberId: Long,
 | 
				
			||||||
        theme: List<String>,
 | 
					        theme: List<String>,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
        limit: Long
 | 
					        limit: Long
 | 
				
			||||||
    ): List<GetAudioContentMainItem> {
 | 
					    ): List<GetAudioContentMainItem> {
 | 
				
			||||||
@@ -464,6 +476,20 @@ class AudioContentQueryRepositoryImpl(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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()) {
 | 
					        if (theme.isNotEmpty()) {
 | 
				
			||||||
@@ -494,7 +520,12 @@ class AudioContentQueryRepositoryImpl(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -510,6 +541,20 @@ class AudioContentQueryRepositoryImpl(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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()) {
 | 
					        if (theme.isNotEmpty()) {
 | 
				
			||||||
@@ -546,7 +591,15 @@ class AudioContentQueryRepositoryImpl(
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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 {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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 {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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 {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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,
 | 
					        curationId: Long,
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
        limit: Long
 | 
					        limit: Long
 | 
				
			||||||
    ): List<GetAudioContentMainItem> {
 | 
					    ): List<GetAudioContentMainItem> {
 | 
				
			||||||
@@ -801,6 +879,20 @@ class AudioContentQueryRepositoryImpl(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,11 +83,18 @@ class AudioContentMainController(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @GetMapping("/theme")
 | 
					    @GetMapping("/theme")
 | 
				
			||||||
    fun getThemeList(
 | 
					    fun getThemeList(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        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")
 | 
					    @GetMapping("/new/all")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,8 +26,8 @@ class AudioContentMainService(
 | 
				
			|||||||
) {
 | 
					) {
 | 
				
			||||||
    @Transactional(readOnly = true)
 | 
					    @Transactional(readOnly = true)
 | 
				
			||||||
    @Cacheable(cacheNames = ["default"], key = "'themeList:' + ':' + #isAdult")
 | 
					    @Cacheable(cacheNames = ["default"], key = "'themeList:' + ':' + #isAdult")
 | 
				
			||||||
    fun getThemeList(isAdult: Boolean): List<String> {
 | 
					    fun getThemeList(isAdult: Boolean, contentType: ContentType): List<String> {
 | 
				
			||||||
        return audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
 | 
					        return audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, contentType = contentType)
 | 
				
			||||||
            .filter {
 | 
					            .filter {
 | 
				
			||||||
                it != "모닝콜" &&
 | 
					                it != "모닝콜" &&
 | 
				
			||||||
                    it != "알람" &&
 | 
					                    it != "알람" &&
 | 
				
			||||||
@@ -73,17 +73,20 @@ class AudioContentMainService(
 | 
				
			|||||||
    ): GetNewContentAllResponse {
 | 
					    ): GetNewContentAllResponse {
 | 
				
			||||||
        val isAdult = member.auth != null && isAdultContentVisible
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val themeList = if (theme.isBlank()) {
 | 
					        val themeList = if (theme.isBlank()) {
 | 
				
			||||||
            audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, isFree = isFree)
 | 
					            audioContentThemeRepository.getActiveThemeOfContent(
 | 
				
			||||||
                .filter {
 | 
					                isAdult = isAdult,
 | 
				
			||||||
                    it != "모닝콜" &&
 | 
					                isFree = isFree,
 | 
				
			||||||
                        it != "알람" &&
 | 
					                contentType = contentType
 | 
				
			||||||
                        it != "슬립콜" &&
 | 
					            ).filter {
 | 
				
			||||||
                        it != "다시듣기" &&
 | 
					                it != "모닝콜" &&
 | 
				
			||||||
                        it != "ASMR" &&
 | 
					                    it != "알람" &&
 | 
				
			||||||
                        it != "릴레이" &&
 | 
					                    it != "슬립콜" &&
 | 
				
			||||||
                        it != "챌린지" &&
 | 
					                    it != "다시듣기" &&
 | 
				
			||||||
                        it != "자기소개"
 | 
					                    it != "ASMR" &&
 | 
				
			||||||
                }
 | 
					                    it != "릴레이" &&
 | 
				
			||||||
 | 
					                    it != "챌린지" &&
 | 
				
			||||||
 | 
					                    it != "자기소개"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            listOf(theme)
 | 
					            listOf(theme)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,15 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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
 | 
					        return queryFactory
 | 
				
			||||||
            .select(audioContent.id)
 | 
					            .select(audioContent.id)
 | 
				
			||||||
            .from(audioContent)
 | 
					            .from(audioContent)
 | 
				
			||||||
 | 
					            .innerJoin(audioContent.member, member)
 | 
				
			||||||
            .where(where)
 | 
					            .where(where)
 | 
				
			||||||
            .fetch()
 | 
					            .fetch()
 | 
				
			||||||
            .size
 | 
					            .size
 | 
				
			||||||
@@ -62,7 +71,15 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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.core.types.dsl.Expressions
 | 
				
			||||||
import com.querydsl.jpa.impl.JPAQueryFactory
 | 
					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.QAudioContent.audioContent
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.ContentCreatorResponse
 | 
					import kr.co.vividnext.sodalive.content.main.ContentCreatorResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.QContentCreatorResponse
 | 
					import kr.co.vividnext.sodalive.content.main.QContentCreatorResponse
 | 
				
			||||||
@@ -22,13 +23,15 @@ class AudioContentMainTabRepository(
 | 
				
			|||||||
    fun findCreatorByThemeContent(
 | 
					    fun findCreatorByThemeContent(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        theme: String,
 | 
					        theme: String,
 | 
				
			||||||
        minCount: Int
 | 
					        minCount: Int,
 | 
				
			||||||
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
    ): List<ContentCreatorResponse> {
 | 
					    ): List<ContentCreatorResponse> {
 | 
				
			||||||
        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
            .and(audioContent.isActive.isTrue)
 | 
					            .and(audioContent.isActive.isTrue)
 | 
				
			||||||
            .and(audioContent.price.gt(0))
 | 
					            .and(audioContent.price.gt(0))
 | 
				
			||||||
@@ -38,6 +41,24 @@ class AudioContentMainTabRepository(
 | 
				
			|||||||
            .and(audioContentTheme.theme.eq(theme))
 | 
					            .and(audioContentTheme.theme.eq(theme))
 | 
				
			||||||
            .and(blockMember.id.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
 | 
					        return queryFactory
 | 
				
			||||||
            .select(
 | 
					            .select(
 | 
				
			||||||
                QContentCreatorResponse(
 | 
					                QContentCreatorResponse(
 | 
				
			||||||
@@ -61,12 +82,17 @@ class AudioContentMainTabRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
            .and(audioContent.isActive.isTrue)
 | 
					            .and(audioContent.isActive.isTrue)
 | 
				
			||||||
            .and(audioContent.price.loe(0))
 | 
					            .and(audioContent.price.loe(0))
 | 
				
			||||||
@@ -74,6 +100,24 @@ class AudioContentMainTabRepository(
 | 
				
			|||||||
            .and(audioContent.limited.isNull)
 | 
					            .and(audioContent.limited.isNull)
 | 
				
			||||||
            .and(blockMember.id.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
 | 
					        return queryFactory
 | 
				
			||||||
            .select(
 | 
					            .select(
 | 
				
			||||||
                QContentCreatorResponse(
 | 
					                QContentCreatorResponse(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package kr.co.vividnext.sodalive.content.main.tab
 | 
					package kr.co.vividnext.sodalive.content.main.tab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.querydsl.jpa.impl.JPAQueryFactory
 | 
					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.content.main.tab.QRecommendSeries.recommendSeries
 | 
				
			||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series
 | 
					import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series
 | 
				
			||||||
import kr.co.vividnext.sodalive.member.QMember.member
 | 
					import kr.co.vividnext.sodalive.member.QMember.member
 | 
				
			||||||
@@ -14,13 +15,27 @@ class RecommendSeriesRepository(
 | 
				
			|||||||
    @Value("\${cloud.aws.cloud-front.host}")
 | 
					    @Value("\${cloud.aws.cloud-front.host}")
 | 
				
			||||||
    private val imageHost: String
 | 
					    private val imageHost: String
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun getNewSeriesList(isAdult: Boolean): List<GetRecommendSeriesListResponse> {
 | 
					    fun getNewSeriesList(isAdult: Boolean, contentType: ContentType): List<GetRecommendSeriesListResponse> {
 | 
				
			||||||
        var where = recommendSeries.isActive.isTrue
 | 
					        var where = recommendSeries.isActive.isTrue
 | 
				
			||||||
            .and(recommendSeries.isFree.isFalse)
 | 
					            .and(recommendSeries.isFree.isFalse)
 | 
				
			||||||
            .and(series.isActive.isTrue)
 | 
					            .and(series.isActive.isTrue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -42,13 +57,27 @@ class RecommendSeriesRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .fetch()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getRecommendSeriesList(isAdult: Boolean): List<GetRecommendSeriesListResponse> {
 | 
					    fun getRecommendSeriesList(isAdult: Boolean, contentType: ContentType): List<GetRecommendSeriesListResponse> {
 | 
				
			||||||
        var where = recommendSeries.isActive.isTrue
 | 
					        var where = recommendSeries.isActive.isTrue
 | 
				
			||||||
            .and(recommendSeries.isFree.isTrue)
 | 
					            .and(recommendSeries.isFree.isTrue)
 | 
				
			||||||
            .and(series.isActive.isTrue)
 | 
					            .and(series.isActive.isTrue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        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.ApiResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.SodaException
 | 
					import kr.co.vividnext.sodalive.common.SodaException
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.content.ContentType
 | 
				
			||||||
import kr.co.vividnext.sodalive.member.Member
 | 
					import kr.co.vividnext.sodalive.member.Member
 | 
				
			||||||
import org.springframework.data.domain.Pageable
 | 
					import org.springframework.data.domain.Pageable
 | 
				
			||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
				
			||||||
@@ -15,16 +16,26 @@ import org.springframework.web.bind.annotation.RestController
 | 
				
			|||||||
class AudioContentMainTabAlarmController(private val service: AudioContentMainTabAlarmService) {
 | 
					class AudioContentMainTabAlarmController(private val service: AudioContentMainTabAlarmService) {
 | 
				
			||||||
    @GetMapping
 | 
					    @GetMapping
 | 
				
			||||||
    fun fetchContentMainTabAlarm(
 | 
					    fun fetchContentMainTabAlarm(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ApiResponse.ok(service.fetchData(member))
 | 
					        ApiResponse.ok(
 | 
				
			||||||
 | 
					            service.fetchData(
 | 
				
			||||||
 | 
					                isAdultContentVisible = isAdultContentVisible ?: true,
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
 | 
					                member
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @GetMapping("/all")
 | 
					    @GetMapping("/all")
 | 
				
			||||||
    fun fetchAlarmContentByTheme(
 | 
					    fun fetchAlarmContentByTheme(
 | 
				
			||||||
        @RequestParam("theme") theme: String,
 | 
					        @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?,
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
				
			||||||
        pageable: Pageable
 | 
					        pageable: Pageable
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
@@ -34,6 +45,8 @@ class AudioContentMainTabAlarmController(private val service: AudioContentMainTa
 | 
				
			|||||||
            service.fetchAlarmContentByTheme(
 | 
					            service.fetchAlarmContentByTheme(
 | 
				
			||||||
                theme,
 | 
					                theme,
 | 
				
			||||||
                member,
 | 
					                member,
 | 
				
			||||||
 | 
					                isAdultContentVisible = isAdultContentVisible ?: true,
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
                offset = pageable.offset,
 | 
					                offset = pageable.offset,
 | 
				
			||||||
                limit = pageable.pageSize.toLong()
 | 
					                limit = pageable.pageSize.toLong()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package kr.co.vividnext.sodalive.content.main.tab.alarm
 | 
					package kr.co.vividnext.sodalive.content.main.tab.alarm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.AudioContentRepository
 | 
					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.GetNewContentAllResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
 | 
					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.curation.AudioContentCurationQueryRepository
 | 
				
			||||||
@@ -21,8 +22,12 @@ class AudioContentMainTabAlarmService(
 | 
				
			|||||||
    private val eventService: EventService,
 | 
					    private val eventService: EventService,
 | 
				
			||||||
    private val curationRepository: AudioContentCurationQueryRepository
 | 
					    private val curationRepository: AudioContentCurationQueryRepository
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun fetchData(member: Member): GetContentMainTabAlarmResponse {
 | 
					    fun fetchData(
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        member: Member
 | 
				
			||||||
 | 
					    ): GetContentMainTabAlarmResponse {
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val contentBannerList = bannerService.getBannerList(
 | 
					        val contentBannerList = bannerService.getBannerList(
 | 
				
			||||||
@@ -36,6 +41,7 @@ class AudioContentMainTabAlarmService(
 | 
				
			|||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = alarmThemeList,
 | 
					            theme = alarmThemeList,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            limit = 10
 | 
					            limit = 10
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,6 +59,7 @@ class AudioContentMainTabAlarmService(
 | 
				
			|||||||
        val rankAlarmContentList = rankingService.getContentRanking(
 | 
					        val rankAlarmContentList = rankingService.getContentRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate,
 | 
					            startDate = startDate,
 | 
				
			||||||
            endDate = endDate,
 | 
					            endDate = endDate,
 | 
				
			||||||
            theme = alarmThemeList[0]
 | 
					            theme = alarmThemeList[0]
 | 
				
			||||||
@@ -66,10 +73,12 @@ class AudioContentMainTabAlarmService(
 | 
				
			|||||||
                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
					                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                        curationId = it.id!!,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                        memberId = memberId,
 | 
				
			||||||
                        isAdult = isAdult
 | 
					                        isAdult = isAdult,
 | 
				
			||||||
 | 
					                        contentType = contentType
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            .filter { it.items.isNotEmpty() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GetContentMainTabAlarmResponse(
 | 
					        return GetContentMainTabAlarmResponse(
 | 
				
			||||||
            contentBannerList = contentBannerList,
 | 
					            contentBannerList = contentBannerList,
 | 
				
			||||||
@@ -84,6 +93,8 @@ class AudioContentMainTabAlarmService(
 | 
				
			|||||||
    fun fetchAlarmContentByTheme(
 | 
					    fun fetchAlarmContentByTheme(
 | 
				
			||||||
        theme: String,
 | 
					        theme: String,
 | 
				
			||||||
        member: Member,
 | 
					        member: Member,
 | 
				
			||||||
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
        limit: Long
 | 
					        limit: Long
 | 
				
			||||||
    ): GetNewContentAllResponse {
 | 
					    ): GetNewContentAllResponse {
 | 
				
			||||||
@@ -94,18 +105,20 @@ class AudioContentMainTabAlarmService(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val totalCount = contentRepository.totalAlarmCountByTheme(
 | 
					        val totalCount = contentRepository.totalAlarmCountByTheme(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = alarmThemeList,
 | 
					            theme = alarmThemeList,
 | 
				
			||||||
            isAdult = isAdult
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val items = contentRepository.findAlarmContentByTheme(
 | 
					        val items = contentRepository.findAlarmContentByTheme(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = alarmThemeList,
 | 
					            theme = alarmThemeList,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            offset = offset,
 | 
					            offset = offset,
 | 
				
			||||||
            limit = limit
 | 
					            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.ApiResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.SodaException
 | 
					import kr.co.vividnext.sodalive.common.SodaException
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.content.ContentType
 | 
				
			||||||
import kr.co.vividnext.sodalive.member.Member
 | 
					import kr.co.vividnext.sodalive.member.Member
 | 
				
			||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
				
			||||||
import org.springframework.web.bind.annotation.GetMapping
 | 
					import org.springframework.web.bind.annotation.GetMapping
 | 
				
			||||||
@@ -14,16 +15,26 @@ import org.springframework.web.bind.annotation.RestController
 | 
				
			|||||||
class AudioContentMainTabAsmrController(private val service: AudioContentMainTabAsmrService) {
 | 
					class AudioContentMainTabAsmrController(private val service: AudioContentMainTabAsmrService) {
 | 
				
			||||||
    @GetMapping
 | 
					    @GetMapping
 | 
				
			||||||
    fun fetchContentMainTabAsmr(
 | 
					    fun fetchContentMainTabAsmr(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        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")
 | 
					    @GetMapping("/popular-content-by-creator")
 | 
				
			||||||
    fun getPopularContentByCreator(
 | 
					    fun getPopularContentByCreator(
 | 
				
			||||||
        @RequestParam creatorId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -31,7 +42,8 @@ class AudioContentMainTabAsmrController(private val service: AudioContentMainTab
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getPopularContentByCreator(
 | 
					            service.getPopularContentByCreator(
 | 
				
			||||||
                creatorId = creatorId,
 | 
					                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 eventService: EventService,
 | 
				
			||||||
    private val curationRepository: AudioContentCurationQueryRepository
 | 
					    private val curationRepository: AudioContentCurationQueryRepository
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun fetchData(member: Member): GetContentMainTabAsmrResponse {
 | 
					    fun fetchData(
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        member: Member
 | 
				
			||||||
 | 
					    ): GetContentMainTabAsmrResponse {
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
        val theme = "ASMR"
 | 
					        val theme = "ASMR"
 | 
				
			||||||
        val tabId = 5L
 | 
					        val tabId = 5L
 | 
				
			||||||
@@ -37,20 +41,23 @@ class AudioContentMainTabAsmrService(
 | 
				
			|||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = listOf(theme),
 | 
					            theme = listOf(theme),
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
            contentType = ContentType.ALL,
 | 
					            contentType = contentType,
 | 
				
			||||||
            limit = 10
 | 
					            limit = 10
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val creatorList = repository.findCreatorByThemeContent(
 | 
					        val creatorList = repository.findCreatorByThemeContent(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = theme,
 | 
					            theme = theme,
 | 
				
			||||||
            minCount = 4
 | 
					            minCount = 4,
 | 
				
			||||||
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val salesCountRankContentList = if (creatorList.isNotEmpty()) {
 | 
					        val salesCountRankContentList = if (creatorList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.fetchCreatorContentBySalesCountTop4(
 | 
					            rankingService.fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
                creatorId = creatorList[0].creatorId,
 | 
					                creatorId = creatorList[0].creatorId,
 | 
				
			||||||
                isAdult = isAdult,
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType,
 | 
				
			||||||
                theme = theme
 | 
					                theme = theme
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -66,10 +73,12 @@ class AudioContentMainTabAsmrService(
 | 
				
			|||||||
                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
					                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                        curationId = it.id!!,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                        memberId = memberId,
 | 
				
			||||||
                        isAdult = isAdult
 | 
					                        isAdult = isAdult,
 | 
				
			||||||
 | 
					                        contentType = contentType
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            .filter { it.items.isNotEmpty() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GetContentMainTabAsmrResponse(
 | 
					        return GetContentMainTabAsmrResponse(
 | 
				
			||||||
            contentBannerList = contentBannerList,
 | 
					            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(
 | 
					        return rankingService.fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
            creatorId = creatorId,
 | 
					            creatorId = creatorId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            theme = "ASMR"
 | 
					            theme = "ASMR"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain
 | 
				
			|||||||
    @GetMapping("/ranking")
 | 
					    @GetMapping("/ranking")
 | 
				
			||||||
    fun getAudioContentRanking(
 | 
					    fun getAudioContentRanking(
 | 
				
			||||||
        @RequestParam("sort-type", required = false) sortType: String?,
 | 
					        @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?,
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
				
			||||||
        pageable: Pageable
 | 
					        pageable: Pageable
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
@@ -42,7 +44,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getAudioContentRanking(
 | 
					            service.getAudioContentRanking(
 | 
				
			||||||
                memberId = member.id!!,
 | 
					                memberId = member.id!!,
 | 
				
			||||||
                isAdult = member.auth != null,
 | 
					                isAdult = member.auth != null && (isAdultContentVisible ?: true),
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
                sortType = sortType ?: "매출"
 | 
					                sortType = sortType ?: "매출"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -71,6 +74,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain
 | 
				
			|||||||
    @GetMapping("/popular-content-by-creator")
 | 
					    @GetMapping("/popular-content-by-creator")
 | 
				
			||||||
    fun getPopularContentByCreator(
 | 
					    fun getPopularContentByCreator(
 | 
				
			||||||
        @RequestParam creatorId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -78,7 +83,8 @@ class AudioContentMainTabContentController(private val service: AudioContentMain
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getPopularContentByCreator(
 | 
					            service.getPopularContentByCreator(
 | 
				
			||||||
                creatorId = creatorId,
 | 
					                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")
 | 
					    @GetMapping("/recommend-content-by-tag")
 | 
				
			||||||
    fun getRecommendedContentByTag(
 | 
					    fun getRecommendedContentByTag(
 | 
				
			||||||
        @RequestParam tag: String,
 | 
					        @RequestParam tag: String,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
        ApiResponse.ok(
 | 
					        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
 | 
					        member: Member
 | 
				
			||||||
    ): GetContentMainTabContentResponse {
 | 
					    ): GetContentMainTabContentResponse {
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val tabId = 3L
 | 
					        val tabId = 3L
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 단편 배너
 | 
					        // 단편 배너
 | 
				
			||||||
@@ -41,24 +41,26 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 새로운 단편 테마
 | 
					        // 새로운 단편 테마
 | 
				
			||||||
        val themeOfContentList = audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
 | 
					        val themeOfContentList = audioContentThemeRepository.getActiveThemeOfContent(
 | 
				
			||||||
            .filter {
 | 
					            isAdult = isAdult,
 | 
				
			||||||
                it != "모닝콜" &&
 | 
					            contentType = contentType
 | 
				
			||||||
                    it != "알람" &&
 | 
					        ).filter {
 | 
				
			||||||
                    it != "슬립콜" &&
 | 
					            it != "모닝콜" &&
 | 
				
			||||||
                    it != "다시듣기" &&
 | 
					                it != "알람" &&
 | 
				
			||||||
                    it != "ASMR" &&
 | 
					                it != "슬립콜" &&
 | 
				
			||||||
                    it != "릴레이" &&
 | 
					                it != "다시듣기" &&
 | 
				
			||||||
                    it != "챌린지" &&
 | 
					                it != "ASMR" &&
 | 
				
			||||||
                    it != "자기소개"
 | 
					                it != "릴레이" &&
 | 
				
			||||||
            }
 | 
					                it != "챌린지" &&
 | 
				
			||||||
 | 
					                it != "자기소개"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 새로운 단편
 | 
					        // 새로운 단편
 | 
				
			||||||
        val newContentList = audioContentRepository.findByTheme(
 | 
					        val newContentList = audioContentRepository.findByTheme(
 | 
				
			||||||
            memberId = member.id!!,
 | 
					            memberId = member.id!!,
 | 
				
			||||||
            theme = themeOfContentList,
 | 
					            theme = themeOfContentList,
 | 
				
			||||||
            isAdult = member.auth != null,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
            contentType = ContentType.ALL,
 | 
					            contentType = contentType,
 | 
				
			||||||
            offset = 0,
 | 
					            offset = 0,
 | 
				
			||||||
            limit = 10
 | 
					            limit = 10
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -76,6 +78,7 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
        val rankContentList = rankingService.getContentRanking(
 | 
					        val rankContentList = rankingService.getContentRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = dailyRankingStartDate,
 | 
					            startDate = dailyRankingStartDate,
 | 
				
			||||||
            endDate = dailyRankingEndDate
 | 
					            endDate = dailyRankingEndDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -85,6 +88,7 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20(
 | 
					        val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20(
 | 
				
			||||||
            memberId = member.id!!,
 | 
					            memberId = member.id!!,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = dailyRankingStartDate,
 | 
					            startDate = dailyRankingStartDate,
 | 
				
			||||||
            endDate = dailyRankingEndDate
 | 
					            endDate = dailyRankingEndDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -92,20 +96,25 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
        val likeCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
 | 
					        val likeCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.fetchCreatorContentByLikeCountTop4(
 | 
					            rankingService.fetchCreatorContentByLikeCountTop4(
 | 
				
			||||||
                creatorId = contentRankCreatorList[0].creatorId,
 | 
					                creatorId = contentRankCreatorList[0].creatorId,
 | 
				
			||||||
                isAdult = member.auth != null
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            emptyList()
 | 
					            emptyList()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val tagList = if (isAdult) {
 | 
					        val tagList = if (isAdult) {
 | 
				
			||||||
            tagCurationService.getTagList(isAdult = isAdult)
 | 
					            tagCurationService.getTagList(isAdult = isAdult, contentType = contentType)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            emptyList()
 | 
					            emptyList()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val tagCurationContentList = if (tagList.isNotEmpty()) {
 | 
					        val tagCurationContentList = if (tagList.isNotEmpty()) {
 | 
				
			||||||
            tagCurationService.getTagCurationContentList(memberId = memberId, tag = tagList[0])
 | 
					            tagCurationService.getTagCurationContentList(
 | 
				
			||||||
 | 
					                memberId = memberId,
 | 
				
			||||||
 | 
					                tag = tagList[0],
 | 
				
			||||||
 | 
					                contentType = contentType
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            emptyList()
 | 
					            emptyList()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -117,10 +126,12 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
                    items = audioContentRepository.findAudioContentByCurationIdV2(
 | 
					                    items = audioContentRepository.findAudioContentByCurationIdV2(
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                        curationId = it.id!!,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                        memberId = memberId,
 | 
				
			||||||
                        isAdult = isAdult
 | 
					                        isAdult = isAdult,
 | 
				
			||||||
 | 
					                        contentType = contentType
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            .filter { it.items.isNotEmpty() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GetContentMainTabContentResponse(
 | 
					        return GetContentMainTabContentResponse(
 | 
				
			||||||
            bannerList = contentBannerList,
 | 
					            bannerList = contentBannerList,
 | 
				
			||||||
@@ -141,6 +152,7 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
    fun getAudioContentRanking(
 | 
					    fun getAudioContentRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        sortType: String
 | 
					        sortType: String
 | 
				
			||||||
    ): List<GetAudioContentRankingItem> {
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
        val currentDateTime = LocalDateTime.now()
 | 
					        val currentDateTime = LocalDateTime.now()
 | 
				
			||||||
@@ -155,6 +167,7 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
        return rankingService.getContentRanking(
 | 
					        return rankingService.getContentRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = dailyRankingStartDate,
 | 
					            startDate = dailyRankingStartDate,
 | 
				
			||||||
            endDate = dailyRankingEndDate,
 | 
					            endDate = dailyRankingEndDate,
 | 
				
			||||||
            sortType = sortType
 | 
					            sortType = sortType
 | 
				
			||||||
@@ -170,7 +183,7 @@ class AudioContentMainTabContentService(
 | 
				
			|||||||
        val isAdult = member.auth != null && isAdultContentVisible
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val themeList = if (theme.isBlank()) {
 | 
					        val themeList = if (theme.isBlank()) {
 | 
				
			||||||
            audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
 | 
					            audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult, contentType = contentType)
 | 
				
			||||||
                .filter {
 | 
					                .filter {
 | 
				
			||||||
                    it != "모닝콜" &&
 | 
					                    it != "모닝콜" &&
 | 
				
			||||||
                        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(
 | 
					        return rankingService.fetchCreatorContentByLikeCountTop4(
 | 
				
			||||||
            creatorId = creatorId,
 | 
					            creatorId = creatorId,
 | 
				
			||||||
            isAdult = isAdult
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getRecommendedContentByTag(memberId: Long, tag: String): List<GetAudioContentMainItem> {
 | 
					    fun getRecommendedContentByTag(
 | 
				
			||||||
        return tagCurationService.getTagCurationContentList(memberId = memberId, tag = tag)
 | 
					        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
 | 
					package kr.co.vividnext.sodalive.content.main.tab.content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.querydsl.jpa.impl.JPAQueryFactory
 | 
					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.QAudioContent.audioContent
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
 | 
					import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.QGetAudioContentMainItem
 | 
					import kr.co.vividnext.sodalive.content.main.QGetAudioContentMainItem
 | 
				
			||||||
@@ -18,7 +19,7 @@ class ContentMainTabTagCurationRepository(
 | 
				
			|||||||
    @Value("\${cloud.aws.cloud-front.host}")
 | 
					    @Value("\${cloud.aws.cloud-front.host}")
 | 
				
			||||||
    private val imageHost: String
 | 
					    private val imageHost: String
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun getTagList(isAdult: Boolean): List<String> {
 | 
					    fun getTagList(isAdult: Boolean, contentType: ContentType): List<String> {
 | 
				
			||||||
        var where = contentHashTagCuration.isActive.isTrue
 | 
					        var where = contentHashTagCuration.isActive.isTrue
 | 
				
			||||||
            .and(audioContent.isActive.isTrue)
 | 
					            .and(audioContent.isActive.isTrue)
 | 
				
			||||||
            .and(audioContent.duration.isNotNull)
 | 
					            .and(audioContent.duration.isNotNull)
 | 
				
			||||||
@@ -27,6 +28,20 @@ class ContentMainTabTagCurationRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(contentHashTagCuration.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -42,18 +57,36 @@ class ContentMainTabTagCurationRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val where = audioContent.isActive.isTrue
 | 
					        var where = audioContent.isActive.isTrue
 | 
				
			||||||
            .and(audioContent.duration.isNotNull)
 | 
					            .and(audioContent.duration.isNotNull)
 | 
				
			||||||
            .and(audioContent.limited.isNull)
 | 
					            .and(audioContent.limited.isNull)
 | 
				
			||||||
            .and(blockMember.id.isNull)
 | 
					            .and(blockMember.id.isNull)
 | 
				
			||||||
            .and(contentHashTagCurationItem.isActive.isTrue)
 | 
					            .and(contentHashTagCurationItem.isActive.isTrue)
 | 
				
			||||||
            .and(contentHashTagCuration.tag.eq(tag))
 | 
					            .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
 | 
					        return queryFactory
 | 
				
			||||||
            .select(
 | 
					            .select(
 | 
				
			||||||
                QGetAudioContentMainItem(
 | 
					                QGetAudioContentMainItem(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,20 @@
 | 
				
			|||||||
package kr.co.vividnext.sodalive.content.main.tab.content
 | 
					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 kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
 | 
				
			||||||
import org.springframework.stereotype.Service
 | 
					import org.springframework.stereotype.Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
class ContentMainTabTagCurationService(private val repository: ContentMainTabTagCurationRepository) {
 | 
					class ContentMainTabTagCurationService(private val repository: ContentMainTabTagCurationRepository) {
 | 
				
			||||||
    fun getTagList(isAdult: Boolean): List<String> {
 | 
					    fun getTagList(isAdult: Boolean, contentType: ContentType): List<String> {
 | 
				
			||||||
        return repository.getTagList(isAdult = isAdult)
 | 
					        return repository.getTagList(isAdult = isAdult, contentType = contentType)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getTagCurationContentList(memberId: Long, tag: String): List<GetAudioContentMainItem> {
 | 
					    fun getTagCurationContentList(
 | 
				
			||||||
        return repository.getTagCurationContentList(memberId = memberId, tag = tag)
 | 
					        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) {
 | 
					class AudioContentMainTabFreeController(private val service: AudioContentMainTabFreeService) {
 | 
				
			||||||
    @GetMapping
 | 
					    @GetMapping
 | 
				
			||||||
    fun fetchContentMainFree(
 | 
					    fun fetchContentMainFree(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        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")
 | 
					    @GetMapping("/introduce-creator")
 | 
				
			||||||
    fun getIntroduceCreator(
 | 
					    fun getIntroduceCreator(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
				
			||||||
        pageable: Pageable
 | 
					        pageable: Pageable
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
@@ -33,6 +43,8 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getIntroduceCreator(
 | 
					            service.getIntroduceCreator(
 | 
				
			||||||
                member,
 | 
					                member,
 | 
				
			||||||
 | 
					                isAdultContentVisible = isAdultContentVisible ?: true,
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
                offset = pageable.offset,
 | 
					                offset = pageable.offset,
 | 
				
			||||||
                limit = pageable.pageSize.toLong()
 | 
					                limit = pageable.pageSize.toLong()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@@ -64,6 +76,8 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab
 | 
				
			|||||||
    @GetMapping("/popular-content-by-creator")
 | 
					    @GetMapping("/popular-content-by-creator")
 | 
				
			||||||
    fun getPopularContentByCreator(
 | 
					    fun getPopularContentByCreator(
 | 
				
			||||||
        @RequestParam creatorId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -71,7 +85,8 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getPopularContentByCreator(
 | 
					            service.getPopularContentByCreator(
 | 
				
			||||||
                creatorId = creatorId,
 | 
					                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 audioContentRepository: AudioContentRepository,
 | 
				
			||||||
    private val audioContentThemeRepository: AudioContentThemeQueryRepository
 | 
					    private val audioContentThemeRepository: AudioContentThemeQueryRepository
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun fetchData(member: Member): GetContentMainTabFreeResponse {
 | 
					    fun fetchData(
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        member: Member
 | 
				
			||||||
 | 
					    ): GetContentMainTabFreeResponse {
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
        val tabId = 7L
 | 
					        val tabId = 7L
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -40,37 +44,43 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
            tabId = tabId,
 | 
					            tabId = tabId,
 | 
				
			||||||
            title = "크리에이터 소개",
 | 
					            title = "크리에이터 소개",
 | 
				
			||||||
            isAdult = isAdult
 | 
					            isAdult = isAdult
 | 
				
			||||||
        )
 | 
					        ).map {
 | 
				
			||||||
            .map {
 | 
					            GetContentCurationResponse(
 | 
				
			||||||
                GetContentCurationResponse(
 | 
					                title = it.title,
 | 
				
			||||||
                    title = it.title,
 | 
					                items = contentRepository.findAudioContentByCurationIdV2(
 | 
				
			||||||
                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
					                    curationId = it.id!!,
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                    memberId = memberId,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                    isAdult = isAdult,
 | 
				
			||||||
                        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)
 | 
					        val themeList = audioContentThemeRepository.getActiveThemeOfContent(
 | 
				
			||||||
            .filter {
 | 
					            isAdult = isAdult,
 | 
				
			||||||
                it != "모닝콜" &&
 | 
					            isFree = true,
 | 
				
			||||||
                    it != "알람" &&
 | 
					            contentType = contentType
 | 
				
			||||||
                    it != "슬립콜" &&
 | 
					        ).filter {
 | 
				
			||||||
                    it != "다시듣기" &&
 | 
					            it != "모닝콜" &&
 | 
				
			||||||
                    it != "ASMR" &&
 | 
					                it != "알람" &&
 | 
				
			||||||
                    it != "릴레이" &&
 | 
					                it != "슬립콜" &&
 | 
				
			||||||
                    it != "챌린지" &&
 | 
					                it != "다시듣기" &&
 | 
				
			||||||
                    it != "자기소개"
 | 
					                it != "ASMR" &&
 | 
				
			||||||
            }
 | 
					                it != "릴레이" &&
 | 
				
			||||||
 | 
					                it != "챌린지" &&
 | 
				
			||||||
 | 
					                it != "자기소개"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        val newFreeContentList = if (themeList.isNotEmpty()) {
 | 
					        val newFreeContentList = if (themeList.isNotEmpty()) {
 | 
				
			||||||
            audioContentRepository.findByTheme(
 | 
					            audioContentRepository.findByTheme(
 | 
				
			||||||
                memberId = member.id!!,
 | 
					                memberId = member.id!!,
 | 
				
			||||||
                theme = themeList,
 | 
					                theme = themeList,
 | 
				
			||||||
                isAdult = member.auth != null,
 | 
					                isAdult = isAdult,
 | 
				
			||||||
                contentType = ContentType.ALL,
 | 
					                contentType = contentType,
 | 
				
			||||||
                offset = 0,
 | 
					                offset = 0,
 | 
				
			||||||
                limit = 10,
 | 
					                limit = 10,
 | 
				
			||||||
                isFree = true
 | 
					                isFree = true
 | 
				
			||||||
@@ -79,9 +89,9 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
            emptyList()
 | 
					            emptyList()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val creatorList = repository.findCreatorWithHasFreeContent(memberId, 4)
 | 
					        val creatorList = repository.findCreatorWithHasFreeContent(memberId, 4, isAdult, contentType)
 | 
				
			||||||
        val playCountRankContentList = if (creatorList.isNotEmpty()) {
 | 
					        val playCountRankContentList = if (creatorList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.fetchFreeContentByCreatorIdTop4(creatorList[0].creatorId, isAdult)
 | 
					            rankingService.fetchFreeContentByCreatorIdTop4(creatorList[0].creatorId, isAdult, contentType)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            emptyList()
 | 
					            emptyList()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -94,10 +104,12 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
					                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                        curationId = it.id!!,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                        memberId = memberId,
 | 
				
			||||||
                        isAdult = isAdult
 | 
					                        isAdult = isAdult,
 | 
				
			||||||
 | 
					                        contentType = contentType
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            .filter { it.items.isNotEmpty() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GetContentMainTabFreeResponse(
 | 
					        return GetContentMainTabFreeResponse(
 | 
				
			||||||
            contentBannerList = contentBannerList,
 | 
					            contentBannerList = contentBannerList,
 | 
				
			||||||
@@ -115,8 +127,14 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getIntroduceCreator(member: Member, offset: Long, limit: Long): List<GetAudioContentMainItem> {
 | 
					    fun getIntroduceCreator(
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        member: Member,
 | 
				
			||||||
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        offset: Long,
 | 
				
			||||||
 | 
					        limit: Long
 | 
				
			||||||
 | 
					    ): List<GetAudioContentMainItem> {
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val introduceCreatorCuration = curationRepository.findByContentMainTabIdAndTitle(
 | 
					        val introduceCreatorCuration = curationRepository.findByContentMainTabIdAndTitle(
 | 
				
			||||||
@@ -130,6 +148,7 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
                curationId = introduceCreatorCuration[0].id!!,
 | 
					                curationId = introduceCreatorCuration[0].id!!,
 | 
				
			||||||
                memberId = memberId,
 | 
					                memberId = memberId,
 | 
				
			||||||
                isAdult = isAdult,
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType,
 | 
				
			||||||
                offset = offset,
 | 
					                offset = offset,
 | 
				
			||||||
                limit = limit
 | 
					                limit = limit
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@@ -153,18 +172,18 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                audioContentThemeRepository.getActiveThemeOfContent(
 | 
					                audioContentThemeRepository.getActiveThemeOfContent(
 | 
				
			||||||
                    isAdult = member.auth != null && isAdultContentVisible,
 | 
					                    isAdult = member.auth != null && isAdultContentVisible,
 | 
				
			||||||
                    isFree = true
 | 
					                    isFree = true,
 | 
				
			||||||
                )
 | 
					                    contentType = contentType
 | 
				
			||||||
                    .filter {
 | 
					                ).filter {
 | 
				
			||||||
                        it != "모닝콜" &&
 | 
					                    it != "모닝콜" &&
 | 
				
			||||||
                            it != "알람" &&
 | 
					                        it != "알람" &&
 | 
				
			||||||
                            it != "슬립콜" &&
 | 
					                        it != "슬립콜" &&
 | 
				
			||||||
                            it != "다시듣기" &&
 | 
					                        it != "다시듣기" &&
 | 
				
			||||||
                            it != "ASMR" &&
 | 
					                        it != "ASMR" &&
 | 
				
			||||||
                            it != "릴레이" &&
 | 
					                        it != "릴레이" &&
 | 
				
			||||||
                            it != "챌린지" &&
 | 
					                        it != "챌린지" &&
 | 
				
			||||||
                            it != "자기소개"
 | 
					                        it != "자기소개"
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            isAdult = member.auth != null && isAdultContentVisible,
 | 
					            isAdult = member.auth != null && isAdultContentVisible,
 | 
				
			||||||
            contentType = contentType,
 | 
					            contentType = contentType,
 | 
				
			||||||
@@ -174,7 +193,11 @@ class AudioContentMainTabFreeService(
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
					    fun getPopularContentByCreator(
 | 
				
			||||||
        return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult)
 | 
					        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.ApiResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.SodaException
 | 
					import kr.co.vividnext.sodalive.common.SodaException
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.content.ContentType
 | 
				
			||||||
import kr.co.vividnext.sodalive.member.Member
 | 
					import kr.co.vividnext.sodalive.member.Member
 | 
				
			||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
				
			||||||
import org.springframework.web.bind.annotation.GetMapping
 | 
					import org.springframework.web.bind.annotation.GetMapping
 | 
				
			||||||
@@ -14,16 +15,26 @@ import org.springframework.web.bind.annotation.RestController
 | 
				
			|||||||
class AudioContentMainTabHomeController(private val service: AudioContentMainTabHomeService) {
 | 
					class AudioContentMainTabHomeController(private val service: AudioContentMainTabHomeService) {
 | 
				
			||||||
    @GetMapping
 | 
					    @GetMapping
 | 
				
			||||||
    fun fetchContentMainHome(
 | 
					    fun fetchContentMainHome(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        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")
 | 
					    @GetMapping("/popular-content-by-creator")
 | 
				
			||||||
    fun getPopularContentByCreator(
 | 
					    fun getPopularContentByCreator(
 | 
				
			||||||
        @RequestParam creatorId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -31,7 +42,8 @@ class AudioContentMainTabHomeController(private val service: AudioContentMainTab
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getPopularContentByCreator(
 | 
					            service.getPopularContentByCreator(
 | 
				
			||||||
                creatorId = creatorId,
 | 
					                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
 | 
					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.GetAudioContentRankingItem
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
 | 
					import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
 | 
				
			||||||
import kr.co.vividnext.sodalive.event.EventService
 | 
					import kr.co.vividnext.sodalive.event.EventService
 | 
				
			||||||
@@ -19,7 +20,11 @@ class AudioContentMainTabHomeService(
 | 
				
			|||||||
    private val rankingService: RankingService,
 | 
					    private val rankingService: RankingService,
 | 
				
			||||||
    private val eventService: EventService
 | 
					    private val eventService: EventService
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun fetchData(member: Member): GetContentMainTabHomeResponse {
 | 
					    fun fetchData(
 | 
				
			||||||
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        member: Member
 | 
				
			||||||
 | 
					    ): GetContentMainTabHomeResponse {
 | 
				
			||||||
        // 주간 랭킹 기간
 | 
					        // 주간 랭킹 기간
 | 
				
			||||||
        val currentDateTime = LocalDateTime.now()
 | 
					        val currentDateTime = LocalDateTime.now()
 | 
				
			||||||
        val startDate = currentDateTime
 | 
					        val startDate = currentDateTime
 | 
				
			||||||
@@ -37,6 +42,8 @@ class AudioContentMainTabHomeService(
 | 
				
			|||||||
        val formattedLastMonday = startDate.format(startDateFormatter)
 | 
					        val formattedLastMonday = startDate.format(startDateFormatter)
 | 
				
			||||||
        val formattedLastSunday = endDate.format(endDateFormatter)
 | 
					        val formattedLastSunday = endDate.format(endDateFormatter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 최근 공지사항
 | 
					        // 최근 공지사항
 | 
				
			||||||
        val latestNotice = noticeService.getLatestNotice()
 | 
					        val latestNotice = noticeService.getLatestNotice()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,7 +51,7 @@ class AudioContentMainTabHomeService(
 | 
				
			|||||||
        val contentBannerList = bannerService.getBannerList(
 | 
					        val contentBannerList = bannerService.getBannerList(
 | 
				
			||||||
            tabId = 1,
 | 
					            tabId = 1,
 | 
				
			||||||
            memberId = member.id!!,
 | 
					            memberId = member.id!!,
 | 
				
			||||||
            isAdult = member.auth != null
 | 
					            isAdult = isAdult
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 인기 크리에이터
 | 
					        // 인기 크리에이터
 | 
				
			||||||
@@ -56,7 +63,8 @@ class AudioContentMainTabHomeService(
 | 
				
			|||||||
        // 인기 시리즈
 | 
					        // 인기 시리즈
 | 
				
			||||||
        val rankSeriesList = rankingService.getSeriesRanking(
 | 
					        val rankSeriesList = rankingService.getSeriesRanking(
 | 
				
			||||||
            memberId = member.id!!,
 | 
					            memberId = member.id!!,
 | 
				
			||||||
            isAdult = member.auth != null,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate.minusDays(1),
 | 
					            startDate = startDate.minusDays(1),
 | 
				
			||||||
            endDate = endDate
 | 
					            endDate = endDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -64,16 +72,18 @@ class AudioContentMainTabHomeService(
 | 
				
			|||||||
        // 인기 콘텐츠
 | 
					        // 인기 콘텐츠
 | 
				
			||||||
        val rankContentList = rankingService.getContentRanking(
 | 
					        val rankContentList = rankingService.getContentRanking(
 | 
				
			||||||
            memberId = member.id!!,
 | 
					            memberId = member.id!!,
 | 
				
			||||||
            isAdult = member.auth != null,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate.minusDays(1),
 | 
					            startDate = startDate.minusDays(1),
 | 
				
			||||||
            endDate = endDate
 | 
					            endDate = endDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 이벤트 배너
 | 
					        // 이벤트 배너
 | 
				
			||||||
        val eventBannerList = eventService.getEventList(isAdult = member.auth != null)
 | 
					        val eventBannerList = eventService.getEventList(isAdult = isAdult)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20(
 | 
					        val contentRankCreatorList = rankingService.fetchCreatorBySellContentCountRankTop20(
 | 
				
			||||||
            memberId = member.id!!,
 | 
					            memberId = member.id!!,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate.minusDays(1),
 | 
					            startDate = startDate.minusDays(1),
 | 
				
			||||||
            endDate = endDate
 | 
					            endDate = endDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -81,7 +91,8 @@ class AudioContentMainTabHomeService(
 | 
				
			|||||||
        val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
 | 
					        val salesCountRankContentList = if (contentRankCreatorList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.fetchCreatorContentBySalesCountTop4(
 | 
					            rankingService.fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
                creatorId = contentRankCreatorList[0].creatorId,
 | 
					                creatorId = contentRankCreatorList[0].creatorId,
 | 
				
			||||||
                isAdult = member.auth != null
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            emptyList()
 | 
					            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(
 | 
					        return rankingService.fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
            creatorId = creatorId,
 | 
					            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.ApiResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.SodaException
 | 
					import kr.co.vividnext.sodalive.common.SodaException
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.content.ContentType
 | 
				
			||||||
import kr.co.vividnext.sodalive.member.Member
 | 
					import kr.co.vividnext.sodalive.member.Member
 | 
				
			||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
				
			||||||
import org.springframework.web.bind.annotation.GetMapping
 | 
					import org.springframework.web.bind.annotation.GetMapping
 | 
				
			||||||
@@ -14,16 +15,26 @@ import org.springframework.web.bind.annotation.RestController
 | 
				
			|||||||
class AudioContentMainTabLiveReplayController(private val service: AudioContentMainTabLiveReplayService) {
 | 
					class AudioContentMainTabLiveReplayController(private val service: AudioContentMainTabLiveReplayService) {
 | 
				
			||||||
    @GetMapping
 | 
					    @GetMapping
 | 
				
			||||||
    fun fetchContentMainTabLiveReplay(
 | 
					    fun fetchContentMainTabLiveReplay(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        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")
 | 
					    @GetMapping("/popular-content-by-creator")
 | 
				
			||||||
    fun getPopularContentByCreator(
 | 
					    fun getPopularContentByCreator(
 | 
				
			||||||
        @RequestParam creatorId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -31,7 +42,8 @@ class AudioContentMainTabLiveReplayController(private val service: AudioContentM
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getPopularContentByCreator(
 | 
					            service.getPopularContentByCreator(
 | 
				
			||||||
                creatorId = creatorId,
 | 
					                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 eventService: EventService,
 | 
				
			||||||
    private val curationRepository: AudioContentCurationQueryRepository
 | 
					    private val curationRepository: AudioContentCurationQueryRepository
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun fetchData(member: Member): GetContentMainTabLiveReplayResponse {
 | 
					    fun fetchData(
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        member: Member
 | 
				
			||||||
 | 
					    ): GetContentMainTabLiveReplayResponse {
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
        val theme = "다시듣기"
 | 
					        val theme = "다시듣기"
 | 
				
			||||||
        val tabId = 6L
 | 
					        val tabId = 6L
 | 
				
			||||||
@@ -37,20 +41,23 @@ class AudioContentMainTabLiveReplayService(
 | 
				
			|||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = listOf(theme),
 | 
					            theme = listOf(theme),
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
            contentType = ContentType.ALL,
 | 
					            contentType = contentType,
 | 
				
			||||||
            limit = 10
 | 
					            limit = 10
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val creatorList = repository.findCreatorByThemeContent(
 | 
					        val creatorList = repository.findCreatorByThemeContent(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            theme = theme,
 | 
					            theme = theme,
 | 
				
			||||||
            minCount = 4
 | 
					            minCount = 4,
 | 
				
			||||||
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val salesCountRankContentList = if (creatorList.isNotEmpty()) {
 | 
					        val salesCountRankContentList = if (creatorList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.fetchCreatorContentBySalesCountTop4(
 | 
					            rankingService.fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
                creatorId = creatorList[0].creatorId,
 | 
					                creatorId = creatorList[0].creatorId,
 | 
				
			||||||
                isAdult = isAdult,
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType,
 | 
				
			||||||
                theme = theme
 | 
					                theme = theme
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -66,10 +73,12 @@ class AudioContentMainTabLiveReplayService(
 | 
				
			|||||||
                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
					                    items = contentRepository.findAudioContentByCurationIdV2(
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                        curationId = it.id!!,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                        memberId = memberId,
 | 
				
			||||||
                        isAdult = isAdult
 | 
					                        isAdult = isAdult,
 | 
				
			||||||
 | 
					                        contentType = contentType
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            .filter { it.items.isNotEmpty() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GetContentMainTabLiveReplayResponse(
 | 
					        return GetContentMainTabLiveReplayResponse(
 | 
				
			||||||
            contentBannerList = contentBannerList,
 | 
					            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(
 | 
					        return rankingService.fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
            creatorId = creatorId,
 | 
					            creatorId = creatorId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            theme = "다시듣기"
 | 
					            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.ApiResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.common.SodaException
 | 
					import kr.co.vividnext.sodalive.common.SodaException
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.content.ContentType
 | 
				
			||||||
import kr.co.vividnext.sodalive.member.Member
 | 
					import kr.co.vividnext.sodalive.member.Member
 | 
				
			||||||
import org.springframework.data.domain.Pageable
 | 
					import org.springframework.data.domain.Pageable
 | 
				
			||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal
 | 
				
			||||||
@@ -15,15 +16,25 @@ import org.springframework.web.bind.annotation.RestController
 | 
				
			|||||||
class AudioContentMainTabSeriesController(private val service: AudioContentMainTabSeriesService) {
 | 
					class AudioContentMainTabSeriesController(private val service: AudioContentMainTabSeriesService) {
 | 
				
			||||||
    @GetMapping
 | 
					    @GetMapping
 | 
				
			||||||
    fun fetchContentMainSeries(
 | 
					    fun fetchContentMainSeries(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ApiResponse.ok(service.fetchData(member))
 | 
					        ApiResponse.ok(
 | 
				
			||||||
 | 
					            service.fetchData(
 | 
				
			||||||
 | 
					                isAdultContentVisible = isAdultContentVisible ?: true,
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
 | 
					                member
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @GetMapping("/original")
 | 
					    @GetMapping("/original")
 | 
				
			||||||
    fun getOriginalAudioDramaList(
 | 
					    fun getOriginalAudioDramaList(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
				
			||||||
        pageable: Pageable
 | 
					        pageable: Pageable
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
@@ -32,7 +43,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getOriginalAudioDramaList(
 | 
					            service.getOriginalAudioDramaList(
 | 
				
			||||||
                memberId = member.id!!,
 | 
					                memberId = member.id!!,
 | 
				
			||||||
                isAdult = member.auth != null,
 | 
					                isAdult = member.auth != null && (isAdultContentVisible ?: true),
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
                offset = pageable.offset,
 | 
					                offset = pageable.offset,
 | 
				
			||||||
                limit = pageable.pageSize.toLong()
 | 
					                limit = pageable.pageSize.toLong()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@@ -41,6 +53,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @GetMapping("/completed-rank")
 | 
					    @GetMapping("/completed-rank")
 | 
				
			||||||
    fun getRank10DaysCompletedSeriesList(
 | 
					    fun getRank10DaysCompletedSeriesList(
 | 
				
			||||||
 | 
					        @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
 | 
				
			||||||
 | 
					        @RequestParam("contentType", required = false) contentType: ContentType? = null,
 | 
				
			||||||
        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
 | 
				
			||||||
        pageable: Pageable
 | 
					        pageable: Pageable
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
@@ -49,7 +63,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getRank10DaysCompletedSeriesList(
 | 
					            service.getRank10DaysCompletedSeriesList(
 | 
				
			||||||
                memberId = member.id!!,
 | 
					                memberId = member.id!!,
 | 
				
			||||||
                isAdult = member.auth != null,
 | 
					                isAdult = member.auth != null && (isAdultContentVisible ?: true),
 | 
				
			||||||
 | 
					                contentType = contentType ?: ContentType.ALL,
 | 
				
			||||||
                offset = pageable.offset,
 | 
					                offset = pageable.offset,
 | 
				
			||||||
                limit = pageable.pageSize.toLong()
 | 
					                limit = pageable.pageSize.toLong()
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@@ -59,6 +74,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT
 | 
				
			|||||||
    @GetMapping("/recommend-by-genre")
 | 
					    @GetMapping("/recommend-by-genre")
 | 
				
			||||||
    fun getRecommendSeriesListByGenre(
 | 
					    fun getRecommendSeriesListByGenre(
 | 
				
			||||||
        @RequestParam genreId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -67,7 +84,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT
 | 
				
			|||||||
            service.getRecommendSeriesListByGenre(
 | 
					            service.getRecommendSeriesListByGenre(
 | 
				
			||||||
                genreId,
 | 
					                genreId,
 | 
				
			||||||
                memberId = member.id!!,
 | 
					                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")
 | 
					    @GetMapping("/recommend-series-by-creator")
 | 
				
			||||||
    fun getRecommendSeriesByCreator(
 | 
					    fun getRecommendSeriesByCreator(
 | 
				
			||||||
        @RequestParam creatorId: Long,
 | 
					        @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?
 | 
					        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
 | 
				
			||||||
    ) = run {
 | 
					    ) = run {
 | 
				
			||||||
        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
					        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 | 
				
			||||||
@@ -82,7 +102,8 @@ class AudioContentMainTabSeriesController(private val service: AudioContentMainT
 | 
				
			|||||||
        ApiResponse.ok(
 | 
					        ApiResponse.ok(
 | 
				
			||||||
            service.getRecommendSeriesByCreator(
 | 
					            service.getRecommendSeriesByCreator(
 | 
				
			||||||
                creatorId = creatorId,
 | 
					                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
 | 
					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.banner.AudioContentBannerService
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
 | 
					import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.tab.RecommendSeriesRepository
 | 
					import kr.co.vividnext.sodalive.content.main.tab.RecommendSeriesRepository
 | 
				
			||||||
@@ -24,8 +25,12 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
    private val eventService: EventService,
 | 
					    private val eventService: EventService,
 | 
				
			||||||
    private val curationRepository: AudioContentCurationQueryRepository
 | 
					    private val curationRepository: AudioContentCurationQueryRepository
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun fetchData(member: Member): GetContentMainTabSeriesResponse {
 | 
					    fun fetchData(
 | 
				
			||||||
        val isAdult = member.auth != null
 | 
					        isAdultContentVisible: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
 | 
					        member: Member
 | 
				
			||||||
 | 
					    ): GetContentMainTabSeriesResponse {
 | 
				
			||||||
 | 
					        val isAdult = member.auth != null && isAdultContentVisible
 | 
				
			||||||
        val memberId = member.id!!
 | 
					        val memberId = member.id!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 메인 배너 (시리즈)
 | 
					        // 메인 배너 (시리즈)
 | 
				
			||||||
@@ -38,6 +43,7 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
        val originalAudioDrama = seriesService.getOriginalAudioDramaList(
 | 
					        val originalAudioDrama = seriesService.getOriginalAudioDramaList(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            offset = 0,
 | 
					            offset = 0,
 | 
				
			||||||
            limit = 20
 | 
					            limit = 20
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -55,18 +61,20 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
        val rankSeriesList = rankingService.getSeriesRanking(
 | 
					        val rankSeriesList = rankingService.getSeriesRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = dailyRankingStartDate,
 | 
					            startDate = dailyRankingStartDate,
 | 
				
			||||||
            endDate = dailyRankingEndDate
 | 
					            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()) {
 | 
					        val recommendSeriesList = if (genreList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.getSeriesAllRankingByGenre(
 | 
					            rankingService.getSeriesAllRankingByGenre(
 | 
				
			||||||
                memberId = memberId,
 | 
					                memberId = memberId,
 | 
				
			||||||
                isAdult = isAdult,
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType,
 | 
				
			||||||
                genreId = genreList[0].id
 | 
					                genreId = genreList[0].id
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } 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 (completedRankStartDate, completedRankEndDate) = calculateStartAndEndDate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val rankCompleteSeriesList = rankingService.getCompleteSeriesRanking(
 | 
					        val rankCompleteSeriesList = rankingService.getCompleteSeriesRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = completedRankStartDate,
 | 
					            startDate = completedRankStartDate,
 | 
				
			||||||
            endDate = completedRankEndDate
 | 
					            endDate = completedRankEndDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -96,6 +105,7 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        val seriesRankCreatorList = rankingService.fetchCreatorBySeriesRevenueRankTop20(
 | 
					        val seriesRankCreatorList = rankingService.fetchCreatorBySeriesRevenueRankTop20(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate.minusDays(1),
 | 
					            startDate = startDate.minusDays(1),
 | 
				
			||||||
            endDate = endDate
 | 
					            endDate = endDate
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -103,7 +113,8 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
        val salesRankContentList = if (seriesRankCreatorList.isNotEmpty()) {
 | 
					        val salesRankContentList = if (seriesRankCreatorList.isNotEmpty()) {
 | 
				
			||||||
            rankingService.fetchCreatorSeriesBySales(
 | 
					            rankingService.fetchCreatorSeriesBySales(
 | 
				
			||||||
                creatorId = seriesRankCreatorList[0].creatorId,
 | 
					                creatorId = seriesRankCreatorList[0].creatorId,
 | 
				
			||||||
                isAdult = isAdult
 | 
					                isAdult = isAdult,
 | 
				
			||||||
 | 
					                contentType = contentType
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            emptyList()
 | 
					            emptyList()
 | 
				
			||||||
@@ -120,7 +131,8 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
                    items = seriesService.fetchSeriesByCurationId(
 | 
					                    items = seriesService.fetchSeriesByCurationId(
 | 
				
			||||||
                        curationId = it.id!!,
 | 
					                        curationId = it.id!!,
 | 
				
			||||||
                        memberId = memberId,
 | 
					                        memberId = memberId,
 | 
				
			||||||
                        isAdult = isAdult
 | 
					                        isAdult = isAdult,
 | 
				
			||||||
 | 
					                        contentType = contentType
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -148,13 +160,15 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
    fun getOriginalAudioDramaList(
 | 
					    fun getOriginalAudioDramaList(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
        limit: Long
 | 
					        limit: Long
 | 
				
			||||||
    ): GetSeriesListResponse {
 | 
					    ): GetSeriesListResponse {
 | 
				
			||||||
        val totalCount = seriesService.getOriginalAudioDramaTotalCount(memberId, isAdult)
 | 
					        val totalCount = seriesService.getOriginalAudioDramaTotalCount(memberId, isAdult, contentType)
 | 
				
			||||||
        val items = seriesService.getOriginalAudioDramaList(
 | 
					        val items = seriesService.getOriginalAudioDramaList(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            offset = offset,
 | 
					            offset = offset,
 | 
				
			||||||
            limit = limit
 | 
					            limit = limit
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@@ -165,6 +179,7 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
    fun getRank10DaysCompletedSeriesList(
 | 
					    fun getRank10DaysCompletedSeriesList(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
        limit: Long
 | 
					        limit: Long
 | 
				
			||||||
    ): GetSeriesListResponse {
 | 
					    ): GetSeriesListResponse {
 | 
				
			||||||
@@ -172,12 +187,14 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        val totalCount = rankingService.getCompleteSeriesRankingTotalCount(
 | 
					        val totalCount = rankingService.getCompleteSeriesRankingTotalCount(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val items = rankingService.getCompleteSeriesRanking(
 | 
					        val items = rankingService.getCompleteSeriesRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate,
 | 
					            startDate = startDate,
 | 
				
			||||||
            endDate = endDate,
 | 
					            endDate = endDate,
 | 
				
			||||||
            offset = offset,
 | 
					            offset = offset,
 | 
				
			||||||
@@ -190,19 +207,26 @@ class AudioContentMainTabSeriesService(
 | 
				
			|||||||
    fun getRecommendSeriesListByGenre(
 | 
					    fun getRecommendSeriesListByGenre(
 | 
				
			||||||
        genreId: Long,
 | 
					        genreId: Long,
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
					    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
				
			||||||
        return rankingService.getSeriesAllRankingByGenre(
 | 
					        return rankingService.getSeriesAllRankingByGenre(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            genreId = genreId
 | 
					            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(
 | 
					        return rankingService.fetchCreatorSeriesBySales(
 | 
				
			||||||
            creatorId = creatorId,
 | 
					            creatorId = creatorId,
 | 
				
			||||||
            isAdult = isAdult
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,10 +35,17 @@ interface ContentSeriesQueryRepository {
 | 
				
			|||||||
    fun getKeywordList(seriesId: Long): List<String>
 | 
					    fun getKeywordList(seriesId: Long): List<String>
 | 
				
			||||||
    fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
 | 
					    fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
 | 
				
			||||||
    fun getRecommendSeriesList(isAuth: Boolean, contentType: ContentType, limit: Long): List<Series>
 | 
					    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 getOriginalAudioDramaList(
 | 
				
			||||||
    fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean): Int
 | 
					        memberId: Long,
 | 
				
			||||||
    fun getGenreList(isAdult: Boolean, memberId: Long): List<GetSeriesGenreListResponse>
 | 
					        isAdult: Boolean,
 | 
				
			||||||
    fun findByCurationId(curationId: Long, memberId: Long, isAdult: Boolean): List<Series>
 | 
					        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(
 | 
					class ContentSeriesQueryRepositoryImpl(
 | 
				
			||||||
@@ -130,7 +137,15 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (contentType != ContentType.ALL) {
 | 
					            if (contentType != ContentType.ALL) {
 | 
				
			||||||
                where = where.and(
 | 
					                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()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -155,6 +176,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -168,7 +203,7 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -179,6 +214,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -191,7 +240,11 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
            .size
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -209,6 +262,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(seriesGenre.isAdult.isFalse)
 | 
					            where = where.and(seriesGenre.isAdult.isFalse)
 | 
				
			||||||
                .and(series.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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -225,7 +292,12 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -239,6 +311,20 @@ class ContentSeriesQueryRepositoryImpl(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,22 +30,23 @@ class ContentSeriesService(
 | 
				
			|||||||
    @Value("\${cloud.aws.cloud-front.host}")
 | 
					    @Value("\${cloud.aws.cloud-front.host}")
 | 
				
			||||||
    private val coverImageHost: String
 | 
					    private val coverImageHost: String
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean): Int {
 | 
					    fun getOriginalAudioDramaTotalCount(memberId: Long, isAdult: Boolean, contentType: ContentType): Int {
 | 
				
			||||||
        return repository.getOriginalAudioDramaTotalCount(memberId, isAdult)
 | 
					        return repository.getOriginalAudioDramaTotalCount(memberId, isAdult, contentType)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getOriginalAudioDramaList(
 | 
					    fun getOriginalAudioDramaList(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        offset: Long = 0,
 | 
					        offset: Long = 0,
 | 
				
			||||||
        limit: Long = 20
 | 
					        limit: Long = 20
 | 
				
			||||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
					    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
				
			||||||
        val originalAudioDramaList = repository.getOriginalAudioDramaList(memberId, isAdult, offset, limit)
 | 
					        val originalAudioDramaList = repository.getOriginalAudioDramaList(memberId, isAdult, contentType, offset, limit)
 | 
				
			||||||
        return seriesToSeriesListItem(originalAudioDramaList, isAdult)
 | 
					        return seriesToSeriesListItem(originalAudioDramaList, isAdult)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getGenreList(memberId: Long, isAdult: Boolean): List<GetSeriesGenreListResponse> {
 | 
					    fun getGenreList(memberId: Long, isAdult: Boolean, contentType: ContentType): List<GetSeriesGenreListResponse> {
 | 
				
			||||||
        return repository.getGenreList(memberId = memberId, isAdult = isAdult)
 | 
					        return repository.getGenreList(memberId = memberId, isAdult = isAdult, contentType = contentType)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getSeriesList(
 | 
					    fun getSeriesList(
 | 
				
			||||||
@@ -191,9 +192,15 @@ class ContentSeriesService(
 | 
				
			|||||||
    fun fetchSeriesByCurationId(
 | 
					    fun fetchSeriesByCurationId(
 | 
				
			||||||
        curationId: Long,
 | 
					        curationId: Long,
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
					    ): 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)
 | 
					        return seriesToSeriesListItem(seriesList, isAdult)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,10 @@
 | 
				
			|||||||
package kr.co.vividnext.sodalive.content.theme
 | 
					package kr.co.vividnext.sodalive.content.theme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.querydsl.jpa.impl.JPAQueryFactory
 | 
					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.QAudioContent.audioContent
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme
 | 
					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.beans.factory.annotation.Value
 | 
				
			||||||
import org.springframework.stereotype.Repository
 | 
					import org.springframework.stereotype.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,12 +29,30 @@ class AudioContentThemeQueryRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .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
 | 
					        var where = audioContent.isActive.isTrue
 | 
				
			||||||
            .and(audioContentTheme.isActive.isTrue)
 | 
					            .and(audioContentTheme.isActive.isTrue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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) {
 | 
					        where = if (isFree) {
 | 
				
			||||||
@@ -44,6 +64,7 @@ class AudioContentThemeQueryRepository(
 | 
				
			|||||||
        return queryFactory
 | 
					        return queryFactory
 | 
				
			||||||
            .select(audioContentTheme.theme)
 | 
					            .select(audioContentTheme.theme)
 | 
				
			||||||
            .from(audioContent)
 | 
					            .from(audioContent)
 | 
				
			||||||
 | 
					            .innerJoin(audioContent.member, member)
 | 
				
			||||||
            .innerJoin(audioContent.theme, audioContentTheme)
 | 
					            .innerJoin(audioContent.theme, audioContentTheme)
 | 
				
			||||||
            .where(where)
 | 
					            .where(where)
 | 
				
			||||||
            .groupBy(audioContentTheme.id)
 | 
					            .groupBy(audioContentTheme.id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.rank
 | 
				
			|||||||
import com.querydsl.core.types.dsl.Expressions
 | 
					import com.querydsl.core.types.dsl.Expressions
 | 
				
			||||||
import com.querydsl.jpa.impl.JPAQueryFactory
 | 
					import com.querydsl.jpa.impl.JPAQueryFactory
 | 
				
			||||||
import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre
 | 
					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.QAudioContent.audioContent
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment
 | 
					import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike
 | 
					import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike
 | 
				
			||||||
@@ -44,6 +45,7 @@ class RankingRepository(
 | 
				
			|||||||
    fun getAudioContentRanking(
 | 
					    fun getAudioContentRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime,
 | 
					        endDate: LocalDateTime,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
@@ -66,6 +68,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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()) {
 | 
					        if (theme.isNotBlank()) {
 | 
				
			||||||
@@ -167,6 +183,7 @@ class RankingRepository(
 | 
				
			|||||||
    fun getSeriesRanking(
 | 
					    fun getSeriesRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime
 | 
					        endDate: LocalDateTime
 | 
				
			||||||
    ): List<Series> {
 | 
					    ): List<Series> {
 | 
				
			||||||
@@ -188,6 +205,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -209,7 +240,7 @@ class RankingRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -226,6 +257,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -244,6 +289,7 @@ class RankingRepository(
 | 
				
			|||||||
    fun getCompleteSeriesRanking(
 | 
					    fun getCompleteSeriesRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime,
 | 
					        endDate: LocalDateTime,
 | 
				
			||||||
        offset: Long,
 | 
					        offset: Long,
 | 
				
			||||||
@@ -270,6 +316,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -288,7 +348,12 @@ class RankingRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .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)
 | 
					        val blockMemberCondition = blockMember.member.id.eq(member.id)
 | 
				
			||||||
            .and(blockMember.isActive.isTrue)
 | 
					            .and(blockMember.isActive.isTrue)
 | 
				
			||||||
            .and(blockMember.blockedMember.id.eq(memberId))
 | 
					            .and(blockMember.blockedMember.id.eq(memberId))
 | 
				
			||||||
@@ -306,6 +371,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -330,6 +409,7 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorBySellContentCountRankTop20(
 | 
					    fun fetchCreatorBySellContentCountRankTop20(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime
 | 
					        endDate: LocalDateTime
 | 
				
			||||||
    ): List<ContentCreatorResponse> {
 | 
					    ): List<ContentCreatorResponse> {
 | 
				
			||||||
@@ -342,16 +422,30 @@ class RankingRepository(
 | 
				
			|||||||
            .and(order.createdAt.goe(startDate))
 | 
					            .and(order.createdAt.goe(startDate))
 | 
				
			||||||
            .and(order.createdAt.lt(endDate))
 | 
					            .and(order.createdAt.lt(endDate))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val memberCondition = member.isActive.isTrue
 | 
					        var memberCondition = member.isActive.isTrue
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
            .and(member.id.eq(audioContent.member.id))
 | 
					            .and(member.id.eq(audioContent.member.id))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val where = audioContent.isActive.isTrue
 | 
					        var where = audioContent.isActive.isTrue
 | 
				
			||||||
            .and(audioContent.price.gt(0))
 | 
					            .and(audioContent.price.gt(0))
 | 
				
			||||||
            .and(audioContent.duration.isNotNull)
 | 
					            .and(audioContent.duration.isNotNull)
 | 
				
			||||||
            .and(audioContent.limited.isNull)
 | 
					            .and(audioContent.limited.isNull)
 | 
				
			||||||
            .and(blockMember.id.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
 | 
					        return queryFactory
 | 
				
			||||||
            .select(
 | 
					            .select(
 | 
				
			||||||
                QContentCreatorResponse(
 | 
					                QContentCreatorResponse(
 | 
				
			||||||
@@ -376,6 +470,7 @@ class RankingRepository(
 | 
				
			|||||||
    fun fetchCreatorContentBySalesCountTop4(
 | 
					    fun fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
        creatorId: Long,
 | 
					        creatorId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        theme: String
 | 
					        theme: String
 | 
				
			||||||
    ): List<GetAudioContentRankingItem> {
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
        var where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
@@ -389,6 +484,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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()) {
 | 
					        if (theme.isNotBlank()) {
 | 
				
			||||||
@@ -423,6 +532,7 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorBySeriesRevenueRankTop20(
 | 
					    fun fetchCreatorBySeriesRevenueRankTop20(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime
 | 
					        endDate: LocalDateTime
 | 
				
			||||||
    ): List<ContentCreatorResponse> {
 | 
					    ): List<ContentCreatorResponse> {
 | 
				
			||||||
@@ -435,7 +545,7 @@ class RankingRepository(
 | 
				
			|||||||
            .and(order.createdAt.goe(startDate))
 | 
					            .and(order.createdAt.goe(startDate))
 | 
				
			||||||
            .and(order.createdAt.lt(startDate))
 | 
					            .and(order.createdAt.lt(startDate))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
            .and(series.isActive.isTrue)
 | 
					            .and(series.isActive.isTrue)
 | 
				
			||||||
            .and(audioContent.isActive.isTrue)
 | 
					            .and(audioContent.isActive.isTrue)
 | 
				
			||||||
@@ -443,6 +553,20 @@ class RankingRepository(
 | 
				
			|||||||
            .and(audioContent.limited.isNull)
 | 
					            .and(audioContent.limited.isNull)
 | 
				
			||||||
            .and(blockMember.id.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
 | 
					        return queryFactory
 | 
				
			||||||
            .select(
 | 
					            .select(
 | 
				
			||||||
                QContentCreatorResponse(
 | 
					                QContentCreatorResponse(
 | 
				
			||||||
@@ -469,7 +593,7 @@ class RankingRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .fetch()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List<Series> {
 | 
					    fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean, contentType: ContentType): List<Series> {
 | 
				
			||||||
        var where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
            .and(series.isActive.isTrue)
 | 
					            .and(series.isActive.isTrue)
 | 
				
			||||||
@@ -481,6 +605,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(series.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -501,7 +639,11 @@ class RankingRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .fetch()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
					    fun fetchFreeContentByCreatorIdTop4(
 | 
				
			||||||
 | 
					        creatorId: Long,
 | 
				
			||||||
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
        var where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
            .and(member.id.eq(creatorId))
 | 
					            .and(member.id.eq(creatorId))
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
@@ -512,6 +654,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
@@ -538,7 +694,11 @@ class RankingRepository(
 | 
				
			|||||||
            .fetch()
 | 
					            .fetch()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorContentByLikeCountTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
					    fun fetchCreatorContentByLikeCountTop4(
 | 
				
			||||||
 | 
					        creatorId: Long,
 | 
				
			||||||
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
        var where = member.isActive.isTrue
 | 
					        var where = member.isActive.isTrue
 | 
				
			||||||
            .and(member.id.eq(creatorId))
 | 
					            .and(member.id.eq(creatorId))
 | 
				
			||||||
            .and(member.role.eq(MemberRole.CREATOR))
 | 
					            .and(member.role.eq(MemberRole.CREATOR))
 | 
				
			||||||
@@ -550,6 +710,20 @@ class RankingRepository(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!isAdult) {
 | 
					        if (!isAdult) {
 | 
				
			||||||
            where = where.and(audioContent.isAdult.isFalse)
 | 
					            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
 | 
					        return queryFactory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
package kr.co.vividnext.sodalive.rank
 | 
					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.ContentCreatorResponse
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
 | 
					import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem
 | 
				
			||||||
import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse
 | 
					import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse
 | 
				
			||||||
@@ -40,6 +41,7 @@ class RankingService(
 | 
				
			|||||||
    fun getContentRanking(
 | 
					    fun getContentRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime,
 | 
					        endDate: LocalDateTime,
 | 
				
			||||||
        offset: Long = 0,
 | 
					        offset: Long = 0,
 | 
				
			||||||
@@ -50,6 +52,7 @@ class RankingService(
 | 
				
			|||||||
        return repository.getAudioContentRanking(
 | 
					        return repository.getAudioContentRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate,
 | 
					            startDate = startDate,
 | 
				
			||||||
            endDate = endDate,
 | 
					            endDate = endDate,
 | 
				
			||||||
            offset = offset,
 | 
					            offset = offset,
 | 
				
			||||||
@@ -62,21 +65,24 @@ class RankingService(
 | 
				
			|||||||
    fun getSeriesRanking(
 | 
					    fun getSeriesRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime
 | 
					        endDate: LocalDateTime
 | 
				
			||||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
					    ): 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)
 | 
					        return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getSeriesAllRankingByGenre(
 | 
					    fun getSeriesAllRankingByGenre(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        genreId: Long
 | 
					        genreId: Long
 | 
				
			||||||
    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
					    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
				
			||||||
        val seriesList = repository.getSeriesAllRankingByGenre(
 | 
					        val seriesList = repository.getSeriesAllRankingByGenre(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            genreId = genreId
 | 
					            genreId = genreId
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult)
 | 
					        return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult)
 | 
				
			||||||
@@ -84,17 +90,20 @@ class RankingService(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fun getCompleteSeriesRankingTotalCount(
 | 
					    fun getCompleteSeriesRankingTotalCount(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
    ): Int {
 | 
					    ): Int {
 | 
				
			||||||
        return repository.getCompleteSeriesRankingTotalCount(
 | 
					        return repository.getCompleteSeriesRankingTotalCount(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun getCompleteSeriesRanking(
 | 
					    fun getCompleteSeriesRanking(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime,
 | 
					        endDate: LocalDateTime,
 | 
				
			||||||
        offset: Long = 0,
 | 
					        offset: Long = 0,
 | 
				
			||||||
@@ -103,6 +112,7 @@ class RankingService(
 | 
				
			|||||||
        val seriesList = repository.getCompleteSeriesRanking(
 | 
					        val seriesList = repository.getCompleteSeriesRanking(
 | 
				
			||||||
            memberId = memberId,
 | 
					            memberId = memberId,
 | 
				
			||||||
            isAdult = isAdult,
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType,
 | 
				
			||||||
            startDate = startDate,
 | 
					            startDate = startDate,
 | 
				
			||||||
            endDate = endDate,
 | 
					            endDate = endDate,
 | 
				
			||||||
            offset = offset,
 | 
					            offset = offset,
 | 
				
			||||||
@@ -179,38 +189,57 @@ class RankingService(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorBySellContentCountRankTop20(
 | 
					    fun fetchCreatorBySellContentCountRankTop20(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime
 | 
					        endDate: LocalDateTime
 | 
				
			||||||
    ): List<ContentCreatorResponse> {
 | 
					    ): List<ContentCreatorResponse> {
 | 
				
			||||||
        return repository.fetchCreatorBySellContentCountRankTop20(memberId, startDate, endDate)
 | 
					        return repository.fetchCreatorBySellContentCountRankTop20(memberId, contentType, startDate, endDate)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorContentBySalesCountTop4(
 | 
					    fun fetchCreatorContentBySalesCountTop4(
 | 
				
			||||||
        creatorId: Long,
 | 
					        creatorId: Long,
 | 
				
			||||||
        isAdult: Boolean,
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        theme: String = ""
 | 
					        theme: String = ""
 | 
				
			||||||
    ): List<GetAudioContentRankingItem> {
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
        return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, theme)
 | 
					        return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, contentType, theme)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorContentByLikeCountTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
					    fun fetchCreatorContentByLikeCountTop4(
 | 
				
			||||||
        return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult)
 | 
					        creatorId: Long,
 | 
				
			||||||
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
 | 
					        return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult, contentType)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorBySeriesRevenueRankTop20(
 | 
					    fun fetchCreatorBySeriesRevenueRankTop20(
 | 
				
			||||||
        memberId: Long,
 | 
					        memberId: Long,
 | 
				
			||||||
 | 
					        contentType: ContentType,
 | 
				
			||||||
        startDate: LocalDateTime,
 | 
					        startDate: LocalDateTime,
 | 
				
			||||||
        endDate: LocalDateTime
 | 
					        endDate: LocalDateTime
 | 
				
			||||||
    ): List<ContentCreatorResponse> {
 | 
					    ): List<ContentCreatorResponse> {
 | 
				
			||||||
        return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, startDate, endDate)
 | 
					        return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, contentType, startDate, endDate)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List<GetSeriesListResponse.SeriesListItem> {
 | 
					    fun fetchCreatorSeriesBySales(
 | 
				
			||||||
        val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult)
 | 
					        creatorId: Long,
 | 
				
			||||||
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
 | 
					    ): List<GetSeriesListResponse.SeriesListItem> {
 | 
				
			||||||
 | 
					        val seriesList = repository.fetchCreatorSeriesBySales(
 | 
				
			||||||
 | 
					            creatorId = creatorId,
 | 
				
			||||||
 | 
					            isAdult = isAdult,
 | 
				
			||||||
 | 
					            contentType = contentType
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        return seriesToSeriesListItem(seriesList, isAdult)
 | 
					        return seriesToSeriesListItem(seriesList, isAdult)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> {
 | 
					    fun fetchFreeContentByCreatorIdTop4(
 | 
				
			||||||
        return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult)
 | 
					        creatorId: Long,
 | 
				
			||||||
 | 
					        isAdult: Boolean,
 | 
				
			||||||
 | 
					        contentType: ContentType
 | 
				
			||||||
 | 
					    ): List<GetAudioContentRankingItem> {
 | 
				
			||||||
 | 
					        return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult, contentType)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user