feat(creator-channel): 후원 탭 repository를 추가한다

This commit is contained in:
2026-06-22 19:17:56 +09:00
parent 046ce700c7
commit 951f6789f0
3 changed files with 351 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
package kr.co.vividnext.sodalive.v2.creator.channel.donation.adapter.out.persistence
import kr.co.vividnext.sodalive.v2.creator.channel.donation.port.out.CreatorChannelDonationQueryPort
interface CreatorChannelDonationQueryRepository : CreatorChannelDonationQueryPort

View File

@@ -0,0 +1,119 @@
package kr.co.vividnext.sodalive.v2.creator.channel.donation.adapter.out.persistence
import com.querydsl.core.types.Projections
import com.querydsl.core.types.dsl.BooleanExpression
import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.explorer.profile.channelDonation.QChannelDonationMessage.channelDonationMessage
import kr.co.vividnext.sodalive.member.QMember.member
import kr.co.vividnext.sodalive.member.block.QBlockMember
import kr.co.vividnext.sodalive.v2.creator.channel.donation.domain.CreatorChannelDonationQueryPolicy
import kr.co.vividnext.sodalive.v2.creator.channel.donation.port.out.CreatorChannelDonationCreatorRecord
import kr.co.vividnext.sodalive.v2.creator.channel.donation.port.out.CreatorChannelDonationRecord
import org.springframework.stereotype.Repository
import java.time.LocalDateTime
@Repository
class DefaultCreatorChannelDonationQueryRepository(
private val queryFactory: JPAQueryFactory
) : CreatorChannelDonationQueryRepository {
private val queryPolicy = CreatorChannelDonationQueryPolicy()
override fun findCreator(creatorId: Long, viewerId: Long?): CreatorChannelDonationCreatorRecord? {
val creator = queryFactory
.select(
member.id,
member.role,
member.nickname,
member.isVisibleDonationRank,
member.donationRankingPeriod
)
.from(member)
.where(
member.id.eq(creatorId),
member.isActive.isTrue
)
.fetchFirst() ?: return null
return CreatorChannelDonationCreatorRecord(
creatorId = creator.get(member.id)!!,
role = creator.get(member.role)!!,
nickname = creator.get(member.nickname)!!,
isVisibleDonationRank = creator.get(member.isVisibleDonationRank)!!,
donationRankingPeriod = creator.get(member.donationRankingPeriod)
)
}
override fun existsBlockedBetween(viewerId: Long, creatorId: Long): Boolean {
val blockMember = QBlockMember("creatorChannelDonationBlockMember")
return queryFactory
.select(blockMember.id)
.from(blockMember)
.where(
blockMember.isActive.isTrue,
blockMember.member.id.eq(viewerId).and(blockMember.blockedMember.id.eq(creatorId))
.or(blockMember.member.id.eq(creatorId).and(blockMember.blockedMember.id.eq(viewerId)))
)
.fetchFirst() != null
}
override fun countChannelDonations(
creatorId: Long,
viewerId: Long,
now: LocalDateTime
): Int {
return queryFactory
.select(channelDonationMessage.id.count())
.from(channelDonationMessage)
.where(channelDonationCondition(creatorId, viewerId, now))
.fetchOne()
?.toInt()
?: 0
}
override fun findChannelDonations(
creatorId: Long,
viewerId: Long,
now: LocalDateTime,
offset: Long,
limit: Int
): List<CreatorChannelDonationRecord> {
return queryFactory
.select(
Projections.constructor(
CreatorChannelDonationRecord::class.java,
channelDonationMessage.member.nickname,
channelDonationMessage.member.profileImage,
channelDonationMessage.can,
channelDonationMessage.additionalMessage,
channelDonationMessage.createdAt
)
)
.from(channelDonationMessage)
.where(channelDonationCondition(creatorId, viewerId, now))
.orderBy(channelDonationMessage.createdAt.desc(), channelDonationMessage.id.desc())
.offset(offset)
.limit(limit.toLong())
.fetch()
}
private fun channelDonationCondition(
creatorId: Long,
viewerId: Long,
now: LocalDateTime
): BooleanExpression {
val monthRange = queryPolicy.currentKstMonthRange(now)
return channelDonationMessage.creator.id.eq(creatorId)
.and(channelDonationMessage.createdAt.goe(monthRange.startInclusiveUtc))
.and(channelDonationMessage.createdAt.lt(monthRange.endExclusiveUtc))
.and(donationVisibilityCondition(creatorId, viewerId))
}
private fun donationVisibilityCondition(creatorId: Long, viewerId: Long): BooleanExpression {
return if (creatorId == viewerId) {
channelDonationMessage.id.isNotNull
} else {
channelDonationMessage.isSecret.isFalse
.or(channelDonationMessage.member.id.eq(viewerId))
}
}
}