feat(content-preference): 콘텐츠 조회 설정 서버 저장 전환을 반영한다
This commit is contained in:
@@ -24,8 +24,8 @@ class HomeController(private val service: HomeService) {
|
||||
ApiResponse.ok(
|
||||
service.fetchData(
|
||||
timezone = timezone,
|
||||
isAdultContentVisible = isAdultContentVisible ?: true,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
member
|
||||
)
|
||||
)
|
||||
@@ -41,8 +41,8 @@ class HomeController(private val service: HomeService) {
|
||||
ApiResponse.ok(
|
||||
service.getLatestContentByTheme(
|
||||
theme = theme,
|
||||
isAdultContentVisible = isAdultContentVisible ?: true,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
member
|
||||
)
|
||||
)
|
||||
@@ -58,8 +58,8 @@ class HomeController(private val service: HomeService) {
|
||||
ApiResponse.ok(
|
||||
service.getDayOfWeekSeriesList(
|
||||
dayOfWeek = dayOfWeek,
|
||||
isAdultContentVisible = isAdultContentVisible ?: true,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
member
|
||||
)
|
||||
)
|
||||
@@ -74,8 +74,8 @@ class HomeController(private val service: HomeService) {
|
||||
) = run {
|
||||
ApiResponse.ok(
|
||||
service.getRecommendContentList(
|
||||
isAdultContentVisible = isAdultContentVisible ?: true,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
member = member
|
||||
)
|
||||
)
|
||||
@@ -95,8 +95,8 @@ class HomeController(private val service: HomeService) {
|
||||
ApiResponse.ok(
|
||||
service.getContentRankingBySort(
|
||||
sort = sort ?: ContentRankingSortType.REVENUE,
|
||||
isAdultContentVisible = isAdultContentVisible ?: true,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
theme = theme,
|
||||
|
||||
@@ -18,6 +18,8 @@ import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomService
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.ViewerContentPreference
|
||||
import kr.co.vividnext.sodalive.query.recommend.RecommendChannelQueryService
|
||||
import kr.co.vividnext.sodalive.rank.ContentRankingSortType
|
||||
import kr.co.vividnext.sodalive.rank.RankingRepository
|
||||
@@ -47,6 +49,7 @@ class HomeService(
|
||||
private val explorerQueryRepository: ExplorerQueryRepository,
|
||||
|
||||
private val langContext: LangContext,
|
||||
private val memberContentPreferenceService: MemberContentPreferenceService,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val imageHost: String
|
||||
@@ -69,17 +72,19 @@ class HomeService(
|
||||
|
||||
fun fetchData(
|
||||
timezone: String,
|
||||
isAdultContentVisible: Boolean,
|
||||
contentType: ContentType,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?,
|
||||
member: Member?
|
||||
): GetHomeResponse {
|
||||
val preference = resolvePreference(member, isAdultContentVisible, contentType)
|
||||
val memberId = member?.id
|
||||
val isAdult = member?.auth != null && isAdultContentVisible
|
||||
val isAdult = preference.isAdult
|
||||
val resolvedContentType = preference.contentType
|
||||
|
||||
val liveList = liveRoomService.getRoomList(
|
||||
dateString = null,
|
||||
status = LiveRoomStatus.NOW,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
isAdultContentVisible = isAdult,
|
||||
pageable = Pageable.ofSize(10),
|
||||
member = member,
|
||||
timezone = timezone
|
||||
@@ -102,14 +107,14 @@ class HomeService(
|
||||
|
||||
val latestContentThemeList = contentThemeService.getActiveThemeOfContent(
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
excludeThemes = listOf("다시듣기")
|
||||
)
|
||||
|
||||
val latestContentList = contentService.getLatestContentByTheme(
|
||||
memberId = memberId,
|
||||
theme = latestContentThemeList,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
isFree = false,
|
||||
isAdult = isAdult
|
||||
)
|
||||
@@ -128,7 +133,7 @@ class HomeService(
|
||||
val originalAudioDramaList = seriesService.getOriginalAudioDramaList(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType
|
||||
contentType = resolvedContentType
|
||||
)
|
||||
|
||||
val auditionList = auditionService.getInProgressAuditionList(isAdult = isAdult)
|
||||
@@ -137,7 +142,7 @@ class HomeService(
|
||||
val translatedDayOfWeekSeriesList = seriesService.getDayOfWeekSeriesList(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
dayOfWeek = getDayOfWeekByTimezone(timezone)
|
||||
)
|
||||
|
||||
@@ -157,7 +162,7 @@ class HomeService(
|
||||
val contentRanking = rankingService.getContentRanking(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
startDate = startDate.minusDays(1),
|
||||
endDate = endDate,
|
||||
sort = ContentRankingSortType.REVENUE
|
||||
@@ -166,17 +171,17 @@ class HomeService(
|
||||
val recommendChannelList = recommendChannelService.getRecommendChannel(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType
|
||||
contentType = resolvedContentType
|
||||
)
|
||||
|
||||
val freeContentList = getRandomizedContentList(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
theme = contentThemeService.getActiveThemeOfContent(
|
||||
isAdult = isAdult,
|
||||
isFree = true,
|
||||
contentType = contentType
|
||||
contentType = resolvedContentType
|
||||
),
|
||||
isFree = true,
|
||||
isPointAvailableOnly = false
|
||||
@@ -186,7 +191,7 @@ class HomeService(
|
||||
val pointAvailableContentList = getRandomizedContentList(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
theme = emptyList(),
|
||||
isFree = false,
|
||||
isPointAvailableOnly = true
|
||||
@@ -212,9 +217,8 @@ class HomeService(
|
||||
recommendChannelList = recommendChannelList,
|
||||
freeContentList = freeContentList,
|
||||
pointAvailableContentList = pointAvailableContentList,
|
||||
recommendContentList = getRecommendContentList(
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
recommendContentList = getRecommendContentListByPreference(
|
||||
preference = preference,
|
||||
member = member,
|
||||
excludeContentIds = excludeContentIds
|
||||
)
|
||||
@@ -223,18 +227,20 @@ class HomeService(
|
||||
|
||||
fun getLatestContentByTheme(
|
||||
theme: String,
|
||||
isAdultContentVisible: Boolean,
|
||||
contentType: ContentType,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?,
|
||||
member: Member?
|
||||
): List<AudioContentMainItem> {
|
||||
val preference = resolvePreference(member, isAdultContentVisible, contentType)
|
||||
val memberId = member?.id
|
||||
val isAdult = member?.auth != null && isAdultContentVisible
|
||||
val isAdult = preference.isAdult
|
||||
val resolvedContentType = preference.contentType
|
||||
|
||||
val themeList = if (theme.isBlank()) {
|
||||
contentThemeService.getActiveThemeOfContent(
|
||||
isAdult = isAdult,
|
||||
isFree = false,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
excludeThemes = listOf("다시듣기")
|
||||
)
|
||||
} else {
|
||||
@@ -244,7 +250,7 @@ class HomeService(
|
||||
return contentService.getLatestContentByTheme(
|
||||
memberId = memberId,
|
||||
theme = themeList,
|
||||
contentType = contentType,
|
||||
contentType = resolvedContentType,
|
||||
isFree = false,
|
||||
isAdult = isAdult
|
||||
)
|
||||
@@ -252,32 +258,34 @@ class HomeService(
|
||||
|
||||
fun getDayOfWeekSeriesList(
|
||||
dayOfWeek: SeriesPublishedDaysOfWeek,
|
||||
isAdultContentVisible: Boolean,
|
||||
contentType: ContentType,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?,
|
||||
member: Member?
|
||||
): List<GetSeriesListResponse.SeriesListItem> {
|
||||
val preference = resolvePreference(member, isAdultContentVisible, contentType)
|
||||
val memberId = member?.id
|
||||
val isAdult = member?.auth != null && isAdultContentVisible
|
||||
val isAdult = preference.isAdult
|
||||
|
||||
return seriesService.getDayOfWeekSeriesList(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = preference.contentType,
|
||||
dayOfWeek = dayOfWeek
|
||||
)
|
||||
}
|
||||
|
||||
fun getContentRankingBySort(
|
||||
sort: ContentRankingSortType,
|
||||
isAdultContentVisible: Boolean,
|
||||
contentType: ContentType,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?,
|
||||
offset: Long?,
|
||||
limit: Long?,
|
||||
theme: String?,
|
||||
member: Member?
|
||||
): List<GetAudioContentRankingItem> {
|
||||
val preference = resolvePreference(member, isAdultContentVisible, contentType)
|
||||
val memberId = member?.id
|
||||
val isAdult = member?.auth != null && isAdultContentVisible
|
||||
val isAdult = preference.isAdult
|
||||
|
||||
val currentDateTime = LocalDateTime.now()
|
||||
val startDate = currentDateTime
|
||||
@@ -291,7 +299,7 @@ class HomeService(
|
||||
return rankingService.getContentRanking(
|
||||
memberId = memberId,
|
||||
isAdult = isAdult,
|
||||
contentType = contentType,
|
||||
contentType = preference.contentType,
|
||||
startDate = startDate.minusDays(1),
|
||||
endDate = endDate,
|
||||
offset = offset ?: 0,
|
||||
@@ -320,13 +328,22 @@ class HomeService(
|
||||
}
|
||||
|
||||
fun getRecommendContentList(
|
||||
isAdultContentVisible: Boolean,
|
||||
contentType: ContentType,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?,
|
||||
member: Member?,
|
||||
excludeContentIds: List<Long> = emptyList()
|
||||
): List<AudioContentMainItem> {
|
||||
val preference = resolvePreference(member, isAdultContentVisible, contentType)
|
||||
return getRecommendContentListByPreference(preference, member, excludeContentIds)
|
||||
}
|
||||
|
||||
private fun getRecommendContentListByPreference(
|
||||
preference: ViewerContentPreference,
|
||||
member: Member?,
|
||||
excludeContentIds: List<Long>
|
||||
): List<AudioContentMainItem> {
|
||||
val memberId = member?.id
|
||||
val isAdult = member?.auth != null && isAdultContentVisible
|
||||
val isAdult = preference.isAdult
|
||||
|
||||
// 3개의 버킷(최근/중간/과거)에서 후보군을 조회한 뒤, 시간감쇠 점수 기반으로 샘플링한다.
|
||||
val buckets = listOf(
|
||||
@@ -350,7 +367,7 @@ class HomeService(
|
||||
val batch = contentService.getLatestContentByTheme(
|
||||
memberId = memberId,
|
||||
theme = emptyList(),
|
||||
contentType = contentType,
|
||||
contentType = preference.contentType,
|
||||
offset = bucket.offset,
|
||||
limit = bucket.limit,
|
||||
sortType = SortType.NEWEST,
|
||||
@@ -374,6 +391,27 @@ class HomeService(
|
||||
return result.take(RECOMMEND_TARGET_SIZE).shuffled()
|
||||
}
|
||||
|
||||
private fun resolvePreference(
|
||||
member: Member?,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?
|
||||
): ViewerContentPreference {
|
||||
if (member == null) {
|
||||
return ViewerContentPreference(
|
||||
countryCode = "KR",
|
||||
isAdultContentVisible = isAdultContentVisible ?: false,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdult = false
|
||||
)
|
||||
}
|
||||
|
||||
return memberContentPreferenceService.resolveForQuery(
|
||||
member = member,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType
|
||||
)
|
||||
}
|
||||
|
||||
private fun pickByTimeDecay(
|
||||
batch: List<AudioContentMainItem>,
|
||||
targetSize: Int,
|
||||
|
||||
@@ -23,8 +23,8 @@ class LiveApiController(
|
||||
) = run {
|
||||
ApiResponse.ok(
|
||||
service.fetchData(
|
||||
isAdultContentVisible = isAdultContentVisible ?: true,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType,
|
||||
timezone = timezone,
|
||||
member = member
|
||||
)
|
||||
|
||||
@@ -8,6 +8,8 @@ import kr.co.vividnext.sodalive.live.room.LiveRoomService
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomStatus
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.ViewerContentPreference
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@@ -17,22 +19,24 @@ class LiveApiService(
|
||||
private val contentService: AudioContentService,
|
||||
private val recommendService: LiveRecommendService,
|
||||
private val creatorCommunityService: CreatorCommunityService,
|
||||
private val memberContentPreferenceService: MemberContentPreferenceService,
|
||||
|
||||
private val blockMemberRepository: BlockMemberRepository
|
||||
) {
|
||||
fun fetchData(
|
||||
isAdultContentVisible: Boolean,
|
||||
contentType: ContentType,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?,
|
||||
timezone: String,
|
||||
member: Member?
|
||||
): LiveMainResponse {
|
||||
val preference = resolvePreference(member, isAdultContentVisible, contentType)
|
||||
val memberId = member?.id
|
||||
val isAdult = member?.auth != null && isAdultContentVisible
|
||||
val isAdult = preference.isAdult
|
||||
|
||||
val liveOnAirRoomList = liveService.getRoomList(
|
||||
dateString = null,
|
||||
status = LiveRoomStatus.NOW,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
isAdultContentVisible = isAdult,
|
||||
pageable = Pageable.ofSize(20),
|
||||
member = member,
|
||||
timezone = timezone
|
||||
@@ -55,7 +59,7 @@ class LiveApiService(
|
||||
val replayLive = contentService.getLatestContentByTheme(
|
||||
memberId = memberId,
|
||||
theme = listOf("다시듣기"),
|
||||
contentType = contentType,
|
||||
contentType = preference.contentType,
|
||||
isFree = false,
|
||||
isAdult = isAdult
|
||||
)
|
||||
@@ -77,7 +81,7 @@ class LiveApiService(
|
||||
val liveReservationRoomList = liveService.getRoomList(
|
||||
dateString = null,
|
||||
status = LiveRoomStatus.RESERVATION,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
isAdultContentVisible = isAdult,
|
||||
pageable = Pageable.ofSize(10),
|
||||
member = member,
|
||||
timezone = timezone
|
||||
@@ -93,4 +97,25 @@ class LiveApiService(
|
||||
liveReservationRoomList = liveReservationRoomList
|
||||
)
|
||||
}
|
||||
|
||||
private fun resolvePreference(
|
||||
member: Member?,
|
||||
isAdultContentVisible: Boolean?,
|
||||
contentType: ContentType?
|
||||
): ViewerContentPreference {
|
||||
if (member == null) {
|
||||
return ViewerContentPreference(
|
||||
countryCode = "KR",
|
||||
isAdultContentVisible = isAdultContentVisible ?: false,
|
||||
contentType = contentType ?: ContentType.ALL,
|
||||
isAdult = false
|
||||
)
|
||||
}
|
||||
|
||||
return memberContentPreferenceService.resolveForQuery(
|
||||
member = member,
|
||||
isAdultContentVisible = isAdultContentVisible,
|
||||
contentType = contentType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user