Compare commits
No commits in common. "5feafe1b48365af947ee77ad58165cc254ec6ebe" and "c9292b7d043a29b95757c3dfc30a32bdccd6a94a" have entirely different histories.
5feafe1b48
...
c9292b7d04
|
@ -9,7 +9,6 @@ import kr.co.vividnext.sodalive.can.payment.QPayment.payment
|
||||||
import kr.co.vividnext.sodalive.member.QMember.member
|
import kr.co.vividnext.sodalive.member.QMember.member
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
import java.time.LocalDateTime
|
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
interface ChargeRepository : JpaRepository<Charge, Long>, ChargeQueryRepository
|
interface ChargeRepository : JpaRepository<Charge, Long>, ChargeQueryRepository
|
||||||
|
@ -17,7 +16,6 @@ interface ChargeRepository : JpaRepository<Charge, Long>, ChargeQueryRepository
|
||||||
interface ChargeQueryRepository {
|
interface ChargeQueryRepository {
|
||||||
fun getOldestChargeWhereRewardCanGreaterThan0(chargeId: Long, memberId: Long, container: String): Charge?
|
fun getOldestChargeWhereRewardCanGreaterThan0(chargeId: Long, memberId: Long, container: String): Charge?
|
||||||
fun getOldestChargeWhereChargeCanGreaterThan0(chargeId: Long, memberId: Long, container: String): Charge?
|
fun getOldestChargeWhereChargeCanGreaterThan0(chargeId: Long, memberId: Long, container: String): Charge?
|
||||||
fun getChargeCountAfterDate(date: LocalDateTime): Int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChargeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : ChargeQueryRepository {
|
class ChargeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : ChargeQueryRepository {
|
||||||
|
@ -61,10 +59,6 @@ class ChargeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : Cha
|
||||||
.fetchFirst()
|
.fetchFirst()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChargeCountAfterDate(date: LocalDateTime): Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPaymentGatewayCondition(container: String): BooleanExpression? {
|
private fun getPaymentGatewayCondition(container: String): BooleanExpression? {
|
||||||
val paymentGatewayCondition = when (container) {
|
val paymentGatewayCondition = when (container) {
|
||||||
"aos" -> {
|
"aos" -> {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package kr.co.vividnext.sodalive.can.charge
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import kr.co.bootpay.Bootpay
|
import kr.co.bootpay.Bootpay
|
||||||
import kr.co.vividnext.sodalive.can.CanRepository
|
import kr.co.vividnext.sodalive.can.CanRepository
|
||||||
import kr.co.vividnext.sodalive.can.charge.event.ChargeSpringEvent
|
|
||||||
import kr.co.vividnext.sodalive.can.payment.Payment
|
import kr.co.vividnext.sodalive.can.payment.Payment
|
||||||
import kr.co.vividnext.sodalive.can.payment.PaymentGateway
|
import kr.co.vividnext.sodalive.can.payment.PaymentGateway
|
||||||
import kr.co.vividnext.sodalive.can.payment.PaymentStatus
|
import kr.co.vividnext.sodalive.can.payment.PaymentStatus
|
||||||
|
@ -16,7 +15,6 @@ import okhttp3.Request
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.context.ApplicationEventPublisher
|
|
||||||
import org.springframework.data.repository.findByIdOrNull
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
import org.springframework.http.HttpHeaders
|
import org.springframework.http.HttpHeaders
|
||||||
import org.springframework.security.core.userdetails.User
|
import org.springframework.security.core.userdetails.User
|
||||||
|
@ -31,8 +29,6 @@ class ChargeService(
|
||||||
private val memberRepository: MemberRepository,
|
private val memberRepository: MemberRepository,
|
||||||
private val objectMapper: ObjectMapper,
|
private val objectMapper: ObjectMapper,
|
||||||
private val okHttpClient: OkHttpClient,
|
private val okHttpClient: OkHttpClient,
|
||||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
|
||||||
|
|
||||||
@Value("\${bootpay.application-id}")
|
@Value("\${bootpay.application-id}")
|
||||||
private val bootpayApplicationId: String,
|
private val bootpayApplicationId: String,
|
||||||
@Value("\${bootpay.private-key}")
|
@Value("\${bootpay.private-key}")
|
||||||
|
@ -84,8 +80,6 @@ class ChargeService(
|
||||||
charge.payment?.method = verifyResult.method
|
charge.payment?.method = verifyResult.method
|
||||||
charge.payment?.status = PaymentStatus.COMPLETE
|
charge.payment?.status = PaymentStatus.COMPLETE
|
||||||
member.charge(charge.chargeCan, charge.rewardCan, "pg")
|
member.charge(charge.chargeCan, charge.rewardCan, "pg")
|
||||||
|
|
||||||
applicationEventPublisher.publishEvent(ChargeSpringEvent(chargeId = charge.id!!, member = member))
|
|
||||||
} else {
|
} else {
|
||||||
throw SodaException("결제정보에 오류가 있습니다.")
|
throw SodaException("결제정보에 오류가 있습니다.")
|
||||||
}
|
}
|
||||||
|
@ -133,8 +127,6 @@ class ChargeService(
|
||||||
charge.payment?.method = "애플(인 앱 결제)"
|
charge.payment?.method = "애플(인 앱 결제)"
|
||||||
charge.payment?.status = PaymentStatus.COMPLETE
|
charge.payment?.status = PaymentStatus.COMPLETE
|
||||||
member.charge(charge.chargeCan, charge.rewardCan, "ios")
|
member.charge(charge.chargeCan, charge.rewardCan, "ios")
|
||||||
|
|
||||||
applicationEventPublisher.publishEvent(ChargeSpringEvent(chargeId = charge.id!!, member = member))
|
|
||||||
} else {
|
} else {
|
||||||
throw SodaException("결제정보에 오류가 있습니다.")
|
throw SodaException("결제정보에 오류가 있습니다.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.can.charge.event
|
|
||||||
|
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
|
||||||
import kr.co.vividnext.sodalive.admin.event.ChargeEvent
|
|
||||||
import kr.co.vividnext.sodalive.admin.event.QChargeEvent.chargeEvent
|
|
||||||
import kr.co.vividnext.sodalive.can.charge.QCharge.charge
|
|
||||||
import kr.co.vividnext.sodalive.can.payment.PaymentStatus
|
|
||||||
import kr.co.vividnext.sodalive.can.payment.QPayment.payment
|
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
|
|
||||||
interface ChargeEventRepository : JpaRepository<ChargeEvent, Long>, ChargeEventQueryRepository
|
|
||||||
|
|
||||||
interface ChargeEventQueryRepository {
|
|
||||||
fun getChargeEvent(): ChargeEvent?
|
|
||||||
fun getPaymentCount(member: Member, method: String, startDate: LocalDateTime, endDate: LocalDateTime): Int
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChargeEventQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : ChargeEventQueryRepository {
|
|
||||||
override fun getChargeEvent(): ChargeEvent? {
|
|
||||||
val now = LocalDateTime.now()
|
|
||||||
return queryFactory
|
|
||||||
.selectFrom(chargeEvent)
|
|
||||||
.where(
|
|
||||||
chargeEvent.isActive.isTrue
|
|
||||||
.and(chargeEvent.startDate.loe(now))
|
|
||||||
.and(chargeEvent.endDate.goe(now))
|
|
||||||
)
|
|
||||||
.orderBy(chargeEvent.id.asc())
|
|
||||||
.fetchFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPaymentCount(
|
|
||||||
member: Member,
|
|
||||||
method: String,
|
|
||||||
startDate: LocalDateTime,
|
|
||||||
endDate: LocalDateTime
|
|
||||||
): Int {
|
|
||||||
val where = charge.member.eq(member)
|
|
||||||
.and(charge.payment.method.eq(method))
|
|
||||||
.and(
|
|
||||||
charge.payment.status.eq(PaymentStatus.COMPLETE)
|
|
||||||
.or(charge.payment.status.eq(PaymentStatus.RETURN))
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryFactory
|
|
||||||
.selectFrom(charge)
|
|
||||||
.innerJoin(charge.payment, payment)
|
|
||||||
.where(where)
|
|
||||||
.fetch()
|
|
||||||
.count()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.can.charge.event
|
|
||||||
|
|
||||||
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.common.SodaException
|
|
||||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
|
||||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
|
||||||
import org.springframework.context.ApplicationEventPublisher
|
|
||||||
import org.springframework.data.repository.findByIdOrNull
|
|
||||||
import org.springframework.stereotype.Service
|
|
||||||
import org.springframework.transaction.annotation.Transactional
|
|
||||||
import kotlin.math.ceil
|
|
||||||
import kotlin.math.round
|
|
||||||
|
|
||||||
@Service
|
|
||||||
class ChargeEventService(
|
|
||||||
private val repository: ChargeEventRepository,
|
|
||||||
private val chargeRepository: ChargeRepository,
|
|
||||||
private val chargeEventRepository: ChargeEventRepository,
|
|
||||||
private val applicationEventPublisher: ApplicationEventPublisher
|
|
||||||
) {
|
|
||||||
@Transactional
|
|
||||||
fun applyChargeEvent(chargeId: Long, member: Member) {
|
|
||||||
val charge = chargeRepository.findByIdOrNull(chargeId)
|
|
||||||
?: throw SodaException("이벤트가 적용되지 않았습니다.")
|
|
||||||
|
|
||||||
if (member.auth != null) {
|
|
||||||
val authDate = member.auth!!.createdAt!!
|
|
||||||
val chargeCount = chargeRepository.getChargeCountAfterDate(authDate)
|
|
||||||
|
|
||||||
if (chargeCount > 0) {
|
|
||||||
applyOtherEvent(charge, member)
|
|
||||||
} else {
|
|
||||||
applyFirstChargeEvent(charge, member)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
applyOtherEvent(charge, member)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyOtherEvent(charge: Charge, member: Member) {
|
|
||||||
val chargeEvent = repository.getChargeEvent()
|
|
||||||
|
|
||||||
if (chargeEvent != null) {
|
|
||||||
val eventChargeCount = chargeEventRepository.getPaymentCount(
|
|
||||||
member = member,
|
|
||||||
method = chargeEvent.title,
|
|
||||||
startDate = chargeEvent.startDate,
|
|
||||||
endDate = chargeEvent.endDate
|
|
||||||
)
|
|
||||||
|
|
||||||
if (eventChargeCount < chargeEvent.availableCount) {
|
|
||||||
val additionalCan = round(charge.chargeCan * chargeEvent.addPercent).toInt()
|
|
||||||
applyEvent(
|
|
||||||
additionalCan = additionalCan,
|
|
||||||
member = member,
|
|
||||||
paymentGateway = charge.payment?.paymentGateway!!,
|
|
||||||
method = chargeEvent.title
|
|
||||||
)
|
|
||||||
|
|
||||||
applicationEventPublisher.publishEvent(
|
|
||||||
FcmEvent(
|
|
||||||
type = FcmEventType.INDIVIDUAL,
|
|
||||||
title = chargeEvent.title,
|
|
||||||
message = "$additionalCan 캔이 추가 지급되었습니다.",
|
|
||||||
recipients = listOf(member.id!!),
|
|
||||||
isAuth = false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyFirstChargeEvent(charge: Charge, member: Member) {
|
|
||||||
val additionalCan = ceil(charge.chargeCan * 0.2).toInt()
|
|
||||||
applyEvent(
|
|
||||||
additionalCan = additionalCan,
|
|
||||||
member = member,
|
|
||||||
paymentGateway = charge.payment?.paymentGateway!!,
|
|
||||||
method = "첫 충전 이벤트"
|
|
||||||
)
|
|
||||||
|
|
||||||
applicationEventPublisher.publishEvent(
|
|
||||||
FcmEvent(
|
|
||||||
type = FcmEventType.INDIVIDUAL,
|
|
||||||
title = "첫 충전 이벤트",
|
|
||||||
message = "$additionalCan 캔이 추가 지급되었습니다.",
|
|
||||||
recipients = listOf(member.id!!),
|
|
||||||
isAuth = false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyEvent(additionalCan: Int, member: Member, paymentGateway: PaymentGateway, method: String) {
|
|
||||||
val eventCharge = Charge(0, additionalCan, status = ChargeStatus.EVENT)
|
|
||||||
eventCharge.title = "$additionalCan 캔"
|
|
||||||
eventCharge.member = member
|
|
||||||
|
|
||||||
val payment = Payment(
|
|
||||||
status = PaymentStatus.COMPLETE,
|
|
||||||
paymentGateway = paymentGateway
|
|
||||||
)
|
|
||||||
payment.method = method
|
|
||||||
eventCharge.payment = payment
|
|
||||||
chargeRepository.save(eventCharge)
|
|
||||||
|
|
||||||
when (paymentGateway) {
|
|
||||||
PaymentGateway.PG -> member.charge(0, additionalCan, "pg")
|
|
||||||
PaymentGateway.GOOGLE_IAP -> member.charge(0, additionalCan, "aos")
|
|
||||||
PaymentGateway.APPLE_IAP -> member.charge(0, additionalCan, "ios")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.can.charge.event
|
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
|
||||||
import org.springframework.context.event.EventListener
|
|
||||||
import org.springframework.scheduling.annotation.Async
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
class ChargeSpringEvent(
|
|
||||||
val chargeId: Long,
|
|
||||||
val member: Member
|
|
||||||
)
|
|
||||||
|
|
||||||
@Component
|
|
||||||
class ChargeSpringEventListener(
|
|
||||||
private val chargeEventService: ChargeEventService
|
|
||||||
) {
|
|
||||||
@Async
|
|
||||||
@EventListener
|
|
||||||
fun applyChargeEvent(event: ChargeSpringEvent) {
|
|
||||||
chargeEventService.applyChargeEvent(event.chargeId, event.member)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -265,17 +265,6 @@ class AudioContentService(
|
||||||
audioContent.content = content
|
audioContent.content = content
|
||||||
audioContent.duration = duration
|
audioContent.duration = duration
|
||||||
|
|
||||||
applicationEventPublisher.publishEvent(
|
|
||||||
FcmEvent(
|
|
||||||
type = FcmEventType.INDIVIDUAL,
|
|
||||||
title = "콘텐츠 등록완료",
|
|
||||||
message = audioContent.title,
|
|
||||||
recipients = listOf(audioContent.member!!.id!!),
|
|
||||||
isAuth = audioContent.isAdult,
|
|
||||||
contentId = contentId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
applicationEventPublisher.publishEvent(
|
applicationEventPublisher.publishEvent(
|
||||||
FcmEvent(
|
FcmEvent(
|
||||||
type = FcmEventType.UPLOAD_CONTENT,
|
type = FcmEventType.UPLOAD_CONTENT,
|
||||||
|
|
|
@ -187,7 +187,7 @@ class OrderQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : Orde
|
||||||
audioContent.title,
|
audioContent.title,
|
||||||
audioContent.isAdult,
|
audioContent.isAdult,
|
||||||
member.id,
|
member.id,
|
||||||
member.profileImage
|
member.profileImage.nullif("profile/default-profile.png")
|
||||||
.prepend("/")
|
.prepend("/")
|
||||||
.prepend(coverImageHost),
|
.prepend(coverImageHost),
|
||||||
member.nickname
|
member.nickname
|
||||||
|
|
|
@ -65,8 +65,7 @@ class FcmSendListener(
|
||||||
tokens = tokens,
|
tokens = tokens,
|
||||||
title = fcmEvent.title,
|
title = fcmEvent.title,
|
||||||
message = fcmEvent.message,
|
message = fcmEvent.message,
|
||||||
container = "ios",
|
container = "ios"
|
||||||
contentId = fcmEvent.contentId
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,8 +76,7 @@ class FcmSendListener(
|
||||||
tokens = tokens,
|
tokens = tokens,
|
||||||
title = fcmEvent.title,
|
title = fcmEvent.title,
|
||||||
message = fcmEvent.message,
|
message = fcmEvent.message,
|
||||||
container = "aos",
|
container = "aos"
|
||||||
contentId = fcmEvent.contentId
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue