추천시리즈 API 추가

This commit is contained in:
Klaus 2024-05-07 16:10:21 +09:00
parent a3442b8f2f
commit 9b5c0696b1
3 changed files with 102 additions and 36 deletions

View File

@ -64,4 +64,13 @@ class ContentSeriesController(private val service: ContentSeriesService) {
)
)
}
@GetMapping("/recommend")
fun getRecommendSeriesList(
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
ApiResponse.ok(service.getRecommendSeriesList(member = member))
}
}

View File

@ -1,5 +1,6 @@
package kr.co.vividnext.sodalive.content.series
import com.querydsl.core.types.dsl.Expressions
import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag
@ -26,6 +27,7 @@ interface ContentSeriesQueryRepository {
fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series?
fun getKeywordList(seriesId: Long): List<String>
fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
fun getRecommendSeriesList(memberId: Long, isAuth: Boolean, limit: Long): List<Series>
}
class ContentSeriesQueryRepositoryImpl(
@ -108,4 +110,20 @@ class ContentSeriesQueryRepositoryImpl(
.where(series.id.eq(seriesId))
.fetchFirst()
}
override fun getRecommendSeriesList(memberId: Long, isAuth: Boolean, limit: Long): List<Series> {
var where = series.isActive.isTrue
if (!isAuth) {
where = where.and(series.isAdult.isFalse)
}
return queryFactory
.selectFrom(series)
.where(where)
.orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc())
.offset(0)
.limit(limit)
.fetch()
}
}

View File

@ -5,11 +5,13 @@ import kr.co.vividnext.sodalive.content.order.OrderRepository
import kr.co.vividnext.sodalive.content.order.OrderType
import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository
import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentListResponse
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.SeriesSortType
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState
import kr.co.vividnext.sodalive.explorer.ExplorerQueryRepository
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.time.LocalDateTime
@ -20,6 +22,7 @@ import java.time.format.DateTimeFormatter
class ContentSeriesService(
private val repository: ContentSeriesRepository,
private val orderRepository: OrderRepository,
private val blockMemberRepository: BlockMemberRepository,
private val explorerQueryRepository: ExplorerQueryRepository,
private val seriesContentRepository: ContentSeriesContentRepository,
@ -40,43 +43,9 @@ class ContentSeriesService(
isAuth = member.auth != null,
offset = offset,
limit = limit
)
).filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!) }
val items = rawItems
.map {
GetSeriesListResponse.SeriesListItem(
seriesId = it.id!!,
title = it.title,
coverImage = "$coverImageHost/${it.coverImage!!}",
publishedDaysOfWeek = publishedDaysOfWeekText(it.publishedDaysOfWeek),
isComplete = it.state == SeriesState.COMPLETE,
creator = GetSeriesListResponse.SeriesListItemCreator(
creatorId = it.member!!.id!!,
nickname = it.member!!.nickname,
profileImage = "$coverImageHost/${it.member!!.profileImage!!}"
)
)
}
.map {
it.numberOfContent = seriesContentRepository.getContentCount(
seriesId = it.seriesId,
isAdult = member.auth != null
)
it
}
.map {
val nowDateTime = LocalDateTime.now()
it.isNew = seriesContentRepository.isNewContent(
seriesId = it.seriesId,
isAdult = member.auth == null,
fromDate = nowDateTime.minusDays(7),
nowDate = nowDateTime
)
it
}
val items = seriesToSeriesListItem(seriesList = rawItems, isAdult = member.auth != null)
return GetSeriesListResponse(totalCount, items)
}
@ -87,6 +56,11 @@ class ContentSeriesService(
isAuth = member.auth != null
) ?: throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요")
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = series.member!!.id!!)
if (isBlocked) {
throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요")
}
val isFollow = explorerQueryRepository.isFollow(
creatorId = series.member!!.id!!,
memberId = member.id!!
@ -167,6 +141,71 @@ class ContentSeriesService(
return GetSeriesContentListResponse(totalCount, contentList)
}
fun getRecommendSeriesList(member: Member): List<GetSeriesListResponse.SeriesListItem> {
val seriesList = repository.getRecommendSeriesList(
memberId = member.id!!,
isAuth = member.auth != null,
limit = 10
).filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!) }
while (seriesList.size < 10) {
seriesList
.toMutableList()
.addAll(
repository.getRecommendSeriesList(
memberId = member.id!!,
isAuth = member.auth != null,
limit = 10L - seriesList.size
).filter {
!blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!)
}
)
}
return seriesToSeriesListItem(seriesList = seriesList, isAdult = member.auth != null)
}
private fun seriesToSeriesListItem(
seriesList: List<Series>,
isAdult: Boolean
): List<GetSeriesListResponse.SeriesListItem> {
return seriesList
.map {
GetSeriesListResponse.SeriesListItem(
seriesId = it.id!!,
title = it.title,
coverImage = "$coverImageHost/${it.coverImage!!}",
publishedDaysOfWeek = publishedDaysOfWeekText(it.publishedDaysOfWeek),
isComplete = it.state == SeriesState.COMPLETE,
creator = GetSeriesListResponse.SeriesListItemCreator(
creatorId = it.member!!.id!!,
nickname = it.member!!.nickname,
profileImage = "$coverImageHost/${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<SeriesPublishedDaysOfWeek>): String {
val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal }
.map {