sodalive-backend-spring-boot/src/main/kotlin/kr/co/vividnext/sodalive/rank/RankingService.kt

276 lines
9.5 KiB
Kotlin

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.GetAudioContentRankingItem
import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse
import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState
import kr.co.vividnext.sodalive.explorer.GetExplorerSectionResponse
import kr.co.vividnext.sodalive.member.MemberService
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.time.LocalDateTime
@Service
class RankingService(
private val repository: RankingRepository,
private val memberService: MemberService,
private val seriesContentRepository: ContentSeriesContentRepository,
@Value("\${cloud.aws.cloud-front.host}")
private val imageHost: String
) {
fun getCreatorRanking(memberId: Long?, rankingDate: String): GetExplorerSectionResponse {
val creatorRankings = repository
.getCreatorRankings()
.filter {
if (memberId != null) {
!memberService.isBlocked(blockedMemberId = memberId, memberId = it.id!!)
} else {
true
}
}
.map { it.toExplorerSectionCreator(imageHost) }
return GetExplorerSectionResponse(
title = "인기 크리에이터",
coloredTitle = "인기",
color = "FF5C49",
desc = rankingDate,
creators = creatorRankings
)
}
fun getContentRanking(
memberId: Long?,
isAdult: Boolean,
contentType: ContentType,
startDate: LocalDateTime,
endDate: LocalDateTime,
offset: Long = 0,
limit: Long = 12,
sortType: String = "매출",
theme: String = ""
): List<GetAudioContentRankingItem> {
var loopCount = 0L
var contentList: List<GetAudioContentRankingItem>
do {
contentList = repository.getAudioContentRanking(
memberId = memberId,
isAdult = isAdult,
contentType = contentType,
startDate = startDate.minusWeeks(loopCount),
endDate = endDate,
offset = offset,
limit = limit,
sortType = sortType,
theme = theme
)
loopCount++
} while (contentList.size < 5 && loopCount < 5)
return contentList
}
fun getSeriesRanking(
memberId: Long?,
isAdult: Boolean,
contentType: ContentType,
startDate: LocalDateTime,
endDate: LocalDateTime
): List<GetSeriesListResponse.SeriesListItem> {
var loopCount = 0L
var seriesList: List<Series>
do {
seriesList = repository.getSeriesRanking(
memberId = memberId,
isAdult = isAdult,
contentType = contentType,
startDate = startDate.minusWeeks(loopCount),
endDate = endDate
)
loopCount++
} while (seriesList.size < 5 && loopCount < 5)
return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult, contentType = contentType)
}
fun getSeriesAllRankingByGenre(
memberId: Long,
isAdult: Boolean,
contentType: ContentType,
genreId: Long
): List<GetSeriesListResponse.SeriesListItem> {
val seriesList = repository.getSeriesAllRankingByGenre(
memberId = memberId,
isAdult = isAdult,
contentType = contentType,
genreId = genreId
)
return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult, contentType = contentType)
}
fun getCompleteSeriesRankingTotalCount(
memberId: Long,
isAdult: Boolean,
contentType: ContentType
): Int {
return repository.getCompleteSeriesRankingTotalCount(
memberId = memberId,
isAdult = isAdult,
contentType = contentType
)
}
fun getCompleteSeriesRanking(
memberId: Long,
isAdult: Boolean,
contentType: ContentType,
startDate: LocalDateTime,
endDate: LocalDateTime,
offset: Long = 0,
limit: Long = 10
): List<GetSeriesListResponse.SeriesListItem> {
val seriesList = repository.getCompleteSeriesRanking(
memberId = memberId,
isAdult = isAdult,
contentType = contentType,
startDate = startDate,
endDate = endDate,
offset = offset,
limit = limit
)
return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult, contentType = contentType)
}
private fun seriesToSeriesListItem(
seriesList: List<Series>,
isAdult: Boolean,
contentType: ContentType
): List<GetSeriesListResponse.SeriesListItem> {
return seriesList
.map {
GetSeriesListResponse.SeriesListItem(
seriesId = it.id!!,
title = it.title,
coverImage = "$imageHost/${it.coverImage!!}",
publishedDaysOfWeek = publishedDaysOfWeekText(it.publishedDaysOfWeek),
isComplete = it.state == SeriesState.COMPLETE,
creator = GetSeriesListResponse.SeriesListItemCreator(
creatorId = it.member!!.id!!,
nickname = it.member!!.nickname,
profileImage = "$imageHost/${it.member!!.profileImage!!}"
)
)
}
.map {
it.numberOfContent = seriesContentRepository.getContentCount(
seriesId = it.seriesId,
isAdult = isAdult,
contentType = contentType
)
it
}
.map {
val nowDateTime = LocalDateTime.now()
it.isNew = seriesContentRepository.isNewContent(
seriesId = it.seriesId,
isAdult = isAdult,
fromDate = nowDateTime.minusDays(7),
nowDate = nowDateTime
)
it
}
}
private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek>): String {
val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal }
.map {
when (it) {
SeriesPublishedDaysOfWeek.SUN -> ""
SeriesPublishedDaysOfWeek.MON -> ""
SeriesPublishedDaysOfWeek.TUE -> ""
SeriesPublishedDaysOfWeek.WED -> ""
SeriesPublishedDaysOfWeek.THU -> ""
SeriesPublishedDaysOfWeek.FRI -> ""
SeriesPublishedDaysOfWeek.SAT -> ""
SeriesPublishedDaysOfWeek.RANDOM -> "랜덤"
}
}
.joinToString(", ") { it }
return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) {
dayOfWeekText
} else if (publishedDaysOfWeek.size < 7) {
"매주 $dayOfWeekText"
} else {
"매일"
}
}
fun fetchCreatorBySellContentCountRankTop20(
memberId: Long?,
isAdult: Boolean,
contentType: ContentType,
startDate: LocalDateTime,
endDate: LocalDateTime
): List<ContentCreatorResponse> {
return repository.fetchCreatorBySellContentCountRankTop20(memberId, isAdult, contentType, startDate, endDate)
}
fun fetchCreatorContentBySalesCountTop4(
creatorId: Long,
isAdult: Boolean,
contentType: ContentType,
theme: String = ""
): List<GetAudioContentRankingItem> {
return repository.fetchCreatorContentBySalesCountTop4(creatorId, isAdult, contentType, theme)
}
fun fetchCreatorContentByLikeCountTop4(
creatorId: Long,
isAdult: Boolean,
contentType: ContentType
): List<GetAudioContentRankingItem> {
return repository.fetchCreatorContentByLikeCountTop4(creatorId, isAdult, contentType)
}
fun fetchCreatorBySeriesRevenueRankTop20(
memberId: Long,
contentType: ContentType,
startDate: LocalDateTime,
endDate: LocalDateTime
): List<ContentCreatorResponse> {
return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, contentType, startDate, endDate)
}
fun fetchCreatorSeriesBySales(
creatorId: Long,
isAdult: Boolean,
contentType: ContentType
): List<GetSeriesListResponse.SeriesListItem> {
val seriesList = repository.fetchCreatorSeriesBySales(
creatorId = creatorId,
isAdult = isAdult,
contentType = contentType
)
return seriesToSeriesListItem(seriesList, isAdult, contentType = contentType)
}
fun fetchFreeContentByCreatorIdTop4(
creatorId: Long,
isAdult: Boolean,
contentType: ContentType
): List<GetAudioContentRankingItem> {
return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult, contentType)
}
}