크리에이터 시리즈 메시지 다국어 처리

크리에이터 정산/시리즈 API 응답 메시지를 다국어 키로 제공한다.
This commit is contained in:
2025-12-23 17:09:59 +09:00
parent f38382d2be
commit 291f9a265b
6 changed files with 132 additions and 34 deletions

View File

@@ -21,7 +21,7 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate
@RequestParam endDateStr: String,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.getCalculateLive(startDateStr, endDateStr, member))
}
@@ -32,7 +32,7 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
pageable: Pageable
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.getCalculateContentList(
startDateStr,
@@ -49,7 +49,7 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
pageable: Pageable
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.getCumulativeSalesByContent(member.id!!, pageable.offset, pageable.pageSize.toLong()))
}
@@ -61,7 +61,7 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
pageable: Pageable
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.getCalculateContentDonationList(
startDateStr,
@@ -80,7 +80,7 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
pageable: Pageable
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.getCalculateCommunityPost(

View File

@@ -26,13 +26,13 @@ data class CreateSeriesRequest(
}
private fun validate() {
if (title.isBlank()) throw SodaException("시리즈 제목을 입력하세요")
if (introduction.isBlank()) throw SodaException("시리즈 소개를 입력하세요")
if (keyword.isBlank()) throw SodaException("시리즈를 설명할 수 있는 키워드를 입력하세요")
if (genreId <= 0) throw SodaException("올바른 장르를 선택하세요")
if (publishedDaysOfWeek.isEmpty()) throw SodaException("시리즈 연재요일을 선택하세요")
if (title.isBlank()) throw SodaException(messageKey = "creator.admin.series.title_required")
if (introduction.isBlank()) throw SodaException(messageKey = "creator.admin.series.introduction_required")
if (keyword.isBlank()) throw SodaException(messageKey = "creator.admin.series.keyword_required")
if (genreId <= 0) throw SodaException(messageKey = "creator.admin.series.genre_required")
if (publishedDaysOfWeek.isEmpty()) throw SodaException(messageKey = "creator.admin.series.published_days_required")
if (publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM) && publishedDaysOfWeek.size > 1) {
throw SodaException("랜덤과 연재요일 동시에 선택할 수 없습니다.")
throw SodaException(messageKey = "creator.admin.series.published_days_random_exclusive")
}
}
}

View File

@@ -4,6 +4,8 @@ import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.creator.admin.content.series.content.AddingContentToTheSeriesRequest
import kr.co.vividnext.sodalive.creator.admin.content.series.content.RemoveContentToTheSeriesRequest
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
import kr.co.vividnext.sodalive.member.Member
import org.springframework.data.domain.Pageable
import org.springframework.lang.Nullable
@@ -23,16 +25,23 @@ import org.springframework.web.multipart.MultipartFile
@RestController
@PreAuthorize("hasRole('CREATOR')")
@RequestMapping("/creator-admin/audio-content/series")
class CreatorAdminContentSeriesController(private val service: CreatorAdminContentSeriesService) {
class CreatorAdminContentSeriesController(
private val service: CreatorAdminContentSeriesService,
private val messageSource: SodaMessageSource,
private val langContext: LangContext
) {
@PostMapping
fun createSeries(
@RequestPart("image") image: MultipartFile?,
@RequestPart("request") requestString: String,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.createSeries(image, requestString, member), "시리즈가 생성되었습니다.")
ApiResponse.ok(
service.createSeries(image, requestString, member),
messageSource.getMessage("creator.admin.series.created", langContext.lang)
)
}
@PutMapping
@@ -43,9 +52,12 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@RequestPart("request") requestString: String,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.modifySeries(image, requestString, member), "시리즈가 수정되었습니다.")
ApiResponse.ok(
service.modifySeries(image, requestString, member),
messageSource.getMessage("creator.admin.series.updated", langContext.lang)
)
}
@GetMapping
@@ -53,7 +65,7 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
pageable: Pageable,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.getSeriesList(
@@ -69,7 +81,7 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@PathVariable id: Long,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.getDetail(id = id, memberId = member.id!!))
}
@@ -80,7 +92,7 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
pageable: Pageable
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.getSeriesContent(
@@ -97,11 +109,11 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@RequestBody request: AddingContentToTheSeriesRequest,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.addingContentToTheSeries(request, memberId = member.id!!),
"콘텐츠가 추가되었습니다."
messageSource.getMessage("creator.admin.series.content_added", langContext.lang)
)
}
@@ -110,11 +122,11 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@RequestBody request: RemoveContentToTheSeriesRequest,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.removeContentInTheSeries(request, memberId = member.id!!),
"콘텐츠를 삭제하였습니다."
messageSource.getMessage("creator.admin.series.content_removed", langContext.lang)
)
}
@@ -124,7 +136,7 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@RequestParam(value = "search_word") searchWord: String,
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(
service.searchContentNotInSeries(
@@ -138,5 +150,8 @@ class CreatorAdminContentSeriesController(private val service: CreatorAdminConte
@PutMapping("/orders")
fun updateSeriesOrders(
@RequestBody request: UpdateOrdersRequest
) = ApiResponse.ok(service.updateSeriesOrders(ids = request.ids), "수정되었습니다.")
) = ApiResponse.ok(
service.updateSeriesOrders(ids = request.ids),
messageSource.getMessage("creator.admin.series.orders_updated", langContext.lang)
)
}

View File

@@ -45,7 +45,7 @@ class CreatorAdminContentSeriesService(
) {
@Transactional
fun createSeries(coverImage: MultipartFile?, requestString: String, member: Member) {
if (coverImage == null) throw SodaException("커버이미지를 선택해 주세요.")
if (coverImage == null) throw SodaException(messageKey = "creator.admin.series.cover_image_required")
val request = objectMapper.readValue(requestString, CreateSeriesRequest::class.java)
val series = request.toSeries()
@@ -139,11 +139,11 @@ class CreatorAdminContentSeriesService(
request.studio == null &&
request.isActive == null
) {
throw SodaException("변경사항이 없습니다.")
throw SodaException(messageKey = "creator.admin.series.no_changes")
}
val series = repository.findByIdAndCreatorId(id = request.seriesId, creatorId = member.id!!)
?: throw SodaException("잘못된 접근입니다.")
?: throw SodaException(messageKey = "creator.admin.series.invalid_access")
if (coverImage != null) {
val metadata = ObjectMetadata()
@@ -175,7 +175,7 @@ class CreatorAdminContentSeriesService(
request.publishedDaysOfWeek.contains(SeriesPublishedDaysOfWeek.RANDOM) &&
request.publishedDaysOfWeek.size > 1
) {
throw SodaException("랜덤과 연재요일 동시에 선택할 수 없습니다.")
throw SodaException(messageKey = "creator.admin.series.published_days_random_exclusive")
}
series.publishedDaysOfWeek.clear()
@@ -245,7 +245,7 @@ class CreatorAdminContentSeriesService(
fun getDetail(id: Long, memberId: Long): GetCreatorAdminContentSeriesDetailResponse {
val series = repository.findByIdAndCreatorId(id = id, creatorId = memberId)
?: throw SodaException("잘못된 접근입니다.")
?: throw SodaException(messageKey = "creator.admin.series.invalid_access")
return series.toDetailResponse(imageHost = coverImageHost)
}
@@ -271,7 +271,7 @@ class CreatorAdminContentSeriesService(
@Transactional
fun addingContentToTheSeries(request: AddingContentToTheSeriesRequest, memberId: Long) {
val series = repository.findByIdAndCreatorId(id = request.seriesId, creatorId = memberId)
?: throw SodaException("잘못된 접근입니다.")
?: throw SodaException(messageKey = "creator.admin.series.invalid_access")
val seriesContentList = mutableListOf<SeriesContent>()
@@ -288,14 +288,14 @@ class CreatorAdminContentSeriesService(
if (seriesContentList.size > 0) {
series.contentList.addAll(seriesContentList.toSet())
} else {
throw SodaException("추가된 콘텐츠가 없습니다.")
throw SodaException(messageKey = "creator.admin.series.no_content_added")
}
}
@Transactional
fun removeContentInTheSeries(request: RemoveContentToTheSeriesRequest, memberId: Long) {
val series = repository.findByIdAndCreatorId(id = request.seriesId, creatorId = memberId)
?: throw SodaException("잘못된 접근입니다.")
?: throw SodaException(messageKey = "creator.admin.series.invalid_access")
series.contentList.removeIf { it.content!!.id == request.contentId }
}

View File

@@ -17,7 +17,7 @@ class CreatorAdminContentSeriesGenreController(private val service: CreatorAdmin
fun getGenreList(
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
ApiResponse.ok(service.getGenreList(isAdult = member.auth != null))
}

View File

@@ -1172,6 +1172,87 @@ class SodaMessageSource {
)
)
private val creatorAdminSeriesRequestMessages = mapOf(
"creator.admin.series.title_required" to mapOf(
Lang.KO to "시리즈 제목을 입력하세요",
Lang.EN to "Please enter a series title.",
Lang.JA to "シリーズのタイトルを入力してください。"
),
"creator.admin.series.introduction_required" to mapOf(
Lang.KO to "시리즈 소개를 입력하세요",
Lang.EN to "Please enter a series introduction.",
Lang.JA to "シリーズ紹介を入力してください。"
),
"creator.admin.series.keyword_required" to mapOf(
Lang.KO to "시리즈를 설명할 수 있는 키워드를 입력하세요",
Lang.EN to "Please enter keywords that describe the series.",
Lang.JA to "シリーズを説明できるキーワードを入力してください。"
),
"creator.admin.series.genre_required" to mapOf(
Lang.KO to "올바른 장르를 선택하세요",
Lang.EN to "Please select a valid genre.",
Lang.JA to "正しいジャンルを選択してください。"
),
"creator.admin.series.published_days_required" to mapOf(
Lang.KO to "시리즈 연재요일을 선택하세요",
Lang.EN to "Please select publishing days.",
Lang.JA to "シリーズの連載曜日を選択してください。"
),
"creator.admin.series.published_days_random_exclusive" to mapOf(
Lang.KO to "랜덤과 연재요일 동시에 선택할 수 없습니다.",
Lang.EN to "You cannot select random and specific days at the same time.",
Lang.JA to "ランダムと連載曜日を同時に選択することはできません。"
),
"creator.admin.series.cover_image_required" to mapOf(
Lang.KO to "커버이미지를 선택해 주세요.",
Lang.EN to "Please select a cover image.",
Lang.JA to "カバー画像を選択してください。"
),
"creator.admin.series.no_changes" to mapOf(
Lang.KO to "변경사항이 없습니다.",
Lang.EN to "No changes to update.",
Lang.JA to "変更事項がありません。"
),
"creator.admin.series.invalid_access" to mapOf(
Lang.KO to "잘못된 접근입니다.",
Lang.EN to "Invalid access.",
Lang.JA to "不正なアクセスです。"
),
"creator.admin.series.no_content_added" to mapOf(
Lang.KO to "추가된 콘텐츠가 없습니다.",
Lang.EN to "No content was added.",
Lang.JA to "追加されたコンテンツがありません。"
)
)
private val creatorAdminSeriesMessages = mapOf(
"creator.admin.series.created" to mapOf(
Lang.KO to "시리즈가 생성되었습니다.",
Lang.EN to "Series created.",
Lang.JA to "シリーズが作成されました。"
),
"creator.admin.series.updated" to mapOf(
Lang.KO to "시리즈가 수정되었습니다.",
Lang.EN to "Series updated.",
Lang.JA to "シリーズが更新されました。"
),
"creator.admin.series.content_added" to mapOf(
Lang.KO to "콘텐츠가 추가되었습니다.",
Lang.EN to "Content added.",
Lang.JA to "コンテンツが追加されました。"
),
"creator.admin.series.content_removed" to mapOf(
Lang.KO to "콘텐츠를 삭제하였습니다.",
Lang.EN to "Content removed.",
Lang.JA to "コンテンツが削除されました。"
),
"creator.admin.series.orders_updated" to mapOf(
Lang.KO to "수정되었습니다.",
Lang.EN to "Updated.",
Lang.JA to "更新されました。"
)
)
private val creatorCommunityMessages = mapOf(
"creator.community.paid_post_image_required" to mapOf(
Lang.KO to "유료 게시글 등록을 위해서는 이미지가 필요합니다.",
@@ -1262,6 +1343,8 @@ class SodaMessageSource {
creatorAdminMemberMessages,
creatorAdminSignatureMessages,
creatorAdminContentMessages,
creatorAdminSeriesRequestMessages,
creatorAdminSeriesMessages,
creatorCommunityMessages
)
for (messages in messageGroups) {