라이브 메인 - 팔로잉 채널 API 추가
This commit is contained in:
		| @@ -5,11 +5,13 @@ import kr.co.vividnext.sodalive.common.SodaException | |||||||
| import kr.co.vividnext.sodalive.member.Member | import kr.co.vividnext.sodalive.member.Member | ||||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal | import org.springframework.security.core.annotation.AuthenticationPrincipal | ||||||
| import org.springframework.web.bind.annotation.GetMapping | import org.springframework.web.bind.annotation.GetMapping | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping | ||||||
| import org.springframework.web.bind.annotation.RestController | import org.springframework.web.bind.annotation.RestController | ||||||
|  |  | ||||||
| @RestController | @RestController | ||||||
|  | @RequestMapping("/live/recommend") | ||||||
| class LiveRecommendController(private val service: LiveRecommendService) { | class LiveRecommendController(private val service: LiveRecommendService) { | ||||||
|     @GetMapping("/live/recommend") |     @GetMapping | ||||||
|     fun getRecommendLive( |     fun getRecommendLive( | ||||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|     ) = run { |     ) = run { | ||||||
| @@ -18,7 +20,7 @@ class LiveRecommendController(private val service: LiveRecommendService) { | |||||||
|         ApiResponse.ok(service.getRecommendLive(member)) |         ApiResponse.ok(service.getRecommendLive(member)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @GetMapping("/live/recommend/channel") |     @GetMapping("/channel") | ||||||
|     fun getRecommendChannelList( |     fun getRecommendChannelList( | ||||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|     ) = run { |     ) = run { | ||||||
| @@ -26,4 +28,13 @@ class LiveRecommendController(private val service: LiveRecommendService) { | |||||||
|  |  | ||||||
|         ApiResponse.ok(service.getRecommendChannelList(member)) |         ApiResponse.ok(service.getRecommendChannelList(member)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @GetMapping("/following/channel/list") | ||||||
|  |     fun getFollowingChannelList( | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.getFollowingChannelList(member)) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.live.recommend.QRecommendLiveCreatorBanner.recom | |||||||
| import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom | import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom | ||||||
| import kr.co.vividnext.sodalive.member.MemberRole | import kr.co.vividnext.sodalive.member.MemberRole | ||||||
| import kr.co.vividnext.sodalive.member.QMember.member | import kr.co.vividnext.sodalive.member.QMember.member | ||||||
|  | import kr.co.vividnext.sodalive.member.following.QCreatorFollowing.creatorFollowing | ||||||
| import org.springframework.beans.factory.annotation.Value | import org.springframework.beans.factory.annotation.Value | ||||||
| import org.springframework.stereotype.Repository | import org.springframework.stereotype.Repository | ||||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||||
| @@ -106,4 +107,79 @@ class LiveRecommendRepository( | |||||||
|             .limit(limit) |             .limit(limit) | ||||||
|             .fetch() |             .fetch() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getOnAirFollowingChannelList( | ||||||
|  |         memberId: Long, | ||||||
|  |         isBlocked: (Long) -> Boolean, | ||||||
|  |         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.prepend("/").prepend(cloudFrontHost), | ||||||
|  |                     Expressions.asBoolean(true) | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |             .from(liveRoom, creatorFollowing) | ||||||
|  |             .rightJoin(liveRoom.member, member) | ||||||
|  |             .innerJoin(creatorFollowing.creator, member) | ||||||
|  |             .where( | ||||||
|  |                 where | ||||||
|  |                     .and(liveRoom.member.id.eq(creatorFollowing.creator.id)) | ||||||
|  |                     .and(creatorFollowing.isActive.isTrue) | ||||||
|  |                     .and(creatorFollowing.member.id.eq(memberId)) | ||||||
|  |                     .and(liveRoom.isActive.isTrue) | ||||||
|  |                     .and(liveRoom.channelName.isNotNull) | ||||||
|  |                     .and(liveRoom.channelName.isNotEmpty) | ||||||
|  |             ) | ||||||
|  |             .groupBy(member.id) | ||||||
|  |             .orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc()) | ||||||
|  |             .limit(20) | ||||||
|  |             .fetch() | ||||||
|  |             .asSequence() | ||||||
|  |             .filter { !isBlocked(it.creatorId) } | ||||||
|  |             .toList() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getFollowingChannelList( | ||||||
|  |         memberId: Long, | ||||||
|  |         withOutCreatorList: List<Long>, | ||||||
|  |         limit: Long, | ||||||
|  |         isBlocked: (Long) -> Boolean | ||||||
|  |     ): 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.prepend("/").prepend(cloudFrontHost), | ||||||
|  |                     Expressions.asBoolean(false) | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |             .from(creatorFollowing) | ||||||
|  |             .innerJoin(creatorFollowing.creator, member) | ||||||
|  |             .where( | ||||||
|  |                 where | ||||||
|  |                     .and(member.id.notIn(withOutCreatorList)) | ||||||
|  |                     .and(creatorFollowing.isActive.isTrue) | ||||||
|  |                     .and(creatorFollowing.member.id.eq(memberId)) | ||||||
|  |             ) | ||||||
|  |             .orderBy(Expressions.numberTemplate(Double::class.java, "function('rand')").asc()) | ||||||
|  |             .limit(limit) | ||||||
|  |             .fetch() | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -41,4 +41,29 @@ class LiveRecommendService( | |||||||
|  |  | ||||||
|         return onAirChannelList + notOnAirCreatorList |         return onAirChannelList + notOnAirCreatorList | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getFollowingChannelList(member: Member): List<GetRecommendChannelResponse> { | ||||||
|  |         val onAirFollowingChannelList = repository.getOnAirFollowingChannelList( | ||||||
|  |             memberId = member.id!!, | ||||||
|  |             isBlocked = { blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it) }, | ||||||
|  |             isAdult = member.auth != null | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         if (onAirFollowingChannelList.size >= 20) { | ||||||
|  |             return onAirFollowingChannelList | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val onAirCreatorIdList = onAirFollowingChannelList.asSequence() | ||||||
|  |             .map { it.creatorId } | ||||||
|  |             .toList() | ||||||
|  |  | ||||||
|  |         val notOnAirFollowingChannelList = repository.getFollowingChannelList( | ||||||
|  |             memberId = member.id!!, | ||||||
|  |             withOutCreatorList = onAirCreatorIdList, | ||||||
|  |             limit = (20 - onAirCreatorIdList.size).toLong(), | ||||||
|  |             isBlocked = { blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it) } | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return onAirFollowingChannelList + notOnAirFollowingChannelList | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user