|
@@ -34,9 +34,11 @@ import com.ym.mec.biz.dal.dto.RongyunBasicUserDto;
|
|
|
import com.ym.mec.biz.dal.entity.*;
|
|
|
import com.ym.mec.biz.dal.enums.GroupType;
|
|
|
import com.ym.mec.biz.dal.enums.TeachModeEnum;
|
|
|
+import com.ym.mec.biz.dal.vo.ImLiveBroadcastRoomVo;
|
|
|
import com.ym.mec.biz.service.*;
|
|
|
import com.ym.mec.common.exception.BizException;
|
|
|
import com.ym.mec.common.page.WrapperUtil;
|
|
|
+import com.ym.mec.common.tenant.TenantContextHolder;
|
|
|
import com.ym.mec.im.IMHelper;
|
|
|
import com.ym.mec.im.message.*;
|
|
|
import com.ym.mec.util.collection.MapUtil;
|
|
@@ -124,6 +126,8 @@ public class RoomServiceImpl implements RoomService {
|
|
|
private RTCRoomPluginContext rtcRoomPluginContext;
|
|
|
@Autowired
|
|
|
private VipGroupDao vipGroupDao;
|
|
|
+ @Autowired
|
|
|
+ private ImLiveBroadcastRoomService imLiveBroadcastRoomService;
|
|
|
|
|
|
@Override
|
|
|
public Integer getCurrentCourseId(String roomId) {
|
|
@@ -208,6 +212,8 @@ public class RoomServiceImpl implements RoomService {
|
|
|
}
|
|
|
|
|
|
RoomResult roomResult = new RoomResult();
|
|
|
+ // 直播间编号
|
|
|
+ roomResult.setLiveRoomId(courseSchedule.getLiveRoomId());
|
|
|
roomResult.setAutoCloseNetworkRoomTime(this.getCloseNetworkRoomTime(courseSchedule, continueCourseTime));
|
|
|
CourseSchedule schedule = courseSchedule;
|
|
|
//如果当前课程是连堂课,那么获取第一节课的课程编号
|
|
@@ -231,7 +237,6 @@ public class RoomServiceImpl implements RoomService {
|
|
|
}
|
|
|
redisTemplate.opsForValue().setIfAbsent(roomId + userId, courseSchedule.getId().toString());
|
|
|
log.info("joinRoom current: roomId={}, userId={}", roomId, userId);
|
|
|
- RoleEnum roleEnum;
|
|
|
|
|
|
// 获取RTC服务提供方
|
|
|
if (StringUtils.isBlank(courseSchedule.getServiceProvider())) {
|
|
@@ -252,19 +257,178 @@ public class RoomServiceImpl implements RoomService {
|
|
|
}
|
|
|
|
|
|
courseSchedule.setServiceProvider(rtcServiceProvider);
|
|
|
+
|
|
|
+ // 更新网络课服务提供方
|
|
|
+ courseScheduleDao.updateServiceProvider(courseSchedule.getId(), courseSchedule.getServiceProvider());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 主讲老师信息
|
|
|
+ SysUser teacherInfo = sysUserFeignService.queryUserById(courseSchedule.getActualTeacherId());
|
|
|
+ if (Objects.isNull(teacherInfo)) {
|
|
|
+ throw new BizException("主讲老师不存在");
|
|
|
}
|
|
|
|
|
|
+ // RTC服务提供方
|
|
|
+ roomResult.setServiceProvider(Optional.ofNullable(courseSchedule.getServiceProvider()).orElse("rongCloud"));
|
|
|
+ //获取当前课程剩余时长
|
|
|
+ roomResult.setSurplusTime(DateUtil.secondsBetween(new Date(), courseSchedule.getEndClassTime()));
|
|
|
+ roomResult.setRoomId(roomId);
|
|
|
+
|
|
|
+ // 网络课形式:RTC房间,直播间
|
|
|
+ if (GroupType.LIVE == courseSchedule.getGroupType()) {
|
|
|
+
|
|
|
+ if (Optional.ofNullable(joinRoom).orElse(true)) {
|
|
|
+
|
|
|
+ String joinImGroupKey = "joinImGroup:" + roomId;
|
|
|
+ // VIP课或网络课,IM群聊已创建标识
|
|
|
+ redisTemplate.opsForValue().setIfAbsent(joinImGroupKey, roomId, 1L, TimeUnit.DAYS);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 直播形式网络课
|
|
|
+ ImLiveBroadcastRoom liveRoom;
|
|
|
+ if (StringUtils.isNotBlank(courseSchedule.getLiveRoomId())) {
|
|
|
+
|
|
|
+ // 直播间状态判断
|
|
|
+ liveRoom = imLiveBroadcastRoomService.lambdaQuery()
|
|
|
+ .eq(ImLiveBroadcastRoom::getRoomUid, courseSchedule.getLiveRoomId())
|
|
|
+ .last("LIMIT 1")
|
|
|
+ .one();
|
|
|
+
|
|
|
+ if (Objects.isNull(liveRoom)) {
|
|
|
+ // 创建网络课直播教室
|
|
|
+ liveRoom = createVipGroupLiveRoom(roomId, courseSchedule);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 直播间状态不在进行中
|
|
|
+ if (liveRoom.getLiveState() != 1) {
|
|
|
+
|
|
|
+ ImLiveBroadcastRoom updateInfo = new ImLiveBroadcastRoom();
|
|
|
+ updateInfo.setId(liveRoom.getId());
|
|
|
+ updateInfo.setLiveStartTime(DateTime.now().toDate());
|
|
|
+
|
|
|
+ // 更新直播间状态
|
|
|
+ imLiveBroadcastRoomService.updateById(updateInfo);
|
|
|
+
|
|
|
+ // 开启直播间
|
|
|
+ imLiveBroadcastRoomService.createLiveRoom(liveRoom);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // 创建网络课直播教室
|
|
|
+ liveRoom = createVipGroupLiveRoom(roomId, courseSchedule);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回直播间配置参数
|
|
|
+ roomResult.setLiveRoom(imLiveBroadcastRoomService.visitorRoomInfo(liveRoom.getRoomUid(), sysUser.getId()));
|
|
|
+
|
|
|
+ // 主动触发用户加入直播间
|
|
|
+ imLiveBroadcastRoomService.joinRoom(liveRoom.getRoomUid(), sysUser.getId());
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // 创建聊天群组
|
|
|
+ if (Optional.ofNullable(joinRoom).orElse(true)) {
|
|
|
+ // 创建IM群聊
|
|
|
+ this.joinImGroup(roomId, courseSchedule.getActualTeacherId(), courseSchedule);
|
|
|
+ }
|
|
|
+
|
|
|
+ // RTC房间网络课
|
|
|
+ genRtcRoomMemberInfoConfig(roomId, joinRoom, sysUser, userId, teacher, courseSchedule, curTime, roomResult, courseId);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("join room: roomId = {}, userId = {}, userName={}, role = {}", roomId, userId);
|
|
|
+ return new BaseResponse(roomResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建网络课直播间
|
|
|
+ * @param roomId 课程房间编号
|
|
|
+ * @param courseSchedule 课程信息
|
|
|
+ * @return ImLiveBroadcastRoom
|
|
|
+ */
|
|
|
+ private ImLiveBroadcastRoom createVipGroupLiveRoom(String roomId, CourseSchedule courseSchedule) {
|
|
|
+
|
|
|
+ // 主动创建直播间
|
|
|
+ VipGroup vipGroup = vipGroupDao.get(Long.parseLong(courseSchedule.getMusicGroupId()));
|
|
|
+ if (Objects.isNull(vipGroup)) {
|
|
|
+ throw new BizException("直播课程组不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(vipGroup.getLiveConfigJson())) {
|
|
|
+ throw new BizException("直播课程组未配置直播间");
|
|
|
+ }
|
|
|
+
|
|
|
+ ImLiveBroadcastRoom liveRoom = JSON.parseObject(vipGroup.getLiveConfigJson(), ImLiveBroadcastRoom.class);
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(liveRoom.getServiceProvider())) {
|
|
|
+ //查询房间过期时间
|
|
|
+ String liveClient = sysConfigDao.findConfigValue("live_client");
|
|
|
+ liveRoom.setServiceProvider(liveClient);
|
|
|
+ }
|
|
|
+
|
|
|
+ String roomUid = "LIVE-" + roomId + "-" + DateTime.now().toDate().getTime();
|
|
|
+ liveRoom.setTenantId(TenantContextHolder.getTenantId());
|
|
|
+ liveRoom.setRoomUid(roomUid);
|
|
|
+ liveRoom.setRoomConfig(JSONObject.toJSONString(liveRoom.getRoomConfig()));
|
|
|
+ liveRoom.setLiveState(1);
|
|
|
+ liveRoom.setRoomState(0);
|
|
|
+ liveRoom.setGroupType("LIVE");
|
|
|
+ liveRoom.setCreatedBy(liveRoom.getSpeakerId());
|
|
|
+ liveRoom.setCreatedTime(DateTime.now().toDate());
|
|
|
+ liveRoom.setLiveStartTime(DateTime.now().toDate());
|
|
|
+ liveRoom.setTenantId(courseSchedule.getTenantId());
|
|
|
+
|
|
|
+ // 创建直播间
|
|
|
+ imLiveBroadcastRoomService.save(liveRoom);
|
|
|
+
|
|
|
+ // 开启直播间
|
|
|
+ imLiveBroadcastRoomService.createLiveRoom(liveRoom);
|
|
|
+
|
|
|
+ // 返回直播间信息
|
|
|
+ return imLiveBroadcastRoomService.lambdaQuery()
|
|
|
+ .eq(ImLiveBroadcastRoom::getRoomUid, courseSchedule.getLiveRoomId())
|
|
|
+ .last("LIMIT 1")
|
|
|
+ .one();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * RTC房间成员信息配置
|
|
|
+ * @param roomId 房间编号
|
|
|
+ * @param joinRoom 是否加入房间
|
|
|
+ * @param sysUser 用户信息
|
|
|
+ * @param userId 用户编号
|
|
|
+ * @param teacher 主讲老师信息
|
|
|
+ * @param courseSchedule 课程信息
|
|
|
+ * @param curTime 当前时间
|
|
|
+ * @param roomResult 房间信息
|
|
|
+ * @param courseId 课程编号
|
|
|
+ * @throws Exception 异常信息
|
|
|
+ */
|
|
|
+ private void genRtcRoomMemberInfoConfig(String roomId,
|
|
|
+ Boolean joinRoom,
|
|
|
+ SysUser sysUser,
|
|
|
+ String userId,
|
|
|
+ Teacher teacher,
|
|
|
+ CourseSchedule courseSchedule,
|
|
|
+ Date curTime,
|
|
|
+ RoomResult roomResult,
|
|
|
+ Long courseId) throws Exception {
|
|
|
+
|
|
|
// 全员静音状态
|
|
|
Boolean muteAll = Optional.ofNullable(courseSchedule.getMuteAll()).orElse(false);
|
|
|
|
|
|
RoomResult.MemberResult userResult = new RoomResult.MemberResult();
|
|
|
RoomMember member = roomMemberDao.findByRidAndUid(roomId, userId);
|
|
|
+
|
|
|
+ RoleEnum roleEnum;
|
|
|
String userName;
|
|
|
if (member == null) {
|
|
|
int count = roomMemberDao.countByRidAndExcludeRole(roomId, RoleEnum.RoleAudience.getValue());
|
|
|
if (count == roomProperties.getMaxCount()) {
|
|
|
log.info("join error Over max count: roomId = {}, userId = {}", roomId, userId);
|
|
|
- return new BaseResponse(ErrorEnum.ERR_OVER_MAX_COUNT, ErrorEnum.ERR_OVER_MAX_COUNT.getErrMsg(), null);
|
|
|
+ throw new BizException(ErrorEnum.ERR_OVER_MAX_COUNT.getErrCode(), ErrorEnum.ERR_OVER_MAX_COUNT.getErrMsg());
|
|
|
+ //return new BaseResponse(ErrorEnum.ERR_OVER_MAX_COUNT, ErrorEnum.ERR_OVER_MAX_COUNT.getErrMsg(), null);
|
|
|
}
|
|
|
|
|
|
boolean microphone = true;
|
|
@@ -302,12 +466,6 @@ public class RoomServiceImpl implements RoomService {
|
|
|
}
|
|
|
// imHelper.joinGroup(new String[]{userId}, roomId, roomId);
|
|
|
|
|
|
- // 主讲老师信息
|
|
|
- SysUser teacherInfo = sysUserFeignService.queryUserById(courseSchedule.getActualTeacherId());
|
|
|
- if (Objects.isNull(teacherInfo)) {
|
|
|
- throw new BizException("主讲老师不存在");
|
|
|
- }
|
|
|
-
|
|
|
RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(courseSchedule.getServiceProvider());
|
|
|
if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
|
|
|
// 腾讯云RTC
|
|
@@ -325,13 +483,6 @@ public class RoomServiceImpl implements RoomService {
|
|
|
.setGroupId(roomId);
|
|
|
}
|
|
|
|
|
|
- if (Optional.ofNullable(joinRoom).orElse(true)) {
|
|
|
- // 创建IM群聊
|
|
|
- this.joinImGroup(roomId, courseSchedule.getActualTeacherId(), courseSchedule);
|
|
|
- // RTC服务提供方
|
|
|
- roomResult.setServiceProvider(Optional.ofNullable(courseSchedule.getServiceProvider()).orElse("rongCloud"));
|
|
|
- }
|
|
|
-
|
|
|
List<CourseScheduleStudentMusicScore> scheduleStudentMusicScores = courseScheduleStudentMusicScoreDao.queryByScoreIdAndCourseId(null, courseId, null, null, null);
|
|
|
Room room = roomDao.findByRid(roomId);
|
|
|
String display = "";
|
|
@@ -375,12 +526,8 @@ public class RoomServiceImpl implements RoomService {
|
|
|
String midi = courseScheduleStudentPaymentDao.getMidiByCourseIdAndUserId(courseId.toString(), userId);
|
|
|
userResult.setPlayMidiJson(JSONObject.parseObject(midi, CustomMessage.class));
|
|
|
|
|
|
- //获取当前课程剩余时长
|
|
|
- roomResult.setSurplusTime(DateUtil.secondsBetween(new Date(), courseSchedule.getEndClassTime()));
|
|
|
-
|
|
|
roomResult.setUserInfo(userResult);
|
|
|
roomResult.setDisplay(display);
|
|
|
- roomResult.setRoomId(roomId);
|
|
|
|
|
|
// 课程人数
|
|
|
{
|
|
@@ -436,7 +583,6 @@ public class RoomServiceImpl implements RoomService {
|
|
|
roomResult.setRandomNumeric("1");
|
|
|
}
|
|
|
log.info("join room: roomId = {}, userId = {}, userName={}, role = {}", roomId, userId, userName, roleEnum);
|
|
|
- return new BaseResponse(roomResult);
|
|
|
}
|
|
|
|
|
|
private void joinImGroup(String roomId, Integer actualTeacherId, CourseSchedule courseSchedule) throws Exception {
|
|
@@ -504,10 +650,7 @@ public class RoomServiceImpl implements RoomService {
|
|
|
throw e;
|
|
|
}
|
|
|
|
|
|
- // 更新网络课服务提供方
|
|
|
- courseScheduleDao.updateServiceProvider(courseSchedule.getId(), courseSchedule.getServiceProvider());
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
private void dismissImGroup(String userId,String roomId, String serviceProvider) throws Exception {
|
|
|
log.info("dismissImGroup: roomId = {}, userId = {}", roomId, userId);
|
|
@@ -818,49 +961,55 @@ public class RoomServiceImpl implements RoomService {
|
|
|
|
|
|
// 删除群组信息
|
|
|
roomDao.deleteByRid(roomId);
|
|
|
- // 删除白板信息
|
|
|
- deleteWhiteboardByUser(roomId, userId);
|
|
|
- // 删除群组
|
|
|
- this.dismissImGroup(userId, roomId, courseSchedule.getServiceProvider());
|
|
|
- //关闭所有曲目播放
|
|
|
- courseScheduleStudentMusicScoreDao.closePlayStatus(courseSchedule.getId(), null, null);
|
|
|
+
|
|
|
+ if (GroupType.LIVE != courseSchedule.getGroupType()) {
|
|
|
+ // 删除白板信息
|
|
|
+ deleteWhiteboardByUser(roomId, userId);
|
|
|
+ // 删除群组
|
|
|
+ this.dismissImGroup(userId, roomId, courseSchedule.getServiceProvider());
|
|
|
+ //关闭所有曲目播放
|
|
|
+ courseScheduleStudentMusicScoreDao.closePlayStatus(courseSchedule.getId(), null, null);
|
|
|
+ }
|
|
|
log.info("leaveRoomSuccess dismiss the room: {}, userId: {}, role={}", roomId, userId, roleEnum.name());
|
|
|
|
|
|
} else {
|
|
|
roomMemberDao.deleteUserByRidAndUid(roomId, userId);
|
|
|
|
|
|
- // 获取RTC服务提供方
|
|
|
- String rtcServiceProvider = Optional.ofNullable(courseSchedule.getServiceProvider()).orElse("rongCloud");
|
|
|
-
|
|
|
- RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(rtcServiceProvider);
|
|
|
- if (rtcServiceProvider.equals(TencentCloudRTCPlugin.PLUGIN_NAME)) {
|
|
|
- // 腾讯云RTC服务
|
|
|
- RTCRoomMessage.MessageContent messageContent = RTCRoomMessage.MessageContent
|
|
|
- .builder()
|
|
|
- .action(EMemberAction.LEAVE.getValue())
|
|
|
- .role(roleEnum.getValue())
|
|
|
- .handUpOn(false)
|
|
|
- .timestamp(System.currentTimeMillis())
|
|
|
- .microphone(false)
|
|
|
- .camera(false)
|
|
|
- .sendUserInfo(getSendUser(userId, roleEnum))
|
|
|
- .build();
|
|
|
-
|
|
|
- RTCRoomMessage roomMessage = RTCRoomMessage.builder()
|
|
|
- .objectName(RTCRoomMessage.MEMBER_CHANGE_MESSAGE)
|
|
|
- .toChatRoomId(roomId)
|
|
|
- .content(messageContent)
|
|
|
- .fromUserId(userId)
|
|
|
- .isPersisted(1)
|
|
|
- .isIncludeSender(1)
|
|
|
- .build();
|
|
|
-
|
|
|
- pluginService.sendChatRoomMessage(roomMessage);
|
|
|
- } else {
|
|
|
- MemberChangedMessage msg = new MemberChangedMessage(MemberChangedMessage.Action_Leave, userId, roleEnum.getValue());
|
|
|
- msg.setUserName(username);
|
|
|
- imHelper.publishMessage(userId, roomId, msg);
|
|
|
+ if (GroupType.LIVE != courseSchedule.getGroupType()) {
|
|
|
+
|
|
|
+ // 获取RTC服务提供方
|
|
|
+ String rtcServiceProvider = Optional.ofNullable(courseSchedule.getServiceProvider()).orElse("rongCloud");
|
|
|
+
|
|
|
+ RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(rtcServiceProvider);
|
|
|
+ if (rtcServiceProvider.equals(TencentCloudRTCPlugin.PLUGIN_NAME)) {
|
|
|
+ // 腾讯云RTC服务
|
|
|
+ RTCRoomMessage.MessageContent messageContent = RTCRoomMessage.MessageContent
|
|
|
+ .builder()
|
|
|
+ .action(EMemberAction.LEAVE.getValue())
|
|
|
+ .role(roleEnum.getValue())
|
|
|
+ .handUpOn(false)
|
|
|
+ .timestamp(System.currentTimeMillis())
|
|
|
+ .microphone(false)
|
|
|
+ .camera(false)
|
|
|
+ .sendUserInfo(getSendUser(userId, roleEnum))
|
|
|
+ .build();
|
|
|
+
|
|
|
+ RTCRoomMessage roomMessage = RTCRoomMessage.builder()
|
|
|
+ .objectName(RTCRoomMessage.MEMBER_CHANGE_MESSAGE)
|
|
|
+ .toChatRoomId(roomId)
|
|
|
+ .content(messageContent)
|
|
|
+ .fromUserId(userId)
|
|
|
+ .isPersisted(1)
|
|
|
+ .isIncludeSender(1)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ pluginService.sendChatRoomMessage(roomMessage);
|
|
|
+ } else {
|
|
|
+ MemberChangedMessage msg = new MemberChangedMessage(MemberChangedMessage.Action_Leave, userId, roleEnum.getValue());
|
|
|
+ msg.setUserName(username);
|
|
|
+ imHelper.publishMessage(userId, roomId, msg);
|
|
|
// imHelper.quit(new String[]{userId}, roomId);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
log.info("leaveRoomSuccess quit group: roomId={}, userId: {}, roomMembers={}", roomId, userId, roomMembers);
|