Merge pull request 'test' (#162) from test into main

Reviewed-on: #162
This commit is contained in:
klaus 2024-04-09 13:27:24 +00:00
commit 8b433027e2
3 changed files with 156 additions and 94 deletions

View File

@ -1,41 +1,36 @@
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 getLiveRoomList( fun getLiveRoomListNow(offset: Long, limit: Long, timezone: String, isAdult: Boolean): List<LiveRoom>
dateString: String?,
status: LiveRoomStatus, fun getLiveRoomListReservationWithDate(
pageable: Pageable, date: LocalDateTime,
member: Member, offset: Long,
timezone: String, limit: Long,
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?
@ -45,67 +40,94 @@ interface LiveRoomQueryRepository {
} }
class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : LiveRoomQueryRepository { class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : LiveRoomQueryRepository {
override fun getLiveRoomList( override fun getLiveRoomListNow(offset: Long, limit: Long, timezone: String, isAdult: Boolean): List<LiveRoom> {
dateString: String?, var where = liveRoom.channelName.isNotNull
status: LiveRoomStatus, .and(liveRoom.channelName.isNotEmpty)
pageable: Pageable, .and(liveRoom.isActive.isTrue)
member: Member, .and(liveRoom.member.isNotNull)
timezone: String,
isAdult: Boolean
): List<LiveRoom> {
var where: Predicate
if (status == LiveRoomStatus.NOW) {
where = liveRoom.channelName.isNotNull
.and(liveRoom.channelName.isNotEmpty)
} else {
where = if (dateString != null) {
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val date = LocalDate.parse(dateString, dateTimeFormatter).atStartOfDay()
.atZone(ZoneId.of(timezone))
.withZoneSameInstant(ZoneId.of("UTC"))
.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) 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) .and(liveRoom.member.isNotNull)
if (!isAdult) {
where = where.and(liveRoom.isAdult.isFalse)
}
return queryFactory return queryFactory
.selectFrom(liveRoom) .selectFrom(liveRoom)
.innerJoin(liveRoom.member, QMember.member) .innerJoin(liveRoom.member, member)
.offset(pageable.offset) .where(where)
.limit(pageable.pageSize.toLong()) .offset(offset)
.limit(limit)
.orderBy(liveRoom.beginDateTime.asc())
.fetch()
}
override fun getLiveRoomListReservationWithoutDate(
timezone: String,
memberId: Long,
isAdult: Boolean
): List<LiveRoom> {
var where = liveRoom.beginDateTime.gt(
LocalDateTime.now()
.atZone(ZoneId.of(timezone))
.withZoneSameInstant(ZoneId.of("UTC"))
.toLocalDateTime()
)
.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)
.limit(10)
.where(where) .where(where)
.orderBy( .orderBy(
*orderByFieldAccountId( CaseBuilder()
memberId = member.id!!, .`when`(member.id.eq(memberId)).then(1)
status = status, .otherwise(2)
offset = pageable.offset, .asc(),
dateString = dateString liveRoom.beginDateTime.asc()
)
) )
.fetch() .fetch()
} }
@ -201,25 +223,4 @@ 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,6 +58,7 @@ 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
@ -115,16 +116,24 @@ class LiveRoomService(
member: Member, member: Member,
timezone: String timezone: String
): List<GetRoomListResponse> { ): List<GetRoomListResponse> {
return repository val roomList = if (status == LiveRoomStatus.NOW) {
.getLiveRoomList( getLiveRoomListNow(pageable, timezone, isAdult = member.auth != null)
dateString = dateString, } else if (dateString != null) {
status = status, getLiveRoomListReservationWithDate(
pageable = pageable, dateString,
member = member, pageable,
timezone = timezone, timezone,
isAdult = member.auth != null isAdult = member.auth != null
) )
.asSequence() } else {
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!!)
@ -174,7 +183,43 @@ 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

@ -0,0 +1,16 @@
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
)