feat(series-main): 시리즈 홈, 요일별 시리즈, 장르별 시리즈 API 추가

This commit is contained in:
2025-11-13 16:02:11 +09:00
parent 27be9a4fc2
commit 4f89b0189e
6 changed files with 293 additions and 10 deletions

View File

@@ -10,6 +10,7 @@ import kr.co.vividnext.sodalive.admin.content.series.banner.dto.SeriesBannerUpda
import kr.co.vividnext.sodalive.aws.s3.S3Uploader
import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.content.series.main.banner.ContentSeriesBannerService
import kr.co.vividnext.sodalive.utils.generateFileName
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.domain.PageRequest
@@ -30,7 +31,7 @@ import org.springframework.web.multipart.MultipartFile
@RequestMapping("/admin/audio-content/series/banner")
@PreAuthorize("hasRole('ADMIN')")
class AdminContentSeriesBannerController(
private val bannerService: AdminContentSeriesBannerService,
private val bannerService: ContentSeriesBannerService,
private val s3Uploader: S3Uploader,
@Value("\${cloud.aws.s3.bucket}")

View File

@@ -1,81 +0,0 @@
package kr.co.vividnext.sodalive.admin.content.series.banner
import kr.co.vividnext.sodalive.admin.content.series.AdminContentSeriesRepository
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.content.series.main.banner.SeriesBanner
import kr.co.vividnext.sodalive.content.series.main.banner.SeriesBannerRepository
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
@Service
class AdminContentSeriesBannerService(
private val bannerRepository: SeriesBannerRepository,
private val seriesRepository: AdminContentSeriesRepository
) {
fun getActiveBanners(pageable: Pageable): Page<SeriesBanner> {
return bannerRepository.findByIsActiveTrueOrderBySortOrderAsc(pageable)
}
fun getBannerById(bannerId: Long): SeriesBanner {
return bannerRepository.findById(bannerId)
.orElseThrow { SodaException("배너를 찾을 수 없습니다: $bannerId") }
}
@org.springframework.transaction.annotation.Transactional
fun registerBanner(seriesId: Long, imagePath: String): SeriesBanner {
val series = seriesRepository.findByIdAndActiveTrue(seriesId)
?: throw SodaException("시리즈를 찾을 수 없습니다: $seriesId")
val finalSortOrder = (bannerRepository.findMaxSortOrder() ?: 0) + 1
val banner = SeriesBanner(
imagePath = imagePath,
series = series,
sortOrder = finalSortOrder
)
return bannerRepository.save(banner)
}
@org.springframework.transaction.annotation.Transactional
fun updateBanner(
bannerId: Long,
imagePath: String? = null,
seriesId: Long? = null
): SeriesBanner {
val banner = bannerRepository.findById(bannerId)
.orElseThrow { SodaException("배너를 찾을 수 없습니다: $bannerId") }
if (!banner.isActive) throw SodaException("비활성화된 배너는 수정할 수 없습니다: $bannerId")
if (imagePath != null) banner.imagePath = imagePath
if (seriesId != null) {
val series = seriesRepository.findByIdAndActiveTrue(seriesId)
?: throw SodaException("시리즈를 찾을 수 없습니다: $seriesId")
banner.series = series
}
return bannerRepository.save(banner)
}
@org.springframework.transaction.annotation.Transactional
fun deleteBanner(bannerId: Long) {
val banner = bannerRepository.findById(bannerId)
.orElseThrow { SodaException("배너를 찾을 수 없습니다: $bannerId") }
banner.isActive = false
bannerRepository.save(banner)
}
@org.springframework.transaction.annotation.Transactional
fun updateBannerOrders(ids: List<Long>): List<SeriesBanner> {
val updated = mutableListOf<SeriesBanner>()
for (index in ids.indices) {
val banner = bannerRepository.findById(ids[index])
.orElseThrow { SodaException("배너를 찾을 수 없습니다: ${ids[index]}") }
if (!banner.isActive) throw SodaException("비활성화된 배너는 수정할 수 없습니다: ${ids[index]}")
banner.sortOrder = index + 1
updated.add(bannerRepository.save(banner))
}
return updated
}
}