浏览代码

Merge branch 'feature/1108_audio' into online

刘俊驰 3 月之前
父节点
当前提交
fb252f7bbc
共有 46 个文件被更改,包括 2605 次插入82 次删除
  1. 1 0
      .gitignore
  2. 145 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetCbsController.java
  3. 151 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicPracticeRecordController.java
  4. 184 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetCbsController.java
  5. 18 9
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java
  6. 42 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionController.java
  7. 15 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicController.java
  8. 142 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenMusicSheetCbsController.java
  9. 145 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicPracticeRecordController.java
  10. 194 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetCbsController.java
  11. 16 3
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java
  12. 38 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionController.java
  13. 5 4
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TenantAlbumSheetController.java
  14. 16 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserMusicController.java
  15. 136 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenMusicSheetCbsController.java
  16. 1 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicSheetController.java
  17. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetDao.java
  18. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicFavorite.java
  19. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Subject.java
  20. 18 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMusicCompareRecord.java
  21. 12 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusic.java
  22. 34 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/FeatureType.java
  23. 2 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicFavoriteService.java
  24. 32 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicPracticeRecordService.java
  25. 5 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  26. 2 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMusicCompareRecordService.java
  27. 5 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicFavoriteServiceImpl.java
  28. 120 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicPracticeRecordServiceImpl.java
  29. 110 22
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  30. 10 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  31. 8 9
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMusicCompareRecordServiceImpl.java
  32. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumMusicServiceImpl.java
  33. 11 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserMusicServiceImpl.java
  34. 5 9
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  35. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  36. 33 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetVo.java
  37. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentHomeVo.java
  38. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentVo.java
  39. 566 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/MusicPracticeRecordWrapper.java
  40. 129 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/MusicSheetWrapper.java
  41. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantGroupAlbumWrapper.java
  42. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicWrapper.java
  43. 155 7
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml
  44. 1 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SubjectMapper.xml
  45. 41 4
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  46. 8 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserMusicMapper.xml

+ 1 - 0
.gitignore

@@ -10,6 +10,7 @@ logback-test.xml
 .settings
 .springBeans
 .sts4-cache
+.DS_Store
 
 ### IntelliJ IDEA ###
 /.idea/

+ 145 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetCbsController.java

@@ -0,0 +1,145 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.InstrumentService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/musicSheet")
+@Api(tags = "曲谱表 API接口")
+public class MusicSheetCbsController extends BaseController {
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+	@Resource
+	private MusicSheetService musicSheetService;
+
+    @Resource
+    private AppVersionInfoService appVersionInfoService;
+
+    @Resource
+    private StudentService studentService;
+
+    @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.MusicSheetDetail> cbsDetail(@PathVariable("id") Long id,
+                                                      @RequestParam(required = false) String tenantAlbumId,
+                                                      @RequestParam(required = false) String providerType) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            sysUser = null;
+        }
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(id);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        cbsMusicSheet.setBizId(id);
+
+        // 设置查询机构 还是平台数据
+        if (StringUtils.isNotBlank(providerType) && SourceTypeEnum.PLATFORM.name().equals(providerType)) {
+            tenantAlbumId = null;
+        } else {
+            tenantAlbumId = StringUtils.isBlank(tenantAlbumId) ? null : "1";
+        }
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(cbsMusicSheet), MusicSheetVo.MusicSheetDetail.class);
+        MusicSheetDetailVo detail = musicSheetService.detail(id.toString(), sysUser, ClientEnum.SYSTEM, tenantAlbumId);
+        if (detail == null) {
+        } else {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(detail.getPaymentType());
+            // 设置业务端曲目分类
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getNotation() ==YesOrNoEnum.YES);
+            musicSheetDetail.setPlay(detail.getPlay());
+            musicSheetDetail.setBuyed(detail.getBuyed());
+            musicSheetDetail.setMusicPrice(detail.getMusicPrice());
+        }
+
+        // 如果是合奏 并且乐器ID = 2268
+        musicSheetDetail.setSpecialPercussionFlag(false);
+        if ("2268".equals(musicSheetDetail.getMusicalInstrumentIds()) && musicSheetDetail.getMusicSheetType() == EMusicSheetType.CONCERT) {
+            musicSheetDetail.setSpecialPercussionFlag(true);
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Long> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Long::parseLong).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Long, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId().longValue());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+}

+ 151 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicPracticeRecordController.java

@@ -0,0 +1,151 @@
+package com.yonge.cooleshow.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.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicPracticeRecordWrapper;
+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.student:}/musicPracticeRecord")
+@Api(tags = "曲目练习记录")
+public class MusicPracticeRecordController {
+
+    @Autowired
+    private MusicPracticeRecordService musicPracticeRecordService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Autowired
+    private StudentService studentService;
+
+    /**
+     * 查询单条
+     * @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));
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(Long.parseLong(wrapper.getMusicSheetId()));
+        if (Objects.isNull(musicSheet)) {
+            throw new com.yonge.toolset.base.exception.BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new com.yonge.toolset.base.exception.BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        if (cbsMusicSheet != null) {
+            from.setRhythmFlag(cbsMusicSheet.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( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record) {
+
+        Long userId = sysUserService.getUserId();
+        record.userId(String.valueOf(userId)).clientType(ClientEnum.STUDENT.getCode());
+        Student student = studentService.getById(userId);
+        if (student == null) {
+            throw BizException.from("学生不存在");
+        }
+        record.setProviderType(student.getTenantId() !=null && student.getTenantId()>0?"TENANT":"PLATFORM");
+
+        // 新增数据
+        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);
+    }
+
+}

+ 184 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetCbsController.java

@@ -0,0 +1,184 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.UserTenantAlbumRecord;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.student:}/musicSheet")
+@Api(tags = "曲谱表 API接口")
+public class MusicSheetCbsController extends BaseController {
+    @Resource
+    private SysUserService sysUserService;
+	@Resource
+	private MusicSheetService musicSheetService;
+    @Resource
+    private AppVersionInfoService appVersionInfoService;
+    @Resource
+    private StudentService studentService;
+    @Resource
+    private InstrumentService instrumentService;
+    @Resource
+    private UserTenantAlbumRecordService userTenantAlbumRecordService;
+
+    /**
+     * 查询单条
+     *
+     * @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") Long id,
+                                                      @RequestParam(required = false) String tenantAlbumId) {
+
+        SysUser sysUser = sysUserService.getUser();
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(id);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        cbsMusicSheet.setBizId(id);
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(cbsMusicSheet), MusicSheetVo.MusicSheetDetail.class);
+        MusicSheetDetailVo detail = musicSheetService.detail(id.toString(), sysUser, ClientEnum.STUDENT, tenantAlbumId);
+        if (detail != null) {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(detail.getPaymentType());
+            // 设置业务端曲目分类
+//            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getNotation() ==YesOrNoEnum.YES);
+            musicSheetDetail.setPlay(detail.getPlay());
+            musicSheetDetail.setBuyed(detail.getBuyed());
+            musicSheetDetail.setMusicPrice(detail.getMusicPrice());
+        }
+        // 如果是合奏 并且乐器ID = 2268
+        musicSheetDetail.setSpecialPercussionFlag(false);
+        if ("2268".equals(musicSheetDetail.getMusicalInstrumentIds()) && musicSheetDetail.getMusicSheetType() == EMusicSheetType.CONCERT) {
+            musicSheetDetail.setSpecialPercussionFlag(true);
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Long> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Long::parseLong).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Long, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId().longValue());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "曲谱表- 传入 MusicSheetVo.MusicSheetQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<MusicSheetWrapper.MusicSheetCloud>> cloudPage(@RequestBody MusicSheetWrapper.MusicSheetCloudQuery query) {
+
+        SysUser sysUser = sysUserService.getUser();
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            return failed("用户信息获取失败");
+        }
+
+        // 检查app版本
+        YesOrNoEnum appAuditVersion = appVersionInfoService.getAppAuditVersion(query.getPlatform(), query.getVersion());
+        // 学生 只能看通过审核 并且 启用的 曲目
+        query.setDelFlag(false);
+        query.setVersionFlag(appAuditVersion == YesOrNoEnum.YES);
+        query.setStatus(true);
+        query.setUserId(student.getUserId());
+        query.setClientType(ClientEnum.STUDENT.name());
+        MusicSheet musicSheet =null;
+        if (query.getExcludeMusicId() !=null) {
+            musicSheet = musicSheetService.getById(query.getExcludeMusicId());
+            if (musicSheet == null) {
+                return failed("曲目不存在");
+            }
+            query.setMusicSheetType(musicSheet.getMusicSheetType());
+        }
+        // 如果是机构学生
+        if (student.getTenantId() !=null && student.getTenantId()>0) {
+            query.setProviderType(SourceTypeEnum.TENANT);
+            query.setSubjectId(Long.parseLong(student.getSubjectId()));
+
+            // 学生可用专辑
+
+            List<UserTenantAlbumRecord> record = userTenantAlbumRecordService.lambdaQuery()
+                    .eq(UserTenantAlbumRecord::getUserId, student.getUserId())
+                    .eq(UserTenantAlbumRecord::getClientType, ClientEnum.STUDENT)
+                    .gt(UserTenantAlbumRecord::getEndTime,new Date())
+                    .orderByAsc(UserTenantAlbumRecord::getEndTime)
+                    .list();
+            if (CollectionUtils.isNotEmpty(record)) {
+                List<Long> albumIds = record.stream().map(UserTenantAlbumRecord::getTenantAlbumId).distinct().collect(Collectors.toList());
+                query.setTenantAlbumIds(albumIds);
+            } else {
+                return HttpResponseResult.succeed(PageUtil.pageInfo(new Page<>()));
+            }
+
+        } else {
+            query.setProviderType(SourceTypeEnum.PLATFORM);
+            if (musicSheet !=null) {
+                query.setMusicTagIds(musicSheet.getMusicTag());
+                if (StringUtils.isNotBlank(musicSheet.getMusicSubject())) {
+                    List<Long> subjectIds = Arrays.stream(musicSheet.getMusicSubject().split(",")).filter(StringUtils::isNotBlank).map(Long::parseLong).collect(Collectors.toList());
+                    query.setMustMatchSubjectIds(subjectIds);
+                }
+            }
+        }
+        IPage<MusicSheetWrapper.MusicSheetCloud> musicSheetCloudIPage = musicSheetService.cloudPage(query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(musicSheetCloudIPage));
+    }
+}

+ 18 - 9
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java

@@ -1,6 +1,10 @@
 package com.yonge.cooleshow.student.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -16,15 +20,13 @@ import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.MusicSortType;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
-import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
-import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
-import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
-import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.AlbumAndSheetVo;
 import com.yonge.cooleshow.biz.dal.vo.CheckVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
@@ -41,6 +43,7 @@ import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -53,9 +56,8 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Optional;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 曲谱表 web 控制层
@@ -82,6 +84,8 @@ public class MusicSheetController extends BaseController {
     @Resource
     private StudentService studentService;
 
+    @Autowired
+    private InstrumentService instrumentService;
 
     /**
      * 查询单条
@@ -220,8 +224,14 @@ public class MusicSheetController extends BaseController {
         if (ClientEnum.invalid(clientType)) {
             return failed("无效的客户端类型");
         }
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("学生不存在");
+        }
 
-        return succeed(musicSheetService.setFavorite(sysUser.getId(),id, ClientEnum.valueOf(clientType)));
+
+        return succeed(musicSheetService
+                .setFavorite(sysUser.getId(),id, ClientEnum.valueOf(clientType),student.getTenantId() !=null && student.getTenantId()>0?"TENANT":"PLATFORM"));
     }
 
 
@@ -490,5 +500,4 @@ public class MusicSheetController extends BaseController {
         return succeed(musicSheetService.searchTenant(queryInfo));
     }
 
-
 }

+ 42 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionController.java

@@ -1,19 +1,26 @@
 package com.yonge.cooleshow.student.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.admin.io.request.SysSuggestionVo;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
 import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionV2Service;
 import com.yonge.cooleshow.common.controller.BaseController;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
 
 @Api(tags = "意见反馈")
 @RestController
@@ -28,6 +35,8 @@ public class SysSuggestionController extends BaseController {
     @Autowired
     private StudentService studentService;
 
+    @Autowired
+    private SysSuggestionV2Service sysSuggestionV2Service;
     @ApiOperation(value = "新增")
     @RequestMapping("sysSuggestion/add")
     public Object add(SysSuggestion sysSuggestion) {
@@ -50,4 +59,35 @@ public class SysSuggestionController extends BaseController {
         return succeed();
     }
 
+
+    /**
+     * 新增
+     *
+     * @param suggestion SysSuggestionVo.SysSuggestion
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "传入sysSuggestion")
+    @PostMapping("sysSuggestion/save")
+    public R<Boolean> add(@Validated @RequestBody SysSuggestionVo.SysSuggestion suggestion,
+                          @RequestHeader(name = "user-agent") String userAgent) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        suggestion.setUserId(sysUser.getId());
+        String userAgent1 = suggestion.getUserAgent();
+        if(StringUtils.isEmpty(userAgent1)){
+            userAgent1 = userAgent;
+        }
+        suggestion.setUserAgent(userAgent1);
+
+        Student student = studentService.getById(sysUser.getId());
+        if (student.getTenantId() != null && student.getTenantId() != -1) {
+            suggestion.setClientType(ClientEnum.TENANT_STUDENT);
+        } else {
+            suggestion.setClientType(ClientEnum.STUDENT);
+        }
+
+        SysSuggestionV2 sysSuggestion = JSON.parseObject(suggestion.jsonString(), SysSuggestionV2.class);
+        sysSuggestion.setCreateTime(new Date());
+        return R.from(sysSuggestionV2Service.add(sysSuggestion));
+    }
+
 }

+ 15 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicController.java

@@ -106,4 +106,19 @@ public class UserMusicController {
 
         return HttpResponseResult.succeed(true);
     }
+
+
+    @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));
+    }
 }

+ 142 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenMusicSheetCbsController.java

@@ -0,0 +1,142 @@
+package com.yonge.cooleshow.student.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.student:}/open/musicSheet")
+@Api(tags = "曲谱表 API接口")
+public class OpenMusicSheetCbsController extends BaseController {
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+	@Resource
+	private MusicSheetService musicSheetService;
+
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    /**
+     * 查询单条
+     *
+     * @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") Long id,
+                                                      @RequestParam(required = false) String tenantAlbumId,
+                                                      @RequestParam(required = false) Long userMusicId) {
+
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(id);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        cbsMusicSheet.setBizId(id);
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(cbsMusicSheet), MusicSheetVo.MusicSheetDetail.class);
+        MusicSheetDetailVo detail;
+        if (userMusicId != null) {
+            UserMusic userMusic = userMusicService.detail(userMusicId);
+            if (userMusic == null) {
+                throw new BizException("参数错误");
+            } else {
+                SysUser sysUser = sysUserFeignService.queryUserById(userMusic.getUserId());
+                detail = musicSheetService.detail(id.toString(), sysUser, ClientEnum.STUDENT, tenantAlbumId);
+            }
+        } else {
+
+            detail = musicSheetService.detail(id.toString(), null, ClientEnum.STUDENT, tenantAlbumId);
+        }
+        if (detail != null) {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(detail.getPaymentType());
+            // 设置业务端曲目分类
+//            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getNotation() ==YesOrNoEnum.YES);
+            musicSheetDetail.setPlay(detail.getPlay());
+            musicSheetDetail.setBuyed(detail.getBuyed());
+            musicSheetDetail.setMusicPrice(detail.getMusicPrice());
+        }
+
+        // 如果是合奏 并且乐器ID = 2268
+        musicSheetDetail.setSpecialPercussionFlag(false);
+        if ("2268".equals(musicSheetDetail.getMusicalInstrumentIds()) && musicSheetDetail.getMusicSheetType() == EMusicSheetType.CONCERT) {
+            musicSheetDetail.setSpecialPercussionFlag(true);
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Long> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Long::parseLong).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Long, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId().longValue());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+}

+ 145 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicPracticeRecordController.java

@@ -0,0 +1,145 @@
+package com.yonge.cooleshow.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.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicPracticeRecordService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicPracticeRecordWrapper;
+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.teacher:}/musicPracticeRecord")
+@Api(tags = "曲目练习记录")
+public class MusicPracticeRecordController {
+
+    @Autowired
+    private MusicPracticeRecordService musicPracticeRecordService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private MusicSheetService 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));
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(Long.parseLong(wrapper.getMusicSheetId()));
+        if (Objects.isNull(musicSheet)) {
+            throw new com.yonge.toolset.base.exception.BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new com.yonge.toolset.base.exception.BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        if (cbsMusicSheet != null) {
+            from.setRhythmFlag(cbsMusicSheet.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( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record) {
+
+        Long 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);
+    }
+
+}

+ 194 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetCbsController.java

@@ -0,0 +1,194 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.mapper.TenantGroupAlbumMapper;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupAlbumWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+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.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.teacher:}/musicSheet")
+@Api(tags = "曲谱表 API接口")
+public class MusicSheetCbsController extends BaseController {
+    @Resource
+    private SysUserService sysUserService;
+	@Resource
+	private MusicSheetService musicSheetService;
+    @Resource
+    private MusicFavoriteService musicFavoriteService;
+    @Resource
+    private CourseCoursewareService courseCoursewareService;
+    @Resource
+    private AppVersionInfoService appVersionInfoService;
+    @Resource
+    private InstrumentService instrumentService;
+    @Resource
+    private TeacherService teacherService;
+    @Resource
+    private TenantGroupAlbumMapper tenantGroupAlbumMapper;
+
+    /**
+     * 查询单条
+     *
+     * @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") Long id,
+                                                      @RequestParam(required = false) String tenantAlbumId,
+                                                      @RequestParam(required = false) String providerType) {
+
+        SysUser sysUser = sysUserService.getUser();
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(id);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        cbsMusicSheet.setBizId(id);
+
+
+        // 设置查询机构 还是平台数据
+        if (StringUtils.isBlank(tenantAlbumId) && StringUtils.isNotBlank(providerType)) {
+            if (SourceTypeEnum.PLATFORM.name().equals(providerType)) {
+                tenantAlbumId = null;
+            } else {
+                tenantAlbumId = "1";
+            }
+        }
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(cbsMusicSheet), MusicSheetVo.MusicSheetDetail.class);
+        MusicSheetDetailVo detail = musicSheetService.detail(id.toString(), sysUser, ClientEnum.TEACHER, tenantAlbumId);
+        if (detail != null) {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(detail.getPaymentType());
+            // 设置业务端曲目分类
+//            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getNotation() ==YesOrNoEnum.YES);
+            musicSheetDetail.setPlay(detail.getPlay());
+            musicSheetDetail.setBuyed(detail.getBuyed());
+            musicSheetDetail.setMusicPrice(detail.getMusicPrice());
+        }
+
+        // 如果是合奏 并且乐器ID = 2268
+        musicSheetDetail.setSpecialPercussionFlag(false);
+        if ("2268".equals(musicSheetDetail.getMusicalInstrumentIds()) && musicSheetDetail.getMusicSheetType() == EMusicSheetType.CONCERT) {
+            musicSheetDetail.setSpecialPercussionFlag(true);
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Long> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Long::parseLong).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Long, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId().longValue());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "曲谱表- 传入 MusicSheetVo.MusicSheetQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<MusicSheetWrapper.MusicSheetCloud>> cloudPage(@RequestBody MusicSheetWrapper.MusicSheetCloudQuery query) {
+
+        SysUser sysUser = sysUserService.getUser();
+        Teacher teacher = teacherService.getById(sysUser.getId());
+        if (teacher == null) {
+            return failed("用户信息获取失败");
+        }
+
+        // 检查app版本
+        YesOrNoEnum appAuditVersion = appVersionInfoService.getAppAuditVersion(query.getPlatform(), query.getVersion());
+        // 学生 只能看通过审核 并且 启用的 曲目
+        query.setDelFlag(false);
+        query.setVersionFlag(appAuditVersion == YesOrNoEnum.YES);
+        query.setStatus(true);
+        query.setUserId(teacher.getUserId());
+        query.setClientType(ClientEnum.TEACHER.name());
+        MusicSheet musicSheet =null;
+        if (query.getExcludeMusicId() !=null) {
+            musicSheet = musicSheetService.getById(query.getExcludeMusicId());
+            if (musicSheet == null) {
+                return failed("曲目不存在");
+            }
+            query.setMusicSheetType(musicSheet.getMusicSheetType());
+        }
+        // 如果是机构老师
+        if (query.getProviderType() != null && query.getProviderType() == SourceTypeEnum.TENANT) {
+            // 查询机构老师可用的专辑ID集合
+            List<TenantGroupAlbumWrapper.BuyTenantAlbum> buyAlbumInfo = tenantGroupAlbumMapper.getBuyAlbumInfo(TenantGroupAlbumWrapper.BuyTenantAlbumQuery.builder().tenantId(teacher.getTenantId()).build());
+            if (CollectionUtils.isEmpty(buyAlbumInfo)) {
+                return HttpResponseResult.succeed(PageUtil.pageInfo(new Page<>()));
+            }
+            query.setTenantAlbumIds(buyAlbumInfo.stream().map(TenantGroupAlbumWrapper.BuyTenantAlbum::getId).collect(Collectors.toList()));
+
+        } else {
+            query.setProviderType(SourceTypeEnum.PLATFORM);
+            if (musicSheet !=null) {
+                query.setMusicTagIds(musicSheet.getMusicTag());
+                if (StringUtils.isNotBlank(musicSheet.getMusicSubject())) {
+                    List<Long> subjectIds = Arrays.stream(musicSheet.getMusicSubject().split(","))
+                            .filter(StringUtils::isNotBlank).map(Long::parseLong).collect(Collectors.toList());
+                    query.setMustMatchSubjectIds(subjectIds);
+                }
+            }
+        }
+        IPage<MusicSheetWrapper.MusicSheetCloud> musicSheetCloudIPage = musicSheetService.cloudPage(query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(musicSheetCloudIPage));
+    }
+}

+ 16 - 3
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java

@@ -69,7 +69,19 @@ public class MusicSheetController extends BaseController {
     @GetMapping("/detail/{id}")
     @ApiOperation(value = "详情", notes = "传入musicTag")
     public HttpResponseResult<MusicSheetDetailVo> detail(@ApiParam(value = "曲谱编号", required = true) @PathVariable("id") String id,
-                                                         @RequestParam(required = false) String tenantAlbumId) {
+                                                         @RequestParam(required = false) String tenantAlbumId,
+                                                         @RequestParam(required = false) String providerType) {
+
+
+        // 设置查询机构 还是平台数据
+        if (StringUtils.isBlank(tenantAlbumId) && StringUtils.isNotBlank(providerType)) {
+            if (SourceTypeEnum.PLATFORM.name().equals(providerType)) {
+                tenantAlbumId = null;
+            } else {
+                tenantAlbumId =  "1";
+            }
+        }
+
         SysUser sysUser = sysUserService.getUser();
         MusicSheetDetailVo detail = musicSheetService.detail(id, sysUser, ClientEnum.TEACHER,tenantAlbumId);
 
@@ -191,13 +203,14 @@ public class MusicSheetController extends BaseController {
     @PostMapping("/favorite/{id}")
     @ApiOperation(value = "曲目收藏/取消收藏")
     public HttpResponseResult<Boolean> favorite(@ApiParam(value = "曲目编号", required = true) @PathVariable("id") Long id,
-                                                @ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "TEACHER") String clientType) {
+                                                @ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "TEACHER") String clientType,
+                                                @RequestParam(value = "providerType", required = false, defaultValue = "PLATFORM") String providerType) {
         SysUser sysUser = sysUserService.getUser();
         if (ClientEnum.invalid(clientType)) {
             return failed("无效的客户端类型");
         }
 
-        return succeed(musicSheetService.setFavorite(sysUser.getId(),id, ClientEnum.valueOf(clientType)));
+        return succeed(musicSheetService.setFavorite(sysUser.getId(),id, ClientEnum.valueOf(clientType),providerType));
     }
 
     /**

+ 38 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionController.java

@@ -1,16 +1,24 @@
 package com.yonge.cooleshow.teacher.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.admin.io.request.SysSuggestionVo;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestionV2;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionV2Service;
 import com.yonge.cooleshow.common.controller.BaseController;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
 
 @Api(tags = "意见反馈")
 @RestController
@@ -22,6 +30,9 @@ public class SysSuggestionController extends BaseController {
     @Autowired
     private SysUserFeignService sysUserFeignService;
 
+    @Autowired
+    private SysSuggestionV2Service sysSuggestionV2Service;
+
     @ApiOperation(value = "新增")
     @RequestMapping("sysSuggestion/add")
     public Object add(SysSuggestion sysSuggestion) {
@@ -38,4 +49,29 @@ public class SysSuggestionController extends BaseController {
         return succeed();
     }
 
+
+    /**
+     * 新增
+     *
+     * @param suggestion SysSuggestionVo.SysSuggestion
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "传入sysSuggestion")
+    @PostMapping("sysSuggestion/save")
+    public R<Boolean> add(@Validated @RequestBody SysSuggestionVo.SysSuggestion suggestion,
+                          @RequestHeader(name = "user-agent") String userAgent) {
+        com.yonge.cooleshow.auth.api.entity.SysUser sysUser = sysUserFeignService.queryUserInfo();
+        suggestion.setUserId(sysUser.getId());
+        String userAgent1 = suggestion.getUserAgent();
+        if(StringUtils.isEmpty(userAgent1)){
+            userAgent1 = userAgent;
+        }
+        suggestion.setUserAgent(userAgent1);
+        suggestion.setClientType(ClientEnum.TEACHER);
+
+        SysSuggestionV2 sysSuggestion = JSON.parseObject(suggestion.jsonString(), SysSuggestionV2.class);
+        sysSuggestion.setCreateTime(new Date());
+        return R.from(sysSuggestionV2Service.add(sysSuggestion));
+    }
+
 }

+ 5 - 4
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TenantAlbumSheetController.java

@@ -83,13 +83,14 @@ public class TenantAlbumSheetController extends BaseController {
     @ApiOperation(value = "分页查询")
     @PostMapping("/page")
     public HttpResponseResult<PageInfo<TenantAlbumMusicWrapper.StudentTenantAlbumMusic>> page(@RequestBody @Validated TenantAlbumMusicWrapper.StudentTenantAlbumMusicQuery query) {
-//        SysUser user = sysUserFeignService.queryUserInfo();
-//        if (user == null || null == user.getId()) {
-//            return failed(HttpStatus.FORBIDDEN, "请登录");
-//        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
 
 //        Teacher teacher = teacherService.getById(user.getId());
 //        query.setTenantId(Optional.ofNullable(teacher.getTenantId()).orElse(-1L));
+        query.setUserId(user.getId());
         query.setClientType(ClientEnum.TEACHER);
         IPage<TenantAlbumMusicWrapper.StudentTenantAlbumMusic> page = tenantAlbumMusicService.selectPage(QueryInfo.getPage(query), query);
         return succeed((PageUtil.pageInfo(page)));

+ 16 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/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.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -103,4 +104,19 @@ public class UserMusicController {
 
         return HttpResponseResult.succeed(true);
     }
+
+
+    @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));
+    }
 }

+ 136 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenMusicSheetCbsController.java

@@ -0,0 +1,136 @@
+package com.yonge.cooleshow.teacher.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
+import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.InstrumentService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open/musicSheet")
+@Api(tags = "曲谱表 API接口")
+public class OpenMusicSheetCbsController extends BaseController {
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+	@Resource
+	private MusicSheetService musicSheetService;
+
+
+    @Autowired
+    private InstrumentService instrumentService;
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    /**
+     * 查询单条
+     *
+     * @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") Long id,
+                                                      @RequestParam(required = false) String tenantAlbumId,
+                                                      @RequestParam(required = false) Long userMusicId) {
+        // 曲目信息
+        MusicSheet musicSheet = musicSheetService.getDao().get(id);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new BizException("曲目信息异常");
+        }
+        CbsMusicSheetWrapper.MusicSheet cbsMusicSheet = musicSheetService.cbsDetail(musicSheet.getCbsMusicSheetId());
+        cbsMusicSheet.setBizId(id);
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(cbsMusicSheet), MusicSheetVo.MusicSheetDetail.class);
+        MusicSheetDetailVo detail;
+        if (userMusicId != null) {
+            UserMusic userMusic = userMusicService.detail(userMusicId);
+            if (userMusic == null) {
+                throw new BizException("参数错误");
+            } else {
+                SysUser sysUser = sysUserFeignService.queryUserById(userMusic.getUserId());
+                detail = musicSheetService.detail(id.toString(), sysUser, ClientEnum.TEACHER, tenantAlbumId);
+            }
+        } else {
+
+            detail = musicSheetService.detail(id.toString(), null, ClientEnum.TEACHER, tenantAlbumId);
+        }
+        if (detail != null) {
+            // 设置曲目付费类型
+            musicSheetDetail.setPaymentType(detail.getPaymentType());
+            // 设置业务端曲目分类
+//            musicSheetDetail.setBizMusicCategoryId(detail.getCategoriesId() == null ? null : detail.getCategoriesId().longValue());
+            musicSheetDetail.setScoreType(detail.getScoreType());
+            musicSheetDetail.setIsConvertibleScore(detail.getNotation() ==YesOrNoEnum.YES);
+            musicSheetDetail.setPlay(detail.getPlay());
+            musicSheetDetail.setBuyed(detail.getBuyed());
+            musicSheetDetail.setMusicPrice(detail.getMusicPrice());
+        }
+
+        // 如果是合奏 并且乐器ID = 2268
+        musicSheetDetail.setSpecialPercussionFlag(false);
+        if ("2268".equals(musicSheetDetail.getMusicalInstrumentIds()) && musicSheetDetail.getMusicSheetType() == EMusicSheetType.CONCERT) {
+            musicSheetDetail.setSpecialPercussionFlag(true);
+        }
+
+        // 设置乐器信息
+        if (StringUtils.isNotBlank(musicSheetDetail.getMusicalInstrumentIds())) {
+            List<Long> instrumentIds = Arrays.stream(musicSheetDetail.getMusicalInstrumentIds().split(","))
+                .map(Long::parseLong).collect(Collectors.toList());
+
+            if (CollectionUtils.isNotEmpty(instrumentIds) && CollectionUtils.isNotEmpty(musicSheetDetail.getMusicalInstruments())) {
+                Map<Long, InstrumentWrapper.Instrument> instrumentMap = instrumentService.getMapByIds(instrumentIds);
+                for (CbsMusicSheetWrapper.MusicalInstrument musicalInstrument : musicSheetDetail.getMusicalInstruments()) {
+                    InstrumentWrapper.Instrument instrument = instrumentMap.get(musicalInstrument.getId().longValue());
+                    if (instrument != null) {
+                        musicalInstrument.setOrientation(instrument.getOrientation());
+                    }
+
+                }
+            }
+        }
+        return R.from(musicSheetDetail);
+    }
+
+}

+ 1 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicSheetController.java

@@ -63,7 +63,7 @@ public class MusicSheetController extends BaseController {
             return failed("无效的客户端类型");
         }
 
-        return succeed(musicSheetService.setFavorite(sysUser.getId(), id, ClientEnum.valueOf(clientType)));
+        return succeed(musicSheetService.setFavorite(sysUser.getId(), id, ClientEnum.valueOf(clientType),"PLATFORM"));
     }
 
 

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetDao.java

@@ -185,6 +185,8 @@ public interface MusicSheetDao extends BaseMapper<MusicSheet> {
      */
     List<StatGroupWrapper> selectMusicAlbumStatInfo(@Param("musicIds") List<Long> musicIds);
 
+    Long selectMusicAlbumNum(@Param("musicId") Long musicId);
+
     /**
      * 修改收藏数
      */
@@ -236,4 +238,6 @@ public interface MusicSheetDao extends BaseMapper<MusicSheet> {
     List<TeacherHomeWrapper.MusicSheetTotal> musicSheetPage(@Param("param") TeacherHomeWrapper.MusicSheetQuery query);
 
     void updateExposureNum(@Param("musicSheetId") Long musicSheetId, @Param("exposureNum") Integer exposureNum);
+
+    IPage<MusicSheetWrapper.MusicSheetCloud> cloudPage(@Param("page") IPage<Object> page, @Param("param") MusicSheetWrapper.MusicSheetCloudQuery query);
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicFavorite.java

@@ -43,6 +43,17 @@ public class MusicFavorite extends BaseEntity {
     @ApiModelProperty(value = "是否收藏(1:收藏;0:取消收藏)")
     private Integer favoriteFlag;  //是否收藏(1:收藏;0:取消收藏)
 
+	@TableField("provider_type_")
+	@ApiModelProperty("曲目评测来源 TENANT 机构 PLATFORM 平台")
+	private String providerType;
+
+	public String getProviderType() {
+		return providerType;
+	}
+
+	public void setProviderType(String providerType) {
+		this.providerType = providerType;
+	}
 
 	public MusicFavorite setId(Long id) {
 	    this.id = id;

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Subject.java

@@ -50,6 +50,9 @@ public class Subject implements Serializable {
     @ApiModelProperty(value = "cbs声部名称")
     private String cbsSubjectName;
 
+	@ApiModelProperty(value = "总控乐器ID")
+	private Long instrumentId;
+
 	@TableField(value = "enable_flag_")
 	private Boolean enableFlag;
 

+ 18 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMusicCompareRecord.java

@@ -92,6 +92,24 @@ public class SysMusicCompareRecord extends BaseEntity {
 
     private Boolean hiddenFlag;
 
+
+
+    private String practiceTime;
+
+    private String practiceSource;
+
+    private String resultAnalyze;
+
+    private Boolean headphoneFlag;
+
+    private Long instrumentId;
+
+
+    private Boolean delFlag;
+
+    private Float playRate;
+	@ApiModelProperty("曲目评测来源 TENANT 机构 PLATFORM 平台")
+    private String providerType;
 	public SysMusicCompareRecord(FeatureType feature) {
 		this.feature = feature;
 	}

+ 12 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusic.java

@@ -61,6 +61,12 @@ public class UserMusic implements Serializable {
     private String videoImg;
 
 
+    @ApiModelProperty("文件类型") // .mp4 视频,其他为音频
+    @TableField(value = "file_type_")
+    private String fileType;
+
+
+
     @ApiModelProperty("发布描述")
     @TableField(value = "desc_")
     private String desc;
@@ -88,7 +94,12 @@ public class UserMusic implements Serializable {
     @TableField(value = "submit_time_")
     private Date submitTime;
 
-	@TableField(value = "create_time_")
+    @ApiModelProperty("是否能被看到评级、评分字段")
+    @TableField(value = "select_flag_")
+    private Boolean selectFlag;
+
+
+    @TableField(value = "create_time_")
     private Date createTime;
 
     @TableField(value = "update_time_")

+ 34 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/FeatureType.java

@@ -5,7 +5,8 @@ import com.yonge.toolset.base.enums.BaseEnum;
 
 public enum FeatureType implements BaseEnum<String, FeatureType> {
     CLOUD_STUDY_TRAIN("小酷Ai训练"),
-    CLOUD_STUDY_EVALUATION("小酷Ai评测");
+    CLOUD_STUDY_EVALUATION("小酷Ai评测"),
+    FOLLOW_UP_TRAINING( "跟练");
 
     @EnumValue
     private String code;
@@ -26,4 +27,36 @@ public enum FeatureType implements BaseEnum<String, FeatureType> {
         return this.desc;
     }
 
+    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;
+        }
+
+    }
+
+    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";
+        }
+    }
 }

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

@@ -23,7 +23,7 @@ public interface MusicFavoriteService extends IService<MusicFavorite> {
      * @param clientType 客户端类型
      * @return list
      */
-    List<MusicFavorite> getFavorite(Long userId, Long musicSheetId, ClientEnum clientType);
+    List<MusicFavorite> getFavorite(Long userId, Long musicSheetId, ClientEnum clientType,String providerType);
 
 
     /**
@@ -33,5 +33,5 @@ public interface MusicFavoriteService extends IService<MusicFavorite> {
      * @param userId 用户id
      * @param userType 用户类型 老师 学生
      */
-    YesOrNoEnum checkFavorite(Long musicSheetId, Long userId, ClientEnum userType);
+    YesOrNoEnum checkFavorite(Long musicSheetId, Long userId, ClientEnum userType,String providerType);
 }

+ 32 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicPracticeRecordService.java

@@ -0,0 +1,32 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+
+import com.yonge.cooleshow.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);
+}

+ 5 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java

@@ -123,7 +123,7 @@ public interface MusicSheetService extends IService<MusicSheet> {
      * @param clientType 客户端类型
      * @return boolean
      */
-    boolean setFavorite(Long userId, Long musicSheetId, ClientEnum clientType);
+    boolean setFavorite(Long userId, Long musicSheetId, ClientEnum clientType,String providerType);
 
     /**
      * 我的单曲
@@ -425,4 +425,8 @@ public interface MusicSheetService extends IService<MusicSheet> {
     com.microsvc.toolkit.common.response.paging.PageInfo<MusicSheetWrapper.MusicSheetApplication> tenantPage(CbsMusicSheetWrapper.MusicSheetApplicationQuery query);
 
     void delPractice(Long musicSheetId,Long userId,ClientEnum clientEnum);
+
+    CbsMusicSheetWrapper.MusicSheet cbsDetail(Long cbsMusicSheetId);
+
+    IPage<MusicSheetWrapper.MusicSheetCloud> cloudPage(MusicSheetWrapper.MusicSheetCloudQuery query);
 }

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

@@ -15,11 +15,11 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
     SysMusicCompareRecordDao getDao();
 
     /**
-     * @describe 保存用户评测记录
      * @param sysMusicCompareRecord
      * @return void
+     * @describe 保存用户评测记录
      */
-    void saveMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord);
+    Long saveMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord);
 
     /**
      * @describe 用户最后一次评测数据

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

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.biz.dal.dao.MusicFavoriteDao;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.MusicFavoriteService;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -33,22 +34,24 @@ public class MusicFavoriteServiceImpl extends ServiceImpl<MusicFavoriteDao,Music
     }
 
     @Override
-    public List<MusicFavorite> getFavorite(Long userId, Long musicSheetId, ClientEnum clientType) {
+    public List<MusicFavorite> getFavorite(Long userId, Long musicSheetId, ClientEnum clientType,String providerType) {
         return this.lambdaQuery()
                    .eq(MusicFavorite::getMusicSheetId, musicSheetId)
                    .eq(MusicFavorite::getUserId, userId)
                    .eq(MusicFavorite::getClientType, clientType)
+                   .eq(MusicFavorite::getProviderType, providerType)
                    .list();
 
     }
 
 
     @Override
-    public YesOrNoEnum checkFavorite(Long musicSheetId, Long userId, ClientEnum userType) {
+    public YesOrNoEnum checkFavorite(Long musicSheetId, Long userId, ClientEnum userType,String providerType) {
         return this.lambdaQuery()
                 .eq(MusicFavorite::getUserId,userId)
                 .eq(MusicFavorite::getMusicSheetId,musicSheetId)
                 .eq(MusicFavorite::getClientType,userType)
+                .eq(StringUtils.isNotEmpty(providerType),MusicFavorite::getProviderType, providerType)
                 .count() >0?YesOrNoEnum.YES:YesOrNoEnum.NO;
 
     }

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

@@ -0,0 +1,120 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.dao.SysMusicCompareRecordDao;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareRecord;
+import com.yonge.cooleshow.biz.dal.enums.FeatureType;
+import com.yonge.cooleshow.biz.dal.service.MusicPracticeRecordService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicPracticeRecordWrapper;
+import com.yonge.toolset.base.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 MusicSheetService 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();
+        if (sysMusicCompareRecord.getFeature() == FeatureType.CLOUD_STUDY_EVALUATION) {
+            sysMusicCompareRecordService.saveMusicCompareData(sysMusicCompareRecord);
+        } else {
+            sysMusicCompareRecordService.insert(sysMusicCompareRecord);
+        }
+
+        return String.valueOf(sysMusicCompareRecord.getId());
+    }
+
+    @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());
+
+        MusicSheet sysMusicScore = musicSheetService.getById(Integer.parseInt(userLastEvaluationData.getMusicSheetId()));
+        if(Objects.nonNull(sysMusicScore)){
+            jsonObject.put("sysMusicScoreName", sysMusicScore.getMusicSheetName());
+        }
+        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);
+    }
+}

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

@@ -16,6 +16,7 @@ import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetApplicationExtendCli
 import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
 import com.google.common.collect.Maps;
 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.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -50,6 +51,7 @@ import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nullable;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -447,8 +449,15 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             SysUser sysUser = sysUserFeignService.queryUserById(musicSheetExtend.getUserId());
             if (sysUser != null) {
                 detailVo.setUserAvatar(sysUser.getAvatar());
+                detailVo.setUserName(sysUser.getUsername());
             }
         }
+        if (musicSheet1.getScoreType() !=null) {
+            detailVo.setScoreType(musicSheet1.getScoreType().name());
+        }
+        if (musicSheet1.getIsConvertibleScore() !=null) {
+            detailVo.setNotation(musicSheet1.getIsConvertibleScore()?YesOrNoEnum.YES:YesOrNoEnum.NO);
+        }
         detailVo.setCategoryId(musicSheet1.getMusicCategoryId()!=null?musicSheet1.getMusicCategoryId().toString():"");
         detailVo.setMusicPrice(musicSheet1.getMusicPrice());
         detailVo.setSubjectNames(musicSheet1.getSubjectNames());
@@ -630,13 +639,18 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                 throw new BizException("未找到曲目信息");
             }
         }
+        boolean tenantFlag =false;
         MusicSheetDetailVo detail ;
         if (sysUser == null || userType == ClientEnum.SYSTEM) {
 
             try {
-                detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.PLATFORM);
+                if (StringUtil.isEmpty(tenantAlbumId)) {
+                    detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.PLATFORM);
+                } else {
+                    detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.TENANT);
+                }
             } catch (Exception e) {
-                detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.TENANT);
+                throw new BizException("未找到曲目信息");
             }
         } else
         if (StringUtil.isEmpty(tenantAlbumId)) {
@@ -649,12 +663,14 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             if (tenantId >0L) {
                 if (userType == ClientEnum.STUDENT) {
                     detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.TENANT);
+                    tenantFlag = true;
                 } else {
                     if (detailVo.getProviderType().contains(SourceTypeEnum.PLATFORM.getCode())) {
                         detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.PLATFORM);
 
                     } else {
                         detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.TENANT);
+                        tenantFlag = true;
                     }
                 }
 
@@ -664,6 +680,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         } else {
 
             detail = this.getCbsDetail(Long.parseLong(id),SourceTypeEnum.TENANT);
+            tenantFlag = true;
         }
         detail.setPlay(YesOrNoEnum.NO);
         detail.setTenantFlag(false);
@@ -693,7 +710,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
 
 
         // 收藏
-        YesOrNoEnum favorite = musicFavoriteService.checkFavorite(Long.parseLong(id),sysUser.getId(),userType);
+        YesOrNoEnum favorite = musicFavoriteService.checkFavorite(Long.parseLong(id),sysUser.getId(),userType,tenantFlag?"TENANT":"PLATFORM");
         detail.setFavorite(favorite);
 
         // 播放状态
@@ -726,12 +743,12 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                         // 老师所在机构启用的专辑
                         Teacher teacher = teacherService.getById(sysUser.getId());
                         if (teacher.getTenantId() >0) {
-                            List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
-                            if (musicSheetIds.contains(detail.getId())) {
-                                detail.setPlay(YesOrNoEnum.YES);
-                                detail.setBuyed(true);
-                                detail.setTenantFlag(true);
-                            }
+//                            List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
+//                            if (musicSheetIds.contains(detail.getId())) {
+//                                detail.setPlay(YesOrNoEnum.YES);
+//                                detail.setBuyed(true);
+//                                detail.setTenantFlag(true);
+//                            }
                         }
                         if (detail.getPlay() ==YesOrNoEnum.NO) {
                             platformMusicUseCheck(sysUser, userType, detail);
@@ -755,7 +772,6 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                 return detail;
             }
             // 机构专辑购买
-//            detail.setPlay(YesOrNoEnum.NO);
             List<Long> collected = Arrays.stream(tenantAlbumId.split(",")).map(Long::parseLong).collect(Collectors.toList());
 
             // 学生生效中的机构专辑
@@ -948,15 +964,8 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
     public void initMusicSheetVos(List<MusicSheetVo> records,SourceTypeEnum sourceTypeEnum) {
         if(CollectionUtils.isNotEmpty(records)){
             List<Long> cbsMusicSheetIds = records.stream().map(e -> e.getCbsMusicSheetId()).collect(Collectors.toList());
-            CbsMusicSheetWrapper.MusicSheetApplicationQuery query = this.getMusicSheetApplicationQuery(sourceTypeEnum);
-            query.setRows(cbsMusicSheetIds.size());
-            query.setMusicSheetIds(cbsMusicSheetIds);
-            List<CbsMusicSheetWrapper.MusicSheetApplication> rows = this.queryCbsMusicSheetApplication(query);
-            if(CollectionUtils.isEmpty(rows)){
-                return;
-            }
-            Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationMap = rows
-                    .stream().collect(Collectors.toMap(CbsMusicSheetWrapper.MusicSheetApplication::getId, Function.identity()));
+            Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationMap = getMusicSheetApplicationMapByCbsIds(sourceTypeEnum, cbsMusicSheetIds);
+            if (musicSheetApplicationMap == null) return;
             for (MusicSheetVo record : records) {
                 CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication = musicSheetApplicationMap.get(record.getCbsMusicSheetId());
                 if(musicSheetApplication != null){
@@ -967,6 +976,20 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
 
     }
 
+    @Nullable
+    private Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> getMusicSheetApplicationMapByCbsIds(SourceTypeEnum sourceTypeEnum, List<Long> cbsMusicSheetIds) {
+        CbsMusicSheetWrapper.MusicSheetApplicationQuery query = this.getMusicSheetApplicationQuery(sourceTypeEnum);
+        query.setRows(cbsMusicSheetIds.size());
+        query.setMusicSheetIds(cbsMusicSheetIds);
+        List<CbsMusicSheetWrapper.MusicSheetApplication> rows = this.queryCbsMusicSheetApplication(query);
+        if(CollectionUtils.isEmpty(rows)){
+            return null;
+        }
+        Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationMap = rows
+                .stream().collect(Collectors.toMap(CbsMusicSheetWrapper.MusicSheetApplication::getId, Function.identity()));
+        return musicSheetApplicationMap;
+    }
+
     @Override
     public IPage<MusicSheetVo> selectStudentPage(IPage<MusicSheetVo> page, StudentMusicSheetSearch query, ClientEnum clientType) {
         List<MusicSheetVo> records = baseMapper.selectStudentMusicPage(page, query, clientType);
@@ -983,6 +1006,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                                                                 .eq(MusicFavorite::getUserId, query.getStudentId())
                                                                 .eq(MusicFavorite::getClientType, clientType)
                                                                 .in(MusicFavorite::getMusicSheetId, musicIdList)
+                                                                .in(MusicFavorite::getProviderType, "PLATFORM" )
                                                                 .list();
                 if (CollectionUtils.isNotEmpty(musicFavoriteList)) {
                     Set<Long> set = musicFavoriteList.stream()
@@ -1025,14 +1049,15 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean setFavorite(Long userId, Long musicSheetId, ClientEnum clientType) {
-        List<MusicFavorite> musicFavorites = musicFavoriteService.getFavorite(userId, musicSheetId, clientType);
+    public boolean setFavorite(Long userId, Long musicSheetId, ClientEnum clientType,String providerType) {
+        List<MusicFavorite> musicFavorites = musicFavoriteService.getFavorite(userId, musicSheetId, clientType,providerType);
         if (CollectionUtils.isEmpty(musicFavorites)) {
             MusicFavorite musicFavorite = new MusicFavorite();
             musicFavorite.setMusicSheetId(musicSheetId);
             musicFavorite.setClientType(clientType);
             musicFavorite.setUserId(userId);
             musicFavorite.setFavoriteTime(new Date());
+            musicFavorite.setProviderType(providerType);
             musicSheetDao.updateFavoriteCount(musicSheetId,YesOrNoEnum.YES);
             return musicFavoriteService.save(musicFavorite);
         } else {
@@ -1067,6 +1092,24 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         List<MusicSheetVo> records = baseMapper.selectFavoriteMusicPage(page, query, clientType);
 
         if (CollectionUtils.isNotEmpty(records)) {
+
+            // 设置收藏来源
+            // 曲目ID集合
+
+            /*
+曲目1:既在机构也在平台,只收藏了平台,则进入是平台,
+曲目1:既在机构也在平台,只收藏了机构,则进入是机构
+曲目1:既在机构也在平台,又收藏了机构也收藏了平台,则进入是平台
+曲目1:只在机构,收藏在机构,则进入是机构
+曲目1:只在平台,收藏在平台,则进入是平台
+             */
+            for (MusicSheetVo record : records) {
+                if (record.getFavoriteProviderType().contains("PLATFORM")) {
+                    record.setFavoriteProviderType("PLATFORM");
+                }
+            }
+
+
             this.initMusicSheetVos(records);
 
             // 更新曲目专辑数量
@@ -1524,7 +1567,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             }
 
             // 曲目收藏
-            List<MusicFavorite> favorite = musicFavoriteService.getFavorite(sysUser.getId(), detail.getId(), clientType);
+            List<MusicFavorite> favorite = musicFavoriteService.getFavorite(sysUser.getId(), detail.getId(), clientType,"PLATFORM");
             if (!CollectionUtils.isEmpty(favorite)) {
                 musicSheetWebsiteDetailVo.setFavorite(YesOrNoEnum.YES);
             }
@@ -2571,6 +2614,51 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         baseMapper.delPractice(musicSheetId,userId,clientEnum);
     }
 
+
+    /**
+     * @param musicSheetId 业务端曲目ID
+     * @return CbsMusicSheetWrapper.MusicSheet
+     */
+    @Override
+    public CbsMusicSheetWrapper.MusicSheet cbsDetail(Long cbsMusicSheetId) {
+        try {
+
+            R<CbsMusicSheetWrapper.MusicSheet> musicSheetR = musicFeignClientService.musicSheetDetail(cbsMusicSheetId , applicationId);
+
+            return musicSheetR.feignData();
+        } catch (Exception e) {
+            log.error("调用音乐服务异常", e);
+            throw new BizException("内容平台服务异常");
+        }
+    }
+
+    @Override
+    public IPage<MusicSheetWrapper.MusicSheetCloud> cloudPage(MusicSheetWrapper.MusicSheetCloudQuery query) {
+        IPage<MusicSheetWrapper.MusicSheetCloud> musicSheetCloudIPage = musicSheetDao.cloudPage(QueryInfo.getPage(query), query);
+        List<MusicSheetWrapper.MusicSheetCloud> records = musicSheetCloudIPage.getRecords();
+        if (CollectionUtils.isEmpty(records)) {
+            return musicSheetCloudIPage;
+        }
+        List<Long> musicSheetIds = records.stream()
+                .map(MusicSheetWrapper.MusicSheetCloud::getCbsMusicSheetId)
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+
+        Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationMapByCbsIds = getMusicSheetApplicationMapByCbsIds(query.getProviderType(), musicSheetIds);
+        if (musicSheetApplicationMapByCbsIds == null) {
+            return musicSheetCloudIPage;
+        }
+        records = records.stream().map(o->{
+            CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication = musicSheetApplicationMapByCbsIds.get(Long.parseLong(o.getCbsMusicSheetId()));
+            if (musicSheetApplication != null) {
+                o.setTitleImg(musicSheetApplication.getMusicCover());
+            }
+            return o;
+        }).collect(Collectors.toList());
+        musicSheetCloudIPage.setRecords(records);
+        return musicSheetCloudIPage;
+    }
+
     private Map<Long,MusicSheet> getMapByCbsIds(List<Long> cbsMusicSheetIds) {
         if (CollectionUtils.isEmpty(cbsMusicSheetIds)) {
             return new HashMap<>();

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

@@ -143,6 +143,16 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
                     detail.setUserStatus(UserStatusEnum.NORMAL);
                 }
             }
+
+            // 设置学生声部乐器ID
+            if (StringUtils.isNotBlank(detail.getSubjectId())) {
+                List<Subject> subjects = subjectDao.findBySubjectByIdList(detail.getSubjectId());
+                // 设置声部乐器
+                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(subjects)) {
+                    detail.setInstrumentId(subjects.stream()
+                        .map(Subject::getInstrumentId).filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining(",")));
+                }
+            }
         }
         return detail;
     }

+ 8 - 9
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMusicCompareRecordServiceImpl.java

@@ -239,20 +239,19 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 
 	@Override
 	@Transactional
-	public void saveMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord) {
+	public Long saveMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord) {
 		Long tenant = sysUserService.getTenantByClient(sysMusicCompareRecord.getUserId(), sysMusicCompareRecord.getClientId());
 		sysMusicCompareRecord.setTenantId(tenant);
-		int record = sysMusicCompareRecordDao.update(sysMusicCompareRecord);
+        sysMusicCompareRecordDao.insert(sysMusicCompareRecord);
 
-		if (record > 0) {
-			SysMusicCompareRecord info = sysMusicCompareRecordDao.get(sysMusicCompareRecord.getId());
+        SysMusicCompareRecord info = sysMusicCompareRecordDao.get(sysMusicCompareRecord.getId());
 
-			if (Objects.nonNull(info)) {
+        if (Objects.nonNull(info)) {
 
-				// 生成曲目评测统计数据
-				saveMusicCompareRecordStatInfo(info);
-			}
-		}
+            // 生成曲目评测统计数据
+            saveMusicCompareRecordStatInfo(info);
+        }
+        return sysMusicCompareRecord.getId();
 	}
 
 	@Override

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

@@ -151,6 +151,7 @@ public class TenantAlbumMusicServiceImpl extends ServiceImpl<TenantAlbumMusicMap
                     .in(MusicFavorite::getMusicSheetId, musicSheetIds)
                     .eq(MusicFavorite::getUserId, query.getUserId())
                     .eq(MusicFavorite::getClientType, query.getClientType().equals(ClientEnum.TENANT_STUDENT) ? ClientEnum.STUDENT : query.getClientType())
+                    .eq(MusicFavorite::getProviderType,"TENANT")
                     .list();
                 favoriteIds = favoriteList.stream().map(MusicFavorite::getMusicSheetId).distinct().collect(Collectors.toList());
             }

+ 11 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserMusicServiceImpl.java

@@ -73,6 +73,7 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
     @Autowired
     private VipCardRecordService vipCardRecordService;
 
+    private static  final List<String> videoList = Lists.newArrayList(".mp4");
 
     /**
      * 查询详情
@@ -187,11 +188,20 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
             }
         }
 
+        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 (!com.alipay.service.schema.util.StringUtil.isEmpty(entity.getVideoUrl())) {
+            if (videoList.stream().noneMatch(entity.getVideoUrl()::endsWith)) {
+                entity.setFileType("AUDIO");
+            } else {
+                entity.setFileType("VIDEO");
+            }
         }
         userMusicService.saveOrUpdate(entity);
         return entity.getId();

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

@@ -299,14 +299,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     private void userOrderDetail( UserOrderVo userOrderVo) {
         if (null != userOrderVo) {
 
-            // 计算优惠券金额
-            CouponOrderWrapper couponOrderWrapper  = couponInfoService.queryUserOrderCouponInfo(userOrderVo.getUserId(),
-                    CouponInfoQuery.CouponOrderQuery.builder()
-                            .clientType(userOrderVo.getOrderClient())
-                            .orderNo(userOrderVo.getOrderNo())
-                            .amount(userOrderVo.getExpectPrice().doubleValue())
-                            .build());
-            userOrderVo.setDiscountPrice(BigDecimal.valueOf(couponOrderWrapper.getDiscountedPrices()));
+            userOrderVo.setDiscountPrice(BigDecimal.ZERO);
 
             List<UserOrderDetailVo> userOrderDetailVos = getUserOrderDetailVos(Lists.newArrayList(userOrderVo.getOrderNo()));
 
@@ -316,12 +309,15 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             }
             userOrderDetailVos.forEach(o -> {
                 if (StringUtils.isNotBlank(o.getDiscountJson())) {
-
                     Map<String,BigDecimal> decimalMap = JSON.parseObject(o.getDiscountJson(), Map.class);
                     BigDecimal bigDecimal = decimalMap.get(EDiscountType.DISCOUNT.name());
                     if (bigDecimal != null) {
                         userOrderVo.setCardDiscountPrice(userOrderVo.getCardDiscountPrice().add(bigDecimal));
                     }
+                    BigDecimal couponDecimal = decimalMap.get(EDiscountType.COUPON.name());
+                    if (couponDecimal != null) {
+                        userOrderVo.setDiscountPrice(userOrderVo.getDiscountPrice().add(couponDecimal));
+                    }
                 }
             });
 

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

@@ -603,6 +603,10 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             .map(UserOrderDetail::getActualPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
+        if (couponAmount.compareTo(currentPrice) >0) {
+            couponAmount = currentPrice;
+        }
+
 
         orderReq.originalPrice(originalPrice.setScale(2, RoundingMode.HALF_UP))
             .currentPrice(currentPrice.setScale(2, RoundingMode.HALF_UP))

+ 33 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetVo.java

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 /**
  * Description
@@ -53,4 +54,36 @@ public class MusicSheetVo extends MusicSheet {
     @ApiModelProperty("所属人信息")
     private CbsMusicSheetWrapper.MusicSheetExtend musicSheetExtend;
 
+    @ApiModelProperty("收藏来源")
+    private String favoriteProviderType;
+
+
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class MusicSheetDetail extends CbsMusicSheetWrapper.MusicSheet {
+
+        @ApiModelProperty("收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)")
+        private String paymentType;
+
+        @ApiModelProperty("是否可转谱(0:否; 1:是)")
+        private Boolean isConvertibleScore;
+
+        @ApiModelProperty("谱面类型")
+        private String scoreType;
+
+        @ApiModelProperty("是否是特殊打击乐")
+        private Boolean specialPercussionFlag;
+
+
+        @ApiModelProperty("是否能播放(0:否,1:是) 学生端进入小酷Ai判断 试用/完整 播放")
+        private YesOrNoEnum play;
+
+        @ApiModelProperty("是否购买(0:否,1:是)")
+        private Boolean buyed = false;
+
+        @ApiModelProperty(value = "曲谱价格")
+        private java.math.BigDecimal musicPrice;  //曲谱价格
+
+    }
+
 }

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentHomeVo.java

@@ -103,6 +103,9 @@ public class StudentHomeVo extends Student {
     @ApiModelProperty("客服数量")
     private Integer customerServiceNum;
 
+    @ApiModelProperty(value = "总控乐器ID")
+    private String instrumentId;
+
     public YesOrNoEnum getTenantAlbumFlag() {
         return tenantAlbumFlag;
     }

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/StudentVo.java

@@ -103,6 +103,9 @@ public class StudentVo extends Student {
     @ApiModelProperty("客服数量")
     private Integer customerServiceNum;
 
+    @ApiModelProperty(value = "总控乐器ID")
+    private String instrumentId;
+
     public YesOrNoEnum getDelFlag() {
         return delFlag;
     }

+ 566 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/MusicPracticeRecordWrapper.java

@@ -0,0 +1,566 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareRecord;
+import com.yonge.cooleshow.biz.dal.enums.DeviceTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.FeatureType;
+import com.yonge.cooleshow.biz.dal.enums.HeardLevelEnum;
+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.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("曲目评测来源 TENANT 机构 PLATFORM 平台")
+        private String providerType;
+
+        @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("yyyyMMdd")));
+        }
+
+
+        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;
+
+
+        @ApiModelProperty("曲目评测来源 TENANT 机构 PLATFORM 平台")
+        private String providerType;
+
+        public static Entity toEntity(SysMusicCompareRecord record) {
+            if (record ==null) {
+                return null;
+            }
+            return Entity.builder()
+                .id(record.getId().toString())
+                .userId(Optional.ofNullable(record.getUserId()).orElse(0L).toString())
+                .clientType(record.getClientId()!=null?record.getClientId().toUpperCase():null)
+                .musicSheetId(record.getMusicSheetId()!=null? record.getMusicSheetId().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())
+                .providerType(record.getProviderType())
+                .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?Long.parseLong(this.userId):null);
+            sysMusicCompareRecord.setMusicSheetId(this.musicSheetId!=null?Long.parseLong(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);
+            sysMusicCompareRecord.setProviderType(this.providerType ==null?"PLATFORM":this.providerType);
+
+            return sysMusicCompareRecord;
+
+        }
+    }
+}

+ 129 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/MusicSheetWrapper.java

@@ -15,6 +15,7 @@ import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheetAccompaniment;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.util.StringUtil;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
@@ -934,4 +935,132 @@ public class MusicSheetWrapper {
         @ApiModelProperty("类型")
         private String subjectType;
     }
+
+
+    @Data
+    public static class MusicSheetCloud {
+
+        @ApiModelProperty("主键")
+        private String id;
+
+        @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;
+
+        @ApiModelProperty(value = "曲谱价格")
+        private java.math.BigDecimal musicPrice;  //曲谱价格
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheet from(String json) {
+            return JSON.parseObject(json, MusicSheet.class);
+        }
+    }
+
+    @Data
+    public static class MusicSheetCloudQuery implements QueryInfo {
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+        private String keyword;
+        private Long musicSheetId;
+        @ApiModelProperty("仅匹配资源名称")
+        private String name;
+
+        @ApiModelProperty("曲目乐器Id")
+        private Long musicalInstrumentId;
+
+        @ApiModelProperty(value = "删除标识", hidden = true)
+        private Boolean delFlag;
+
+        @ApiModelProperty(value = "启用停用标识,曲目状态(0:停用,1:启用)")
+        private Boolean status;
+
+        @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(value = "必须要匹配声部ID")
+        private List<Long> mustMatchSubjectIds;
+
+        @ApiModelProperty("是否查看收藏")
+        private Boolean favoriteFlag = false;
+
+        @ApiModelProperty("最近练习 当前曲目ID")
+        private Long excludeMusicId;
+
+        @ApiModelProperty("app版本")
+        private String version;
+
+        @ApiModelProperty("platform")
+        private String platform;
+
+        @ApiModelProperty("id集合")
+        private List<Long> ids;
+
+        private Long albumId;
+
+        private Long subjectId;
+
+        @ApiModelProperty("可用机构专辑ID集合")
+        private List<Long> tenantAlbumIds;
+
+        private MusicSheetTypeEnum musicSheetType;
+
+        // 是否为机构学生用户
+        @ApiModelProperty(value = "提供方 TENANT 机构 PLATFORM 平台")
+        private SourceTypeEnum providerType;
+
+        @ApiModelProperty("标签id(多个逗号隔开)")
+        private String musicTagIds;
+
+        @ApiModelProperty(hidden = true)
+        private List<Long> musicTagIdList;
+
+        public void setMusicTagIds(String musicTagIds) {
+            this.musicTagIds = musicTagIds;
+            if (StringUtils.isNotBlank(musicTagIds)) {
+                this.musicTagIdList = StringUtil.toLongList(musicTagIds);
+            }
+        }
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheetQuery from(String json) {
+            return JSON.parseObject(json, MusicSheetQuery.class);
+        }
+    }
 }

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantGroupAlbumWrapper.java

@@ -180,6 +180,9 @@ public class TenantGroupAlbumWrapper {
 
     }
     @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
     @ApiModel(" BuyTenantAlbumQuery-可购买机构专辑信息查询")
     public static class BuyTenantAlbumQuery {
 

+ 17 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicWrapper.java

@@ -53,6 +53,14 @@ public class UserMusicWrapper {
         private Long id;
 
 
+        @ApiModelProperty("文件类型 音频 AUDIO,视频:VIDEO")
+        private String fileType;
+
+
+        @ApiModelProperty("关联练习数据ID")
+        private Long musicPracticeRecordId;
+
+
         @ApiModelProperty(value = "去除的ID,推荐作品列表需要去除原本作品")
         private Long exclusionId;
 
@@ -142,6 +150,10 @@ public class UserMusicWrapper {
         @ApiModelProperty("视频地址")
         private String videoUrl;
 
+        @ApiModelProperty("文件类型") // .mp4 视频,其他为音频
+        private String fileType;
+
+
         @ApiModelProperty("视频封面图")
         private String videoImg;
 
@@ -166,6 +178,9 @@ public class UserMusicWrapper {
 
         @ApiModelProperty("发布作品时间")
         private Date submitTime;
+        @ApiModelProperty("是否能被看到评级、评分字段")
+        private Boolean selectFlag;
+
 
         @ApiModelProperty("录制上传时间")
         private Date createTime;
@@ -225,6 +240,8 @@ public class UserMusicWrapper {
         @ApiModelProperty("json配置")
         private String jsonConfig;
 
+        @ApiModelProperty("是否能被看到评级、评分字段")
+        private Boolean selectFlag;
     }
 
 }

+ 155 - 7
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml

@@ -591,9 +591,10 @@
     </select>
 
     <select id="selectFavoriteMusicPage" resultType="com.yonge.cooleshow.biz.dal.vo.MusicSheetVo">
-        select <include refid="Base_Column_List"/>
+        select distinct <include refid="Base_Column_List"/>
         ,su.username_ as addName
         ,su.avatar_ as addUserAvatar
+        ,group_concat(mf.provider_type_) as favoriteProviderType
         ,(select group_concat(mt.name_) from music_tag mt
         where find_in_set(mt.id_,t.music_tag_) and mt.del_flag_ = 0  and mt.state_ = 1) as musicTagNames
         ,(select group_concat(s.name_) from subject s
@@ -602,9 +603,6 @@
         from music_sheet t
         left join sys_user su on t.create_by_ = su.id_
         left join music_favorite mf on t.id_ = mf.music_sheet_id_
-        <if test="param.auditStatus != null">
-            left join music_sheet_auth_record msar ON msar.music_sheet_id_ = t.id_
-        </if>
         <where>
 
             mf.client_type_ = #{clientType}
@@ -629,9 +627,7 @@
                 and mf.user_id_ = #{param.studentId}
             </if>
         </where>
-        <if test="param.auditStatus != null">
-            group by msar.music_sheet_id_
-        </if>
+        group by t.id_
         order by mf.id_ desc
     </select>
 
@@ -1380,5 +1376,157 @@
         limit #{param.rows}
 
     </select>
+
+    <select id="cloudPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper$MusicSheetCloud">
+        select t.id_, t.music_sheet_name_,t.title_img_,t.composer_,t.cbs_music_sheet_id_ ,t.payment_type_,t.music_price_ as musicPrice
+        from (
+        select a.* from
+        music_sheet a
+        <if test="param.providerType != null and param.providerType.code == 'TENANT'">
+            left join tenant_album_music tam on a.id_ = tam.music_sheet_id_ and tam.del_flag_ = 0 and tam.tenant_album_id_ in
+            <foreach collection="param.tenantAlbumIds" item="item" open="(" close=")" separator=",">
+                #{item}
+            </foreach>
+        </if>
+        <where>
+            a.cbs_music_sheet_id_ is not null
+            <if test="param.providerType != null and param.providerType.code == 'TENANT'">
+               and tam.id_ is not null
+            </if>
+            <if test="param.name != null and param.name != ''">
+                and a.music_sheet_name_ like concat('%',#{param.name},'%')
+            </if>
+            <if test="param.status != null">
+
+                <if test="param.providerType != null">
+                    <if test="param.providerType.code == 'TENANT'">
+                        and a.tenant_state_ = #{param.status}
+                    </if>
+
+                    <if test="param.providerType.code == 'PLATFORM'">
+                        and a.state_ = #{param.status}
+                    </if>
+                </if>
+
+                <if test="param.providerType == null">
+                    and a.state_ = #{param.status}
+                </if>
+            </if>
+            <if test="param.delFlag != null">
+                <if test="param.providerType != null">
+                    <if test="param.providerType.code == 'TENANT'">
+                        and a.tenant_del_flag_ = #{param.delFlag}
+                    </if>
+
+                    <if test="param.providerType.code == 'PLATFORM'">
+                        and a.del_flag_ = #{param.delFlag}
+                    </if>
+                </if>
+
+                <if test="param.providerType == null">
+                    and a.del_flag_ = #{param.delFlag}
+                </if>
+
+            </if>
+            <if test="param.versionFlag != null">
+                and a.audit_version_ = #{param.versionFlag}
+            </if>
+
+            <if test="param.mustMatchSubjectIds != null and param.mustMatchSubjectIds.size() != 0">
+                and
+                <foreach collection="param.mustMatchSubjectIds" separator="and" item="item" open="(" close=")">
+                    find_in_set(#{item},a.music_subject_)
+                </foreach>
+            </if>
+            <if test="param.excludeMusicId != null">
+                and a.id_ != #{param.excludeMusicId}
+            </if>
+            <if test="param.ids != null and param.ids.size() != 0">
+                and a.id_ in
+                <foreach collection="param.ids" item="item" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+
+
+            <if test="param.providerType != null and param.providerType.code == 'TENANT'">
+                <if test="param.albumId != null">
+                    and tam.tenant_album_id_ = #{param.albumId}
+                    and tam.subject_type_ in ('ENSEMBLE', 'MUSIC', 'SUBJECT')
+                </if>
+                <if test="param.albumId == null and (param.recentFlag == null or param.recentFlag == 0) and (param.favoriteFlag == null or param.favoriteFlag == 0)">
+                    and 1=2
+                </if>
+            </if>
+            <if test="param.providerType != null">
+                and find_in_set(#{param.providerType},a.provider_type_)
+            </if>
+            <if test="param.musicSheetType != null">
+                and a.music_sheet_type_ = #{param.musicSheetType}
+            </if>
+            <if test="param.subjectId != null">
+                and (find_in_set(#{param.subjectId},a.music_subject_)or a.music_subject_ is null or a.music_subject_ = '' OR a.is_all_subject_)
+            </if>
+            <if test="param.musicTagIdList != null and param.musicTagIdList.size() >0">
+                and
+                <foreach collection="param.musicTagIdList" open="(" close=")" separator="or" item="item">
+                    find_in_set(#{item},a.music_tag_)
+                </foreach>
+            </if>
+        </where>
+        ) t
+        <if test="param.recentFlag != null and param.recentFlag == 1">
+            left join sys_music_compare_record msar on t.id_ = msar.music_sheet_id_ and msar.provider_type_ = #{param.providerType}
+        </if>
+        <if test="param.albumId != null and param.providerType.code == 'TENANT'">
+            left join tenant_album_music tam on t.id_ = tam.music_sheet_id_ and tam.del_flag_ = 0  and tam.tenant_album_id_ = #{param.albumId}
+        </if>
+
+        <if test="param.albumId != null and param.providerType.code == 'PLATFORM'">
+            left join album_music_relate amr on t.id_ = amr.music_sheet_id_ and amr.album_id_ = #{param.albumId}
+        </if>
+        <if test="param.favoriteFlag != null and param.favoriteFlag == 1">
+            left join music_favorite mf on t.id_ = mf.music_sheet_id_ and mf.user_id_ = #{param.userId} and mf.client_type_ = #{param.clientType} and mf.provider_type_ = #{param.providerType}
+        </if>
+        <where>
+
+            <if test="param.favoriteFlag != null and param.favoriteFlag == 1">
+                and mf.id_ is not null
+            </if>
+
+            <if test="param.recentFlag != null and param.recentFlag == 1">
+                <if test="param.userId != null">
+                    and msar.user_id_ = #{param.userId}
+                </if>
+                <if test="param.clientType != null and param.clientType != ''">
+                    and msar.client_id_ = #{param.clientType}
+                </if>
+            </if>
+
+            <if test="param.providerType != null and param.providerType.code == 'PLATFORM'">
+                <if test="param.albumId != null">
+                    and amr.id_ is not null
+                </if>
+
+            </if>
+
+        </where>
+
+        GROUP BY t.id_
+        order by
+        <if test="param.recentFlag !=null and param.recentFlag == true">
+            max(msar.create_time_) desc,
+        </if>
+        <if test="param.favoriteFlag != null and param.favoriteFlag == 1">
+            mf.id_ desc,
+        </if>
+
+        t.sort_group_, t.sort_num_, t.sort_num2_, t.alias_
+    </select>
+    <select id="selectMusicAlbumNum" resultType="java.lang.Long">
+        SELECT COUNT(DISTINCT t1.id_) AS total
+        FROM album_music_relate t1 JOIN music_sheet t2 ON (t1.music_sheet_id_ = t2.id_)
+        WHERE t1.music_sheet_id_ = #{musicId}
+    </select>
     <!--单曲专辑数量统计-->
 </mapper>

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

@@ -17,6 +17,7 @@
         <result column="create_time_" property="createTime"/>
         <result column="update_time_" property="updateTime"/>
         <result column="del_flag_" property="delFlag"/>
+        <result column="instrument_id_" property="instrumentId"/>
     </resultMap>
 
     <!-- 根据主键查询一条记录 -->

+ 41 - 4
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml

@@ -30,8 +30,17 @@
 		<result column="monday_" property="monday"/>
 		<result column="create_time_" property="createTime" />
 		<result column="part_index_" property="partIndex" />
-		<result column="custom_configuration_" property="customConfiguration" />
 		<result column="tenant_id_" property="tenantId" />
+        <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"/>
+        <result column="provider_type_" property="providerType"/>
 	</resultMap>
 
 	<!-- 根据主键查询一条记录 -->
@@ -48,11 +57,13 @@
 	<insert id="insert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysMusicCompareRecord" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
 		INSERT INTO sys_music_compare_record (id_,user_id_,music_sheet_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_,update_time_,part_index_,custom_configuration_,tenant_id_)
+												source_time_,feature_,create_time_,update_time_,part_index_,custom_configuration_,tenant_id_,
+        practice_time_,practice_source_,result_analyze_,headphone_flag_,instrument_id_,hidden_flag_,del_flag_,play_rate_,provider_type_)
 		VALUES(#{id},#{userId},#{musicSheetId},#{heardLevel,typeHandler=com.yonge.toolset.mybatis.dal.CustomEnumTypeHandler},#{behaviorId},#{scoreData},
 		       #{score},#{intonation},#{cadence},#{integrity},
 		       #{recordFilePath},#{videoFilePath},#{deviceType,typeHandler=com.yonge.toolset.mybatis.dal.CustomEnumTypeHandler},#{clientId},#{playTime},#{speed},#{monday},
-		       #{sourceTime},#{feature,typeHandler=com.yonge.toolset.mybatis.dal.CustomEnumTypeHandler}, NOW(), NOW(),#{partIndex},#{customConfiguration},#{tenantId})
+		       #{sourceTime},#{feature,typeHandler=com.yonge.toolset.mybatis.dal.CustomEnumTypeHandler}, NOW(), NOW(),#{partIndex},#{customConfiguration},#{tenantId},
+        #{practiceTime},#{practiceSource},#{resultAnalyze},#{headphoneFlag},#{instrumentId},#{hiddenFlag},#{delFlag},#{playRate},#{providerType})
 	</insert>
 
 	<!-- 根据主键查询一条记录 -->
@@ -117,7 +128,33 @@
 		</if>
 		<if test="heardLevel!=null">
 			heard_level_ = #{heardLevel,typeHandler=com.yonge.toolset.mybatis.dal.CustomEnumTypeHandler},
-		</if>
+		</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} 
 	</update>

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

@@ -19,6 +19,8 @@
         t.json_config_,
         t.like_num_,
         t.submit_time_,
+        t.select_flag_,
+        t.file_type_ ,
         t.update_time_ as createTime
 		FROM user_music t
         left join music_sheet t1 on t1.id_ = t.music_sheet_id_
@@ -42,6 +44,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