차단 사용자 제외를 조회 쿼리로 통합

홈, 추천 채널, 랭킹 조회에서 차단 사용자 제외를
애플리케이션 필터링 대신 DB 쿼리로 처리한다.
콘텐츠/랭킹/추천 조회 API에 memberId 인자를 전달한다.
This commit is contained in:
2026-02-12 16:01:53 +09:00
parent 7afbf1bff8
commit 232d97e37e
7 changed files with 110 additions and 75 deletions

View File

@@ -9,6 +9,7 @@ import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike
import kr.co.vividnext.sodalive.member.MemberRole
import kr.co.vividnext.sodalive.member.QMember.member
import kr.co.vividnext.sodalive.member.auth.QAuth.auth
import kr.co.vividnext.sodalive.member.block.QBlockMember.blockMember
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Repository
@@ -19,7 +20,19 @@ class RecommendChannelQueryRepository(
@Value("\${cloud.aws.cloud-front.host}")
private val imageHost: String
) {
fun getRecommendChannelList(isAdult: Boolean, contentType: ContentType): List<RecommendChannelResponse> {
fun getRecommendChannelList(
memberId: Long?,
isAdult: Boolean,
contentType: ContentType
): List<RecommendChannelResponse> {
val blockMemberCondition = if (memberId != null) {
blockMember.member.id.eq(member.id)
.and(blockMember.isActive.isTrue)
.and(blockMember.blockedMember.id.eq(memberId))
} else {
null
}
var where = member.role.eq(MemberRole.CREATOR)
.and(audioContent.isActive.isTrue)
@@ -39,7 +52,7 @@ class RecommendChannelQueryRepository(
}
}
return queryFactory
var select = queryFactory
.select(
QRecommendChannelResponse(
member.id,
@@ -52,6 +65,13 @@ class RecommendChannelQueryRepository(
.from(member)
.innerJoin(auth).on(auth.member.id.eq(member.id))
.innerJoin(audioContent).on(audioContent.member.id.eq(member.id))
if (memberId != null) {
where = where.and(blockMember.id.isNull)
select = select.leftJoin(blockMember).on(blockMemberCondition)
}
return select
.where(where)
.groupBy(member.id)
.having(audioContent.id.count().goe(3))
@@ -60,14 +80,26 @@ class RecommendChannelQueryRepository(
.fetch()
}
fun getContentsByCreatorIdLikeDesc(creatorId: Long, isAdult: Boolean): List<RecommendChannelContentItem> {
fun getContentsByCreatorIdLikeDesc(
creatorId: Long,
memberId: Long?,
isAdult: Boolean
): List<RecommendChannelContentItem> {
val blockMemberCondition = if (memberId != null) {
blockMember.member.id.eq(audioContent.member.id)
.and(blockMember.isActive.isTrue)
.and(blockMember.blockedMember.id.eq(memberId))
} else {
null
}
var where = audioContent.member.id.eq(creatorId)
if (!isAdult) {
where = where.and(audioContent.isAdult.isFalse)
}
return queryFactory
var select = queryFactory
.select(
QRecommendChannelContentItem(
audioContent.id,
@@ -88,6 +120,13 @@ class RecommendChannelQueryRepository(
audioContentComment.audioContent.id.eq(audioContent.id)
.and(audioContentComment.isActive.isTrue)
)
if (memberId != null) {
where = where.and(blockMember.id.isNull)
select = select.leftJoin(blockMember).on(blockMemberCondition)
}
return select
.where(where)
.groupBy(audioContent.id)
.orderBy(audioContentLike.id.countDistinct().desc())

View File

@@ -18,6 +18,7 @@ class RecommendChannelQueryService(private val repository: RecommendChannelQuery
contentType: ContentType
): List<RecommendChannelResponse> {
val recommendChannelList = repository.getRecommendChannelList(
memberId = memberId,
isAdult = isAdult,
contentType = contentType
)
@@ -25,6 +26,7 @@ class RecommendChannelQueryService(private val repository: RecommendChannelQuery
return recommendChannelList.map {
it.contentList = repository.getContentsByCreatorIdLikeDesc(
creatorId = it.channelId,
memberId = memberId,
isAdult = isAdult
)