From fcd435f4706ac52d1692221f3897078d397c1ae9 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 4 Aug 2023 22:42:14 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20-=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=ED=85=8C=EB=A7=88=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../theme/AdminContentThemeController.kt | 36 ++++++++++ .../theme/AdminContentThemeRepository.kt | 48 +++++++++++++ .../content/theme/AdminContentThemeService.kt | 70 +++++++++++++++++++ .../theme/CreateContentThemeRequest.kt | 3 + .../content/theme/UpdateThemeOrdersRequest.kt | 5 ++ 5 files changed, 162 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeController.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeRepository.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeService.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/CreateContentThemeRequest.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/UpdateThemeOrdersRequest.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeController.kt new file mode 100644 index 0000000..354aabb --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeController.kt @@ -0,0 +1,36 @@ +package kr.co.vividnext.sodalive.admin.content.theme + +import kr.co.vividnext.sodalive.common.ApiResponse +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.RequestPart +import org.springframework.web.bind.annotation.RestController +import org.springframework.web.multipart.MultipartFile + +@RestController +@RequestMapping("/admin/audio-content/theme") +@PreAuthorize("hasRole('ADMIN')") +class AdminContentThemeController(private val service: AdminContentThemeService) { + @PostMapping + fun enrollmentTheme( + @RequestPart("image") image: MultipartFile, + @RequestPart("request") requestString: String + ) = ApiResponse.ok(service.uploadThemeImage(image, requestString), "등록되었습니다.") + + @DeleteMapping("/{id}") + fun deleteTheme(@PathVariable id: Long) = ApiResponse.ok(service.deleteTheme(id), "삭제되었습니다.") + + @PutMapping("/orders") + fun updateTagOrders( + @RequestBody request: UpdateThemeOrdersRequest + ) = ApiResponse.ok(service.updateTagOrders(request.ids), "수정되었습니다.") + + @GetMapping + fun getThemes() = ApiResponse.ok(service.getThemes()) +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeRepository.kt new file mode 100644 index 0000000..77f2af2 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeRepository.kt @@ -0,0 +1,48 @@ +package kr.co.vividnext.sodalive.admin.content.theme + +import com.querydsl.jpa.impl.JPAQueryFactory +import kr.co.vividnext.sodalive.content.theme.AudioContentTheme +import kr.co.vividnext.sodalive.content.theme.GetAudioContentThemeResponse +import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme +import kr.co.vividnext.sodalive.content.theme.QGetAudioContentThemeResponse +import org.springframework.beans.factory.annotation.Value +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface AdminContentThemeRepository : JpaRepository, AdminContentThemeQueryRepository + +interface AdminContentThemeQueryRepository { + fun findIdByTheme(theme: String): Long? + fun getActiveThemes(): List +} + +class AdminContentThemeQueryRepositoryImpl( + private val queryFactory: JPAQueryFactory, + + @Value("\${cloud.aws.cloud-front.host}") + private val cloudFrontHost: String +) : AdminContentThemeQueryRepository { + override fun findIdByTheme(theme: String): Long? { + return queryFactory + .select(audioContentTheme.id) + .from(audioContentTheme) + .where(audioContentTheme.theme.eq(theme)) + .fetchOne() + } + + override fun getActiveThemes(): List { + return queryFactory + .select( + QGetAudioContentThemeResponse( + audioContentTheme.id, + audioContentTheme.theme, + audioContentTheme.image.prepend("/").prepend(cloudFrontHost) + ) + ) + .from(audioContentTheme) + .where(audioContentTheme.isActive.isTrue) + .orderBy(audioContentTheme.orders.asc()) + .fetch() + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeService.kt new file mode 100644 index 0000000..00e6237 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/AdminContentThemeService.kt @@ -0,0 +1,70 @@ +package kr.co.vividnext.sodalive.admin.content.theme + +import com.fasterxml.jackson.databind.ObjectMapper +import kr.co.vividnext.sodalive.aws.s3.S3Uploader +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.content.theme.AudioContentTheme +import kr.co.vividnext.sodalive.content.theme.GetAudioContentThemeResponse +import kr.co.vividnext.sodalive.utils.generateFileName +import org.springframework.beans.factory.annotation.Value +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import org.springframework.web.multipart.MultipartFile + +@Service +class AdminContentThemeService( + private val s3Uploader: S3Uploader, + private val objectMapper: ObjectMapper, + private val repository: AdminContentThemeRepository, + + @Value("\${cloud.aws.s3.bucket}") + private val bucket: String +) { + @Transactional + fun uploadThemeImage(image: MultipartFile, requestString: String) { + val request = objectMapper.readValue(requestString, CreateContentThemeRequest::class.java) + themeExistCheck(request) + + val fileName = generateFileName() + val imagePath = s3Uploader.upload( + inputStream = image.inputStream, + bucket = bucket, + filePath = "audio_content_theme/$fileName" + ) + + return createTheme(request.theme, imagePath) + } + + fun createTheme(theme: String, imagePath: String) { + repository.save(AudioContentTheme(theme = theme, image = imagePath)) + } + + fun themeExistCheck(request: CreateContentThemeRequest) { + repository.findIdByTheme(request.theme)?.let { throw SodaException("이미 등록된 테마 입니다.") } + } + + @Transactional + fun deleteTheme(id: Long) { + val theme = repository.findByIdOrNull(id) + ?: throw SodaException("잘못된 요청입니다.") + + theme.theme = "${theme.theme}_deleted" + theme.isActive = false + } + + @Transactional + fun updateTagOrders(ids: List) { + for (index in ids.indices) { + val theme = repository.findByIdOrNull(ids[index]) + + if (theme != null) { + theme.orders = index + 1 + } + } + } + + fun getThemes(): List { + return repository.getActiveThemes() + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/CreateContentThemeRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/CreateContentThemeRequest.kt new file mode 100644 index 0000000..9df9b30 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/CreateContentThemeRequest.kt @@ -0,0 +1,3 @@ +package kr.co.vividnext.sodalive.admin.content.theme + +data class CreateContentThemeRequest(val theme: String) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/UpdateThemeOrdersRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/UpdateThemeOrdersRequest.kt new file mode 100644 index 0000000..dacdc47 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/theme/UpdateThemeOrdersRequest.kt @@ -0,0 +1,5 @@ +package kr.co.vividnext.sodalive.admin.content.theme + +data class UpdateThemeOrdersRequest( + val ids: List +)