parent
0350f86322
commit
3b807543b7
|
@ -46,4 +46,22 @@ class ContentSeriesController(private val service: ContentSeriesService) {
|
|||
service.getSeriesDetail(seriesId = id, member = member)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/content")
|
||||
fun getSeriesContentList(
|
||||
@PathVariable id: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getSeriesContentList(
|
||||
seriesId = id,
|
||||
member = member,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import kr.co.vividnext.sodalive.content.series.content.QGetSeriesContentMinMaxPr
|
|||
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series
|
||||
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent
|
||||
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.keyword.QSeriesKeyword.seriesKeyword
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
|
@ -25,7 +24,6 @@ interface ContentSeriesQueryRepository {
|
|||
): List<Series>
|
||||
|
||||
fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series?
|
||||
fun getPublishedDaysOfWeek(seriesId: Long): Set<SeriesPublishedDaysOfWeek>
|
||||
fun getKeywordList(seriesId: Long): List<String>
|
||||
fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
|
||||
}
|
||||
|
@ -85,14 +83,6 @@ class ContentSeriesQueryRepositoryImpl(
|
|||
.fetchFirst()
|
||||
}
|
||||
|
||||
override fun getPublishedDaysOfWeek(seriesId: Long): Set<SeriesPublishedDaysOfWeek> {
|
||||
return queryFactory
|
||||
.select(series.publishedDaysOfWeek)
|
||||
.from(series)
|
||||
.where(series.id.eq(seriesId))
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
override fun getKeywordList(seriesId: Long): List<String> {
|
||||
return queryFactory
|
||||
.select(hashTag.tag)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package kr.co.vividnext.sodalive.content.series
|
||||
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
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.SeriesPublishedDaysOfWeek
|
||||
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType
|
||||
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState
|
||||
|
@ -16,6 +19,7 @@ import java.time.format.DateTimeFormatter
|
|||
@Service
|
||||
class ContentSeriesService(
|
||||
private val repository: ContentSeriesRepository,
|
||||
private val orderRepository: OrderRepository,
|
||||
private val explorerQueryRepository: ExplorerQueryRepository,
|
||||
private val seriesContentRepository: ContentSeriesContentRepository,
|
||||
|
||||
|
@ -97,7 +101,9 @@ class ContentSeriesService(
|
|||
val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt()
|
||||
val rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt()
|
||||
|
||||
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||
val seriesContentList = getSeriesContentList(seriesId = seriesId, member = member, offset = 0, limit = 5)
|
||||
|
||||
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd")
|
||||
return GetSeriesDetailResponse(
|
||||
seriesId = seriesId,
|
||||
title = series.title,
|
||||
|
@ -124,11 +130,43 @@ class ContentSeriesService(
|
|||
minPrice = minPrice,
|
||||
maxPrice = maxPrice,
|
||||
keywordList = keywordList,
|
||||
publishedDaysOfWeek = publishedDaysOfWeekText(series.publishedDaysOfWeek)
|
||||
|
||||
publishedDaysOfWeek = publishedDaysOfWeekText(series.publishedDaysOfWeek),
|
||||
contentList = seriesContentList.items,
|
||||
contentCount = seriesContentList.totalCount
|
||||
)
|
||||
}
|
||||
|
||||
fun getSeriesContentList(seriesId: Long, member: Member, offset: Long, limit: Long): GetSeriesContentListResponse {
|
||||
val isAdult = member.auth != null
|
||||
|
||||
val totalCount = seriesContentRepository.getContentCount(seriesId, isAdult = isAdult)
|
||||
val contentList = seriesContentRepository.getContentList(
|
||||
seriesId = seriesId,
|
||||
isAdult = isAdult,
|
||||
imageHost = coverImageHost,
|
||||
offset = offset,
|
||||
limit = limit
|
||||
)
|
||||
.map {
|
||||
val (isExistsAudioContent, orderType) = orderRepository.isExistOrderedAndOrderType(
|
||||
memberId = member.id!!,
|
||||
contentId = it.contentId
|
||||
)
|
||||
|
||||
if (isExistsAudioContent) {
|
||||
if (orderType == OrderType.RENTAL) {
|
||||
it.isRented = true
|
||||
} else {
|
||||
it.isOwned = true
|
||||
}
|
||||
}
|
||||
|
||||
it
|
||||
}
|
||||
|
||||
return GetSeriesContentListResponse(totalCount, contentList)
|
||||
}
|
||||
|
||||
private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek>): String {
|
||||
val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal }
|
||||
.map {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package kr.co.vividnext.sodalive.content.series
|
||||
|
||||
import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentListItem
|
||||
|
||||
data class GetSeriesDetailResponse(
|
||||
val seriesId: Long,
|
||||
val title: String,
|
||||
|
@ -14,15 +16,17 @@ data class GetSeriesDetailResponse(
|
|||
var rentalMinPrice: Int,
|
||||
var rentalMaxPrice: Int,
|
||||
val rentalPeriod: Int,
|
||||
var minPrice: Int,
|
||||
var maxPrice: Int,
|
||||
var keywordList: List<String>,
|
||||
var publishedDaysOfWeek: String
|
||||
val minPrice: Int,
|
||||
val maxPrice: Int,
|
||||
val keywordList: List<String>,
|
||||
val publishedDaysOfWeek: String,
|
||||
val contentList: List<GetSeriesContentListItem>,
|
||||
val contentCount: Int
|
||||
) {
|
||||
data class GetSeriesDetailCreator(
|
||||
val creatorId: Long,
|
||||
val nickname: String,
|
||||
val profileImage: String,
|
||||
var isFollow: Boolean
|
||||
val isFollow: Boolean
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package kr.co.vividnext.sodalive.content.series.content
|
||||
|
||||
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.creator.admin.content.series.QSeries.series
|
||||
|
@ -12,6 +13,14 @@ interface ContentSeriesContentRepository : JpaRepository<SeriesContent, Long>, C
|
|||
|
||||
interface ContentSeriesContentQueryRepository {
|
||||
fun getContentCount(seriesId: Long, isAdult: Boolean): Int
|
||||
fun getContentList(
|
||||
seriesId: Long,
|
||||
isAdult: Boolean,
|
||||
imageHost: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetSeriesContentListItem>
|
||||
|
||||
fun isNewContent(seriesId: Long, isAdult: Boolean, fromDate: LocalDateTime, nowDate: LocalDateTime): Boolean
|
||||
}
|
||||
|
||||
|
@ -36,6 +45,53 @@ class ContentSeriesContentQueryRepositoryImpl(
|
|||
.size
|
||||
}
|
||||
|
||||
override fun getContentList(
|
||||
seriesId: Long,
|
||||
isAdult: Boolean,
|
||||
imageHost: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetSeriesContentListItem> {
|
||||
var where = series.id.eq(seriesId)
|
||||
.and(audioContent.isActive.isTrue)
|
||||
.and(audioContent.duration.isNotNull)
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(audioContent.isAdult.isFalse)
|
||||
}
|
||||
|
||||
val formattedDate = Expressions.stringTemplate(
|
||||
"DATE_FORMAT({0}, {1})",
|
||||
Expressions.dateTimeTemplate(
|
||||
LocalDateTime::class.java,
|
||||
"CONVERT_TZ({0},{1},{2})",
|
||||
audioContent.releaseDate,
|
||||
"UTC",
|
||||
"Asia/Seoul"
|
||||
),
|
||||
"%y.%m.%d"
|
||||
)
|
||||
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetSeriesContentListItem(
|
||||
audioContent.id,
|
||||
audioContent.title,
|
||||
audioContent.coverImage.prepend("/").prepend(imageHost),
|
||||
formattedDate,
|
||||
audioContent.duration,
|
||||
audioContent.price,
|
||||
Expressions.asBoolean(false),
|
||||
Expressions.asBoolean(false)
|
||||
)
|
||||
)
|
||||
.from(seriesContent)
|
||||
.innerJoin(seriesContent.series, series)
|
||||
.innerJoin(seriesContent.content, audioContent)
|
||||
.where(where)
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun isNewContent(
|
||||
seriesId: Long,
|
||||
isAdult: Boolean,
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package kr.co.vividnext.sodalive.content.series.content
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
|
||||
data class GetSeriesContentListResponse(
|
||||
val totalCount: Int,
|
||||
val items: List<GetSeriesContentListItem>
|
||||
)
|
||||
|
||||
data class GetSeriesContentListItem @QueryProjection constructor(
|
||||
val contentId: Long,
|
||||
val title: String,
|
||||
val coverImage: String,
|
||||
val releaseDate: String,
|
||||
val duration: String,
|
||||
val price: Int,
|
||||
var isRented: Boolean,
|
||||
var isOwned: Boolean
|
||||
)
|
Loading…
Reference in New Issue