| @@ -7,6 +7,8 @@ import org.springframework.context.annotation.Configuration | |||||||
| import org.springframework.data.redis.cache.RedisCacheConfiguration | import org.springframework.data.redis.cache.RedisCacheConfiguration | ||||||
| import org.springframework.data.redis.cache.RedisCacheManager | import org.springframework.data.redis.cache.RedisCacheManager | ||||||
| import org.springframework.data.redis.connection.RedisConnectionFactory | import org.springframework.data.redis.connection.RedisConnectionFactory | ||||||
|  | import org.springframework.data.redis.connection.RedisStandaloneConfiguration | ||||||
|  | import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration | ||||||
| import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory | ||||||
| import org.springframework.data.redis.core.RedisTemplate | import org.springframework.data.redis.core.RedisTemplate | ||||||
| import org.springframework.data.redis.repository.configuration.EnableRedisRepositories | import org.springframework.data.redis.repository.configuration.EnableRedisRepositories | ||||||
| @@ -26,7 +28,12 @@ class RedisConfig( | |||||||
| ) { | ) { | ||||||
|     @Bean |     @Bean | ||||||
|     fun redisConnectionFactory(): RedisConnectionFactory { |     fun redisConnectionFactory(): RedisConnectionFactory { | ||||||
|         return LettuceConnectionFactory(host, port) |         val clientConfiguration = LettuceClientConfiguration.builder() | ||||||
|  |             .useSsl() | ||||||
|  |             .disablePeerVerification() | ||||||
|  |             .build() | ||||||
|  |  | ||||||
|  |         return LettuceConnectionFactory(RedisStandaloneConfiguration(host, port), clientConfiguration) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Bean |     @Bean | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ import kr.co.vividnext.sodalive.live.room.info.LiveRoomInfoRedisRepository | |||||||
| import kr.co.vividnext.sodalive.live.room.info.LiveRoomMember | import kr.co.vividnext.sodalive.live.room.info.LiveRoomMember | ||||||
| import kr.co.vividnext.sodalive.live.room.kickout.LiveRoomKickOutService | import kr.co.vividnext.sodalive.live.room.kickout.LiveRoomKickOutService | ||||||
| import kr.co.vividnext.sodalive.live.room.visit.LiveRoomVisitService | import kr.co.vividnext.sodalive.live.room.visit.LiveRoomVisitService | ||||||
| import kr.co.vividnext.sodalive.live.roulette.RouletteRepository | import kr.co.vividnext.sodalive.live.roulette.NewRouletteRepository | ||||||
| import kr.co.vividnext.sodalive.live.tag.LiveTagRepository | import kr.co.vividnext.sodalive.live.tag.LiveTagRepository | ||||||
| import kr.co.vividnext.sodalive.member.Gender | import kr.co.vividnext.sodalive.member.Gender | ||||||
| import kr.co.vividnext.sodalive.member.Member | import kr.co.vividnext.sodalive.member.Member | ||||||
| @@ -66,7 +66,7 @@ import kotlin.concurrent.write | |||||||
| @Transactional(readOnly = true) | @Transactional(readOnly = true) | ||||||
| class LiveRoomService( | class LiveRoomService( | ||||||
|     private val repository: LiveRoomRepository, |     private val repository: LiveRoomRepository, | ||||||
|     private val rouletteRepository: RouletteRepository, |     private val rouletteRepository: NewRouletteRepository, | ||||||
|     private val roomInfoRepository: LiveRoomInfoRedisRepository, |     private val roomInfoRepository: LiveRoomInfoRedisRepository, | ||||||
|     private val roomCancelRepository: LiveRoomCancelRepository, |     private val roomCancelRepository: LiveRoomCancelRepository, | ||||||
|     private val kickOutService: LiveRoomKickOutService, |     private val kickOutService: LiveRoomKickOutService, | ||||||
| @@ -679,7 +679,15 @@ class LiveRoomService( | |||||||
|             .getNotificationUserIds(room.member!!.id!!) |             .getNotificationUserIds(room.member!!.id!!) | ||||||
|             .contains(member.id) |             .contains(member.id) | ||||||
|  |  | ||||||
|         val isActiveRoulette = rouletteRepository.findByIdOrNull(room.member!!.id!!)?.isActive ?: false |         var isActiveRoulette = false | ||||||
|  |         val rouletteList = rouletteRepository.findByCreatorId(creatorId = room.member!!.id!!) | ||||||
|  |  | ||||||
|  |         for (roulette in rouletteList) { | ||||||
|  |             if (roulette.isActive) { | ||||||
|  |                 isActiveRoulette = true | ||||||
|  |                 break | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         val donationRankingTop3UserIds = if (room.member!!.isVisibleDonationRank) { |         val donationRankingTop3UserIds = if (room.member!!.isVisibleDonationRank) { | ||||||
|             explorerQueryRepository |             explorerQueryRepository | ||||||
| @@ -1004,10 +1012,12 @@ class LiveRoomService( | |||||||
|                     kickOutService.deleteKickOutData(roomId = room.id!!) |                     kickOutService.deleteKickOutData(roomId = room.id!!) | ||||||
|                     roomInfoRepository.deleteById(roomInfo.roomId) |                     roomInfoRepository.deleteById(roomInfo.roomId) | ||||||
|  |  | ||||||
|                     val roulette = rouletteRepository.findByIdOrNull(member.id!!) |                     val rouletteList = rouletteRepository.findByCreatorId(creatorId = member.id!!) | ||||||
|                     if (roulette != null) { |                     if (rouletteList.isNotEmpty()) { | ||||||
|                         roulette.isActive = false |                         rouletteList.forEach { | ||||||
|                         rouletteRepository.save(roulette) |                             it.isActive = false | ||||||
|  |                             rouletteRepository.save(it) | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     roomInfo.removeSpeaker(member) |                     roomInfo.removeSpeaker(member) | ||||||
|   | |||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | data class CreateNewRouletteRequest( | ||||||
|  |     val can: Int, | ||||||
|  |     val isActive: Boolean, | ||||||
|  |     val items: List<RouletteItem> | ||||||
|  | ) | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | data class GetNewRouletteResponse( | ||||||
|  |     val id: Long, | ||||||
|  |     val can: Int, | ||||||
|  |     val isActive: Boolean, | ||||||
|  |     val items: List<RouletteItem> | ||||||
|  | ) | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | import org.springframework.data.redis.core.RedisHash | ||||||
|  | import org.springframework.data.redis.core.index.Indexed | ||||||
|  | import javax.persistence.Id | ||||||
|  |  | ||||||
|  | @RedisHash("newRoulette") | ||||||
|  | data class NewRoulette( | ||||||
|  |     @Id | ||||||
|  |     val id: Long, | ||||||
|  |     @Indexed | ||||||
|  |     val creatorId: Long, | ||||||
|  |     var can: Int, | ||||||
|  |     var isActive: Boolean, | ||||||
|  |     var items: List<RouletteItem> = mutableListOf() | ||||||
|  | ) | ||||||
| @@ -0,0 +1,87 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.common.ApiResponse | ||||||
|  | import kr.co.vividnext.sodalive.common.SodaException | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
|  | import kr.co.vividnext.sodalive.member.MemberRole | ||||||
|  | import org.springframework.security.access.prepost.PreAuthorize | ||||||
|  | import org.springframework.security.core.annotation.AuthenticationPrincipal | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable | ||||||
|  | import org.springframework.web.bind.annotation.PostMapping | ||||||
|  | import org.springframework.web.bind.annotation.PutMapping | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam | ||||||
|  | import org.springframework.web.bind.annotation.RestController | ||||||
|  |  | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/new-roulette") | ||||||
|  | class NewRouletteController(private val service: NewRouletteService) { | ||||||
|  |     @GetMapping("/creator") | ||||||
|  |     @PreAuthorize("hasRole('CREATOR')") | ||||||
|  |     fun getAllRoulette( | ||||||
|  |         @RequestParam creatorId: Long, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.getAllRoulette(creatorId = creatorId, memberId = member.id!!)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping | ||||||
|  |     @PreAuthorize("hasRole('CREATOR')") | ||||||
|  |     fun createNewRoulette( | ||||||
|  |         @RequestBody request: CreateNewRouletteRequest, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null || member.role != MemberRole.CREATOR) { | ||||||
|  |             throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.createRoulette(memberId = member.id!!, request = request)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PutMapping | ||||||
|  |     @PreAuthorize("hasRole('CREATOR')") | ||||||
|  |     fun updateNewRoulette( | ||||||
|  |         @RequestBody request: UpdateNewRouletteRequest, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null || member.role != MemberRole.CREATOR) { | ||||||
|  |             throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.updateRoulette(memberId = member.id!!, request = request)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @GetMapping | ||||||
|  |     fun getRoulette( | ||||||
|  |         @RequestParam creatorId: Long, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ): ApiResponse<GetRouletteResponse> { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         return ApiResponse.ok(service.getRoulette(creatorId = creatorId, memberId = member.id!!)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/spin") | ||||||
|  |     fun spinRoulette( | ||||||
|  |         @RequestBody request: SpinRouletteRequest, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.spinRoulette(request = request, memberId = member.id!!)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PostMapping("/refund/{id}") | ||||||
|  |     fun refundDonation( | ||||||
|  |         @PathVariable id: Long, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.refundDonation(id, member)) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | import org.springframework.data.repository.CrudRepository | ||||||
|  |  | ||||||
|  | interface NewRouletteRepository : CrudRepository<NewRoulette, Long> { | ||||||
|  |     fun findByCreatorId(creatorId: Long): List<NewRoulette> | ||||||
|  | } | ||||||
| @@ -0,0 +1,246 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.can.CanRepository | ||||||
|  | import kr.co.vividnext.sodalive.can.charge.Charge | ||||||
|  | import kr.co.vividnext.sodalive.can.charge.ChargeRepository | ||||||
|  | import kr.co.vividnext.sodalive.can.charge.ChargeStatus | ||||||
|  | import kr.co.vividnext.sodalive.can.payment.CanPaymentService | ||||||
|  | import kr.co.vividnext.sodalive.can.payment.Payment | ||||||
|  | import kr.co.vividnext.sodalive.can.payment.PaymentGateway | ||||||
|  | import kr.co.vividnext.sodalive.can.payment.PaymentStatus | ||||||
|  | import kr.co.vividnext.sodalive.can.use.CanUsage | ||||||
|  | import kr.co.vividnext.sodalive.can.use.UseCanCalculateRepository | ||||||
|  | import kr.co.vividnext.sodalive.can.use.UseCanCalculateStatus | ||||||
|  | import kr.co.vividnext.sodalive.common.SodaException | ||||||
|  | import kr.co.vividnext.sodalive.live.room.LiveRoomRepository | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
|  | import kr.co.vividnext.sodalive.member.MemberRepository | ||||||
|  | import kr.co.vividnext.sodalive.member.MemberRole | ||||||
|  | import org.springframework.data.repository.findByIdOrNull | ||||||
|  | import org.springframework.stereotype.Service | ||||||
|  | import org.springframework.transaction.annotation.Transactional | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | class NewRouletteService( | ||||||
|  |     private val idGenerator: RedisIdGenerator, | ||||||
|  |     private val canPaymentService: CanPaymentService, | ||||||
|  |  | ||||||
|  |     private val canRepository: CanRepository, | ||||||
|  |     private val repository: NewRouletteRepository, | ||||||
|  |     private val oldRepository: RouletteRepository, | ||||||
|  |     private val roomRepository: LiveRoomRepository, | ||||||
|  |     private val memberRepository: MemberRepository, | ||||||
|  |     private val chargeRepository: ChargeRepository, | ||||||
|  |     private val useCanCalculateRepository: UseCanCalculateRepository | ||||||
|  | ) { | ||||||
|  |     fun getAllRoulette(creatorId: Long, memberId: Long): List<GetNewRouletteResponse> { | ||||||
|  |         if (creatorId != memberId) throw SodaException("잘못된 요청입니다.") | ||||||
|  |  | ||||||
|  |         var rouletteList = repository.findByCreatorId(creatorId) | ||||||
|  |         if (rouletteList.isEmpty()) { | ||||||
|  |             val roulette = oldRepository.findByIdOrNull(creatorId) | ||||||
|  |             if (roulette != null) { | ||||||
|  |                 repository.save( | ||||||
|  |                     NewRoulette( | ||||||
|  |                         id = idGenerator.generateId(SEQUENCE_NAME), | ||||||
|  |                         creatorId = creatorId, | ||||||
|  |                         can = roulette.can, | ||||||
|  |                         isActive = false, | ||||||
|  |                         items = roulette.items | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |  | ||||||
|  |                 rouletteList = repository.findByCreatorId(creatorId) | ||||||
|  |                 oldRepository.deleteById(roulette.creatorId) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         rouletteList.sortedBy { it.id } | ||||||
|  |  | ||||||
|  |         return rouletteList.asSequence() | ||||||
|  |             .map { | ||||||
|  |                 GetNewRouletteResponse( | ||||||
|  |                     it.id, | ||||||
|  |                     it.can, | ||||||
|  |                     it.isActive, | ||||||
|  |                     it.items | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             .toList() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun createRoulette(memberId: Long, request: CreateNewRouletteRequest): Boolean { | ||||||
|  |         rouletteValidate(can = request.can, items = request.items) | ||||||
|  |  | ||||||
|  |         if (request.isActive) { | ||||||
|  |             val rouletteList = repository.findByCreatorId(creatorId = memberId) | ||||||
|  |             rouletteList.forEach { | ||||||
|  |                 it.isActive = false | ||||||
|  |                 repository.save(it) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val roulette = NewRoulette( | ||||||
|  |             id = idGenerator.generateId(SEQUENCE_NAME), | ||||||
|  |             creatorId = memberId, | ||||||
|  |             can = request.can, | ||||||
|  |             isActive = request.isActive, | ||||||
|  |             items = request.items | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         repository.save(roulette) | ||||||
|  |         return request.isActive | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun updateRoulette(memberId: Long, request: UpdateNewRouletteRequest): Boolean { | ||||||
|  |         rouletteValidate(can = request.can, items = request.items) | ||||||
|  |  | ||||||
|  |         val rouletteList = repository.findByCreatorId(creatorId = memberId) | ||||||
|  |  | ||||||
|  |         if (rouletteList.isEmpty()) { | ||||||
|  |             throw SodaException("잘못된 요청입니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var isActive = false | ||||||
|  |         rouletteList.forEach { | ||||||
|  |             if (request.isActive || it.isActive) { | ||||||
|  |                 isActive = true | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (it.id == request.id) { | ||||||
|  |                 it.can = request.can | ||||||
|  |                 it.items = request.items | ||||||
|  |                 it.isActive = request.isActive | ||||||
|  |                 repository.save(it) | ||||||
|  |             } else if (request.isActive) { | ||||||
|  |                 it.isActive = false | ||||||
|  |                 repository.save(it) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return isActive | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getRoulette(creatorId: Long, memberId: Long): GetRouletteResponse { | ||||||
|  |         val rouletteList = repository.findByCreatorId(creatorId = creatorId) | ||||||
|  |  | ||||||
|  |         if (rouletteList.isEmpty()) { | ||||||
|  |             throw SodaException("룰렛을 사용할 수 없습니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var activeRoulette: NewRoulette? = null | ||||||
|  |         for (roulette in rouletteList) { | ||||||
|  |             if (roulette.isActive) { | ||||||
|  |                 activeRoulette = roulette | ||||||
|  |                 break | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (activeRoulette == null || activeRoulette.items.isEmpty()) { | ||||||
|  |             throw SodaException("룰렛을 사용할 수 없습니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return GetRouletteResponse( | ||||||
|  |             can = activeRoulette.can, | ||||||
|  |             isActive = activeRoulette.isActive, | ||||||
|  |             items = activeRoulette.items | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun spinRoulette(request: SpinRouletteRequest, memberId: Long): GetRouletteResponse { | ||||||
|  |         // STEP 1 - 라이브 정보 가져오기 | ||||||
|  |         val room = roomRepository.findByIdOrNull(request.roomId) | ||||||
|  |             ?: throw SodaException("해당하는 라이브가 없습니다.") | ||||||
|  |  | ||||||
|  |         val host = room.member ?: throw SodaException("잘못된 요청입니다.") | ||||||
|  |  | ||||||
|  |         if (host.role != MemberRole.CREATOR) { | ||||||
|  |             throw SodaException("비비드넥스트와 계약한\n크리에이터의 룰렛만 사용하실 수 있습니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // STEP 2 - 룰렛 데이터 가져오기 | ||||||
|  |         val rouletteList = repository.findByCreatorId(creatorId = host.id!!) | ||||||
|  |  | ||||||
|  |         if (rouletteList.isEmpty()) { | ||||||
|  |             throw SodaException("룰렛을 사용할 수 없습니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var activeRoulette: NewRoulette? = null | ||||||
|  |         for (roulette in rouletteList) { | ||||||
|  |             if (roulette.isActive) { | ||||||
|  |                 activeRoulette = roulette | ||||||
|  |                 break | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (activeRoulette == null || activeRoulette.items.isEmpty()) { | ||||||
|  |             throw SodaException("룰렛을 사용할 수 없습니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // STEP 3 - 캔 사용 | ||||||
|  |         canPaymentService.spendCan( | ||||||
|  |             memberId = memberId, | ||||||
|  |             needCan = activeRoulette.can, | ||||||
|  |             canUsage = CanUsage.SPIN_ROULETTE, | ||||||
|  |             liveRoom = room, | ||||||
|  |             container = request.container | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return GetRouletteResponse( | ||||||
|  |             can = activeRoulette.can, | ||||||
|  |             isActive = activeRoulette.isActive, | ||||||
|  |             items = activeRoulette.items | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun refundDonation(roomId: Long, member: Member) { | ||||||
|  |         val donator = memberRepository.findByIdOrNull(member.id) | ||||||
|  |             ?: throw SodaException("룰렛 돌리기에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요.") | ||||||
|  |  | ||||||
|  |         val useCan = canRepository.getCanUsedForLiveRoomNotRefund( | ||||||
|  |             memberId = member.id!!, | ||||||
|  |             roomId = roomId, | ||||||
|  |             canUsage = CanUsage.SPIN_ROULETTE | ||||||
|  |         ) ?: throw SodaException("룰렛 돌리기에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요.") | ||||||
|  |         useCan.isRefund = true | ||||||
|  |  | ||||||
|  |         val useCanCalculates = useCanCalculateRepository.findByUseCanIdAndStatus(useCan.id!!) | ||||||
|  |         useCanCalculates.forEach { | ||||||
|  |             it.status = UseCanCalculateStatus.REFUND | ||||||
|  |             val charge = Charge(0, it.can, status = ChargeStatus.REFUND_CHARGE) | ||||||
|  |             charge.title = "${it.can} 캔" | ||||||
|  |             charge.useCan = useCan | ||||||
|  |  | ||||||
|  |             when (it.paymentGateway) { | ||||||
|  |                 PaymentGateway.GOOGLE_IAP -> donator.googleRewardCan += charge.rewardCan | ||||||
|  |                 PaymentGateway.APPLE_IAP -> donator.appleRewardCan += charge.rewardCan | ||||||
|  |                 else -> donator.pgRewardCan += charge.rewardCan | ||||||
|  |             } | ||||||
|  |             charge.member = donator | ||||||
|  |  | ||||||
|  |             val payment = Payment( | ||||||
|  |                 status = PaymentStatus.COMPLETE, | ||||||
|  |                 paymentGateway = it.paymentGateway | ||||||
|  |             ) | ||||||
|  |             payment.method = "룰렛 환불" | ||||||
|  |             charge.payment = payment | ||||||
|  |  | ||||||
|  |             chargeRepository.save(charge) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun rouletteValidate(can: Int, items: List<RouletteItem>) { | ||||||
|  |         if (can < 5) { | ||||||
|  |             throw SodaException("룰렛 금액은 최소 5캔 입니다.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (items.size < 2 || items.size > 10) { | ||||||
|  |             throw SodaException("룰렛 옵션은 최소 2개, 최대 10개까지 설정할 수 있습니다.") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     companion object { | ||||||
|  |         const val SEQUENCE_NAME = "newRoulette:sequence" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | import org.springframework.data.redis.core.StringRedisTemplate | ||||||
|  | import org.springframework.stereotype.Service | ||||||
|  |  | ||||||
|  | @Service | ||||||
|  | class RedisIdGenerator(private val stringRedisTemplate: StringRedisTemplate) { | ||||||
|  |     fun generateId(key: String): Long { | ||||||
|  |         return stringRedisTemplate.opsForValue().increment(key, 1) ?: 1L | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -86,7 +86,7 @@ class RouletteService( | |||||||
|         val host = room.member ?: throw SodaException("잘못된 요청입니다.") |         val host = room.member ?: throw SodaException("잘못된 요청입니다.") | ||||||
|  |  | ||||||
|         if (host.role != MemberRole.CREATOR) { |         if (host.role != MemberRole.CREATOR) { | ||||||
|             throw SodaException("비비드넥스트와 계약한\n크리에이터에게만 후원을 하실 수 있습니다.") |             throw SodaException("비비드넥스트와 계약한\n크리에이터의 룰렛만 사용하실 수 있습니다.") | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // STEP 2 - 룰렛 데이터 가져오기 |         // STEP 2 - 룰렛 데이터 가져오기 | ||||||
| @@ -138,7 +138,7 @@ class RouletteService( | |||||||
|                 status = PaymentStatus.COMPLETE, |                 status = PaymentStatus.COMPLETE, | ||||||
|                 paymentGateway = it.paymentGateway |                 paymentGateway = it.paymentGateway | ||||||
|             ) |             ) | ||||||
|             payment.method = "환불" |             payment.method = "룰렛 환불" | ||||||
|             charge.payment = payment |             charge.payment = payment | ||||||
|  |  | ||||||
|             chargeRepository.save(charge) |             chargeRepository.save(charge) | ||||||
|   | |||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package kr.co.vividnext.sodalive.live.roulette | ||||||
|  |  | ||||||
|  | data class UpdateNewRouletteRequest( | ||||||
|  |     val id: Long, | ||||||
|  |     val can: Int, | ||||||
|  |     val isActive: Boolean, | ||||||
|  |     val items: List<RouletteItem> | ||||||
|  | ) | ||||||
		Reference in New Issue
	
	Block a user