Merge pull request '19금 콘텐츠 보기 설정 적용' (#289) from test into main

Reviewed-on: #289
This commit is contained in:
klaus 2025-03-19 02:05:17 +00:00
commit 56eb6b3ce3
27 changed files with 963 additions and 194 deletions

View File

@ -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

View File

@ -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")

View File

@ -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)
} }

View File

@ -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
}
)
)
) )
} }
} }

View File

@ -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(

View File

@ -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

View File

@ -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()
) )

View File

@ -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
) )

View File

@ -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
) )
) )
} }

View File

@ -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"
) )
} }

View File

@ -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
)
) )
} }
} }

View File

@ -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)
} }
} }

View File

@ -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(

View File

@ -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)
} }
} }

View File

@ -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
) )
) )
} }

View File

@ -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)
} }
} }

View File

@ -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
) )
) )
} }

View File

@ -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
) )
} }
} }

View File

@ -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
) )
) )
} }

View File

@ -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 = "다시듣기"
) )
} }

View File

@ -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
) )
) )
} }

View File

@ -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
) )
} }

View File

@ -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

View File

@ -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)
} }

View File

@ -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)

View File

@ -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

View File

@ -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)
} }
} }