瀏覽代碼

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
weifanli 3 年之前
父節點
當前提交
57a763512f
共有 34 個文件被更改,包括 718 次插入106 次删除
  1. 6 20
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetController.java
  2. 1 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/UserWithdrawalController.java
  3. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/constant/LiveRoomConstant.java
  4. 5 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleDao.java
  5. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetAccompanimentDao.java
  6. 170 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/PracticeScheduleDto.java
  7. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VideoLessonGroupSearch.java
  8. 56 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleDate.java
  9. 14 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicSheet.java
  10. 5 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/CourseGroupEnum.java
  11. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java
  12. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  13. 9 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/LiveRoomService.java
  14. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetAccompanimentService.java
  15. 15 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  16. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VideoLessonGroupService.java
  17. 23 18
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  18. 65 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  19. 98 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/LiveRoomServiceImpl.java
  20. 6 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/LiveRoomVideoServiceImpl.java
  21. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetAccompanimentServiceImpl.java
  22. 33 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  23. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherFreeTimeServiceImpl.java
  24. 10 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonGroupServiceImpl.java
  25. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/LiveCourseGroupStudentCourseVo.java
  26. 1 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml
  27. 6 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  28. 3 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetAccompanimentMapper.xml
  29. 7 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/VideoLessonGroupMapper.xml
  30. 3 1
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseScheduleController.java
  31. 101 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentLiveRoomController.java
  32. 13 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/VideoLessonController.java
  33. 8 18
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java
  34. 4 3
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherLiveRoomController.java

+ 6 - 20
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetController.java

@@ -96,23 +96,10 @@ public class MusicSheetController extends BaseController {
         musicSheetDto.setAuditStatus(AuthStatusEnum.PASS);
         musicSheetDto.setDelFlag(false);
         musicSheetDto.setSourceType(SourceTypeEnum.PLATFORM);
-        List<MusicSheetAccompaniment> list;
-        if (!AudioTypeEnum.MIDI.getCode().equals(musicSheetDto.getAudioType().getCode())){
-            list = musicSheetDto.getBackground();
-            if (CollectionUtils.isEmpty(list)){
-                return failed("mp3音频文件对应的主音或者伴奏文件没有提供");
-            }
-            musicSheetService.saveMp3AndAccompaniment(musicSheetDto,sysUser);
-        } else {
-            MusicSheet musicSheet = new MusicSheet();
-            BeanUtils.copyProperties(musicSheetDto, musicSheet);
-            musicSheet.setCreateBy(sysUser.getId());
-            musicSheet.setCreateTime(new Date());
-            musicSheet.setUpdateTime(new Date());
-            musicSheet.setUpdateBy(sysUser.getId());
-            musicSheet.setState(YesOrNoEnum.NO);
-            musicSheetService.save(musicSheet);
-        }
+
+        musicSheetDto.setCreateBy(sysUser.getId());
+        musicSheetDto.setCreateTime(new Date());
+        musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());
 
         return succeed("新增曲谱成功");
 
@@ -136,7 +123,7 @@ public class MusicSheetController extends BaseController {
 
     @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
     @PostMapping(value="/update", consumes="application/json", produces="application/json")
-    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheet musicSheet) {
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetDto musicSheet) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null  || sysUser.getId() == null) {
             return failed("用户信息获取失败");
@@ -151,8 +138,7 @@ public class MusicSheetController extends BaseController {
 
         musicSheet.setUpdateBy(sysUser.getId());
         musicSheet.setUpdateTime(new Date());
-        boolean result = musicSheetService.updateById(musicSheet);
-        if (result){
+        if ( musicSheetService.saveMusicSheet(musicSheet,sysUser.getId())){
             return succeed("修改成功");
         } else {
             return failed("修改失败");

+ 1 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/UserWithdrawalController.java

@@ -28,6 +28,7 @@ import com.yonge.cooleshow.biz.dal.service.UserWithdrawalService;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.lang.reflect.InvocationTargetException;
+import java.math.RoundingMode;
 import java.util.*;
 
 @RestController

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/constant/LiveRoomConstant.java

@@ -23,4 +23,6 @@ public interface LiveRoomConstant {
     //房间的信息
     String LIVE_ROOM_INFO = String.join(":", COOLESHOW, "LIVE_ROOM_INFO", ROOM_UID);
 
+    //记录老师最后变更的状态消息时间
+    String LIVE_TEACHER_LAST_TIME = String.join(":", COOLESHOW, "LIVE_TEACHER_LAST_TIME", USER_ID);
 }

+ 5 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleDao.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.biz.dal.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
@@ -99,6 +100,9 @@ public interface CourseScheduleDao extends BaseMapper<CourseSchedule> {
     //学生端-课表-日历-用户
     List<CourseStudent> queryCourseTeacher(@Param("param") MyCourseSearch search);
 
+    //新增组
+    void addCourseGroup(PracticeScheduleDto scheduleDto);
+
     /**
      * 学生-查询直播课
      *
@@ -109,6 +113,6 @@ public interface CourseScheduleDao extends BaseMapper<CourseSchedule> {
      *              <p> - subjectId 声部id
      *              <p> - type PRACTICE 陪练课 LIVE 直播课
      */
-    List<CourseStudent> queryStudentLiveCourse(@Param("param") Map<String, Object> param);
+    <T> IPage<T> queryStudentLiveCourse(Page<T> page, @Param("param") Map<String, Object> param);
 }
 

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetAccompanimentDao.java

@@ -13,4 +13,10 @@ import java.util.List;
  **/
 public interface MusicSheetAccompanimentDao extends BaseMapper<MusicSheetAccompaniment> {
 
+    /**
+     * 删除原音
+     *
+     * @param musicSheetId 曲目id
+     */
+    void delByMusicSheetId(Long musicSheetId);
 }

+ 170 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/PracticeScheduleDto.java

@@ -0,0 +1,170 @@
+package com.yonge.cooleshow.biz.dal.dto;
+
+import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
+import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleDate;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author: cy
+ * @Date: 2022/4/20
+ */
+@ApiModel(value = "PracticeScheduleDto")
+public class PracticeScheduleDto implements Serializable {
+	@ApiModelProperty(value = "课程组id")
+	private Long groupId;
+	@ApiModelProperty(value = "学生id")
+	private Long studentId;
+	@ApiModelProperty(value = "老师id")
+	private Long teacherId;
+	@ApiModelProperty(value = "类型 practice陪练课 live直播课")
+	private String type;
+	@ApiModelProperty(value = "课程组名称")
+	private String courseGroupName;
+	@ApiModelProperty(value = "声部id")
+	private String subjectId;
+	@ApiModelProperty(value = "单课时长")
+	private Integer singleCourseMinutes;
+	@ApiModelProperty(value = "课程数")
+	private Integer courseNum;
+	@ApiModelProperty(value = "课程介绍")
+	private String courseIntroduce;
+	@ApiModelProperty(value = "课程组售价")
+	private BigDecimal coursePrice;
+	@ApiModelProperty(value = "课程单价")
+	private BigDecimal unitPrice;
+	@ApiModelProperty(value = "课程组状态 ING进行中 COMPLETE已完成 DISSOLVE-未成课(解散课程) CANCEL已取消-未开始报名前可取消 APPLY报名中 NOT_SALE未开售")
+	private String status;
+	@ApiModelProperty(value = "最少成课人数")
+	private Integer mixStudentNum;
+	@ApiModelProperty(value = "课程开始时间")
+	private Date courseStartTime;
+	@ApiModelProperty(value = "上课时间")
+	private List<CourseScheduleDate> classTime;
+
+	public BigDecimal getUnitPrice() {
+		return unitPrice;
+	}
+
+	public void setUnitPrice(BigDecimal unitPrice) {
+		this.unitPrice = unitPrice;
+	}
+
+	public Long getGroupId() {
+		return groupId;
+	}
+
+	public void setGroupId(Long groupId) {
+		this.groupId = groupId;
+	}
+
+	public Long getStudentId() {
+		return studentId;
+	}
+
+	public void setStudentId(Long studentId) {
+		this.studentId = studentId;
+	}
+
+	public Long getTeacherId() {
+		return teacherId;
+	}
+
+	public void setTeacherId(Long teacherId) {
+		this.teacherId = teacherId;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getCourseGroupName() {
+		return courseGroupName;
+	}
+
+	public void setCourseGroupName(String courseGroupName) {
+		this.courseGroupName = courseGroupName;
+	}
+
+	public String getSubjectId() {
+		return subjectId;
+	}
+
+	public void setSubjectId(String subjectId) {
+		this.subjectId = subjectId;
+	}
+
+	public Integer getSingleCourseMinutes() {
+		return singleCourseMinutes;
+	}
+
+	public void setSingleCourseMinutes(Integer singleCourseMinutes) {
+		this.singleCourseMinutes = singleCourseMinutes;
+	}
+
+	public Integer getCourseNum() {
+		return courseNum;
+	}
+
+	public void setCourseNum(Integer courseNum) {
+		this.courseNum = courseNum;
+	}
+
+	public String getCourseIntroduce() {
+		return courseIntroduce;
+	}
+
+	public void setCourseIntroduce(String courseIntroduce) {
+		this.courseIntroduce = courseIntroduce;
+	}
+
+	public BigDecimal getCoursePrice() {
+		return coursePrice;
+	}
+
+	public void setCoursePrice(BigDecimal coursePrice) {
+		this.coursePrice = coursePrice;
+	}
+
+	public String getStatus() {
+		return status;
+	}
+
+	public void setStatus(String status) {
+		this.status = status;
+	}
+
+	public Integer getMixStudentNum() {
+		return mixStudentNum;
+	}
+
+	public void setMixStudentNum(Integer mixStudentNum) {
+		this.mixStudentNum = mixStudentNum;
+	}
+
+	public Date getCourseStartTime() {
+		return courseStartTime;
+	}
+
+	public void setCourseStartTime(Date courseStartTime) {
+		this.courseStartTime = courseStartTime;
+	}
+
+	public List<CourseScheduleDate> getClassTime() {
+		return classTime;
+	}
+
+	public void setClassTime(List<CourseScheduleDate> classTime) {
+		this.classTime = classTime;
+	}
+}

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VideoLessonGroupSearch.java

@@ -20,6 +20,17 @@ public class VideoLessonGroupSearch extends QueryInfo {
     @ApiModelProperty(value = "筛选条件")
     private String search;
 
+    @ApiModelProperty(value = "学生id")
+    private Long studentId;
+
+    public Long getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
+
     public AuthStatusEnum getAuditStatus() {
         return auditStatus;
     }

+ 56 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleDate.java

@@ -0,0 +1,56 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Author: cy
+ * @Date: 2022/4/20
+ */
+@ApiModel(value = "CourseScheduleDate")
+public class CourseScheduleDate implements Serializable {
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @ApiModelProperty(value = "上课日期")
+    private Date classDate;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty(value = "上课时间")
+    private Date startTime;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty(value = "下课时间")
+    private Date endTime;
+
+    public Date getClassDate() {
+        return classDate;
+    }
+
+    public void setClassDate(Date classDate) {
+        this.classDate = classDate;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+}
+

+ 14 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicSheet.java

@@ -54,15 +54,20 @@ public class MusicSheet implements Serializable {
 
     @NotNull(message = "曲谱音频文件类型不能为空!")
     @TableField("audio_type_")
-    @ApiModelProperty(value = "曲目音频类型 MP3:mp3, MIDI:midi, MP3_METRONOME:mp3_metronome")
+    @ApiModelProperty(value = "曲目音频类型 MP3:mp3, MIDI:midi,")
     private AudioTypeEnum audioType;
 
+	@TableField("mp3_type_")
+	@ApiModelProperty(value = "mp3类型 MP3:mp3, MP3_METRONOME:MP3_METRONOME,")
+	private AudioTypeEnum mp3Type;
+
     @NotBlank(message = "曲谱标签不能为空!")
     @TableField("music_tag_")
     @ApiModelProperty(value = "曲谱标签(多个标签用逗号分隔)")
     private String musicTag;  //曲谱标签(多个标签用逗号分隔)
 
     @TableField("play_speed_")
+	@NotNull(message = "默认播放速度不能为空!")
     @ApiModelProperty(value = "默认播放速度")
     private Integer playSpeed;  //默认播放速度
 
@@ -108,7 +113,6 @@ public class MusicSheet implements Serializable {
     @ApiModelProperty(value = "曲谱价格")
     private java.math.BigDecimal musicPrice;  //曲谱价格
 
-    @NotBlank(message = "音频文件存储路径不能为空!")
     @TableField("audio_file_url_")
     @ApiModelProperty(value = "音频文件存储路径")
     private String audioFileUrl;  //音频文件存储路径
@@ -409,4 +413,12 @@ public class MusicSheet implements Serializable {
 	public void setSourceType(SourceTypeEnum sourceType) {
 		this.sourceType = sourceType;
 	}
+
+	public AudioTypeEnum getMp3Type() {
+		return mp3Type;
+	}
+
+	public void setMp3Type(AudioTypeEnum mp3Type) {
+		this.mp3Type = mp3Type;
+	}
 }

+ 5 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/CourseGroupEnum.java

@@ -4,12 +4,12 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.yonge.cooleshow.common.enums.BaseEnum;
 
 public enum CourseGroupEnum implements BaseEnum<String,CourseGroupEnum> {
-    ING("ING", "进行中"),
-    COMPLETE("COMPLETE", "已完成"),
+    ING("ING", "进行中"),//课程已开始进行中
+    COMPLETE("COMPLETE", "已完成"),//课程组课程全部完成
     DISSOLVE("DISSOLVE", "未成课"),//解散课程
-    CANCEL("CANCEL", "已取消"),
-    APPLY("APPLY", "报名中"),
-    NOT_SALE("NOT_SALE", "未开售");
+    CANCEL("CANCEL", "已取消"),//课程已取消
+    APPLY("APPLY", "报名中"),//开售中可以报名
+    NOT_SALE("NOT_SALE", "未开售");//还未到开售日期
 
     @EnumValue
     private String code;

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

@@ -135,5 +135,10 @@ public interface CourseGroupService extends IService<CourseGroup> {
      * 学生购买直播课程-成功-回调
      */
     void buyLiveCourseSuccess(UserOrderDetailVo orderParam);
+
+    /**
+     * 定时任务-定时修改为报名中状态-每隔10分钟执行一次
+     */
+    void openCourseGroup();
 }
 

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

@@ -3,6 +3,7 @@ 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.dao.CourseScheduleDao;
+import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
@@ -176,6 +177,8 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
      *              <p> - classDate 查询时间-年月
      *              <p> - subjectId 声部id
      */
-    List<CourseStudent> queryStudentLiveCourse(Map<String, Object> param);
+    PageInfo<CourseStudent> queryStudentLiveCourse(Map<String, Object> param);
+
+    void creatPractice(PracticeScheduleDto scheduleDto);
 }
 

+ 9 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/LiveRoomService.java

@@ -2,10 +2,7 @@ package com.yonge.cooleshow.biz.dal.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dao.LiveRoomDao;
-import com.yonge.cooleshow.biz.dal.entity.ImRoomMessage;
-import com.yonge.cooleshow.biz.dal.entity.LiveRoom;
-import com.yonge.cooleshow.biz.dal.entity.RoomInfoCache;
-import com.yonge.cooleshow.biz.dal.entity.RoomUserInfoCache;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.vo.RoomVo;
 
 import java.util.List;
@@ -47,6 +44,14 @@ public interface LiveRoomService extends IService<LiveRoom> {
     String createTempLiveRoom(Map<String, Object> param);
 
     /**
+     * <p>主讲人处理进入和退出房间数据
+     * <p>观看者只处理退出房间数据
+     *
+     * @param userState 用户状态数据
+     */
+    void opsRoom(List<ImUserStateSync> userState);
+
+    /**
      * 同步点赞数量
      *
      * @param roomUid 房间uid

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetAccompanimentService.java

@@ -11,4 +11,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
  **/
 public interface MusicSheetAccompanimentService extends IService<MusicSheetAccompaniment> {
 
+    /**
+     * 删除原音
+     *
+     * @param musicSheetId
+     */
+    void delByMusicSheetId(Long musicSheetId);
 }

+ 15 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java

@@ -17,12 +17,6 @@ import com.yonge.cooleshow.biz.dal.vo.*;
  * @version v1.0
  **/
 public interface MusicSheetService extends IService<MusicSheet> {
-    /**
-     * 保存mp3以及相应的主音或者伴奏文件
-     * @param musicSheetDto
-     * @return
-     */
-    boolean saveMp3AndAccompaniment(MusicSheetDto musicSheetDto, SysUser sysUser);
 
 
     /**
@@ -165,5 +159,20 @@ public interface MusicSheetService extends IService<MusicSheet> {
      * @return
      */
     Integer countTeacherMusicSheet(SysUser sysUser);
+    /***
+     * 查询待处理的记录数
+     * @author liweifan
+     * @updateTime 2022/3/30 18:41
+     * @return: java.lang.Integer
+     */
+    Integer getUserToDoNum();
+
+    /**
+     * 保存曲目信息
+     *
+     * @param musicSheetDto
+     * @return
+     */
+    boolean saveMusicSheet(MusicSheetDto musicSheetDto,Long userId);
 
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VideoLessonGroupService.java

@@ -42,4 +42,6 @@ public interface VideoLessonGroupService extends IService<VideoLessonGroup> {
     IPage<LessonGroupVo> selectLessonGroup(IPage<LessonGroupVo> page, VideoLessonGroupSearch query);
 
     IPage<VideoLessonAuthGroup> queryGroupList(IPage<VideoLessonAuthGroup> page, VideoGroupSearch query);
+
+    IPage<LessonGroupVo> selectLessonGroupById(IPage<LessonGroupVo> page, VideoLessonGroupSearch query);
 }

+ 23 - 18
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java

@@ -638,8 +638,10 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         //查询直播课服务费
         String liveServiceRateStr = sysConfigService.findConfigValue(SysConfigConstant.LIVE_SERVICE_RATE);
         BigDecimal liveServiceRate = new BigDecimal(liveServiceRateStr).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
+        //总课酬  1 - (1 * 手续费率)
+        BigDecimal totalRatePrice = expectPrice.subtract(expectPrice.multiply(liveServiceRate)).setScale(2, RoundingMode.HALF_UP);
         //获取每节课的课酬 key 课堂数  value 课酬
-        Map<Integer, BigDecimal> singerCourseSalary = getSingerCourseSalary(expectPrice, courseGroup.getCourseNum(), liveServiceRate);
+        Map<Integer, BigDecimal> singerCourseSalary = getCourseAveragePrice(courseGroup.getCourseNum(), totalRatePrice);
         //写入课酬表计算-根据课程组总金额计算分配到每节课的金额
         Date now = new Date();
         List<CourseScheduleTeacherSalary> teacherSalaryList = new ArrayList<>();
@@ -660,23 +662,6 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         courseScheduleTeacherSalaryService.getDao().insertBatch(teacherSalaryList);
     }
 
-
-    /**
-     * 学生购买直播课程,计算每节课课酬
-     *
-     * @param totalPrice     课酬总金额
-     * @param totalCourseNum 课程总数
-     * @param rate           课酬费率
-     * @return key 课堂数  value 课酬
-     */
-    private Map<Integer, BigDecimal> getSingerCourseSalary(BigDecimal totalPrice, Integer totalCourseNum, BigDecimal rate) {
-        //1 - (1 * 手续费率)
-        BiFunction<BigDecimal, BigDecimal, BigDecimal> getPrice = (p, r) -> p.subtract(p.multiply(r)).setScale(2, RoundingMode.HALF_UP);
-        //总课酬
-        BigDecimal totalRatePrice = getPrice.apply(totalPrice, rate);
-        return getCourseAveragePrice(totalCourseNum, totalRatePrice);
-    }
-
     /**
      * 计算课堂每节课价格
      *
@@ -722,5 +707,25 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                 .orElseThrow(() -> new BizException("用户不存在"));
     }
+
+    /**
+     * 定时任务-定时修改为报名中状态-每隔10分钟执行一次
+     */
+    public void openCourseGroup() {
+        LocalDate toDay = LocalDate.now();
+        //查询今天未开售的课程组
+        List<CourseGroup> courseGroupList = this.list(Wrappers.<CourseGroup>lambdaQuery()
+                .eq(CourseGroup::getSalesStartDate, toDay.toString())
+                .eq(CourseGroup::getStatus, CourseGroupEnum.NOT_SALE.getCode()));
+        if (CollectionUtils.isEmpty(courseGroupList)) {
+            return;
+        }
+        //修改为报名中状态
+        courseGroupList.forEach(courseGroup -> {
+            courseGroup.setStatus(CourseGroupEnum.APPLY.getCode());
+            this.updateById(courseGroup);
+        })  ;
+    }
+
 }
 

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

@@ -10,10 +10,12 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleRepliedDao;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentPaymentDao;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
+import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.enums.CourseGroupEnum;
 import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.PageUtil;
@@ -28,16 +30,14 @@ import com.yonge.cooleshow.common.page.PageInfo;
 import com.yonge.toolset.utils.date.DateUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.annotations.Param;
 import org.redisson.api.RMap;
 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 org.springframework.validation.annotation.Validated;
 
-import javax.validation.Valid;
+import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
@@ -69,7 +69,6 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
     private TeacherFreeTimeService teacherFreeTimeService;
     @Autowired
     private CourseGroupService courseGroupService;
-
     @Autowired
     private CourseScheduleStudentPaymentService courseScheduleStudentPaymentService;
 
@@ -772,7 +771,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
      *              <p> - subjectId 声部id
      */
     @Override
-    public List<CourseStudent> queryStudentLiveCourse(Map<String, Object> param) {
+    public PageInfo<CourseStudent> queryStudentLiveCourse(Map<String, Object> param) {
         String classDate = WrapperUtil.toStr(param, "classDate");
         String[] classDateSp = classDate.split("-");
         LocalDate firstDay;
@@ -786,8 +785,68 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         param.put("type", CourseScheduleEnum.LIVE.getCode());
         param.put("startDate", firstDay.toString());
         param.put("endDate", lastDay.toString());
-       return baseMapper.queryStudentLiveCourse(param);
+        Page<CourseStudent> pageInfo = PageUtil.getPageInfo(param);
+        pageInfo.setAsc(" cs.start_time_");
+       return PageUtil.pageInfo(baseMapper.queryStudentLiveCourse(pageInfo,param));
+    }
+
+
+    /**
+     * @Description: 创建陪练课
+     * @Author: cy
+     * @Date: 2022/4/20
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void creatPractice(PracticeScheduleDto scheduleDto){
+        //创建单号
+        String orderNo="";
+        scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
+        scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
+        scheduleDto.setMixStudentNum(1);
+
+        //写入course_group
+        baseMapper.addCourseGroup(scheduleDto);
+        Long groupId = scheduleDto.getGroupId();
+
+        BigDecimal unitPrice = scheduleDto.getUnitPrice();
+        List<CourseScheduleDate> classTime = scheduleDto.getClassTime();
+        for (int i = 0; i < classTime.size(); i++) {
+            CourseScheduleDate date = classTime.get(i);
+            CourseSchedule schedule = new CourseSchedule();
+            schedule.setClassDate(date.getClassDate());
+            schedule.setStartTime(date.getStartTime());
+            schedule.setEndTime(date.getEndTime());
+            schedule.setCourseGroupId(groupId);
+            schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
+            schedule.classNum(i+1);
+            schedule.setTeacherId(scheduleDto.getTeacherId());
+            schedule.setLock(1);
+            schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
+            schedule.setCreatedBy(scheduleDto.getStudentId());
+            //写入course_schedule
+            baseMapper.insert(schedule);
+
+            Long scheduleId = schedule.getId();
+            CourseScheduleStudentPayment payment = new CourseScheduleStudentPayment();
+            payment.setUserId(scheduleDto.getStudentId());
+            payment.setCourseId(scheduleId);
+            payment.setCourseGroupId(groupId);
+            payment.setCourseType(CourseScheduleEnum.PRACTICE.getCode());
+            payment.setOrderNo(orderNo);
+            payment.setOriginalPrice(unitPrice);
+            payment.setExpectPrice(unitPrice);
+            payment.setActualPrice(unitPrice);
+            //写course_schedule_student_payment
+            courseScheduleStudentPaymentService.save(payment);
+        }
     }
 
+    /**
+     * 陪练课下单
+     *
+     * 调用下单接口
+     * 成功:将course_schedule中lock_改为0
+     * 失败:回滚以上数据
+     */
 }
 

+ 98 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/LiveRoomServiceImpl.java

@@ -325,6 +325,102 @@ public class LiveRoomServiceImpl extends ServiceImpl<LiveRoomDao, LiveRoom> impl
         log.info("destroyLiveRoom success: {}", roomId);
     }
 
+
+    /**
+     * <p>主讲人处理进入和退出房间数据
+     * <p>观看者只处理退出房间数据
+     *
+     * @param userState 用户状态数据
+     */
+    public void opsRoom(List<ImUserStateSync> userState) {
+        if (CollectionUtils.isEmpty(userState)) {
+            return;
+        }
+        userState.forEach(user -> {
+            log.info("opsRoom>>>> {}", JSONObject.toJSONString(user));
+            if (StringUtils.isBlank(user.getStatus())) {
+                return;
+            }
+            Date now = new Date();
+            //获取当前用户状态变更的时间
+            long userStateTime = Optional.ofNullable(user.getTime()).orElse(now.getTime());
+            String userIdStr = user.getUserid();
+            RBucket<Long> userStateTimeCache = redissonClient.getBucket(LIVE_TEACHER_LAST_TIME.replace(USER_ID, userIdStr));
+            if (userStateTimeCache.isExists()) {
+                //缓存的时间比当前传入时间大则放弃这条数据
+                long cacheTime = userStateTimeCache.get();
+                if (cacheTime > userStateTime) {
+                    return;
+                }
+            }
+            //将最新的时间写入缓存
+            userStateTimeCache.set(userStateTime, 5L, TimeUnit.MINUTES);
+            //直播间号
+            String roomUid;
+            //根据用户id获取用户当前房间号
+            RBucket<String> roomUidCache = redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userIdStr));
+            if (!roomUidCache.isExists()) {
+                return;
+            }
+            roomUid = roomUidCache.get();
+            //根据房间号获取房间信息
+            RBucket<RoomInfoCache> roomInfoCache = redissonClient.getBucket(LIVE_ROOM_INFO.replace(ROOM_UID, roomUid));
+            if (!roomInfoCache.isExists()) {
+                return;
+            }
+            RoomInfoCache roomInfo = roomInfoCache.get();
+            //主讲人
+            if (roomInfo.getSpeakerId().toString().equals(userIdStr)) {
+                //主讲人进入房间
+                if (user.getStatus().equals("0")) {
+                    roomInfo.setSpeakerState(0);
+                    roomInfo.setJoinRoomTime(now);
+                    log.info("opsRoom>>>> join roomInfo {}", JSONObject.toJSONString(roomInfo));
+                    roomInfoCache.set(roomInfo);
+                    return;
+                }
+                roomInfo.setExitRoomTime(now);
+                log.info("opsRoom>>>> exit roomInfo {}", JSONObject.toJSONString(roomInfo));
+                roomInfoCache.set(roomInfo);
+                return;
+            }
+            //观看者只接受退出消息 status=0 是进入房间
+            if (user.getStatus().equals("0")) {
+                return;
+            }
+            //观看者
+            Long userId = Long.valueOf(userIdStr);
+            //从房间累计用户信息中查询该用户的信息
+            RMap<Long, RoomUserInfoCache> roomTotalUser = redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
+            //该房间未查询到用户数据则不处理
+            if (!roomTotalUser.isExists() && !roomTotalUser.containsKey(userId)) {
+                return;
+            }
+            //查询到用户数据
+            RoomUserInfoCache userInfo = roomTotalUser.get(userId);
+            //用户是在房间的状态 并且 突然离线 - 那么融云会发送用户离线消息-此刻就发送退出房间消息给主讲人
+            if (userInfo.getState() == 0 && user.getStatus().equals("1")) {
+                ImRoomMessage message = new ImRoomMessage();
+                message.setFromUserId(userId.toString());
+                message.setToChatroomId(roomUid);
+                message.setObjectName(ImRoomMessage.RC_CHATROOM_LEAVE);
+                try {
+                    publishRoomMessage(message);
+                } catch (Exception e) {
+                    log.error("opsRoom>>>>  looker error {}", e.getMessage());
+                    log.error("opsRoom>>>>  looker error sendMessage {} : leave : {}", message, JSONObject.toJSONString(userInfo));
+                }
+                log.info("opsRoom>>>> looker leave : {}", JSONObject.toJSONString(userInfo));
+            }
+            //记录退出时间 并写入缓存
+            userInfo.setLastOutTime(now);
+            userInfo.setState(1);
+            roomTotalUser.fastPut(userId, userInfo);
+            log.info("opsRoom>>>> looker userInfo: {}", JSONObject.toJSONString(userInfo));
+        });
+
+    }
+
     /**
      * 同步点赞数量
      *
@@ -352,7 +448,7 @@ public class LiveRoomServiceImpl extends ServiceImpl<LiveRoomDao, LiveRoom> impl
         roomInfo.setLikeNum(getLike(roomUid));
         roomInfo.setLookNum(getLooker(roomUid));
 
-        //记录当前对应的房间uid
+        //记录当前用户对应的房间uid
         redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userId.toString())).set(roomUid, 2L, TimeUnit.DAYS);
 
         Date now = new Date();
@@ -484,7 +580,7 @@ public class LiveRoomServiceImpl extends ServiceImpl<LiveRoomDao, LiveRoom> impl
         param.put("year", "2022");
         param.put("singleCourseMinutes", 60);
         param.put("teacherId", 4);
-        List<CourseCalendarEntity> courseTimeEntities =  courseScheduleService.createLiveCourseCalendar(param);
+        List<CourseCalendarEntity> courseTimeEntities = courseScheduleService.createLiveCourseCalendar(param);
         result.put("自动生成课时", courseTimeEntities);
 
         //获取房间信息

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

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yonge.cooleshow.biz.dal.dao.LiveRoomVideoDao;
 import com.yonge.cooleshow.biz.dal.entity.LiveRoom;
@@ -48,16 +49,13 @@ public class LiveRoomVideoServiceImpl extends ServiceImpl<LiveRoomVideoDao, Live
             Integer notifyType = recordNotify.getType();
             if (Objects.nonNull(notifyType)) {
                 Date now = new Date();
-                LiveRoomVideo video = this.getOne(new QueryWrapper<LiveRoomVideo>().lambda()
-                        .eq(LiveRoomVideo::getRoomUid, roomUid)
-                        .eq(LiveRoomVideo::getRecordId, recordId));
                 //notifyType 1: 录制开始;4: 文件上传-融云回调完成
                 if (notifyType == 1) {
-                    video = new LiveRoomVideo();
+                    LiveRoomVideo video = new LiveRoomVideo();
                     LiveRoom room = liveRoomService.getOne(new QueryWrapper<LiveRoom>().lambda()
                             .eq(LiveRoom::getRoomUid, roomUid));
                     video.setCourseGroupId(room.getCourseGroupId());
-                    video.setCourseId(room.getId());
+                    video.setCourseId(room.getCourseId());
                     video.setRoomUid(roomUid);
                     video.setRecordId(recordId);
                     video.setUrl(fileUrl);
@@ -67,11 +65,13 @@ public class LiveRoomVideoServiceImpl extends ServiceImpl<LiveRoomVideoDao, Live
                     this.save(video);
                 }
                 if (notifyType == 4) {
+                    LiveRoomVideo video = this.getOne(Wrappers.<LiveRoomVideo>lambdaQuery()
+                            .eq(LiveRoomVideo::getRoomUid, roomUid)
+                            .eq(LiveRoomVideo::getRecordId, recordId));
                     video.setEndTime(now);
                     video.setType(notifyType);
                     this.updateById(video);
                 }
-
             }
         }
     }

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

@@ -26,4 +26,9 @@ public class MusicSheetAccompanimentServiceImpl extends ServiceImpl<MusicSheetAc
     public MusicSheetAccompanimentDao getDao() {
         return musicSheetAccompanimentDao;
     }
+
+    @Override
+    public void delByMusicSheetId(Long musicSheetId) {
+        musicSheetAccompanimentDao.delByMusicSheetId(musicSheetId);
+    }
 }

+ 33 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java

@@ -63,26 +63,21 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
         return musicSheetDao;
     }
 
-    @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean saveMp3AndAccompaniment(MusicSheetDto musicSheetDto, SysUser sysUser) {
+    public boolean saveMp3AndAccompaniment(MusicSheetDto musicSheetDto,Long userId) {
         MusicSheet musicSheet = new MusicSheet();
         BeanUtils.copyProperties(musicSheetDto, musicSheet);
         //保存主表
-        musicSheet.setCreateBy(sysUser.getId());
-        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setUpdateBy(userId);
         musicSheet.setUpdateTime(new Date());
         musicSheet.setState(YesOrNoEnum.NO);
-        musicSheet.setCreateTime(new Date());
-        int count = musicSheetDao.insert(musicSheet);
+        this.saveOrUpdate(musicSheet);
 
         Long sheetId = musicSheet.getId();
         List<MusicSheetAccompaniment> list = musicSheetDto.getBackground();
-        list.forEach(musicSheetAccompaniment -> musicSheetAccompaniment.setMusicSheetId(sheetId).setCreateBy(sysUser.getId()).setCreateTime(new Date()));
-        musicSheetAccompanimentService.saveBatch(list);
-        count += list.size();
+        list.forEach(musicSheetAccompaniment -> musicSheetAccompaniment.setMusicSheetId(sheetId).setCreateBy(userId).setCreateTime(new Date()));
+        return musicSheetAccompanimentService.saveBatch(list);
 
-        return count > 1;
     }
 
     @Override
@@ -272,4 +267,32 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
                 .count();
     }
 
+    @Override
+    public Integer getUserToDoNum() {
+        return baseMapper.getUserToDoNum();
+    }
+
+    @Override
+    public boolean saveMusicSheet(MusicSheetDto musicSheetDto,Long userId) {
+
+        if (musicSheetDto.getId() != null) {
+            musicSheetAccompanimentService.delByMusicSheetId(musicSheetDto.getId());
+        }
+
+        List<MusicSheetAccompaniment> list;
+        if (!AudioTypeEnum.MIDI.getCode().equals(musicSheetDto.getAudioType().getCode())){
+            list = musicSheetDto.getBackground();
+            if (CollectionUtils.isEmpty(list)){
+                throw new BizException("mp3音频文件对应的主音或者伴奏文件没有提供");
+            }
+            return saveMp3AndAccompaniment(musicSheetDto,userId);
+        } else {
+            MusicSheet musicSheet = new MusicSheet();
+            BeanUtils.copyProperties(musicSheetDto, musicSheet);
+            musicSheet.setUpdateTime(new Date());
+            musicSheet.setUpdateBy(userId);
+            musicSheet.setState(YesOrNoEnum.NO);
+            return this.saveOrUpdate(musicSheet);
+        }
+    }
 }

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

@@ -8,6 +8,7 @@ import com.yonge.cooleshow.biz.dal.entity.TeacherFreeTime;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
 import com.yonge.cooleshow.biz.dal.service.TeacherFreeTimeService;
 import com.yonge.cooleshow.biz.dal.vo.TeacherFreeTimeVo;
+import com.yonge.cooleshow.common.exception.BizException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -61,6 +62,9 @@ public class TeacherFreeTimeServiceImpl extends ServiceImpl<TeacherFreeTimeDao,
     @Override
     public TeacherFreeTimeVo getDetail(PracticeTimesSetting practiceTimesSetting) {
         TeacherFreeTimeVo getDetail=baseMapper.getDetail(practiceTimesSetting);
+        if (getDetail==null){
+            return getDetail;
+        }
         List<TeacherSubjectPrice> priceList=baseMapper.getPrice(getDetail.getId());
         getDetail.setSubjectPrice(priceList);
         return getDetail;

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

@@ -231,4 +231,14 @@ public class VideoLessonGroupServiceImpl extends ServiceImpl<VideoLessonGroupDao
     public IPage<VideoLessonAuthGroup> queryGroupList(IPage<VideoLessonAuthGroup> page, VideoGroupSearch query) {
         return page.setRecords(baseMapper.queryGroupList(page, query));
     }
+
+    /**
+     * @Description: 学生端-我的-我的课程-购买的视频课组
+     * @Author: cy
+     * @Date: 2022/4/20
+     */
+    @Override
+    public IPage<LessonGroupVo> selectLessonGroupById(IPage<LessonGroupVo> page, VideoLessonGroupSearch query) {
+        return page.setRecords(baseMapper.selectLessonGroup(page, query));
+    }
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/LiveCourseGroupStudentCourseVo.java

@@ -47,6 +47,9 @@ public class LiveCourseGroupStudentCourseVo {
     @ApiModelProperty("学生考勤id")
     private Long studentAttendanceId;
 
+    @ApiModelProperty("订单编号")
+    private String orderNo;
+
     public Long getCourseId() {
         return courseId;
     }
@@ -103,4 +106,12 @@ public class LiveCourseGroupStudentCourseVo {
     public void setStudentAttendanceId(Long studentAttendanceId) {
         this.studentAttendanceId = studentAttendanceId;
     }
+
+    public String getOrderNo() {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo) {
+        this.orderNo = orderNo;
+    }
 }

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

@@ -247,6 +247,7 @@
         cs.start_time_ as startTime,
         cs.end_time_ as endTime,
         cs.status_ as courseStatue,
+        cssp.order_no_ as orderNo,
         sa.id_ as studentAttendanceId
         from course_schedule cs
         left join course_schedule_student_payment cssp on cs.id_ = cssp.course_id_

+ 6 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -426,7 +426,12 @@
         <if test="param.courseState != null">
             and cs.status_ = #{param.courseState}
         </if>
-        ORDER BY cs.start_time_
     </select>
 
+    <insert id="addCourseGroup" parameterType="com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto" useGeneratedKeys="true" keyProperty="groupId">
+        Insert INTO course_group(teacher_id_,type_,name_,subject_id_,single_course_minutes_,course_num_,course_introduce_,
+        course_price_,status_,created_by_,mix_student_num_,course_start_time_)
+        VALUES (#{teacherId},#{type},#{courseGroupName},#{subjectId},#{singleCourseMinutes},#{courseNum},#{courseIntroduce},
+        #{coursePrice},#{status},#{studentId},#{mixStudentNum},#{courseStartTime})
+    </insert>
 </mapper>

+ 3 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetAccompanimentMapper.xml

@@ -17,6 +17,7 @@
 		id_, music_sheet_id_, music_subject_, audio_file_url_, sort_number_, create_time_, create_by_
 	</sql>
 
-
-
+	<delete id="delByMusicSheetId">
+		delete  from music_sheet_accompaniment where music_sheet_id_ = #{musicSheetId}
+    </delete>
 </mapper>

+ 7 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/VideoLessonGroupMapper.xml

@@ -220,6 +220,10 @@
 			<if test="param.auditStatus !=null">
 				AND g.audit_status_ = #{param.auditStatus}
 			</if>
+			<if	test="param.studentId != null">
+				g.id_ IN
+				(SELECT video_lesson_group_id_ FROM video_lesson_purchase_record WHERE student_id_=#{param.studentId} AND order_status_=1)
+			</if>
 		</where>
 	</select>
 	<select id="queryGroupList" resultType="com.yonge.cooleshow.biz.dal.vo.VideoLessonAuthGroup">
@@ -258,4 +262,7 @@
 			</if>
 		</where>
 	</select>
+	<select id="selectLessonGroupById" resultType="com.yonge.cooleshow.biz.dal.vo.LessonGroupVo">
+
+	</select>
 </mapper>

+ 3 - 1
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseScheduleController.java

@@ -120,10 +120,12 @@ public class StudentCourseScheduleController extends BaseController {
             @ApiImplicitParam(name = "classDate", dataType = "String", required = true, value = "年月"),
             @ApiImplicitParam(name = "courseState", dataType = "String", value = "课程状态 NOT_START未开始 ING进行中 COMPLETE已完成 CANCEL已取消"),
             @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
     })
     @ApiOperation("学生-查询直播课")
     @PostMapping("/queryStudentLiveCourse")
-    public HttpResponseResult<List<CourseStudent>> queryStudentLiveCourse(@RequestBody Map<String, Object> param) {
+    public HttpResponseResult<PageInfo<CourseStudent>> queryStudentLiveCourse(@RequestBody Map<String, Object> param) {
         return succeed(courseScheduleService.queryStudentLiveCourse(param));
     }
 

+ 101 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentLiveRoomController.java

@@ -0,0 +1,101 @@
+package com.yonge.cooleshow.student.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.entity.ImUserStateSync;
+import com.yonge.cooleshow.biz.dal.entity.RoomInfoCache;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.biz.dal.vo.RoomVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播房间与课程的关系表表(LiveRoom)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:41:16
+ */
+@Api(tags = "直播房间与课程的关系表表")
+@RestController
+@RequestMapping("/liveRoom")
+public class StudentLiveRoomController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(StudentLiveRoomController.class);
+    /**
+     * 服务对象
+     */
+    @Resource
+    private LiveRoomService liveRoomService;
+
+    /**
+     * 根据房间uid查询房间信息
+     *
+     * @param roomUid 房间uid
+     */
+    @GetMapping("queryRoomInfo")
+    public HttpResponseResult<RoomVo> queryRoomInfo(@RequestParam("roomUid") String roomUid) {
+        return succeed(liveRoomService.queryRoomInfo(roomUid));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "roomTitle", dataType = "String", value = "房间标题"),
+            @ApiImplicitParam(name = "liveRemark", dataType = "String", value = "直播内容/最多200个字"),
+    })
+    @ApiOperation("创建临时房间-直播间")
+    @PostMapping("/createTempLiveRoom")
+    public HttpResponseResult<String> createTempLiveRoom(@RequestBody Map<String, Object> param) {
+        return succeed(liveRoomService.createTempLiveRoom(param));
+    }
+
+    @ApiOperation("同步点赞数量")
+    @GetMapping("/syncLike")
+    public HttpResponseResult<Object> syncLike(@ApiParam(value = "房间uid", required = true) String roomUid,
+                                       @ApiParam(value = "点赞数", required = true) Integer likeNum) {
+        liveRoomService.syncLike(roomUid, likeNum);
+        return succeed();
+    }
+
+    @ApiOperation("进入房间")
+    @GetMapping(value = "/joinRoom")
+    public HttpResponseResult<RoomInfoCache> joinRoom(String roomUid, Long userId) {
+        return succeed(liveRoomService.joinRoom(roomUid, userId));
+    }
+
+    @ApiOperation("定时任务-创建房间-直播间")
+    @GetMapping("/createCourseLiveRoom")
+    public void createCourseLiveRoom() {
+        liveRoomService.createCourseLiveRoom();
+    }
+
+    @ApiOperation("定时任务-销毁房间-直播间")
+    @GetMapping("/destroyExpiredLiveRoom")
+    public void destroyExpiredLiveRoom() {
+        liveRoomService.destroyExpiredLiveRoom();
+    }
+
+    /**
+     * 同步融云用户状态变更
+     *
+     * @param userState
+     */
+    @PostMapping(value = "/syncUserStatus")
+    public void statusImUser(@RequestBody List<ImUserStateSync> userState) {
+        log.info("opsRoom >>>>> : {}", JSONObject.toJSONString(userState));
+        liveRoomService.opsRoom(userState);
+    }
+
+    @ApiOperation("方便测试观察房间数据的方法")
+    @GetMapping("/test")
+    public Object destroyExpiredLiveRoom(@RequestParam("roomUid") String roomUid) {
+        return liveRoomService.test(roomUid);
+    }
+
+}
+

+ 13 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/VideoLessonController.java

@@ -20,6 +20,7 @@ import com.yonge.cooleshow.common.page.PageInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -94,4 +95,16 @@ public class VideoLessonController extends BaseController {
         IPage<LessonGroupVo> pages = videoLessonGroupService.selectLessonGroup(PageUtil.getPage(query), query);
         return succeed(PageUtil.pageInfo(pages));
     }
+
+    @ApiOperation(value = "学生端-我的-我的课程-购买的视频课组")
+    @PostMapping("/selectMyGroup")
+    public HttpResponseResult<PageInfo<LessonGroupVo>> myLessonGroup(@RequestBody VideoLessonGroupSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setStudentId(user.getId());
+        IPage<LessonGroupVo> pages = videoLessonGroupService.selectLessonGroupById(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
 }

+ 8 - 18
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java

@@ -76,28 +76,17 @@ public class MusicSheetController extends BaseController {
         musicSheetDto.setAuditStatus(AuthStatusEnum.DOING);
         musicSheetDto.setSubmitAuditTime(new Date());
         musicSheetDto.setSourceType(SourceTypeEnum.TEACHER);
-        List<MusicSheetAccompaniment> list;
-        if (!AudioTypeEnum.MIDI.getCode().equals(musicSheetDto.getAudioType().getCode())){
-            list = musicSheetDto.getBackground();
-            if (CollectionUtils.isEmpty(list)){
-                return failed("mp3音频文件对应的主音或者伴奏文件没有提供");
-            }
-            musicSheetService.saveMp3AndAccompaniment(musicSheetDto,sysUser);
-        } else {
-            MusicSheet musicSheet = new MusicSheet();
-            BeanUtils.copyProperties(musicSheetDto, musicSheet);
-            musicSheet.setCreateBy(sysUser.getId());
-            musicSheet.setCreateTime(new Date());
-            musicSheet.setState(YesOrNoEnum.NO);
-            musicSheetService.save(musicSheet);
-        }
+
+        musicSheetDto.setCreateBy(sysUser.getId());
+        musicSheetDto.setCreateTime(new Date());
+        musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());
         return succeed("新增曲谱成功");
     }
 
 
     @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
     @PostMapping(value="/update", consumes="application/json", produces="application/json")
-    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheet musicSheet) {
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetDto musicSheet) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null  || sysUser.getId() == null) {
             return failed("用户信息获取失败");
@@ -110,8 +99,9 @@ public class MusicSheetController extends BaseController {
         musicSheet.setUpdateTime(new Date());
         musicSheet.setSubmitAuditTime(new Date());
         musicSheet.setAuditStatus(AuthStatusEnum.DOING);
-        boolean result = musicSheetService.updateById(musicSheet);
-        if (result){
+        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setUpdateTime(new Date());
+        if ( musicSheetService.saveMusicSheet(musicSheet,sysUser.getId())){
             return succeed("修改成功");
         } else {
             return failed("修改失败");

+ 4 - 3
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/LiveRoomController.java → cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherLiveRoomController.java

@@ -26,8 +26,8 @@ import java.util.Map;
 @Api(tags = "直播房间与课程的关系表表")
 @RestController
 @RequestMapping("/liveRoom")
-public class LiveRoomController extends BaseController {
-    private final static Logger log = LoggerFactory.getLogger(LiveRoomController.class);
+public class TeacherLiveRoomController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(TeacherLiveRoomController.class);
     /**
      * 服务对象
      */
@@ -87,7 +87,8 @@ public class LiveRoomController extends BaseController {
      */
     @PostMapping(value = "/syncUserStatus")
     public void statusImUser(@RequestBody List<ImUserStateSync> userState) {
-        log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(userState));
+        log.info("opsRoom >>>>> : {}", JSONObject.toJSONString(userState));
+        liveRoomService.opsRoom(userState);
     }
 
     @ApiOperation("方便测试观察房间数据的方法")