From 84de4e0c5ab2f6a65b5c9023e069317ffc62cadf Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 15:27:26 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EB=A7=88=EC=BC=80=ED=8C=85=20-=20=EB=A7=A4?= =?UTF-8?q?=EC=B2=B4=20=ED=8C=8C=ED=8A=B8=EB=84=88=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=20-=20=EB=A7=88=EC=BC=80=ED=8C=85=20PID=20?= =?UTF-8?q?=EA=B0=80=20=EB=B3=80=EA=B2=BD=EB=90=A0=20=EB=95=8C=20LOGIN=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/marketing/AdTrackingHistory.kt | 5 +++- .../sodalive/member/MemberController.kt | 23 ++++++++++++++----- .../sodalive/member/MemberService.kt | 6 ++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/marketing/AdTrackingHistory.kt b/src/main/kotlin/kr/co/vividnext/sodalive/marketing/AdTrackingHistory.kt index 5a1eb2b..8578245 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/marketing/AdTrackingHistory.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/marketing/AdTrackingHistory.kt @@ -42,5 +42,8 @@ enum class AdTrackingHistoryType { FIRST_PAYMENT, // 재결제 - REPEAT_PAYMENT + REPEAT_PAYMENT, + + // 자동로그인 + LOGIN } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt index 54f1f8b..61000c0 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberController.kt @@ -135,13 +135,24 @@ class MemberController( ) = run { if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - ApiResponse.ok( - service.updateMarketingInfo( - memberId = member.id!!, - adid = request.adid, - pid = request.pid - ) + val memberId = member.id!! + val marketingPid = request.pid + + val changedMarketingPid = service.updateMarketingInfo( + memberId = memberId, + adid = request.adid, + pid = marketingPid ) + + if (changedMarketingPid) { + trackingService.saveTrackingHistory( + pid = marketingPid, + type = AdTrackingHistoryType.LOGIN, + memberId = memberId + ) + } + + ApiResponse.ok(Unit) } @PutMapping("/adid/update") diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt index e646fac..81af3f0 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt @@ -648,7 +648,7 @@ class MemberService( } @Transactional - fun updateMarketingInfo(memberId: Long, adid: String, pid: String) { + fun updateMarketingInfo(memberId: Long, adid: String, pid: String): Boolean { val member = repository.findByIdOrNull(id = memberId) ?: throw SodaException("로그인 정보를 확인해주세요.") @@ -659,6 +659,10 @@ class MemberService( if (pid != member.activePid && pid.isNotBlank()) { member.activePid = pid member.partnerExpirationDatetime = LocalDateTime.now().plusYears(1) + + return true } + + return false } } From 5b3c5731eec9ff8e041d9ae1d1e47946ad1ce3d6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 16:31:31 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EB=A7=88?= =?UTF-8?q?=EC=BC=80=ED=8C=85=20-=20=EA=B4=91=EA=B3=A0=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20-=20LOGIN=20=EA=B8=B0=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../marketing/statistics/AdminAdStatisticsRepository.kt | 7 +++++++ .../marketing/statistics/GetAdminAdStatisticsResponse.kt | 1 + 2 files changed, 8 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt index a15d326..98985c7 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt @@ -35,6 +35,12 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) { .otherwise(0) .sum() + val loginCount = CaseBuilder() + .`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.LOGIN)) + .then(1) + .otherwise(0) + .sum() + val firstPaymentCount = CaseBuilder() .`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)) .then(1) @@ -84,6 +90,7 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) { adTrackingHistory.mediaGroup, adTrackingHistory.id.pid, adTrackingHistory.pidName, + loginCount, signUpCount, firstPaymentCount, roundedValueDecimalPlaces2(firstPaymentTotalAmount), diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/GetAdminAdStatisticsResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/GetAdminAdStatisticsResponse.kt index 1a7adff..2e125d2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/GetAdminAdStatisticsResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/GetAdminAdStatisticsResponse.kt @@ -12,6 +12,7 @@ data class GetAdminAdStatisticsItem @QueryProjection constructor( val mediaGroup: String, val pid: String, val pidName: String, + val loginCount: Int, val signUpCount: Int, val firstPaymentCount: Int, val firstPaymentTotalAmount: Double, From 3e25accaa3d6340dc22ddb9f50d578f0fce26afc Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 16:38:58 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EB=A7=88?= =?UTF-8?q?=EC=BC=80=ED=8C=85=20-=20=EA=B4=91=EA=B3=A0=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20-=20=EB=82=A0=EC=A7=9C=EB=B3=84=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/AdminAdStatisticsController.kt | 9 ++++++++- .../statistics/AdminAdStatisticsRepository.kt | 11 ++++++++++- .../statistics/AdminAdStatisticsService.kt | 13 +++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsController.kt index 1848592..6249319 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsController.kt @@ -5,6 +5,7 @@ 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.RequestParam import org.springframework.web.bind.annotation.RestController @RestController @@ -12,8 +13,14 @@ import org.springframework.web.bind.annotation.RestController @RequestMapping("/admin/marketing/statistics") class AdminAdStatisticsController(private val service: AdminAdStatisticsService) { @GetMapping - fun getStatistics(pageable: Pageable) = ApiResponse.ok( + fun getStatistics( + @RequestParam startDateStr: String, + @RequestParam endDateStr: String, + pageable: Pageable + ) = ApiResponse.ok( service.getStatistics( + startDateStr = startDateStr, + endDateStr = endDateStr, offset = pageable.offset, limit = pageable.pageSize.toLong() ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt index 98985c7..cd7f46c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsRepository.kt @@ -28,7 +28,12 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) { ).toInt() } - fun getAdStatisticsDataList(offset: Long, limit: Long): List { + fun getAdStatisticsDataList( + startDate: LocalDateTime, + endDate: LocalDateTime, + offset: Long, + limit: Long + ): List { val signUpCount = CaseBuilder() .`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.SIGNUP)) .then(1) @@ -101,6 +106,10 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) { ) ) .from(adTrackingHistory) + .where( + adTrackingHistory.id.createdAt.goe(startDate), + adTrackingHistory.id.createdAt.loe(endDate) + ) .groupBy( getFormattedDate(adTrackingHistory.id.createdAt), adTrackingHistory.mediaGroup, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsService.kt index 6e1bb5c..262272d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/marketing/statistics/AdminAdStatisticsService.kt @@ -1,14 +1,23 @@ package kr.co.vividnext.sodalive.admin.marketing.statistics +import kr.co.vividnext.sodalive.extensions.convertLocalDateTime import org.springframework.stereotype.Service @Service class AdminAdStatisticsService( private val repository: AdminAdStatisticsRepository ) { - fun getStatistics(offset: Long, limit: Long): GetAdminAdStatisticsResponse { + fun getStatistics( + startDateStr: String, + endDateStr: String, + offset: Long, + limit: Long + ): GetAdminAdStatisticsResponse { + val startDate = startDateStr.convertLocalDateTime() + val endDate = endDateStr.convertLocalDateTime(hour = 23, minute = 59, second = 59) + val totalCount = repository.getAdStatisticsDataTotalCount() - val items = repository.getAdStatisticsDataList(offset, limit) + val items = repository.getAdStatisticsDataList(startDate, endDate, offset, limit) return GetAdminAdStatisticsResponse( totalCount = totalCount,