서비스 공지사항 API 추가
This commit is contained in:
parent
0c106540cd
commit
baad5653e8
|
@ -0,0 +1,10 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
data class CreateNoticeRequest(
|
||||||
|
val title: String,
|
||||||
|
val content: String
|
||||||
|
) {
|
||||||
|
fun toEntity(): ServiceNotice {
|
||||||
|
return ServiceNotice(title, content)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
data class GetNoticeResponse(
|
||||||
|
val totalCount: Int,
|
||||||
|
val noticeList: List<NoticeItem>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NoticeItem(
|
||||||
|
val id: Long,
|
||||||
|
val title: String,
|
||||||
|
val content: String,
|
||||||
|
val date: String
|
||||||
|
)
|
|
@ -0,0 +1,15 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||||
|
import javax.persistence.Column
|
||||||
|
import javax.persistence.Entity
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class ServiceNotice(
|
||||||
|
@Column(nullable = false)
|
||||||
|
var title: String,
|
||||||
|
@Column(columnDefinition = "TEXT", nullable = false)
|
||||||
|
var content: String,
|
||||||
|
@Column(nullable = false)
|
||||||
|
var isActive: Boolean = true
|
||||||
|
) : BaseEntity()
|
|
@ -0,0 +1,38 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
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.DeleteMapping
|
||||||
|
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("/notice")
|
||||||
|
class ServiceNoticeController(private val service: ServiceNoticeService) {
|
||||||
|
@PostMapping
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
fun createNotice(@RequestBody request: CreateNoticeRequest) = ApiResponse.ok(
|
||||||
|
service.save(request),
|
||||||
|
"등록되었습니다."
|
||||||
|
)
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
fun updateNotice(@RequestBody request: UpdateNoticeRequest) = ApiResponse.ok(
|
||||||
|
service.update(request),
|
||||||
|
"수정되었습니다."
|
||||||
|
)
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
fun deleteCoin(@PathVariable id: Long) = ApiResponse.ok(service.delete(id), "삭제되었습니다.")
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
fun getNoticeList(pageable: Pageable, timezone: String) = ApiResponse.ok(service.getNoticeList(pageable, timezone))
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.common.SodaException
|
||||||
|
import org.springframework.data.domain.Pageable
|
||||||
|
import org.springframework.data.repository.findByIdOrNull
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
class ServiceNoticeService(private val repository: ServiceServiceNoticeRepository) {
|
||||||
|
@Transactional
|
||||||
|
fun save(request: CreateNoticeRequest): Long {
|
||||||
|
if (request.title.isBlank()) throw SodaException("제목을 입력하세요.")
|
||||||
|
if (request.content.isBlank()) throw SodaException("내용을 입력하세요.")
|
||||||
|
|
||||||
|
val notice = request.toEntity()
|
||||||
|
return repository.save(notice).id!!
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun update(request: UpdateNoticeRequest) {
|
||||||
|
if (request.id <= 0) throw SodaException("잘못된 요청입니다.")
|
||||||
|
if (request.title.isNullOrBlank() && request.content.isNullOrBlank()) {
|
||||||
|
throw SodaException("수정할 내용을 입력하세요.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val notice = repository.findByIdOrNull(request.id)
|
||||||
|
?: throw SodaException("잘못된 요청입니다.")
|
||||||
|
|
||||||
|
if (!request.title.isNullOrBlank()) notice.title = request.title
|
||||||
|
if (!request.content.isNullOrBlank()) notice.content = request.content
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
fun delete(id: Long) {
|
||||||
|
if (id <= 0) throw SodaException("잘못된 요청입니다.")
|
||||||
|
val notice = repository.findByIdOrNull(id)
|
||||||
|
?: throw SodaException("잘못된 요청입니다.")
|
||||||
|
|
||||||
|
notice.isActive = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNoticeList(pageable: Pageable, timezone: String): GetNoticeResponse {
|
||||||
|
val totalCount = repository.getNoticeTotalCount()
|
||||||
|
val noticeList = repository.getNoticeList(pageable)
|
||||||
|
.asSequence()
|
||||||
|
.map {
|
||||||
|
val createdAt = it.createdAt!!
|
||||||
|
.atZone(ZoneId.of("UTC"))
|
||||||
|
.withZoneSameInstant(ZoneId.of(timezone))
|
||||||
|
|
||||||
|
NoticeItem(
|
||||||
|
it.id!!,
|
||||||
|
it.title,
|
||||||
|
it.content,
|
||||||
|
createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
return GetNoticeResponse(totalCount, noticeList)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
|
import kr.co.vividnext.sodalive.notice.QServiceNotice.serviceNotice
|
||||||
|
import org.springframework.data.domain.Pageable
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface ServiceServiceNoticeRepository : JpaRepository<ServiceNotice, Long>, ServiceNoticeQueryRepository
|
||||||
|
|
||||||
|
interface ServiceNoticeQueryRepository {
|
||||||
|
fun getNoticeTotalCount(): Int
|
||||||
|
fun getNoticeList(pageable: Pageable): List<ServiceNotice>
|
||||||
|
}
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class ServiceNoticeQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : ServiceNoticeQueryRepository {
|
||||||
|
override fun getNoticeTotalCount(): Int {
|
||||||
|
return queryFactory
|
||||||
|
.select(serviceNotice.id)
|
||||||
|
.from(serviceNotice)
|
||||||
|
.where(serviceNotice.isActive.isTrue)
|
||||||
|
.fetch()
|
||||||
|
.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getNoticeList(pageable: Pageable): List<ServiceNotice> {
|
||||||
|
return queryFactory
|
||||||
|
.selectFrom(serviceNotice)
|
||||||
|
.where(serviceNotice.isActive.isTrue)
|
||||||
|
.offset(pageable.offset)
|
||||||
|
.limit(pageable.pageSize.toLong())
|
||||||
|
.orderBy(serviceNotice.id.desc())
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package kr.co.vividnext.sodalive.notice
|
||||||
|
|
||||||
|
data class UpdateNoticeRequest(
|
||||||
|
val id: Long,
|
||||||
|
val title: String? = null,
|
||||||
|
val content: String? = null
|
||||||
|
)
|
Loading…
Reference in New Issue