Browse Source

Merge remote-tracking branch 'origin/master_saas' into master_saas

zouxuan 3 years ago
parent
commit
cfa452f365

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Employee.java

@@ -95,6 +95,9 @@ public class Employee extends SysUser {
 	@ApiModelProperty(value = "机构id列表")
 	private List<Integer> tenantIds;
 
+	@ApiModelProperty(value = "创建该机构的人")
+    private Integer createTenantUserId;
+
 	private String contactAddress;
 
 	private String postalCode;
@@ -303,4 +306,12 @@ public class Employee extends SysUser {
     public void setTenantIds(List<Integer> tenantIds) {
         this.tenantIds = tenantIds;
     }
+
+    public Integer getCreateTenantUserId() {
+        return createTenantUserId;
+    }
+
+    public void setCreateTenantUserId(Integer createTenantUserId) {
+        this.createTenantUserId = createTenantUserId;
+    }
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/RoomUserInfoVo.java

@@ -31,6 +31,9 @@ public class RoomUserInfoVo implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date lastOutTime;
 
+    //0:在房间 1:不在房间
+    private Integer state;
+
     public Integer getUserId() {
         return userId;
     }
@@ -86,4 +89,12 @@ public class RoomUserInfoVo implements Serializable {
     public void setTenantId(Integer tenantId) {
         this.tenantId = tenantId;
     }
+
+    public Integer getState() {
+        return state;
+    }
+
+    public void setState(Integer state) {
+        this.state = state;
+    }
 }

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ImLiveBroadcastRoomService.java

@@ -33,6 +33,8 @@ public interface ImLiveBroadcastRoomService extends IService<ImLiveBroadcastRoom
 
     void delete(Integer id);
 
+    void destroyExpiredLiveRoom();
+
     void syncLike(String roomUid, Integer likeNum);
 
     void quitRoom(List<ImUserState> userState);

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ContractServiceImpl.java

@@ -1045,6 +1045,7 @@ public class ContractServiceImpl implements ContractService, InitializingBean {
         sysUserContracts.setUrl(pdfFilePath);
         sysUserContracts.setUserId(userId);
         sysUserContracts.setVersion(tenantContractTemplate.getVersion());
+        sysUserContracts.setTenantId(user.getTenantId());
 
         sysUserContractsService.insert(sysUserContracts);
 

+ 8 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/EmployeeServiceImpl.java

@@ -138,8 +138,12 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
         if (user != null) {
             employee.setAvatar(user.getAvatar());
         }
+        Integer userId = employee.getId();
+        if(Objects.nonNull(employee.getCreateTenantUserId())){
+            userId = employee.getCreateTenantUserId();
+        }
         //添加平台用户和机构的关系
-        addUserTenant(employee.getTenantIds(), tenantId, employee.getId());
+        addUserTenant(employee.getTenantIds(), tenantId, userId);
         //添加到OA
         oaUserService.addOaUser(employee);
     }
@@ -152,10 +156,10 @@ public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee> impl
      * @param userId       用户id
      */
     private void addUserTenant(List<Integer> tenantIds, Integer userTenantId, Integer userId) {
+        if (CollectionUtils.isEmpty(tenantIds)) {
+            throw new BizException("平台账号必须指定一个机构");
+        }
         if (Objects.nonNull(userTenantId) && userTenantId == -1) {
-            if (CollectionUtils.isEmpty(tenantIds)) {
-                throw new BizException("平台账号必须指定一个机构!");
-            }
             Date now = new Date();
             tenantIds.forEach(t -> {
                 SysUserTenant userTenant = new SysUserTenant();

+ 226 - 113
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomServiceImpl.java

@@ -32,7 +32,6 @@ 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.RList;
 import org.redisson.api.RMap;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
@@ -43,6 +42,8 @@ import org.springframework.stereotype.Service;
 
 import java.io.Serializable;
 import java.util.*;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 /**
  * 直播房间管理表(ImLiveBroadcastRoom)表服务实现类
@@ -73,8 +74,6 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     public static final String USER_ID = "${userId}";
     public static final String ROOM_UID = "${roomUid}";
 
-    //直播间用户列表
-    public static final String LIVE_ROOM_USER_LIST = "IM:LIVE_ROOM_USER_LIST:" + ROOM_UID;
     //直播间累计用户信息-指只要进入到该房间的用户都要记录
     public static final String LIVE_ROOM_TOTAL_USER_LIST = "IM:LIVE_ROOM_TOTAL_USER_LIST:" + ROOM_UID;
     //主讲人信息
@@ -208,7 +207,59 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     }
 
     /**
-     * 关闭房间
+     * 定时任务,每分钟执行
+     * 销毁主讲人退出超过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;
+        }
+        Date now = new Date();
+        list.forEach(room -> {
+            //过期时间= 房间正式开始时间+30分钟
+            Date expiredTime = DateUtil.addMinutes(room.getCreatedTime(), 30);
+            // 现在 大于等于 过期时间
+            if (now.getTime() >= expiredTime.getTime()) {
+                //获取直播间主讲人信息
+                RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, room.getSpeakerId().toString()));
+                if (speakerCache.isExists()) {
+                    RoomSpeakerInfo speakerInfo = speakerCache.get();
+                    //超过30分钟,没有进入房间
+                    if (Objects.isNull(speakerInfo.getJoinRoomTime())) {
+                        roomDestroy(room.getId());
+                    }
+                    //超过30分钟,但是未开启直播,则销毁
+                    if (Objects.isNull(speakerInfo.getState())) {
+                        roomDestroy(room.getId());
+                    }
+                    //现在 大于 (传入时间+30分钟) 则销毁
+                    Consumer<Date> consumer = date -> {
+                        Date comparedTime = DateUtil.addMinutes(date, 30);
+                        if (now.getTime() >= comparedTime.getTime()) {
+                            roomDestroy(room.getId());
+                        }
+                    };
+                    //如果直播状态=1(关闭直播),并且现在 大于等于 结束直播时间 +30分钟,则销毁
+                    if (speakerInfo.getState() == 1) {
+                        consumer.accept(speakerInfo.getEndLiveTime());
+                    }
+                    //现在 大于等于 退出时间 +30分钟,则销毁
+                    if (Objects.nonNull(speakerInfo.getExitRoomTime())) {
+                        consumer.accept(speakerInfo.getExitRoomTime());
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * 关闭房间-融云
+     * 获取所有直播间缓存数据并写入数据库后并清理缓存
      *
      * @param id 直播房间表id
      */
@@ -221,15 +272,19 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         if (room.getLiveState() == 0) {
             throw new BizException("直播未开始");
         }
+
+        String roomUid = room.getRoomUid();
+        Integer speakerId = room.getSpeakerId();
         try {
-            imFeignService.destroyLiveRoom(room.getRoomUid());
+            imFeignService.destroyLiveRoom(roomUid);
         } catch (Exception e) {
             log.error(e.getMessage(), e.getCause());
             throw new BizException(e.getMessage());
         }
-        //获取所有直播间缓存数据并写入数据库
-        insertLiveAllData(room.getRoomUid(), room.getSpeakerId());
-        //todo 删除直播间缓存数据
+
+        //获取所有直播间缓存数据并写入数据库后并清理缓存
+        insertAndCleanLiveData(roomUid, speakerId);
+        log.info("roomDestroy>>>> insertAndCleanLiveData {}", JSONObject.toJSONString(room));
 
         //将房间状态改为已销毁
         Date date = new Date();
@@ -242,44 +297,69 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 
         //向聊天室发自定义消息踢出所有人
         ImRoomMessage message = new ImRoomMessage();
-        message.setFromUserId(room.getSpeakerId().toString());
-        message.setToChatroomId(room.getRoomUid());
+        message.setFromUserId(speakerId.toString());
+        message.setToChatroomId(roomUid);
         message.setObjectName(ImRoomMessage.FORCED_OFFLINE);
         imFeignService.publishRoomMsg(message);
+        log.info("roomDestroy>>>> FORCED_OFFLINE {}", JSONObject.toJSONString(message));
     }
 
-    //获取该直播间所有数据
-    private void insertLiveAllData(String roomUid, Integer userId) {
+    //获取该直播间所有数据写入数据库-并清理缓存
+    private void insertAndCleanLiveData(String roomUid, Integer speakerId) {
+        //总观看人数
+        int totalLookNum = 0;
         //获取直播间所有人数据写入 im_live_broadcast_room_member
-        RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
-        List<ImLiveBroadcastRoomMember> memberList = new ArrayList<>();
-        roomTotalUser.forEach((k, 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);
-        }
-
-        //获取直播间数据
-        ImLiveBroadcastRoomVo roomVo = queryRoomInfo(roomUid);
-        //获取直播间主讲人信息
-        RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, roomVo.getSpeakerId().toString()));
-        RoomSpeakerInfo speakerInfo = speakerCache.get();
-        //获取直播间数据写入im_live_broadcast_room_data
-        ImLiveBroadcastRoomData liveData = new ImLiveBroadcastRoomData();
-        liveData.setTenantId(speakerInfo.getTenantId());
-        liveData.setRoomUid(roomUid);
-        liveData.setLikeNum(roomVo.getLikeNum());
-        liveData.setTotalUserNum(roomVo.getTotalLookNum());
-        liveData.setUpdatedTime(new Date());
-        liveData.setLiveTime(speakerInfo.getTotalLiveTime());
-        liveBroadcastRoomDataService.save(liveData);
+        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 = memberList.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();
+        }
+
     }
 
     /**
@@ -314,12 +394,11 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, user.getUserid()));
             if (speakerCache.isExists()) {
                 RoomSpeakerInfo speakerInfo = speakerCache.get();
-                speakerInfo.setState(2);//主讲人退出房间后房间为暂停直播状态(超过半小时还未开播则自动清算)
-                speakerInfo.setExitRoomTime(now);
-                speakerCache.set(speakerInfo);
                 //主讲人退出房间关闭录像
-                closeLive(speakerInfo.getRoomUid(), userId);
+                closeLive(speakerInfo);
+                speakerInfo.setExitRoomTime(now);
                 log.info("quitRoom>>>> speakerCache {}", JSONObject.toJSONString(speakerInfo));
+                speakerCache.set(speakerInfo);
                 return;
             }
 
@@ -332,34 +411,29 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
 
             //从房间累计用户信息中查询该用户的信息
             RMap<Integer, RoomUserInfoVo> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
-
-            RoomUserInfoVo userInfo;
             //该房间未查询到用户数据则不处理
-            if (!roomTotalUser.containsKey(userId)) {
+            if (!roomTotalUser.isExists() && !roomTotalUser.containsKey(userId)) {
                 return;
             }
             //查询到用户数据
-            userInfo = roomTotalUser.get(userId);
-            //查询该房间当前直播间用户列表
-            RList<Object> roomUserCache = redissonClient.getList(LIVE_ROOM_USER_LIST.replace(ROOM_UID, roomUid));
-            if (roomUserCache.contains(userInfo)) {
-                //只有在房间的时候并且是杀进程那么融云会发送用户离线消息-此刻就发送退出房间消息给主讲人
-                if (user.getStatus().equals("1")) {
-                    ImRoomMessage message = new ImRoomMessage();
-                    message.setFromUserId(userId.toString());
-                    message.setToChatroomId(roomUid);
-                    message.setObjectName(ImRoomMessage.LOOKER_LOGIN_OUT);
-                    imFeignService.publishRoomMsg(message);
-                }
-                //从该房间当前直播间用户列表中移除
-                roomUserCache.remove(userInfo);
+            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);
+                imFeignService.publishRoomMsg(message);
+                log.info("quitRoom>>>> LOOKER_LOGIN_OUT : {}", JSONObject.toJSONString(userInfo));
             }
             //每次退出房间计算当前用户观看时长
             int minutesBetween = getMinutesBetween(userInfo.getDynamicJoinTime(), now);
             userInfo.setTotalViewTime(userInfo.getTotalViewTime() + minutesBetween);
             //记录退出时间 并写入缓存
             userInfo.setLastOutTime(now);
-            roomTotalUser.put(userId, userInfo);
+            userInfo.setState(1);
+            roomTotalUser.fastPut(userId, userInfo);
+            log.info("quitRoom>>>> userInfo: {}", JSONObject.toJSONString(userInfo));
         });
 
     }
@@ -403,25 +477,22 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         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));
-        //查询直播间当前用户数据缓存
-        RList<RoomUserInfoVo> roomUserCacheList = redissonClient.getList(LIVE_ROOM_USER_LIST.replace(ROOM_UID, roomUid));
         //判断是否第一次进房间
         RoomUserInfoVo userInfo;
         Date now = new Date();
         if (roomTotalUser.containsKey(userId)) {
             //多次进入更新动态进入时间
             userInfo = roomTotalUser.get(userId);
-            roomUserCacheList.remove(userInfo);
         } else {
             //第一次进该房间 写入用户首次进入时间
             userInfo = getUserInfo(userId);
             userInfo.setFirstJoinTime(now);
             userInfo.setTotalViewTime(0);
         }
+        userInfo.setState(0);//0 进入/在房间
         userInfo.setDynamicJoinTime(now);
-        roomTotalUser.put(userId, userInfo);
-        //将数据添加到当前直播间
-        roomUserCacheList.add(userInfo);
+        roomTotalUser.fastPut(userId, userInfo);
+        log.info("joinRoom>>>> userInfo: {}", JSONObject.toJSONString(userInfo));
     }
 
     /**
@@ -441,6 +512,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         roomSpeakerInfo.setState(0);
         roomSpeakerInfo.setStartLiveTime(new Date());
         speakerCache.set(roomSpeakerInfo);
+        log.info("startLive>>>> roomSpeakerInfo: {}", JSONObject.toJSONString(roomSpeakerInfo));
     }
 
     /**
@@ -449,23 +521,31 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      * @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) {
             //停止录制视频
-            imFeignService.stopRecord(roomUid);
+            imFeignService.stopRecord(roomSpeakerInfo.getRoomUid());
         }
         if (stateFlag) {
+            Date now = new Date();
+            roomSpeakerInfo.setEndLiveTime(now);
             roomSpeakerInfo.setState(1);
             //计算时长
-            int minutesBetween = getMinutesBetween(roomSpeakerInfo.getStartLiveTime(), new Date());
+            int minutesBetween = getMinutesBetween(roomSpeakerInfo.getStartLiveTime(), now);
             int i = Objects.isNull(roomSpeakerInfo.getTotalLiveTime()) ? 0 : roomSpeakerInfo.getTotalLiveTime();
             roomSpeakerInfo.setTotalLiveTime(i + minutesBetween);
-            speakerCache.set(roomSpeakerInfo);
         }
+        log.info("closeLive>>>> roomSpeakerInfo: {}", JSONObject.toJSONString(roomSpeakerInfo));
     }
 
     /**
@@ -538,19 +618,23 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     }
 
     private void getRoomData(ImLiveBroadcastRoomVo roomVo) {
-        //生成0点赞
+        //点赞
         Object like = redissonClient.getBucket(LIVE_ROOM_LIKE.replace(ROOM_UID, roomVo.getRoomUid())).get();
         if (Objects.isNull(like)) {
             like = 0;
         }
         roomVo.setLikeNum((int) like);
-        //0用户数量
-        RList<Object> list = redissonClient.getList(LIVE_ROOM_USER_LIST.replace(ROOM_UID, roomVo.getRoomUid()));
-        int size = list.size();
-        roomVo.setLookNum(size);
-        //0累计总用户数量
-        int totalLook = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomVo.getRoomUid())).size();
-        roomVo.setTotalLookNum(totalLook);
+        //累计总用户数量
+        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) {
@@ -569,22 +653,35 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      * 测试
      */
     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;
         }
-        //0用户数量
-        RList<RoomUserInfoVo> userList = redissonClient.getList(LIVE_ROOM_USER_LIST.replace(ROOM_UID, roomUid));
-        int size = userList.size();
-        //0累计总用户数量
-        RMap<Integer, RoomUserInfoVo> totalUserCache = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
-        int totalLook = totalUserCache.size();
-        Map<String, Object> roomDataCacheMap = new HashMap<>();
-        roomDataCacheMap.put("点赞数", like);
-        roomDataCacheMap.put("实时观看数", size);
-        roomDataCacheMap.put("总观看人数", totalLook);
+        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()));
@@ -593,21 +690,8 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         } else {
             result.put("主讲人信息", "主讲人信息不存在");
         }
-        //获取实时观看人信息
-        if (userList.isExists()) {
-            result.put("正在观看的人员信息", userList.get());
-        } else {
-            result.put("正在观看的人员信息", "没有正在观看的人员数据");
-        }
-        //获取总用户信息
-        if (totalUserCache.isExists()) {
-            result.put("总人员数据", totalUserCache.values());
-        } else {
-            result.put("总人员数据", "没有人员数据");
-        }
-
-        result.put("roomDataCacheMap", roomDataCacheMap);
-
+        result.put("总观看人数", totalLook);
+        result.put("实时观看数", look);
         return result;
     }
 
@@ -627,12 +711,27 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     }
 
     /**
-     * 查询直播间用户信息
+     * 查询在观看直播的用户信息
      *
      * @param roomUid 直播间uid
      */
+    @Override
     public List<RoomUserInfoVo> queryRoomUserInfo(String roomUid) {
-        return redissonClient.getList(LIVE_ROOM_USER_LIST.replace(ROOM_UID, 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) {
@@ -641,10 +740,13 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         SysUser sysUser = sysUserFeignService.queryUserById(userId);
         String name = userId.toString();
         if (Objects.nonNull(sysUser)) {
-            if (StringUtils.isNotBlank(sysUser.getRealName())) {
-                name = sysUser.getRealName();
+            name = sysUser.getPhone();
+            if (sysUser.getUserType().contains("STUDENT")) {
+                name = sysUser.getUsername();
             } else {
-                name = sysUser.getPhone();
+                if (StringUtils.isNotBlank(sysUser.getRealName())) {
+                    name = sysUser.getRealName();
+                }
             }
         }
         userInfo.setUserName(name);
@@ -671,7 +773,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         private Integer speakerId;
         //主讲人名称
         private String speakerName;
-        //直播状态 0 直播中 1关闭直播 2暂停直播(直接断开退出直播间后超过半小时还未开播则自动清算)
+        //直播状态 0 直播中 1关闭直播
         private Integer state;
         //房间uid
         private String roomUid;
@@ -683,6 +785,9 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         //开始直播时间
         @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;
@@ -780,6 +885,14 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         public void setTenantId(Integer tenantId) {
             this.tenantId = tenantId;
         }
+
+        public Date getEndLiveTime() {
+            return endLiveTime;
+        }
+
+        public void setEndLiveTime(Date endLiveTime) {
+            this.endLiveTime = endLiveTime;
+        }
     }
 
 }

+ 8 - 8
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentServeServiceImpl.java

@@ -389,7 +389,7 @@ public class StudentServeServiceImpl implements StudentServeService {
                     musicGroupIds = new HashSet<>();
                 }
                 
-                List<Mapper> mapperList = courseScheduleStudentPaymentDao.queryUserMusicGroupCourseNumByClassTime(GroupType.MUSIC, musicGroupIds, userId, new Date(2019, 1, 1), LocalDateToUdate(monDayDate));
+                List<Mapper> mapperList = courseScheduleStudentPaymentDao.queryUserMusicGroupCourseNumByClassTime(GroupType.MUSIC, musicGroupIds, userId, new Date(0, 1, 1), LocalDateToUdate(monDayDate));
                 Map<Object, Object> map = mapperList.stream().collect(Collectors.toMap(Mapper :: getKey, Mapper :: getValue));
                 
                 List<StudentServeCourseDto> weekCourseInfo = typeCourseMap.get(CourseSchedule.CourseScheduleType.SINGLE).stream().filter(c -> c.getCourseStartTime().compareTo(nextMonday) < 0).collect(Collectors.toList());
@@ -403,7 +403,7 @@ public class StudentServeServiceImpl implements StudentServeService {
                         }
                         
                         //学生在当前乐团没有上过课,就不需要生成服务指标
-                        if(map.get(groupCourseInfoEntry.getKey()) != null && (int)map.get(groupCourseInfoEntry.getKey()) == 0){
+                        if(map.get(groupCourseInfoEntry.getKey()) != null && (long)map.get(groupCourseInfoEntry.getKey()) == 0){
                         	continue;
                         }
                         
@@ -504,7 +504,7 @@ public class StudentServeServiceImpl implements StudentServeService {
                     continue;
                 }
                 
-                List<Mapper> mapperList = courseScheduleStudentPaymentDao.queryUserMusicGroupCourseNumByClassTime(GroupType.MUSIC, musicGroupIds, userId, new Date(2019, 1, 1), LocalDateToUdate(monDayDate));
+                List<Mapper> mapperList = courseScheduleStudentPaymentDao.queryUserMusicGroupCourseNumByClassTime(GroupType.MUSIC, musicGroupIds, userId, new Date(0, 1, 1), LocalDateToUdate(monDayDate));
                 Map<Object, Object> map = mapperList.stream().collect(Collectors.toMap(Mapper :: getKey, Mapper :: getValue));
                 
                 
@@ -512,7 +512,7 @@ public class StudentServeServiceImpl implements StudentServeService {
                 for (String groupId : musicGroupIds) {
                 	
                     //学生在当前乐团没有上过课,就不需要生成服务指标
-                    if(map.get(groupId) == null || (int)map.get(groupId) == 0){
+                    if(map.get(groupId) == null || (long)map.get(groupId) == 0){
                     	continue;
                     }
                     
@@ -592,15 +592,15 @@ public class StudentServeServiceImpl implements StudentServeService {
             if(CollectionUtils.isEmpty(musicGroupIds)){
                 continue;
             }
-            
-            List<Mapper> mapperList = courseScheduleStudentPaymentDao.queryUserMusicGroupCourseNumByClassTime(GroupType.MUSIC, musicGroupIds, noCourseServeStudentId, new Date(2019, 1, 1), LocalDateToUdate(monDayDate));
+        	
+            List<Mapper> mapperList = courseScheduleStudentPaymentDao.queryUserMusicGroupCourseNumByClassTime(GroupType.MUSIC, musicGroupIds, noCourseServeStudentId, new Date(0, 1, 1), LocalDateToUdate(monDayDate));
             Map<Object, Object> map = mapperList.stream().collect(Collectors.toMap(Mapper :: getKey, Mapper :: getValue));
             
             Map<Integer, Integer> teacherNumMap = new HashMap<>();
             for (String groupId : musicGroupIds) {
-                
+            	
                 //学生在当前乐团没有上过课,就不需要生成服务指标
-                if(map.get(groupId) == null || (int)map.get(groupId) == 0){
+                if(map.get(groupId) == null || (long)map.get(groupId) == 0){
                 	continue;
                 }
                 

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoServiceImpl.java

@@ -492,6 +492,8 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         e.setUserType(SysUserType.SYSTEM.getCode());
         e.setOrganIdList(String.valueOf(orgId));
         e.setPassword(pw);
+        e.setTenantIds(Lists.newArrayList(tenantInfo.getId()));
+        e.setCreateTenantUserId(tenantInfo.getCreatedBy());
         try {
             log.info("createUser >>>> {}", e);
             employeeService.add(e);

+ 6 - 2
mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

@@ -882,8 +882,12 @@
 	
 	<select id="queryUserMusicGroupCourseNumByClassTime" resultMap="Mapper" parameterType="map">
 		select cssp.music_group_id_ key_,count(cssp.id_) value_ from course_schedule_student_payment cssp left join course_schedule cs on cssp.course_schedule_id_ = cs.id_
-		where cssp.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} and find_in_set(cssp.music_group_id_ , #{musicGroupIds}) and cssp.user_id_ = #{userId}
-		and cs.class_date_ between #{startDate} and #{endDate}
+		where cssp.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} and 
+		cssp.music_group_id_ IN
+                <foreach collection="musicGroupIds" separator="," item="musicGroupId" open="(" close=")">
+                    #{musicGroupId}
+                </foreach>
+		and cssp.user_id_ = #{userId} and cs.class_date_ between #{startDate} and #{endDate}
 		group by cssp.music_group_id_
 	</select>
 </mapper>

+ 6 - 0
mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java

@@ -248,4 +248,10 @@ public interface TaskRemoteService {
      */
     @GetMapping("task/createLiveRoom")
     void createLiveRoom();
+
+    /**
+     * 每分钟-查询是否有直播间需要销毁
+     */
+    @GetMapping("task/destroyExpiredLiveRoom")
+    void destroyExpiredLiveRoom();
 }

+ 5 - 0
mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java

@@ -299,4 +299,9 @@ public class TaskRemoteServiceFallback implements TaskRemoteService {
     public void createLiveRoom() {
         logger.error("直播间创建失败");
     }
+
+    @Override
+    public void destroyExpiredLiveRoom() {
+        logger.error("销毁直播间失败");
+    }
 }

+ 22 - 0
mec-task/src/main/java/com/ym/mec/task/jobs/DestroyExpiredLiveRoomTask.java

@@ -0,0 +1,22 @@
+package com.ym.mec.task.jobs;
+
+import com.ym.mec.task.TaskRemoteService;
+import com.ym.mec.task.core.BaseTask;
+import com.ym.mec.task.core.TaskException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author hgw
+ * Created by 2022-03-04
+ */
+public class DestroyExpiredLiveRoomTask extends BaseTask {
+
+    @Autowired
+    private TaskRemoteService taskRemoteService;
+
+    @Override
+    public void execute() throws TaskException {
+        taskRemoteService.destroyExpiredLiveRoom();
+    }
+
+}

+ 6 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

@@ -573,4 +573,10 @@ public class TaskController extends BaseController {
     public void createLiveRoom(){
         imLiveBroadcastRoomService.createLiveRoom();
     }
+
+    @ApiOperation("每分钟-查询是否有直播间需要销毁")
+    @GetMapping(value = "/destroyExpiredLiveRoom")
+    public void destroyExpiredLiveRoom(){
+        imLiveBroadcastRoomService.destroyExpiredLiveRoom();
+    }
 }