|
|
@@ -0,0 +1,980 @@
|
|
|
+package com.ym.mec.biz.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.fasterxml.jackson.annotation.JsonFormat;
|
|
|
+import com.ym.mec.auth.api.client.SysUserFeignService;
|
|
|
+import com.ym.mec.auth.api.entity.SysUser;
|
|
|
+import com.ym.mec.biz.dal.dao.ImLiveBroadcastRoomDao;
|
|
|
+import com.ym.mec.biz.dal.dao.SysConfigDao;
|
|
|
+import com.ym.mec.biz.dal.dto.ImLiveBroadcastRoomDto;
|
|
|
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoom;
|
|
|
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomData;
|
|
|
+import com.ym.mec.biz.dal.entity.ImLiveBroadcastRoomMember;
|
|
|
+import com.ym.mec.biz.dal.enums.MessageTypeEnum;
|
|
|
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo;
|
|
|
+import com.ym.mec.biz.dal.vo.RoomUserInfoVo;
|
|
|
+import com.ym.mec.biz.service.*;
|
|
|
+import com.ym.mec.common.entity.ImRoomMessage;
|
|
|
+import com.ym.mec.common.entity.ImUserState;
|
|
|
+import com.ym.mec.common.exception.BizException;
|
|
|
+import com.ym.mec.common.page.PageInfo;
|
|
|
+import com.ym.mec.common.page.PageUtil;
|
|
|
+import com.ym.mec.common.page.WrapperUtil;
|
|
|
+import com.ym.mec.common.tenant.TenantContextHolder;
|
|
|
+import com.ym.mec.im.ImFeignService;
|
|
|
+import com.ym.mec.util.date.DateUtil;
|
|
|
+import com.ym.mec.util.http.HttpUtil;
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.redisson.api.RBucket;
|
|
|
+import org.redisson.api.RMap;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.io.Serializable;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.BiConsumer;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 直播房间管理表(ImLiveBroadcastRoom)表服务实现类
|
|
|
+ *
|
|
|
+ * @author hgw
|
|
|
+ * @since 2022-02-17 20:52:05
|
|
|
+ */
|
|
|
+@Service("imLiveBroadcastRoomService")
|
|
|
+public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastRoomDao, ImLiveBroadcastRoom> implements ImLiveBroadcastRoomService {
|
|
|
+
|
|
|
+ private final static Logger log = LoggerFactory.getLogger(ImLiveBroadcastRoomServiceImpl.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserFeignService sysUserFeignService;
|
|
|
+ @Autowired
|
|
|
+ private ImFeignService imFeignService;
|
|
|
+ @Autowired
|
|
|
+ private RedissonClient redissonClient;
|
|
|
+ @Autowired
|
|
|
+ private SysMessageService sysMessageService;
|
|
|
+ @Autowired
|
|
|
+ private SysConfigDao sysConfigDao;
|
|
|
+ @Autowired
|
|
|
+ private ImLiveBroadcastRoomMemberService liveBroadcastRoomMemberService;
|
|
|
+ @Autowired
|
|
|
+ private ImLiveBroadcastRoomDataService liveBroadcastRoomDataService;
|
|
|
+
|
|
|
+ public static final String USER_ID = "${userId}";
|
|
|
+ public static final String ROOM_UID = "${roomUid}";
|
|
|
+
|
|
|
+ //直播间累计用户信息-指只要进入到该房间的用户都要记录
|
|
|
+ public static final String LIVE_ROOM_TOTAL_USER_LIST = "IM:LIVE_ROOM_TOTAL_USER_LIST:" + ROOM_UID;
|
|
|
+ //主讲人信息
|
|
|
+ public static final String LIVE_SPEAKER_INFO = "IM:LIVE_SPEAKER_INFO:" + USER_ID;
|
|
|
+ //用户对应的直播间Uid
|
|
|
+ public static final String LIVE_USER_ROOM = "IM:LIVE_ROOM_USER:" + USER_ID;
|
|
|
+ //房间点赞数
|
|
|
+ public static final String LIVE_ROOM_LIKE = "IM:LIVE_ROOM_LIKE:" + ROOM_UID;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 进入直播间检查数据
|
|
|
+ *
|
|
|
+ * @param roomUid 房间uid
|
|
|
+ * @param userId 用户id
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ImLiveBroadcastRoomVo queryRoomAndCheck(String roomUid, Integer userId) {
|
|
|
+ SysUser sysUser;
|
|
|
+ if (Objects.isNull(userId)) {
|
|
|
+ sysUser = getSysUser();
|
|
|
+ } else {
|
|
|
+ sysUser = getSysUser(userId);
|
|
|
+ }
|
|
|
+ return queryRoomAndCheck(roomUid, sysUser);
|
|
|
+ }
|
|
|
+
|
|
|
+ public ImLiveBroadcastRoomVo queryRoomAndCheck(String roomUid, SysUser sysUser) {
|
|
|
+ //直播间信息校验
|
|
|
+ Optional<ImLiveBroadcastRoomVo> optional = Optional.ofNullable(roomUid)
|
|
|
+ .map(this::queryRoomInfo);
|
|
|
+ optional.orElseThrow(() -> new BizException("直播间不存在"));
|
|
|
+ optional.filter(r -> r.getTenantId().equals(sysUser.getTenantId()))
|
|
|
+ .orElseThrow(() -> new BizException("您不是该直播机构人员,不可观看!"));
|
|
|
+ optional.filter(r -> r.getRoomState() != 1).orElseThrow(() -> new BizException("直播间不存在"));
|
|
|
+ ImLiveBroadcastRoomVo room = optional.get();
|
|
|
+ if (room.getLiveState() == 0) {
|
|
|
+ throw new BizException("直播未开始,直播开启的时间是 "
|
|
|
+ + DateUtil.format(room.getLiveStartTime(), DateUtil.EXPANDED_DATE_TIME_FORMAT));
|
|
|
+ }
|
|
|
+ if (room.getLiveState() == 2) {
|
|
|
+ throw new BizException("直播已结束!");
|
|
|
+ }
|
|
|
+ return room;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询直播间信息
|
|
|
+ *
|
|
|
+ * @param roomUid 直播间uid
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ImLiveBroadcastRoomVo queryRoomInfo(String roomUid) {
|
|
|
+ List<ImLiveBroadcastRoomVo> list = baseMapper.queryPage(new HashMap<String, Object>() {{
|
|
|
+ put("roomUid", roomUid);
|
|
|
+ }});
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ ImLiveBroadcastRoomVo roomVo = list.get(0);
|
|
|
+ getRoomData(roomVo);
|
|
|
+ return roomVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询直播间列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public PageInfo<ImLiveBroadcastRoomVo> queryPage(Map<String, Object> param) {
|
|
|
+ Page<ImLiveBroadcastRoomVo> pageInfo = PageUtil.getPageInfo(param);
|
|
|
+ pageInfo.setDesc("a.created_time_");
|
|
|
+ param.put("tenantId", TenantContextHolder.getTenantId());
|
|
|
+ BiConsumer<String, String> addTimeCons = (key, time) -> Optional.ofNullable(param.get(key)).map(String::valueOf)
|
|
|
+ .ifPresent(date -> param.put(key, date + " " + time));
|
|
|
+ addTimeCons.accept("startTime", "00:00:00");
|
|
|
+ addTimeCons.accept("endTime", "23:59:59");
|
|
|
+ IPage<ImLiveBroadcastRoomVo> page = baseMapper.queryPage(pageInfo, param);
|
|
|
+ return PageUtil.pageInfo(page);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 预创建直播间
|
|
|
+ *
|
|
|
+ * @param dto 直播间信息
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void add(ImLiveBroadcastRoomDto dto) {
|
|
|
+ SysUser sysUser = getSysUser(dto.getSpeakerId());
|
|
|
+ ImLiveBroadcastRoom obj = new ImLiveBroadcastRoom();
|
|
|
+ BeanUtils.copyProperties(dto, obj);
|
|
|
+ Date now = new Date();
|
|
|
+ String roomUid = "LIVE-" + sysUser.getId() + "-" + now.getTime();
|
|
|
+ obj.setTenantId(TenantContextHolder.getTenantId());
|
|
|
+ obj.setRoomUid(roomUid);
|
|
|
+ obj.setRoomConfig(JSONObject.toJSONString(dto.getRoomConfig()));
|
|
|
+ obj.setLiveState(0);
|
|
|
+ obj.setRoomState(0);
|
|
|
+ obj.setCreatedBy(getSysUser().getId());
|
|
|
+ obj.setCreatedTime(now);
|
|
|
+ this.save(obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改直播间信息
|
|
|
+ *
|
|
|
+ * @param dto
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void update(ImLiveBroadcastRoomDto dto) {
|
|
|
+ ImLiveBroadcastRoom obj = this.getById(dto.getId());
|
|
|
+ BeanUtils.copyProperties(dto, obj);
|
|
|
+ obj.setRoomConfig(JSONObject.toJSONString(dto.getRoomConfig()));
|
|
|
+ obj.setUpdatedBy(getSysUser().getId());
|
|
|
+ obj.setUpdatedTime(new Date());
|
|
|
+ log.info("update room >>> :{}", JSONObject.toJSONString(obj));
|
|
|
+ this.updateById(obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否禁言
|
|
|
+ *
|
|
|
+ * @param id 房间id
|
|
|
+ * @param whetherChat 是否允许聊天互动 0允许 1不允许
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void whetherChat(Integer id, Integer whetherChat) {
|
|
|
+ ImLiveBroadcastRoom obj = this.getById(id);
|
|
|
+ ImLiveBroadcastRoomDto.RoomConfig roomConfig = getRoomConfig(obj.getRoomConfig()).orElse(null);
|
|
|
+ if (Objects.isNull(roomConfig)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ roomConfig.setWhether_chat(whetherChat);
|
|
|
+ obj.setRoomConfig(JSONObject.toJSONString(roomConfig));
|
|
|
+ this.updateById(obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除直播间
|
|
|
+ *
|
|
|
+ * @param id 直播间id
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void delete(Integer id) {
|
|
|
+ ImLiveBroadcastRoom obj = this.getById(id);
|
|
|
+ if (obj.getLiveState() == 1) {
|
|
|
+ throw new BizException("直播已经开始,无法删除");
|
|
|
+ }
|
|
|
+ obj.setId(id);
|
|
|
+ obj.setRoomState(1);
|
|
|
+ obj.setUpdatedBy(getSysUser().getId());
|
|
|
+ obj.setUpdatedTime(new Date());
|
|
|
+ this.updateById(obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 定时任务,每分钟执行
|
|
|
+ * 销毁主讲人退出超过30分钟的直播间
|
|
|
+ */
|
|
|
+ public void destroyExpiredLiveRoom() {
|
|
|
+ //查询已经开始并且没有删除及销毁的直播间
|
|
|
+ List<ImLiveBroadcastRoom> list = this.list(new WrapperUtil<ImLiveBroadcastRoom>()
|
|
|
+ .hasEq("live_state_", 1)
|
|
|
+ .hasEq("room_state_", 0)
|
|
|
+ .queryWrapper());
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //查询房间过期时间
|
|
|
+ String expiredMinuteStr = sysConfigDao.findConfigValue("destroy_expired_live_room_minute");
|
|
|
+ if (StringUtils.isEmpty(expiredMinuteStr)) {
|
|
|
+ log.info("roomDestroy>>>> 未查询到配置:destroy_expired_live_room_minute");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int expiredMinute = Integer.parseInt(expiredMinuteStr);
|
|
|
+ Date now = new Date();
|
|
|
+ list.forEach(room -> {
|
|
|
+ try {
|
|
|
+ destroyExpiredLiveRoom(now, room, expiredMinute);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("roomDestroy>>>> failed roomId:{} msg:{}", room.getId(), e.getMessage());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void destroyExpiredLiveRoom(Date now, ImLiveBroadcastRoom room, int expiredMinute) {
|
|
|
+ log.error("roomDestroy destroyExpiredLiveRoom >>>> now {} roomInfo : {} expiredMinute:{}", now, JSONObject.toJSONString(room), expiredMinute);
|
|
|
+ //获取直播间主讲人信息
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString()));
|
|
|
+ if (speakerCache.isExists()) {
|
|
|
+ RoomSpeakerInfo speakerInfo = speakerCache.get();
|
|
|
+ //过期时间= 房间正式开始时间+expiredMinute 分钟
|
|
|
+ Date expiredTime = DateUtil.addMinutes(room.getCreatedTime(), expiredMinute);
|
|
|
+ //先决条件 当前时间 大于(创建房间时填入的开播时间 + 设置的过期分钟数)
|
|
|
+ if (now.getTime() >= expiredTime.getTime()) {
|
|
|
+
|
|
|
+ //1.主播没有进入房间,则直接销毁房间
|
|
|
+ if (Objects.isNull(speakerInfo.getJoinRoomTime())) {
|
|
|
+ log.info("roomDestroy not joinRoom >>>> cache : {}", JSONObject.toJSONString(test(room.getRoomUid(), room.getSpeakerId())));
|
|
|
+ roomDestroy(room);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //如果主播已经进入了房间 就判断是否退出过房间
|
|
|
+ if (Objects.nonNull(speakerInfo.getExitRoomTime())) {
|
|
|
+ //如果退出过房间 判断退出时间是否大于进入时间
|
|
|
+ if (speakerInfo.getExitRoomTime().getTime() > speakerInfo.getJoinRoomTime().getTime()) {
|
|
|
+ //如果退出时间大于进入时间,就将退出时间+expiredMinute分钟
|
|
|
+ Date exitExpiredTime = DateUtil.addMinutes(speakerInfo.getExitRoomTime(), expiredMinute);
|
|
|
+ if (now.getTime() >= exitExpiredTime.getTime()) {
|
|
|
+ log.info("roomDestroy exitExpiredTime >>>> cache : {}", JSONObject.toJSONString(test(room.getRoomUid(), room.getSpeakerId())));
|
|
|
+ roomDestroy(room);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭房间-融云
|
|
|
+ * 获取所有直播间缓存数据并写入数据库后并清理缓存
|
|
|
+ *
|
|
|
+ * @param id 直播房间表id
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void roomDestroy(Integer id) {
|
|
|
+ ImLiveBroadcastRoom room = this.getById(id);
|
|
|
+ if (Objects.isNull(room)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (room.getLiveState() == 0) {
|
|
|
+ throw new BizException("直播未开始");
|
|
|
+ }
|
|
|
+ roomDestroy(room);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void roomDestroy(ImLiveBroadcastRoom room) {
|
|
|
+ log.error("roomDestroy>>>> room : {}", JSONObject.toJSONString(room));
|
|
|
+ String roomUid = room.getRoomUid();
|
|
|
+ Integer speakerId = room.getSpeakerId();
|
|
|
+
|
|
|
+ try {
|
|
|
+ //向聊天室发自定义消息踢出所有人
|
|
|
+ ImRoomMessage message = new ImRoomMessage();
|
|
|
+ message.setFromUserId(speakerId.toString());
|
|
|
+ message.setToChatroomId(roomUid);
|
|
|
+ message.setObjectName(ImRoomMessage.FORCED_OFFLINE);
|
|
|
+ imFeignService.publishRoomMsg(message);
|
|
|
+ log.info("roomDestroy>>>> FORCED_OFFLINE {}", JSONObject.toJSONString(message));
|
|
|
+ //销毁直播间
|
|
|
+ imFeignService.destroyLiveRoom(roomUid);
|
|
|
+ log.info("roomDestroy>>>> destroyLiveRoom {}", JSONObject.toJSONString(message));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("roomDestroy>>>> errorMsg{}", e.getMessage(), e.getCause());
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取所有直播间缓存数据并写入数据库后并清理缓存
|
|
|
+ insertAndCleanLiveData(roomUid, speakerId);
|
|
|
+ log.info("roomDestroy>>>> insertAndCleanLiveData {}", JSONObject.toJSONString(room));
|
|
|
+
|
|
|
+ //将房间状态改为已销毁
|
|
|
+ Date date = new Date();
|
|
|
+ room.setRoomState(2);
|
|
|
+ room.setLiveState(2);
|
|
|
+ Integer userId = -1;
|
|
|
+ try {
|
|
|
+ userId = getSysUser().getId();
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ }
|
|
|
+ room.setUpdatedBy(userId);
|
|
|
+ room.setUpdatedTime(date);
|
|
|
+ room.setLiveEndTime(date);
|
|
|
+ this.updateById(room);
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取该直播间所有数据写入数据库-并清理缓存
|
|
|
+ private void insertAndCleanLiveData(String roomUid, Integer speakerId) {
|
|
|
+ //总观看人数
|
|
|
+ int totalLookNum = 0;
|
|
|
+ //获取直播间所有人数据写入 im_live_broadcast_room_member
|
|
|
+ RMap<Integer, RoomUserInfoVo> roomTotalUserCache = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
|
|
|
+ if (roomTotalUserCache.isExists()) {
|
|
|
+ List<RoomUserInfoVo> roomTotalUser = new ArrayList<>(roomTotalUserCache.values());
|
|
|
+ List<ImLiveBroadcastRoomMember> memberList = new ArrayList<>();
|
|
|
+ roomTotalUser.forEach(v -> {
|
|
|
+ ImLiveBroadcastRoomMember member = new ImLiveBroadcastRoomMember();
|
|
|
+ member.setTenantId(v.getTenantId());
|
|
|
+ member.setRoomUid(roomUid);
|
|
|
+ member.setUserId(v.getUserId());
|
|
|
+ member.setJoinTime(v.getFirstJoinTime());
|
|
|
+ member.setTotalTime(v.getTotalViewTime());
|
|
|
+ memberList.add(member);
|
|
|
+ });
|
|
|
+ if (CollectionUtils.isNotEmpty(memberList)) {
|
|
|
+ liveBroadcastRoomMemberService.getDao().insertBatch(memberList);
|
|
|
+ totalLookNum = roomTotalUser.size();
|
|
|
+ }
|
|
|
+ //删除用户对应的直播间关系缓存
|
|
|
+ roomTotalUser.stream()
|
|
|
+ .map(RoomUserInfoVo::getUserId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .forEach(id -> redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, id.toString())).delete());
|
|
|
+ //删除直播间所有人数据
|
|
|
+ roomTotalUserCache.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取直播点赞
|
|
|
+ int like = 0;
|
|
|
+ RBucket<Object> likeCache = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid));
|
|
|
+ if (likeCache.isExists()) {
|
|
|
+ like = (int) likeCache.get();
|
|
|
+ //删除房间点赞数据
|
|
|
+ likeCache.delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取直播间主讲人信息 写入im_live_broadcast_room_data
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, speakerId.toString()));
|
|
|
+ if (speakerCache.isExists()) {
|
|
|
+ ImLiveBroadcastRoomData liveData = new ImLiveBroadcastRoomData();
|
|
|
+ RoomSpeakerInfo speakerInfo = speakerCache.get();
|
|
|
+ liveData.setTenantId(speakerInfo.getTenantId());
|
|
|
+ liveData.setRoomUid(roomUid);
|
|
|
+ liveData.setLikeNum(like);
|
|
|
+ liveData.setTotalUserNum(totalLookNum);
|
|
|
+ liveData.setUpdatedTime(new Date());
|
|
|
+ liveData.setLiveTime(speakerInfo.getTotalLiveTime());
|
|
|
+ liveBroadcastRoomDataService.save(liveData);
|
|
|
+ //删除房间主讲人数据
|
|
|
+ speakerCache.delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步点赞数量
|
|
|
+ *
|
|
|
+ * @param roomUid 房间uid
|
|
|
+ * @param likeNum 点赞数
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void syncLike(String roomUid, Integer likeNum) {
|
|
|
+ redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).set(likeNum);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <p>主讲人处理进入和退出房间数据
|
|
|
+ * <p>观看者只处理退出房间数据
|
|
|
+ *
|
|
|
+ * @param userState 用户状态数据
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void opsRoom(List<ImUserState> userState) {
|
|
|
+ if (CollectionUtils.isEmpty(userState)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ userState.forEach(user -> {
|
|
|
+ log.info("opsRoom>>>> {}", JSONObject.toJSONString(user));
|
|
|
+ if (StringUtils.isBlank(user.getStatus())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Date now = new Date();
|
|
|
+ //查询主讲人userId,若是主讲人
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, user.getUserid()));
|
|
|
+ if (speakerCache.isExists()) {
|
|
|
+ RoomSpeakerInfo speakerInfo = speakerCache.get();
|
|
|
+ //主讲人进入房间
|
|
|
+ if (user.getStatus().equals("0")) {
|
|
|
+ speakerInfo.setJoinRoomTime(now);
|
|
|
+ log.info("opsRoom>>>> join speakerCache {}", JSONObject.toJSONString(speakerInfo));
|
|
|
+ speakerCache.set(speakerInfo);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //主讲人退出房间关闭录像
|
|
|
+ closeLive(speakerInfo);
|
|
|
+ speakerInfo.setExitRoomTime(now);
|
|
|
+ log.info("opsRoom>>>> exit speakerCache {}", JSONObject.toJSONString(speakerInfo));
|
|
|
+ speakerCache.set(speakerInfo);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //未查询到主讲人信息,观看者只接受退出消息 status=0 是进入房间
|
|
|
+ if (user.getStatus().equals("0")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //获取当前用户所在房间的uid
|
|
|
+ RBucket<String> userRoom = redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, user.getUserid()));
|
|
|
+ if (!userRoom.isExists()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String roomUid = userRoom.get();
|
|
|
+ Integer userId = Integer.valueOf(user.getUserid());
|
|
|
+
|
|
|
+ //从房间累计用户信息中查询该用户的信息
|
|
|
+ RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
|
|
|
+ //该房间未查询到用户数据则不处理
|
|
|
+ if (!roomTotalUser.isExists() && !roomTotalUser.containsKey(userId)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //查询到用户数据
|
|
|
+ RoomUserInfoVo userInfo = roomTotalUser.get(userId);
|
|
|
+ //用户是在房间的状态 并且 突然离线 - 那么融云会发送用户离线消息-此刻就发送退出房间消息给主讲人
|
|
|
+ if (userInfo.getState() == 0 && user.getStatus().equals("1")) {
|
|
|
+ ImRoomMessage message = new ImRoomMessage();
|
|
|
+ message.setFromUserId(userId.toString());
|
|
|
+ message.setToChatroomId(roomUid);
|
|
|
+ message.setObjectName(ImRoomMessage.LOOKER_LOGIN_OUT);
|
|
|
+ try {
|
|
|
+ imFeignService.publishRoomMsg(message);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("opsRoom>>>> looker error {}", e.getMessage());
|
|
|
+ log.error("opsRoom>>>> looker error sendMessage {} : LOOKER_LOGIN_OUT : {}", message, JSONObject.toJSONString(userInfo));
|
|
|
+ }
|
|
|
+ log.info("opsRoom>>>> looker LOOKER_LOGIN_OUT : {}", JSONObject.toJSONString(userInfo));
|
|
|
+ }
|
|
|
+ //每次退出房间计算当前用户观看时长
|
|
|
+ int minutesBetween = getMinutesBetween(userInfo.getDynamicJoinTime(), now);
|
|
|
+ userInfo.setTotalViewTime(userInfo.getTotalViewTime() + minutesBetween);
|
|
|
+ //记录退出时间 并写入缓存
|
|
|
+ userInfo.setLastOutTime(now);
|
|
|
+ userInfo.setState(1);
|
|
|
+ roomTotalUser.fastPut(userId, userInfo);
|
|
|
+ log.info("opsRoom>>>> looker userInfo: {}", JSONObject.toJSONString(userInfo));
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 主讲人登录专用
|
|
|
+ *
|
|
|
+ * @param roomUid
|
|
|
+ */
|
|
|
+ public ImLiveBroadcastRoomVo speakerJoinRoom(String roomUid) {
|
|
|
+ SysUser sysUser = getSysUser();
|
|
|
+ ImLiveBroadcastRoomVo roomVo = queryRoomAndCheck(roomUid, sysUser);
|
|
|
+ Integer userId = sysUser.getId();
|
|
|
+ if (!userId.equals(roomVo.getSpeakerId())) {
|
|
|
+ throw new BizException("您不是该直播间的主讲人");
|
|
|
+ }
|
|
|
+ Date now = new Date();
|
|
|
+ //获取直播间信息
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
|
|
|
+ if (!speakerCache.isExists()) {
|
|
|
+ //没有主讲人信息则生成一个
|
|
|
+ createSpeakerInfo(this.getById(roomVo.getId()), sysUser);
|
|
|
+ speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
|
|
|
+ }
|
|
|
+ RoomSpeakerInfo speakerInfo = speakerCache.get();
|
|
|
+ speakerInfo.setJoinRoomTime(now);
|
|
|
+ speakerCache.set(speakerInfo);
|
|
|
+ return roomVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 进入房间-修改用户对应的房间号信息
|
|
|
+ *
|
|
|
+ * @param roomUid 房间uid
|
|
|
+ * @param userId 用户id
|
|
|
+ */
|
|
|
+ public void joinRoom(String roomUid, Integer userId) {
|
|
|
+ //记录用户当前房间uid
|
|
|
+ redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userId.toString())).set(roomUid);
|
|
|
+ //房间累计用户信息-指只要进入到该房间的用户都要记录
|
|
|
+ RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
|
|
|
+ //判断是否第一次进房间
|
|
|
+ RoomUserInfoVo userInfo;
|
|
|
+ Date now = new Date();
|
|
|
+ if (roomTotalUser.containsKey(userId)) {
|
|
|
+ //多次进入更新动态进入时间
|
|
|
+ userInfo = roomTotalUser.get(userId);
|
|
|
+ } else {
|
|
|
+ //第一次进该房间 写入用户首次进入时间
|
|
|
+ userInfo = getUserInfo(userId);
|
|
|
+ userInfo.setFirstJoinTime(now);
|
|
|
+ userInfo.setTotalViewTime(0);
|
|
|
+ }
|
|
|
+ userInfo.setState(0);//0 进入/在房间
|
|
|
+ userInfo.setDynamicJoinTime(now);
|
|
|
+ roomTotalUser.fastPut(userId, userInfo);
|
|
|
+ log.info("joinRoom>>>> userInfo: {}", JSONObject.toJSONString(userInfo));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开始直播-录像
|
|
|
+ *
|
|
|
+ * @param roomUid 房间uid
|
|
|
+ */
|
|
|
+ public void startLive(String roomUid, Integer userId) {
|
|
|
+ //查询房间信息是否允许录像
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
|
|
|
+ RoomSpeakerInfo roomSpeakerInfo = speakerCache.get();
|
|
|
+ if (Objects.nonNull(roomSpeakerInfo.getWhetherVideo()) && roomSpeakerInfo.getWhetherVideo() == 0) {
|
|
|
+ //开始录制视频
|
|
|
+ try {
|
|
|
+ imFeignService.startRecord(roomUid);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("startRecord error: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //开始直播
|
|
|
+ roomSpeakerInfo.setState(0);
|
|
|
+ roomSpeakerInfo.setStartLiveTime(new Date());
|
|
|
+ speakerCache.set(roomSpeakerInfo);
|
|
|
+ log.info("startLive>>>> roomSpeakerInfo: {}", JSONObject.toJSONString(roomSpeakerInfo));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭直播-录像
|
|
|
+ *
|
|
|
+ * @param roomUid 房间uid
|
|
|
+ */
|
|
|
+ public void closeLive(String roomUid, Integer userId) {
|
|
|
+ //查询房间主播信息
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
|
|
|
+ RoomSpeakerInfo roomSpeakerInfo = speakerCache.get();
|
|
|
+ //关闭直播
|
|
|
+ closeLive(roomSpeakerInfo);
|
|
|
+ speakerCache.set(roomSpeakerInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void closeLive(RoomSpeakerInfo roomSpeakerInfo) {
|
|
|
+ boolean stateFlag = Objects.nonNull(roomSpeakerInfo.getState()) && roomSpeakerInfo.getState() == 0;
|
|
|
+ if (Objects.nonNull(roomSpeakerInfo.getWhetherVideo()) && roomSpeakerInfo.getWhetherVideo() == 0
|
|
|
+ && stateFlag) {
|
|
|
+ //停止录制视频
|
|
|
+ try {
|
|
|
+ imFeignService.stopRecord(roomSpeakerInfo.getRoomUid());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("stopRecord error: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (stateFlag) {
|
|
|
+ Date now = new Date();
|
|
|
+ roomSpeakerInfo.setEndLiveTime(now);
|
|
|
+ roomSpeakerInfo.setState(1);
|
|
|
+ //计算时长
|
|
|
+ int minutesBetween = getMinutesBetween(roomSpeakerInfo.getStartLiveTime(), now);
|
|
|
+ int i = Objects.isNull(roomSpeakerInfo.getTotalLiveTime()) ? 0 : roomSpeakerInfo.getTotalLiveTime();
|
|
|
+ roomSpeakerInfo.setTotalLiveTime(i + minutesBetween);
|
|
|
+ }
|
|
|
+ log.info("closeLive>>>> roomSpeakerInfo: {}", JSONObject.toJSONString(roomSpeakerInfo));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 定时任务,每分钟执行
|
|
|
+ * 提前30分钟主动去融云注册并创建房间
|
|
|
+ */
|
|
|
+ public void createLiveRoom() {
|
|
|
+ Date now = new Date();
|
|
|
+ Date endTime = DateUtil.addMinutes(now, 30);
|
|
|
+ List<ImLiveBroadcastRoom> list = this.list(new WrapperUtil<ImLiveBroadcastRoom>()
|
|
|
+ .hasEq("live_state_", 0)
|
|
|
+ .hasEq("room_state_", 0)
|
|
|
+ .hasGe("live_start_time_", now)
|
|
|
+ .hasLe("live_start_time_", endTime)
|
|
|
+ .queryWrapper());
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ list.forEach(this::createLiveRoom);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 去融云创建房间
|
|
|
+ */
|
|
|
+ private void createLiveRoom(ImLiveBroadcastRoom room) {
|
|
|
+ log.info("createLiveRoom>>>>>>roomUid:{}", room.getRoomUid());
|
|
|
+ try {
|
|
|
+ //生成主讲人信息到缓存
|
|
|
+ SysUser sysUser = getSysUser(room.getSpeakerId());
|
|
|
+ createSpeakerInfo(room, sysUser);
|
|
|
+ //去融云创建房间
|
|
|
+ imFeignService.createLiveRoom(room.getRoomUid(), room.getRoomTitle());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(">>>>>>>>>> createLiveRoom error roomUid:{} msg:{}", room.getRoomUid(), e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //生成主讲人信息
|
|
|
+ private void createSpeakerInfo(ImLiveBroadcastRoom room, SysUser sysUser) {
|
|
|
+ Date now = new Date();
|
|
|
+ RoomSpeakerInfo speakerInfo = new RoomSpeakerInfo();
|
|
|
+ speakerInfo.setSpeakerId(sysUser.getId());
|
|
|
+ speakerInfo.setSpeakerName(sysUser.getRealName());
|
|
|
+ speakerInfo.setCreateRoomTime(now);
|
|
|
+ speakerInfo.setRoomUid(room.getRoomUid());
|
|
|
+ speakerInfo.setTenantId(sysUser.getTenantId());
|
|
|
+ speakerInfo.setTotalLiveTime(0);
|
|
|
+
|
|
|
+ //查询房间信息是否允许录像
|
|
|
+ ImLiveBroadcastRoom one = this.getOne(new QueryWrapper<ImLiveBroadcastRoom>().eq("room_uid_", room.getRoomUid()));
|
|
|
+ boolean video = getRoomConfig(one.getRoomConfig())
|
|
|
+ .filter(c -> Objects.nonNull(c.getWhether_video()))
|
|
|
+ .map(c -> c.getWhether_video() == 0)
|
|
|
+ .orElse(false);
|
|
|
+ if (video) {
|
|
|
+ //可以录制视频
|
|
|
+ speakerInfo.setWhetherVideo(0);
|
|
|
+ } else {
|
|
|
+ //不可以录制视频
|
|
|
+ speakerInfo.setWhetherVideo(1);
|
|
|
+ }
|
|
|
+ //写入主讲人信息
|
|
|
+ redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString())).set(speakerInfo);
|
|
|
+
|
|
|
+ //生成0点赞
|
|
|
+ redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, room.getRoomUid())).set(0);
|
|
|
+
|
|
|
+ //修改房间状态为开始
|
|
|
+ room.setLiveState(1);
|
|
|
+ room.setUpdatedTime(now);
|
|
|
+ room.setUpdatedBy(-2);
|
|
|
+ baseMapper.updateById(room);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Optional<ImLiveBroadcastRoomDto.RoomConfig> getRoomConfig(String roomConfig) {
|
|
|
+ return Optional.ofNullable(roomConfig)
|
|
|
+ .map(c -> JSON.parseObject(c, ImLiveBroadcastRoomDto.RoomConfig.class));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void getRoomData(ImLiveBroadcastRoomVo roomVo) {
|
|
|
+ //点赞数
|
|
|
+ Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomVo.getRoomUid())).get();
|
|
|
+ if (Objects.isNull(like)) {
|
|
|
+ like = 0;
|
|
|
+ }
|
|
|
+ roomVo.setLikeNum((int) like);
|
|
|
+ //累计总用户数量
|
|
|
+ List<RoomUserInfoVo> roomUserInfoVos = queryTotalRoomUserInfo(roomVo.getRoomUid());
|
|
|
+ if (CollectionUtils.isNotEmpty(roomUserInfoVos)) {
|
|
|
+ roomVo.setTotalLookNum(roomUserInfoVos.size());
|
|
|
+ //在房间观看用户数量
|
|
|
+ roomVo.setLookNum(queryRoomUserInfo(roomUserInfoVos).size());
|
|
|
+ } else {
|
|
|
+ roomVo.setTotalLookNum(0);
|
|
|
+ roomVo.setLookNum(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private SysUser getSysUser(Integer userId) {
|
|
|
+ return Optional.ofNullable(userId)
|
|
|
+ .map(sysUserFeignService::queryUserById)
|
|
|
+ .orElseThrow(() -> new BizException("用户不存在"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private SysUser getSysUser() {
|
|
|
+ //修改机构基础信息
|
|
|
+ return Optional.ofNullable(sysUserFeignService.queryUserInfo())
|
|
|
+ .orElseThrow(() -> new BizException("用户不存在"));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试
|
|
|
+ */
|
|
|
+ public Map<String, Object> test(String roomUid, Integer userId) {
|
|
|
+ //test
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ //点赞数
|
|
|
+ Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomUid)).get();
|
|
|
+ if (Objects.isNull(like)) {
|
|
|
+ like = 0;
|
|
|
+ }
|
|
|
+ result.put("点赞数", like);
|
|
|
+
|
|
|
+ int totalLook = 0;
|
|
|
+ int look = 0;
|
|
|
+ List<RoomUserInfoVo> inRoomUserInfo;
|
|
|
+
|
|
|
+ //累计总观看的用户数量
|
|
|
+ List<RoomUserInfoVo> totalUserInfo = queryTotalRoomUserInfo(roomUid);
|
|
|
+ if (CollectionUtils.isNotEmpty(totalUserInfo)) {
|
|
|
+ //正在房间观看的用户数据
|
|
|
+ inRoomUserInfo = queryRoomUserInfo(totalUserInfo);
|
|
|
+ if (CollectionUtils.isNotEmpty(inRoomUserInfo)) {
|
|
|
+ look = inRoomUserInfo.size();
|
|
|
+ result.put("正在观看的人员信息", inRoomUserInfo);
|
|
|
+ } else {
|
|
|
+ result.put("正在观看的人员信息", "没有正在观看的人员数据");
|
|
|
+ }
|
|
|
+ totalLook = totalUserInfo.size();
|
|
|
+ result.put("总人员数据", totalUserInfo);
|
|
|
+ } else {
|
|
|
+ result.put("总人员数据", "没有人员数据");
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取主讲人信息
|
|
|
+ RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userId.toString()));
|
|
|
+ if (speakerCache.isExists()) {
|
|
|
+ result.put("主讲人信息", speakerCache.get());
|
|
|
+ } else {
|
|
|
+ result.put("主讲人信息", "主讲人信息不存在");
|
|
|
+ }
|
|
|
+ result.put("总观看人数", totalLook);
|
|
|
+ result.put("实时观看数", look);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void shareGroup(String roomUid, String groupIds) {
|
|
|
+ ImLiveBroadcastRoomVo imLiveBroadcastRoomVo = queryRoomInfo(roomUid);
|
|
|
+ if (imLiveBroadcastRoomVo == null) {
|
|
|
+ throw new BizException("直播间信息异常!");
|
|
|
+ }
|
|
|
+ SysUser sysUser = sysUserFeignService.queryUserInfo();
|
|
|
+ String baseApiUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
|
|
|
+ StringBuffer pushUrl = new StringBuffer(baseApiUrl).append("/#/liveClassTransfer?roomUid=").append(roomUid);
|
|
|
+ sysMessageService.batchSendImGroupMessage(MessageTypeEnum.IM_SHARE_LIVE_URL, sysUser.getId().toString(), null, groupIds.split(","), null,
|
|
|
+ imLiveBroadcastRoomVo.getTenantName(), imLiveBroadcastRoomVo.getRoomTitle(), imLiveBroadcastRoomVo.getSpeakerName(),
|
|
|
+ DateUtil.format(imLiveBroadcastRoomVo.getLiveStartTime(), DateUtil.CHINESE_DATA_FORMAT_1),
|
|
|
+ imLiveBroadcastRoomVo.getLiveRemark(), HttpUtil.getSortUrl(pushUrl.toString()));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询在观看直播的用户信息
|
|
|
+ *
|
|
|
+ * @param roomUid 直播间uid
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<RoomUserInfoVo> queryRoomUserInfo(String roomUid) {
|
|
|
+ List<RoomUserInfoVo> roomUserInfoVos = queryTotalRoomUserInfo(roomUid);
|
|
|
+ return queryRoomUserInfo(roomUserInfoVos);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<RoomUserInfoVo> queryRoomUserInfo(List<RoomUserInfoVo> totalUserInfo) {
|
|
|
+ return totalUserInfo.stream()
|
|
|
+ .filter(o -> Objects.nonNull(o.getState()) && o.getState() == 0)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<RoomUserInfoVo> queryTotalRoomUserInfo(String roomUid) {
|
|
|
+ RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
|
|
|
+ return roomTotalUser.values().stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private RoomUserInfoVo getUserInfo(Integer userId) {
|
|
|
+ RoomUserInfoVo userInfo = new RoomUserInfoVo();
|
|
|
+ userInfo.setUserId(userId);
|
|
|
+ SysUser sysUser = sysUserFeignService.queryUserById(userId);
|
|
|
+ String name = userId.toString();
|
|
|
+ if (Objects.nonNull(sysUser)) {
|
|
|
+ name = sysUser.getPhone();
|
|
|
+ if (sysUser.getUserType().contains("STUDENT")) {
|
|
|
+ name = sysUser.getUsername();
|
|
|
+ } else {
|
|
|
+ if (StringUtils.isNotBlank(sysUser.getRealName())) {
|
|
|
+ name = sysUser.getRealName();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ userInfo.setUserName(name);
|
|
|
+ userInfo.setTenantId(sysUser.getTenantId());
|
|
|
+ return userInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算时间差-分钟数不满一分钟为0
|
|
|
+ private int getMinutesBetween(Date startDT, Date endDT) {
|
|
|
+ if (Objects.isNull(startDT) || Objects.isNull(endDT)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ //课程结束时间-课程开始时间
|
|
|
+ long durationTime = endDT.getTime() - startDT.getTime();
|
|
|
+ //相差多少分钟
|
|
|
+ return new Long(durationTime / 1000 / 60).intValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 主讲人信息
|
|
|
+ */
|
|
|
+ public static class RoomSpeakerInfo implements Serializable {
|
|
|
+ //主讲人id
|
|
|
+ private Integer speakerId;
|
|
|
+ //主讲人名称
|
|
|
+ private String speakerName;
|
|
|
+ //直播状态 0 直播中 1关闭直播
|
|
|
+ private Integer state;
|
|
|
+ //房间uid
|
|
|
+ private String roomUid;
|
|
|
+ //房间创建时间
|
|
|
+ private Date createRoomTime;
|
|
|
+ //进入房间时间
|
|
|
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
|
|
+ private Date joinRoomTime;
|
|
|
+ //开始直播时间
|
|
|
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
|
|
+ private Date startLiveTime;
|
|
|
+ //开始直播时间
|
|
|
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
|
|
+ private Date endLiveTime;
|
|
|
+ //退出房间时间
|
|
|
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
|
|
+ private Date exitRoomTime;
|
|
|
+ //总直播时间
|
|
|
+ private Integer totalLiveTime = 0;
|
|
|
+ //是否录像 0允许 1不允许
|
|
|
+ private Integer whetherVideo;
|
|
|
+ //机构
|
|
|
+ private Integer tenantId;
|
|
|
+
|
|
|
+ public Integer getSpeakerId() {
|
|
|
+ return speakerId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setSpeakerId(Integer speakerId) {
|
|
|
+ this.speakerId = speakerId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getSpeakerName() {
|
|
|
+ return speakerName;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setSpeakerName(String speakerName) {
|
|
|
+ this.speakerName = speakerName;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Integer getState() {
|
|
|
+ return state;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setState(Integer state) {
|
|
|
+ this.state = state;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getRoomUid() {
|
|
|
+ return roomUid;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setRoomUid(String roomUid) {
|
|
|
+ this.roomUid = roomUid;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Date getJoinRoomTime() {
|
|
|
+ return joinRoomTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setJoinRoomTime(Date joinRoomTime) {
|
|
|
+ this.joinRoomTime = joinRoomTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Date getStartLiveTime() {
|
|
|
+ return startLiveTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setStartLiveTime(Date startLiveTime) {
|
|
|
+ this.startLiveTime = startLiveTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Integer getTotalLiveTime() {
|
|
|
+ return totalLiveTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setTotalLiveTime(Integer totalLiveTime) {
|
|
|
+ this.totalLiveTime = totalLiveTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Date getCreateRoomTime() {
|
|
|
+ return createRoomTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setCreateRoomTime(Date createRoomTime) {
|
|
|
+ this.createRoomTime = createRoomTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Date getExitRoomTime() {
|
|
|
+ return exitRoomTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setExitRoomTime(Date exitRoomTime) {
|
|
|
+ this.exitRoomTime = exitRoomTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Integer getWhetherVideo() {
|
|
|
+ return whetherVideo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setWhetherVideo(Integer whetherVideo) {
|
|
|
+ this.whetherVideo = whetherVideo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Integer getTenantId() {
|
|
|
+ return tenantId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setTenantId(Integer tenantId) {
|
|
|
+ this.tenantId = tenantId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Date getEndLiveTime() {
|
|
|
+ return endLiveTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setEndLiveTime(Date endLiveTime) {
|
|
|
+ this.endLiveTime = endLiveTime;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|