콘텐츠 메인

- 무료 탭 API
This commit is contained in:
Klaus 2025-02-08 02:40:25 +09:00
parent 3410045f83
commit 9be78062be
6 changed files with 186 additions and 2 deletions

View File

@ -68,7 +68,8 @@ interface AudioContentQueryRepository {
isAdult: Boolean = false,
contentType: ContentType,
offset: Long = 0,
limit: Long = 20
limit: Long = 20,
isFree: Boolean = false
): List<GetAudioContentMainItem>
fun totalCountByTheme(
@ -339,7 +340,8 @@ class AudioContentQueryRepositoryImpl(
isAdult: Boolean,
contentType: ContentType,
offset: Long,
limit: Long
limit: Long,
isFree: Boolean
): List<GetAudioContentMainItem> {
val blockMemberCondition = blockMember.member.id.eq(member.id)
.and(blockMember.isActive.isTrue)
@ -383,6 +385,10 @@ class AudioContentQueryRepositoryImpl(
where = where.and(audioContentTheme.theme.eq(theme))
}
if (isFree) {
where = where.and(audioContent.price.loe(0))
}
return queryFactory
.select(
QGetAudioContentMainItem(

View File

@ -105,4 +105,26 @@ class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFact
.orderBy(audioContentCuration.orders.asc())
.fetch()
}
fun findByContentMainTabIdAndTitle(
tabId: Long,
title: String,
isAdult: Boolean,
offset: Long = 0,
limit: Long = 12
): List<AudioContentCuration> {
var where = audioContentCuration.isActive.isTrue
.and(audioContentMainTab.id.eq(tabId))
if (!isAdult) {
where = where.and(audioContentCuration.isAdult.isFalse)
}
return queryFactory
.selectFrom(audioContentCuration)
.innerJoin(audioContentCuration.tab, audioContentMainTab)
.where(where)
.orderBy(audioContentCuration.orders.asc())
.fetch()
}
}

View File

@ -40,4 +40,31 @@ class RecommendSeriesRepository(
.orderBy(recommendSeries.orders.asc())
.fetch()
}
fun getRecommendSeriesList(isAdult: Boolean): List<GetRecommendSeriesListResponse> {
var where = recommendSeries.isActive.isTrue
.and(recommendSeries.isFree.isTrue)
.and(series.isActive.isTrue)
if (!isAdult) {
where = where.and(series.isAdult.isFalse)
}
return queryFactory
.select(
QGetRecommendSeriesListResponse(
series.id,
series.title,
recommendSeries.imagePath.prepend("/").prepend(imageHost),
member.id,
member.nickname
)
)
.from(recommendSeries)
.innerJoin(recommendSeries.series, series)
.innerJoin(series.member, member)
.where(where)
.orderBy(recommendSeries.orders.asc())
.fetch()
}
}

View File

@ -0,0 +1,22 @@
package kr.co.vividnext.sodalive.content.main.tab.free
import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.member.Member
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/v2/audio-content/main/series")
class AudioContentMainTabFreeController(private val service: AudioContentMainTabFreeService) {
@GetMapping
fun fetchContentMainFree(
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
ApiResponse.ok(service.fetchData(member))
}
}

View File

@ -0,0 +1,91 @@
package kr.co.vividnext.sodalive.content.main.tab.free
import kr.co.vividnext.sodalive.content.AudioContentRepository
import kr.co.vividnext.sodalive.content.ContentType
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService
import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationQueryRepository
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
import kr.co.vividnext.sodalive.content.main.tab.RecommendSeriesRepository
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
import kr.co.vividnext.sodalive.member.Member
import org.springframework.stereotype.Service
@Service
class AudioContentMainTabFreeService(
private val bannerService: AudioContentBannerService,
private val recommendSeriesRepository: RecommendSeriesRepository,
private val curationRepository: AudioContentCurationQueryRepository,
private val contentRepository: AudioContentRepository,
private val audioContentRepository: AudioContentRepository,
private val audioContentThemeRepository: AudioContentThemeQueryRepository
) {
fun fetchData(member: Member): GetContentMainTabFreeResponse {
val isAdult = member.auth != null
val memberId = member.id!!
val tabId = 7L
val contentBannerList = bannerService.getBannerList(
tabId = tabId,
memberId = memberId,
isAdult = isAdult
)
val introduceCreator = curationRepository.findByContentMainTabIdAndTitle(
tabId = tabId,
title = "크리에이터 소개",
isAdult = isAdult
)
.map {
GetContentCurationResponse(
title = it.title,
items = contentRepository.findAudioContentByCurationId(
curationId = it.id!!,
isAdult = isAdult,
contentType = ContentType.ALL
)
)
}
val recommendSeriesList = recommendSeriesRepository.getRecommendSeriesList(isAdult = isAdult)
val themeList = audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
val newFreeContentList = if (themeList.isNotEmpty()) {
audioContentRepository.findByTheme(
memberId = member.id!!,
theme = themeList[0],
isAdult = member.auth != null,
contentType = ContentType.ALL,
offset = 0,
limit = 10,
isFree = true
)
} else {
emptyList()
}
val curationList = curationRepository.findByContentMainTabId(tabId = tabId, isAdult = isAdult)
.map {
GetContentCurationResponse(
title = it.title,
items = contentRepository.findAudioContentByCurationId(
curationId = it.id!!,
isAdult = isAdult,
contentType = ContentType.ALL
)
)
}
return GetContentMainTabFreeResponse(
contentBannerList = contentBannerList,
introduceCreator = if (introduceCreator.isNotEmpty()) {
introduceCreator[0]
} else {
null
},
recommendSeriesList = recommendSeriesList,
themeList = themeList,
newFreeContentList = newFreeContentList,
curationList = curationList
)
}
}

View File

@ -0,0 +1,16 @@
package kr.co.vividnext.sodalive.content.main.tab.free
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse
import kr.co.vividnext.sodalive.content.main.tab.GetContentCurationResponse
import kr.co.vividnext.sodalive.content.main.tab.GetRecommendSeriesListResponse
data class GetContentMainTabFreeResponse(
val tabId: Long = 7,
val contentBannerList: List<GetAudioContentBannerResponse>,
val introduceCreator: GetContentCurationResponse?,
val recommendSeriesList: List<GetRecommendSeriesListResponse>,
val themeList: List<String>,
val newFreeContentList: List<GetAudioContentMainItem>,
val curationList: List<GetContentCurationResponse>
)