From 353807404a014bae86187704ba61d65f8391c3be Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 17 Mar 2025 14:31:42 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EA=B4=91?= =?UTF-8?q?=EA=B3=A0=ED=86=B5=EA=B3=84=20-=20=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=EB=82=B4=EB=A6=BC=EC=B0=A8=EC=88=9C=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/AdminMemberStatisticsRepository.kt | 3 ++ .../member/AdminMemberStatisticsService.kt | 53 ++++++++++--------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsRepository.kt index 25c69fc..4dff07c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsRepository.kt @@ -82,6 +82,7 @@ class AdminMemberStatisticsRepository(private val queryFactory: JPAQueryFactory) .groupBy(getFormattedDate(member.createdAt)) .offset(offset) .limit(limit) + .orderBy(member.createdAt.desc()) .fetch() } @@ -106,6 +107,7 @@ class AdminMemberStatisticsRepository(private val queryFactory: JPAQueryFactory) .groupBy(getFormattedDate(signOut.createdAt)) .offset(offset) .limit(limit) + .orderBy(signOut.createdAt.desc()) .fetch() } @@ -134,6 +136,7 @@ class AdminMemberStatisticsRepository(private val queryFactory: JPAQueryFactory) .groupBy(getFormattedDate(charge.createdAt)) .offset(offset) .limit(limit) + .orderBy(charge.createdAt.desc()) .fetch() } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsService.kt index 754a013..2024110 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/statistics/member/AdminMemberStatisticsService.kt @@ -4,6 +4,7 @@ import kr.co.vividnext.sodalive.common.SodaException import org.springframework.data.domain.Pageable import org.springframework.stereotype.Service import java.time.LocalDate +import java.time.LocalDateTime import java.time.LocalTime import java.time.ZoneId import java.time.format.DateTimeFormatter @@ -16,9 +17,16 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics endDateStr: String, pageable: Pageable ): GetMemberStatisticsResponse { + val startDate = LocalDate.parse(startDateStr) + val endDate = LocalDate.parse(endDateStr) + val now = LocalDateTime.now() + .atZone(ZoneId.of("UTC")) + .withZoneSameInstant(ZoneId.of("Asia/Seoul")) + .toLocalDate() + val dateRange = getPagedDateRange( - startDate = startDateStr, - endDate = endDateStr, + startDate = startDate, + endDate = endDate.coerceAtMost(now), page = pageable.pageNumber + 1, pageSize = pageable.pageSize ) @@ -27,47 +35,47 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics throw SodaException("잘못된 접근입니다.") } - var startDate = LocalDate.parse(startDateStr).atStartOfDay() + var startDateTime = startDate.atStartOfDay() .atZone(ZoneId.of("Asia/Seoul")) .withZoneSameInstant(ZoneId.of("UTC")) .toLocalDateTime() - var endDate = LocalDate.parse(endDateStr).atTime(LocalTime.MAX) + var endDateTime = endDate.atTime(LocalTime.MAX) .atZone(ZoneId.of("Asia/Seoul")) .withZoneSameInstant(ZoneId.of("UTC")) .toLocalDateTime() - val totalSignUpCount = repository.getTotalSignUpCount(startDate = startDate, endDate = endDate) - val totalSignOutCount = repository.getTotalSignOutCount(startDate = startDate, endDate = endDate) - val totalPaymentMemberCount = repository.getPaymentMemberCount(startDate = startDate, endDate = endDate) + val totalSignUpCount = repository.getTotalSignUpCount(startDate = startDateTime, endDate = endDateTime) + val totalSignOutCount = repository.getTotalSignOutCount(startDate = startDateTime, endDate = endDateTime) + val totalPaymentMemberCount = repository.getPaymentMemberCount(startDate = startDateTime, endDate = endDateTime) - startDate = dateRange.startDate + startDateTime = dateRange.startDate .atZone(ZoneId.of("Asia/Seoul")) .withZoneSameInstant(ZoneId.of("UTC")) .toLocalDateTime() - endDate = dateRange.endDate + endDateTime = dateRange.endDate .atZone(ZoneId.of("Asia/Seoul")) .withZoneSameInstant(ZoneId.of("UTC")) .toLocalDateTime() val signUpCountInRange = repository.getSignUpCountInRange( - startDate = startDate, - endDate = endDate, + startDate = startDateTime, + endDate = endDateTime, offset = pageable.offset, limit = pageable.pageSize.toLong() ).associateBy({ it.date }, { it.memberCount }) val signOutCountInRange = repository.getSignOutCountInRange( - startDate = startDate, - endDate = endDate, + startDate = startDateTime, + endDate = endDateTime, offset = pageable.offset, limit = pageable.pageSize.toLong() ).associateBy({ it.date }, { it.memberCount }) val paymentMemberCountInRange = repository.getPaymentMemberCountInRange( - startDate = startDate, - endDate = endDate, + startDate = startDateTime, + endDate = endDateTime, offset = pageable.offset, limit = pageable.pageSize.toLong() ) @@ -75,8 +83,8 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics val paymentMemberCountInRangeMap = paymentMemberCountInRange.associateBy({ it.date }, { it.memberCount }) val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") - val items = generateSequence(dateRange.startDate) { it.plusDays(1) } - .takeWhile { !it.isAfter(dateRange.endDate) } + val items = generateSequence(dateRange.endDate) { it.minusDays(1) } + .takeWhile { !it.isBefore(dateRange.startDate) } .map { val date = it.format(formatter) GetMemberStatisticsItem( @@ -97,17 +105,14 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics ) } - private fun getPagedDateRange(startDate: String, endDate: String, page: Int, pageSize: Int): PagedDateRange? { - val start = LocalDate.parse(startDate) - val end = LocalDate.parse(endDate) - - val totalDays = ChronoUnit.DAYS.between(start, end).toInt() + 1 + private fun getPagedDateRange(startDate: LocalDate, endDate: LocalDate, page: Int, pageSize: Int): PagedDateRange? { + val totalDays = ChronoUnit.DAYS.between(startDate, endDate).toInt() + 1 val totalPages = (totalDays + pageSize - 1) / pageSize // 전체 페이지 개수 계산 if (page < 1 || page > totalPages) return null // 페이지 범위를 벗어나면 null 반환 - val rangeStart = start.plusDays((page - 1) * pageSize.toLong()).atStartOfDay() - val rangeEnd = start.plusDays((page * pageSize - 1).toLong()).coerceAtMost(end).atTime(LocalTime.MAX) + val rangeEnd = endDate.minusDays((page - 1) * pageSize.toLong()).atTime(LocalTime.MAX) + val rangeStart = endDate.minusDays((page * pageSize - 1).toLong()).coerceAtLeast(startDate).atStartOfDay() return PagedDateRange(rangeStart, rangeEnd, totalDays) }