Browse Source

Merge remote-tracking branch 'origin/online1' into online1

Joburgess 3 years ago
parent
commit
34a53485bd
38 changed files with 860 additions and 87 deletions
  1. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java
  2. 8 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentRegistrationDao.java
  3. 12 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysMusicCompareRecordDao.java
  4. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/EduOrganStudentDataDto.java
  5. 6 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/IndexBaseDto.java
  6. 46 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicCompareRankingDto.java
  7. 41 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicalNotesPlayStatDto.java
  8. 54 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCompareHelper.java
  9. 71 10
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WebSocketInfo.java
  10. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/IndexBaseMonthData.java
  11. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicCompareRecord.java
  12. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicScore.java
  13. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicScoreAccompaniment.java
  14. 12 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysSuggestion.java
  15. 71 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/HeardLevelEnum.java
  16. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/IndexDataType.java
  17. 41 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MusicalErrorTypeEnum.java
  18. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/OrganCloudStudyStudentDataQueryInfo.java
  19. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysExamSongQueryInfo.java
  20. 21 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysMusicCompareRecordQueryInfo.java
  21. 32 7
      mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java
  22. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SoundSocketService.java
  23. 14 7
      mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java
  24. 2 3
      mec-biz/src/main/java/com/ym/mec/biz/service/WebSocketEventHandler.java
  25. 19 3
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCheckHandler.java
  26. 46 27
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCompareHandler.java
  27. 49 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentServiceImpl.java
  28. 74 15
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java
  29. 45 0
      mec-biz/src/main/resources/config/mybatis/StudentMapper.xml
  30. 10 0
      mec-biz/src/main/resources/config/mybatis/StudentRegistrationMapper.xml
  31. 19 7
      mec-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  32. 2 1
      mec-biz/src/main/resources/config/mybatis/SysMusicScoreAccompanimentMapper.xml
  33. 12 2
      mec-biz/src/main/resources/config/mybatis/SysMusicScoreMapper.xml
  34. 6 2
      mec-biz/src/main/resources/config/mybatis/SysSuggestionMapper.xml
  35. 3 2
      mec-student/src/main/java/com/ym/mec/student/controller/CloudStudyController.java
  36. 13 0
      mec-student/src/main/java/com/ym/mec/student/controller/SysMusicCompareRecordController.java
  37. 13 0
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/SysMusicCompareRecordController.java
  38. 13 0
      mec-web/src/main/java/com/ym/mec/web/controller/education/SysMusicCompareRecordController.java

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java

@@ -351,4 +351,14 @@ public interface StudentDao extends com.ym.mec.common.dal.BaseDAO<Integer, Stude
 
     List<Map<Integer, Integer>> getTeacherExperienceMemberStudentNum(@Param("teacherIds") List<Integer> teacherIds,
                                                                      @Param("organId") Integer organId);
+
+    List<Map<Integer, String>> getStudentSubjectMapList(@Param("studentIds") List<Integer> studentIds);
+
+    /**
+     * 获取新增人数占比(已上乐团课小于等于4)
+     * @return
+     */
+    List<BaseMapDto<Integer,Long>> getOrganCloudNewStudentNum(@Param("musicGroupIds") List<String> musicGroupIds, @Param("userIds") List<Integer> userIds);
+
+    List<Map<Long, Long>> groupOrganId(@Param("organIds") List<Integer> organIds, @Param("userIds") List<Integer> userIds);
 }

+ 8 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentRegistrationDao.java

@@ -675,4 +675,12 @@ public interface StudentRegistrationDao extends BaseDAO<Long, StudentRegistratio
      * @return java.util.List<java.util.Map<java.lang.Integer,java.lang.String>>
      */
     List<Map<Integer, String>> queryStudentMusicGroupNamesMap(@Param("studentIds") List<Integer> studentIds);
+
+    /**
+     * 获取在读并且进行中的乐团编号
+     * @return
+     */
+    List<String> findMusicGroupIds();
+
+    List<Integer> findStudentIds();
 }

+ 12 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysMusicCompareRecordDao.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.dal.dao;
 
 import com.ym.mec.biz.dal.dto.*;
+import com.ym.mec.biz.dal.enums.HeardLevelEnum;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import org.apache.ibatis.annotations.Param;
@@ -20,7 +21,17 @@ public interface SysMusicCompareRecordDao extends BaseDAO<Long, SysMusicCompareR
      * @return java.util.List<com.ym.mec.biz.dal.dto.MusicCompareRankingDto>
      */
     List<MusicCompareRankingDto> getUserTrainStat(@Param("startTime") String startTime,
-                                                  @Param("endTime") String endTime);
+                                                  @Param("endTime") String endTime,
+                                                  @Param("heardLevel")HeardLevelEnum heardLevel);
+
+    /**
+     * @describe 获取用户最后一次评测数据
+     * @author Joburgess
+     * @date 2021/8/23 0023
+     * @param userId:
+     * @return com.ym.mec.biz.dal.entity.SysMusicCompareRecord
+     */
+    SysMusicCompareRecord getUserLastEvaluationData(@Param("userId") Integer userId);
 
     /**
      * @describe 获取用户训练总览

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/EduOrganStudentDataDto.java

@@ -45,6 +45,28 @@ public class EduOrganStudentDataDto {
     @ApiModelProperty("云教练新增人数")
     private int newCloudStudyStudentNum;
 
+    @ApiModelProperty("新用户人数")
+    private int newStudentNum;
+
+    @ApiModelProperty("新用户占比")
+    private float newStudentDuty;
+
+    public int getNewStudentNum() {
+        return newStudentNum;
+    }
+
+    public void setNewStudentNum(int newStudentNum) {
+        this.newStudentNum = newStudentNum;
+    }
+
+    public float getNewStudentDuty() {
+        return newStudentDuty;
+    }
+
+    public void setNewStudentDuty(float newStudentDuty) {
+        this.newStudentDuty = newStudentDuty;
+    }
+
     public int getIndex() {
         return index;
     }

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/IndexBaseDto.java

@@ -37,6 +37,12 @@ public class IndexBaseDto {
         this.title = title;
     }
 
+    public IndexBaseDto(IndexDataType dataType, List<IndexBaseMonthData> indexMonthData) {
+        this.dataType = dataType;
+        this.title = dataType.getMsg();
+        this.indexMonthData = indexMonthData;
+    }
+
     public IndexBaseDto(String title, BigDecimal percent, List<IndexBaseMonthData> indexMonthData) {
         this.title = title;
         this.percent = percent;

+ 46 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicCompareRankingDto.java

@@ -2,6 +2,8 @@ package com.ym.mec.biz.dal.dto;
 
 import io.swagger.annotations.ApiModelProperty;
 
+import java.math.BigDecimal;
+
 /**
  * @Author Joburgess
  * @Date 2021/8/11 0011
@@ -17,9 +19,21 @@ public class MusicCompareRankingDto {
     @ApiModelProperty("学员姓名")
     private String studentName;
 
+    @ApiModelProperty("声部编号")
+    private Integer subjectId;
+
+    @ApiModelProperty("声部名称")
+    private String subjectName;
+
+    @ApiModelProperty("演奏曲目")
+    private String musicScoreName;
+
     @ApiModelProperty("排名")
     private int rankNum = -1;
 
+    @ApiModelProperty("得分")
+    private int score;
+
     @ApiModelProperty("训练天数")
     private int trainDays = 0;
 
@@ -64,6 +78,22 @@ public class MusicCompareRankingDto {
         this.rankNum = rankNum;
     }
 
+    public Integer getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Integer subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
     public int getTrainDays() {
         return trainDays;
     }
@@ -72,6 +102,14 @@ public class MusicCompareRankingDto {
         this.trainDays = trainDays;
     }
 
+    public String getMusicScoreName() {
+        return musicScoreName;
+    }
+
+    public void setMusicScoreName(String musicScoreName) {
+        this.musicScoreName = musicScoreName;
+    }
+
     public int getTrainTime() {
         return trainTime;
     }
@@ -95,4 +133,12 @@ public class MusicCompareRankingDto {
     public void setVipUser(int vipUser) {
         this.vipUser = vipUser;
     }
+
+    public int getScore() {
+        return score;
+    }
+
+    public void setScore(int score) {
+        this.score = score;
+    }
 }

+ 41 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicalNotesPlayStatDto.java

@@ -0,0 +1,41 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.enums.MusicalErrorTypeEnum;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/8/23 0023
+ */
+public class MusicalNotesPlayStatDto {
+
+    @ApiModelProperty("音符数")
+    private int musicalNotesIndex;
+
+    @ApiModelProperty("错误类型")
+    private MusicalErrorTypeEnum musicalErrorType;
+
+    public MusicalNotesPlayStatDto() {
+    }
+
+    public MusicalNotesPlayStatDto(int musicalNotesIndex, MusicalErrorTypeEnum musicalErrorType) {
+        this.musicalNotesIndex = musicalNotesIndex;
+        this.musicalErrorType = musicalErrorType;
+    }
+
+    public int getMusicalNotesIndex() {
+        return musicalNotesIndex;
+    }
+
+    public void setMusicalNotesIndex(int musicalNotesIndex) {
+        this.musicalNotesIndex = musicalNotesIndex;
+    }
+
+    public MusicalErrorTypeEnum getMusicalErrorType() {
+        return musicalErrorType;
+    }
+
+    public void setMusicalErrorType(MusicalErrorTypeEnum musicalErrorType) {
+        this.musicalErrorType = musicalErrorType;
+    }
+}

+ 54 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCompareHelper.java

@@ -5,6 +5,7 @@ import be.tarsos.dsp.SilenceDetector;
 import be.tarsos.dsp.pitch.PitchDetectionHandler;
 import be.tarsos.dsp.pitch.PitchDetectionResult;
 import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
+import com.ym.mec.biz.dal.enums.HeardLevelEnum;
 import com.ym.mec.biz.service.impl.SoundCompareHandler;
 import io.swagger.annotations.ApiModelProperty;
 import org.springframework.util.CollectionUtils;
@@ -35,6 +36,9 @@ public class SoundCompareHelper implements PitchDetectionHandler {
     @ApiModelProperty(value = "声部编号")
     private Integer subjectId;
 
+    @ApiModelProperty(value = "评测等级")
+    private HeardLevelEnum heardLevel = HeardLevelEnum.ADVANCED;
+
     @ApiModelProperty(value = "小节开始时间")
     private double measureStartTime = 0;
 
@@ -63,12 +67,22 @@ public class SoundCompareHelper implements PitchDetectionHandler {
     @ApiModelProperty(value = "音符频率字典")
     private Map<Integer, Float> musicalNotePitchMap = new HashMap<>();
 
+    @ApiModelProperty(value = "每个音符评测结果")
+    private List<MusicalNotesPlayStatDto> musicalNotesPlayStats = new ArrayList<>();
+
     @ApiModelProperty(value = "偏移时间量,解决客户端录音播放不同步导致的声音留白")
     private int offsetTime = -1;
 
     private List<MusicPitchDetailDto> musicXmlInfos;
 
     private String clientId;
+
+    private Integer detailId;
+
+    private Integer examSongId;
+
+    private String xmlUrl;
+
     /**
      * @describe 分贝检测器
      */
@@ -106,6 +120,14 @@ public class SoundCompareHelper implements PitchDetectionHandler {
         this.subjectId = subjectId;
     }
 
+    public HeardLevelEnum getHeardLevel() {
+        return heardLevel;
+    }
+
+    public void setHeardLevel(HeardLevelEnum heardLevel) {
+        this.heardLevel = heardLevel;
+    }
+
     public DeviceTypeEnum getDeviceType() {
         return deviceType;
     }
@@ -114,6 +136,30 @@ public class SoundCompareHelper implements PitchDetectionHandler {
         this.deviceType = deviceType;
     }
 
+    public Integer getDetailId() {
+        return detailId;
+    }
+
+    public void setDetailId(Integer detailId) {
+        this.detailId = detailId;
+    }
+
+    public Integer getExamSongId() {
+        return examSongId;
+    }
+
+    public void setExamSongId(Integer examSongId) {
+        this.examSongId = examSongId;
+    }
+
+    public String getXmlUrl() {
+        return xmlUrl;
+    }
+
+    public void setXmlUrl(String xmlUrl) {
+        this.xmlUrl = xmlUrl;
+    }
+
     public int getOffsetTime() {
         return offsetTime;
     }
@@ -186,6 +232,14 @@ public class SoundCompareHelper implements PitchDetectionHandler {
         this.measureEndTime = measureEndTime;
     }
 
+    public List<MusicalNotesPlayStatDto> getMusicalNotesPlayStats() {
+        return musicalNotesPlayStats;
+    }
+
+    public void setMusicalNotesPlayStats(List<MusicalNotesPlayStatDto> musicalNotesPlayStats) {
+        this.musicalNotesPlayStats = musicalNotesPlayStats;
+    }
+
     public List<MusicPitchDetailDto> getRecordMeasurePithInfo() {
         return recordMeasurePithInfo;
     }

+ 71 - 10
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WebSocketInfo.java

@@ -1,32 +1,93 @@
 package com.ym.mec.biz.dal.dto;
 
-import com.alibaba.fastjson.JSONObject;
-
-import java.util.HashMap;
+import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
+import org.springframework.http.HttpStatus;
 
 /**
  * @Author Joburgess
  * @Date 2021/6/17 0017
  */
-public class WebSocketInfo {
+public class WebSocketInfo<T> {
+
+    private Head header = new Head();
+
+    private T body;
+
+    public static class Head{
+        private int status = HttpStatus.OK.value();
+        private String commond = "";
+        private WebsocketTypeEnum type;
+
+        public Head() {
+        }
+
+        public Head(int status) {
+            this.status = status;
+        }
+
+        public Head(String commond) {
+            this.commond = commond;
+        }
+
+        public Head(String commond, WebsocketTypeEnum type) {
+            this.commond = commond;
+            this.type = type;
+        }
+
+        public int getStatus() {
+            return status;
+        }
+
+        public void setStatus(int status) {
+            this.status = status;
+        }
+
+        public String getCommond() {
+            return commond;
+        }
+
+        public void setCommond(String commond) {
+            this.commond = commond;
+        }
 
-    private HashMap<String, String> header = new HashMap<>();
+        public WebsocketTypeEnum getType() {
+            return type;
+        }
+
+        public void setType(WebsocketTypeEnum type) {
+            this.type = type;
+        }
+    }
+
+    public WebSocketInfo() {
+    }
+
+    public WebSocketInfo(Head header) {
+        this.header = header;
+    }
+
+    public static WebSocketInfo success(){
+        return new WebSocketInfo(new Head());
+    }
+
+    public static WebSocketInfo success(String commond){
+        return new WebSocketInfo(new Head(commond));
+    }
 
-    private Object body;
 
-    public HashMap<String, String> getHeader() {
+    public Head getHeader() {
         return header;
     }
 
-    public void setHeader(HashMap<String, String> header) {
+    public void setHeader(Head header) {
         this.header = header;
     }
 
-    public Object getBody() {
+    public T getBody() {
         return body;
     }
 
-    public void setBody(Object body) {
+    public void setBody(T body) {
         this.body = body;
     }
 }

+ 5 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/IndexBaseMonthData.java

@@ -60,6 +60,11 @@ public class IndexBaseMonthData {
 		this.percent = BigDecimal.ZERO;
 	}
 
+	public IndexBaseMonthData(Date month, Integer organId, BigDecimal percent) {
+		this.month = month;
+		this.percent = percent;
+	}
+
 	public Long getId() {
 		return id;
 	}

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

@@ -2,6 +2,7 @@ package com.ym.mec.biz.dal.entity;
 
 import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
 import com.ym.mec.biz.dal.enums.FeatureType;
+import com.ym.mec.biz.dal.enums.HeardLevelEnum;
 import com.ym.mec.util.date.DateUtil;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
@@ -26,6 +27,8 @@ public class SysMusicCompareRecord {
 	/** 教程编号 */
 	private Integer sysMusicScoreId;
 
+	private HeardLevelEnum heardLevel;
+
 	private String sysMusicScoreName;
 	
 	/** 评分数据 */
@@ -92,6 +95,14 @@ public class SysMusicCompareRecord {
 		this.clientId = clientId;
 	}
 
+	public HeardLevelEnum getHeardLevel() {
+		return heardLevel;
+	}
+
+	public void setHeardLevel(HeardLevelEnum heardLevel) {
+		this.heardLevel = heardLevel;
+	}
+
 	public void setSysMusicScoreId(Integer sysMusicScoreId){
 		this.sysMusicScoreId = sysMusicScoreId;
 	}

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

@@ -51,6 +51,8 @@ public class SysMusicScore {
 	 * 客户端类型
 	 */
 	private ClientTypeEnum clientType;
+
+	private String rankIds;
 	
 	/**  */
 	private java.util.Date updateTime;
@@ -58,6 +60,14 @@ public class SysMusicScore {
 	/**  */
 	private java.util.Date createTime;
 
+	public String getRankIds() {
+		return rankIds;
+	}
+
+	public void setRankIds(String rankIds) {
+		this.rankIds = rankIds;
+	}
+
 	public ClientTypeEnum getClientType() {
 		return clientType;
 	}

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysMusicScoreAccompaniment.java

@@ -58,8 +58,18 @@ public class SysMusicScoreAccompaniment {
 
 	private String memo;
 
+	private String rankIds;
+
 	private ClientTypeEnum clientType;
 
+	public String getRankIds() {
+		return rankIds;
+	}
+
+	public void setRankIds(String rankIds) {
+		this.rankIds = rankIds;
+	}
+
 	public ClientTypeEnum getClientType() {
 		return clientType;
 	}

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysSuggestion.java

@@ -23,6 +23,10 @@ public class SysSuggestion {
 	/** 内容 */
 	@ApiModelProperty(value = "内容",required = false)
 	private String content;
+
+	/** 媒体 */
+	@ApiModelProperty(value = "媒体",required = false)
+	private String url;
 	
 	/** 用户编号 */
 	@ApiModelProperty(value = "用户编号",required = false)
@@ -40,6 +44,14 @@ public class SysSuggestion {
 	/** 提交时间 */
 	private java.util.Date createTime;
 
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
 	public String getUsername() {
 		return username;
 	}

+ 71 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/HeardLevelEnum.java

@@ -0,0 +1,71 @@
+package com.ym.mec.biz.dal.enums;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+public enum HeardLevelEnum implements BaseEnum<String, HeardLevelEnum> {
+    BEGINNER("BEGINNER","初学者", 9, 0.05f, 0),
+    ADVANCED("ADVANCED","进阶者", 3, 0.09f, 0),
+    PERFORMER("PERFORMER","小演奏家", 1, 0.3f, 0);
+
+    private String code;
+
+    private String msg;
+
+    /** 音准音分偏差数 */
+    private float intonationCentsRange;
+
+    /** 节奏评分截取时间占比 */
+    private float cadenceRange;
+
+    /** 完整性 */
+    private float integrityRange;
+
+    HeardLevelEnum(String code, String msg, float intonationCentsRange, float cadenceRange, float integrityRange) {
+        this.code = code;
+        this.msg = msg;
+        this.intonationCentsRange = intonationCentsRange;
+        this.cadenceRange = cadenceRange;
+        this.integrityRange = integrityRange;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public float getIntonationCentsRange() {
+        return intonationCentsRange;
+    }
+
+    public void setIntonationCentsRange(float intonationCentsRange) {
+        this.intonationCentsRange = intonationCentsRange;
+    }
+
+    public float getCadenceRange() {
+        return cadenceRange;
+    }
+
+    public void setCadenceRange(float cadenceRange) {
+        this.cadenceRange = cadenceRange;
+    }
+
+    public float getIntegrityRange() {
+        return integrityRange;
+    }
+
+    public void setIntegrityRange(float integrityRange) {
+        this.integrityRange = integrityRange;
+    }
+}

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/IndexDataType.java

@@ -78,6 +78,9 @@ public enum IndexDataType implements BaseEnum<String, IndexDataType> {
     MEMBER_STUDENT_NUM("MEMBER_STUDENT_NUM", "会员数量", false, false),
     EXPERIENCE_MEMBER_STUDENT_NUM("EXPERIENCE_MEMBER_STUDENT_NUM", "试用会员数量", false, false),
     NEW_MEMBER_STUDENT_NUM("NEW_MEMBER_STUDENT_NUM", "新增会员数量", false, false),
+
+    CLOUD_STUDY_TRAIN_NUM("CLOUD_STUDY_TRAIN_NUM", "云教练训练次数", false, false),
+    CLOUD_STUDY_TRAIN_TIME("CLOUD_STUDY_TRAIN_TIME", "云教练训练时长", false, false),
     ;
 
     private String code;

+ 41 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MusicalErrorTypeEnum.java

@@ -0,0 +1,41 @@
+package com.ym.mec.biz.dal.enums;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+/**
+ * 员工角色枚举
+ */
+public enum MusicalErrorTypeEnum implements BaseEnum<String, MusicalErrorTypeEnum> {
+	RIGHT("RIGHT", "演奏正确"),
+	WRONG("WRONG", "错音"),
+	CADENCE_WRONG("CADENCE_WRONG", "节奏错误"),
+	INTONATION_WRONG("INTONATION_WRONG", "音准错误"),
+	INTEGRITY_WRONG("INTEGRITY_WRONG", "完整度不足"),
+	NOT_PLAY("NOT_PLAY", "未演奏");
+
+	private String code;
+
+	private String msg;
+
+	MusicalErrorTypeEnum(String code, String msg) {
+		this.code = code;
+		this.msg = msg;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	@Override
+	public String getCode() {
+		return this.code;
+	}
+}

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/OrganCloudStudyStudentDataQueryInfo.java

@@ -39,6 +39,28 @@ public class OrganCloudStudyStudentDataQueryInfo extends QueryInfo {
     @ApiModelProperty("云教练新增人数")
     private String newCloudStudyStudentNum;
 
+    @ApiModelProperty("新用户人数")
+    private String newStudentNum;
+
+    @ApiModelProperty("新用户人数占比")
+    private String newStudentDuty;
+
+    public String getNewStudentNum() {
+        return newStudentNum;
+    }
+
+    public void setNewStudentNum(String newStudentNum) {
+        this.newStudentNum = newStudentNum;
+    }
+
+    public String getNewStudentDuty() {
+        return newStudentDuty;
+    }
+
+    public void setNewStudentDuty(String newStudentDuty) {
+        this.newStudentDuty = newStudentDuty;
+    }
+
     public String getDate() {
         return date;
     }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysExamSongQueryInfo.java

@@ -20,6 +20,9 @@ public class SysExamSongQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "曲库分类",required = true)
     private Integer categoriesId;
 
+    @ApiModelProperty(value = "是否收费",required = true)
+    private Integer rankType;
+
     private Integer sysMusicScoreId;
 
     private Integer parentId;
@@ -30,6 +33,14 @@ public class SysExamSongQueryInfo extends QueryInfo {
 
     private List<Integer> categoriesIdList;
 
+    public Integer getRankType() {
+        return rankType;
+    }
+
+    public void setRankType(Integer rankType) {
+        this.rankType = rankType;
+    }
+
     public List<Integer> getCategoriesIdList() {
         return categoriesIdList;
     }

+ 21 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/SysMusicCompareRecordQueryInfo.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.dal.page;
 
 import com.ym.mec.biz.dal.enums.FeatureType;
+import com.ym.mec.biz.dal.enums.HeardLevelEnum;
 import com.ym.mec.common.page.QueryInfo;
 import io.swagger.annotations.ApiModelProperty;
 import org.apache.ibatis.annotations.Param;
@@ -21,11 +22,15 @@ public class SysMusicCompareRecordQueryInfo extends QueryInfo {
 
     private String musicGroupId;
 
+    private int orderType;
+
     @ApiModelProperty("排序字段:TRAINDAYS(训练天数);TRAINTIME(训练时长);TRAINNUM(训练次数)")
     private String sortField = "TRAINDAYS";
 
     private FeatureType featureType;
 
+    private HeardLevelEnum heardLevel;
+
     public FeatureType getFeatureType() {
         return featureType;
     }
@@ -42,6 +47,14 @@ public class SysMusicCompareRecordQueryInfo extends QueryInfo {
         this.teacherId = teacherId;
     }
 
+    public int getOrderType() {
+        return orderType;
+    }
+
+    public void setOrderType(int orderType) {
+        this.orderType = orderType;
+    }
+
     public Integer getUserId() {
         return userId;
     }
@@ -81,4 +94,12 @@ public class SysMusicCompareRecordQueryInfo extends QueryInfo {
     public void setSortField(String sortField) {
         this.sortField = sortField;
     }
+
+    public HeardLevelEnum getHeardLevel() {
+        return heardLevel;
+    }
+
+    public void setHeardLevel(HeardLevelEnum heardLevel) {
+        this.heardLevel = heardLevel;
+    }
 }

+ 32 - 7
mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java

@@ -1,20 +1,24 @@
 package com.ym.mec.biz.handler;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.biz.dal.dto.WebSocketClientDetail;
 import com.ym.mec.biz.dal.dto.WebSocketInfo;
 import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
 import com.ym.mec.biz.service.SoundSocketService;
 import com.ym.mec.biz.service.WebSocketEventHandler;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.formula.functions.T;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.web.socket.*;
 import org.springframework.web.socket.handler.AbstractWebSocketHandler;
 
+import java.io.IOException;
 import java.util.Date;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -24,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
 @Service
 public class WebSocketHandler extends AbstractWebSocketHandler {
 
-    private final Logger LOGGER = LoggerFactory.getLogger(WebSocketHandler.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketHandler.class);
 
     /**
      * @describe 存储客户端链接
@@ -67,13 +71,13 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     protected void handleTextMessage(WebSocketSession session, TextMessage message){
         String phone = session.getPrincipal().getName().split(":")[1];
         LOGGER.info("{}: {}", phone, message.getPayload());
-        WebSocketInfo webSocketInfo = JSON.parseObject(message.getPayload(), WebSocketInfo.class);
+        WebSocketInfo<JSONObject> webSocketInfo = JSON.parseObject(message.getPayload(), WebSocketInfo.class);
 
-        WebsocketTypeEnum websocketType = WebsocketTypeEnum.SOUND_COMPARE;
-        if(webSocketInfo.getHeader().containsKey(SoundSocketService.TAG)){
-            websocketType = WebsocketTypeEnum.valueOf(webSocketInfo.getHeader().get(SoundSocketService.TAG));
+        if(Objects.isNull(webSocketInfo.getHeader().getType())){
+            webSocketInfo.getHeader().setType(WebsocketTypeEnum.SOUND_COMPARE);
         }
-        appMap.get(websocketType).receiveTextMessage(session, phone, message);
+
+        appMap.get(webSocketInfo.getHeader().getType()).receiveTextMessage(session, phone, webSocketInfo);
     }
 
     @Override
@@ -105,7 +109,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
         super.afterConnectionClosed(session, status);
         String phone = session.getPrincipal().getName().split(":")[1];
-        LOGGER.info("{}离线", phone);
+        LOGGER.info("{}离线: {}s", phone, (System.currentTimeMillis() - WS_CLIENTS.get(phone).getLoginTime().getTime())*1000);
         appMap.values().forEach(e->e.afterConnectionClosed(session, phone));
         WS_CLIENTS.remove(phone);
     }
@@ -114,4 +118,25 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     public boolean supportsPartialMessages() {
         return super.supportsPartialMessages();
     }
+
+    /**
+     * @describe 发送文本消息
+     * @author Joburgess
+     * @date 2021/8/23 0023
+     * @param phone: 接收人手机号
+     * @param message:
+     * @return boolean
+     */
+    public static <T> boolean sendTextMessage(String phone, T message){
+        if(!WS_CLIENTS.containsKey(phone)||!WS_CLIENTS.get(phone).getSession().isOpen()){
+            return false;
+        }
+        try {
+            WS_CLIENTS.get(phone).getSession().sendMessage(new TextMessage(JSON.toJSONString(message)));
+        } catch (IOException e) {
+            LOGGER.error("消息发送失败:{}", e);
+            return false;
+        }
+        return true;
+    }
 }

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

@@ -9,6 +9,7 @@ public interface SoundSocketService {
     String TAG = "TAG";
     String COMMOND = "commond";
     String MUSIC_XML = "musicXml";
+    String CHECK_END = "checkEnd";
     String RECORD_START = "recordStart";
     String RECORD_END = "recordEnd";
     String RECORD_CANCEL = "recordCancel";

+ 14 - 7
mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java

@@ -1,14 +1,13 @@
 package com.ym.mec.biz.service;
 
-import com.ym.mec.biz.dal.dto.CountStudentTrainDataDto;
-import com.ym.mec.biz.dal.dto.MusicCompareRankingDto;
-import com.ym.mec.biz.dal.dto.SoundCompareHelper;
-import com.ym.mec.biz.dal.dto.StatDto;
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import com.ym.mec.biz.dal.page.SysMusicCompareRecordQueryInfo;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
 
+import java.util.List;
 import java.util.Map;
 
 public interface SysMusicCompareRecordService extends BaseService<Long, SysMusicCompareRecord> {
@@ -24,14 +23,22 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
     void saveMusicCompareData(String phone, SoundCompareHelper soundCompareInfo);
 
     /**
+     * @describe 用户最后一次评测数据
+     * @author Joburgess
+     * @date 2021/8/23 0023
+     * @param userId:
+     * @return java.util.List<com.ym.mec.biz.dal.dto.MusicalNotesPlayStatDto>
+     */
+    Object getLastEvaluationMusicalNotesPlayStats(Integer userId);
+
+    /**
      * @describe 云教练排行榜
      * @author Joburgess
      * @date 2021/8/11 0011
-     * @param startDate:
-     * @param endDate:
+     * @param queryInfo:
      * @return com.ym.mec.biz.dal.dto.StatDto
      */
-    StatDto rankingList(Integer headUserId, String startDate, String endDate);
+    StatDto rankingList(SysMusicCompareRecordQueryInfo queryInfo);
 
     /**
      * @describe 学员训练数据统计

+ 2 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/WebSocketEventHandler.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.service;
 
+import com.ym.mec.biz.dal.dto.WebSocketInfo;
 import org.springframework.web.socket.BinaryMessage;
 import org.springframework.web.socket.TextMessage;
 import org.springframework.web.socket.WebSocketSession;
@@ -10,8 +11,6 @@ import org.springframework.web.socket.WebSocketSession;
  **/
 public interface WebSocketEventHandler {
 
-
-
     /**
      * @describe 连接成功
      * @author Joburgess
@@ -29,7 +28,7 @@ public interface WebSocketEventHandler {
      * @param message: 文本信息
      * @return void
      */
-    void receiveTextMessage(WebSocketSession session, String phone, TextMessage message);
+    void receiveTextMessage(WebSocketSession session, String phone, WebSocketInfo message);
 
     /**
      * @describe 接收到二进制数据

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

@@ -6,6 +6,7 @@ import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
 import be.tarsos.dsp.pitch.PitchDetectionHandler;
 import be.tarsos.dsp.pitch.PitchDetectionResult;
 import be.tarsos.dsp.pitch.PitchProcessor;
+import be.tarsos.dsp.util.PitchConverter;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.biz.dal.dto.MusicPitchDetailDto;
@@ -50,8 +51,15 @@ public class SoundCheckHandler implements WebSocketEventHandler {
     }
 
     @Override
-    public void receiveTextMessage(WebSocketSession session, String phone, TextMessage message) {
-        userSoundCheckInfo.put(phone, 0);
+    public void receiveTextMessage(WebSocketSession session, String phone, WebSocketInfo message) {
+        switch (message.getHeader().getCommond()) {
+            case SoundSocketService.CHECK_END:
+                userSoundCheckInfo.remove(phone);
+                break;
+            default:
+                userSoundCheckInfo.put(phone, 0);
+                break;
+        }
     }
 
     @Override
@@ -62,7 +70,15 @@ public class SoundCheckHandler implements WebSocketEventHandler {
         try {
             AudioDispatcher dispatcher = AudioDispatcherFactory.fromByteArray(message.getPayload().array(), SoundCompareHandler.soundCompareConfig.audioFormat, SoundCompareHandler.soundCompareConfig.simpleSize, SoundCompareHandler.soundCompareConfig.overlap);
             dispatcher.addAudioProcessor(new PitchProcessor(SoundCompareHandler.soundCompareConfig.algo, SoundCompareHandler.soundCompareConfig.simpleRate, SoundCompareHandler.soundCompareConfig.simpleSize, (pitchDetectionResult, audioEvent) -> {
-
+                if(pitchDetectionResult.getPitch()<=0){
+                    return;
+                }
+                double normalCents = PitchConverter.hertzToAbsoluteCent(COMPARE_FREQUENCY);
+                double recordCents = PitchConverter.hertzToAbsoluteCent(pitchDetectionResult.getPitch());
+                if(Math.abs(normalCents - recordCents)<3){
+                    WebSocketHandler.sendTextMessage(phone, WebSocketInfo.success("checkDone"));
+                    userSoundCheckInfo.remove(phone);
+                }
             }));
             dispatcher.run();
         } catch (UnsupportedAudioFileException e) {

+ 46 - 27
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCompareHandler.java

@@ -8,11 +8,10 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.biz.dal.config.SoundCompareConfig;
 import com.ym.mec.biz.dal.dao.SysMusicScoreAccompanimentDao;
-import com.ym.mec.biz.dal.dto.MusicPitchDetailDto;
-import com.ym.mec.biz.dal.dto.SoundCompareHelper;
-import com.ym.mec.biz.dal.dto.WavHeader;
-import com.ym.mec.biz.dal.dto.WebSocketInfo;
+import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
+import com.ym.mec.biz.dal.enums.HeardLevelEnum;
+import com.ym.mec.biz.dal.enums.MusicalErrorTypeEnum;
 import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
 import com.ym.mec.biz.handler.WebSocketHandler;
 import com.ym.mec.biz.service.SoundSocketService;
@@ -23,7 +22,6 @@ import com.ym.mec.common.exception.BizException;
 import com.ym.mec.thirdparty.storage.StoragePluginContext;
 import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
 import com.ym.mec.util.upload.UploadUtil;
-import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,7 +29,6 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.socket.BinaryMessage;
-import org.springframework.web.socket.TextMessage;
 import org.springframework.web.socket.WebSocketSession;
 
 import javax.sound.sampled.UnsupportedAudioFileException;
@@ -88,15 +85,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
     }
 
     @Override
-    public void receiveTextMessage(WebSocketSession session, String phone, TextMessage message) {
-        WebSocketInfo webSocketInfo = JSON.parseObject(message.getPayload(), WebSocketInfo.class);
-        JSONObject bodyObject = (JSONObject) webSocketInfo.getBody();
+    public void receiveTextMessage(WebSocketSession session, String phone, WebSocketInfo message) {
+        JSONObject bodyObject = (JSONObject) message.getBody();
 
-        String commond = "";
-        if(webSocketInfo.getHeader().containsKey(SoundSocketService.COMMOND)){
-            commond = webSocketInfo.getHeader().get(SoundSocketService.COMMOND);
-        }
-        switch (commond){
+        switch (message.getHeader().getCommond()){
             case SoundSocketService.MUSIC_XML:
                 userSoundInfoMap.put(phone, new SoundCompareHelper());
                 userSoundInfoMap.get(phone).setClientId(((OAuth2Authentication)session.getPrincipal()).getOAuth2Request().getClientId());
@@ -110,6 +102,18 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                 if(bodyObject.containsKey("behaviorId")){
                     userSoundInfoMap.get(phone).setBehaviorId(bodyObject.getString("behaviorId"));
                 }
+                if(bodyObject.containsKey("detailId")){
+                    userSoundInfoMap.get(phone).setDetailId(bodyObject.getInteger("detailId"));
+                }
+                if(bodyObject.containsKey("examSongId")){
+                    userSoundInfoMap.get(phone).setExamSongId(bodyObject.getInteger("examSongId"));
+                }
+                if(bodyObject.containsKey("xmlUrl")){
+                    userSoundInfoMap.get(phone).setXmlUrl(bodyObject.getString("xmlUrl"));
+                }
+                if(bodyObject.containsKey("heardLevel")){
+                    userSoundInfoMap.get(phone).setHeardLevel(HeardLevelEnum.valueOf(bodyObject.getString("heardLevel")));
+                }
                 List<Integer> subjectIds = sysMusicScoreAccompanimentDao.findSubjectByMusicScoreId(userSoundInfoMap.get(phone).getMusicScoreId(), null);
                 if(!CollectionUtils.isEmpty(subjectIds)){
                     userSoundInfoMap.get(phone).setSubjectId(subjectIds.get(0));
@@ -154,9 +158,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                             userSoundInfoMap.get(phone).getMeasureEndTime().remove(lastMeasureIndex);
                         }
                     }
+                } catch (IOException | NullPointerException e) {
+                    LOGGER.error("评分错误:", e);
+                } finally {
                     calTotalScore(phone);
-                } catch (IOException e) {
-                    throw new BizException("评分错误:", e);
                 }
                 createHeader(phone);
                 break;
@@ -397,6 +402,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) pitch);
                 }
 
+                boolean cadenceRight = false;
+                boolean intonationRight = false;
+                boolean integrityRight = false;
+
                 //有效节奏占比
                 float cadenceDuty = cadenceValidNum/compareNum;
                 //如果频率出现断层或这个音量出现断层,则当前音符节奏无效
@@ -404,11 +413,13 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     cadenceDuty = 0;
                 }
                 //节奏
-                if(cadenceDuty>=soundCompareConfig.cadenceValidDuty){
+                if(cadenceDuty>=userSoundInfoMap.get(phone).getHeardLevel().getCadenceRange()){
                     cadenceNum++;
+                    cadenceRight = true;
                 }
-                //音准
+                //音准、完成度
                 if (!CollectionUtils.isEmpty(measureSoundPitchInfos)){
+                    //音准
                     Double avgPitch = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<5).collect(Collectors.averagingDouble(pitch -> pitch.getFrequency()));
                     //音分
                     double recordCents = 0;
@@ -419,7 +430,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     if(musicXmlInfo.getFrequency()>0){
                         cents =  PitchConverter.hertzToAbsoluteCent(musicXmlInfo.getFrequency());
                     }
-                    double score = 100 - Math.round(Math.abs(cents - recordCents)) + soundCompareConfig.intonationCentsRange;
+                    double score = 100 - Math.round(Math.abs(cents - recordCents)) + userSoundInfoMap.get(phone).getHeardLevel().getIntonationCentsRange();
                     if (score < 0){
                         score = 0;
                     }else if(score > 100){
@@ -427,6 +438,9 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     }
                     intonationScore += score;
                     musicXmlInfo.setAvgFrequency(avgPitch.floatValue());
+                    intonationRight = score>70;
+
+                    integrityValidNum = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<5).count();
                 }
                 //完成度
                 if(integrityValidNum > compareNum){
@@ -434,6 +448,17 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                 }
                 float integrityDuty = integrityValidNum/compareNum;
                 integrityScore += integrityDuty;
+                integrityRight = integrityDuty>0.7;
+
+                if(!cadenceRight){
+                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.CADENCE_WRONG));
+                }else if(!intonationRight){
+                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.INTONATION_WRONG));
+                }else if(!integrityRight){
+                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.INTEGRITY_WRONG));
+                }else{
+                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.RIGHT));
+                }
             }
 
             BigDecimal measureNum = new BigDecimal(totalCompareNum);
@@ -508,9 +533,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
     private WebSocketInfo createPushInfo(String phone, String command, Integer measureIndex,
                                          BigDecimal intonation, BigDecimal cadence, BigDecimal integrity){
         WebSocketInfo webSocketInfo = new WebSocketInfo();
-        HashMap<String, String> header = new HashMap<>();
-        header.put("commond", command);
-        webSocketInfo.setHeader(header);
+        webSocketInfo.setHeader(new WebSocketInfo.Head(command));
         Map<String, Object> result = new HashMap<>(5);
         BigDecimal score = cadence;
         if(Objects.isNull(userSoundInfoMap.get(phone).getSubjectId())||userSoundInfoMap.get(phone).getSubjectId()!=23){
@@ -528,11 +551,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
         LOGGER.info("小节频分:{}", JSON.toJSONString(webSocketInfo));
 
         //推送结果
-        try {
-            WebSocketHandler.WS_CLIENTS.get(phone).getSession().sendMessage(new TextMessage(JSON.toJSONString(webSocketInfo)));
-        } catch (IOException e) {
-            LOGGER.error("{}评分结果推送失败", phone);
-        }
+        WebSocketHandler.sendTextMessage(phone, webSocketInfo);
         return webSocketInfo;
     }
 }

+ 49 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentServiceImpl.java

@@ -542,6 +542,19 @@ public class StudentServiceImpl extends BaseServiceImpl<Integer, Student> implem
         if(!CollectionUtils.isEmpty(organsNewCloudStudyNumMapList)){
             organsNewCloudStudyNumMap = MapUtil.convertIntegerMap(organsNewCloudStudyNumMapList);
         }
+        //获取新增人数占比(已上乐团课小于等于4)
+        //获取有在读学员的乐团编号
+        //获取有在读学员的学员编号
+        List<String> musicGroupIds = studentRegistrationDao.findMusicGroupIds();
+        List<Integer> studentIdList = studentRegistrationDao.findStudentIds();
+        List<BaseMapDto<Integer, Long>> studentMusicCourseNum = studentDao.getOrganCloudNewStudentNum(musicGroupIds,studentIdList);
+        Map<String, Long> organsNewCloudNewStudentNumMap = new HashMap<>();
+        if(!CollectionUtils.isEmpty(studentMusicCourseNum)){
+            List<BaseMapDto<Integer, Long>> collect = studentMusicCourseNum.stream().filter(e -> e.getValue() < 5).collect(Collectors.toList());
+            List<Integer> userIdList = collect.stream().map(e -> e.getKey()).collect(Collectors.toList());
+            List<Map<Long, Long>> organsNewCloudNewStudentNumMapList = studentDao.groupOrganId(organIds,userIdList);
+            organsNewCloudNewStudentNumMap = MapUtil.convertIntegerMap(organsNewCloudNewStudentNumMapList);
+        }
 
         List<EduOrganStudentDataDto> result = new ArrayList<>();
 
@@ -573,6 +586,10 @@ public class StudentServiceImpl extends BaseServiceImpl<Integer, Student> implem
             if(organsNewCloudStudyNumMap.containsKey(organ.getId().toString())){
                 organStudentVipData.setNewCloudStudyStudentNum(organsNewCloudStudyNumMap.get(organ.getId().toString()).intValue());
             }
+            if(organsNewCloudNewStudentNumMap.containsKey(organ.getId().toString())){
+                organStudentVipData.setNewStudentNum(organsNewCloudNewStudentNumMap.get(organ.getId().toString()).intValue());
+                organStudentVipData.setNewStudentDuty(new BigDecimal(organStudentVipData.getNewStudentNum()).divide(new BigDecimal(organStudentVipData.getTotalStudentNum()), 4, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100)).floatValue());
+            }
             result.add(organStudentVipData);
         }
         return result;
@@ -624,6 +641,20 @@ public class StudentServiceImpl extends BaseServiceImpl<Integer, Student> implem
             organsNewCloudStudyNumMap = MapUtil.convertIntegerMap(organsNewCloudStudyNumMapList);
         }
 
+        //获取新增人数占比(已上乐团课小于等于4)
+        //获取有在读学员的乐团编号
+        //获取有在读学员的学员编号
+        List<String> musicGroupIds = studentRegistrationDao.findMusicGroupIds();
+        List<Integer> studentIdList = studentRegistrationDao.findStudentIds();
+        List<BaseMapDto<Integer, Long>> studentMusicCourseNum = studentDao.getOrganCloudNewStudentNum(musicGroupIds,studentIdList);
+        Map<String, Long> organsNewCloudNewStudentNumMap = new HashMap<>();
+        if(!CollectionUtils.isEmpty(studentMusicCourseNum)){
+            List<BaseMapDto<Integer, Long>> collect = studentMusicCourseNum.stream().filter(e -> e.getValue() < 5).collect(Collectors.toList());
+            List<Integer> userIdList = collect.stream().map(e -> e.getKey()).collect(Collectors.toList());
+            List<Map<Long, Long>> organsNewCloudNewStudentNumMapList = studentDao.groupOrganId(organIds,userIdList);
+            organsNewCloudNewStudentNumMap = MapUtil.convertIntegerMap(organsNewCloudNewStudentNumMapList);
+        }
+
         List<EduOrganStudentDataDto> result = new ArrayList<>();
 
         for (Organization organ : organs) {
@@ -654,6 +685,10 @@ public class StudentServiceImpl extends BaseServiceImpl<Integer, Student> implem
             if(organsNewCloudStudyNumMap.containsKey(organ.getId().toString())){
                 organStudentVipData.setNewCloudStudyStudentNum(organsNewCloudStudyNumMap.get(organ.getId().toString()).intValue());
             }
+            if(organsNewCloudNewStudentNumMap.containsKey(organ.getId().toString())){
+                organStudentVipData.setNewStudentNum(organsNewCloudNewStudentNumMap.get(organ.getId().toString()).intValue());
+                organStudentVipData.setNewStudentDuty(new BigDecimal(organStudentVipData.getNewStudentNum()).divide(new BigDecimal(organStudentVipData.getTotalStudentNum()), 4, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100)).floatValue());
+            }
             result.add(organStudentVipData);
         }
         Comparator<EduOrganStudentDataDto> comparing = null;
@@ -713,6 +748,20 @@ public class StudentServiceImpl extends BaseServiceImpl<Integer, Student> implem
                 comparing.thenComparing(EduOrganStudentDataDto::getCloudStudyLivelyStudentDuty, "ASC".equals(queryInfo.getCloudStudyLivelyStudentDuty())?Comparator.naturalOrder():Comparator.reverseOrder());
             }
         }
+        if(StringUtils.isNotBlank(queryInfo.getNewStudentNum())){
+            if(Objects.isNull(comparing)){
+                comparing = Comparator.comparing(EduOrganStudentDataDto::getNewStudentNum, "ASC".equals(queryInfo.getNewStudentNum())?Comparator.naturalOrder():Comparator.reverseOrder());
+            }else{
+                comparing.thenComparing(EduOrganStudentDataDto::getNewStudentNum, "ASC".equals(queryInfo.getNewStudentNum())?Comparator.naturalOrder():Comparator.reverseOrder());
+            }
+        }
+        if(StringUtils.isNotBlank(queryInfo.getNewStudentDuty())){
+            if(Objects.isNull(comparing)){
+                comparing = Comparator.comparing(EduOrganStudentDataDto::getNewStudentDuty, "ASC".equals(queryInfo.getNewStudentDuty())?Comparator.naturalOrder():Comparator.reverseOrder());
+            }else{
+                comparing.thenComparing(EduOrganStudentDataDto::getNewStudentDuty, "ASC".equals(queryInfo.getNewStudentDuty())?Comparator.naturalOrder():Comparator.reverseOrder());
+            }
+        }
 
         if(Objects.isNull(comparing)){
             comparing = Comparator.comparing(EduOrganStudentDataDto::getOrganId);

+ 74 - 15
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java

@@ -1,13 +1,16 @@
 package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.StudentDao;
 import com.ym.mec.biz.dal.dao.SysMusicCompareRecordDao;
 import com.ym.mec.biz.dal.dao.TeacherDao;
 import com.ym.mec.biz.dal.dto.*;
+import com.ym.mec.biz.dal.entity.IndexBaseMonthData;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import com.ym.mec.biz.dal.enums.FeatureType;
+import com.ym.mec.biz.dal.enums.IndexDataType;
 import com.ym.mec.biz.dal.page.SysMusicCompareRecordQueryInfo;
 import com.ym.mec.biz.service.SysMusicCompareRecordService;
 import com.ym.mec.common.dal.BaseDAO;
@@ -15,6 +18,8 @@ import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
+import io.swagger.models.auth.In;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -55,8 +60,17 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 		SysMusicCompareRecord sysMusicCompareRecord = new SysMusicCompareRecord();
 		sysMusicCompareRecord.setUserId(user.getId());
 		sysMusicCompareRecord.setSysMusicScoreId(soundCompareInfo.getMusicScoreId());
+		sysMusicCompareRecord.setHeardLevel(soundCompareInfo.getHeardLevel());
 		sysMusicCompareRecord.setBehaviorId(soundCompareInfo.getBehaviorId());
-		sysMusicCompareRecord.setScoreData(JSON.toJSONString(soundCompareInfo.getUserMeasureScoreMap()));
+		Map<String, Object> scoreData = new HashMap<>();
+		scoreData.put("userMeasureScore", soundCompareInfo.getUserMeasureScoreMap());
+		Map<String, Object> musicalNotesPlayStats = new HashMap<>();
+		musicalNotesPlayStats.put("detailId", soundCompareInfo.getDetailId());
+		musicalNotesPlayStats.put("examSongId", soundCompareInfo.getExamSongId());
+		musicalNotesPlayStats.put("xmlUrl", soundCompareInfo.getXmlUrl());
+		musicalNotesPlayStats.put("notesData", soundCompareInfo.getMusicalNotesPlayStats());
+		scoreData.put("musicalNotesPlayStats", musicalNotesPlayStats);
+		sysMusicCompareRecord.setScoreData(JSON.toJSONString(scoreData));
 		if (Objects.nonNull(soundCompareInfo.getUserMeasureScoreMap()) && soundCompareInfo.getUserMeasureScoreMap().containsKey(-1)){
 			Map<String, Object> finalScore = soundCompareInfo.getUserMeasureScoreMap().get(-1);
 			sysMusicCompareRecord.setScore((BigDecimal) finalScore.get("score"));
@@ -76,27 +90,56 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	}
 
 	@Override
-	public StatDto rankingList(Integer headUserId, String startDate, String endDate) {
-		SysUser user = teacherDao.getUser(headUserId);
+	public Object getLastEvaluationMusicalNotesPlayStats(Integer userId) {
+		SysMusicCompareRecord userLastEvaluationData = sysMusicCompareRecordDao.getUserLastEvaluationData(userId);
+		if(StringUtils.isBlank(userLastEvaluationData.getScoreData())){
+			return null;
+		}
+		JSONObject jsonObject = JSON.parseObject(userLastEvaluationData.getScoreData());
+		if(!jsonObject.containsKey("musicalNotesPlayStats")){
+			return null;
+		}
+		return jsonObject.get("musicalNotesPlayStats");
+	}
+
+	@Override
+	public StatDto rankingList(SysMusicCompareRecordQueryInfo queryInfo) {
 		StatDto result = new StatDto();
 		MusicCompareRankingDto head = new MusicCompareRankingDto();
-		head.setUserId(headUserId);
-		List<MusicCompareRankingDto> userTrainStat = sysMusicCompareRecordDao.getUserTrainStat(startDate, endDate);
+		head.setUserId(queryInfo.getUserId());
+		List<MusicCompareRankingDto> userTrainStat = sysMusicCompareRecordDao.getUserTrainStat(queryInfo.getStartTime(), queryInfo.getEndTime(), queryInfo.getHeardLevel());
 		List<MusicCompareRankingDto> detail = new ArrayList<>();
-		userTrainStat.sort(Comparator.comparing(m->m.getTrainDays()+m.getTrainNum()+m.getTrainTime()));
+		switch (queryInfo.getOrderType()){
+			case 1:
+				userTrainStat.sort(Comparator.comparing(MusicCompareRankingDto::getScore, Comparator.reverseOrder()).thenComparing(MusicCompareRankingDto::getUserId));
+				break;
+			case 2:
+				userTrainStat.sort(Comparator.comparing(MusicCompareRankingDto::getTrainDays, Comparator.reverseOrder()).thenComparing(MusicCompareRankingDto::getUserId));
+				break;
+			default:
+				userTrainStat.sort(Comparator.comparing(MusicCompareRankingDto::getTrainTime, Comparator.reverseOrder()).thenComparing(MusicCompareRankingDto::getUserId));
+				break;
+		}
+
+		List<Integer> studentIds = userTrainStat.stream().limit(10).map(MusicCompareRankingDto::getUserId).collect(Collectors.toList());
+		Map<Integer, String> studentSubjectMap = new HashMap<>();
+		if(!CollectionUtils.isEmpty(studentIds)){
+			List<Map<Integer, String>> studentSubjectMapList = studentDao.getStudentSubjectMapList(studentIds);
+			studentSubjectMap = MapUtil.convertIntegerMap(studentSubjectMapList);
+		}
+
 		for (int i = 0; i < userTrainStat.size(); i++) {
-			userTrainStat.get(i).setRankNum(userTrainStat.size()-i);
+			userTrainStat.get(i).setRankNum(i+1);
 			userTrainStat.get(i).setTrainTime(userTrainStat.get(i).getTrainTime()/60);
-			if(userTrainStat.get(i).getUserId().equals(headUserId)){
-				head = userTrainStat.get(i);
+			if(studentSubjectMap.containsKey(userTrainStat.get(i).getUserId())){
+				userTrainStat.get(i).setSubjectName(studentSubjectMap.get(userTrainStat.get(i).getUserId()));
 			}
-			if(userTrainStat.get(i).getRankNum()<=10){
+			if(detail.size()<10){
 				detail.add(userTrainStat.get(i));
 			}
-		}
-		if(Objects.isNull(head.getRankNum())&&Objects.nonNull(user)){
-			head.setAvatar(user.getAvatar());
-			head.setStudentName(user.getUsername());
+			if(userTrainStat.get(i).getUserId().equals(queryInfo.getUserId())){
+				head = userTrainStat.get(i);
+			}
 		}
 		result.setHead(head);
 		detail.sort(Comparator.comparing(MusicCompareRankingDto::getRankNum).thenComparing(MusicCompareRankingDto::getUserId));
@@ -127,6 +170,7 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 
 		PageInfo<SysMusicCompareRecord> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
 		Map<String, Object> params = new HashMap<>();
+		queryInfo.setFeatureType(FeatureType.CLOUD_STUDY_EVALUATION);
 		MapUtil.populateMap(params, queryInfo);
 
 		List<SysMusicCompareRecord> dataList = null;
@@ -141,8 +185,23 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 		}
 		pageInfo.setRows(dataList);
 		Map<String, Object> result = new HashMap<>();
+		userTrainOverView.setTrainTime(userTrainOverView.getTrainTime()/60);
 		result.put("userTrainOverView",userTrainOverView);
-		result.put("userTrainChartData",userTrainChartData);
+
+		List<IndexBaseDto> userTrainChartResult = new ArrayList<>();
+		List<IndexBaseMonthData> trainNumData = new ArrayList<>();
+		List<IndexBaseMonthData> trainTimeData = new ArrayList<>();
+
+		for (StudentTrainChartDto data : userTrainChartData) {
+			Date trainDate = Date.from(data.getTrainDate().atStartOfDay(DateUtil.zoneId).toInstant());
+			trainTimeData.add(new IndexBaseMonthData(trainDate, null, new BigDecimal(data.getTrainTime()/60)));
+			trainNumData.add(new IndexBaseMonthData(trainDate, null, new BigDecimal(data.getTrainNum())));
+		}
+
+		userTrainChartResult.add(new IndexBaseDto(IndexDataType.CLOUD_STUDY_TRAIN_TIME, trainTimeData));
+		userTrainChartResult.add(new IndexBaseDto(IndexDataType.CLOUD_STUDY_TRAIN_NUM, trainNumData));
+
+		result.put("userTrainChartData", userTrainChartResult);
 		result.put("detail",pageInfo);
 		return result;
 	}

+ 45 - 0
mec-biz/src/main/resources/config/mybatis/StudentMapper.xml

@@ -1180,6 +1180,51 @@
         GROUP BY stu.teacher_id_
     </select>
 
+    <select id="getStudentSubjectMapList" resultType="java.util.Map">
+        SELECT stu.user_id_ 'key',sub.name_ 'value'
+        FROM student stu
+             LEFT JOIN `subject` sub ON stu.subject_id_list_ = sub.id_
+        WHERE stu.user_id_ IN
+        <foreach collection="studentIds" item="studentId" open="(" close=")" separator=",">
+            #{studentId}
+        </foreach>
+    </select>
+    <select id="getOrganCloudNewStudentNum" resultType="com.ym.mec.biz.dal.dto.BaseMapDto">
+        SELECT cssp.`user_id_` 'key',count(cs.`id_`) 'value' FROM `course_schedule_student_payment` cssp
+        STRAIGHT_JOIN `course_schedule` cs on cssp.`course_schedule_id_` = cs.`id_`
+        WHERE cs.`status_` = 'OVER' AND cs.`group_type_` = 'MUSIC' AND cs.`del_flag_` = 0
+        <if test="musicGroupIds != null and musicGroupIds.size() > 0">
+            AND cs.music_group_id_ IN
+            <foreach collection="musicGroupIds" item="musicGroupId" open="(" close=")" separator=",">
+                #{musicGroupId}
+            </foreach>
+        </if>
+        <if test="userIds != null and userIds.size() > 0">
+            AND cssp.user_id_ IN
+            <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
+                #{userId}
+            </foreach>
+        </if>
+        GROUP BY cssp.`user_id_`
+    </select>
+    <select id="groupOrganId" resultType="java.util.Map">
+        SELECT su.organ_id_ 'key',COUNT(DISTINCT su.id_) 'value' FROM sys_user su
+        WHERE 1 = 1
+        <if test="userIds!=null and userIds.size() > 0">
+            AND su.id_ IN
+            <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
+                #{userId}
+            </foreach>
+        </if>
+        <if test="organIds!=null and organIds.size() > 0">
+            AND su.organ_id_ IN
+            <foreach collection="organIds" item="organId" open="(" close=")" separator=",">
+                #{organId}
+            </foreach>
+        </if>
+        GROUP BY su.organ_id_
+    </select>
+
     <update id="updateGrade"><![CDATA[
         UPDATE student SET current_grade_num_=current_grade_num_+1
         WHERE current_grade_num_>=1

+ 10 - 0
mec-biz/src/main/resources/config/mybatis/StudentRegistrationMapper.xml

@@ -1687,4 +1687,14 @@
         </if>
         GROUP BY sr.user_id_
     </select>
+    <select id="findMusicGroupIds" resultType="java.lang.String">
+        SELECT DISTINCT sr.music_group_id_ FROM student_registration sr
+        LEFT JOIN music_group mg ON sr.music_group_id_ = mg.id_
+        WHERE sr.music_group_status_ = 'NORMAL' AND mg.status_ = 'PROGRESS'
+    </select>
+    <select id="findStudentIds" resultType="java.lang.Integer">
+        SELECT DISTINCT sr.user_id_ FROM student_registration sr
+        LEFT JOIN music_group mg ON sr.music_group_id_ = mg.id_
+        WHERE sr.music_group_status_ = 'NORMAL' AND mg.status_ = 'PROGRESS'
+    </select>
 </mapper>

+ 19 - 7
mec-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml

@@ -10,6 +10,7 @@
 		<result column="id_" property="id" />
 		<result column="user_id_" property="userId" />
 		<result column="sys_music_score_id_" property="sysMusicScoreId" />
+		<result column="heard_level_" property="heardLevel" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler" />
 		<result column="sys_music_score_name_" property="sysMusicScoreName" />
 		<result column="behavior_id_" property="behaviorId"/>
 		<result column="score_data_" property="scoreData" />
@@ -43,10 +44,11 @@
 		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
 		</selectKey>
 		-->
-		INSERT INTO sys_music_compare_record (id_,user_id_,sys_music_score_id_,behavior_id_,score_data_,score_,intonation_,cadence_,integrity_,
+		INSERT INTO sys_music_compare_record (id_,user_id_,sys_music_score_id_,heard_level_,behavior_id_,score_data_,score_,intonation_,cadence_,integrity_,
 		                                      record_file_path_,device_type_,client_id_,play_time_,monday_,
 											feature_,create_time_)
-		VALUES(#{id},#{userId},#{sysMusicScoreId},#{behaviorId},#{scoreData},#{score},#{intonation},#{cadence},#{integrity},
+		VALUES(#{id},#{userId},#{sysMusicScoreId},#{heardLevel,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{behaviorId},#{scoreData},
+		       #{score},#{intonation},#{cadence},#{integrity},
 		       #{recordFilePath},#{deviceType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{clientId},#{playTime},#{monday},
 		       #{feature,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}, NOW())
 	</insert>
@@ -118,7 +120,7 @@
 	<!-- 分页查询 -->
 	<select id="queryPage" resultMap="SysMusicCompareRecord" parameterType="map">
 		SELECT
-			smcr.id_, smcr.user_id_, smcr.sys_music_score_id_, smcr.score_, smcr.intonation_, smcr.cadence_,
+			smcr.id_, smcr.user_id_, smcr.sys_music_score_id_,smcr.heard_level_, smcr.score_, smcr.intonation_, smcr.cadence_,
 		       smcr.integrity_, smcr.record_file_path_, smcr.client_id_, smcr.device_type_, smcr.play_time_,
 		       smcr.monday_, smcr.create_time_,
 			sms.name_ sys_music_score_name_
@@ -140,19 +142,25 @@
 			smcr.user_id_ userId,
 			su.avatar_ avatar,
 		    su.username_ studentName,
+		    sms.name_ musicScoreName,
 			COUNT(smcr.id_) trainNum,
-			COUNT(DISTINCT DAY(smcr.create_time_)) trainDays,
+		    MAX(smcr.score_) score,
+			COUNT(DISTINCT DATE(smcr.create_time_)) trainDays,
 			SUM(smcr.play_time_) trainTime
 		FROM sys_music_compare_record smcr
-				 LEFT JOIN sys_user su ON smcr.user_id_=su.id_
+			LEFT JOIN sys_user su ON smcr.user_id_=su.id_
+			LEFT JOIN sys_music_score sms ON smcr.sys_music_score_id_ = sms.id_
 		WHERE EXISTS (SELECT user_id_ FROM student WHERE user_id_=smcr.user_id_)
 		AND DATE_FORMAT(smcr.create_time_, '%Y-%m-%d') BETWEEN #{startTime} AND #{endTime}
+		<if test="heardLevel!=null">
+			AND smcr.heard_level_ = #{heardLevel, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+		</if>
 		GROUP BY smcr.user_id_
 	</select>
 
 	<select id="getUserTrainOverView" resultType="com.ym.mec.biz.dal.dto.StudentTrainOverviewDto">
 		SELECT
-			COUNT(smcr.id_) trainNum,
+			COUNT(DISTINCT smcr.behavior_id_) trainNum,
 			COUNT(DISTINCT DAY(smcr.create_time_)) trainDays,
 			SUM(smcr.play_time_) trainTime
 		FROM sys_music_compare_record smcr
@@ -163,7 +171,7 @@
 	<select id="getUserTrainChartData" resultType="com.ym.mec.biz.dal.dto.StudentTrainChartDto">
 		SELECT
 			DATE_FORMAT(smcr.create_time_, '%Y-%m-%d') trainDate,
-			COUNT(smcr.id_) trainNum,
+			COUNT(DISTINCT smcr.behavior_id_) trainNum,
 			SUM(smcr.play_time_) trainTime
 		FROM sys_music_compare_record smcr
 		WHERE smcr.user_id_=#{userId}
@@ -369,4 +377,8 @@
 							   DATE( smcr.create_time_ ))= CURDATE()) t
 		GROUP BY t.organ_id_
 	</select>
+
+    <select id="getUserLastEvaluationData" resultMap="SysMusicCompareRecord">
+		SELECT * FROM sys_music_compare_record WHERE user_id_=#{userId} ORDER BY create_time_ DESC LIMIT 1
+	</select>
 </mapper>

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

@@ -24,6 +24,7 @@
 		<result column="update_time_" property="updateTime" />
 		<result column="is_show_fingering_" property="isShowFingering" />
 		<result column="memo_" property="memo" />
+		<result column="rank_ids_" property="rankIds" />
 		<result column="client_type_" property="clientType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
 	</resultMap>
 
@@ -119,7 +120,7 @@
 	
 	<!-- 分页查询 -->
 	<select id="queryPage" resultMap="SysMusicScoreAccompaniment" parameterType="map">
-		SELECT sesa.*,ses.name_,ses.type_,ses.url_,s.name_ subject_name_,sesc.name_ categories_name_,sesc.id_ categories_id_,ses.client_type_
+		SELECT sesa.*,ses.name_,ses.type_,ses.url_,s.name_ subject_name_,sesc.name_ categories_name_,sesc.id_ categories_id_,ses.client_type_,ses.rank_ids_
 		FROM sys_music_score ses
 		LEFT JOIN sys_music_score_accompaniment sesa ON ses.id_ = sesa.exam_song_id_
 		LEFT JOIN sys_music_score_categories sesc ON sesc.id_ = ses.music_score_categories_id_

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

@@ -19,6 +19,7 @@
 		<result column="create_user_name_" property="createUserName" />
 		<result column="del_flag_" property="delFlag" />
 		<result column="order_" property="order" />
+		<result column="rank_ids_" property="rankIds" />
 		<result column="client_type_" property="clientType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
 		<result column="update_time_" property="updateTime" />
 		<result column="create_time_" property="createTime" />
@@ -36,9 +37,9 @@
 	
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.SysMusicScore" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		INSERT INTO sys_music_score (music_score_categories_id_,name_,type_,speed_,url_,create_user_id_,order_,update_time_,create_time_,client_type_)
+		INSERT INTO sys_music_score (music_score_categories_id_,name_,type_,speed_,url_,create_user_id_,order_,update_time_,create_time_,client_type_,rank_ids_)
 		VALUES(#{musicScoreCategoriesId},#{name},#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
-		       #{speed},#{url},#{createUserId},#{order},NOW(),NOW(),#{clientType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
+		       #{speed},#{url},#{createUserId},#{order},NOW(),NOW(),#{clientType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{rankIds})
 	</insert>
 
 	<!-- 根据主键查询一条记录 -->
@@ -47,6 +48,7 @@
 		<if test="clientType != null">
 			client_type_ = #{clientType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
 		</if>
+			rank_ids_ = #{rankIds},
 		<if test="order != null">
 			order_ = #{order},
 		</if>
@@ -127,6 +129,14 @@
 					AND ses.type_ = #{type}
 				</if>
 			</if>
+			<if test="rankType != null">
+				<if test="rankType == 0">
+					AND ses.rank_ids_ IS NULL
+				</if>
+				<if test="rankType == 1">
+					AND ses.rank_ids_ IS NOT NULL
+				</if>
+			</if>
 			<if test="type == null or type == ''">
 				<if test="createUserId != null">
 					AND ses.create_user_id_ = #{createUserId}

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

@@ -11,6 +11,7 @@
         <result column="mobile_no_" property="mobileNo"/>
         <result column="title_" property="title"/>
         <result column="content_" property="content"/>
+        <result column="url_" property="url"/>
         <result column="user_id_" property="userId"/>
         <result column="username_" property="username"/>
         <result column="create_time_" property="createTime"/>
@@ -31,14 +32,17 @@
     <!-- 向数据库增加一条记录 -->
     <insert id="insert" parameterType="com.ym.mec.biz.dal.entity.SysSuggestion" useGeneratedKeys="true" keyColumn="id"
             keyProperty="id">
-        INSERT INTO sys_suggestion (id_,mobile_no_,title_,content_,user_id_,create_time_,client_type_,type_)
-        VALUES(#{id},#{mobileNo},#{title},#{content},#{userId},now(),#{clientType},#{type, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
+        INSERT INTO sys_suggestion (mobile_no_,title_,content_,user_id_,create_time_,client_type_,type_,url_)
+        VALUES(#{mobileNo},#{title},#{content},#{userId},now(),#{clientType},#{type, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{url})
     </insert>
 
     <!-- 根据主键查询一条记录 -->
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.SysSuggestion">
         UPDATE sys_suggestion
         <set>
+            <if test="url != null">
+                url_ = #{url},
+            </if>
             <if test="clientType != null">
                 client_type_ = #{clientType},
             </if>

+ 3 - 2
mec-student/src/main/java/com/ym/mec/student/controller/CloudStudyController.java

@@ -32,12 +32,13 @@ public class CloudStudyController extends BaseController {
 
     @ApiOperation("云教练排行榜")
     @GetMapping("rankingList")
-    public HttpResponseResult rankingList(String startDate, String endDate){
+    public HttpResponseResult rankingList(SysMusicCompareRecordQueryInfo queryInfo){
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null) {
             return failed("获取用户信息失败");
         }
-        return succeed(sysMusicCompareRecordService.rankingList(sysUser.getId(), startDate, endDate));
+        queryInfo.setUserId(sysUser.getId());
+        return succeed(sysMusicCompareRecordService.rankingList(queryInfo));
     }
 
     @ApiOperation("学员训练数据统计")

+ 13 - 0
mec-student/src/main/java/com/ym/mec/student/controller/SysMusicCompareRecordController.java

@@ -2,6 +2,7 @@ package com.ym.mec.student.controller;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.MusicalNotesPlayStatDto;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import com.ym.mec.biz.service.SysMusicCompareRecordService;
 import com.ym.mec.common.controller.BaseController;
@@ -10,10 +11,12 @@ import com.ym.mec.common.exception.BizException;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -45,4 +48,14 @@ public class SysMusicCompareRecordController extends BaseController {
         return succeed(sysMusicCompareRecordService.insert(record));
     }
 
+    @ApiOperation(value = "用户最后一次评测数据")
+    @GetMapping("getLastEvaluationMusicalNotesPlayStats")
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId()));
+    }
+
 }

+ 13 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/SysMusicCompareRecordController.java

@@ -2,6 +2,7 @@ package com.ym.mec.teacher.controller;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.MusicalNotesPlayStatDto;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import com.ym.mec.biz.service.SysMusicCompareRecordService;
 import com.ym.mec.common.controller.BaseController;
@@ -10,10 +11,12 @@ import com.ym.mec.common.exception.BizException;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -45,4 +48,14 @@ public class SysMusicCompareRecordController extends BaseController {
         return succeed(sysMusicCompareRecordService.insert(record));
     }
 
+    @ApiOperation(value = "用户最后一次评测数据")
+    @GetMapping("getLastEvaluationMusicalNotesPlayStats")
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId()));
+    }
+
 }

+ 13 - 0
mec-web/src/main/java/com/ym/mec/web/controller/education/SysMusicCompareRecordController.java

@@ -2,6 +2,7 @@ package com.ym.mec.web.controller.education;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.MusicalNotesPlayStatDto;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import com.ym.mec.biz.service.SysMusicCompareRecordService;
 import com.ym.mec.common.controller.BaseController;
@@ -10,10 +11,12 @@ import com.ym.mec.common.exception.BizException;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -45,4 +48,14 @@ public class SysMusicCompareRecordController extends BaseController {
         return succeed(sysMusicCompareRecordService.insert(record));
     }
 
+    @ApiOperation(value = "用户最后一次评测数据")
+    @GetMapping("getLastEvaluationMusicalNotesPlayStats")
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId()));
+    }
+
 }