踢出房间校验优化

This commit is contained in:
tianfeng 2026-03-19 15:39:25 +08:00
parent 85e8973b43
commit 29cea647b6

View File

@ -11,7 +11,7 @@ import com.red.circle.framework.core.response.ResponseErrorCode;
import com.red.circle.live.inner.endpoint.LiveMicClient; import com.red.circle.live.inner.endpoint.LiveMicClient;
import com.red.circle.other.app.dto.clientobject.room.RoomBlackProcessCO; import com.red.circle.other.app.dto.clientobject.room.RoomBlackProcessCO;
import com.red.circle.other.app.dto.cmd.room.RoomBlackCmd; import com.red.circle.other.app.dto.cmd.room.RoomBlackCmd;
import com.red.circle.other.domain.gateway.props.PropsNobleVipGateway; import com.red.circle.other.domain.enums.VipAbilityType;
import com.red.circle.other.domain.gateway.user.UserProfileGateway; import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile; import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService; import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
@ -28,17 +28,13 @@ import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.inner.asserts.RoomErrorCode; import com.red.circle.other.inner.asserts.RoomErrorCode;
import com.red.circle.other.inner.asserts.user.UserErrorCode; import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.enums.config.EnumConfigKey; import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.enums.live.RoomUserRolesEnum;
import com.red.circle.other.inner.enums.material.NobleVipEnum;
import com.red.circle.other.inner.enums.material.PropsCommodityType;
import com.red.circle.other.inner.enums.material.PropsVipActualEquityEnum;
import com.red.circle.other.inner.model.dto.material.props.PropsNobleVipAbilityDTO;
import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateUtils; import com.red.circle.tool.core.date.DateUtils;
import com.red.circle.tool.core.date.TimestampUtils; import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.json.JacksonUtils; import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils; import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils; import com.red.circle.tool.core.text.StringUtils;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -61,9 +57,7 @@ public class RoomBlackJoinCmdExe {
private final RoomMemberService roomMemberService; private final RoomMemberService roomMemberService;
private final UserProfileGateway userProfileGateway; private final UserProfileGateway userProfileGateway;
private final AdministratorService administratorService; private final AdministratorService administratorService;
private final PropsNobleVipGateway propsNobleVipGateway;
private final ApiOperationLogService apiOperationLogService; private final ApiOperationLogService apiOperationLogService;
private final EnumConfigCacheService enumConfigCacheService;
private final RoomUserBlacklistService roomUserBlacklistService; private final RoomUserBlacklistService roomUserBlacklistService;
private final RoomProfileManagerService roomProfileManagerService; private final RoomProfileManagerService roomProfileManagerService;
private final LiveMicClient liveMicClient; private final LiveMicClient liveMicClient;
@ -83,12 +77,13 @@ public class RoomBlackJoinCmdExe {
.setCreateTime(DateUtils.now()) .setCreateTime(DateUtils.now())
); );
// 时间参数校验
if (cmd.getOutTime() <= 0) { if (cmd.getOutTime() <= 0) {
log.warn("RoomBlackProcessCO 请求时间参数错误:{}", cmd.getOutTime());
ResponseAssert.failure(ResponseErrorCode.REQUEST_PARAMETER_ERROR); ResponseAssert.failure(ResponseErrorCode.REQUEST_PARAMETER_ERROR);
return null; return null;
} }
// 操作者无踢出权限
List<String> authResources = administratorAuthService.listAuthResources(cmd.getUserId()); List<String> authResources = administratorAuthService.listAuthResources(cmd.getUserId());
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, authResources.contains("KICK_ROOM")); ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, authResources.contains("KICK_ROOM"));
@ -96,118 +91,71 @@ public class RoomBlackJoinCmdExe {
ResponseAssert.isFalse(UserErrorCode.NOT_OPERATION_ME, ResponseAssert.isFalse(UserErrorCode.NOT_OPERATION_ME,
Objects.equals(cmd.getUserId(), cmd.requiredReqUserId())); Objects.equals(cmd.getUserId(), cmd.requiredReqUserId()));
String superAdminIds = enumConfigCacheService.getValue(EnumConfigKey.ASWAT_ADMINS, // 不可操作系统管理员
cmd.requireReqSysOrigin());
// 权限不足: 不可操作管理员
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION,
StringUtils.isNotBlank(superAdminIds) && superAdminIds administratorService.existsAdmin(cmd.getUserId()));
.contains(String.valueOf(cmd.getUserId())));
// 被踢用户信息
UserProfile beBlackUserProfile = userProfileGateway.getByUserId(cmd.getUserId()); UserProfile beBlackUserProfile = userProfileGateway.getByUserId(cmd.getUserId());
// 没有找到用户信息
ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, beBlackUserProfile); ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, beBlackUserProfile);
// 房间不存在 // 房间信息
RoomProfile beBlackRoomProfile = roomProfileManagerService.getProfileById(cmd.getRoomId()); RoomProfile roomProfile = roomProfileManagerService.getProfileById(cmd.getRoomId());
ResponseAssert.notNull(RoomErrorCode.ROOM_NOT_EXISTS, beBlackRoomProfile); ResponseAssert.notNull(RoomErrorCode.ROOM_NOT_EXISTS, roomProfile);
RoomMember requestMember = roomMemberService // 操作者房间成员信息
.getRoomMember(cmd.getRoomId(), cmd.requiredReqUserId()); RoomMember requestMember = roomMemberService.getRoomMember(cmd.getRoomId(), cmd.requiredReqUserId());
ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, requestMember); ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, requestMember);
if (!(StringUtils.isNotBlank(superAdminIds) && superAdminIds // 被踢用户开启了防拉黑权限
.contains(String.valueOf(cmd.requiredReqUserId())))) { ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION,
userProfileGateway.getUserVipAbility(cmd.getUserId(), VipAbilityType.ANTI_BLOCK));
Long wearNobleVipSourceId = getWearNobleVipSourceId(beBlackUserProfile); // 被操作人角色校验
PropsNobleVipAbilityDTO vipAbilities = propsNobleVipGateway.getAbilityDTO( RoomMember beOptMember = roomMemberService.getRoomMember(cmd.getRoomId(), cmd.getUserId());
wearNobleVipSourceId);
Boolean vip = Objects.nonNull(vipAbilities) && (Objects.equals(vipAbilities.getVipType(),
NobleVipEnum.EMPEROR.name())||Objects.equals(vipAbilities.getVipType(),
NobleVipEnum.KING.name()));
// 2043 权限不足
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, vip);
// 2023-9-7仅房主可以踢VIPvip56不能踢
if (!requestMember.checkHomeowner()) {
// 实际VIP权益
List<PropsVipActualEquityEnum> vipActualList = listUserPropsVipActualEquity(
beBlackUserProfile);
// 2043 权限不足
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION,
CollectionUtils.isNotEmpty(vipActualList) && vipActualList
.contains(PropsVipActualEquityEnum.PROHIBIT_KICK));
}
}
// 超级管理员除了不能拉黑本房间房主其余都可以拉黑
if (StringUtils.isNotBlank(superAdminIds) && superAdminIds
.contains(String.valueOf(cmd.requiredReqUserId()))) {
superAdminBlacklist(cmd, beBlackUserProfile, beBlackRoomProfile);
return new RoomBlackProcessCO()
.setRoomId(cmd.getRoomId())
.setRoles("SUPER_ADMIN")
.setRemark("系统管理员");
}
// 权限不足(必须是房主/管理员)
// ResponseAssert.isTrue(CommonErrorCode.INSUFFICIENT_PERMISSION,
// requestMember.checkHomeownerOrAdmin());
RoomMember beOptMember = roomMemberService
.getRoomMember(cmd.getRoomId(), cmd.getUserId());
// 如果为空表示被操作人角色为游客
if (Objects.nonNull(beOptMember)) { if (Objects.nonNull(beOptMember)) {
// 不能是房主 // 不能踢房主
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, beOptMember.checkHomeowner());
beOptMember.checkHomeowner()); // 不能踢同级
// 权限不能相同
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION,
Objects.equals(beOptMember.getRoles(), requestMember.getRoles())); Objects.equals(beOptMember.getRoles(), requestMember.getRoles()));
} }
// 权限不足 // 不能踢房间创建者
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION,
Objects.equals(beBlackRoomProfile.getUserId(), cmd.getUserId())); Objects.equals(roomProfile.getUserId(), cmd.getUserId()));
List<Long> roomOnlineUserIds = ResponseAssert.requiredSuccess(liveMicClient.getLiveRoomUserIds(cmd.getRoomId(), 200)); // 被踢用户不在房间中
List<Long> roomOnlineUserIds = ResponseAssert.requiredSuccess(
liveMicClient.getLiveRoomUserIds(cmd.getRoomId(), 200));
if (CollectionUtils.isEmpty(roomOnlineUserIds) || !roomOnlineUserIds.contains(beBlackUserProfile.getId())) { if (CollectionUtils.isEmpty(roomOnlineUserIds) || !roomOnlineUserIds.contains(beBlackUserProfile.getId())) {
log.info("用户不在房间,无法拉黑 createUserId:{} roomOnlineUserIds:{} blackUserId:{}", cmd.requiredReqUserId(), roomOnlineUserIds, beBlackUserProfile.getId()); log.info("用户不在房间,无法拉黑 reqUserId:{} blackUserId:{}", cmd.requiredReqUserId(), beBlackUserProfile.getId());
return null; return null;
} }
Boolean isSuccess = ResponseAssert.requiredSuccess( // 执行拉黑
ResponseAssert.requiredSuccess(
imGroupClient.banGroupMember(new GroupBanCmd() imGroupClient.banGroupMember(new GroupBanCmd()
.setGroupId(beBlackRoomProfile.getRoomAccount()) .setGroupId(roomProfile.getRoomAccount())
.setUserId(beBlackUserProfile.getId()) .setUserId(beBlackUserProfile.getId())
.setDuration(cmd.getOutTime() * 60) .setDuration(cmd.getOutTime() * 60)
.setDescription(cmd.requiredReqUserId() .setDescription(cmd.requiredReqUserId() + "#" + requestMember.getRoles() + "#" + beBlackUserProfile.getId())
+ "#"
+ requestMember.getRoles()
+ "#"
+ beBlackUserProfile.getId())
) )
); );
log.info("imGroupClient拉黑结果:{}", isSuccess);
// if (Objects.equals(isSuccess, Boolean.TRUE)) {
roomUserBlacklistService.add(new RoomUserBlacklist() roomUserBlacklistService.add(new RoomUserBlacklist()
.setTimingId(IdWorker.getId()) .setTimingId(IdWorker.getId())
.setSysOrigin(cmd.requireReqSysOrigin()) .setSysOrigin(cmd.requireReqSysOrigin())
.setUserId(beBlackUserProfile.getId()) .setUserId(beBlackUserProfile.getId())
.setRoomId(beBlackRoomProfile.getId()) .setRoomId(roomProfile.getId())
.setCreateUserRoles(requestMember.getRoles()) .setCreateUserRoles(requestMember.getRoles())
.setCreateUser(cmd.requiredReqUserId()) .setCreateUser(cmd.requiredReqUserId())
.setExpiredTime(TimestampUtils.nowPlusMinutes(cmd.getOutTime())) .setExpiredTime(TimestampUtils.nowPlusMinutes(cmd.getOutTime()))
.setCreateTime(TimestampUtils.now()) .setCreateTime(TimestampUtils.now())
); );
// }
trtcClient.removeUser(new TrtcRemoveUserCmd() trtcClient.removeUser(new TrtcRemoveUserCmd()
.setRoomId(Long.parseLong(beBlackRoomProfile.getRoomAccount())) .setRoomId(Long.parseLong(roomProfile.getRoomAccount()))
.setUserIds(Collections.singletonList(beBlackUserProfile.getId())) .setUserIds(Collections.singletonList(beBlackUserProfile.getId()))
.setLogOrigin("黑名单")); .setLogOrigin("黑名单"));
@ -216,40 +164,4 @@ public class RoomBlackJoinCmdExe {
.setRoles(requestMember.getRoles()) .setRoles(requestMember.getRoles())
.setRemark("常规操作"); .setRemark("常规操作");
} }
private List<PropsVipActualEquityEnum> listUserPropsVipActualEquity(UserProfile userProfile) {
return userProfileGateway.listUserActualEquityEnum(userProfile.getId());
}
private void superAdminBlacklist(RoomBlackCmd cmd, UserProfile baseInfo,
RoomProfile roomProfile) {
RoomMember beOptMember = roomMemberService.getRoomMember(cmd.getRoomId(), cmd.getUserId());
ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION,
Objects.nonNull(beOptMember) && beOptMember.checkHomeowner());
RoomMember requestMember = roomMemberService
.getRoomMember(cmd.getRoomId(), cmd.requiredReqUserId());
roomUserBlacklistService.add(new RoomUserBlacklist()
.setTimingId(IdWorker.getId())
.setSysOrigin(cmd.requireReqSysOrigin())
.setUserId(baseInfo.getId())
.setRoomId(roomProfile.getId())
.setCreateUserRoles(Objects.isNull(requestMember) ? RoomUserRolesEnum.ADMIN.name()
: requestMember.getRoles())
.setCreateUser(cmd.requiredReqUserId())
.setExpiredTime(TimestampUtils.nowPlusMinutes(cmd.getOutTime()))
);
}
private Long getWearNobleVipSourceId(UserProfile userProfile) {
return userProfile.filterProps(
props -> Objects.nonNull(props.getPropsResources()) && PropsCommodityType.NOBLE_VIP.eq(
props.getPropsResources().getType())).stream().findFirst()
.map(props -> props.getPropsResources().getId())
.orElse(null);
}
} }