浏览代码

Merge branch 'online1' of http://git.dayaedu.com/yonge/mec into network_room_music_scode_apeed

zouxuan 3 年之前
父节点
当前提交
5b59a684a0
共有 29 个文件被更改,包括 489 次插入205 次删除
  1. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/config/SoundCompareConfig.java
  2. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherAttendanceDao.java
  3. 3 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicGroupSubjectGoodsAndInfoDto.java
  4. 27 80
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCompareHelper.java
  5. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentPaymentOrderExportDto.java
  6. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SellOrder.java
  7. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/HeardLevelEnum.java
  8. 21 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/StudentPreRegistrationQueryInfo.java
  9. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/SellOrderService.java
  10. 6 1
      mec-biz/src/main/java/com/ym/mec/biz/service/SubjectChangeService.java
  11. 9 0
      mec-biz/src/main/java/com/ym/mec/biz/service/TeacherAttendanceService.java
  12. 15 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java
  13. 5 3
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupSubjectPlanServiceImpl.java
  14. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ReplacementInstrumentActivityServiceImpl.java
  15. 50 8
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SellOrderServiceImpl.java
  16. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCheckHandler.java
  17. 126 67
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCompareHandler.java
  18. 12 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRegistrationServiceImpl.java
  19. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRepairServiceImpl.java
  20. 42 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SubjectChangeServiceImpl.java
  21. 6 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java
  22. 12 0
      mec-biz/src/main/resources/config/mybatis/StudentPreRegistrationMapper.xml
  23. 12 0
      mec-biz/src/main/resources/config/mybatis/TeacherAttendanceMapper.xml
  24. 2 0
      mec-im/src/main/java/com/ym/mec/im/IMHelper.java
  25. 5 3
      mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java
  26. 3 0
      mec-student/src/main/java/com/ym/mec/student/controller/MemberRankController.java
  27. 50 22
      mec-student/src/main/java/com/ym/mec/student/controller/MusicGroupController.java
  28. 12 1
      mec-student/src/main/java/com/ym/mec/student/controller/StudentOrderController.java
  29. 5 4
      mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/config/SoundCompareConfig.java

@@ -35,7 +35,7 @@ public class SoundCompareConfig {
     /**
      * @describe 有效分贝大小
      */
-    public int validDb = 35;
+    public int validDb = -65;
     /**
      * @describe 有效频率
      */

+ 5 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherAttendanceDao.java

@@ -266,4 +266,9 @@ public interface TeacherAttendanceDao extends BaseDAO<Long, TeacherAttendance> {
      * @return java.lang.Long
      */
 	Long findFirstSign(@Param("currentScheduleId") Long currentScheduleId, @Param("userId") Integer userId);
+
+	void updateDeviceNum(@Param("courseId") Integer courseId,
+						 @Param("userId") String userId,
+						 @Param("signInDeviceNum") String signInDeviceNum,
+						 @Param("signOutDeviceNum") String signOutDeviceNum);
 }

+ 3 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicGroupSubjectGoodsAndInfoDto.java

@@ -53,7 +53,7 @@ public class MusicGroupSubjectGoodsAndInfoDto {
     
     private List<StudentPaymentOrderDetail> studentPaymentOrderDetailList;
     
-    private Map<CourseScheduleType, BigDecimal> memberCoursePrice = new HashMap<CourseScheduleType, BigDecimal>();
+    private Map<String, BigDecimal> memberCoursePrice = new HashMap<String, BigDecimal>();
 
     public Map getCourseScheduleInfo() {
         return CourseScheduleInfo;
@@ -143,11 +143,11 @@ public class MusicGroupSubjectGoodsAndInfoDto {
 		this.studentPaymentOrderDetailList = studentPaymentOrderDetailList;
 	}
 
-	public Map<CourseScheduleType, BigDecimal> getMemberCoursePrice() {
+	public Map<String, BigDecimal> getMemberCoursePrice() {
 		return memberCoursePrice;
 	}
 
-	public void setMemberCoursePrice(Map<CourseScheduleType, BigDecimal> memberCoursePrice) {
+	public void setMemberCoursePrice(Map<String, BigDecimal> memberCoursePrice) {
 		this.memberCoursePrice = memberCoursePrice;
 	}
 }

+ 27 - 80
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCompareHelper.java

@@ -4,7 +4,6 @@ import be.tarsos.dsp.AudioEvent;
 import be.tarsos.dsp.SilenceDetector;
 import be.tarsos.dsp.pitch.PitchDetectionHandler;
 import be.tarsos.dsp.pitch.PitchDetectionResult;
-import com.alibaba.fastjson.JSON;
 import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
 import com.ym.mec.biz.dal.enums.HeardLevelEnum;
 import com.ym.mec.biz.service.impl.SoundCompareHandler;
@@ -18,7 +17,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * @Author Joburgess
@@ -64,8 +62,8 @@ public class SoundCompareHelper implements PitchDetectionHandler {
     @ApiModelProperty(value = "小节结束时间字典")
     private Map<Integer, MusicPitchDetailDto> measureEndTime = new HashMap<>();
 
-//    @ApiModelProperty(value = "录音音频信息")
-//    private List<MusicPitchDetailDto> recordMeasurePithInfo = new ArrayList<>();
+    @ApiModelProperty(value = "录音音频信息")
+    private List<MusicPitchDetailDto> recordMeasurePithInfo = new ArrayList<>();
 
     @ApiModelProperty(value = "小节分数记录")
     private Map<String, BigDecimal> userScoreMap = new HashMap<>();
@@ -83,10 +81,6 @@ public class SoundCompareHelper implements PitchDetectionHandler {
 
     private List<MusicPitchDetailDto> musicXmlInfos;
 
-    private long firstMeasureStartBytes = 0;
-
-    private long recordBytes = 0;
-
     private String clientId;
 
     private Integer detailId;
@@ -95,15 +89,6 @@ public class SoundCompareHelper implements PitchDetectionHandler {
 
     private String xmlUrl;
 
-    /** 演奏音频数据中频率变更明显持续数量 */
-    private int obviousChangeNum = 0;
-
-    /** 演奏音频中但前小节所有频率数据 */
-    private List<MusicPitchDetailDto> currPitchInfos = new ArrayList<>();
-    private List<MusicPitchDetailDto> currTmpPitchInfos = new ArrayList<>();
-
-    private List<MusicPitchDetailDto> recordMeasurePitchInfos = new ArrayList<>();
-
     /**
      * @describe 分贝检测器
      */
@@ -277,28 +262,20 @@ public class SoundCompareHelper implements PitchDetectionHandler {
         this.musicalNotesPlayStats = musicalNotesPlayStats;
     }
 
-    public Map<String, BigDecimal> getUserScoreMap() {
-        return userScoreMap;
+    public List<MusicPitchDetailDto> getRecordMeasurePithInfo() {
+        return recordMeasurePithInfo;
     }
 
-    public void setUserScoreMap(Map<String, BigDecimal> userScoreMap) {
-        this.userScoreMap = userScoreMap;
+    public void setRecordMeasurePithInfo(List<MusicPitchDetailDto> recordMeasurePithInfo) {
+        this.recordMeasurePithInfo = recordMeasurePithInfo;
     }
 
-    public long getFirstMeasureStartBytes() {
-        return firstMeasureStartBytes;
-    }
-
-    public void setFirstMeasureStartBytes(long firstMeasureStartBytes) {
-        this.firstMeasureStartBytes = firstMeasureStartBytes;
-    }
-
-    public long getRecordBytes() {
-        return recordBytes;
+    public Map<String, BigDecimal> getUserScoreMap() {
+        return userScoreMap;
     }
 
-    public void setRecordBytes(long recordBytes) {
-        this.recordBytes = recordBytes;
+    public void setUserScoreMap(Map<String, BigDecimal> userScoreMap) {
+        this.userScoreMap = userScoreMap;
     }
 
     public Map<Integer, Map<String, Object>> getUserMeasureScoreMap() {
@@ -309,59 +286,29 @@ public class SoundCompareHelper implements PitchDetectionHandler {
         this.userMeasureScoreMap = userMeasureScoreMap;
     }
 
-    public List<MusicPitchDetailDto> getRecordMeasurePitchInfos() {
-        return recordMeasurePitchInfos;
-    }
-
-    public void setRecordMeasurePitchInfos(List<MusicPitchDetailDto> recordMeasurePitchInfos) {
-        this.recordMeasurePitchInfos = recordMeasurePitchInfos;
-    }
-
     @Override
     public void handlePitch(PitchDetectionResult pitchDetectionResult, AudioEvent audioEvent) {
         int timeStamp = (int) (measureStartTime + audioEvent.getTimeStamp()*1000);
         float pitch = pitchDetectionResult.getPitch();
-        int decibel = (int) (100 - Math.abs(silenceDetector.currentSPL()));
-
-        if(decibel <= SoundCompareHandler.soundCompareConfig.validDb){
-            pitch = -1;
-            decibel = 0;
-        }
-
-        SoundCompareHandler.LOGGER.info("时间:{}, 频率:{}, 分贝:{}", timeStamp, pitch, decibel);
-
-        if(currPitchInfos.size()>0&&(Math.abs(currPitchInfos.get(currPitchInfos.size()-1).getFrequency()-pitch)>10||Math.abs(currPitchInfos.get(currPitchInfos.size()-1).getDecibel()-decibel)>10)){
-            Double avgPitch = currPitchInfos.stream().skip(1).collect(Collectors.averagingDouble(MusicPitchDetailDto::getFrequency));
-            Double avgDb = currPitchInfos.stream().skip(1).collect(Collectors.averagingDouble(MusicPitchDetailDto::getDecibel));
-
-            MusicPitchDetailDto measureDetail = new MusicPitchDetailDto(currPitchInfos.get(0).getTimeStamp(), avgPitch.floatValue(), avgDb);
-            measureDetail.setEndTimeStamp(timeStamp);
-            measureDetail.setDuration(measureDetail.getEndTimeStamp()-measureDetail.getTimeStamp());
-
-            if(measureDetail.getDuration()>25&&(avgPitch>0||avgDb>SoundCompareHandler.soundCompareConfig.validDb)){
-                recordMeasurePitchInfos.add(measureDetail);
-            }
-
-            currPitchInfos.clear();
-
-            //初始化偏移时间
-            if(offsetTime == -1 && recordMeasurePitchInfos.size() == 1){
-                offsetTime = recordMeasurePitchInfos.get(0).getTimeStamp();
-                for (MusicPitchDetailDto musicXmlInfo : musicXmlInfos) {
-                    if(!musicXmlInfo.getDontEvaluating()){
-                        if(offsetTime > musicXmlInfo.getTimeStamp()) {
-                            offsetTime = offsetTime - musicXmlInfo.getTimeStamp();
-                        }
-                        break;
-                    }
-                }
-                musicXmlInfos.forEach(e->e.setTimeStamp(e.getTimeStamp()+offsetTime));
-                for (Map.Entry<Integer, MusicPitchDetailDto> musicPitchDetailDtoEntry : measureEndTime.entrySet()) {
-                    musicPitchDetailDtoEntry.getValue().setTimeStamp(musicPitchDetailDtoEntry.getValue().getTimeStamp() + offsetTime);
-                    musicPitchDetailDtoEntry.getValue().setEndTimeStamp(musicPitchDetailDtoEntry.getValue().getEndTimeStamp() + offsetTime);
+        if(offsetTime == -1 && !DeviceTypeEnum.IOS.equals(deviceType) && pitch>0){
+            int preTimeStamp = CollectionUtils.isEmpty(recordMeasurePithInfo)?0:recordMeasurePithInfo.get(recordMeasurePithInfo.size()-1).getTimeStamp();
+            offsetTime = timeStamp - (timeStamp - preTimeStamp)/2;
+            for (MusicPitchDetailDto musicXmlInfo : musicXmlInfos) {
+                if(!musicXmlInfo.getDontEvaluating()){
+                    if(offsetTime > musicXmlInfo.getTimeStamp())
+                        offsetTime = offsetTime - musicXmlInfo.getTimeStamp();
+                    break;
                 }
             }
+            for (Map.Entry<Integer, MusicPitchDetailDto> musicPitchDetailDtoEntry : measureEndTime.entrySet()) {
+                musicPitchDetailDtoEntry.getValue().setTimeStamp(musicPitchDetailDtoEntry.getValue().getTimeStamp() + offsetTime);
+                musicPitchDetailDtoEntry.getValue().setEndTimeStamp(musicPitchDetailDtoEntry.getValue().getEndTimeStamp() + offsetTime);
+            }
+        }
+        if(silenceDetector.currentSPL()< SoundCompareHandler.soundCompareConfig.validDb){
+            pitch = -1;
         }
-        currPitchInfos.add(new MusicPitchDetailDto(timeStamp, pitch, decibel));
+//            LOGGER.info("时间:{}, 频率:{}, 分贝:{}", timeStamp, pitch, silenceDetecor.currentSPL());
+        recordMeasurePithInfo.add(new MusicPitchDetailDto(timeStamp, pitch, silenceDetector.currentSPL()));
     }
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentPaymentOrderExportDto.java

@@ -92,6 +92,17 @@ public class StudentPaymentOrderExportDto extends StudentPaymentOrder {
 
     private Integer payingStatus;
 
+    //订单金额
+    private BigDecimal orderAmount = BigDecimal.ZERO;
+
+    public BigDecimal getOrderAmount() {
+        return orderAmount;
+    }
+
+    public void setOrderAmount(BigDecimal orderAmount) {
+        this.orderAmount = orderAmount;
+    }
+
     public BigDecimal getSporadicAmount() {
         return sporadicAmount;
     }

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

@@ -206,6 +206,17 @@ public class SellOrder {
     @ApiModelProperty(value="优惠券减免")
     private BigDecimal couponRemitAmount = BigDecimal.ZERO;
 
+    @ApiModelProperty(value="订单金额")
+    private BigDecimal orderAmount = BigDecimal.ZERO;
+
+    public BigDecimal getOrderAmount() {
+        return orderAmount;
+    }
+
+    public void setOrderAmount(BigDecimal orderAmount) {
+        this.orderAmount = orderAmount;
+    }
+
     public BigDecimal getCouponRemitAmount() {
         return couponRemitAmount;
     }

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

@@ -3,7 +3,7 @@ package com.ym.mec.biz.dal.enums;
 import com.ym.mec.common.enums.BaseEnum;
 
 public enum HeardLevelEnum implements BaseEnum<String, HeardLevelEnum> {
-    BEGINNER("BEGINNER","入门级", 0.1f, 0.7f, 1.5f),
+	BEGINNER("BEGINNER","入门级", 0.1f, 0.7f, 1.5f),
     ADVANCED("ADVANCED","进阶级", 1, 0.9f, 1.3f),
     PERFORMER("PERFORMER","大师级", 3, 0.93f, 1.1f);
 

+ 21 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/page/StudentPreRegistrationQueryInfo.java

@@ -24,7 +24,11 @@ public class StudentPreRegistrationQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "云教练提供方式",required = false)
     private String cloudTeacherMethod;
 
-
+    /** 老师推荐声部 */
+	private Integer teacherRecommandSubjectId;
+	
+	/** 选报声部 */
+	private Integer selectionSubjectId;
 
     public String getName() {
         return name;
@@ -73,4 +77,20 @@ public class StudentPreRegistrationQueryInfo extends QueryInfo {
     public void setCloudTeacherMethod(String cloudTeacherMethod) {
         this.cloudTeacherMethod = cloudTeacherMethod;
     }
+
+	public Integer getTeacherRecommandSubjectId() {
+		return teacherRecommandSubjectId;
+	}
+
+	public void setTeacherRecommandSubjectId(Integer teacherRecommandSubjectId) {
+		this.teacherRecommandSubjectId = teacherRecommandSubjectId;
+	}
+
+	public Integer getSelectionSubjectId() {
+		return selectionSubjectId;
+	}
+
+	public void setSelectionSubjectId(Integer selectionSubjectId) {
+		this.selectionSubjectId = selectionSubjectId;
+	}
 }

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

@@ -32,7 +32,7 @@ public interface SellOrderService extends BaseService<Integer, SellOrder> {
      * @param studentPaymentOrder
      * @return
      */
-    List<SellOrder> addOrderDetail2SellOrder(List<StudentPaymentOrderDetail> orderDetails, StudentPaymentOrder studentPaymentOrder, MusicGroup musicGroup);
+    List<SellOrder> addOrderDetail2SellOrder(List<StudentPaymentOrderDetail> orderDetails, StudentPaymentOrder studentPaymentOrder, MusicGroup musicGroup,BigDecimal musicRemitFee);
 
     void batchInsert(List<SellOrder> sellOrders);
 

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

@@ -80,5 +80,10 @@ public interface SubjectChangeService extends BaseService<Integer, SubjectChange
      * @param balance
      * @return
      */
-    List<SellOrder> addSellOrder(Long orderId, String musicGroupId, List<Integer> goodsIds, BigDecimal totalAmount, BigDecimal balance,KitGroupPurchaseTypeEnum kitGroupPurchaseType);
+    List<SellOrder> addSellOrder(Long orderId,
+                                 String musicGroupId,
+                                 List<Integer> goodsIds,
+                                 BigDecimal totalAmount,
+                                 BigDecimal balance,
+                                 KitGroupPurchaseTypeEnum kitGroupPurchaseType,BigDecimal couponRemitAmount);
 }

+ 9 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TeacherAttendanceService.java

@@ -185,4 +185,13 @@ public interface TeacherAttendanceService extends BaseService<Long, TeacherAtten
 	 * @param teacherAttendanceId
 	 */
 	void rejectTeacherAttendanceComplaints(long teacherAttendanceId,String content);
+
+	/**
+	 * 更新签退设备号
+	 * @param courseId
+	 * @param userId
+	 * @param signInDeviceNum
+	 * @param signOutDeviceNum
+	 */
+	void updateDeviceNum(Integer courseId, String userId,String signInDeviceNum, String signOutDeviceNum);
 }

+ 15 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java

@@ -187,6 +187,8 @@ public class ExportServiceImpl implements ExportService {
                     row.setSubjectName(vipGroupInfo.getSubjectName());
                     row.setEduTeacher(vipGroupInfo.getEducationalTeacherName());
                 }
+            }else if(row.getGroupType() == GroupType.MEMBER){
+                row.setCloudTeacherFee(row.getActualAmount());
             } else if (row.getGroupType().equals(GroupType.SPORADIC)) {
                 //考级报名
                 if (row.getType().equals(OrderTypeEnum.DEGREE_REGISTRATION)) {
@@ -308,6 +310,7 @@ public class ExportServiceImpl implements ExportService {
             row.setPaymentChannel(paymentChannel);
             row.setId(i);
             row.setRepairFee(row.getRepairFee().add(row.getMaintenanceFee()).add(row.getMaintenanceProductFee()));
+            row.setOrderAmount(row.getExpectAmount().add(row.getCouponRemitFee()));
             i++;
         }
 
@@ -317,9 +320,13 @@ public class ExportServiceImpl implements ExportService {
 
         HSSFWorkbook workbook = null;
         try {
-            String[] header = {"序号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "应付金额", "现金支付", "余额支付", "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "云教练", "押金", "乐器", "教辅费用", "上门费", "账户充值", "其它", "手续费", "到账时间",
+            String[] header = {"序号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额", "现金支付", "余额支付", "优惠金额",
+                    "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "云教练", "押金", "乐器", "教辅费用", "上门费",
+                    "账户充值", "其它", "手续费", "到账时间",
                     "关联乐团ID/VIP课ID", "课程形态", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"};
-            String[] body = {"id", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "expectAmount", "actualAmount", "balancePaymentAmount", "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "cloudTeacherFee", "leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "transferFee", "payTime", "musicGroupId",
+            String[] body = {"id", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount", "expectAmount", "actualAmount", "balancePaymentAmount",  "couponRemitFee",
+                    "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "cloudTeacherFee",
+                    "leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "transferFee", "payTime", "musicGroupId",
                     "groupType.desc", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"};
             workbook = POIUtil.exportExcel(header, body, studentPaymentOrderExportDtos);
             workbook.write(fileOutputStream);
@@ -631,6 +638,7 @@ public class ExportServiceImpl implements ExportService {
                 paymentChannel = "余额";
             }
             row.setPaymentChannel(paymentChannel);
+            row.setOrderAmount(row.getExpectAmount().add(row.getCouponRemitFee()));
             i++;
         }
 
@@ -786,9 +794,12 @@ public class ExportServiceImpl implements ExportService {
 
         HSSFWorkbook workbook = null;
         try {
-            String[] header = {"序号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "应付金额", "现金支付", "余额支付", "分润账户", "分润金额", "分配余额", "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "云教练", "押金", "乐器", "教辅费用", "上门费", "账户充值", "其它", "手续费", "到账时间",
+            String[] header = {"序号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额", "现金支付", "余额支付", "分润账户", "分润金额", "分配余额", "优惠金额", "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "云教练", "押金", "乐器", "教辅费用", "上门费", "账户充值", "其它", "手续费", "到账时间",
                     "关联乐团ID/VIP课ID", "课程形态", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"};
-            String[] body = {"id", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "expectAmount", "actualAmount", "balancePaymentAmount", "routeMerNo", "routeAmount", "routeBalance", "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "cloudTeacherFee", "leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "transferFee", "payTime", "musicGroupId",
+            String[] body = {"id", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount"
+                    , "expectAmount", "actualAmount", "balancePaymentAmount", "routeMerNo", "routeAmount", "routeBalance",  "couponRemitFee",
+                    "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "cloudTeacherFee", "leaseFee", "musicalFee", "teachingFee", "visitFee",
+                    "rechargeFee", "otherFee", "transferFee", "payTime", "musicGroupId",
                     "groupType.desc", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"};
             workbook = POIUtil.exportExcel(header, body, studentPaymentOrderExportDtos);
             workbook.write(fileOutputStream);

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

@@ -184,18 +184,20 @@ public class MusicGroupSubjectPlanServiceImpl extends BaseServiceImpl<Integer, M
 				musicGroupSubjectGoodsAndInfo.setMemberPrivilegesItemList(memberRankPrivilegesService.queryByMemberRankId(1));
 			}
 			
-			Map<CourseScheduleType, BigDecimal> memberCoursePrice = new HashMap<CourseScheduleType, BigDecimal>();
+			Map<String, BigDecimal> memberCoursePrice = new HashMap<String, BigDecimal>();
 			
 			OrganizationCourseUnitPriceSettings singleUnitPriceSettings = organizationCourseUnitPriceSettingsService.queryByOrganIdAndCourseTypeAndChargeType(musicGroup.getOrganId(), CourseScheduleType.SINGLE, musicGroup.getChargeTypeId());
 			if (singleUnitPriceSettings != null) {
-				memberCoursePrice.put(CourseScheduleType.SINGLE,
+				memberCoursePrice.put(CourseScheduleType.SINGLE.name(),
 						singleUnitPriceSettings.getUnitPrice().multiply(new BigDecimal(1980)).setScale(0, BigDecimal.ROUND_HALF_UP));
 			}
 			OrganizationCourseUnitPriceSettings mixUnitPriceSettings = organizationCourseUnitPriceSettingsService.queryByOrganIdAndCourseTypeAndChargeType(musicGroup.getOrganId(), CourseScheduleType.MIX, musicGroup.getChargeTypeId());
 			if (mixUnitPriceSettings != null) {
-				memberCoursePrice.put(CourseScheduleType.MIX,
+				memberCoursePrice.put(CourseScheduleType.MIX.name(),
 						mixUnitPriceSettings.getUnitPrice().multiply(new BigDecimal(1980)).setScale(0, BigDecimal.ROUND_HALF_UP));
 			}
+			
+			musicGroupSubjectGoodsAndInfo.setMemberCoursePrice(memberCoursePrice);
 		}
 		
 		// 查询已购买内容

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

@@ -324,6 +324,8 @@ public class ReplacementInstrumentActivityServiceImpl extends BaseServiceImpl<In
 
         String orderNo = idGeneratorService.generatorId("payment") + "";
 
+        studentPaymentOrder.setActualAmount(amount);
+        studentPaymentOrder.setExpectAmount(amount.add(balance));
         studentPaymentOrder.setPaymentChannel("BALANCE");
         studentPaymentOrder.setUserId(userId);
         studentPaymentOrder.setGroupType(GroupType.REPLACEMENT);
@@ -554,6 +556,7 @@ public class ReplacementInstrumentActivityServiceImpl extends BaseServiceImpl<In
             sellOrder.setActualAmount(sellOrderExpectAmount.subtract(sellOrderBalance));
             sellOrder.setBalanceAmount(sellOrderBalance);
             sellOrder.setExpectAmount(sellOrderExpectAmount);
+            sellOrder.setCouponRemitAmount(groupPurchasePriceMap.get(sellOrder.getGoodsId()).subtract(sellOrderExpectAmount));
             sellOrder.setNum(1);
             sellOrder.setUserId(order.getUserId());
             sellOrder.setPaymentChannel(order.getPaymentChannel());

+ 50 - 8
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SellOrderServiceImpl.java

@@ -161,26 +161,22 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                 }
                 BigDecimal sellOrderActualAmount = BigDecimal.ZERO;
                 BigDecimal sellOrderBalance = BigDecimal.ZERO;
-                BigDecimal sellOrderCouponBalance = BigDecimal.ZERO;
                 if (complementPrice.compareTo(BigDecimal.ZERO) > 0) {
                     sellOrderActualAmount = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(goodsActualAmount).divide(complementPrice, 2, BigDecimal.ROUND_DOWN);
                     sellOrderBalance = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(goodsBalance).divide(complementPrice, 2, BigDecimal.ROUND_DOWN);
-                    sellOrderCouponBalance = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(couponBalance).divide(complementPrice, 2, BigDecimal.ROUND_DOWN);
                 }
 
                 complementGoodsNum = complementGoodsNum - sellOrder.getNum();
                 if (complementGoodsNum <= 0) {
                     sellOrderActualAmount = goodsActualAmount.subtract(hasRouteSellOrderActualAmount);
                     sellOrderBalance = goodsBalance.subtract(hasRouteSellOrderBalance);
-                    sellOrderCouponBalance = couponBalance.subtract(hasRouteCouponBalance);
                 }
                 hasRouteSellOrderActualAmount = hasRouteSellOrderActualAmount.add(sellOrderActualAmount);
                 hasRouteSellOrderBalance = hasRouteSellOrderBalance.add(sellOrderBalance);
-                hasRouteCouponBalance = hasRouteCouponBalance.add(sellOrderCouponBalance);
 
-                sellOrder.setExpectAmount(sellOrderActualAmount.add(sellOrderBalance).add(sellOrderCouponBalance));
+                sellOrder.setExpectAmount(sellOrderActualAmount.add(sellOrderBalance));
                 sellOrder.setBalanceAmount(sellOrderBalance);
-                sellOrder.setCouponRemitAmount(sellOrderCouponBalance);
+//                sellOrder.setCouponRemitAmount(sellOrderCouponBalance);
                 sellOrder.setActualAmount(sellOrderActualAmount);
                 sellOrder.setOrganId(order.getOrganId());
                 sellOrder.setCooperationOrganId(musicGroup.getCooperationOrganId());
@@ -206,13 +202,37 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                 }
             }
         }
-        sellOrderDao.batchInsert(sellOrderList);
+        if (sellOrderList.size() > 0) {
+            //如果有优惠券金额
+            if (couponRemitFee.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal reduce = sellOrderList.stream().map(e -> e.getExpectAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                List<SellOrder> sellOrders = sellOrderList.stream().filter(e -> e.getExpectAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
+                //可用优惠券金额
+                BigDecimal subCouponMarketAmount = couponRemitFee;
+                for (int j = 0; j < sellOrders.size(); j++) {
+                    SellOrder sellOrder = sellOrders.get(j);
+                    //如果是最后一件商品
+                    if (j == sellOrders.size() - 1) {
+                        sellOrder.setCouponRemitAmount(subCouponMarketAmount);
+                    } else {
+                        //获取比例
+                        BigDecimal ratioAmount = sellOrder.getExpectAmount().divide(reduce, 6, BigDecimal.ROUND_HALF_UP);
+                        //获取分配的减免金额
+                        BigDecimal multiply = couponRemitFee.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
+                        subCouponMarketAmount = subCouponMarketAmount.subtract(multiply);
+                        sellOrder.setCouponRemitAmount(multiply);
+                    }
+                }
+            }
+            sellOrderDao.batchInsert(sellOrderList);
+        }
         return sellOrderList;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-    public List<SellOrder> addOrderDetail2SellOrder(List<StudentPaymentOrderDetail> orderDetails, StudentPaymentOrder studentPaymentOrder, MusicGroup musicGroup) {
+    public List<SellOrder> addOrderDetail2SellOrder(List<StudentPaymentOrderDetail> orderDetails,
+                                                    StudentPaymentOrder studentPaymentOrder, MusicGroup musicGroup,BigDecimal musicRemitFee) {
         List<SellOrder> sellOrders = new ArrayList<>();
         //总余额支付
         BigDecimal totalBalance = studentPaymentOrder.getBalancePaymentAmount() != null ? studentPaymentOrder.getBalancePaymentAmount() : BigDecimal.ZERO;
@@ -304,6 +324,7 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                     sellOrder.setActualAmount(sellOrderExpectAmount.subtract(sellOrderBalance));
                     sellOrder.setBalanceAmount(sellOrderBalance);
                     sellOrder.setExpectAmount(sellOrderExpectAmount);
+//                    sellOrder.setCouponRemitAmount(goods.getGroupPurchasePrice().subtract(sellOrderExpectAmount));
                     sellOrder.setNum(1);
                     sellOrder.setUserId(studentPaymentOrder.getUserId());
                     sellOrder.setPaymentChannel(studentPaymentOrder.getPaymentChannel());
@@ -337,6 +358,27 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
             sellOrders.addAll(sellOrderList);
         }
         if (sellOrders.size() > 0) {
+            //如果有优惠券金额
+            if (musicRemitFee.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal reduce = sellOrders.stream().map(e -> e.getExpectAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                List<SellOrder> sellOrderList = sellOrders.stream().filter(e -> e.getExpectAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
+                //可用优惠券金额
+                BigDecimal subCouponMarketAmount = musicRemitFee;
+                for (int j = 0; j < sellOrderList.size(); j++) {
+                    SellOrder sellOrder = sellOrderList.get(j);
+                    //如果是最后一件商品
+                    if (j == sellOrderList.size() - 1) {
+                        sellOrder.setCouponRemitAmount(subCouponMarketAmount);
+                    } else {
+                        //获取比例
+                        BigDecimal ratioAmount = sellOrder.getExpectAmount().divide(reduce, 6, BigDecimal.ROUND_HALF_UP);
+                        //获取分配的减免金额
+                        BigDecimal multiply = musicRemitFee.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
+                        subCouponMarketAmount = subCouponMarketAmount.subtract(multiply);
+                        sellOrder.setCouponRemitAmount(multiply);
+                    }
+                }
+            }
             sellOrderDao.batchInsert(sellOrders);
         }
         return sellOrders;

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCheckHandler.java

@@ -1,25 +1,36 @@
 package com.ym.mec.biz.service.impl;
 
 import be.tarsos.dsp.AudioDispatcher;
+import be.tarsos.dsp.AudioEvent;
 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;
 import com.ym.mec.biz.dal.dto.SoundCheckHelper;
+import com.ym.mec.biz.dal.dto.SoundCheckInfoDto;
 import com.ym.mec.biz.dal.dto.WebSocketInfo;
 import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
 import com.ym.mec.biz.handler.WebSocketHandler;
 import com.ym.mec.biz.service.SoundSocketService;
 import com.ym.mec.biz.service.WebSocketEventHandler;
 import com.ym.mec.common.exception.BizException;
+import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.web.socket.BinaryMessage;
+import org.springframework.web.socket.TextMessage;
 import org.springframework.web.socket.WebSocketSession;
 
 import javax.sound.sampled.UnsupportedAudioFileException;
+import java.io.File;
+import java.io.IOException;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**

+ 126 - 67
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundCompareHandler.java

@@ -6,7 +6,6 @@ import be.tarsos.dsp.pitch.PitchProcessor;
 import be.tarsos.dsp.util.PitchConverter;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.ym.mec.biz.dal.config.SoundCompareConfig;
 import com.ym.mec.biz.dal.dao.SysMusicScoreAccompanimentDao;
 import com.ym.mec.biz.dal.dto.*;
@@ -32,6 +31,7 @@ import org.springframework.web.socket.WebSocketSession;
 
 import javax.sound.sampled.UnsupportedAudioFileException;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.math.BigDecimal;
@@ -50,7 +50,7 @@ import static com.ym.mec.biz.service.SoundSocketService.VIDEO_UPDATE;
 @Service
 public class SoundCompareHandler implements WebSocketEventHandler {
 
-    public static final Logger LOGGER = LoggerFactory.getLogger(SoundCompareHandler.class);
+    private final Logger LOGGER = LoggerFactory.getLogger(SoundCompareHandler.class);
 
     private BigDecimal oneHundred = new BigDecimal(100);
 
@@ -99,9 +99,6 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                 userSoundInfoMap.get(phone).setMusicXmlInfos(musicXmlInfos);
                 musicXmlInfos = musicXmlInfos.stream().filter(m->!m.getDontEvaluating()).collect(Collectors.toList());
                 userSoundInfoMap.get(phone).setMusicScoreId(bodyObject.getInteger("id"));
-                if(bodyObject.containsKey("beatLength")){
-                    userSoundInfoMap.get(phone).setFirstMeasureStartBytes((long) (bodyObject.getLong("beatLength")/1000f*(soundCompareConfig.audioFormat.getFrameSize()*soundCompareConfig.audioFormat.getFrameRate())));
-                }
                 if(bodyObject.containsKey("platform")){
                     userSoundInfoMap.get(phone).setDeviceType(DeviceTypeEnum.valueOf(bodyObject.getString("platform")));
                 }
@@ -151,9 +148,8 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     File file = new File(tmpDir+phone + "_"+ userSoundInfoMap.get(phone).getMusicScoreId() +"_"+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +".wav");
                     userSoundInfoMap.get(phone).setFile(file);
                     userSoundInfoMap.get(phone).setAccessFile(new RandomAccessFile(file, "rw"));
-                    userSoundInfoMap.get(phone).getAccessFile().seek(44);
                     userSoundInfoMap.get(phone).setRecordFilePath(file.getAbsolutePath());
-                } catch (IOException e) {
+                } catch (FileNotFoundException e) {
                     throw new BizException("文件创建失败:", e);
                 }
                 break;
@@ -182,10 +178,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                 createHeader(phone, false);
                 break;
             case SoundSocketService.PROXY_MESSAGE:
-//                if(DeviceTypeEnum.IOS.equals(userSoundInfoMap.get(phone).getDeviceType())&&bodyObject.containsKey(SoundSocketService.OFFSET_TIME)){
-//                    int offsetTime = bodyObject.getIntValue(SoundSocketService.OFFSET_TIME);
-//                    calOffsetTime(phone, offsetTime);
-//                }
+                if(DeviceTypeEnum.IOS.equals(userSoundInfoMap.get(phone).getDeviceType())&&bodyObject.containsKey(SoundSocketService.OFFSET_TIME)){
+                    int offsetTime = bodyObject.getIntValue(SoundSocketService.OFFSET_TIME);
+                    calOffsetTime(phone, offsetTime);
+                }
                 break;
             case VIDEO_UPDATE:
                 SysMusicCompareRecord update = null;
@@ -211,27 +207,24 @@ public class SoundCompareHandler implements WebSocketEventHandler {
         if(!userSoundInfoMap.containsKey(phone)){
             return;
         }
-        userSoundInfoMap.get(phone).setRecordBytes(userSoundInfoMap.get(phone).getRecordBytes()+message.getPayloadLength());
-        if(userSoundInfoMap.get(phone).getRecordBytes()<userSoundInfoMap.get(phone).getFirstMeasureStartBytes()){
-            return;
-        }
         try {
             if(Objects.nonNull(userSoundInfoMap.get(phone).getAccessFile())){
                 userSoundInfoMap.get(phone).getAccessFile().write(message.getPayload().array());
-            }else{
-                return;
             }
 
             AudioDispatcher dispatcher = AudioDispatcherFactory.fromByteArray(message.getPayload().array(), soundCompareConfig.audioFormat, soundCompareConfig.simpleSize, soundCompareConfig.overlap);
+
             dispatcher.addAudioProcessor(userSoundInfoMap.get(phone).silenceDetector);
             dispatcher.addAudioProcessor(new PitchProcessor(soundCompareConfig.algo, soundCompareConfig.simpleRate, soundCompareConfig.simpleSize, userSoundInfoMap.get(phone)));
             dispatcher.run();
+            if(Objects.isNull(userSoundInfoMap.get(phone).getAccessFile())){
+                return;
+            }
 
             double recordTime = userSoundInfoMap.get(phone).getAccessFile().length()/(soundCompareConfig.audioFormat.getFrameSize()*soundCompareConfig.audioFormat.getFrameRate())*1000;
             userSoundInfoMap.get(phone).setMeasureStartTime(recordTime);
-
             for (Map.Entry<Integer, MusicPitchDetailDto> userMeasureEndTimeMapEntry : userSoundInfoMap.get(phone).getMeasureEndTime().entrySet()) {
-                if(recordTime>(userMeasureEndTimeMapEntry.getValue().getEndTimeStamp()+100)){
+                if(recordTime>(userMeasureEndTimeMapEntry.getValue().getEndTimeStamp())){
                     if(userMeasureEndTimeMapEntry.getValue().getDontEvaluating()){
                         continue;
                     }else{
@@ -268,7 +261,6 @@ public class SoundCompareHandler implements WebSocketEventHandler {
             musicPitchDetailDtoEntry.getValue().setTimeStamp(musicPitchDetailDtoEntry.getValue().getTimeStamp() + offsetTime);
             musicPitchDetailDtoEntry.getValue().setEndTimeStamp(musicPitchDetailDtoEntry.getValue().getEndTimeStamp() + offsetTime);
         }
-        userSoundInfoMap.get(phone).getMusicXmlInfos().forEach(e->e.setTimeStamp(e.getTimeStamp()+offsetTime));
     }
 
     /**
@@ -355,32 +347,111 @@ public class SoundCompareHandler implements WebSocketEventHandler {
             for (int i = 0; i < userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureIndex).size(); i++) {
                 MusicPitchDetailDto musicXmlInfo = userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureIndex).get(i);
 
-                int startTimeStamp = musicXmlInfo.getTimeStamp();
-                int endTimeStamp = musicXmlInfo.getTimeStamp() + musicXmlInfo.getDuration();
+                int ot5 = (int) (musicXmlInfo.getDuration()*0.1);
+                int startTimeStamp = musicXmlInfo.getTimeStamp() + userSoundInfoMap.get(phone).getOffsetTime() + ot5;
+                int endTimeStamp = musicXmlInfo.getTimeStamp()  + userSoundInfoMap.get(phone).getOffsetTime() + musicXmlInfo.getDuration() - ot5;
+
+                //时间范围内有效节奏数量
+                float cadenceValidNum = 0;
+                //时间范围内有效音频数量
+                float integrityValidNum = 0;
+                //时间范围内匹配次数
+                float compareNum = 0;
 
-                int ot5 = (int) (musicXmlInfo.getDuration()*0.22<70?70:musicXmlInfo.getDuration()*0.22);
-                int rightTimeRange = ot5>200?200:ot5;
+                List<MusicPitchDetailDto> measureSoundPitchInfos = new ArrayList<>();
 
-                List<MusicPitchDetailDto> recordPitchs = userSoundInfoMap.get(phone).getRecordMeasurePitchInfos().stream().filter(m -> m.getTimeStamp()>=startTimeStamp-rightTimeRange && m.getTimeStamp() < endTimeStamp-rightTimeRange).collect(Collectors.toList());
+                for (int j = 0; j < userSoundInfoMap.get(phone).getRecordMeasurePithInfo().size(); j++) {
+                    MusicPitchDetailDto recordInfo = userSoundInfoMap.get(phone).getRecordMeasurePithInfo().get(j);
+                    //如果在时间范围之外直接跳过
+                    if(recordInfo.getTimeStamp()<startTimeStamp||recordInfo.getTimeStamp()>endTimeStamp){
+                        continue;
+                    }
+                    measureSoundPitchInfos.add(recordInfo);
+                    compareNum++;
+                    //如果在最低有效频率以下则跳过
+                    if(recordInfo.getFrequency()<soundCompareConfig.validFrequency&&musicXmlInfo.getFrequency()!=-1){
+                        continue;
+                    }
+                    cadenceValidNum++;
+                    //如果频率差值在节奏误差范围内
+//                    if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=soundCompareConfig.integrityFrequencyRange){
+//                        integrityValidNum++;
+//                    }
+                }
+
+                //非正常频率次数
+                int errPitchNum = 0;
+                //分贝变化次数
+                int decibelChangeNum = 0;
+
+                if(CollectionUtils.isEmpty(measureSoundPitchInfos)){
+                    userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) 0);
+                }else{
+                    Map<Integer, Long> collect = measureSoundPitchInfos.stream().map(pitch -> (int)pitch.getFrequency()).collect(Collectors.groupingBy(Integer::intValue, Collectors.counting()));
+                    //出现次数最多的频率
+                    Integer pitch = collect.entrySet().stream().max(Comparator.comparing(e -> e.getValue())).get().getKey();
+                    //当前频率
+                    double cf = -1;
+                    //频率持续数量
+                    int fnum = 0;
+                    //是否演奏中
+                    boolean ing = false;
+                    //当前分贝
+                    double cd = 0;
+                    //分贝变化方向,-1变小,1变大
+                    int dcd = -1;
+                    //分贝持续数量
+                    int dnum = 0;
+                    for (MusicPitchDetailDto musicalNotesPitch : measureSoundPitchInfos) {
+                        //计算频率断层次数
+                        if (Math.abs(musicalNotesPitch.getFrequency() - cf) > 20){
+                            fnum ++;
+                        }
+                        if (fnum>=5){
+                            cf = musicalNotesPitch.getFrequency();
+                            fnum = 0;
+                            if (cf != -1){
+                                errPitchNum ++;
+                                ing = true;
+                                cd = musicalNotesPitch.getDecibel();
+                            }
+                        }
+                        //计算声音大小断层册数
+                        if(ing && Math.abs(musicalNotesPitch.getDecibel() - cd) > 10){
+                            dnum ++;
+                        }
+                        if (dnum > 2){
+                            int tdcd = cd > musicalNotesPitch.getDecibel() ? -1 : 1;
+                            cd = musicalNotesPitch.getDecibel();
+                            dnum = 0;
+                            if (tdcd != dcd) {
+                                decibelChangeNum++;
+                            }
+                            dcd = tdcd;
+                        }
+                    }
+                    userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) pitch);
+                }
 
                 boolean cadenceRight = false;
                 boolean intonationRight = false;
                 boolean integrityRight = false;
 
-                float integrityDuty = 0;
-                if(recordPitchs.size()>0){
-                    integrityDuty = recordPitchs.get(0).getDuration()/(float)musicXmlInfo.getDuration();
+                //有效节奏占比
+                float cadenceDuty = cadenceValidNum/compareNum;
+                //如果频率出现断层或这个音量出现断层,则当前音符节奏无效
+                if(errPitchNum>=2 || decibelChangeNum>1){
+                    cadenceDuty = 0;
                 }
-                integrityDuty = scoreMapping(integrityDuty, userSoundInfoMap.get(phone).getHeardLevel().getIntegrityRange(), 1);
                 //节奏
-                if(recordPitchs.size()==1){
+                if(cadenceDuty>=userSoundInfoMap.get(phone).getHeardLevel().getCadenceRange()){
                     cadenceNum++;
                     cadenceRight = true;
                 }
                 //音准、完成度
-                if (cadenceRight){
+                if (cadenceRight && !CollectionUtils.isEmpty(measureSoundPitchInfos)){
                     //音准
-                    float avgPitch = recordPitchs.get(0).getFrequency();
+                    Double avgPitch = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<15).collect(Collectors.averagingDouble(pitch -> pitch.getFrequency()));
                     //音分
                     double recordCents = 0;
                     if (avgPitch > 0){
@@ -390,40 +461,29 @@ public class SoundCompareHandler implements WebSocketEventHandler {
                     if(musicXmlInfo.getFrequency()>0){
                         cents =  PitchConverter.hertzToAbsoluteCent(musicXmlInfo.getFrequency());
                     }
-                    double score = 100 - Math.round(Math.abs(cents - recordCents)) + 3;
+                    double score = 100 - Math.round(Math.abs(cents - recordCents)) + userSoundInfoMap.get(phone).getHeardLevel().getIntonationCentsRange();
                     if (score < 0){
                         score = 0;
                     }else if(score > 100){
                         score = 100;
                     }
-
-                    score = Math.pow(score/100f, userSoundInfoMap.get(phone).getHeardLevel().getIntonationCentsRange())*100;
-
-                    if(Objects.nonNull(userSoundInfoMap.get(phone).getSubjectId())&&userSoundInfoMap.get(phone).getSubjectId()==23){
-                        score = 100;
-                        integrityDuty = 1;
-                    }
-
                     intonationScore += score;
-                    musicXmlInfo.setAvgFrequency(avgPitch);
+                    musicXmlInfo.setAvgFrequency(avgPitch.floatValue());
                     intonationRight = score>70;
 
-                    integrityScore += integrityDuty;
-                    integrityRight = integrityDuty>0.7;
+                    if(score>0){
+                        integrityValidNum = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<15).count();
+                    }else{
+                        integrityValidNum = 0;
+                    }
                 }
-
-                //如果当前音符不需要演奏
-                if (musicXmlInfo.getFrequency()<0&&recordPitchs.size()<=0){
-                    cadenceNum++;
-                    cadenceRight = true;
-
-                    intonationScore += 100;
-                    musicXmlInfo.setAvgFrequency(-1);
-                    intonationRight = true;
-
-                    integrityScore += 1;
-                    integrityRight = true;
+                //完成度
+                if(integrityValidNum > compareNum){
+                    integrityValidNum = compareNum;
                 }
+                float integrityDuty = integrityValidNum/compareNum;
+                integrityScore += integrityDuty;
+                integrityRight = integrityDuty>0.7;
 
                 if(!cadenceRight){
                     userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.CADENCE_WRONG));
@@ -468,11 +528,6 @@ public class SoundCompareHandler implements WebSocketEventHandler {
         createPushInfo(phone, "measureScore", measureIndex, intonation, cadence, integrity);
     }
 
-    private float scoreMapping(float score, float divisor, float maxValue){
-        score = score*divisor;
-        return score>maxValue?maxValue:score;
-    }
-
     /**
      * @describe 计算最终评分
      * @author Joburgess
@@ -488,15 +543,15 @@ public class SoundCompareHandler implements WebSocketEventHandler {
         BigDecimal integrity = BigDecimal.ZERO;
 
         if(currentCompareNum>0){
-            intonation = userSoundInfoMap.get(phone).getUserScoreMap().get("intonation").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_UP);
-            cadence = userSoundInfoMap.get(phone).getUserScoreMap().get("cadence").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_UP);
-            integrity = userSoundInfoMap.get(phone).getUserScoreMap().get("integrity").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_UP);
+            intonation = userSoundInfoMap.get(phone).getUserScoreMap().get("intonation").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_DOWN);
+            cadence = userSoundInfoMap.get(phone).getUserScoreMap().get("cadence").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_DOWN);
+            integrity = userSoundInfoMap.get(phone).getUserScoreMap().get("integrity").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_DOWN);
         }
 
         //计算分数并推送
         createPushInfo(phone, "overall", -1, intonation, cadence, integrity);
 
-        LOGGER.info("评分数据:{}", JSON.toJSONString(userSoundInfoMap.get(phone), SerializerFeature.DisableCircularReferenceDetect));
+        LOGGER.info("评分数据:{}", JSON.toJSONString(userSoundInfoMap.get(phone)));
     }
 
     /**
@@ -515,8 +570,12 @@ public class SoundCompareHandler implements WebSocketEventHandler {
         WebSocketInfo webSocketInfo = new WebSocketInfo();
         webSocketInfo.setHeader(new WebSocketInfo.Head(command));
         Map<String, Object> result = new HashMap<>(5);
-        BigDecimal score  = intonation.add(cadence).add(integrity).divide(new BigDecimal(3), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_UP);
-
+        //打击乐只看节奏分
+        BigDecimal score = cadence;
+        //非打击乐总分为平均分
+        if(Objects.isNull(userSoundInfoMap.get(phone).getSubjectId())||userSoundInfoMap.get(phone).getSubjectId()!=23){
+            score = intonation.add(cadence).add(integrity).divide(new BigDecimal(3), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_UP);
+        }
         result.put("score", score);
         result.put("intonation", intonation);
         result.put("cadence", cadence);

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

@@ -1206,7 +1206,18 @@ public class StudentRegistrationServiceImpl extends BaseServiceImpl<Long, Studen
 
             //销售订单详情
             if (orderDetails.size() > 0) {
-                sellOrderService.addOrderDetail2SellOrder(orderDetails, studentPaymentOrder, musicGroup);
+                BigDecimal couponRemitFee = studentPaymentOrder.getCouponRemitFee();
+                if(couponRemitFee.compareTo(BigDecimal.ZERO) > 0){
+                    BigDecimal musicFee = orderDetails.stream().filter(o -> o.getType().getCode().equals("MUSICAL")
+                            || o.getType().getCode().equals("ACCESSORIES") || o.getType().getCode().equals("TEACHING"))
+                            .map(o -> o.getPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                    BigDecimal expectAmount = studentPaymentOrder.getExpectAmount();
+                    //获取比例
+                    BigDecimal ratioAmount = musicFee.divide(expectAmount, 6, BigDecimal.ROUND_HALF_UP);
+                    //获取分配的减免金额
+                    couponRemitFee = couponRemitFee.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
+                }
+                sellOrderService.addOrderDetail2SellOrder(orderDetails, studentPaymentOrder, musicGroup,couponRemitFee);
             }
 
             //课程处理

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRepairServiceImpl.java

@@ -1013,6 +1013,28 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
             sellOrder.setCooperationOrganId(studentGoodsSell.getCooperationOrganId());
         }
         if (sellOrderList.size() > 0) {
+            //如果有优惠券金额
+            BigDecimal couponMarketAmount = studentGoodsSell.getCouponMarketAmount();
+            if (couponMarketAmount.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal reduce = sellOrderList.stream().map(e -> e.getExpectAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                List<SellOrder> sellOrders = sellOrderList.stream().filter(e -> e.getExpectAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
+                //可用优惠券金额
+                BigDecimal subCouponMarketAmount = couponMarketAmount;
+                for (int i = 0; i < sellOrders.size(); i++) {
+                    SellOrder sellOrder = sellOrders.get(i);
+                    //如果是最后一件商品
+                    if (i == sellOrders.size() - 1) {
+                        sellOrder.setCouponRemitAmount(subCouponMarketAmount);
+                    } else {
+                        //获取比例
+                        BigDecimal ratioAmount = sellOrder.getExpectAmount().divide(reduce, 6, BigDecimal.ROUND_HALF_UP);
+                        //获取分配的减免金额
+                        BigDecimal multiply = couponMarketAmount.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
+                        subCouponMarketAmount = subCouponMarketAmount.subtract(multiply);
+                        sellOrder.setCouponRemitAmount(multiply);
+                    }
+                }
+            }
             sellOrderService.batchInsert(sellOrderList);
         }
     }

+ 42 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SubjectChangeServiceImpl.java

@@ -375,7 +375,12 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
             if (StringUtils.isNotBlank(goodsIds)) {
                 List<Integer> goodsIdList = Arrays.stream(goodsIds.split(",")).map(Integer::parseInt).collect(Collectors.toList());
                 //添加新订单
-                this.addSellOrder(studentPaymentOrder.getId(), subjectChange.getMusicGroupId(), goodsIdList, BigDecimal.ZERO, BigDecimal.ZERO, subjectChange.getKitGroupPurchaseType());
+                this.addSellOrder(studentPaymentOrder.getId(),
+                        subjectChange.getMusicGroupId(),
+                        goodsIdList,
+                        BigDecimal.ZERO,
+                        BigDecimal.ZERO,
+                        subjectChange.getKitGroupPurchaseType(),BigDecimal.ZERO);
             }
             //乐保处理
             studentInstrumentService.subjectChangeUpdateInstrument(subjectChange);
@@ -625,7 +630,12 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
                 	sellOrderService.refundByOrderId(subjectChange.getOriginalOrderId().longValue(), false);
                 }
                 //添加新订单
-                List<SellOrder> sellOrders = this.addSellOrder(studentPaymentOrder.getId(), subjectChange.getMusicGroupId(), goodsIdList, studentPaymentOrder.getExpectAmount(), studentPaymentOrder.getBalancePaymentAmount(), subjectChange.getKitGroupPurchaseType());
+                List<SellOrder> sellOrders = this.addSellOrder(studentPaymentOrder.getId(),
+                        subjectChange.getMusicGroupId(),
+                        goodsIdList,
+                        studentPaymentOrder.getExpectAmount(),
+                        studentPaymentOrder.getBalancePaymentAmount(),
+                        subjectChange.getKitGroupPurchaseType(),studentPaymentOrder.getCouponRemitFee());
                 if(sellOrders != null && sellOrders.size() > 0){
                     SubjectChange change = subjectChangeDao.get(subjectChange.getId());
                     BigDecimal instrumentAmount = sellOrders.stream().filter(e -> e.getType() == SellTypeEnum.INSTRUMENT).map(e -> e.getExpectAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
@@ -742,7 +752,12 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
 
     @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-    public List<SellOrder> addSellOrder(Long orderId, String musicGroupId, List<Integer> goodsIds, BigDecimal totalAmount, BigDecimal balance, KitGroupPurchaseTypeEnum kitGroupPurchaseType) {
+    public List<SellOrder> addSellOrder(Long orderId,
+                                        String musicGroupId,
+                                        List<Integer> goodsIds,
+                                        BigDecimal totalAmount,
+                                        BigDecimal balance,
+                                        KitGroupPurchaseTypeEnum kitGroupPurchaseType,BigDecimal couponRemitAmount) {
         if (goodsIds == null || goodsIds.size() <= 0) {
             return null;
         }
@@ -865,7 +880,30 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
                 }
             }
         }
-        sellOrderDao.batchInsert(sellOrderList);
+        if (sellOrderList.size() > 0) {
+            //如果有优惠券金额
+            if (couponRemitAmount.compareTo(BigDecimal.ZERO) > 0) {
+                BigDecimal reduce = sellOrderList.stream().map(e -> e.getExpectAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                List<SellOrder> sellOrders = sellOrderList.stream().filter(e -> e.getExpectAmount().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
+                //可用优惠券金额
+                BigDecimal subCouponMarketAmount = couponRemitAmount;
+                for (int j = 0; j < sellOrders.size(); j++) {
+                    SellOrder sellOrder = sellOrders.get(j);
+                    //如果是最后一件商品
+                    if (j == sellOrders.size() - 1) {
+                        sellOrder.setCouponRemitAmount(subCouponMarketAmount);
+                    } else {
+                        //获取比例
+                        BigDecimal ratioAmount = sellOrder.getExpectAmount().divide(reduce, 6, BigDecimal.ROUND_HALF_UP);
+                        //获取分配的减免金额
+                        BigDecimal multiply = couponRemitAmount.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
+                        subCouponMarketAmount = subCouponMarketAmount.subtract(multiply);
+                        sellOrder.setCouponRemitAmount(multiply);
+                    }
+                }
+            }
+            sellOrderService.batchInsert(sellOrderList);
+        }
         return sellOrderList;
     }
 }

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java

@@ -912,4 +912,10 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 			throw new BizException("操作失败: 当前申述状态不允许该操作");
 		}
 	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void updateDeviceNum(Integer courseId, String userId, String signInDeviceNum, String signOutDeviceNum) {
+		teacherAttendanceDao.updateDeviceNum(courseId,userId,signInDeviceNum,signOutDeviceNum);
+	}
 }

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

@@ -177,6 +177,12 @@
             <if test="subjectId != null">
                 and (spr.subject_first_ = #{subjectId} or spr.subject_second_ = #{subjectId})
             </if>
+            <if test="teacherRecommandSubjectId != null">
+                and (spr.teacher_recommand_subject_id_ = #{teacherRecommandSubjectId})
+            </if>
+            <if test="selectionSubjectId != null">
+                and (spr.selection_subject_id_ = #{selectionSubjectId})
+            </if>
             <if test="name != null">
                 and (spr.phone_ like concat('%',#{name},'%') or spr.user_name_ like concat('%',#{name},'%') or
                 spr.user_id_ like concat('%',#{name},'%'))
@@ -208,6 +214,12 @@
             <if test="subjectId != null">
                 and (spr.subject_first_ = #{subjectId} or spr.subject_second_ = #{subjectId})
             </if>
+            <if test="teacherRecommandSubjectId != null">
+                and (spr.teacher_recommand_subject_id_ = #{teacherRecommandSubjectId})
+            </if>
+            <if test="selectionSubjectId != null">
+                and (spr.selection_subject_id_ = #{selectionSubjectId})
+            </if>
             <if test="name != null">
                 and (spr.phone_ like concat('%',#{name},'%') or spr.user_name_ like concat('%',#{name},'%') or
                 spr.user_id_ like concat('%',#{name},'%'))

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

@@ -684,6 +684,18 @@
                 ,sign_in_longitude_latitude_ = NULL,sign_out_longitude_latitude_ = NULL
         WHERE course_schedule_id_ = #{courseScheduleId}
     </update>
+    <update id="updateDeviceNum">
+        UPDATE teacher_attendance
+        <set>
+            <if test="signInDeviceNum != null and signInDeviceNum != ''">
+                sign_in_device_no_ = #{signInDeviceNum}
+            </if>
+            <if test="signOutDeviceNum != null and signOutDeviceNum != ''">
+                sign_out_device_no_ = #{signOutDeviceNum}
+            </if>
+        </set>
+        WHERE course_schedule_id_ = #{courseId} AND teacher_id_ = #{userId}
+    </update>
 
     <delete id="deleteByMusicGroupId" parameterType="map" >
 		DELETE ta FROM teacher_attendance ta LEFT JOIN course_schedule cs ON ta.course_schedule_id_ = cs.id_

+ 2 - 0
mec-im/src/main/java/com/ym/mec/im/IMHelper.java

@@ -6,6 +6,7 @@ import com.ym.pojo.IMApiResultInfo;
 import com.ym.pojo.IMTokenInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import java.net.HttpURLConnection;
@@ -111,6 +112,7 @@ public class IMHelper {
      * @param groupName:要加入的群 Id 对应的名称。(必传)
      * @return CodeSuccessResult
      **/
+    @Async
     public IMApiResultInfo joinGroup(String[] userId, String groupId, String groupName)
             throws Exception {
         if (userId == null) {

+ 5 - 3
mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java

@@ -317,7 +317,8 @@ public class RoomServiceImpl implements RoomService {
         if(!aBoolean){
             RoleEnum roleEnum = RoleEnum.getEnumByValue(roomMember.getRole());
             if(roleEnum == RoleTeacher && StringUtils.isNotEmpty(deviceNum)){
-                signInSuccess(roomMember,deviceNum);
+                teacherAttendanceService.updateDeviceNum(Integer.parseInt(roomId.substring(1)),userId,deviceNum,null);
+//                signInSuccess(roomMember,deviceNum);
             }
             return;
         }
@@ -435,7 +436,7 @@ public class RoomServiceImpl implements RoomService {
         return roomMember;
     }
 
-    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,isolation = Isolation.SERIALIZABLE)
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
     @Override
     public void leaveRoomSuccess(String roomId,String userId,String deviceNum) throws Exception {
         log.info("leaveRoomSuccess: roomId={}, userId={},deviceNum={}", roomId,userId,deviceNum);
@@ -458,7 +459,8 @@ public class RoomServiceImpl implements RoomService {
             if (StringUtils.isNotEmpty(deviceNum)){
                 //如果设备号不为空,更新设备号
                 if(roleEnum == RoleTeacher){
-                    teacherAttendanceService.addTeacherAttendanceSignOut(firstCourseId.longValue(),parseInt,deviceNum);
+                    teacherAttendanceService.updateDeviceNum(firstCourseId,userId,null,deviceNum);
+//                    teacherAttendanceService.addTeacherAttendanceSignOut(firstCourseId.longValue(),parseInt,deviceNum);
                 }
             }
             return;

+ 3 - 0
mec-student/src/main/java/com/ym/mec/student/controller/MemberRankController.java

@@ -93,6 +93,9 @@ public class MemberRankController extends BaseController {
 		if (sysUser == null) {
 			return failed(HttpStatus.FORBIDDEN, "请登录");
 		}
+		if(sysUser.getOrganId() == 43){
+			throw new BizException("活动仅对乐团老生学员开放");
+		}
 		//买2赠1、买3赠2
 		Integer buyNum = memberPayParamDto.getBuyNum();
 		int giveNum = buyNum == 2?1:buyNum == 3?2:0;

+ 50 - 22
mec-student/src/main/java/com/ym/mec/student/controller/MusicGroupController.java

@@ -1,38 +1,66 @@
 package com.ym.mec.student.controller;
 
+import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.ADD_STUDENT;
+import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.MUSIC_APPLY;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+
+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;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
 import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
 import com.ym.mec.biz.dal.dao.StudentPreRegistrationDao;
+import com.ym.mec.biz.dal.dto.MusicGroupSubjectGoodsAndInfoDto;
 import com.ym.mec.biz.dal.dto.RegisterPayDto;
 import com.ym.mec.biz.dal.dto.RenewParamDto;
-import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.entity.ApprovalStatus;
+import com.ym.mec.biz.dal.entity.Goods;
+import com.ym.mec.biz.dal.entity.MusicGroup;
+import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
 import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum;
+import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderDetail;
+import com.ym.mec.biz.dal.entity.MusicGroupQuit;
 import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
-import com.ym.mec.biz.dal.enums.*;
-import com.ym.mec.biz.service.*;
+import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
+import com.ym.mec.biz.dal.entity.StudentPaymentOrderDetail;
+import com.ym.mec.biz.dal.entity.StudentPreRegistration;
+import com.ym.mec.biz.dal.entity.StudentRegistration;
+import com.ym.mec.biz.dal.enums.CourseViewTypeEnum;
+import com.ym.mec.biz.dal.enums.DealStatusEnum;
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
+import com.ym.mec.biz.dal.enums.OrderTypeEnum;
+import com.ym.mec.biz.dal.enums.PayStatus;
+import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
+import com.ym.mec.biz.service.MusicGroupService;
+import com.ym.mec.biz.service.MusicGroupSubjectPlanService;
+import com.ym.mec.biz.service.OrganizationService;
+import com.ym.mec.biz.service.StudentPaymentOrderDetailService;
+import com.ym.mec.biz.service.StudentPaymentOrderService;
+import com.ym.mec.biz.service.StudentRegistrationService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.ADD_STUDENT;
-import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.MUSIC_APPLY;
 
 @RequestMapping("musicGroup")
 @Api(tags = "乐团服务")
@@ -122,7 +150,7 @@ public class MusicGroupController extends BaseController {
     @GetMapping("/getSubjectGoodsAndInfo")
     @ApiImplicitParams({@ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String"),
             @ApiImplicitParam(name = "subjectId", value = "声部编号", required = true, dataType = "Integer")})
-    public HttpResponseResult getSubjectGoodsAndInfo(String musicGroupId, Integer subjectId) {
+    public HttpResponseResult<MusicGroupSubjectGoodsAndInfoDto> getSubjectGoodsAndInfo(String musicGroupId, Integer subjectId) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         return succeed(musicGroupSubjectPlanService.getSubjectGoodsAndInfo(musicGroupId, subjectId));
     }

+ 12 - 1
mec-student/src/main/java/com/ym/mec/student/controller/StudentOrderController.java

@@ -897,7 +897,18 @@ public class StudentOrderController extends BaseController {
         //销售订单详情
         if (orderDetails.size() > 0) {
             MusicGroup musicGroup = musicGroupService.get(order.getMusicGroupId());
-            sellOrders = sellOrderService.addOrderDetail2SellOrder(orderDetails, order, musicGroup);
+            BigDecimal couponRemitFee = order.getCouponRemitFee();
+            if(couponRemitFee.compareTo(BigDecimal.ZERO) > 0){
+                BigDecimal musicFee = orderDetails.stream().filter(o -> o.getType().getCode().equals("MUSICAL")
+                        || o.getType().getCode().equals("ACCESSORIES") || o.getType().getCode().equals("TEACHING"))
+                        .map(o -> o.getPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                BigDecimal expectAmount = order.getExpectAmount();
+                //获取比例
+                BigDecimal ratioAmount = musicFee.divide(expectAmount, 6, BigDecimal.ROUND_HALF_UP);
+                //获取分配的减免金额
+                couponRemitFee = couponRemitFee.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
+            }
+            sellOrders = sellOrderService.addOrderDetail2SellOrder(orderDetails, order, musicGroup,couponRemitFee);
         }
         return succeed(sellOrders);
 

+ 5 - 4
mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java

@@ -2655,15 +2655,16 @@ public class ExportController extends BaseController {
                     row.setReceiveStatusStr("自动确认");
                     break;
             }
+            row.setOrderAmount(row.getExpectAmount().add(row.getCouponRemitAmount()));
         }
         OutputStream outputStream = response.getOutputStream();
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{
-                    "交易流水号", "订单号", "销售日期", "销售类型", "商品名称", "数量", "应付金额(元)", "余额支付(元)",
-                    "现金支付(元)", "销售成本(元)", "学员姓名", "交易方式", "收款账户", "账户类型", "扣减库存", "所属分部",
+                    "交易流水号", "订单号", "销售日期", "销售类型", "商品名称", "数量", "订单金额(元)", "应付金额(元)", "余额支付(元)",
+                    "现金支付(元)", "优惠金额(元)", "销售成本(元)", "学员姓名", "交易方式", "收款账户", "账户类型", "扣减库存", "所属分部",
                     "所属学校", "教务老师", "确认收货", "状态"}, new String[]{
-                    "transNo", "orderNo", "sellTime", "type.desc", "goodsName", "num", "expectAmount", "balanceAmount",
-                    "actualAmount", "sellCost", "userName", "paymentChannelStr", "merNo", "accountTypeStr", "stockType.msg", "organName",
+                    "transNo", "orderNo", "sellTime", "type.desc", "goodsName", "num", "orderAmount", "expectAmount", "balanceAmount",
+                    "actualAmount", "couponRemitAmount", "sellCost", "userName", "paymentChannelStr", "merNo", "accountTypeStr", "stockType.msg", "organName",
                     "schoolName", "eduTeacher", "receiveStatusStr", "status.msg"}, rows);
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attachment;filename=lender-" + DateUtil.getDate(new Date()) + ".xls");