package kr.co.vividnext.sodalive.rank 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 { !memberService.isBlocked(blockedMemberId = memberId, memberId = it.id!!) } .map { it.toExplorerSectionCreator(imageHost) } return GetExplorerSectionResponse( title = "인기 크리에이터", coloredTitle = "인기", color = "FF5C49", desc = rankingDate, creators = creatorRankings ) } fun getContentRanking( memberId: Long, isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime, offset: Long = 0, limit: Long = 12, sortType: String = "매출", theme: String = "" ): List { return repository.getAudioContentRanking( memberId = memberId, isAdult = isAdult, startDate = startDate, endDate = endDate, offset = offset, limit = limit, sortType = sortType, theme = theme ) } fun getSeriesRanking( memberId: Long, isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime ): List { val seriesList = repository.getSeriesRanking(memberId, isAdult, startDate, endDate) return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult) } fun getSeriesAllRankingByGenre( memberId: Long, isAdult: Boolean, genreId: Long ): List { val seriesList = repository.getSeriesAllRankingByGenre( memberId = memberId, isAdult = isAdult, genreId = genreId ) return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult) } fun getCompleteSeriesRankingTotalCount( memberId: Long, isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime ): Int { return repository.getCompleteSeriesRankingTotalCount( memberId = memberId, isAdult = isAdult, startDate = startDate, endDate = endDate ) } fun getCompleteSeriesRanking( memberId: Long, isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime, offset: Long = 0, limit: Long = 10 ): List { val seriesList = repository.getCompleteSeriesRanking( memberId = memberId, isAdult = isAdult, startDate = startDate, endDate = endDate, offset = offset, limit = limit ) return seriesToSeriesListItem(seriesList = seriesList, isAdult = isAdult) } private fun seriesToSeriesListItem( seriesList: List, isAdult: Boolean ): List { 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 ) 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): 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 fetchCreatorByContentRevenueRankTop20( memberId: Long, startDate: LocalDateTime, endDate: LocalDateTime ): List { return repository.fetchCreatorByContentRevenueRankTop20(memberId, startDate, endDate) } fun fetchCreatorContentBySalesTop2(creatorId: Long, isAdult: Boolean): List { return repository.fetchCreatorContentBySalesTop2(creatorId, isAdult) } fun fetchCreatorContentBySalesCountTop2(creatorId: Long, isAdult: Boolean): List { return repository.fetchCreatorContentBySalesCountTop2(creatorId, isAdult) } fun fetchCreatorBySeriesRevenueRankTop20( memberId: Long, startDate: LocalDateTime, endDate: LocalDateTime ): List { return repository.fetchCreatorBySeriesRevenueRankTop20(memberId, startDate, endDate) } fun fetchCreatorSeriesBySales(creatorId: Long, isAdult: Boolean): List { val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult) return seriesToSeriesListItem(seriesList, isAdult) } }