From e507af8d5b49f29c80b962c00514e77e8f87387c Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 15 Oct 2023 00:51:16 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20-=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=9E=AD?= =?UTF-8?q?=ED=82=B9=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/AudioContentRepository.kt | 54 +++++++++++++++++++ .../content/main/AudioContentMainService.kt | 34 +++++++++++- .../main/GetAudioContentMainResponse.kt | 3 +- .../content/main/GetAudioContentRanking.kt | 20 +++++++ 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentRanking.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt index 6ed2e41..706f197 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -2,15 +2,19 @@ package kr.co.vividnext.sodalive.content import com.querydsl.core.types.dsl.Expressions import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.can.use.QUseCan.useCan import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.QBundleAudioContent.bundleAudioContent import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem +import kr.co.vividnext.sodalive.content.main.GetAudioContentRankingItem import kr.co.vividnext.sodalive.content.main.GetNewContentUploadCreator import kr.co.vividnext.sodalive.content.main.QGetAudioContentMainItem +import kr.co.vividnext.sodalive.content.main.QGetAudioContentRankingItem import kr.co.vividnext.sodalive.content.main.banner.AudioContentBanner import kr.co.vividnext.sodalive.content.main.banner.QAudioContentBanner.audioContentBanner import kr.co.vividnext.sodalive.content.main.curation.AudioContentCuration import kr.co.vividnext.sodalive.content.main.curation.QAudioContentCuration.audioContentCuration +import kr.co.vividnext.sodalive.content.order.QOrder.order import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme import kr.co.vividnext.sodalive.event.QEvent.event import kr.co.vividnext.sodalive.member.QMember.member @@ -78,6 +82,14 @@ interface AudioContentQueryRepository { cloudfrontHost: String, isAdult: Boolean ): List + + fun getAudioContentRanking( + cloudfrontHost: String, + isAdult: Boolean, + startDate: LocalDateTime, + endDate: LocalDateTime, + limit: Long = 12 + ): List } @Repository @@ -424,4 +436,46 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) .orderBy(audioContent.id.desc()) .fetch() } + + override fun getAudioContentRanking( + cloudfrontHost: String, + isAdult: Boolean, + startDate: LocalDateTime, + endDate: LocalDateTime, + limit: Long + ): List { + var where = audioContent.isActive.isTrue + .and(audioContent.member.isNotNull) + .and(audioContent.duration.isNotNull) + .and(audioContent.member.isActive.isTrue) + .and(useCan.createdAt.goe(startDate)) + .and(useCan.createdAt.lt(endDate)) + + if (!isAdult) { + where = where.and(audioContent.isAdult.isFalse) + } + + return queryFactory + .select( + QGetAudioContentRankingItem( + audioContent.id, + audioContent.title, + audioContent.coverImage.prepend("/").prepend(cloudfrontHost), + audioContentTheme.theme, + audioContent.price, + audioContent.duration, + member.id, + member.nickname + ) + ) + .from(useCan) + .innerJoin(useCan.order, order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .innerJoin(audioContent.theme, audioContentTheme) + .where(where) + .orderBy(order.can.sum().desc()) + .limit(limit) + .fetch() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt index 6e3a544..72b5dfa 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt @@ -12,6 +12,10 @@ import kr.co.vividnext.sodalive.member.block.BlockMemberRepository import org.springframework.beans.factory.annotation.Value import org.springframework.data.domain.Pageable import org.springframework.stereotype.Service +import java.time.DayOfWeek +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import java.time.temporal.TemporalAdjusters @Service class AudioContentMainService( @@ -126,13 +130,41 @@ class AudioContentMainService( .filter { it.contents.isNotEmpty() } .toList() + val currentDateTime = LocalDateTime.now() + val startDate = currentDateTime + .withHour(15) + .withMinute(0) + .withSecond(0) + .minusWeeks(1) + .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)) + val endDate = startDate + .plusDays(7) + + val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일") + val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일") + + val contentRankingItemList = repository + .getAudioContentRanking( + cloudfrontHost = imageHost, + startDate = startDate, + endDate = endDate, + isAdult = isAdult + ) + + val contentRanking = GetAudioContentRanking( + startDate = startDate.format(startDateFormatter), + endDate = endDate.format(endDateFormatter), + contentRankingItemList + ) + return GetAudioContentMainResponse( newContentUploadCreatorList = newContentUploadCreatorList, bannerList = bannerList, orderList = orderList, themeList = themeList, newContentList = newContentList, - curationList = curationList + curationList = curationList, + contentRanking = contentRanking ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentMainResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentMainResponse.kt index 60b708a..9734f21 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentMainResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentMainResponse.kt @@ -9,5 +9,6 @@ data class GetAudioContentMainResponse( val orderList: List, val themeList: List, val newContentList: List, - val curationList: List + val curationList: List, + val contentRanking: GetAudioContentRanking ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentRanking.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentRanking.kt new file mode 100644 index 0000000..1d9dbdf --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/GetAudioContentRanking.kt @@ -0,0 +1,20 @@ +package kr.co.vividnext.sodalive.content.main + +import com.querydsl.core.annotations.QueryProjection + +data class GetAudioContentRanking( + val startDate: String, + val endDate: String, + val items: List +) + +data class GetAudioContentRankingItem @QueryProjection constructor( + val contentId: Long, + val title: String, + val coverImageUrl: String, + val themeStr: String, + val price: Int, + val duration: String, + val creatorId: Long, + val creatorNickname: String +) -- 2.40.1 From f889ae52320aa25fd44005c4165a6d76f6ab4a57 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 15 Oct 2023 01:03:20 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=9E=AD=ED=82=B9=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20-=20group=20by=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/vividnext/sodalive/content/AudioContentRepository.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt index 706f197..5bbb47b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -474,6 +474,7 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) .innerJoin(audioContent.member, member) .innerJoin(audioContent.theme, audioContentTheme) .where(where) + .groupBy(audioContent.id) .orderBy(order.can.sum().desc()) .limit(limit) .fetch() -- 2.40.1 From 333458a18418e3f82971f0b218b3ed7fd70f1f5e Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 15 Oct 2023 01:20:54 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=9E=AD=ED=82=B9=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20-=20endDate=20=ED=91=9C=EC=8B=9C?= =?UTF-8?q?=EB=82=A0=EC=A7=9C=20=ED=95=98=EB=A3=A8=20=EC=A0=84=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vividnext/sodalive/content/main/AudioContentMainService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt index 72b5dfa..d54007c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt @@ -153,7 +153,7 @@ class AudioContentMainService( val contentRanking = GetAudioContentRanking( startDate = startDate.format(startDateFormatter), - endDate = endDate.format(endDateFormatter), + endDate = endDate.minusDays(1).format(endDateFormatter), contentRankingItemList ) -- 2.40.1 From 9146e2e231efb510b84509993ed6ca7e8cf999c4 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 15 Oct 2023 03:23:03 +0900 Subject: [PATCH 4/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=9E=AD?= =?UTF-8?q?=ED=82=B9=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=84=EC=B2=B4?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/AudioContentController.kt | 9 +++++ .../sodalive/content/AudioContentService.kt | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt index 5a9deda..c83d903 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt @@ -148,4 +148,13 @@ class AudioContentController(private val service: AudioContentService) { ApiResponse.ok(service.audioContentLike(request, member)) } + + @GetMapping("/ranking") + fun getAudioContentRanking( + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.getAudioContentRanking(member = member)) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index fbeb3ee..cf05527 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -13,6 +13,7 @@ import kr.co.vividnext.sodalive.content.like.AudioContentLike import kr.co.vividnext.sodalive.content.like.AudioContentLikeRepository import kr.co.vividnext.sodalive.content.like.PutAudioContentLikeRequest import kr.co.vividnext.sodalive.content.like.PutAudioContentLikeResponse +import kr.co.vividnext.sodalive.content.main.GetAudioContentRanking import kr.co.vividnext.sodalive.content.order.OrderRepository import kr.co.vividnext.sodalive.content.order.OrderType import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository @@ -29,9 +30,11 @@ import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import org.springframework.web.multipart.MultipartFile import java.text.SimpleDateFormat +import java.time.DayOfWeek import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter +import java.time.temporal.TemporalAdjusters import java.util.Locale @Service @@ -573,4 +576,34 @@ class AudioContentService( ) } } + + fun getAudioContentRanking(member: Member): GetAudioContentRanking { + val currentDateTime = LocalDateTime.now() + val startDate = currentDateTime + .withHour(15) + .withMinute(0) + .withSecond(0) + .minusWeeks(1) + .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)) + val endDate = startDate + .plusDays(7) + + val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일") + val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일") + + val contentRankingItemList = repository + .getAudioContentRanking( + cloudfrontHost = coverImageHost, + startDate = startDate, + endDate = endDate, + isAdult = member.auth != null, + limit = 50 + ) + + return GetAudioContentRanking( + startDate = startDate.format(startDateFormatter), + endDate = endDate.minusDays(1).format(endDateFormatter), + items = contentRankingItemList + ) + } } -- 2.40.1 From 149a3ad2f1208818ef0121bec2d2263eef62f260 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 15 Oct 2023 03:38:26 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=9E=AD?= =?UTF-8?q?=ED=82=B9=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=84=EC=B2=B4?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20API=20-=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/AudioContentController.kt | 11 +++++++++-- .../sodalive/content/AudioContentRepository.kt | 2 ++ .../vividnext/sodalive/content/AudioContentService.kt | 9 +++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt index c83d903..286f232 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt @@ -151,10 +151,17 @@ class AudioContentController(private val service: AudioContentService) { @GetMapping("/ranking") fun getAudioContentRanking( - @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, + pageable: Pageable ) = run { if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - ApiResponse.ok(service.getAudioContentRanking(member = member)) + ApiResponse.ok( + service.getAudioContentRanking( + member = member, + offset = pageable.offset, + limit = pageable.pageSize.toLong() + ) + ) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt index 5bbb47b..3bf9362 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentRepository.kt @@ -88,6 +88,7 @@ interface AudioContentQueryRepository { isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime, + offset: Long = 0, limit: Long = 12 ): List } @@ -442,6 +443,7 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime, + offset: Long, limit: Long ): List { var where = audioContent.isActive.isTrue diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index cf05527..40c2adb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -577,7 +577,11 @@ class AudioContentService( } } - fun getAudioContentRanking(member: Member): GetAudioContentRanking { + fun getAudioContentRanking( + member: Member, + offset: Long, + limit: Long + ): GetAudioContentRanking { val currentDateTime = LocalDateTime.now() val startDate = currentDateTime .withHour(15) @@ -597,7 +601,8 @@ class AudioContentService( startDate = startDate, endDate = endDate, isAdult = member.auth != null, - limit = 50 + offset = offset, + limit = limit ) return GetAudioContentRanking( -- 2.40.1