From ca4ea0e5ea3b7bebc75abbdec6aba6ac2223a1ea Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 1 Aug 2024 22:03:41 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20-=20?= =?UTF-8?q?=EC=98=A4=EB=94=94=EC=98=A4=20=EB=93=B1=EB=A1=9D=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../creatorCommunity/CreatorCommunity.kt | 2 ++ .../CreatorCommunityController.kt | 4 +++ .../CreatorCommunityService.kt | 25 ++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt index 68143c7..7143dc2 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt @@ -17,6 +17,8 @@ data class CreatorCommunity( var isCommentAvailable: Boolean, var isAdult: Boolean, @Column(nullable = true) + var audioPath: String? = null, + @Column(nullable = true) var imagePath: String? = null, var isActive: Boolean = true ) : BaseEntity() { 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 0307940..7c72840 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 @@ -27,6 +27,9 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @PostMapping @PreAuthorize("hasRole('CREATOR')") fun createCommunityPost( + @Nullable + @RequestPart("contentFile") + audioFile: MultipartFile?, @Nullable @RequestPart("postImage") postImage: MultipartFile?, @@ -37,6 +40,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { ApiResponse.ok( service.createCommunityPost( + audioFile = audioFile, postImage = postImage, requestString = requestString, member = member 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 cf429c1..da14f5a 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 @@ -50,13 +50,22 @@ class CreatorCommunityService( private val imageHost: String ) { @Transactional - fun createCommunityPost(postImage: MultipartFile?, requestString: String, member: Member) { + fun createCommunityPost( + audioFile: MultipartFile?, + postImage: MultipartFile?, + requestString: String, + member: Member + ) { val request = objectMapper.readValue(requestString, CreateCommunityPostRequest::class.java) if (request.price > 0 && postImage == null) { throw SodaException("유료 게시글 등록을 위해서는 이미지가 필요합니다.") } + if (audioFile != null && postImage == null) { + throw SodaException("오디오 등록을 위해서는 이미지가 필요합니다.") + } + val post = CreatorCommunity( content = request.content, price = request.price, @@ -84,6 +93,20 @@ class CreatorCommunityService( post.imagePath = imagePath } + if (audioFile != null) { + val metadata = ObjectMetadata() + metadata.contentLength = audioFile.size + + val audioPath = s3Uploader.upload( + inputStream = audioFile.inputStream, + bucket = imageBucket, + filePath = "creator_community/${post.id}/${generateFileName(prefix = "${post.id}-audio")}.m4a", + metadata = metadata + ) + + post.audioPath = audioPath + } + applicationEventPublisher.publishEvent( FcmEvent( type = FcmEventType.CHANGE_NOTICE, From 429dc2b848a43ee1b1e2e33506c22463fe918741 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 5 Aug 2024 17:31:47 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20-=20?= =?UTF-8?q?=EC=98=A4=EB=94=94=EC=98=A4=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B2=84=ED=82=B7=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../profile/creatorCommunity/CreatorCommunityService.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 da14f5a..fa8174e 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 @@ -46,6 +46,9 @@ class CreatorCommunityService( @Value("\${cloud.aws.s3.bucket}") private val imageBucket: String, + @Value("\${cloud.aws.s3.content-bucket}") + private val contentBucket: String, + @Value("\${cloud.aws.cloud-front.host}") private val imageHost: String ) { @@ -99,7 +102,7 @@ class CreatorCommunityService( val audioPath = s3Uploader.upload( inputStream = audioFile.inputStream, - bucket = imageBucket, + bucket = contentBucket, filePath = "creator_community/${post.id}/${generateFileName(prefix = "${post.id}-audio")}.m4a", metadata = metadata ) From c2d7d12767c6fda9674d588fe151975f8b092493 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 5 Aug 2024 17:57:12 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20-=20=EC=98=A4=EB=94=94=EC=98=A4=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=EA=B0=80=20=EC=9E=88=EB=8A=94=20=ED=8F=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=8A=94=20=EC=98=A4=EB=94=94=EC=98=A4=20URL?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../creatorCommunity/CreatorCommunity.kt | 2 ++ .../CreatorCommunityRepository.kt | 3 ++ .../CreatorCommunityService.kt | 33 +++++++++++++++++++ .../GetCommunityPostListResponse.kt | 1 + .../SelectCommunityPostResponse.kt | 3 ++ 5 files changed, 42 insertions(+) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt index 7143dc2..e22cee7 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt @@ -28,6 +28,7 @@ data class CreatorCommunity( fun toCommunityPostListResponse( imageHost: String, + audioUrl: String?, content: String, date: String, isLike: Boolean, @@ -46,6 +47,7 @@ data class CreatorCommunity( } else { null }, + audioUrl = audioUrl, content = content, price = price, date = date, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityRepository.kt index 49e22a7..6f3ffcf 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunityRepository.kt @@ -64,6 +64,7 @@ class CreatorCommunityQueryRepositoryImpl(private val queryFactory: JPAQueryFact creatorCommunity.member.nickname, creatorCommunity.member.profileImage.coalesce("profile/default_profile.png"), creatorCommunity.imagePath, + creatorCommunity.audioPath, creatorCommunity.content, creatorCommunity.createdAt, creatorCommunity.isCommentAvailable, @@ -149,6 +150,7 @@ class CreatorCommunityQueryRepositoryImpl(private val queryFactory: JPAQueryFact creatorCommunity.member.nickname, creatorCommunity.member.profileImage.coalesce("profile/default_profile.png"), creatorCommunity.imagePath, + creatorCommunity.audioPath, creatorCommunity.content, creatorCommunity.createdAt, creatorCommunity.isCommentAvailable, @@ -179,6 +181,7 @@ class CreatorCommunityQueryRepositoryImpl(private val queryFactory: JPAQueryFact creatorCommunity.member.nickname, creatorCommunity.member.profileImage.coalesce("profile/default_profile.png"), creatorCommunity.imagePath, + creatorCommunity.audioPath, creatorCommunity.content, creatorCommunity.createdAt, creatorCommunity.isCommentAvailable, 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 fa8174e..11e3c72 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 @@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity import com.amazonaws.services.s3.model.ObjectMetadata import com.fasterxml.jackson.databind.ObjectMapper +import kr.co.vividnext.sodalive.aws.cloudfront.AudioContentCloudFront import kr.co.vividnext.sodalive.aws.s3.S3Uploader import kr.co.vividnext.sodalive.can.payment.CanPaymentService import kr.co.vividnext.sodalive.can.use.CanUsage @@ -41,6 +42,7 @@ class CreatorCommunityService( private val s3Uploader: S3Uploader, private val objectMapper: ObjectMapper, + private val audioContentCloudFront: AudioContentCloudFront, private val applicationEventPublisher: ApplicationEventPublisher, @Value("\${cloud.aws.s3.bucket}") @@ -212,8 +214,18 @@ class CreatorCommunityService( val existOrdered = useCanRepository.isExistOrdered(postId = it.id, memberId = memberId) + val audioUrl = if ((it.price <= 0 || existOrdered) && it.audioPath != null) { + audioContentCloudFront.generateSignedURL( + resourcePath = it.audioPath, + expirationTime = 1000 * 60 * 30 + ) + } else { + null + } + it.toCommunityPostListResponse( imageHost = imageHost, + audioUrl = audioUrl, date = getTimeAgoString(it.date), isLike = isLike, memberId = memberId, @@ -268,8 +280,18 @@ class CreatorCommunityService( val existOrdered = useCanRepository.isExistOrdered(postId = post.id, memberId = memberId) + val audioUrl = if ((post.price <= 0 || existOrdered) && post.audioPath != null) { + audioContentCloudFront.generateSignedURL( + resourcePath = post.audioPath, + expirationTime = 1000 * 60 * 30 + ) + } else { + null + } + return post.toCommunityPostListResponse( imageHost = imageHost, + audioUrl = audioUrl, date = getTimeAgoString(post.date), isLike = isLike, memberId = memberId, @@ -440,6 +462,7 @@ class CreatorCommunityService( it.toCommunityPostListResponse( imageHost = imageHost, + audioUrl = null, date = getTimeAgoString(it.date), isLike = isLike, memberId = memberId, @@ -506,8 +529,18 @@ class CreatorCommunityService( null } + val audioUrl = if (post.audioPath != null) { + audioContentCloudFront.generateSignedURL( + resourcePath = post.audioPath!!, + expirationTime = 1000 * 60 * 30 + ) + } else { + null + } + return post.toCommunityPostListResponse( imageHost = imageHost, + audioUrl = audioUrl, content = post.content, date = getTimeAgoString(post.createdAt!!), isLike = isLike, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/GetCommunityPostListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/GetCommunityPostListResponse.kt index b4b9b94..81a5f22 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/GetCommunityPostListResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/GetCommunityPostListResponse.kt @@ -9,6 +9,7 @@ data class GetCommunityPostListResponse @QueryProjection constructor( val creatorNickname: String, val creatorProfileUrl: String, val imageUrl: String?, + val audioUrl: String?, val content: String, val price: Int, val date: String, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/SelectCommunityPostResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/SelectCommunityPostResponse.kt index ec0cb2d..8f69f6f 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/SelectCommunityPostResponse.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/SelectCommunityPostResponse.kt @@ -10,6 +10,7 @@ data class SelectCommunityPostResponse @QueryProjection constructor( val creatorNickname: String, val creatorProfileUrl: String, val imagePath: String?, + val audioPath: String?, val content: String, val date: LocalDateTime, val isCommentAvailable: Boolean, @@ -17,6 +18,7 @@ data class SelectCommunityPostResponse @QueryProjection constructor( ) { fun toCommunityPostListResponse( imageHost: String, + audioUrl: String?, date: String, isLike: Boolean, memberId: Long, @@ -35,6 +37,7 @@ data class SelectCommunityPostResponse @QueryProjection constructor( } else { null }, + audioUrl = audioUrl, content = if (price > 0 && memberId != creatorId) { if (existOrdered) { content From 80b91aa445b43883f6bcbd8ed508ff16894c1f67 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 5 Aug 2024 20:36:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20-=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20contentFile=20->=20audioFile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../profile/creatorCommunity/CreatorCommunityController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7c72840..85c61b8 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 @@ -28,7 +28,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { @PreAuthorize("hasRole('CREATOR')") fun createCommunityPost( @Nullable - @RequestPart("contentFile") + @RequestPart("audioFile") audioFile: MultipartFile?, @Nullable @RequestPart("postImage")