刘俊驰 7 meses atrás
pai
commit
06b5f5afd8
59 arquivos alterados com 3457 adições e 204 exclusões
  1. 3 0
      mec-application/src/main/java/com/ym/mec/config/WebMvcConfig.java
  2. 139 0
      mec-application/src/main/java/com/ym/mec/student/controller/MusicPracticeRecordController.java
  3. 155 0
      mec-application/src/main/java/com/ym/mec/student/controller/MusicSheetController.java
  4. 5 0
      mec-application/src/main/java/com/ym/mec/student/controller/StudentManageController.java
  5. 19 0
      mec-application/src/main/java/com/ym/mec/student/controller/UserMusicController.java
  6. 88 0
      mec-application/src/main/java/com/ym/mec/student/controller/open/OpenMusicSheetController.java
  7. 140 0
      mec-application/src/main/java/com/ym/mec/teacher/controller/MusicPracticeRecordController.java
  8. 159 0
      mec-application/src/main/java/com/ym/mec/teacher/controller/MusicSheetController.java
  9. 16 0
      mec-application/src/main/java/com/ym/mec/teacher/controller/UserMusicController.java
  10. 88 0
      mec-application/src/main/java/com/ym/mec/teacher/controller/open/OpenMusicSheetController.java
  11. 107 0
      mec-application/src/main/java/com/ym/mec/vo/MusicSheetAccompanimentVo.java
  12. 705 0
      mec-application/src/main/java/com/ym/mec/vo/MusicSheetVo.java
  13. 23 0
      mec-application/src/main/java/com/ym/mec/vo/MusicalInstrumentWrapper.java
  14. 138 0
      mec-application/src/main/java/com/ym/mec/web/controller/MusicPracticeRecordController.java
  15. 147 0
      mec-application/src/main/java/com/ym/mec/web/controller/MusicSheetController.java
  16. 88 0
      mec-application/src/main/java/com/ym/mec/web/controller/open/OpenMusicSheetController.java
  17. 0 12
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java
  18. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/InstrumentDao.java
  19. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysMusicCompareRecordDao.java
  20. 12 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Student.java
  21. 18 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicCompareRecord.java
  22. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicScore.java
  23. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/UserMusic.java
  24. 35 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/FeatureType.java
  25. 15 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysExamSongQueryInfo.java
  26. 560 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/MusicPracticeRecordWrapper.java
  27. 132 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/MusicSheetAccompanimentWrapper.java
  28. 37 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/MusicSheetWrapper.java
  29. 14 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/UserMusicWrapper.java
  30. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/InstrumentService.java
  31. 31 0
      mec-biz/src/main/java/com/ym/mec/biz/service/MusicPracticeRecordService.java
  32. 4 1
      mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java
  33. 15 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicScoreService.java
  34. 5 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java
  35. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseConvertLogServiceImpl.java
  36. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleConvertServiceImpl.java
  37. 3 3
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  38. 7 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/InstrumentServiceImpl.java
  39. 122 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicPracticeRecordServiceImpl.java
  40. 90 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentManageServiceImpl.java
  41. 19 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java
  42. 44 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicScoreServiceImpl.java
  43. 12 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/UserMusicServiceImpl.java
  44. 2 1
      mec-biz/src/main/resources/config/mybatis/CoursePatrolEvaluationMapper.xml
  45. 2 0
      mec-biz/src/main/resources/config/mybatis/CourseScheduleEvaluateMapper.xml
  46. 126 142
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  47. 1 1
      mec-biz/src/main/resources/config/mybatis/DemoGroupMapper.xml
  48. 6 0
      mec-biz/src/main/resources/config/mybatis/InstrumentMapper.xml
  49. 1 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml
  50. 7 4
      mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml
  51. 6 4
      mec-biz/src/main/resources/config/mybatis/StudentAttendanceMapper.xml
  52. 8 5
      mec-biz/src/main/resources/config/mybatis/StudentStatisticsMapper.xml
  53. 2 2
      mec-biz/src/main/resources/config/mybatis/StudentVisitMapper.xml
  54. 1 0
      mec-biz/src/main/resources/config/mybatis/SubjectMapper.xml
  55. 46 2
      mec-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  56. 2 1
      mec-biz/src/main/resources/config/mybatis/SysMusicScoreAccompanimentMapper.xml
  57. 15 2
      mec-biz/src/main/resources/config/mybatis/SysMusicScoreMapper.xml
  58. 8 0
      mec-biz/src/main/resources/config/mybatis/UserMusicMapper.xml
  59. 5 0
      mec-common/common-core/src/main/java/com/ym/mec/common/config/LocalFastJsonHttpMessageConverter.java

+ 3 - 0
mec-application/src/main/java/com/ym/mec/config/WebMvcConfig.java

@@ -11,6 +11,7 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.microsvc.toolkit.common.webportal.converter.EnumsConvertorFactory;
 import com.ym.mec.common.config.EnumConverterFactory;
 import com.ym.mec.common.config.LocalFastJsonHttpMessageConverter;
 import com.ym.mec.common.enums.BaseEnum;
@@ -52,6 +53,8 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 枚举映射转换
+		registry.addConverterFactory(new EnumsConvertorFactory());
 	}
 
 	@Override

+ 139 - 0
mec-application/src/main/java/com/ym/mec/student/controller/MusicPracticeRecordController.java

@@ -0,0 +1,139 @@
+package com.ym.mec.student.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.common.enums.music.EEvaluationStandard;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.validator.group.ValidGroups;
+import com.ym.mec.biz.dal.entity.UserMusic;
+import com.ym.mec.biz.dal.enums.ClientEnum;
+import com.ym.mec.biz.dal.wrapper.MusicPracticeRecordWrapper;
+import com.ym.mec.biz.service.MusicPracticeRecordService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.biz.service.SysUserService;
+import com.ym.mec.biz.service.UserMusicService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/musicPracticeRecord")
+@Api(tags = "曲目练习记录")
+public class MusicPracticeRecordController {
+
+    @Autowired
+    private MusicPracticeRecordService musicPracticeRecordService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    /**
+     * 查询单条
+     * @param id 详情ID
+     * @return R<MusicPracticeRecordVo.MusicPracticeRecord>
+     */
+    @ApiOperation(value = "详情", notes = "曲目练习记录-根据详情ID查询单条, 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public R<MusicPracticeRecordWrapper.MusicPracticeRecord> detail(@PathVariable("id") Long id) {
+
+        MusicPracticeRecordWrapper.Entity wrapper = musicPracticeRecordService.detail(id);
+
+        if (wrapper == null) {
+            throw new BizException("记录不存在");
+        }
+
+        // 上传过作品,用作品视频路径覆盖上传视频路径
+        // ID集合
+        Map<Long, UserMusic> userMusicMap = userMusicService.getMapByMusicPracticeRecordIds(Lists.newArrayList(Long.parseLong(wrapper.getId())));
+
+        UserMusic userMusic = userMusicMap.get(Long.parseLong(wrapper.getId()));
+        if (Objects.nonNull(userMusic)) {
+            wrapper.setVideoFilePath(userMusic.getVideoUrl());
+        }
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(JSON.toJSONString(wrapper));
+
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(Integer.parseInt(wrapper.getMusicSheetId()));
+        if (musicSheet != null) {
+            from.setRhythmFlag(musicSheet.getEvaluationStandard() != EEvaluationStandard.FREQUENCY);
+        }
+
+        return R.from(from);
+    }
+
+
+    /**
+     * 新增
+     * @param record MusicPracticeRecordVo.MusicPracticeRecord
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "曲目练习记录- 传入 MusicPracticeRecordVo.MusicPracticeRecord")
+    @PostMapping("/save")
+    public R<String> add(@Validated(ValidGroups.Add.class) @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record) {
+
+        Integer userId = sysUserService.getUserId();
+        record.userId(String.valueOf(userId)).clientType(ClientEnum.STUDENT.getCode());
+
+        // 新增数据
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(record.jsonString());
+        if (record.getDelFlag() !=null && record.getDelFlag()) {
+            from.setDelFlag(false);
+            from.setHiddenFlag(true);
+        }
+
+        return R.from(musicPracticeRecordService.add(from));
+    }
+
+    @ApiOperation(value = "用户最后一次评测数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "recordId", value = "曲目练习记录Id", dataType = "long")
+    })
+    @GetMapping("/getLastEvaluationMusicalNotesPlayStats")
+    public Object getLastEvaluationMusicalNotesPlayStats(Long recordId){
+        return R.from(musicPracticeRecordService.getLastEvaluationMusicalNotesPlayStats(recordId));
+    }
+
+    @ApiOperation(value = "上传音频文件")
+    @PostMapping("videoUpload")
+    public R<Boolean> videoUpload( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record){
+
+        if (Objects.isNull(record.getId())) {
+            throw BizException.from("recordId不能为空");
+        }
+        if (Objects.isNull(record.getVideoFilePath())) {
+            throw BizException.from("videoUrl不能为空");
+        }
+
+        MusicPracticeRecordWrapper.Entity practiceRecord = musicPracticeRecordService.getById(record.getId());
+        if (Objects.isNull(practiceRecord)) {
+            throw BizException.from("记录不存在");
+        }
+
+        practiceRecord.setVideoFilePath(record.getVideoFilePath());
+        musicPracticeRecordService.update(practiceRecord);
+
+        return R.from(true);
+    }
+
+}

+ 155 - 0
mec-application/src/main/java/com/ym/mec/student/controller/MusicSheetController.java

@@ -0,0 +1,155 @@
+package com.ym.mec.student.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.ym.mec.biz.dal.entity.Instrument;
+import com.ym.mec.biz.dal.entity.Student;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.entity.Teacher;
+import com.ym.mec.biz.dal.enums.ClientEnum;
+import com.ym.mec.biz.dal.enums.ClientTypeEnum;
+import com.ym.mec.biz.dal.page.SysExamSongQueryInfo;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import com.ym.mec.biz.dal.wrapper.MusicSheetWrapper;
+import com.ym.mec.biz.service.InstrumentService;
+import com.ym.mec.biz.service.StudentService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.biz.service.SysUserService;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.vo.MusicSheetVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/musicSheet")
+@Api(tags = "曲谱表")
+public class MusicSheetController {
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+
+    @Resource
+    private SysUserService sysUserService;
+
+    @Autowired
+    private StudentService studentService;
+
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<MusicSheetVo.MusicSheet>
+     */
+    @ApiOperation(value = "查询内容平台数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/cbsDetail/{id}")
+    public R<MusicSheetVo.MusicSheetDetail> cbsDetail(@PathVariable("id") Integer id) {
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(Long.valueOf(id));
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        SysMusicScore detail = musicSheetService.get(id);
+        if (detail == null) {
+            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(StringUtils.isBlank(detail.getRankIds()) ? "FREE" : "VIP");
+            // 设置业务端曲目分类
+            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getIsConvertibleScore());
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Integer> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Integer::parseInt).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Integer, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "曲谱表- 传入 MusicSheetVo.MusicSheetQuery")
+    @PostMapping("/page")
+    public R<PageInfo<MusicSheetWrapper.MusicSheet>> page(@RequestBody MusicSheetVo.MusicSheetQuery query) {
+
+        SysExamSongQueryInfo queryInfo = new SysExamSongQueryInfo();
+
+        Integer userId = sysUserService.getUserId();
+        Student student = studentService.get(userId);
+        if(query.getMusicSheetCategoriesId() != null) {
+            queryInfo.setCategoriesId(query.getMusicSheetCategoriesId().toString());
+        }
+        if (query.getMusicalInstrumentId() != null) {
+            // 乐器转换为声部
+            Instrument instrument = instrumentService.getById(query.getMusicalInstrumentId());
+            if (instrument != null) {
+                queryInfo.setSubjectId(instrument.getSubjectId());
+            }
+        } else if (StringUtils.isNotBlank(student.getSubjectIdList())){
+            queryInfo.setSubjectId(Integer.parseInt(student.getSubjectIdList()));
+        }
+        queryInfo.setPage(query.getPage());
+        queryInfo.setRows(query.getRows());
+        queryInfo.setName(query.getName());
+        queryInfo.setType("COMMON");
+        queryInfo.setClientFlag(true);
+        queryInfo.setClientType(ClientTypeEnum.SMART_PRACTICE);
+        queryInfo.setRecentFlag(query.getRecentFlag());
+        queryInfo.setUserId(userId);
+        queryInfo.setClientId(ClientEnum.STUDENT.getCode().toLowerCase());
+        PageInfo<SysMusicScore> sysMusicScorePageInfo1 = musicSheetService.queryMusicScorePageInfo(queryInfo);
+        PageInfo<MusicSheetWrapper.MusicSheet> convert = sysMusicScorePageInfo1.convert(o -> {
+            MusicSheetWrapper.MusicSheet musicSheet = new MusicSheetWrapper.MusicSheet();
+            musicSheet.setId(o.getId().toString());
+            musicSheet.setMusicSheetCategoriesId(o.getCategoriesId());
+            musicSheet.setMusicSheetName(o.getName());
+            musicSheet.setTitleImg(o.getTitleImg());
+            musicSheet.setComposer(o.getComposer());
+            musicSheet.setCbsMusicSheetId(o.getCbsMusicSheetId());
+            musicSheet.setUsedNum(0L);
+            musicSheet.setPaymentType(StringUtils.isNotBlank(o.getRankIds()) && o.getRankIds().contains("1") ? "VIP" : "FREE");
+            musicSheet.setAudioPlayTypes(o.getAudioPlayTypes());
+
+            return musicSheet;
+        });
+
+
+        return R.from(convert);
+    }
+}

+ 5 - 0
mec-application/src/main/java/com/ym/mec/student/controller/StudentManageController.java

@@ -34,6 +34,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Api(tags = "学生管理")
@@ -84,6 +85,9 @@ public class StudentManageController extends BaseController {
     @Autowired
     private CloudTeacherOrderService cloudTeacherOrderService;
 
+    @Autowired
+    private InstrumentService instrumentService;
+
     private final static Logger LOGGER = LoggerFactory.getLogger(StudentManageController.class);
 
     @Autowired
@@ -172,6 +176,7 @@ public class StudentManageController extends BaseController {
         Student student = studentManageService.getStudentUserInfo(user.getId(), user, datas);
         datas.put("student", student);
 
+
         // 注册IM用户Token
         try {
             ImGroupWrapper.ImUserInfo register = imGroupCoreService.getUserSig(String.valueOf(student.getId()),

+ 19 - 0
mec-application/src/main/java/com/ym/mec/student/controller/UserMusicController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.microsvc.toolkit.common.response.paging.PageInfo;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
@@ -20,8 +21,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
 
 import java.util.Arrays;
 import java.util.List;
@@ -59,6 +62,22 @@ public class UserMusicController  extends BaseController {
         return succeed(records.get(0));
     }
 
+
+
+    @ApiOperation(value = "详情")
+    @GetMapping("/musicPracticeRecord/{id}")
+    public R<UserMusicWrapper.UserMusic> musicPracticeRecord(@PathVariable("id") Long id) {
+
+        UserMusicWrapper.UserMusicQuery build = UserMusicWrapper.UserMusicQuery.builder().musicPracticeRecordId(id).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(build), build);
+        List<UserMusicWrapper.UserMusic> records = pages.getRecords();
+        if (records.isEmpty()) {
+            return R.from(new UserMusicWrapper.UserMusic()).data(null);
+        }
+
+        return R.from(records.get(0));
+    }
+
     @ApiOperation(value = "查询分页", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusicQuery")
     @PostMapping("/page")
     public HttpResponseResult<PageInfo<UserMusicWrapper.UserMusic>> page(@RequestBody UserMusicWrapper.UserMusicQuery query) {

+ 88 - 0
mec-application/src/main/java/com/ym/mec/student/controller/open/OpenMusicSheetController.java

@@ -0,0 +1,88 @@
+package com.ym.mec.student.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import com.ym.mec.biz.service.InstrumentService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.vo.MusicSheetVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/open/musicSheet")
+@Api(tags = "曲谱表")
+public class OpenMusicSheetController {
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<MusicSheetVo.MusicSheet>
+     */
+    @ApiOperation(value = "查询内容平台数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/cbsDetail/{id}")
+    public R<MusicSheetVo.OpenMusicSheetDetail> cbsDetail(@PathVariable("id") Integer id) {
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(Long.valueOf(id));
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        SysMusicScore detail = musicSheetService.get(id);
+        if (detail == null) {
+            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(StringUtils.isBlank(detail.getRankIds()) ? "FREE" : "VIP");
+            // 设置业务端曲目分类
+            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Integer> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Integer::parseInt).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Integer, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(MusicSheetVo.OpenMusicSheetDetail.from(musicSheetDetail.jsonString()));
+    }
+
+}

+ 140 - 0
mec-application/src/main/java/com/ym/mec/teacher/controller/MusicPracticeRecordController.java

@@ -0,0 +1,140 @@
+package com.ym.mec.teacher.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.common.enums.music.EEvaluationStandard;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.validator.group.ValidGroups;
+import com.ym.mec.biz.dal.entity.UserMusic;
+import com.ym.mec.biz.dal.enums.ClientEnum;
+import com.ym.mec.biz.dal.wrapper.MusicPracticeRecordWrapper;
+import com.ym.mec.biz.service.MusicPracticeRecordService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.biz.service.SysUserService;
+import com.ym.mec.biz.service.UserMusicService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/musicPracticeRecord")
+@Api(tags = "曲目练习记录")
+public class MusicPracticeRecordController {
+
+    @Autowired
+    private MusicPracticeRecordService musicPracticeRecordService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    /**
+     * 查询单条
+     * @param id 详情ID
+     * @return R<MusicPracticeRecordVo.MusicPracticeRecord>
+     */
+    @ApiOperation(value = "详情", notes = "曲目练习记录-根据详情ID查询单条, 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public R<MusicPracticeRecordWrapper.MusicPracticeRecord> detail(@PathVariable("id") Long id) {
+
+        MusicPracticeRecordWrapper.Entity wrapper = musicPracticeRecordService.detail(id);
+
+        if (wrapper == null) {
+            throw new BizException("记录不存在");
+        }
+
+        // 上传过作品,用作品视频路径覆盖上传视频路径
+        // ID集合
+        Map<Long, UserMusic> userMusicMap = userMusicService.getMapByMusicPracticeRecordIds(Lists.newArrayList(Long.parseLong(wrapper.getId())));
+
+        UserMusic userMusic = userMusicMap.get(Long.parseLong(wrapper.getId()));
+        if (Objects.nonNull(userMusic)) {
+            wrapper.setVideoFilePath(userMusic.getVideoUrl());
+        }
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(JSON.toJSONString(wrapper));
+
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(Integer.parseInt(wrapper.getMusicSheetId()));
+        if (musicSheet != null) {
+            from.setRhythmFlag(musicSheet.getEvaluationStandard() != EEvaluationStandard.FREQUENCY);
+        }
+
+        return R.from(from);
+    }
+
+
+    /**
+     * 新增
+     * @param record MusicPracticeRecordVo.MusicPracticeRecord
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "曲目练习记录- 传入 MusicPracticeRecordVo.MusicPracticeRecord")
+    @PostMapping("/save")
+    public R<String> add(@Validated(ValidGroups.Add.class) @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record) {
+
+        Integer userId = sysUserService.getUserId();
+        record.userId(String.valueOf(userId)).clientType(ClientEnum.TEACHER.getCode());
+
+        // 新增数据
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(record.jsonString());
+        if (record.getDelFlag() !=null && record.getDelFlag()) {
+            from.setDelFlag(false);
+            from.setHiddenFlag(true);
+        }
+
+        return R.from(musicPracticeRecordService.add(from));
+    }
+
+    @ApiOperation(value = "用户最后一次评测数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "recordId", value = "曲目练习记录Id", dataType = "long")
+    })
+    @GetMapping("/getLastEvaluationMusicalNotesPlayStats")
+    public Object getLastEvaluationMusicalNotesPlayStats(Long recordId){
+        return R.from(musicPracticeRecordService.getLastEvaluationMusicalNotesPlayStats(recordId));
+    }
+
+    @ApiOperation(value = "上传音频文件")
+    @PostMapping("videoUpload")
+    public R<Boolean> videoUpload( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record){
+
+        if (Objects.isNull(record.getId())) {
+            throw BizException.from("recordId不能为空");
+        }
+        if (Objects.isNull(record.getVideoFilePath())) {
+            throw BizException.from("videoUrl不能为空");
+        }
+
+        MusicPracticeRecordWrapper.Entity practiceRecord = musicPracticeRecordService.getById(record.getId());
+        if (Objects.isNull(practiceRecord)) {
+            throw BizException.from("记录不存在");
+        }
+
+        practiceRecord.setVideoFilePath(record.getVideoFilePath());
+        musicPracticeRecordService.update(practiceRecord);
+
+        return R.from(true);
+    }
+
+}

+ 159 - 0
mec-application/src/main/java/com/ym/mec/teacher/controller/MusicSheetController.java

@@ -0,0 +1,159 @@
+package com.ym.mec.teacher.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.entity.Instrument;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.entity.Teacher;
+import com.ym.mec.biz.dal.enums.ClientEnum;
+import com.ym.mec.biz.dal.enums.ClientTypeEnum;
+import com.ym.mec.biz.dal.page.SysExamSongQueryInfo;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import com.ym.mec.biz.dal.wrapper.MusicSheetWrapper;
+import com.ym.mec.biz.service.InstrumentService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.biz.service.SysUserService;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.vo.MusicSheetVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/musicSheet")
+@Api(tags = "曲谱表")
+public class MusicSheetController {
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    @Resource
+    private TeacherDao teacherDao;
+    @Resource
+    private SysUserService sysUserService;
+
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<MusicSheetVo.MusicSheet>
+     */
+    @ApiOperation(value = "查询内容平台数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/cbsDetail/{id}")
+    public R<MusicSheetVo.MusicSheetDetail> cbsDetail(@PathVariable("id") Integer id) {
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(Long.valueOf(id));
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        SysMusicScore detail = musicSheetService.get(id);
+        if (detail == null) {
+            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(StringUtils.isBlank(detail.getRankIds()) ? "FREE" : "VIP");
+            // 设置业务端曲目分类
+            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getIsConvertibleScore());
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Integer> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Integer::parseInt).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Integer, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+
+    @ApiOperation(value = "查询分页", notes = "曲谱表- 传入 MusicSheetVo.MusicSheetQuery")
+    @PostMapping("/page")
+    public R<PageInfo<MusicSheetWrapper.MusicSheet>> page(@RequestBody MusicSheetVo.MusicSheetQuery query) {
+
+        //判断用户是否可以访问云练习
+        Integer userId = sysUserService.getUserId();
+        Teacher teacher = teacherDao.get(userId);
+        if (teacher == null) {
+            throw new BizException("老师信息不存在");
+        }
+        //是否限制用户使用云教练
+        if(teacher.getCoursewareLimit()){
+            throw new BizException("您没有权限使用云练习");
+        }
+        SysExamSongQueryInfo queryInfo = new SysExamSongQueryInfo();
+
+        if(query.getMusicSheetCategoriesId() != null) {
+            queryInfo.setCategoriesId(query.getMusicSheetCategoriesId().toString());
+        }
+        if (query.getMusicalInstrumentId() != null) {
+            // 乐器转换为声部
+            Instrument instrument = instrumentService.getById(query.getMusicalInstrumentId());
+            if (instrument != null) {
+                queryInfo.setSubjectId(instrument.getSubjectId());
+            }
+        }
+
+        queryInfo.setPage(query.getPage());
+        queryInfo.setRows(query.getRows());
+        queryInfo.setName(query.getName());
+        queryInfo.setType("COMMON");
+        queryInfo.setClientFlag(true);
+        queryInfo.setClientType(ClientTypeEnum.SMART_PRACTICE);
+        queryInfo.setUserId(userId);
+        queryInfo.setRecentFlag(query.getRecentFlag());
+        queryInfo.setClientId(ClientEnum.TEACHER.getCode().toLowerCase());
+        PageInfo<SysMusicScore> sysMusicScorePageInfo1 = musicSheetService.queryMusicScorePageInfo(queryInfo);
+        PageInfo<MusicSheetWrapper.MusicSheet> convert = sysMusicScorePageInfo1.convert(o -> {
+            MusicSheetWrapper.MusicSheet musicSheet = new MusicSheetWrapper.MusicSheet();
+            musicSheet.setId(o.getId().toString());
+            musicSheet.setMusicSheetCategoriesId(o.getCategoriesId());
+            musicSheet.setMusicSheetName(o.getName());
+            musicSheet.setTitleImg(o.getTitleImg());
+            musicSheet.setComposer(o.getComposer());
+            musicSheet.setCbsMusicSheetId(o.getCbsMusicSheetId());
+            musicSheet.setUsedNum(0L);
+            musicSheet.setPaymentType(StringUtils.isNotBlank(o.getRankIds()) && o.getRankIds().contains("1") ? "VIP" : "FREE");
+            musicSheet.setAudioPlayTypes(o.getAudioPlayTypes());
+
+            return musicSheet;
+        });
+
+
+        return R.from(convert);
+    }
+}

+ 16 - 0
mec-application/src/main/java/com/ym/mec/teacher/controller/UserMusicController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.microsvc.toolkit.common.response.paging.PageInfo;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
@@ -57,6 +58,21 @@ public class UserMusicController  extends BaseController {
         return succeed(records.get(0));
     }
 
+    @ApiOperation(value = "详情")
+    @GetMapping("/musicPracticeRecord/{id}")
+    public R<UserMusicWrapper.UserMusic> musicPracticeRecord(@PathVariable("id") Long id) {
+
+        UserMusicWrapper.UserMusicQuery build = UserMusicWrapper.UserMusicQuery.builder().musicPracticeRecordId(id).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(build), build);
+        List<UserMusicWrapper.UserMusic> records = pages.getRecords();
+        if (records.isEmpty()) {
+            return R.from(new UserMusicWrapper.UserMusic()).data(null);
+        }
+
+        return R.from(records.get(0));
+    }
+
+
     @ApiOperation(value = "查询分页", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusicQuery")
     @PostMapping("/page")
     public HttpResponseResult<PageInfo<UserMusicWrapper.UserMusic>> page(@RequestBody UserMusicWrapper.UserMusicQuery query) {

+ 88 - 0
mec-application/src/main/java/com/ym/mec/teacher/controller/open/OpenMusicSheetController.java

@@ -0,0 +1,88 @@
+package com.ym.mec.teacher.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import com.ym.mec.biz.service.InstrumentService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.vo.MusicSheetVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open/musicSheet")
+@Api(tags = "曲谱表")
+public class OpenMusicSheetController {
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<MusicSheetVo.MusicSheet>
+     */
+    @ApiOperation(value = "查询内容平台数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/cbsDetail/{id}")
+    public R<MusicSheetVo.OpenMusicSheetDetail> cbsDetail(@PathVariable("id") Integer id) {
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(Long.valueOf(id));
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        SysMusicScore detail = musicSheetService.get(id);
+        if (detail == null) {
+            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(StringUtils.isBlank(detail.getRankIds()) ? "FREE" : "VIP");
+            // 设置业务端曲目分类
+            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Integer> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Integer::parseInt).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Integer, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(MusicSheetVo.OpenMusicSheetDetail.from(musicSheetDetail.jsonString()));
+    }
+
+}

+ 107 - 0
mec-application/src/main/java/com/ym/mec/vo/MusicSheetAccompanimentVo.java

@@ -0,0 +1,107 @@
+package com.ym.mec.vo;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 曲谱伴奏表
+ * 2022-12-07 10:16:58
+ */
+@ApiModel(value = "MusicSheetAccompanimentVo对象", description = "曲谱伴奏表查询视图对象")
+public class MusicSheetAccompanimentVo {
+
+    @Data
+    @ApiModel(" MusicSheetAccompanimentQuery-曲谱伴奏表")
+    public static class MusicSheetAccompanimentQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheetAccompanimentQuery from(String json) {
+            return JSON.parseObject(json, MusicSheetAccompanimentQuery.class);
+        }
+    }
+
+    @Data
+    @ApiModel(" MusicSheetAccompaniment-曲谱伴奏表")
+    public static class MusicSheetAccompaniment {
+
+
+		@ApiModelProperty("主键")
+        private Long id;
+
+
+		@ApiModelProperty("曲谱ID")
+        private Long musicId;
+
+
+		@ApiModelProperty("声部")
+        private String musicSubject;
+
+
+		@ApiModelProperty("MP3原声音频文件URL")
+        private String audioFileUrl;
+
+
+		@ApiModelProperty("map节拍器伴奏")
+        private String metronomeUrl;
+
+
+		@ApiModelProperty("伴奏轨迹")
+        private String track;
+
+
+		@ApiModelProperty("排序号")
+        private Boolean sortNumber;
+
+
+		@ApiModelProperty("速度")
+        private String speed;
+
+        @ApiModelProperty("曲目缓存")
+        private String musicSvg;
+
+		@ApiModelProperty("创建人(老师或者是后台平台用户)")
+        private Long createBy;
+
+
+		@ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+        @ApiModelProperty("五线谱PDF文件")
+        private String musicPdfUrl;
+
+
+        @ApiModelProperty("首调PDF文件")
+        private String firstPdfUrl;
+
+
+        @ApiModelProperty("固定调PDF文件")
+        private String jianPdfUrl;
+
+
+        @ApiModelProperty("音频类型,SING:演唱,PLAY:演奏")
+        private String audioPlayType;
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheetAccompaniment from(String json) {
+            return JSON.parseObject(json, MusicSheetAccompaniment.class);
+        }
+    }
+
+}

+ 705 - 0
mec-application/src/main/java/com/ym/mec/vo/MusicSheetVo.java

@@ -0,0 +1,705 @@
+package com.ym.mec.vo;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.common.enums.music.EAudioType;
+import com.dayaedu.cbs.common.enums.music.EEvaluationStandard;
+import com.dayaedu.cbs.common.enums.music.EMusicAvailableType;
+import com.dayaedu.cbs.common.enums.music.EMusicPlayMode;
+import com.dayaedu.cbs.common.enums.music.EMusicSourceType;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 曲谱表
+ * 2022-12-07 10:16:58
+ */
+@ApiModel(value = "MusicSheetVo对象", description = "曲谱表查询视图对象")
+public class MusicSheetVo {
+
+    @Data
+    @ApiModel(" MusicSheetQuery-曲谱表")
+    public static class MusicSheetQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+        private String keyword;
+
+        @ApiModelProperty("仅匹配资源名称")
+        private String name;
+
+        @ApiModelProperty("声部Id")
+        private String musicSubject;
+
+        @ApiModelProperty("曲目乐器Id")
+        private Long musicalInstrumentId;
+
+        @ApiModelProperty("曲谱分类编号")
+        private Integer musicSheetCategoriesId;
+
+        private List<Integer> musicSheetCategoriesIdList;
+
+        @ApiModelProperty(value = "删除标识", hidden = true)
+        private Boolean delFlag;
+
+        @ApiModelProperty(value = "启用停用标识,曲目状态(0:停用,1:启用)")
+        private Boolean status;
+
+        @ApiModelProperty(value = "排序 0:默认 1:首页热门,2热门列表")
+        private Integer sortType = 0;
+
+        @ApiModelProperty(value = "是否审核数据")
+        private Boolean versionFlag = false;
+
+        @ApiModelProperty(value = "用户ID",hidden = true)
+        private Long userId;
+
+        @ApiModelProperty(value = "用户类型",hidden = true)
+        private String clientType;
+
+        @ApiModelProperty("是否最近练习")
+        private Boolean recentFlag = false;
+
+        @ApiModelProperty("最近练习 当前曲目ID")
+        private Long excludeMusicId;
+
+        @ApiModelProperty("app版本")
+        private String version;
+
+        @ApiModelProperty("platform")
+        private String platform;
+
+        @ApiModelProperty("id集合")
+        private List<Long> ids;
+
+        @ApiModelProperty("曲目教程id集合")
+        private String musicTutorialIds;
+
+        @ApiModelProperty("曲目标签id集合")
+        private String musicTagIds;
+
+        @ApiModelProperty("内容平台ID为null")
+        private Boolean cbsIdIsNull;
+
+        @ApiModelProperty("是否转换")
+        private Boolean convertFlag;
+
+        @ApiModelProperty("教材版本ID/ 曲目标签ID")
+        private Long bookVersionId;
+
+        @ApiModelProperty("音频类型,SING:演唱,PLAY:演奏")
+        private List<String> audioPlayTypes;
+
+        @ApiModelProperty("标签分类搜索 HOT 热门,NEW 最新,RECOMMEND 推荐")
+        private String searchType;
+
+        @ApiModelProperty("是否只查询基础信息")
+        private Boolean basicFlag = false;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheetQuery from(String json) {
+            return JSON.parseObject(json, MusicSheetQuery.class);
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" MusicSheet-曲谱表")
+    public static class MusicSheet {
+
+		@ApiModelProperty("主键")
+        private Long id;
+
+        @ApiModelProperty("曲谱分类")
+        private Integer musicSheetCategoriesId;
+
+//        @ApiModelProperty(value = "曲谱类型(SINGLE:单曲,CONCERT:合奏)")
+//        private EMusicSheetType musicSheetType;
+
+        @ApiModelProperty("曲谱分类名称")
+        private String musicSheetCategoriesName;
+
+		@ApiModelProperty("曲谱名称")
+        private String musicSheetName;
+
+		@ApiModelProperty("封面图")
+        private String titleImg;
+
+		@ApiModelProperty("曲谱来源id")
+        private Long userId;
+
+//		@ApiModelProperty("曲目来源类型 TEACHER 老师 PLATFORM 平台")
+//        private ESourceFrom sourceType;
+
+        @ApiModelProperty("多声轨选择")
+        private String multiTracksSelection;
+
+        @ApiModelProperty("是否公开")
+        private Boolean openFlag;
+
+        @ApiModelProperty("作曲人")
+        private String composer;
+
+        @ApiModelProperty("上传人")
+        private String uploadUser;
+
+		@ApiModelProperty("曲谱声部(适用的乐器,可能是多个,用逗号分隔)")
+        private String musicSubject;
+
+		@ApiModelProperty("mp3曲谱类型  MP3;MP3_METRONOME")
+        private String mp3Type;
+
+		@ApiModelProperty("曲目图片")
+        private String musicImg;
+
+		@ApiModelProperty("曲谱音频文件类型(midi;mp3)")
+        private EAudioType audioType;
+
+		@ApiModelProperty("是否可以转简谱(0:否,1:是)")
+        private Integer notation;
+
+		@ApiModelProperty("曲谱标签(多个标签用逗号分隔)")
+        private String musicTag;
+
+		@ApiModelProperty("默认播放速度")
+        private String playSpeed;
+
+		@ApiModelProperty("是否可以评测(0:否;1:是)")
+        private Boolean canEvaluate;
+
+        @ApiModelProperty("是否支持混音节拍器")
+        private Boolean isMixBeat;
+
+		@ApiModelProperty("伴奏类型  HOMEMODE:自制 COMMON:普通")
+        private String accompanimentType;
+
+		@ApiModelProperty("是否展示指法(0:否;1:是)")
+        private Boolean showFingering;
+
+		@ApiModelProperty("曲目状态(0:停用,1:启用)")
+        private Boolean status;
+
+		@ApiModelProperty("曲目停用原因")
+        private String reason;
+
+		@ApiModelProperty("排序号")
+        private Integer sortNumber;
+
+		@ApiModelProperty("midi路径")
+        private String midiUrl;
+
+		@ApiModelProperty("伴奏含节拍器路径")
+        private String metronomeUrl;
+
+		@ApiModelProperty("伴奏(不含节拍器)路径")
+        private String url;
+
+		@ApiModelProperty("音频文件存储路径")
+        private String audioFileUrl;
+
+		@ApiModelProperty("XML文件存储路径")
+        private String xmlFileUrl;
+
+		@ApiModelProperty("是否自带节拍器(0:否;1:是)")
+        private Boolean hasBeat;
+
+		@ApiModelProperty("曲目配置")
+        private String extConfigJson;
+
+
+        @ApiModelProperty("是否节奏音乐")
+        private Boolean rhythmFlag;
+
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+		@ApiModelProperty("创建人(老师或者是后台平台用户)")
+        private Long createBy;
+
+        @ApiModelProperty("创建用户")
+        private String createUser;
+
+		@ApiModelProperty("更新时间")
+        private Date updateTime;
+
+		@ApiModelProperty("更新人(老师或者是后台平台用户)")
+        private Long updateBy;
+
+        @ApiModelProperty("更新用户")
+        private String updateUser;
+
+		@ApiModelProperty("备注")
+        private String remark;
+
+		@ApiModelProperty("假删除标识 0:未删除 1:已删除")
+        private Boolean delFlag;
+
+        @ApiModelProperty("伴奏")
+        private List<MusicSheetAccompanimentVo.MusicSheetAccompaniment> background;
+
+        @ApiModelProperty("曲目缓存")
+        private String musicJSON;
+
+        @ApiModelProperty("曲目缓存svg")
+        private String musicSvg;
+
+        @ApiModelProperty("曲目缓存简谱svg")
+        private String musicJianSvg;
+
+        @ApiModelProperty("曲目缓存首调svg")
+        private String musicFirstSvg;
+
+
+        @ApiModelProperty("被使用次数")
+        private Long usedNum = 0L;
+
+        @ApiModelProperty("曲目赏析")
+        private String appreciationUrl;
+
+        @ApiModelProperty("曲目创作ID")
+        private Long musicSheetCreationId;
+
+        @ApiModelProperty(" 可用乐器(多个,用逗号分隔)")
+        private String cbsMusicalInstrumentIds;
+
+
+
+        @ApiModelProperty(" 可用乐器(多个,用逗号分隔)")
+        private String cbsMusicalInstrumentIdNames;
+
+        @ApiModelProperty("内容平台曲目ID")
+        private Long cbsMusicSheetId;
+
+        @ApiModelProperty("首调图片")
+        private String musicFirstImg;
+        @ApiModelProperty("固定调图片")
+        private String musicJianImg;
+
+
+        @ApiModelProperty("五线谱PDF文件")
+        private String musicPdfUrl;
+
+
+        @ApiModelProperty("首调PDF文件")
+        private String firstPdfUrl;
+
+
+        @ApiModelProperty("固定调PDF文件")
+        private String jianPdfUrl;
+
+
+
+        @ApiModelProperty("曲目类型(SINGLE:单曲 CONCERT:合奏)")
+        private String musicSheetType;
+
+        @ApiModelProperty("乐器信息")
+        private List<InstrumentWrapper.Instrument> musicalInstruments;
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+
+
+        @ApiModelProperty("是否可转谱(0:否; 1:是)")
+        private Boolean isConvertibleScore;
+
+        @ApiModelProperty("谱面类型")
+        private String scoreType;
+
+
+        @ApiModelProperty("音频类型,SING:演唱,PLAY:演奏")
+        private String audioPlayTypes;
+
+
+        @ApiModelProperty("是否总谱渲染")
+        private Boolean isScoreRender;
+
+        @ApiModelProperty("演奏是否默认展示总谱渲染")
+        private Boolean defaultScoreRender;
+
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheet from(String json) {
+            return JSON.parseObject(json, MusicSheet.class);
+        }
+
+
+        public MusicSheet createBy(String createBy) {
+            this.createBy = Long.parseLong(createBy);
+            return this;
+        }
+
+        public MusicSheet createUser(String createUser) {
+            this.createUser = createUser;
+            return this;
+        }
+
+        public MusicSheet updateBy(String updateBy) {
+            this.updateBy = Long.parseLong(updateBy);
+            return this;
+        }
+
+        public MusicSheet updateUser(String updateUser) {
+            this.updateUser = updateUser;
+            return this;
+        }
+
+        public MusicSheet notation(Integer notation) {
+            this.notation = notation;
+            return this;
+        }
+
+        public MusicSheet userId(String userId) {
+            this.userId = Long.valueOf(userId);
+            return this;
+        }
+    }
+
+
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class MusicSheetDetail extends CbsMusicSheetWrapper.MusicSheet {
+        @ApiModelProperty
+        private Long bizMusicCategoryId;
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+        @ApiModelProperty("是否可转谱(0:否; 1:是)")
+        private Boolean isConvertibleScore;
+
+        @ApiModelProperty("谱面类型")
+        private String scoreType;
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" MusicSheet-曲谱表")
+    public static class OpenMusicSheetDetail implements Serializable {
+
+        @ApiModelProperty("主键")
+        private Long id;
+
+        @ApiModelProperty("业务平台曲目ID")
+        private Long bizId;
+
+        @ApiModelProperty("曲目分类ID")
+        private Long musicCategoryId;
+
+        @ApiModelProperty("曲目分类名称")
+        private String musicCategoryName;
+
+        @ApiModelProperty("曲目标签")
+        private String musicTag;
+
+        @ApiModelProperty("曲目标签名称")
+        private String musicTagNames;
+
+        @ApiModelProperty("曲目封面图")
+        private String musicCover;
+
+        @ApiModelProperty("曲目名称")
+        private String name;
+
+        @ApiModelProperty("是否审核版本")
+        private Boolean appAuditFlag;
+
+        @ApiModelProperty("曲目声部(多个,用逗号分隔)")
+        private String subjectIds;
+
+        @ApiModelProperty("曲目声部code")
+        private String subjectCodes;
+
+        @ApiModelProperty("曲目声部名称")
+        private String subjectNames;
+
+        @ApiModelProperty("曲目乐器(多个,用逗号分隔)")
+        private String musicalInstrumentIds;
+
+        @ApiModelProperty("曲目乐器code")
+        private String musicalInstrumentIdCodes;
+
+        @ApiModelProperty("曲目乐器名称")
+        private String musicalInstrumentNames;
+
+        @ApiModelProperty("作曲人/音乐人")
+        private String composer;
+
+        @ApiModelProperty("曲目类型(SINGLE:单曲 CONCERT:合奏)")
+        private EMusicSheetType musicSheetType;
+
+        @ApiModelProperty("是否使用系统节拍器(0:否;1:是)")
+        private Boolean isUseSystemBeat;
+
+        @ApiModelProperty("是否可评测(0:否;1:是)")
+        private Boolean isEvaluated;
+
+        @ApiModelProperty("是否可转谱(0:否; 1:是)")
+        private Boolean isConvertibleScore;
+
+        @ApiModelProperty("是否展示指法(0:否;1:是)")
+        private Boolean isShowFingering;
+
+        @ApiModelProperty("是否播入节拍器(0: 否 1:是)")
+        private Boolean isPlayBeat;
+
+        @ApiModelProperty("多声轨选择")
+        private String multiTracksSelection;
+
+        @ApiModelProperty("播放速度")
+        private String playSpeed;
+
+        @ApiModelProperty("播放模式(MIDI;MP3)")
+        private EMusicPlayMode playMode;
+
+        @ApiModelProperty("XML文件")
+        private String xmlFileUrl;
+
+        @ApiModelProperty("MIDI文件(保留字段)")
+        private String midiFileUrl;
+
+        @ApiModelProperty("曲目JSON")
+        private String musicJson;
+
+        @ApiModelProperty("曲目缓存JSON(后续使用)")
+        private String musicSvgJson;
+
+        @ApiModelProperty("曲目缓存")
+        private String musicSvg;
+
+        @ApiModelProperty("评测标准 节奏 AMPLITUDE 音准 FREQUENCY 分贝 DECIBELS")
+        private EEvaluationStandard evaluationStandard;
+
+        @ApiModelProperty("简谱缓存")
+        private String musicJianSvg;
+
+        @ApiModelProperty("首调缓存")
+        private String musicFirstSvg;
+
+        @ApiModelProperty("谱面图片JSON(后续使用)")
+        private String musicImgJson;
+
+        @ApiModelProperty("五线谱图片")
+        private String musicImg;
+
+        @ApiModelProperty("首调图片")
+        private String musicFirstImg;
+
+        @ApiModelProperty("固定调图片")
+        private String musicJianImg;
+
+        @ApiModelProperty("谱面参数设置")
+        private String extConfigJson;
+
+        @ApiModelProperty("谱面样式参数设置")
+        private String extStyleConfigJson;
+
+        @ApiModelProperty("可用类型(PLATFORM: 平台; ORG: 机构; PERSON: 个人)")
+        private EMusicAvailableType availableType;
+
+        @ApiModelProperty("来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)")
+        private EMusicSourceType sourceType;
+
+        @ApiModelProperty("音频类型(HOMEMODE: 自制 COMMON: 普通)")
+        private EAudioType audioType;
+
+        @ApiModelProperty("曲目状态(0:停用,1:启用)")
+        private Boolean status;
+
+        @ApiModelProperty("停用原因")
+        private String reason;
+
+        @ApiModelProperty("备注")
+        private String remark;
+
+        @ApiModelProperty("逻辑删除标识(0: 未删 1:已删)")
+        private Boolean delFlag;
+
+        @ApiModelProperty("评测频率,详情返回,指定应用端")
+        private String evaluationFrequency;
+
+        @ApiModelProperty("乐器信息")
+        private List<CbsMusicSheetWrapper.MusicalInstrument> musicalInstruments;
+
+        @ApiModelProperty
+        private Long bizMusicCategoryId;
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+        public static OpenMusicSheetDetail from(String json) {
+            return JSON.parseObject(json, OpenMusicSheetDetail.class);
+        }
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" MusicSheet-曲谱表")
+    public static class OpenMusicSheet implements Serializable {
+
+        @ApiModelProperty("主键")
+        private Long id;
+
+        @ApiModelProperty("曲谱分类")
+        private Integer musicSheetCategoriesId;
+
+        @ApiModelProperty("曲谱分类名称")
+        private String musicSheetCategoriesName;
+
+        @ApiModelProperty("曲谱名称")
+        private String musicSheetName;
+
+        @ApiModelProperty("封面图")
+        private String titleImg;
+
+//        @ApiModelProperty("曲目来源类型 TEACHER 老师 PLATFORM 平台")
+//        private ESourceFrom sourceType;
+
+        @ApiModelProperty("多声轨选择")
+        private String multiTracksSelection;
+
+        @ApiModelProperty("是否公开")
+        private Boolean openFlag;
+
+        @ApiModelProperty("作曲人")
+        private String composer;
+
+        @ApiModelProperty("曲谱声部(适用的乐器,可能是多个,用逗号分隔)")
+        private String musicSubject;
+
+        @ApiModelProperty("mp3曲谱类型  MP3;MP3_METRONOME")
+        private String mp3Type;
+
+        @ApiModelProperty("曲目图片")
+        private String musicImg;
+
+        @ApiModelProperty("曲谱音频文件类型(midi;mp3)")
+        private EAudioType audioType;
+
+        @ApiModelProperty("是否可以转简谱(0:否,1:是)")
+        private Integer notation;
+
+        @ApiModelProperty("曲谱标签(多个标签用逗号分隔)")
+        private String musicTag;
+
+        @ApiModelProperty("默认播放速度")
+        private String playSpeed;
+
+        @ApiModelProperty("是否可以评测(0:否;1:是)")
+        private Boolean canEvaluate;
+
+        @ApiModelProperty("伴奏类型  HOMEMODE:自制 COMMON:普通")
+        private String accompanimentType;
+
+        @ApiModelProperty("是否展示指法(0:否;1:是)")
+        private Boolean showFingering;
+
+        @ApiModelProperty("曲目状态(0:停用,1:启用)")
+        private Boolean status;
+
+        @ApiModelProperty("曲目停用原因")
+        private String reason;
+
+        @ApiModelProperty("排序号")
+        private Integer sortNumber;
+
+        @ApiModelProperty("midi路径")
+        private String midiUrl;
+
+        @ApiModelProperty("XML文件存储路径")
+        private String xmlFileUrl;
+
+        @ApiModelProperty("是否自带节拍器(0:否;1:是)")
+        private Boolean hasBeat;
+
+        @ApiModelProperty("曲目配置")
+        private String extConfigJson;
+
+        @ApiModelProperty("是否节奏音乐")
+        private Boolean rhythmFlag;
+
+        @ApiModelProperty("备注")
+        private String remark;
+
+        @ApiModelProperty("假删除标识 0:未删除 1:已删除")
+        private Boolean delFlag;
+
+        @ApiModelProperty("曲目缓存")
+        private String musicJSON;
+
+        @ApiModelProperty("曲目缓存svg")
+        private String musicSvg;
+
+        @ApiModelProperty("曲目缓存简谱svg")
+        private String musicJianSvg;
+
+        @ApiModelProperty("曲目缓存首调svg")
+        private String musicFirstSvg;
+
+        @ApiModelProperty("被使用次数")
+        private Long usedNum = 0L;
+
+        @ApiModelProperty("曲目赏析")
+        private String appreciationUrl;
+
+        @ApiModelProperty("曲目创作ID")
+        private Long musicSheetCreationId;
+
+        @ApiModelProperty(" 可用乐器(多个,用逗号分隔)")
+        private String cbsMusicalInstrumentIds;
+
+        @ApiModelProperty(" 可用乐器(多个,用逗号分隔)")
+        private String cbsMusicalInstrumentIdNames;
+
+        @ApiModelProperty("内容平台曲目ID")
+        private Long cbsMusicSheetId;
+
+        @ApiModelProperty("首调图片")
+        private String musicFirstImg;
+
+        @ApiModelProperty("固定调图片")
+        private String musicJianImg;
+
+        @ApiModelProperty("曲目类型(SINGLE:单曲 CONCERT:合奏)")
+        private String musicSheetType;
+
+        /*@ApiModelProperty("乐器信息")
+        private List<InstrumentWrapper.Instrument> musicalInstruments;*/
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+        public static OpenMusicSheet from(String json) {
+            return JSON.parseObject(json, OpenMusicSheet.class);
+        }
+
+    }
+}

+ 23 - 0
mec-application/src/main/java/com/ym/mec/vo/MusicalInstrumentWrapper.java

@@ -0,0 +1,23 @@
+package com.ym.mec.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+public class MusicalInstrumentWrapper {
+
+
+    @Data
+    @ApiModel(" MusicalInstrumentQuery-曲目乐器")
+    public static class MusicalInstrumentQuery  {
+
+        @ApiModelProperty("声部")
+        private Integer subjectId;
+        @ApiModelProperty("声部")
+        private List<Integer> subjectIds;
+        @ApiModelProperty("是否启用")
+        private Boolean enableFlag;
+    }
+}

+ 138 - 0
mec-application/src/main/java/com/ym/mec/web/controller/MusicPracticeRecordController.java

@@ -0,0 +1,138 @@
+package com.ym.mec.web.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.common.enums.music.EEvaluationStandard;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.validator.group.ValidGroups;
+import com.ym.mec.biz.dal.entity.UserMusic;
+import com.ym.mec.biz.dal.enums.ClientEnum;
+import com.ym.mec.biz.dal.wrapper.MusicPracticeRecordWrapper;
+import com.ym.mec.biz.service.MusicPracticeRecordService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.biz.service.SysUserService;
+import com.ym.mec.biz.service.UserMusicService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.web:}/musicPracticeRecord")
+@Api(tags = "曲目练习记录")
+public class MusicPracticeRecordController {
+
+    @Autowired
+    private MusicPracticeRecordService musicPracticeRecordService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    /**
+     * 查询单条
+     * @param id 详情ID
+     * @return R<MusicPracticeRecordVo.MusicPracticeRecord>
+     */
+    @ApiOperation(value = "详情", notes = "曲目练习记录-根据详情ID查询单条, 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public R<MusicPracticeRecordWrapper.MusicPracticeRecord> detail(@PathVariable("id") Long id) {
+
+        MusicPracticeRecordWrapper.Entity wrapper = musicPracticeRecordService.detail(id);
+
+        if (wrapper == null) {
+            throw new BizException("记录不存在");
+        }
+
+        // 上传过作品,用作品视频路径覆盖上传视频路径
+        // ID集合
+        Map<Long, UserMusic> userMusicMap = userMusicService.getMapByMusicPracticeRecordIds(Lists.newArrayList(Long.parseLong(wrapper.getId())));
+
+        UserMusic userMusic = userMusicMap.get(Long.parseLong(wrapper.getId()));
+        if (Objects.nonNull(userMusic)) {
+            wrapper.setVideoFilePath(userMusic.getVideoUrl());
+        }
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(JSON.toJSONString(wrapper));
+
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(Integer.parseInt(wrapper.getMusicSheetId()));
+        if (musicSheet != null) {
+            from.setRhythmFlag(musicSheet.getEvaluationStandard() != EEvaluationStandard.FREQUENCY);
+        }
+
+        return R.from(from);
+    }
+
+
+    /**
+     * 新增
+     * @param record MusicPracticeRecordVo.MusicPracticeRecord
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "曲目练习记录- 传入 MusicPracticeRecordVo.MusicPracticeRecord")
+    @PostMapping("/save")
+    public R<String> add(@Validated(ValidGroups.Add.class) @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record) {
+
+        Integer userId = sysUserService.getUserId();
+        record.userId(String.valueOf(userId)).clientType("education");
+
+        // 新增数据
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(record.jsonString());
+        if (record.getDelFlag() !=null && record.getDelFlag()) {
+            from.setDelFlag(false);
+            from.setHiddenFlag(true);
+        }
+
+        return R.from(musicPracticeRecordService.add(from));
+    }
+
+    @ApiOperation(value = "用户最后一次评测数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "recordId", value = "曲目练习记录Id", dataType = "long")
+    })
+    @GetMapping("/getLastEvaluationMusicalNotesPlayStats")
+    public Object getLastEvaluationMusicalNotesPlayStats(Long recordId){
+        return R.from(musicPracticeRecordService.getLastEvaluationMusicalNotesPlayStats(recordId));
+    }
+
+    @ApiOperation(value = "上传音频文件")
+    @PostMapping("videoUpload")
+    public R<Boolean> videoUpload( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record){
+
+        if (Objects.isNull(record.getId())) {
+            throw BizException.from("recordId不能为空");
+        }
+        if (Objects.isNull(record.getVideoFilePath())) {
+            throw BizException.from("videoUrl不能为空");
+        }
+
+        MusicPracticeRecordWrapper.Entity practiceRecord = musicPracticeRecordService.getById(record.getId());
+        if (Objects.isNull(practiceRecord)) {
+            throw BizException.from("记录不存在");
+        }
+
+        practiceRecord.setVideoFilePath(record.getVideoFilePath());
+        musicPracticeRecordService.update(practiceRecord);
+
+        return R.from(true);
+    }
+
+}

+ 147 - 0
mec-application/src/main/java/com/ym/mec/web/controller/MusicSheetController.java

@@ -0,0 +1,147 @@
+package com.ym.mec.web.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.ym.mec.biz.dal.entity.Instrument;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.enums.ClientEnum;
+import com.ym.mec.biz.dal.enums.ClientTypeEnum;
+import com.ym.mec.biz.dal.page.SysExamSongQueryInfo;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import com.ym.mec.biz.dal.wrapper.MusicSheetWrapper;
+import com.ym.mec.biz.service.InstrumentService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.biz.service.SysUserService;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.vo.MusicSheetVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.web:}/musicSheet")
+@Api(tags = "曲谱表")
+public class MusicSheetController {
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    @Resource
+    private SysUserService sysUserService;
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<MusicSheetVo.MusicSheet>
+     */
+    @ApiOperation(value = "查询内容平台数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/cbsDetail/{id}")
+    public R<MusicSheetVo.MusicSheetDetail> cbsDetail(@PathVariable("id") Integer id) {
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(Long.valueOf(id));
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        SysMusicScore detail = musicSheetService.get(id);
+        if (detail == null) {
+            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(StringUtils.isBlank(detail.getRankIds()) ? "FREE" : "VIP");
+            // 设置业务端曲目分类
+            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getIsConvertibleScore());
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Integer> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Integer::parseInt).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Integer, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "曲谱表- 传入 MusicSheetVo.MusicSheetQuery")
+    @PostMapping("/page")
+    public R<PageInfo<MusicSheetWrapper.MusicSheet>> page(@RequestBody MusicSheetVo.MusicSheetQuery query) {
+
+        SysExamSongQueryInfo queryInfo = new SysExamSongQueryInfo();
+
+        Integer userId = sysUserService.getUserId();
+        if(query.getMusicSheetCategoriesId() != null) {
+            queryInfo.setCategoriesId(query.getMusicSheetCategoriesId().toString());
+        }
+        if (query.getMusicalInstrumentId() != null) {
+            // 乐器转换为声部
+            Instrument instrument = instrumentService.getById(query.getMusicalInstrumentId());
+            if (instrument != null) {
+                queryInfo.setSubjectId(instrument.getSubjectId());
+            } else {
+                queryInfo.setSubjectId(-1);
+            }
+        }
+
+        queryInfo.setPage(query.getPage());
+        queryInfo.setRows(query.getRows());
+        queryInfo.setName(query.getName());
+        queryInfo.setRecentFlag(query.getRecentFlag());
+        queryInfo.setExcludeMusicId(query.getExcludeMusicId());
+        queryInfo.setType("COMMON");
+        queryInfo.setClientFlag(true);
+        queryInfo.setClientType(ClientTypeEnum.SMART_PRACTICE);
+        queryInfo.setUserId(userId);
+        queryInfo.setRecentFlag(query.getRecentFlag());
+        queryInfo.setClientId("education");
+        PageInfo<SysMusicScore> sysMusicScorePageInfo = musicSheetService.queryMusicScorePage(queryInfo);
+        PageInfo<MusicSheetWrapper.MusicSheet> convert = sysMusicScorePageInfo.convert(o -> {
+            MusicSheetWrapper.MusicSheet musicSheet = new MusicSheetWrapper.MusicSheet();
+            musicSheet.setId(o.getId().toString());
+            musicSheet.setMusicSheetCategoriesId(o.getCategoriesId());
+            musicSheet.setMusicSheetName(o.getName());
+            musicSheet.setTitleImg(o.getTitleImg());
+            musicSheet.setComposer(o.getComposer());
+            musicSheet.setCbsMusicSheetId(o.getCbsMusicSheetId());
+            musicSheet.setUsedNum(0L);
+            musicSheet.setPaymentType(StringUtils.isNotBlank(o.getRankIds()) && o.getRankIds().contains("1") ? "VIP" : "FREE");
+            musicSheet.setAudioPlayTypes(o.getAudioPlayTypes());
+
+            return musicSheet;
+        });
+
+
+        return R.from(convert);
+    }
+}

+ 88 - 0
mec-application/src/main/java/com/ym/mec/web/controller/open/OpenMusicSheetController.java

@@ -0,0 +1,88 @@
+package com.ym.mec.web.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
+import com.ym.mec.biz.service.InstrumentService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.vo.MusicSheetVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.web:}/open/musicSheet")
+@Api(tags = "曲谱表")
+public class OpenMusicSheetController {
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    /**
+     * 查询单条
+     *
+     * @param id 详情ID
+     * @return R<MusicSheetVo.MusicSheet>
+     */
+    @ApiOperation(value = "查询内容平台数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/cbsDetail/{id}")
+    public R<MusicSheetVo.OpenMusicSheetDetail> cbsDetail(@PathVariable("id") Integer id) {
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(Long.valueOf(id));
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        SysMusicScore detail = musicSheetService.get(id);
+        if (detail == null) {
+            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(StringUtils.isBlank(detail.getRankIds()) ? "FREE" : "VIP");
+            // 设置业务端曲目分类
+            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Integer> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Integer::parseInt).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Integer, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(MusicSheetVo.OpenMusicSheetDetail.from(musicSheetDetail.jsonString()));
+    }
+
+}

+ 0 - 12
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java

@@ -71,12 +71,8 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
 
     int batchDeleteByCourseSchedules(@Param("courseScheduleIds") List<Long> courseScheduleIds);
 
-    int batchDelete(@Param("courseScheduleIds") List<Long> courseScheduleIds);
-
     int batchDeleteCourseSchedulesWithLogic(@Param("courseScheduleIds") List<Long> courseScheduleIds);
 
-    int batchDeleteAllCourseSchedules(@Param("courseScheduleIds") List<Long> courseScheduleIds);
-
     /**
      * @param courseScheduleIds: 课程计划编号
      * @return java.util.List<java.lang.Long>
@@ -867,14 +863,6 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
 
 
     /**
-     * 根据班级编号列表删除课程
-     *
-     * @param classGroupIds 班级编号列表
-     * @return
-     */
-    int deleteCourseSchedulesByClassGroupIds(@Param("courseScheduleIds") List<Long> courseScheduleIds);
-
-    /**
      * @param currentCourseDate: 班级编号
      * @return java.lang.Integer
      * @describe 统计已上的课时数

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/InstrumentDao.java

@@ -22,4 +22,5 @@ public interface InstrumentDao extends BaseMapper<Instrument> {
 	 */
 	List<InstrumentWrapper.Instrument> selectPage(@Param("page") IPage<InstrumentWrapper.Instrument> page, @Param("param") InstrumentWrapper.InstrumentQuery param);
 
+    List<Instrument> getBySubjectId(@Param("subjectId") String subjectId);
 }

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysMusicCompareRecordDao.java

@@ -132,4 +132,6 @@ public interface SysMusicCompareRecordDao extends BaseDAO<Long, SysMusicCompareR
     int countByStudent(Map<String, Object> params);
 
     List<MusicCompareRecordWapper.Result> queryPageByStudent(Map<String, Object> params);
+
+    Long getLastData(@Param("clientId") String clientId, @Param("userId") Integer userId, @Param("feature") String feature, @Param("sysMusicScoreId") Integer sysMusicScoreId);
 }

+ 12 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Student.java

@@ -1,12 +1,13 @@
 package com.ym.mec.biz.dal.entity;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.ym.mec.auth.api.entity.SysUser;
 import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -79,6 +80,7 @@ public class Student extends SysUser {
 	private String extSubjectIds;
 	
 	private Map<Integer,String> extSjectNamesMap = new HashMap<Integer, String>();
+	private List<Map<String, Object>> extInstrumentNames = new ArrayList<>();
 
 	@ApiModelProperty(value = "家长姓名")
 	private String parentName;
@@ -92,8 +94,16 @@ public class Student extends SysUser {
     @ApiModelProperty("IM绑定设备")
     private String imDeviceId;
 
+	public List<Map<String, Object>> getExtInstrumentNames() {
+		return extInstrumentNames;
+	}
+
+	public Student setExtInstrumentNames(List<Map<String, Object>> extInstrumentNames) {
+		this.extInstrumentNames = extInstrumentNames;
+		return this;
+	}
 
-    public String getImDeviceId() {
+	public String getImDeviceId() {
         return imDeviceId;
     }
 

+ 18 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicCompareRecord.java

@@ -87,6 +87,24 @@ public class SysMusicCompareRecord extends BaseEntity {
 
 	private Integer subjectId;
 
+    private String customConfiguration;
+
+    private String practiceTime;
+
+    private String practiceSource;
+
+    private String resultAnalyze;
+
+    private Boolean headphoneFlag;
+
+    private Long instrumentId;
+
+    private Boolean hiddenFlag;
+
+    private Boolean delFlag;
+
+    private Float playRate;
+
 	public SysMusicCompareRecord(FeatureType feature) {
 		this.feature = feature;
 	}

+ 7 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicScore.java

@@ -181,6 +181,13 @@ public class SysMusicScore {
     @ApiModelProperty("曲目状态 ")
 	private List<SysMusicScoreAccompaniment> background;
 
+    private String titleImg;
+
+    private String composer;
+
+
+    @ApiModelProperty("音频类型,SING:演唱,PLAY:演奏")
+    private String audioPlayTypes;
     @ApiModelProperty("使用状态 试用: FREE 锁定: LOCK 解锁:UNLOCK")
     private String useStatus;
 

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

@@ -66,6 +66,11 @@ public class UserMusic implements Serializable {
 	@TableField(value = "video_url_")
     private String videoUrl;
 
+    @ApiModelProperty("文件类型") // .mp4 视频,其他为音频
+    @TableField(value = "file_type_")
+    private String fileType;
+
+
     @ApiModelProperty("json配置")
 	@TableField(value = "json_config_")
     private String jsonConfig;
@@ -86,6 +91,12 @@ public class UserMusic implements Serializable {
     @TableField(value = "submit_time_")
     private Date submitTime;
 
+
+
+    @ApiModelProperty("是否能被看到评级、评分字段")
+    @TableField(value = "select_flag_")
+    private Boolean selectFlag;
+
     @TableField(value = "create_time_")
     private Date createTime;
 

+ 35 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/FeatureType.java

@@ -4,7 +4,8 @@ import com.ym.mec.common.enums.BaseEnum;
 
 public enum FeatureType implements BaseEnum<String, FeatureType> {
 	CLOUD_STUDY_TRAIN("CLOUD_STUDY_TRAIN", "云教练训练"),
-	CLOUD_STUDY_EVALUATION("CLOUD_STUDY_EVALUATION", "云教练评测");
+	CLOUD_STUDY_EVALUATION("CLOUD_STUDY_EVALUATION", "云教练评测"),
+    FOLLOW_UP_TRAINING("FOLLOW_UP_TRAINING", "跟练");
 
 	private String code;
 
@@ -15,7 +16,27 @@ public enum FeatureType implements BaseEnum<String, FeatureType> {
 		this.desc = desc;
 	}
 
-	@Override
+    public static FeatureType format(String feature) {
+        switch (feature){
+
+//            UNIT_TEST("单元测试"),
+//                PRACTICE("自主练习"),
+//                EVALUATION("评测"),
+//                LESSON_TRAINING("课后练习"),
+//                FOLLOW_UP_TRAINING("跟练"),
+            case "PRACTICE":
+                return CLOUD_STUDY_TRAIN;
+            case "FOLLOW_UP_TRAINING":
+                return FOLLOW_UP_TRAINING;
+            case "EVALUATION":
+                return CLOUD_STUDY_EVALUATION;
+            default:
+                return CLOUD_STUDY_TRAIN;
+        }
+
+    }
+
+    @Override
 	public String getCode() {
 		return code;
 	}
@@ -24,4 +45,16 @@ public enum FeatureType implements BaseEnum<String, FeatureType> {
 		return desc;
 	}
 
+    public String toCbs() {
+        switch (this) {
+            case CLOUD_STUDY_TRAIN:
+                return "PRACTICE";
+            case FOLLOW_UP_TRAINING:
+                return "FOLLOW_UP_TRAINING";
+            case CLOUD_STUDY_EVALUATION:
+                return "EVALUATION";
+            default:
+                return "PRACTICE";
+        }
+    }
 }

+ 15 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysExamSongQueryInfo.java

@@ -59,9 +59,23 @@ public class SysExamSongQueryInfo extends QueryInfo {
     @ApiModelProperty("谱面类型")
     private String scoreType;
 
-    @ApiModelProperty("用户ID")
+
+    @ApiModelProperty("是否最近练习")
+    private Boolean recentFlag = false;
+
+    @ApiModelProperty("最近练习 当前曲目ID")
+    private Long excludeMusicId;
+
+    @ApiModelProperty(value = "用户ID",hidden = true)
     private Integer userId;
 
+    @ApiModelProperty(value = "用户类型",hidden = true)
+    private String clientId;
+
+    @ApiModelProperty("仅匹配资源名称")
+    private String name;
+
+
     @ApiModelProperty("用户类型")
     private ClientEnum userType;
 }

+ 560 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/MusicPracticeRecordWrapper.java

@@ -0,0 +1,560 @@
+package com.ym.mec.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
+import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
+import com.ym.mec.biz.dal.enums.FeatureType;
+import com.ym.mec.biz.dal.enums.HeardLevelEnum;
+import com.ym.mec.biz.dal.enums.im.CK;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.temporal.WeekFields;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.OptionalInt;
+
+/**
+ * 曲目练习记录
+ * 2022-12-07 10:16:58
+ */
+@ApiModel(value = "MusicPracticeRecordWrapper对象", description = "曲目练习记录查询对象")
+public class MusicPracticeRecordWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" MusicPracticeRecordQuery-曲目练习记录")
+    public static class MusicPracticeRecordQuery implements QueryInfo {
+
+    	@ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("曲目名称")
+        private String musicSheetName;
+
+        @ApiModelProperty("评测难度")
+        private String heardLevel;
+
+
+        @ApiModelProperty("最低总分")
+        private BigDecimal minScore = BigDecimal.ZERO;
+
+
+        @ApiModelProperty("最高总分")
+        private BigDecimal maxScore = new BigDecimal(100);
+
+        @ApiModelProperty("是否生成作品")
+        private Boolean userMusicFlag;
+
+        @ApiModelProperty("生成作品开始时间")
+        private Date userMusicStartTime;
+
+        @ApiModelProperty("生成作品结束时间")
+        private Date userMusicEndTime;
+
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+
+        @ApiModelProperty("用户编号")
+        private Long userId;
+
+        @ApiModelProperty("客户端类型")
+        private String clientType;
+
+
+        @ApiModelProperty("班级ID")
+        private Long classGroupId;
+
+        @ApiModelProperty("曲目编号")
+        private Long musicSheetId;
+
+        @ApiModelProperty("功能")
+        private String feature;
+
+        @ApiModelProperty("练习类型")
+        private List<String> practiceTypes;
+
+        @ApiModelProperty("评测结果数据 ")
+        private Boolean scoreData;
+
+        @ApiModelProperty("练习时间(按月:202209)")
+        private String practiceMonth;
+
+        @ApiModelProperty("练习来源")
+        private String practiceSource;
+
+
+        @ApiModelProperty("评测乐器ID")
+        private Long instrumentId;
+
+
+        @ApiModelProperty("声部Id")
+        private String subjectId;
+
+        @ApiModelProperty("乐团Id")
+        private String orchestraId;
+
+        @ApiModelProperty("学校Id")
+        private Long schoolId;
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+
+        @ApiModelProperty("伴学老师Id")
+        private Long teacherId;
+
+        @ApiModelProperty("删除标记")
+        private Boolean delFlag;
+
+        @ApiModelProperty("练习达标时间")
+        private Integer practiceTargetMinute;
+
+        @ApiModelProperty("周练习达标匹配")
+        private Boolean practiceTargetMatch;
+
+        @ApiModelProperty("周练习匹配")
+        private Boolean practiceMatch;
+
+        @ApiModelProperty("老师统计查询")
+        private Boolean teacherStatQuery;
+
+        @ApiModelProperty("学校统计查询")
+        private Boolean schoolStatQuery;
+
+        @ApiModelProperty("完整评测标记")
+        private Boolean completeEvaluation;
+
+        @ApiModelProperty("排除学生人数")
+        private List<Long> excludeStudentIds;
+
+        @ApiModelProperty("排序字段,1:综合得分,2:音准,3:节奏:4:完整度,5:评测时间 6:生成时间,7:评测进度")
+        private Integer sortType;
+
+        @ApiModelProperty("是否升序")
+        private Boolean asc;
+
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicPracticeRecordQuery from(String json) {
+            return JSON.parseObject(json, MusicPracticeRecordQuery.class);
+        }
+
+        public String getSubjectId() {
+            return Optional.ofNullable(subjectId).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String getOrchestraId() {
+            return Optional.ofNullable(orchestraId).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String getPracticeMonth() {
+            return Optional.ofNullable(practiceMonth).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public MusicPracticeRecordQuery scoreData(Boolean scoreData) {
+            this.scoreData = scoreData;
+            return this;
+        }
+
+
+        public MusicPracticeRecordQuery userId(String userId) {
+            this.userId = Long.parseLong(userId);
+            return this;
+        }
+
+        public MusicPracticeRecordQuery clientType(String clientType) {
+            this.clientType = clientType;
+            return this;
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+	@ApiModel(" MusicPracticeRecord-曲目练习记录")
+    public static class MusicPracticeRecord {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("用户编号")
+        private Long userId;
+
+        @ApiModelProperty("客户端类型")
+        private String clientType;
+
+        @ApiModelProperty("曲目编号")
+        private Long musicSheetId;
+
+        @ApiModelProperty("曲目名称")
+        private String musicSheetName;
+
+        @ApiModelProperty("行为编号,同一编号为一次")
+        private String behaviorId;
+
+        @ApiModelProperty("评分数据")
+        private String scoreData;
+
+        @ApiModelProperty("总分")
+        private BigDecimal score;
+
+        @ApiModelProperty("音准")
+        private BigDecimal intonation;
+
+        @ApiModelProperty("节奏")
+        private BigDecimal cadence;
+
+        @ApiModelProperty("完成度")
+        private BigDecimal integrity;
+
+        @ApiModelProperty("录音文件地址")
+        private String recordFilePath;
+
+        @ApiModelProperty("录像文件地址")
+        private String videoFilePath;
+
+        @ApiModelProperty("设备类型")
+        private String deviceType;
+
+        @ApiModelProperty("源音时长")
+        private Float sourceTime;
+
+        @ApiModelProperty("演奏时长")
+        private Float playTime;
+
+
+        @ApiModelProperty("演奏倍率")
+        private Float playRate;
+
+
+        @ApiModelProperty("速度")
+        private String speed;
+
+        @ApiModelProperty("周一日期")
+        private String monday;
+
+        @ApiModelProperty("功能")
+        private String feature;
+
+        @ApiModelProperty("评测难度")
+        private String heardLevel;
+
+        @ApiModelProperty("部分索引")
+        private String partIndex;
+
+        @ApiModelProperty("自定义配置 默认空字符串")
+        private String customConfiguration;
+
+        @ApiModelProperty("练习时间")
+        private String practiceTime;
+
+        @ApiModelProperty("练习来源")
+        private String practiceSource;
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        @ApiModelProperty("评测乐器ID")
+        private Long instrumentId;
+
+        @ApiModelProperty("评测乐器")
+        private String instrumentName;
+
+        @ApiModelProperty("是否节奏音乐")
+        private Boolean rhythmFlag;
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+        @ApiModelProperty("是否生成作品")
+        private Boolean userMusicFlag;
+
+        @ApiModelProperty("生成作品时间")
+        private Date userMusicTime;
+
+        @ApiModelProperty("评测进度")
+        private BigDecimal evaluationProgressNumber;
+
+        @ApiModelProperty("评测进度")
+        private String evaluationProgress;
+
+        @ApiModelProperty("是否佩戴耳机")
+        private Boolean headphoneFlag;
+
+        @ApiModelProperty("假删除标识 0:未删除 1:已删除")
+        private Boolean delFlag;
+
+
+        @ApiModelProperty("是否隐藏评测记录 0:不隐藏 1:隐藏")
+        private Boolean hiddenFlag;
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicPracticeRecord from(String json) {
+            return JSON.parseObject(json, MusicPracticeRecord.class);
+        }
+
+        // 初始化默认值
+        public MusicPracticeRecord initDefaultValue() {
+
+            return this.customConfiguration(Optional.ofNullable(getCustomConfiguration()).orElse(""))
+                .monday(Optional.ofNullable(getMonday()).orElse(LocalDate.now().with(WeekFields.of(DayOfWeek.MONDAY, 1).dayOfWeek(), DayOfWeek.MONDAY.getValue()).toString()))
+                .sourceTime(Optional.ofNullable(getSourceTime()).orElse(0F))
+                .playTime(Optional.ofNullable(getPlayTime()).orElse(0F))
+                .speed(Optional.ofNullable(getSpeed()).orElse("90"))
+                .practiceTime(Optional.ofNullable(getPracticeTime()).orElse(DateTime.now().toString(CK.FORMAT_YYYY_MM_DD)));
+        }
+
+
+        public MusicPracticeRecord sourceTime(Float sourceTime) {
+            this.sourceTime = sourceTime;
+            return this;
+        }
+
+        public MusicPracticeRecord playTime(Float playTime) {
+            this.playTime = playTime;
+            return this;
+        }
+
+        public MusicPracticeRecord speed(String speed) {
+            this.speed = speed;
+            return this;
+        }
+
+        public MusicPracticeRecord monday(String monday) {
+            this.monday = monday;
+            return this;
+        }
+
+        public MusicPracticeRecord customConfiguration(String customConfiguration) {
+            this.customConfiguration = customConfiguration;
+            return this;
+        }
+
+        public MusicPracticeRecord practiceTime(String practiceTime) {
+            this.practiceTime = practiceTime;
+            return this;
+        }
+
+        public MusicPracticeRecord userId(String userId) {
+            this.userId = Long.parseLong(userId);
+            return this;
+        }
+
+        public MusicPracticeRecord clientType(String clientType) {
+            this.clientType = clientType;
+            return this;
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class Entity{
+
+        @ApiModelProperty("主键ID")
+        private String id;
+
+        @ApiModelProperty("用户编号")
+        private String userId;
+
+        @ApiModelProperty("客户端类型")
+        private String clientType;
+
+        @ApiModelProperty("曲目编号")
+        private String musicSheetId;
+
+        @ApiModelProperty("行为编号,同一编号为一次")
+        private String behaviorId;
+
+        @ApiModelProperty("评分数据")
+        private String scoreData;
+
+        @ApiModelProperty("总分")
+        private BigDecimal score;
+
+        @ApiModelProperty("音准")
+        private BigDecimal intonation;
+
+        @ApiModelProperty("节奏")
+        private BigDecimal cadence;
+
+        @ApiModelProperty("完成度")
+        private BigDecimal integrity;
+
+        @ApiModelProperty("录音文件地址")
+        private String recordFilePath;
+
+        @ApiModelProperty("录像文件地址")
+        private String videoFilePath;
+
+        @ApiModelProperty("设备类型")
+        private String deviceType;
+
+        @ApiModelProperty("源音时长")
+        private Float sourceTime;
+
+        @ApiModelProperty("演奏时长")
+        private Float playTime;
+
+
+
+        @ApiModelProperty("演奏倍率")
+        private Float playRate;
+
+
+        @ApiModelProperty("速度")
+        private String speed;
+
+        @ApiModelProperty("周一日期")
+        private String monday;
+
+        @ApiModelProperty("功能")
+        private String feature;
+
+        @ApiModelProperty("评测难度")
+        private String heardLevel;
+
+
+        @ApiModelProperty("评测乐器ID")
+        private String instrumentId;
+
+
+        @ApiModelProperty("评测结果分析")
+        private String resultAnalyze;
+
+        @ApiModelProperty("部分索引")
+        private String partIndex;
+
+        @ApiModelProperty("练习时间")
+        private String practiceTime;
+
+        @ApiModelProperty("练习来源")
+        private String practiceSource;
+
+        @ApiModelProperty("自定义配置 默认空字符串")
+        private String customConfiguration;
+
+
+        @ApiModelProperty("是否佩戴耳机")
+        private Boolean headphoneFlag;
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        @ApiModelProperty("假删除标识 0:未删除 1:已删除")
+        private Boolean delFlag;
+
+
+        public static MusicPracticeRecordWrapper.Entity toEntity(SysMusicCompareRecord record) {
+            if (record ==null) {
+                return null;
+            }
+            return Entity.builder()
+                .id(record.getId().toString())
+                .userId(Optional.ofNullable(record.getUserId()).orElse(0).toString())
+                .clientType(record.getClientId()!=null?record.getClientId().toUpperCase():null)
+                .musicSheetId(record.getSysMusicScoreId()!=null? record.getSysMusicScoreId().toString():null)
+                .behaviorId(record.getBehaviorId())
+                .scoreData(record.getScoreData())
+                .score(record.getScore())
+                .intonation(record.getIntonation())
+                .cadence(record.getCadence())
+                .integrity(record.getIntegrity())
+                .recordFilePath(record.getRecordFilePath())
+                .videoFilePath(record.getVideoFilePath())
+                .deviceType(record.getDeviceType() !=null?record.getDeviceType().name():null)
+                .sourceTime(record.getSourceTime())
+                .playTime(record.getPlayTime())
+                .playRate(record.getPlayRate())
+                .speed(String.valueOf(OptionalInt.of(record.getSpeed()).orElse(0)))
+                .monday(record.getMonday())
+                .feature(record.getFeature()!=null?record.getFeature().toCbs():null)
+                .heardLevel(record.getHeardLevel() !=null?record.getHeardLevel().getCode():null)
+                .instrumentId(record.getInstrumentId()!=null?record.getInstrumentId().toString():null)
+                .resultAnalyze(record.getResultAnalyze())
+                .partIndex(record.getPartIndex())
+                .practiceTime(record.getPracticeTime())
+                .practiceSource(record.getPracticeSource())
+                .customConfiguration(record.getCustomConfiguration())
+                .headphoneFlag(record.getHeadphoneFlag())
+                .updateTime(record.getCreateTime())
+                .createTime(record.getCreateTime())
+                .delFlag(record.getDelFlag())
+                .build();
+        }
+
+        public SysMusicCompareRecord toSysMusicCompareRecord(){
+            SysMusicCompareRecord sysMusicCompareRecord = new SysMusicCompareRecord();
+            sysMusicCompareRecord.setId((this.id!=null?Long.parseLong(this.id):null));
+            sysMusicCompareRecord.setBehaviorId((this.behaviorId));
+            sysMusicCompareRecord.setUserId(this.userId!=null?Integer.parseInt(this.userId):null);
+            sysMusicCompareRecord.setSysMusicScoreId(this.musicSheetId!=null?Integer.parseInt(this.musicSheetId):null);
+            sysMusicCompareRecord.setHeardLevel(this.heardLevel!=null? HeardLevelEnum.valueOf(this.heardLevel):null);
+            sysMusicCompareRecord.setScoreData(this.scoreData);
+            sysMusicCompareRecord.setScore(this.score);
+            sysMusicCompareRecord.setIntonation(this.intonation);
+            sysMusicCompareRecord.setCadence(this.cadence);
+            sysMusicCompareRecord.setIntegrity(this.integrity);
+            sysMusicCompareRecord.setRecordFilePath(this.recordFilePath);
+            sysMusicCompareRecord.setVideoFilePath(this.videoFilePath);
+            sysMusicCompareRecord.setClientId(this.clientType!=null?this.clientType.toLowerCase():null);
+            sysMusicCompareRecord.setDeviceType(DeviceTypeEnum.valueOf(this.deviceType));
+            sysMusicCompareRecord.setSourceTime(this.sourceTime);
+            sysMusicCompareRecord.setPlayTime(this.playTime);
+            sysMusicCompareRecord.setSpeed(this.speed!=null?Integer.parseInt(this.speed):90);
+            sysMusicCompareRecord.setMonday(this.monday);
+            sysMusicCompareRecord.setFeature(this.feature!=null? FeatureType.format(this.feature):null);
+            sysMusicCompareRecord.setHeardLevel(this.heardLevel!=null? HeardLevelEnum.valueOf(this.heardLevel):null);
+            sysMusicCompareRecord.setCreateTime(this.createTime);
+            sysMusicCompareRecord.setPartIndex(this.partIndex);
+            sysMusicCompareRecord.setCustomConfiguration(this.customConfiguration);
+            sysMusicCompareRecord.setPracticeTime(this.practiceTime);
+            sysMusicCompareRecord.setPracticeSource(this.practiceSource);
+            sysMusicCompareRecord.setResultAnalyze(this.resultAnalyze);
+            sysMusicCompareRecord.setHeadphoneFlag(this.headphoneFlag);
+            sysMusicCompareRecord.setInstrumentId(this.instrumentId!=null?Long.parseLong(this.instrumentId):null);
+            sysMusicCompareRecord.setDelFlag(this.delFlag);
+            sysMusicCompareRecord.setPlayRate(this.playRate);
+
+            return sysMusicCompareRecord;
+
+        }
+    }
+}

+ 132 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/MusicSheetAccompanimentWrapper.java

@@ -0,0 +1,132 @@
+package com.ym.mec.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 lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 曲谱伴奏表
+ * 2022-12-07 10:16:58
+ */
+@ApiModel(value = "MusicSheetAccompanimentWrapper对象", description = "曲谱伴奏表查询对象")
+public class MusicSheetAccompanimentWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" MusicSheetAccompanimentQuery-曲谱伴奏表")
+    public static class MusicSheetAccompanimentQuery 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 MusicSheetAccompanimentQuery from(String json) {
+            return JSON.parseObject(json, MusicSheetAccompanimentQuery.class);
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+	@ApiModel(" MusicSheetAccompaniment-曲谱伴奏表")
+    public static class MusicSheetAccompaniment {
+
+        @ApiModelProperty("主键")
+        private Long id;
+
+        @ApiModelProperty("曲谱ID")
+        private Long musicId;
+
+        @ApiModelProperty("声部")
+        private String musicSubject;
+
+        @ApiModelProperty("MP3原声音频文件URL")
+        private String audioFileUrl;
+
+        @ApiModelProperty("map节拍器伴奏")
+        private String metronomeUrl;
+
+        @ApiModelProperty("伴奏轨迹")
+        private String track;
+
+        @ApiModelProperty("排序号")
+        private Boolean sortNumber;
+
+        @ApiModelProperty("速度")
+        private String speed;
+
+        @ApiModelProperty("曲目缓存")
+        private String musicSvg;
+
+        @ApiModelProperty("创建人(老师或者是后台平台用户)")
+        private Long createBy;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        @ApiModelProperty("五线谱PDF文件")
+        private String musicPdfUrl;
+
+
+        @ApiModelProperty("首调PDF文件")
+        private String firstPdfUrl;
+
+
+        @ApiModelProperty("固定调PDF文件")
+        private String jianPdfUrl;
+
+
+        @ApiModelProperty("音频类型,SING:演唱,PLAY:演奏")
+        private String audioPlayType;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheetAccompaniment from(String json) {
+            return JSON.parseObject(json, MusicSheetAccompaniment.class);
+        }
+
+
+        public MusicSheetAccompaniment musicId(Long musicId) {
+            this.musicId = musicId;
+            return this;
+        }
+
+        public MusicSheetAccompaniment musicSubject(String musicSubject) {
+            this.musicSubject = musicSubject;
+            return this;
+        }
+
+        public MusicSheetAccompaniment createBy(Long createBy) {
+            this.createBy = createBy;
+            return this;
+        }
+    }
+
+}

+ 37 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/MusicSheetWrapper.java

@@ -56,9 +56,44 @@ public class MusicSheetWrapper {
         }
     }
 
-	@ApiModel(" MusicSheet-曲谱表")
+    @Data
+    @ApiModel(" MusicSheet-曲谱表")
     public static class MusicSheet {
 
+        @ApiModelProperty("主键")
+        private String id;
+
+        @ApiModelProperty("曲谱分类")
+        private Integer musicSheetCategoriesId;
+
+        @ApiModelProperty("曲谱名称")
+        private String musicSheetName;
+
+
+        @ApiModelProperty("封面图")
+        private String titleImg;
+
+
+
+        @ApiModelProperty("作曲人")
+        private String composer;
+
+
+        @ApiModelProperty("内容平台曲目ID")
+        private String cbsMusicSheetId;
+
+
+
+        @ApiModelProperty("被使用次数")
+        private Long usedNum;
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+
+        @ApiModelProperty("音频类型,SING:演唱,PLAY:演奏")
+        private String audioPlayTypes;
+
         public String jsonString() {
             return JSON.toJSONString(this);
         }
@@ -66,7 +101,7 @@ public class MusicSheetWrapper {
         public static MusicSheet from(String json) {
             return JSON.parseObject(json, MusicSheet.class);
         }
-	}
+    }
 
     @Data
     @ApiModel(" AddMusicSheet-曲谱新增/修改表")

+ 14 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/UserMusicWrapper.java

@@ -51,6 +51,11 @@ public class UserMusicWrapper {
         @ApiModelProperty(value = "id",hidden = true)
         private Long id;
 
+        @ApiModelProperty("文件类型 音频 AUDIO,视频:VIDEO")
+        private String fileType;
+
+        @ApiModelProperty("关联练习数据ID")
+        private Long musicPracticeRecordId;
 
         @ApiModelProperty(value = "去除的ID,推荐作品列表需要去除原本作品")
         private Long exclusionId;
@@ -140,6 +145,9 @@ public class UserMusicWrapper {
         private String videoUrl;
 
 
+        @ApiModelProperty("文件类型") // .mp4 视频,其他为音频
+        private String fileType;
+
         @ApiModelProperty("录音文件地址")
         private String recordFilePath;
 
@@ -162,6 +170,9 @@ public class UserMusicWrapper {
         @ApiModelProperty("发布作品时间")
         private Date submitTime;
 
+        @ApiModelProperty("是否能被看到评级、评分字段")
+        private Boolean selectFlag;
+
         @ApiModelProperty("录制上传时间")
         private Date createTime;
 
@@ -221,6 +232,9 @@ public class UserMusicWrapper {
         @ApiModelProperty("json配置")
         private String jsonConfig;
 
+        @ApiModelProperty("是否能被看到评级、评分字段")
+        private Boolean selectFlag;
+
     }
 
 }

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/InstrumentService.java

@@ -53,7 +53,7 @@ public interface InstrumentService extends IService<Instrument>  {
 
     List<InstrumentWrapper.Instrument> getList(InstrumentWrapper.InstrumentQuery query);
 
-    List<Integer> getInstrumentIdsBySubjectId(Integer subjectId);
+    List<Instrument> getInstrumentIdsBySubjectId(String subjectId);
 
     void modify(InstrumentWrapper.Update update);
 }

+ 31 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/MusicPracticeRecordService.java

@@ -0,0 +1,31 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.wrapper.MusicPracticeRecordWrapper;
+
+public interface MusicPracticeRecordService {
+
+    /**
+     * 查询记录详情
+     */
+    MusicPracticeRecordWrapper.Entity detail(Long id);
+
+    /**
+     * 添加记录
+     */
+    String add(MusicPracticeRecordWrapper.MusicPracticeRecord from);
+
+
+    Object getLastEvaluationMusicalNotesPlayStats(Long recordId);
+
+    /**
+     * 查询记录
+     *
+     */
+    MusicPracticeRecordWrapper.Entity getById(Long id);
+
+    /**
+     * 更新练习记录
+     *
+     */
+    void update(MusicPracticeRecordWrapper.Entity practiceRecord);
+}

+ 4 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java

@@ -8,8 +8,8 @@ import com.ym.mec.biz.dal.page.MusicCompareRecordWapper;
 import com.ym.mec.biz.dal.page.SysMusicCompareRecordQueryInfo;
 import com.ym.mec.biz.dal.page.TeacherCloudTrainingQueryInfo;
 import com.ym.mec.common.page.PageInfo;
-import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.BaseService;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 import java.util.Map;
@@ -35,6 +35,9 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
      */
     void saveMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord);
 
+    @Transactional
+    long insertMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord);
+
     /**
      * @describe 用户最后一次评测数据
      * @author Joburgess

+ 15 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicScoreService.java

@@ -48,5 +48,20 @@ public interface SysMusicScoreService extends BaseService<Integer, SysMusicScore
 
     void del(Long id);
 
+    /**
+     * 查询总控平台曲目信息
+     * @param musicSheetId 业务端曲目ID
+     * @return CbsMusicSheetWrapper.MusicSheet
+     */
+    CbsMusicSheetWrapper.MusicSheet cbsDetail(Integer musicSheetId);
+
+    /**
+     * 查询总控平台曲目信息
+     * @param cbsMusicSheetId 总控平台曲目ID
+     * @return CbsMusicSheetWrapper.MusicSheet
+     */
+    CbsMusicSheetWrapper.MusicSheet getCbsMusicSheetByCbsId(Long cbsMusicSheetId);
+
+
     MusicSheetWrapper.ClientMusicSheetInfo queryMusicScoreDetail(MusicSheetWrapper.ClientMusicSheetInfoQuery id);
 }

+ 5 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java

@@ -568,7 +568,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
                     courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
                     teacherAttendanceDao.batchDeleteByCourseSchedules(courseScheduleIds);
                     // 删除基础提高班课程
-                    courseScheduleDao.deleteCourseSchedulesByClassGroupIds(courseScheduleIds);
+                    courseScheduleDao.batchDeleteByCourseSchedules(courseScheduleIds);
                 }
 
                 List<ImGroupModel> imGroupModelList = new ArrayList<>();
@@ -2919,7 +2919,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
                 //删除课程以及关联的学员老师
                 courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseScheduleIds);
                 courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
-                courseScheduleDao.deleteCourseSchedulesByClassGroupIds(courseScheduleIds);
+                courseScheduleDao.batchDeleteByCourseSchedules(courseScheduleIds);
             }
             //取消所有预排课
             musicGroupSchoolTermStudentCourseDetailDao.deleteByDetailId(musicGroupSchoolTermCourseDetailId, null);
@@ -2960,7 +2960,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
             //删除课程以及关联的学员老师
             courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseScheduleIds);
             courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
-            courseScheduleDao.deleteCourseSchedulesByClassGroupIds(courseScheduleIds);
+            courseScheduleDao.batchDeleteByCourseSchedules(courseScheduleIds);
         }
     }
 
@@ -4447,7 +4447,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
             List<Long> delCourseIds = courseScheduleDao.findNoStudentCourseIds(courseIds);
             if (delCourseIds != null && delCourseIds.size() > 0) {
                 //删除课程
-                courseScheduleDao.deleteCourseSchedulesByClassGroupIds(delCourseIds);
+                courseScheduleDao.batchDeleteByCourseSchedules(delCourseIds);
                 //删除教师考勤
                 teacherAttendanceDao.batchDeleteByCourseSchedules(delCourseIds);
                 //删除教师课酬
@@ -4954,7 +4954,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
             List<Long> delCourseIds = courseScheduleDao.findNoStudentCourseIds(courseIds);
             if (delCourseIds != null && delCourseIds.size() > 0) {
                 //删除课程
-                courseScheduleDao.deleteCourseSchedulesByClassGroupIds(delCourseIds);
+                courseScheduleDao.batchDeleteByCourseSchedules(delCourseIds);
                 //删除教师考勤
                 teacherAttendanceDao.batchDeleteByCourseSchedules(delCourseIds);
                 //删除教师课酬

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

@@ -81,7 +81,7 @@ public class CourseConvertLogServiceImpl extends BaseServiceImpl<Integer, Course
 		courseConvertLog.setOldClassName(classGroup.getName());
 		courseConvertLog.setOldCourseJson(JSONObject.toJSONString(courseSchedules));
 		//删除课程
-		courseScheduleDao.batchDelete(oldCourseIdList);
+		courseScheduleDao.batchDeleteByCourseSchedules(oldCourseIdList);
 
 		//记录老师考勤
 		List<TeacherAttendance> teacherAttendances = teacherAttendanceDao.findByCourseSchedules(oldCourseIdList);

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

@@ -191,7 +191,7 @@ public class CourseScheduleConvertServiceImpl implements CourseScheduleConvertSe
 
     private void delByCourse(List<Long> newCourseIdList){
         //删除转换后的课程、课酬、学员课程价值
-        courseScheduleService.getDao().batchDelete(newCourseIdList);
+        courseScheduleService.getDao().batchDeleteByCourseSchedules(newCourseIdList);
         //删除老师考勤
         teacherAttendanceService.getDao().batchDeleteByCourseSchedules(newCourseIdList);
         //删除老师课酬

+ 3 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -350,7 +350,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 				}
 			}
 		}
-		courseScheduleDao.batchDeleteAllCourseSchedules(courseScheduleIds);
+		courseScheduleDao.batchDeleteByCourseSchedules(courseScheduleIds);
 		courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
 		courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseScheduleIds);
 		// 删除考勤
@@ -376,7 +376,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		}
 		List<Long> courseScheduleIds = courseScheduleList.stream().map(CourseSchedule::getId).collect(Collectors.toList());
 
-		courseScheduleDao.batchDelete(courseScheduleIds);
+		courseScheduleDao.batchDeleteByCourseSchedules(courseScheduleIds);
 		courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
 		courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseScheduleIds);
 		// 删除考勤
@@ -973,7 +973,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		oldCourseScheduleTeacherSalaries = oldCourseScheduleTeacherSalaries.stream().filter(c->TeachTypeEnum.BISHOP.equals(c.getTeacherRole())).collect(Collectors.toList());
 		oldCourseScheduleTeacherSalaries.forEach(o->o.setCourseSchedule(idCourseMap.get(o.getCourseScheduleId())));
 
-		courseScheduleDao.batchDeleteAllCourseSchedules(courseScheduleIds);
+		courseScheduleDao.batchDeleteByCourseSchedules(courseScheduleIds);
 		courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIds);
 		courseScheduleStudentPaymentDao.deleteByCourseSchedule(courseScheduleIds);
 		// 删除考勤

+ 7 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/InstrumentServiceImpl.java

@@ -14,6 +14,7 @@ import com.ym.mec.biz.dal.wrapper.InstrumentWrapper;
 import com.ym.mec.biz.service.InstrumentService;
 import com.ym.mec.biz.service.SubjectService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
@@ -36,6 +37,9 @@ public class InstrumentServiceImpl extends ServiceImpl<InstrumentDao, Instrument
     @Resource
     private SubjectService subjectService;
 
+    @Autowired
+    private InstrumentDao instrumentDao;
+
     /**
      * 查询详情
      *
@@ -189,14 +193,12 @@ public class InstrumentServiceImpl extends ServiceImpl<InstrumentDao, Instrument
     }
 
     @Override
-    public List<Integer> getInstrumentIdsBySubjectId(Integer subjectId) {
-        List<Instrument> list = this.lambdaQuery()
-            .eq(Instrument::getSubjectId, subjectId)
-            .list();
+    public List<Instrument> getInstrumentIdsBySubjectId(String subjectId) {
+        List<Instrument> list = instrumentDao.getBySubjectId(subjectId);
         if (CollectionUtils.isEmpty(list)) {
             return new ArrayList<>();
         }
-        return list.stream().map(Instrument::getId).collect(Collectors.toList());
+        return list;
     }
 
     @Override

+ 122 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicPracticeRecordServiceImpl.java

@@ -0,0 +1,122 @@
+package com.ym.mec.biz.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.biz.dal.dao.SysMusicCompareRecordDao;
+import com.ym.mec.biz.dal.dao.SysMusicScoreDao;
+import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.dal.enums.FeatureType;
+import com.ym.mec.biz.dal.wrapper.MusicPracticeRecordWrapper;
+import com.ym.mec.biz.service.MusicPracticeRecordService;
+import com.ym.mec.biz.service.SysMusicCompareRecordService;
+import com.ym.mec.biz.service.SysMusicScoreService;
+import com.ym.mec.common.exception.BizException;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.Objects;
+
+@Service
+public class MusicPracticeRecordServiceImpl implements MusicPracticeRecordService {
+
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+    @Autowired
+    private SysMusicScoreService musicSheetService;
+
+    @Autowired
+    private SysMusicCompareRecordDao sysMusicCompareRecordDao;
+
+    /**
+     * 查询记录详情
+     *
+     * @param id
+     */
+    @Override
+    public MusicPracticeRecordWrapper.Entity detail(Long id) {
+        SysMusicCompareRecord sysMusicCompareRecord = sysMusicCompareRecordService.get(id);
+        if (sysMusicCompareRecord == null) {
+            throw new BizException("记录不存在");
+        }
+        return MusicPracticeRecordWrapper.Entity.toEntity(sysMusicCompareRecord);
+
+    }
+
+    /**
+     * 添加记录
+     *
+     * @param from
+     */
+    @Override
+    public String add(MusicPracticeRecordWrapper.MusicPracticeRecord from) {
+
+
+        // 曲目练习记录
+        from.setCreateTime(new Date());
+        MusicPracticeRecordWrapper.Entity musicPracticeRecord = JSON.parseObject(from.initDefaultValue().jsonString(),
+            MusicPracticeRecordWrapper.Entity.class);
+        SysMusicCompareRecord sysMusicCompareRecord = musicPracticeRecord.toSysMusicCompareRecord();
+        Long id = null;
+        if (sysMusicCompareRecord.getFeature() == FeatureType.CLOUD_STUDY_EVALUATION) {
+            id = sysMusicCompareRecordService.insertMusicCompareData(sysMusicCompareRecord);
+        } else {
+            id = sysMusicCompareRecordService.insert(sysMusicCompareRecord);
+        }
+
+        return String.valueOf(id);
+    }
+
+    @Override
+    public Object getLastEvaluationMusicalNotesPlayStats(Long recordId) {
+        MusicPracticeRecordWrapper.Entity userLastEvaluationData = detail(recordId);
+        if(Objects.isNull(userLastEvaluationData)){
+            return null;
+        }
+        if(StringUtils.isBlank(userLastEvaluationData.getScoreData())){
+            return null;
+        }
+
+        JSONObject jsonObject = JSON.parseObject(userLastEvaluationData.getScoreData());
+        jsonObject.put("recordId", userLastEvaluationData.getId());
+        jsonObject.put("score", userLastEvaluationData.getScore());
+        jsonObject.put("cadence", userLastEvaluationData.getCadence());
+        jsonObject.put("intonation", userLastEvaluationData.getIntonation());
+        jsonObject.put("integrity", userLastEvaluationData.getIntegrity());
+        jsonObject.put("heardLevel", userLastEvaluationData.getHeardLevel());
+        jsonObject.put("videoFilePath", userLastEvaluationData.getVideoFilePath());
+        jsonObject.put("partIndex", userLastEvaluationData.getPartIndex());
+        jsonObject.put("customConfiguration", userLastEvaluationData.getCustomConfiguration());
+
+        SysMusicScore sysMusicScore = musicSheetService.get(Integer.parseInt(userLastEvaluationData.getMusicSheetId()));
+        if(Objects.nonNull(sysMusicScore)){
+            jsonObject.put("sysMusicScoreName", sysMusicScore.getName());
+        }
+        return jsonObject;
+    }
+
+    /**
+     * 查询记录
+     *
+     * @param id
+     */
+    @Override
+    public MusicPracticeRecordWrapper.Entity getById(Long id) {
+        return detail(id);
+    }
+
+    /**
+     * 更新练习记录
+     *
+     * @param practiceRecord
+     */
+    @Override
+    public void update(MusicPracticeRecordWrapper.Entity practiceRecord) {
+
+        SysMusicCompareRecord sysMusicCompareRecord = practiceRecord.toSysMusicCompareRecord();
+        sysMusicCompareRecordService.update(sysMusicCompareRecord);
+    }
+}

+ 90 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentManageServiceImpl.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.*;
@@ -124,6 +125,9 @@ public class StudentManageServiceImpl implements StudentManageService {
     @Autowired
     private MemberRankSettingService memberRankSettingService;
 
+    @Autowired
+    private InstrumentService instrumentService;
+
     @Override
     public PageInfo<StudentManageListDto> findStudentsByOrganId(StudentManageQueryInfo queryInfo) {
         PageInfo<StudentManageListDto> pageInfo = new PageInfo<StudentManageListDto>(queryInfo.getPage(), queryInfo.getRows());
@@ -1328,6 +1332,92 @@ public class StudentManageServiceImpl implements StudentManageService {
         // 学员会员信息
         datas.put("vipInfo", cloudTeacherOrderService.getEffectiveCloudTeacherOrder(Lists.newArrayList(student.getUserId())));
 
+
+        // 通过学生声部换乐器ID
+        if (StringUtils.isNotBlank(student.getSubjectIdList())) {
+            String subjectId = student.getSubjectIdList();
+            if ("5".equals(student.getSubjectIdList())) {
+                subjectId = "6";
+            } else  if("122".equals(student.getSubjectIdList())){
+                subjectId = "122,121,113,23";
+            }
+            List<Integer> instrumentIdsBySubjectId = instrumentService.getInstrumentIdsBySubjectId(subjectId)
+                .stream().map(Instrument::getId).collect(Collectors.toList());
+            if (!CollectionUtils.isEmpty(instrumentIdsBySubjectId)) {
+                // 逗号隔开
+                datas.put("instrumentId", StringUtils.join(instrumentIdsBySubjectId, ","));
+            }
+        }
+
+        // 扩展乐器
+        if (student.getExtSjectNamesMap() !=null && !student.getExtSjectNamesMap().isEmpty()) {
+            Set<Integer> integers = student.getExtSjectNamesMap().keySet();
+            Set<Integer> extInstrumentIds = Sets.newConcurrentHashSet();
+            for (Integer integer : integers) {
+                extInstrumentIds.add(integer);
+
+                if ("5".equals(integer.toString())) {
+                    extInstrumentIds.add(6);
+                } else  if("122".equals(integer.toString())){
+                    extInstrumentIds.add(121);
+                    extInstrumentIds.add(113);
+                    extInstrumentIds.add(23);
+                }
+            }
+
+            // 根据声部查询对应乐器信息
+            List<Instrument> instruments = instrumentService.getInstrumentIdsBySubjectId(StringUtils.join(extInstrumentIds, ","));
+            List<Map<String, Object>> extInstrumentNames = Lists.newArrayList();
+            if (!CollectionUtils.isEmpty(instruments)) {
+
+                Map<Integer, List<Instrument>> collect = instruments.stream().collect(Collectors.groupingBy(Instrument::getSubjectId, Collectors.toList()));
+                for (Map.Entry<Integer, String> entry : student.getExtSjectNamesMap().entrySet()) {
+
+                    // 默认声部映射乐器ID
+                    String instrumentIds = "";
+                    if (collect.containsKey(entry.getKey())) {
+                        instrumentIds = collect.get(entry.getKey()).stream()
+                            .map(Instrument::getId).map(String::valueOf).collect(Collectors.joining(","));
+                    }
+
+                    // 萨克斯乐器,对应中音萨克斯
+                    if (entry.getKey() == 5 || entry.getKey() == 6) {
+
+                        instrumentIds = collect.entrySet().stream()
+                            .filter(x -> x.getKey() == 5 || x.getKey() == 6)
+                            .flatMap(x -> x.getValue().stream())
+                            .map(Instrument::getId)
+                            .map(String::valueOf).collect(Collectors.joining(","));
+                    }
+
+                    // 打击乐器,对应小军鼓,打击乐(键盘),打击乐(键盘+小鼓),打击乐
+                    if (entry.getKey() == 122 || entry.getKey() == 121 || entry.getKey() == 113 || entry.getKey() == 23) {
+
+                        instrumentIds = collect.entrySet().stream()
+                            .filter(x -> x.getKey() == 122 || x.getKey() == 121 || x.getKey() == 113 || x.getKey() == 23)
+                            .flatMap(x -> x.getValue().stream())
+                            .map(Instrument::getId)
+                            .map(String::valueOf).collect(Collectors.joining(","));
+                    }
+                    String finalInstrumentIds = instrumentIds;
+                    extInstrumentNames.add(new HashMap<String, Object>(){{
+                        put("subjectId", entry.getKey());
+                        put("subjectName", entry.getValue());
+                        put("instrumentIds", finalInstrumentIds);
+                    }});
+                }
+
+                /*List<Integer> instrumentIdsBySubjectId = instruments.stream().map(Instrument::getId).collect(Collectors.toList());
+                Map<Integer, InstrumentWrapper.Instrument> mapByIds = instrumentService.getMapByIds(instrumentIdsBySubjectId);
+                mapByIds.forEach((k,v)->{
+                    if (v !=null) {
+                        extInstrumentNamesMap.put(k, v.getName());
+                    }
+                });*/
+            }
+            student.setExtInstrumentNames(extInstrumentNames);
+        }
+
         return student;
     }
 }

+ 19 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java

@@ -93,7 +93,9 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 
 			updateCampData(bean);
 		}
-		return insert;
+
+        return sysMusicCompareRecordDao.getLastData(bean.getClientId(),bean.getUserId()
+            ,bean.getFeature().getCode(),bean.getSysMusicScoreId());
 	}
 
     @Override
@@ -165,6 +167,22 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 				.updateUserWeekTrainData(userId, LocalDate.now().with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue()));
 	}
 
+    @Override
+    @Transactional
+    public long insertMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord) {
+
+        Integer userId = sysMusicCompareRecord.getUserId();
+
+        sysMusicCompareRecordDao.insert(sysMusicCompareRecord);
+        Long id = sysMusicCompareRecordDao.getLastData(sysMusicCompareRecord.getClientId(),sysMusicCompareRecord.getUserId()
+            ,sysMusicCompareRecord.getFeature().getCode(),sysMusicCompareRecord.getSysMusicScoreId());
+        studentDao.addStudentCloudStudySequenceDays(userId);
+        updateCampData(sysMusicCompareRecord);
+        sysMusicCompareWeekDataService
+            .updateUserWeekTrainData(userId, LocalDate.now().with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue()));
+        return id;
+    }
+
 	@Override
 	public JSONObject getLastEvaluationMusicalNotesPlayStats(Integer userId, Long recordId) {
 		SysMusicCompareRecord userLastEvaluationData;

+ 44 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicScoreServiceImpl.java

@@ -219,6 +219,9 @@ public class SysMusicScoreServiceImpl extends BaseServiceImpl<Integer, SysMusicS
 //            record.setMusicScoreCategoriesId(musicSheetApplication.getMusicSheetCategoryId().intValue());
 //            record.setCategoriesId(musicSheetApplication.getMusicSheetCategoryId().intValue());
 //        }
+        record.setAudioPlayTypes(musicSheetApplication.getAudioPlayTypes());
+        record.setTitleImg(musicSheetApplication.getMusicCover());
+        record.setComposer(musicSheetApplication.getComposer());
         record.setName(musicSheetApplication.getName());
         record.setCategoriesName(musicSheetApplication.getMusicSheetCategoryName());
         record.setSpeed(musicSheetApplication.getPlaySpeed());
@@ -317,8 +320,11 @@ public class SysMusicScoreServiceImpl extends BaseServiceImpl<Integer, SysMusicS
         this.initCategoryIds(queryInfo);
         if(queryInfo.getSubjectId() != null){
             if(queryInfo.getSubjectId() == 5){
-                queryInfo.setSubjectId(6);
+                queryInfo.setSubjectId(null);
                 queryInfo.setSubjectIds("6");
+            }else if(queryInfo.getSubjectId() == 122){
+                queryInfo.setSubjectId(null);
+                queryInfo.setSubjectIds("122,121,113,23");
             }else {
                 queryInfo.setSubjectIds(queryInfo.getSubjectId().toString());
             }
@@ -661,4 +667,41 @@ public class SysMusicScoreServiceImpl extends BaseServiceImpl<Integer, SysMusicS
 
     }
 
+    /**
+     * @param musicSheetId 业务端曲目ID
+     * @return CbsMusicSheetWrapper.MusicSheet
+     */
+    @Override
+    public CbsMusicSheetWrapper.MusicSheet cbsDetail(Integer musicSheetId) {
+        // 曲目信息
+        SysMusicScore musicSheet = getDao().get(musicSheetId);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+
+
+        if (StringUtils.isBlank(musicSheet.getCbsMusicSheetId())) {
+            throw new BizException("曲目信息异常");
+        }
+        return getCbsMusicSheetByCbsId(Long.parseLong(musicSheet.getCbsMusicSheetId()));
+    }
+
+    /**
+     * 查询总控平台曲目信息
+     *
+     * @param cbsMusicSheetId 总控平台曲目ID
+     * @return CbsMusicSheetWrapper.MusicSheet
+     */
+    @Override
+    public CbsMusicSheetWrapper.MusicSheet getCbsMusicSheetByCbsId(Long cbsMusicSheetId) {
+        try {
+
+            R<CbsMusicSheetWrapper.MusicSheet> musicSheetR = musicFeignClientService.musicSheetDetail(cbsMusicSheetId, applicationId);
+
+            return musicSheetR.feignData();
+        } catch (Exception e) {
+            log.error("调用音乐服务异常", e);
+            throw new BizException("内容平台服务异常");
+        }
+    }
 }

+ 12 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/UserMusicServiceImpl.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alipay.service.schema.util.StringUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.microsvc.toolkit.common.webportal.exception.BizException;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.ym.mec.auth.api.entity.SysUser;
@@ -71,6 +72,7 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
     private UserMusicMapper userMusicMapper;
 
 
+    private static  final List<String> videoList = Lists.newArrayList(".mp4");
     /**
      * 查询详情
      * @param id 详情ID
@@ -187,12 +189,20 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
                 throw new BizException("已发布的作品不能修改为草稿");
             }
         }
-
+        Date date = new Date();
         if (entity.getType() == null) {
         } else if (entity.getType().equals(EUserMusicType.DRAFT)) {
             entity.setSubmitTime(null);
         } else if (old == null || old.getType().equals(EUserMusicType.DRAFT)) {
-            entity.setSubmitTime(new Date());
+            entity.setSubmitTime(date);
+        }
+        entity.setUpdateTime(date);
+        if (!StringUtil.isEmpty(entity.getVideoUrl())) {
+            if (videoList.stream().noneMatch(entity.getVideoUrl()::endsWith)) {
+                entity.setFileType("AUDIO");
+            } else {
+                entity.setFileType("VIDEO");
+            }
         }
         userMusicService.saveOrUpdate(entity);
         return entity.getId();

+ 2 - 1
mec-biz/src/main/resources/config/mybatis/CoursePatrolEvaluationMapper.xml

@@ -29,6 +29,7 @@
             left join sys_user su on cs.actual_teacher_id_ = su.id_
         </if>
         <where>
+            cs.del_flag_ = '0'
             <if test="param.patrolFlag != null and param.patrolFlag">
                 and t.id_ is not null
             </if>
@@ -92,7 +93,7 @@
             left join music_group mg on mg.id_ = cs.music_group_id_
             left join course_patrol_evaluation cpe on cpe.course_schedule_id_ = cs.id_
         <where>
-            cs.teach_mode_ = 'OFFLINE'
+            cs.teach_mode_ = 'OFFLINE' AND cs.del_flag_ = '0'
             <if test="param.startTime != null">
                 and cs.class_date_ &gt;= date_format(#{param.startTime},'%Y-%m-%d')
             </if>

+ 2 - 0
mec-biz/src/main/resources/config/mybatis/CourseScheduleEvaluateMapper.xml

@@ -362,6 +362,7 @@
         WHERE cs.id_ >= 1
           AND vg.id_ >= 1
           AND cs.is_lock_ = 0
+          AND cs.del_flag_ = '0'
           AND s.operating_tag_ = 0
           and cssp.tenant_id_ = #{tenantId}
         GROUP BY vg.organ_id_
@@ -378,6 +379,7 @@
           AND pg.buy_months_ >= 1
           AND cs.id_ >= 1
           AND cs.is_lock_ = 0
+          AND cs.del_flag_ = '0'
           AND s.operating_tag_ = 0
           and pg.tenant_id_ = #{tenantId}
         GROUP BY pg.organ_id_

+ 126 - 142
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -386,25 +386,22 @@
     </update>
 
     <!-- 根据主键删除一条记录 -->
-    <delete id="delete">
-        DELETE
-        FROM course_schedule
-        WHERE id_ = #{id}
-    </delete>
+    <update id="delete">
+        update course_schedule set del_flag_    = '1',del_time_ = NOW() WHERE id_ = #{id}
+    </update>
 
-    <delete id="deleteCourseSchedulesByMusicGroupID" parameterType="map">
-        DELETE
-        FROM course_schedule
+    <update id="deleteCourseSchedulesByMusicGroupID" parameterType="map">
+        update course_schedule set del_flag_    = '1',del_time_ = NOW()
         WHERE music_group_id_ = #{musicGroupId}
         <if test="groupType != null and groupType != ''">
           AND group_type_ = #{groupType}
         </if>
           and status_ = 'NOT_START'
-    </delete>
+    </update>
 
     <update id="logicDeleteCourseSchedulesByMusicGroupID">
         update course_schedule
-        set del_flag_    = '1'
+        set del_flag_    = '1',del_time_ = NOW()
         WHERE music_group_id_ = #{musicGroupID}
           AND group_type_ = 'MUSIC'
           and status_ = 'NOT_START'
@@ -412,32 +409,24 @@
 
     <update id="resumeCourseScheduleByMusicGroupId">
         update course_schedule
-        set del_flag_    = '0'
+        set del_flag_    = '0',del_time_ = null
         WHERE music_group_id_ = #{musicGroupID}
           AND group_type_ = 'MUSIC'
           and status_ = 'NOT_START'
           and del_flag_ = '1'
     </update>
 
-    <delete id="batchDeleteCourseSchedules">
-        DELETE FROM course_schedule
+    <update id="batchDeleteCourseSchedules">
+        update course_schedule set del_flag_    = '1',del_time_ = NOW()
         WHERE
         CONCAT( class_date_, ' ', start_class_time_ ) &gt; NOW()
         AND id_ IN
         <foreach collection="courseScheduleIds" item="courseScheduleId" open="(" close=")" separator=",">
             #{courseScheduleId}
         </foreach>
-    </delete>
+    </update>
     <delete id="batchDeleteByCourseSchedules">
-        UPDATE course_schedule SET del_flag_ = '1',update_time_ = NOW()
-        WHERE id_ IN
-        <foreach collection="courseScheduleIds" item="courseScheduleId" open="(" close=")" separator=",">
-            #{courseScheduleId}
-        </foreach>
-    </delete>
-
-    <delete id="batchDelete">
-        DELETE FROM course_schedule
+        UPDATE course_schedule SET del_flag_ = '1',del_time_ = NOW()
         WHERE id_ IN
         <foreach collection="courseScheduleIds" item="courseScheduleId" open="(" close=")" separator=",">
             #{courseScheduleId}
@@ -455,18 +444,10 @@
             </foreach>
     </update>
 
-    <delete id="batchDeleteAllCourseSchedules">
-        DELETE FROM course_schedule
-        WHERE id_ IN
-        <foreach collection="courseScheduleIds" item="courseScheduleId" open="(" close=")" separator=",">
-            #{courseScheduleId}
-        </foreach>
-    </delete>
-
     <select id="filterNotStartCourseIdsWithIds" resultType="long">
         SELECT id_ FROM course_schedule
         WHERE
-        CONCAT( class_date_, ' ', start_class_time_ ) &gt; NOW()
+        CONCAT( class_date_, ' ', start_class_time_ ) &gt; NOW() AND del_flag_ = '0'
         AND id_ IN
         <foreach collection="courseScheduleIds" item="courseScheduleId" open="(" close=")" separator=",">
             #{courseScheduleId}
@@ -475,14 +456,14 @@
 
     <!-- 分页查询 -->
     <select id="queryPage" resultMap="CourseSchedule" parameterType="map">
-        SELECT * FROM course_schedule where tenant_id_ = #{tenantId} ORDER BY id_
+        SELECT * FROM course_schedule where tenant_id_ = #{tenantId} AND del_flag_ = '0' ORDER BY id_
         <include refid="global.limit"/>
     </select>
 
     <!-- 查询当前表的总记录数 -->
     <select id="queryCount" resultType="int">
         SELECT COUNT(*)
-        FROM course_schedule where tenant_id_ = #{tenantId}
+        FROM course_schedule where tenant_id_ = #{tenantId} AND del_flag_ = '0'
     </select>
 
     <resultMap type="com.ym.mec.biz.dal.dto.TeacherAttendanceDto" id="TeacherAttendanceViewUtilEntity">
@@ -570,7 +551,7 @@
                  LEFT JOIN school s ON mg.school_id_ = s.id_
                  LEFT JOIN sys_user su ON cs.actual_teacher_id_ = su.id_
                  LEFT JOIN teacher_attendance ta ON cs.id_ = ta.course_schedule_id_
-        WHERE cs.actual_teacher_id_ = #{teacherId}
+        WHERE cs.actual_teacher_id_ = #{teacherId} AND cs.del_flag_ = '0'
           AND (CONCAT(cs.class_date_, ' ', cs.end_class_time_) BETWEEN #{startTime} AND #{endTime})
           AND cs.schoole_id_ = #{schoolId}
           AND ta.sign_in_time_ IS NOT NULL AND cs.pre_course_flag_ != 1
@@ -944,7 +925,7 @@
                  LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
         WHERE cs.class_date_ BETWEEN #{firstDayOfMonth} AND #{lastDayOfMonth}
           AND cg.music_group_id_ = #{musicGroupID}
-          AND cg.group_type_ = 'MUSIC' AND cs.pre_course_flag_ = 0
+          AND cg.group_type_ = 'MUSIC' AND cs.pre_course_flag_ = 0 AND cs.del_flag_ = '0'
         GROUP BY cs.class_date_
     </select>
 
@@ -952,7 +933,7 @@
             resultType="int">
         SELECT COUNT(*)
         FROM course_schedule cs
-        WHERE cs.teacher_id_ = #{teacherId}
+        WHERE cs.teacher_id_ = #{teacherId} AND cs.del_flag_ = '0'
           AND cs.class_date_ = DATE_FORMAT(#{classDate}, '%Y-%m-%d')
           AND (
                     CONCAT(cs.class_date_, ' ', cs.start_class_time_) &lt;
@@ -977,7 +958,7 @@
         FROM
         course_schedule cs
         WHERE
-        cs.teacher_id_ = #{teacherId}
+        cs.teacher_id_ = #{teacherId} AND cs.del_flag_ = '0'
         AND cs.class_date_ IN
         <foreach collection="dates" item="date" open="(" close=")" separator=",">
             #{date}
@@ -989,7 +970,7 @@
         FROM
         course_schedule cs
         WHERE
-        cs.tenant_id_ = #{tenantId}
+        cs.tenant_id_ = #{tenantId} AND cs.del_flag_ = '0'
         and cs.class_date_ IN
         <foreach collection="dates" item="date" open="(" close=")" separator=",">
             DATE_FORMAT(#{date},'%Y-%m-%d')
@@ -1019,7 +1000,7 @@
         FROM
         course_schedule cs
         LEFT JOIN course_schedule_teacher_salary csts ON cs.id_ = csts.course_schedule_id_
-        WHERE cs.tenant_id_ = #{tenantId} and
+        WHERE cs.tenant_id_ = #{tenantId} AND cs.del_flag_ = '0' and
         cs.class_date_ IN
         <foreach collection="dates" item="date" open="(" close=")" separator=",">
             DATE_FORMAT(#{date},'%Y-%m-%d')
@@ -1045,7 +1026,7 @@
     <!-- 获取班级未开始的课程 -->
     <select id="findClassGroupNoStartCourseSchedules" resultMap="CourseSchedule">
         SELECT * FROM course_schedule
-        WHERE status_ = 'NOT_START' AND pre_course_flag_ = 0
+        WHERE status_ = 'NOT_START' AND pre_course_flag_ = 0 AND del_flag_ = '0'
         AND class_group_id_ IN
         <foreach collection="classGroupIds" item="classGroupId" index="index" open="(" close=")" separator=",">
             #{classGroupId}
@@ -1296,7 +1277,7 @@
         LEFT JOIN course_schedule cs ON cs.id_ = cssp.course_schedule_id_
         LEFT JOIN school s ON s.id_ = cs.schoole_id_
         LEFT JOIN sys_user su ON cs.actual_teacher_id_ = su.id_
-        WHERE cs.is_lock_ = 0
+        WHERE cs.is_lock_ = 0 AND cs.del_flag_ = '0'
         AND cs.status_ = 'NOT_START'
         AND cssp.user_id_ = #{userId}
         AND cs.class_date_ = DATE_FORMAT(#{date}, '%Y%m%d')
@@ -1313,7 +1294,7 @@
     <select id="countClassTimes" resultType="int">
         SELECT COUNT(*)
         FROM course_schedule
-        WHERE class_group_id_ = #{classGroupId}
+        WHERE class_group_id_ = #{classGroupId} AND del_flag_ = '0'
           AND CONCAT(class_date_, ' ', end_class_time_) &lt;= #{startClassTime} AND pre_course_flag_ = 0
     </select>
     <select id="getCourseSchedules" resultMap="courseScheduleDto">
@@ -1349,7 +1330,7 @@
     <select id="findVipGroupNotStartCourseScheduleIds" resultType="long">
         SELECT cs.id_
         FROM course_schedule cs
-        WHERE cs.music_group_id_ = #{groupId}
+        WHERE cs.music_group_id_ = #{groupId} AND cs.del_flag_ = '0'
           AND cs.group_type_ = #{groupType}
           AND CONCAT(cs.class_date_, ' ', cs.start_class_time_) &gt; NOW()
     </select>
@@ -1371,7 +1352,7 @@
         teach_mode_
         FROM
         course_schedule
-        where tenant_id_ = #{tenantId}
+        where tenant_id_ = #{tenantId} AND del_flag_ = '0'
         <if test="classGroupId!=null">
             AND class_group_id_ = #{classGroupId}
         </if>
@@ -1394,14 +1375,14 @@
         select *
         from course_schedule
         where CONCAT(class_date_, ' ', end_class_time_) &lt;= now()
-          and status_ != 'OVER'
+          and status_ != 'OVER' AND del_flag_ = '0'
     </select>
 
     <select id="queryUnderwayWithNoUpdateStatus" resultMap="CourseSchedule">
         select *
         from course_schedule
         where CONCAT(class_date_, ' ', start_class_time_) &lt;= now()
-          and status_ = 'NOT_START'
+          and status_ = 'NOT_START' AND del_flag_ = '0'
     </select>
 
     <update id="batchUpdate" parameterType="java.util.List">
@@ -1539,7 +1520,7 @@
         SELECT cs.*
         FROM course_schedule cs
                  left join teacher_attendance ta on ta.course_schedule_id_ = cs.id_
-        WHERE ta.sign_in_time_ is null
+        WHERE ta.sign_in_time_ is null AND cs.del_flag_ = '0'
           and SUBTIME(start_class_time_, CONCAT(#{minutes}, '00')) &lt; CURRENT_TIME()
     </select>
 
@@ -1650,7 +1631,7 @@
     <sql id="teacherGroupCourseQueryCondition">
         <where>
             cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1
-            AND cs.music_group_id_ = #{groupId}
+            AND cs.music_group_id_ = #{groupId} AND cs.del_flag_ = '0'
             AND cs.group_type_ = #{groupType}
         </where>
     </sql>
@@ -1804,7 +1785,7 @@
         SELECT *
         FROM course_schedule
         WHERE class_group_id_ = #{classGroupId}
-          AND class_date_ >= #{startDate}
+          AND class_date_ >= #{startDate} AND del_flag_ = '0'
         ORDER BY class_date_ ASC
         LIMIT #{times}
     </select>
@@ -2000,7 +1981,7 @@
         select cssp.user_id_ key_, count(1) value_
         from course_schedule cs
                  right join course_schedule_student_payment cssp on cs.id_ = cssp.course_schedule_id_
-        where class_date_ = date(DATE_ADD(now(), INTERVAL 1 DAY)) AND cs.pre_course_flag_ != 1
+        where class_date_ = date(DATE_ADD(now(), INTERVAL 1 DAY)) AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         group by cssp.user_id_
     </select>
 
@@ -2009,7 +1990,7 @@
         from course_schedule cs
                  right join course_schedule_student_payment cssp on cs.id_ = cssp.course_schedule_id_
         where CONCAT(cs.class_date_, ' ', cs.start_class_time_) &lt; DATE_ADD(now(), INTERVAL 90 MINUTE)
-          and cs.status_ = 'NOT_START' AND cs.pre_course_flag_ != 1
+          and cs.status_ = 'NOT_START' AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
     </select>
 
     <select id="queryTeacherCoursesTimesOfTomorrow" resultMap="Mapper">
@@ -2017,7 +1998,7 @@
         from course_schedule cs
                  right join course_schedule_teacher_salary cssp on cs.id_ = cssp.course_schedule_id_
                  left join sys_user u on u.id_ = cssp.user_id_
-        where cs.merge_flag_ IN (0,1) AND class_date_ = date(DATE_ADD(now(), INTERVAL 1 DAY)) AND cs.pre_course_flag_ != 1
+        where cs.merge_flag_ IN (0,1) AND cs.class_date_ = date(DATE_ADD(now(), INTERVAL 1 DAY)) AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         group by cssp.user_id_
     </select>
 
@@ -2109,7 +2090,7 @@
                cs.schoole_id_
         from course_schedule cs
                  LEFT JOIN course_schedule_teacher_salary csts ON cs.id_ = csts.course_schedule_id_
-        where cs.class_group_id_ = #{classGroupId}
+        where cs.class_group_id_ = #{classGroupId} AND cs.del_flag_ = '0'
     </select>
     <select id="findByClassGroupAndStatus" resultMap="CourseSchedule">
         select cs.id_,
@@ -2137,7 +2118,7 @@
         from course_schedule cs
                  LEFT JOIN course_schedule_teacher_salary csts ON cs.id_ = csts.course_schedule_id_
         where cs.class_group_id_ = #{classGroupId} AND cs.pre_course_flag_ != 1
-          AND cs.status_ = #{status}
+          AND cs.status_ = #{status} AND cs.del_flag_ = '0'
     </select>
     <select id="findByClassGroups" resultMap="CourseSchedule">
         select
@@ -2168,7 +2149,7 @@
         <foreach collection="classGroupIds" item="classGroupId" open="(" close=")" separator=",">
             #{classGroupId}
         </foreach>
-        AND cs.pre_course_flag_ != 1
+        AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         ORDER BY start_class_time_
     </select>
     <select id="findStudentMap" resultType="java.util.Map">
@@ -2181,7 +2162,7 @@
     <select id="findOneCourseScheduleByClassGroupId" resultMap="CourseSchedule">
         SELECT *
         FROM course_schedule
-        WHERE class_group_id_ = #{classGroupId}  AND pre_course_flag_ = 0
+        WHERE class_group_id_ = #{classGroupId}  AND pre_course_flag_ = 0 AND del_flag_ = '0'
         LIMIT 1
     </select>
     <select id="countClassGroupCourseTimes" resultType="map">
@@ -2206,21 +2187,21 @@
         SELECT COUNT(1)
         FROM course_schedule
         WHERE class_group_id_ = #{classGroupId}
-          AND (del_flag_ != 1 OR del_flag_ IS NULL) AND pre_course_flag_ = 0
+        AND del_flag_ = '0' AND pre_course_flag_ = 0
     </select>
     <select id="findMusicGroupCourseSchedules" resultMap="CourseSchedule">
         SELECT cs.*
         FROM course_schedule cs
                  LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
         WHERE cg.music_group_id_ = #{musicGroupId}
-          AND cs.group_type_ = #{groupType}
+          AND cs.group_type_ = #{groupType} AND cs.del_flag_ = '0'
           AND status_ = #{status} AND cs.pre_course_flag_ != 1
     </select>
     <select id="findMusicGroupAllCourseSchedules" resultMap="CourseSchedule">
         SELECT cs.*
         FROM course_schedule cs
                  LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
-        WHERE cg.music_group_id_ = #{musicGroupId}
+        WHERE cg.music_group_id_ = #{musicGroupId} AND cs.del_flag_ = '0'
           AND cs.group_type_ = #{groupType} AND cs.pre_course_flag_ != 1
     </select>
     <select id="findMusicGroupCourseSchedulesWithStudent" resultMap="CourseSchedule">
@@ -2259,28 +2240,21 @@
     </delete>
 
     <select id="getClassGroupNotStartCourse" resultMap="CourseSchedule">
-        SELECT * FROM course_schedule WHERE class_group_id_=#{classGroupId} AND CONCAT(class_date_,' ', start_class_time_) &gt; NOW()
+        SELECT * FROM course_schedule WHERE class_group_id_=#{classGroupId} AND CONCAT(class_date_,' ', start_class_time_) &gt; NOW() AND del_flag_ = '0'
     </select>
 
     <select id="getClassGroupCourses" resultMap="CourseSchedule">
-        SELECT * FROM course_schedule WHERE class_group_id_=#{classGroupId}
+        SELECT * FROM course_schedule WHERE class_group_id_=#{classGroupId} AND del_flag_ = '0'
     </select>
 
-    <delete id="deleteCourseSchedulesByClassGroupIds">
-        DELETE FROM course_schedule WHERE id_ IN
-        <foreach collection="courseScheduleIds" item="courseScheduleId" open="(" close=")" separator=",">
-            #{courseScheduleId}
-        </foreach>
-    </delete>
-    <delete id="deleteByGroup">
-        DELETE
-        FROM course_schedule
+    <update id="deleteByGroup">
+        update course_schedule SET del_flag_ = '1',del_time_ = NOW()
         WHERE music_group_id_ = #{groupId}
           AND group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-    </delete>
-    <delete id="deletePreCourse">
-        DELETE FROM course_schedule WHERE music_group_id_ = #{musicGroupId} AND group_type_ = 'MUSIC' AND pre_course_flag_ = 1
-    </delete>
+    </update>
+    <update id="deletePreCourse">
+        update course_schedule SET del_flag_ = '1',del_time_ = NOW() WHERE music_group_id_ = #{musicGroupId} AND group_type_ = 'MUSIC' AND pre_course_flag_ = 1
+    </update>
 
     <select id="countCurrentTimes" resultType="int">
         SELECT COUNT(*)
@@ -2329,7 +2303,7 @@
         SELECT count(cs.id_)
         FROM course_schedule cs
         WHERE cs.music_group_id_ = #{vipGroupId}
-          AND cs.group_type_ = #{groupType}
+          AND cs.group_type_ = #{groupType} AND cs.del_flag_ = '0'
     </select>
     <select id="findCourseNoStartNum" resultType="java.lang.Integer">
         SELECT COUNT(cs.id_)
@@ -2337,7 +2311,7 @@
         WHERE cs.music_group_id_ = #{vipGroupId}
           AND cs.group_type_ = 'VIP'
           AND cs.status_ = 'NOT_START'
-          AND cs.del_flag_ != '1'
+          AND cs.del_flag_ = '0'
     </select>
     <select id="findCourseEndNum" resultType="java.lang.Integer">
         SELECT COUNT(cs.id_)
@@ -2349,7 +2323,7 @@
     </select>
     <select id="countCourseNum" resultType="java.lang.Integer">
         SELECT COUNT(cs.id_) FROM course_schedule cs
-        WHERE cs.music_group_id_ = #{vipGroupId} AND cs.group_type_ = 'VIP' AND cs.del_flag_ != '1'
+        WHERE cs.music_group_id_ = #{vipGroupId} AND cs.group_type_ = 'VIP' AND cs.del_flag_ = '0'
         <if test="teachMode != null">
             AND cs.teach_mode_ = #{teachMode}
         </if>
@@ -2544,13 +2518,13 @@
     <select id="getMinCourseTime" resultType="java.util.Date">
         SELECT MIN(CONCAT(class_date_, ' ', start_class_time_))
         FROM course_schedule
-        WHERE group_type_ = #{groupType}
+        WHERE group_type_ = #{groupType} AND del_flag_ = '0'
           AND music_group_id_ = #{groupId} AND pre_course_flag_ = 0
     </select>
     <select id="getMaxCourseTime" resultType="java.util.Date">
         SELECT MAX(CONCAT(class_date_, ' ', end_class_time_))
         FROM course_schedule
-        WHERE group_type_ = #{groupType}
+        WHERE group_type_ = #{groupType} AND del_flag_ = '0'
           AND music_group_id_ = #{groupId} AND pre_course_flag_ = 0
     </select>
     <select id="findSurplusCourseWithGroup" resultMap="CourseSchedule">
@@ -2572,7 +2546,7 @@
     <select id="countClassGroupOverCourseNum" resultType="int">
         SELECT COUNT(*)
         FROM course_schedule
-        WHERE class_group_id_ = #{classGroupId}
+        WHERE class_group_id_ = #{classGroupId} AND del_flag_ = '0'
           AND CONCAT(class_date_, ' ', end_class_time_) &lt; NOW() AND pre_course_flag_ = 0
     </select>
 
@@ -2687,7 +2661,7 @@
         SELECT MIN(CONCAT(class_date_, ' ', start_class_time_))
         FROM course_schedule
         WHERE group_type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-          AND music_group_id_ = #{groupId}
+          AND music_group_id_ = #{groupId} AND del_flag_ = '0'
     </select>
 
     <select id="findGroupCourseEndTime" resultType="java.util.Date">
@@ -2700,7 +2674,7 @@
         SELECT COUNT(*)
         FROM course_schedule
         WHERE group_type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-          AND music_group_id_ = #{groupId}
+          AND music_group_id_ = #{groupId} AND del_flag_ = '0'
     </select>
     <sql id="queryVipCourseScheduleIds">
         <if test="mergeCourseType != null and mergeCourseType != ''">
@@ -2886,7 +2860,7 @@
         WHERE cs.group_type_ = 'PRACTICE'
           AND cssp.user_id_ = #{userId}
           AND cssp.expect_price_ = 0
-          AND pg.type_ = 'FREE'
+          AND pg.type_ = 'FREE' AND cs.del_flag_ = '0'
     </select>
     <select id="findTeacherCoursesWithIncludeDateRange" resultMap="CourseSchedule" useCache="false" flushCache="true">
         SELECT cs.id_,
@@ -2960,7 +2934,7 @@
         LEFT JOIN student_attendance sa ON cs.id_ = sa.course_schedule_id_
         WHERE TIMESTAMPDIFF(MINUTE, #{endDateTime}, CONCAT(cs.class_date_, ' ', cs.start_class_time_)) >= 0
           AND TIMESTAMPDIFF(MINUTE, #{endDateTime}, CONCAT(cs.class_date_, ' ', cs.start_class_time_)) &lt;= #{continueCourseTime}
-          AND cs.teacher_id_ = #{courseSchedule.teacherId}
+          AND cs.teacher_id_ = #{courseSchedule.teacherId} AND cs.del_flag_ = '0'
           AND cs.class_group_id_ = #{courseSchedule.classGroupId}
           AND (NOW() > CONCAT(cs.class_date_,' ', cs.start_class_time_) OR sa.sign_in_time_ IS NOT NULL) AND cs.pre_course_flag_ != 1
         LIMIT 1
@@ -2971,7 +2945,7 @@
         LEFT JOIN teacher_attendance ta ON cs.id_ = ta.course_schedule_id_
         WHERE TIMESTAMPDIFF(MINUTE, #{endDateTime}, CONCAT(cs.class_date_, ' ', cs.start_class_time_)) >= 0
           AND TIMESTAMPDIFF(MINUTE, #{endDateTime}, CONCAT(cs.class_date_, ' ', cs.start_class_time_)) &lt;= #{continueCourseTime}
-          AND cs.teacher_id_ = #{courseSchedule.teacherId}
+          AND cs.teacher_id_ = #{courseSchedule.teacherId} AND cs.del_flag_ = '0'
           AND cs.class_group_id_ = #{courseSchedule.classGroupId}
           AND (NOW() > CONCAT(cs.class_date_,' ', cs.start_class_time_) OR ta.sign_in_time_ IS NOT NULL) AND cs.pre_course_flag_ != 1
         LIMIT 1
@@ -2988,7 +2962,7 @@
         COUNT(cs.Id_) AS 'value'
         FROM
         course_schedule cs
-        WHERE cs.status_='OVER'
+        WHERE cs.status_='OVER' AND cs.del_flag_ = '0'
         AND DATE_FORMAT(cs.class_date_,'%Y-%m')=DATE_FORMAT(NOW(),'%Y-%m')
         AND cs.group_type_ = #{groupType}
         AND cs.music_group_id_ IN
@@ -3003,7 +2977,7 @@
         FROM
             course_schedule cs
         WHERE CONCAT(cs.class_date_, ' ', cs.start_class_time_) &lt; NOW()
-            AND cs.group_type_ = #{groupType}
+            AND cs.group_type_ = #{groupType} AND cs.del_flag_ = '0'
             AND cs.music_group_id_ = #{groupId} AND cs.pre_course_flag_ != 1
     </select>
     <select id="findUserCourses" resultMap="CourseSchedule">
@@ -3200,7 +3174,7 @@
                cs.leave_student_num_,
                cs.schoole_id_
         FROM course_schedule cs
-        WHERE cs.group_type_ = #{groupType}
+        WHERE cs.group_type_ = #{groupType} AND cs.del_flag_ = '0'
           AND cs.music_group_id_ = #{groupId}
         ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_) DESC
         LIMIT 1
@@ -3216,6 +3190,7 @@
         <foreach collection="classGroupIds" item="classGroupId" open="(" close=")" separator=",">
             #{classGroupId}
         </foreach>
+        AND del_flag_ = '0'
         GROUP BY class_group_id_
         )
     </select>
@@ -3241,7 +3216,7 @@
                schoole_id_
         FROM course_schedule
         WHERE group_type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-          AND music_group_id_ = #{groupId}
+          AND music_group_id_ = #{groupId} AND del_flag_ = '0'
           AND CONCAT(class_date_, ' ', start_class_time_) &gt; NOW()
     </select>
 
@@ -3267,7 +3242,7 @@
                schoole_id_
         FROM course_schedule
         WHERE group_type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-          AND music_group_id_ = #{groupId}
+          AND music_group_id_ = #{groupId} AND del_flag_ = '0'
           AND CONCAT(class_date_, ' ', start_class_time_) &gt; NOW()
     </select>
     <select id="getSubjectNameById" resultType="java.lang.String">
@@ -3297,7 +3272,7 @@
         cs.status_
         FROM course_schedule cs
         LEFT JOIN course_schedule_evaluate cse ON cs.id_ = cse.course_schedule_id_
-        WHERE cs.group_type_ = #{groupType} AND cs.pre_course_flag_ != 10 and cs.tenant_id_ = #{tenantId}
+        WHERE cs.group_type_ = #{groupType} AND cs.pre_course_flag_ != 10 and cs.tenant_id_ = #{tenantId} AND cs.del_flag_ = '0'
         <if test="groupId != null">
             AND cs.music_group_id_ = #{groupId}
         </if>
@@ -3310,7 +3285,7 @@
     <select id="getLastEndCourse" resultMap="CourseSchedule">
         SELECT cs.id_
         FROM course_schedule cs
-        WHERE cs.music_group_id_ = #{groupId}
+        WHERE cs.music_group_id_ = #{groupId} AND cs.del_flag_ = '0'
           AND cs.group_type_ = #{groupType}
           AND NOW() > CONCAT(cs.class_date_, ' ', cs.end_class_time_) AND cs.pre_course_flag_ != 1
         ORDER BY cs.class_date_, cs.end_class_time_ ASC
@@ -3341,7 +3316,7 @@
         LEFT JOIN course_schedule cs ON cs.class_group_id_ = cg.id_ AND CONCAT( cs.class_date_, ' ',
         cs.start_class_time_ ) > NOW( )
         WHERE
-        cg.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+        cg.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} AND cs.del_flag_ = '0'
         AND cg.music_group_id_ IN
         <foreach collection="groupIds" item="groupId" separator="," open="(" close=")">
             #{groupId}
@@ -3358,7 +3333,7 @@
         FROM
         course_schedule cs
         WHERE
-        cs.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+        cs.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} AND cs.del_flag_ = '0'
         AND cs.music_group_id_ IN
         <foreach collection="groupIds" item="groupId" separator="," open="(" close=")">
             #{groupId}
@@ -3390,7 +3365,7 @@
         FROM teacher_attendance ta
                  LEFT JOIN course_schedule cs ON ta.course_schedule_id_ = cs.id_
                  LEFT JOIN student_attendance sa ON ta.course_schedule_id_ = sa.course_schedule_id_
-        WHERE ta.sign_out_status_ = 1
+        WHERE ta.sign_out_status_ = 1 AND cs.del_flag_ = '0'
           AND ta.sign_in_time_ IS NOT NULL
           AND MONTH(ta.sign_in_time_) = #{month}
           AND cs.teach_mode_ = 'ONLINE'
@@ -3506,7 +3481,7 @@
         WHERE cs.class_group_id_ = #{classGroupId}
         AND TIMESTAMPDIFF(MINUTE, CONCAT(cs.class_date_," ",cs.end_class_time_),#{startTime}) &lt;= #{continueCourseTime}
         AND TIMESTAMPDIFF(MINUTE, CONCAT(cs.class_date_," ",cs.end_class_time_),#{startTime}) >= 0
-        AND cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1
+        AND cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         ORDER BY cs.class_date_ DESC,cs.end_class_time_ DESC
         LIMIT 1
     </select>
@@ -3515,14 +3490,15 @@
         WHERE cs.class_group_id_ = #{classGroupId}
         AND TIMESTAMPDIFF(MINUTE, #{endTime},CONCAT(cs.class_date_," ",cs.start_class_time_)) &lt;= #{continueCourseTime}
         AND TIMESTAMPDIFF(MINUTE, #{endTime},CONCAT(cs.class_date_," ",cs.start_class_time_)) >= 0
-        AND cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1
+        AND cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         ORDER BY cs.class_date_ DESC,cs.start_class_time_ DESC
         LIMIT 1
     </select>
     <select id="findLastOverTime" resultType="java.util.Map">
         SELECT cs.music_group_id_ 'key',MAX(CONCAT(cs.class_date_,' ',cs.start_class_time_)) 'value'
         FROM course_schedule cs
-        WHERE cs.status_ = 'OVER' AND cs.group_type_ = 'VIP' AND cs.music_group_id_ IN
+        WHERE cs.status_ = 'OVER' AND cs.group_type_ = 'VIP' AND cs.del_flag_ = '0'
+        AND cs.music_group_id_ IN
         <foreach collection="vipGroupIds" open="(" close=")" separator="," item="item">
             #{item}
         </foreach>
@@ -3533,7 +3509,7 @@
         <foreach collection="courseScheduleIds" open="(" close=")" separator="," item="item">
             #{item}
         </foreach>
-        AND cs.status_ = 'NOT_START'
+        AND cs.status_ = 'NOT_START' AND cs.del_flag_ = '0'
     </select>
     <select id="getLastTime" resultType="java.util.Date">
         SELECT MAX(CONCAT(cs.class_date_," ",cs.end_class_time_))
@@ -3558,7 +3534,7 @@
             #{studentId}
         </foreach>
         AND cssp.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-        AND cs.class_date_ BETWEEN #{startTime} AND #{endTime}
+        AND cs.class_date_ BETWEEN #{startTime} AND #{endTime} AND cs.del_flag_ = '0'
         GROUP BY
         cssp.user_id_
     </select>
@@ -3576,7 +3552,7 @@
             #{studentId}
         </foreach>
         AND cssp.group_type_ = 'PRACTICE'
-        AND pg.type_='CHARGE'
+        AND pg.type_='CHARGE' AND cs.del_flag_ = '0'
         AND cs.class_date_ BETWEEN #{startTime} AND #{endTime}
         GROUP BY
         cssp.user_id_
@@ -3594,7 +3570,7 @@
         <foreach collection="studentIds" item="studentId" separator="," open="(" close=")">
             #{studentId}
         </foreach>
-        AND cssp.group_type_ = 'VIP'
+        AND cssp.group_type_ = 'VIP' AND cs.del_flag_ = '0'
         AND CONCAT(cs.class_date_," ",cs.start_class_time_) &gt; NOW()
         GROUP BY
         cssp.user_id_
@@ -3662,7 +3638,7 @@
                 cs.schoole_id_,
                 cs.organ_id_
         FROM course_schedule cs LEFT JOIN course_schedule_teacher_salary csts ON csts.course_schedule_id_=cs.id_
-        WHERE csts.user_id_=#{teacherId}
+        WHERE csts.user_id_=#{teacherId} AND cs.del_flag_ = '0'
         AND cs.class_date_ = DATE_FORMAT(#{startClassTime},'%Y-%m-%d')
         AND cs.start_class_time_ &lt; DATE_FORMAT(#{startClassTime},'%H:%i:%S')
         ORDER BY start_class_time_ DESC LIMIT 1;
@@ -3694,7 +3670,7 @@
         FROM course_schedule cs
             LEFT JOIN course_schedule_teacher_salary csts ON csts.course_schedule_id_=cs.id_
             LEFT JOIN teacher_attendance ta ON cs.id_=ta.course_schedule_id_ AND ta.teacher_id_=#{teacherId}
-        WHERE csts.user_id_=#{teacherId}
+        WHERE csts.user_id_=#{teacherId} AND cs.del_flag_ = '0'
         AND cs.class_date_ = DATE_FORMAT(#{startClassTime},'%Y-%m-%d')
         AND cs.start_class_time_ &lt; DATE_FORMAT(#{startClassTime},'%H:%i:%S') AND cs.pre_course_flag_ != 1
         AND ta.sign_in_status_ IS NOT NULL
@@ -3706,12 +3682,13 @@
 		(SELECT cs.type_ course_type_,SUM(TIMESTAMPDIFF(MINUTE,STR_TO_DATE(concat(cs.class_date_,' ',cs.start_class_time_),'%Y-%m-%d %H:%i:%s'),
         STR_TO_DATE(concat(cs.class_date_,' ',cs.end_class_time_),'%Y-%m-%d %H:%i:%s'))) remain_minutes_,COUNT(cs.id_) temp_merged_course_num_
 		FROM course_schedule cs WHERE FIND_IN_SET(cs.class_group_id_,#{classGroupIdList}) AND cs.status_ = 'NOT_START'
-		AND cs.merge_flag_ = 0 AND cs.member_flag_ = #{memberFlag} AND cs.pre_course_flag_ != 1 GROUP BY cs.type_
+		AND cs.merge_flag_ = 0 AND cs.del_flag_ = '0' AND cs.member_flag_ = #{memberFlag} AND cs.pre_course_flag_ != 1 GROUP BY cs.type_
 		UNION ALL
 		SELECT ncs.type_ course_type_,SUM(TIMESTAMPDIFF(MINUTE,STR_TO_DATE(concat(ncs.class_date_,' ',ncs.start_class_time_),'%Y-%m-%d %H:%i:%s'),
         STR_TO_DATE(concat(ncs.class_date_,' ',ncs.end_class_time_),'%Y-%m-%d %H:%i:%s'))) remain_minutes_,COUNT(cs.id_) temp_merged_course_num_
 		FROM course_schedule cs LEFT JOIN course_schedule ncs ON ncs.id_ = cs.new_course_id_
-		WHERE FIND_IN_SET(cs.class_group_id_,#{classGroupIdList}) AND cs.new_course_id_ &gt; 0 AND ncs.status_ = 'NOT_START' AND cs.pre_course_flag_ != 1 AND cs.member_flag_ = #{memberFlag} GROUP BY ncs.type_) a
+		WHERE FIND_IN_SET(cs.class_group_id_,#{classGroupIdList}) AND cs.new_course_id_ &gt; 0 AND cs.del_flag_ = '0'
+		AND ncs.status_ = 'NOT_START' AND cs.pre_course_flag_ != 1 AND cs.member_flag_ = #{memberFlag} GROUP BY ncs.type_) a
 		group BY a.course_type_
     </select>
 
@@ -3745,25 +3722,26 @@
     </select>
 
     <select id="countCourseMergeTime" resultType="int">
-        SELECT COUNT(id_) FROM course_schedule WHERE new_course_id_=#{courseId}
+        SELECT COUNT(id_) FROM course_schedule WHERE new_course_id_=#{courseId} AND del_flag_ = '0'
     </select>
 
     <select id="findByMainMergeCourse" resultMap="CourseSchedule">
         SELECT
         <include refid="resultSql"/>
-        FROM course_schedule cs WHERE new_course_id_=#{mainMergeCourseId}
+        FROM course_schedule cs WHERE new_course_id_=#{mainMergeCourseId} AND cs.del_flag_ = '0'
     </select>
 
     <select id="querySubCourseNumMap" resultType="java.util.Map">
         SELECT cs.type_ 'key',COUNT(CASE WHEN (CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW()) THEN 1 ELSE NULL END) 'value'
         FROM course_schedule cs
-        WHERE cs.class_group_id_ = #{classGroupId} AND cs.pre_course_flag_ != 1
+        WHERE cs.class_group_id_ = #{classGroupId} AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         GROUP BY cs.type_
     </select>
     <select id="querySubCourseTimeMap" resultType="java.util.Map">
         SELECT cs.type_ 'key',SUM(ROUND((UNIX_TIMESTAMP(CONCAT(cs.class_date_,' ',cs.end_class_time_)) - UNIX_TIMESTAMP(CONCAT(cs.class_date_,' ',cs.start_class_time_)))/60)) 'value'
         FROM course_schedule cs
         WHERE cs.class_group_id_ = #{classGroupId} AND CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW() AND cs.pre_course_flag_ != 1
+         AND cs.del_flag_ = '0'
         GROUP BY cs.type_
     </select>
     <select id="findClassMaxCourseNumMap" resultType="java.util.Map">
@@ -3772,7 +3750,7 @@
         <foreach collection="classGroupIds" open="(" close=")" separator="," item="item">
             #{item}
         </foreach>
-        AND CONCAT(cs.class_date_," ",cs.start_class_time_) > NOW() AND cs.pre_course_flag_ != 1
+        AND CONCAT(cs.class_date_," ",cs.start_class_time_) > NOW() AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         GROUP BY cs.class_group_id_,cs.type_)c
         GROUP BY c.type_
     </select>
@@ -3789,7 +3767,7 @@
                 #{item}
             </foreach>
         </if>
-        AND CONCAT(cs.class_date_," ",cs.start_class_time_) > NOW() AND cs.pre_course_flag_ != 1
+        AND CONCAT(cs.class_date_," ",cs.start_class_time_) > NOW() AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         GROUP BY cssp.course_schedule_id_
     </select>
     <select id="findNoStudentCourseIds" resultType="Long">
@@ -3799,6 +3777,7 @@
         <foreach collection="courseIds" open="(" close=")" separator="," item="item">
             #{item}
         </foreach>
+        AND cs.del_flag_ = '0'
         GROUP BY cssp.course_schedule_id_,cs.id_  HAVING COUNT(cssp.id_) = 0
     </select>
     <select id="findNoStartMasterCourseNum" resultType="int">
@@ -3808,7 +3787,7 @@
             #{item}
         </foreach>
         AND merge_flag_ IN (1,2) AND pre_course_flag_ = 0
-        AND status_ = 'NOT_START'
+        AND status_ = 'NOT_START' AND del_flag_ = '0'
     </select>
     <select id="getLock" resultMap="CourseSchedule">
         SELECT * FROM course_schedule WHERE id_ = #{courseId}
@@ -3825,7 +3804,7 @@
             <foreach collection="courseIds" item="courseId" open="(" close=")" separator=",">
                 #{courseId}
             </foreach>
-        AND pre_course_flag_ = 0
+        AND pre_course_flag_ = 0 AND del_flag_ = '0'
         GROUP BY
             new_course_id_
     </select>
@@ -3848,7 +3827,7 @@
             LEFT JOIN practice_group vg ON vg.id_ = cs.music_group_id_
         </if>
         WHERE cssp.user_id_ = #{studentId} AND CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW()
-        AND vg.educational_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1
+        AND vg.educational_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         <include refid="global.limit"/>
     </select>
     <select id="countStudentNoStartCourse" resultType="int">
@@ -3861,10 +3840,10 @@
             LEFT JOIN practice_group vg ON vg.id_ = cs.music_group_id_
         </if>
         WHERE cssp.user_id_ = #{studentId} AND CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW()
-        AND vg.educational_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1
+        AND vg.educational_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
     </select>
     <select id="findCoursesByClassGroupIdAndCourseIds" resultMap="CourseSchedule">
-        SELECT * FROM course_schedule WHERE class_group_id_ = #{classGroupId}
+        SELECT * FROM course_schedule WHERE class_group_id_ = #{classGroupId} AND del_flag_ = '0'
         AND id_ IN
         <foreach collection="allLockCourseIds" item="courseId" open="(" close=")" separator=",">
             #{courseId}
@@ -3874,10 +3853,11 @@
     <select id="queryTotalCourseTimes" resultType="java.lang.Integer">
         SELECT SUM(ROUND((UNIX_TIMESTAMP(CONCAT(cs.class_date_,' ',cs.end_class_time_)) - UNIX_TIMESTAMP(CONCAT(cs.class_date_,' ',cs.start_class_time_)))/60))
         FROM course_schedule cs
-        WHERE cs.class_group_id_ = #{classGroupId} AND CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW()
+        WHERE cs.class_group_id_ = #{classGroupId} AND CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW() AND cs.del_flag_ = '0'
     </select>
     <select id="getUnderwayCourseNum" resultType="int">
-        SELECT COUNT(*) FROM course_schedule WHERE music_group_id_ = #{musicGroupId} AND group_type_ = #{groupType} AND status_=#{status} AND pre_course_flag_ = 0
+        SELECT COUNT(*) FROM course_schedule WHERE music_group_id_ = #{musicGroupId}
+        AND group_type_ = #{groupType} AND status_=#{status} AND pre_course_flag_ = 0 AND del_flag_ = '0'
     </select>
 
     <select id="getMusicGroupCourseInfo" resultMap="CourseSchedule"><![CDATA[
@@ -3889,7 +3869,7 @@
             AND cs.start_class_time_ >= DATE_FORMAT(#{startTime},'%H:%i:%S')
             AND cs.end_class_time_ <= DATE_FORMAT(#{endTime},'%H:%i:%S')
             AND cs.group_type_ = 'MUSIC'
-            AND cs.teach_mode_ = 'OFFLINE' AND cs.pre_course_flag_ != 1
+            AND cs.teach_mode_ = 'OFFLINE' AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         ORDER BY cs.id_ ASC
     ]]></select>
     <select id="findHasCourseStudent" resultType="java.lang.Integer">
@@ -3900,7 +3880,7 @@
             #{item}
         </foreach>
         AND CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW()
-        AND FIND_IN_SET(cs.group_type_,#{groupType})
+        AND FIND_IN_SET(cs.group_type_,#{groupType}) AND cs.del_flag_ = '0'
         GROUP BY cssp.user_id_
     </select>
 
@@ -3928,7 +3908,7 @@
     <select id="getMusicGroupHasStartCourseNum" resultType="integer">
         SELECT COUNT(*) FROM course_schedule
         WHERE music_group_id_ = #{musicGroupId}
-        AND group_type_='MUSIC'
+        AND group_type_='MUSIC' AND del_flag_ = '0'
         AND status_ IN ('UNDERWAY','OVER') AND pre_course_flag_ = 0
     </select>
 
@@ -3938,7 +3918,8 @@
         <foreach collection="ids" item="id" open="(" close=")" separator=",">
             #{id}
         </foreach>
-        AND group_type_='MUSIC' AND DATE_FORMAT(NOW(),'%Y-%m-%d') >= class_date_ AND member_flag_ = 1 AND pre_course_flag_ = 0
+        AND group_type_='MUSIC' AND DATE_FORMAT(NOW(),'%Y-%m-%d') >= class_date_
+        AND member_flag_ = 1 AND pre_course_flag_ = 0 AND del_flag_ = '0'
         GROUP BY music_group_id_
     </select>
 
@@ -4017,7 +3998,7 @@
         FROM
         course_schedule cs
         WHERE
-            cs.merge_flag_ = 2
+            cs.merge_flag_ = 2 AND cs.del_flag_ = '0'
             AND cs.new_course_id_ IN
             <foreach collection="courseIds" item="courseId" open="(" close=")" separator=",">
                 #{courseId}
@@ -4025,7 +4006,7 @@
     </select>
     <select id="queryPreCourseListByClassGroupId" resultMap="CourseSchedule">
         SELECT <include refid="resultSql"/> FROM course_schedule cs WHERE class_group_id_ = #{classGroupId}
-        AND is_lock_ = 1 AND pre_course_flag_ = 1
+        AND is_lock_ = 1 AND pre_course_flag_ = 1 AND cs.del_flag_ = '0'
     </select>
 
     <select id="queryPreCourseListByClassGroupIds" resultType="int">
@@ -4034,11 +4015,12 @@
         <foreach collection="classGroupIds" open="(" item="classGroupId" separator="," close=")">
             #{classGroupId}
         </foreach>
-        AND is_lock_ = 1 AND pre_course_flag_ = 1
+        AND is_lock_ = 1 AND pre_course_flag_ = 1 AND cs.del_flag_ = '0'
     </select>
 
     <select id="queryPreCourseListByMusicGroupId" resultMap="CourseSchedule">
-        SELECT * FROM course_schedule WHERE music_group_id_ = #{musicGroupId} AND group_type_ = 'MUSIC' AND is_lock_ = 1 AND pre_course_flag_ = 1
+        SELECT * FROM course_schedule WHERE music_group_id_ = #{musicGroupId}
+        AND group_type_ = 'MUSIC' AND is_lock_ = 1 AND pre_course_flag_ = 1 AND del_flag_ = '0'
     </select>
     <select id="sumCourseMinutes" resultType="int">
         SELECT SUM(c.course_mintues_) FROM (SELECT FLOOR((UNIX_TIMESTAMP(CONCAT(class_date_, ' ', end_class_time_)) -
@@ -4066,12 +4048,12 @@
         <foreach collection="classGroupSet" open="(" close=")" item="classGroupId" separator=",">
             #{classGroupId}
         </foreach>
-        AND group_type_ = 'MUSIC' AND pre_course_flag_ = 1
+        AND group_type_ = 'MUSIC' AND pre_course_flag_ = 1 AND del_flag_ = '0'
         GROUP BY class_group_id_
     </select>
     <select id="queryOverPreCourseListByMusicGroupId" resultType="int">
         SELECT count(id_) FROM course_schedule WHERE music_group_id_ = #{musicGroupId} AND group_type_ = 'MUSIC' AND is_lock_ = 1 AND pre_course_flag_ = 1
-                                        AND CONCAT(class_date_,' ', start_class_time_) &lt;= NOW()
+                                        AND CONCAT(class_date_,' ', start_class_time_) &lt;= NOW() AND del_flag_ = '0'
     </select>
     <select id="queryClassDateList" resultType="java.lang.String">
         SELECT CONCAT(cs.class_date_,' ',cs.start_class_time_,'~',end_class_time_) start_class_time_ FROM course_schedule cs
@@ -4121,7 +4103,7 @@
         FROM course_schedule cs
         LEFT JOIN teacher_attendance ta ON ta.course_schedule_id_ = cs.id_
         LEFT JOIN class_group cg ON cs.class_group_id_ = cg.id_
-        WHERE ta.teacher_id_ = #{teacherId} AND cs.id_ IN
+        WHERE ta.teacher_id_ = #{teacherId} AND cs.del_flag_ = '0' AND cs.id_ IN
         <foreach collection="courseIds" item="courseId" open="(" close=")" separator=",">
             #{courseId}
         </foreach>
@@ -4147,7 +4129,7 @@
         LEFT JOIN course_schedule_student_payment cssp ON s.user_id_ = cssp.user_id_
         LEFT JOIN course_schedule cs ON cs.id_ = cssp.course_schedule_id_ AND cs.group_type_ = #{groupType} AND cs.del_flag_ = '0' AND cs.pre_course_flag_ != 1
         LEFT JOIN sys_user su ON su.id_ = s.user_id_
-        WHERE 1=1 and s.tenant_id_ = #{tenantId}
+        WHERE s.tenant_id_ = #{tenantId}
         <if test="hasMember != null">
             <if test="hasMember == 1">
                 AND s.member_rank_setting_id_ IS NOT NULL
@@ -4257,7 +4239,7 @@
     </select>
     <sql id="countStudyStandardWaitVisitSql">
         WHERE csts.user_id_ = #{teacherId} AND cs.evaluate_flag_ = 1 AND sa.qualified_flag_ = 0
-        AND sv.id_ IS NULL AND sa.status_ IN ('NORMAL','LATE')
+        AND sv.id_ IS NULL AND sa.status_ IN ('NORMAL','LATE') AND cs.del_flag_ = '0'
         <if test="startDate != null and startDate != ''">
             AND cs.class_date_ >= #{startDate}
         </if>
@@ -4313,6 +4295,7 @@
         left join school co ON co.id_ = cs.schoole_id_
         left join student_attendance sa ON sa.course_schedule_id_ = cs.id_ AND sa.user_id_ = cssp.user_id_
         where cssp.music_group_id_ = #{queryInfo.groupId} AND cssp.user_id_ = #{queryInfo.userId} AND cssp.group_type_ = #{queryInfo.groupType}
+        AND cs.del_flag_ = '0'
         <if test="queryInfo.courseStatus != null and queryInfo.courseStatus != ''">
             <if test=" queryInfo.groupType == 'LIVE'">
                 <if test="queryInfo.courseStatus == 'UNDERWAY'">
@@ -4345,7 +4328,7 @@
     </select>
     
     <select id="queryStartedCourseMusicGroupIdList" resultType="java.lang.String">
-		select distinct cs.music_group_id_ from course_schedule cs where cs.group_type_ = #{groupType} and cs.status_ = 'OVER'
+		select distinct cs.music_group_id_ from course_schedule cs where cs.group_type_ = #{groupType} and cs.status_ = 'OVER' AND cs.del_flag_ = '0'
     </select>
 
     <select id="checkCourseIsSettlementReport" resultType="int">
@@ -4378,6 +4361,7 @@
 
     <sql id="selectPage">
         <where>
+            cs.del_flag_ = '0'
             <if test="param.teacherId != null">
                 and ( cs.actual_teacher_id_ = #{param.teacherId})
             </if>
@@ -4454,7 +4438,8 @@
     </select>
 
     <update id="updateTeachingPointByClassGroupId">
-        update course_schedule set teaching_point_ = #{teachingPoint} where class_group_id_ = #{classGroupId} and status_ = 'NOT_START'
+        update course_schedule set teaching_point_ = #{teachingPoint} where class_group_id_ = #{classGroupId}
+        and status_ = 'NOT_START' AND del_flag_ = '0'
     </update>
 
     <select id="getSummaryOfCurrentSemesterCourses"
@@ -4514,8 +4499,7 @@
         select * from course_schedule
         where teacher_id_ = #{teacherId}
         and CONCAT(class_date_," ",end_class_time_) &gt;= #{startTime}
-        and CONCAT(class_date_," ",start_class_time_) &lt;= #{endTime}
-
+        and CONCAT(class_date_," ",start_class_time_) &lt;= #{endTime} AND del_flag_ = '0'
     </select>
 
     <select id="liveCourseRemind" resultMap="CourseSchedule">
@@ -4523,7 +4507,7 @@
         from course_schedule cs
         where cs.status_ = 'NOT_START'
           and cs.type_ = 'LIVE'
-        and cs.live_remind_ = 0
+        and cs.live_remind_ = 0 AND cs.del_flag_ = '0'
           and cs.class_date_ = date_format(now(),'%Y-%m-%d')
           and CONCAT(class_date_,' ',start_class_time_)  &lt;= date_format(date_add(now(),interval #{minutes} minute),'%Y-%m-%d %H:%i:%s')
           and CONCAT(class_date_,' ',start_class_time_)  &gt;= date_format(now(),'%Y-%m-%d %H:%i:%s')
@@ -4540,7 +4524,7 @@
 
     <select id="getCloseLiveCourseRoom" resultMap="CourseSchedule">
         select * from course_schedule
-        where status_ = 'OVER' and type_ = 'LIVE'  and  continuous_course_ = 0
+        where status_ = 'OVER' and type_ = 'LIVE'  and  continuous_course_ = 0 AND del_flag_ = '0'
         <if test="studentRemindTime != null" >
             and CONCAT(class_date_,' ',end_class_time_) &lt;= date_format(date_add(now(),interval -#{studentRemindTime} minute),'%Y-%m-%d %H:%i:%s')
             and live_remind_ = 1
@@ -4570,12 +4554,12 @@
     <select id="getTeacherContinuousCourse" resultMap="CourseSchedule">
         SELECT <include refid="resultSql"/> FROM course_schedule cs
         WHERE cs.class_group_id_ = #{classGroupId}
-        AND cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1 AND cs.class_date_ = #{classDate}
+        AND cs.actual_teacher_id_ = #{teacherId} AND cs.pre_course_flag_ != 1 AND cs.class_date_ = #{classDate} AND cs.del_flag_ = '0'
         ORDER BY cs.class_date_ DESC,cs.end_class_time_ DESC
     </select>
 
     <select id="findByRoomUid"  resultMap="CourseSchedule">
-        select * from course_schedule where live_room_id_ = #{roomUid} and group_type_ = #{type.name}
+        select * from course_schedule where live_room_id_ = #{roomUid} and group_type_ = #{type.name} AND del_flag_ = '0'
     </select>
     <select id="exportCourseIncome" resultType="com.ym.mec.biz.dal.dto.ExportCourseIncomeDto">
         select o.name_ organName,cs.id_ courseId,SUM(cssp.actual_price_) amount from course_schedule cs
@@ -4590,7 +4574,7 @@
     <select id="getNotStartOnlineNoLive" resultMap="CourseSchedule">
         select * from course_schedule where status_ = 'NOT_START' and teach_mode_ = 'ONLINE' and group_type_ IN ('COMM','DEMO','MUSIC','PRACTICE','VIP')
         and CONCAT(class_date_,' ',start_class_time_) &lt;= date_format(date_add(now(),interval #{beforeTime} minute),'%Y-%m-%d %H:%i:%s')
-
+        AND del_flag_ = '0'
         and live_remind_ = 0
         and tenant_id_ = #{tenantInfoId}
     </select>
@@ -4598,7 +4582,7 @@
     <select id="getEndTimeBetweenYesterdayAndNow" resultMap="CourseSchedule">
         select * from course_schedule where status_ = 'OVER' and teach_mode_ = 'ONLINE' and group_type_ IN ('COMM','DEMO','MUSIC','PRACTICE','VIP')
         and CONCAT(class_date_,' ',end_class_time_) &gt;= date_format(date_add(now(),interval -1 day),'%Y-%m-%d')
-        and CONCAT(class_date_,' ',end_class_time_) &lt;= date_format(now(),'%Y-%m-%d %H:%i:%s')
+        and CONCAT(class_date_,' ',end_class_time_) &lt;= date_format(now(),'%Y-%m-%d %H:%i:%s') AND del_flag_ = '0'
     </select>
     <select id="queryTeacherCanViewClassCourseSchedule" resultType="java.lang.Long">
         select distinct csts.course_schedule_id_ from class_group_teacher_mapper cgtm

+ 1 - 1
mec-biz/src/main/resources/config/mybatis/DemoGroupMapper.xml

@@ -280,7 +280,7 @@
         <include refid="global.limit"/>
     </select>
     <select id="countTeacherDemoGroups" resultType="Integer">
-		SELECT COUNT(DISTINCT cs.class_date_) FROM course_schedule cs WHERE cs.type_ = 'DEMO' AND cs.actual_teacher_id_ = #{teacherId}
+		SELECT COUNT(DISTINCT cs.class_date_) FROM course_schedule cs WHERE cs.type_ = 'DEMO' AND cs.actual_teacher_id_ = #{teacherId} AND cs.del_flag_ = '0'
 	</select>
 
     <select id="findDemoGroupStartClassTimesWithWeekByTeacherId"

+ 6 - 0
mec-biz/src/main/resources/config/mybatis/InstrumentMapper.xml

@@ -36,4 +36,10 @@
         </where>
 	</select>
 
+    <select id="getBySubjectId" resultType="com.ym.mec.biz.dal.entity.Instrument">
+        SELECT
+            <include refid="baseColumns" />
+        FROM instrument t
+        WHERE find_in_set(t.subject_id_, #{subjectId})
+    </select>
 </mapper>

+ 1 - 0
mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml

@@ -748,6 +748,7 @@
                      LEFT JOIN music_group mg ON mg.id_ = cs.music_group_id_
         WHERE cs.actual_teacher_id_ = #{teacherId}
           AND cs.group_type_ = 'MUSIC' AND cs.pre_course_flag_ != 1
+        AND cs.del_flag_ = '0'
         GROUP BY mg.id_
     </select>
     <select id="queryUserMusicInfos" resultMap="queryUserMusicGroupsMap">

+ 7 - 4
mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml

@@ -458,7 +458,7 @@
             #{classGroupId}
         </foreach>
         <![CDATA[AND class_date_ >= #{startDate,jdbcType=DATE} AND class_date_ <=#{endDate,jdbcType=DATE} ]]>
-        AND (del_flag_ =0 OR del_flag_ IS NULL)
+        AND del_flag_ = '0'
         GROUP BY class_group_id_
     </select>
 
@@ -640,6 +640,7 @@
             WHERE
                 cssp.user_id_ = #{studentId}
                 AND cs.actual_teacher_id_ = t.id_
+                AND cs.del_flag_ = '0'
 		        AND pg.type_='TRIAL'
                 AND cssp.group_type_ = 'PRACTICE')
     </select>
@@ -647,7 +648,9 @@
     <select id="findLastPracticeSubject" resultType="int">
         SELECT pg.subject_id_ FROM course_schedule_student_payment cssp LEFT JOIN course_schedule cs ON cs.id_=cssp.course_schedule_id_
         LEFT JOIN practice_group pg ON cssp.music_group_id_=pg.id_
-        WHERE cssp.group_type_='PRACTICE' AND cssp.user_id_=#{studentId} ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_) DESC LIMIT 1
+        WHERE cssp.group_type_='PRACTICE' AND cssp.user_id_=#{studentId}
+        AND cs.del_flag_ = '0'
+        ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_) DESC LIMIT 1
     </select>
 
     <select id="findStudentTrialPractices" resultMap="PracticeGroupDto">
@@ -665,7 +668,7 @@
         WHERE
             pg.student_id_ = #{studentId}
             AND cs.group_type_ = 'PRACTICE'
-            AND pg.type_ = 'TRIAL'
+            AND pg.type_ = 'TRIAL' AND cs.del_flag_ = '0'
         GROUP BY pg.id_
         ORDER BY pg.id_
     </select>
@@ -678,7 +681,7 @@
         WHERE
             pg.student_id_ = #{studentId}
             AND cs.group_type_ = 'PRACTICE'
-            AND pg.type_ = 'TRIAL'
+            AND pg.type_ = 'TRIAL' AND cs.del_flag_ = '0'
     </select>
     <select id="findStudentAndTeacherTrialPractices" resultMap="com.ym.mec.biz.dal.dao.CourseScheduleDao.CourseSchedule">
         SELECT

+ 6 - 4
mec-biz/src/main/resources/config/mybatis/StudentAttendanceMapper.xml

@@ -621,7 +621,7 @@
     </select>
     <sql id="exportStudentAttendancesQueryPageSql">
         <where>
-                cs.pre_course_flag_ != 1 and cs.tenant_id_ = #{tenantId}
+                cs.pre_course_flag_ != 1 and cs.tenant_id_ = #{tenantId} AND cs.del_flag_ = '0'
             <if test="organId != null and organId != ''">
                 AND FIND_IN_SET(cs.organ_id_,#{organId})
             </if>
@@ -674,7 +674,8 @@
     <select id="getLeaveNum" resultType="java.lang.Integer">
         SELECT COUNT(sa.id_) FROM student_attendance sa
         LEFT JOIN course_schedule cs ON cs.id_ = sa.course_schedule_id_
-        WHERE DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month} AND sa.user_id_ = #{userId} AND sa.status_ = 'LEAVE' AND cs.pre_course_flag_ != 1
+        WHERE DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month} AND sa.user_id_ = #{userId}
+        AND sa.status_ = 'LEAVE' AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         <if test="attendanceId != null">
             AND sa.id_ != #{attendanceId}
         </if>
@@ -682,7 +683,8 @@
     <select id="queryLeaveNum" resultType="java.util.Map">
         SELECT sa.user_id_ 'key',COUNT(sa.id_) 'value' FROM student_attendance sa
         LEFT JOIN course_schedule cs ON cs.id_ = sa.course_schedule_id_
-        WHERE sa.status_ = 'LEAVE' AND DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month} AND cs.pre_course_flag_ != 1
+        WHERE sa.status_ = 'LEAVE' AND DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month}
+        AND cs.pre_course_flag_ != 1 AND cs.del_flag_ = '0'
         AND sa.user_id_ IN
         <foreach collection="userIds" item="userId" separator="," open="(" close=")">
             #{userId}
@@ -719,7 +721,7 @@
         left join course_schedule_student_payment cssp on cs.id_ = cssp.course_schedule_id_
         left join  student_attendance sa on sa.course_schedule_id_ = cs.id_ and sa.user_id_ = cssp.user_id_
         <where>
-            and cs.status_ = 'OVER'
+            and cs.status_ = 'OVER' AND cs.del_flag_ = '0'
             <if test="param.musicGroupId != null">
                 and cs.music_group_id_ = #{param.musicGroupId}
             </if>

+ 8 - 5
mec-biz/src/main/resources/config/mybatis/StudentStatisticsMapper.xml

@@ -568,7 +568,7 @@
 		from student_statistics ss
 		left join (select cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
 		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
-		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{queryInfo.month} AND cs.type_ = 'VIP'
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{queryInfo.month} AND cs.type_ = 'VIP' AND cs.del_flag_ = '0'
 		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
 		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
 		left join sys_user su ON su.id_ = ss.user_id_
@@ -589,7 +589,8 @@
 		from student_statistics ss
 		left join (select cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
 		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
-		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate} AND cs.type_ = 'VIP'
+		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate}
+		AND cs.type_ = 'VIP' AND cs.del_flag_ = '0'
 		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
 		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
 		left join sys_user su ON su.id_ = ss.user_id_
@@ -616,7 +617,8 @@
 		from student_statistics ss
 		left join (select COUNT(cssp.id_) course_sum_,cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
 		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
-		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate} AND cs.status_ = 'OVER' AND cs.type_ = 'VIP'
+		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate}
+		AND cs.status_ = 'OVER' AND cs.type_ = 'VIP' AND cs.del_flag_ = '0'
 		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
 		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
 		left join sys_user su ON su.id_ = ss.user_id_
@@ -643,7 +645,7 @@
 		from student_statistics ss
 		left join (select cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) consumerNum from course_schedule cs
 		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
-		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month} AND cs.type_ = 'VIP'
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month} AND cs.type_ = 'VIP' AND cs.del_flag_ = '0'
 		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
 		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
 		left join sys_user su ON su.id_ = ss.user_id_
@@ -681,7 +683,8 @@
 		left join (
 		select cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
 		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
-		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{startDate} AND #{endDate} AND cs.type_ = 'VIP'
+		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{startDate} AND #{endDate}
+		AND cs.type_ = 'VIP' AND cs.del_flag_ = '0'
 		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
 		group by cssp.user_id_) cs ON ss.user_id_ = cs.user_id_
 		left join sys_user su ON su.id_ = ss.user_id_

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

@@ -201,7 +201,7 @@
         SELECT s.id_ user_id_,s.username_,s.avatar_ head_url_,s.gender_,s.phone_ FROM course_schedule cs
         LEFT JOIN course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
         LEFT JOIN sys_user s ON s.id_ = cssp.user_id_
-        WHERE cs.actual_teacher_id_ = #{teacherId}
+        WHERE cs.actual_teacher_id_ = #{teacherId} AND cs.del_flag_ = '0'
         <if test="student != null and student != ''">
             AND (s.phone_ LIKE CONCAT('%',#{student},'%') OR s.username_ LIKE CONCAT('%',#{student},'%'))
         </if>
@@ -213,7 +213,7 @@
         SELECT COUNT(DISTINCT s.id_) FROM course_schedule cs
         LEFT JOIN course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
         LEFT JOIN sys_user s ON s.id_ = cssp.user_id_
-        WHERE cs.actual_teacher_id_ = #{teacherId}
+        WHERE cs.actual_teacher_id_ = #{teacherId} AND cs.del_flag_ = '0'
         <if test="student != null and student != ''">
             AND (s.phone_ LIKE CONCAT('%',#{student},'%') OR s.username_ LIKE CONCAT('%',#{student},'%'))
         </if>

+ 1 - 0
mec-biz/src/main/resources/config/mybatis/SubjectMapper.xml

@@ -15,6 +15,7 @@
         <result column="img_" property="img"/>
         <result column="create_time_" property="createTime"/>
         <result column="update_time_" property="updateTime"/>
+        <result column="instrumentIds" property="instrumentIds"/>
         <result column="del_flag_" property="delFlag" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
     </resultMap>
 

+ 46 - 2
mec-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml

@@ -32,6 +32,15 @@
 		<result column="part_index_" property="partIndex" />
         <result column="tenant_id_" property="tenantId"/>
         <result column="subject_id_" property="subjectId"/>
+        <result column="custom_configuration_" property="customConfiguration"/>
+        <result column="practice_time_" property="practiceTime"/>
+        <result column="practice_source_" property="practiceSource"/>
+        <result column="result_analyze_" property="resultAnalyze"/>
+        <result column="headphone_flag_" property="headphoneFlag"/>
+        <result column="instrument_id_" property="instrumentId"/>
+        <result column="hidden_flag_" property="hiddenFlag"/>
+        <result column="del_flag_" property="delFlag"/>
+        <result column="play_rate_" property="playRate"/>
 	</resultMap>
 
 	<!-- 根据主键查询一条记录 -->
@@ -48,11 +57,13 @@
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.SysMusicCompareRecord" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
 		INSERT INTO sys_music_compare_record (id_,user_id_,sys_music_score_id_,heard_level_,behavior_id_,score_data_,score_,intonation_,cadence_,integrity_,
 		                                      record_file_path_,video_file_path_,device_type_,client_id_,play_time_,speed_,monday_,
-												source_time_,feature_,create_time_,create_date_,update_time_,part_index_,tenant_id_,subject_id_)
+												source_time_,feature_,create_time_,create_date_,update_time_,part_index_,tenant_id_,subject_id_,
+        custom_configuration_,practice_time_,practice_source_,result_analyze_,headphone_flag_,instrument_id_,hidden_flag_,del_flag_,play_rate_)
 		VALUES(#{id},#{userId},#{sysMusicScoreId},#{heardLevel,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{behaviorId},#{scoreData},
 		       #{score},#{intonation},#{cadence},#{integrity},
 		       #{recordFilePath},#{videoFilePath},#{deviceType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{clientId},#{playTime},#{speed},#{monday},
-		       #{sourceTime},#{feature,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}, #{createTime}, #{createDate}, NOW(),#{partIndex},#{tenantId},#{subjectId})
+		       #{sourceTime},#{feature,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}, #{createTime}, #{createDate}, NOW(),#{partIndex},#{tenantId},#{subjectId}
+            ,#{customConfiguration},#{practiceTime},#{practiceSource},#{resultAnalyze},#{headphoneFlag},#{instrumentId},#{hiddenFlag},#{delFlag},#{playRate})
 	</insert>
 	<insert id="init">
 		insert into sys_music_compare_day_data (user_id_, day_, train_num_, train_time_, tenant_id_)
@@ -125,6 +136,33 @@
 		<if test="heardLevel!=null">
 			heard_level_ = #{heardLevel,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
 		</if>
+        <if test="customConfiguration != null and customConfiguration != ''">
+            custom_configuration_ = #{customConfiguration},
+        </if>
+        <if test="practiceSource != null and practiceSource != ''">
+            practice_source_ = #{practiceSource},
+        </if>
+        <if test="practiceSource != null and practiceSource != ''">
+            practice_time_ = #{practiceTime},
+        </if>
+        <if test="resultAnalyze != null and resultAnalyze != ''">
+            result_analyze_ = #{resultAnalyze},
+        </if>
+        <if test="headphoneFlag != null">
+            headphone_flag_ = #{headphoneFlag},
+        </if>
+        <if test="instrumentId != null">
+            instrument_id_ = #{instrumentId},
+        </if>
+        <if test="hiddenFlag != null">
+            hidden_flag_ = #{hiddenFlag},
+        </if>
+        <if test="delFlag != null">
+            del_flag_ = #{delFlag},
+        </if>
+        <if test="playRate != null">
+            play_rate_ = #{playRate},
+        </if>
 		update_time_ = NOW()
 	</set> WHERE id_ = #{id} and tenant_id_ = #{tenantId}
 	</update>
@@ -597,4 +635,10 @@
 		<include refid="queryPageByStudentSql"/>
 		order by mcr.create_date_ DESC
 	</select>
+
+	<select id="getLastData" resultType="java.lang.Long">
+        select id_ from sys_music_compare_record
+        where client_id_ =#{clientId} and user_id_ = #{userId} and feature_ = #{feature} and sys_music_score_id_ = #{sysMusicScoreId}
+        order by  create_time_ desc,id_ desc   limit 1
+    </select>
 </mapper>

+ 2 - 1
mec-biz/src/main/resources/config/mybatis/SysMusicScoreAccompanimentMapper.xml

@@ -154,8 +154,9 @@
 		<include refid="queryPageSql"/>
 	</select>
     <select id="querySubjectIds" resultMap="com.ym.mec.biz.dal.dao.SubjectDao.Subject">
-		SELECT s.* FROM sys_music_score sms
+		SELECT s.*,i.id_ as instrumentIds FROM sys_music_score sms
 		LEFT JOIN `subject` s ON FIND_IN_SET(s.id_,sms.subject_ids_)
+        left join instrument i on i.subject_id_ = s.id_
 		WHERE sms.del_flag_ = 0 AND sms.cbs_music_sheet_id_ IS NOT NULL AND s.id_ IS NOT NULL
 		<if test="categoriesIdList != null and categoriesIdList.size > 0">
 			AND sms.cbs_music_categories_id_ IN

+ 15 - 2
mec-biz/src/main/resources/config/mybatis/SysMusicScoreMapper.xml

@@ -146,9 +146,16 @@
 		SELECT ses.*,su.real_name_ create_user_name_,ses.cbs_music_categories_id_ categories_id_,ses.subject_ids_
 		FROM sys_music_score ses
 		LEFT JOIN sys_user su ON ses.create_user_id_ = su.id_
+        <if test="recentFlag !=null and recentFlag == true">
+            right JOIN sys_music_compare_record sms ON ses.id_ = sms.sys_music_score_id_ and sms.user_id_ = #{userId} and sms.client_id_ = #{clientId}
+        </if>
 		<include refid="queryPageSql"/>
 		GROUP BY ses.id_
-		ORDER BY ses.cbs_music_categories_id_ DESC,ses.order_ ASC,ses.create_time_ DESC,ses.id_ desc
+        order by
+        <if test="recentFlag !=null and recentFlag == true">
+             max(sms.create_time_) desc,
+        </if>
+		 ses.cbs_music_categories_id_ DESC,ses.order_ ASC,ses.create_time_ DESC,ses.id_ desc
 		<include refid="global.limit"/>
 	</select>
 	
@@ -267,6 +274,9 @@
 			<if test="search != null and search != ''">
 				AND (ses.cbs_music_sheet_id_ = #{search} OR ses.name_ LIKE CONCAT('%',#{search},'%'))
 			</if>
+            <if test="name != null and name != ''">
+                AND ses.name_ LIKE CONCAT('%',#{name},'%')
+            </if>
 			<if test="showFlag != null">
 				AND ses.show_flag_ = #{showFlag}
 			</if>
@@ -286,7 +296,7 @@
 				AND (FIND_IN_SET(#{subjectId},ses.subject_ids_) OR ses.subject_ids_ IS NULL OR ses.subject_ids_ = '' OR ses.is_all_subject_)
 			</if>
 			<if test="subjectIds != null and subjectIds != ''">
-				AND (FIND_IN_SET(#{subjectIds},ses.subject_ids_) OR ses.subject_ids_ IS NULL OR ses.subject_ids_ = '' OR ses.is_all_subject_)
+				AND (INTE_ARRAY(#{subjectIds},ses.subject_ids_) OR ses.subject_ids_ IS NULL OR ses.subject_ids_ = '' OR ses.is_all_subject_)
 			</if>
 			<if test="clientType != null">
 				AND ses.client_type_ = #{clientType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
@@ -320,6 +330,9 @@
 					AND ses.create_user_id_ = #{createUserId}
 				</if>
 			</if>
+            <if test="excludeMusicId !=null">
+                AND ses.id_ != #{excludeMusicId}
+            </if>
 		</where>
 	</sql>
 

+ 8 - 0
mec-biz/src/main/resources/config/mybatis/UserMusicMapper.xml

@@ -21,6 +21,8 @@
                t.del_flag_,
                t.expire_flag_,
                t.submit_time_,
+                t.select_flag_,
+                t.file_type_ ,
                t.update_time_ as createTime
 		FROM user_music t
         left join sys_music_score t1 on t1.id_ = t.music_sheet_id_
@@ -44,6 +46,12 @@
             <if test="param.exclusionId != null">
                 and t.id_ != #{param.exclusionId}
             </if>
+            <if test="param.fileType != null">
+                and t.file_type_ = #{param.fileType}
+            </if>
+            <if test="param.musicPracticeRecordId != null">
+                and t.music_practice_record_id_ = #{param.musicPracticeRecordId}
+            </if>
         </where>
         <if test="param.sort != null">
             order by

+ 5 - 0
mec-common/common-core/src/main/java/com/ym/mec/common/config/LocalFastJsonHttpMessageConverter.java

@@ -6,6 +6,7 @@ import java.lang.reflect.Type;
 import java.math.BigDecimal;
 import java.util.Date;
 
+import com.microsvc.toolkit.common.enums.ConverterEnum;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -69,6 +70,10 @@ class EnumFilter implements ValueFilter {
 		if (BaseEnum.class.isAssignableFrom(value.getClass())) {
 			return ((BaseEnum<?, ?>) value).getCode();
 		}
+		// ConverterEnum枚举映射转换
+		if (ConverterEnum.class.isAssignableFrom(value.getClass())) {
+			return ((ConverterEnum<?>) value).getCode();
+		}
 		return value;
 	}
 }