오디션 메시지 다국어 처리

This commit is contained in:
2025-12-22 18:54:10 +09:00
parent ff1b8aa413
commit 8785741855
4 changed files with 65 additions and 10 deletions

View File

@@ -7,6 +7,8 @@ import kr.co.vividnext.sodalive.aws.s3.S3Uploader
import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.fcm.FcmEvent import kr.co.vividnext.sodalive.fcm.FcmEvent
import kr.co.vividnext.sodalive.fcm.FcmEventType import kr.co.vividnext.sodalive.fcm.FcmEventType
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
import kr.co.vividnext.sodalive.utils.generateFileName import kr.co.vividnext.sodalive.utils.generateFileName
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.context.ApplicationEventPublisher import org.springframework.context.ApplicationEventPublisher
@@ -22,6 +24,8 @@ class AdminAuditionService(
private val repository: AdminAuditionRepository, private val repository: AdminAuditionRepository,
private val roleRepository: AdminAuditionRoleRepository, private val roleRepository: AdminAuditionRoleRepository,
private val applicationEventPublisher: ApplicationEventPublisher, private val applicationEventPublisher: ApplicationEventPublisher,
private val langContext: LangContext,
private val messageSource: SodaMessageSource,
@Value("\${cloud.aws.s3.bucket}") @Value("\${cloud.aws.s3.bucket}")
private val bucket: String private val bucket: String
@@ -44,7 +48,7 @@ class AdminAuditionService(
fun updateAudition(image: MultipartFile?, requestString: String) { fun updateAudition(image: MultipartFile?, requestString: String) {
val request = objectMapper.readValue(requestString, UpdateAuditionRequest::class.java) val request = objectMapper.readValue(requestString, UpdateAuditionRequest::class.java)
val audition = repository.findByIdOrNull(id = request.id) val audition = repository.findByIdOrNull(id = request.id)
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.") ?: throw SodaException(messageKey = "admin.audition.invalid_request_retry")
if (request.title != null) { if (request.title != null) {
audition.title = request.title audition.title = request.title
@@ -63,7 +67,7 @@ class AdminAuditionService(
(audition.status == AuditionStatus.COMPLETED || audition.status == AuditionStatus.IN_PROGRESS) && (audition.status == AuditionStatus.COMPLETED || audition.status == AuditionStatus.IN_PROGRESS) &&
request.status == AuditionStatus.NOT_STARTED request.status == AuditionStatus.NOT_STARTED
) { ) {
throw SodaException("모집전 상태로 변경할 수 없습니다.") throw SodaException(messageKey = "admin.audition.status_cannot_revert")
} }
audition.status = request.status audition.status = request.status
@@ -88,11 +92,14 @@ class AdminAuditionService(
} }
if (request.status != null && request.status == AuditionStatus.IN_PROGRESS && audition.isActive) { if (request.status != null && request.status == AuditionStatus.IN_PROGRESS && audition.isActive) {
val title = messageSource.getMessage("admin.audition.fcm.title.new", langContext.lang).orEmpty()
val messageTemplate = messageSource.getMessage("admin.audition.fcm.message.new", langContext.lang).orEmpty()
val message = String.format(messageTemplate, audition.title)
applicationEventPublisher.publishEvent( applicationEventPublisher.publishEvent(
FcmEvent( FcmEvent(
type = FcmEventType.IN_PROGRESS_AUDITION, type = FcmEventType.IN_PROGRESS_AUDITION,
title = "새로운 오디션 등록!", title = title,
message = "'${audition.title}'이 등록되었습니다. 지금 바로 오리지널 오디오 드라마 오디션에 지원해보세요!", message = message,
isAuth = audition.isAdult, isAuth = audition.isAdult,
auditionId = audition.id ?: -1 auditionId = audition.id ?: -1
) )

View File

@@ -11,11 +11,11 @@ data class CreateAuditionRequest(
) { ) {
init { init {
if (title.isBlank()) { if (title.isBlank()) {
throw SodaException("오디션 제목을 입력하세요") throw SodaException(messageKey = "admin.audition.title_required")
} }
if (information.isBlank() || information.length < 10) { if (information.isBlank() || information.length < 10) {
throw SodaException("오디션 정보는 최소 10글자 입니다") throw SodaException(messageKey = "admin.audition.information_min_length")
} }
} }

View File

@@ -10,7 +10,7 @@ class AdminAuditionApplicantService(private val repository: AdminAuditionApplica
@Transactional @Transactional
fun deleteAuditionApplicant(id: Long) { fun deleteAuditionApplicant(id: Long) {
val applicant = repository.findByIdOrNull(id) val applicant = repository.findByIdOrNull(id)
?: throw SodaException("잘못된 요청입니다.") ?: throw SodaException(messageKey = "common.error.invalid_request")
applicant.isActive = false applicant.isActive = false
} }

View File

@@ -4,7 +4,7 @@ import org.springframework.stereotype.Component
@Component @Component
class SodaMessageSource { class SodaMessageSource {
private val messages = mapOf( private val commonMessages = mapOf(
"common.error.unknown" to mapOf( "common.error.unknown" to mapOf(
Lang.KO to "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.", Lang.KO to "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.",
Lang.EN to "An unknown error occurred. Please try again.", Lang.EN to "An unknown error occurred. Please try again.",
@@ -42,8 +42,56 @@ class SodaMessageSource {
) )
) )
private val auditionMessages = mapOf(
"admin.audition.invalid_request_retry" to mapOf(
Lang.KO to "잘못된 요청입니다.\n다시 시도해 주세요.",
Lang.EN to "Invalid request. Please try again.",
Lang.JA to "不正なリクエストです。もう一度やり直してください。"
),
"admin.audition.status_cannot_revert" to mapOf(
Lang.KO to "모집전 상태로 변경할 수 없습니다.",
Lang.EN to "Cannot change to not-started status.",
Lang.JA to "募集前の状態に変更できません。"
)
)
private val auditionRequestMessages = mapOf(
"admin.audition.title_required" to mapOf(
Lang.KO to "오디션 제목을 입력하세요",
Lang.EN to "Please enter an audition title.",
Lang.JA to "オーディションのタイトルを入力してください。"
),
"admin.audition.information_min_length" to mapOf(
Lang.KO to "오디션 정보는 최소 10글자 입니다",
Lang.EN to "Audition information must be at least 10 characters.",
Lang.JA to "オーディション情報は最低10文字です。"
)
)
private val auditionNotificationMessages = mapOf(
"admin.audition.fcm.title.new" to mapOf(
Lang.KO to "새로운 오디션 등록!",
Lang.EN to "New audition posted!",
Lang.JA to "新しいオーディション登録!"
),
"admin.audition.fcm.message.new" to mapOf(
Lang.KO to "'%s'이 등록되었습니다. 지금 바로 오리지널 오디오 드라마 오디션에 지원해보세요!",
Lang.EN to "'%s' is now available. Apply for the original audio drama audition now!",
Lang.JA to "「%s」が登録されました。今すぐオリジナルオーディオドラマのオーディションに応募してみてください"
)
)
fun getMessage(key: String, lang: Lang): String? { fun getMessage(key: String, lang: Lang): String? {
val translations = messages[key] ?: return null val messageGroups = listOf(
commonMessages,
auditionMessages,
auditionRequestMessages,
auditionNotificationMessages
)
for (messages in messageGroups) {
val translations = messages[key] ?: continue
return translations[lang] ?: translations[Lang.KO] return translations[lang] ?: translations[Lang.KO]
} }
return null
}
} }