시리즈 리스트 상세 API
This commit is contained in:
		| @@ -1,8 +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.admin.content.series.genre.QSeriesGenre.seriesGenre | ||||
| import kr.co.vividnext.sodalive.content.QAudioContent.audioContent | ||||
| import kr.co.vividnext.sodalive.content.hashtag.QHashTag.hashTag | ||||
| 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.SeriesPublishedDaysOfWeek | ||||
| 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 java.time.LocalDateTime | ||||
|  | ||||
| interface ContentSeriesRepository : JpaRepository<Series, Long>, ContentSeriesQueryRepository | ||||
|  | ||||
| @@ -28,7 +24,7 @@ interface ContentSeriesQueryRepository { | ||||
|         limit: Long | ||||
|     ): 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 getKeywordList(seriesId: Long): List<String> | ||||
|     fun getSeriesContentMinMaxPrice(seriesId: Long): GetSeriesContentMinMaxPriceResponse | ||||
| @@ -75,8 +71,7 @@ class ContentSeriesQueryRepositoryImpl( | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     override fun getSeriesDetail(seriesId: Long, isAuth: Boolean, imageHost: String): GetSeriesDetailResponse? { | ||||
|         val qCreator = QMember.member | ||||
|     override fun getSeriesDetail(seriesId: Long, isAuth: Boolean): Series? { | ||||
|         var where = series.id.eq(seriesId) | ||||
|             .and(series.isActive.isTrue) | ||||
|  | ||||
| @@ -84,48 +79,8 @@ class ContentSeriesQueryRepositoryImpl( | ||||
|             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 | ||||
|             .select( | ||||
|                 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) | ||||
|             .selectFrom(series) | ||||
|             .where(where) | ||||
|             .fetchFirst() | ||||
|     } | ||||
|   | ||||
| @@ -10,6 +10,8 @@ import kr.co.vividnext.sodalive.member.Member | ||||
| import org.springframework.beans.factory.annotation.Value | ||||
| import org.springframework.stereotype.Service | ||||
| import java.time.LocalDateTime | ||||
| import java.time.ZoneId | ||||
| import java.time.format.DateTimeFormatter | ||||
|  | ||||
| @Service | ||||
| class ContentSeriesService( | ||||
| @@ -76,32 +78,59 @@ class ContentSeriesService( | ||||
|     } | ||||
|  | ||||
|     fun getSeriesDetail(seriesId: Long, member: Member): GetSeriesDetailResponse { | ||||
|         val seriesDetail = repository.getSeriesDetail( | ||||
|         val series = repository.getSeriesDetail( | ||||
|             seriesId = seriesId, | ||||
|             isAuth = member.auth != null, | ||||
|             imageHost = coverImageHost | ||||
|             isAuth = member.auth != null | ||||
|         ) ?: throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요") | ||||
|  | ||||
|         seriesDetail.creator.isFollow = explorerQueryRepository.isFollow( | ||||
|             creatorId = seriesDetail.creator.creatorId, | ||||
|         val isFollow = explorerQueryRepository.isFollow( | ||||
|             creatorId = series.member!!.id!!, | ||||
|             memberId = member.id!! | ||||
|         ) | ||||
|  | ||||
|         seriesDetail.publishedDaysOfWeek = publishedDaysOfWeekText( | ||||
|         val publishedDaysOfWeek = publishedDaysOfWeekText( | ||||
|             repository.getPublishedDaysOfWeek(seriesId = seriesId) | ||||
|         ) | ||||
|  | ||||
|         seriesDetail.keywordList = repository.getKeywordList(seriesId = seriesId) | ||||
|         val keywordList = repository.getKeywordList(seriesId = seriesId) | ||||
|             .filter { it.isNotBlank() } | ||||
|  | ||||
|         val minMaxPrice = repository.getSeriesContentMinMaxPrice(seriesId = seriesId) | ||||
|         seriesDetail.minPrice = minMaxPrice.minPrice | ||||
|         seriesDetail.maxPrice = minMaxPrice.maxPrice | ||||
|         seriesDetail.rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt() | ||||
|         seriesDetail.rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt() | ||||
|         val minPrice = minMaxPrice.minPrice | ||||
|         val maxPrice = minMaxPrice.maxPrice | ||||
|         val rentalMinPrice = (minMaxPrice.minPrice * 0.7).toInt() | ||||
|         val rentalMaxPrice = (minMaxPrice.maxPrice * 0.7).toInt() | ||||
|  | ||||
|         if (!seriesDetail.validate()) throw SodaException("잘못된 시리즈 입니다.\n다시 시도해 주세요") | ||||
|         return seriesDetail | ||||
|         val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") | ||||
|         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 { | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| package kr.co.vividnext.sodalive.content.series | ||||
|  | ||||
| import com.querydsl.core.annotations.QueryProjection | ||||
|  | ||||
| data class GetSeriesDetailResponse @QueryProjection constructor( | ||||
| data class GetSeriesDetailResponse( | ||||
|     val seriesId: Long, | ||||
|     val title: String, | ||||
|     val coverImage: String, | ||||
| @@ -21,14 +19,10 @@ data class GetSeriesDetailResponse @QueryProjection constructor( | ||||
|     var keywordList: List<String>, | ||||
|     var publishedDaysOfWeek: String | ||||
| ) { | ||||
|     data class GetSeriesDetailCreator @QueryProjection constructor( | ||||
|     data class GetSeriesDetailCreator( | ||||
|         val creatorId: Long, | ||||
|         val nickname: String, | ||||
|         val coverImage: String, | ||||
|         val profileImage: String, | ||||
|         var isFollow: Boolean | ||||
|     ) | ||||
|  | ||||
|     fun validate(): Boolean { | ||||
|         return keywordList.isNotEmpty() && publishedDaysOfWeek.isBlank() | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user