커뮤니티 API 추가
This commit is contained in:
parent
7e02acd22c
commit
8a3d11ae59
|
@ -0,0 +1,7 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
data class CreateCommunityPostRequest(
|
||||
val content: String,
|
||||
val isCommentAvailable: Boolean,
|
||||
val isAdult: Boolean
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.FetchType
|
||||
import javax.persistence.JoinColumn
|
||||
import javax.persistence.ManyToOne
|
||||
|
||||
@Entity
|
||||
data class CreatorCommunity(
|
||||
@Column(columnDefinition = "TEXT", nullable = false)
|
||||
var content: String,
|
||||
var isCommentAvailable: Boolean,
|
||||
var isAdult: Boolean,
|
||||
@Column(nullable = true)
|
||||
var imagePath: String? = null,
|
||||
val isActive: Boolean = true
|
||||
) : BaseEntity() {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "member_id", nullable = false)
|
||||
var member: Member? = null
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.CreateCommunityPostCommentRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.ModifyCommunityPostCommentRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.PostCommunityPostLikeRequest
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.lang.Nullable
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.PutMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
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("/creator-community")
|
||||
class CreatorCommunityController(private val service: CreatorCommunityService) {
|
||||
@PostMapping
|
||||
@PreAuthorize("hasRole('CREATOR')")
|
||||
fun createCommunityPost(
|
||||
@Nullable
|
||||
@RequestPart("postImage")
|
||||
postImage: MultipartFile?,
|
||||
@RequestPart("request") requestString: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.createCommunityPost(
|
||||
postImage = postImage,
|
||||
requestString = requestString,
|
||||
member = member
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@PreAuthorize("hasRole('CREATOR')")
|
||||
fun modifyCommunityPost(
|
||||
@Nullable
|
||||
@RequestPart("postImage")
|
||||
postImage: MultipartFile?,
|
||||
@RequestPart("request") requestString: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.modifyCommunityPost(
|
||||
postImage = postImage,
|
||||
requestString = requestString,
|
||||
member = member
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
fun getCommunityPostList(
|
||||
@RequestParam creatorId: Long,
|
||||
@RequestParam timezone: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getCommunityPostList(
|
||||
creatorId = creatorId,
|
||||
memberId = member.id!!,
|
||||
timezone = timezone,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong(),
|
||||
isAdult = member.auth != null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@PostMapping("/like")
|
||||
fun communityPostLike(
|
||||
@RequestBody request: PostCommunityPostLikeRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(service.communityPostLike(request, member))
|
||||
}
|
||||
|
||||
@PostMapping("/comment")
|
||||
fun createCommunityPostComment(
|
||||
@RequestBody request: CreateCommunityPostCommentRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.createCommunityPostComment(
|
||||
comment = request.comment,
|
||||
postId = request.postId,
|
||||
parentId = request.parentId,
|
||||
member = member
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@PutMapping("/comment")
|
||||
fun modifyCommunityPostComment(
|
||||
@RequestBody request: ModifyCommunityPostCommentRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.modifyCommunityPostComment(request = request, member = member)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/comment")
|
||||
fun getCommunityPostCommentList(
|
||||
@PathVariable("id") postId: Long,
|
||||
@RequestParam timezone: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getCommunityPostCommentList(
|
||||
postId = postId,
|
||||
timezone = timezone,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.QCreatorCommunity.creatorCommunity
|
||||
import kr.co.vividnext.sodalive.member.QMember.member
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
interface CreatorCommunityRepository : JpaRepository<CreatorCommunity, Long>, CreatorCommunityQueryRepository
|
||||
|
||||
interface CreatorCommunityQueryRepository {
|
||||
fun findByIdAndMemberId(id: Long, memberId: Long): CreatorCommunity?
|
||||
|
||||
fun getCommunityPostList(
|
||||
creatorId: Long,
|
||||
offset: Long,
|
||||
limit: Long,
|
||||
isAdult: Boolean
|
||||
): List<CreatorCommunity>
|
||||
|
||||
fun findByIdAndActive(postId: Long): CreatorCommunity?
|
||||
}
|
||||
|
||||
class CreatorCommunityQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CreatorCommunityQueryRepository {
|
||||
override fun findByIdAndMemberId(id: Long, memberId: Long): CreatorCommunity? {
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunity)
|
||||
.where(
|
||||
creatorCommunity.id.eq(id)
|
||||
.and(creatorCommunity.member.id.eq(memberId))
|
||||
)
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
override fun getCommunityPostList(
|
||||
creatorId: Long,
|
||||
offset: Long,
|
||||
limit: Long,
|
||||
isAdult: Boolean
|
||||
): List<CreatorCommunity> {
|
||||
var where = creatorCommunity.member.id.eq(creatorId)
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(creatorCommunity.isAdult.isFalse)
|
||||
}
|
||||
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunity)
|
||||
.innerJoin(creatorCommunity.member, member)
|
||||
.where(where)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun findByIdAndActive(postId: Long): CreatorCommunity? {
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunity)
|
||||
.where(
|
||||
creatorCommunity.id.eq(postId)
|
||||
.and(creatorCommunity.isActive.isTrue)
|
||||
)
|
||||
.fetchFirst()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,277 @@
|
|||
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.s3.S3Uploader
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.CreatorCommunityComment
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.CreatorCommunityCommentRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.GetCommunityPostCommentListResponse
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.ModifyCommunityPostCommentRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.CreatorCommunityLike
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.CreatorCommunityLikeRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.PostCommunityPostLikeRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.PostCommunityPostLikeResponse
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.utils.generateFileName
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import java.time.Duration
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Service
|
||||
class CreatorCommunityService(
|
||||
private val repository: CreatorCommunityRepository,
|
||||
private val likeRepository: CreatorCommunityLikeRepository,
|
||||
private val commentRepository: CreatorCommunityCommentRepository,
|
||||
|
||||
private val s3Uploader: S3Uploader,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
|
||||
@Value("\${cloud.aws.s3.bucket}")
|
||||
private val imageBucket: String,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val imageHost: String
|
||||
) {
|
||||
@Transactional
|
||||
fun createCommunityPost(postImage: MultipartFile?, requestString: String, member: Member) {
|
||||
val request = objectMapper.readValue(requestString, CreateCommunityPostRequest::class.java)
|
||||
|
||||
val post = CreatorCommunity(
|
||||
content = request.content,
|
||||
isCommentAvailable = request.isCommentAvailable,
|
||||
isAdult = request.isAdult
|
||||
)
|
||||
post.member = member
|
||||
repository.save(post)
|
||||
|
||||
if (postImage != null) {
|
||||
val metadata = ObjectMetadata()
|
||||
metadata.contentLength = postImage.size
|
||||
|
||||
// 커버 이미지 파일명 생성
|
||||
val imageFileName = generateFileName(prefix = "${post.id}-image")
|
||||
|
||||
// 커버 이미지 업로드
|
||||
val imagePath = s3Uploader.upload(
|
||||
inputStream = postImage.inputStream,
|
||||
bucket = imageBucket,
|
||||
filePath = "creator_community/${post.id}/$imageFileName",
|
||||
metadata = metadata
|
||||
)
|
||||
|
||||
post.imagePath = imagePath
|
||||
}
|
||||
|
||||
applicationEventPublisher.publishEvent(
|
||||
FcmEvent(
|
||||
type = FcmEventType.CHANGE_NOTICE,
|
||||
title = member.nickname,
|
||||
message = "공지를 등록했습니다.",
|
||||
creatorId = member.id!!
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun modifyCommunityPost(postImage: MultipartFile?, requestString: String, member: Member) {
|
||||
val request = objectMapper.readValue(requestString, ModifyCommunityPostRequest::class.java)
|
||||
|
||||
val post = repository.findByIdAndMemberId(id = request.creatorCommunityId, memberId = member.id!!)
|
||||
?: throw SodaException("잘못된 요청입니다.")
|
||||
|
||||
if (request.content != null) {
|
||||
post.content = request.content
|
||||
}
|
||||
|
||||
if (request.isCommentAvailable != null) {
|
||||
post.isCommentAvailable = request.isCommentAvailable
|
||||
}
|
||||
|
||||
if (request.isAdult != null) {
|
||||
post.isAdult = request.isAdult
|
||||
}
|
||||
|
||||
if (postImage != null) {
|
||||
val metadata = ObjectMetadata()
|
||||
metadata.contentLength = postImage.size
|
||||
|
||||
// 커버 이미지 파일명 생성
|
||||
val imageFileName = generateFileName(prefix = "${post.id}-image")
|
||||
|
||||
// 커버 이미지 업로드
|
||||
val imagePath = s3Uploader.upload(
|
||||
inputStream = postImage.inputStream,
|
||||
bucket = imageBucket,
|
||||
filePath = "creator_community/${post.id}/$imageFileName",
|
||||
metadata = metadata
|
||||
)
|
||||
|
||||
post.imagePath = imagePath
|
||||
}
|
||||
}
|
||||
|
||||
fun getCommunityPostList(
|
||||
creatorId: Long,
|
||||
memberId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long,
|
||||
isAdult: Boolean
|
||||
): List<GetCommunityPostListResponse> {
|
||||
val postList = repository.getCommunityPostList(
|
||||
creatorId = creatorId,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
isAdult = isAdult
|
||||
)
|
||||
|
||||
return postList
|
||||
.asSequence()
|
||||
.map {
|
||||
val isLike = likeRepository.findByIdAndMemberId(id = it.id!!, memberId = memberId)?.isActive ?: false
|
||||
val likeCount = likeRepository.totalCountCommunityPostLikeByPostId(it.id!!)
|
||||
val commentCount = if (it.isCommentAvailable) {
|
||||
commentRepository.totalCountCommentByPostId(postId = it.id!!)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
val commentList = commentRepository.findByPostId(
|
||||
cloudFrontHost = imageHost,
|
||||
timezone = timezone,
|
||||
id = it.id!!,
|
||||
offset = 0,
|
||||
limit = 1
|
||||
)
|
||||
|
||||
val firstComment = if (commentList.isNotEmpty()) {
|
||||
commentList[0]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
GetCommunityPostListResponse(
|
||||
creatorNickname = it.member!!.nickname,
|
||||
creatorProfileUrl = if (it.member!!.profileImage != null) {
|
||||
"$imageHost/${it.member!!.profileImage}"
|
||||
} else {
|
||||
"$imageHost/profile/default-profile.png"
|
||||
},
|
||||
imageUrl = if (it.imagePath != null) {
|
||||
"$imageHost/${it.imagePath!!}"
|
||||
} else {
|
||||
null
|
||||
},
|
||||
content = it.content,
|
||||
date = getTimeAgoString(it.createdAt!!),
|
||||
isLike = isLike,
|
||||
likeCount = likeCount,
|
||||
commentCount = commentCount,
|
||||
firstComment = firstComment
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
private fun getTimeAgoString(dateTime: LocalDateTime): String {
|
||||
val now = LocalDateTime.now()
|
||||
val duration = Duration.between(dateTime, now)
|
||||
|
||||
return when {
|
||||
duration.toMinutes() < 60 -> "${duration.toMinutes()}분전"
|
||||
duration.toHours() < 24 -> "${duration.toHours()}시간전"
|
||||
duration.toDays() < 30 -> "${duration.toDays()}일전"
|
||||
duration.toDays() < 365 -> "${duration.toDays() / 30}분전"
|
||||
else -> "${duration.toDays() / 365}년전"
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun communityPostLike(request: PostCommunityPostLikeRequest, member: Member): PostCommunityPostLikeResponse {
|
||||
var postLike = likeRepository.findByIdAndMemberId(id = request.postId, memberId = member.id!!)
|
||||
|
||||
if (postLike == null) {
|
||||
postLike = CreatorCommunityLike()
|
||||
postLike.member = member
|
||||
|
||||
val post = repository.findByIdAndActive(request.postId)
|
||||
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
|
||||
postLike.creatorCommunity = post
|
||||
likeRepository.save(postLike)
|
||||
} else {
|
||||
postLike.isActive = !postLike.isActive
|
||||
}
|
||||
|
||||
return PostCommunityPostLikeResponse(like = postLike.isActive)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun createCommunityPostComment(comment: String, postId: Long, parentId: Long?, member: Member) {
|
||||
val post = repository.findByIdOrNull(id = postId)
|
||||
?: throw SodaException("잘못된 게시물 입니다.\n다시 시도해 주세요.")
|
||||
|
||||
val postComment = CreatorCommunityComment(comment = comment)
|
||||
postComment.creatorCommunity = post
|
||||
postComment.member = member
|
||||
|
||||
val parent = if (parentId != null) {
|
||||
commentRepository.findByIdOrNull(id = parentId)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
postComment.parent = parent
|
||||
}
|
||||
|
||||
commentRepository.save(postComment)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun modifyCommunityPostComment(request: ModifyCommunityPostCommentRequest, member: Member) {
|
||||
val postComment = commentRepository.findByIdOrNull(id = request.commentId)
|
||||
?: throw SodaException("잘못된 접근 입니다.\n확인 후 다시 시도해 주세요.")
|
||||
|
||||
if (request.comment != null && postComment.member!!.id!! == member.id!!) {
|
||||
postComment.comment = request.comment
|
||||
}
|
||||
|
||||
if (
|
||||
request.isActive != null &&
|
||||
(
|
||||
postComment.member!!.id!! == member.id!! ||
|
||||
postComment.creatorCommunity!!.member!!.id!! == member.id!!
|
||||
)
|
||||
) {
|
||||
postComment.isActive = request.isActive
|
||||
}
|
||||
}
|
||||
|
||||
fun getCommunityPostCommentList(
|
||||
postId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetCommunityPostCommentListResponse {
|
||||
val commentList = commentRepository.findByPostId(
|
||||
cloudFrontHost = imageHost,
|
||||
timezone = timezone,
|
||||
id = postId,
|
||||
offset = offset,
|
||||
limit = limit
|
||||
)
|
||||
|
||||
val totalCount = commentRepository.totalCountCommentByPostId(postId = postId)
|
||||
|
||||
return GetCommunityPostCommentListResponse(totalCount = totalCount, items = commentList)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.GetCommunityPostCommentListItem
|
||||
|
||||
data class GetCommunityPostListResponse @QueryProjection constructor(
|
||||
val creatorNickname: String,
|
||||
val creatorProfileUrl: String,
|
||||
val imageUrl: String?,
|
||||
val content: String,
|
||||
val date: String,
|
||||
val isLike: Boolean,
|
||||
val likeCount: Int,
|
||||
val commentCount: Int,
|
||||
val firstComment: GetCommunityPostCommentListItem?
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
data class ModifyCommunityPostRequest(
|
||||
val creatorCommunityId: Long,
|
||||
val content: String?,
|
||||
val isCommentAvailable: Boolean?,
|
||||
val isAdult: Boolean?
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
|
||||
data class CreateCommunityPostCommentRequest(val comment: String, val postId: Long, val parentId: Long?)
|
|
@ -0,0 +1,37 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
|
||||
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunity
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.FetchType
|
||||
import javax.persistence.JoinColumn
|
||||
import javax.persistence.ManyToOne
|
||||
import javax.persistence.OneToMany
|
||||
|
||||
@Entity
|
||||
data class CreatorCommunityComment(
|
||||
@Column(columnDefinition = "TEXT", nullable = false)
|
||||
var comment: String,
|
||||
var isActive: Boolean = true
|
||||
) : BaseEntity() {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "parent_id", nullable = true)
|
||||
var parent: CreatorCommunityComment? = null
|
||||
set(value) {
|
||||
value?.children?.add(this)
|
||||
field = value
|
||||
}
|
||||
|
||||
@OneToMany(mappedBy = "parent")
|
||||
var children: MutableList<CreatorCommunityComment> = mutableListOf()
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "member_id", nullable = false)
|
||||
var member: Member? = null
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "creator_community_id", nullable = false)
|
||||
var creatorCommunity: CreatorCommunity? = null
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.QCreatorCommunityComment.creatorCommunityComment
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
interface CreatorCommunityCommentRepository :
|
||||
JpaRepository<CreatorCommunityComment, Long>, CreatorCommunityCommentQueryRepository
|
||||
|
||||
interface CreatorCommunityCommentQueryRepository {
|
||||
fun findByPostId(
|
||||
cloudFrontHost: String,
|
||||
timezone: String,
|
||||
id: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetCommunityPostCommentListItem>
|
||||
|
||||
fun commentReplyCountByCommentId(commentId: Long): Int
|
||||
|
||||
fun totalCountCommentByPostId(postId: Long): Int
|
||||
}
|
||||
|
||||
class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
private val queryFactory: JPAQueryFactory
|
||||
) : CreatorCommunityCommentQueryRepository {
|
||||
override fun findByPostId(
|
||||
cloudFrontHost: String,
|
||||
timezone: String,
|
||||
id: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetCommunityPostCommentListItem> {
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunityComment)
|
||||
.where(
|
||||
creatorCommunityComment.isActive.isTrue
|
||||
.and(creatorCommunityComment.creatorCommunity.id.eq(id))
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
.asSequence()
|
||||
.map {
|
||||
val date = it.createdAt!!
|
||||
.atZone(ZoneId.of("UTC"))
|
||||
.withZoneSameInstant(ZoneId.of(timezone))
|
||||
|
||||
GetCommunityPostCommentListItem(
|
||||
id = it.id!!,
|
||||
writerId = it.member!!.id!!,
|
||||
nickname = it.member!!.nickname,
|
||||
profileUrl = if (it.member!!.profileImage != null) {
|
||||
"$cloudFrontHost/${it.member!!.profileImage}"
|
||||
} else {
|
||||
"$cloudFrontHost/profile/default-profile.png"
|
||||
},
|
||||
comment = it.comment,
|
||||
date = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd E hh:mm a")),
|
||||
replyCount = commentReplyCountByCommentId(it.id!!)
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
override fun commentReplyCountByCommentId(commentId: Long): Int {
|
||||
return queryFactory.select(creatorCommunityComment.id)
|
||||
.from(creatorCommunityComment)
|
||||
.where(
|
||||
creatorCommunityComment.isActive.isTrue
|
||||
.and(creatorCommunityComment.parent.isNotNull)
|
||||
.and(creatorCommunityComment.parent.id.eq(commentId))
|
||||
)
|
||||
.fetch()
|
||||
.size
|
||||
}
|
||||
|
||||
override fun totalCountCommentByPostId(postId: Long): Int {
|
||||
return queryFactory.select(creatorCommunityComment.id)
|
||||
.from(creatorCommunityComment)
|
||||
.where(
|
||||
creatorCommunityComment.creatorCommunity.id.eq(postId)
|
||||
.and(creatorCommunityComment.isActive.isTrue)
|
||||
.and(creatorCommunityComment.parent.isNull)
|
||||
)
|
||||
.fetch()
|
||||
.size
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
|
||||
data class GetCommunityPostCommentListResponse(
|
||||
val totalCount: Int,
|
||||
val items: List<GetCommunityPostCommentListItem>
|
||||
)
|
||||
|
||||
data class GetCommunityPostCommentListItem(
|
||||
val id: Long,
|
||||
val writerId: Long,
|
||||
val nickname: String,
|
||||
val profileUrl: String,
|
||||
val comment: String,
|
||||
val date: String,
|
||||
val replyCount: Int
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
|
||||
data class ModifyCommunityPostCommentRequest(val commentId: Long, val comment: String?, val isActive: Boolean?)
|
|
@ -0,0 +1,22 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like
|
||||
|
||||
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunity
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.FetchType
|
||||
import javax.persistence.JoinColumn
|
||||
import javax.persistence.ManyToOne
|
||||
|
||||
@Entity
|
||||
data class CreatorCommunityLike(
|
||||
var isActive: Boolean = true
|
||||
) : BaseEntity() {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "member_id", nullable = false)
|
||||
var member: Member? = null
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "creator_community_id", nullable = false)
|
||||
var creatorCommunity: CreatorCommunity? = null
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.QCreatorCommunityLike.creatorCommunityLike
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
interface CreatorCommunityLikeRepository :
|
||||
JpaRepository<CreatorCommunityLike, Long>, CreatorCommunityLikeQueryRepository {
|
||||
fun findByIdAndMemberId(id: Long, memberId: Long): CreatorCommunityLike?
|
||||
}
|
||||
|
||||
interface CreatorCommunityLikeQueryRepository {
|
||||
fun totalCountCommunityPostLikeByPostId(postId: Long): Int
|
||||
}
|
||||
|
||||
class CreatorCommunityLikeQueryRepositoryImpl(
|
||||
private val queryFactory: JPAQueryFactory
|
||||
) : CreatorCommunityLikeQueryRepository {
|
||||
override fun totalCountCommunityPostLikeByPostId(postId: Long): Int {
|
||||
return queryFactory
|
||||
.select(creatorCommunityLike.id)
|
||||
.from(creatorCommunityLike)
|
||||
.where(
|
||||
creatorCommunityLike.isActive.isTrue
|
||||
.and(creatorCommunityLike.creatorCommunity.id.eq(postId))
|
||||
)
|
||||
.fetch()
|
||||
.size
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like
|
||||
|
||||
data class PostCommunityPostLikeRequest(val postId: Long)
|
|
@ -0,0 +1,3 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like
|
||||
|
||||
data class PostCommunityPostLikeResponse(val like: Boolean)
|
Loading…
Reference in New Issue