Compare commits

..

No commits in common. "8b433027e2b208f72a39f18996b954274f47bdab" and "5bd4ff76104a94fb3b9f1a8c37c2bbd276ed8aa1" have entirely different histories.

3 changed files with 93 additions and 155 deletions

View File

@ -1,36 +1,41 @@
package kr.co.vividnext.sodalive.live.room package kr.co.vividnext.sodalive.live.room
import com.querydsl.core.types.OrderSpecifier
import com.querydsl.core.types.Predicate
import com.querydsl.core.types.Projections 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.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
import kr.co.vividnext.sodalive.can.use.QUseCanCalculate.useCanCalculate import kr.co.vividnext.sodalive.can.use.QUseCanCalculate.useCanCalculate
import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
import kr.co.vividnext.sodalive.live.room.QQuarterLiveRankings.quarterLiveRankings
import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationItem 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.member.Member
import kr.co.vividnext.sodalive.member.QMember
import kr.co.vividnext.sodalive.member.QMember.member import kr.co.vividnext.sodalive.member.QMember.member
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter
@Repository @Repository
interface LiveRoomRepository : JpaRepository<LiveRoom, Long>, LiveRoomQueryRepository interface LiveRoomRepository : JpaRepository<LiveRoom, Long>, LiveRoomQueryRepository
interface LiveRoomQueryRepository { interface LiveRoomQueryRepository {
fun getLiveRoomListNow(offset: Long, limit: Long, timezone: String, isAdult: Boolean): List<LiveRoom> fun getLiveRoomList(
dateString: String?,
fun getLiveRoomListReservationWithDate( status: LiveRoomStatus,
date: LocalDateTime, pageable: Pageable,
offset: Long, member: Member,
limit: Long, timezone: String,
isAdult: Boolean isAdult: Boolean
): List<LiveRoom> ): List<LiveRoom>
fun getLiveRoomListReservationWithoutDate(timezone: String, memberId: Long, isAdult: Boolean): List<LiveRoom>
fun getLiveRoom(id: Long): LiveRoom? fun getLiveRoom(id: Long): LiveRoom?
fun getLiveRoomAndAccountId(roomId: Long, memberId: Long): LiveRoom? fun getLiveRoomAndAccountId(roomId: Long, memberId: Long): LiveRoom?
fun getRecentRoomInfo(memberId: Long, cloudFrontHost: String): GetRecentRoomInfoResponse? fun getRecentRoomInfo(memberId: Long, cloudFrontHost: String): GetRecentRoomInfoResponse?
@ -40,94 +45,67 @@ interface LiveRoomQueryRepository {
} }
class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : LiveRoomQueryRepository { class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : LiveRoomQueryRepository {
override fun getLiveRoomListNow(offset: Long, limit: Long, timezone: String, isAdult: Boolean): List<LiveRoom> { override fun getLiveRoomList(
var where = liveRoom.channelName.isNotNull dateString: String?,
.and(liveRoom.channelName.isNotEmpty) status: LiveRoomStatus,
.and(liveRoom.isActive.isTrue) pageable: Pageable,
.and(liveRoom.member.isNotNull) member: Member,
if (!isAdult) {
where = where.and(liveRoom.isAdult.isFalse)
}
return queryFactory
.selectFrom(liveRoom)
.innerJoin(liveRoom.member, member)
.leftJoin(quarterLiveRankings).on(liveRoom.id.eq(quarterLiveRankings.roomId))
.where(where)
.offset(offset)
.limit(limit)
.orderBy(
quarterLiveRankings.totalCan.desc(),
quarterLiveRankings.totalParticipants.desc(),
liveRoom.beginDateTime.desc(),
liveRoom.member.createdAt.desc()
)
.fetch()
}
override fun getLiveRoomListReservationWithDate(
date: LocalDateTime,
offset: Long,
limit: Long,
isAdult: Boolean
): List<LiveRoom> {
var where = liveRoom.beginDateTime.goe(date)
.and(liveRoom.beginDateTime.lt(date.plusDays(1)))
.and(
liveRoom.channelName.isNull
.or(liveRoom.channelName.isEmpty)
)
.and(liveRoom.isActive.isTrue)
.and(liveRoom.member.isNotNull)
if (!isAdult) {
where = where.and(liveRoom.isAdult.isFalse)
}
return queryFactory
.selectFrom(liveRoom)
.innerJoin(liveRoom.member, member)
.where(where)
.offset(offset)
.limit(limit)
.orderBy(liveRoom.beginDateTime.asc())
.fetch()
}
override fun getLiveRoomListReservationWithoutDate(
timezone: String, timezone: String,
memberId: Long,
isAdult: Boolean isAdult: Boolean
): List<LiveRoom> { ): List<LiveRoom> {
var where = liveRoom.beginDateTime.gt( var where: Predicate
LocalDateTime.now()
.atZone(ZoneId.of(timezone)) if (status == LiveRoomStatus.NOW) {
.withZoneSameInstant(ZoneId.of("UTC")) where = liveRoom.channelName.isNotNull
.toLocalDateTime() .and(liveRoom.channelName.isNotEmpty)
) } else {
.and( where = if (dateString != null) {
liveRoom.channelName.isNull val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
.or(liveRoom.channelName.isEmpty) val date = LocalDate.parse(dateString, dateTimeFormatter).atStartOfDay()
) .atZone(ZoneId.of(timezone))
.and(liveRoom.isActive.isTrue) .withZoneSameInstant(ZoneId.of("UTC"))
.and(liveRoom.member.isNotNull) .toLocalDateTime()
liveRoom.beginDateTime.goe(date)
.and(liveRoom.beginDateTime.lt(date.plusDays(1)))
.and(
liveRoom.channelName.isNull
.or(liveRoom.channelName.isEmpty)
)
} else {
liveRoom.beginDateTime.gt(
LocalDateTime.now()
.atZone(ZoneId.of(timezone))
.withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime()
)
.and(
liveRoom.channelName.isNull
.or(liveRoom.channelName.isEmpty)
)
}
}
if (!isAdult) { if (!isAdult) {
where = where.and(liveRoom.isAdult.isFalse) where = where.and(liveRoom.isAdult.isFalse)
} }
where = where.and(liveRoom.isActive.isTrue)
.and(liveRoom.member.isNotNull)
return queryFactory return queryFactory
.selectFrom(liveRoom) .selectFrom(liveRoom)
.innerJoin(liveRoom.member, member) .innerJoin(liveRoom.member, QMember.member)
.limit(10) .offset(pageable.offset)
.limit(pageable.pageSize.toLong())
.where(where) .where(where)
.orderBy( .orderBy(
CaseBuilder() *orderByFieldAccountId(
.`when`(member.id.eq(memberId)).then(1) memberId = member.id!!,
.otherwise(2) status = status,
.asc(), offset = pageable.offset,
liveRoom.beginDateTime.asc() dateString = dateString
)
) )
.fetch() .fetch()
} }
@ -223,4 +201,25 @@ class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : L
) )
.fetch() .fetch()
} }
private fun orderByFieldAccountId(
memberId: Long,
status: LiveRoomStatus,
offset: Long,
dateString: String?
): Array<out OrderSpecifier<*>> {
return if (status == LiveRoomStatus.NOW) {
arrayOf(Expressions.numberTemplate(Double::class.java, "function('rand')").asc())
} else if (status == LiveRoomStatus.RESERVATION && offset == 0L && dateString == null) {
arrayOf(
CaseBuilder()
.`when`(member.id.eq(memberId)).then(1)
.otherwise(2)
.asc(),
liveRoom.beginDateTime.asc()
)
} else {
arrayOf(liveRoom.beginDateTime.asc())
}
}
} }

View File

@ -58,7 +58,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.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -116,24 +115,16 @@ class LiveRoomService(
member: Member, member: Member,
timezone: String timezone: String
): List<GetRoomListResponse> { ): List<GetRoomListResponse> {
val roomList = if (status == LiveRoomStatus.NOW) { return repository
getLiveRoomListNow(pageable, timezone, isAdult = member.auth != null) .getLiveRoomList(
} else if (dateString != null) { dateString = dateString,
getLiveRoomListReservationWithDate( status = status,
dateString, pageable = pageable,
pageable, member = member,
timezone, timezone = timezone,
isAdult = member.auth != null isAdult = member.auth != null
) )
} else { .asSequence()
getLiveRoomListReservationWithoutDate(
timezone,
memberId = member.id!!,
isAdult = member.auth != null
)
}
return roomList
.filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!) } .filter { !blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!) }
.map { .map {
val roomInfo = roomInfoRepository.findByIdOrNull(it.id!!) val roomInfo = roomInfoRepository.findByIdOrNull(it.id!!)
@ -183,43 +174,7 @@ class LiveRoomService(
isPrivateRoom = it.type == LiveRoomType.PRIVATE isPrivateRoom = it.type == LiveRoomType.PRIVATE
) )
} }
} .toList()
private fun getLiveRoomListNow(pageable: Pageable, timezone: String, isAdult: Boolean): List<LiveRoom> {
return repository.getLiveRoomListNow(
offset = pageable.offset,
limit = pageable.pageSize.toLong(),
timezone = timezone,
isAdult = isAdult
)
}
private fun getLiveRoomListReservationWithDate(
dateString: String,
pageable: Pageable,
timezone: String,
isAdult: Boolean
): List<LiveRoom> {
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val date = LocalDate.parse(dateString, dateTimeFormatter).atStartOfDay()
.atZone(ZoneId.of(timezone))
.withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime()
return repository.getLiveRoomListReservationWithDate(
date = date,
offset = pageable.offset,
limit = pageable.pageSize.toLong(),
isAdult = isAdult
)
}
private fun getLiveRoomListReservationWithoutDate(
timezone: String,
memberId: Long,
isAdult: Boolean
): List<LiveRoom> {
return repository.getLiveRoomListReservationWithoutDate(timezone, memberId, isAdult)
} }
@Transactional @Transactional

View File

@ -1,16 +0,0 @@
package kr.co.vividnext.sodalive.live.room
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
@Entity
data class QuarterLiveRankings(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
val roomId: Long,
val totalCan: Int,
val totalParticipants: Int
)