diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt index 7e2581b..e8ef45b 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt @@ -12,6 +12,7 @@ import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerService import kr.co.vividnext.sodalive.content.main.curation.AudioContentCurationService import kr.co.vividnext.sodalive.content.series.ContentSeriesService import kr.co.vividnext.sodalive.content.series.GetSeriesListResponse +import kr.co.vividnext.sodalive.content.series.translation.SeriesTranslationRepository import kr.co.vividnext.sodalive.content.theme.AudioContentThemeService import kr.co.vividnext.sodalive.content.translation.ContentTranslationRepository import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek @@ -53,6 +54,7 @@ class HomeService( private val contentTranslationRepository: ContentTranslationRepository, private val aiCharacterTranslationRepository: AiCharacterTranslationRepository, + private val seriesTranslationRepository: SeriesTranslationRepository, private val langContext: LangContext, @@ -133,20 +135,25 @@ class HomeService( isAdult = isAdult ) + // 오직 보이스온에서만 val originalAudioDramaList = seriesService.getOriginalAudioDramaList( isAdult = isAdult, contentType = contentType, orderByRandom = true ) + val translatedOriginalAudioDramaList = getTranslatedSeriesList(seriesList = originalAudioDramaList) + val auditionList = auditionService.getInProgressAuditionList(isAdult = isAdult) + // 요일별 시리즈 val dayOfWeekSeriesList = seriesService.getDayOfWeekSeriesList( memberId = memberId, isAdult = isAdult, contentType = contentType, dayOfWeek = getDayOfWeekByTimezone(timezone) ) + val translatedDayOfWeekSeriesList = getTranslatedSeriesList(seriesList = dayOfWeekSeriesList) // 인기 캐릭터 조회 val translatedPopularCharacters = getTranslatedAiCharacterList(aiCharacterList = characterService.getPopularCharacters()) @@ -280,9 +287,9 @@ class HomeService( latestContentList = translatedLatestContentList, bannerList = bannerList, eventBannerList = eventBannerList, - originalAudioDramaList = originalAudioDramaList, + originalAudioDramaList = translatedOriginalAudioDramaList, auditionList = auditionList, - dayOfWeekSeriesList = dayOfWeekSeriesList, + dayOfWeekSeriesList = translatedDayOfWeekSeriesList, popularCharacters = translatedPopularCharacters, contentRanking = translatedContentRanking, recommendChannelList = translatedRecommendChannelList, @@ -479,6 +486,44 @@ class HomeService( } } + /** + * 시리즈 리스트의 제목을 현재 언어(locale)에 맞춰 일괄 번역한다. + * + * 처리 절차: + * - 입력된 시리즈들의 seriesId 집합을 만들고, 요청 언어 코드(langContext.lang.code)로 + * seriesTranslationRepository에서 번역 데이터를 한 번에 조회한다. + * - 각 항목에 대해 번역된 제목이 존재하고 비어있지 않으면 title만 번역 값으로 교체한다. + * - 번역이 없거나 공백이면 원본 항목을 그대로 반환한다. + * + * 성능: + * - N건의 항목을 1회의 조회로 해결하기 위해 IN 쿼리를 사용한다. + * + * @param seriesList 번역 대상 SeriesListItem 목록 + * @return 제목이 가능한 항목은 번역된 목록(불변 사본), 그 외는 원본 항목 유지 + */ + private fun getTranslatedSeriesList( + seriesList: List + ): List { + val seriesIds = seriesList.map { it.seriesId } + + return if (seriesIds.isNotEmpty()) { + val translations = seriesTranslationRepository + .findBySeriesIdInAndLocale(seriesIds = seriesIds, locale = langContext.lang.code) + .associateBy { it.seriesId } + + seriesList.map { item -> + val translatedTitle = translations[item.seriesId]?.renderedPayload?.title + if (translatedTitle.isNullOrBlank()) { + item + } else { + item.copy(title = translatedTitle) + } + } + } else { + seriesList + } + } + /** * AI 캐릭터 리스트의 이름/설명을 현재 언어(locale)에 맞춰 일괄 번역한다. * diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/translation/SeriesTranslationRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/translation/SeriesTranslationRepository.kt index bfb3b93..266bcbc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/series/translation/SeriesTranslationRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/series/translation/SeriesTranslationRepository.kt @@ -4,4 +4,5 @@ import org.springframework.data.jpa.repository.JpaRepository interface SeriesTranslationRepository : JpaRepository { fun findBySeriesIdAndLocale(seriesId: Long, locale: String): SeriesTranslation? + fun findBySeriesIdInAndLocale(seriesIds: List, locale: String): List }