parent
0350f86322
commit
3b807543b7
|
@ -46,4 +46,22 @@ class ContentSeriesController(private val service: ContentSeriesService) {
|
||||||
service.getSeriesDetail(seriesId = id, member = member)
|
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.QSeries.series
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent
|
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.Series
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
|
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.QSeriesKeyword.seriesKeyword
|
import kr.co.vividnext.sodalive.creator.admin.content.series.keyword.QSeriesKeyword.seriesKeyword
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
|
||||||
|
@ -25,7 +24,6 @@ interface ContentSeriesQueryRepository {
|
||||||
): List<Series>
|
): List<Series>
|
||||||
|
|
||||||
fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series?
|
fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series?
|
||||||
fun getPublishedDaysOfWeek(seriesId: Long): Set<SeriesPublishedDaysOfWeek>
|
|
||||||
fun getKeywordList(seriesId: Long): List<String>
|
fun getKeywordList(seriesId: Long): List<String>
|
||||||
fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
|
fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse
|
||||||
}
|
}
|
||||||
|
@ -85,14 +83,6 @@ class ContentSeriesQueryRepositoryImpl(
|
||||||
.fetchFirst()
|
.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> {
|
override fun getKeywordList(seriesId: Long): List<String> {
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(hashTag.tag)
|
.select(hashTag.tag)
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package kr.co.vividnext.sodalive.content.series
|
package kr.co.vividnext.sodalive.content.series
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.common.SodaException
|
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.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.SeriesPublishedDaysOfWeek
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType
|
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.creator.admin.content.series.SeriesState
|
||||||
|
@ -16,6 +19,7 @@ import java.time.format.DateTimeFormatter
|
||||||
@Service
|
@Service
|
||||||
class ContentSeriesService(
|
class ContentSeriesService(
|
||||||
private val repository: ContentSeriesRepository,
|
private val repository: ContentSeriesRepository,
|
||||||
|
private val orderRepository: OrderRepository,
|
||||||
private val explorerQueryRepository: ExplorerQueryRepository,
|
private val explorerQueryRepository: ExplorerQueryRepository,
|
||||||
private val seriesContentRepository: ContentSeriesContentRepository,
|
private val seriesContentRepository: ContentSeriesContentRepository,
|
||||||
|
|
||||||
|
@ -97,7 +101,9 @@ class ContentSeriesService(
|
||||||
val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt()
|
val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt()
|
||||||
val rentalMaxPrice = (minMaxPrice.maxPrice * 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(
|
return GetSeriesDetailResponse(
|
||||||
seriesId = seriesId,
|
seriesId = seriesId,
|
||||||
title = series.title,
|
title = series.title,
|
||||||
|
@ -124,11 +130,43 @@ class ContentSeriesService(
|
||||||
minPrice = minPrice,
|
minPrice = minPrice,
|
||||||
maxPrice = maxPrice,
|
maxPrice = maxPrice,
|
||||||
keywordList = keywordList,
|
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 {
|
private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek>): String {
|
||||||
val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal }
|
val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal }
|
||||||
.map {
|
.map {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package kr.co.vividnext.sodalive.content.series
|
package kr.co.vividnext.sodalive.content.series
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentListItem
|
||||||
|
|
||||||
data class GetSeriesDetailResponse(
|
data class GetSeriesDetailResponse(
|
||||||
val seriesId: Long,
|
val seriesId: Long,
|
||||||
val title: String,
|
val title: String,
|
||||||
|
@ -14,15 +16,17 @@ data class GetSeriesDetailResponse(
|
||||||
var rentalMinPrice: Int,
|
var rentalMinPrice: Int,
|
||||||
var rentalMaxPrice: Int,
|
var rentalMaxPrice: Int,
|
||||||
val rentalPeriod: Int,
|
val rentalPeriod: Int,
|
||||||
var minPrice: Int,
|
val minPrice: Int,
|
||||||
var maxPrice: Int,
|
val maxPrice: Int,
|
||||||
var keywordList: List<String>,
|
val keywordList: List<String>,
|
||||||
var publishedDaysOfWeek: String
|
val publishedDaysOfWeek: String,
|
||||||
|
val contentList: List<GetSeriesContentListItem>,
|
||||||
|
val contentCount: Int
|
||||||
) {
|
) {
|
||||||
data class GetSeriesDetailCreator(
|
data class GetSeriesDetailCreator(
|
||||||
val creatorId: Long,
|
val creatorId: Long,
|
||||||
val nickname: String,
|
val nickname: String,
|
||||||
val profileImage: String,
|
val profileImage: String,
|
||||||
var isFollow: Boolean
|
val isFollow: Boolean
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package kr.co.vividnext.sodalive.content.series.content
|
package kr.co.vividnext.sodalive.content.series.content
|
||||||
|
|
||||||
|
import com.querydsl.core.types.dsl.Expressions
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series
|
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series
|
||||||
|
@ -12,6 +13,14 @@ interface ContentSeriesContentRepository : JpaRepository<SeriesContent, Long>, C
|
||||||
|
|
||||||
interface ContentSeriesContentQueryRepository {
|
interface ContentSeriesContentQueryRepository {
|
||||||
fun getContentCount(seriesId: Long, isAdult: Boolean): Int
|
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
|
fun isNewContent(seriesId: Long, isAdult: Boolean, fromDate: LocalDateTime, nowDate: LocalDateTime): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +45,53 @@ class ContentSeriesContentQueryRepositoryImpl(
|
||||||
.size
|
.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(
|
override fun isNewContent(
|
||||||
seriesId: Long,
|
seriesId: Long,
|
||||||
isAdult: Boolean,
|
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