Merge pull request '크리에이터 커뮤니티' (#201) from test into main
Reviewed-on: #201
This commit is contained in:
		| @@ -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() { | ||||
| @@ -26,6 +28,7 @@ data class CreatorCommunity( | ||||
|  | ||||
|     fun toCommunityPostListResponse( | ||||
|         imageHost: String, | ||||
|         audioUrl: String?, | ||||
|         content: String, | ||||
|         date: String, | ||||
|         isLike: Boolean, | ||||
| @@ -44,6 +47,7 @@ data class CreatorCommunity( | ||||
|             } else { | ||||
|                 null | ||||
|             }, | ||||
|             audioUrl = audioUrl, | ||||
|             content = content, | ||||
|             price = price, | ||||
|             date = date, | ||||
|   | ||||
| @@ -27,6 +27,9 @@ class CreatorCommunityController(private val service: CreatorCommunityService) { | ||||
|     @PostMapping | ||||
|     @PreAuthorize("hasRole('CREATOR')") | ||||
|     fun createCommunityPost( | ||||
|         @Nullable | ||||
|         @RequestPart("audioFile") | ||||
|         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 | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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,22 +42,35 @@ class CreatorCommunityService( | ||||
|  | ||||
|     private val s3Uploader: S3Uploader, | ||||
|     private val objectMapper: ObjectMapper, | ||||
|     private val audioContentCloudFront: AudioContentCloudFront, | ||||
|     private val applicationEventPublisher: ApplicationEventPublisher, | ||||
|  | ||||
|     @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 | ||||
| ) { | ||||
|     @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 +98,20 @@ class CreatorCommunityService( | ||||
|             post.imagePath = imagePath | ||||
|         } | ||||
|  | ||||
|         if (audioFile != null) { | ||||
|             val metadata = ObjectMetadata() | ||||
|             metadata.contentLength = audioFile.size | ||||
|  | ||||
|             val audioPath = s3Uploader.upload( | ||||
|                 inputStream = audioFile.inputStream, | ||||
|                 bucket = contentBucket, | ||||
|                 filePath = "creator_community/${post.id}/${generateFileName(prefix = "${post.id}-audio")}.m4a", | ||||
|                 metadata = metadata | ||||
|             ) | ||||
|  | ||||
|             post.audioPath = audioPath | ||||
|         } | ||||
|  | ||||
|         applicationEventPublisher.publishEvent( | ||||
|             FcmEvent( | ||||
|                 type = FcmEventType.CHANGE_NOTICE, | ||||
| @@ -186,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, | ||||
| @@ -242,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, | ||||
| @@ -414,6 +462,7 @@ class CreatorCommunityService( | ||||
|  | ||||
|                 it.toCommunityPostListResponse( | ||||
|                     imageHost = imageHost, | ||||
|                     audioUrl = null, | ||||
|                     date = getTimeAgoString(it.date), | ||||
|                     isLike = isLike, | ||||
|                     memberId = memberId, | ||||
| @@ -480,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, | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user