From 7ab25470b6fd7670df4d3d92a78c191b76efd81d Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 12 Dec 2025 05:57:04 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=EB=B3=B4=EA=B8=B0=20API=20-=20languageCode=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=9D=BC=20=EB=B2=88=EC=97=AD=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/AudioContentController.kt | 6 ++- .../sodalive/content/AudioContentService.kt | 54 +++++++++++++++++-- .../main/AudioContentMainController.kt | 2 + .../content/main/AudioContentMainService.kt | 31 ++++++++++- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt index 95b84e3..9c1f24f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentController.kt @@ -108,6 +108,7 @@ class AudioContentController(private val service: AudioContentService) { @RequestParam("category-id", required = false) categoryId: Long? = 0, @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null, @RequestParam("contentType", required = false) contentType: ContentType? = null, + @RequestParam("languageCode", required = false) languageCode: String? = null, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, pageable: Pageable ) = run { @@ -120,6 +121,7 @@ class AudioContentController(private val service: AudioContentService) { categoryId = categoryId ?: 0, isAdultContentVisible = isAdultContentVisible ?: true, contentType = contentType ?: ContentType.ALL, + languageCode = languageCode, member = member, offset = pageable.offset, limit = pageable.pageSize.toLong() @@ -241,6 +243,7 @@ class AudioContentController(private val service: AudioContentService) { @GetMapping("/all") fun getAllContents( + @RequestParam("languageCode", required = false) languageCode: String? = null, @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null, @RequestParam("contentType", required = false) contentType: ContentType? = null, @RequestParam("isFree", required = false) isFree: Boolean? = null, @@ -261,7 +264,8 @@ class AudioContentController(private val service: AudioContentService) { sortType = sortType ?: SortType.NEWEST, isFree = isFree ?: false, isAdult = (isAdultContentVisible ?: true) && member.auth != null, - isPointAvailableOnly = isPointAvailableOnly ?: false + isPointAvailableOnly = isPointAvailableOnly ?: false, + languageCode = languageCode ) ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt index 54a0533..f718319 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt @@ -928,6 +928,7 @@ class AudioContentService( categoryId: Long = 0, isAdultContentVisible: Boolean, contentType: ContentType, + languageCode: String?, offset: Long, limit: Long ): GetAudioContentListResponse { @@ -981,9 +982,32 @@ class AudioContentService( it } + val translatedContentList = if (!languageCode.isNullOrBlank()) { + val contentIds = items.map { it.contentId } + + if (contentIds.isNotEmpty()) { + val translations = contentTranslationRepository + .findByContentIdInAndLocale(contentIds = contentIds, locale = languageCode) + .associateBy { it.contentId } + + items.map { item -> + val translatedTitle = translations[item.contentId]?.renderedPayload?.title + if (translatedTitle.isNullOrBlank()) { + item + } else { + item.copy(title = translatedTitle) + } + } + } else { + items + } + } else { + items + } + return GetAudioContentListResponse( totalCount = totalCount, - items = items + items = translatedContentList ) } @@ -1121,9 +1145,10 @@ class AudioContentService( isFree: Boolean = false, isAdult: Boolean = false, orderByRandom: Boolean = false, - isPointAvailableOnly: Boolean = false + isPointAvailableOnly: Boolean = false, + languageCode: String? = null ): List { - return repository.getLatestContentByTheme( + val contentList = repository.getLatestContentByTheme( theme = theme, contentType = contentType, offset = offset, @@ -1134,5 +1159,28 @@ class AudioContentService( orderByRandom = orderByRandom, isPointAvailableOnly = isPointAvailableOnly ) + + return if (!languageCode.isNullOrBlank()) { + val contentIds = contentList.map { it.contentId } + + if (contentIds.isNotEmpty()) { + val translations = contentTranslationRepository + .findByContentIdInAndLocale(contentIds = contentIds, locale = languageCode) + .associateBy { it.contentId } + + contentList.map { item -> + val translatedTitle = translations[item.contentId]?.renderedPayload?.title + if (translatedTitle.isNullOrBlank()) { + item + } else { + item.copy(title = translatedTitle) + } + } + } else { + contentList + } + } else { + contentList + } } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt index c534be5..892306c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainController.kt @@ -100,6 +100,7 @@ class AudioContentMainController( @GetMapping("/new/all") fun getNewContentAllByTheme( @RequestParam("theme") theme: String, + @RequestParam("languageCode", required = false) languageCode: String? = null, @RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null, @RequestParam("contentType", required = false) contentType: ContentType? = null, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, @@ -112,6 +113,7 @@ class AudioContentMainController( theme = theme, isAdultContentVisible = isAdultContentVisible ?: true, contentType = contentType ?: ContentType.ALL, + languageCode = languageCode, member = member, pageable = pageable ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt index 72a025e..addeb8e 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/main/AudioContentMainService.kt @@ -6,6 +6,7 @@ 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.curation.GetAudioContentCurationResponse import kr.co.vividnext.sodalive.content.theme.AudioContentThemeQueryRepository +import kr.co.vividnext.sodalive.content.translation.ContentTranslationRepository import kr.co.vividnext.sodalive.event.EventItem import kr.co.vividnext.sodalive.member.Member import kr.co.vividnext.sodalive.member.block.BlockMemberRepository @@ -21,6 +22,8 @@ class AudioContentMainService( private val blockMemberRepository: BlockMemberRepository, private val audioContentThemeRepository: AudioContentThemeQueryRepository, + private val contentTranslationRepository: ContentTranslationRepository, + @Value("\${cloud.aws.cloud-front.host}") private val imageHost: String ) { @@ -57,6 +60,7 @@ class AudioContentMainService( theme: String, isAdultContentVisible: Boolean, contentType: ContentType, + languageCode: String?, member: Member, pageable: Pageable ): GetNewContentAllResponse { @@ -76,7 +80,7 @@ class AudioContentMainService( isAdult = isAdult, contentType = contentType ) - val items = repository.findByThemeFor2Weeks( + val contentList = repository.findByThemeFor2Weeks( cloudfrontHost = imageHost, memberId = member.id!!, theme = themeList, @@ -87,7 +91,30 @@ class AudioContentMainService( ) .filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.creatorId) } - return GetNewContentAllResponse(totalCount, items) + val translatedContentList = if (!languageCode.isNullOrBlank()) { + val contentIds = contentList.map { it.contentId } + + if (contentIds.isNotEmpty()) { + val translations = contentTranslationRepository + .findByContentIdInAndLocale(contentIds = contentIds, locale = languageCode) + .associateBy { it.contentId } + + contentList.map { item -> + val translatedTitle = translations[item.contentId]?.renderedPayload?.title + if (translatedTitle.isNullOrBlank()) { + item + } else { + item.copy(title = translatedTitle) + } + } + } else { + contentList + } + } else { + contentList + } + + return GetNewContentAllResponse(totalCount, translatedContentList) } @Transactional(readOnly = true)