feat(creator-community): 작성과 상세에 본문 번역을 적용한다

This commit is contained in:
2026-09-10 15:13:40 +09:00
parent 1b19ade69e
commit 11e29460b7
3 changed files with 629 additions and 15 deletions
@@ -27,6 +27,7 @@ import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
import kr.co.vividnext.sodalive.utils.generateFileName
import kr.co.vividnext.sodalive.utils.validateImage
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
import kr.co.vividnext.sodalive.v2.home.following.application.HomeFollowingNewsPublishService
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
@@ -39,6 +40,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import org.springframework.web.multipart.MultipartFile
import java.time.LocalDateTime
import java.time.ZoneId
import javax.persistence.EntityManager
import javax.persistence.LockModeType
@Service
@Transactional(readOnly = true)
@@ -58,6 +61,8 @@ class CreatorCommunityService(
private val messageSource: SodaMessageSource,
private val langContext: LangContext,
private val homeFollowingNewsPublishService: HomeFollowingNewsPublishService,
private val creatorCommunityTranslationService: CreatorCommunityTranslationService,
private val entityManager: EntityManager,
@Value("\${cloud.aws.s3.bucket}")
private val imageBucket: String,
@@ -144,6 +149,7 @@ class CreatorCommunityService(
)
)
publishCommunityPostCreatedAfterCommit(post, member)
requestTranslationsAfterCommit(post.id!!)
}
private fun publishCommunityPostCreatedAfterCommit(post: CreatorCommunity, member: Member) {
@@ -166,6 +172,12 @@ class CreatorCommunityService(
}
}
private fun requestTranslationsAfterCommit(postId: Long) {
afterCommit {
creatorCommunityTranslationService.requestTranslations(postId, null)
}
}
private fun CreatorCommunity.newsContentPreview(): String {
if (price <= 0) {
return content
@@ -199,13 +211,17 @@ class CreatorCommunityService(
fun modifyCommunityPost(postImage: MultipartFile?, requestString: String, member: Member) {
val request = objectMapper.readValue(requestString, ModifyCommunityPostRequest::class.java)
val post = repository.findByIdAndMemberId(id = request.creatorCommunityId, memberId = member.id!!)
val post = repository.findByIdAndMemberIdForUpdate(postId = request.creatorCommunityId, memberId = member.id!!)
?: throw SodaException(messageKey = "common.error.invalid_request")
entityManager.refresh(post, LockModeType.PESSIMISTIC_WRITE)
postImage?.let { validateImage(it, post.price > 0) }
if (request.content != null) {
if (request.content != null && request.content != post.content) {
post.content = request.content
post.languageCode = null
post.contentRevision += 1
requestTranslationsAfterCommit(post.id!!)
}
if (request.isCommentAvailable != null) {
@@ -246,8 +262,9 @@ class CreatorCommunityService(
@Transactional
fun updateCommunityPostFixed(request: UpdateCommunityPostFixedRequest, member: Member) {
val post = repository.findByIdAndMemberId(id = request.postId, memberId = member.id!!)
val post = repository.findByIdAndMemberIdForUpdate(postId = request.postId, memberId = member.id!!)
?: throw SodaException(messageKey = "common.error.invalid_request")
entityManager.refresh(post, LockModeType.PESSIMISTIC_WRITE)
if (request.isFixed) {
if (!post.isFixed) {
@@ -285,6 +302,8 @@ class CreatorCommunityService(
limit = limit,
isAdult = isAdult
)
val displayContents = creatorCommunityTranslationService
.findDisplayContents(postList.map { it.id }, langContext.lang.code)
return postList
.map {
@@ -337,7 +356,7 @@ class CreatorCommunityService(
null
}
it.toCommunityPostListResponse(
it.copy(content = displayContents[it.id]?.content ?: it.content).toCommunityPostListResponse(
imageHost = imageHost,
audioUrl = audioUrl,
date = it.date.getTimeAgoString(),
@@ -376,6 +395,12 @@ class CreatorCommunityService(
throw SodaException(message = String.format(messageTemplate, post.creatorNickname))
}
val displayContent = creatorCommunityTranslationService
.findDisplayContents(listOf(post.id), langContext.lang.code)[post.id]
if (displayContent?.hasValidTranslation != true) {
creatorCommunityTranslationService.requestTranslations(post.id, langContext.lang.code)
}
val isLike = likeRepository.findByPostIdAndMemberId(postId = post.id, memberId = memberId)?.isActive ?: false
val likeCount = likeRepository.totalCountCommunityPostLikeByPostId(post.id)
val commentCount = if (post.isCommentAvailable) {
@@ -417,7 +442,7 @@ class CreatorCommunityService(
null
}
return post.toCommunityPostListResponse(
return post.copy(content = displayContent?.content ?: post.content).toCommunityPostListResponse(
imageHost = imageHost,
audioUrl = audioUrl,
date = post.date.getTimeAgoString(),
@@ -610,11 +635,13 @@ class CreatorCommunityService(
isAdult: Boolean
): List<GetCommunityPostListResponse> {
val postList = repository.getLatestPostListFromCreatorsYouFollow(memberId = memberId, isAdult = isAdult)
val visiblePostList = postList.filter {
!isBlockedBetweenMembers(memberId = memberId, creatorId = it.creatorId)
}
val displayContents = creatorCommunityTranslationService
.findDisplayContents(visiblePostList.map { it.id }, langContext.lang.code)
return postList
.filter {
!isBlockedBetweenMembers(memberId = memberId, creatorId = it.creatorId)
}
return visiblePostList
.map {
val isLike =
likeRepository.findByPostIdAndMemberId(postId = it.id, memberId = memberId)?.isActive ?: false
@@ -649,7 +676,7 @@ class CreatorCommunityService(
val existOrdered = useCanRepository.isExistCommunityPostOrdered(postId = it.id, memberId = memberId)
it.toCommunityPostListResponse(
it.copy(content = displayContents[it.id]?.content ?: it.content).toCommunityPostListResponse(
imageHost = imageHost,
audioUrl = null,
date = it.date.getTimeAgoString(),