관리자 광고통계

- 날짜 내림차순으로 정렬
This commit is contained in:
Klaus 2025-03-17 14:31:42 +09:00
parent 81fa445964
commit 353807404a
2 changed files with 32 additions and 24 deletions

View File

@ -82,6 +82,7 @@ class AdminMemberStatisticsRepository(private val queryFactory: JPAQueryFactory)
.groupBy(getFormattedDate(member.createdAt)) .groupBy(getFormattedDate(member.createdAt))
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
.orderBy(member.createdAt.desc())
.fetch() .fetch()
} }
@ -106,6 +107,7 @@ class AdminMemberStatisticsRepository(private val queryFactory: JPAQueryFactory)
.groupBy(getFormattedDate(signOut.createdAt)) .groupBy(getFormattedDate(signOut.createdAt))
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
.orderBy(signOut.createdAt.desc())
.fetch() .fetch()
} }
@ -134,6 +136,7 @@ class AdminMemberStatisticsRepository(private val queryFactory: JPAQueryFactory)
.groupBy(getFormattedDate(charge.createdAt)) .groupBy(getFormattedDate(charge.createdAt))
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
.orderBy(charge.createdAt.desc())
.fetch() .fetch()
} }

View File

@ -4,6 +4,7 @@ import kr.co.vividnext.sodalive.common.SodaException
import org.springframework.data.domain.Pageable import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime import java.time.LocalTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -16,9 +17,16 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics
endDateStr: String, endDateStr: String,
pageable: Pageable pageable: Pageable
): GetMemberStatisticsResponse { ): 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( val dateRange = getPagedDateRange(
startDate = startDateStr, startDate = startDate,
endDate = endDateStr, endDate = endDate.coerceAtMost(now),
page = pageable.pageNumber + 1, page = pageable.pageNumber + 1,
pageSize = pageable.pageSize pageSize = pageable.pageSize
) )
@ -27,47 +35,47 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics
throw SodaException("잘못된 접근입니다.") throw SodaException("잘못된 접근입니다.")
} }
var startDate = LocalDate.parse(startDateStr).atStartOfDay() var startDateTime = startDate.atStartOfDay()
.atZone(ZoneId.of("Asia/Seoul")) .atZone(ZoneId.of("Asia/Seoul"))
.withZoneSameInstant(ZoneId.of("UTC")) .withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime() .toLocalDateTime()
var endDate = LocalDate.parse(endDateStr).atTime(LocalTime.MAX) var endDateTime = endDate.atTime(LocalTime.MAX)
.atZone(ZoneId.of("Asia/Seoul")) .atZone(ZoneId.of("Asia/Seoul"))
.withZoneSameInstant(ZoneId.of("UTC")) .withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime() .toLocalDateTime()
val totalSignUpCount = repository.getTotalSignUpCount(startDate = startDate, endDate = endDate) val totalSignUpCount = repository.getTotalSignUpCount(startDate = startDateTime, endDate = endDateTime)
val totalSignOutCount = repository.getTotalSignOutCount(startDate = startDate, endDate = endDate) val totalSignOutCount = repository.getTotalSignOutCount(startDate = startDateTime, endDate = endDateTime)
val totalPaymentMemberCount = repository.getPaymentMemberCount(startDate = startDate, endDate = endDate) val totalPaymentMemberCount = repository.getPaymentMemberCount(startDate = startDateTime, endDate = endDateTime)
startDate = dateRange.startDate startDateTime = dateRange.startDate
.atZone(ZoneId.of("Asia/Seoul")) .atZone(ZoneId.of("Asia/Seoul"))
.withZoneSameInstant(ZoneId.of("UTC")) .withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime() .toLocalDateTime()
endDate = dateRange.endDate endDateTime = dateRange.endDate
.atZone(ZoneId.of("Asia/Seoul")) .atZone(ZoneId.of("Asia/Seoul"))
.withZoneSameInstant(ZoneId.of("UTC")) .withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime() .toLocalDateTime()
val signUpCountInRange = repository.getSignUpCountInRange( val signUpCountInRange = repository.getSignUpCountInRange(
startDate = startDate, startDate = startDateTime,
endDate = endDate, endDate = endDateTime,
offset = pageable.offset, offset = pageable.offset,
limit = pageable.pageSize.toLong() limit = pageable.pageSize.toLong()
).associateBy({ it.date }, { it.memberCount }) ).associateBy({ it.date }, { it.memberCount })
val signOutCountInRange = repository.getSignOutCountInRange( val signOutCountInRange = repository.getSignOutCountInRange(
startDate = startDate, startDate = startDateTime,
endDate = endDate, endDate = endDateTime,
offset = pageable.offset, offset = pageable.offset,
limit = pageable.pageSize.toLong() limit = pageable.pageSize.toLong()
).associateBy({ it.date }, { it.memberCount }) ).associateBy({ it.date }, { it.memberCount })
val paymentMemberCountInRange = repository.getPaymentMemberCountInRange( val paymentMemberCountInRange = repository.getPaymentMemberCountInRange(
startDate = startDate, startDate = startDateTime,
endDate = endDate, endDate = endDateTime,
offset = pageable.offset, offset = pageable.offset,
limit = pageable.pageSize.toLong() limit = pageable.pageSize.toLong()
) )
@ -75,8 +83,8 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics
val paymentMemberCountInRangeMap = paymentMemberCountInRange.associateBy({ it.date }, { it.memberCount }) val paymentMemberCountInRangeMap = paymentMemberCountInRange.associateBy({ it.date }, { it.memberCount })
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val items = generateSequence(dateRange.startDate) { it.plusDays(1) } val items = generateSequence(dateRange.endDate) { it.minusDays(1) }
.takeWhile { !it.isAfter(dateRange.endDate) } .takeWhile { !it.isBefore(dateRange.startDate) }
.map { .map {
val date = it.format(formatter) val date = it.format(formatter)
GetMemberStatisticsItem( GetMemberStatisticsItem(
@ -97,17 +105,14 @@ class AdminMemberStatisticsService(private val repository: AdminMemberStatistics
) )
} }
private fun getPagedDateRange(startDate: String, endDate: String, page: Int, pageSize: Int): PagedDateRange? { private fun getPagedDateRange(startDate: LocalDate, endDate: LocalDate, page: Int, pageSize: Int): PagedDateRange? {
val start = LocalDate.parse(startDate) val totalDays = ChronoUnit.DAYS.between(startDate, endDate).toInt() + 1
val end = LocalDate.parse(endDate)
val totalDays = ChronoUnit.DAYS.between(start, end).toInt() + 1
val totalPages = (totalDays + pageSize - 1) / pageSize // 전체 페이지 개수 계산 val totalPages = (totalDays + pageSize - 1) / pageSize // 전체 페이지 개수 계산
if (page < 1 || page > totalPages) return null // 페이지 범위를 벗어나면 null 반환 if (page < 1 || page > totalPages) return null // 페이지 범위를 벗어나면 null 반환
val rangeStart = start.plusDays((page - 1) * pageSize.toLong()).atStartOfDay() val rangeEnd = endDate.minusDays((page - 1) * pageSize.toLong()).atTime(LocalTime.MAX)
val rangeEnd = start.plusDays((page * pageSize - 1).toLong()).coerceAtMost(end).atTime(LocalTime.MAX) val rangeStart = endDate.minusDays((page * pageSize - 1).toLong()).coerceAtLeast(startDate).atStartOfDay()
return PagedDateRange(rangeStart, rangeEnd, totalDays) return PagedDateRange(rangeStart, rangeEnd, totalDays)
} }