Merge pull request '콘텐츠 메인 API - 캐싱을 적용하기 위해 AudioContentMainManageService 추가' (#71) from test into main
Reviewed-on: #71
This commit is contained in:
commit
2acffd8afc
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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> {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue