feat(content-all): 전체 탭 조회 서비스를 추가한다

This commit is contained in:
2026-06-25 11:25:25 +09:00
parent 2aeb9418a9
commit 2bced956dc
3 changed files with 473 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
package kr.co.vividnext.sodalive.v2.content.all.application
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
import kr.co.vividnext.sodalive.v2.common.domain.ContentSort
import kr.co.vividnext.sodalive.v2.content.all.domain.MainContentAll
import kr.co.vividnext.sodalive.v2.content.all.domain.MainContentAllQueryPolicy
import kr.co.vividnext.sodalive.v2.content.all.domain.MainContentAllType
import kr.co.vividnext.sodalive.v2.content.all.domain.MainContentPage
import kr.co.vividnext.sodalive.v2.content.all.port.out.MainContentAllQueryPort
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
@Service
@Transactional(readOnly = true)
class MainContentAllQueryService(
private val queryPort: MainContentAllQueryPort,
private val memberContentPreferenceService: MemberContentPreferenceService,
private val queryPolicy: MainContentAllQueryPolicy = MainContentAllQueryPolicy(),
private val langContext: LangContext
) {
fun getContents(
type: String?,
sort: String?,
dayOfWeek: String?,
page: Int?,
size: Int?,
member: Member?
): MainContentAll {
val resolvedType = queryPolicy.resolveType(type)
val resolvedSort = queryPolicy.resolveSort(sort)
val resolvedDayOfWeek = queryPolicy.resolveDayOfWeek(resolvedType, dayOfWeek)
val resolvedPage = queryPolicy.createPage(page, size)
val now = LocalDateTime.now()
val memberId = member?.id
val canViewAdultContent = canViewAdultContent(member)
return when (resolvedType) {
MainContentAllType.AUDIO -> getAudioContents(
type = resolvedType,
sort = resolvedSort,
dayOfWeek = resolvedDayOfWeek,
page = resolvedPage,
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now
)
MainContentAllType.FREE -> getAudioContents(
type = resolvedType,
sort = resolvedSort,
dayOfWeek = resolvedDayOfWeek,
page = resolvedPage,
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now,
onlyFree = true
)
MainContentAllType.POINT -> getAudioContents(
type = resolvedType,
sort = resolvedSort,
dayOfWeek = resolvedDayOfWeek,
page = resolvedPage,
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now,
onlyPointAvailable = true
)
MainContentAllType.SERIES -> getSeriesContents(
type = resolvedType,
sort = resolvedSort,
dayOfWeek = resolvedDayOfWeek,
page = resolvedPage,
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now
)
MainContentAllType.ORIGINAL -> getSeriesContents(
type = resolvedType,
sort = resolvedSort,
dayOfWeek = null,
page = resolvedPage,
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now,
onlyOriginal = true
)
}
}
private fun getAudioContents(
type: MainContentAllType,
sort: ContentSort,
dayOfWeek: SeriesPublishedDaysOfWeek?,
page: MainContentPage,
memberId: Long?,
canViewAdultContent: Boolean,
now: LocalDateTime,
onlyFree: Boolean = false,
onlyPointAvailable: Boolean = false
): MainContentAll {
val totalCount = queryPort.countAudios(memberId, canViewAdultContent, now, onlyFree, onlyPointAvailable)
val audios = queryPort.findAudios(
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now,
sort = sort,
offset = page.offset,
limit = page.size + 1,
onlyFree = onlyFree,
onlyPointAvailable = onlyPointAvailable
)
return MainContentAll(
type = type,
totalCount = totalCount,
audios = queryPolicy.limitItems(audios, page),
series = emptyList(),
sort = sort,
dayOfWeek = dayOfWeek,
page = page,
hasNext = queryPolicy.hasNext(audios, page)
)
}
private fun getSeriesContents(
type: MainContentAllType,
sort: ContentSort,
dayOfWeek: SeriesPublishedDaysOfWeek?,
page: MainContentPage,
memberId: Long?,
canViewAdultContent: Boolean,
now: LocalDateTime,
onlyOriginal: Boolean = false
): MainContentAll {
val totalCount = queryPort.countSeries(memberId, canViewAdultContent, now, onlyOriginal, dayOfWeek)
val series = queryPort.findSeries(
memberId = memberId,
canViewAdultContent = canViewAdultContent,
now = now,
sort = sort,
offset = page.offset,
limit = page.size + 1,
onlyOriginal = onlyOriginal,
dayOfWeek = dayOfWeek,
locale = langContext.lang.code
)
return MainContentAll(
type = type,
totalCount = totalCount,
audios = emptyList(),
series = queryPolicy.limitItems(series, page),
sort = sort,
dayOfWeek = dayOfWeek,
page = page,
hasNext = queryPolicy.hasNext(series, page)
)
}
private fun canViewAdultContent(member: Member?): Boolean {
if (member == null) return false
return memberContentPreferenceService.canViewAdultContent(member)
}
}

View File

@@ -0,0 +1,48 @@
package kr.co.vividnext.sodalive.v2.content.all.port.out
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
import kr.co.vividnext.sodalive.v2.common.domain.ContentSort
import kr.co.vividnext.sodalive.v2.content.all.domain.MainContentAllAudio
import kr.co.vividnext.sodalive.v2.content.all.domain.MainContentAllSeries
import java.time.LocalDateTime
interface MainContentAllQueryPort {
fun countAudios(
memberId: Long?,
canViewAdultContent: Boolean,
now: LocalDateTime,
onlyFree: Boolean = false,
onlyPointAvailable: Boolean = false
): Int
fun findAudios(
memberId: Long?,
canViewAdultContent: Boolean,
now: LocalDateTime,
sort: ContentSort,
offset: Long,
limit: Int,
onlyFree: Boolean = false,
onlyPointAvailable: Boolean = false
): List<MainContentAllAudio>
fun countSeries(
memberId: Long?,
canViewAdultContent: Boolean,
now: LocalDateTime,
onlyOriginal: Boolean = false,
dayOfWeek: SeriesPublishedDaysOfWeek? = null
): Int
fun findSeries(
memberId: Long?,
canViewAdultContent: Boolean,
now: LocalDateTime,
sort: ContentSort,
offset: Long,
limit: Int,
onlyOriginal: Boolean = false,
dayOfWeek: SeriesPublishedDaysOfWeek? = null,
locale: String
): List<MainContentAllSeries>
}