From be6f7971c61423d9ace1c13d28bec9d30b248c9e Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 4 Feb 2026 22:36:37 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=A7=80=EA=B8=88=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=20=EC=A4=91=20-=20=EB=B3=B8=EC=9D=B8=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EC=9D=84=20=ED=95=98=EC=A7=80=20=EC=95=8A=EC=95=84?= =?UTF-8?q?=EB=8F=84=2019=EA=B8=88=20=EB=B0=A9=EC=86=A1=EC=9D=B4=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/co/vividnext/sodalive/live/room/LiveRoomService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt index 6938f1e4..691d6567 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomService.kt @@ -206,7 +206,7 @@ class LiveRoomService( timezone, memberId = member?.id, isCreator = member?.role == MemberRole.CREATOR, - isAdult = member?.auth != null && isAdultContentVisible, + isAdult = true, effectiveGender = effectiveGender ) } else if (dateString != null) { From 3e41e763e34150dbd6f6abdae60e049da933f0eb Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 5 Feb 2026 17:16:54 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/content/AdminContentController.kt | 11 ++++--- .../admin/content/AdminContentService.kt | 31 ++++++++++++++++--- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentController.kt index 65ebb64c..7e303c80 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentController.kt @@ -2,13 +2,15 @@ package kr.co.vividnext.sodalive.admin.content import kr.co.vividnext.sodalive.common.ApiResponse import org.springframework.data.domain.Pageable +import org.springframework.http.MediaType import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PutMapping -import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RequestPart import org.springframework.web.bind.annotation.RestController +import org.springframework.web.multipart.MultipartFile @RestController @PreAuthorize("hasRole('ADMIN')") @@ -38,10 +40,11 @@ class AdminContentController(private val service: AdminContentService) { ) ) - @PutMapping + @PutMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) fun modifyAudioContent( - @RequestBody request: UpdateAdminContentRequest - ) = ApiResponse.ok(service.updateAudioContent(request)) + @RequestPart("request") requestString: String, + @RequestPart("coverImage", required = false) coverImage: MultipartFile? = null + ) = ApiResponse.ok(service.updateAudioContent(coverImage, requestString)) @GetMapping("/main/tab") fun getContentMainTabList() = ApiResponse.ok(service.getContentMainTabList()) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt index 344f9b81..14f591b5 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt @@ -1,15 +1,21 @@ package kr.co.vividnext.sodalive.admin.content +import com.amazonaws.services.s3.model.ObjectMetadata +import com.fasterxml.jackson.databind.ObjectMapper import kr.co.vividnext.sodalive.admin.content.curation.AdminContentCurationRepository import kr.co.vividnext.sodalive.admin.content.tab.AdminContentMainTabRepository import kr.co.vividnext.sodalive.admin.content.theme.AdminContentThemeRepository import kr.co.vividnext.sodalive.aws.cloudfront.AudioContentCloudFront +import kr.co.vividnext.sodalive.aws.s3.S3Uploader import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.content.main.tab.GetContentMainTabItem +import kr.co.vividnext.sodalive.utils.generateFileName +import org.springframework.beans.factory.annotation.Value import org.springframework.data.domain.Pageable import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import org.springframework.web.multipart.MultipartFile @Service class AdminContentService( @@ -17,7 +23,11 @@ class AdminContentService( private val themeRepository: AdminContentThemeRepository, private val audioContentCloudFront: AudioContentCloudFront, private val curationRepository: AdminContentCurationRepository, - private val contentMainTabRepository: AdminContentMainTabRepository + private val contentMainTabRepository: AdminContentMainTabRepository, + private val objectMapper: ObjectMapper, + private val s3Uploader: S3Uploader, + @Value("\${cloud.aws.s3.bucket}") + private val bucket: String ) { fun getAudioContentList(status: ContentReleaseStatus, pageable: Pageable): GetAdminContentListResponse { val totalCount = repository.getAudioContentTotalCount(status = status) @@ -82,12 +92,25 @@ class AdminContentService( } @Transactional - fun updateAudioContent(request: UpdateAdminContentRequest) { + fun updateAudioContent(coverImage: MultipartFile?, requestString: String) { + val request = objectMapper.readValue(requestString, UpdateAdminContentRequest::class.java) val audioContent = repository.findByIdOrNull(id = request.id) ?: throw SodaException(messageKey = "admin.content.not_found") - if (request.isDefaultCoverImage) { - audioContent.coverImage = "`profile/default_profile.png`" + if (coverImage != null) { + val metadata = ObjectMetadata() + metadata.contentLength = coverImage.size + + val fileName = generateFileName() + val imagePath = s3Uploader.upload( + inputStream = coverImage.inputStream, + bucket = bucket, + filePath = "audio_content_cover/${request.id}/$fileName", + metadata = metadata + ) + audioContent.coverImage = imagePath + } else if (request.isDefaultCoverImage) { + audioContent.coverImage = "profile/default_profile.png" } if (request.isActive != null) { From 328be036f714896c0634abf5b47f12c97acbbd92 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 5 Feb 2026 18:01:33 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=8B=9C=20=ED=8C=8C=EC=9D=BC=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=ED=8C=A8=ED=84=B4=EC=9D=84=20=ED=81=AC=EB=A6=AC?= =?UTF-8?q?=EC=97=90=EC=9D=B4=ED=84=B0=EA=B0=80=20=EC=98=AC=EB=A6=AC?= =?UTF-8?q?=EB=8D=98=20=ED=8C=A8=ED=84=B4=EA=B3=BC=20=EB=8F=99=EC=9D=BC?= =?UTF-8?q?=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/vividnext/sodalive/admin/content/AdminContentService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt index 14f591b5..dbdbd277 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/content/AdminContentService.kt @@ -101,7 +101,7 @@ class AdminContentService( val metadata = ObjectMetadata() metadata.contentLength = coverImage.size - val fileName = generateFileName() + val fileName = generateFileName(prefix = "${request.id}-cover") val imagePath = s3Uploader.upload( inputStream = coverImage.inputStream, bucket = bucket, From d90a872e797695f4e3bcbdd40155e7d05198d927 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 6 Feb 2026 13:52:30 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EB=B8=8C=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20-=20apple-test,=20google-test=20=EA=B3=84?= =?UTF-8?q?=EC=A0=95=EC=9D=80=20isAdult=EA=B0=80=20true=EC=9D=B8=20?= =?UTF-8?q?=EB=B0=A9=EC=9D=B4=20=ED=95=AD=EC=83=81=20=EB=B3=B4=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sodalive/live/room/LiveRoomRepository.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt index c64de8ab..849a1adc 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/LiveRoomRepository.kt @@ -89,11 +89,13 @@ class LiveRoomQueryRepositoryImpl( .and(liveRoom.isActive.isTrue) .and(liveRoom.member.isNotNull) - if (!isAdult) { + val isAdultRestricted = !isAdult || memberId == 17L || memberId == 16L + if (isAdultRestricted) { where = where.and(liveRoom.isAdult.isFalse) } - if (isCreator && memberId != null) { + val hasMemberId = memberId != null + if (isCreator && hasMemberId) { where = where.and( liveRoom.isAvailableJoinCreator.isTrue .or(liveRoom.member.id.eq(memberId)) @@ -106,7 +108,7 @@ class LiveRoomQueryRepositoryImpl( Gender.FEMALE -> liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.FEMALE_ONLY) Gender.NONE -> liveRoom.genderRestriction.isNotNull } - where = if (memberId != null) { + where = if (hasMemberId) { where.and(genderCondition.or(liveRoom.member.id.eq(memberId))) } else { where.and(genderCondition) @@ -118,7 +120,7 @@ class LiveRoomQueryRepositoryImpl( .innerJoin(liveRoom.member, member) .leftJoin(quarterLiveRankings).on(liveRoom.id.eq(quarterLiveRankings.roomId)) - if (memberId != null) { + if (hasMemberId) { val blockMemberCondition = blockMember.member.id.eq(member.id) .and(blockMember.blockedMember.id.eq(memberId)) .and(blockMember.isActive.isTrue) @@ -158,7 +160,8 @@ class LiveRoomQueryRepositoryImpl( .and(liveRoom.isActive.isTrue) .and(liveRoom.member.isNotNull) - if (!isAdult) { + val isAdultRestricted = !isAdult || memberId == 17L || memberId == 16L + if (isAdultRestricted) { where = where.and(liveRoom.isAdult.isFalse) } @@ -223,7 +226,8 @@ class LiveRoomQueryRepositoryImpl( .and(liveRoom.isActive.isTrue) .and(liveRoom.member.isNotNull) - if (!isAdult) { + val isAdultRestricted = !isAdult || memberId == 17L || memberId == 16L + if (isAdultRestricted) { where = where.and(liveRoom.isAdult.isFalse) }