commit
7959d3e5ed
|
@ -236,4 +236,24 @@ class AudioContentController(private val service: AudioContentService) {
|
||||||
|
|
||||||
ApiResponse.ok(service.unpinAtTheTop(contentId = id, member = member))
|
ApiResponse.ok(service.unpinAtTheTop(contentId = id, member = member))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/replay-live")
|
||||||
|
fun replayLive(
|
||||||
|
@RequestParam("isAdultContentVisible", required = false) isAdultContentVisible: Boolean? = null,
|
||||||
|
@RequestParam("contentType", required = false) contentType: ContentType? = null,
|
||||||
|
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||||
|
) = run {
|
||||||
|
ApiResponse.ok(
|
||||||
|
service.getLatestContentByTheme(
|
||||||
|
theme = listOf("다시듣기"),
|
||||||
|
contentType = contentType ?: ContentType.ALL,
|
||||||
|
isFree = false,
|
||||||
|
isAdult = if (member != null) {
|
||||||
|
(isAdultContentVisible ?: true) && member.auth != null
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -490,10 +490,8 @@ class AudioContentQueryRepositoryImpl(
|
||||||
where = where.and(audioContentTheme.theme.`in`(theme))
|
where = where.and(audioContentTheme.theme.`in`(theme))
|
||||||
}
|
}
|
||||||
|
|
||||||
where = if (isFree) {
|
if (isFree) {
|
||||||
where.and(audioContent.price.loe(0))
|
where = where.and(audioContent.price.loe(0))
|
||||||
} else {
|
|
||||||
where.and(audioContent.price.gt(0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
|
|
|
@ -16,6 +16,7 @@ import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.CreatorCo
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.CreatorCommunityLikeRepository
|
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.PostCommunityPostLikeRequest
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.PostCommunityPostLikeResponse
|
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.like.PostCommunityPostLikeResponse
|
||||||
|
import kr.co.vividnext.sodalive.extensions.getTimeAgoString
|
||||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
|
@ -28,8 +29,6 @@ import org.springframework.data.repository.findByIdOrNull
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
import org.springframework.web.multipart.MultipartFile
|
import org.springframework.web.multipart.MultipartFile
|
||||||
import java.time.Duration
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class CreatorCommunityService(
|
class CreatorCommunityService(
|
||||||
|
@ -243,7 +242,7 @@ class CreatorCommunityService(
|
||||||
it.toCommunityPostListResponse(
|
it.toCommunityPostListResponse(
|
||||||
imageHost = imageHost,
|
imageHost = imageHost,
|
||||||
audioUrl = audioUrl,
|
audioUrl = audioUrl,
|
||||||
date = getTimeAgoString(it.date),
|
date = it.date.getTimeAgoString(),
|
||||||
isLike = isLike,
|
isLike = isLike,
|
||||||
memberId = memberId,
|
memberId = memberId,
|
||||||
existOrdered = if (memberId == it.creatorId) {
|
existOrdered = if (memberId == it.creatorId) {
|
||||||
|
@ -314,7 +313,7 @@ class CreatorCommunityService(
|
||||||
return post.toCommunityPostListResponse(
|
return post.toCommunityPostListResponse(
|
||||||
imageHost = imageHost,
|
imageHost = imageHost,
|
||||||
audioUrl = audioUrl,
|
audioUrl = audioUrl,
|
||||||
date = getTimeAgoString(post.date),
|
date = post.date.getTimeAgoString(),
|
||||||
isLike = isLike,
|
isLike = isLike,
|
||||||
memberId = memberId,
|
memberId = memberId,
|
||||||
existOrdered = if (memberId == post.creatorId) {
|
existOrdered = if (memberId == post.creatorId) {
|
||||||
|
@ -328,19 +327,6 @@ class CreatorCommunityService(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
@Transactional
|
||||||
fun communityPostLike(request: PostCommunityPostLikeRequest, member: Member): PostCommunityPostLikeResponse {
|
fun communityPostLike(request: PostCommunityPostLikeRequest, member: Member): PostCommunityPostLikeResponse {
|
||||||
var postLike = likeRepository.findByPostIdAndMemberId(postId = request.postId, memberId = member.id!!)
|
var postLike = likeRepository.findByPostIdAndMemberId(postId = request.postId, memberId = member.id!!)
|
||||||
|
@ -506,7 +492,7 @@ class CreatorCommunityService(
|
||||||
it.toCommunityPostListResponse(
|
it.toCommunityPostListResponse(
|
||||||
imageHost = imageHost,
|
imageHost = imageHost,
|
||||||
audioUrl = null,
|
audioUrl = null,
|
||||||
date = getTimeAgoString(it.date),
|
date = it.date.getTimeAgoString(),
|
||||||
isLike = isLike,
|
isLike = isLike,
|
||||||
memberId = memberId,
|
memberId = memberId,
|
||||||
existOrdered = if (memberId == it.creatorId) {
|
existOrdered = if (memberId == it.creatorId) {
|
||||||
|
@ -590,7 +576,7 @@ class CreatorCommunityService(
|
||||||
imageHost = imageHost,
|
imageHost = imageHost,
|
||||||
audioUrl = audioUrl,
|
audioUrl = audioUrl,
|
||||||
content = post.content,
|
content = post.content,
|
||||||
date = getTimeAgoString(post.createdAt!!),
|
date = post.createdAt!!.getTimeAgoString(),
|
||||||
isLike = isLike,
|
isLike = isLike,
|
||||||
existOrdered = true,
|
existOrdered = true,
|
||||||
likeCount = likeCount,
|
likeCount = likeCount,
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package kr.co.vividnext.sodalive.extensions
|
||||||
|
|
||||||
|
import java.time.Duration
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
fun LocalDateTime.getTimeAgoString(): String {
|
||||||
|
val now = LocalDateTime.now()
|
||||||
|
val duration = Duration.between(this, now)
|
||||||
|
|
||||||
|
return when {
|
||||||
|
duration.toMinutes() < 1 -> "방금 전"
|
||||||
|
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}년전"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package kr.co.vividnext.sodalive.live.room
|
||||||
|
|
||||||
|
import com.querydsl.core.annotations.QueryProjection
|
||||||
|
import kr.co.vividnext.sodalive.extensions.getTimeAgoString
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
data class GetLatestFinishedLiveQueryResponse @QueryProjection constructor(
|
||||||
|
val memberId: Long,
|
||||||
|
val nickname: String,
|
||||||
|
val profileImageUrl: String,
|
||||||
|
val title: String,
|
||||||
|
val updatedAt: LocalDateTime
|
||||||
|
)
|
||||||
|
|
||||||
|
data class GetLatestFinishedLiveResponse(
|
||||||
|
val memberId: Long,
|
||||||
|
val nickname: String,
|
||||||
|
val profileImageUrl: String,
|
||||||
|
val title: String,
|
||||||
|
val timeAgo: String
|
||||||
|
) {
|
||||||
|
constructor(response: GetLatestFinishedLiveQueryResponse) : this(
|
||||||
|
response.memberId,
|
||||||
|
response.nickname,
|
||||||
|
response.profileImageUrl,
|
||||||
|
response.title,
|
||||||
|
response.updatedAt.getTimeAgoString()
|
||||||
|
)
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ data class GetRoomListResponse(
|
||||||
val title: String,
|
val title: String,
|
||||||
val content: String,
|
val content: String,
|
||||||
val beginDateTime: String,
|
val beginDateTime: String,
|
||||||
|
val beginDateTimeUtc: String,
|
||||||
val numberOfParticipate: Int,
|
val numberOfParticipate: Int,
|
||||||
val numberOfPeople: Int,
|
val numberOfPeople: Int,
|
||||||
val coverImageUrl: String,
|
val coverImageUrl: String,
|
||||||
|
|
|
@ -171,7 +171,7 @@ class LiveRoomController(
|
||||||
) = run {
|
) = run {
|
||||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||||
|
|
||||||
ApiResponse.ok(service.getDonationTotal(roomId, memberId = member.id!!))
|
ApiResponse.ok(service.getDonationTotal(roomId))
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/info/set/speaker")
|
@PutMapping("/info/set/speaker")
|
||||||
|
@ -291,4 +291,11 @@ class LiveRoomController(
|
||||||
|
|
||||||
ApiResponse.ok(service.getHeartList(roomId))
|
ApiResponse.ok(service.getHeartList(roomId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/latest-finished-live")
|
||||||
|
fun getLatestFinishedLive(
|
||||||
|
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||||
|
) = run {
|
||||||
|
ApiResponse.ok(service.getLatestFinishedLive(member))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.querydsl.core.types.Projections
|
||||||
import com.querydsl.core.types.dsl.CaseBuilder
|
import com.querydsl.core.types.dsl.CaseBuilder
|
||||||
import com.querydsl.core.types.dsl.Expressions
|
import com.querydsl.core.types.dsl.Expressions
|
||||||
import com.querydsl.core.types.dsl.NumberExpression
|
import com.querydsl.core.types.dsl.NumberExpression
|
||||||
|
import com.querydsl.jpa.JPAExpressions
|
||||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
import kr.co.vividnext.sodalive.can.use.CanUsage
|
import kr.co.vividnext.sodalive.can.use.CanUsage
|
||||||
import kr.co.vividnext.sodalive.can.use.QUseCan.useCan
|
import kr.co.vividnext.sodalive.can.use.QUseCan.useCan
|
||||||
|
@ -14,6 +15,7 @@ import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationItem
|
||||||
import kr.co.vividnext.sodalive.live.room.donation.QGetLiveRoomDonationItem
|
import kr.co.vividnext.sodalive.live.room.donation.QGetLiveRoomDonationItem
|
||||||
import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListItem
|
import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListItem
|
||||||
import kr.co.vividnext.sodalive.live.room.like.QGetLiveRoomHeartListItem
|
import kr.co.vividnext.sodalive.live.room.like.QGetLiveRoomHeartListItem
|
||||||
|
import kr.co.vividnext.sodalive.member.MemberRole
|
||||||
import kr.co.vividnext.sodalive.member.QMember.member
|
import kr.co.vividnext.sodalive.member.QMember.member
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
@ -60,6 +62,7 @@ interface LiveRoomQueryRepository {
|
||||||
fun getTotalHeartCount(roomId: Long): Int?
|
fun getTotalHeartCount(roomId: Long): Int?
|
||||||
fun getLiveRoomCreatorId(roomId: Long): Long?
|
fun getLiveRoomCreatorId(roomId: Long): Long?
|
||||||
fun getHeartList(roomId: Long): List<GetLiveRoomHeartListItem>
|
fun getHeartList(roomId: Long): List<GetLiveRoomHeartListItem>
|
||||||
|
fun getLatestFinishedLive(): List<GetLatestFinishedLiveQueryResponse>
|
||||||
}
|
}
|
||||||
|
|
||||||
class LiveRoomQueryRepositoryImpl(
|
class LiveRoomQueryRepositoryImpl(
|
||||||
|
@ -380,4 +383,39 @@ class LiveRoomQueryRepositoryImpl(
|
||||||
.orderBy(useCan.can.add(useCan.rewardCan).sum().desc())
|
.orderBy(useCan.can.add(useCan.rewardCan).sum().desc())
|
||||||
.fetch()
|
.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getLatestFinishedLive(): List<GetLatestFinishedLiveQueryResponse> {
|
||||||
|
val liveRoom = liveRoom
|
||||||
|
val subLiveRoom = QLiveRoom.liveRoom
|
||||||
|
|
||||||
|
val subQuery = JPAExpressions
|
||||||
|
.select(subLiveRoom.member.id, subLiveRoom.updatedAt.max())
|
||||||
|
.from(subLiveRoom)
|
||||||
|
.where(
|
||||||
|
subLiveRoom.isActive.isFalse
|
||||||
|
.and(subLiveRoom.channelName.isNotNull)
|
||||||
|
.and(subLiveRoom.member.role.eq(MemberRole.CREATOR))
|
||||||
|
)
|
||||||
|
.groupBy(subLiveRoom.member.id)
|
||||||
|
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
QGetLatestFinishedLiveQueryResponse(
|
||||||
|
member.id,
|
||||||
|
member.nickname,
|
||||||
|
member.profileImage.prepend("/").prepend(cloudFrontHost),
|
||||||
|
liveRoom.title,
|
||||||
|
liveRoom.updatedAt
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.from(liveRoom)
|
||||||
|
.innerJoin(liveRoom.member, member)
|
||||||
|
.where(
|
||||||
|
Expressions.list(liveRoom.member.id, liveRoom.updatedAt)
|
||||||
|
.`in`(subQuery)
|
||||||
|
)
|
||||||
|
.orderBy(liveRoom.updatedAt.desc())
|
||||||
|
.limit(20)
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,11 +176,15 @@ class LiveRoomService(
|
||||||
.withLocale(Locale.KOREAN)
|
.withLocale(Locale.KOREAN)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val beginDateTimeUtc = it.beginDateTime
|
||||||
|
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||||
|
|
||||||
GetRoomListResponse(
|
GetRoomListResponse(
|
||||||
roomId = it.id!!,
|
roomId = it.id!!,
|
||||||
title = it.title,
|
title = it.title,
|
||||||
content = it.notice,
|
content = it.notice,
|
||||||
beginDateTime = beginDateTime,
|
beginDateTime = beginDateTime,
|
||||||
|
beginDateTimeUtc = beginDateTimeUtc,
|
||||||
numberOfParticipate = (roomInfo?.listenerCount ?: 0) +
|
numberOfParticipate = (roomInfo?.listenerCount ?: 0) +
|
||||||
(roomInfo?.speakerCount ?: 0) +
|
(roomInfo?.speakerCount ?: 0) +
|
||||||
(roomInfo?.managerCount ?: 0),
|
(roomInfo?.managerCount ?: 0),
|
||||||
|
@ -993,7 +997,7 @@ class LiveRoomService(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDonationTotal(roomId: Long, memberId: Long): GetLiveRoomDonationTotalResponse {
|
fun getDonationTotal(roomId: Long): GetLiveRoomDonationTotalResponse {
|
||||||
return GetLiveRoomDonationTotalResponse(
|
return GetLiveRoomDonationTotalResponse(
|
||||||
totalDonationCan = repository.getDonationTotal(roomId = roomId) ?: 0
|
totalDonationCan = repository.getDonationTotal(roomId = roomId) ?: 0
|
||||||
)
|
)
|
||||||
|
@ -1292,4 +1296,18 @@ class LiveRoomService(
|
||||||
totalHeart = heartList.sumOf { it.heart }
|
totalHeart = heartList.sumOf { it.heart }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLatestFinishedLive(member: Member?): List<GetLatestFinishedLiveResponse> {
|
||||||
|
return repository.getLatestFinishedLive()
|
||||||
|
.filter {
|
||||||
|
if (member?.id != null) {
|
||||||
|
!blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.memberId)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map {
|
||||||
|
GetLatestFinishedLiveResponse(response = it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue