시리즈 리스트 상세 API
This commit is contained in:
parent
bb8dda6da0
commit
3ec0cf4fac
|
@ -1,8 +1,6 @@
|
||||||
package kr.co.vividnext.sodalive.content.series
|
package kr.co.vividnext.sodalive.content.series
|
||||||
|
|
||||||
import com.querydsl.core.types.dsl.Expressions
|
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
import kr.co.vividnext.sodalive.admin.content.series.genre.QSeriesGenre.seriesGenre
|
|
||||||
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
||||||
import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag
|
import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag
|
||||||
import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentMinMaxPriceResponse
|
import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentMinMaxPriceResponse
|
||||||
|
@ -12,9 +10,7 @@ import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seri
|
||||||
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.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 kr.co.vividnext.sodalive.member.QMember
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
import java.time.LocalDateTime
|
|
||||||
|
|
||||||
interface ContentSeriesRepository : JpaRepository<Series, Long>, ContentSeriesQueryRepository
|
interface ContentSeriesRepository : JpaRepository<Series, Long>, ContentSeriesQueryRepository
|
||||||
|
|
||||||
|
@ -28,7 +24,7 @@ interface ContentSeriesQueryRepository {
|
||||||
limit: Long
|
limit: Long
|
||||||
): List<Series>
|
): List<Series>
|
||||||
|
|
||||||
fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse?
|
fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series?
|
||||||
fun getPublishedDaysOfWeek(seriesId: Long): Set<SeriesPublishedDaysOfWeek>
|
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
|
||||||
|
@ -75,8 +71,7 @@ class ContentSeriesQueryRepositoryImpl(
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse? {
|
override fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series? {
|
||||||
val qCreator = QMember.member
|
|
||||||
var where = series.id.eq(seriesId)
|
var where = series.id.eq(seriesId)
|
||||||
.and(series.isActive.isTrue)
|
.and(series.isActive.isTrue)
|
||||||
|
|
||||||
|
@ -84,48 +79,8 @@ class ContentSeriesQueryRepositoryImpl(
|
||||||
where = where.and(series.isAdult.isFalse)
|
where = where.and(series.isAdult.isFalse)
|
||||||
}
|
}
|
||||||
|
|
||||||
val formattedDate = Expressions.stringTemplate(
|
|
||||||
"DATE_FORMAT({0}, {1})",
|
|
||||||
Expressions.dateTimeTemplate(
|
|
||||||
LocalDateTime::class.java,
|
|
||||||
"CONVERT_TZ({0},{1},{2})",
|
|
||||||
series.createdAt,
|
|
||||||
"UTC",
|
|
||||||
"Asia/Seoul"
|
|
||||||
),
|
|
||||||
"%Y-%m-%d"
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.selectFrom(series)
|
||||||
QGetSeriesDetailResponse(
|
|
||||||
series.id,
|
|
||||||
series.title,
|
|
||||||
series.coverImage.prepend("/").prepend(imageHost),
|
|
||||||
series.introduction,
|
|
||||||
seriesGenre.genre,
|
|
||||||
series.isAdult,
|
|
||||||
series.writer,
|
|
||||||
series.studio,
|
|
||||||
formattedDate,
|
|
||||||
QGetSeriesDetailResponse_GetSeriesDetailCreator(
|
|
||||||
qCreator.id,
|
|
||||||
qCreator.nickname,
|
|
||||||
qCreator.profileImage.prepend("/").prepend(imageHost),
|
|
||||||
Expressions.constant(false)
|
|
||||||
),
|
|
||||||
Expressions.constant(0),
|
|
||||||
Expressions.constant(0),
|
|
||||||
Expressions.constant(15),
|
|
||||||
Expressions.constant(0),
|
|
||||||
Expressions.constant(0),
|
|
||||||
Expressions.constant<List<String>>(emptyList()),
|
|
||||||
Expressions.constant("")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.from(series)
|
|
||||||
.innerJoin(series.member, qCreator)
|
|
||||||
.innerJoin(series.genre, seriesGenre)
|
|
||||||
.where(where)
|
.where(where)
|
||||||
.fetchFirst()
|
.fetchFirst()
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import kr.co.vividnext.sodalive.member.Member
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class ContentSeriesService(
|
class ContentSeriesService(
|
||||||
|
@ -76,32 +78,59 @@ class ContentSeriesService(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSeriesDetail(seriesId: Long, member: Member): GetSeriesDetailResponse {
|
fun getSeriesDetail(seriesId: Long, member: Member): GetSeriesDetailResponse {
|
||||||
val seriesDetail = repository.getSeriesDetail(
|
val series = repository.getSeriesDetail(
|
||||||
seriesId = seriesId,
|
seriesId = seriesId,
|
||||||
isAuth = member.auth != null,
|
isAuth = member.auth != null
|
||||||
imageHost = coverImageHost
|
|
||||||
) ?: throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요")
|
) ?: throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요")
|
||||||
|
|
||||||
seriesDetail.creator.isFollow = explorerQueryRepository.isFollow(
|
val isFollow = explorerQueryRepository.isFollow(
|
||||||
creatorId = seriesDetail.creator.creatorId,
|
creatorId = series.member!!.id!!,
|
||||||
memberId = member.id!!
|
memberId = member.id!!
|
||||||
)
|
)
|
||||||
|
|
||||||
seriesDetail.publishedDaysOfWeek = publishedDaysOfWeekText(
|
val publishedDaysOfWeek = publishedDaysOfWeekText(
|
||||||
repository.getPublishedDaysOfWeek(seriesId = seriesId)
|
repository.getPublishedDaysOfWeek(seriesId = seriesId)
|
||||||
)
|
)
|
||||||
|
|
||||||
seriesDetail.keywordList = repository.getKeywordList(seriesId = seriesId)
|
val keywordList = repository.getKeywordList(seriesId = seriesId)
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
|
|
||||||
val minMaxPrice = repository.getSeriesContentMinMaxPrice(seriesId = seriesId)
|
val minMaxPrice = repository.getSeriesContentMinMaxPrice(seriesId = seriesId)
|
||||||
seriesDetail.minPrice = minMaxPrice.minPrice
|
val minPrice = minMaxPrice.minPrice
|
||||||
seriesDetail.maxPrice = minMaxPrice.maxPrice
|
val maxPrice = minMaxPrice.maxPrice
|
||||||
seriesDetail.rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt()
|
val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt()
|
||||||
seriesDetail.rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt()
|
val rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt()
|
||||||
|
|
||||||
if (!seriesDetail.validate()) throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요")
|
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||||
return seriesDetail
|
return GetSeriesDetailResponse(
|
||||||
|
seriesId = seriesId,
|
||||||
|
title = series.title,
|
||||||
|
coverImage = "$coverImageHost/${series.coverImage}",
|
||||||
|
introduction = series.introduction,
|
||||||
|
genre = series.genre!!.genre,
|
||||||
|
isAdult = series.isAdult,
|
||||||
|
writer = series.writer,
|
||||||
|
studio = series.studio,
|
||||||
|
publishedDate = series.createdAt!!
|
||||||
|
.atZone(ZoneId.of("UTC"))
|
||||||
|
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
|
||||||
|
.toLocalDateTime()
|
||||||
|
.format(dateTimeFormatter),
|
||||||
|
creator = GetSeriesDetailResponse.GetSeriesDetailCreator(
|
||||||
|
creatorId = series.member!!.id!!,
|
||||||
|
nickname = series.member!!.nickname,
|
||||||
|
profileImage = "$coverImageHost/${series.member!!.profileImage}",
|
||||||
|
isFollow = isFollow
|
||||||
|
),
|
||||||
|
rentalMinPrice = rentalMinPrice,
|
||||||
|
rentalMaxPrice = rentalMaxPrice,
|
||||||
|
rentalPeriod = 15,
|
||||||
|
minPrice = minPrice,
|
||||||
|
maxPrice = maxPrice,
|
||||||
|
keywordList = keywordList,
|
||||||
|
publishedDaysOfWeek = publishedDaysOfWeek
|
||||||
|
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek>): String {
|
private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek>): String {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package kr.co.vividnext.sodalive.content.series
|
package kr.co.vividnext.sodalive.content.series
|
||||||
|
|
||||||
import com.querydsl.core.annotations.QueryProjection
|
data class GetSeriesDetailResponse(
|
||||||
|
|
||||||
data class GetSeriesDetailResponse @QueryProjection constructor(
|
|
||||||
val seriesId: Long,
|
val seriesId: Long,
|
||||||
val title: String,
|
val title: String,
|
||||||
val coverImage: String,
|
val coverImage: String,
|
||||||
|
@ -21,14 +19,10 @@ data class GetSeriesDetailResponse @QueryProjection constructor(
|
||||||
var keywordList: List<String>,
|
var keywordList: List<String>,
|
||||||
var publishedDaysOfWeek: String
|
var publishedDaysOfWeek: String
|
||||||
) {
|
) {
|
||||||
data class GetSeriesDetailCreator @QueryProjection constructor(
|
data class GetSeriesDetailCreator(
|
||||||
val creatorId: Long,
|
val creatorId: Long,
|
||||||
val nickname: String,
|
val nickname: String,
|
||||||
val coverImage: String,
|
val profileImage: String,
|
||||||
var isFollow: Boolean
|
var isFollow: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
fun validate(): Boolean {
|
|
||||||
return keywordList.isNotEmpty() && publishedDaysOfWeek.isBlank()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue