관리자 포인트 지급 정책 리스트, 생성, 수정 API
This commit is contained in:
parent
1cb2ee77b5
commit
d94418067f
|
@ -0,0 +1,37 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.point
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.point.PointRewardPolicy
|
||||||
|
import kr.co.vividnext.sodalive.useraction.ActionType
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
data class CreatePointRewardPolicyRequest(
|
||||||
|
val title: String,
|
||||||
|
val actionType: ActionType,
|
||||||
|
val threshold: Int,
|
||||||
|
val pointAmount: Int,
|
||||||
|
val startDate: String,
|
||||||
|
val endDate: String,
|
||||||
|
val isActive: Boolean
|
||||||
|
) {
|
||||||
|
fun toEntity(): PointRewardPolicy {
|
||||||
|
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
|
||||||
|
|
||||||
|
return PointRewardPolicy(
|
||||||
|
title = title,
|
||||||
|
actionType = actionType,
|
||||||
|
threshold = threshold,
|
||||||
|
pointAmount = pointAmount,
|
||||||
|
startDate = LocalDateTime.parse(startDate, dateTimeFormatter)
|
||||||
|
.atZone(ZoneId.of("Asia/Seoul"))
|
||||||
|
.withZoneSameInstant(ZoneId.of("UTC"))
|
||||||
|
.toLocalDateTime(),
|
||||||
|
endDate = LocalDateTime.parse(endDate, dateTimeFormatter).withSecond(59)
|
||||||
|
.atZone(ZoneId.of("Asia/Seoul"))
|
||||||
|
.withZoneSameInstant(ZoneId.of("UTC"))
|
||||||
|
.toLocalDateTime(),
|
||||||
|
isActive = isActive
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.point
|
||||||
|
|
||||||
|
import com.querydsl.core.annotations.QueryProjection
|
||||||
|
import kr.co.vividnext.sodalive.useraction.ActionType
|
||||||
|
|
||||||
|
data class GetPointRewardPolicyResponse @QueryProjection constructor(
|
||||||
|
val id: Long,
|
||||||
|
val title: String,
|
||||||
|
val actionType: ActionType,
|
||||||
|
val threshold: Int,
|
||||||
|
val pointAmount: Int,
|
||||||
|
val startDate: String,
|
||||||
|
val endDate: String,
|
||||||
|
val isActive: Boolean
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.point
|
||||||
|
|
||||||
|
data class ModifyPointRewardPolicyRequest(
|
||||||
|
val title: String?,
|
||||||
|
val startDate: String?,
|
||||||
|
val endDate: String?,
|
||||||
|
val isActive: Boolean?
|
||||||
|
)
|
|
@ -0,0 +1,36 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.point
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||||
|
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.PathVariable
|
||||||
|
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("/admin/point-policies")
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
class PointPolicyController(private val service: PointPolicyService) {
|
||||||
|
@GetMapping
|
||||||
|
fun getAll(pageable: Pageable) = ApiResponse.ok(
|
||||||
|
service.getAll(
|
||||||
|
offset = pageable.offset,
|
||||||
|
limit = pageable.pageSize.toLong()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
fun create(
|
||||||
|
@RequestBody request: CreatePointRewardPolicyRequest
|
||||||
|
) = ApiResponse.ok(service.create(request))
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
fun update(
|
||||||
|
@PathVariable id: Long,
|
||||||
|
@RequestBody request: ModifyPointRewardPolicyRequest
|
||||||
|
) = ApiResponse.ok(service.update(id, request))
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.point
|
||||||
|
|
||||||
|
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.point.PointRewardPolicy
|
||||||
|
import kr.co.vividnext.sodalive.point.QPointRewardPolicy.pointRewardPolicy
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
interface PointPolicyRepository : JpaRepository<PointRewardPolicy, Long>, PointPolicyQueryRepository
|
||||||
|
|
||||||
|
interface PointPolicyQueryRepository {
|
||||||
|
fun getAll(offset: Long, limit: Long): List<GetPointRewardPolicyResponse>
|
||||||
|
}
|
||||||
|
|
||||||
|
class PointPolicyQueryRepositoryImpl(
|
||||||
|
private val queryFactory: JPAQueryFactory
|
||||||
|
) : PointPolicyQueryRepository {
|
||||||
|
override fun getAll(offset: Long, limit: Long): List<GetPointRewardPolicyResponse> {
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QGetPointRewardPolicyResponse(
|
||||||
|
pointRewardPolicy.id,
|
||||||
|
pointRewardPolicy.title,
|
||||||
|
pointRewardPolicy.actionType,
|
||||||
|
pointRewardPolicy.threshold,
|
||||||
|
pointRewardPolicy.pointAmount,
|
||||||
|
getFormattedDate(pointRewardPolicy.startDate),
|
||||||
|
getFormattedDate(pointRewardPolicy.endDate),
|
||||||
|
pointRewardPolicy.isActive
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(pointRewardPolicy)
|
||||||
|
.orderBy(pointRewardPolicy.isActive.desc(), pointRewardPolicy.startDate.desc())
|
||||||
|
.offset(offset)
|
||||||
|
.limit(limit)
|
||||||
|
.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"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package kr.co.vividnext.sodalive.admin.point
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.common.SodaException
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class PointPolicyService(private val repository: PointPolicyRepository) {
|
||||||
|
fun getAll(offset: Long, limit: Long): List<GetPointRewardPolicyResponse> {
|
||||||
|
return repository.getAll(offset, limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(request: CreatePointRewardPolicyRequest) {
|
||||||
|
val pointPolicy = request.toEntity()
|
||||||
|
repository.save(pointPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(id: Long, request: ModifyPointRewardPolicyRequest) {
|
||||||
|
val pointPolicy = repository.findByIdOrNull(id)
|
||||||
|
?: throw SodaException("잘못된 접근입니다.")
|
||||||
|
|
||||||
|
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
|
||||||
|
|
||||||
|
if (request.title != null) {
|
||||||
|
pointPolicy.title = request.title
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.startDate != null) {
|
||||||
|
pointPolicy.startDate = LocalDateTime.parse(request.startDate, dateTimeFormatter)
|
||||||
|
.atZone(ZoneId.of("Asia/Seoul"))
|
||||||
|
.withZoneSameInstant(ZoneId.of("UTC"))
|
||||||
|
.toLocalDateTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.endDate != null) {
|
||||||
|
pointPolicy.endDate = LocalDateTime.parse(request.endDate, dateTimeFormatter).withSecond(59)
|
||||||
|
.atZone(ZoneId.of("Asia/Seoul"))
|
||||||
|
.withZoneSameInstant(ZoneId.of("UTC"))
|
||||||
|
.toLocalDateTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.isActive != null) {
|
||||||
|
pointPolicy.isActive = request.isActive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue