parent
0f68b297a0
commit
37516a0072
|
@ -0,0 +1,21 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.marketing.statistics
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
import org.springframework.data.domain.Pageable
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@RequestMapping("/admin/marketing/statistics")
|
||||||
|
class AdminAdStatisticsController(private val service: AdminAdStatisticsService) {
|
||||||
|
@GetMapping
|
||||||
|
fun getStatistics(pageable: Pageable) = ApiResponse.ok(
|
||||||
|
service.getStatistics(
|
||||||
|
offset = pageable.offset,
|
||||||
|
limit = pageable.pageSize.toLong()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.marketing.statistics
|
||||||
|
|
||||||
|
import com.querydsl.core.types.dsl.CaseBuilder
|
||||||
|
import com.querydsl.core.types.dsl.DateTimePath
|
||||||
|
import com.querydsl.core.types.dsl.Expressions
|
||||||
|
import com.querydsl.core.types.dsl.NumberExpression
|
||||||
|
import com.querydsl.core.types.dsl.StringTemplate
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
|
import kr.co.vividnext.sodalive.marketing.AdTrackingHistoryType
|
||||||
|
import kr.co.vividnext.sodalive.marketing.QAdTrackingHistory.adTrackingHistory
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) {
|
||||||
|
fun getAdStatisticsDataTotalCount(): Int {
|
||||||
|
return queryFactory
|
||||||
|
.select(adTrackingHistory.id.pid)
|
||||||
|
.from(adTrackingHistory)
|
||||||
|
.groupBy(
|
||||||
|
getFormattedDate(adTrackingHistory.id.createdAt),
|
||||||
|
adTrackingHistory.mediaGroup,
|
||||||
|
adTrackingHistory.id.pid,
|
||||||
|
adTrackingHistory.pidName
|
||||||
|
)
|
||||||
|
.fetch()
|
||||||
|
.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAdStatisticsDataList(offset: Long, limit: Long): List<GetAdminAdStatisticsItem> {
|
||||||
|
val signUpCount = CaseBuilder()
|
||||||
|
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.SIGNUP))
|
||||||
|
.then(1)
|
||||||
|
.otherwise(0)
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
val firstPaymentCount = CaseBuilder()
|
||||||
|
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT))
|
||||||
|
.then(1)
|
||||||
|
.otherwise(0)
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
val firstPaymentTotalAmount = CaseBuilder()
|
||||||
|
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT))
|
||||||
|
.then(adTrackingHistory.price)
|
||||||
|
.otherwise(Expressions.constant(0.0))
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
val repeatPaymentCount = CaseBuilder()
|
||||||
|
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
|
||||||
|
.then(1)
|
||||||
|
.otherwise(0)
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
val repeatPaymentTotalAmount = CaseBuilder()
|
||||||
|
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
|
||||||
|
.then(adTrackingHistory.price)
|
||||||
|
.otherwise(Expressions.constant(0.0))
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
val allPaymentCount = CaseBuilder()
|
||||||
|
.`when`(
|
||||||
|
adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)
|
||||||
|
.or(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
|
||||||
|
)
|
||||||
|
.then(1)
|
||||||
|
.otherwise(0)
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
val allPaymentTotalAmount = CaseBuilder()
|
||||||
|
.`when`(
|
||||||
|
adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)
|
||||||
|
.or(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
|
||||||
|
)
|
||||||
|
.then(adTrackingHistory.price)
|
||||||
|
.otherwise(Expressions.constant(0.0))
|
||||||
|
.sum()
|
||||||
|
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QGetAdminAdStatisticsItem(
|
||||||
|
getFormattedDate(adTrackingHistory.id.createdAt),
|
||||||
|
adTrackingHistory.mediaGroup,
|
||||||
|
adTrackingHistory.id.pid,
|
||||||
|
adTrackingHistory.pidName,
|
||||||
|
signUpCount,
|
||||||
|
firstPaymentCount,
|
||||||
|
roundedValueDecimalPlaces2(firstPaymentTotalAmount),
|
||||||
|
repeatPaymentCount,
|
||||||
|
roundedValueDecimalPlaces2(repeatPaymentTotalAmount),
|
||||||
|
allPaymentCount,
|
||||||
|
roundedValueDecimalPlaces2(allPaymentTotalAmount)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(adTrackingHistory)
|
||||||
|
.groupBy(
|
||||||
|
getFormattedDate(adTrackingHistory.id.createdAt),
|
||||||
|
adTrackingHistory.mediaGroup,
|
||||||
|
adTrackingHistory.id.pid,
|
||||||
|
adTrackingHistory.pidName
|
||||||
|
)
|
||||||
|
.offset(offset)
|
||||||
|
.limit(limit)
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFormattedDate(dateTimePath: DateTimePath<LocalDateTime>): StringTemplate {
|
||||||
|
return Expressions.stringTemplate(
|
||||||
|
"DATE_FORMAT({0}, {1})",
|
||||||
|
Expressions.dateTimeTemplate(
|
||||||
|
LocalDateTime::class.java,
|
||||||
|
"CONVERT_TZ({0},{1},{2})",
|
||||||
|
dateTimePath,
|
||||||
|
"UTC",
|
||||||
|
"Asia/Seoul"
|
||||||
|
),
|
||||||
|
"%Y-%m-%d"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun roundedValueDecimalPlaces2(valueExpression: NumberExpression<Double>): NumberExpression<Double> {
|
||||||
|
return Expressions.numberTemplate(
|
||||||
|
Double::class.java,
|
||||||
|
"ROUND({0}, {1})",
|
||||||
|
valueExpression,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.marketing.statistics
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class AdminAdStatisticsService(
|
||||||
|
private val repository: AdminAdStatisticsRepository
|
||||||
|
) {
|
||||||
|
fun getStatistics(offset: Long, limit: Long): GetAdminAdStatisticsResponse {
|
||||||
|
val totalCount = repository.getAdStatisticsDataTotalCount()
|
||||||
|
val items = repository.getAdStatisticsDataList(offset, limit)
|
||||||
|
|
||||||
|
return GetAdminAdStatisticsResponse(
|
||||||
|
totalCount = totalCount,
|
||||||
|
items = items
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.marketing.statistics
|
||||||
|
|
||||||
|
import com.querydsl.core.annotations.QueryProjection
|
||||||
|
|
||||||
|
data class GetAdminAdStatisticsResponse(
|
||||||
|
val totalCount: Int,
|
||||||
|
val items: List<GetAdminAdStatisticsItem>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class GetAdminAdStatisticsItem @QueryProjection constructor(
|
||||||
|
val date: String,
|
||||||
|
val mediaGroup: String,
|
||||||
|
val pid: String,
|
||||||
|
val pidName: String,
|
||||||
|
val signUpCount: Int,
|
||||||
|
val firstPaymentCount: Int,
|
||||||
|
val firstPaymentTotalAmount: Double,
|
||||||
|
val repeatPaymentCount: Int,
|
||||||
|
val repeatPaymentTotalAmount: Double,
|
||||||
|
val allPaymentCount: Int,
|
||||||
|
val allPaymentTotalAmount: Double
|
||||||
|
)
|
Loading…
Reference in New Issue