Merge pull request '콘텐츠 메인 API - 캐싱을 적용하기 위해 AudioContentMainManageService 추가' (#71) from test into main

Reviewed-on: #71
This commit is contained in:
klaus 2023-11-07 11:24:40 +00:00
commit 2acffd8afc
4 changed files with 103 additions and 77 deletions

View File

@ -12,7 +12,10 @@ import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@RequestMapping("/audio-content/main") @RequestMapping("/audio-content/main")
class AudioContentMainController(private val service: AudioContentMainService) { class AudioContentMainController(
private val service: AudioContentMainService,
private val manageService: AudioContentMainManageService
) {
@GetMapping @GetMapping
fun getMain( fun getMain(
@ -20,7 +23,7 @@ class AudioContentMainController(private val service: AudioContentMainService) {
) = run { ) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.") if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
ApiResponse.ok(service.getMain(memberId = member.id!!, isAdult = member.auth != null)) ApiResponse.ok(manageService.getMain(member))
} }
@GetMapping("/new") @GetMapping("/new")
@ -40,7 +43,7 @@ class AudioContentMainController(private val service: AudioContentMainService) {
) = run { ) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.") if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
ApiResponse.ok(service.getThemeList(member)) ApiResponse.ok(service.getThemeList(isAdult = member.auth != null))
} }
@GetMapping("/new/all") @GetMapping("/new/all")

View File

@ -0,0 +1,94 @@
package kr.co.vividnext.sodalive.content.main
import kr.co.vividnext.sodalive.content.AudioContentRepository
import kr.co.vividnext.sodalive.content.AudioContentService
import kr.co.vividnext.sodalive.content.order.OrderService
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.DayOfWeek
import java.time.LocalDateTime
import java.time.temporal.TemporalAdjusters
@Service
class AudioContentMainManageService(
private val service: AudioContentMainService,
private val orderService: OrderService,
private val audioContentService: AudioContentService,
private val repository: AudioContentRepository,
private val blockMemberRepository: BlockMemberRepository,
private val audioContentThemeRepository: AudioContentThemeQueryRepository,
@Value("\${cloud.aws.cloud-front.host}")
private val imageHost: String
) {
@Transactional(readOnly = true)
fun getMain(member: Member): GetAudioContentMainResponse {
val memberId = member.id!!
val isAdult = member.auth != null
val newContentUploadCreatorList = service.getNewContentUploadCreatorList(
memberId = memberId,
isAdult = isAdult
)
val bannerList = service.getAudioContentMainBannerList(memberId = memberId, isAdult = isAdult)
val orderList = orderService.getAudioContentMainOrderList(
memberId = memberId,
limit = 20
)
// 콘텐츠 테마
val themeList = audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
// 새 콘텐츠 20개 - 시간 내림차순 정렬
val newContentList = repository.findByTheme(
cloudfrontHost = imageHost,
isAdult = isAdult
)
.asSequence()
.filter {
!blockMemberRepository.isBlocked(
blockedMemberId = memberId,
memberId = it.creatorId
)
}
.toList()
val curationList = service.getAudioContentCurationList(memberId = memberId, isAdult = isAdult)
val currentDateTime = LocalDateTime.now()
val startDate = currentDateTime
.minusWeeks(1)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
.withHour(15)
.withMinute(0)
.withSecond(0)
val endDate = startDate.plusDays(7)
val contentRankingSortTypeList = audioContentService.getContentRankingSortTypeList()
val contentRanking = audioContentService.getAudioContentRanking(
isAdult = isAdult,
startDate = startDate,
endDate = endDate,
offset = 0,
limit = 12
)
return GetAudioContentMainResponse(
newContentUploadCreatorList = newContentUploadCreatorList,
bannerList = bannerList,
orderList = orderList,
themeList = themeList,
newContentList = newContentList,
curationList = curationList,
contentRankingSortTypeList = contentRankingSortTypeList,
contentRanking = contentRanking
)
}
}

View File

@ -1,11 +1,9 @@
package kr.co.vividnext.sodalive.content.main package kr.co.vividnext.sodalive.content.main
import kr.co.vividnext.sodalive.content.AudioContentRepository import kr.co.vividnext.sodalive.content.AudioContentRepository
import kr.co.vividnext.sodalive.content.AudioContentService
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerType import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerType
import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerResponse
import kr.co.vividnext.sodalive.content.main.curation.GetAudioContentCurationResponse import kr.co.vividnext.sodalive.content.main.curation.GetAudioContentCurationResponse
import kr.co.vividnext.sodalive.content.order.OrderService
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
import kr.co.vividnext.sodalive.event.EventItem import kr.co.vividnext.sodalive.event.EventItem
import kr.co.vividnext.sodalive.member.Member import kr.co.vividnext.sodalive.member.Member
@ -15,85 +13,20 @@ import org.springframework.cache.annotation.Cacheable
import org.springframework.data.domain.Pageable import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional import org.springframework.transaction.annotation.Transactional
import java.time.DayOfWeek
import java.time.LocalDateTime
import java.time.temporal.TemporalAdjusters
@Service @Service
class AudioContentMainService( class AudioContentMainService(
private val repository: AudioContentRepository, private val repository: AudioContentRepository,
private val audioContentService: AudioContentService,
private val blockMemberRepository: BlockMemberRepository, private val blockMemberRepository: BlockMemberRepository,
private val orderService: OrderService,
private val audioContentThemeRepository: AudioContentThemeQueryRepository, private val audioContentThemeRepository: AudioContentThemeQueryRepository,
@Value("\${cloud.aws.cloud-front.host}") @Value("\${cloud.aws.cloud-front.host}")
private val imageHost: String private val imageHost: String
) { ) {
@Transactional(readOnly = true) @Transactional(readOnly = true)
fun getMain(memberId: Long, isAdult: Boolean): GetAudioContentMainResponse { @Cacheable(cacheNames = ["default"], key = "'themeList:' + ':' + #isAdult")
// 2주일 이내에 콘텐츠를 올린 크리에이터 20명 조회 fun getThemeList(isAdult: Boolean): List<String> {
val newContentUploadCreatorList = getNewContentUploadCreatorList(memberId = memberId, isAdult = isAdult) return audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
val bannerList = getAudioContentMainBannerList(memberId = memberId, isAdult = isAdult)
// 구매목록 20개
val orderList = orderService.getAudioContentMainOrderList(
memberId = memberId,
limit = 20
)
// 콘텐츠 테마
val themeList = audioContentThemeRepository.getActiveThemeOfContent(isAdult = isAdult)
// 새 콘텐츠 20개 - 시간 내림차순 정렬
val newContentList = repository.findByTheme(
cloudfrontHost = imageHost,
isAdult = isAdult
)
.asSequence()
.filter {
!blockMemberRepository.isBlocked(
blockedMemberId = memberId,
memberId = it.creatorId
)
}
.toList()
val curationList = getAudioContentCurationList(memberId = memberId, isAdult = isAdult)
val currentDateTime = LocalDateTime.now()
val startDate = currentDateTime
.minusWeeks(1)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
.withHour(15)
.withMinute(0)
.withSecond(0)
val endDate = startDate.plusDays(7)
val contentRankingSortTypeList = audioContentService.getContentRankingSortTypeList()
val contentRanking = audioContentService.getAudioContentRanking(
isAdult = isAdult,
startDate = startDate,
endDate = endDate,
offset = 0,
limit = 12
)
return GetAudioContentMainResponse(
newContentUploadCreatorList = newContentUploadCreatorList,
bannerList = bannerList,
orderList = orderList,
themeList = themeList,
newContentList = newContentList,
curationList = curationList,
contentRankingSortTypeList = contentRankingSortTypeList,
contentRanking = contentRanking
)
}
fun getThemeList(member: Member): List<String> {
return audioContentThemeRepository.getActiveThemeOfContent(isAdult = member.auth != null)
} }
fun getNewContentByTheme(theme: String, member: Member, pageable: Pageable): List<GetAudioContentMainItem> { fun getNewContentByTheme(theme: String, member: Member, pageable: Pageable): List<GetAudioContentMainItem> {

View File

@ -4,9 +4,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
@Repository @Repository
class AudioContentThemeQueryRepository( class AudioContentThemeQueryRepository(
@ -29,8 +27,6 @@ class AudioContentThemeQueryRepository(
.fetch() .fetch()
} }
@Transactional(readOnly = true)
@Cacheable(cacheNames = ["default"], key = "'activeThemeOfContent:' + ':' + #isAdult")
fun getActiveThemeOfContent(isAdult: Boolean = false): List<String> { fun getActiveThemeOfContent(isAdult: Boolean = false): List<String> {
var where = audioContent.isActive.isTrue var where = audioContent.isActive.isTrue
.and(audioContentTheme.isActive.isTrue) .and(audioContentTheme.isActive.isTrue)