콘텐츠 메시지 다국어 처리
This commit is contained in:
@@ -36,7 +36,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.createAudioContent(
|
||||
@@ -57,7 +57,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.modifyAudioContent(
|
||||
@@ -74,7 +74,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestBody request: UploadCompleteRequest,
|
||||
@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.uploadComplete(
|
||||
@@ -91,7 +91,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.deleteAudioContent(
|
||||
@@ -111,7 +111,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.getAudioContentList(
|
||||
@@ -134,7 +134,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
|
||||
@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(
|
||||
@@ -151,7 +151,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.generateUrl(contentId = id, member = member))
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestBody request: AddAllPlaybackTrackingRequest,
|
||||
@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.addAllPlaybackTracking(request, member))
|
||||
}
|
||||
@@ -170,7 +170,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@RequestBody request: PutAudioContentLikeRequest,
|
||||
@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.audioContentLike(request, member))
|
||||
}
|
||||
@@ -179,7 +179,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
fun getAudioContentRankingSort(
|
||||
@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.getContentRankingSortTypeList())
|
||||
}
|
||||
@@ -221,7 +221,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.pinToTheTop(contentId = id, member = member))
|
||||
}
|
||||
@@ -232,7 +232,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.unpinAtTheTop(contentId = id, member = member))
|
||||
}
|
||||
@@ -248,7 +248,7 @@ class AudioContentController(private val service: AudioContentService) {
|
||||
@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.getLatestContentByTheme(
|
||||
|
||||
@@ -31,6 +31,7 @@ import kr.co.vividnext.sodalive.extensions.convertLocalDateTime
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
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.i18n.translation.LanguageTranslationEvent
|
||||
import kr.co.vividnext.sodalive.i18n.translation.LanguageTranslationTargetType
|
||||
import kr.co.vividnext.sodalive.i18n.translation.PapagoTranslationService
|
||||
@@ -74,6 +75,7 @@ class AudioContentService(
|
||||
private val audioContentCloudFront: AudioContentCloudFront,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
|
||||
private val contentThemeTranslationRepository: ContentThemeTranslationRepository,
|
||||
@@ -117,7 +119,7 @@ class AudioContentService(
|
||||
val request = objectMapper.readValue(requestString, ModifyAudioContentRequest::class.java)
|
||||
|
||||
val audioContent = repository.findByIdAndCreatorId(request.contentId, member.id!!)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
if (request.title != null) audioContent.title = request.title
|
||||
if (request.detail != null) audioContent.detail = request.detail
|
||||
@@ -189,7 +191,7 @@ class AudioContentService(
|
||||
@Transactional
|
||||
fun deleteAudioContent(audioContentId: Long, member: Member) {
|
||||
val audioContent = repository.findByIdAndCreatorId(audioContentId, member.id!!)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
audioContent.isActive = false
|
||||
audioContent.releaseDate = null
|
||||
@@ -203,7 +205,7 @@ class AudioContentService(
|
||||
member: Member
|
||||
): CreateAudioContentResponse {
|
||||
// coverImage 체크
|
||||
if (coverImage == null) throw SodaException("커버이미지를 선택해 주세요.")
|
||||
if (coverImage == null) throw SodaException(messageKey = "content.error.cover_image_required")
|
||||
|
||||
// request 내용 파싱
|
||||
val request = objectMapper.readValue(requestString, CreateAudioContentRequest::class.java)
|
||||
@@ -222,18 +224,18 @@ class AudioContentService(
|
||||
|
||||
// contentFile 체크
|
||||
if (contentFile == null) {
|
||||
throw SodaException("콘텐츠를 선택해 주세요.")
|
||||
throw SodaException(messageKey = "content.error.content_required")
|
||||
}
|
||||
|
||||
// 테마 체크
|
||||
val theme = themeQueryRepository.findThemeByIdAndActive(id = request.themeId)
|
||||
?: throw SodaException("잘못된 테마입니다. 다시 선택해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_theme")
|
||||
|
||||
if ((request.themeId == 12L || request.themeId == 13L || request.themeId == 14L) && request.price < 5) {
|
||||
throw SodaException("알람, 모닝콜, 슬립콜 테마의 콘텐츠는 5캔 이상의 유료콘텐츠로 등록이 가능합니다.")
|
||||
throw SodaException(messageKey = "content.error.alarm_theme_price_min")
|
||||
}
|
||||
|
||||
if (request.price in 1..4) throw SodaException("콘텐츠의 최소금액은 5캔 입니다.")
|
||||
if (request.price in 1..4) throw SodaException(messageKey = "content.error.minimum_price")
|
||||
|
||||
val isFullDetailVisible = if (request.price >= 50) {
|
||||
request.isFullDetailVisible
|
||||
@@ -388,34 +390,34 @@ class AudioContentService(
|
||||
if (previewStartTime != null && previewEndTime != null) {
|
||||
val startTimeArray = previewStartTime.split(":")
|
||||
if (startTimeArray.size != 3) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
|
||||
for (time in startTimeArray) {
|
||||
if (time.length != 2) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
}
|
||||
|
||||
val endTimeArray = previewEndTime.split(":")
|
||||
if (endTimeArray.size != 3) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
|
||||
for (time in endTimeArray) {
|
||||
if (time.length != 2) {
|
||||
throw SodaException("미리 듣기 시간 형식은 00:30:00 과 같아야 합니다")
|
||||
throw SodaException(messageKey = "content.error.preview_time_format")
|
||||
}
|
||||
}
|
||||
|
||||
val timeDifference = timeDifference(previewStartTime, previewEndTime)
|
||||
|
||||
if (timeDifference < 15000) {
|
||||
throw SodaException("미리 듣기의 최소 시간은 15초 입니다.")
|
||||
throw SodaException(messageKey = "content.error.preview_time_minimum")
|
||||
}
|
||||
} else {
|
||||
if (previewStartTime != null || previewEndTime != null) {
|
||||
throw SodaException("미리 듣기 시작 시간과 종료 시간 둘 다 입력을 하거나 둘 다 입력 하지 않아야 합니다.")
|
||||
throw SodaException(messageKey = "content.error.preview_time_both_required")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,10 +447,10 @@ class AudioContentService(
|
||||
@Transactional
|
||||
fun uploadComplete(contentId: Long, content: String, duration: String) {
|
||||
val keyFileName = content.split("/").last()
|
||||
if (!keyFileName.startsWith(contentId.toString())) throw SodaException("잘못된 요청입니다.")
|
||||
if (!keyFileName.startsWith(contentId.toString())) throw SodaException(messageKey = "common.error.invalid_request")
|
||||
|
||||
val audioContent = repository.findByIdOrNull(contentId)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
?: throw SodaException(messageKey = "common.error.invalid_request")
|
||||
|
||||
audioContent.content = content
|
||||
audioContent.duration = duration
|
||||
@@ -456,7 +458,7 @@ class AudioContentService(
|
||||
applicationEventPublisher.publishEvent(
|
||||
FcmEvent(
|
||||
type = FcmEventType.INDIVIDUAL,
|
||||
title = "콘텐츠 등록완료",
|
||||
title = formatMessage("content.notification.upload_complete_title"),
|
||||
message = audioContent.title,
|
||||
recipients = listOf(audioContent.member!!.id!!),
|
||||
isAuth = null,
|
||||
@@ -471,7 +473,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = contentId,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -483,7 +485,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = contentId,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -505,7 +507,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = audioContent.id!!,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -517,7 +519,7 @@ class AudioContentService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.UPLOAD_CONTENT,
|
||||
title = audioContent.member!!.nickname,
|
||||
message = "콘텐츠를 업로드 하였습니다. - ${audioContent.title}",
|
||||
message = formatMessage("content.notification.uploaded_message", audioContent.title),
|
||||
isAuth = audioContent.isAdult,
|
||||
contentId = audioContent.id!!,
|
||||
creatorId = audioContent.member!!.id,
|
||||
@@ -538,12 +540,12 @@ class AudioContentService(
|
||||
|
||||
// 오디오 콘텐츠 조회 (content_id, 제목, 내용, 테마, 태그, 19여부, 이미지, 콘텐츠 PATH)
|
||||
val audioContent = repository.findByIdOrNull(id)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
// 크리에이터(유저) 정보
|
||||
val creatorId = audioContent.member!!.id!!
|
||||
val creator = explorerQueryRepository.getMember(creatorId)
|
||||
?: throw SodaException("없는 사용자 입니다.")
|
||||
?: throw SodaException(messageKey = "content.error.user_not_found")
|
||||
|
||||
val creatorFollowing = explorerQueryRepository.getCreatorFollowing(
|
||||
creatorId = creatorId,
|
||||
@@ -557,7 +559,9 @@ class AudioContentService(
|
||||
|
||||
// 차단된 사용자 체크
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = creatorId)
|
||||
if (isBlocked && !isExistsAudioContent) throw SodaException("${creator.nickname}님의 요청으로 콘텐츠 접근이 제한됩니다.")
|
||||
if (isBlocked && !isExistsAudioContent) {
|
||||
throw SodaException(formatMessage("content.error.access_restricted_by_creator", creator.nickname))
|
||||
}
|
||||
|
||||
val orderSequence = if (isExistsAudioContent) {
|
||||
limitedEditionOrderRepository.getOrderSequence(
|
||||
@@ -595,7 +599,7 @@ class AudioContentService(
|
||||
audioContent.releaseDate != null &&
|
||||
audioContent.releaseDate!! < LocalDateTime.now()
|
||||
) {
|
||||
throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
}
|
||||
|
||||
// 댓글
|
||||
@@ -628,11 +632,13 @@ class AudioContentService(
|
||||
audioContent.releaseDate != null &&
|
||||
audioContent.releaseDate!! >= LocalDateTime.now()
|
||||
) {
|
||||
val releaseDatePattern = messageSource.getMessage("content.release_date.format", langContext.lang)
|
||||
?: "yyyy년 MM월 dd일 HH시 mm분 오픈예정"
|
||||
audioContent.releaseDate!!
|
||||
.atZone(ZoneId.of("UTC"))
|
||||
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
|
||||
.toLocalDateTime()
|
||||
.format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 HH시 mm분 오픈예정"))
|
||||
.format(DateTimeFormatter.ofPattern(releaseDatePattern, langContext.lang.locale))
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -1114,8 +1120,13 @@ class AudioContentService(
|
||||
limit: Long,
|
||||
sortType: String = "매출"
|
||||
): GetAudioContentRanking {
|
||||
val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일")
|
||||
val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일")
|
||||
val normalizedSortType = normalizeRankingSortType(sortType)
|
||||
val startDatePattern = messageSource.getMessage("content.ranking.date.start_format", langContext.lang)
|
||||
?: "yyyy년 MM월 dd일"
|
||||
val endDatePattern = messageSource.getMessage("content.ranking.date.end_format", langContext.lang)
|
||||
?: "MM월 dd일"
|
||||
val startDateFormatter = DateTimeFormatter.ofPattern(startDatePattern, langContext.lang.locale)
|
||||
val endDateFormatter = DateTimeFormatter.ofPattern(endDatePattern, langContext.lang.locale)
|
||||
|
||||
val contentRankingItemList = repository
|
||||
.getAudioContentRanking(
|
||||
@@ -1126,7 +1137,7 @@ class AudioContentService(
|
||||
contentType = contentType,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
sortType = sortType
|
||||
sortType = normalizedSortType
|
||||
)
|
||||
|
||||
return GetAudioContentRanking(
|
||||
@@ -1137,16 +1148,19 @@ class AudioContentService(
|
||||
}
|
||||
|
||||
fun getContentRankingSortTypeList(): List<String> {
|
||||
return listOf("매출", "댓글", "좋아요")
|
||||
val salesLabel = messageSource.getMessage("content.ranking.sort_type.sales", langContext.lang) ?: "매출"
|
||||
val commentLabel = messageSource.getMessage("content.ranking.sort_type.comment", langContext.lang) ?: "댓글"
|
||||
val likeLabel = messageSource.getMessage("content.ranking.sort_type.like", langContext.lang) ?: "좋아요"
|
||||
return listOf(salesLabel, commentLabel, likeLabel)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun pinToTheTop(contentId: Long, member: Member) {
|
||||
val audioContent = repository.findByIdAndCreatorId(contentId = contentId, creatorId = member.id!!)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
if (audioContent.releaseDate != null && audioContent.releaseDate!! >= LocalDateTime.now()) {
|
||||
throw SodaException("콘텐츠 오픈 후 채널에 고정이 가능합니다.")
|
||||
throw SodaException(messageKey = "content.error.pin_available_after_open")
|
||||
}
|
||||
|
||||
var pinContent = pinContentRepository.findByContentIdAndMemberId(
|
||||
@@ -1176,14 +1190,14 @@ class AudioContentService(
|
||||
val pinContent = pinContentRepository.findByContentIdAndMemberId(
|
||||
contentId = contentId,
|
||||
memberId = member.id!!
|
||||
) ?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
) ?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
pinContent.isActive = false
|
||||
}
|
||||
|
||||
fun generateUrl(contentId: Long, member: Member): GenerateUrlResponse {
|
||||
val audioContent = repository.findByIdOrNull(contentId)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
val isExistsAudioContent = orderRepository.isExistOrdered(
|
||||
memberId = member.id!!,
|
||||
@@ -1312,4 +1326,28 @@ class AudioContentService(
|
||||
.distinct()
|
||||
.toList()
|
||||
}
|
||||
|
||||
private fun normalizeRankingSortType(sortType: String?): String {
|
||||
val trimmed = sortType?.trim().orEmpty()
|
||||
val internalTypes = setOf("매출", "댓글", "좋아요", "후원")
|
||||
if (trimmed in internalTypes) return trimmed
|
||||
|
||||
val salesLabel = messageSource.getMessage("content.ranking.sort_type.sales", langContext.lang)
|
||||
val commentLabel = messageSource.getMessage("content.ranking.sort_type.comment", langContext.lang)
|
||||
val likeLabel = messageSource.getMessage("content.ranking.sort_type.like", langContext.lang)
|
||||
val donationLabel = messageSource.getMessage("content.ranking.sort_type.donation", langContext.lang)
|
||||
|
||||
return when (trimmed) {
|
||||
salesLabel -> "매출"
|
||||
commentLabel -> "댓글"
|
||||
likeLabel -> "좋아요"
|
||||
donationLabel -> "후원"
|
||||
else -> "매출"
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestBody request: CreateCategoryRequest,
|
||||
@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.createCategory(request = request, member = member))
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestBody request: ModifyCategoryRequest,
|
||||
@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.modifyCategory(request = request, member = member))
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestBody request: UpdateCategoryOrdersRequest,
|
||||
@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.updateCategoryOrders(request = request, member = member))
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@PathVariable("id") categoryId: 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.deleteCategory(categoryId = categoryId, member = member))
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class CategoryController(private val service: CategoryService) {
|
||||
@RequestParam creatorId: 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.getCategoryList(creatorId = creatorId, memberId = member.id!!))
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class CategoryService(
|
||||
@Transactional
|
||||
fun modifyCategory(request: ModifyCategoryRequest, member: Member) {
|
||||
val category = repository.findByIdAndMemberId(categoryId = request.categoryId, memberId = member.id!!)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
?: throw SodaException(messageKey = "common.error.invalid_request")
|
||||
|
||||
if (!request.title.isNullOrBlank()) {
|
||||
validateTitle(title = request.title)
|
||||
@@ -108,7 +108,7 @@ class CategoryService(
|
||||
@Transactional
|
||||
fun deleteCategory(categoryId: Long, member: Member) {
|
||||
val category = repository.findByIdAndMemberId(categoryId = categoryId, memberId = member.id!!)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
?: throw SodaException(messageKey = "common.error.invalid_request")
|
||||
category.isActive = false
|
||||
|
||||
categoryContentRepository.deleteByCategoryId(categoryId = categoryId)
|
||||
@@ -128,7 +128,7 @@ class CategoryService(
|
||||
@Transactional
|
||||
fun getCategoryList(creatorId: Long, memberId: Long): List<GetCategoryListResponse> {
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = creatorId)
|
||||
if (isBlocked) throw SodaException("잘못된 접근입니다.")
|
||||
if (isBlocked) throw SodaException(messageKey = "category.error.invalid_access")
|
||||
|
||||
// 기본 카테고리 목록 조회 (원본 언어 기준)
|
||||
val baseList = repository.findByCreatorId(creatorId = creatorId)
|
||||
@@ -205,6 +205,6 @@ class CategoryService(
|
||||
}
|
||||
|
||||
private fun validateTitle(title: String) {
|
||||
if (title.length < 2) throw SodaException("카테고리명은 2글자 이상 입력하세요")
|
||||
if (title.length < 2) throw SodaException(messageKey = "category.error.title_min_length")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class AudioContentCommentController(
|
||||
@RequestBody request: RegisterCommentRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
val commentId = service.registerComment(
|
||||
comment = request.comment,
|
||||
@@ -62,7 +62,7 @@ class AudioContentCommentController(
|
||||
@RequestBody request: ModifyCommentRequest,
|
||||
@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.modifyComment(request = request, member = member))
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class AudioContentCommentController(
|
||||
@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.getCommentList(
|
||||
@@ -93,7 +93,7 @@ class AudioContentCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
): ApiResponse<GetAudioContentCommentListResponse> {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
return ApiResponse.ok(
|
||||
service.getCommentReplyList(
|
||||
|
||||
@@ -7,6 +7,8 @@ import kr.co.vividnext.sodalive.content.LanguageDetectTargetType
|
||||
import kr.co.vividnext.sodalive.content.order.OrderRepository
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
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.member.Member
|
||||
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
@@ -24,6 +26,8 @@ class AudioContentCommentService(
|
||||
private val audioContentRepository: AudioContentRepository,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
private val orderRepository: OrderRepository,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val cloudFrontHost: String
|
||||
@@ -38,11 +42,13 @@ class AudioContentCommentService(
|
||||
languageCode: String?
|
||||
): Long {
|
||||
val audioContent = audioContentRepository.findByIdOrNull(id = audioContentId)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
val creator = audioContent.member!!
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = creator.id!!)
|
||||
if (isBlocked) throw SodaException("${creator.nickname}님의 요청으로 댓글쓰기가 제한됩니다.")
|
||||
if (isBlocked) {
|
||||
throw SodaException(formatMessage("content.comment.error.blocked_by_creator", creator.nickname))
|
||||
}
|
||||
|
||||
val (isExistsAudioContent, _) = orderRepository.isExistOrderedAndOrderType(
|
||||
memberId = member.id!!,
|
||||
@@ -50,7 +56,7 @@ class AudioContentCommentService(
|
||||
)
|
||||
|
||||
if (isSecret && !isExistsAudioContent) {
|
||||
throw SodaException("콘텐츠 구매 후 비밀댓글을 등록할 수 있습니다.")
|
||||
throw SodaException(messageKey = "content.comment.error.secret_requires_purchase")
|
||||
}
|
||||
|
||||
val audioContentComment = AudioContentComment(comment = comment, languageCode = languageCode, isSecret = isSecret)
|
||||
@@ -78,9 +84,9 @@ class AudioContentCommentService(
|
||||
member.nickname
|
||||
},
|
||||
message = if (parent != null) {
|
||||
"댓글에 답글을 달았습니다.: ${audioContent.title}"
|
||||
formatMessage("content.comment.notification.reply", audioContent.title)
|
||||
} else {
|
||||
"콘텐츠에 댓글을 달았습니다.: ${audioContent.title}"
|
||||
formatMessage("content.comment.notification.new", audioContent.title)
|
||||
},
|
||||
contentId = audioContentId,
|
||||
commentParentId = parentId,
|
||||
@@ -105,7 +111,7 @@ class AudioContentCommentService(
|
||||
@Transactional
|
||||
fun modifyComment(request: ModifyCommentRequest, member: Member) {
|
||||
val audioContentComment = repository.findByIdOrNull(request.commentId)
|
||||
?: throw SodaException("잘못된 접근 입니다.\n확인 후 다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.comment.error.invalid_access_retry")
|
||||
|
||||
if (audioContentComment.member!!.id!! == member.id!!) {
|
||||
if (request.comment != null) {
|
||||
@@ -164,4 +170,9 @@ class AudioContentCommentService(
|
||||
|
||||
return GetAudioContentCommentListResponse(totalCount, commentList)
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class AudioContentDonationController(private val service: AudioContentDonationSe
|
||||
@RequestBody request: AudioContentDonationRequest,
|
||||
@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.donation(request = request, member = member))
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ class AudioContentDonationService(
|
||||
) {
|
||||
@Transactional
|
||||
fun donation(request: AudioContentDonationRequest, member: Member) {
|
||||
if (request.donationCan < 1) throw SodaException("1캔 이상 후원하실 수 있습니다.")
|
||||
if (request.comment.isBlank()) throw SodaException("함께 보낼 메시지를 입력하세요.")
|
||||
if (request.donationCan < 1) throw SodaException(messageKey = "content.donation.error.minimum_can")
|
||||
if (request.comment.isBlank()) throw SodaException(messageKey = "content.donation.error.comment_required")
|
||||
|
||||
val audioContent = queryRepository.findByIdAndActive(request.contentId)
|
||||
?: throw SodaException("잘못된 콘텐츠 입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "content.error.invalid_content_retry")
|
||||
|
||||
canPaymentService.spendCan(
|
||||
memberId = member.id!!,
|
||||
|
||||
@@ -22,7 +22,7 @@ class AudioContentMainController(
|
||||
fun newContentUploadCreatorList(
|
||||
@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.getNewContentUploadCreatorList(
|
||||
@@ -36,7 +36,7 @@ class AudioContentMainController(
|
||||
fun getMainBannerList(
|
||||
@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.getAudioContentMainBannerList(
|
||||
@@ -50,7 +50,7 @@ class AudioContentMainController(
|
||||
fun getMainOrderList(
|
||||
@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(
|
||||
orderService.getAudioContentMainOrderList(
|
||||
@@ -68,7 +68,7 @@ class AudioContentMainController(
|
||||
@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.getNewContentByTheme(
|
||||
@@ -87,7 +87,7 @@ class AudioContentMainController(
|
||||
@RequestParam("contentType", required = false) contentType: ContentType? = null,
|
||||
@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.getThemeList(
|
||||
@@ -105,7 +105,7 @@ class AudioContentMainController(
|
||||
@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.getNewContentFor2WeeksByTheme(
|
||||
@@ -125,7 +125,7 @@ class AudioContentMainController(
|
||||
@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.getAudioContentCurationListWithPaging(
|
||||
|
||||
Reference in New Issue
Block a user