한정판 콘텐츠 주문 기능 추가

This commit is contained in:
Klaus 2024-03-26 17:44:26 +09:00
parent 17c5bade83
commit 2d1f333095
4 changed files with 93 additions and 15 deletions

View File

@ -191,7 +191,7 @@ class AudioContentService(
} else {
false
},
isOnlyRental = request.isOnlyRental,
isOnlyRental = if (request.limited != null && request.limited > 0) false else request.isOnlyRental,
isCommentAvailable = request.isCommentAvailable
)
audioContent.theme = theme

View File

@ -0,0 +1,22 @@
package kr.co.vividnext.sodalive.content.order
import kr.co.vividnext.sodalive.common.BaseEntity
import kr.co.vividnext.sodalive.content.AudioContent
import javax.persistence.Entity
import javax.persistence.FetchType
import javax.persistence.JoinColumn
import javax.persistence.ManyToOne
import javax.persistence.OneToOne
@Entity
data class LimitedEditionOrder(
val sequence: Int
) : BaseEntity() {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "content_id", nullable = false)
var audioContent: AudioContent? = null
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", nullable = false)
var order: Order? = null
}

View File

@ -0,0 +1,30 @@
package kr.co.vividnext.sodalive.content.order
import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.content.order.QLimitedEditionOrder.limitedEditionOrder
import org.springframework.data.jpa.repository.JpaRepository
interface LimitedEditionOrderRepository : JpaRepository<LimitedEditionOrder, Long>, LimitedEditionOrderQueryRepository
interface LimitedEditionOrderQueryRepository {
fun getNextSequence(contentId: Long): Int
}
class LimitedEditionOrderQueryRepositoryImpl(
private val queryFactory: JPAQueryFactory
) : LimitedEditionOrderQueryRepository {
override fun getNextSequence(contentId: Long): Int {
val maxSequence = queryFactory.select(limitedEditionOrder.sequence)
.from(limitedEditionOrder)
.where(limitedEditionOrder.audioContent.id.eq(contentId))
.orderBy(limitedEditionOrder.sequence.desc())
.limit(1)
.fetchFirst()
return if (maxSequence == null) {
1
} else {
maxSequence + 1
}
}
}

View File

@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.content.order
import kr.co.vividnext.sodalive.can.payment.CanPaymentService
import kr.co.vividnext.sodalive.can.use.CanUsage
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.content.AudioContent
import kr.co.vividnext.sodalive.content.AudioContentRepository
import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
import kr.co.vividnext.sodalive.content.like.AudioContentLikeRepository
@ -21,6 +22,7 @@ class OrderService(
private val audioContentRepository: AudioContentRepository,
private val audioContentCommentQueryRepository: AudioContentCommentRepository,
private val audioContentLikeQueryRepository: AudioContentLikeRepository,
private val limitedEditionOrderRepository: LimitedEditionOrderRepository,
@Value("\${cloud.aws.cloud-front.host}")
private val audioContentCoverImageHost: String
@ -29,24 +31,15 @@ class OrderService(
fun order(contentId: Long, orderType: OrderType, container: String, member: Member) {
val content = audioContentRepository.findByIdAndActive(contentId)
?: throw SodaException("잘못된 콘텐츠 입니다\n다시 시도해 주세요.")
validateOrder(memberId = member.id!!, content = content)
val order = if (content.isOnlyRental) {
Order(type = OrderType.RENTAL)
val order = if (content.limited != null && content.remaining != null) {
if (content.remaining!! <= 0) throw SodaException("해당 콘텐츠가 매진되었습니다.")
orderLimitedEditionContent(content, member)
} else {
Order(type = orderType)
orderContent(orderType, content, member)
}
if (member.id!! == content.member!!.id!!) throw SodaException("자신이 올린 콘텐츠는 구매할 수 없습니다.")
if (repository.isExistOrdered(memberId = member.id!!, contentId = contentId)) {
throw SodaException("이미 구매한 콘텐츠 입니다.")
}
order.member = member
order.creator = content.member
order.audioContent = content
repository.save(order)
canPaymentService.spendCan(
memberId = member.id!!,
needCan = order.can,
@ -56,6 +49,39 @@ class OrderService(
)
}
private fun orderContent(orderType: OrderType, content: AudioContent, member: Member): Order {
val order = if (content.isOnlyRental) {
Order(type = OrderType.RENTAL)
} else {
Order(type = orderType)
}
order.member = member
order.creator = content.member
order.audioContent = content
return repository.save(order)
}
private fun orderLimitedEditionContent(content: AudioContent, member: Member): Order {
val order = orderContent(OrderType.KEEP, content, member)
val sequence = limitedEditionOrderRepository.getNextSequence(content.id!!)
val limitedEditionOrder = LimitedEditionOrder(sequence = sequence)
limitedEditionOrder.order = order
limitedEditionOrder.audioContent = content
limitedEditionOrderRepository.save(limitedEditionOrder)
content.remaining = content.remaining!! - 1
return order
}
private fun validateOrder(memberId: Long, content: AudioContent) {
if (memberId == content.member!!.id!!) throw SodaException("자신이 올린 콘텐츠는 구매할 수 없습니다.")
if (repository.isExistOrdered(memberId = memberId, contentId = content.id!!)) {
throw SodaException("이미 구매한 콘텐츠 입니다.")
}
}
fun getAudioContentOrderList(
member: Member,
offset: Long,