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