diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerController.kt index b47792a5..21a4c8e1 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerController.kt @@ -5,6 +5,8 @@ import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.explorer.profile.PostCreatorNoticeRequest import kr.co.vividnext.sodalive.explorer.profile.PostWriteCheersRequest import kr.co.vividnext.sodalive.explorer.profile.PutWriteCheersRequest +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.security.access.prepost.PreAuthorize @@ -20,12 +22,16 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/explorer") -class ExplorerController(private val service: ExplorerService) { +class ExplorerController( + private val service: ExplorerService, + private val messageSource: SodaMessageSource, + private val langContext: LangContext +) { @GetMapping("/creator-rank") fun getCreatorRank( @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.getCreatorRank(memberId = member.id!!)) } @@ -34,7 +40,7 @@ class ExplorerController(private val service: ExplorerService) { fun getExplorer( @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.getExplorer(member)) } @@ -44,7 +50,7 @@ class ExplorerController(private val service: ExplorerService) { @RequestParam channel: 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.getSearchChannel(channel, member)) } @@ -55,7 +61,7 @@ class ExplorerController(private val service: ExplorerService) { @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.getCreatorProfile( creatorId = creatorId, @@ -72,7 +78,7 @@ class ExplorerController(private val service: ExplorerService) { @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.getCreatorProfileDonationRanking(creatorId, pageable, member)) } @@ -81,8 +87,9 @@ class ExplorerController(private val service: ExplorerService) { @RequestBody request: PostWriteCheersRequest, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? ) = run { - if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - ApiResponse.ok(service.writeCheers(request, member), "등록되었습니다.") + if (member == null) throw SodaException(messageKey = "common.error.bad_credentials") + val message = messageSource.getMessage("explorer.cheers.created", langContext.lang) + ApiResponse.ok(service.writeCheers(request, member), message) } @PutMapping("/profile/cheers") @@ -90,8 +97,9 @@ class ExplorerController(private val service: ExplorerService) { @RequestBody request: PutWriteCheersRequest, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? ) = run { - if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - ApiResponse.ok(service.modifyCheers(request, member), "수정되었습니다.") + if (member == null) throw SodaException(messageKey = "common.error.bad_credentials") + val message = messageSource.getMessage("explorer.cheers.updated", langContext.lang) + ApiResponse.ok(service.modifyCheers(request, member), message) } @PostMapping("/profile/notice") @@ -100,8 +108,9 @@ class ExplorerController(private val service: ExplorerService) { @RequestBody request: PostCreatorNoticeRequest, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? ) = run { - if (member == null) throw SodaException("로그인 정보를 확인해주세요.") - ApiResponse.ok(service.saveNotice(member, request.notice), "공지사항이 저장되었습니다.") + if (member == null) throw SodaException(messageKey = "common.error.bad_credentials") + val message = messageSource.getMessage("explorer.notice.saved", langContext.lang) + ApiResponse.ok(service.saveNotice(member, request.notice), message) } @GetMapping("/profile/{id}/follower-list") @@ -110,7 +119,7 @@ class ExplorerController(private val service: ExplorerService) { @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.getFollowerList(creatorId, member, pageable)) } @@ -121,7 +130,7 @@ class ExplorerController(private val service: ExplorerService) { @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.getCreatorProfileCheers(creatorId, timezone, pageable)) } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt index dfce6763..9f8c586d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerQueryRepository.kt @@ -19,6 +19,9 @@ import kr.co.vividnext.sodalive.explorer.profile.CreatorCheers import kr.co.vividnext.sodalive.explorer.profile.QChannelNotice.channelNotice import kr.co.vividnext.sodalive.explorer.profile.QCreatorCheers.creatorCheers import kr.co.vividnext.sodalive.explorer.profile.TimeDifferenceResult +import kr.co.vividnext.sodalive.i18n.Lang +import kr.co.vividnext.sodalive.i18n.LangContext +import kr.co.vividnext.sodalive.i18n.SodaMessageSource import kr.co.vividnext.sodalive.live.room.LiveRoom import kr.co.vividnext.sodalive.live.room.LiveRoomType import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom @@ -40,11 +43,12 @@ import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter -import java.util.Locale @Repository class ExplorerQueryRepository( private val queryFactory: JPAQueryFactory, + private val messageSource: SodaMessageSource, + private val langContext: LangContext, @Value("\${cloud.aws.cloud-front.host}") private val cloudFrontHost: String @@ -243,7 +247,7 @@ class ExplorerQueryRepository( val creator = queryFactory .selectFrom(member) .where(member.id.eq(creatorId)) - .fetchFirst() ?: throw SodaException("없는 사용자 입니다.") + .fetchFirst() ?: throw SodaException(messageKey = "member.validation.user_not_found") val creatorTagCount = creator.tags .asSequence() @@ -383,6 +387,12 @@ class ExplorerQueryRepository( ) } + val dateTimePattern = messageSource + .getMessage("explorer.date.live_room.datetime_format", langContext.lang) + ?: messageSource.getMessage("explorer.date.live_room.datetime_format", Lang.KO).orEmpty() + val dateTimeFormatter = DateTimeFormatter.ofPattern(dateTimePattern) + .withLocale(langContext.lang.locale) + return result .map { val reservations = it.reservations @@ -393,11 +403,7 @@ class ExplorerQueryRepository( val beginDateTime = it.beginDateTime .atZone(ZoneId.of("UTC")) .withZoneSameInstant(ZoneId.of(timezone)) - .format( - DateTimeFormatter - .ofPattern("yyyy년 MM월 dd일 (E) a hh시 mm분") - .withLocale(Locale.KOREAN) - ) + .format(dateTimeFormatter) val beginDateTimeUtc = it.beginDateTime .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) @@ -451,6 +457,12 @@ class ExplorerQueryRepository( } fun getCheersList(creatorId: Long, timezone: String, offset: Long, limit: Long): GetCheersResponse { + val cheersDatePattern = messageSource + .getMessage("explorer.date.cheers.format", langContext.lang) + ?: messageSource.getMessage("explorer.date.cheers.format", Lang.KO).orEmpty() + val cheersDateFormatter = DateTimeFormatter.ofPattern(cheersDatePattern) + .withLocale(langContext.lang.locale) + val totalCount = queryFactory .selectFrom(creatorCheers) .where( @@ -489,7 +501,7 @@ class ExplorerQueryRepository( }, content = it.cheers, languageCode = it.languageCode, - date = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd E hh:mm a")), + date = date.format(cheersDateFormatter), replyList = it.children.asSequence() .map { cheers -> val replyDate = cheers.createdAt!! @@ -507,7 +519,7 @@ class ExplorerQueryRepository( }, content = cheers.cheers, languageCode = cheers.languageCode, - date = replyDate.format(DateTimeFormatter.ofPattern("yyyy.MM.dd E hh:mm a")), + date = replyDate.format(cheersDateFormatter), replyList = listOf() ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt index c438b835..9a81fcd9 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/ExplorerService.kt @@ -19,7 +19,9 @@ import kr.co.vividnext.sodalive.explorer.profile.PutWriteCheersRequest import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityService import kr.co.vividnext.sodalive.fcm.FcmEvent import kr.co.vividnext.sodalive.fcm.FcmEventType +import kr.co.vividnext.sodalive.i18n.Lang import kr.co.vividnext.sodalive.i18n.LangContext +import kr.co.vividnext.sodalive.i18n.SodaMessageSource import kr.co.vividnext.sodalive.live.room.detail.GetRoomDetailUser import kr.co.vividnext.sodalive.member.Member import kr.co.vividnext.sodalive.member.MemberRole @@ -50,6 +52,7 @@ class ExplorerService( private val applicationEventPublisher: ApplicationEventPublisher, private val contentTranslationRepository: ContentTranslationRepository, + private val messageSource: SodaMessageSource, private val langContext: LangContext, @Value("\${cloud.aws.cloud-front.host}") @@ -68,15 +71,20 @@ class ExplorerService( val lastSunday = lastMonday .plusDays(6) - val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일") - val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일") + val startDatePattern = messageSource.getMessage("explorer.date.creator_rank.start_format", langContext.lang) + ?: messageSource.getMessage("explorer.date.creator_rank.start_format", Lang.KO).orEmpty() + val endDatePattern = messageSource.getMessage("explorer.date.creator_rank.end_format", langContext.lang) + ?: messageSource.getMessage("explorer.date.creator_rank.end_format", Lang.KO).orEmpty() + val startDateFormatter = DateTimeFormatter.ofPattern(startDatePattern).withLocale(langContext.lang.locale) + val endDateFormatter = DateTimeFormatter.ofPattern(endDatePattern).withLocale(langContext.lang.locale) val formattedLastMonday = lastMonday.format(startDateFormatter) val formattedLastSunday = lastSunday.format(endDateFormatter) return GetExplorerSectionResponse( - title = "인기 크리에이터", - coloredTitle = "인기", + title = messageSource.getMessage("explorer.section.creator_rank.title", langContext.lang).orEmpty(), + coloredTitle = messageSource.getMessage("explorer.section.creator_rank.colored_title", langContext.lang) + .orEmpty(), color = "FF5C49", desc = "$formattedLastMonday ~ $formattedLastSunday", creators = creatorRankings @@ -99,15 +107,20 @@ class ExplorerService( val lastSunday = lastMonday .plusDays(6) - val startDateFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일") - val endDateFormatter = DateTimeFormatter.ofPattern("MM월 dd일") + val startDatePattern = messageSource.getMessage("explorer.date.creator_rank.start_format", langContext.lang) + ?: messageSource.getMessage("explorer.date.creator_rank.start_format", Lang.KO).orEmpty() + val endDatePattern = messageSource.getMessage("explorer.date.creator_rank.end_format", langContext.lang) + ?: messageSource.getMessage("explorer.date.creator_rank.end_format", Lang.KO).orEmpty() + val startDateFormatter = DateTimeFormatter.ofPattern(startDatePattern).withLocale(langContext.lang.locale) + val endDateFormatter = DateTimeFormatter.ofPattern(endDatePattern).withLocale(langContext.lang.locale) val formattedLastMonday = lastMonday.format(startDateFormatter) val formattedLastSunday = lastSunday.format(endDateFormatter) val creatorRankingSection = GetExplorerSectionResponse( - title = "인기 크리에이터", - coloredTitle = "인기", + title = messageSource.getMessage("explorer.section.creator_rank.title", langContext.lang).orEmpty(), + coloredTitle = messageSource.getMessage("explorer.section.creator_rank.colored_title", langContext.lang) + .orEmpty(), color = "FF5C49", desc = "$formattedLastMonday ~ $formattedLastSunday", creators = creatorRankings @@ -121,16 +134,18 @@ class ExplorerService( .map { it.toExplorerSectionCreator(cloudFrontHost) } val newCreatorsSection = GetExplorerSectionResponse( - title = "새로 시작", - coloredTitle = "새로", + title = messageSource.getMessage("explorer.section.new_creators.title", langContext.lang).orEmpty(), + coloredTitle = messageSource.getMessage("explorer.section.new_creators.colored_title", langContext.lang) + .orEmpty(), color = "5FD28F", creators = newCreators ) sections.add(newCreatorsSection) val maleCreatorSection = GetExplorerSectionResponse( - title = "남자 크리에이터", - coloredTitle = "남자", + title = messageSource.getMessage("explorer.section.male_creators.title", langContext.lang).orEmpty(), + coloredTitle = messageSource.getMessage("explorer.section.male_creators.colored_title", langContext.lang) + .orEmpty(), color = "39abde", creators = queryRepository .findCreatorByGender(1) @@ -139,8 +154,9 @@ class ExplorerService( ) val femaleCreatorSection = GetExplorerSectionResponse( - title = "여자 크리에이터", - coloredTitle = "여자", + title = messageSource.getMessage("explorer.section.female_creators.title", langContext.lang).orEmpty(), + coloredTitle = messageSource.getMessage("explorer.section.female_creators.colored_title", langContext.lang) + .orEmpty(), color = "ffa517", creators = queryRepository .findCreatorByGender(0) @@ -162,7 +178,7 @@ class ExplorerService( fun getSearchChannel(channel: String, member: Member): List { if (channel.length < 2) { - throw SodaException("두 글자 이상 입력 하셔야 합니다.") + throw SodaException(messageKey = "explorer.search.channel.min_length") } return queryRepository.getSearchChannel(channel, member.id!!) @@ -179,11 +195,17 @@ class ExplorerService( member: Member ): GetCreatorProfileResponse { // 크리에이터(유저) 정보 - val creatorAccount = queryRepository.getMember(creatorId) ?: throw SodaException("없는 사용자 입니다.") + val creatorAccount = queryRepository.getMember(creatorId) + ?: throw SodaException(messageKey = "member.validation.user_not_found") // 차단된 사용자 체크 val isBlocked = memberService.isBlocked(blockedMemberId = member.id!!, memberId = creatorId) - if (isBlocked) throw SodaException("${creatorAccount.nickname}님의 요청으로 채널 접근이 제한됩니다.") + if (isBlocked) { + val messageTemplate = messageSource + .getMessage("explorer.creator.blocked_access", langContext.lang) + .orEmpty() + throw SodaException(message = String.format(messageTemplate, creatorAccount.nickname)) + } val isCreator = creatorAccount.role == MemberRole.CREATOR @@ -461,10 +483,16 @@ class ExplorerService( @Transactional fun writeCheers(request: PostWriteCheersRequest, member: Member) { - val creator = queryRepository.getMember(request.creatorId) ?: throw SodaException("없는 사용자 입니다.") + val creator = queryRepository.getMember(request.creatorId) + ?: throw SodaException(messageKey = "member.validation.user_not_found") val isBlocked = memberService.isBlocked(blockedMemberId = member.id!!, memberId = request.creatorId) - if (isBlocked) throw SodaException("${creator.nickname}님의 요청으로 팬토크 작성이 제한됩니다.") + if (isBlocked) { + val messageTemplate = messageSource + .getMessage("explorer.creator.blocked_cheers", langContext.lang) + .orEmpty() + throw SodaException(message = String.format(messageTemplate, creator.nickname)) + } val cheers = CreatorCheers(cheers = request.content, languageCode = request.languageCode) cheers.member = member @@ -510,7 +538,7 @@ class ExplorerService( @Transactional fun modifyCheers(request: PutWriteCheersRequest, member: Member) { val cheers = queryRepository.getCheers(request.cheersId) - ?: throw SodaException("잘못된 요청입니다.") + ?: throw SodaException(messageKey = "common.error.invalid_request") if (cheers.member!!.id!! == member.id!!) { if (request.content != null) { @@ -544,7 +572,7 @@ class ExplorerService( FcmEvent( type = FcmEventType.CHANGE_NOTICE, title = member.nickname, - message = "새 글이 등록되었습니다.", + message = messageSource.getMessage("explorer.notice.fcm.message", langContext.lang).orEmpty(), creatorId = member.id!! ) ) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityController.kt index c84e587f..b85e3cf3 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityController.kt @@ -36,7 +36,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @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.createCommunityPost( @@ -57,7 +57,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @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.modifyCommunityPost( @@ -75,7 +75,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @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.getCommunityPostList( @@ -95,7 +95,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @RequestParam timezone: 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.getCommunityPostDetail( @@ -112,7 +112,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @RequestBody request: PostCommunityPostLikeRequest, @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.communityPostLike(request, member)) } @@ -122,7 +122,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @RequestBody request: CreateCommunityPostCommentRequest, @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.createCommunityPostComment( @@ -140,7 +140,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @RequestBody request: ModifyCommunityPostCommentRequest, @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.modifyCommunityPostComment(request = request, member = member) @@ -154,7 +154,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @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.getCommunityPostCommentList( @@ -174,7 +174,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @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.getCommentReplyList( @@ -191,7 +191,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @RequestParam timezone: 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.getLatestPostListFromCreatorsYouFollow( @@ -207,7 +207,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @RequestBody request: PurchasePostRequest, @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.purchasePost( diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityService.kt index b71f6669..5a66eba2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityService.kt @@ -19,6 +19,8 @@ import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.PostCommu import kr.co.vividnext.sodalive.extensions.getTimeAgoString 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 kr.co.vividnext.sodalive.utils.generateFileName @@ -45,6 +47,8 @@ class CreatorCommunityService( private val objectMapper: ObjectMapper, private val audioContentCloudFront: AudioContentCloudFront, private val applicationEventPublisher: ApplicationEventPublisher, + private val messageSource: SodaMessageSource, + private val langContext: LangContext, @Value("\${cloud.aws.s3.bucket}") private val imageBucket: String, @@ -65,11 +69,11 @@ class CreatorCommunityService( val request = objectMapper.readValue(requestString, CreateCommunityPostRequest::class.java) if (request.price > 0 && postImage == null) { - throw SodaException("유료 게시글 등록을 위해서는 이미지가 필요합니다.") + throw SodaException(messageKey = "creator.community.paid_post_image_required") } if (audioFile != null && postImage == null) { - throw SodaException("오디오 등록을 위해서는 이미지가 필요합니다.") + throw SodaException(messageKey = "creator.community.audio_post_image_required") } postImage?.let { validateImage(it, request.price > 0) } @@ -119,7 +123,7 @@ class CreatorCommunityService( FcmEvent( type = FcmEventType.CHANGE_NOTICE, title = member.nickname, - message = "새 글이 등록되었습니다.", + message = messageSource.getMessage("creator.community.fcm.new_post", langContext.lang).orEmpty(), creatorId = member.id!! ) ) @@ -130,7 +134,7 @@ class CreatorCommunityService( val request = objectMapper.readValue(requestString, ModifyCommunityPostRequest::class.java) val post = repository.findByIdAndMemberId(id = request.creatorCommunityId, memberId = member.id!!) - ?: throw SodaException("잘못된 요청입니다.") + ?: throw SodaException(messageKey = "common.error.invalid_request") postImage?.let { validateImage(it, post.price > 0) } @@ -269,10 +273,15 @@ class CreatorCommunityService( isAdult: Boolean ): GetCommunityPostListResponse { val post = repository.getCommunityPost(postId, isAdult = isAdult) - ?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.") + ?: throw SodaException(messageKey = "creator.community.invalid_request_retry") val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = post.creatorId) - if (isBlocked) throw SodaException("${post.creatorNickname}님의 요청으로 접근이 제한됩니다.") + if (isBlocked) { + val messageTemplate = messageSource + .getMessage("creator.community.blocked_access", langContext.lang) + .orEmpty() + throw SodaException(message = String.format(messageTemplate, post.creatorNickname)) + } val isLike = likeRepository.findByPostIdAndMemberId(postId = post.id, memberId = memberId)?.isActive ?: false val likeCount = likeRepository.totalCountCommunityPostLikeByPostId(post.id) @@ -345,7 +354,7 @@ class CreatorCommunityService( postLike.member = member val post = repository.findByIdAndActive(request.postId, isAdult = member.auth != null) - ?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.") + ?: throw SodaException(messageKey = "creator.community.invalid_request_retry") postLike.creatorCommunity = post likeRepository.save(postLike) @@ -365,11 +374,11 @@ class CreatorCommunityService( isSecret: Boolean = false ) { val post = repository.findByIdOrNull(id = postId) - ?: throw SodaException("잘못된 게시물 입니다.\n다시 시도해 주세요.") + ?: throw SodaException(messageKey = "creator.community.invalid_post_retry") val isExistOrdered = useCanRepository.isExistCommunityPostOrdered(postId = postId, memberId = member.id!!) if (isSecret && !isExistOrdered) { - throw SodaException("게시글을 구매 후 비밀댓글을 등록할 수 있습니다.") + throw SodaException(messageKey = "creator.community.secret_comment_purchase_required") } val postComment = CreatorCommunityComment(comment = comment, isSecret = isSecret) @@ -392,7 +401,7 @@ class CreatorCommunityService( @Transactional fun modifyCommunityPostComment(request: ModifyCommunityPostCommentRequest, member: Member) { val postComment = commentRepository.findByIdOrNull(id = request.commentId) - ?: throw SodaException("잘못된 접근 입니다.\n확인 후 다시 시도해 주세요.") + ?: throw SodaException(messageKey = "creator.community.invalid_access_retry") if (request.comment != null && postComment.member!!.id!! == member.id!!) { postComment.comment = request.comment @@ -530,10 +539,15 @@ class CreatorCommunityService( container: String ): GetCommunityPostListResponse { val post = repository.findByIdAndActive(postId, isAdult) - ?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.") + ?: throw SodaException(messageKey = "creator.community.invalid_request_retry") val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = post.member!!.id!!) - if (isBlocked) throw SodaException("${post.member!!.nickname}님의 요청으로 접근이 제한됩니다.") + if (isBlocked) { + val messageTemplate = messageSource + .getMessage("creator.community.blocked_access", langContext.lang) + .orEmpty() + throw SodaException(message = String.format(messageTemplate, post.member!!.nickname)) + } val existOrdered = useCanRepository.isExistCommunityPostOrdered(postId = postId, memberId = memberId) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/i18n/SodaMessageSource.kt b/src/main/kotlin/kr/co/vividnext/sodalive/i18n/SodaMessageSource.kt index bffaaf79..90faed6d 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/i18n/SodaMessageSource.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/i18n/SodaMessageSource.kt @@ -988,6 +988,159 @@ class SodaMessageSource { ) ) + private val explorerSectionMessages = mapOf( + "explorer.section.creator_rank.title" to mapOf( + Lang.KO to "인기 크리에이터", + Lang.EN to "Top creators", + Lang.JA to "人気クリエイター" + ), + "explorer.section.creator_rank.colored_title" to mapOf( + Lang.KO to "인기", + Lang.EN to "Top", + Lang.JA to "人気" + ), + "explorer.section.new_creators.title" to mapOf( + Lang.KO to "새로 시작", + Lang.EN to "New creators", + Lang.JA to "新規クリエイター" + ), + "explorer.section.new_creators.colored_title" to mapOf( + Lang.KO to "새로", + Lang.EN to "New", + Lang.JA to "新規" + ), + "explorer.section.male_creators.title" to mapOf( + Lang.KO to "남자 크리에이터", + Lang.EN to "Male creators", + Lang.JA to "男性クリエイター" + ), + "explorer.section.male_creators.colored_title" to mapOf( + Lang.KO to "남자", + Lang.EN to "Male", + Lang.JA to "男性" + ), + "explorer.section.female_creators.title" to mapOf( + Lang.KO to "여자 크리에이터", + Lang.EN to "Female creators", + Lang.JA to "女性クリエイター" + ), + "explorer.section.female_creators.colored_title" to mapOf( + Lang.KO to "여자", + Lang.EN to "Female", + Lang.JA to "女性" + ) + ) + + private val explorerDateMessages = mapOf( + "explorer.date.creator_rank.start_format" to mapOf( + Lang.KO to "yyyy년 MM월 dd일", + Lang.EN to "MMM dd, yyyy", + Lang.JA to "yyyy年MM月dd日" + ), + "explorer.date.creator_rank.end_format" to mapOf( + Lang.KO to "MM월 dd일", + Lang.EN to "MMM dd", + Lang.JA to "MM月dd日" + ), + "explorer.date.live_room.datetime_format" to mapOf( + Lang.KO to "yyyy년 MM월 dd일 (E) a hh시 mm분", + Lang.EN to "EEE, MMM dd, yyyy h:mm a", + Lang.JA to "yyyy年MM月dd日(E) a hh時 mm分" + ), + "explorer.date.cheers.format" to mapOf( + Lang.KO to "yyyy.MM.dd E hh:mm a", + Lang.EN to "MMM dd, yyyy E hh:mm a", + Lang.JA to "yyyy.MM.dd E hh:mm a" + ) + ) + + private val explorerResponseMessages = mapOf( + "explorer.cheers.created" to mapOf( + Lang.KO to "등록되었습니다.", + Lang.EN to "Registered.", + Lang.JA to "登録されました。" + ), + "explorer.cheers.updated" to mapOf( + Lang.KO to "수정되었습니다.", + Lang.EN to "Updated.", + Lang.JA to "更新されました。" + ), + "explorer.notice.saved" to mapOf( + Lang.KO to "공지사항이 저장되었습니다.", + Lang.EN to "Notice has been saved.", + Lang.JA to "お知らせが保存されました。" + ), + "explorer.notice.fcm.message" to mapOf( + Lang.KO to "새 글이 등록되었습니다.", + Lang.EN to "A new post has been added.", + Lang.JA to "新しい投稿が登録されました。" + ) + ) + + private val explorerValidationMessages = mapOf( + "explorer.search.channel.min_length" to mapOf( + Lang.KO to "두 글자 이상 입력 하셔야 합니다.", + Lang.EN to "Please enter at least 2 characters.", + Lang.JA to "2文字以上入力してください。" + ) + ) + + private val explorerAccessMessages = mapOf( + "explorer.creator.blocked_access" to mapOf( + Lang.KO to "%s님의 요청으로 채널 접근이 제한됩니다.", + Lang.EN to "Channel access is restricted at %s's request.", + Lang.JA to "%sさんの要請によりチャンネルへのアクセスが制限されています。" + ), + "explorer.creator.blocked_cheers" to mapOf( + Lang.KO to "%s님의 요청으로 팬토크 작성이 제한됩니다.", + Lang.EN to "Fan talk posting is restricted at %s's request.", + Lang.JA to "%sさんの要請によりファントークの投稿が制限されています。" + ) + ) + + private val creatorCommunityMessages = mapOf( + "creator.community.paid_post_image_required" to mapOf( + Lang.KO to "유료 게시글 등록을 위해서는 이미지가 필요합니다.", + Lang.EN to "An image is required to post paid content.", + Lang.JA to "有料投稿を登録するには画像が必要です。" + ), + "creator.community.audio_post_image_required" to mapOf( + Lang.KO to "오디오 등록을 위해서는 이미지가 필요합니다.", + Lang.EN to "An image is required to upload audio.", + Lang.JA to "オーディオを登録するには画像が必要です。" + ), + "creator.community.fcm.new_post" to mapOf( + Lang.KO to "새 글이 등록되었습니다.", + Lang.EN to "A new post has been added.", + Lang.JA to "新しい投稿が登録されました。" + ), + "creator.community.invalid_request_retry" to mapOf( + Lang.KO to "잘못된 요청입니다.\n다시 시도해 주세요.", + Lang.EN to "Invalid request.\nPlease try again.", + Lang.JA to "不正なリクエストです。\nもう一度お試しください。" + ), + "creator.community.invalid_post_retry" to mapOf( + Lang.KO to "잘못된 게시물 입니다.\n다시 시도해 주세요.", + Lang.EN to "Invalid post.\nPlease try again.", + Lang.JA to "不正な投稿です。\nもう一度お試しください。" + ), + "creator.community.secret_comment_purchase_required" to mapOf( + Lang.KO to "게시글을 구매 후 비밀댓글을 등록할 수 있습니다.", + Lang.EN to "You can post a secret comment after purchasing the post.", + Lang.JA to "投稿を購入した後に秘密コメントを登録できます。" + ), + "creator.community.invalid_access_retry" to mapOf( + Lang.KO to "잘못된 접근 입니다.\n확인 후 다시 시도해 주세요.", + Lang.EN to "Invalid access.\nPlease check and try again.", + Lang.JA to "不正なアクセスです。\n確認して再度お試しください。" + ), + "creator.community.blocked_access" to mapOf( + Lang.KO to "%s님의 요청으로 접근이 제한됩니다.", + Lang.EN to "Access is restricted at %s's request.", + Lang.JA to "%sさんの要請によりアクセスが制限されています。" + ) + ) + fun getMessage(key: String, lang: Lang): String? { val messageGroups = listOf( commonMessages, @@ -1026,7 +1179,13 @@ class SodaMessageSource { liveRoomMessages, liveRoomMenuMessages, memberProviderMessages, - memberGenderMessages + memberGenderMessages, + explorerSectionMessages, + explorerDateMessages, + explorerResponseMessages, + explorerValidationMessages, + explorerAccessMessages, + creatorCommunityMessages ) for (messages in messageGroups) { val translations = messages[key] ?: continue