From e8d16217b0e8578e6aa4e145cbe4ccf6c7b89f58 Mon Sep 17 00:00:00 2001
From: Klaus <klaus@vividnext.co.kr>
Date: Tue, 3 Sep 2024 22:19:07 +0900
Subject: [PATCH] =?UTF-8?q?=EC=B0=A8=EB=8B=A8=ED=95=9C=20=EC=9C=A0?=
 =?UTF-8?q?=EC=A0=80=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20API?=
 =?UTF-8?q?=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../sodalive/member/MemberController.kt       | 12 ++++-
 .../sodalive/member/MemberService.kt          |  8 +++-
 .../member/block/BlockMemberRepository.kt     | 44 ++++++++++++++++++-
 .../block/GetBlockedMemberListResponse.kt     | 15 +++++++
 4 files changed, 74 insertions(+), 5 deletions(-)
 create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/member/block/GetBlockedMemberListResponse.kt

diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt
index a003f6b..9c6087a 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt
@@ -6,6 +6,7 @@ import kr.co.vividnext.sodalive.member.block.MemberBlockRequest
 import kr.co.vividnext.sodalive.member.following.CreatorFollowRequest
 import kr.co.vividnext.sodalive.member.login.LoginRequest
 import kr.co.vividnext.sodalive.member.notification.UpdateNotificationSettingRequest
+import org.springframework.data.domain.Pageable
 import org.springframework.security.core.annotation.AuthenticationPrincipal
 import org.springframework.security.core.userdetails.User
 import org.springframework.web.bind.annotation.GetMapping
@@ -155,11 +156,18 @@ class MemberController(private val service: MemberService) {
 
     @GetMapping("/block")
     fun getBlockedMemberList(
-        @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.getBlockedMemberList(member.id!!))
+        ApiResponse.ok(
+            service.getBlockedMemberList(
+                member.id!!,
+                offset = pageable.offset,
+                limit = pageable.pageSize.toLong()
+            )
+        )
     }
 
     @PostMapping("/block")
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt
index 23d7b56..4d7b59a 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt
@@ -14,6 +14,7 @@ import kr.co.vividnext.sodalive.live.reservation.LiveReservationRepository
 import kr.co.vividnext.sodalive.live.room.detail.GetRoomDetailUser
 import kr.co.vividnext.sodalive.member.block.BlockMember
 import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
+import kr.co.vividnext.sodalive.member.block.GetBlockedMemberListResponse
 import kr.co.vividnext.sodalive.member.block.MemberBlockRequest
 import kr.co.vividnext.sodalive.member.following.CreatorFollowing
 import kr.co.vividnext.sodalive.member.following.CreatorFollowingRepository
@@ -357,8 +358,11 @@ class MemberService(
         }
     }
 
-    fun getBlockedMemberList(memberId: Long): List<Long> {
-        return blockMemberRepository.getBlockedMemberIdList(memberId = memberId)
+    fun getBlockedMemberList(memberId: Long, offset: Long, limit: Long): GetBlockedMemberListResponse {
+        val totalCount = blockMemberRepository.getBlockedMemberTotalCount(memberId)
+        val items = blockMemberRepository.getBlockedMemberList(offset = offset, limit = limit, memberId = memberId)
+
+        return GetBlockedMemberListResponse(totalCount = totalCount, items = items)
     }
 
     @Transactional
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/block/BlockMemberRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/block/BlockMemberRepository.kt
index b463f0d..fa3803e 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/member/block/BlockMemberRepository.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/block/BlockMemberRepository.kt
@@ -1,7 +1,9 @@
 package kr.co.vividnext.sodalive.member.block
 
 import com.querydsl.jpa.impl.JPAQueryFactory
+import kr.co.vividnext.sodalive.member.QMember.member
 import kr.co.vividnext.sodalive.member.block.QBlockMember.blockMember
+import org.springframework.beans.factory.annotation.Value
 import org.springframework.data.jpa.repository.JpaRepository
 import org.springframework.stereotype.Repository
 
@@ -12,10 +14,17 @@ interface BlockMemberQueryRepository {
     fun getBlockAccount(blockedMemberId: Long, memberId: Long): BlockMember?
     fun isBlocked(blockedMemberId: Long, memberId: Long): Boolean
     fun getBlockedMemberIdList(memberId: Long): List<Long>
+    fun getBlockedMemberList(offset: Long, limit: Long, memberId: Long): List<GetBlockedMemberListItem>
+    fun getBlockedMemberTotalCount(memberId: Long): Int
 }
 
 @Repository
-class BlockMemberQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : BlockMemberQueryRepository {
+class BlockMemberQueryRepositoryImpl(
+    private val queryFactory: JPAQueryFactory,
+
+    @Value("\${cloud.aws.cloud-front.host}")
+    private val cloudFrontHost: String
+) : BlockMemberQueryRepository {
     override fun getBlockAccount(blockedMemberId: Long, memberId: Long): BlockMember? {
         return queryFactory
             .selectFrom(blockMember)
@@ -51,4 +60,37 @@ class BlockMemberQueryRepositoryImpl(private val queryFactory: JPAQueryFactory)
             )
             .fetch()
     }
+
+    override fun getBlockedMemberList(offset: Long, limit: Long, memberId: Long): List<GetBlockedMemberListItem> {
+        return queryFactory
+            .select(
+                QGetBlockedMemberListItem(
+                    blockMember.blockedMember.id,
+                    blockMember.blockedMember.nickname,
+                    blockMember.blockedMember.profileImage.prepend("").prepend(cloudFrontHost),
+                    blockMember.blockedMember.isActive
+                )
+            )
+            .from(blockMember)
+            .innerJoin(blockMember.blockedMember, member)
+            .where(
+                blockMember.member.id.eq(memberId)
+                    .and(blockMember.isActive.isTrue)
+            )
+            .offset(offset)
+            .limit(limit)
+            .fetch()
+    }
+
+    override fun getBlockedMemberTotalCount(memberId: Long): Int {
+        return queryFactory
+            .select(blockMember.id)
+            .from(blockMember)
+            .where(
+                blockMember.member.id.eq(memberId)
+                    .and(blockMember.isActive.isTrue)
+            )
+            .fetch()
+            .size
+    }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/block/GetBlockedMemberListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/block/GetBlockedMemberListResponse.kt
new file mode 100644
index 0000000..057fd13
--- /dev/null
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/block/GetBlockedMemberListResponse.kt
@@ -0,0 +1,15 @@
+package kr.co.vividnext.sodalive.member.block
+
+import com.querydsl.core.annotations.QueryProjection
+
+data class GetBlockedMemberListResponse(
+    val totalCount: Int,
+    val items: List<GetBlockedMemberListItem>
+)
+
+data class GetBlockedMemberListItem @QueryProjection constructor(
+    val memberId: Long,
+    val nickname: String,
+    val profileImageUrl: String,
+    val isBlocked: Boolean
+)