feat(creator-channel): 커뮤니티 탭 응답 조립을 추가한다

This commit is contained in:
2026-06-22 00:01:45 +09:00
parent bd4e865f2e
commit e0e6b34d21
4 changed files with 242 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.extensions
import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZoneOffset
private val DEFAULT_KST_ZONE_ID: ZoneId = ZoneId.of("Asia/Seoul")
private val UTC_ZONE_ID: ZoneId = ZoneId.of("UTC")
@@ -26,3 +27,7 @@ fun LocalDateTime.convertToUtc(timeZone: ZoneId = DEFAULT_KST_ZONE_ID): LocalDat
.withZoneSameInstant(UTC_ZONE_ID)
.toLocalDateTime()
}
fun LocalDateTime.toUtcIso(): String {
return atOffset(ZoneOffset.UTC).toInstant().toString()
}

View File

@@ -0,0 +1,32 @@
package kr.co.vividnext.sodalive.v2.api.creator.channel.community.application
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.v2.api.creator.channel.community.dto.CreatorChannelCommunityTabResponse
import kr.co.vividnext.sodalive.v2.creator.channel.community.application.CreatorChannelCommunityQueryService
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
@Service
@Transactional(readOnly = true)
class CreatorChannelCommunityFacade(
private val creatorChannelCommunityQueryService: CreatorChannelCommunityQueryService
) {
fun getCommunityTab(
creatorId: Long,
viewer: Member,
page: Int?,
size: Int?,
now: LocalDateTime = LocalDateTime.now()
): CreatorChannelCommunityTabResponse {
return CreatorChannelCommunityTabResponse.from(
creatorChannelCommunityQueryService.getCommunityTab(
creatorId = creatorId,
viewer = viewer,
page = page,
size = size,
now = now
)
)
}
}

View File

@@ -0,0 +1,67 @@
package kr.co.vividnext.sodalive.v2.api.creator.channel.community.dto
import com.fasterxml.jackson.annotation.JsonProperty
import kr.co.vividnext.sodalive.extensions.toUtcIso
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityPost
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityTab
data class CreatorChannelCommunityTabResponse(
val communityPostCount: Int,
val communityPosts: List<CreatorChannelCommunityPostResponse>,
val page: Int,
val size: Int,
@JsonProperty("hasNext")
val hasNext: Boolean
) {
companion object {
fun from(tab: CreatorChannelCommunityTab): CreatorChannelCommunityTabResponse {
return CreatorChannelCommunityTabResponse(
communityPostCount = tab.communityPostCount,
communityPosts = tab.communityPosts.map(CreatorChannelCommunityPostResponse::from),
page = tab.page.page,
size = tab.page.size,
hasNext = tab.hasNext
)
}
}
}
data class CreatorChannelCommunityPostResponse(
val postId: Long,
val creatorId: Long,
val creatorNickname: String,
val creatorProfileUrl: String,
val createdAtUtc: String,
val content: String,
val imageUrl: String?,
val audioUrl: String?,
val price: Int,
@JsonProperty("isCommentAvailable")
val isCommentAvailable: Boolean,
val existOrdered: Boolean,
val likeCount: Int,
val commentCount: Int,
@JsonProperty("isPinned")
val isPinned: Boolean
) {
companion object {
fun from(post: CreatorChannelCommunityPost): CreatorChannelCommunityPostResponse {
return CreatorChannelCommunityPostResponse(
postId = post.postId,
creatorId = post.creatorId,
creatorNickname = post.creatorNickname,
creatorProfileUrl = post.creatorProfileUrl,
createdAtUtc = post.createdAt.toUtcIso(),
content = post.content,
imageUrl = post.imageUrl,
audioUrl = post.audioUrl,
price = post.price,
isCommentAvailable = post.isCommentAvailable,
existOrdered = post.existOrdered,
likeCount = post.likeCount,
commentCount = post.commentCount,
isPinned = post.isPinned
)
}
}
}