From 382de101dd41035517702c2dc4506afa41deb20a Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 1 May 2024 13:35:51 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8B=9C=EA=B7=B8=EB=8B=88=EC=B2=98=20?= =?UTF-8?q?=ED=9B=84=EC=9B=90=20-=20=EC=9E=AC=EC=83=9D=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/live/room/LiveRoomController.kt | 10 +++++ .../sodalive/live/room/LiveRoomService.kt | 44 +++++++++++++++++++ .../room/donation/LiveRoomDonationResponse.kt | 5 +++ .../live/signature/SignatureCanRepository.kt | 30 +++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationResponse.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt index b034601..18c3a01 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomController.kt @@ -205,6 +205,16 @@ class LiveRoomController( ApiResponse.ok(service.donation(request, member)) } + @PostMapping("/donation/v2") + fun donationV2( + @RequestBody request: LiveRoomDonationRequest, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.donationV2(request, member)) + } + @PostMapping("/donation/refund/{id}") fun refundDonation( @PathVariable id: Long, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt index a4ac5e4..4f9edfe 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt @@ -33,6 +33,7 @@ import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationStatusResp import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationTotalResponse import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessage import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationRequest +import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse import kr.co.vividnext.sodalive.live.room.info.LiveRoomInfo import kr.co.vividnext.sodalive.live.room.info.LiveRoomInfoRedisRepository @@ -1059,6 +1060,49 @@ class LiveRoomService( ) } + @Transactional + fun donationV2(request: LiveRoomDonationRequest, member: Member): LiveRoomDonationResponse? { + val room = repository.findByIdOrNull(request.roomId) + ?: throw SodaException("해당하는 라이브가 없습니다.") + + val host = room.member ?: throw SodaException("잘못된 요청입니다.") + + if (host.role != MemberRole.CREATOR) { + throw SodaException("비비드넥스트와 계약한\n크리에이터에게만 후원을 하실 수 있습니다.") + } + + canPaymentService.spendCan( + memberId = member.id!!, + needCan = request.can, + canUsage = CanUsage.DONATION, + liveRoom = room, + container = request.container + ) + + if (request.message.isNotBlank()) { + val lock = getOrCreateLock(memberId = member.id!!) + lock.write { + val roomInfo = roomInfoRepository.findByIdOrNull(room.id!!) + ?: throw SodaException("해당하는 라이브의 정보가 없습니다.") + + roomInfo.addDonationMessage( + nickname = member.nickname, + can = request.can, + donationMessage = request.message + ) + + roomInfoRepository.save(roomInfo) + } + } + + return signatureCanRepository.findByCreatorIdAndCan( + creatorId = host.id!!, + can = request.can, + imageHost = cloudFrontHost, + isAdult = room.isAdult + ) + } + @Transactional fun refundDonation(roomId: Long, member: Member) { val donator = memberRepository.findByIdOrNull(member.id) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationResponse.kt new file mode 100644 index 0000000..1161080 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/donation/LiveRoomDonationResponse.kt @@ -0,0 +1,5 @@ +package kr.co.vividnext.sodalive.live.room.donation + +import com.querydsl.core.annotations.QueryProjection + +data class LiveRoomDonationResponse @QueryProjection constructor(val imageUrl: String, val time: Int) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCanRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCanRepository.kt index 2976998..df2bfe9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCanRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCanRepository.kt @@ -1,6 +1,8 @@ package kr.co.vividnext.sodalive.live.signature import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationResponse +import kr.co.vividnext.sodalive.live.room.donation.QLiveRoomDonationResponse import kr.co.vividnext.sodalive.live.signature.QSignatureCan.signatureCan import org.springframework.data.jpa.repository.JpaRepository @@ -8,6 +10,7 @@ interface SignatureCanRepository : JpaRepository, SignatureC interface SignatureCanQueryRepository { fun findImageByCreatorIdAndCan(creatorId: Long, can: Int, imageHost: String, isAdult: Boolean): String? + fun findByCreatorIdAndCan(creatorId: Long, can: Int, imageHost: String, isAdult: Boolean): LiveRoomDonationResponse? } class SignatureCanQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : SignatureCanQueryRepository { @@ -27,4 +30,31 @@ class SignatureCanQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) .orderBy(signatureCan.isAdult.desc()) .fetchFirst() } + + override fun findByCreatorIdAndCan( + creatorId: Long, + can: Int, + imageHost: String, + isAdult: Boolean + ): LiveRoomDonationResponse? { + var where = signatureCan.creator.id.eq(creatorId) + .and(signatureCan.can.eq(can)) + .and(signatureCan.isActive.isTrue) + + if (!isAdult) { + where = where.and(signatureCan.isAdult.isFalse()) + } + + return queryFactory + .select( + QLiveRoomDonationResponse( + signatureCan.image.prepend("/").prepend(imageHost), + signatureCan.time + ) + ) + .from(signatureCan) + .where(where) + .orderBy(signatureCan.isAdult.desc()) + .fetchFirst() + } }