刘俊驰 5 місяців тому
батько
коміт
7e6bdccbd3
21 змінених файлів з 1375 додано та 26 видалено
  1. 134 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/MusicPracticeRecordController.java
  2. 98 7
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java
  3. 15 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicController.java
  4. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetDao.java
  5. 16 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMusicCompareRecord.java
  6. 12 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusic.java
  7. 34 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/FeatureType.java
  8. 32 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicPracticeRecordService.java
  9. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  10. 2 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMusicCompareRecordService.java
  11. 120 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicPracticeRecordServiceImpl.java
  12. 33 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  13. 8 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMusicCompareRecordServiceImpl.java
  14. 11 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserMusicServiceImpl.java
  15. 29 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetVo.java
  16. 558 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/MusicPracticeRecordWrapper.java
  17. 102 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/MusicSheetWrapper.java
  18. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicWrapper.java
  19. 100 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml
  20. 40 4
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  21. 8 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserMusicMapper.xml

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

@@ -0,0 +1,134 @@
+package com.yonge.cooleshow.student;
+
+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.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;
+
+    /**
+     * 查询单条
+     * @param id 详情ID
+     * @return R<MusicPracticeRecordVo.MusicPracticeRecord>
+     */
+    @ApiOperation(value = "详情", notes = "曲目练习记录-根据详情ID查询单条, 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public R<MusicPracticeRecordWrapper.MusicPracticeRecord> detail(@PathVariable("id") Long id) {
+
+        MusicPracticeRecordWrapper.Entity wrapper = musicPracticeRecordService.detail(id);
+
+        if (wrapper == null) {
+            throw new BizException("记录不存在");
+        }
+
+        // 上传过作品,用作品视频路径覆盖上传视频路径
+        // ID集合
+        Map<Long, UserMusic> userMusicMap = userMusicService.getMapByMusicPracticeRecordIds(Lists.newArrayList(Long.parseLong(wrapper.getId())));
+
+        UserMusic userMusic = userMusicMap.get(Long.parseLong(wrapper.getId()));
+        if (Objects.nonNull(userMusic)) {
+            wrapper.setVideoFilePath(userMusic.getVideoUrl());
+        }
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(JSON.toJSONString(wrapper));
+
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(Long.parseLong(wrapper.getMusicSheetId()));
+        if (musicSheet != null) {
+            from.setRhythmFlag(musicSheet.getEvaluationStandard() != EEvaluationStandard.FREQUENCY);
+        }
+
+        return R.from(from);
+    }
+
+
+    /**
+     * 新增
+     * @param record MusicPracticeRecordVo.MusicPracticeRecord
+     * @return R<Boolean>
+     */
+    @ApiOperation(value = "新增", notes = "曲目练习记录- 传入 MusicPracticeRecordVo.MusicPracticeRecord")
+    @PostMapping("/save")
+    public R<String> add( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record) {
+
+        Long userId = sysUserService.getUserId();
+        record.userId(String.valueOf(userId)).clientType(ClientEnum.STUDENT.getCode());
+
+        // 新增数据
+        MusicPracticeRecordWrapper.MusicPracticeRecord from = MusicPracticeRecordWrapper.MusicPracticeRecord.from(record.jsonString());
+        if (record.getDelFlag() !=null && record.getDelFlag()) {
+            from.setDelFlag(false);
+            from.setHiddenFlag(true);
+        }
+
+        return R.from(musicPracticeRecordService.add(from));
+    }
+
+    @ApiOperation(value = "用户最后一次评测数据")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "recordId", value = "曲目练习记录Id", dataType = "long")
+    })
+    @GetMapping("/getLastEvaluationMusicalNotesPlayStats")
+    public Object getLastEvaluationMusicalNotesPlayStats(Long recordId){
+        return R.from(musicPracticeRecordService.getLastEvaluationMusicalNotesPlayStats(recordId));
+    }
+
+    @ApiOperation(value = "上传音频文件")
+    @PostMapping("videoUpload")
+    public R<Boolean> videoUpload( @RequestBody MusicPracticeRecordWrapper.MusicPracticeRecord record){
+
+        if (Objects.isNull(record.getId())) {
+            throw BizException.from("recordId不能为空");
+        }
+        if (Objects.isNull(record.getVideoFilePath())) {
+            throw BizException.from("videoUrl不能为空");
+        }
+
+        MusicPracticeRecordWrapper.Entity practiceRecord = musicPracticeRecordService.getById(record.getId());
+        if (Objects.isNull(practiceRecord)) {
+            throw BizException.from("记录不存在");
+        }
+
+        practiceRecord.setVideoFilePath(record.getVideoFilePath());
+        musicPracticeRecordService.update(practiceRecord);
+
+        return R.from(true);
+    }
+
+}

+ 98 - 7
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;
 
     /**
      * 查询单条
@@ -491,4 +495,91 @@ public class MusicSheetController extends BaseController {
     }
 
 
+
+    /**
+     * 查询单条
+     *
+     * @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) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            sysUser = null;
+        }
+        CbsMusicSheetWrapper.MusicSheet musicSheet = musicSheetService.cbsDetail(id);
+        musicSheet.setBizId(id);
+
+        MusicSheetVo.MusicSheetDetail musicSheetDetail = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetVo.MusicSheetDetail.class);
+        MusicSheetDetailVo detail = musicSheetService.detail(id.toString(), sysUser, ClientEnum.STUDENT, null);
+        if (detail == null) {
+//            musicSheetDetail.setBizMusicCategoryId(null);
+        } else {
+            // 设置曲目付费类型
+            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());
+        }
+
+        // 如果是合奏 并且乐器ID = 2268
+        musicSheetDetail.setSpecialPercussionFlag(false);
+
+        // 设置乐器信息
+        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 = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        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);
+
+        // 如果是机构学生
+        if (student.getTenantId() !=null && student.getTenantId()>0) {
+            query.setProviderType(SourceTypeEnum.TENANT);
+        } else {
+            query.setProviderType(SourceTypeEnum.PLATFORM);
+        }
+        IPage<MusicSheetWrapper.MusicSheetCloud> musicSheetCloudIPage = musicSheetService.cloudPage(query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(musicSheetCloudIPage));
+    }
 }

+ 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));
+    }
 }

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

@@ -229,4 +229,6 @@ public interface MusicSheetDao extends BaseMapper<MusicSheet> {
     void delPractice(@Param("musicSheetId") Long musicSheetId, @Param("userId") Long userId, @Param("clientEnum") ClientEnum clientEnum);
 
     int countTeacherEnable(@Param("userId") Long userId);
+
+    IPage<MusicSheetWrapper.MusicSheetCloud> cloudPage(@Param("page") IPage<Object> page, @Param("param") MusicSheetWrapper.MusicSheetCloudQuery query);
 }

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

@@ -92,6 +92,22 @@ 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;
 	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";
+        }
+    }
 }

+ 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);
+}

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

@@ -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 musicSheetId);
+
+    IPage<MusicSheetWrapper.MusicSheetCloud> cloudPage(MusicSheetWrapper.MusicSheetCloudQuery query);
 }

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

@@ -14,11 +14,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 用户最后一次评测数据

+ 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);
+    }
+}

+ 33 - 0
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;
@@ -2571,6 +2572,38 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         baseMapper.delPractice(musicSheetId,userId,clientEnum);
     }
 
+
+    /**
+     * @param musicSheetId 业务端曲目ID
+     * @return CbsMusicSheetWrapper.MusicSheet
+     */
+    @Override
+    public CbsMusicSheetWrapper.MusicSheet cbsDetail(Long musicSheetId) {
+        // 曲目信息
+        MusicSheet musicSheet = getDao().get(musicSheetId);
+        if (Objects.isNull(musicSheet)) {
+            throw new BizException("曲目信息不存在");
+        }
+
+
+        if (musicSheet.getCbsMusicSheetId() ==null) {
+            throw new BizException("曲目信息异常");
+        } try {
+
+            R<CbsMusicSheetWrapper.MusicSheet> musicSheetR = musicFeignClientService.musicSheetDetail(musicSheet.getCbsMusicSheetId() , applicationId);
+
+            return musicSheetR.feignData();
+        } catch (Exception e) {
+            log.error("调用音乐服务异常", e);
+            throw new BizException("内容平台服务异常");
+        }
+    }
+
+    @Override
+    public IPage<MusicSheetWrapper.MusicSheetCloud> cloudPage(MusicSheetWrapper.MusicSheetCloudQuery query) {
+        return musicSheetDao.cloudPage(QueryInfo.getPage(query),query);
+    }
+
     private Map<Long,MusicSheet> getMapByCbsIds(List<Long> cbsMusicSheetIds) {
         if (CollectionUtils.isEmpty(cbsMusicSheetIds)) {
             return new HashMap<>();

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

@@ -3,7 +3,6 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
-import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.MusicSheetDao;
 import com.yonge.cooleshow.biz.dal.dao.SysMusicCompareRecordDao;
 import com.yonge.cooleshow.biz.dal.dto.*;
@@ -240,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

+ 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();

+ 29 - 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,32 @@ public class MusicSheetVo extends MusicSheet {
     @ApiModelProperty("所属人信息")
     private CbsMusicSheetWrapper.MusicSheetExtend musicSheetExtend;
 
+
+
+    @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;
+
+
+    }
+
 }

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

@@ -0,0 +1,558 @@
+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("是否隐藏评测记录 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;
+
+        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())
+                .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);
+
+            return sysMusicCompareRecord;
+
+        }
+    }
+}

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

@@ -934,4 +934,106 @@ 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;
+
+        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;
+
+        @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("最近练习 当前曲目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;
+
+        private MusicSheetTypeEnum musicSheetType;
+
+        // 是否为机构学生用户
+        private SourceTypeEnum providerType;
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static MusicSheetQuery from(String json) {
+            return JSON.parseObject(json, MusicSheetQuery.class);
+        }
+    }
 }

+ 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;
     }
 
 }

+ 100 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml

@@ -1333,5 +1333,105 @@
         set hidden_flag_ = 1
         where user_id_ = #{userId} and music_sheet_id_ = #{musicSheetId} and client_id_ = #{clientEnum}
     </update>
+
+    <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_
+        from music_sheet t
+        <if test="param.recentFlag != null and param.recentFlag == 1">
+            left join sys_music_compare_record msar on t.id_ = msar.music_sheet_id_
+        </if>
+        <if test="param.albumId != null">
+            left join tenant_album_music tam on t.id_ = tam.music_sheet_id_ and tam.del_flag_ = 0
+        </if>
+        <where>
+            t.cbs_music_sheet_id_ is not null
+            <if test="param.name != null and param.name != ''">
+                and t.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 t.tenant_state_ = #{param.status}
+                    </if>
+
+                    <if test="param.providerType.code == 'PLATFORM'">
+                        and t.state_ = #{param.status}
+                    </if>
+                </if>
+
+                <if test="param.providerType == null">
+                    and t.state_ = #{param.status}
+                </if>
+            </if>
+            <if test="param.delFlag != null">
+                <if test="param.providerType != null">
+                    <if test="param.providerType.code == 'TENANT'">
+                        and t.tenant_del_flag_ = #{param.delFlag}
+                    </if>
+
+                    <if test="param.providerType.code == 'PLATFORM'">
+                        and t.del_flag_ = #{param.delFlag}
+                    </if>
+                </if>
+
+                <if test="param.providerType == null">
+                    and t.del_flag_ = #{param.delFlag}
+                </if>
+
+            </if>
+            <if test="param.versionFlag != null">
+                and t.audit_version_ = #{param.versionFlag}
+            </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.excludeMusicId != null">
+                and t.id_ != #{param.excludeMusicId}
+            </if>
+            <if test="param.ids != null and param.ids.size() != 0">
+                and t.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 1=2
+                </if>
+            </if>
+
+            <if test="param.providerType != null">
+                and find_in_set(#{param.providerType},t.provider_type_)
+            </if>
+            <if test="param.musicSheetType != null">
+                and t.music_sheet_type_ = #{param.musicSheetType}
+            </if>
+            <if test="param.subjectId != null">
+                and (find_in_set(#{param.subjectId},t.music_subject_)or t.music_subject_ is null or t.music_subject_ = '' OR t.is_all_subject_)
+            </if>
+
+        </where>
+
+        GROUP BY t.id_
+        <if test="param.recentFlag !=null and param.recentFlag == true">
+            order by
+            max(msar.create_time_) desc
+        </if>
+        <if test="param.recentFlag == null">
+            order by tam.level_,tam.type_,tam.sort_number_
+        </if>
+    </select>
     <!--单曲专辑数量统计-->
 </mapper>

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

@@ -30,8 +30,16 @@
 		<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"/>
 	</resultMap>
 
 	<!-- 根据主键查询一条记录 -->
@@ -48,11 +56,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_)
 		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})
 	</insert>
 
 	<!-- 根据主键查询一条记录 -->
@@ -117,7 +127,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