From cf03eae4ec0baae8affee1c0fd8209e6797cb797 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 1 May 2024 12:23:09 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EA=B4=80=EB=A6=AC=EC=9E=90=20=EC=8B=9C=EA=B7=B8?= =?UTF-8?q?=EB=8B=88=EC=B2=98=20-=20=EC=9E=AC=EC=83=9D=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EB=93=B1=EB=A1=9D/=EC=88=98=EC=A0=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/signature/CreatorAdminSignatureController.kt | 7 +++++-- .../admin/signature/CreatorAdminSignatureRepository.kt | 1 + .../admin/signature/CreatorAdminSignatureService.kt | 9 +++++++-- .../creator/admin/signature/GetSignatureListResponse.kt | 1 + .../co/vividnext/sodalive/live/signature/SignatureCan.kt | 1 + 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureController.kt index df3115d..22a3ed8 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureController.kt @@ -31,6 +31,7 @@ class CreatorAdminSignatureController(private val service: CreatorAdminSignature @PostMapping fun createSignature( @RequestParam("can") can: Int, + @RequestParam("time") time: Int, @RequestParam("image") image: MultipartFile, @RequestParam("isAdult", required = false) isAdult: Boolean = false, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? @@ -38,7 +39,7 @@ class CreatorAdminSignatureController(private val service: CreatorAdminSignature if (member == null) throw SodaException("로그인 정보를 확인해주세요.") ApiResponse.ok( - service.createSignature(can = can, image = image, isAdult = isAdult, memberId = member.id!!), + service.createSignature(can = can, time = time, image = image, isAdult = isAdult, memberId = member.id!!), "등록되었습니다." ) } @@ -47,13 +48,14 @@ class CreatorAdminSignatureController(private val service: CreatorAdminSignature fun modifySignature( @RequestParam("id") id: Long, @RequestParam("can", required = false) can: Int?, + @RequestParam("time", required = false) time: Int?, @RequestParam("image", required = false) image: MultipartFile?, @RequestParam("isActive", required = false) isActive: Boolean?, @RequestParam("isAdult", required = false) isAdult: Boolean?, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? ) = run { if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - if (can == null && image == null && isActive == null && isAdult == null) { + if (can == null && time == null && image == null && isActive == null && isAdult == null) { throw SodaException("변경사항이 없습니다.") } @@ -61,6 +63,7 @@ class CreatorAdminSignatureController(private val service: CreatorAdminSignature service.modifySignature( id = id, can = can, + time = time, image = image, isActive = isActive, isAdult = isAdult, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureRepository.kt index 7fcc302..da27d01 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureRepository.kt @@ -40,6 +40,7 @@ class CreatorAdminSignatureQueryRepositoryImpl( QGetSignatureListItem( signatureCan.id, signatureCan.can, + signatureCan.time, signatureCan.image.prepend("/").prepend(imageHost), signatureCan.isAdult, member.nickname diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt index 9c1f57c..b4192aa 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt @@ -37,11 +37,11 @@ class CreatorAdminSignatureService( } @Transactional - fun createSignature(can: Int, image: MultipartFile, memberId: Long, isAdult: Boolean) { + fun createSignature(can: Int, time: Int, image: MultipartFile, memberId: Long, isAdult: Boolean) { val member = memberRepository.findCreatorByIdOrNull(memberId = memberId) ?: throw SodaException("잘못된 접근입니다.") - val signatureCan = SignatureCan(can = can, isAdult = isAdult) + val signatureCan = SignatureCan(can = can, time = time, isAdult = isAdult) signatureCan.creator = member repository.save(signatureCan) @@ -61,6 +61,7 @@ class CreatorAdminSignatureService( fun modifySignature( id: Long, can: Int?, + time: Int?, image: MultipartFile?, isActive: Boolean?, memberId: Long, @@ -73,6 +74,10 @@ class CreatorAdminSignatureService( signatureCan.can = can } + if (time != null) { + signatureCan.time = time + } + if (isActive != null) { signatureCan.isActive = isActive } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/GetSignatureListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/GetSignatureListResponse.kt index 9c8028d..c5f019f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/GetSignatureListResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/GetSignatureListResponse.kt @@ -10,6 +10,7 @@ data class GetSignatureListResponse( data class GetSignatureListItem @QueryProjection constructor( val id: Long, val can: Int, + val time: Int, val image: String, val isAdult: Boolean, val nickname: String diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCan.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCan.kt index c9ee36f..108764e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCan.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/signature/SignatureCan.kt @@ -10,6 +10,7 @@ import javax.persistence.ManyToOne @Entity data class SignatureCan( var can: Int, + var time: Int = 7, var isAdult: Boolean = false, var isActive: Boolean = true ) : BaseEntity() { From 382de101dd41035517702c2dc4506afa41deb20a Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 1 May 2024 13:35:51 +0900 Subject: [PATCH 2/4] =?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() + } } From 1a89177eccbf3bc84bd2f0c1f7d333878cf27e32 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 1 May 2024 15:16:48 +0900 Subject: [PATCH 3/4] =?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=BA=94=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/signature/CreatorAdminSignatureService.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt index b4192aa..12d0f36 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt @@ -41,6 +41,9 @@ class CreatorAdminSignatureService( val member = memberRepository.findCreatorByIdOrNull(memberId = memberId) ?: throw SodaException("잘못된 접근입니다.") + if (can <= 0) throw SodaException("1캔 이상 입력하세요") + if (time < 3 || time > 20) throw SodaException("입력가능한 시간은 3~20초 입니다.") + val signatureCan = SignatureCan(can = can, time = time, isAdult = isAdult) signatureCan.creator = member repository.save(signatureCan) @@ -70,11 +73,11 @@ class CreatorAdminSignatureService( val signatureCan = repository.findSignatureByIdOrNull(id = id, memberId = memberId) ?: throw SodaException("잘못된 요청입니다.") - if (can != null) { + if (can != null && can > 0) { signatureCan.can = can } - if (time != null) { + if (time != null && time >= 3 && time <= 20) { signatureCan.time = time } From f4d9fa69e4f585f9a7c3ebab7267afd95303e0a6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 1 May 2024 19:13:27 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EA=B4=80=EB=A6=AC=EC=9E=90=20=EC=8B=9C=EA=B7=B8?= =?UTF-8?q?=EB=8B=88=EC=B2=98=20=EC=84=A4=EC=A0=95=20-=20=EC=9E=AC?= =?UTF-8?q?=EC=83=9D=20=EC=8B=9C=EA=B0=84,=20=EC=BA=94=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/signature/CreatorAdminSignatureService.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt index 12d0f36..10ae45d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/signature/CreatorAdminSignatureService.kt @@ -41,8 +41,8 @@ class CreatorAdminSignatureService( val member = memberRepository.findCreatorByIdOrNull(memberId = memberId) ?: throw SodaException("잘못된 접근입니다.") - if (can <= 0) throw SodaException("1캔 이상 입력하세요") - if (time < 3 || time > 20) throw SodaException("입력가능한 시간은 3~20초 입니다.") + if (can <= 0) throw SodaException("1캔 이상 설정할 수 있습니다.") + if (time < 3 || time > 20) throw SodaException("시간은 3초 이상 20초 이하로 설정할 수 있습니다.") val signatureCan = SignatureCan(can = can, time = time, isAdult = isAdult) signatureCan.creator = member @@ -73,11 +73,13 @@ class CreatorAdminSignatureService( val signatureCan = repository.findSignatureByIdOrNull(id = id, memberId = memberId) ?: throw SodaException("잘못된 요청입니다.") - if (can != null && can > 0) { + if (can != null) { + if (can <= 0) throw SodaException("1캔 이상 설정할 수 있습니다.") signatureCan.can = can } - if (time != null && time >= 3 && time <= 20) { + if (time != null) { + if (time < 3 || time > 20) throw SodaException("시간은 3초 이상 20초 이하로 설정할 수 있습니다.") signatureCan.time = time }