فهرست منبع

Merge branch 'feature/0803-im'

zouxuan 1 سال پیش
والد
کامیت
4a0b8606ee
37فایلهای تغییر یافته به همراه1123 افزوده شده و 1001 حذف شده
  1. 59 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/entity/BaseResponse.java
  2. 61 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ErrorEnum.java
  3. 0 9
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentPaymentDao.java
  4. 27 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ImNetworkRoomMemberStatusMapper.java
  5. 2 40
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/BasicUserInfo.java
  6. 2 32
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/CourseScheduleStudentMusicSheetResult.java
  7. 2 16
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkBaseDto.java
  8. 9 57
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkCustomMessage.java
  9. 5 41
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkDisplayDataDto.java
  10. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkMetronomeMessage.java
  11. 2 30
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkMusicSheetDto.java
  12. 2 112
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudentPayment.java
  13. 2 60
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImNetworkRoom.java
  14. 3 117
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImNetworkRoomMember.java
  15. 52 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImNetworkRoomMemberStatus.java
  16. 27 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/ImNetworkRoomMemberStatusMapper.java
  17. 0 13
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleStudentPaymentService.java
  18. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java
  19. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImNetworkRoomMemberService.java
  20. 53 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImNetworkRoomMemberStatusService.java
  21. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImNetworkRoomService.java
  22. 25 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImService.java
  23. 37 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/RoomService.java
  24. 0 17
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleStudentPaymentServiceImpl.java
  25. 71 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  26. 27 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImNetworkRoomMemberServiceImpl.java
  27. 102 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImNetworkRoomMemberStatusServiceImpl.java
  28. 65 356
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImNetworkRoomServiceImpl.java
  29. 166 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImServiceImpl.java
  30. 183 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/RoomServiceImpl.java
  31. 63 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/ImNetworkRoomMemberStatusWrapper.java
  32. 0 11
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml
  33. 0 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/ImNetworkRoomMapper.xml
  34. 13 12
      cooleshow-user/user-biz/src/main/resources/config/mybatis/ImNetworkRoomMemberMapper.xml
  35. 23 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/ImNetworkRoomMemberStatusMapper.xml
  36. 0 29
      cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomMemberController.java
  37. 28 34
      cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/controller/RoomController.java

+ 59 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/entity/BaseResponse.java

@@ -0,0 +1,59 @@
+package com.yonge.cooleshow.common.entity;
+
+import com.yonge.cooleshow.common.enums.ErrorEnum;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import static com.yonge.cooleshow.common.enums.ErrorEnum.ERR_SUCCESS;
+
+@Data
+public class BaseResponse<T> {
+    private @Getter int errCode;
+    private @Setter @Getter String errMsg;
+    private @Setter @Getter String errDetail;
+    private @Getter BaseResponseResult data;
+
+
+    public void setData(T data) {
+        this.data = new BaseResponseResult<T>(data);
+    }
+
+    public static <T> BaseResponse<T> success(T data) {
+        BaseResponse<T> response = success();
+        response.setData(data);
+        return response;
+    }
+
+    public static <T> BaseResponse<T> success() {
+        BaseResponse<T> response = new BaseResponse();
+        response.setErr(ERR_SUCCESS);
+        return response;
+    }
+
+    public static <T> BaseResponse<T> failed(ErrorEnum err,T data) {
+        BaseResponse<T> response = failed(err);
+        response.setData(data);
+        return response;
+    }
+
+    public static <T> BaseResponse<T> failed(ErrorEnum err) {
+        BaseResponse<T> response = new BaseResponse();
+        response.setErr(err);
+        return response;
+    }
+
+    public void setErr(ErrorEnum error) {
+        this.errCode = error.getErrCode();
+        this.errMsg = error.getErrMsg();
+        this.errDetail = error.getErrMsg();
+    }
+
+    class BaseResponseResult<R> {
+        private @Setter @Getter R result;
+
+        BaseResponseResult(R result) {
+            this.result = result;
+        }
+    }
+}

+ 61 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ErrorEnum.java

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.common.enums;
+
+import lombok.Getter;
+
+/**
+ * Created by weiqinxiao on 2019/2/25.
+ */
+public enum ErrorEnum {
+    ERR_SUCCESS(0x0000, "OK"),
+    ERR_OTHER(0x00FF, "Error"),
+    ERR_BIZ_EX(500, "业务异常"),
+
+    ERR_REQUEST_PARA_ERR(1, "Missing or invalid parameter"),
+    ERR_INVALID_AUTH(2, "Invalid or expired authorization"),
+    ERR_ACCESS_DENIED(3, "Access denied"),
+    ERR_BAD_REQUEST(4, "Bad request"),
+
+    //IM error
+    ERR_IM_TOKEN_ERROR(10, "IM token error"),
+    ERR_CREATE_ROOM_ERROR(11, "Create room error"),
+    ERR_JOIN_ROOM_ERROR(12, "Join room error"),
+    JOIN_ROOM_ERROR(35, "加入房间失败,请前往线下教室"),
+    ROOM_NOT_START(36, "网络教室暂未开启,请稍后重试"),
+    CLOUD_BALANCE_NOT_FEE(37, "云教室受限不可进入,请联系教务老师。"),
+    ERR_MESSAGE_ERROR(13, "IM Message send error"),
+
+
+    //room error
+    ERR_ROOM_NOT_EXIST(20, "Room not exist"),
+    ERR_USER_NOT_EXIST_IN_ROOM(21, "User not exist in room"),
+    ERR_EXIT_ROOM_ERROR(22, "Exit room error"),
+    ERR_TEACHER_NOT_EXIST_IN_ROOM(23, "Teacher not exist in room"),
+    ERR_ASSISTANT_NOT_EXIST_IN_ROOM(24, "Assistant not exist in room"),
+    ERR_CREATE_WHITE_BOARD(25, "Create whiteboard error"),
+    ERR_WHITE_BOARD_NOT_EXIST(26, "Whiteboard not exist"),
+    ERR_DELETE_WHITE_BOARD(27, "Delete whiteboard error"),
+    ERR_USER_EXIST_IN_ROOM(28, "User exist in room"),
+    ERR_CHANGE_SELF_ROLE(29, "Can not change self role"),
+    ERR_APPLY_TICKET_INVALID(30, "Apply ticket invalid"),
+    ERR_OVER_MAX_COUNT(31, "云教室人数已超上线"),
+    ERR_TEACHER_EXIST_IN_ROOM(32, "Teacher exist in room"),
+    ERR_DOWNGRADE_ROLE(33, "Can't downgrade role"),
+    ERR_CHANGE_ROLE(34, "Only change student to teacher");
+
+    private @Getter int errCode;
+    private @Getter String errMsg;
+    private ErrorEnum(int errCode, String errMsg) {
+        this.errCode = errCode;
+        this.errMsg = errMsg;
+    }
+
+    public static ErrorEnum getEnumByValue(long errCode) {
+        for(ErrorEnum item : ErrorEnum.values()) {
+            if(item.getErrCode() == errCode) {
+                return item;
+            }
+        }
+
+        throw new IllegalArgumentException();
+    }
+}

+ 0 - 9
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentPaymentDao.java

@@ -57,15 +57,6 @@ public interface CourseScheduleStudentPaymentDao extends BaseMapper<CourseSchedu
      */
     List<String> selectOrderNoByGroupId(Long courseGroupId);
 
-    //重置节拍器设置
-    void cleanPlayMidi(@Param("courseScheduleId") Long courseScheduleId);
-
-    //获取节拍器数据
-    String getMidiByCourseIdAndUserId(@Param("courseScheduleId") Long courseScheduleId, @Param("userId") Long userId);
-
-    //获取伴奏数据
-    String getMusicSheetByCourseIdAndUserId(@Param("courseScheduleId") Long courseScheduleId, @Param("userId") Long userId);
-
     //调整节拍器
     void adjustPlayMidi(@Param("courseScheduleId") long courseScheduleId, @Param("userId") String userId, @Param("content") String content);
 

+ 27 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ImNetworkRoomMemberStatusMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMemberStatus;
+import com.yonge.cooleshow.biz.dal.wrapper.ImNetworkRoomMemberStatusWrapper;
+
+/**
+ * 网络教室成员状态表
+ * 2023-08-14 15:47:02
+ */
+@Repository
+public interface ImNetworkRoomMemberStatusMapper extends BaseMapper<ImNetworkRoomMemberStatus> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus>
+	 * @param param ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery
+	 * @return List<ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus>
+	 */
+	List<ImNetworkRoomMemberStatus> selectPage(@Param("page") IPage<ImNetworkRoomMemberStatus> page, @Param("param") ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery param);
+	
+}

+ 2 - 40
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/BasicUserInfo.java

@@ -1,12 +1,14 @@
 package com.yonge.cooleshow.biz.dal.dto;
 
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 /**
 * @description: 用户基本信息
 * @author zx
 * @date 2022/3/22 13:51
 */
+@Data
 public class BasicUserInfo {
     @ApiModelProperty(value = "用户编号", required = true)
     private Long userId;
@@ -22,44 +24,4 @@ public class BasicUserInfo {
 
     @ApiModelProperty("IM用户ID")
     private String imUserId;
-
-    public String getAvatar() {
-        return avatar;
-    }
-
-    public void setAvatar(String avatar) {
-        this.avatar = avatar;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getRealName() {
-        return realName;
-    }
-
-    public void setRealName(String realName) {
-        this.realName = realName;
-    }
-
-    public String getImUserId() {
-        return imUserId;
-    }
-
-    public void setImUserId(String imUserId) {
-        this.imUserId = imUserId;
-    }
 }

+ 2 - 32
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/CourseScheduleStudentMusicSheetResult.java

@@ -2,7 +2,9 @@ package com.yonge.cooleshow.biz.dal.dto;
 
 import com.yonge.cooleshow.biz.dal.entity.CourseScheduleStudentMusicSheet;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
+@Data
 public class CourseScheduleStudentMusicSheetResult extends CourseScheduleStudentMusicSheet {
     @ApiModelProperty(value = "原音")
     private String mp3Url;
@@ -15,36 +17,4 @@ public class CourseScheduleStudentMusicSheetResult extends CourseScheduleStudent
 
     @ApiModelProperty(value = "伴奏音量")
     private Integer soundVolume = 100;
-
-    public Integer getSoundVolume() {
-        return soundVolume;
-    }
-
-    public void setSoundVolume(Integer soundVolume) {
-        this.soundVolume = soundVolume;
-    }
-
-    public String getMp3Url() {
-        return mp3Url;
-    }
-
-    public void setMp3Url(String mp3Url) {
-        this.mp3Url = mp3Url;
-    }
-
-    public String getAudioFileUrl() {
-        return audioFileUrl;
-    }
-
-    public void setAudioFileUrl(String audioFileUrl) {
-        this.audioFileUrl = audioFileUrl;
-    }
-
-    public String getMusicSheetName() {
-        return musicSheetName;
-    }
-
-    public void setMusicSheetName(String musicSheetName) {
-        this.musicSheetName = musicSheetName;
-    }
 }

+ 2 - 16
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkBaseDto.java

@@ -2,7 +2,9 @@ package com.yonge.cooleshow.biz.dal.dto;
 
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
+@Data
 public class ImNetworkBaseDto {
 
     @ApiModelProperty(value = "房间号(课程编号)",required = true)
@@ -10,20 +12,4 @@ public class ImNetworkBaseDto {
 
     @ApiModelProperty("客户端类型 ")
     private ClientEnum clientType;
-
-    public Long getRoomId() {
-        return roomId;
-    }
-
-    public void setRoomId(Long roomId) {
-        this.roomId = roomId;
-    }
-
-    public ClientEnum getClientType() {
-        return clientType;
-    }
-
-    public void setClientType(ClientEnum clientType) {
-        this.clientType = clientType;
-    }
 }

+ 9 - 57
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkCustomMessage.java

@@ -3,8 +3,10 @@ package com.yonge.cooleshow.biz.dal.dto;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import io.rong.messages.BaseMessage;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 import org.apache.commons.lang3.StringUtils;
 
+@Data
 public class ImNetworkCustomMessage extends BaseMessage {
     @ApiModelProperty(value = "节拍器开关",required = true)
     private boolean enable;
@@ -21,67 +23,17 @@ public class ImNetworkCustomMessage extends BaseMessage {
     @ApiModelProperty(value = "学员编号列表,都还分割",required = true)
     private String userId;
 
-    @ApiModelProperty(value = "房间号(课程编号)",required = true)
-    private Long roomId;
+    @ApiModelProperty(value = "当前用户")
+    private Long currentUserId;
+
+    @ApiModelProperty(value = "房间号",required = true)
+    private String roomId;
 
     @ApiModelProperty("客户端类型")
     private ClientEnum clientType;
 
-    public Long getRoomId() {
-        return roomId;
-    }
-
-    public void setRoomId(Long roomId) {
-        this.roomId = roomId;
-    }
-
-    public int getPlayVolume() {
-        return playVolume;
-    }
-
-    public void setPlayVolume(int playVolume) {
-        this.playVolume = playVolume;
-    }
-
-    public Boolean getEnable() {
-        return enable;
-    }
-
-    public void setEnable(Boolean enable) {
-        this.enable = enable;
-    }
-
-    public int getCustomType() {
-        return customType;
-    }
-
-    public void setCustomType(int customType) {
-        this.customType = customType;
-    }
-
-    public int getRate() {
-        return rate;
-    }
-
-    public void setRate(int rate) {
-        this.rate = rate;
-    }
-
-    public String getUserId() {
-        return userId;
-    }
-
-    public void setUserId(String userId) {
-        this.userId = userId;
-    }
-
-    public ClientEnum getClientType() {
-        return clientType;
-    }
-
-    public void setClientType(ClientEnum clientType) {
-        this.clientType = clientType;
-    }
+    @ApiModelProperty("服务提供方")
+    private String serviceProvider;
 
     @Override
     public String getType() {

+ 5 - 41
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkDisplayDataDto.java

@@ -3,7 +3,9 @@ package com.yonge.cooleshow.biz.dal.dto;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImNetworkDisplayEnum;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
+@Data
 public class ImNetworkDisplayDataDto {
 
 	@ApiModelProperty(value = "房间号",required = true)
@@ -13,7 +15,9 @@ public class ImNetworkDisplayDataDto {
     private ImNetworkDisplayEnum type;
 
 	@ApiModelProperty(value = "即将展示的对应人的 userId",required = true)
-    private String userId;
+    private Long userId;
+
+	private Long teacherId;
 
 	@ApiModelProperty(value = "display uri",required = true)
     private String uri;
@@ -21,46 +25,6 @@ public class ImNetworkDisplayDataDto {
 	@ApiModelProperty("客户端类型 ")
 	private ClientEnum clientType;
 
-	public String getRoomId() {
-		return roomId;
-	}
-
-	public void setRoomId(String roomId) {
-		this.roomId = roomId;
-	}
-
-	public ImNetworkDisplayEnum getType() {
-		return type;
-	}
-
-	public void setType(ImNetworkDisplayEnum type) {
-		this.type = type;
-	}
-
-	public String getUserId() {
-		return userId;
-	}
-
-	public void setUserId(String userId) {
-		this.userId = userId;
-	}
-
-	public String getUri() {
-		return uri;
-	}
-
-	public void setUri(String uri) {
-		this.uri = uri;
-	}
-
-	public ClientEnum getClientType() {
-		return clientType;
-	}
-
-	public void setClientType(ClientEnum clientType) {
-		this.clientType = clientType;
-	}
-
 	@Override
 	public String toString() {
 		return "ImNetworkDisplayDataDto{" +

+ 1 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkMetronomeMessage.java

@@ -23,7 +23,7 @@ public class ImNetworkMetronomeMessage extends BaseMessage {
 
     @Override
     public String toString() {
-        return "{\"enable\":" + content.getEnable() +
+        return "{\"enable\":" + content.isEnable() +
                 ", \"customType\":" + content.getCustomType() +
                 ", \"rate\":" + content.getRate() +
                 ", \"playVolume\":" + content.getPlayVolume() +

+ 2 - 30
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/ImNetworkMusicSheetDto.java

@@ -1,8 +1,9 @@
 package com.yonge.cooleshow.biz.dal.dto;
 
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
+@Data
 public class ImNetworkMusicSheetDto extends ImNetworkBaseDto{
 
     @ApiModelProperty(value = "伴奏编号",required = true)
@@ -11,35 +12,6 @@ public class ImNetworkMusicSheetDto extends ImNetworkBaseDto{
     @ApiModelProperty(value = "伴奏下载状态(1下载成功0下载中2下载失败)",required = true)
     private Integer status;
 
-    @ApiModelProperty("客户端类型 ")
-    private ClientEnum clientType;
-
-    public Long getAccompanimentId() {
-        return accompanimentId;
-    }
-
-    public void setAccompanimentId(Long accompanimentId) {
-        this.accompanimentId = accompanimentId;
-    }
-
-    public Integer getStatus() {
-        return status;
-    }
-
-    public void setStatus(Integer status) {
-        this.status = status;
-    }
-
-    @Override
-    public ClientEnum getClientType() {
-        return clientType;
-    }
-
-    @Override
-    public void setClientType(ClientEnum clientType) {
-        this.clientType = clientType;
-    }
-
     @Override
     public String toString() {
         return "ImNetworkMusicSheetDto{" +

+ 2 - 112
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudentPayment.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -17,6 +18,7 @@ import java.util.Date;
  * @author hgw
  * @since 2022-03-23 14:35:20
  */
+@Data
 @ApiModel(value = "course_schedule_student_payment-课程学生缴费表")
 public class CourseScheduleStudentPayment implements Serializable {
     @TableId(value = "id_", type = IdType.AUTO)
@@ -63,117 +65,5 @@ public class CourseScheduleStudentPayment implements Serializable {
     @ApiModelProperty(value = "类型 practice陪练课 live直播课")
     private String courseType;
 
-    @TableField("play_midi_")
-    @ApiModelProperty(value = "网络教室节拍器参数")
-    private String playMidi;
-
-    @TableField("music_sheet_download_json_")
-    @ApiModelProperty(value = "网络教室当前课程曲目下载信息")
-    private String musicSheetDownloadJson;
-
-    public String getMusicSheetDownloadJson() {
-        return musicSheetDownloadJson;
-    }
-
-    public void setMusicSheetDownloadJson(String musicSheetDownloadJson) {
-        this.musicSheetDownloadJson = musicSheetDownloadJson;
-    }
-
-    public String getPlayMidi() {
-        return playMidi;
-    }
-
-    public void setPlayMidi(String playMidi) {
-        this.playMidi = playMidi;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public Long getCourseGroupId() {
-        return courseGroupId;
-    }
-
-    public void setCourseGroupId(Long courseGroupId) {
-        this.courseGroupId = courseGroupId;
-    }
-
-    public Long getCourseId() {
-        return courseId;
-    }
-
-    public void setCourseId(Long courseId) {
-        this.courseId = courseId;
-    }
-
-    public String getOrderNo() {
-        return orderNo;
-    }
-
-    public void setOrderNo(String orderNo) {
-        this.orderNo = orderNo;
-    }
-
-    public BigDecimal getOriginalPrice() {
-        return originalPrice;
-    }
-
-    public void setOriginalPrice(BigDecimal originalPrice) {
-        this.originalPrice = originalPrice;
-    }
-
-    public BigDecimal getExpectPrice() {
-        return expectPrice;
-    }
-
-    public void setExpectPrice(BigDecimal expectPrice) {
-        this.expectPrice = expectPrice;
-    }
-
-    public BigDecimal getActualPrice() {
-        return actualPrice;
-    }
-
-    public void setActualPrice(BigDecimal actualPrice) {
-        this.actualPrice = actualPrice;
-    }
-
-    public Date getCreatedTime() {
-        return createdTime;
-    }
-
-    public void setCreatedTime(Date createdTime) {
-        this.createdTime = createdTime;
-    }
-
-    public Date getUpdatedTime() {
-        return updatedTime;
-    }
-
-    public void setUpdatedTime(Date updatedTime) {
-        this.updatedTime = updatedTime;
-    }
-
-    public String getCourseType() {
-        return courseType;
-    }
-
-    public void setCourseType(String courseType) {
-        this.courseType = courseType;
-    }
-
 }
 

+ 2 - 60
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImNetworkRoom.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
 
 import java.io.Serializable;
 
@@ -17,6 +18,7 @@ import java.io.Serializable;
  * @author zx
  * @since 2022-03-30 16:36:36
  */
+@Data
 @ApiModel(value = "im_network_room-网络教室房间")
 public class ImNetworkRoom implements Serializable {
     @TableId(value = "id_", type = IdType.AUTO)
@@ -27,10 +29,6 @@ public class ImNetworkRoom implements Serializable {
     @ApiModelProperty(value = "房间编号;")
     private String roomId;
 
-    @TableField("course_schedule_id_")
-    @ApiModelProperty(value = "课程编号")
-    private Long courseScheduleId;
-
     @TableField("display_")
     @ApiModelProperty(value = "用于移动端房间渲染")
     //type 1老师0助教
@@ -48,61 +46,5 @@ public class ImNetworkRoom implements Serializable {
     @ApiModelProperty(value = "创建时间;")
     private Date createTime;
 
-    public Integer getSoundVolume() {
-        return soundVolume;
-    }
-
-    public void setSoundVolume(Integer soundVolume) {
-        this.soundVolume = soundVolume;
-    }
-
-    public String getDisplay() {
-        return display;
-    }
-
-    public void setDisplay(String display) {
-        this.display = display;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public String getRoomId() {
-        return roomId;
-    }
-
-    public void setRoomId(String roomId) {
-        this.roomId = roomId;
-    }
-
-    public Long getCourseScheduleId() {
-        return courseScheduleId;
-    }
-
-    public void setCourseScheduleId(Long courseScheduleId) {
-        this.courseScheduleId = courseScheduleId;
-    }
-
-    public Date getUpdateTime() {
-        return updateTime;
-    }
-
-    public void setUpdateTime(Date updateTime) {
-        this.updateTime = updateTime;
-    }
-
-    public Date getCreateTime() {
-        return createTime;
-    }
-
-    public void setCreateTime(Date createTime) {
-        this.createTime = createTime;
-    }
-
 }
 

+ 3 - 117
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImNetworkRoomMember.java

@@ -9,6 +9,7 @@ import com.yonge.cooleshow.biz.dal.dto.CourseScheduleStudentMusicSheetResult;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.util.List;
@@ -19,16 +20,13 @@ import java.util.List;
  * @author zx
  * @since 2022-03-30 16:36:37
  */
+@Data
 @ApiModel(value = "im_network_room_member-网络教室成员")
 public class ImNetworkRoomMember implements Serializable {
     @TableId(value = "id_", type = IdType.AUTO)
     @ApiModelProperty(value = "主键;")
     private Long id;
 
-    @TableField("course_schedule_id_")
-    @ApiModelProperty(value = "课程编号")
-    private Long courseScheduleId;
-
     @TableField("room_id_")
     @ApiModelProperty(value = "房间号")
     private String roomId;
@@ -72,120 +70,8 @@ public class ImNetworkRoomMember implements Serializable {
     @ApiModelProperty(value = "当前用户伴奏信息")
     private List<CourseScheduleStudentMusicSheetResult> musicSheetResults;
 
-    @TableField(exist = false)
+    @TableField("im_user_id_")
     @ApiModelProperty(value = "IM用户ID")
     private String imUserId;
-
-    public List<CourseScheduleStudentMusicSheetResult> getMusicSheetResults() {
-        return musicSheetResults;
-    }
-
-    public void setMusicSheetResults(List<CourseScheduleStudentMusicSheetResult> musicSheetResults) {
-        this.musicSheetResults = musicSheetResults;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getAvatar() {
-        return avatar;
-    }
-
-    public void setAvatar(String avatar) {
-        this.avatar = avatar;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Long getCourseScheduleId() {
-        return courseScheduleId;
-    }
-
-    public void setCourseScheduleId(Long courseScheduleId) {
-        this.courseScheduleId = courseScheduleId;
-    }
-
-    public String getRoomId() {
-        return roomId;
-    }
-
-    public void setRoomId(String roomId) {
-        this.roomId = roomId;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public Date getJoinTime() {
-        return joinTime;
-    }
-
-    public void setJoinTime(Date joinTime) {
-        this.joinTime = joinTime;
-    }
-
-    public Integer getRole() {
-        return role;
-    }
-
-    public void setRole(Integer role) {
-        this.role = role;
-    }
-
-    public boolean isCameraFlag() {
-        return cameraFlag;
-    }
-
-    public void setCameraFlag(boolean cameraFlag) {
-        this.cameraFlag = cameraFlag;
-    }
-
-    public boolean isMicFlag() {
-        return micFlag;
-    }
-
-    public void setMicFlag(boolean micFlag) {
-        this.micFlag = micFlag;
-    }
-
-    public boolean isMusicModeFlag() {
-        return musicModeFlag;
-    }
-
-    public void setMusicModeFlag(boolean musicModeFlag) {
-        this.musicModeFlag = musicModeFlag;
-    }
-
-    public boolean isHandFlag() {
-        return handFlag;
-    }
-
-    public void setHandFlag(boolean handFlag) {
-        this.handFlag = handFlag;
-    }
-
-    public String getImUserId() {
-        return imUserId;
-    }
-
-    public void setImUserId(String imUserId) {
-        this.imUserId = imUserId;
-    }
 }
 

+ 52 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImNetworkRoomMemberStatus.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import lombok.Data;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+
+/**
+ * 网络教室成员状态表
+ * 2023-08-14 15:47:02
+ */
+@Data
+@ApiModel(" ImNetworkRoomMemberStatus-网络教室成员状态表")
+@TableName("im_network_room_member_status")
+public class ImNetworkRoomMemberStatus implements Serializable {
+
+    @ApiModelProperty("主键;") 
+	    @TableId(value = "id_")
+	    private Long id;
+
+    @ApiModelProperty("房间号") 
+	@TableField(value = "room_id_")
+    private String roomId;
+
+    @ApiModelProperty("用户编号") 
+	@TableField(value = "user_id_")
+    private String userId;
+
+    @TableField(value = "im_user_id_")
+    @ApiModelProperty(value = "IM用户ID")
+    private String imUserId;
+
+    @ApiModelProperty("角色0学员1老师;") 
+	@TableField(value = "role_")
+    private Integer role;
+
+    @ApiModelProperty("网络教室节拍器参数") 
+	@TableField(value = "play_midi_")
+    private String playMidi;
+
+    @ApiModelProperty("网络教室当前课程曲目下载信息") 
+	@TableField(value = "music_sheet_download_json_")
+    private String musicSheetDownloadJson;
+
+}

+ 27 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/ImNetworkRoomMemberStatusMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMemberStatus;
+import com.yonge.cooleshow.biz.dal.wrapper.ImNetworkRoomMemberStatusWrapper;
+
+/**
+ * 网络教室成员状态表
+ * 2023-08-14 15:47:02
+ */
+@Repository
+public interface ImNetworkRoomMemberStatusMapper extends BaseMapper<ImNetworkRoomMemberStatus> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus>
+	 * @param param ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery
+	 * @return List<ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus>
+	 */
+	List<ImNetworkRoomMemberStatus> selectPage(@Param("page") IPage<ImNetworkRoomMemberStatus> page, @Param("param") ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery param);
+	
+}

+ 0 - 13
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleStudentPaymentService.java

@@ -47,19 +47,6 @@ public interface CourseScheduleStudentPaymentService extends IService<CourseSche
     List<String> getOrderNoByGroupId( Long courseGroupId);
 
     /**
-    * @description: 获取网络教室成员midi
-     * @param courseScheduleId
-     * @param userId
-    * @return com.yonge.cooleshow.biz.dal.dto.ImNetworkCustomMessage
-    * @author zx
-    * @date 2022/4/6 14:15
-    */
-    ImNetworkCustomMessage getMemberMidi(long courseScheduleId, Long userId);
-
-    //获取伴奏信息
-    ImNetworkRoomMusicSheetDownloadData getMemberExamSong(long courseScheduleId, Long userId);
-
-    /**
     * @description:
      * @param scheduleId    课程编号
      * @param userId    学员编号

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java

@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
 import com.yonge.cooleshow.biz.dal.dao.ImGroupDao;
+import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.dto.ImGroupResultDto;
 import com.yonge.cooleshow.biz.dal.dto.ImGroupSearchDto;
+import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
 import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImHistoryMessage;
@@ -176,11 +178,14 @@ public interface ImGroupService extends IService<ImGroup> {
      */
     void groupTransfer();
 
+    void joinImGroup(String roomId, BasicUserInfo userInfo, String serverProvider, List<Long> studentIds) throws Exception;
+
     /**
      * 用户导入
      */
     void importUser();
 
     int queryCount();
+
 }
 

+ 4 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImNetworkRoomMemberService.java

@@ -21,7 +21,10 @@ public interface ImNetworkRoomMemberService extends IService<ImNetworkRoomMember
 
     ImNetworkRoomMemberDao getDao();
 
-    ImNetworkRoomMember initRoomMember(String roomId, BasicUserInfo sysUser, RoleEnum userRole);
+    //初始化房间用户信息
+    ImNetworkRoomMember initRoomMember(String roomId, BasicUserInfo sysUser, RoleEnum userRole,Boolean microphone);
 
+    //获取房间用户列表
+    List<ImNetworkRoomMember> queryByRoomId(String roomId);
 }
 

+ 53 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImNetworkRoomMemberStatusService.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkCustomMessage;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkRoomMusicSheetDownloadData;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember;
+import com.yonge.cooleshow.biz.dal.wrapper.ImNetworkRoomMemberStatusWrapper;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMemberStatus;
+
+/**
+ * 网络教室成员状态表
+ * 2023-08-14 15:47:02
+ */
+public interface ImNetworkRoomMemberStatusService extends IService<ImNetworkRoomMemberStatus>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return ImNetworkRoomMemberStatus
+     */
+	ImNetworkRoomMemberStatus detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<ImNetworkRoomMemberStatus>
+     * @param query ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery
+     * @return IPage<ImNetworkRoomMemberStatus>
+     */
+    IPage<ImNetworkRoomMemberStatus> selectPage(IPage<ImNetworkRoomMemberStatus> page, ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery query);
+	
+    /**
+     * 添加
+     * @param imNetworkRoomMemberStatus ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus
+     * @return Boolean
+     */
+     Boolean add(ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus imNetworkRoomMemberStatus);   
+
+    /**
+     * 更新
+     * @param imNetworkRoomMemberStatus ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus
+     * @return Boolean
+     */
+     Boolean update(ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus imNetworkRoomMemberStatus);
+
+    void add(ImNetworkRoomMember roomMember);
+
+    //获取网络教室成员midi
+    ImNetworkCustomMessage getMemberMidi(String roomId, Long userId);
+
+    //获取伴奏信息
+    ImNetworkRoomMusicSheetDownloadData getMemberExamSong(String roomId, Long userId);
+}

+ 2 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImNetworkRoomService.java

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.biz.dal.dto.*;
 import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoom;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.UserRoleEnum;
+import com.yonge.cooleshow.common.entity.BaseResponse;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 import java.util.List;
@@ -21,7 +22,7 @@ public interface ImNetworkRoomService extends IService<ImNetworkRoom> {
     ImNetworkRoomDao getDao();
 
     //加入网络教室
-    HttpResponseResult<ImNetworkRoomResult> joinRoom(Long courseScheduleId, ClientEnum clientType) throws Exception;
+    BaseResponse<ImNetworkRoomResult> joinRoom(Long courseScheduleId, ClientEnum clientType) throws Exception;
 
     //加入网络教室成功
     void joinRoomSuccess(String roomId, String imUserId) throws Exception;

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImService.java

@@ -0,0 +1,25 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkCustomMessage;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoom;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 网络教室成员(ImNetworkRoomMember)表服务接口
+ *
+ * @author zx
+ * @since 2022-03-30 16:36:38
+ */
+public interface ImService{
+
+
+    //发送人员变动消息
+    void publishMemberChangedMessage(ImNetworkRoomMember roomMember,String serviceProvider) throws Exception;
+
+    //发送display改动通知
+    void sendDisplay(String imUserId, ImNetworkRoom room,String serviceProvider) throws Exception;
+
+    void sendImPlayMidiMessage(ImNetworkCustomMessage customMessage) throws Exception;
+}
+

+ 37 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/RoomService.java

@@ -0,0 +1,37 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.microsvc.toolkit.middleware.rtc.message.RTCRoomConfig;
+import com.yonge.cooleshow.biz.dal.dao.ImNetworkRoomDao;
+import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkDisplayDataDto;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoom;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember;
+import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
+
+/**
+ * 网络教室房间(ImNetworkRoom)表服务接口
+ *
+ * @author zx
+ * @since 2022-03-30 16:36:36
+ */
+public interface RoomService extends IService<ImNetworkRoom> {
+
+    ImNetworkRoomDao getDao();
+
+    //初始化网络教室基本信息
+    ImNetworkRoom initRoom(String roomId, RoleEnum userRole, Long userId) throws Exception;
+
+    //获取腾讯相关房间配置信息
+    RTCRoomConfig getRtcRoomConfig(String serviceProvider, BasicUserInfo basicUserInfo);
+
+    //用户成功推出房间
+    void quitRoomSuccess(RoleEnum roleEnum, ImNetworkRoomMember roomMember, String serviceProvider) throws Exception;
+
+    //修改节拍器
+    void updateDisplay(String imUserId, ImNetworkRoom room, String serviceProvider) throws Exception;
+
+    //移动端用来渲染页面
+    void display(ImNetworkDisplayDataDto displayData,String serviceProvider) throws Exception;
+}
+

+ 0 - 17
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleStudentPaymentServiceImpl.java

@@ -73,23 +73,6 @@ public class CourseScheduleStudentPaymentServiceImpl extends ServiceImpl<CourseS
 
     }
 
-    @Override
-    public ImNetworkCustomMessage getMemberMidi(long courseScheduleId, Long userId) {
-        String midi = baseMapper.getMidiByCourseIdAndUserId(courseScheduleId, userId);
-        if(StringUtils.isNotEmpty(midi)){
-            return JSONObject.parseObject(midi, ImNetworkCustomMessage.class);
-        }
-        return new ImNetworkCustomMessage();
-    }
-
-    @Override
-    public ImNetworkRoomMusicSheetDownloadData getMemberExamSong(long courseScheduleId, Long userId) {
-        String musicSheet = baseMapper.getMusicSheetByCourseIdAndUserId(courseScheduleId, userId);
-        if(StringUtils.isNotEmpty(musicSheet)){
-            return JSONObject.parseObject(musicSheet, ImNetworkRoomMusicSheetDownloadData.class);
-        }
-        return new ImNetworkRoomMusicSheetDownloadData();
-    }
 
     @Override
     @Transactional(rollbackFor = Exception.class)

+ 71 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java

@@ -16,12 +16,17 @@ import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
 import com.microsvc.toolkit.middleware.im.message.MessageWrapper;
 import com.microsvc.toolkit.middleware.im.message.TencentRequest;
 import com.microsvc.toolkit.middleware.im.properties.ImConfigProperties;
+import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginContext;
+import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginService;
+import com.microsvc.toolkit.middleware.rtc.impl.TencentCloudRTCPlugin;
+import com.microsvc.toolkit.middleware.rtc.message.ImGroupMemberWrapper;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.config.AppGlobalServiceConfig;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentPaymentDao;
 import com.yonge.cooleshow.biz.dal.dao.ImGroupDao;
 import com.yonge.cooleshow.biz.dal.dao.ImGroupMemberAuditDao;
+import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.dto.ImGroupResultDto;
 import com.yonge.cooleshow.biz.dal.dto.ImGroupSearchDto;
 import com.yonge.cooleshow.biz.dal.entity.*;
@@ -43,17 +48,13 @@ import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.TeacherService;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
-import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
-import com.yonge.cooleshow.biz.dal.entity.ImGroup;
-import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
-import com.yonge.cooleshow.biz.dal.entity.ImHistoryMessage;
-import com.yonge.cooleshow.biz.dal.entity.StudentStar;
-import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.support.IMHelper;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
@@ -77,6 +78,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -161,6 +163,13 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     @Autowired
     private ImConfigProperties imConfig;
 
+    @Autowired
+    private IMHelper imHelper;
+    @Resource
+    private RedisTemplate<String,Object> redisTemplate;
+    @Autowired
+    private RTCRoomPluginContext rtcRoomPluginContext;
+
 
     @Value("${cn.rongcloud.im.appkey}")
     private String appKey;
@@ -923,6 +932,62 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         return getDao().queryCount();
     }
 
+    @Override
+    public void joinImGroup(String roomId, BasicUserInfo userInfo, String serverProvider, List<Long> studentIds) throws Exception {
+
+        String joinImGroupKey = "joinImGroup:" + roomId;
+        // VIP课或网络课,IM群聊已创建标识
+        Boolean exists = redisTemplate.opsForValue().setIfAbsent(joinImGroupKey, roomId, 1L, TimeUnit.DAYS);
+
+        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(serverProvider);
+        if (Optional.ofNullable(exists).orElse(false)) {
+            // 群组老师信息
+            List<ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList(ImGroupMemberWrapper.ImGroupMember
+                    .builder()
+                    .userId(userInfo.getUserId())
+                    .imUserIdFormat(true)
+                    .build());
+
+            for (Long studentId : studentIds) {
+                groupMembers.add(ImGroupMemberWrapper.ImGroupMember
+                        .builder()
+                        .userId(studentId)
+                        .imUserIdFormat(false)
+                        .build());
+            }
+            try {
+                // 创建群组
+                log.info("createImGroup: roomId = {}, userId = {}", roomId, userInfo.getUserId());
+                if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
+
+                    // 群组帐号注册
+                    try {
+                        pluginService.register(userInfo.getImUserId(), userInfo.getRealName(), userInfo.getAvatar());
+                    } catch (Exception e) {
+                        log.error("直播房间群主注册失败: userId={}",userInfo.getUserId(), e);
+                    }
+
+                    // 生成群组
+                    pluginService.chatRoomCreate(roomId, roomId, userInfo.getImUserId());
+
+                    // 加入群组成员
+                    log.info("joinImGroup: roomId = {}, serviceProvider={}, userIds = {}", roomId,serverProvider, groupMembers);
+                    pluginService.chatRoomGroupJoin(roomId, roomId, groupMembers);
+                } else {
+                    String[] integers = groupMembers.stream().map(e->e.getImUserId()).collect(Collectors.toList()).toArray(new String[]{});
+                    imHelper.joinGroup(integers, roomId, roomId);
+                }
+
+            } catch (Exception e) {
+
+                redisTemplate.delete(joinImGroupKey);
+                // 异常抛出,删除缓存标识
+                throw e;
+            }
+
+        }
+    }
+
     private void groupTransfer(List<ImGroup> records) {
         String fansIcon = sysConfigService.findConfigValue(SysConfigConstant.ICON_FANS_GROUP_DEFAULT);
         String courseIcon = sysConfigService.findConfigValue(SysConfigConstant.ICON_COURSE_GROUP_DEFAULT);

+ 27 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImNetworkRoomMemberServiceImpl.java

@@ -4,17 +4,21 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yonge.cooleshow.biz.dal.dao.ImNetworkRoomMemberDao;
 import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMemberStatus;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 import com.yonge.cooleshow.biz.dal.enums.UserRoleEnum;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberService;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberStatusService;
+import com.yonge.cooleshow.common.enums.EStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -31,6 +35,9 @@ public class ImNetworkRoomMemberServiceImpl extends ServiceImpl<ImNetworkRoomMem
     @Autowired
     private ImGroupService imGroupService;
 
+    @Autowired
+    private ImNetworkRoomMemberStatusService imNetworkRoomMemberStatusService;
+
     @Override
     public ImNetworkRoomMemberDao getDao() {
         return this.baseMapper;
@@ -38,23 +45,22 @@ public class ImNetworkRoomMemberServiceImpl extends ServiceImpl<ImNetworkRoomMem
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public ImNetworkRoomMember initRoomMember(String roomId, BasicUserInfo sysUser, RoleEnum userRole) {
+    public ImNetworkRoomMember initRoomMember(String roomId, BasicUserInfo sysUser, RoleEnum userRole,Boolean microphone) {
         ImNetworkRoomMember roomMember = baseMapper.findByRidAndUid(roomId, sysUser.getUserId(), userRole.ordinal());
         if(Objects.isNull(roomMember)){
             roomMember = new ImNetworkRoomMember();
             roomMember.setRoomId(roomId);
             roomMember.setCameraFlag(true);
             roomMember.setHandFlag(false);
-            roomMember.setMicFlag(true);
+            roomMember.setMicFlag(microphone);
             roomMember.setMusicModeFlag(false);
             roomMember.setRole(userRole.ordinal());
             roomMember.setUserId(sysUser.getUserId());
-//            roomMember.setUsername(userRole == UserRoleEnum.STUDENT?sysUser.getUsername():sysUser.getRealName());
             roomMember.setUsername(sysUser.getUsername());
             roomMember.setAvatar(sysUser.getAvatar());
-            roomMember.setCourseScheduleId(Long.parseLong(roomId));
             baseMapper.insert(roomMember);
-
+            //生成用户房间状态表
+            imNetworkRoomMemberStatusService.add(roomMember);
         }
 
         roomMember.setImUserId(imGroupService.getImUserId(sysUser.getUserId(),userRole));
@@ -62,5 +68,21 @@ public class ImNetworkRoomMemberServiceImpl extends ServiceImpl<ImNetworkRoomMem
         return roomMember;
     }
 
+    @Override
+    public List<ImNetworkRoomMember> queryByRoomId(String roomId) {
+        //获取房间所有成员
+        List<ImNetworkRoomMember> roomMemberList = baseMapper.queryByRoomId(roomId);
+        for (ImNetworkRoomMember item : roomMemberList) {
+            if (EStatus.ENABLE.match(item.getRole())) {
+                // 老师
+                item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.TEACHER.name()));
+            } else {
+                // 学生
+                item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.STUDENT.name()));
+            }
+        }
+        return roomMemberList;
+    }
+
 }
 

+ 102 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImNetworkRoomMemberStatusServiceImpl.java

@@ -0,0 +1,102 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkCustomMessage;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkRoomMusicSheetDownloadData;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.beans.BeanUtils;
+import lombok.extern.slf4j.Slf4j;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMemberStatus;
+import com.yonge.cooleshow.biz.dal.wrapper.ImNetworkRoomMemberStatusWrapper;
+import com.yonge.cooleshow.biz.dal.mapper.ImNetworkRoomMemberStatusMapper;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberStatusService;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 网络教室成员状态表
+ * 2023-08-14 15:47:02
+ */
+@Slf4j
+@Service
+public class ImNetworkRoomMemberStatusServiceImpl extends ServiceImpl<ImNetworkRoomMemberStatusMapper, ImNetworkRoomMemberStatus> implements ImNetworkRoomMemberStatusService {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return ImNetworkRoomMemberStatus
+     */
+	@Override
+    public ImNetworkRoomMemberStatus detail(Long id) {
+        
+        return baseMapper.selectById(id);
+    }
+    
+    /**
+     * 分页查询
+     * @param page IPage<ImNetworkRoomMemberStatus>
+     * @param query ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery
+     * @return IPage<ImNetworkRoomMemberStatus>
+     */
+    @Override
+    public IPage<ImNetworkRoomMemberStatus> selectPage(IPage<ImNetworkRoomMemberStatus> page, ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatusQuery query) {
+        
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+	
+    /**
+     * 添加
+     * @param imNetworkRoomMemberStatus ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus imNetworkRoomMemberStatus) {    	
+        
+        return this.save(JSON.parseObject(imNetworkRoomMemberStatus.jsonString(), ImNetworkRoomMemberStatus.class));
+    }
+
+    /**
+     * 更新
+     * @param imNetworkRoomMemberStatus ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(ImNetworkRoomMemberStatusWrapper.ImNetworkRoomMemberStatus imNetworkRoomMemberStatus){
+
+        return this.updateById(JSON.parseObject(imNetworkRoomMemberStatus.jsonString(), ImNetworkRoomMemberStatus.class));       
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void add(ImNetworkRoomMember roomMember) {
+        ImNetworkRoomMemberStatus roomMemberStatus = new ImNetworkRoomMemberStatus();
+        roomMemberStatus.setRoomId(roomMember.getRoomId());
+        roomMemberStatus.setRole(roomMember.getRole());
+        roomMemberStatus.setImUserId(roomMember.getImUserId());
+        baseMapper.insert(roomMemberStatus);
+    }
+
+    @Override
+    public ImNetworkCustomMessage getMemberMidi(String roomId, Long userId) {
+        String midi = this.lambdaQuery().eq(ImNetworkRoomMemberStatus::getRoomId,roomId)
+                .eq(ImNetworkRoomMemberStatus::getUserId,userId).last("LIMIT 1").one().getPlayMidi();
+        if(StringUtils.isNotEmpty(midi)){
+            return JSONObject.parseObject(midi, ImNetworkCustomMessage.class);
+        }
+        return new ImNetworkCustomMessage();
+    }
+
+    @Override
+    public ImNetworkRoomMusicSheetDownloadData getMemberExamSong(String roomId, Long userId) {
+        String musicSheet = this.lambdaQuery().eq(ImNetworkRoomMemberStatus::getRoomId,roomId)
+                .eq(ImNetworkRoomMemberStatus::getUserId,userId).last("LIMIT 1").one().getMusicSheetDownloadJson();
+        if(StringUtils.isNotEmpty(musicSheet)){
+            return JSONObject.parseObject(musicSheet, ImNetworkRoomMusicSheetDownloadData.class);
+        }
+        return new ImNetworkRoomMusicSheetDownloadData();
+    }
+}

+ 65 - 356
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImNetworkRoomServiceImpl.java

@@ -10,6 +10,7 @@ import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginService;
 import com.microsvc.toolkit.middleware.rtc.enums.EMemberAction;
 import com.microsvc.toolkit.middleware.rtc.impl.TencentCloudRTCPlugin;
 import com.microsvc.toolkit.middleware.rtc.message.ImGroupMemberWrapper;
+import com.microsvc.toolkit.middleware.rtc.message.RTCRoomConfig;
 import com.microsvc.toolkit.middleware.rtc.message.RTCRoomMessage;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.ImNetworkRoomDao;
@@ -23,8 +24,10 @@ import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.IMHelper;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.entity.BaseResponse;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.cooleshow.common.enums.ErrorEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.utils.date.DateUtil;
 import org.apache.commons.lang3.StringUtils;
@@ -84,6 +87,12 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
 
     @Autowired
     private ImGroupService imGroupService;
+    @Autowired
+    private RoomService roomService;
+    @Autowired
+    private ImNetworkRoomMemberStatusService imNetworkRoomMemberStatusService;
+    @Autowired
+    private ImService imService;
 
     private String QUIT_ROOM_SUCCESS = "quitRoomSuccess:";
 
@@ -94,8 +103,7 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public HttpResponseResult<ImNetworkRoomResult> joinRoom(Long courseScheduleId, ClientEnum clientType) throws Exception {
-
+    public BaseResponse<ImNetworkRoomResult> joinRoom(Long courseScheduleId, ClientEnum clientType) throws Exception {
         // 当前登录用户ID
         Long userId = sysUserService.getUserId();
         CourseSchedule courseSchedule = Optional.ofNullable(courseScheduleService.getById(courseScheduleId)).
@@ -113,65 +121,50 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
         courseSchedule.setUpdatedTime(now);
         //是否提前进入教室
         if (roomNotStart(courseSchedule)) {
-            return HttpResponseResult.failed(ImNetworkRoomErrorEnum.ROOM_NOT_START.getRemark());
+            return BaseResponse.failed(ErrorEnum.ROOM_NOT_START);
         }
         String roomId = courseScheduleId.toString();
         ImNetworkRoomResult joinRoomResult = new ImNetworkRoomResult();
         //初始化房间信息
-        ImNetworkRoom room = this.initRoom(roomId,courseScheduleId,userRole,sysUser.getUserId(),now);
+        ImNetworkRoom room = roomService.initRoom(roomId,userRole,sysUser.getUserId());
         BeanUtils.copyProperties(room,joinRoomResult);
         //定时销毁房间
         //初始化房间用户信息
-        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.initRoomMember(roomId,sysUser,userRole);
+        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.initRoomMember(roomId,sysUser,userRole,!courseSchedule.getMuteAll());
         joinRoomResult.setRoomMember(roomMember);
         //获取教室剩余时长
         joinRoomResult.setSurplusTime(DateUtil.secondsBetween(now, courseSchedule.getEndTime()));
         //获取房间所有成员
-        List<ImNetworkRoomMember> roomMemberList = imNetworkRoomMemberService.getDao().queryByRoomId(roomId);
-        for (ImNetworkRoomMember item : roomMemberList) {
-            if (EStatus.ENABLE.match(item.getRole())) {
-                // 老师
-                item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.TEACHER.name()));
-            } else {
-                // 学生
-                item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.STUDENT.name()));
-            }
-        }
+        List<ImNetworkRoomMember> roomMemberList = imNetworkRoomMemberService.queryByRoomId(roomId);
+
         joinRoomResult.setRoomMemberList(roomMemberList);
-        //如果是老师,重置节拍器数据
+        //如果是老师,
         if(userRole == RoleEnum.RoleTeacher){
-            courseScheduleStudentPaymentService.getDao().cleanPlayMidi(courseScheduleId);
+            //重置节拍器数据
+            imNetworkRoomMemberStatusService.lambdaUpdate().set(ImNetworkRoomMemberStatus::getPlayMidi,null)
+                            .eq(ImNetworkRoomMemberStatus::getRoomId,roomId).update();
             //获取所有学员的伴奏下载详情
             setMusicSheetList(roomMemberList,courseScheduleId);
         }else {
             //获取节拍器信息
-            joinRoomResult.setMidiJson(courseScheduleStudentPaymentService.getMemberMidi(courseScheduleId, sysUser.getUserId()));
+            joinRoomResult.setMidiJson(imNetworkRoomMemberStatusService.getMemberMidi(roomId, sysUser.getUserId()));
         }
         //课程结束后关闭教室的时间
         joinRoomResult.setAutoCloseNetworkRoomTime(sysConfigDao.findConfigValue(SysConfigConstant.DESTROY_EXPIRED_PRACTICE_ROOM_MINUTE));
 
-        // IM用户ID
-        String imUserId = imGroupService.getImUserId(sysUser.getUserId(),userRole);
-        roomMember.setImUserId(imUserId);
         // 创建IM群聊
-        this.joinImGroup(roomId, courseSchedule.getTeacherId().intValue(), courseSchedule);
-        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(courseSchedule.getServiceProvider());
-        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
-            // 腾讯云RTC
-            // 用户IM帐号创建
-            String userSig = "";
-            try {
-                userSig = pluginService.register(String.valueOf(sysUser.getUserId()), sysUser.getRealName(), sysUser.getAvatar());
-            } catch (Exception e) {
-                log.error("直播房间用户注册失败: userId={}", sysUser.getUserId(), e);
-            }
-
-            // 返回配置参数
-            joinRoomResult.setUserSig(userSig);
-            joinRoomResult.setRtcRoomConfig(rtcRoomPluginContext.getPluginService().getRTCRoomConfig(String.valueOf(sysUser.getUserId())));
-            joinRoomResult.setGroupId(roomId);
-        }
-        return HttpResponseResult.succeed(joinRoomResult);
+        //获取老师基本信息
+        BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(courseSchedule.getTeacherId());
+        //获取学员列表
+        List<CourseScheduleStudentPayment> studentPayments = courseScheduleStudentPaymentService.getDao().queryByCourseId(courseScheduleId);
+        List<Long> studentIds = studentPayments.stream().map(e -> e.getUserId()).collect(Collectors.toList());
+        //创建并加入群组
+        imGroupService.joinImGroup(roomId, basicUserInfo,
+                courseSchedule.getServiceProvider(), studentIds);
+        //获取腾讯所需基本信息配置
+        joinRoomResult.setRtcRoomConfig(roomService.getRtcRoomConfig(courseSchedule.getServiceProvider(),sysUser));
+        joinRoomResult.setGroupId(roomId);
+        return BaseResponse.success(joinRoomResult);
     }
 
     private void setMusicSheetList(List<ImNetworkRoomMember> roomMemberList,Long courseScheduleId){
@@ -192,14 +185,12 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void joinRoomSuccess(String roomId, String imUserId) throws Exception {
-
+        log.info("joinRoomSuccess: roomId={}, imUserId={}", roomId, imUserId);
         // 用户ID
         Long userId = Long.parseLong(imGroupService.analysisImUserId(imUserId));
-
         // 客户端类型
         ClientEnum clientType = ClientEnum.valueOf(imGroupService.analysisImUserClient(imUserId));
 
-        log.info("joinRoomSuccess: roomId={}, userId={}", roomId, userId);
         CourseSchedule courseSchedule = Optional.ofNullable(courseScheduleService.getById(roomId)).
                 orElseThrow(()->new BizException("房间信息不存在"));
         BasicUserInfo sysUser = Optional.ofNullable(teacherDao.getBasicUserInfo(userId)).
@@ -214,54 +205,15 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
         }else {
             studentAttendanceService.signIn(userId,courseSchedule);
         }
-        Date now = new Date();
         //获取房间信息
-        ImNetworkRoom room = this.initRoom(roomId, Long.parseLong(roomId), userRole, userId, now);
+        ImNetworkRoom room = roomService.initRoom(roomId, userRole, userId);
         //获取房间用户信息
-        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.initRoomMember(roomId,sysUser,userRole);
-        // IM用户ID
-        roomMember.setImUserId(imUserId);
+        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.initRoomMember(roomId,sysUser,userRole,!courseSchedule.getMuteAll());
         //发送人员变动消息
         // 获取RTC服务提供方
-        String rtcServiceProvider = Optional.ofNullable(courseSchedule.getServiceProvider()).orElse("rongCloud");
-
-        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(rtcServiceProvider);
-        if (rtcServiceProvider.equals(TencentCloudRTCPlugin.PLUGIN_NAME)) {
-            // 腾讯云RTC服务
-            RTCRoomMessage.MessageContent.MessageContentBuilder action = RTCRoomMessage.MessageContent.builder()
-                    .action(EMemberAction.JOIN.getValue());
-
-            if (userRole == RoleEnum.RoleTeacher) {
-                action.role(userRole.getValue());
-            } else {
-                action.role(userRole.getValue());
-            }
-            action.handUpOn(roomMember.isHandFlag())
-                    .microphone(roomMember.isMicFlag())
-                    .timestamp(now.getTime())
-                    .camera(true)
-                    .sendUserInfo(getSendUser(sysUserService.findUserById(userId),userRole));
-
-            // 开启全员静音,重置学员状态
-            if (courseSchedule.getMuteAll()) {
-                action.microphone(false);
-            }
-
-            RTCRoomMessage roomMessage = RTCRoomMessage.builder()
-                    .objectName(RTCRoomMessage.MEMBER_CHANGE_MESSAGE)
-                    .fromUserId(userId.toString())
-                    .content(action.build())
-                    .toChatRoomId(roomId)
-                    .isPersisted(1)
-                    .isIncludeSender(1)
-                    .build();
-
-            pluginService.sendChatRoomMessage(roomMessage);
-        } else {
-            publishMemberChangedMessage(roomMember);
-        }
+        imService.publishMemberChangedMessage(roomMember,courseSchedule.getServiceProvider());
         //sendDisplay
-        this.sendDisplay(imUserId, room);
+        imService.sendDisplay(imUserId, room,courseSchedule.getServiceProvider());
     }
 
     private RTCRoomMessage.MessageUser getSendUser(SysUser sysUser,RoleEnum role) {
@@ -277,17 +229,6 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
         return build;
     }
 
-    //发送人员变动消息
-    private void publishMemberChangedMessage(ImNetworkRoomMember roomMember) throws Exception {
-        ImNetworkRoomMemberChangedMessage msg = new ImNetworkRoomMemberChangedMessage(roomMember,ImNetworkRoomMemberChangedEnum.JOIN);
-        //获取节拍器信息
-        ImNetworkCustomMessage imNetworkCustomMessage = courseScheduleStudentPaymentService.getMemberMidi(Long.parseLong(roomMember.getRoomId()), roomMember.getUserId());
-        msg.setMetronomeSwitch(imNetworkCustomMessage.getEnable());
-        //获取伴奏信息
-        ImNetworkRoomMusicSheetDownloadData musicSheetDownloadData = courseScheduleStudentPaymentService.getMemberExamSong(Long.parseLong(roomMember.getRoomId()), roomMember.getUserId());
-        msg.setExamSongSwitch(musicSheetDownloadData.getEnable());
-        imHelper.publishMessage(roomMember.getImUserId(), roomMember.getRoomId(), msg);
-    }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -310,17 +251,12 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void quitRoomSuccess(String roomId, String imUserId) throws Exception {
-
         // 用户ID
         Long userId = Long.parseLong(imGroupService.analysisImUserId(imUserId));
-
         // 客户端类型
         ClientEnum clientType = ClientEnum.valueOf(imGroupService.analysisImUserClient(imUserId));
-
-
         // 客户端类型
         UserRoleEnum userRole = UserRoleEnum.convert(clientType);
-
         log.info("quitRoomSuccess: roomId={}, userId={}", roomId, userId);
         //防止幂等
         StringBuffer sb  = new StringBuffer(QUIT_ROOM_SUCCESS).append(roomId).append(userId);
@@ -333,115 +269,44 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
         if(Objects.isNull(roomMember)){
             return;
         }
-        // 设置IM用户ID
-        roomMember.setImUserId(imUserId);
 
         CourseSchedule courseSchedule = Optional.ofNullable(courseScheduleService.getById(roomId))
                 .orElseThrow(()->new BizException("房间信息不存在"));
         Long courseScheduleId = courseSchedule.getId();
-        UserRoleEnum roleEnum = UserRoleEnum.STUDENT;
+        RoleEnum roleEnum = RoleEnum.RoleStudent;
         if(Objects.equals(courseSchedule.getTeacherId(),userId)
                 && ClientEnum.TEACHER == clientType){
-
-            roleEnum = UserRoleEnum.TEACHER;
+            roleEnum = RoleEnum.RoleTeacher;
             teacherAttendanceService.signOut(userId,courseSchedule);
         }else {
             //记录考勤签退
             studentAttendanceService.signOut(userId,courseSchedule);
         }
-        ImNetworkRoom room = baseMapper.findByRoomId(roomId);
-        if (roleEnum == UserRoleEnum.TEACHER){
-            //如果老师退出房间,关闭伴奏
-            courseScheduleStudentMusicSheetService.getDao().closePlayStatus(courseScheduleId,null);
-            courseScheduleStudentPaymentService.getDao().adjustPlayMidi(courseScheduleId, null, null);
-            courseScheduleStudentPaymentService.getDao().adjustExamSong(courseScheduleId, null, null);
-            if (isUserDisplay(room.getDisplay(), userId)) {
-                room.setDisplay("");
-                this.updateDisplay(imUserId,room);
-            }
-            //老师退出房间,初始化节拍器和伴奏播放配置
-            courseScheduleStudentPaymentService.adjustPlayMidiAndMusicSheet(courseSchedule.getId(), null, null,"");
-        }
-        int memberNum = imNetworkRoomMemberService.getDao().countByRoomId(roomId);
-        if (memberNum <= 1) {
-            imHelper.dismiss(imUserId, roomId);
-            courseScheduleStudentMusicSheetService.getDao().closePlayStatus(courseSchedule.getId(),null);
-            log.info("leaveRoomSuccess dismiss the room: {},userId: {}", roomId, userId);
-        } else {
-            ImNetworkRoomMemberChangedMessage msg = new ImNetworkRoomMemberChangedMessage(roomMember,ImNetworkRoomMemberChangedEnum.LEAVE);
-            imHelper.publishMessage(imUserId, roomId, msg);
-            imHelper.quit(new String[]{imUserId}, roomId);
-            log.info("leaveRoomSuccess quit group: roomId={},userId: {}", roomId, userId);
-        }
-        //删房间用户信息
-        imNetworkRoomMemberService.getDao().deleteById(roomMember.getId());
-    }
-
-
-    private String getImUserId(Long userId,ClientEnum clientEnum){
-        String imUserId = String.valueOf(userId);
-        if (ClientEnum.STUDENT == clientEnum) {
-            imUserId = imGroupService.getImUserId( imUserId, ClientEnum.STUDENT.name());
-        }
-        return imUserId;
-    }
 
-    private String getImUserId(Long userId,RoleEnum clientEnum){
-        String imUserId = String.valueOf(userId);
-        if (RoleEnum.RoleStudent == clientEnum) {
-            imUserId = imGroupService.getImUserId(imUserId, ClientEnum.STUDENT.name());
+        if (roleEnum == RoleEnum.RoleTeacher || imNetworkRoomMemberService.getDao().countByRoomId(roomId) <= 1){
+            //如果老师退出房间,初始化节拍器和伴奏播放配置
+            courseScheduleStudentMusicSheetService.getDao().closePlayStatus(courseScheduleId,null);
         }
-        return imUserId;
+        //退出房间
+        roomService.quitRoomSuccess(roleEnum,roomMember,courseSchedule.getServiceProvider());
     }
 
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void sendImPlayMidiMessage(ImNetworkCustomMessage customMessage) throws Exception {
-        SysUser user = sysUserService.getUser();
-        Long userId = user.getId();
-        Long roomId = customMessage.getRoomId();
-        log.info("sendImPlayMidiMessage: roomId={}, userId={}", roomId, userId);
-        ImNetworkMetronomeMessage displayMessage = new ImNetworkMetronomeMessage(customMessage);
-
-        String imUserId = imGroupService.getImUserId(userId,customMessage.getClientType());
-        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.lambdaQuery().eq(ImNetworkRoomMember::getUserId, userId)
-                .eq(ImNetworkRoomMember::getRoomId, roomId).last("LIMIT 1").one();
-        // 获取RTC服务提供方
-        CourseSchedule courseSchedule = courseScheduleService.getById(roomId);
-        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(courseSchedule.getServiceProvider());
-        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
-
-            // 腾讯云RTC服务
-            RTCRoomMessage.MessageContent messageContent = RTCRoomMessage.MessageContent
-                    .builder()
-                    .enable(customMessage.getEnable())
-                    .rate(customMessage.getRate())
-                    .customType(customMessage.getCustomType())
-                    .userId(customMessage.getUserId())
-                    .playVolume(customMessage.getPlayVolume())
-                    .sendUserInfo(getSendUser(user, RoleEnum.getEnumByValue(roomMember.getRole())))
-                    .build();
-
-            RTCRoomMessage roomMessage = RTCRoomMessage.builder()
-                    .objectName(RTCRoomMessage.PLAY_MIDI_MESSAGE)
-                    .content(messageContent)
-                    .toChatRoomId(roomMember.getRoomId())
-                    .fromUserId(imUserId)
-                    .isIncludeSender(1)
-                    .isPersisted(1)
-                    .build();
-
-            pluginService.sendChatRoomMessage(roomMessage);
-        } else {
-            imHelper.publishMessage(imUserId, roomId.toString(), displayMessage, 1);
-        }
-
+        customMessage.setCurrentUserId(sysUserService.getUserId());
+        CourseSchedule courseSchedule = courseScheduleService.getById(customMessage.getRoomId());
+        customMessage.setServiceProvider(courseSchedule.getServiceProvider());
+        //发送节拍器消息
+        imService.sendImPlayMidiMessage(customMessage);
         //记录节拍器信息
         String collect = Arrays.stream(customMessage.getUserId().split(","))
                 .map(x -> x.split(":")[0]).collect(Collectors.joining(","));
-
-        courseScheduleStudentPaymentService.getDao().adjustPlayMidi(roomId, collect, customMessage.toString());
+        imNetworkRoomMemberStatusService.lambdaUpdate()
+                        .eq(ImNetworkRoomMemberStatus::getRoomId,customMessage.getRoomId())
+                                .in(ImNetworkRoomMemberStatus::getUserId,collect)
+                                        .set(ImNetworkRoomMemberStatus::getPlayMidi,customMessage.toString());
     }
 
     @Override
@@ -523,35 +388,10 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
     public void display(ImNetworkDisplayDataDto displayData) throws Exception {
         log.info("display in data = {}", displayData);
         Long userId = sysUserService.getUserId();
-
-        StringBuffer display = new StringBuffer("display://type=").append(displayData.getType().ordinal()).append("?userId=");
-        switch (displayData.getType()) {
-            case NONE:
-                //清空当前 room 的 display
-                display = new StringBuffer();
-                break;
-            case TEACHER:
-                Long teacherId = Optional.ofNullable(courseScheduleService.getById(displayData.getRoomId())).
-                        map(CourseSchedule::getTeacherId).
-                        orElseThrow(()->new BizException("房间信息不存在"));
-                display.append(teacherId).append("?uri=");
-                break;
-            case SCREEN:
-                display.append(userId).append("?uri=");
-                break;
-            case STUDENT:
-                display.append(displayData.getUserId()).append("?uri=").append(displayData.getUri());
-                break;
-            default:
-                display.append(userId).append("?uri=").append(displayData.getUri());
-                break;
-        }
-        ImNetworkRoom room = baseMapper.findByRoomId(displayData.getRoomId());
-        room.setDisplay(display.toString());
-
-        String imUserId = imGroupService.getImUserId(userId,displayData.getClientType());
-
-        this.updateDisplay(imUserId,room);
+        CourseSchedule courseSchedule = courseScheduleService.getById(displayData.getRoomId());
+        displayData.setUserId(userId);
+        displayData.setTeacherId(courseSchedule.getTeacherId());
+        roomService.display(displayData,courseSchedule.getServiceProvider());
     }
 
     @Override
@@ -644,7 +484,7 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
             deviceResourceMessage.setUserId(imUserId);
             switch (deviceControl.getDeviceType()) {
                 case EXAM_SONG:
-                    ImNetworkRoomMusicSheetDownloadData msg = courseScheduleStudentPaymentService.getMemberExamSong(scheduleId, userId);
+                    ImNetworkRoomMusicSheetDownloadData msg = imNetworkRoomMemberStatusService.getMemberExamSong(roomId, userId);
                     msg.setEnable(enable);
                     courseScheduleStudentPaymentService.getDao().adjustExamSong(scheduleId,userId, JSON.toJSONString(msg));
 
@@ -727,7 +567,7 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
                     roomMember.setMusicModeFlag(deviceControl.getEnable());
                     break;
                 case EXAM_SONG:
-                    ImNetworkRoomMusicSheetDownloadData msg = courseScheduleStudentPaymentService.getMemberExamSong(scheduleId, userId);
+                    ImNetworkRoomMusicSheetDownloadData msg = imNetworkRoomMemberStatusService.getMemberExamSong(roomId, userId);
                     msg.setEnable(deviceControl.getEnable());
                     courseScheduleStudentPaymentService.getDao().adjustExamSong(scheduleId,userId, JSON.toJSONString(msg));
                     break;
@@ -779,7 +619,7 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
                 break;
             case EXAM_SONG:
                 long scheduleId = Long.parseLong(deviceControl.getRoomId());
-                ImNetworkRoomMusicSheetDownloadData msg = courseScheduleStudentPaymentService.getMemberExamSong(scheduleId, sysUser.getId());
+                ImNetworkRoomMusicSheetDownloadData msg = imNetworkRoomMemberStatusService.getMemberExamSong(roomMember.getRoomId(), sysUser.getId());
                 msg.setEnable(deviceControl.getEnable());
                 courseScheduleStudentPaymentService.getDao().adjustExamSong(scheduleId, sysUser.getId(), JSON.toJSONString(msg));
                 break;
@@ -879,7 +719,7 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
                 break;
             case EXAM_SONG:
                 long scheduleId = Long.parseLong(deviceStatusSync.getRoomId());
-                ImNetworkRoomMusicSheetDownloadData msg = courseScheduleStudentPaymentService.getMemberExamSong(scheduleId, userId);
+                ImNetworkRoomMusicSheetDownloadData msg = imNetworkRoomMemberStatusService.getMemberExamSong(deviceStatusSync.getRoomId(), userId);
                 msg.setEnable(deviceStatusSync.getEnable());
                 courseScheduleStudentPaymentService.getDao().adjustExamSong(scheduleId, userId, JSON.toJSONString(msg));
                 break;
@@ -1021,75 +861,12 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
         return courseSchedule.getStartTime().compareTo(addMinutes) > 0;
     }
 
-    public ImNetworkRoom initRoom(String roomId,Long courseId,RoleEnum userRole,Long userId,Date now) throws Exception {
-        ImNetworkRoom room = baseMapper.findByRoomId(roomId);
-        String display = "";
-        if (userRole == RoleEnum.RoleTeacher) {
-            display = "display://type=0?userId=" + userId + "?uri=";
-        }
-        if(Objects.isNull(room)){
-            room = new ImNetworkRoom();
-            //创建房间
-            room.setCourseScheduleId(courseId);
-            room.setRoomId(roomId);
-            room.setCreateTime(now);
-            room.setUpdateTime(now);
-            room.setDisplay(display);
-            baseMapper.insert(room);
-            IMApiResultInfo resultInfo = imHelper.createGroup(new String[]{userId.toString()}, roomId, roomId);
-            if(resultInfo.getCode() != 200){
-                log.error("创建群聊失败 resultInfo:{}",resultInfo);
-            }
-        }else {
-            if(userRole == RoleEnum.RoleTeacher){
-                room.setDisplay(display);
-                baseMapper.updateById(room);
-            }
-        }
-        return room;
-    }
 
     //修改节拍器
-    public void updateDisplay(String imUserId,ImNetworkRoom room) throws Exception {
-        baseMapper.updateById(room);
-        // IM发送用户消息
-        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.lambdaQuery().eq(ImNetworkRoomMember::getUserId, imUserId)
-                .eq(ImNetworkRoomMember::getRoomId, room.getRoomId()).last("LIMIT 1").one();
-        CourseSchedule courseSchedule = courseScheduleService.getById(room.getRoomId());
-        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(courseSchedule.getServiceProvider())) {
-            sendDisplayMessage(room.getDisplay(), roomMember);
-        } else {
-            this.sendDisplay(imUserId,room);
-        }
-    }
-
-    private void sendDisplayMessage(String display, ImNetworkRoomMember roomMember) throws Exception {
-        // 获取RTC服务提供方
-        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(TencentCloudRTCPlugin.PLUGIN_NAME);
-        // 腾讯云RTC服务
-        RTCRoomMessage.MessageUser sendUser = getSendUser(sysUserService.findUserById(roomMember.getUserId()), RoleEnum.getEnumByValue(roomMember.getRole()));
-        RTCRoomMessage.MessageContent.MessageContentBuilder action = RTCRoomMessage.MessageContent.builder()
-                .display(display)
-                .sendUserInfo(sendUser);
-
-
-        RTCRoomMessage roomMessage = RTCRoomMessage.builder()
-                .objectName(RTCRoomMessage.DISPLAY_MESSAGE)
-                .content(action.build())
-                .toChatRoomId(roomMember.getRoomId())
-                .fromUserId(sendUser.getSendUserId())
-                .isIncludeSender(1)
-                .isPersisted(1)
-                .build();
-
-        pluginService.sendChatRoomMessage(roomMessage);
-    }
-
-    public void sendDisplay(String imUserId,ImNetworkRoom room) throws Exception {
-        //发送display改动通知
-        ImNetworkDisplayMessage displayMessage = new ImNetworkDisplayMessage(room.getDisplay());
-
-        imHelper.publishMessage(imUserId, room.getRoomId(), displayMessage, 0);
+    public void updateDisplay(String imUserId,ImNetworkRoom room,String serviceProvider) throws Exception {
+        roomService.updateById(room);
+        //节拍器修改消息发送
+        imService.sendDisplay(imUserId,room,serviceProvider);
     }
 
     public boolean isUserDisplay(String display, Long userId) {
@@ -1101,72 +878,4 @@ public class ImNetworkRoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNe
         }
         return result;
     }
-
-    private void joinImGroup(String roomId, Integer actualTeacherId, CourseSchedule courseSchedule) throws Exception {
-
-        String joinImGroupKey = "joinImGroup:" + 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)) {
-
-            try {
-                // 创建群组
-                log.info("createImGroup: roomId = {}, userId = {}", roomId, actualTeacherId);
-                if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
-
-                    // 群组帐号注册
-                    TeacherVo teacherVo = teacherDao.detail(courseSchedule.getTeacherId());
-                    if (Objects.nonNull(teacherVo)) {
-                        try {
-                            pluginService.register(courseSchedule.getTeacherId().toString(), teacherVo.getRealName(), teacherVo.getAvatar());
-                        } catch (Exception e) {
-                            log.error("直播房间群主注册失败: userId={}", courseSchedule.getTeacherId(), e);
-                        }
-                    }
-
-                    // 生成群组
-                    pluginService.chatRoomCreate(roomId, roomId, courseSchedule.getTeacherId().toString());
-
-                    // 群组老师信息
-                    List<ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList(ImGroupMemberWrapper.ImGroupMember
-                            .builder()
-                            .userId(Long.valueOf(actualTeacherId))
-                            .imUserIdFormat(false)
-                            .build());
-
-                    List<CourseScheduleStudentPayment> payments = courseScheduleStudentPaymentService.getByCourseId(Long.parseLong(roomId.substring(1)));
-                    // 群组学生信息
-                    if (org.apache.commons.collections.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, roomId, groupMembers);
-                } else {
-
-                    List<CourseScheduleStudentPayment> payments = courseScheduleStudentPaymentService.getByCourseId(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);
-                }
-
-            } catch (Exception e) {
-
-                redisTemplate.delete(joinImGroupKey);
-                // 异常抛出,删除缓存标识
-                throw e;
-            }
-
-        }
-    }
 }

+ 166 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImServiceImpl.java

@@ -0,0 +1,166 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginContext;
+import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginService;
+import com.microsvc.toolkit.middleware.rtc.enums.EMemberAction;
+import com.microsvc.toolkit.middleware.rtc.impl.TencentCloudRTCPlugin;
+import com.microsvc.toolkit.middleware.rtc.message.RTCRoomMessage;
+import com.yonge.cooleshow.biz.dal.dto.*;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoom;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember;
+import com.yonge.cooleshow.biz.dal.enums.ImNetworkRoomMemberChangedEnum;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberService;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberStatusService;
+import com.yonge.cooleshow.biz.dal.service.ImService;
+import com.yonge.cooleshow.biz.dal.support.IMHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+ * 网络教室成员(ImNetworkRoomMember)表服务实现类
+ *
+ * @author zx
+ * @since 2022-03-30 16:36:38
+ */
+@Service("imService")
+public class ImServiceImpl implements ImService {
+
+    private final static Logger log = LoggerFactory.getLogger(ImServiceImpl.class);
+
+    @Autowired
+    private RTCRoomPluginContext rtcRoomPluginContext;
+
+    @Autowired
+    private ImNetworkRoomMemberStatusService imNetworkRoomMemberStatusService;
+
+    @Autowired
+    private IMHelper imHelper;
+
+    @Autowired
+    private ImNetworkRoomMemberService imNetworkRoomMemberService;
+
+
+    @Override
+    public void publishMemberChangedMessage(ImNetworkRoomMember roomMember,String serviceProvider) throws Exception {
+        //发送人员变动消息
+        // 获取RTC服务提供方
+        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(serviceProvider);
+        if (serviceProvider.equals(TencentCloudRTCPlugin.PLUGIN_NAME)) {
+            // 腾讯云RTC服务
+            RTCRoomMessage.MessageContent.MessageContentBuilder action = RTCRoomMessage.MessageContent.builder()
+                    .action(EMemberAction.JOIN.getValue());
+
+            action.handUpOn(roomMember.isHandFlag())
+                    .microphone(roomMember.isMicFlag())
+                    .timestamp(new Date().getTime())
+                    .camera(roomMember.isCameraFlag())
+                    .role(roomMember.getRole())
+                    .microphone(roomMember.isMicFlag())
+                    .sendUserInfo(this.getSendUser(roomMember));
+
+            RTCRoomMessage roomMessage = RTCRoomMessage.builder()
+                    .objectName(RTCRoomMessage.MEMBER_CHANGE_MESSAGE)
+                    .fromUserId(roomMember.getImUserId())
+                    .content(action.build())
+                    .toChatRoomId(roomMember.getRoomId())
+                    .isPersisted(1)
+                    .isIncludeSender(1)
+                    .build();
+
+            pluginService.sendChatRoomMessage(roomMessage);
+        } else {
+            ImNetworkRoomMemberChangedMessage msg = new ImNetworkRoomMemberChangedMessage(roomMember, ImNetworkRoomMemberChangedEnum.JOIN);
+            //获取节拍器信息
+            ImNetworkCustomMessage imNetworkCustomMessage = imNetworkRoomMemberStatusService.getMemberMidi(roomMember.getRoomId(), roomMember.getUserId());
+            msg.setMetronomeSwitch(imNetworkCustomMessage.isEnable());
+            //获取伴奏信息
+            ImNetworkRoomMusicSheetDownloadData musicSheetDownloadData = imNetworkRoomMemberStatusService.getMemberExamSong(roomMember.getRoomId(), roomMember.getUserId());
+            msg.setExamSongSwitch(musicSheetDownloadData.getEnable());
+            imHelper.publishMessage(roomMember.getImUserId(), roomMember.getRoomId(), msg);
+        }
+    }
+
+    @Override
+    public void sendDisplay(String imUserId, ImNetworkRoom room,String serviceProvider) throws Exception {
+        // IM发送用户消息
+        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.lambdaQuery().eq(ImNetworkRoomMember::getUserId, imUserId)
+                .eq(ImNetworkRoomMember::getRoomId, room.getRoomId()).last("LIMIT 1").one();
+        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(serviceProvider)) {
+            // 获取RTC服务提供方
+            RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(TencentCloudRTCPlugin.PLUGIN_NAME);
+            // 腾讯云RTC服务
+            RTCRoomMessage.MessageUser sendUser = getSendUser(roomMember);
+            RTCRoomMessage.MessageContent.MessageContentBuilder action = RTCRoomMessage.MessageContent.builder()
+                    .display(room.getDisplay())
+                    .sendUserInfo(sendUser);
+
+
+            RTCRoomMessage roomMessage = RTCRoomMessage.builder()
+                    .objectName(RTCRoomMessage.DISPLAY_MESSAGE)
+                    .content(action.build())
+                    .toChatRoomId(roomMember.getRoomId())
+                    .fromUserId(sendUser.getSendUserId())
+                    .isIncludeSender(1)
+                    .isPersisted(1)
+                    .build();
+
+            pluginService.sendChatRoomMessage(roomMessage);
+        } else {
+            //发送display改动通知
+            ImNetworkDisplayMessage displayMessage = new ImNetworkDisplayMessage(room.getDisplay());
+            imHelper.publishMessage(imUserId, room.getRoomId(), displayMessage, 0);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void sendImPlayMidiMessage(ImNetworkCustomMessage customMessage) throws Exception {
+        log.info("sendImPlayMidiMessage: customMessage={}", customMessage);
+        ImNetworkMetronomeMessage displayMessage = new ImNetworkMetronomeMessage(customMessage);
+
+        ImNetworkRoomMember roomMember = imNetworkRoomMemberService.lambdaQuery().eq(ImNetworkRoomMember::getUserId, customMessage.getCurrentUserId())
+                .eq(ImNetworkRoomMember::getRoomId, customMessage.getRoomId()).last("LIMIT 1").one();
+        // 获取RTC服务提供方
+        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(customMessage.getServiceProvider());
+        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
+            // 腾讯云RTC服务
+            RTCRoomMessage.MessageContent messageContent = RTCRoomMessage.MessageContent
+                    .builder()
+                    .enable(customMessage.isEnable())
+                    .rate(customMessage.getRate())
+                    .customType(customMessage.getCustomType())
+                    .userId(customMessage.getUserId())
+                    .playVolume(customMessage.getPlayVolume())
+                    .sendUserInfo(getSendUser(roomMember))
+                    .build();
+
+            RTCRoomMessage roomMessage = RTCRoomMessage.builder()
+                    .objectName(RTCRoomMessage.PLAY_MIDI_MESSAGE)
+                    .content(messageContent)
+                    .toChatRoomId(roomMember.getRoomId())
+                    .fromUserId(roomMember.getImUserId())
+                    .isIncludeSender(1)
+                    .isPersisted(1)
+                    .build();
+
+            pluginService.sendChatRoomMessage(roomMessage);
+        } else {
+            imHelper.publishMessage(roomMember.getImUserId(), roomMember.getRoomId(), displayMessage, 1);
+        }
+    }
+
+    private RTCRoomMessage.MessageUser getSendUser(ImNetworkRoomMember roomMember) {
+        RTCRoomMessage.MessageUser build = RTCRoomMessage.MessageUser.builder()
+                .sendUserId(roomMember.getImUserId())
+                .sendUserName(roomMember.getUsername())
+                .avatarUrl(roomMember.getAvatar())
+                .build();
+        return build;
+    }
+}
+

+ 183 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/RoomServiceImpl.java

@@ -0,0 +1,183 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginContext;
+import com.microsvc.toolkit.middleware.rtc.RTCRoomPluginService;
+import com.microsvc.toolkit.middleware.rtc.impl.TencentCloudRTCPlugin;
+import com.microsvc.toolkit.middleware.rtc.message.RTCRoomConfig;
+import com.yonge.cooleshow.biz.dal.dao.ImNetworkRoomDao;
+import com.yonge.cooleshow.biz.dal.dao.ImNetworkRoomMemberDao;
+import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkDisplayDataDto;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkRoomMemberChangedMessage;
+import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.enums.ImNetworkRoomMemberChangedEnum;
+import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberStatusService;
+import com.yonge.cooleshow.biz.dal.service.ImService;
+import com.yonge.cooleshow.biz.dal.service.RoomService;
+import com.yonge.cooleshow.biz.dal.support.IMHelper;
+import com.yonge.toolset.base.exception.BizException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 网络教室房间(ImNetworkRoom)表服务实现类
+ *
+ * @author zx
+ * @since 2022-03-30 16:36:36
+ */
+@Service("roomService")
+public class RoomServiceImpl extends ServiceImpl<ImNetworkRoomDao, ImNetworkRoom> implements RoomService {
+
+    private final static Logger log = LoggerFactory.getLogger(RoomServiceImpl.class);
+
+    @Resource
+    private IMHelper imHelper;
+    @Autowired
+    private RTCRoomPluginContext rtcRoomPluginContext;
+    @Autowired
+    private ImNetworkRoomMemberStatusService imNetworkRoomMemberStatusService;
+    @Autowired
+    private ImNetworkRoomMemberDao imNetworkRoomMemberDao;
+    @Autowired
+    private ImService imService;
+    @Autowired
+    private ImGroupService imGroupService;
+
+    @Override
+    public ImNetworkRoomDao getDao() {
+        return baseMapper;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ImNetworkRoom initRoom(String roomId, RoleEnum userRole, Long userId) throws Exception {
+        ImNetworkRoom room = baseMapper.findByRoomId(roomId);
+        String display = "";
+        if (userRole == RoleEnum.RoleTeacher) {
+            display = "display://type=0?userId=" + userId + "?uri=";
+        }
+        if(Objects.isNull(room)){
+            room = new ImNetworkRoom();
+            //创建房间
+            room.setRoomId(roomId);
+            room.setDisplay(display);
+            baseMapper.insert(room);
+            IMApiResultInfo resultInfo = imHelper.createGroup(new String[]{userId.toString()}, roomId, roomId);
+            if(resultInfo.getCode() != 200){
+                log.error("创建群聊失败 resultInfo:{}",resultInfo);
+            }
+        }else {
+            if(userRole == RoleEnum.RoleTeacher){
+                room.setDisplay(display);
+                baseMapper.updateById(room);
+            }
+        }
+        return room;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public RTCRoomConfig getRtcRoomConfig(String serviceProvider, BasicUserInfo basicUserInfo) {
+        RTCRoomPluginService pluginService = rtcRoomPluginContext.getPluginService(serviceProvider);
+        if (TencentCloudRTCPlugin.PLUGIN_NAME.equals(pluginService.pluginName())) {
+            // 腾讯云RTC
+            // 用户IM帐号创建
+            try {
+                pluginService.register(basicUserInfo.getImUserId(), basicUserInfo.getRealName(), basicUserInfo.getAvatar());
+            } catch (Exception e) {
+                log.error("直播房间用户注册失败: userId={}", basicUserInfo.getUserId(), e);
+            }
+            return rtcRoomPluginContext.getPluginService().getRTCRoomConfig(String.valueOf(basicUserInfo.getUserId()));
+        }
+        return new RTCRoomConfig();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void quitRoomSuccess(RoleEnum roleEnum, ImNetworkRoomMember roomMember,String serviceProvider) throws Exception {
+        String roomId = roomMember.getRoomId();
+        String imUserId = roomMember.getImUserId();
+        ImNetworkRoom room = baseMapper.findByRoomId(roomId);
+        if (roleEnum == RoleEnum.RoleTeacher){
+            //如果老师退出房间,初始化节拍器和伴奏播放配置
+            imNetworkRoomMemberStatusService.lambdaUpdate().eq(ImNetworkRoomMemberStatus::getRoomId,roomId)
+                    .set(ImNetworkRoomMemberStatus::getPlayMidi,null)
+                    .set(ImNetworkRoomMemberStatus::getMusicSheetDownloadJson,null).update();
+            if (isUserDisplay(room.getDisplay(), roomMember.getUserId())) {
+                room.setDisplay("");
+                this.updateDisplay(imUserId,room,serviceProvider);
+            }
+        }
+        int memberNum = imNetworkRoomMemberDao.countByRoomId(roomId);
+        if (memberNum <= 1) {
+            imHelper.dismiss(imUserId, roomId);
+            log.info("leaveRoomSuccess dismiss the room: {},userId: {}", roomId, imUserId);
+        } else {
+            ImNetworkRoomMemberChangedMessage msg = new ImNetworkRoomMemberChangedMessage(roomMember, ImNetworkRoomMemberChangedEnum.LEAVE);
+            imHelper.publishMessage(imUserId, roomId, msg);
+            imHelper.quit(new String[]{imUserId}, roomId);
+            log.info("leaveRoomSuccess quit group: roomId={},userId: {}", roomId, imUserId);
+        }
+        //删房间用户信息
+        imNetworkRoomMemberDao.deleteById(roomMember.getId());
+    }
+
+    //修改节拍器
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateDisplay(String imUserId, ImNetworkRoom room, String serviceProvider) throws Exception {
+        baseMapper.updateById(room);
+        //节拍器修改消息发送
+        imService.sendDisplay(imUserId,room,serviceProvider);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void display(ImNetworkDisplayDataDto displayData,String serviceProvider) throws Exception {
+        StringBuffer display = new StringBuffer("display://type=").append(displayData.getType().ordinal()).append("?userId=");
+        switch (displayData.getType()) {
+            case NONE:
+                //清空当前 room 的 display
+                display = new StringBuffer();
+                break;
+            case TEACHER:
+                display.append(displayData.getTeacherId()).append("?uri=");
+                break;
+            case SCREEN:
+                display.append(displayData.getUserId()).append("?uri=");
+                break;
+            case STUDENT:
+                display.append(displayData.getUserId()).append("?uri=").append(displayData.getUri());
+                break;
+            default:
+                display.append(displayData.getUserId()).append("?uri=").append(displayData.getUri());
+                break;
+        }
+        ImNetworkRoom room = baseMapper.findByRoomId(displayData.getRoomId());
+        room.setDisplay(display.toString());
+
+        String imUserId = imGroupService.getImUserId(displayData.getUserId(), displayData.getClientType());
+
+        this.updateDisplay(imUserId,room,serviceProvider);
+    }
+
+    public boolean isUserDisplay(String display, Long userId) {
+        boolean result = false;
+        if (!display.isEmpty() && display.contains("userId=" + userId)) {
+            if (display.contains("type=0") || display.contains("type=2")) {
+                result = true;
+            }
+        }
+        return result;
+    }
+}

+ 63 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/ImNetworkRoomMemberStatusWrapper.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.util.Optional;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 网络教室成员状态表
+ * 2023-08-14 15:51:26
+ */
+@ApiModel(value = "ImNetworkRoomMemberStatusWrapper对象", description = "网络教室成员状态表查询对象")
+public class ImNetworkRoomMemberStatusWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" ImNetworkRoomMemberStatusQuery-网络教室成员状态表")
+    public static class ImNetworkRoomMemberStatusQuery implements QueryInfo {
+    
+    	@ApiModelProperty("当前页")
+        private Integer page;
+        
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+        
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+        
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+        
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static ImNetworkRoomMemberStatusQuery from(String json) {
+            return JSON.parseObject(json, ImNetworkRoomMemberStatusQuery.class);
+        }
+    }  
+
+	@ApiModel(" ImNetworkRoomMemberStatus-网络教室成员状态表")
+    public static class ImNetworkRoomMemberStatus {
+        
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static ImNetworkRoomMemberStatus from(String json) {
+            return JSON.parseObject(json, ImNetworkRoomMemberStatus.class);
+        }
+	}
+
+}

+ 0 - 11
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

@@ -33,9 +33,6 @@
         </foreach>
     </insert>
 
-    <update id="cleanPlayMidi">
-        UPDATE course_schedule_student_payment SET play_midi_ = NULL WHERE course_id_ = #{courseScheduleId}
-    </update>
     <update id="adjustPlayMidi">
         UPDATE course_schedule_student_payment cssp
         <set>
@@ -91,14 +88,6 @@
             </if>
         </where>
     </select>
-    <select id="getMidiByCourseIdAndUserId" resultType="java.lang.String">
-        SELECT play_midi_ FROM course_schedule_student_payment
-        WHERE user_id_ = #{userId} AND course_id_ = #{courseScheduleId} LIMIT 1
-    </select>
-    <select id="getMusicSheetByCourseIdAndUserId" resultType="java.lang.String">
-        SELECT music_sheet_download_json_ FROM course_schedule_student_payment
-        WHERE user_id_ = #{userId} AND course_id_ = #{courseScheduleId} LIMIT 1
-    </select>
     <select id="queryByCourseId" resultMap="BaseResultMap">
         SELECT <include refid="Base_Column_List"/> FROM course_schedule_student_payment
         WHERE course_id_ = #{courseScheduleId}

+ 0 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/ImNetworkRoomMapper.xml

@@ -4,7 +4,6 @@
     <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.ImNetworkRoom">
         <id column="id_" jdbcType="INTEGER" property="id"/>
         <result column="room_id_" jdbcType="VARCHAR" property="roomId"/>
-        <result column="course_schedule_id_" jdbcType="INTEGER" property="courseScheduleId"/>
         <result column="display_" jdbcType="VARCHAR" property="display"/>
         <result column="sound_volume_" jdbcType="INTEGER" property="soundVolume"/>
         <result column="update_time_" jdbcType="TIMESTAMP" property="updateTime"/>

+ 13 - 12
cooleshow-user/user-biz/src/main/resources/config/mybatis/ImNetworkRoomMemberMapper.xml

@@ -3,9 +3,9 @@
 <mapper namespace="com.yonge.cooleshow.biz.dal.dao.ImNetworkRoomMemberDao">
     <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember">
         <id column="id_" jdbcType="INTEGER" property="id"/>
-        <result column="course_schedule_id_" jdbcType="INTEGER" property="courseScheduleId"/>
         <result column="room_id_" jdbcType="VARCHAR" property="roomId"/>
         <result column="user_id_" jdbcType="INTEGER" property="userId"/>
+        <result column="im_user_id_" property="imUserId"/>
         <result column="username_" jdbcType="VARCHAR" property="username"/>
         <result column="avatar_" jdbcType="VARCHAR" property="avatar"/>
         <result column="join_time_" jdbcType="TIMESTAMP" property="joinTime"/>
@@ -17,27 +17,28 @@
     </resultMap>
 
     <sql id="Base_Column_List">
-        id_
-        , course_schedule_id_, room_id_, user_id_, join_time_, role_,
-        camera_flag_, mic_flag_, music_mode_flag_, hand_flag_,username_,avatar_
+        id_ , room_id_, user_id_, join_time_, role_,
+        camera_flag_, mic_flag_, music_mode_flag_, hand_flag_,username_,avatar_,im_user_id_
     </sql>
 
     <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
             parameterType="com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember">
-        insert into im_network_room_member(course_schedule_id_, room_id_, user_id_, join_time_, role_, camera_flag_,
-        mic_flag_, music_mode_flag_, hand_flag_,username_,avatar_)
+        insert into im_network_room_member(room_id_, user_id_, join_time_, role_, camera_flag_,
+        mic_flag_, music_mode_flag_, hand_flag_,username_,avatar_,im_user_id_)
         values
         <foreach collection="entities" item="entity" separator=",">
-            (#{entity.courseScheduleId}, #{entity.roomId}, #{entity.userId}, #{entity.joinTime}, #{entity.role},
-            #{entity.cameraFlag}, #{entity.micFlag}, #{entity.musicModeFlag}, #{entity.handFlag}, #{entity.username}, #{entity.avatar})
+            (#{entity.roomId}, #{entity.userId}, #{entity.joinTime}, #{entity.role},
+            #{entity.cameraFlag}, #{entity.micFlag}, #{entity.musicModeFlag},
+             #{entity.handFlag}, #{entity.username}, #{entity.avatar},#{entity.imUserId})
         </foreach>
     </insert>
     <insert id="insert" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
             parameterType="com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMember">
-        INSERT INTO im_network_room_member(course_schedule_id_, room_id_, user_id_, join_time_, role_, camera_flag_,
-                                           mic_flag_, music_mode_flag_, hand_flag_,username_,avatar_)
-        VALUES (#{entity.courseScheduleId}, #{entity.roomId}, #{entity.userId},NOW(), #{entity.role},
-                #{entity.cameraFlag}, #{entity.micFlag}, #{entity.musicModeFlag}, #{entity.handFlag}, #{entity.username}, #{entity.avatar})
+        INSERT INTO im_network_room_member(room_id_, user_id_, join_time_, role_, camera_flag_,
+                                           mic_flag_, music_mode_flag_, hand_flag_,username_,avatar_,im_user_id_)
+        VALUES (#{entity.roomId}, #{entity.userId},NOW(), #{entity.role},
+                #{entity.cameraFlag}, #{entity.micFlag}, #{entity.musicModeFlag},
+                #{entity.handFlag}, #{entity.username}, #{entity.avatar}, #{entity.imUserId})
         ON DUPLICATE KEY UPDATE
         room_id_ = VALUES(room_id_),
         user_id_ = VALUES(user_id_),

+ 23 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/ImNetworkRoomMemberStatusMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.ImNetworkRoomMemberStatusMapper">
+
+	 
+    
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id_ AS id
+        , t.room_id_ AS roomId
+        , t.user_id_ AS userId
+        , t.role_ AS role
+        , t.play_midi_ AS playMidi
+        , t.music_sheet_download_json_ AS musicSheetDownloadJson
+        </sql> 
+    
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.entity.ImNetworkRoomMemberStatus">
+		SELECT         
+        	<include refid="baseColumns" />
+		FROM im_network_room_member_status t
+	</select>
+    
+</mapper>

+ 0 - 29
cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomMemberController.java

@@ -1,29 +0,0 @@
-package com.yonge.cooleshow.classroom.controller;
-
-
-import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberService;
-import com.yonge.cooleshow.common.controller.BaseController;
-import io.swagger.annotations.Api;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-
-/**
- * 网络教室成员(ImNetworkRoomMember)表控制层
- *
- * @author zx
- * @since 2022-03-30 16:36:37
- */
-@Api(tags = "网络教室成员")
-@RestController
-@RequestMapping("/imNetworkRoomMember")
-public class ImNetworkRoomMemberController extends BaseController {
-    /**
-     * 服务对象
-     */
-    @Resource
-    private ImNetworkRoomMemberService imNetworkRoomMemberService;
-
-}
-

+ 28 - 34
cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomController.java → cooleshow-user/user-classroom/src/main/java/com/yonge/cooleshow/classroom/controller/RoomController.java

@@ -8,7 +8,7 @@ import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.common.controller.BaseController;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.entity.BaseResponse;
 import com.yonge.toolset.base.exception.BizException;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
-import java.text.MessageFormat;
+import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -34,9 +34,9 @@ import java.util.Optional;
 @Api(tags = "网络教室房间")
 @RestController
 @RequestMapping("/room")
-public class ImNetworkRoomController extends BaseController {
+public class RoomController extends BaseController {
 
-    private final static Logger log = LoggerFactory.getLogger(ImNetworkRoomController.class);
+    private final static Logger log = LoggerFactory.getLogger(RoomController.class);
     /**
      * 服务对象
      */
@@ -49,7 +49,7 @@ public class ImNetworkRoomController extends BaseController {
 
     @ApiOperation("加入网络教室")
     @PostMapping(value = "/join")
-    public HttpResponseResult<ImNetworkRoomResult> joinRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
+    public BaseResponse<ImNetworkRoomResult> joinRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
 
         // 设置请求客户端来源
         if (Objects.isNull(imNetworkBaseDto.getClientType())) {
@@ -61,16 +61,10 @@ public class ImNetworkRoomController extends BaseController {
                 .orElseThrow(()->new BizException("房间号不可为空")), imNetworkBaseDto.getClientType());
     }
 
-//    @ApiOperation("加入网络教室状态回调")
-//    @PostMapping(value = "joinRoomSuccess", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
-//    public HttpResponseResult joinRoomSuccess(Long courseScheduleId) throws Exception {
-//        imNetworkRoomService.joinRoomSuccess(courseScheduleId.toString(),UserRoleEnum.TEACHER);
-//        return succeed();
-//    }
 
     @ApiOperation("加入网络教室状态回调")
     @PostMapping(value = "joinRoomFailure")
-    public HttpResponseResult joinRoomFailure(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
+    public BaseResponse joinRoomFailure(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
 
         // 设置请求客户端来源
         if (Objects.isNull(imNetworkBaseDto.getClientType())) {
@@ -80,7 +74,7 @@ public class ImNetworkRoomController extends BaseController {
         imNetworkRoomService.joinRoomFailure(Optional.ofNullable(imNetworkBaseDto)
                 .map(ImNetworkBaseDto::getRoomId)
                 .orElseThrow(()->new BizException("房间号不可为空")).toString(), imNetworkBaseDto.getClientType());
-        return succeed();
+        return BaseResponse.success();
     }
 
     @PostMapping(value = "/statusSync")
@@ -103,7 +97,7 @@ public class ImNetworkRoomController extends BaseController {
 
     @ApiOperation("退出网络教室")
     @PostMapping(value = "/leave")
-    public HttpResponseResult leaveRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
+    public BaseResponse leaveRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
 
         // 设置请求客户端来源
         if (Objects.isNull(imNetworkBaseDto.getClientType())) {
@@ -124,12 +118,12 @@ public class ImNetworkRoomController extends BaseController {
         imNetworkRoomService.quitRoomSuccess(Optional.ofNullable(imNetworkBaseDto)
                 .map(ImNetworkBaseDto::getRoomId)
                 .orElseThrow(()->new BizException("房间号不可为空")).toString(), imUserId);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation("控制学员节拍器")
     @PostMapping(value = "/sendImPlayMidiMessage")
-    public HttpResponseResult sendImPlayMidiMessage(@RequestBody ImNetworkCustomMessage customMessage) throws Exception {
+    public BaseResponse sendImPlayMidiMessage(@RequestBody ImNetworkCustomMessage customMessage) throws Exception {
 
         // 设置客户端类型
         if (Objects.isNull(customMessage.getClientType())) {
@@ -137,12 +131,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.sendImPlayMidiMessage(customMessage);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation("移动端用来渲染页面")
     @PostMapping(value = "/display")
-    public HttpResponseResult display(@RequestBody ImNetworkDisplayDataDto displayData) throws Exception {
+    public BaseResponse display(@RequestBody ImNetworkDisplayDataDto displayData) throws Exception {
 
         // 设置客户端类型
         if (Objects.isNull(displayData.getClientType())) {
@@ -150,12 +144,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.display(displayData);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "批量控制学员设备开关")
     @PostMapping(value = "/device/batchControl")
-    public Object batchControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)throws Exception {
+    public BaseResponse batchControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)throws Exception {
 
         // 设置客户端类型
         if (Objects.isNull(deviceControl.getClientType())) {
@@ -163,12 +157,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.batchControlDevice(deviceControl);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "控制学员设备开关")
     @PostMapping(value = "/device/control")
-    public HttpResponseResult controlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
+    public BaseResponse controlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
             throws Exception {
 
         // 设置客户端类型
@@ -177,12 +171,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.controlDevice(deviceControl);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "学员同意打开,麦克风、摄像头")
     @PostMapping(value = "/device/approve")
-    public HttpResponseResult approveControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl) throws Exception {
+    public BaseResponse approveControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl) throws Exception {
         deviceControl.setEnable(true);
 
         // 设置客户端类型
@@ -191,12 +185,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.approveControlDevice(deviceControl);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "学员拒绝打开,麦克风、摄像头")
     @PostMapping(value = "/device/reject")
-    public HttpResponseResult rejectControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
+    public BaseResponse rejectControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
             throws Exception {
         deviceControl.setEnable(false);
 
@@ -206,7 +200,7 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.rejectControlDevice(deviceControl);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "学员设备状态同步")
@@ -220,12 +214,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.deviceStatusSync(deviceControl);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "老师在网络教室选择完伴奏后、通知学员下载伴奏")
     @PostMapping(value = "pushDownloadMusicSheetMsg")
-    public HttpResponseResult pushDownloadMusicSheetMsg(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
+    public BaseResponse pushDownloadMusicSheetMsg(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
 
         // 设置客户端类型
         if (Objects.isNull(musicSheetDto.getClientType())) {
@@ -233,12 +227,12 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.pushDownloadMusicSheetMsg(musicSheetDto);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "学员伴奏下载状态回调")
     @PostMapping(value = "musicSheetDownNotify")
-    public HttpResponseResult adjustMusicScore(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
+    public BaseResponse adjustMusicScore(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
 
         // 设置客户端类型
         if (Objects.isNull(musicSheetDto.getClientType())) {
@@ -246,13 +240,13 @@ public class ImNetworkRoomController extends BaseController {
         }
 
         imNetworkRoomService.musicSheetDownNotify(musicSheetDto);
-        return succeed();
+        return BaseResponse.success();
     }
 
     @ApiOperation(value = "查询不在教室的学员")
     @PostMapping(value = "/queryNoJoinStu")
-    public HttpResponseResult queryNoJoinStu(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
-        return succeed(imNetworkRoomService.queryNoJoinStu(Optional.ofNullable(imNetworkBaseDto)
+    public BaseResponse<List<BasicUserInfo>> queryNoJoinStu(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
+        return BaseResponse.success(imNetworkRoomService.queryNoJoinStu(Optional.ofNullable(imNetworkBaseDto)
                 .map(ImNetworkBaseDto::getRoomId)
                 .orElseThrow(()->new BizException("房间号不可为空"))));
     }