Merge pull request '콘텐츠 메인 캐싱 전략 변경' (#55) from test into main
Reviewed-on: #55
This commit is contained in:
		| @@ -10,9 +10,6 @@ import org.springframework.data.redis.connection.RedisConnectionFactory | ||||
| import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory | ||||
| import org.springframework.data.redis.core.RedisTemplate | ||||
| import org.springframework.data.redis.repository.configuration.EnableRedisRepositories | ||||
| import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer | ||||
| import org.springframework.data.redis.serializer.RedisSerializationContext | ||||
| import org.springframework.data.redis.serializer.StringRedisSerializer | ||||
| import java.time.Duration | ||||
|  | ||||
| @Configuration | ||||
| @@ -37,29 +34,19 @@ class RedisConfig( | ||||
|     } | ||||
|  | ||||
|     @Bean | ||||
|     fun cacheManager(connectionFactory: RedisConnectionFactory): RedisCacheManager { | ||||
|         val defaultConfig = RedisCacheConfiguration.defaultCacheConfig() | ||||
|             .entryTtl(Duration.ofHours(1)) // Default TTL | ||||
|             .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer())) | ||||
|             .serializeValuesWith( | ||||
|                 RedisSerializationContext.SerializationPair.fromSerializer( | ||||
|                     GenericJackson2JsonRedisSerializer() | ||||
|                 ) | ||||
|             ) | ||||
|     fun cacheManager(redisConnectionFactory: RedisConnectionFactory): RedisCacheManager { | ||||
|         val defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig() | ||||
|             .entryTtl(Duration.ofMinutes(30)) | ||||
|  | ||||
|         val weekLivedCacheConfig = RedisCacheConfiguration.defaultCacheConfig() | ||||
|         val cacheConfigMap = mutableMapOf<String, RedisCacheConfiguration>() | ||||
|         cacheConfigMap["default"] = RedisCacheConfiguration.defaultCacheConfig() | ||||
|             .entryTtl(Duration.ofMinutes(30)) | ||||
|         cacheConfigMap["cache_ttl_3_days"] = RedisCacheConfiguration.defaultCacheConfig() | ||||
|             .entryTtl(Duration.ofDays(3)) | ||||
|             .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer())) | ||||
|             .serializeValuesWith( | ||||
|                 RedisSerializationContext.SerializationPair.fromSerializer( | ||||
|                     GenericJackson2JsonRedisSerializer() | ||||
|                 ) | ||||
|             ) | ||||
|  | ||||
|         return RedisCacheManager.RedisCacheManagerBuilder | ||||
|             .fromConnectionFactory(connectionFactory) | ||||
|             .cacheDefaults(defaultConfig) | ||||
|             .withCacheConfiguration("weekLivedCache", weekLivedCacheConfig) | ||||
|         return RedisCacheManager.builder(redisConnectionFactory) | ||||
|             .cacheDefaults(defaultCacheConfig) | ||||
|             .withInitialCacheConfigurations(cacheConfigMap) | ||||
|             .build() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -17,7 +17,6 @@ import kr.co.vividnext.sodalive.content.order.QOrder.order | ||||
| import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme | ||||
| import kr.co.vividnext.sodalive.event.QEvent.event | ||||
| import kr.co.vividnext.sodalive.member.QMember.member | ||||
| import org.springframework.cache.annotation.Cacheable | ||||
| import org.springframework.data.jpa.repository.JpaRepository | ||||
| import org.springframework.stereotype.Repository | ||||
| import java.time.LocalDateTime | ||||
| @@ -77,9 +76,6 @@ interface AudioContentQueryRepository { | ||||
|  | ||||
|     fun getAudioContentMainBannerList(isAdult: Boolean): List<AudioContentBanner> | ||||
|     fun getAudioContentCurations(isAdult: Boolean): List<AudioContentCuration> | ||||
|  | ||||
|     fun getAudioContentCurationList(isAdult: Boolean, offset: Long = 0, limit: Long = 10): List<AudioContentCuration> | ||||
|  | ||||
|     fun findAudioContentByCurationId( | ||||
|         curationId: Long, | ||||
|         cloudfrontHost: String, | ||||
| @@ -390,10 +386,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     @Cacheable( | ||||
|         value = ["getAudioContentCurations"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     override fun getAudioContentCurations(isAdult: Boolean): List<AudioContentCuration> { | ||||
|         var where = audioContentCuration.isActive.isTrue | ||||
|  | ||||
| @@ -408,26 +400,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     override fun getAudioContentCurationList( | ||||
|         isAdult: Boolean, | ||||
|         offset: Long, | ||||
|         limit: Long | ||||
|     ): List<AudioContentCuration> { | ||||
|         var where = audioContentCuration.isActive.isTrue | ||||
|  | ||||
|         if (!isAdult) { | ||||
|             where = where.and(audioContentCuration.isAdult.isFalse) | ||||
|         } | ||||
|  | ||||
|         return queryFactory | ||||
|             .selectFrom(audioContentCuration) | ||||
|             .where(where) | ||||
|             .orderBy(audioContentCuration.orders.asc()) | ||||
|             .offset(offset) | ||||
|             .limit(limit) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     override fun findAudioContentByCurationId( | ||||
|         curationId: Long, | ||||
|         cloudfrontHost: String, | ||||
| @@ -465,10 +437,6 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     @Cacheable( | ||||
|         value = ["weekLivedCache"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     override fun getAudioContentRanking( | ||||
|         cloudfrontHost: String, | ||||
|         isAdult: Boolean, | ||||
|   | ||||
| @@ -23,33 +23,6 @@ class AudioContentMainController(private val service: AudioContentMainService) { | ||||
|         ApiResponse.ok(service.getMain(member = member)) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/new-content-upload-creator") | ||||
|     fun getNewContentUploadCreatorList( | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok(service.getNewContentUploadCreatorList(member = member)) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/banner-list") | ||||
|     fun getAudioContentMainBannerList( | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok(service.getAudioContentMainBannerList(member = member)) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/order-list") | ||||
|     fun getAudioContentMainOrderList( | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok(service.getAudioContentMainOrderList(member = member)) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/new") | ||||
|     fun getNewContentByTheme( | ||||
|         @RequestParam("theme") theme: String, | ||||
| @@ -80,29 +53,4 @@ class AudioContentMainController(private val service: AudioContentMainService) { | ||||
|  | ||||
|         ApiResponse.ok(service.getNewContentFor2WeeksByTheme(theme, member, pageable)) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/curation-list") | ||||
|     fun getAudioContentMainCurationList( | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, | ||||
|         pageable: Pageable | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok( | ||||
|             service.getAudioContentMainCurationList( | ||||
|                 member, | ||||
|                 offset = pageable.offset, | ||||
|                 limit = pageable.pageSize.toLong() | ||||
|             ) | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/content-ranking") | ||||
|     fun getAudioContentMainContentRanking( | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|  | ||||
|         ApiResponse.ok(service.getAudioContentMainContentRanking(member)) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -30,62 +30,12 @@ class AudioContentMainService( | ||||
| ) { | ||||
|     fun getMain(member: Member): GetAudioContentMainResponse { | ||||
|         val isAdult = member.auth != null | ||||
|         val memberId = member.id!! | ||||
|  | ||||
|         // 2주일 이내에 콘텐츠를 올린 크리에이터 20명 조회 | ||||
|         val newContentUploadCreatorList = repository.getNewContentUploadCreatorList( | ||||
|             cloudfrontHost = imageHost, | ||||
|             isAdult = isAdult | ||||
|         ) | ||||
|             .asSequence() | ||||
|             .filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.creatorId) } | ||||
|             .toList() | ||||
|         val newContentUploadCreatorList = getNewContentUploadCreatorList(memberId = memberId, isAdult = isAdult) | ||||
|  | ||||
|         val bannerList = repository.getAudioContentMainBannerList(isAdult = isAdult) | ||||
|             .asSequence() | ||||
|             .filter { | ||||
|                 if (it.type == AudioContentBannerType.CREATOR && it.creator != null) { | ||||
|                     !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.creator!!.id!!) | ||||
|                 } else { | ||||
|                     true | ||||
|                 } | ||||
|             } | ||||
|             .map { | ||||
|                 GetAudioContentBannerResponse( | ||||
|                     type = it.type, | ||||
|                     thumbnailImageUrl = "$imageHost/${it.thumbnailImage}", | ||||
|                     eventItem = if (it.type == AudioContentBannerType.EVENT && it.event != null) { | ||||
|                         EventItem( | ||||
|                             id = it.event!!.id!!, | ||||
|                             thumbnailImageUrl = if (!it.event!!.thumbnailImage.startsWith("https://")) { | ||||
|                                 "$imageHost/${it.event!!.thumbnailImage}" | ||||
|                             } else { | ||||
|                                 it.event!!.thumbnailImage | ||||
|                             }, | ||||
|                             detailImageUrl = if ( | ||||
|                                 it.event!!.detailImage != null && | ||||
|                                 !it.event!!.detailImage!!.startsWith("https://") | ||||
|                             ) { | ||||
|                                 "$imageHost/${it.event!!.detailImage}" | ||||
|                             } else { | ||||
|                                 it.event!!.detailImage | ||||
|                             }, | ||||
|                             popupImageUrl = null, | ||||
|                             link = it.event!!.link, | ||||
|                             title = it.event!!.title, | ||||
|                             isPopup = false | ||||
|                         ) | ||||
|                     } else { | ||||
|                         null | ||||
|                     }, | ||||
|                     creatorId = if (it.type == AudioContentBannerType.CREATOR && it.creator != null) { | ||||
|                         it.creator!!.id | ||||
|                     } else { | ||||
|                         null | ||||
|                     }, | ||||
|                     link = it.link | ||||
|                 ) | ||||
|             } | ||||
|             .toList() | ||||
|         val bannerList = getAudioContentMainBannerList(memberId = memberId, isAdult = isAdult) | ||||
|  | ||||
|         // 구매목록 20개 | ||||
|         val orderList = orderService.getAudioContentMainOrderList( | ||||
| @@ -102,34 +52,10 @@ class AudioContentMainService( | ||||
|             isAdult = isAdult | ||||
|         ) | ||||
|             .asSequence() | ||||
|             .filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.creatorId) } | ||||
|             .filter { !blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = it.creatorId) } | ||||
|             .toList() | ||||
|  | ||||
|         val curationList = repository | ||||
|             .getAudioContentCurations(isAdult = isAdult) | ||||
|             .asSequence() | ||||
|             .map { | ||||
|                 GetAudioContentCurationResponse( | ||||
|                     curationId = it.id!!, | ||||
|                     title = it.title, | ||||
|                     description = it.description, | ||||
|                     contents = repository.findAudioContentByCurationId( | ||||
|                         curationId = it.id!!, | ||||
|                         cloudfrontHost = imageHost, | ||||
|                         isAdult = isAdult | ||||
|                     ) | ||||
|                         .asSequence() | ||||
|                         .filter { content -> | ||||
|                             !blockMemberRepository.isBlocked( | ||||
|                                 blockedMemberId = member.id!!, | ||||
|                                 memberId = content.creatorId | ||||
|                             ) | ||||
|                         } | ||||
|                         .toList() | ||||
|                 ) | ||||
|             } | ||||
|             .filter { it.contents.isNotEmpty() } | ||||
|             .toList() | ||||
|         val curationList = getAudioContentCurationList(memberId = memberId, isAdult = isAdult) | ||||
|  | ||||
|         val currentDateTime = LocalDateTime.now() | ||||
|         val startDate = currentDateTime | ||||
| @@ -138,25 +64,9 @@ class AudioContentMainService( | ||||
|             .withHour(15) | ||||
|             .withMinute(0) | ||||
|             .withSecond(0) | ||||
|         val endDate = startDate | ||||
|             .plusDays(7) | ||||
|         val endDate = startDate.plusDays(7) | ||||
|  | ||||
|         val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일") | ||||
|         val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일") | ||||
|  | ||||
|         val contentRankingItemList = repository | ||||
|             .getAudioContentRanking( | ||||
|                 cloudfrontHost = imageHost, | ||||
|                 startDate = startDate.minusDays(1), | ||||
|                 endDate = endDate.minusDays(1), | ||||
|                 isAdult = isAdult | ||||
|             ) | ||||
|  | ||||
|         val contentRanking = GetAudioContentRanking( | ||||
|             startDate = startDate.format(startDateFormatter), | ||||
|             endDate = endDate.minusDays(1).format(endDateFormatter), | ||||
|             contentRankingItemList | ||||
|         ) | ||||
|         val contentRanking = getContentRanking(isAdult = isAdult, startDate = startDate, endDate = endDate) | ||||
|  | ||||
|         return GetAudioContentMainResponse( | ||||
|             newContentUploadCreatorList = newContentUploadCreatorList, | ||||
| @@ -169,87 +79,6 @@ class AudioContentMainService( | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @Cacheable( | ||||
|         value = ["getNewContentUploadCreatorList"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     fun getNewContentUploadCreatorList(member: Member): List<GetNewContentUploadCreator> { | ||||
|         val isAdult = member.auth != null | ||||
|  | ||||
|         // 2주일 이내에 콘텐츠를 올린 크리에이터 20명 조회 | ||||
|         return repository.getNewContentUploadCreatorList( | ||||
|             cloudfrontHost = imageHost, | ||||
|             isAdult = isAdult | ||||
|         ) | ||||
|             .asSequence() | ||||
|             .filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.creatorId) } | ||||
|             .toList() | ||||
|     } | ||||
|  | ||||
|     @Cacheable( | ||||
|         value = ["getAudioContentMainBannerList"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     fun getAudioContentMainBannerList(member: Member): List<GetAudioContentBannerResponse> { | ||||
|         val isAdult = member.auth != null | ||||
|  | ||||
|         return repository | ||||
|             .getAudioContentMainBannerList(isAdult = isAdult) | ||||
|             .asSequence() | ||||
|             .filter { | ||||
|                 if (it.type == AudioContentBannerType.CREATOR && it.creator != null) { | ||||
|                     !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.creator!!.id!!) | ||||
|                 } else { | ||||
|                     true | ||||
|                 } | ||||
|             } | ||||
|             .map { | ||||
|                 GetAudioContentBannerResponse( | ||||
|                     type = it.type, | ||||
|                     thumbnailImageUrl = "$imageHost/${it.thumbnailImage}", | ||||
|                     eventItem = if (it.type == AudioContentBannerType.EVENT && it.event != null) { | ||||
|                         EventItem( | ||||
|                             id = it.event!!.id!!, | ||||
|                             thumbnailImageUrl = if (!it.event!!.thumbnailImage.startsWith("https://")) { | ||||
|                                 "$imageHost/${it.event!!.thumbnailImage}" | ||||
|                             } else { | ||||
|                                 it.event!!.thumbnailImage | ||||
|                             }, | ||||
|                             detailImageUrl = if ( | ||||
|                                 it.event!!.detailImage != null && | ||||
|                                 !it.event!!.detailImage!!.startsWith("https://") | ||||
|                             ) { | ||||
|                                 "$imageHost/${it.event!!.detailImage}" | ||||
|                             } else { | ||||
|                                 it.event!!.detailImage | ||||
|                             }, | ||||
|                             popupImageUrl = null, | ||||
|                             link = it.event!!.link, | ||||
|                             title = it.event!!.title, | ||||
|                             isPopup = false | ||||
|                         ) | ||||
|                     } else { | ||||
|                         null | ||||
|                     }, | ||||
|                     creatorId = if (it.type == AudioContentBannerType.CREATOR && it.creator != null) { | ||||
|                         it.creator!!.id | ||||
|                     } else { | ||||
|                         null | ||||
|                     }, | ||||
|                     link = it.link | ||||
|                 ) | ||||
|             } | ||||
|             .toList() | ||||
|     } | ||||
|  | ||||
|     fun getAudioContentMainOrderList(member: Member): List<GetAudioContentMainItem> { | ||||
|         return orderService | ||||
|             .getAudioContentMainOrderList( | ||||
|                 member = member, | ||||
|                 limit = 20 | ||||
|             ) | ||||
|     } | ||||
|  | ||||
|     fun getThemeList(member: Member): List<String> { | ||||
|         return audioContentThemeRepository.getActiveThemeOfContent(isAdult = member.auth != null) | ||||
|     } | ||||
| @@ -280,23 +109,69 @@ class AudioContentMainService( | ||||
|         return GetNewContentAllResponse(totalCount, items) | ||||
|     } | ||||
|  | ||||
|     @Cacheable( | ||||
|         value = ["getAudioContentMainCurationList"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     fun getAudioContentMainCurationList( | ||||
|         member: Member, | ||||
|         offset: Long, | ||||
|         limit: Long | ||||
|     ): List<GetAudioContentCurationResponse> { | ||||
|         val isAdult = member.auth != null | ||||
|     @Cacheable(cacheNames = ["default"], key = "'getNewContentUploadCreatorList:' + #memberId + ':' + #isAdult") | ||||
|     fun getNewContentUploadCreatorList(memberId: Long, isAdult: Boolean): List<GetNewContentUploadCreator> { | ||||
|         return repository.getNewContentUploadCreatorList( | ||||
|             cloudfrontHost = imageHost, | ||||
|             isAdult = isAdult | ||||
|         ) | ||||
|             .asSequence() | ||||
|             .filter { !blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = it.creatorId) } | ||||
|             .toList() | ||||
|     } | ||||
|  | ||||
|         return repository | ||||
|             .getAudioContentCurationList( | ||||
|                 isAdult = isAdult, | ||||
|                 offset = offset, | ||||
|                 limit = limit | ||||
|             ) | ||||
|     @Cacheable(cacheNames = ["default"], key = "'getAudioContentMainBannerList:' + #memberId + ':' + #isAdult") | ||||
|     fun getAudioContentMainBannerList(memberId: Long, isAdult: Boolean) = | ||||
|         repository.getAudioContentMainBannerList(isAdult = isAdult) | ||||
|             .asSequence() | ||||
|             .filter { | ||||
|                 if (it.type == AudioContentBannerType.CREATOR && it.creator != null) { | ||||
|                     !blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = it.creator!!.id!!) | ||||
|                 } else { | ||||
|                     true | ||||
|                 } | ||||
|             } | ||||
|             .map { | ||||
|                 GetAudioContentBannerResponse( | ||||
|                     type = it.type, | ||||
|                     thumbnailImageUrl = "$imageHost/${it.thumbnailImage}", | ||||
|                     eventItem = if (it.type == AudioContentBannerType.EVENT && it.event != null) { | ||||
|                         EventItem( | ||||
|                             id = it.event!!.id!!, | ||||
|                             thumbnailImageUrl = if (!it.event!!.thumbnailImage.startsWith("https://")) { | ||||
|                                 "$imageHost/${it.event!!.thumbnailImage}" | ||||
|                             } else { | ||||
|                                 it.event!!.thumbnailImage | ||||
|                             }, | ||||
|                             detailImageUrl = if ( | ||||
|                                 it.event!!.detailImage != null && | ||||
|                                 !it.event!!.detailImage!!.startsWith("https://") | ||||
|                             ) { | ||||
|                                 "$imageHost/${it.event!!.detailImage}" | ||||
|                             } else { | ||||
|                                 it.event!!.detailImage | ||||
|                             }, | ||||
|                             popupImageUrl = null, | ||||
|                             link = it.event!!.link, | ||||
|                             title = it.event!!.title, | ||||
|                             isPopup = false | ||||
|                         ) | ||||
|                     } else { | ||||
|                         null | ||||
|                     }, | ||||
|                     creatorId = if (it.type == AudioContentBannerType.CREATOR && it.creator != null) { | ||||
|                         it.creator!!.id | ||||
|                     } else { | ||||
|                         null | ||||
|                     }, | ||||
|                     link = it.link | ||||
|                 ) | ||||
|             } | ||||
|             .toList() | ||||
|  | ||||
|     @Cacheable(cacheNames = ["default"], key = "'getAudioContentCurationList:' + #memberId + ':' + #isAdult") | ||||
|     fun getAudioContentCurationList(memberId: Long, isAdult: Boolean) = | ||||
|         repository.getAudioContentCurations(isAdult = isAdult) | ||||
|             .asSequence() | ||||
|             .map { | ||||
|                 GetAudioContentCurationResponse( | ||||
| @@ -310,31 +185,19 @@ class AudioContentMainService( | ||||
|                     ) | ||||
|                         .asSequence() | ||||
|                         .filter { content -> | ||||
|                             !blockMemberRepository.isBlocked( | ||||
|                                 blockedMemberId = member.id!!, | ||||
|                                 memberId = content.creatorId | ||||
|                             ) | ||||
|                             !blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = content.creatorId) | ||||
|                         } | ||||
|                         .toList() | ||||
|                 ) | ||||
|             } | ||||
|             .filter { it.contents.isNotEmpty() } | ||||
|             .toList() | ||||
|     } | ||||
|  | ||||
|     fun getAudioContentMainContentRanking(member: Member): GetAudioContentRanking { | ||||
|         val isAdult = member.auth != null | ||||
|  | ||||
|         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) | ||||
|  | ||||
|     @Cacheable( | ||||
|         cacheNames = ["cache_ttl_3_days"], | ||||
|         key = "'getAudioContentCurationList:' + ':' + #isAdult + ':' + #startDate + ':' + #endDate" | ||||
|     ) | ||||
|     fun getContentRanking(isAdult: Boolean, startDate: LocalDateTime, endDate: LocalDateTime): GetAudioContentRanking { | ||||
|         val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일") | ||||
|         val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일") | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory | ||||
| import kr.co.vividnext.sodalive.content.QAudioContent.audioContent | ||||
| import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme | ||||
| import org.springframework.beans.factory.annotation.Value | ||||
| import org.springframework.cache.annotation.Cacheable | ||||
| import org.springframework.stereotype.Repository | ||||
|  | ||||
| @Repository | ||||
| @@ -27,6 +28,7 @@ class AudioContentThemeQueryRepository( | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     @Cacheable(cacheNames = ["default"], key = "'getActiveThemeOfContent:' + ':' + #isAdult") | ||||
|     fun getActiveThemeOfContent(isAdult: Boolean = false): List<String> { | ||||
|         var where = audioContent.isActive.isTrue | ||||
|             .and(audioContentTheme.isActive.isTrue) | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import kr.co.vividnext.sodalive.aws.s3.S3Uploader | ||||
| import kr.co.vividnext.sodalive.common.SodaException | ||||
| import kr.co.vividnext.sodalive.utils.generateFileName | ||||
| import org.springframework.beans.factory.annotation.Value | ||||
| import org.springframework.cache.annotation.Cacheable | ||||
| import org.springframework.data.repository.findByIdOrNull | ||||
| import org.springframework.stereotype.Service | ||||
| import org.springframework.transaction.annotation.Transactional | ||||
| @@ -21,10 +20,6 @@ class EventService( | ||||
|     @Value("\${cloud.aws.cloud-front.host}") | ||||
|     private val cloudFrontHost: String | ||||
| ) { | ||||
|     @Cacheable( | ||||
|         value = ["getEventList"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     fun getEventList(): GetEventResponse { | ||||
|         val eventList = repository.getEventList() | ||||
|             .asSequence() | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import kr.co.vividnext.sodalive.member.MemberRole | ||||
| import kr.co.vividnext.sodalive.member.QMember.member | ||||
| import kr.co.vividnext.sodalive.member.following.QCreatorFollowing.creatorFollowing | ||||
| import org.springframework.beans.factory.annotation.Value | ||||
| import org.springframework.cache.annotation.Cacheable | ||||
| import org.springframework.stereotype.Repository | ||||
| import java.time.LocalDateTime | ||||
|  | ||||
| @@ -20,10 +19,6 @@ class LiveRecommendRepository( | ||||
|     @Value("\${cloud.aws.cloud-front.host}") | ||||
|     private val cloudFrontHost: String | ||||
| ) { | ||||
|     @Cacheable( | ||||
|         value = ["getRecommendLive"], | ||||
|         cacheManager = "cacheManager" | ||||
|     ) | ||||
|     fun getRecommendLive( | ||||
|         memberId: Long, | ||||
|         isBlocked: (Long) -> Boolean, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user