From 468add08191580b449fe2c09dce62b16101bd67d Mon Sep 17 00:00:00 2001
From: Klaus <klaus@vividnext.co.kr>
Date: Tue, 26 Sep 2023 19:15:42 +0900
Subject: [PATCH] =?UTF-8?q?=ED=81=90=EB=A0=88=EC=9D=B4=EC=85=98=20?=
 =?UTF-8?q?=EC=A0=84=EC=B2=B4=EB=B3=B4=EA=B8=B0=20-=20=EC=B4=9D=20?=
 =?UTF-8?q?=EA=B0=9C=EC=88=98,=20=EC=A0=95=EB=A0=AC=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../AudioContentCurationController.kt         |  5 +-
 .../AudioContentCurationQueryRepository.kt    | 60 ++++++++++---------
 .../curation/AudioContentCurationService.kt   | 57 +++++++++++++++---
 .../curation/GetCurationContentResponse.kt    |  8 +++
 4 files changed, 95 insertions(+), 35 deletions(-)
 create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/GetCurationContentResponse.kt

diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationController.kt
index 3906fe8..b3bae41 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationController.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationController.kt
@@ -2,12 +2,14 @@ package kr.co.vividnext.sodalive.content.main.curation
 
 import kr.co.vividnext.sodalive.common.ApiResponse
 import kr.co.vividnext.sodalive.common.SodaException
+import kr.co.vividnext.sodalive.content.SortType
 import kr.co.vividnext.sodalive.member.Member
 import org.springframework.data.domain.Pageable
 import org.springframework.security.core.annotation.AuthenticationPrincipal
 import org.springframework.web.bind.annotation.GetMapping
 import org.springframework.web.bind.annotation.PathVariable
 import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RequestParam
 import org.springframework.web.bind.annotation.RestController
 
 @RestController
@@ -16,11 +18,12 @@ class AudioContentCurationController(private val service: AudioContentCurationSe
     @GetMapping("/{id}")
     fun getCurationContent(
         @PathVariable id: Long,
+        @RequestParam("sort-type", required = false) sortType: SortType = SortType.NEWEST,
         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
         pageable: Pageable
     ) = run {
         if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
 
-        ApiResponse.ok(service.getCurationContent(id, member, pageable))
+        ApiResponse.ok(service.getCurationContent(id, sortType, member, pageable))
     }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt
index 67c8cbf..fb82df9 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationQueryRepository.kt
@@ -1,21 +1,42 @@
 package kr.co.vividnext.sodalive.content.main.curation
 
 import com.querydsl.jpa.impl.JPAQueryFactory
+import kr.co.vividnext.sodalive.content.AudioContent
 import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
-import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
-import kr.co.vividnext.sodalive.content.main.QGetAudioContentMainItem
-import kr.co.vividnext.sodalive.member.QMember.member
-import org.springframework.beans.factory.annotation.Value
+import kr.co.vividnext.sodalive.content.SortType
 import org.springframework.stereotype.Repository
 
 @Repository
-class AudioContentCurationQueryRepository(
-    private val queryFactory: JPAQueryFactory,
+class AudioContentCurationQueryRepository(private val queryFactory: JPAQueryFactory) {
+    fun findTotalCountByCurationId(curationId: Long, isAdult: Boolean = false): Int {
+        var where = audioContent.isActive.isTrue
+            .and(audioContent.curation.id.eq(curationId))
+
+        if (!isAdult) {
+            where = where.and(audioContent.isAdult.isFalse)
+        }
+
+        return queryFactory
+            .select(audioContent.id)
+            .from(audioContent)
+            .where(where)
+            .fetch()
+            .size
+    }
+
+    fun findByCurationId(
+        curationId: Long,
+        isAdult: Boolean = false,
+        sortType: SortType = SortType.NEWEST,
+        offset: Long = 0,
+        limit: Long = 10
+    ): List<AudioContent> {
+        val orderBy = when (sortType) {
+            SortType.NEWEST -> audioContent.createdAt.desc()
+            SortType.PRICE_HIGH -> audioContent.price.desc()
+            SortType.PRICE_LOW -> audioContent.price.asc()
+        }
 
-    @Value("\${cloud.aws.cloud-front.host}")
-    private val cloudFrontHost: String
-) {
-    fun findByCurationId(curationId: Long, offset: Long, limit: Long, isAdult: Boolean): List<GetAudioContentMainItem> {
         var where = audioContent.isActive.isTrue
             .and(audioContent.member.isNotNull)
             .and(audioContent.duration.isNotNull)
@@ -27,26 +48,11 @@ class AudioContentCurationQueryRepository(
         }
 
         return queryFactory
-            .select(
-                QGetAudioContentMainItem(
-                    audioContent.id,
-                    audioContent.coverImage.prepend("/").prepend(cloudFrontHost),
-                    audioContent.title,
-                    audioContent.isAdult,
-                    member.id,
-                    member.profileImage
-                        .prepend("/")
-                        .prepend(cloudFrontHost),
-                    member.nickname
-                )
-            )
-            .from(audioContent)
-            .innerJoin(audioContent.member, member)
-            .leftJoin(audioContent.curation, QAudioContentCuration.audioContentCuration)
+            .selectFrom(audioContent)
             .where(where)
             .offset(offset)
             .limit(limit)
-            .orderBy(audioContent.id.desc())
+            .orderBy(orderBy)
             .fetch()
     }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationService.kt
index 0b6dffd..a8511a9 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/AudioContentCurationService.kt
@@ -1,30 +1,73 @@
 package kr.co.vividnext.sodalive.content.main.curation
 
-import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
+import kr.co.vividnext.sodalive.content.GetAudioContentListItem
+import kr.co.vividnext.sodalive.content.SortType
+import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
+import kr.co.vividnext.sodalive.content.like.AudioContentLikeRepository
 import kr.co.vividnext.sodalive.member.Member
 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
 
 @Service
 class AudioContentCurationService(
     private val repository: AudioContentCurationQueryRepository,
-    private val blockMemberRepository: BlockMemberRepository
+    private val blockMemberRepository: BlockMemberRepository,
+    private val commentRepository: AudioContentCommentRepository,
+    private val audioContentLikeRepository: AudioContentLikeRepository,
+
+    @Value("\${cloud.aws.cloud-front.host}")
+    private val cloudFrontHost: String
 ) {
-    fun getCurationContent(curationId: Long, member: Member, pageable: Pageable): List<GetAudioContentMainItem> {
-        return repository.findByCurationId(
+    fun getCurationContent(
+        curationId: Long,
+        sortType: SortType,
+        member: Member,
+        pageable: Pageable
+    ): GetCurationContentResponse {
+        val totalCount = repository.findTotalCountByCurationId(curationId, member.auth != null)
+
+        val audioContentList = repository.findByCurationId(
             curationId = curationId,
+            isAdult = member.auth != null,
+            sortType = sortType,
             offset = pageable.offset,
-            limit = pageable.pageSize.toLong(),
-            isAdult = member.auth != null
+            limit = pageable.pageSize.toLong()
         )
+
+        val items = audioContentList
             .asSequence()
             .filter { content ->
                 !blockMemberRepository.isBlocked(
                     blockedMemberId = member.id!!,
-                    memberId = content.creatorId
+                    memberId = content.member!!.id!!
+                )
+            }
+            .map {
+                val commentCount = commentRepository
+                    .totalCountCommentByContentId(it.id!!)
+
+                val likeCount = audioContentLikeRepository
+                    .totalCountAudioContentLike(it.id!!)
+
+                GetAudioContentListItem(
+                    contentId = it.id!!,
+                    coverImageUrl = "$cloudFrontHost/${it.coverImage!!}",
+                    title = it.title,
+                    price = it.price,
+                    themeStr = it.theme!!.theme,
+                    duration = it.duration,
+                    likeCount = likeCount,
+                    commentCount = commentCount,
+                    isAdult = it.isAdult
                 )
             }
             .toList()
+
+        return GetCurationContentResponse(
+            totalCount = totalCount,
+            items = items
+        )
     }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/GetCurationContentResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/GetCurationContentResponse.kt
new file mode 100644
index 0000000..3cad629
--- /dev/null
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/curation/GetCurationContentResponse.kt
@@ -0,0 +1,8 @@
+package kr.co.vividnext.sodalive.content.main.curation
+
+import kr.co.vividnext.sodalive.content.GetAudioContentListItem
+
+data class GetCurationContentResponse(
+    val totalCount: Int,
+    val items: List<GetAudioContentListItem>
+)