|  | @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.serializer.SerializerFeature;
 | 
	
		
			
				|  |  |  import com.google.common.collect.Lists;
 | 
	
		
			
				|  |  | +import com.google.common.collect.Maps;
 | 
	
		
			
				|  |  |  import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginContext;
 | 
	
		
			
				|  |  |  import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginService;
 | 
	
		
			
				|  |  |  import com.microsvc.toolkit.middleware.rtc.enums.EMemberAction;
 | 
	
	
		
			
				|  | @@ -267,6 +268,9 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 获取RTC服务提供方
 | 
	
		
			
				|  |  |          String rtcServiceProvider = Optional.ofNullable(sysConfigDao.findConfigValue("rtc_service_provider")).orElse("rongCloud");
 | 
	
		
			
				|  |  | +        if (StringUtils.isBlank(courseSchedule.getServiceProvider())) {
 | 
	
		
			
				|  |  | +            courseSchedule.setServiceProvider(rtcServiceProvider);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(rtcServiceProvider);
 | 
	
		
			
				|  |  |          if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
 | 
	
	
		
			
				|  | @@ -274,7 +278,7 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |              // 用户IM帐号创建
 | 
	
		
			
				|  |  |              String userSig = "";
 | 
	
		
			
				|  |  |              try {
 | 
	
		
			
				|  |  | -                userSig = pluginService.register(String.valueOf(sysUser.getId()), sysUser.getUsername(), sysUser.getAvatar());
 | 
	
		
			
				|  |  | +                userSig = pluginService.register(String.valueOf(sysUser.getId()), sysUser.getRealName(), sysUser.getAvatar());
 | 
	
		
			
				|  |  |              } catch (Exception e) {
 | 
	
		
			
				|  |  |                  log.error("直播房间用户注册失败: userId={}", sysUser.getId(), e);
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -283,56 +287,10 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |              roomResult.userSig(userSig)
 | 
	
		
			
				|  |  |                      .rtcRoomConfig(rtcRoomPluginContext.getPluginService().getRTCRoomConfig(String.valueOf(sysUser.getId())))
 | 
	
		
			
				|  |  |                      .setGroupId(roomId);
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -            // 融云RTC
 | 
	
		
			
				|  |  | -            // TODO:创建IM群聊,后续注释掉,统一使用后续流程
 | 
	
		
			
				|  |  | -            this.joinImGroup(roomId, courseSchedule.getActualTeacherId());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        // 创建网络课聊天室
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            String joinImGroupKey = "joinImGroup:" + roomId;
 | 
	
		
			
				|  |  | -            // VIP课或网络课,IM群聊已创建标识
 | 
	
		
			
				|  |  | -            Boolean exists = redisTemplate.opsForValue().setIfAbsent(joinImGroupKey, roomId, 1L, TimeUnit.DAYS);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if (Optional.ofNullable(exists).orElse(false)) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                // 生成群组,更新服务提供方
 | 
	
		
			
				|  |  | -                if (StringUtils.isBlank(courseSchedule.getServiceProvider())) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    // 创建群组
 | 
	
		
			
				|  |  | -                    log.info("createImGroup: roomId = {}, userId = {}", roomId, teacherInfo.getId());
 | 
	
		
			
				|  |  | -                    pluginService.chatRoomCreate(roomId, courseSchedule.getName(), teacherInfo.getId().toString());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    // 更新网络课服务提供方
 | 
	
		
			
				|  |  | -                    courseScheduleDao.updateServiceProvider(courseSchedule.getId(), rtcServiceProvider);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                // 群组老师信息
 | 
	
		
			
				|  |  | -                List<ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList(ImGroupMemberWrapper.ImGroupMember
 | 
	
		
			
				|  |  | -                        .builder()
 | 
	
		
			
				|  |  | -                        .userId(Long.valueOf(teacherInfo.getId()))
 | 
	
		
			
				|  |  | -                        .imUserIdFormat(false)
 | 
	
		
			
				|  |  | -                        .build());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                List<CourseScheduleStudentPayment> payments = courseScheduleStudentPaymentDao.findByCourseSchedule(Long.parseLong(roomId.substring(1)));
 | 
	
		
			
				|  |  | -                // 群组学生信息
 | 
	
		
			
				|  |  | -                if (CollectionUtils.isNotEmpty(payments)) {
 | 
	
		
			
				|  |  | -                    for (CourseScheduleStudentPayment item : payments) {
 | 
	
		
			
				|  |  | -                        groupMembers.add(ImGroupMemberWrapper.ImGroupMember
 | 
	
		
			
				|  |  | -                                .builder()
 | 
	
		
			
				|  |  | -                                .userId(Long.valueOf(item.getUserId()))
 | 
	
		
			
				|  |  | -                                .imUserIdFormat(false)
 | 
	
		
			
				|  |  | -                                .build());
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                // 加入群组成员
 | 
	
		
			
				|  |  | -                log.info("joinImGroup: roomId = {}, serviceProvider={}, userIds = {}", roomId, courseSchedule.getServiceProvider(), groupMembers);
 | 
	
		
			
				|  |  | -                pluginService.chatRoomGroupJoin(roomId, courseSchedule.getName(), groupMembers);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        // 创建IM群聊
 | 
	
		
			
				|  |  | +        this.joinImGroup(roomId, courseSchedule.getActualTeacherId(), courseSchedule);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          List<CourseScheduleStudentMusicScore> scheduleStudentMusicScores = courseScheduleStudentMusicScoreDao.queryByScoreIdAndCourseId(null, courseId, null, null, null);
 | 
	
		
			
				|  |  |          Room room = roomDao.findByRid(roomId);
 | 
	
	
		
			
				|  | @@ -405,23 +363,78 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |          return new BaseResponse(roomResult);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private void joinImGroup(String roomId,Integer actualTeacherId) throws Exception {
 | 
	
		
			
				|  |  | +    private void joinImGroup(String roomId, Integer actualTeacherId, CourseSchedule courseSchedule) throws Exception {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          String joinImGroupKey = "joinImGroup:" + roomId;
 | 
	
		
			
				|  |  | -        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(joinImGroupKey, roomId, 1l, TimeUnit.DAYS);
 | 
	
		
			
				|  |  | -        if (aBoolean) {
 | 
	
		
			
				|  |  | -            log.info("joinImGroup: roomId = {}, userId = {}", roomId, actualTeacherId);
 | 
	
		
			
				|  |  | -            List<CourseScheduleStudentPayment> payments = courseScheduleStudentPaymentDao.findByCourseSchedule(Long.parseLong(roomId.substring(1)));
 | 
	
		
			
				|  |  | -            List<String> collect = payments.stream().map(e -> e.getUserId().toString()).collect(Collectors.toList());
 | 
	
		
			
				|  |  | -            collect.add(actualTeacherId.toString());
 | 
	
		
			
				|  |  | -            String[] integers = collect.toArray(new String[]{});
 | 
	
		
			
				|  |  | -            imHelper.joinGroup(integers, roomId, roomId);
 | 
	
		
			
				|  |  | +        // VIP课或网络课,IM群聊已创建标识
 | 
	
		
			
				|  |  | +        Boolean exists = redisTemplate.opsForValue().setIfAbsent(joinImGroupKey, roomId, 1L, TimeUnit.DAYS);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(courseSchedule.getServiceProvider());
 | 
	
		
			
				|  |  | +        if (Optional.ofNullable(exists).orElse(false)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 创建群组
 | 
	
		
			
				|  |  | +            log.info("createImGroup: roomId = {}, userId = {}", roomId, actualTeacherId);
 | 
	
		
			
				|  |  | +            if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                try {
 | 
	
		
			
				|  |  | +                    // 生成群组,更新服务提供方
 | 
	
		
			
				|  |  | +                    pluginService.chatRoomCreate(roomId, courseSchedule.getName(), actualTeacherId.toString());
 | 
	
		
			
				|  |  | +                } catch (Exception e) {
 | 
	
		
			
				|  |  | +                    log.error("joinImGroup TENCENT_CLOUD error: roomId = {}, userId = {}", roomId, actualTeacherId, e);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // 更新网络课服务提供方
 | 
	
		
			
				|  |  | +                courseScheduleDao.updateServiceProvider(courseSchedule.getId(), courseSchedule.getServiceProvider());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // 群组老师信息
 | 
	
		
			
				|  |  | +                List<ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList(ImGroupMemberWrapper.ImGroupMember
 | 
	
		
			
				|  |  | +                        .builder()
 | 
	
		
			
				|  |  | +                        .userId(Long.valueOf(actualTeacherId))
 | 
	
		
			
				|  |  | +                        .imUserIdFormat(false)
 | 
	
		
			
				|  |  | +                        .build());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                List<CourseScheduleStudentPayment> payments = courseScheduleStudentPaymentDao.findByCourseSchedule(Long.parseLong(roomId.substring(1)));
 | 
	
		
			
				|  |  | +                // 群组学生信息
 | 
	
		
			
				|  |  | +                if (CollectionUtils.isNotEmpty(payments)) {
 | 
	
		
			
				|  |  | +                    for (CourseScheduleStudentPayment item : payments) {
 | 
	
		
			
				|  |  | +                        groupMembers.add(ImGroupMemberWrapper.ImGroupMember
 | 
	
		
			
				|  |  | +                                .builder()
 | 
	
		
			
				|  |  | +                                .userId(Long.valueOf(item.getUserId()))
 | 
	
		
			
				|  |  | +                                .imUserIdFormat(false)
 | 
	
		
			
				|  |  | +                                .build());
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // 加入群组成员
 | 
	
		
			
				|  |  | +                log.info("joinImGroup: roomId = {}, serviceProvider={}, userIds = {}", roomId, courseSchedule.getServiceProvider(), groupMembers);
 | 
	
		
			
				|  |  | +                pluginService.chatRoomGroupJoin(roomId, courseSchedule.getName(), groupMembers);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                List<CourseScheduleStudentPayment> payments = courseScheduleStudentPaymentDao.findByCourseSchedule(Long.parseLong(roomId.substring(1)));
 | 
	
		
			
				|  |  | +                List<String> collect = payments.stream().map(e -> e.getUserId().toString()).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +                collect.add(actualTeacherId.toString());
 | 
	
		
			
				|  |  | +                String[] integers = collect.toArray(new String[]{});
 | 
	
		
			
				|  |  | +                imHelper.joinGroup(integers, roomId, roomId);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    private void dismissImGroup(String userId,String roomId) throws Exception {
 | 
	
		
			
				|  |  | +    private void dismissImGroup(String userId,String roomId, String serviceProvider) throws Exception {
 | 
	
		
			
				|  |  |          log.info("dismissImGroup: roomId = {}, userId = {}", roomId, userId);
 | 
	
		
			
				|  |  |          String joinImGroupKey = "joinImGroup:" + roomId;
 | 
	
		
			
				|  |  |          redisTemplate.delete(joinImGroupKey);
 | 
	
		
			
				|  |  | -        imHelper.dismiss(userId, roomId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(serviceProvider);
 | 
	
		
			
				|  |  | +        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
 | 
	
		
			
				|  |  | +            // 腾讯云群销毁
 | 
	
		
			
				|  |  | +            pluginService.chatRoomDestroy(roomId);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            // 融云群销毁
 | 
	
		
			
				|  |  | +            // 销毁群组
 | 
	
		
			
				|  |  | +            imHelper.dismiss(userId, roomId);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -496,7 +509,7 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |          Room room = roomDao.findByRid(roomId);
 | 
	
		
			
				|  |  |          if (room == null) {
 | 
	
		
			
				|  |  |              saveRoom(roomId, roomId, curTime, display);
 | 
	
		
			
				|  |  | -            this.joinImGroup(roomId,schedule.getActualTeacherId());
 | 
	
		
			
				|  |  | +            this.joinImGroup(roomId, schedule.getActualTeacherId(), schedule);
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  |              if (roleEnum == RoleTeacher || roleEnum == RoleEnum.RoleAssistant) {
 | 
	
		
			
				|  |  |                  updateDisplay(roomId, userId, display, 0);
 | 
	
	
		
			
				|  | @@ -685,7 +698,7 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |              roomMemberDao.deleteUserByRidAndUid(roomId, userId);
 | 
	
		
			
				|  |  |              roomDao.deleteByRid(roomId);
 | 
	
		
			
				|  |  |              deleteWhiteboardByUser(roomId, userId);
 | 
	
		
			
				|  |  | -            this.dismissImGroup(userId, roomId);
 | 
	
		
			
				|  |  | +            this.dismissImGroup(userId, roomId, courseSchedule.getServiceProvider());
 | 
	
		
			
				|  |  |              courseScheduleStudentMusicScoreDao.closePlayStatus(courseSchedule.getId(), null, null);
 | 
	
		
			
				|  |  |              log.info("leaveRoomSuccess dismiss the room: {},userId: {}", roomId, userId);
 | 
	
		
			
				|  |  |          } else {
 | 
	
	
		
			
				|  | @@ -742,13 +755,20 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |      @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public void destroyRoom(String roomId) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 查询课程信息
 | 
	
		
			
				|  |  | +        CourseSchedule courseSchedule = courseScheduleDao.get(Long.parseLong(roomId.substring(1)));
 | 
	
		
			
				|  |  | +        if (Objects.isNull(courseSchedule)) {
 | 
	
		
			
				|  |  | +            throw new BizException("无效的课程编号");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          whiteboardDao.deleteByRid(roomId);
 | 
	
		
			
				|  |  |          Room room = roomDao.findByRid(roomId);
 | 
	
		
			
				|  |  |          if (room == null) {
 | 
	
		
			
				|  |  |              List<RoomMember> list = roomMemberDao.findByRid(roomId);
 | 
	
		
			
				|  |  |              if (!list.isEmpty()) {
 | 
	
		
			
				|  |  |                  try {
 | 
	
		
			
				|  |  | -                    this.dismissImGroup(list.get(0).getUid(), roomId);
 | 
	
		
			
				|  |  | +                    this.dismissImGroup(list.get(0).getUid(), roomId, courseSchedule.getServiceProvider());
 | 
	
		
			
				|  |  |                  } catch (Exception e) {
 | 
	
		
			
				|  |  |                      log.error("destroyRoom: {}", e.getMessage());
 | 
	
		
			
				|  |  |                      e.printStackTrace();
 | 
	
	
		
			
				|  | @@ -2026,6 +2046,18 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  |      public void userIMOfflineKick(String userId) {
 | 
	
		
			
				|  |  |          List<RoomMember> members = roomMemberDao.findByUid(userId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 查询课程信息
 | 
	
		
			
				|  |  | +        List<Long> collect = members.stream()
 | 
	
		
			
				|  |  | +                .map(x -> x.getRid().substring(1))
 | 
	
		
			
				|  |  | +                .map(Long::valueOf).distinct().collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Map<String, String> serviceProviderMap = Maps.newHashMap();
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isNotEmpty(collect)) {
 | 
	
		
			
				|  |  | +            serviceProviderMap = courseScheduleDao.findByCourseScheduleIds(collect).stream()
 | 
	
		
			
				|  |  | +                    .collect(Collectors.toMap(x -> x.getId().toString(), CourseSchedule::getServiceProvider, (o, n) -> n));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          for (RoomMember member : members) {
 | 
	
		
			
				|  |  |              int userRole = member.getRole();
 | 
	
		
			
				|  |  |              log.info("userIMOfflineKick: roomId={}, {}, role={}", member.getRid(), userId, RoleEnum.getEnumByValue(userRole));
 | 
	
	
		
			
				|  | @@ -2041,7 +2073,10 @@ public class RoomServiceImpl implements RoomService {
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  if (roomMemberDao.countByRid(member.getRid()) == 1) {
 | 
	
		
			
				|  |  | -                    this.dismissImGroup(member.getUid(), member.getRid());
 | 
	
		
			
				|  |  | +                    // 群组当前人数为1时,解散群组
 | 
	
		
			
				|  |  | +                    this.dismissImGroup(member.getUid(), member.getRid(),
 | 
	
		
			
				|  |  | +                            serviceProviderMap.getOrDefault(member.getRid().substring(1), "rongCloud"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                      roomMemberDao.deleteUserByRidAndUid(member.getRid(), member.getUid());
 | 
	
		
			
				|  |  |                      roomDao.deleteByRid(member.getRid());
 | 
	
		
			
				|  |  |                      deleteWhiteboardByUser(member.getRid(), member.getUid());
 |