Merge pull request '크리에이터 커뮤니티' (#102) from test into main
Reviewed-on: #102
This commit is contained in:
commit
5c250ea4ae
|
@ -11,6 +11,7 @@ import kr.co.vividnext.sodalive.explorer.profile.CreatorCheers
|
|||
import kr.co.vividnext.sodalive.explorer.profile.CreatorCheersRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.PostWriteCheersRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.PutWriteCheersRequest
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityService
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
||||
import kr.co.vividnext.sodalive.live.room.detail.GetRoomDetailUser
|
||||
|
@ -36,6 +37,8 @@ class ExplorerService(
|
|||
private val queryRepository: ExplorerQueryRepository,
|
||||
private val cheersRepository: CreatorCheersRepository,
|
||||
private val noticeRepository: ChannelNoticeRepository,
|
||||
private val communityService: CreatorCommunityService,
|
||||
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
|
@ -227,6 +230,16 @@ class ExplorerService(
|
|||
// 공지사항
|
||||
val notice = queryRepository.getNoticeString(creatorId)
|
||||
|
||||
// 커뮤니티
|
||||
val communityPostList = communityService.getCommunityPostList(
|
||||
creatorId = creatorId,
|
||||
memberId = member.id!!,
|
||||
timezone = timezone,
|
||||
offset = 0,
|
||||
limit = 3,
|
||||
isAdult = member.auth != null
|
||||
)
|
||||
|
||||
// 응원
|
||||
val cheers = queryRepository.getCheersList(creatorId, timezone = timezone, offset = 0, limit = 4)
|
||||
|
||||
|
@ -262,6 +275,7 @@ class ExplorerService(
|
|||
liveRoomList = liveRoomList,
|
||||
contentList = contentList,
|
||||
notice = notice,
|
||||
communityPostList = communityPostList,
|
||||
cheers = cheers,
|
||||
activitySummary = GetCreatorActivitySummary(
|
||||
liveCount = liveCount,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package kr.co.vividnext.sodalive.explorer
|
||||
|
||||
import kr.co.vividnext.sodalive.content.GetAudioContentListItem
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.GetCommunityPostListResponse
|
||||
|
||||
data class GetCreatorProfileResponse(
|
||||
val creator: CreatorResponse,
|
||||
|
@ -9,6 +10,7 @@ data class GetCreatorProfileResponse(
|
|||
val liveRoomList: List<LiveRoomResponse>,
|
||||
val contentList: List<GetAudioContentListItem>,
|
||||
val notice: String,
|
||||
val communityPostList: List<GetCommunityPostListResponse>,
|
||||
val cheers: GetCheersResponse,
|
||||
val activitySummary: GetCreatorActivitySummary,
|
||||
val isBlock: Boolean
|
||||
|
|
|
@ -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,
|
||||
var isActive: Boolean = true
|
||||
) : BaseEntity() {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "member_id", nullable = false)
|
||||
var member: Member? = null
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
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.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
|
||||
@RequestMapping("/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
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
fun getCommunityPostDetail(
|
||||
@PathVariable("id") postId: Long,
|
||||
@RequestParam timezone: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getCommunityPostDetail(
|
||||
postId = postId,
|
||||
memberId = member.id!!,
|
||||
timezone = timezone,
|
||||
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()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/comment/{id}")
|
||||
fun getCommentReplyList(
|
||||
@PathVariable("id") commentId: Long,
|
||||
@RequestParam timezone: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getCommentReplyList(
|
||||
commentId = commentId,
|
||||
timezone = timezone,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/latest")
|
||||
fun getLatestPostListFromCreatorsYouFollow(
|
||||
@RequestParam timezone: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getLatestPostListFromCreatorsYouFollow(
|
||||
timezone = timezone,
|
||||
memberId = member.id!!,
|
||||
isAdult = member.auth != null
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
import com.querydsl.core.types.dsl.Expressions
|
||||
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 kr.co.vividnext.sodalive.member.following.QCreatorFollowing.creatorFollowing
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
|
||||
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, isAdult: Boolean): CreatorCommunity?
|
||||
fun getLatestPostListFromCreatorsYouFollow(memberId: Long, isAdult: Boolean): List<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)
|
||||
.and(creatorCommunity.isActive.isTrue)
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(creatorCommunity.isAdult.isFalse)
|
||||
}
|
||||
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunity)
|
||||
.innerJoin(creatorCommunity.member, member)
|
||||
.where(where)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.orderBy(creatorCommunity.createdAt.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun findByIdAndActive(postId: Long, isAdult: Boolean): CreatorCommunity? {
|
||||
var where = creatorCommunity.id.eq(postId)
|
||||
.and(creatorCommunity.isActive.isTrue)
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(creatorCommunity.isAdult.isFalse)
|
||||
}
|
||||
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunity)
|
||||
.where(where)
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
override fun getLatestPostListFromCreatorsYouFollow(memberId: Long, isAdult: Boolean): List<CreatorCommunity> {
|
||||
val creatorCommunity = QCreatorCommunity.creatorCommunity
|
||||
val latest = QCreatorCommunity.creatorCommunity
|
||||
|
||||
val localDate = LocalDate.now().minusDays(7)
|
||||
val localTime = LocalTime.of(0, 0)
|
||||
var where = creatorCommunity.isActive.isTrue
|
||||
.and(creatorCommunity.createdAt.after(LocalDateTime.of(localDate, localTime)))
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(creatorCommunity.isAdult.isFalse)
|
||||
}
|
||||
|
||||
val subQuery = queryFactory
|
||||
.select(latest.member.id, latest.createdAt.max().`as`("maxCreatedAt"))
|
||||
.from(latest)
|
||||
.groupBy(latest.member.id)
|
||||
|
||||
where = where.and(
|
||||
Expressions.list(creatorCommunity.member.id, creatorCommunity.createdAt).`in`(subQuery)
|
||||
)
|
||||
|
||||
val memberSubQuery = queryFactory
|
||||
.select(creatorFollowing.creator.id)
|
||||
.from(creatorFollowing)
|
||||
.where(creatorFollowing.member.id.eq(memberId))
|
||||
|
||||
where = where.and(
|
||||
creatorCommunity.member.id.`in`(memberSubQuery)
|
||||
)
|
||||
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunity)
|
||||
.where(where)
|
||||
.orderBy(creatorCommunity.createdAt.desc())
|
||||
.limit(10)
|
||||
.fetch()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,429 @@
|
|||
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 (request.isActive != null) {
|
||||
post.isActive = request.isActive
|
||||
}
|
||||
|
||||
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.findByPostIdAndMemberId(postId = 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 = if (it.isCommentAvailable) {
|
||||
commentRepository.findByPostId(
|
||||
cloudFrontHost = imageHost,
|
||||
timezone = timezone,
|
||||
id = it.id!!,
|
||||
offset = 0,
|
||||
limit = 1
|
||||
)
|
||||
} else {
|
||||
listOf()
|
||||
}
|
||||
|
||||
val firstComment = if (it.isCommentAvailable && commentList.isNotEmpty()) {
|
||||
commentList[0]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
GetCommunityPostListResponse(
|
||||
postId = it.id!!,
|
||||
creatorId = it.member!!.id!!,
|
||||
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!!),
|
||||
isCommentAvailable = it.isCommentAvailable,
|
||||
isAdult = it.isAdult,
|
||||
isLike = isLike,
|
||||
likeCount = likeCount,
|
||||
commentCount = commentCount,
|
||||
firstComment = firstComment
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getCommunityPostDetail(
|
||||
postId: Long,
|
||||
memberId: Long,
|
||||
timezone: String,
|
||||
isAdult: Boolean
|
||||
): GetCommunityPostListResponse {
|
||||
val post = repository.findByIdAndActive(postId, isAdult = isAdult)
|
||||
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
|
||||
val isLike = likeRepository.findByPostIdAndMemberId(postId = post.id!!, memberId = memberId)?.isActive ?: false
|
||||
val likeCount = likeRepository.totalCountCommunityPostLikeByPostId(post.id!!)
|
||||
val commentCount = if (post.isCommentAvailable) {
|
||||
commentRepository.totalCountCommentByPostId(postId = post.id!!)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
val commentList = if (post.isCommentAvailable) {
|
||||
commentRepository.findByPostId(
|
||||
cloudFrontHost = imageHost,
|
||||
timezone = timezone,
|
||||
id = post.id!!,
|
||||
offset = 0,
|
||||
limit = 1
|
||||
)
|
||||
} else {
|
||||
listOf()
|
||||
}
|
||||
|
||||
val firstComment = if (post.isCommentAvailable && commentList.isNotEmpty()) {
|
||||
commentList[0]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
return GetCommunityPostListResponse(
|
||||
postId = post.id!!,
|
||||
creatorId = post.member!!.id!!,
|
||||
creatorNickname = post.member!!.nickname,
|
||||
creatorProfileUrl = if (post.member!!.profileImage != null) {
|
||||
"$imageHost/${post.member!!.profileImage}"
|
||||
} else {
|
||||
"$imageHost/profile/default-profile.png"
|
||||
},
|
||||
imageUrl = if (post.imagePath != null) {
|
||||
"$imageHost/${post.imagePath!!}"
|
||||
} else {
|
||||
null
|
||||
},
|
||||
content = post.content,
|
||||
date = getTimeAgoString(post.createdAt!!),
|
||||
isCommentAvailable = post.isCommentAvailable,
|
||||
isAdult = post.isAdult,
|
||||
isLike = isLike,
|
||||
likeCount = likeCount,
|
||||
commentCount = commentCount,
|
||||
firstComment = firstComment
|
||||
)
|
||||
}
|
||||
|
||||
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.findByPostIdAndMemberId(postId = request.postId, memberId = member.id!!)
|
||||
|
||||
if (postLike == null) {
|
||||
postLike = CreatorCommunityLike()
|
||||
postLike.member = member
|
||||
|
||||
val post = repository.findByIdAndActive(request.postId, isAdult = member.auth != null)
|
||||
?: 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)
|
||||
}
|
||||
|
||||
fun getCommentReplyList(
|
||||
commentId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetCommunityPostCommentListResponse {
|
||||
val commentList = commentRepository.getCommunityCommentReplyList(
|
||||
cloudFrontHost = imageHost,
|
||||
commentId = commentId,
|
||||
timezone = timezone,
|
||||
offset = offset,
|
||||
limit = limit
|
||||
)
|
||||
|
||||
val totalCount = commentRepository.commentReplyCountByCommentId(commentId)
|
||||
return GetCommunityPostCommentListResponse(totalCount = totalCount, items = commentList)
|
||||
}
|
||||
|
||||
fun getLatestPostListFromCreatorsYouFollow(
|
||||
timezone: String,
|
||||
memberId: Long,
|
||||
isAdult: Boolean
|
||||
): List<GetCommunityPostListResponse> {
|
||||
val postList = repository.getLatestPostListFromCreatorsYouFollow(memberId = memberId, isAdult = isAdult)
|
||||
|
||||
return postList
|
||||
.asSequence()
|
||||
.map {
|
||||
val isLike =
|
||||
likeRepository.findByPostIdAndMemberId(postId = 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 = if (it.isCommentAvailable) {
|
||||
commentRepository.findByPostId(
|
||||
cloudFrontHost = imageHost,
|
||||
timezone = timezone,
|
||||
id = it.id!!,
|
||||
offset = 0,
|
||||
limit = 1
|
||||
)
|
||||
} else {
|
||||
listOf()
|
||||
}
|
||||
|
||||
val firstComment = if (it.isCommentAvailable && commentList.isNotEmpty()) {
|
||||
commentList[0]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
GetCommunityPostListResponse(
|
||||
postId = it.id!!,
|
||||
creatorId = it.member!!.id!!,
|
||||
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!!),
|
||||
isCommentAvailable = it.isCommentAvailable,
|
||||
isAdult = it.isAdult,
|
||||
isLike = isLike,
|
||||
likeCount = likeCount,
|
||||
commentCount = commentCount,
|
||||
firstComment = firstComment
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
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 postId: Long,
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String,
|
||||
val creatorProfileUrl: String,
|
||||
val imageUrl: String?,
|
||||
val content: String,
|
||||
val date: String,
|
||||
val isCommentAvailable: Boolean,
|
||||
val isAdult: Boolean,
|
||||
val isLike: Boolean,
|
||||
val likeCount: Int,
|
||||
val commentCount: Int,
|
||||
val firstComment: GetCommunityPostCommentListItem?
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity
|
||||
|
||||
data class ModifyCommunityPostRequest(
|
||||
val creatorCommunityId: Long,
|
||||
val content: String?,
|
||||
val isCommentAvailable: Boolean?,
|
||||
val isAdult: Boolean?,
|
||||
val isActive: 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,142 @@
|
|||
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
|
||||
|
||||
fun getCommunityCommentReplyList(
|
||||
cloudFrontHost: String,
|
||||
commentId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetCommunityPostCommentListItem>
|
||||
}
|
||||
|
||||
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))
|
||||
.and(creatorCommunityComment.parent.isNull)
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.orderBy(creatorCommunityComment.createdAt.desc())
|
||||
.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
|
||||
}
|
||||
|
||||
override fun getCommunityCommentReplyList(
|
||||
cloudFrontHost: String,
|
||||
commentId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetCommunityPostCommentListItem> {
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunityComment)
|
||||
.where(
|
||||
creatorCommunityComment.isActive.isTrue
|
||||
.and(creatorCommunityComment.parent.isNotNull)
|
||||
.and(creatorCommunityComment.parent.id.eq(commentId))
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.orderBy(creatorCommunityComment.createdAt.desc())
|
||||
.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()
|
||||
}
|
||||
}
|
|
@ -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,42 @@
|
|||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.QCreatorCommunity.creatorCommunity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.QCreatorCommunityLike.creatorCommunityLike
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
interface CreatorCommunityLikeRepository :
|
||||
JpaRepository<CreatorCommunityLike, Long>, CreatorCommunityLikeQueryRepository
|
||||
|
||||
interface CreatorCommunityLikeQueryRepository {
|
||||
fun findByPostIdAndMemberId(postId: Long, memberId: Long): CreatorCommunityLike?
|
||||
|
||||
fun totalCountCommunityPostLikeByPostId(postId: Long): Int
|
||||
}
|
||||
|
||||
class CreatorCommunityLikeQueryRepositoryImpl(
|
||||
private val queryFactory: JPAQueryFactory
|
||||
) : CreatorCommunityLikeQueryRepository {
|
||||
override fun findByPostIdAndMemberId(postId: Long, memberId: Long): CreatorCommunityLike? {
|
||||
return queryFactory
|
||||
.selectFrom(creatorCommunityLike)
|
||||
.innerJoin(creatorCommunityLike.creatorCommunity, creatorCommunity)
|
||||
.where(
|
||||
creatorCommunityLike.creatorCommunity.id.eq(postId)
|
||||
.and(creatorCommunityLike.member.id.eq(memberId))
|
||||
)
|
||||
.fetchFirst()
|
||||
}
|
||||
|
||||
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)
|
|
@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.report
|
|||
|
||||
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import kr.co.vividnext.sodalive.explorer.profile.CreatorCheers
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunity
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.EnumType
|
||||
|
@ -27,8 +28,12 @@ data class Report(
|
|||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "cheers_id", nullable = true)
|
||||
var cheers: CreatorCheers? = null
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "community_post_id", nullable = true)
|
||||
var communityPost: CreatorCommunity? = null
|
||||
}
|
||||
|
||||
enum class ReportType {
|
||||
PROFILE, USER, CHEERS, AUDIO_CONTENT
|
||||
PROFILE, USER, CHEERS, AUDIO_CONTENT, COMMUNITY_POST
|
||||
}
|
||||
|
|
|
@ -5,5 +5,6 @@ data class ReportRequest(
|
|||
val reason: String,
|
||||
val reportedMemberId: Long? = null,
|
||||
val cheersId: Long? = null,
|
||||
val audioContentId: Long? = null
|
||||
val audioContentId: Long? = null,
|
||||
val communityPostId: Long? = null
|
||||
)
|
||||
|
|
|
@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.report
|
|||
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.explorer.profile.CreatorCheersRepository
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunityRepository
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
|
@ -13,7 +14,8 @@ import org.springframework.transaction.annotation.Transactional
|
|||
class ReportService(
|
||||
private val repository: ReportRepository,
|
||||
private val memberRepository: MemberRepository,
|
||||
private val cheersRepository: CreatorCheersRepository
|
||||
private val cheersRepository: CreatorCheersRepository,
|
||||
private val creatorCommunityRepository: CreatorCommunityRepository
|
||||
) {
|
||||
@Transactional
|
||||
fun save(member: Member, request: ReportRequest) {
|
||||
|
@ -35,18 +37,32 @@ class ReportService(
|
|||
null
|
||||
}
|
||||
|
||||
val communityPost = if (request.communityPostId != null) {
|
||||
creatorCommunityRepository.findByIdOrNull(request.communityPostId)
|
||||
?: throw SodaException("신고가 접수되었습니다.")
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val report = Report(type = request.type, reason = request.reason)
|
||||
report.member = member
|
||||
report.reportedAccount = reportedAccount
|
||||
report.cheers = cheers
|
||||
report.communityPost = communityPost
|
||||
repository.save(report)
|
||||
}
|
||||
|
||||
private fun conditionAllIsNull(request: ReportRequest, isNull: Boolean): Boolean {
|
||||
return if (isNull) {
|
||||
request.reportedMemberId == null && request.cheersId == null && request.audioContentId == null
|
||||
request.reportedMemberId == null &&
|
||||
request.cheersId == null &&
|
||||
request.audioContentId == null &&
|
||||
request.communityPostId == null
|
||||
} else {
|
||||
request.reportedMemberId != null && request.cheersId != null && request.audioContentId != null
|
||||
request.reportedMemberId != null &&
|
||||
request.cheersId != null &&
|
||||
request.audioContentId != null &&
|
||||
request.communityPostId != null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue