후원 랭킹 조회 캐시 적용
This commit is contained in:
@@ -113,30 +113,6 @@ class ExplorerQueryRepository(
|
|||||||
.fetchOne()
|
.fetchOne()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMemberDonationRankingTotal(creatorId: Long): Int {
|
|
||||||
val userMember = QMember("user")
|
|
||||||
|
|
||||||
val donation = useCan.rewardCan.add(useCan.can).sum()
|
|
||||||
return queryFactory
|
|
||||||
.select(userMember.id)
|
|
||||||
.from(useCanCalculate)
|
|
||||||
.innerJoin(useCanCalculate.useCan, useCan)
|
|
||||||
.innerJoin(useCan.member, userMember)
|
|
||||||
.where(
|
|
||||||
useCan.isRefund.isFalse
|
|
||||||
.and(useCanCalculate.recipientCreatorId.eq(creatorId))
|
|
||||||
.and(
|
|
||||||
useCan.canUsage.eq(CanUsage.DONATION)
|
|
||||||
.or(useCan.canUsage.eq(CanUsage.SPIN_ROULETTE))
|
|
||||||
.or(useCan.canUsage.eq(CanUsage.LIVE))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.groupBy(useCan.member.id)
|
|
||||||
.orderBy(donation.desc())
|
|
||||||
.fetch()
|
|
||||||
.size
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMemberDonationRanking(
|
fun getMemberDonationRanking(
|
||||||
creatorId: Long,
|
creatorId: Long,
|
||||||
limit: Long,
|
limit: Long,
|
||||||
|
|||||||
@@ -403,6 +403,14 @@ class ExplorerService(
|
|||||||
val firstDayOfLastWeek = currentDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusDays(7)
|
val firstDayOfLastWeek = currentDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusDays(7)
|
||||||
val firstDayOfMonth = currentDate.with(TemporalAdjusters.firstDayOfMonth())
|
val firstDayOfMonth = currentDate.with(TemporalAdjusters.firstDayOfMonth())
|
||||||
|
|
||||||
|
val donationMemberTotal = donationRankingService.getMemberDonationRankingTotal(creatorId)
|
||||||
|
val donationRanking = donationRankingService.getMemberDonationRanking(
|
||||||
|
creatorId = creatorId,
|
||||||
|
offset = pageable.offset,
|
||||||
|
limit = pageable.pageSize.toLong(),
|
||||||
|
withDonationCan = creatorId == member.id!!
|
||||||
|
)
|
||||||
|
|
||||||
return GetDonationAllResponse(
|
return GetDonationAllResponse(
|
||||||
accumulatedCansToday = if (creatorId == member.id!!) {
|
accumulatedCansToday = if (creatorId == member.id!!) {
|
||||||
queryRepository.getDonationCoinsDateRange(
|
queryRepository.getDonationCoinsDateRange(
|
||||||
@@ -436,13 +444,8 @@ class ExplorerService(
|
|||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
totalCount = queryRepository.getMemberDonationRankingTotal(creatorId),
|
totalCount = donationMemberTotal,
|
||||||
userDonationRanking = queryRepository.getMemberDonationRanking(
|
userDonationRanking = donationRanking
|
||||||
creatorId,
|
|
||||||
offset = pageable.offset,
|
|
||||||
limit = pageable.pageSize.toLong(),
|
|
||||||
withDonationCan = creatorId == member.id!!
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.springframework.stereotype.Repository
|
|||||||
class CreatorDonationRankingQueryRepository(private val queryFactory: JPAQueryFactory) {
|
class CreatorDonationRankingQueryRepository(private val queryFactory: JPAQueryFactory) {
|
||||||
fun getMemberDonationRanking(
|
fun getMemberDonationRanking(
|
||||||
creatorId: Long,
|
creatorId: Long,
|
||||||
|
offset: Long,
|
||||||
limit: Long
|
limit: Long
|
||||||
): List<DonationRankingProjection> {
|
): List<DonationRankingProjection> {
|
||||||
val donationCan = useCan.rewardCan.add(useCan.can).sum()
|
val donationCan = useCan.rewardCan.add(useCan.can).sum()
|
||||||
@@ -38,12 +39,33 @@ class CreatorDonationRankingQueryRepository(private val queryFactory: JPAQueryFa
|
|||||||
.or(useCan.canUsage.eq(CanUsage.LIVE))
|
.or(useCan.canUsage.eq(CanUsage.LIVE))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.offset(0)
|
.offset(offset)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.groupBy(member.id)
|
.groupBy(member.id)
|
||||||
.orderBy(donationCan.desc(), member.id.desc())
|
.orderBy(donationCan.desc(), member.id.desc())
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMemberDonationRankingTotal(creatorId: Long): Int {
|
||||||
|
return queryFactory
|
||||||
|
.select(member.id)
|
||||||
|
.from(useCanCalculate)
|
||||||
|
.innerJoin(useCanCalculate.useCan, useCan)
|
||||||
|
.innerJoin(useCan.member, member)
|
||||||
|
.where(
|
||||||
|
useCan.member.isActive.isTrue
|
||||||
|
.and(useCan.isRefund.isFalse)
|
||||||
|
.and(useCanCalculate.recipientCreatorId.eq(creatorId))
|
||||||
|
.and(
|
||||||
|
useCan.canUsage.eq(CanUsage.DONATION)
|
||||||
|
.or(useCan.canUsage.eq(CanUsage.SPIN_ROULETTE))
|
||||||
|
.or(useCan.canUsage.eq(CanUsage.LIVE))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.groupBy(member.id)
|
||||||
|
.fetch()
|
||||||
|
.size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class DonationRankingProjection @QueryProjection constructor(
|
data class DonationRankingProjection @QueryProjection constructor(
|
||||||
|
|||||||
@@ -20,18 +20,41 @@ class CreatorDonationRankingService(
|
|||||||
@Value("\${cloud.aws.cloud-front.host}")
|
@Value("\${cloud.aws.cloud-front.host}")
|
||||||
private val imageHost: String
|
private val imageHost: String
|
||||||
) {
|
) {
|
||||||
|
fun getMemberDonationRankingTotal(creatorId: Long): Int {
|
||||||
|
val cacheKey = "creator_donation_ranking_member_total_v2:$creatorId"
|
||||||
|
val cachedTotal = redisTemplate.opsForValue().get(cacheKey) as? Int
|
||||||
|
if (cachedTotal != null) {
|
||||||
|
return cachedTotal
|
||||||
|
}
|
||||||
|
|
||||||
|
val total = repository.getMemberDonationRankingTotal(creatorId)
|
||||||
|
|
||||||
|
val now = LocalDateTime.now()
|
||||||
|
val nextMonday = now.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).with(LocalTime.MIN)
|
||||||
|
val secondsUntilNextMonday = ChronoUnit.SECONDS.between(now, nextMonday)
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(
|
||||||
|
cacheKey,
|
||||||
|
total,
|
||||||
|
Duration.ofSeconds(secondsUntilNextMonday)
|
||||||
|
)
|
||||||
|
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
fun getMemberDonationRanking(
|
fun getMemberDonationRanking(
|
||||||
creatorId: Long,
|
creatorId: Long,
|
||||||
limit: Long,
|
offset: Long = 0,
|
||||||
|
limit: Long = 10,
|
||||||
withDonationCan: Boolean
|
withDonationCan: Boolean
|
||||||
): List<MemberDonationRankingResponse> {
|
): List<MemberDonationRankingResponse> {
|
||||||
val cacheKey = "creator_donation_ranking_v2:$creatorId:$limit:$withDonationCan"
|
val cacheKey = "creator_donation_ranking_v2:$creatorId:$offset:$limit:$withDonationCan"
|
||||||
val cachedData = redisTemplate.opsForValue().get(cacheKey) as? MemberDonationRankingListResponse
|
val cachedData = redisTemplate.opsForValue().get(cacheKey) as? MemberDonationRankingListResponse
|
||||||
if (cachedData != null) {
|
if (cachedData != null) {
|
||||||
return cachedData.rankings
|
return cachedData.rankings
|
||||||
}
|
}
|
||||||
|
|
||||||
val memberDonationRanking = repository.getMemberDonationRanking(creatorId, limit)
|
val memberDonationRanking = repository.getMemberDonationRanking(creatorId, offset, limit)
|
||||||
|
|
||||||
val result = memberDonationRanking.map {
|
val result = memberDonationRanking.map {
|
||||||
MemberDonationRankingResponse(
|
MemberDonationRankingResponse(
|
||||||
|
|||||||
@@ -888,9 +888,7 @@ class LiveRoomService(
|
|||||||
3,
|
3,
|
||||||
withDonationCan = false
|
withDonationCan = false
|
||||||
)
|
)
|
||||||
.asSequence()
|
|
||||||
.map { it.userId }
|
.map { it.userId }
|
||||||
.toList()
|
|
||||||
} else {
|
} else {
|
||||||
listOf()
|
listOf()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user