Merge pull request '라이브 시작시간 4시간이 지나도 라이브를 시작하지 않은 경우 자동취소로직 추가' (#30) from test into main

Reviewed-on: #30
This commit is contained in:
klaus 2023-09-12 14:09:37 +00:00
commit 07a92af982
3 changed files with 108 additions and 0 deletions

View File

@ -15,6 +15,10 @@ import org.springframework.web.multipart.MultipartFile
@RestController @RestController
@RequestMapping("/admin/live") @RequestMapping("/admin/live")
class AdminLiveController(private val service: AdminLiveService) { class AdminLiveController(private val service: AdminLiveService) {
@PostMapping("/cancel-not-started")
@PreAuthorize("hasRole('BOT')")
fun cancelNotStartedLive4hoursPassed() = ApiResponse.ok(service.cancelNotStartedLive4hoursPassed())
@GetMapping @GetMapping
@PreAuthorize("hasRole('ADMIN')") @PreAuthorize("hasRole('ADMIN')")
fun getOnAirLive() = ApiResponse.ok(data = service.getLiveList()) fun getOnAirLive() = ApiResponse.ok(data = service.getLiveList())
@ -24,6 +28,7 @@ class AdminLiveController(private val service: AdminLiveService) {
fun getRecommendCreatorBanner(pageable: Pageable) = ApiResponse.ok(service.getRecommendCreator(pageable)) fun getRecommendCreatorBanner(pageable: Pageable) = ApiResponse.ok(service.getRecommendCreator(pageable))
@PostMapping("/recommend-creator") @PostMapping("/recommend-creator")
@PreAuthorize("hasRole('ADMIN')")
fun createRecommendCreatorBanner( fun createRecommendCreatorBanner(
@RequestParam("image") image: MultipartFile, @RequestParam("image") image: MultipartFile,
@RequestParam("creator_id") creatorId: Long, @RequestParam("creator_id") creatorId: Long,
@ -36,6 +41,7 @@ class AdminLiveController(private val service: AdminLiveService) {
) )
@PutMapping("/recommend-creator") @PutMapping("/recommend-creator")
@PreAuthorize("hasRole('ADMIN')")
fun updateRecommendCreatorBanner( fun updateRecommendCreatorBanner(
@RequestParam("recommend_creator_banner_id") recommendCreatorBannerId: Long, @RequestParam("recommend_creator_banner_id") recommendCreatorBannerId: Long,
@RequestParam("image", required = false) image: MultipartFile?, @RequestParam("image", required = false) image: MultipartFile?,
@ -49,6 +55,7 @@ class AdminLiveController(private val service: AdminLiveService) {
) )
@PutMapping("/recommend-creator/orders") @PutMapping("/recommend-creator/orders")
@PreAuthorize("hasRole('ADMIN')")
fun updateRecommendCreatorBannerOrders( fun updateRecommendCreatorBannerOrders(
@RequestBody request: UpdateAdminRecommendCreatorBannerOrdersRequest @RequestBody request: UpdateAdminRecommendCreatorBannerOrdersRequest
) = ApiResponse.ok( ) = ApiResponse.ok(

View File

@ -8,6 +8,7 @@ import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
import kr.co.vividnext.sodalive.member.QMember.member import kr.co.vividnext.sodalive.member.QMember.member
import org.springframework.data.domain.Pageable import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
import java.time.LocalDateTime
@Repository @Repository
class AdminLiveRoomQueryRepository(private val queryFactory: JPAQueryFactory) { class AdminLiveRoomQueryRepository(private val queryFactory: JPAQueryFactory) {
@ -36,4 +37,15 @@ class AdminLiveRoomQueryRepository(private val queryFactory: JPAQueryFactory) {
.orderBy(recommendLiveCreatorBanner.orders.asc(), recommendLiveCreatorBanner.id.desc()) .orderBy(recommendLiveCreatorBanner.orders.asc(), recommendLiveCreatorBanner.id.desc())
.fetch() .fetch()
} }
fun getNotStartedLive4hoursPassed(): List<LiveRoom> {
return queryFactory
.selectFrom(liveRoom)
.where(
liveRoom.isActive.isTrue
.and(liveRoom.channelName.isNotNull)
.and(liveRoom.beginDateTime.loe(LocalDateTime.now().minusHours(12)))
)
.fetch()
}
} }

View File

@ -2,12 +2,28 @@ package kr.co.vividnext.sodalive.admin.live
import com.amazonaws.services.s3.model.ObjectMetadata import com.amazonaws.services.s3.model.ObjectMetadata
import kr.co.vividnext.sodalive.aws.s3.S3Uploader import kr.co.vividnext.sodalive.aws.s3.S3Uploader
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.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.common.SodaException
import kr.co.vividnext.sodalive.fcm.FcmEvent
import kr.co.vividnext.sodalive.fcm.FcmEventType
import kr.co.vividnext.sodalive.live.recommend.RecommendLiveCreatorBanner import kr.co.vividnext.sodalive.live.recommend.RecommendLiveCreatorBanner
import kr.co.vividnext.sodalive.live.recommend.RecommendLiveCreatorBannerRepository import kr.co.vividnext.sodalive.live.recommend.RecommendLiveCreatorBannerRepository
import kr.co.vividnext.sodalive.live.reservation.LiveReservationRepository
import kr.co.vividnext.sodalive.live.room.cancel.LiveRoomCancel
import kr.co.vividnext.sodalive.live.room.cancel.LiveRoomCancelRepository
import kr.co.vividnext.sodalive.member.MemberRepository import kr.co.vividnext.sodalive.member.MemberRepository
import kr.co.vividnext.sodalive.utils.generateFileName import kr.co.vividnext.sodalive.utils.generateFileName
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.context.ApplicationEventPublisher
import org.springframework.data.domain.Pageable import org.springframework.data.domain.Pageable
import org.springframework.data.repository.findByIdOrNull import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@ -20,10 +36,18 @@ import java.time.format.DateTimeFormatter
@Service @Service
class AdminLiveService( class AdminLiveService(
private val recommendCreatorBannerRepository: RecommendLiveCreatorBannerRepository, private val recommendCreatorBannerRepository: RecommendLiveCreatorBannerRepository,
private val roomCancelRepository: LiveRoomCancelRepository,
private val repository: AdminLiveRoomQueryRepository, private val repository: AdminLiveRoomQueryRepository,
private val memberRepository: MemberRepository, private val memberRepository: MemberRepository,
private val s3Uploader: S3Uploader, private val s3Uploader: S3Uploader,
private val useCanCalculateRepository: UseCanCalculateRepository,
private val reservationRepository: LiveReservationRepository,
private val chargeRepository: ChargeRepository,
private val canRepository: CanRepository,
private val applicationEventPublisher: ApplicationEventPublisher,
@Value("\${cloud.aws.s3.bucket}") @Value("\${cloud.aws.s3.bucket}")
private val bucket: String, private val bucket: String,
@Value("\${cloud.aws.cloud-front.host}") @Value("\${cloud.aws.cloud-front.host}")
@ -237,4 +261,69 @@ class AdminLiveService(
} }
} }
} }
@Transactional
fun cancelNotStartedLive4hoursPassed() {
val findRoomList = repository.getNotStartedLive4hoursPassed()
for (room in findRoomList) {
room.isActive = false
val roomCancel = LiveRoomCancel("관리자에 의한 취소 - 노쇼")
roomCancel.room = room
roomCancelRepository.save(roomCancel)
// 유료방인 경우 환불처리
if (room.price > 0) {
val bookerList = reservationRepository.getReservationBookerList(roomId = room.id!!)
for (booker in bookerList) {
val useCan = canRepository.getCanUsedForLiveRoomNotRefund(
memberId = booker.id!!,
roomId = room.id!!,
canUsage = CanUsage.LIVE
) ?: continue
useCan.isRefund = true
val useCanCalculate = useCanCalculateRepository.findByUseCanIdAndStatus(useCanId = useCan.id!!)
useCanCalculate.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.PG -> booker.pgRewardCan += charge.rewardCan
PaymentGateway.GOOGLE_IAP -> booker.googleRewardCan += charge.rewardCan
PaymentGateway.APPLE_IAP -> booker.appleRewardCan += charge.rewardCan
}
charge.member = booker
val payment = Payment(
status = PaymentStatus.COMPLETE,
paymentGateway = it.paymentGateway
)
payment.method = "환불"
charge.payment = payment
chargeRepository.save(charge)
}
}
}
// 예약현황 취소
val pushTokenListMap = memberRepository.getPushTokenFromReservationList(room.id!!)
reservationRepository.cancelReservation(roomId = room.id!!)
// 라이브 취소 푸시 발송
applicationEventPublisher.publishEvent(
FcmEvent(
type = FcmEventType.CANCEL_LIVE,
title = room.member!!.nickname,
message = "라이브 취소 : ${room.title}",
recipientsMap = pushTokenListMap
)
)
}
}
} }