라이브룸 성별 제한 추가

라이브룸 생성/수정 요청에 genderRestriction 필드 추가
라이브룸 상세 응답에 genderRestriction 필드 추가
This commit is contained in:
2026-02-02 14:44:07 +09:00
parent 6b0ceffe06
commit 96513eef6a
10 changed files with 219 additions and 38 deletions

View File

@@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.fcm
import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
import kr.co.vividnext.sodalive.i18n.Lang import kr.co.vividnext.sodalive.i18n.Lang
import kr.co.vividnext.sodalive.i18n.SodaMessageSource import kr.co.vividnext.sodalive.i18n.SodaMessageSource
import kr.co.vividnext.sodalive.live.room.GenderRestriction
import kr.co.vividnext.sodalive.member.MemberRepository import kr.co.vividnext.sodalive.member.MemberRepository
import org.springframework.scheduling.annotation.Async import org.springframework.scheduling.annotation.Async
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
@@ -33,7 +34,8 @@ class FcmEvent(
val auditionId: Long? = null, val auditionId: Long? = null,
val commentParentId: Long? = null, val commentParentId: Long? = null,
val myMemberId: Long? = null, val myMemberId: Long? = null,
val isAvailableJoinCreator: Boolean? = null val isAvailableJoinCreator: Boolean? = null,
val genderRestriction: GenderRestriction? = null
) )
@Component @Component
@@ -69,7 +71,8 @@ class FcmSendListener(
val pushTokens = memberRepository.getCreateLiveRoomNotificationRecipientPushTokens( val pushTokens = memberRepository.getCreateLiveRoomNotificationRecipientPushTokens(
creatorId = fcmEvent.creatorId!!, creatorId = fcmEvent.creatorId!!,
isAuth = fcmEvent.isAuth ?: false, isAuth = fcmEvent.isAuth ?: false,
isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false,
genderRestriction = fcmEvent.genderRestriction
) )
sendPush(pushTokens, fcmEvent, roomId = fcmEvent.roomId) sendPush(pushTokens, fcmEvent, roomId = fcmEvent.roomId)
} }
@@ -79,7 +82,8 @@ class FcmSendListener(
creatorId = fcmEvent.creatorId!!, creatorId = fcmEvent.creatorId!!,
roomId = fcmEvent.roomId!!, roomId = fcmEvent.roomId!!,
isAuth = fcmEvent.isAuth ?: false, isAuth = fcmEvent.isAuth ?: false,
isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false,
genderRestriction = fcmEvent.genderRestriction
) )
sendPush(pushTokens, fcmEvent, roomId = fcmEvent.roomId) sendPush(pushTokens, fcmEvent, roomId = fcmEvent.roomId)
} }

View File

@@ -1448,6 +1448,11 @@ class SodaMessageSource {
) )
private val liveRoomMessages = mapOf( private val liveRoomMessages = mapOf(
"live.room.gender_restricted" to mapOf(
Lang.KO to "입장 가능한 성별이 아닙니다.",
Lang.EN to "Your gender is not allowed to enter this room.",
Lang.JA to "入場可能な性別ではありません。"
),
"live.room.max_reservations" to mapOf( "live.room.max_reservations" to mapOf(
Lang.KO to "예약 라이브는 최대 3개까지 가능합니다.", Lang.KO to "예약 라이브는 최대 3개까지 가능합니다.",
Lang.EN to "You can reserve up to 3 live sessions.", Lang.EN to "You can reserve up to 3 live sessions.",

View File

@@ -15,5 +15,6 @@ data class CreateLiveRoomRequest(
val menuPanId: Long = 0, val menuPanId: Long = 0,
val menuPan: String = "", val menuPan: String = "",
val isActiveMenuPan: Boolean = false, val isActiveMenuPan: Boolean = false,
val isAvailableJoinCreator: Boolean = true val isAvailableJoinCreator: Boolean = true,
val genderRestriction: GenderRestriction = GenderRestriction.ALL
) )

View File

@@ -9,5 +9,6 @@ data class EditLiveRoomInfoRequest(
val menuPanId: Long = 0, val menuPanId: Long = 0,
val menuPan: String = "", val menuPan: String = "",
val isActiveMenuPan: Boolean? = null, val isActiveMenuPan: Boolean? = null,
val isAdult: Boolean? = null val isAdult: Boolean? = null,
val genderRestriction: GenderRestriction? = null
) )

View File

@@ -32,7 +32,9 @@ data class LiveRoom(
@Enumerated(value = EnumType.STRING) @Enumerated(value = EnumType.STRING)
val type: LiveRoomType = LiveRoomType.OPEN, val type: LiveRoomType = LiveRoomType.OPEN,
@Column(nullable = true) @Column(nullable = true)
var password: String? = null var password: String? = null,
@Enumerated(value = EnumType.STRING)
var genderRestriction: GenderRestriction = GenderRestriction.ALL
) : BaseEntity() { ) : BaseEntity() {
@OneToOne(fetch = FetchType.LAZY) @OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false) @JoinColumn(name = "member_id", nullable = false)
@@ -67,3 +69,7 @@ enum class LiveRoomType {
enum class LiveRoomStatus { enum class LiveRoomStatus {
NOW, RESERVATION NOW, RESERVATION
} }
enum class GenderRestriction {
ALL, MALE_ONLY, FEMALE_ONLY
}

View File

@@ -14,8 +14,10 @@ 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.live.room.like.GetLiveRoomHeartListItem import kr.co.vividnext.sodalive.live.room.like.GetLiveRoomHeartListItem
import kr.co.vividnext.sodalive.live.room.like.QGetLiveRoomHeartListItem import kr.co.vividnext.sodalive.live.room.like.QGetLiveRoomHeartListItem
import kr.co.vividnext.sodalive.member.Gender
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.block.QBlockMember.blockMember
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
@@ -32,7 +34,8 @@ interface LiveRoomQueryRepository {
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> ): List<LiveRoom>
fun getLiveRoomListReservationWithDate( fun getLiveRoomListReservationWithDate(
@@ -41,14 +44,16 @@ interface LiveRoomQueryRepository {
limit: Long, limit: Long,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> ): List<LiveRoom>
fun getLiveRoomListReservationWithoutDate( fun getLiveRoomListReservationWithoutDate(
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> ): List<LiveRoom>
fun getLiveRoom(id: Long): LiveRoom? fun getLiveRoom(id: Long): LiveRoom?
@@ -76,7 +81,8 @@ class LiveRoomQueryRepositoryImpl(
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> { ): List<LiveRoom> {
var where = liveRoom.channelName.isNotNull var where = liveRoom.channelName.isNotNull
.and(liveRoom.channelName.isNotEmpty) .and(liveRoom.channelName.isNotEmpty)
@@ -94,10 +100,33 @@ class LiveRoomQueryRepositoryImpl(
) )
} }
return queryFactory if (effectiveGender != null && effectiveGender != Gender.NONE) {
where = when (effectiveGender) {
Gender.MALE -> where.and(
liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.MALE_ONLY)
)
Gender.FEMALE -> where.and(
liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.FEMALE_ONLY)
)
Gender.NONE -> where
}
}
var select = queryFactory
.selectFrom(liveRoom) .selectFrom(liveRoom)
.innerJoin(liveRoom.member, member) .innerJoin(liveRoom.member, member)
.leftJoin(quarterLiveRankings).on(liveRoom.id.eq(quarterLiveRankings.roomId)) .leftJoin(quarterLiveRankings).on(liveRoom.id.eq(quarterLiveRankings.roomId))
if (memberId != null) {
val blockMemberCondition = blockMember.member.id.eq(member.id)
.and(blockMember.blockedMember.id.eq(memberId))
.and(blockMember.isActive.isTrue)
select = select.leftJoin(blockMember).on(blockMemberCondition)
where = where.and(blockMember.id.isNull)
}
return select
.where(where) .where(where)
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
@@ -116,7 +145,8 @@ class LiveRoomQueryRepositoryImpl(
limit: Long, limit: Long,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> { ): List<LiveRoom> {
var where = liveRoom.beginDateTime.goe(date) var where = liveRoom.beginDateTime.goe(date)
.and(liveRoom.beginDateTime.lt(date.plusDays(1))) .and(liveRoom.beginDateTime.lt(date.plusDays(1)))
@@ -138,9 +168,32 @@ class LiveRoomQueryRepositoryImpl(
) )
} }
return queryFactory if (effectiveGender != null && effectiveGender != Gender.NONE) {
where = when (effectiveGender) {
Gender.MALE -> where.and(
liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.MALE_ONLY)
)
Gender.FEMALE -> where.and(
liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.FEMALE_ONLY)
)
Gender.NONE -> where
}
}
var select = queryFactory
.selectFrom(liveRoom) .selectFrom(liveRoom)
.innerJoin(liveRoom.member, member) .innerJoin(liveRoom.member, member)
if (memberId != null) {
val blockMemberCondition = blockMember.member.id.eq(member.id)
.and(blockMember.blockedMember.id.eq(memberId))
.and(blockMember.isActive.isTrue)
select = select.leftJoin(blockMember).on(blockMemberCondition)
where = where.and(blockMember.id.isNull)
}
return select
.where(where) .where(where)
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
@@ -152,7 +205,8 @@ class LiveRoomQueryRepositoryImpl(
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> { ): List<LiveRoom> {
var where = liveRoom.beginDateTime.gt( var where = liveRoom.beginDateTime.gt(
LocalDateTime.now() LocalDateTime.now()
@@ -178,6 +232,18 @@ class LiveRoomQueryRepositoryImpl(
) )
} }
if (effectiveGender != null && effectiveGender != Gender.NONE) {
where = when (effectiveGender) {
Gender.MALE -> where.and(
liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.MALE_ONLY)
)
Gender.FEMALE -> where.and(
liveRoom.genderRestriction.`in`(GenderRestriction.ALL, GenderRestriction.FEMALE_ONLY)
)
Gender.NONE -> where
}
}
val orderBy = if (memberId != null) { val orderBy = if (memberId != null) {
listOf( listOf(
CaseBuilder() CaseBuilder()
@@ -190,10 +256,21 @@ class LiveRoomQueryRepositoryImpl(
listOf(liveRoom.beginDateTime.asc()) listOf(liveRoom.beginDateTime.asc())
} }
return queryFactory var select = queryFactory
.selectFrom(liveRoom) .selectFrom(liveRoom)
.innerJoin(liveRoom.member, member) .innerJoin(liveRoom.member, member)
.limit(10) .limit(10)
if (memberId != null) {
val blockMemberCondition = blockMember.member.id.eq(member.id)
.and(blockMember.blockedMember.id.eq(memberId))
.and(blockMember.isActive.isTrue)
select = select.leftJoin(blockMember).on(blockMemberCondition)
where = where.and(blockMember.id.isNull)
}
return select
.where(where) .where(where)
.orderBy(*orderBy.toTypedArray()) .orderBy(*orderBy.toTypedArray())
.fetch() .fetch()

View File

@@ -193,13 +193,21 @@ class LiveRoomService(
member: Member?, member: Member?,
timezone: String timezone: String
): List<GetRoomListResponse> { ): List<GetRoomListResponse> {
val effectiveGender = member?.let {
if (it.auth != null) {
if (it.auth!!.gender == 1) Gender.MALE else Gender.FEMALE
} else {
it.gender
}
}
val roomList = if (status == LiveRoomStatus.NOW) { val roomList = if (status == LiveRoomStatus.NOW) {
getLiveRoomListNow( getLiveRoomListNow(
pageable, pageable,
timezone, timezone,
memberId = member?.id, memberId = member?.id,
isCreator = member?.role == MemberRole.CREATOR, isCreator = member?.role == MemberRole.CREATOR,
isAdult = member?.auth != null && isAdultContentVisible isAdult = member?.auth != null && isAdultContentVisible,
effectiveGender = effectiveGender
) )
} else if (dateString != null) { } else if (dateString != null) {
getLiveRoomListReservationWithDate( getLiveRoomListReservationWithDate(
@@ -208,14 +216,16 @@ class LiveRoomService(
timezone, timezone,
memberId = member?.id, memberId = member?.id,
isCreator = member?.role == MemberRole.CREATOR, isCreator = member?.role == MemberRole.CREATOR,
isAdult = member?.auth != null && isAdultContentVisible isAdult = member?.auth != null && isAdultContentVisible,
effectiveGender = effectiveGender
) )
} else { } else {
getLiveRoomListReservationWithoutDate( getLiveRoomListReservationWithoutDate(
timezone, timezone,
isCreator = member?.role == MemberRole.CREATOR, isCreator = member?.role == MemberRole.CREATOR,
memberId = member?.id, memberId = member?.id,
isAdult = member?.auth != null && isAdultContentVisible isAdult = member?.auth != null && isAdultContentVisible,
effectiveGender = effectiveGender
) )
} }
@@ -223,13 +233,6 @@ class LiveRoomService(
val languageTagByMemberId = buildLanguageTagMap(creatorIds) val languageTagByMemberId = buildLanguageTagMap(creatorIds)
return roomList return roomList
.filter {
if (member?.id != null) {
!blockMemberRepository.isBlocked(blockedMemberId = member.id!!, memberId = it.member!!.id!!)
} else {
true
}
}
.map { .map {
val roomInfo = roomInfoRepository.findByIdOrNull(it.id!!) val roomInfo = roomInfoRepository.findByIdOrNull(it.id!!)
@@ -296,7 +299,8 @@ class LiveRoomService(
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> { ): List<LiveRoom> {
return repository.getLiveRoomListNow( return repository.getLiveRoomListNow(
offset = pageable.offset, offset = pageable.offset,
@@ -304,7 +308,8 @@ class LiveRoomService(
timezone = timezone, timezone = timezone,
memberId = memberId, memberId = memberId,
isCreator = isCreator, isCreator = isCreator,
isAdult = isAdult isAdult = isAdult,
effectiveGender = effectiveGender
) )
} }
@@ -314,7 +319,8 @@ class LiveRoomService(
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> { ): List<LiveRoom> {
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val date = LocalDate.parse(dateString, dateTimeFormatter).atStartOfDay() val date = LocalDate.parse(dateString, dateTimeFormatter).atStartOfDay()
@@ -328,7 +334,8 @@ class LiveRoomService(
limit = pageable.pageSize.toLong(), limit = pageable.pageSize.toLong(),
memberId = memberId, memberId = memberId,
isCreator = isCreator, isCreator = isCreator,
isAdult = isAdult isAdult = isAdult,
effectiveGender = effectiveGender
) )
} }
@@ -336,9 +343,10 @@ class LiveRoomService(
timezone: String, timezone: String,
memberId: Long?, memberId: Long?,
isCreator: Boolean, isCreator: Boolean,
isAdult: Boolean isAdult: Boolean,
effectiveGender: Gender?
): List<LiveRoom> { ): List<LiveRoom> {
return repository.getLiveRoomListReservationWithoutDate(timezone, memberId, isCreator, isAdult) return repository.getLiveRoomListReservationWithoutDate(timezone, memberId, isCreator, isAdult, effectiveGender)
} }
@Transactional @Transactional
@@ -400,7 +408,8 @@ class LiveRoomService(
}, },
type = request.type, type = request.type,
password = request.password, password = request.password,
isAvailableJoinCreator = request.isAvailableJoinCreator isAvailableJoinCreator = request.isAvailableJoinCreator,
genderRestriction = request.genderRestriction
) )
room.member = member room.member = member
@@ -479,7 +488,8 @@ class LiveRoomService(
isAuth = createdRoom.isAdult, isAuth = createdRoom.isAdult,
isAvailableJoinCreator = createdRoom.isAvailableJoinCreator, isAvailableJoinCreator = createdRoom.isAvailableJoinCreator,
roomId = createdRoom.id, roomId = createdRoom.id,
creatorId = createdRoom.member!!.id creatorId = createdRoom.member!!.id,
genderRestriction = createdRoom.genderRestriction
) )
) )
@@ -494,6 +504,10 @@ class LiveRoomService(
throw SodaException(messageKey = "live.room.adult_verification_required") throw SodaException(messageKey = "live.room.adult_verification_required")
} }
if (!member.canEnter(room.genderRestriction) && room.member!!.id!! != member.id!!) {
throw SodaException(messageKey = "live.room.gender_restricted")
}
val beginDateTime = room.beginDateTime val beginDateTime = room.beginDateTime
.atZone(ZoneId.of("UTC")) .atZone(ZoneId.of("UTC"))
.withZoneSameInstant(ZoneId.of(timezone)) .withZoneSameInstant(ZoneId.of(timezone))
@@ -521,6 +535,7 @@ class LiveRoomService(
isPaid = false, isPaid = false,
isAdult = room.isAdult, isAdult = room.isAdult,
isPrivateRoom = room.type == LiveRoomType.PRIVATE, isPrivateRoom = room.type == LiveRoomType.PRIVATE,
genderRestriction = room.genderRestriction,
password = room.password password = room.password
) )
response.manager = GetRoomDetailManager(room.member!!, cloudFrontHost = cloudFrontHost) response.manager = GetRoomDetailManager(room.member!!, cloudFrontHost = cloudFrontHost)
@@ -640,7 +655,8 @@ class LiveRoomService(
isAuth = room.isAdult, isAuth = room.isAdult,
isAvailableJoinCreator = room.isAvailableJoinCreator, isAvailableJoinCreator = room.isAvailableJoinCreator,
roomId = room.id, roomId = room.id,
creatorId = room.member!!.id creatorId = room.member!!.id,
genderRestriction = room.genderRestriction
) )
) )
} }
@@ -739,6 +755,10 @@ class LiveRoomService(
) )
} }
if (room.member!!.id!! != member.id!! && !member.canEnter(room.genderRestriction)) {
throw SodaException(messageKey = "live.room.gender_restricted")
}
val lock = getOrCreateLock(memberId = member.id!!) val lock = getOrCreateLock(memberId = member.id!!)
lock.write { lock.write {
var roomInfo = roomInfoRepository.findByIdOrNull(request.roomId) var roomInfo = roomInfoRepository.findByIdOrNull(request.roomId)
@@ -853,6 +873,10 @@ class LiveRoomService(
room.isAdult = request.isAdult room.isAdult = request.isAdult
} }
if (request.genderRestriction != null) {
room.genderRestriction = request.genderRestriction
}
if (request.isActiveMenuPan != null) { if (request.isActiveMenuPan != null) {
if (request.isActiveMenuPan) { if (request.isActiveMenuPan) {
if (request.menuPanId > 0) { if (request.menuPanId > 0) {

View File

@@ -1,5 +1,6 @@
package kr.co.vividnext.sodalive.live.room.detail package kr.co.vividnext.sodalive.live.room.detail
import kr.co.vividnext.sodalive.live.room.GenderRestriction
import kr.co.vividnext.sodalive.member.Member import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRole import kr.co.vividnext.sodalive.member.MemberRole
@@ -11,6 +12,7 @@ data class GetRoomDetailResponse(
var isPaid: Boolean, var isPaid: Boolean,
val isAdult: Boolean, val isAdult: Boolean,
val isPrivateRoom: Boolean, val isPrivateRoom: Boolean,
val genderRestriction: GenderRestriction,
val password: String?, val password: String?,
val tags: List<String>, val tags: List<String>,
val channelName: String?, val channelName: String?,

View File

@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.member
import kr.co.vividnext.sodalive.common.BaseEntity import kr.co.vividnext.sodalive.common.BaseEntity
import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse import kr.co.vividnext.sodalive.explorer.GetExplorerSectionCreatorResponse
import kr.co.vividnext.sodalive.live.room.GenderRestriction
import kr.co.vividnext.sodalive.member.auth.Auth import kr.co.vividnext.sodalive.member.auth.Auth
import kr.co.vividnext.sodalive.member.following.CreatorFollowing import kr.co.vividnext.sodalive.member.following.CreatorFollowing
import kr.co.vividnext.sodalive.member.notification.MemberNotification import kr.co.vividnext.sodalive.member.notification.MemberNotification
@@ -148,6 +149,22 @@ data class Member(
follow = follow follow = follow
) )
} }
fun canEnter(restriction: GenderRestriction): Boolean {
val effectiveGender = if (auth != null) {
if (auth!!.gender == 1) Gender.MALE else Gender.FEMALE
} else {
gender
}
if (effectiveGender == Gender.NONE) return true
return when (restriction) {
GenderRestriction.ALL -> true
GenderRestriction.MALE_ONLY -> effectiveGender == Gender.MALE
GenderRestriction.FEMALE_ONLY -> effectiveGender == Gender.FEMALE
}
}
} }
enum class Gender { enum class Gender {

View File

@@ -5,6 +5,7 @@ import kr.co.vividnext.sodalive.fcm.PushTokenInfo
import kr.co.vividnext.sodalive.fcm.QPushToken.pushToken import kr.co.vividnext.sodalive.fcm.QPushToken.pushToken
import kr.co.vividnext.sodalive.fcm.QPushTokenInfo import kr.co.vividnext.sodalive.fcm.QPushTokenInfo
import kr.co.vividnext.sodalive.live.reservation.QLiveReservation.liveReservation import kr.co.vividnext.sodalive.live.reservation.QLiveReservation.liveReservation
import kr.co.vividnext.sodalive.live.room.GenderRestriction
import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
import kr.co.vividnext.sodalive.member.QMember.member import kr.co.vividnext.sodalive.member.QMember.member
import kr.co.vividnext.sodalive.member.auth.QAuth.auth import kr.co.vividnext.sodalive.member.auth.QAuth.auth
@@ -35,14 +36,16 @@ interface MemberQueryRepository {
fun getCreateLiveRoomNotificationRecipientPushTokens( fun getCreateLiveRoomNotificationRecipientPushTokens(
creatorId: Long, creatorId: Long,
isAuth: Boolean, isAuth: Boolean,
isAvailableJoinCreator: Boolean isAvailableJoinCreator: Boolean,
genderRestriction: GenderRestriction? = null
): List<PushTokenInfo> ): List<PushTokenInfo>
fun getStartLiveRoomNotificationRecipientPushTokens( fun getStartLiveRoomNotificationRecipientPushTokens(
creatorId: Long, creatorId: Long,
roomId: Long, roomId: Long,
isAuth: Boolean, isAuth: Boolean,
isAvailableJoinCreator: Boolean isAvailableJoinCreator: Boolean,
genderRestriction: GenderRestriction? = null
): List<PushTokenInfo> ): List<PushTokenInfo>
fun getUploadContentNotificationRecipientPushTokens( fun getUploadContentNotificationRecipientPushTokens(
@@ -132,7 +135,8 @@ class MemberQueryRepositoryImpl(
override fun getCreateLiveRoomNotificationRecipientPushTokens( override fun getCreateLiveRoomNotificationRecipientPushTokens(
creatorId: Long, creatorId: Long,
isAuth: Boolean, isAuth: Boolean,
isAvailableJoinCreator: Boolean isAvailableJoinCreator: Boolean,
genderRestriction: GenderRestriction?
): List<PushTokenInfo> { ): List<PushTokenInfo> {
val member = QMember.member val member = QMember.member
val creator = QMember.member val creator = QMember.member
@@ -158,6 +162,10 @@ class MemberQueryRepositoryImpl(
where = where.and(creatorFollowing.member.role.ne(MemberRole.CREATOR)) where = where.and(creatorFollowing.member.role.ne(MemberRole.CREATOR))
} }
if (genderRestriction != null && genderRestriction != GenderRestriction.ALL) {
where = where.and(getGenderCondition(genderRestriction))
}
return queryFactory return queryFactory
.select( .select(
QPushTokenInfo( QPushTokenInfo(
@@ -180,7 +188,8 @@ class MemberQueryRepositoryImpl(
creatorId: Long, creatorId: Long,
roomId: Long, roomId: Long,
isAuth: Boolean, isAuth: Boolean,
isAvailableJoinCreator: Boolean isAvailableJoinCreator: Boolean,
genderRestriction: GenderRestriction?
): List<PushTokenInfo> { ): List<PushTokenInfo> {
val member = QMember.member val member = QMember.member
val creator = QMember.member val creator = QMember.member
@@ -206,6 +215,10 @@ class MemberQueryRepositoryImpl(
where = where.and(creatorFollowing.member.role.ne(MemberRole.CREATOR)) where = where.and(creatorFollowing.member.role.ne(MemberRole.CREATOR))
} }
if (genderRestriction != null && genderRestriction != GenderRestriction.ALL) {
where = where.and(getGenderCondition(genderRestriction))
}
val followingMemberPushToken = queryFactory val followingMemberPushToken = queryFactory
.select( .select(
QPushTokenInfo( QPushTokenInfo(
@@ -237,6 +250,10 @@ class MemberQueryRepositoryImpl(
where = where.and(auth.isNotNull) where = where.and(auth.isNotNull)
} }
if (genderRestriction != null && genderRestriction != GenderRestriction.ALL) {
where = where.and(getGenderCondition(genderRestriction, liveReservation.member))
}
val reservationMemberPushToken = queryFactory val reservationMemberPushToken = queryFactory
.select( .select(
QPushTokenInfo( QPushTokenInfo(
@@ -256,6 +273,33 @@ class MemberQueryRepositoryImpl(
return (followingMemberPushToken + reservationMemberPushToken).distinctBy { it.token } return (followingMemberPushToken + reservationMemberPushToken).distinctBy { it.token }
} }
private fun getGenderCondition(
genderRestriction: GenderRestriction,
qMember: QMember = member
) = when (genderRestriction) {
GenderRestriction.MALE_ONLY -> {
auth.isNotNull.and(auth.gender.eq(1))
.or(
auth.isNull.and(
qMember.gender.eq(Gender.MALE)
.or(qMember.gender.eq(Gender.NONE))
)
)
}
GenderRestriction.FEMALE_ONLY -> {
auth.isNotNull.and(auth.gender.eq(0))
.or(
auth.isNull.and(
qMember.gender.eq(Gender.FEMALE)
.or(qMember.gender.eq(Gender.NONE))
)
)
}
else -> null
}
override fun getUploadContentNotificationRecipientPushTokens( override fun getUploadContentNotificationRecipientPushTokens(
creatorId: Long, creatorId: Long,
isAuth: Boolean isAuth: Boolean