번역 제목 조회 방식 수정

This commit is contained in:
2026-02-13 16:47:22 +09:00
parent 88612b3479
commit 999507ee15
2 changed files with 79 additions and 46 deletions

View File

@@ -6,6 +6,7 @@ import kr.co.vividnext.sodalive.content.ContentType
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment import kr.co.vividnext.sodalive.content.comment.QAudioContentComment.audioContentComment
import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike import kr.co.vividnext.sodalive.content.like.QAudioContentLike.audioContentLike
import kr.co.vividnext.sodalive.content.translation.ContentTranslationPayload
import kr.co.vividnext.sodalive.content.translation.QContentTranslation.contentTranslation import kr.co.vividnext.sodalive.content.translation.QContentTranslation.contentTranslation
import kr.co.vividnext.sodalive.member.MemberRole import kr.co.vividnext.sodalive.member.MemberRole
import kr.co.vividnext.sodalive.member.QMember.member import kr.co.vividnext.sodalive.member.QMember.member
@@ -101,30 +102,23 @@ class RecommendChannelQueryRepository(
where = where.and(audioContent.isAdult.isFalse) where = where.and(audioContent.isAdult.isFalse)
} }
val titleExpression = if (locale != null) { val coverImageUrl = audioContent.coverImage.prepend("/").prepend(imageHost)
val translatedTitle = Expressions.stringTemplate( val payloadExpression = if (locale != null) {
"JSON_EXTRACT({0}, '$.title')", contentTranslation.renderedPayload
contentTranslation.renderedPayload
)
val coalesceTitle = Expressions.stringTemplate(
"COALESCE(NULLIF({0}, ''), {1})",
translatedTitle,
audioContent.title
)
coalesceTitle
} else { } else {
audioContent.title Expressions.nullExpression(ContentTranslationPayload::class.java)
} }
val likeCountExpression = audioContentLike.id.countDistinct()
val commentCountExpression = audioContentComment.id.countDistinct()
var select = queryFactory var select = queryFactory
.select( .select(
QRecommendChannelContentItem( audioContent.id,
audioContent.id, audioContent.title,
titleExpression, payloadExpression,
audioContent.coverImage.prepend("/").prepend(imageHost), coverImageUrl,
audioContentLike.id.countDistinct(), likeCountExpression,
audioContentComment.id.countDistinct() commentCountExpression
)
) )
.from(audioContent) .from(audioContent)
.leftJoin(audioContentLike) .leftJoin(audioContentLike)
@@ -151,11 +145,29 @@ class RecommendChannelQueryRepository(
select = select.leftJoin(blockMember).on(blockMemberCondition) select = select.leftJoin(blockMember).on(blockMemberCondition)
} }
return select val results = select
.where(where) .where(where)
.groupBy(audioContent.id) .groupBy(audioContent.id)
.orderBy(audioContentLike.id.countDistinct().desc()) .orderBy(likeCountExpression.desc())
.limit(3) .limit(3)
.fetch() .fetch()
return results.map { row ->
val contentId = row.get(audioContent.id)!!
val originTitle = row.get(audioContent.title)!!
val payload = row.get(payloadExpression)
val translatedTitle = payload?.title
val thumbnailImageUrl = row.get(coverImageUrl)!!
val likeCount = row.get(likeCountExpression) ?: 0L
val commentCount = row.get(commentCountExpression) ?: 0L
RecommendChannelContentItem(
contentId = contentId,
title = if (translatedTitle.isNullOrBlank()) originTitle else translatedTitle,
thumbnailImageUrl = thumbnailImageUrl,
likeCount = likeCount,
commentCount = commentCount
)
}
} }
} }

View File

@@ -13,6 +13,7 @@ import kr.co.vividnext.sodalive.content.main.QContentCreatorResponse
import kr.co.vividnext.sodalive.content.main.QGetAudioContentRankingItem import kr.co.vividnext.sodalive.content.main.QGetAudioContentRankingItem
import kr.co.vividnext.sodalive.content.order.QOrder.order import kr.co.vividnext.sodalive.content.order.QOrder.order
import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme import kr.co.vividnext.sodalive.content.theme.QAudioContentTheme.audioContentTheme
import kr.co.vividnext.sodalive.content.translation.ContentTranslationPayload
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series import kr.co.vividnext.sodalive.creator.admin.content.series.QSeries.series
import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent import kr.co.vividnext.sodalive.creator.admin.content.series.QSeriesContent.seriesContent
import kr.co.vividnext.sodalive.creator.admin.content.series.Series import kr.co.vividnext.sodalive.creator.admin.content.series.Series
@@ -112,35 +113,27 @@ class RankingRepository(
where = where.and(audioContentTheme.theme.eq(theme)) where = where.and(audioContentTheme.theme.eq(theme))
} }
val titleExpression = if (locale != null) { val coverImageUrl = audioContent.coverImage.prepend("/").prepend(imageHost)
val translatedTitle = Expressions.stringTemplate( val creatorProfileImageUrl = member.profileImage.prepend("/").prepend(imageHost)
"JSON_EXTRACT({0}, '$.title')", val payloadExpression = if (locale != null) {
contentTranslation.renderedPayload contentTranslation.renderedPayload
)
val coalesceTitle = Expressions.stringTemplate(
"COALESCE(NULLIF({0}, ''), {1})",
translatedTitle,
audioContent.title
)
coalesceTitle
} else { } else {
audioContent.title Expressions.nullExpression(ContentTranslationPayload::class.java)
} }
var select = queryFactory var select = queryFactory
.select( .select(
QGetAudioContentRankingItem( audioContent.id,
audioContent.id, audioContent.title,
titleExpression, payloadExpression,
audioContent.coverImage.prepend("/").prepend(imageHost), coverImageUrl,
audioContentTheme.theme, audioContentTheme.theme,
audioContent.price, audioContent.price,
audioContent.duration, audioContent.duration,
member.id, member.id,
member.nickname, member.nickname,
audioContent.isPointAvailable, audioContent.isPointAvailable,
member.profileImage.prepend("/").prepend(imageHost) creatorProfileImageUrl
)
) )
select = when (sortType) { select = when (sortType) {
@@ -258,10 +251,38 @@ class RankingRepository(
} }
} }
return select val results = select
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
.fetch() .fetch()
return results.map { row ->
val contentId = row.get(audioContent.id)!!
val originTitle = row.get(audioContent.title)!!
val payload = row.get(payloadExpression)
val translatedTitle = payload?.title
val imageUrl = row.get(coverImageUrl)!!
val themeStr = row.get(audioContentTheme.theme) ?: ""
val price = row.get(audioContent.price) ?: 0
val duration = row.get(audioContent.duration) ?: ""
val creatorId = row.get(member.id)!!
val creatorNickname = row.get(member.nickname)!!
val isPointAvailable = row.get(audioContent.isPointAvailable) ?: false
val creatorProfileImageUrlValue = row.get(creatorProfileImageUrl)!!
GetAudioContentRankingItem(
contentId = contentId,
title = if (translatedTitle.isNullOrBlank()) originTitle else translatedTitle,
coverImageUrl = imageUrl,
themeStr = themeStr,
price = price,
duration = duration,
creatorId = creatorId,
creatorNickname = creatorNickname,
isPointAvailable = isPointAvailable,
creatorProfileImageUrl = creatorProfileImageUrlValue
)
}
} }
fun getSeriesRanking( fun getSeriesRanking(