번역된 테마로 콘텐츠를 조회해도 한글 테마처럼 처리하기
This commit is contained in:
@@ -21,6 +21,7 @@ import kr.co.vividnext.sodalive.content.order.OrderType
|
||||
import kr.co.vividnext.sodalive.content.pin.PinContent
|
||||
import kr.co.vividnext.sodalive.content.pin.PinContentRepository
|
||||
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
|
||||
import kr.co.vividnext.sodalive.content.theme.translation.ContentThemeTranslationRepository
|
||||
import kr.co.vividnext.sodalive.content.translation.ContentTranslation
|
||||
import kr.co.vividnext.sodalive.content.translation.ContentTranslationPayload
|
||||
import kr.co.vividnext.sodalive.content.translation.ContentTranslationRepository
|
||||
@@ -75,6 +76,8 @@ class AudioContentService(
|
||||
|
||||
private val langContext: LangContext,
|
||||
|
||||
private val contentThemeTranslationRepository: ContentThemeTranslationRepository,
|
||||
|
||||
@Value("\${cloud.aws.s3.content-bucket}")
|
||||
private val audioContentBucket: String,
|
||||
|
||||
@@ -1140,8 +1143,20 @@ class AudioContentService(
|
||||
orderByRandom: Boolean = false,
|
||||
isPointAvailableOnly: Boolean = false
|
||||
): List<AudioContentMainItem> {
|
||||
/**
|
||||
* - AS-IS theme은 한글만 처리하도록 되어 있음
|
||||
* - TO-BE 번역된 theme이 들어와도 동일한 동작을 하도록 처리
|
||||
*/
|
||||
val normalizedTheme = normalizeThemeForQuery(
|
||||
themes = theme,
|
||||
contentType = contentType,
|
||||
isFree = isFree,
|
||||
isAdult = isAdult,
|
||||
isPointAvailableOnly = isPointAvailableOnly
|
||||
)
|
||||
|
||||
val contentList = repository.getLatestContentByTheme(
|
||||
theme = theme,
|
||||
theme = normalizedTheme,
|
||||
contentType = contentType,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
@@ -1170,4 +1185,60 @@ class AudioContentService(
|
||||
contentList
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* theme 파라미터로 번역된 테마명이 들어와도 한글 원문 테마로 조회되도록 정규화한다.
|
||||
* - 현재 언어(locale)에 해당하는 테마 번역 목록을 활성 테마 집합과 매칭하여 역매핑한다.
|
||||
* - 입력이 이미 한글인 경우 그대로 유지한다.
|
||||
* - 매칭 실패 시 원본 값을 유지한다.
|
||||
*/
|
||||
private fun normalizeThemeForQuery(
|
||||
themes: List<String>,
|
||||
contentType: ContentType,
|
||||
isFree: Boolean,
|
||||
isAdult: Boolean,
|
||||
isPointAvailableOnly: Boolean
|
||||
): List<String> {
|
||||
if (themes.isEmpty()) return themes
|
||||
|
||||
val themesWithIds = themeQueryRepository.getActiveThemeWithIdsOfContent(
|
||||
isAdult = isAdult,
|
||||
isFree = isFree,
|
||||
isPointAvailableOnly = isPointAvailableOnly,
|
||||
contentType = contentType
|
||||
)
|
||||
|
||||
if (themesWithIds.isEmpty()) return themes
|
||||
|
||||
val idByKorean = themesWithIds.associate { it.theme to it.id }
|
||||
val koreanById = themesWithIds.associate { it.id to it.theme }
|
||||
|
||||
val locale = langContext.lang.code
|
||||
// 번역 테마를 역매핑하기 위해 현재 locale의 번역 목록을 조회
|
||||
val translatedByTextToId = run {
|
||||
val ids = themesWithIds.map { it.id }
|
||||
if (ids.isEmpty()) {
|
||||
emptyMap()
|
||||
} else {
|
||||
contentThemeTranslationRepository
|
||||
.findByContentThemeIdInAndLocale(ids, locale)
|
||||
.associate { it.theme to it.contentThemeId }
|
||||
}
|
||||
}
|
||||
|
||||
return themes.asSequence()
|
||||
.map { input ->
|
||||
when {
|
||||
idByKorean.containsKey(input) -> input // 이미 한글 원문
|
||||
translatedByTextToId.containsKey(input) -> {
|
||||
val id = translatedByTextToId[input]!!
|
||||
koreanById[id] ?: input
|
||||
}
|
||||
|
||||
else -> input
|
||||
}
|
||||
}
|
||||
.distinct()
|
||||
.toList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.content.main.banner.GetAudioContentBannerRespons
|
||||
import kr.co.vividnext.sodalive.content.main.curation.GetAudioContentCurationResponse
|
||||
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository
|
||||
import kr.co.vividnext.sodalive.content.theme.AudioContentThemeService
|
||||
import kr.co.vividnext.sodalive.content.theme.translation.ContentThemeTranslationRepository
|
||||
import kr.co.vividnext.sodalive.content.translation.ContentTranslationRepository
|
||||
import kr.co.vividnext.sodalive.event.EventItem
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
@@ -25,6 +26,8 @@ class AudioContentMainService(
|
||||
private val audioContentThemeRepository: AudioContentThemeQueryRepository,
|
||||
private val audioContentThemeService: AudioContentThemeService,
|
||||
|
||||
private val contentThemeTranslationRepository: ContentThemeTranslationRepository,
|
||||
|
||||
private val contentTranslationRepository: ContentTranslationRepository,
|
||||
|
||||
private val langContext: LangContext,
|
||||
@@ -80,8 +83,12 @@ class AudioContentMainService(
|
||||
member: Member,
|
||||
pageable: Pageable
|
||||
): GetNewContentAllResponse {
|
||||
/**
|
||||
* - AS-IS theme은 한글만 처리하도록 되어 있음
|
||||
* - TO-BE 번역된 theme이 들어와도 동일한 동작을 하도록 처리
|
||||
*/
|
||||
val isAdult = member.auth != null && isAdultContentVisible
|
||||
val themeList = if (theme.isBlank()) {
|
||||
val themeListRaw = if (theme.isBlank()) {
|
||||
audioContentThemeRepository.getActiveThemeOfContent(
|
||||
isAdult = isAdult,
|
||||
contentType = contentType
|
||||
@@ -90,6 +97,12 @@ class AudioContentMainService(
|
||||
listOf(theme)
|
||||
}
|
||||
|
||||
val themeList = normalizeThemeForQuery(
|
||||
themes = themeListRaw,
|
||||
contentType = contentType,
|
||||
isAdult = isAdult
|
||||
)
|
||||
|
||||
val totalCount = repository.totalCountNewContentFor2Weeks(
|
||||
themeList,
|
||||
memberId = member.id!!,
|
||||
@@ -128,6 +141,56 @@ class AudioContentMainService(
|
||||
return GetNewContentAllResponse(totalCount, translatedContentList)
|
||||
}
|
||||
|
||||
/**
|
||||
* 번역된 테마명이 들어와도 한글 원문 테마로 조회되도록 정규화한다.
|
||||
*/
|
||||
private fun normalizeThemeForQuery(
|
||||
themes: List<String>,
|
||||
contentType: ContentType,
|
||||
isAdult: Boolean
|
||||
): List<String> {
|
||||
if (themes.isEmpty()) return themes
|
||||
|
||||
val themesWithIds = audioContentThemeRepository.getActiveThemeWithIdsOfContent(
|
||||
isAdult = isAdult,
|
||||
isFree = false,
|
||||
isPointAvailableOnly = false,
|
||||
contentType = contentType
|
||||
)
|
||||
|
||||
if (themesWithIds.isEmpty()) return themes
|
||||
|
||||
val idByKorean = themesWithIds.associate { it.theme to it.id }
|
||||
val koreanById = themesWithIds.associate { it.id to it.theme }
|
||||
|
||||
val locale = langContext.lang.code
|
||||
val translatedByTextToId = run {
|
||||
val ids = themesWithIds.map { it.id }
|
||||
if (ids.isEmpty()) {
|
||||
emptyMap()
|
||||
} else {
|
||||
contentThemeTranslationRepository
|
||||
.findByContentThemeIdInAndLocale(ids, locale)
|
||||
.associate { it.theme to it.contentThemeId }
|
||||
}
|
||||
}
|
||||
|
||||
return themes.asSequence()
|
||||
.map { input ->
|
||||
when {
|
||||
idByKorean.containsKey(input) -> input
|
||||
translatedByTextToId.containsKey(input) -> {
|
||||
val id = translatedByTextToId[input]!!
|
||||
koreanById[id] ?: input
|
||||
}
|
||||
|
||||
else -> input
|
||||
}
|
||||
}
|
||||
.distinct()
|
||||
.toList()
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Cacheable(cacheNames = ["default"], key = "'newContentUploadCreatorList:' + #memberId + ':' + #isAdult")
|
||||
fun getNewContentUploadCreatorList(memberId: Long, isAdult: Boolean): List<ContentCreatorResponse> {
|
||||
|
||||
Reference in New Issue
Block a user