|  | @@ -39,6 +39,7 @@ import com.ym.mec.biz.dal.enums.EAnchorStatus;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.enums.EGroupDefinedDataType;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.enums.EOnOffStatus;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.enums.MessageTypeEnum;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.enums.live.ELiveViewMode;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.page.LiveRoomGoodsOrderQueryInfo;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.vo.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.redisson.RedissonMessageService;
 | 
	
	
		
			
				|  | @@ -60,6 +61,7 @@ import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  |  import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 | 
	
		
			
				|  |  |  import org.jetbrains.annotations.NotNull;
 | 
	
		
			
				|  |  |  import org.joda.time.DateTime;
 | 
	
		
			
				|  |  | +import org.redisson.api.RAtomicLong;
 | 
	
		
			
				|  |  |  import org.redisson.api.RBucket;
 | 
	
		
			
				|  |  |  import org.redisson.api.RLock;
 | 
	
		
			
				|  |  |  import org.redisson.api.RMap;
 | 
	
	
		
			
				|  | @@ -145,6 +147,8 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |      public static final String LIVE_USER_STATE_TIME = String.join(":", "IM:LIVE_USER_STATE_TIME", USER_ID);
 | 
	
		
			
				|  |  |      //主讲人信息
 | 
	
		
			
				|  |  |      public static final String LIVE_SPEAKER_INFO = String.join(":", "IM:LIVE_SPEAKER_INFO", ROOM_UID, USER_ID);
 | 
	
		
			
				|  |  | +    // 直播间游客信息
 | 
	
		
			
				|  |  | +    public static final String LIVE_VISITOR_INFO = String.join(":", "IM:LIVE_VISITOR_INFO", ROOM_UID, USER_ID);
 | 
	
		
			
				|  |  |      //主讲人最近一次加入房间的clientIp
 | 
	
		
			
				|  |  |      public static final String LIVE_SPEAKER_LAST_CLIENT_IP = String.join(":", "IM:LIVE_SPEAKER_LAST_CLIENT_IP", ROOM_UID, USER_ID);
 | 
	
		
			
				|  |  |      //直播提前开始时间
 | 
	
	
		
			
				|  | @@ -161,20 +165,25 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public ImLiveBroadcastRoomVo queryRoomAndCheck(String roomUid, Integer userId, Integer osType) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          SysUser sysUser = Optional.ofNullable(userId)
 | 
	
		
			
				|  |  |                  .map(this::getSysUser)
 | 
	
		
			
				|  |  |                  .orElseGet(this::getSysUser);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          // 默认学生端查询
 | 
	
		
			
				|  |  |          osType = Optional.ofNullable(osType).orElse(1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 移动端-学生端
 | 
	
		
			
				|  |  |          if (osType == 1) {
 | 
	
		
			
				|  |  |              //学生端
 | 
	
		
			
				|  |  |              return studentQueryRoomAndCheck(roomUid, sysUser);
 | 
	
		
			
				|  |  | -        } else if (osType == 2) {
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 移动端-老师端
 | 
	
		
			
				|  |  | +        if (osType == 2) {
 | 
	
		
			
				|  |  |              //老师端
 | 
	
		
			
				|  |  |              return teacherQueryRoomAndCheck(roomUid, sysUser);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // 直播助手
 | 
	
		
			
				|  |  | +        // PC端-直播助手
 | 
	
		
			
				|  |  |          if (osType == 3) {
 | 
	
		
			
				|  |  |              // 校验直播间是否存在
 | 
	
		
			
				|  |  |              ImLiveBroadcastRoomVo vo = Optional.ofNullable(roomUid).map(this::queryRoomInfo)
 | 
	
	
		
			
				|  | @@ -188,6 +197,60 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          return queryRoomAndCheck(roomUid, sysUser);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 游客直播间信息
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param roomUid 直播间编号
 | 
	
		
			
				|  |  | +     * @param userId  游客编号
 | 
	
		
			
				|  |  | +     * @return ImLiveBroadcastRoomVo
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public ImLiveBroadcastRoomVo visitorRoomInfo(String roomUid, Integer userId) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 直播间游客信息
 | 
	
		
			
				|  |  | +        RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
 | 
	
		
			
				|  |  | +        if (!roomTotalUser.containsKey(userId)) {
 | 
	
		
			
				|  |  | +            throw new BizException("您无法观看该直播,请刷新重试");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 游客信息
 | 
	
		
			
				|  |  | +        RoomUserInfoVo userInfo = JSONObject.toJavaObject(JSONObject.parseObject(roomTotalUser.get(userId)),
 | 
	
		
			
				|  |  | +                RoomUserInfoVo.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 游客直播间信息校验
 | 
	
		
			
				|  |  | +        ImLiveBroadcastRoomVo roomVo = getVisitorLiveBroadcastRoomVo(roomUid);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 用户直播间黑名单
 | 
	
		
			
				|  |  | +        roomVo.setBlacklistFlag(0);
 | 
	
		
			
				|  |  | +        //黑名单查询-查询当前用户是否在黑名单中
 | 
	
		
			
				|  |  | +        int count = imLiveRoomBlackService.count(Wrappers.<ImLiveRoomBlack>lambdaQuery()
 | 
	
		
			
				|  |  | +                .eq(ImLiveRoomBlack::getRoomUid, roomVo.getRoomUid())
 | 
	
		
			
				|  |  | +                .eq(ImLiveRoomBlack::getUserId, userInfo.getUserId()));
 | 
	
		
			
				|  |  | +        if (count > 0) {
 | 
	
		
			
				|  |  | +            roomVo.setBlacklistFlag(1);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        LivePluginService pluginService = livePluginContext.getPluginService(roomVo.getServiceProvider());
 | 
	
		
			
				|  |  | +        // 直播房间配置信息
 | 
	
		
			
				|  |  | +        String userSig = "";
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            // 游客IM聊天ID
 | 
	
		
			
				|  |  | +            String imUserId = MessageFormat.format("VISITOR_{0}", userInfo.getUserId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 生成聊天签名
 | 
	
		
			
				|  |  | +            userSig = pluginService.register(imUserId, userInfo.getUserName(), userInfo.getAvatar());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            log.error("直播房间游客注册失败: userId={}", userInfo.getUserId(), e);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 直播房间统计信息
 | 
	
		
			
				|  |  | +        getRoomData(roomVo);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 直播间配置信息
 | 
	
		
			
				|  |  | +        return roomVo.userSig(userSig).liveRoomConfig(pluginService.getLiveRoomConfig());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      public ImLiveBroadcastRoomVo studentQueryRoomAndCheck(String roomUid, SysUser sysUser) {
 | 
	
		
			
				|  |  |          //如果是学生端,则需要检查是否有权限进入
 | 
	
		
			
				|  |  |          Map<String, Object> param = new HashMap<>();
 | 
	
	
		
			
				|  | @@ -1004,7 +1067,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          userid = setFromUserId(userid,roomVo);
 | 
	
		
			
				|  |  |          // 消息发送用户
 | 
	
		
			
				|  |  |          LiveRoomMessage.MessageUser messageUser = null;
 | 
	
		
			
				|  |  | -        SysUser sysUser = sysUserFeignService.queryUserInfo();
 | 
	
		
			
				|  |  | +        SysUser sysUser = getRoomSysUser(Integer.parseInt(userid), roomVo.getRoomUid());
 | 
	
		
			
				|  |  |          if (Objects.nonNull(sysUser)) {
 | 
	
		
			
				|  |  |              // 发送用户信息
 | 
	
		
			
				|  |  |              messageUser = LiveRoomMessage.MessageUser
 | 
	
	
		
			
				|  | @@ -1059,7 +1122,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          String fromUserId = setFromUserId(userid, roomVo);
 | 
	
		
			
				|  |  |          // 消息发送用户
 | 
	
		
			
				|  |  |          LiveRoomMessage.MessageUser messageUser = null;
 | 
	
		
			
				|  |  | -        SysUser sysUser = sysUserFeignService.queryUserById(Integer.parseInt(userid));
 | 
	
		
			
				|  |  | +        SysUser sysUser = getRoomSysUser(Integer.parseInt(userid), roomVo.getRoomUid());
 | 
	
		
			
				|  |  |          if (Objects.nonNull(sysUser)) {
 | 
	
		
			
				|  |  |              // 发送用户信息
 | 
	
		
			
				|  |  |              messageUser = LiveRoomMessage.MessageUser
 | 
	
	
		
			
				|  | @@ -1118,7 +1181,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          // 直播间统计数据
 | 
	
		
			
				|  |  |          getRoomData(roomVo);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        String userId = setFromUserId(fromUserId.toString(),roomVo);
 | 
	
		
			
				|  |  | +        String userId = setFromUserId(fromUserId.toString(), roomVo);
 | 
	
		
			
				|  |  |          // 缓存JoinRoom用户信息到redis
 | 
	
		
			
				|  |  |          RBucket<Object> bucket = redissonClient.getBucket(RedissonMessageService.LIVE_ROOM_MEMBER + roomUid);
 | 
	
		
			
				|  |  |          if (!bucket.isExists()) {
 | 
	
	
		
			
				|  | @@ -1129,7 +1192,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 消息发送用户
 | 
	
		
			
				|  |  |          LiveRoomMessage.MessageUser messageUser = null;
 | 
	
		
			
				|  |  | -        SysUser sysUser = sysUserFeignService.queryUserInfo();
 | 
	
		
			
				|  |  | +        SysUser sysUser = getRoomSysUser(fromUserId, roomUid);
 | 
	
		
			
				|  |  |          if (Objects.nonNull(sysUser)) {
 | 
	
		
			
				|  |  |              // 发送用户信息
 | 
	
		
			
				|  |  |              messageUser = LiveRoomMessage.MessageUser
 | 
	
	
		
			
				|  | @@ -1383,13 +1446,26 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |              throw new BizException("当前用户所在机构没有加入直播间的权限");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        // 加入直播间用户信息
 | 
	
		
			
				|  |  | +        joinRoomUserInfo(roomUid, userId, imLiveBroadcastRoomVo);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 加入直播间用户信息
 | 
	
		
			
				|  |  | +     * @param roomUid 直播间编号
 | 
	
		
			
				|  |  | +     * @param userId 用户编号
 | 
	
		
			
				|  |  | +     * @param imLiveBroadcastRoomVo ImLiveBroadcastRoomVo
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private void joinRoomUserInfo(String roomUid, Integer userId, ImLiveBroadcastRoomVo imLiveBroadcastRoomVo) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          //记录用户当前房间uid
 | 
	
		
			
				|  |  |          redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userId.toString())).set(roomUid, 12L, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | -        //房间累计用户信息-指只要进入到该房间的用户都要记录
 | 
	
		
			
				|  |  | -        RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          //判断是否第一次进房间
 | 
	
		
			
				|  |  |          RoomUserInfoVo userInfo;
 | 
	
		
			
				|  |  | -        Date now = new Date();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //房间累计用户信息-指只要进入到该房间的用户都要记录
 | 
	
		
			
				|  |  | +        RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
 | 
	
		
			
				|  |  |          if (roomTotalUser.containsKey(userId)) {
 | 
	
		
			
				|  |  |              //多次进入更新动态进入时间
 | 
	
		
			
				|  |  |              userInfo = JSONObject.toJavaObject(JSONObject.parseObject(roomTotalUser.get(userId)), RoomUserInfoVo.class);
 | 
	
	
		
			
				|  | @@ -1403,7 +1479,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |              if (Objects.isNull(liveRoomMember)) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  // 初次进入房间
 | 
	
		
			
				|  |  | -                getLiveRoomUserInfo(userId, imLiveBroadcastRoomVo, now);
 | 
	
		
			
				|  |  | +                getLiveRoomUserInfo(userId, imLiveBroadcastRoomVo);
 | 
	
		
			
				|  |  |              } else {
 | 
	
		
			
				|  |  |                  // 更新直播间用户信息
 | 
	
		
			
				|  |  |                  ImLiveBroadcastRoomMember roomMember = new ImLiveBroadcastRoomMember();
 | 
	
	
		
			
				|  | @@ -1416,17 +1492,20 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  |              //第一次进该房间 写入用户首次进入时间
 | 
	
		
			
				|  |  | -            userInfo = getLiveRoomUserInfo(userId, imLiveBroadcastRoomVo, now);
 | 
	
		
			
				|  |  | +            userInfo = getLiveRoomUserInfo(userId, imLiveBroadcastRoomVo);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          //查询主讲人信息
 | 
	
		
			
				|  |  |          RBucket<RoomSpeakerInfo> speakerCache = getRoomSpeakerInfoCache(roomUid, imLiveBroadcastRoomVo.getSpeakerId().toString());
 | 
	
		
			
				|  |  |          if (speakerCache.isExists()) {
 | 
	
		
			
				|  |  |              //如果用户进来时主讲人已经开启直播则修改学生观看时间
 | 
	
		
			
				|  |  |              Integer state = speakerCache.get().getState();
 | 
	
		
			
				|  |  |              if (Objects.nonNull(state) && state == 0 && imLiveBroadcastRoomVo.getPushStatus() == 1) {
 | 
	
		
			
				|  |  | -                userInfo.setDynamicLookTime(now);
 | 
	
		
			
				|  |  | +                userInfo.setDynamicLookTime(DateTime.now().toDate());
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 直播间用户、在线用户数据缓存
 | 
	
		
			
				|  |  |          roomTotalUser.fastPut(userId, JSONObject.toJSONString(userInfo));
 | 
	
		
			
				|  |  |          //在线人员列表
 | 
	
		
			
				|  |  |          RMap<Integer, String> onlineUserInfo = getOnlineUserCache(roomUid);
 | 
	
	
		
			
				|  | @@ -1441,12 +1520,185 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |              this.sendBlackJoinRoom(userId, imLiveBroadcastRoomVo);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        log.info("join sendOnlineUserCount>>>>   roomUid: {}  fromUserId:{}  count:{}", roomUid, userId, onlineUserInfo.size());
 | 
	
		
			
				|  |  | +        log.info("joinRoom>>>> sendOnlineUserCount>>>>   roomUid: {}  fromUserId:{}  count:{}", roomUid, userId, onlineUserInfo.size());
 | 
	
		
			
				|  |  |          log.info("joinRoom>>>> userInfo: {}", JSONObject.toJSONString(userInfo));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | +     * 游客加入直播间
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param roomUid 直播间编号
 | 
	
		
			
				|  |  | +     * @param userId  游客编号
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void visitorJoinRoom(String roomUid, Integer userId) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 游客直播间信息
 | 
	
		
			
				|  |  | +        ImLiveBroadcastRoomVo roomVo = getVisitorLiveBroadcastRoomVo(roomUid);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 加入直播间用户信息
 | 
	
		
			
				|  |  | +        joinRoomUserInfo(roomUid, userId, roomVo);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 游客访问直播间信息
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param roomUid 直播间编号
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private ImLiveBroadcastRoomVo getVisitorLiveBroadcastRoomVo(String roomUid) {
 | 
	
		
			
				|  |  | +        // 查询直播间信息
 | 
	
		
			
				|  |  | +        ImLiveBroadcastRoomVo roomVo = getImLiveBroadcastRoomVo(roomUid);
 | 
	
		
			
				|  |  | +        if (Objects.isNull(roomVo) || roomVo.getRoomState() == 1) {
 | 
	
		
			
				|  |  | +            log.info("visitorJoinRoom>>>> joinRoom LIVE_ROOM_CANCEL roomUid: {}", roomUid);
 | 
	
		
			
				|  |  | +            throw new BizException("直播间不存在");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 判断当前直播间观看模式是否为游客模式且,直播状态
 | 
	
		
			
				|  |  | +        if (ELiveViewMode.VISITOR != roomVo.getViewMode()) {
 | 
	
		
			
				|  |  | +            log.info("visitorJoinRoom>>>> joinRoom LOGOUT roomUid: {} viewMode: {}", roomUid, roomVo.getViewMode());
 | 
	
		
			
				|  |  | +            throw new BizException("请登陆");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 判断当前直播间是否在直播中,直播状态 0未开始 1开始 2结束
 | 
	
		
			
				|  |  | +        if (roomVo.getLiveState() == 0) {
 | 
	
		
			
				|  |  | +            log.info("visitorJoinRoom>>>> joinRoom LIVE_NOT_START roomUid: {} liveState: {}", roomUid, roomVo.getLiveState());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Date liveStartTime = DateUtil.addMinutes(roomVo.getLiveStartTime(), -PRE_LIVE_TIME_MINUTE);
 | 
	
		
			
				|  |  | +            throw new BizException(DateUtil.format(liveStartTime, "yyyy年MM月dd日 HH点mm分") + " 可进入直播间准备");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (roomVo.getLiveState() == 2) {
 | 
	
		
			
				|  |  | +            log.info("visitorJoinRoom>>>> joinRoom LIVE_CLOSED roomUid: {} liveState: {}", roomUid, roomVo.getLiveState());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //如果直播结束了还是推广状态则将推广修改为取消
 | 
	
		
			
				|  |  | +            if (roomVo.getPopularize() == 1) {
 | 
	
		
			
				|  |  | +                this.update(Wrappers.<ImLiveBroadcastRoom>lambdaUpdate()
 | 
	
		
			
				|  |  | +                        .set(ImLiveBroadcastRoom::getPopularize, 0)
 | 
	
		
			
				|  |  | +                        .eq(ImLiveBroadcastRoom::getId, roomVo.getId()));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            throw new BizException("直播已结束!");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return roomVo;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 游客加入直播间凭据
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param roomUid     直播间编号
 | 
	
		
			
				|  |  | +     * @param fingerprint 游客凭据
 | 
	
		
			
				|  |  | +     * @return RoomUserInfoVo
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public RoomUserInfoVo getVisitorCredentials(String roomUid, String fingerprint) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 游客直播间信息校验
 | 
	
		
			
				|  |  | +        ImLiveBroadcastRoomVo roomVo = getVisitorLiveBroadcastRoomVo(roomUid);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 为当前游客生成惟一用户ID
 | 
	
		
			
				|  |  | +        String cacheKey = MessageFormat.format("fingerprint:{0}:{1}", roomUid, fingerprint);
 | 
	
		
			
				|  |  | +        RBucket<Object> bucket = redissonClient.getBucket(cacheKey);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Integer userId;
 | 
	
		
			
				|  |  | +        if (bucket.isExists()) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 查询游客用户ID
 | 
	
		
			
				|  |  | +            userId = Optional.ofNullable(bucket.get()).map(x -> (int) x).orElse(-1);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            String today = DateTime.now().toString("yyMMdd");
 | 
	
		
			
				|  |  | +            // 用户Id缓存key
 | 
	
		
			
				|  |  | +            String userIdKey = MessageFormat.format("fingerprint:userId:{1}", today);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            RAtomicLong atomicLong = redissonClient.getAtomicLong(userIdKey);
 | 
	
		
			
				|  |  | +            if (!atomicLong.isExists()) {
 | 
	
		
			
				|  |  | +                // 设置默认初始化值
 | 
	
		
			
				|  |  | +                atomicLong.set(10000);
 | 
	
		
			
				|  |  | +                // 设置缓存失效时间
 | 
	
		
			
				|  |  | +                atomicLong.expire(1L, TimeUnit.DAYS);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 生成游客用户ID
 | 
	
		
			
				|  |  | +            userId = (int) atomicLong.getAndIncrement();
 | 
	
		
			
				|  |  | +            // 设置用户ID缓存
 | 
	
		
			
				|  |  | +            bucket.set(userId + Integer.parseInt(today), 12L, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //房间累计用户信息-指只要进入到该房间的用户都要记录
 | 
	
		
			
				|  |  | +        RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        RoomUserInfoVo userInfo;
 | 
	
		
			
				|  |  | +        if (roomTotalUser.containsKey(userId)) {
 | 
	
		
			
				|  |  | +            //多次进入更新动态进入时间
 | 
	
		
			
				|  |  | +            userInfo = JSONObject.toJavaObject(JSONObject.parseObject(roomTotalUser.get(userId)), RoomUserInfoVo.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Integer exists = liveBroadcastRoomMemberService.lambdaQuery()
 | 
	
		
			
				|  |  | +                    .eq(ImLiveBroadcastRoomMember::getTenantId, userInfo.getTenantId())
 | 
	
		
			
				|  |  | +                    .eq(ImLiveBroadcastRoomMember::getRoomUid, roomUid)
 | 
	
		
			
				|  |  | +                    .eq(ImLiveBroadcastRoomMember::getUserId, userInfo.getUserId())
 | 
	
		
			
				|  |  | +                    .count();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (exists <= 0) {
 | 
	
		
			
				|  |  | +                // 初次进入房间
 | 
	
		
			
				|  |  | +                getLiveRoomVisitorInfo(userId, roomVo, fingerprint);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            //第一次进该房间 写入用户首次进入时间
 | 
	
		
			
				|  |  | +            userInfo = getLiveRoomVisitorInfo(userId, roomVo, fingerprint);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 缓存用户信息
 | 
	
		
			
				|  |  | +        roomTotalUser.fastPut(userId, JSONObject.toJSONString(userInfo));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 游客缓存信息
 | 
	
		
			
				|  |  | +        getRoomVisitorInfoCache(roomUid, userId.toString()).set(userInfo, 12L, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 返回直播间访客信息
 | 
	
		
			
				|  |  | +        return userInfo;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 获取直播间游客信息
 | 
	
		
			
				|  |  | +     * @param userId 游客编号
 | 
	
		
			
				|  |  | +     * @param imLiveBroadcastRoomVo ImLiveBroadcastRoomVo
 | 
	
		
			
				|  |  | +     * @param fingerprint 游客凭据
 | 
	
		
			
				|  |  | +     * @return RoomUserInfoVo
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private RoomUserInfoVo getLiveRoomVisitorInfo(Integer userId, ImLiveBroadcastRoomVo imLiveBroadcastRoomVo, String fingerprint) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        RoomUserInfoVo userInfo = new RoomUserInfoVo();
 | 
	
		
			
				|  |  | +        // 生成游客账号信息,缓存信息
 | 
	
		
			
				|  |  | +        userInfo.setTenantId(-1);
 | 
	
		
			
				|  |  | +        userInfo.setUserId(userId);
 | 
	
		
			
				|  |  | +        userInfo.setUserName(MessageFormat.format("游客{0}", String.valueOf(userId)));
 | 
	
		
			
				|  |  | +        userInfo.setTotalViewTime(0);
 | 
	
		
			
				|  |  | +        userInfo.setFirstJoinTime(DateTime.now().toDate());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 游客默认头像
 | 
	
		
			
				|  |  | +        String defaultAvatar = sysConfigDao.findByParamName(SysConfigService.VISITOR_DEFAULT_AVATAR).getParanValue();
 | 
	
		
			
				|  |  | +        userInfo.setAvatar(Optional.ofNullable(defaultAvatar).orElse(""));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 记录直播间用户信息
 | 
	
		
			
				|  |  | +        ImLiveBroadcastRoomMember roomMember = new ImLiveBroadcastRoomMember();
 | 
	
		
			
				|  |  | +        roomMember.setTenantId(userInfo.getTenantId());
 | 
	
		
			
				|  |  | +        roomMember.setRoomUid(imLiveBroadcastRoomVo.getRoomUid());
 | 
	
		
			
				|  |  | +        roomMember.setUserId(userInfo.getUserId());
 | 
	
		
			
				|  |  | +        roomMember.setJoinTime(DateTime.now().toDate());
 | 
	
		
			
				|  |  | +        roomMember.setTotalTime(0);
 | 
	
		
			
				|  |  | +        roomMember.setOnlineStatus(1);
 | 
	
		
			
				|  |  | +        roomMember.setBanStatus(0);
 | 
	
		
			
				|  |  | +        roomMember.setLiveRoomStatus(1);
 | 
	
		
			
				|  |  | +        roomMember.setFingerprint(fingerprint);
 | 
	
		
			
				|  |  | +        roomMember.setVisitorName(userInfo.getUserName());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 保存直播间用户信息
 | 
	
		
			
				|  |  | +        liveBroadcastRoomMemberService.save(roomMember);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return userInfo;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  |       * 发送黑名单进入消息
 | 
	
		
			
				|  |  |       * @param userId 用户id
 | 
	
		
			
				|  |  |       */
 | 
	
	
		
			
				|  | @@ -1462,18 +1714,21 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          String fromUserid = setFromUserId(userId.toString(),roomVo);
 | 
	
		
			
				|  |  |          // 消息发送用户
 | 
	
		
			
				|  |  |          LiveRoomMessage.MessageUser messageUser = null;
 | 
	
		
			
				|  |  | -        SysUser sysUser = sysUserFeignService.queryUserById(userId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 直播间访问用户信息
 | 
	
		
			
				|  |  | +        SysUser sysUser = getRoomSysUser(userId, roomUid);
 | 
	
		
			
				|  |  |          if (Objects.nonNull(sysUser)) {
 | 
	
		
			
				|  |  |              // 发送用户信息
 | 
	
		
			
				|  |  |              messageUser = LiveRoomMessage.MessageUser
 | 
	
		
			
				|  |  | -                .builder()
 | 
	
		
			
				|  |  | -                .sendUserId(sysUser.getId().toString())
 | 
	
		
			
				|  |  | -                .sendUserName(sysUser.getUsername())
 | 
	
		
			
				|  |  | -                .avatarUrl(sysUser.getAvatar())
 | 
	
		
			
				|  |  | -                .blackFlag(true)
 | 
	
		
			
				|  |  | -                .build();
 | 
	
		
			
				|  |  | +                    .builder()
 | 
	
		
			
				|  |  | +                    .sendUserId(sysUser.getId().toString())
 | 
	
		
			
				|  |  | +                    .sendUserName(sysUser.getUsername())
 | 
	
		
			
				|  |  | +                    .avatarUrl(sysUser.getAvatar())
 | 
	
		
			
				|  |  | +                    .blackFlag(true)
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          LiveRoomMessage.MessageContent messageContent = LiveRoomMessage.MessageContent
 | 
	
		
			
				|  |  |              .builder()
 | 
	
		
			
				|  |  |              .sendUserInfo(messageUser)
 | 
	
	
		
			
				|  | @@ -1492,23 +1747,53 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |              livePluginContext.getPluginService(roomVo.getServiceProvider()).sendChatRoomMessage(message);
 | 
	
		
			
				|  |  |              log.info("sendBlackJoinRoom>>>> message: {}", JSONObject.toJSONString(message));
 | 
	
		
			
				|  |  |          } catch (Exception e) {
 | 
	
		
			
				|  |  | -            log.error("sendBlackJoinRoom>>>> error {}", e.getMessage());
 | 
	
		
			
				|  |  |              log.error("sendBlackJoinRoom>>>> sendMessage {} :", JSONObject.toJSONString(message));
 | 
	
		
			
				|  |  | +            log.error("sendBlackJoinRoom>>>> error", e);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 直播间访问用户信息
 | 
	
		
			
				|  |  | +     * @param userId 用户编号
 | 
	
		
			
				|  |  | +     * @param roomUid 直播间编号
 | 
	
		
			
				|  |  | +     * @return SysUser
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private SysUser getRoomSysUser(Integer userId, String roomUid) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        SysUser sysUser = null;
 | 
	
		
			
				|  |  | +        // 直播间游客或学生用户匹配
 | 
	
		
			
				|  |  | +        RBucket<RoomUserInfoVo> visitorInfoCache = getRoomVisitorInfoCache(roomUid, userId.toString());
 | 
	
		
			
				|  |  | +        if (getRoomVisitorInfoCache(roomUid, userId.toString()).isExists()) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 游客身份信息
 | 
	
		
			
				|  |  | +            RoomUserInfoVo userInfoVo = visitorInfoCache.get();
 | 
	
		
			
				|  |  | +            if (Objects.nonNull(userInfoVo)) {
 | 
	
		
			
				|  |  | +                sysUser = new SysUser();
 | 
	
		
			
				|  |  | +                sysUser.setId(userInfoVo.getUserId());
 | 
	
		
			
				|  |  | +                sysUser.setUsername(userInfoVo.getUserName());
 | 
	
		
			
				|  |  | +                sysUser.setAvatar(userInfoVo.getAvatar());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 登录用户信息
 | 
	
		
			
				|  |  | +            sysUser = sysUserFeignService.queryUserById(userId);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return sysUser;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 获取直播间用户信息
 | 
	
		
			
				|  |  |       * @param userId 用户id
 | 
	
		
			
				|  |  |       * @param imLiveBroadcastRoomVo 直播间信息
 | 
	
		
			
				|  |  | -     * @param now 当前时间
 | 
	
		
			
				|  |  |       * @return RoomUserInfoVo
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @NotNull
 | 
	
		
			
				|  |  | -    private RoomUserInfoVo getLiveRoomUserInfo(Integer userId, ImLiveBroadcastRoomVo imLiveBroadcastRoomVo, Date now) {
 | 
	
		
			
				|  |  | +    private RoomUserInfoVo getLiveRoomUserInfo(Integer userId, ImLiveBroadcastRoomVo imLiveBroadcastRoomVo) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          RoomUserInfoVo userInfo = getUserInfo(userId);
 | 
	
		
			
				|  |  | -        userInfo.setFirstJoinTime(now);
 | 
	
		
			
				|  |  | +        userInfo.setFirstJoinTime(DateTime.now().toDate());
 | 
	
		
			
				|  |  |          userInfo.setTotalViewTime(0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 记录直播间用户信息
 | 
	
	
		
			
				|  | @@ -2087,18 +2372,20 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 直播间统计数据
 | 
	
		
			
				|  |  | +     * 观看数、点赞数,在线人数
 | 
	
		
			
				|  |  | +     * @param roomVo ImLiveBroadcastRoomVo
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  |      private void getRoomData(ImLiveBroadcastRoomVo roomVo) {
 | 
	
		
			
				|  |  | -        //点赞数
 | 
	
		
			
				|  |  | -        Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomVo.getRoomUid())).get();
 | 
	
		
			
				|  |  | -        if (Objects.isNull(like)) {
 | 
	
		
			
				|  |  | -            like = 0;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        like = syncLikeCount(roomVo.getRoomUid());
 | 
	
		
			
				|  |  | +        // 同步点赞数
 | 
	
		
			
				|  |  | +        int likeNums = syncLikeCount(roomVo.getRoomUid());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        roomVo.setLikeNum((int) like);
 | 
	
		
			
				|  |  | +        roomVo.setLikeNum(likeNums);
 | 
	
		
			
				|  |  |          roomVo.setTotalLookNum(0);
 | 
	
		
			
				|  |  |          roomVo.setLookNum(0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          //累计总用户数量
 | 
	
		
			
				|  |  |          // roomVo.setTotalLookNum(getNum.apply(this::getTotalUserCache, roomVo.getRoomUid()));
 | 
	
		
			
				|  |  |          // //在房间观看用户数量
 | 
	
	
		
			
				|  | @@ -2606,24 +2893,24 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |       * 同步直播间点赞数
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * @param roomUid 直播间uid
 | 
	
		
			
				|  |  | -     * @return
 | 
	
		
			
				|  |  | +     * @return int
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    @Transactional
 | 
	
		
			
				|  |  |      public int syncLikeCount(String roomUid) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 直播间信息
 | 
	
		
			
				|  |  |          ImLiveBroadcastRoomVo room = getImLiveBroadcastRoomVo(roomUid);
 | 
	
		
			
				|  |  |          if (room == null) {
 | 
	
		
			
				|  |  |              return 0;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        // 融云直播间
 | 
	
		
			
				|  |  |          if (room.getServiceProvider().equals(RongCloudLivePlugin.PLUGIN_NAME)) {
 | 
	
		
			
				|  |  |              //点赞数
 | 
	
		
			
				|  |  | -            Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).get();
 | 
	
		
			
				|  |  | -            if (Objects.isNull(like)) {
 | 
	
		
			
				|  |  | -                like = 0;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return (int) like;
 | 
	
		
			
				|  |  | +            return (int) Optional.ofNullable(redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).get()).orElse(0);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 腾讯云直播
 | 
	
		
			
				|  |  |          LivePluginService pluginService = livePluginContext.getPluginService(room.getServiceProvider());
 | 
	
		
			
				|  |  |          List<TencentWrapper.ChatRoomGroupCounter> chatRoomGroupCounters = null;
 | 
	
		
			
				|  |  |          try {
 | 
	
	
		
			
				|  | @@ -2648,6 +2935,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |                                                                        .eq(ImLiveBroadcastRoomData::getRoomUid, roomUid)
 | 
	
		
			
				|  |  |                                                                        .last("limit 1")
 | 
	
		
			
				|  |  |                                                                        .one();
 | 
	
		
			
				|  |  | +            // 同步点赞数
 | 
	
		
			
				|  |  |              if (one != null) {
 | 
	
		
			
				|  |  |                  ImLiveBroadcastRoomData imLiveBroadcastRoomData = new ImLiveBroadcastRoomData();
 | 
	
		
			
				|  |  |                  imLiveBroadcastRoomData.setId(one.getId());
 | 
	
	
		
			
				|  | @@ -2735,6 +3023,16 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 | 
	
		
			
				|  |  |          return redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId).replace(ROOM_UID, roomUid));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 直播间游客信息
 | 
	
		
			
				|  |  | +     * @param roomUid 直播间编号
 | 
	
		
			
				|  |  | +     * @param userId 游客编号
 | 
	
		
			
				|  |  | +     * @return RBucket<RoomUserInfoVo>
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private RBucket<RoomUserInfoVo> getRoomVisitorInfoCache(String roomUid, String userId) {
 | 
	
		
			
				|  |  | +        return redissonClient.getBucket(LIVE_VISITOR_INFO.replace(USER_ID, userId).replace(ROOM_UID, roomUid));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private RoomUserInfoVo getUserInfo(Integer userId) {
 | 
	
		
			
				|  |  |          RoomUserInfoVo userInfo = new RoomUserInfoVo();
 | 
	
		
			
				|  |  |          userInfo.setUserId(userId);
 |