Browse Source

Merge remote-tracking branch 'origin/master'

周箭河 4 năm trước cách đây
mục cha
commit
7b8504e00d
31 tập tin đã thay đổi với 662 bổ sung62 xóa
  1. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysUserCashAccountDetailDao.java
  2. 4 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysUserCoursesAccountDetailDao.java
  3. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherIncomeDto.java
  4. 12 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherServeDto.java
  5. 12 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupApplyDto.java
  6. 33 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCashAccountDetail.java
  7. 35 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCoursesAccountDetail.java
  8. 5 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/DeductReasonEnum.java
  9. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/TeachIncomeTypeEnum.java
  10. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/TeacherServeQueryInfo.java
  11. 14 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SoundService.java
  12. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupService.java
  13. 22 20
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java
  14. 191 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundServiceImpl.java
  15. 22 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java
  16. 1 3
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  17. 1 1
      mec-biz/src/main/resources/config/mybatis/CourseScheduleTeacherSalaryMapper.xml
  18. 3 0
      mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml
  19. 18 0
      mec-biz/src/main/resources/config/mybatis/StudentExtracurricularExercisesSituationMapper.xml
  20. 12 0
      mec-biz/src/main/resources/config/mybatis/SysUserCashAccountDetailMapper.xml
  21. 14 9
      mec-biz/src/main/resources/config/mybatis/SysUserCoursesAccountDetailMapper.xml
  22. 1 1
      mec-biz/src/main/resources/config/mybatis/VipGroupMapper.xml
  23. 6 0
      mec-common/common-core/pom.xml
  24. 19 1
      mec-student/src/main/java/com/ym/mec/student/controller/SysMessageController.java
  25. 69 0
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/SoundController.java
  26. 6 5
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherVipGroupController.java
  27. 96 3
      mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java
  28. 20 4
      mec-web/src/main/java/com/ym/mec/web/controller/SysMessageController.java
  29. 0 1
      mec-web/src/main/java/com/ym/mec/web/controller/SysUserCoursesAccountDetailController.java
  30. 1 1
      mec-web/src/main/java/com/ym/mec/web/controller/VipGroupManageController.java
  31. 19 1
      mec-web/src/main/java/com/ym/mec/web/controller/education/SysEduMessageController.java

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

@@ -37,4 +37,6 @@ public interface SysUserCashAccountDetailDao extends BaseDAO<Long, SysUserCashAc
      */
     List<SysUserCashAccountDetail> queryAccountDetail(Map<String, Object> params);
     int countAccountDetails(Map<String, Object> params);
+
+    List<SysUserCashAccountDetail> exportDetail(Integer userId);
 }

+ 4 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysUserCoursesAccountDetailDao.java

@@ -3,7 +3,10 @@ package com.ym.mec.biz.dal.dao;
 import com.ym.mec.biz.dal.entity.SysUserCoursesAccountDetail;
 import com.ym.mec.common.dal.BaseDAO;
 
+import java.util.List;
+
 public interface SysUserCoursesAccountDetailDao extends BaseDAO<Long, SysUserCoursesAccountDetail> {
 
-	
+
+    List<SysUserCoursesAccountDetail> exportDetail(Integer userId);
 }

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherIncomeDto.java

@@ -26,6 +26,8 @@ public class TeacherIncomeDto extends CourseSchedule {
 
     private long sortNum;
 
+    private List<TeacherSalaryDeductReasonDto> incomes;
+
     private List<TeacherSalaryDeductReasonDto> deductReasons;
 
     public long getSortNum() {
@@ -93,4 +95,12 @@ public class TeacherIncomeDto extends CourseSchedule {
     public void setBelongToDaya(Boolean belongToDaya) {
         this.belongToDaya = belongToDaya;
     }
+
+    public List<TeacherSalaryDeductReasonDto> getIncomes() {
+        return incomes;
+    }
+
+    public void setIncomes(List<TeacherSalaryDeductReasonDto> incomes) {
+        this.incomes = incomes;
+    }
 }

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherServeDto.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.dal.dto;
 import com.ym.mec.biz.dal.enums.JobNatureEnum;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -51,6 +52,17 @@ public class TeacherServeDto {
     /** 及时训练评价次数 */
     private Integer exercisesMessageTimelyNum;
 
+    @ApiModelProperty(value = "提交率")
+    private String submitRate;
+
+    public String getSubmitRate() {
+        return submitRate;
+    }
+
+    public void setSubmitRate(String submitRate) {
+        this.submitRate = submitRate;
+    }
+
     public Integer getExpectExercisesNum() {
         return expectExercisesNum;
     }

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupApplyDto.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.dal.dto;
 
+import com.sun.org.apache.xpath.internal.operations.Bool;
 import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice;
 import io.swagger.annotations.ApiModelProperty;
@@ -24,6 +25,17 @@ public class VipGroupApplyDto {
 
     private BigDecimal singleClassPrice;
 
+    @ApiModelProperty(value = "是否允许超出活动允许的学生使用次数")
+    private Boolean allowOverstepActivityStudentNum = false;
+
+    public Boolean getAllowOverstepActivityStudentNum() {
+        return allowOverstepActivityStudentNum;
+    }
+
+    public void setAllowOverstepActivityStudentNum(Boolean allowOverstepActivityStudentNum) {
+        this.allowOverstepActivityStudentNum = allowOverstepActivityStudentNum;
+    }
+
     public BigDecimal getSingleClassPrice() {
         return singleClassPrice;
     }

+ 33 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCashAccountDetail.java

@@ -23,6 +23,15 @@ public class SysUserCashAccountDetail {
 	@ApiModelProperty(value = "用户编号",required = false)
 	private Integer userId;
 
+	@ApiModelProperty(value = "手机号",required = false)
+	private String phone;
+
+	@ApiModelProperty(value = "姓名",required = false)
+	private String username;
+
+	@ApiModelProperty(value = "声部",required = false)
+	private String subjectName;
+
 	/** 交易流水号 */
 	@ApiModelProperty(value = "交易流水号",required = false)
 	private String transNo;
@@ -79,6 +88,30 @@ public class SysUserCashAccountDetail {
 	@ApiModelProperty(value = "平台账户号",required = false)
 	private String platformAccountNo;
 
+	public String getPhone() {
+		return phone;
+	}
+
+	public void setPhone(String phone) {
+		this.phone = phone;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getSubjectName() {
+		return subjectName;
+	}
+
+	public void setSubjectName(String subjectName) {
+		this.subjectName = subjectName;
+	}
+
 	public String getAttribute() {
 		return attribute;
 	}

+ 35 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCoursesAccountDetail.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.dal.entity;
 import com.ym.mec.biz.dal.enums.DealStatusEnum;
 import com.ym.mec.biz.dal.enums.PlatformCashAccountDetailTypeEnum;
 import com.ym.mec.biz.dal.enums.TransTypeEnum;
+import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
 /**
@@ -15,6 +16,15 @@ public class SysUserCoursesAccountDetail {
 	
 	/** 用户编号 */
 	private Integer userId;
+
+	@ApiModelProperty(value = "手机号",required = false)
+	private String phone;
+
+	@ApiModelProperty(value = "姓名",required = false)
+	private String username;
+
+	@ApiModelProperty(value = "声部",required = false)
+	private String subjectName;
 	
 	/** 交易流水号 */
 	private String transNo;
@@ -54,7 +64,31 @@ public class SysUserCoursesAccountDetail {
 	
 	/** 平台账户号 */
 	private String platformAccountNo;
-	
+
+	public String getPhone() {
+		return phone;
+	}
+
+	public void setPhone(String phone) {
+		this.phone = phone;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getSubjectName() {
+		return subjectName;
+	}
+
+	public void setSubjectName(String subjectName) {
+		this.subjectName = subjectName;
+	}
+
 	public void setId(Long id){
 		this.id = id;
 	}

+ 5 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/DeductReasonEnum.java

@@ -11,7 +11,11 @@ public enum DeductReasonEnum implements BaseEnum<String,DeductReasonEnum> {
     SIGN_OUT_TIME_ERR("SIGN_OUT_TIME_ERR", "签退时间异常", ""),
     GPS_ERR("GPS_ERR", "位置异常", ""),
     NOT_SETTLEMENT("NOT_SETTLEMENT", "不结算课酬", "特殊老师不结算课酬"),
-    TRAIL("TRAIL", "试用期扣减", "试用期老师课酬按正式老师的80%计算");
+    TRAIL("TRAIL", "试用期扣减", "试用期老师课酬按正式老师的80%计算"),
+
+    //收入
+    SALARY("SALARY", "基本课酬", "课时应发课酬"),
+    COURSE_SUBSIDY("COURSE_SUBSIDY", "课酬调剂", "课时课酬调剂金额");
 
     private String code;
 

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/TeachIncomeTypeEnum.java

@@ -4,7 +4,7 @@ import com.ym.mec.common.enums.BaseEnum;
 
 public enum TeachIncomeTypeEnum implements BaseEnum<String, TeachIncomeTypeEnum> {
 	SALARY("SALARY", "课酬"),
-	SUBSIDY("SUBSIDY", "教学点补贴"),
+	SUBSIDY("SUBSIDY", "课程补贴"),
 	SALE_REWARD("SALE_REWARD", "销售奖励");
 
 	private String code;

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

@@ -44,6 +44,17 @@ public class TeacherServeQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "及时训练评价次数是否达到预期")
     private Integer exercisesMessageTimelyNumIsAchieve;
 
+    @ApiModelProperty(value = "服务是否异常")
+    private Boolean serviceIsError;
+
+    public Boolean getServiceIsError() {
+        return serviceIsError;
+    }
+
+    public void setServiceIsError(Boolean serviceIsError) {
+        this.serviceIsError = serviceIsError;
+    }
+
     public JobNatureEnum getJobNature() {
         return jobNature;
     }

+ 14 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SoundService.java

@@ -0,0 +1,14 @@
+package com.ym.mec.biz.service;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/19 0019
+ **/
+public interface SoundService {
+
+    void compare(MultipartFile record, Integer musicScoreId);
+
+}

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

@@ -25,6 +25,7 @@ import com.ym.mec.biz.dal.page.VipGroupAttendanceQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupSalaryQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupTeachingRecordQueryInfo;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
 
@@ -37,7 +38,7 @@ public interface VipGroupService extends BaseService<Long, VipGroup> {
      * @param vipGroup: VIP课申请信息
      * @return void
      */
-    String createVipGroup(VipGroupApplyDto vipGroup);
+    HttpResponseResult createVipGroup(VipGroupApplyDto vipGroup);
 
     /**
      * @describe 获取教务与教师共有分部

+ 22 - 20
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java

@@ -2160,14 +2160,17 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
             //教师
             Teacher teacher = idTeacherMap.get(teacherSalary.getUserId());
 
-            if(Objects.nonNull(teacherSalary.getActualSalary())){
-                continue;
-            }
-
             if(Objects.isNull(teacherSalary.getSubsidy())){
                 teacherSalary.setSubsidy(zero);
             }
 
+            teacherSalary.setExpectSalary(teacherSalary.getExpectSalary().setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP));
+            teacherSalary.setSubsidy(teacherSalary.getSubsidy().setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP));
+
+            if(Objects.nonNull(teacherSalary.getActualSalary())){
+                continue;
+            }
+
             switch (courseSchedule.getGroupType()){
                 case MUSIC:
                     calMusicCourseTeacherActualSalary(courseSchedule, teacherSalary, teacherAttendances, school, teacher, attendanceRange, false);
@@ -2278,6 +2281,9 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
                     teacherSalary.setSubsidy(zero);
                 }
 
+                teacherSalary.setExpectSalary(teacherSalary.getExpectSalary().setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP));
+                teacherSalary.setSubsidy(teacherSalary.getSubsidy().setScale(BigDecimal.ZERO.intValue(), BigDecimal.ROUND_HALF_UP));
+
                 BigDecimal oldSalary = null;
                 BigDecimal oldSubsidy = null;
                 if(Objects.nonNull(teacherSalary.getSettlementTime())){
@@ -2331,6 +2337,13 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
                 }
                 teacherIncomeInfo.setBelongToDaya(teacherSalary.getBelongToDaya());
                 teacherIncomeInfo.setSortNum(courseSchedule.getStartClassTime().getTime()+courseSchedule.getId());
+
+                //收入项
+                List<TeacherSalaryDeductReasonDto> incomes = new ArrayList<>();
+                incomes.add(new TeacherSalaryDeductReasonDto(DeductReasonEnum.SALARY, teacherIncomeInfo.getExpectSalary()));
+                incomes.add(new TeacherSalaryDeductReasonDto(DeductReasonEnum.COURSE_SUBSIDY, teacherIncomeInfo.getSubsidy()));
+                teacherIncomeInfo.setIncomes(incomes);
+
                 dataList.add(teacherIncomeInfo);
             }
         }
@@ -2436,18 +2449,12 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         salaryResult.put("amount", BigDecimal.ZERO);
         salaryResult.put("data", Collections.emptyList());
 
-        Map<String, Object> subsidyResult = new HashMap<>();
-        subsidyResult.put("desc", "教学点补贴");
-        subsidyResult.put("amount", BigDecimal.ZERO);
-        subsidyResult.put("data", Collections.emptyList());
-
         Map<String, Object> saleRewardResult = new HashMap<>();
         saleRewardResult.put("desc", "销售奖励");
         saleRewardResult.put("amount", BigDecimal.ZERO);
         saleRewardResult.put("data", Collections.emptyList());
 
         data.add(salaryResult);
-        data.add(subsidyResult);
         data.add(saleRewardResult);
 
         result.put("data", data);
@@ -2493,10 +2500,10 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         List<LocalDateBigDecimalMapDto> subsidyList = new ArrayList<>();
         List<LocalDateBigDecimalMapDto> saleRewardList = new ArrayList<>();
         for (LocalDateBigDecimalMapDto localDateBigDecimalMapDto : monthIncomeMapList) {
-            if(localDateBigDecimalMapDto.getAmount().compareTo(BigDecimal.ZERO)<0){
-                localDateBigDecimalMapDto.setSubsidy(localDateBigDecimalMapDto.getSubsidy().subtract(localDateBigDecimalMapDto.getAmount().abs()));
-                localDateBigDecimalMapDto.setAmount(BigDecimal.ZERO);
-            }
+//            if(localDateBigDecimalMapDto.getAmount().compareTo(BigDecimal.ZERO)<0){
+//                localDateBigDecimalMapDto.setSubsidy(localDateBigDecimalMapDto.getSubsidy().subtract(localDateBigDecimalMapDto.getAmount().abs()));
+//                localDateBigDecimalMapDto.setAmount(BigDecimal.ZERO);
+//            }
 
             LocalDateBigDecimalMapDto subsidyData = new LocalDateBigDecimalMapDto();
             BeanUtils.copyProperties(localDateBigDecimalMapDto, subsidyData);
@@ -2511,15 +2518,10 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
 
         BigDecimal reduce = monthIncomeMapList.stream().map(LocalDateBigDecimalMapDto::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
 
-        BigDecimal subsidy = monthIncomeMapList.stream().map(LocalDateBigDecimalMapDto::getSubsidy).reduce(BigDecimal.ZERO, BigDecimal::add);
-
-        result.put("total", reduce.add(subsidy));
+        result.put("total", reduce);
         salaryResult.put("amount", reduce);
         salaryResult.put("data", monthIncomeMapList);
 
-        subsidyResult.put("amount", subsidy);
-        subsidyResult.put("data", subsidyList);
-
         saleRewardResult.put("data", saleRewardList);
 
         return result;

+ 191 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundServiceImpl.java

@@ -0,0 +1,191 @@
+package com.ym.mec.biz.service.impl;
+
+import be.tarsos.dsp.AudioDispatcher;
+import be.tarsos.dsp.AudioEvent;
+import be.tarsos.dsp.AudioProcessor;
+import be.tarsos.dsp.SilenceDetector;
+import be.tarsos.dsp.beatroot.BeatRootOnsetEventHandler;
+import be.tarsos.dsp.io.PipedAudioStream;
+import be.tarsos.dsp.io.TarsosDSPAudioFormat;
+import be.tarsos.dsp.io.TarsosDSPAudioInputStream;
+import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
+import be.tarsos.dsp.onsets.ComplexOnsetDetector;
+import be.tarsos.dsp.onsets.OnsetHandler;
+import com.alibaba.fastjson.JSON;
+import com.ym.mec.biz.dal.dao.SysMusicScoreDao;
+import com.ym.mec.biz.dal.entity.SysMusicScore;
+import com.ym.mec.biz.service.SoundService;
+import com.ym.mec.common.exception.BizException;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/19 0019
+ */
+@Service
+public class SoundServiceImpl implements SoundService {
+
+    private float sampleRate = 44100;
+
+    @Autowired
+    private SysMusicScoreDao sysMusicScoreDao;
+
+    /**
+     * @describe 音频节拍信息提取
+     * @author Joburgess
+     * @date 2021/5/19 0019
+     * @return
+     */
+    private List<Double> beatExtractor(byte[] bytes, String url) throws UnsupportedAudioFileException, IOException {
+        List<Double> times = new ArrayList<>();
+        int size = 256;
+        int overlap = 128;
+        AudioDispatcher dispatcher = StringUtils.isBlank(url)?getFromByteArray(bytes, size, overlap):getFromFile(url, size, overlap);
+
+        ComplexOnsetDetector detector = new ComplexOnsetDetector(size);
+        BeatRootOnsetEventHandler handler = new BeatRootOnsetEventHandler();
+        detector.setHandler(handler);
+
+        dispatcher.addAudioProcessor(detector);
+        dispatcher.run();
+
+        handler.trackBeats(new OnsetHandler() {
+            @Override
+            public void handleOnset(double time, double salience) {
+                times.add(time);
+            }
+        });
+        return times;
+    }
+
+    /**
+     * @describe 音频分贝信息提取
+     * @author Joburgess
+     * @date 2021/5/19 0019
+     * @param bytes: 文件字节
+     * @return java.util.List<java.lang.Double>
+     */
+    private List<Double> soundPressureLevelExtractor(byte[] bytes, String url, Double duration) throws UnsupportedAudioFileException, IOException {
+        List<Double> pitchs = new ArrayList<>();
+        int size = 2048;
+        int overlap = 0;
+        Double[] t = new Double[1];
+        final SilenceDetector silenceDetecor = new SilenceDetector();
+        AudioDispatcher dispatcher = StringUtils.isBlank(url)?getFromByteArray(bytes, size, overlap):getFromFile(url, size, overlap);
+        dispatcher.addAudioProcessor(silenceDetecor);
+        dispatcher.addAudioProcessor(new AudioProcessor() {
+            @Override
+            public void processingFinished() {
+
+            }
+
+            @Override
+            public boolean process(AudioEvent audioEvent) {
+                t[0] = audioEvent.getEndTimeStamp();
+                pitchs.add(Double.isInfinite(silenceDetecor.currentSPL())?0:silenceDetecor.currentSPL());
+                return true;
+            }
+        });
+        dispatcher.run();
+        duration = t[0];
+        return pitchs;
+    }
+
+    private AudioDispatcher getFromByteArray(byte[] bytes, int size, int overlap) throws UnsupportedAudioFileException {
+        AudioFormat audioFormat = new AudioFormat(sampleRate, 16, 1, true, false);
+        AudioDispatcher dispatcher = AudioDispatcherFactory.fromByteArray(bytes, audioFormat, size, overlap);
+        return dispatcher;
+    }
+
+    private AudioDispatcher getFromFile(String url, int size, int overlap) throws UnsupportedAudioFileException, IOException {
+        PipedAudioStream file = new PipedAudioStream(url);
+        TarsosDSPAudioInputStream stream = file.getMonoStream(44100,0);
+
+        AudioDispatcher dispatcher = new AudioDispatcher(stream, size, overlap);
+        return dispatcher;
+    }
+
+    @Override
+    public void compare(MultipartFile record, Integer musicScoreId) {
+        SysMusicScore sysMusicScore = sysMusicScoreDao.get(musicScoreId);
+        if(Objects.isNull(sysMusicScore)|| StringUtils.isBlank(sysMusicScore.getUrl())){
+            throw new BizException("伴奏信息错误");
+        }
+
+        try {
+            URL url = new URL(sysMusicScore.getUrl());
+            String filePath = FileUtils.getTempDirectoryPath()+ System.currentTimeMillis() + ".mp3";
+            File f = new File(filePath);
+            FileUtils.copyURLToFile(url, f);
+
+//            AudioSystem.getAudioFileFormat(loadedFile);
+
+            double l_s = 0;
+            double l_r = 0;
+
+            //相似度
+            List<Double> pitchs_s = soundPressureLevelExtractor(null, filePath, l_s);
+            List<Double> pitchs_r = soundPressureLevelExtractor(record.getBytes(), null, l_r);
+
+            int maxLength = pitchs_s.size();
+            if(pitchs_r.size()<maxLength){
+                maxLength = pitchs_r.size();
+            }
+
+            Double pitchSize = Double.valueOf(0);
+            Double allPitchGap = Double.valueOf(0);
+            for(int i=0;i<maxLength;i++){
+                Double pitch1 = Math.abs(pitchs_s.get(i));
+                Double pitch2 = Math.abs(pitchs_r.get(i));
+                Double pitchGap = Math.abs(pitch1-pitch2);
+                if(pitchGap>pitch1){
+                    pitchGap = pitch1;
+                }
+                allPitchGap+=pitchGap;
+                pitchSize+=pitch1;
+            }
+            Double intonation = 1-(allPitchGap/pitchSize);
+            System.out.printf("音准:%.2f \r\n", intonation);
+
+            //节奏
+            List<Double> times_s = beatExtractor(null, filePath);
+            List<Double> times_r = beatExtractor(record.getBytes(), null);
+
+            float sameTimes = 0;
+            for (Double time1 : times_s) {
+                for (Double time2 : times_r) {
+                    if(Math.abs(time2-time1)<0.1){
+                        sameTimes++;
+                    }
+                }
+            }
+            Double cadence = Double.valueOf(sameTimes/times_s.size());
+            System.out.printf("节奏:%.2f", cadence);
+        } catch (UnsupportedAudioFileException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }finally {
+            return;
+        }
+    }
+}

+ 22 - 7
mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java

@@ -14,7 +14,9 @@ import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.*;
 import com.ym.mec.biz.service.*;
 import com.ym.mec.common.constant.CommonConstants;
+import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.entity.ImGroupMember;
 import com.ym.mec.common.entity.ImGroupModel;
 import com.ym.mec.common.exception.BizException;
@@ -33,15 +35,18 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.http.HttpStatus;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.MessageFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
@@ -163,7 +168,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
 	@Override
-	public String createVipGroup(VipGroupApplyDto vipGroup) {
+	public HttpResponseResult createVipGroup(VipGroupApplyDto vipGroup) {
 
 		if (Objects.isNull(vipGroup.getVipGroupApplyBaseInfo().getUserId())){
 			throw new BizException("请选择指导老师");
@@ -242,15 +247,21 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 		//获取活动信息
 		VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupApplyBaseInfo().getVipGroupActivityId());
-		if(Objects.nonNull(vipGroupActivity)&&Objects.nonNull(vipGroupActivity.getStudentMaxUsedTimes())&&vipGroupActivity.getStudentMaxUsedTimes()!=-1&&StringUtils.isNotBlank(vipGroupApplyBaseInfoDto.getStudentIdList())){
+		if(!vipGroup.getAllowOverstepActivityStudentNum()&&Objects.nonNull(vipGroupActivity)&&Objects.nonNull(vipGroupActivity.getStudentMaxUsedTimes())&&vipGroupActivity.getStudentMaxUsedTimes()!=-1&&StringUtils.isNotBlank(vipGroupApplyBaseInfoDto.getStudentIdList())){
 			List<String> tempStudentIds = Arrays.asList(vipGroupApplyBaseInfoDto.getStudentIdList().split(","));
+			List<Integer> errStudentIds = new ArrayList<>();
 			for (String studentIdStr : tempStudentIds) {
 				int useNum = vipGroupDao.countStudentUserActivityNum(vipGroup.getVipGroupApplyBaseInfo().getVipGroupActivityId(), Integer.valueOf(studentIdStr));
 				if(useNum>=vipGroupActivity.getStudentMaxUsedTimes()){
-					SysUser student = teacherDao.getUser(Integer.valueOf(studentIdStr));
-					throw new BizException("{}学员已超过该活动购买次数限制", student.getUsername());
+					errStudentIds.add(Integer.valueOf(studentIdStr));
 				}
 			}
+			if(errStudentIds.size()>0){
+				List<SimpleUserDto> students = teacherDao.getUsersSimpleInfo(errStudentIds);
+				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+				String studentNames = StringUtils.join(students.stream().map(SimpleUserDto::getNickName).collect(Collectors.toList()), "、");
+				return BaseController.failed(HttpStatus.PARTIAL_CONTENT,"该活动"+studentNames+"学员创建及成课之和已达上限,是否继续创建该课程?");
+			}
 		}
 		//判断课程安排是否超出范围
 		if(Objects.nonNull(vipGroupActivity)&&(Objects.nonNull(vipGroupActivity.getCoursesEndTime())||Objects.nonNull(vipGroupActivity.getCoursesStartTime()))){
@@ -456,7 +467,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 //		}else {
 		sysMessageService.batchSeoMessage(userIds,MessageTypeEnum.BACKSTAGE_TEACHER_APPLY_VIP, JSONObject.toJSONString(memo),teacher.getRealName());
 //		}
-		return vipGroupApplyBaseInfoDto.getAuditStatus().getCode();
+		return BaseController.succeed(vipGroupApplyBaseInfoDto.getAuditStatus().getCode());
 	}
 
 	@Override
@@ -2911,13 +2922,17 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 		}
 
 		if(Objects.nonNull(vipGroupActivity)&&Objects.nonNull(vipGroupActivity.getStudentMaxUsedTimes())&&vipGroupActivity.getStudentMaxUsedTimes()!=-1&&!CollectionUtils.isEmpty(studentIds)){
+			List<Integer> errStudentIds = new ArrayList<>();
 			for (Integer studentId : studentIds) {
 				int useNum = vipGroupDao.countStudentUseingActivityNum(vipGroup.getVipGroupActivityId(), Integer.valueOf(studentId));
 				if(useNum>=vipGroupActivity.getStudentMaxUsedTimes()){
-					SysUser student = teacherDao.getUser(studentId);
-					throw new BizException("{}学员已超过该活动购买次数限制", student.getUsername());
+					errStudentIds.add(studentId);
 				}
 			}
+			if(errStudentIds.size()>0){
+				List<SimpleUserDto> students = teacherDao.getUsersSimpleInfo(errStudentIds);
+				throw new BizException("学员{}已超过该活动购买次数限制", StringUtils.join(students.stream().map(SimpleUserDto::getNickName).collect(Collectors.toList()), ","));
+			}
 		}
 
 		Date now=new Date();

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

@@ -3790,7 +3790,7 @@
                 AND cs.status_ = #{courseStatus, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
             </if>
             <if test="teachIncomeType!=null and teachIncomeType=='SUBSIDY'">
-                AND IF(csts.settlement_time_ IS NULL, s.subsidy_ IS NOT NULL AND s.subsidy_>0, csts.subsidy_ IS NOT NULL AND csts.subsidy_>0)
+                AND csts.subsidy_!=0
             </if>
         </where>
     </sql>
@@ -3801,7 +3801,6 @@
         FROM
             course_schedule cs
             LEFT JOIN course_schedule_teacher_salary csts ON csts.course_schedule_id_ = cs.id_
-            LEFT JOIN school s ON cs.schoole_id_=s.id_
         <include refid="queryTeacherCourseCondition"></include>
         ORDER BY cs.class_date_ DESC,cs.start_class_time_ DESC,cs.id_ DESC
         <include refid="global.limit" />
@@ -3813,7 +3812,6 @@
         FROM
         course_schedule cs
         LEFT JOIN course_schedule_teacher_salary csts ON csts.course_schedule_id_ = cs.id_
-        LEFT JOIN school s ON cs.schoole_id_=s.id_
         <include refid="queryTeacherCourseCondition"></include>
     </select>
 

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

@@ -1129,7 +1129,7 @@
 				DATE_FORMAT( cs.class_date_, '%Y-%m-%d' ) dateStr,
 			</if>
 		    SUM(csts.subsidy_) subsidy,
-			SUM( csts.actual_salary_ - csts.subsidy_ ) amount
+			SUM( csts.actual_salary_) amount
 		FROM
 			course_schedule_teacher_salary csts
 				LEFT JOIN course_schedule cs ON csts.course_schedule_id_ = cs.id_

+ 3 - 0
mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml

@@ -287,6 +287,9 @@
             <if test="type != null and type == 0">
                 AND pg.be_renew_group_id_ IS NOT NULL AND pg.type_='CHARGE'
             </if>
+            <if test="type != null and type == 2">
+                AND pg.type_='FREE'
+            </if>
             <if test="practiceGroupType != null">
                 AND pg.type_=#{practiceGroupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
             </if>

+ 18 - 0
mec-biz/src/main/resources/config/mybatis/StudentExtracurricularExercisesSituationMapper.xml

@@ -290,6 +290,9 @@
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==0">
 				AND exercises_message_num_ &lt; exercises_reply_num_
 			</if>
+			<if test="serviceIsError!=null and serviceIsError">
+				AND (actual_exercises_num_ &lt; expect_exercises_num_ OR exercises_message_num_ &lt; exercises_reply_num_)
+			</if>
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==1">
 				AND exercises_message_num_ &gt;= exercises_reply_num_
 			</if>
@@ -310,6 +313,9 @@
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==0">
 				AND IF(DATE_FORMAT(last_submit_time_, '%Y-%m-%d') BETWEEN #{submitStartDate} AND #{submitEndDate},exercises_message_num_,0) &lt; exercises_reply_num_
 			</if>
+			<if test="serviceIsError!=null and serviceIsError">
+				AND (actual_exercises_num_ &lt; expect_exercises_num_ OR IF(DATE_FORMAT(last_submit_time_, '%Y-%m-%d') BETWEEN #{submitStartDate} AND #{submitEndDate},exercises_message_num_,0) &lt; exercises_reply_num_)
+			</if>
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==1">
 				AND IF(DATE_FORMAT(last_submit_time_, '%Y-%m-%d') BETWEEN #{submitStartDate} AND #{submitEndDate},exercises_message_num_,0) &gt;= exercises_reply_num_
 			</if>
@@ -378,6 +384,9 @@
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==0">
 				AND exercises_message_num_ &lt; exercises_reply_num_
 			</if>
+			<if test="serviceIsError!=null and serviceIsError">
+				AND (actual_exercises_num_ &lt; expect_exercises_num_ OR exercises_message_num_ &lt; exercises_reply_num_)
+			</if>
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==1">
 				AND exercises_message_num_ &gt;= exercises_reply_num_
 			</if>
@@ -398,6 +407,9 @@
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==0">
 				AND IF(DATE_FORMAT(last_submit_time_, '%Y-%m-%d') BETWEEN #{submitStartDate} AND #{submitEndDate},exercises_message_num_,0) &lt; exercises_reply_num_
 			</if>
+			<if test="serviceIsError!=null and serviceIsError">
+				AND (actual_exercises_num_ &lt; expect_exercises_num_ OR IF(DATE_FORMAT(last_submit_time_, '%Y-%m-%d') BETWEEN #{submitStartDate} AND #{submitEndDate},exercises_message_num_,0) &lt; exercises_reply_num_)
+			</if>
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==1">
 				AND IF(DATE_FORMAT(last_submit_time_, '%Y-%m-%d') BETWEEN #{submitStartDate} AND #{submitEndDate},exercises_message_num_,0) &gt;= exercises_reply_num_
 			</if>
@@ -592,6 +604,9 @@
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==0">
 				AND SUM(exercises_message_num_) &lt; SUM(exercises_reply_num_)
 			</if>
+			<if test="serviceIsError!=null and serviceIsError">
+				AND (SUM(actual_exercises_num_) &lt; SUM(expect_exercises_num_) OR SUM(exercises_message_num_) &lt; SUM(exercises_reply_num_))
+			</if>
 			<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==1">
 				AND SUM(exercises_message_num_) &gt;= SUM(exercises_reply_num_)
 			</if>
@@ -639,6 +654,9 @@
 				<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==0">
 					AND SUM(exercises_message_num_) &lt; SUM(exercises_reply_num_)
 				</if>
+				<if test="serviceIsError!=null and serviceIsError">
+					AND (SUM(actual_exercises_num_) &lt; SUM(expect_exercises_num_) OR SUM(exercises_message_num_) &lt; SUM(exercises_reply_num_))
+				</if>
 				<if test="exercisesMessageNumIsAchieve!=null and exercisesMessageNumIsAchieve==1">
 					AND SUM(exercises_message_num_) &gt;= SUM(exercises_reply_num_)
 				</if>

+ 12 - 0
mec-biz/src/main/resources/config/mybatis/SysUserCashAccountDetailMapper.xml

@@ -9,6 +9,9 @@
     <resultMap type="com.ym.mec.biz.dal.entity.SysUserCashAccountDetail" id="SysUserCashAccountDetail">
         <result column="id_" property="id"/>
         <result column="user_id_" property="userId"/>
+        <result column="phone_" property="phone"/>
+        <result column="username_" property="username"/>
+        <result column="subject_name_" property="subjectName"/>
         <result column="trans_no_" property="transNo"/>
         <result column="type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="trans_type_" property="transType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
@@ -238,4 +241,13 @@
             <include refid="queryAccountDetailCondition"/>
         ) t
     </select>
+    <select id="exportDetail" resultMap="SysUserCashAccountDetail">
+        SELECT su.username_,su.phone_,GROUP_CONCAT(sb.name_) subject_name_,cad.* FROM sys_user_cash_account_detail cad
+        LEFT JOIN sys_user su ON su.id_ = cad.user_id_
+        LEFT JOIN student s ON s.user_id_ = su.id_
+        LEFT JOIN `subject` sb ON FIND_IN_SET(sb.id_,s.subject_id_list_)
+        WHERE cad.user_id_ = #{userId}
+        GROUP BY cad.id_
+        ORDER BY cad.id_ DESC
+    </select>
 </mapper>

+ 14 - 9
mec-biz/src/main/resources/config/mybatis/SysUserCoursesAccountDetailMapper.xml

@@ -9,6 +9,9 @@
 	<resultMap type="com.ym.mec.biz.dal.entity.SysUserCoursesAccountDetail" id="SysUserCoursesAccountDetail">
 		<result column="id_" property="id" />
 		<result column="user_id_" property="userId" />
+		<result column="phone_" property="phone"/>
+		<result column="username_" property="username"/>
+		<result column="subject_name_" property="subjectName"/>
 		<result column="trans_no_" property="transNo" />
 		<result column="type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
 		<result column="trans_type_" property="transType"  typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
@@ -36,13 +39,9 @@
 	
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.SysUserCoursesAccountDetail" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		<!--
-		<selectKey resultClass="int" keyProperty="id" > 
-		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
-		</selectKey>
-		-->
 		INSERT INTO sys_user_courses_account_detail (id_,user_id_,trans_no_,type_,trans_type_,status_,amount_,balance_,description_,comment_,attribute1_,channel_,platform_account_no_,create_time_,update_time_)
-		VALUES(#{id},#{userId},#{transNo},#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{transType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{amount},#{balance},#{description},#{comment},#{attribute1},#{channel},#{platformAccountNo},NOW(),NOW())
+		VALUES(#{id},#{userId},#{transNo},#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{transType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+		       #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{amount},#{balance},#{description},#{comment},#{attribute1},#{channel},#{platformAccountNo},NOW(),NOW())
 	</insert>
 	
 	<!-- 根据主键查询一条记录 -->
@@ -52,9 +51,6 @@
 			<if test="status != null">
 				status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
 			</if>
-			<if test="id != null">
-				id_ = #{id},
-			</if>
 			<if test="balance != null">
 				balance_ = #{balance},
 			</if>
@@ -118,4 +114,13 @@
 		SELECT COUNT(*) FROM sys_user_courses_account_detail
 		<include refid="queryPageCondition" />
 	</select>
+	<select id="exportDetail" resultMap="SysUserCoursesAccountDetail">
+		SELECT su.username_,su.phone_,GROUP_CONCAT(sb.name_) subject_name_,cad.* FROM sys_user_courses_account_detail cad
+		LEFT JOIN sys_user su ON su.id_ = cad.user_id_
+		LEFT JOIN student s ON s.user_id_ = su.id_
+		LEFT JOIN `subject` sb ON FIND_IN_SET(sb.id_,s.subject_id_list_)
+		WHERE cad.user_id_ = #{userId}
+		GROUP BY cad.id_
+		ORDER BY cad.id_ DESC
+	</select>
 </mapper>

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

@@ -1042,7 +1042,7 @@
         FROM vip_group vg
         LEFT JOIN class_group_student_mapper cgsm ON vg.id_=cgsm.music_group_id_ AND cgsm.group_type_='VIP'
         WHERE vg.vip_group_activity_id_=#{vipGroupActivityId}
-            AND ((vg.group_status_=1 AND FIND_IN_SET(#{studentId}, vg.student_id_list_)) OR cgsm.user_id_=#{studentId});
+            AND ((vg.group_status_ NOT IN (3, 7) AND FIND_IN_SET(#{studentId}, vg.student_id_list_)) OR cgsm.user_id_=#{studentId});
     </select>
 
     <select id="countStudentUseingActivityNum" resultType="int">

+ 6 - 0
mec-common/common-core/pom.xml

@@ -66,5 +66,11 @@
 			<artifactId>emoji-java</artifactId>
 		</dependency>
 
+
+		<dependency>
+			<groupId>com.github.dragoon000320</groupId>
+			<artifactId>tarsosdsp</artifactId>
+			<version>1.0</version>
+		</dependency>
 	</dependencies>
 </project>

+ 19 - 1
mec-student/src/main/java/com/ym/mec/student/controller/SysMessageController.java

@@ -3,6 +3,8 @@ package com.ym.mec.student.controller;
 import com.alibaba.fastjson.JSON;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.AppVersionInfoDao;
+import com.ym.mec.biz.dal.entity.AppVersionInfo;
 import com.ym.mec.biz.dal.enums.MessageSendMode;
 import com.ym.mec.biz.dal.page.SysMessageQueryInfo;
 import com.ym.mec.biz.service.SysMessageService;
@@ -37,6 +39,9 @@ public class SysMessageController extends BaseController {
 	@Autowired
 	private SysUserFeignService sysUserFeignService;
 
+	@Autowired
+	private AppVersionInfoDao appVersionInfoDao;
+
 	@ApiOperation("获取所有消息列表")
 	@GetMapping(value = "list")
 	public Object list(SysMessageQueryInfo queryInfo){
@@ -52,7 +57,20 @@ public class SysMessageController extends BaseController {
 
 	@ApiOperation("获取消息分类类型")
 	@GetMapping(value = "typeList")
-	public Object typeList(){
+	public Object typeList(String memo){
+		//如果用户使用的版本比当前版本号大,那么屏蔽缴费信息
+		if(StringUtils.isNotEmpty(memo)){
+			//获取当前使用的版本
+			AppVersionInfo appVersionInfo = appVersionInfoDao.queryNewestByPlatform("ios-student").get(0);
+			int defaultVersion = Integer.parseInt(appVersionInfo.getVersion().replaceAll("\\.",""));
+			int currentVersion = Integer.parseInt(memo.replaceAll("\\.",""));
+			if(currentVersion > defaultVersion){
+				return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
+						"{\"value\":\"课程信息\",\"key\":\"COURSE\"}," +
+						"{\"value\":\"作业信息\",\"key\":\"WORK\"}," +
+						"{\"value\":\"其他\",\"key\":\"DEFAULT\"}]"));
+			}
+		}
 		return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
 				"{\"value\":\"缴费信息\",\"key\":\"PAY\"}," +
 				"{\"value\":\"课程信息\",\"key\":\"COURSE\"}," +

+ 69 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/SoundController.java

@@ -0,0 +1,69 @@
+package com.ym.mec.teacher.controller;
+
+import be.tarsos.dsp.AudioDispatcher;
+import be.tarsos.dsp.AudioEvent;
+import be.tarsos.dsp.AudioProcessor;
+import be.tarsos.dsp.SilenceDetector;
+import be.tarsos.dsp.beatroot.BeatRootOnsetEventHandler;
+import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
+import be.tarsos.dsp.onsets.ComplexOnsetDetector;
+import be.tarsos.dsp.onsets.OnsetHandler;
+import com.netflix.discovery.converters.Auto;
+import com.ym.mec.biz.service.SoundService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import java.io.File;
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/19 0019
+ */
+@Api(tags = "音频服务")
+@RequestMapping("sound")
+@RestController
+public class SoundController extends BaseController {
+
+    private final Logger LOGGER = LoggerFactory.getLogger(SoundController.class);
+
+    @Autowired
+    private SoundService soundService;
+
+    @ApiOperation(value = "评分")
+    @PostMapping("compare")
+    public HttpResponseResult compare(@RequestParam("record") MultipartFile record, Integer musicScoreId){
+        Map<String, String> result = new HashMap<>();
+
+        LOGGER.info("文件名:{},伴奏编号:{}", record.getOriginalFilename(), musicScoreId);
+
+        DecimalFormat df   = new DecimalFormat("######0.00");
+
+        result.put("score", df.format(Math.random()*100));
+        result.put("intonation", df.format(Math.random()*100));
+        result.put("cadence", df.format(Math.random()*100));
+        result.put("integrity", df.format(Math.random()*100));
+
+        soundService.compare(record, musicScoreId);
+
+        return succeed(result);
+    }
+
+}

+ 6 - 5
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherVipGroupController.java

@@ -63,8 +63,7 @@ public class TeacherVipGroupController extends BaseController {
 		vipGroupApplyDto.getVipGroupApplyBaseInfo().setTeacherId(Long.valueOf(userId));
 		vipGroupApplyDto.getVipGroupApplyBaseInfo().setOrganIdList(teacher.getTeacherOrganId().toString());
 		vipGroupApplyDto.getVipGroupApplyBaseInfo().setOrganId(teacher.getTeacherOrganId());
-		vipGroupService.createVipGroup(vipGroupApplyDto);
-		return succeed();
+		return vipGroupService.createVipGroup(vipGroupApplyDto);
 	}
 
 	@ApiOperation("vip课申请-双11")
@@ -118,9 +117,11 @@ public class TeacherVipGroupController extends BaseController {
 			}
 		}
 
-		vipGroupService.createVipGroup(vipGroupApplyDto);
-		vipGroupService.addVipGroupStudents(vipGroupApplyDto.getVipGroupApplyBaseInfo().getId(), studentIds, new HashMap<>());
-		return succeed();
+		HttpResponseResult result = vipGroupService.createVipGroup(vipGroupApplyDto);
+		if(result.getCode()==200){
+			vipGroupService.addVipGroupStudents(vipGroupApplyDto.getVipGroupApplyBaseInfo().getId(), studentIds, new HashMap<>());
+		}
+		return result;
 	}
 
 	@ApiOperation("获取vip课课程和课酬总费用")

+ 96 - 3
mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java

@@ -6,12 +6,15 @@ import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.*;
 import com.ym.mec.biz.service.*;
+import com.ym.mec.common.constant.CommonConstants;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.service.IdGeneratorService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
@@ -130,9 +133,86 @@ public class ExportController extends BaseController {
     private MusicGroupQuitService musicGroupQuitService;
     @Autowired
     private IndexBaseMonthDataService indexService;
-
     @Autowired
     private TeacherCourseStatisticsService teacherCourseStatisticsService;
+    @Autowired
+    private SysUserCashAccountDetailDao sysUserCashAccountDetailDao;
+    @Autowired
+    private SysUserCoursesAccountDetailDao sysUserCoursesAccountDetailDao;
+
+    @ApiOperation(value = "学生个人账户余额导出")
+    @PostMapping("export/userCashAccountDetail")
+    @PreAuthorize("@pcs.hasPermissions('export/userCashAccountDetail')")
+    public void userCashAccountDetail(HttpServletResponse response, Integer userId) throws IOException {
+       List<SysUserCashAccountDetail> cashAccountDetails = sysUserCashAccountDetailDao.exportDetail(userId);
+       if(cashAccountDetails.size() < 1){
+           throw new BizException("没有可导出数据");
+       }
+       if(cashAccountDetails.size() > 49999){
+           throw new BizException("数据超长,请联系管理员");
+       }
+        OutputStream outputStream = response.getOutputStream();
+        try {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"学员编号", "姓名", "电话", "声部",
+                    "交易类型", "交易金额", "交易时间", "备注"}, new String[]{
+                    "userId", "username", "phone", "subjectName",
+                    "type.msg", "amount", "createTime", "comment"}, cashAccountDetails);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=classGroup-" + DateUtil.getDate(new Date()) + ".xls");
+            response.flushBuffer();
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    @ApiOperation(value = "学生个人课程余额导出")
+    @PostMapping("export/userCoursesAccount")
+    @PreAuthorize("@pcs.hasPermissions('export/userCoursesAccount')")
+    public void userCoursesAccount(HttpServletResponse response, Integer userId) throws IOException {
+        List<SysUserCoursesAccountDetail> coursesAccountDetails = sysUserCoursesAccountDetailDao.exportDetail(userId);
+        if(coursesAccountDetails.size() < 1){
+            throw new BizException("没有可导出数据");
+        }
+        if(coursesAccountDetails.size() > 49999){
+            throw new BizException("数据超长,请联系管理员");
+        }
+        OutputStream outputStream = response.getOutputStream();
+        try {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"学员编号", "姓名", "电话", "声部",
+                    "交易类型", "交易金额", "交易时间", "备注"}, new String[]{
+                    "userId", "username", "phone", "subjectName",
+                    "type.msg", "amount", "createTime", "comment"}, coursesAccountDetails);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=classGroup-" + DateUtil.getDate(new Date()) + ".xls");
+            response.flushBuffer();
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 
     @ApiOperation(value = "班级列表导出")
     @PostMapping("export/classGroup")
@@ -2525,13 +2605,26 @@ public class ExportController extends BaseController {
         }
         OutputStream outputStream = response.getOutputStream();
 
+        BigDecimal oneHundred = new BigDecimal(100);
+        BigDecimal zero = new BigDecimal("0.00");
+
         for (TeacherServeDto row : result.getRows()) {
             row.setDateRange(com.ym.mec.util.date.DateUtil.dateToString(row.getMonday(), "yyyy-MM-dd") + '~' + com.ym.mec.util.date.DateUtil.dateToString(row.getSunday(), "yyyy-MM-dd"));
+            if(row.getActualExercisesNum()<=0){
+                row.setSubmitRate(zero.toString()+"%");
+            }else{
+                BigDecimal submitRate = new BigDecimal(row.getExercisesReplyNum()).divide(new BigDecimal(row.getActualExercisesNum()), CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP).multiply(oneHundred);
+                row.setSubmitRate(submitRate+"%");
+            }
         }
 
         try {
-            String[] header = {"分部", "老师编号", "老师姓名", "服务周期", "课后作业(节)", "课外作业(人)", "是否异常", "提醒时间", "操作人"};
-            String[] body = {"organName", "teacherId", "teacherName", "dateRange", "homeworkNum", "exerciseNum", "unDone==0?'否':'是'", "remindDate", "operatorName"};
+            String[] header = {"分部", "老师编号", "老师姓名", "服务周期", "课后作业(节)", "课外作业(人)",
+                    "作业布置", "作业点评", "作业提交率",
+                    "提醒时间", "操作人"};
+            String[] body = {"organName", "teacherId", "teacherName", "dateRange", "homeworkNum", "exerciseNum",
+                    "expectExercisesNum>actualExercisesNum?'异常':'正常'", "exercisesReplyNum>exercisesMessageNum?'异常':'正常'", "submitRate",
+                    "remindDate", "operatorName"};
             HSSFWorkbook workbook = POIUtil.exportExcel(header, body, result.getRows());
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attachment;filename=teacherDefaultSalary-" + DateUtil.getDate(new Date()) + ".xls");

+ 20 - 4
mec-web/src/main/java/com/ym/mec/web/controller/SysMessageController.java

@@ -1,9 +1,12 @@
 package com.ym.mec.web.controller;
 
 import com.alibaba.fastjson.JSON;
+import com.ym.mec.biz.dal.dao.AppVersionInfoDao;
+import com.ym.mec.biz.dal.entity.AppVersionInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -20,9 +23,6 @@ import com.ym.mec.biz.service.SysMessageService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.page.PageInfo;
 
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-
 @RestController
 @Api(tags = "消息服务")
 @RequestMapping("sysMessage")
@@ -34,6 +34,9 @@ public class SysMessageController extends BaseController {
 	@Autowired
 	private SysUserFeignService sysUserFeignService;
 
+	@Autowired
+	private AppVersionInfoDao appVersionInfoDao;
+
 	@ApiOperation("获取所有消息列表")
 	@GetMapping(value = "list")
 	public Object list(SysMessageQueryInfo queryInfo){
@@ -51,7 +54,20 @@ public class SysMessageController extends BaseController {
 
 	@ApiOperation("获取消息分类类型")
 	@GetMapping(value = "typeList")
-	public Object typeList(){
+	public Object typeList(String memo){
+		//如果用户使用的版本比当前版本号大,那么屏蔽缴费信息
+		if(StringUtils.isNotEmpty(memo)){
+			//获取当前使用的版本
+			AppVersionInfo appVersionInfo = appVersionInfoDao.queryNewestByPlatform("ios-education").get(0);
+			int defaultVersion = Integer.parseInt(appVersionInfo.getVersion().replaceAll("\\.",""));
+			int currentVersion = Integer.parseInt(memo.replaceAll("\\.",""));
+			if(currentVersion > defaultVersion){
+				return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
+						"{\"value\":\"学员信息\",\"key\":\"STUDENT\"}," +
+						"{\"value\":\"乐团信息\",\"key\":\"MUSIC\"}," +
+						"{\"value\":\"其他\",\"key\":\"DEFAULT\"}]"));
+			}
+		}
 		return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
 				"{\"value\":\"缴费信息\",\"key\":\"PAY\"}," +
 				"{\"value\":\"学员信息\",\"key\":\"STUDENT\"}," +

+ 0 - 1
mec-web/src/main/java/com/ym/mec/web/controller/SysUserCoursesAccountDetailController.java

@@ -24,7 +24,6 @@ public class SysUserCoursesAccountDetailController extends BaseController {
     @ApiOperation(value = "分页查询用户交易明细")
     @GetMapping("/queryPage")
     public Object queryPage(CashAccountDetail queryInfo) {
-        SysUser user = sysUserFeignService.queryUserInfo();
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if(sysUser == null){
             return failed("获取用户信息失败");

+ 1 - 1
mec-web/src/main/java/com/ym/mec/web/controller/VipGroupManageController.java

@@ -158,7 +158,7 @@ public class VipGroupManageController extends BaseController {
                 vipGroupApplyDto.getVipGroupApplyBaseInfo().setOrganId(Integer.parseInt(employee.getOrganIdList()));
             }
         }
-        return succeed(vipGroupService.createVipGroup(vipGroupApplyDto));
+        return vipGroupService.createVipGroup(vipGroupApplyDto);
     }
 
     @ApiOperation(value = "获取教务与指导老师公共分部")

+ 19 - 1
mec-web/src/main/java/com/ym/mec/web/controller/education/SysEduMessageController.java

@@ -3,6 +3,8 @@ package com.ym.mec.web.controller.education;
 import com.alibaba.fastjson.JSON;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.AppVersionInfoDao;
+import com.ym.mec.biz.dal.entity.AppVersionInfo;
 import com.ym.mec.biz.dal.enums.MessageSendMode;
 import com.ym.mec.biz.dal.page.SysMessageQueryInfo;
 import com.ym.mec.biz.service.SysMessageService;
@@ -35,6 +37,9 @@ public class SysEduMessageController extends BaseController {
 	@Autowired
 	private SysUserFeignService sysUserFeignService;
 
+	@Autowired
+	private AppVersionInfoDao appVersionInfoDao;
+
 	@ApiOperation("获取所有消息列表")
 	@GetMapping(value = "list")
 	public Object list(SysMessageQueryInfo queryInfo){
@@ -50,7 +55,20 @@ public class SysEduMessageController extends BaseController {
 
 	@ApiOperation("获取消息分类类型")
 	@GetMapping(value = "typeList")
-	public Object typeList(){
+	public Object typeList(String memo){
+		//如果用户使用的版本比当前版本号大,那么屏蔽缴费信息
+		if(StringUtils.isNotEmpty(memo)){
+			//获取当前使用的版本
+			AppVersionInfo appVersionInfo = appVersionInfoDao.queryNewestByPlatform("ios-education").get(0);
+			int defaultVersion = Integer.parseInt(appVersionInfo.getVersion().replaceAll("\\.",""));
+			int currentVersion = Integer.parseInt(memo.replaceAll("\\.",""));
+			if(currentVersion > defaultVersion){
+				return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
+						"{\"value\":\"学员信息\",\"key\":\"STUDENT\"}," +
+						"{\"value\":\"乐团信息\",\"key\":\"MUSIC\"}," +
+						"{\"value\":\"其他\",\"key\":\"DEFAULT\"}]"));
+			}
+		}
 		return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
 				"{\"value\":\"缴费信息\",\"key\":\"PAY\"}," +
 				"{\"value\":\"学员信息\",\"key\":\"STUDENT\"}," +