추천시리즈 API 추가 #177
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,57 @@ 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!!) }
|
||||
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue