라이브 중 리스트
- 리스트 정렬 조건 수정 - 1. 15분 동안 받은 캔 - 2. 15분 동안 참여한 참여자 - 3. 최근 시작한 라이브 - 4. 최근 가입한 크리에이터
This commit is contained in:
		| @@ -1,41 +1,36 @@ | ||||
| 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.dsl.CaseBuilder | ||||
| import com.querydsl.core.types.dsl.Expressions | ||||
| import com.querydsl.jpa.impl.JPAQueryFactory | ||||
| import kr.co.vividnext.sodalive.can.use.CanUsage | ||||
| import kr.co.vividnext.sodalive.can.use.QUseCan.useCan | ||||
| 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.QQuarterLiveRankings.quarterLiveRankings | ||||
| import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationItem | ||||
| 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 org.springframework.data.domain.Pageable | ||||
| import org.springframework.data.jpa.repository.JpaRepository | ||||
| import org.springframework.stereotype.Repository | ||||
| import java.time.LocalDate | ||||
| import java.time.LocalDateTime | ||||
| import java.time.ZoneId | ||||
| import java.time.format.DateTimeFormatter | ||||
|  | ||||
| @Repository | ||||
| interface LiveRoomRepository : JpaRepository<LiveRoom, Long>, LiveRoomQueryRepository | ||||
|  | ||||
| interface LiveRoomQueryRepository { | ||||
|     fun getLiveRoomList( | ||||
|         dateString: String?, | ||||
|         status: LiveRoomStatus, | ||||
|         pageable: Pageable, | ||||
|         member: Member, | ||||
|         timezone: String, | ||||
|     fun getLiveRoomListNow(offset: Long, limit: Long, timezone: String, isAdult: Boolean): List<LiveRoom> | ||||
|  | ||||
|     fun getLiveRoomListReservationWithDate( | ||||
|         date: LocalDateTime, | ||||
|         offset: Long, | ||||
|         limit: Long, | ||||
|         isAdult: Boolean | ||||
|     ): List<LiveRoom> | ||||
|  | ||||
|     fun getLiveRoomListReservationWithoutDate(timezone: String, memberId: Long, isAdult: Boolean): List<LiveRoom> | ||||
|  | ||||
|     fun getLiveRoom(id: Long): LiveRoom? | ||||
|     fun getLiveRoomAndAccountId(roomId: Long, memberId: Long): LiveRoom? | ||||
|     fun getRecentRoomInfo(memberId: Long, cloudFrontHost: String): GetRecentRoomInfoResponse? | ||||
| @@ -45,67 +40,92 @@ interface LiveRoomQueryRepository { | ||||
| } | ||||
|  | ||||
| class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : LiveRoomQueryRepository { | ||||
|     override fun getLiveRoomList( | ||||
|         dateString: String?, | ||||
|         status: LiveRoomStatus, | ||||
|         pageable: Pageable, | ||||
|         member: Member, | ||||
|         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) | ||||
|                     ) | ||||
|             } | ||||
|         } | ||||
|     override fun getLiveRoomListNow(offset: Long, limit: Long, timezone: String, isAdult: Boolean): List<LiveRoom> { | ||||
|         var where = liveRoom.channelName.isNotNull | ||||
|             .and(liveRoom.channelName.isNotEmpty) | ||||
|             .and(liveRoom.isActive.isTrue) | ||||
|             .and(liveRoom.member.isNotNull) | ||||
|  | ||||
|         if (!isAdult) { | ||||
|             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) | ||||
|             .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, QMember.member) | ||||
|             .offset(pageable.offset) | ||||
|             .limit(pageable.pageSize.toLong()) | ||||
|             .innerJoin(liveRoom.member, member) | ||||
|             .offset(offset) | ||||
|             .limit(limit) | ||||
|             .where(where) | ||||
|             .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) | ||||
|             .orderBy( | ||||
|                 *orderByFieldAccountId( | ||||
|                     memberId = member.id!!, | ||||
|                     status = status, | ||||
|                     offset = pageable.offset, | ||||
|                     dateString = dateString | ||||
|                 ) | ||||
|                 CaseBuilder() | ||||
|                     .`when`(member.id.eq(memberId)).then(1) | ||||
|                     .otherwise(2) | ||||
|                     .asc(), | ||||
|                 liveRoom.beginDateTime.asc() | ||||
|             ) | ||||
|             .fetch() | ||||
|     } | ||||
| @@ -201,25 +221,4 @@ class LiveRoomQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : L | ||||
|             ) | ||||
|             .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()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -58,6 +58,7 @@ import org.springframework.data.repository.findByIdOrNull | ||||
| import org.springframework.stereotype.Service | ||||
| import org.springframework.transaction.annotation.Transactional | ||||
| import org.springframework.web.multipart.MultipartFile | ||||
| import java.time.LocalDate | ||||
| import java.time.LocalDateTime | ||||
| import java.time.ZoneId | ||||
| import java.time.format.DateTimeFormatter | ||||
| @@ -115,16 +116,24 @@ class LiveRoomService( | ||||
|         member: Member, | ||||
|         timezone: String | ||||
|     ): List<GetRoomListResponse> { | ||||
|         return repository | ||||
|             .getLiveRoomList( | ||||
|                 dateString = dateString, | ||||
|                 status = status, | ||||
|                 pageable = pageable, | ||||
|                 member = member, | ||||
|                 timezone = timezone, | ||||
|         val roomList = if (status == LiveRoomStatus.NOW) { | ||||
|             getLiveRoomListNow(pageable, timezone, isAdult = member.auth != null) | ||||
|         } else if (dateString != null) { | ||||
|             getLiveRoomListReservationWithDate( | ||||
|                 dateString, | ||||
|                 pageable, | ||||
|                 timezone, | ||||
|                 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!!) } | ||||
|             .map { | ||||
|                 val roomInfo = roomInfoRepository.findByIdOrNull(it.id!!) | ||||
| @@ -174,7 +183,43 @@ class LiveRoomService( | ||||
|                     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 | ||||
|   | ||||
| @@ -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 | ||||
| ) | ||||
		Reference in New Issue
	
	Block a user