시리즈 리스트 - 번역 데이터 조회 기능 추가

This commit is contained in:
2025-12-16 01:07:20 +09:00
parent db18d5c8b5
commit 0eed29eadc

View File

@@ -6,11 +6,14 @@ import kr.co.vividnext.sodalive.content.order.OrderRepository
import kr.co.vividnext.sodalive.content.order.OrderType
import kr.co.vividnext.sodalive.content.series.content.ContentSeriesContentRepository
import kr.co.vividnext.sodalive.content.series.content.GetSeriesContentListResponse
import kr.co.vividnext.sodalive.content.series.translation.SeriesTranslationRepository
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesSortType
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesState
import kr.co.vividnext.sodalive.explorer.ExplorerQueryRepository
import kr.co.vividnext.sodalive.i18n.Lang
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
import org.springframework.beans.factory.annotation.Value
@@ -26,6 +29,8 @@ class ContentSeriesService(
private val blockMemberRepository: BlockMemberRepository,
private val explorerQueryRepository: ExplorerQueryRepository,
private val seriesContentRepository: ContentSeriesContentRepository,
private val langContext: LangContext,
private val seriesTranslationRepository: SeriesTranslationRepository,
@Value("\${cloud.aws.cloud-front.host}")
private val coverImageHost: String
@@ -83,7 +88,7 @@ class ContentSeriesService(
).filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!) }
val items = seriesToSeriesListItem(seriesList = rawItems, isAdult = isAuth, contentType = contentType)
return GetSeriesListResponse(totalCount, items)
return GetSeriesListResponse(totalCount, getTranslatedSeriesList(items))
}
fun getSeriesListByGenre(
@@ -338,27 +343,105 @@ class ContentSeriesService(
}
private fun publishedDaysOfWeekText(publishedDaysOfWeek: Set<SeriesPublishedDaysOfWeek>): String {
/**
* i18n을 적용하여 언어별로 요일 표시를 변경한다.
*/
val lang = langContext.lang
val labelRandom = when (lang) {
Lang.EN -> "Random"
Lang.JA -> "ランダム"
else -> "랜덤"
}
val labels = when (lang) {
Lang.EN -> mapOf(
SeriesPublishedDaysOfWeek.SUN to "Sun",
SeriesPublishedDaysOfWeek.MON to "Mon",
SeriesPublishedDaysOfWeek.TUE to "Tue",
SeriesPublishedDaysOfWeek.WED to "Wed",
SeriesPublishedDaysOfWeek.THU to "Thu",
SeriesPublishedDaysOfWeek.FRI to "Fri",
SeriesPublishedDaysOfWeek.SAT to "Sat",
SeriesPublishedDaysOfWeek.RANDOM to labelRandom
)
Lang.JA -> mapOf(
SeriesPublishedDaysOfWeek.SUN to "",
SeriesPublishedDaysOfWeek.MON to "",
SeriesPublishedDaysOfWeek.TUE to "",
SeriesPublishedDaysOfWeek.WED to "",
SeriesPublishedDaysOfWeek.THU to "",
SeriesPublishedDaysOfWeek.FRI to "",
SeriesPublishedDaysOfWeek.SAT to "",
SeriesPublishedDaysOfWeek.RANDOM to labelRandom
)
else -> mapOf(
SeriesPublishedDaysOfWeek.SUN to "",
SeriesPublishedDaysOfWeek.MON to "",
SeriesPublishedDaysOfWeek.TUE to "",
SeriesPublishedDaysOfWeek.WED to "",
SeriesPublishedDaysOfWeek.THU to "",
SeriesPublishedDaysOfWeek.FRI to "",
SeriesPublishedDaysOfWeek.SAT to "",
SeriesPublishedDaysOfWeek.RANDOM to labelRandom
)
}
val dayOfWeekText = publishedDaysOfWeek.toList().sortedBy { it.ordinal }
.map {
when (it) {
SeriesPublishedDaysOfWeek.SUN -> ""
SeriesPublishedDaysOfWeek.MON -> ""
SeriesPublishedDaysOfWeek.TUE -> ""
SeriesPublishedDaysOfWeek.WED -> ""
SeriesPublishedDaysOfWeek.THU -> ""
SeriesPublishedDaysOfWeek.FRI -> ""
SeriesPublishedDaysOfWeek.SAT -> ""
SeriesPublishedDaysOfWeek.RANDOM -> "랜덤"
}
}
.map { labels[it] ?: it.name }
.joinToString(", ") { it }
return if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)) {
val containsRandom = publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM)
return if (containsRandom) {
dayOfWeekText
} else if (publishedDaysOfWeek.size < 7) {
"매주 $dayOfWeekText"
when (lang) {
Lang.EN -> "Every $dayOfWeekText"
Lang.JA -> "毎週 $dayOfWeekText"
else -> "매주 $dayOfWeekText"
}
} else {
"매일"
when (lang) {
Lang.EN -> "Daily"
Lang.JA -> "毎日"
else -> "매일"
}
}
}
/**
* 시리즈 리스트의 제목을 현재 언어(locale)에 맞춰 일괄 번역한다.
*
* 처리 절차:
* - 입력된 시리즈들의 seriesId 집합을 만들고, 요청 언어 코드(langContext.lang.code)로
* seriesTranslationRepository에서 번역 데이터를 한 번에 조회한다.
* - 각 항목에 대해 번역된 제목이 존재하고 비어있지 않으면 title만 번역 값으로 교체한다.
* - 번역이 없거나 공백이면 원본 항목을 그대로 반환한다.
*
* 성능:
* - N건의 항목을 1회의 조회로 해결하기 위해 IN 쿼리를 사용한다.
*
* @param seriesList 번역 대상 SeriesListItem 목록
* @return 제목이 가능한 항목은 번역된 목록(불변 사본), 그 외는 원본 항목 유지
*/
private fun getTranslatedSeriesList(
seriesList: List<GetSeriesListResponse.SeriesListItem>
): List<GetSeriesListResponse.SeriesListItem> {
val seriesIds = seriesList.map { it.seriesId }
if (seriesIds.isEmpty()) return seriesList
val translations = seriesTranslationRepository
.findBySeriesIdInAndLocale(seriesIds = seriesIds, locale = langContext.lang.code)
.associateBy { it.seriesId }
return seriesList.map { item ->
val translatedTitle = translations[item.seriesId]?.renderedPayload?.title
if (translatedTitle.isNullOrBlank()) {
item
} else {
item.copy(title = translatedTitle)
}
}
}
}