diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventController.kt new file mode 100644 index 0000000..0502923 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventController.kt @@ -0,0 +1,32 @@ +package kr.co.vividnext.sodalive.admin.event + +import kr.co.vividnext.sodalive.common.ApiResponse +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/event/charge") +class AdminChargeEventController(private val service: AdminChargeEventService) { + @PostMapping + @PreAuthorize("hasRole('ADMIN')") + fun createChargeEvent(@RequestBody request: CreateChargeEventRequest): ApiResponse { + service.createChargeEvent(request) + return ApiResponse.ok(null, "등록되었습니다.") + } + + @PutMapping + @PreAuthorize("hasRole('ADMIN')") + fun modifyChargeEvent(@RequestBody request: ModifyChargeEventRequest) = ApiResponse.ok( + service.modifyChargeEvent(request), + "수정되었습니다." + ) + + @GetMapping("/list") + @PreAuthorize("hasRole('ADMIN')") + fun getChargeEventList() = ApiResponse.ok(service.getChargeEventList()) +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventRepository.kt new file mode 100644 index 0000000..4cd02e4 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventRepository.kt @@ -0,0 +1,22 @@ +package kr.co.vividnext.sodalive.admin.event + +import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.admin.event.QChargeEvent.chargeEvent +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface AdminChargeEventRepository : JpaRepository, AdminChargeEventQueryRepository + +interface AdminChargeEventQueryRepository { + fun getChargeEventList(): List +} + +class AdminChargeEventQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : AdminChargeEventQueryRepository { + override fun getChargeEventList(): List { + return queryFactory + .selectFrom(chargeEvent) + .orderBy(chargeEvent.createdAt.desc()) + .fetch() + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventService.kt new file mode 100644 index 0000000..fac0957 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/AdminChargeEventService.kt @@ -0,0 +1,100 @@ +package kr.co.vividnext.sodalive.admin.event + +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.ZoneId +import java.time.format.DateTimeFormatter + +@Service +@Transactional(readOnly = true) +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) + .atZone(ZoneId.of("Asia/Seoul")) + .withZoneSameInstant(ZoneId.of("UTC")) + .toLocalDateTime() + + val endDate = LocalDate.parse(request.endDateString, dateTimeFormatter).atTime(23, 59, 59) + .atZone(ZoneId.of("Asia/Seoul")) + .withZoneSameInstant(ZoneId.of("UTC")) + .toLocalDateTime() + + val chargeEvent = ChargeEvent( + title = request.title, + startDate = startDate, + endDate = endDate, + availableCount = request.availableCount, + addPercent = request.addPercent / 100f + ) + + return repository.save(chargeEvent).id!! + } + + @Transactional + fun modifyChargeEvent(request: ModifyChargeEventRequest) { + val chargeEvent = repository.findByIdOrNull(request.id) + ?: throw SodaException("해당하는 충전이벤트가 없습니다\n다시 시도해 주세요.") + + if (request.title != null) { + chargeEvent.title = request.title + } + + val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + if (request.startDateString != null) { + chargeEvent.startDate = LocalDate.parse(request.startDateString, dateTimeFormatter).atTime(0, 0) + .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) + .atZone(ZoneId.of("Asia/Seoul")) + .withZoneSameInstant(ZoneId.of("UTC")) + .toLocalDateTime() + } + + if (request.availableCount != null) { + chargeEvent.availableCount = request.availableCount + } + + if (request.addPercent != null) { + chargeEvent.addPercent = request.addPercent / 100f + } + + if (request.isActive != null) { + chargeEvent.isActive = request.isActive + } + } + + fun getChargeEventList(): List { + 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/ChargeEvent.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/ChargeEvent.kt new file mode 100644 index 0000000..2d93162 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/ChargeEvent.kt @@ -0,0 +1,15 @@ +package kr.co.vividnext.sodalive.admin.event + +import kr.co.vividnext.sodalive.common.BaseEntity +import java.time.LocalDateTime +import javax.persistence.Entity + +@Entity +data class ChargeEvent( + var title: String, + var startDate: LocalDateTime, + var endDate: LocalDateTime, + var availableCount: Int, + var addPercent: Float, + var isActive: Boolean = true +) : BaseEntity() diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/CreateChargeEventRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/CreateChargeEventRequest.kt new file mode 100644 index 0000000..7e81f4e --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/CreateChargeEventRequest.kt @@ -0,0 +1,9 @@ +package kr.co.vividnext.sodalive.admin.event + +data class CreateChargeEventRequest( + val title: String, + val startDateString: String, + val endDateString: String, + val availableCount: Int, + val addPercent: Int +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/GetChargeEventListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/GetChargeEventListResponse.kt new file mode 100644 index 0000000..fbac78b --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/GetChargeEventListResponse.kt @@ -0,0 +1,11 @@ +package kr.co.vividnext.sodalive.admin.event + +data class GetChargeEventListResponse( + val id: Long, + val title: String, + val startDate: String, + val endDate: String, + val availableCount: Int, + val addPercent: Int, + val isActive: Boolean +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/ModifyChargeEventRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/ModifyChargeEventRequest.kt new file mode 100644 index 0000000..1086ae2 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/event/ModifyChargeEventRequest.kt @@ -0,0 +1,11 @@ +package kr.co.vividnext.sodalive.admin.event + +data class ModifyChargeEventRequest( + val id: Long, + val title: String? = null, + val startDateString: String? = null, + val endDateString: String? = null, + val availableCount: Int? = null, + val addPercent: Int? = null, + val isActive: Boolean? = null +)