From b9063fb22f9457146b30117e4c814f60b1df6cce Mon Sep 17 00:00:00 2001
From: Klaus <klaus@vividnext.co.kr>
Date: Fri, 14 Mar 2025 02:44:34 +0900
Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20-=20=EC=B6=A9?=
 =?UTF-8?q?=EC=A0=84=EC=9D=B4=EB=B2=A4=ED=8A=B8=20-=20=EC=8B=9C=EA=B0=84?=
 =?UTF-8?q?=20=EA=B3=84=EC=82=B0=EC=9D=84=20Querydsl=20=EC=BD=94=EB=93=9C?=
 =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=88=98=ED=96=89=20-=20=EB=93=B1?=
 =?UTF-8?q?=EB=A1=9D/=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EC=9D=B4=EB=B2=A4?=
 =?UTF-8?q?=ED=8A=B8=20=EC=A7=84=ED=96=89=EA=B8=B0=EA=B0=84=EC=97=90=20?=
 =?UTF-8?q?=EC=8B=9C=EA=B0=84=EB=8F=84=20=ED=8F=AC=ED=95=A8=ED=95=98?=
 =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../charge/AdminChargeEventRepository.kt      | 35 ++++++++++++++++--
 .../event/charge/AdminChargeEventService.kt   | 36 ++++---------------
 .../charge/GetChargeEventListResponse.kt      |  4 ++-
 3 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventRepository.kt
index d8dfa4e..a78f36c 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventRepository.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventRepository.kt
@@ -1,22 +1,51 @@
 package kr.co.vividnext.sodalive.admin.event.charge
 
+import com.querydsl.core.types.dsl.DateTimePath
+import com.querydsl.core.types.dsl.Expressions
+import com.querydsl.core.types.dsl.StringTemplate
 import com.querydsl.jpa.impl.JPAQueryFactory
 import kr.co.vividnext.sodalive.admin.event.charge.QChargeEvent.chargeEvent
 import org.springframework.data.jpa.repository.JpaRepository
 import org.springframework.stereotype.Repository
+import java.time.LocalDateTime
 
 @Repository
 interface AdminChargeEventRepository : JpaRepository<ChargeEvent, Long>, AdminChargeEventQueryRepository
 
 interface AdminChargeEventQueryRepository {
-    fun getChargeEventList(): List<ChargeEvent>
+    fun getChargeEventList(): List<GetChargeEventListResponse>
 }
 
 class AdminChargeEventQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : AdminChargeEventQueryRepository {
-    override fun getChargeEventList(): List<ChargeEvent> {
+    override fun getChargeEventList(): List<GetChargeEventListResponse> {
         return queryFactory
-            .selectFrom(chargeEvent)
+            .select(
+                QGetChargeEventListResponse(
+                    chargeEvent.id,
+                    chargeEvent.title,
+                    getFormattedDate(chargeEvent.startDate),
+                    getFormattedDate(chargeEvent.endDate),
+                    chargeEvent.availableCount,
+                    chargeEvent.addPercent.multiply(100).castToNum(Int::class.java),
+                    chargeEvent.isActive
+                )
+            )
+            .from(chargeEvent)
             .orderBy(chargeEvent.createdAt.desc())
             .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 %H:%i"
+        )
+    }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventService.kt
index 27aad89..c36d54e 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/AdminChargeEventService.kt
@@ -4,7 +4,7 @@ import kr.co.vividnext.sodalive.common.SodaException
 import org.springframework.data.repository.findByIdOrNull
 import org.springframework.stereotype.Service
 import org.springframework.transaction.annotation.Transactional
-import java.time.LocalDate
+import java.time.LocalDateTime
 import java.time.ZoneId
 import java.time.format.DateTimeFormatter
 
@@ -13,13 +13,13 @@ import java.time.format.DateTimeFormatter
 class AdminChargeEventService(private val repository: AdminChargeEventRepository) {
     @Transactional
     fun createChargeEvent(request: CreateChargeEventRequest): Long {
-        val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
-        val startDate = LocalDate.parse(request.startDateString, dateTimeFormatter).atTime(0, 0)
+        val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
+        val startDate = LocalDateTime.parse(request.startDateString, dateTimeFormatter)
             .atZone(ZoneId.of("Asia/Seoul"))
             .withZoneSameInstant(ZoneId.of("UTC"))
             .toLocalDateTime()
 
-        val endDate = LocalDate.parse(request.endDateString, dateTimeFormatter).atTime(23, 59, 59)
+        val endDate = LocalDateTime.parse(request.endDateString, dateTimeFormatter).withSecond(59)
             .atZone(ZoneId.of("Asia/Seoul"))
             .withZoneSameInstant(ZoneId.of("UTC"))
             .toLocalDateTime()
@@ -44,16 +44,16 @@ class AdminChargeEventService(private val repository: AdminChargeEventRepository
             chargeEvent.title = request.title
         }
 
-        val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
+        val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
         if (request.startDateString != null) {
-            chargeEvent.startDate = LocalDate.parse(request.startDateString, dateTimeFormatter).atTime(0, 0)
+            chargeEvent.startDate = LocalDateTime.parse(request.startDateString, dateTimeFormatter)
                 .atZone(ZoneId.of("Asia/Seoul"))
                 .withZoneSameInstant(ZoneId.of("UTC"))
                 .toLocalDateTime()
         }
 
         if (request.endDateString != null) {
-            chargeEvent.endDate = LocalDate.parse(request.endDateString, dateTimeFormatter).atTime(23, 59, 59)
+            chargeEvent.endDate = LocalDateTime.parse(request.endDateString, dateTimeFormatter).withSecond(59)
                 .atZone(ZoneId.of("Asia/Seoul"))
                 .withZoneSameInstant(ZoneId.of("UTC"))
                 .toLocalDateTime()
@@ -74,27 +74,5 @@ class AdminChargeEventService(private val repository: AdminChargeEventRepository
 
     fun getChargeEventList(): List<GetChargeEventListResponse> {
         return repository.getChargeEventList()
-            .map {
-                val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
-                val startDate = it.startDate
-                    .atZone(ZoneId.of("UTC"))
-                    .withZoneSameInstant(ZoneId.of("Asia/Seoul"))
-                    .format(dateTimeFormatter)
-
-                val endDate = it.endDate
-                    .atZone(ZoneId.of("UTC"))
-                    .withZoneSameInstant(ZoneId.of("Asia/Seoul"))
-                    .format(dateTimeFormatter)
-
-                GetChargeEventListResponse(
-                    id = it.id!!,
-                    title = it.title,
-                    startDate = startDate,
-                    endDate = endDate,
-                    availableCount = it.availableCount,
-                    addPercent = (it.addPercent * 100).toInt(),
-                    isActive = it.isActive
-                )
-            }
     }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/GetChargeEventListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/GetChargeEventListResponse.kt
index ee6ae16..a751445 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/GetChargeEventListResponse.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/charge/GetChargeEventListResponse.kt
@@ -1,6 +1,8 @@
 package kr.co.vividnext.sodalive.admin.event.charge
 
-data class GetChargeEventListResponse(
+import com.querydsl.core.annotations.QueryProjection
+
+data class GetChargeEventListResponse @QueryProjection constructor(
     val id: Long,
     val title: String,
     val startDate: String,