feat(content-preference): 콘텐츠 조회 설정 서버 저장 전환을 반영한다
This commit is contained in:
@@ -5,6 +5,7 @@ import kr.co.vividnext.sodalive.common.SodaException
|
||||
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.contentpreference.MemberContentPreferenceService
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.DeleteMapping
|
||||
@@ -22,6 +23,7 @@ class CharacterCommentController(
|
||||
private val service: CharacterCommentService,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
private val memberContentPreferenceService: MemberContentPreferenceService,
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val imageHost: String
|
||||
) {
|
||||
@@ -33,7 +35,7 @@ class CharacterCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
if (request.comment.isBlank()) throw SodaException(messageKey = "chat.character.comment.required")
|
||||
|
||||
val id = service.addComment(characterId, member, request.comment)
|
||||
@@ -48,7 +50,7 @@ class CharacterCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
if (request.comment.isBlank()) throw SodaException(messageKey = "chat.character.comment.required")
|
||||
|
||||
val id = service.addReply(characterId, commentId, member, request.comment, request.languageCode)
|
||||
@@ -63,7 +65,7 @@ class CharacterCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
|
||||
val data = service.listComments(imageHost, characterId, cursor, limit)
|
||||
ApiResponse.ok(data)
|
||||
@@ -78,7 +80,7 @@ class CharacterCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
|
||||
// characterId는 서비스 내부 검증(원본 댓글과 캐릭터 일치)에서 검증됨
|
||||
val data = service.getReplies(imageHost, commentId, cursor, limit)
|
||||
@@ -92,7 +94,7 @@ class CharacterCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
service.deleteComment(characterId, commentId, member)
|
||||
val message = messageSource.getMessage("chat.character.comment.deleted", langContext.lang)
|
||||
ApiResponse.ok(true, message)
|
||||
@@ -106,9 +108,15 @@ class CharacterCommentController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
service.reportComment(characterId, commentId, member, request.content)
|
||||
val message = messageSource.getMessage("chat.character.comment.reported", langContext.lang)
|
||||
ApiResponse.ok(true, message)
|
||||
}
|
||||
|
||||
private fun validateAdultAccess(member: Member) {
|
||||
if (!memberContentPreferenceService.getStoredPreference(member).isAdult) {
|
||||
throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.translation.PapagoTranslationService
|
||||
import kr.co.vividnext.sodalive.i18n.translation.TranslateRequest
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
@@ -49,6 +50,7 @@ class ChatCharacterController(
|
||||
private val aiCharacterTranslationRepository: AiCharacterTranslationRepository,
|
||||
|
||||
private val langContext: LangContext,
|
||||
private val memberContentPreferenceService: MemberContentPreferenceService,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val imageHost: String
|
||||
@@ -57,6 +59,8 @@ class ChatCharacterController(
|
||||
fun getCharacterMain(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
): ApiResponse<CharacterMainResponse> = run {
|
||||
val isAdultAccessible = resolveIsAdultAccessible(member)
|
||||
|
||||
// 배너 조회 (최대 10개)
|
||||
val banners = bannerService.getActiveBanners(PageRequest.of(0, 10))
|
||||
.content
|
||||
@@ -68,7 +72,7 @@ class ChatCharacterController(
|
||||
}
|
||||
|
||||
// 최근 대화한 캐릭터(채팅방) 조회 (회원별 최근 순으로 최대 10개)
|
||||
val recentCharacters = if (member == null || member.auth == null) {
|
||||
val recentCharacters = if (member == null || !isAdultAccessible) {
|
||||
emptyList()
|
||||
} else {
|
||||
chatRoomService.listMyChatRooms(member, 0, 10)
|
||||
@@ -156,7 +160,7 @@ class ChatCharacterController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
if (!resolveIsAdultAccessible(member)) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
|
||||
// 캐릭터 상세 정보 조회
|
||||
val character = service.getCharacterDetail(characterId)
|
||||
@@ -396,7 +400,8 @@ class ChatCharacterController(
|
||||
fun getRecommendCharacters(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
val recent = if (member == null || member.auth == null) {
|
||||
val isAdultAccessible = resolveIsAdultAccessible(member)
|
||||
val recent = if (member == null || !isAdultAccessible) {
|
||||
emptyList()
|
||||
} else {
|
||||
chatRoomService
|
||||
@@ -447,4 +452,12 @@ class ChatCharacterController(
|
||||
aiCharacterList
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveIsAdultAccessible(member: Member?): Boolean {
|
||||
if (member == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return memberContentPreferenceService.getStoredPreference(member).isAdult
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import kr.co.vividnext.sodalive.chat.character.image.dto.CharacterImagePurchaseR
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
@@ -25,6 +26,7 @@ class CharacterImageController(
|
||||
private val imageService: CharacterImageService,
|
||||
private val imageCloudFront: ImageContentCloudFront,
|
||||
private val canPaymentService: CanPaymentService,
|
||||
private val memberContentPreferenceService: MemberContentPreferenceService,
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val imageHost: String
|
||||
) {
|
||||
@@ -37,7 +39,7 @@ class CharacterImageController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
|
||||
val pageSize = if (size <= 0) 20 else minOf(size, 20)
|
||||
|
||||
@@ -125,7 +127,7 @@ class CharacterImageController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
|
||||
val pageSize = if (size <= 0) 20 else minOf(size, 20)
|
||||
val expiration = 5L * 60L * 1000L // 5분
|
||||
@@ -199,7 +201,7 @@ class CharacterImageController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
if (member.auth == null) throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
validateAdultAccess(member)
|
||||
|
||||
val image = imageService.getById(req.imageId)
|
||||
if (!image.isActive) throw SodaException(messageKey = "chat.character.image.inactive")
|
||||
@@ -223,4 +225,10 @@ class CharacterImageController(
|
||||
val signedUrl = imageCloudFront.generateSignedURL(image.imagePath, expiration)
|
||||
ApiResponse.ok(CharacterImagePurchaseResponse(imageUrl = signedUrl))
|
||||
}
|
||||
|
||||
private fun validateAdultAccess(member: Member) {
|
||||
if (!memberContentPreferenceService.getStoredPreference(member).isAdult) {
|
||||
throw SodaException(messageKey = "common.error.adult_verification_required")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user