From 17c5bade83f005be1b63ef347810e34811962929 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 26 Mar 2024 15:04:03 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20-=20=ED=95=9C=EC=A0=95=ED=8C=90=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EC=9D=84=20=EC=9C=84=ED=95=B4=20=EA=B0=9C=EC=88=98=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt | 2 ++ .../kr/co/vividnext/sodalive/content/AudioContentService.kt | 2 ++ .../co/vividnext/sodalive/content/CreateAudioContentRequest.kt | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt index 44acb16..8536827 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContent.kt @@ -34,6 +34,8 @@ data class AudioContent( var detail: String, val price: Int = 0, var releaseDate: LocalDateTime? = null, + val limited: Int? = null, + var remaining: Int? = null, @Enumerated(value = EnumType.STRING) val type: AudioContentType = AudioContentType.INDIVIDUAL, val isGeneratePreview: Boolean = true, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index de0e173..f62c88a 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -183,6 +183,8 @@ class AudioContentService( 0 }, releaseDate = releaseDate, + limited = request.limited, + remaining = request.limited, isAdult = request.isAdult, isGeneratePreview = if (request.type == AudioContentType.INDIVIDUAL) { request.isGeneratePreview diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt index 2ebb4b5..23ae26e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt @@ -5,6 +5,8 @@ data class CreateAudioContentRequest( val detail: String, val tags: String, val price: Int, + val limited: Int? = null, + val remaining: Int? = null, val timezone: String = "Asia/Seoul", val releaseDate: String? = null, val themeId: Long = 0, -- 2.40.1 From 2d1f33309575aff9e360229e84e17336223d46cb Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 26 Mar 2024 17:44:26 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=ED=95=9C=EC=A0=95=ED=8C=90=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=A3=BC=EB=AC=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/AudioContentService.kt | 2 +- .../content/order/LimitedEditionOrder.kt | 22 ++++++++ .../order/LimitedEditionOrderRepository.kt | 30 +++++++++++ .../sodalive/content/order/OrderService.kt | 54 ++++++++++++++----- 4 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrder.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index f62c88a..9a0ff30 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -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 diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrder.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrder.kt new file mode 100644 index 0000000..766f82c --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrder.kt @@ -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 +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt new file mode 100644 index 0000000..7e7c576 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt @@ -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, 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 + } + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/order/OrderService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/OrderService.kt index 0ca2b85..06cba52 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/order/OrderService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/OrderService.kt @@ -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, -- 2.40.1 From 327f7ad341cbd09bd838a90a206a46cc9e49ae74 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 26 Mar 2024 20:04:20 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20-=20=ED=95=9C=EC=A0=95=ED=8C=90=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/content/AudioContentService.kt | 23 +++++++++++++++---- .../content/GetAudioContentDetailResponse.kt | 3 +++ .../order/LimitedEditionOrderRepository.kt | 19 +++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index 9a0ff30..86f5a31 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -14,6 +14,7 @@ import kr.co.vividnext.sodalive.content.like.AudioContentLikeRepository import kr.co.vividnext.sodalive.content.like.PutAudioContentLikeRequest import kr.co.vividnext.sodalive.content.like.PutAudioContentLikeResponse import kr.co.vividnext.sodalive.content.main.GetAudioContentRanking +import kr.co.vividnext.sodalive.content.order.LimitedEditionOrderRepository import kr.co.vividnext.sodalive.content.order.OrderRepository import kr.co.vividnext.sodalive.content.order.OrderType import kr.co.vividnext.sodalive.content.pin.PinContent @@ -47,6 +48,7 @@ class AudioContentService( private val blockMemberRepository: BlockMemberRepository, private val hashTagRepository: HashTagRepository, private val orderRepository: OrderRepository, + private val limitedEditionOrderRepository: LimitedEditionOrderRepository, private val themeQueryRepository: AudioContentThemeQueryRepository, private val playbackTrackingRepository: PlaybackTrackingRepository, private val commentRepository: AudioContentCommentRepository, @@ -465,11 +467,21 @@ class AudioContentService( contentId = audioContent.id!! ) + val existOrdered = isExistsBundleAudioContent || isExistsAudioContent + val orderSequence = if (existOrdered) { + limitedEditionOrderRepository.getOrderSequence( + contentId = audioContent.id!!, + memberId = member.id!! + ) + } else { + null + } + if ( - !isExistsAudioContent && - !isExistsBundleAudioContent && + !existOrdered && !audioContent.isActive && - audioContent.releaseDate == null + audioContent.releaseDate != null && + audioContent.releaseDate!! < LocalDateTime.now() ) { throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.") } @@ -593,11 +605,14 @@ class AudioContentService( price = audioContent.price, duration = audioContent.duration ?: "", releaseDate = releaseDate, + totalContentCount = audioContent.limited, + remainingContentCount = audioContent.remaining, + orderSequence = orderSequence, isActivePreview = audioContent.isGeneratePreview, isAdult = audioContent.isAdult, isMosaic = audioContent.isAdult && member.auth == null, isOnlyRental = audioContent.isOnlyRental, - existOrdered = isExistsBundleAudioContent || isExistsAudioContent, + existOrdered = existOrdered, orderType = orderType, remainingTime = remainingTime, creatorOtherContentList = creatorOtherContentList, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/GetAudioContentDetailResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/GetAudioContentDetailResponse.kt index 0049565..77e5ea7 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/GetAudioContentDetailResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/GetAudioContentDetailResponse.kt @@ -15,6 +15,9 @@ data class GetAudioContentDetailResponse( val price: Int, val duration: String, val releaseDate: String?, + val totalContentCount: Int?, + val remainingContentCount: Int?, + val orderSequence: Int?, val isActivePreview: Boolean, val isAdult: Boolean, val isMosaic: Boolean, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt index 7e7c576..a97cf49 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/order/LimitedEditionOrderRepository.kt @@ -1,13 +1,18 @@ package kr.co.vividnext.sodalive.content.order import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.order.QLimitedEditionOrder.limitedEditionOrder +import kr.co.vividnext.sodalive.content.order.QOrder.order +import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.data.jpa.repository.JpaRepository interface LimitedEditionOrderRepository : JpaRepository, LimitedEditionOrderQueryRepository interface LimitedEditionOrderQueryRepository { fun getNextSequence(contentId: Long): Int + + fun getOrderSequence(contentId: Long, memberId: Long): Int? } class LimitedEditionOrderQueryRepositoryImpl( @@ -16,6 +21,7 @@ class LimitedEditionOrderQueryRepositoryImpl( override fun getNextSequence(contentId: Long): Int { val maxSequence = queryFactory.select(limitedEditionOrder.sequence) .from(limitedEditionOrder) + .innerJoin(limitedEditionOrder.audioContent, audioContent) .where(limitedEditionOrder.audioContent.id.eq(contentId)) .orderBy(limitedEditionOrder.sequence.desc()) .limit(1) @@ -27,4 +33,17 @@ class LimitedEditionOrderQueryRepositoryImpl( maxSequence + 1 } } + + override fun getOrderSequence(contentId: Long, memberId: Long): Int? { + return queryFactory.select(limitedEditionOrder.sequence) + .from(limitedEditionOrder) + .innerJoin(limitedEditionOrder.audioContent, audioContent) + .innerJoin(limitedEditionOrder.order, order) + .innerJoin(order.member, member) + .where( + limitedEditionOrder.audioContent.id.eq(contentId) + .and(limitedEditionOrder.order.member.id.eq(memberId)) + ) + .fetchFirst() + } } -- 2.40.1 From b929b51525205071fec33bd513ea24da6550e930 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 27 Mar 2024 18:17:56 +0900 Subject: [PATCH 4/5] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20-=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/vividnext/sodalive/content/CreateAudioContentRequest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt index 23ae26e..7a155c1 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/CreateAudioContentRequest.kt @@ -6,7 +6,6 @@ data class CreateAudioContentRequest( val tags: String, val price: Int, val limited: Int? = null, - val remaining: Int? = null, val timezone: String = "Asia/Seoul", val releaseDate: String? = null, val themeId: Long = 0, -- 2.40.1 From 6b7b3efcb17645ef4aa825a79e82b81d41365adb Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 27 Mar 2024 19:29:58 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90,=20=ED=81=AC?= =?UTF-8?q?=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20-=20=ED=95=9C=EC=A0=95=ED=8C=90=20=EC=B4=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=88=98=20=EB=B0=8F=20=EB=82=A8=EC=9D=80=20=EA=B0=9C?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vividnext/sodalive/admin/content/AdminContentRepository.kt | 2 ++ .../sodalive/admin/content/GetAdminContentListResponse.kt | 2 ++ .../creator/admin/content/CreatorAdminContentRepository.kt | 2 ++ .../creator/admin/content/GetCreatorAdminContentListResponse.kt | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentRepository.kt index 4164c93..a62b247 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentRepository.kt @@ -82,6 +82,8 @@ class AdminAudioContentQueryRepositoryImpl( audioContentTheme.theme, audioContentTheme.id, audioContent.price, + audioContent.limited, + audioContent.remaining, audioContent.isAdult, audioContent.duration, audioContent.content, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/GetAdminContentListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/GetAdminContentListResponse.kt index 40f974a..1fe1ba7 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/GetAdminContentListResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/GetAdminContentListResponse.kt @@ -18,6 +18,8 @@ data class GetAdminContentListItem @QueryProjection constructor( val theme: String, val themeId: Long, val price: Int, + val totalContentCount: Int?, + val remainingContentCount: Int?, val isAdult: Boolean, val remainingTime: String, var contentUrl: String, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/CreatorAdminContentRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/CreatorAdminContentRepository.kt index e856992..4a0a3da 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/CreatorAdminContentRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/CreatorAdminContentRepository.kt @@ -81,6 +81,8 @@ class CreatorAdminAudioContentQueryRepositoryImpl( audioContent.member!!.nickname, audioContentTheme.theme, audioContent.price, + audioContent.limited, + audioContent.remaining, audioContent.isAdult, audioContent.isCommentAvailable, audioContent.duration, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/GetCreatorAdminContentListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/GetCreatorAdminContentListResponse.kt index 5467fd3..5176950 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/GetCreatorAdminContentListResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/content/GetCreatorAdminContentListResponse.kt @@ -15,6 +15,8 @@ data class GetCreatorAdminContentListItem @QueryProjection constructor( val creatorNickname: String, val theme: String, val price: Int, + val totalContentCount: Int?, + val remainingContentCount: Int?, val isAdult: Boolean, val isCommentAvailable: Boolean, val remainingTime: String, -- 2.40.1