콘텐츠 메인 무료 탭
- 채널별 추천 무료 콘텐츠 API 추가
This commit is contained in:
		| @@ -32,6 +32,7 @@ data class AudioContent( | ||||
|     var title: String, | ||||
|     @Column(columnDefinition = "TEXT", nullable = false) | ||||
|     var detail: String, | ||||
|     var playCount: Long = 0, | ||||
|     var price: Int = 0, | ||||
|     var releaseDate: LocalDateTime? = null, | ||||
|     val limited: Int? = null, | ||||
|   | ||||
| @@ -60,4 +60,39 @@ class AudioContentMainTabRepository( | ||||
|             .limit(20) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     fun findCreatorWithHasFreeContent(memberId: Long, minCount: Int): List<ContentCreatorResponse> { | ||||
|         val blockMemberCondition = blockMember.member.id.eq(member.id) | ||||
|             .and(blockMember.isActive.isTrue) | ||||
|             .and(blockMember.blockedMember.id.eq(memberId)) | ||||
|  | ||||
|         val where = member.isActive.isTrue | ||||
|             .and(member.role.eq(MemberRole.CREATOR)) | ||||
|             .and(audioContent.isActive.isTrue) | ||||
|             .and(audioContent.price.loe(0)) | ||||
|             .and(audioContent.duration.isNotNull) | ||||
|             .and(audioContent.limited.isNull) | ||||
|             .and(blockMember.id.isNull) | ||||
|  | ||||
|         return queryFactory | ||||
|             .select( | ||||
|                 QContentCreatorResponse( | ||||
|                     member.id, | ||||
|                     member.nickname, | ||||
|                     member.profileImage.prepend("/").prepend(imageHost) | ||||
|                 ) | ||||
|             ) | ||||
|             .from(member) | ||||
|             .innerJoin(audioContent).on(member.id.eq(audioContent.member.id)) | ||||
|             .leftJoin(blockMember).on(blockMemberCondition) | ||||
|             .where(where) | ||||
|             .groupBy(member.id) | ||||
|             .having(audioContent.id.count().goe(minCount)) | ||||
|             .orderBy( | ||||
|                 Expressions.numberTemplate(Double::class.java, "function('rand')").asc() | ||||
|             ) | ||||
|             .offset(0) | ||||
|             .limit(20) | ||||
|             .fetch() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -60,4 +60,19 @@ class AudioContentMainTabFreeController(private val service: AudioContentMainTab | ||||
|             ) | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/popular-content-by-creator") | ||||
|     fun getPopularContentByCreator( | ||||
|         @RequestParam creatorId: Long, | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok( | ||||
|             service.getPopularContentByCreator( | ||||
|                 creatorId = creatorId, | ||||
|                 isAdult = member.auth != null | ||||
|             ) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,20 +3,25 @@ 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.GetAudioContentMainItem | ||||
| import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem | ||||
| 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.AudioContentMainTabRepository | ||||
| 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 kr.co.vividnext.sodalive.rank.RankingService | ||||
| import org.springframework.stereotype.Service | ||||
|  | ||||
| @Service | ||||
| class AudioContentMainTabFreeService( | ||||
|     private val repository: AudioContentMainTabRepository, | ||||
|     private val bannerService: AudioContentBannerService, | ||||
|     private val recommendSeriesRepository: RecommendSeriesRepository, | ||||
|     private val curationRepository: AudioContentCurationQueryRepository, | ||||
|     private val contentRepository: AudioContentRepository, | ||||
|     private val rankingService: RankingService, | ||||
|     private val audioContentRepository: AudioContentRepository, | ||||
|     private val audioContentThemeRepository: AudioContentThemeQueryRepository | ||||
| ) { | ||||
| @@ -63,6 +68,13 @@ class AudioContentMainTabFreeService( | ||||
|             emptyList() | ||||
|         } | ||||
|  | ||||
|         val creatorList = repository.findCreatorWithHasFreeContent(memberId, 4) | ||||
|         val playCountRankContentList = if (creatorList.isNotEmpty()) { | ||||
|             rankingService.fetchFreeContentByCreatorIdTop4(creatorList[0].creatorId, isAdult) | ||||
|         } else { | ||||
|             emptyList() | ||||
|         } | ||||
|  | ||||
|         val curationList = curationRepository.findByContentMainTabId(tabId = tabId, isAdult = isAdult) | ||||
|             .filter { it.title != "크리에이터 소개" } | ||||
|             .map { | ||||
| @@ -86,6 +98,8 @@ class AudioContentMainTabFreeService( | ||||
|             recommendSeriesList = recommendSeriesList, | ||||
|             themeList = themeList, | ||||
|             newFreeContentList = newFreeContentList, | ||||
|             creatorList = creatorList, | ||||
|             playCountRankContentList = playCountRankContentList, | ||||
|             curationList = curationList | ||||
|         ) | ||||
|     } | ||||
| @@ -131,4 +145,8 @@ class AudioContentMainTabFreeService( | ||||
|             isFree = true | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     fun getPopularContentByCreator(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> { | ||||
|         return rankingService.fetchFreeContentByCreatorIdTop4(creatorId, isAdult) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package kr.co.vividnext.sodalive.content.main.tab.free | ||||
|  | ||||
| import kr.co.vividnext.sodalive.content.main.ContentCreatorResponse | ||||
| import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem | ||||
| import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem | ||||
| 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 | ||||
| @@ -12,5 +14,7 @@ data class GetContentMainTabFreeResponse( | ||||
|     val recommendSeriesList: List<GetRecommendSeriesListResponse>, | ||||
|     val themeList: List<String>, | ||||
|     val newFreeContentList: List<GetAudioContentMainItem>, | ||||
|     val creatorList: List<ContentCreatorResponse>, | ||||
|     val playCountRankContentList: List<GetAudioContentRankingItem>, | ||||
|     val curationList: List<GetContentCurationResponse> | ||||
| ) | ||||
|   | ||||
| @@ -508,4 +508,38 @@ class RankingRepository( | ||||
|             .limit(10) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> { | ||||
|         var where = member.isActive.isTrue | ||||
|             .and(member.id.eq(creatorId)) | ||||
|             .and(member.role.eq(MemberRole.CREATOR)) | ||||
|             .and(audioContent.isActive.isTrue) | ||||
|             .and(audioContent.duration.isNotNull) | ||||
|             .and(audioContent.limited.isNull) | ||||
|  | ||||
|         if (!isAdult) { | ||||
|             where = where.and(series.isAdult.isFalse) | ||||
|         } | ||||
|  | ||||
|         return queryFactory | ||||
|             .select( | ||||
|                 QGetAudioContentRankingItem( | ||||
|                     audioContent.id, | ||||
|                     audioContent.title, | ||||
|                     audioContent.coverImage.prepend("/").prepend(imageHost), | ||||
|                     audioContentTheme.theme, | ||||
|                     audioContent.price, | ||||
|                     audioContent.duration, | ||||
|                     member.id, | ||||
|                     member.nickname, | ||||
|                     member.profileImage.prepend("/").prepend(imageHost) | ||||
|                 ) | ||||
|             ) | ||||
|             .from(audioContent) | ||||
|             .where(where) | ||||
|             .orderBy(audioContent.playCount.desc()) | ||||
|             .offset(0) | ||||
|             .limit(4) | ||||
|             .fetch() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -209,4 +209,8 @@ class RankingService( | ||||
|         val seriesList = repository.fetchCreatorSeriesBySales(creatorId = creatorId, isAdult = isAdult) | ||||
|         return seriesToSeriesListItem(seriesList, isAdult) | ||||
|     } | ||||
|  | ||||
|     fun fetchFreeContentByCreatorIdTop4(creatorId: Long, isAdult: Boolean): List<GetAudioContentRankingItem> { | ||||
|         return repository.fetchFreeContentByCreatorIdTop4(creatorId, isAdult) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user