라이브 메인 - 추천라이브, 추천채널, 예약중인 라이브, 진행중인 라이브, 이벤트 배너 API 추가
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
data class GetRecommendChannelResponse(
|
||||
val creatorId: Long,
|
||||
val nickname: String,
|
||||
val profileImageUrl: String,
|
||||
val isOnAir: Boolean
|
||||
)
|
@@ -0,0 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
data class GetRecommendLiveResponse(
|
||||
val imageUrl: String,
|
||||
val creatorId: Long
|
||||
)
|
@@ -0,0 +1,29 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class LiveRecommendController(private val service: LiveRecommendService) {
|
||||
@GetMapping("/live/recommend")
|
||||
fun getRecommendLive(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(service.getRecommendLive(member))
|
||||
}
|
||||
|
||||
@GetMapping("/live/recommend/channel")
|
||||
fun getRecommendChannelList(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
|
||||
ApiResponse.ok(service.getRecommendChannelList(member))
|
||||
}
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import com.querydsl.core.types.Projections
|
||||
import com.querydsl.core.types.dsl.Expressions
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.live.recommend.QRecommendLiveCreatorBanner.recommendLiveCreatorBanner
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoomType
|
||||
import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
|
||||
import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import kr.co.vividnext.sodalive.member.QMember.member
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Repository
|
||||
class LiveRecommendRepository(private val queryFactory: JPAQueryFactory) {
|
||||
fun getRecommendLive(memberId: Long, isAdult: Boolean): List<GetRecommendLiveResponse> {
|
||||
val dateNow = LocalDateTime.now()
|
||||
|
||||
var where = recommendLiveCreatorBanner.startDate.loe(dateNow)
|
||||
.and(recommendLiveCreatorBanner.endDate.goe(dateNow))
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(recommendLiveCreatorBanner.isAdult.isFalse)
|
||||
}
|
||||
|
||||
return queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
GetRecommendLiveResponse::class.java,
|
||||
recommendLiveCreatorBanner.image,
|
||||
recommendLiveCreatorBanner.creator.id
|
||||
)
|
||||
)
|
||||
.from(recommendLiveCreatorBanner)
|
||||
.where(where)
|
||||
.orderBy(recommendLiveCreatorBanner.orders.asc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
fun getOnAirRecommendChannelList(
|
||||
memberId: Long,
|
||||
isAdult: Boolean
|
||||
): List<GetRecommendChannelResponse> {
|
||||
var where = member.role.eq(MemberRole.CREATOR)
|
||||
.and(member.isActive.isTrue)
|
||||
|
||||
if (!isAdult) {
|
||||
where = where.and(liveRoom.isAdult.isFalse)
|
||||
}
|
||||
|
||||
return queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
GetRecommendChannelResponse::class.java,
|
||||
member.id,
|
||||
member.nickname,
|
||||
member.profileImage,
|
||||
Expressions.asBoolean(true)
|
||||
)
|
||||
)
|
||||
.from(liveRoom)
|
||||
.rightJoin(liveRoom.member, member)
|
||||
.where(
|
||||
where
|
||||
.and(liveRoom.isActive.isTrue)
|
||||
.and(liveRoom.type.ne(LiveRoomType.SECRET))
|
||||
.and(liveRoom.channelName.isNotNull)
|
||||
.and(liveRoom.channelName.isNotEmpty)
|
||||
)
|
||||
.groupBy(member.id)
|
||||
.orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc())
|
||||
.limit(20)
|
||||
.fetch()
|
||||
}
|
||||
|
||||
fun getRecommendChannelList(
|
||||
memberId: Long,
|
||||
withOutCreatorList: List<Long>,
|
||||
limit: Long
|
||||
): List<GetRecommendChannelResponse> {
|
||||
val where = member.role.eq(MemberRole.CREATOR)
|
||||
.and(member.isActive.isTrue)
|
||||
|
||||
return queryFactory
|
||||
.select(
|
||||
Projections.constructor(
|
||||
GetRecommendChannelResponse::class.java,
|
||||
member.id,
|
||||
member.nickname,
|
||||
member.profileImage,
|
||||
Expressions.asBoolean(false)
|
||||
)
|
||||
)
|
||||
.from(member)
|
||||
.where(where.and(member.id.notIn(withOutCreatorList)))
|
||||
.orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc())
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class LiveRecommendService(private val repository: LiveRecommendRepository) {
|
||||
|
||||
fun getRecommendLive(member: Member): List<GetRecommendLiveResponse> {
|
||||
return repository.getRecommendLive(
|
||||
memberId = member.id!!,
|
||||
isAdult = member.auth != null
|
||||
)
|
||||
}
|
||||
|
||||
fun getRecommendChannelList(member: Member): List<GetRecommendChannelResponse> {
|
||||
val onAirChannelList = repository.getOnAirRecommendChannelList(member.id!!, isAdult = member.auth != null)
|
||||
|
||||
if (onAirChannelList.size >= 20) {
|
||||
return onAirChannelList
|
||||
}
|
||||
|
||||
val onAirCreatorIdList = onAirChannelList.asSequence()
|
||||
.map { it.creatorId }
|
||||
.toList()
|
||||
|
||||
val notOnAirCreatorList = repository.getRecommendChannelList(
|
||||
member.id!!,
|
||||
withOutCreatorList = onAirCreatorIdList,
|
||||
limit = (20 - onAirChannelList.size).toLong()
|
||||
)
|
||||
|
||||
return onAirChannelList + notOnAirCreatorList
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package kr.co.vividnext.sodalive.live.recommend
|
||||
|
||||
import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import java.time.LocalDateTime
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.FetchType
|
||||
import javax.persistence.JoinColumn
|
||||
import javax.persistence.ManyToOne
|
||||
|
||||
@Entity
|
||||
data class RecommendLiveCreatorBanner(
|
||||
@Column(nullable = false)
|
||||
var image: String,
|
||||
@Column(nullable = false)
|
||||
var startDate: LocalDateTime,
|
||||
@Column(nullable = false)
|
||||
var endDate: LocalDateTime,
|
||||
@Column(nullable = false)
|
||||
var isAdult: Boolean = false,
|
||||
@Column(nullable = false)
|
||||
var orders: Int = 1
|
||||
) : BaseEntity() {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "creator_id", nullable = false)
|
||||
var creator: Member? = null
|
||||
}
|
Reference in New Issue
Block a user