시그니처 후원 시간 추가 #171
| @@ -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, | ||||
|   | ||||
| @@ -40,6 +40,7 @@ class CreatorAdminSignatureQueryRepositoryImpl( | ||||
|             QGetSignatureListItem( | ||||
|                 signatureCan.id, | ||||
|                 signatureCan.can, | ||||
|                 signatureCan.time, | ||||
|                 signatureCan.image.prepend("/").prepend(imageHost), | ||||
|                 signatureCan.isAdult, | ||||
|                 member.nickname | ||||
|   | ||||
| @@ -37,11 +37,14 @@ 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) | ||||
|         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) | ||||
|  | ||||
| @@ -61,6 +64,7 @@ class CreatorAdminSignatureService( | ||||
|     fun modifySignature( | ||||
|         id: Long, | ||||
|         can: Int?, | ||||
|         time: Int?, | ||||
|         image: MultipartFile?, | ||||
|         isActive: Boolean?, | ||||
|         memberId: Long, | ||||
| @@ -70,9 +74,15 @@ class CreatorAdminSignatureService( | ||||
|             ?: throw SodaException("잘못된 요청입니다.") | ||||
|  | ||||
|         if (can != null) { | ||||
|             if (can <= 0) throw SodaException("1캔 이상 설정할 수 있습니다.") | ||||
|             signatureCan.can = can | ||||
|         } | ||||
|  | ||||
|         if (time != null) { | ||||
|             if (time < 3 || time > 20) throw SodaException("시간은 3초 이상 20초 이하로 설정할 수 있습니다.") | ||||
|             signatureCan.time = time | ||||
|         } | ||||
|  | ||||
|         if (isActive != null) { | ||||
|             signatureCan.isActive = isActive | ||||
|         } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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<SignatureCan, Long>, 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() | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user