浏览代码

Merge remote-tracking branch 'origin/master'

周箭河 4 年之前
父节点
当前提交
f3a8454819
共有 27 个文件被更改,包括 774 次插入285 次删除
  1. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java
  2. 9 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleStudentPaymentDao.java
  3. 16 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/VipGroupStudentCoursePriceDao.java
  4. 13 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupApplyBaseInfoDto.java
  5. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupApplyDto.java
  6. 20 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupStudentDto.java
  7. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseScheduleStudentPayment.java
  8. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/VipGroupCategory.java
  9. 99 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/VipGroupStudentCoursePrice.java
  10. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java
  11. 13 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SysUserCashAccountService.java
  12. 2 6
      mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupService.java
  13. 8 0
      mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupStudentCoursePriceService.java
  14. 75 13
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  15. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleTeacherSalaryServiceImpl.java
  16. 65 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysUserCashAccountServiceImpl.java
  17. 223 227
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java
  18. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupStudentCoursePriceServiceImpl.java
  19. 14 0
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  20. 19 9
      mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml
  21. 6 3
      mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml
  22. 7 7
      mec-biz/src/main/resources/config/mybatis/VipGroupCategoryMapper.xml
  23. 7 4
      mec-biz/src/main/resources/config/mybatis/VipGroupMapper.xml
  24. 93 0
      mec-biz/src/main/resources/config/mybatis/VipGroupStudentCoursePriceMapper.xml
  25. 1 1
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherVipGroupController.java
  26. 15 0
      mec-web/src/main/java/com/ym/mec/web/controller/CourseScheduleController.java
  27. 10 14
      mec-web/src/main/java/com/ym/mec/web/controller/VipGroupManageController.java

+ 4 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java

@@ -578,6 +578,8 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
 
     int batchUpdate(List<CourseSchedule> courseScheduleList);
 
+    int cleanCoursMergeId(@Param("courseIds") List<Long> courseIds);
+
     /**
      * 查询提前指定分钟数还未签到的用户
      *
@@ -1670,6 +1672,8 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
      */
     int countCourseMergeTime(@Param("courseId") Long courseId);
 
+    List<CourseSchedule> findByMainMergeCourse(@Param("mainMergeCourseId") Long mainMergeCourseId);
+
     /**
      * 获取班级剩余的课程类型和课程数量
      *

+ 9 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleStudentPaymentDao.java

@@ -211,6 +211,15 @@ public interface CourseScheduleStudentPaymentDao extends BaseDAO<Long, CourseSch
     List<CourseScheduleStudentPayment> findByCourseSchedule(@Param("courseScheduleId") Long courseScheduleId);
 
     /**
+     * @describe 获取合并课程的学员缴费记录
+     * @author Joburgess
+     * @date 2021/1/21 0021
+     * @param mainMergeCourseId:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment>
+     */
+    List<CourseScheduleStudentPayment> findByMainMergedCourse(@Param("mainMergeCourseId") Long mainMergeCourseId);
+
+    /**
      * @param groupId:
      * @return java.util.List<com.ym.mec.biz.dal.dto.VipGroupGiveCourseSortDto>
      * @describe 获取小课需要调整的缴费记录

+ 16 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/VipGroupStudentCoursePriceDao.java

@@ -0,0 +1,16 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice;
+import com.ym.mec.common.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface VipGroupStudentCoursePriceDao extends BaseDAO<Long, VipGroupStudentCoursePrice> {
+
+    int batchInsert(@Param("datas")List<VipGroupStudentCoursePrice> datas);
+
+    List<VipGroupStudentCoursePrice> getVipGroupStudentCoursePrice(@Param("vipGroupId") Long vipGroupId,
+                                                      @Param("studentId") Integer studentId);
+	
+}

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupApplyBaseInfoDto.java

@@ -1,9 +1,11 @@
 package com.ym.mec.biz.dal.dto;
 
 import com.ym.mec.biz.dal.entity.VipGroup;
+import com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * @Author Joburgess
@@ -32,6 +34,17 @@ public class VipGroupApplyBaseInfoDto extends VipGroup {
     @ApiModelProperty(value = "教师线下课课酬")
     private BigDecimal offlineTeacherSalary;
 
+    @ApiModelProperty(value = "课程组学员缴费设置")
+    private List<VipGroupStudentCoursePrice> vipGroupStudentCoursePrices;
+
+    public List<VipGroupStudentCoursePrice> getVipGroupStudentCoursePrices() {
+        return vipGroupStudentCoursePrices;
+    }
+
+    public void setVipGroupStudentCoursePrices(List<VipGroupStudentCoursePrice> vipGroupStudentCoursePrices) {
+        this.vipGroupStudentCoursePrices = vipGroupStudentCoursePrices;
+    }
+
     public String getSubjectIdList() {
         return subjectIdList;
     }

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

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.dal.dto;
 
 import com.ym.mec.biz.dal.entity.CourseSchedule;
+import com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.math.BigDecimal;

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/VipGroupStudentDto.java

@@ -28,12 +28,32 @@ public class VipGroupStudentDto {
 
     private BigDecimal courseSalary;
 
+    private BigDecimal balance;
+
+    private BigDecimal allBalance;
+
     private Date applyDate;
 
     private Date refundDate;
 
     private Integer studentStatus;
 
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public void setBalance(BigDecimal balance) {
+        this.balance = balance;
+    }
+
+    public BigDecimal getAllBalance() {
+        return allBalance;
+    }
+
+    public void setAllBalance(BigDecimal allBalance) {
+        this.allBalance = allBalance;
+    }
+
     public Date getApplyDate() {
         return applyDate;
     }

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

@@ -55,6 +55,16 @@ public class CourseScheduleStudentPayment implements Comparable<CourseScheduleSt
 
 	private String examSongDownloadJson;
 
+	private Boolean beMerged = false;
+
+	public Boolean getBeMerged() {
+		return beMerged;
+	}
+
+	public void setBeMerged(Boolean beMerged) {
+		this.beMerged = beMerged;
+	}
+
 	public CourseScheduleStudentPayment() {
 	}
 

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

@@ -38,6 +38,17 @@ public class VipGroupCategory {
 	@ApiModelProperty(value = "线下课单价",required = false)
 	private BigDecimal offlineClassesUnitPrice;
 
+	@ApiModelProperty(value = "是否乐理课")
+	private Boolean musicTheory = false;
+
+	public Boolean getMusicTheory() {
+		return musicTheory;
+	}
+
+	public void setMusicTheory(Boolean musicTheory) {
+		this.musicTheory = musicTheory;
+	}
+
 	public BigDecimal getOnlineClassesUnitPrice() {
 		return onlineClassesUnitPrice;
 	}

+ 99 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/VipGroupStudentCoursePrice.java

@@ -0,0 +1,99 @@
+package com.ym.mec.biz.dal.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.math.BigDecimal;
+
+/**
+ * 对应数据库表(vip_group_student_course_price):
+ */
+public class VipGroupStudentCoursePrice {
+
+	/**  */
+	private Long id;
+	
+	/** vip课程组编号 */
+	private Long vipGroupId;
+	
+	/** 学员编号 */
+	private Integer studentId;
+	
+	/** 线上课单价 */
+	private java.math.BigDecimal onlineClassesUnitPrice;
+	
+	/** 线下课单价 */
+	private java.math.BigDecimal offlineClassesUnitPrice;
+	
+	/** 支付价格 */
+	private java.math.BigDecimal paymentPrice;
+
+	public VipGroupStudentCoursePrice() {
+	}
+
+	public VipGroupStudentCoursePrice(Integer studentId, BigDecimal onlineClassesUnitPrice, BigDecimal offlineClassesUnitPrice) {
+		this.studentId = studentId;
+		this.onlineClassesUnitPrice = onlineClassesUnitPrice;
+		this.offlineClassesUnitPrice = offlineClassesUnitPrice;
+	}
+
+	public VipGroupStudentCoursePrice(Integer studentId, BigDecimal onlineClassesUnitPrice, BigDecimal offlineClassesUnitPrice, BigDecimal paymentPrice) {
+		this.studentId = studentId;
+		this.onlineClassesUnitPrice = onlineClassesUnitPrice;
+		this.offlineClassesUnitPrice = offlineClassesUnitPrice;
+		this.paymentPrice = paymentPrice;
+	}
+
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setVipGroupId(Long vipGroupId){
+		this.vipGroupId = vipGroupId;
+	}
+	
+	public Long getVipGroupId(){
+		return this.vipGroupId;
+	}
+			
+	public void setStudentId(Integer studentId){
+		this.studentId = studentId;
+	}
+	
+	public Integer getStudentId(){
+		return this.studentId;
+	}
+			
+	public void setOnlineClassesUnitPrice(java.math.BigDecimal onlineClassesUnitPrice){
+		this.onlineClassesUnitPrice = onlineClassesUnitPrice;
+	}
+	
+	public java.math.BigDecimal getOnlineClassesUnitPrice(){
+		return this.onlineClassesUnitPrice;
+	}
+			
+	public void setOfflineClassesUnitPrice(java.math.BigDecimal offlineClassesUnitPrice){
+		this.offlineClassesUnitPrice = offlineClassesUnitPrice;
+	}
+	
+	public java.math.BigDecimal getOfflineClassesUnitPrice(){
+		return this.offlineClassesUnitPrice;
+	}
+			
+	public void setPaymentPrice(java.math.BigDecimal paymentPrice){
+		this.paymentPrice = paymentPrice;
+	}
+	
+	public java.math.BigDecimal getPaymentPrice(){
+		return this.paymentPrice;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java

@@ -635,4 +635,14 @@ public interface CourseScheduleService extends BaseService<Long, CourseSchedule>
 	 * @return void
 	 */
 	void courseMerge(CourseMergeDto courseMergeInfo);
+
+	/**
+	 * @describe 合并课程还原
+	 * @author Joburgess
+	 * @date 2021/1/21 0021
+	 * @param mainCourseId:
+	 * @param operatorId:
+	 * @return void
+	 */
+	void mergeCourseSplit(Long mainCourseId, Integer operatorId);
 }

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SysUserCashAccountService.java

@@ -54,6 +54,19 @@ public interface SysUserCashAccountService extends BaseService<Integer, SysUserC
 	boolean appendCourseBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, String description);
 
 	/**
+	 * @describe 从账户金额与课程金额中扣减指定金额
+	 * 优先课程金额,不够再扣减账户金额
+	 * @author Joburgess
+	 * @date 2021/1/20 0020
+	 * @param userId:
+	 * @param decimal:
+	 * @param type:
+	 * @param description:
+	 * @return void
+	 */
+	void subtractFromCourseBalanceAndBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, String description);
+
+	/**
 	 * 将课程余额转入到可用余额
 	 * @param userId
 	 * @return

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

@@ -164,14 +164,10 @@ public interface VipGroupService extends BaseService<Long, VipGroup> {
      * @date 2019/10/23
      * @param vipGroup: vip课程
      * @param teacherId: 要计算课酬的老师的编号
-     * @param onlineClassesUnitPrice: 线上课程单价
-     * @param offlineClassesUnitPrice: 线下课程单价
      * @return java.util.Map
      */
     <K extends VipGroup> Map<String, BigDecimal> countVipGroupPredictFee(K vipGroup,
-                                                     Integer teacherId,
-                                                     BigDecimal onlineClassesUnitPrice,
-                                                     BigDecimal offlineClassesUnitPrice);
+                                                     Integer teacherId);
 
     /**
      * @describe 计算vip课程购买总价,及老师课酬-只是学生人数统计方式不同
@@ -393,7 +389,7 @@ public interface VipGroupService extends BaseService<Long, VipGroup> {
      * @param studentIds:
      * @return void
      */
-    void addVipGroupStudents(Long vipGroupId,List<Integer> studentIds);
+    void addVipGroupStudents(Long vipGroupId,List<Integer> studentIds, Map<Integer, VipGroupStudentCoursePrice> studentCoursePriceMap);
 
     /**
      * 更新vipgroup至完成状态

+ 8 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/VipGroupStudentCoursePriceService.java

@@ -0,0 +1,8 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice;
+import com.ym.mec.common.service.BaseService;
+
+public interface VipGroupStudentCoursePriceService extends BaseService<Long, VipGroupStudentCoursePrice> {
+
+}

+ 75 - 13
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -2780,7 +2780,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
 			BigDecimal teacherSalary=BigDecimal.ZERO;
 
-			Map<String, BigDecimal> salaryMap = vipGroupService.countVipGroupPredictFee(vipGroup, vipGroup.getUserId(), null, null);
+			Map<String, BigDecimal> salaryMap = vipGroupService.countVipGroupPredictFee(vipGroup, vipGroup.getUserId());
 
 			ClassGroupTeacherSalary classGroupTeacherSalary = classGroupTeacherSalaryDao.findByVipGoupAndTeacher(vipGroupCourseAdjustInfo.getVipGroupId().intValue(), courseSchedules.get(0).getActualTeacherId());
 
@@ -3358,7 +3358,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 					if (newCourseSchedule.getGroupType() == GroupType.MUSIC) {
 						courseScheduleTeacherSalaryService.createMusicGroupCourseTeacherSalary(null, newCourseSchedule, ts);
 					} else if (newCourseSchedule.getGroupType() == GroupType.VIP) {
-						Map<String, BigDecimal> salaryMap = vipGroupService.countVipGroupPredictFee(vipGroup, teacherId, null, null);
+						Map<String, BigDecimal> salaryMap = vipGroupService.countVipGroupPredictFee(vipGroup, teacherId);
 
 						BigDecimal teacherSalary=null;
 
@@ -3559,7 +3559,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
                     BigDecimal onlineTeacherSalary = new BigDecimal(0), offlineTeacherSalary = new BigDecimal(0);
 
-					Map<String, BigDecimal> salaryMap = vipGroupService.countVipGroupPredictFee(byCourseSchedule, newCourseSchedule.getActualTeacherId(), null, null);
+					Map<String, BigDecimal> salaryMap = vipGroupService.countVipGroupPredictFee(byCourseSchedule, newCourseSchedule.getActualTeacherId());
 
                     List<CourseSchedule> courseSchedules = new ArrayList<>();
                     courseSchedules.add(newCourseSchedule);
@@ -5297,7 +5297,6 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
 		Map<Integer, List<CourseScheduleStudentPayment>> otherStudentCourseMap = courseScheduleStudentPayments.stream().filter(c -> !courseMergeInfo.getId().equals(c.getCourseScheduleId())).collect(Collectors.groupingBy(CourseScheduleStudentPayment::getUserId));
 
-
 		List<CourseScheduleStudentPayment> newPayments = new ArrayList<>();
 		List<CourseScheduleStudentPayment> updatePayments = new ArrayList<>();
 
@@ -5309,10 +5308,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 				updatePayment.setExpectPrice(updatePayment.getExpectPrice().add(salary));
 				updatePayments.add(updatePayment);
 
-				for (CourseScheduleStudentPayment studentCoursePayment : studentCoursePayments) {
-					studentCoursePayment.setExpectPrice(BigDecimal.ZERO);
-					updatePayments.add(studentCoursePayment);
-				}
+//				for (CourseScheduleStudentPayment studentCoursePayment : studentCoursePayments) {
+//					studentCoursePayment.setExpectPrice(BigDecimal.ZERO);
+//					updatePayments.add(studentCoursePayment);
+//				}
 				continue;
 			}
 			CourseScheduleStudentPayment newPayment = new CourseScheduleStudentPayment();
@@ -5323,11 +5322,12 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 			newPayment.setGroupType(courseMergeInfo.getGroupType());
 			newPayment.setExpectPrice(salary);
 			newPayment.setId(null);
+			newPayment.setBeMerged(true);
 			newPayments.add(newPayment);
-			for (CourseScheduleStudentPayment studentCoursePayment : studentCoursePayments) {
-				studentCoursePayment.setExpectPrice(BigDecimal.ZERO);
-				updatePayments.add(studentCoursePayment);
-			}
+//			for (CourseScheduleStudentPayment studentCoursePayment : studentCoursePayments) {
+//				studentCoursePayment.setExpectPrice(BigDecimal.ZERO);
+//				updatePayments.add(studentCoursePayment);
+//			}
 		}
 
 		List<CourseSchedule> courseSchedules=new ArrayList<>();
@@ -5357,7 +5357,9 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		}
 		courseScheduleDao.batchUpdate(mergeCourses);
 
-		courseScheduleStudentPaymentDao.batchUpdate(updatePayments);
+		if(!CollectionUtils.isEmpty(updatePayments)){
+			courseScheduleStudentPaymentDao.batchUpdate(updatePayments);
+		}
 		if(!CollectionUtils.isEmpty(newPayments))
 			courseScheduleStudentPaymentDao.batchInsert(newPayments);
 
@@ -5367,4 +5369,64 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 			courseScheduleModifyLogDao.batchInsert(insertCourseScheduleModifyLogList);
 		}
 	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void mergeCourseSplit(Long mainCourseId, Integer operatorId) {
+		List<CourseSchedule> courseSchedules = courseScheduleDao.findByMainMergeCourse(mainCourseId);
+		if(CollectionUtils.isEmpty(courseSchedules)){
+			throw new BizException("未找到相关合并课程信息");
+		}
+		Date now = new Date();
+		List<Long> courseIds = courseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
+		CourseSchedule mainCourse = courseSchedules.stream().filter(c -> mainCourseId.equals(c.getId())).findFirst().get();
+		if(now.compareTo(mainCourse.getStartClassTime())>=0){
+			throw new BizException("已结束的主课暂不支持此操作");
+		}
+
+		List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByMainMergedCourse(mainCourseId);
+		Map<Integer, CourseScheduleStudentPayment> studentMainCoursePaymentMap = courseScheduleStudentPayments.stream().filter(c -> c.getCourseScheduleId().equals(mainCourseId)).collect(Collectors.toMap(CourseScheduleStudentPayment::getUserId, c -> c, (c1, c2) -> c1));
+
+		List<CourseScheduleStudentPayment> otherCoursePayments = courseScheduleStudentPayments.stream().filter(c -> c.getCourseScheduleId().equals(mainCourseId)).collect(Collectors.toList());
+
+		List<Integer> deletePaymentIds = new ArrayList<>();
+		List<CourseScheduleStudentPayment> updatePayments = new ArrayList<>();
+
+		otherCoursePayments.sort(Comparator.comparing(CourseScheduleStudentPayment::getCreateTime).reversed());
+		for (CourseScheduleStudentPayment otherCoursePayment : otherCoursePayments) {
+			CourseScheduleStudentPayment mainCoursePayment = studentMainCoursePaymentMap.get(otherCoursePayment.getUserId());
+			if(Objects.isNull(mainCoursePayment.getBeMerged())){
+				throw new BizException("当前课程暂不支持此操作");
+			}
+			if(mainCoursePayment.getBeMerged()){
+				deletePaymentIds.add(mainCoursePayment.getId().intValue());
+				continue;
+			}
+			mainCoursePayment.setExpectPrice(mainCoursePayment.getExpectPrice().subtract(otherCoursePayment.getExpectPrice()));
+			updatePayments.add(mainCoursePayment);
+		}
+
+		courseScheduleStudentPaymentDao.batchDeleteWithID(deletePaymentIds);
+		courseScheduleStudentPaymentDao.batchUpdate(updatePayments);
+
+		List<CourseScheduleModifyLog> insertCourseScheduleModifyLogList = new ArrayList<>();
+		for (CourseSchedule courseSchedule : courseSchedules) {
+			CourseScheduleModifyLog courseScheduleModifyLog = new CourseScheduleModifyLog();
+			courseScheduleModifyLog.setCourseScheduleId(courseSchedule.getId());
+			courseScheduleModifyLog.setCreateTime(now);
+			courseScheduleModifyLog.setPreviousCourseSchedule(JsonUtil.toJSONString(courseSchedule));
+
+			//课程信息变更
+			courseSchedule.setNote("合并课程还原");
+
+			courseScheduleModifyLog.setCurrentCourseSchedule(JsonUtil.toJSONString(courseSchedule));
+			courseScheduleModifyLog.setOperatorId(operatorId);
+			insertCourseScheduleModifyLogList.add(courseScheduleModifyLog);
+		}
+		courseScheduleDao.batchUpdate(courseSchedules);
+		courseScheduleDao.cleanCoursMergeId(courseIds);
+		if (insertCourseScheduleModifyLogList.size() > 0) {
+			courseScheduleModifyLogDao.batchInsert(insertCourseScheduleModifyLogList);
+		}
+    }
 }

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

@@ -798,7 +798,7 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         BigDecimal onlineTeacherSalary=BigDecimal.ZERO,
                 offlineTeacherSalary=BigDecimal.ZERO;
 
-        Map<String, BigDecimal> salary = vipGroupService.countVipGroupPredictFee(vipGroup, vipGroup.getUserId(), null, null);
+        Map<String, BigDecimal> salary = vipGroupService.countVipGroupPredictFee(vipGroup, vipGroup.getUserId());
 
         if(Objects.nonNull(salary)){
             onlineTeacherSalary=salary.get("onlineTeacherSalary");

+ 65 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysUserCashAccountServiceImpl.java

@@ -256,6 +256,71 @@ public class SysUserCashAccountServiceImpl extends BaseServiceImpl<Integer, SysU
     }
 
     @Override
+    public void subtractFromCourseBalanceAndBalance(Integer userId, BigDecimal decimal, PlatformCashAccountDetailTypeEnum type, String description) {
+        SysUserCashAccount cashAccount = sysUserCashAccountDao.getLocked(userId);
+        if (cashAccount == null) {
+            throw new BizException("用户[{}]现金账户不存在", userId);
+        }
+        decimal = decimal.abs();
+        BigDecimal allBalance = cashAccount.getCourseBalance().add(cashAccount.getBalance());
+        BigDecimal changeMoney = decimal;
+        if (changeMoney.compareTo(allBalance)>0) {
+            throw new BizException("现金账户[{}]课程余额不足,可用余额剩{}元", userId, allBalance.doubleValue());
+        }
+
+        if (changeMoney.compareTo(BigDecimal.ZERO) == 0) {
+            return;
+        }
+
+        Date date = new Date();
+        SysUserCoursesAccountDetail sysUserCoursesAccountDetail = new SysUserCoursesAccountDetail();
+        if(changeMoney.compareTo(cashAccount.getCourseBalance())>0){
+            changeMoney = changeMoney.subtract(cashAccount.getCourseBalance());
+            cashAccount.setCourseBalance(BigDecimal.ZERO);
+            sysUserCoursesAccountDetail.setAmount(changeMoney);
+        }else{
+            cashAccount.setCourseBalance(cashAccount.getCourseBalance().subtract(changeMoney));
+            sysUserCoursesAccountDetail.setAmount(changeMoney);
+            changeMoney = BigDecimal.ZERO;
+        }
+        cashAccount.setUpdateTime(date);
+
+        String comment = description;
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser != null && sysUser.getId()!=null){
+            comment +=  "-" + sysUser.getId();
+        }
+        sysUserCoursesAccountDetail.setUserId(userId);
+        sysUserCoursesAccountDetail.setBalance(cashAccount.getCourseBalance());
+        sysUserCoursesAccountDetail.setComment(comment);
+        sysUserCoursesAccountDetail.setDescription("总扣费金额:"+decimal);
+        sysUserCoursesAccountDetail.setStatus(DealStatusEnum.SUCCESS);
+        sysUserCoursesAccountDetail.setType(type);
+        sysUserCoursesAccountDetail.setUpdateTime(date);
+        sysUserCoursesAccountDetail.setCreateTime(date);
+        sysUserCoursesAccountDetailDao.insert(sysUserCoursesAccountDetail);
+
+        if(changeMoney.compareTo(BigDecimal.ZERO)==0){
+            sysUserCashAccountDao.update(cashAccount);
+            return;
+        }
+        cashAccount.setBalance(cashAccount.getBalance().subtract(changeMoney));
+        sysUserCashAccountDao.update(cashAccount);
+
+        SysUserCashAccountDetail detail = new SysUserCashAccountDetail();
+        detail.setAmount(changeMoney);
+        detail.setBalance(cashAccount.getBalance());
+        detail.setComment(comment);
+        detail.setCreateTime(date);
+        detail.setDescription("总扣费金额:"+decimal);
+        detail.setStatus(DealStatusEnum.SUCCESS);
+        detail.setType(type);
+        detail.setUpdateTime(date);
+        detail.setUserId(userId);
+        sysUserCashAccountDetailDao.insert(detail);
+    }
+
+    @Override
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean transferCourseBalanceToBalance(Integer userId, BigDecimal money) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();

+ 223 - 227
mec-biz/src/main/java/com/ym/mec/biz/service/impl/VipGroupServiceImpl.java

@@ -149,6 +149,8 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 	private GroupClassService groupClassService;
 	@Autowired
 	private StudentPaymentRouteOrderService studentPaymentRouteOrderService;
+	@Autowired
+	private VipGroupStudentCoursePriceDao vipGroupStudentCoursePriceDao;
 
 	private static final Logger LOGGER = LoggerFactory
 			.getLogger(VipGroup.class);
@@ -205,23 +207,17 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
         if(Objects.isNull(vipGroupApplyBaseInfoDto.getOfflineClassesUnitPrice())
             &&Objects.isNull(vipGroupApplyBaseInfoDto.getOnlineClassesUnitPrice())){
-            throw new BizException("请设置教师课酬");
+            throw new BizException("请设置课程单价");
         }
 
 		if(StringUtils.isBlank(vipGroupApplyBaseInfoDto.getStudentIdList())){
 			throw new BizException("请选择学员");
 		}
 
-        if(Objects.isNull(vipGroupApplyBaseInfoDto.getOnlineTeacherSalary())){
-        	vipGroupApplyBaseInfoDto.setOnlineTeacherSalary(new BigDecimal(0));
-		}
-
-		if(Objects.isNull(vipGroupApplyBaseInfoDto.getOfflineTeacherSalary())){
-			vipGroupApplyBaseInfoDto.setOfflineTeacherSalary(new BigDecimal(0));
+        if(Objects.isNull(vipGroupApplyBaseInfoDto.getOnlineTeacherSalary())||Objects.isNull(vipGroupApplyBaseInfoDto.getOfflineTeacherSalary())){
+			throw new BizException("请设置教师课酬");
 		}
 
-		//获取活动信息
-		VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupApplyBaseInfo().getVipGroupActivityId().intValue());
 		Integer totalClassTimes=vipGroupApplyBaseInfoDto.getOnlineClassesNum()+vipGroupApplyBaseInfoDto.getOfflineClassesNum();
 		//获取第一节课
 		CourseSchedule firstCourseSchedule = vipGroup.getCourseSchedules().stream().min(Comparator.comparing(CourseSchedule::getStartClassTime)).get();
@@ -241,8 +237,13 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 		    throw new BizException("创建失败,报名截止时间必须在开课时间前一天");
         }
 
+		List<Integer> canBuyStudentIds = Arrays.stream(vipGroupApplyBaseInfoDto.getStudentIdList().split(",")).map(e -> Integer.valueOf(e)).collect(Collectors.toList());
+		List<VipGroupStudentCoursePrice> vscps = vipGroup.getVipGroupApplyBaseInfo().getVipGroupStudentCoursePrices();
+
+		//获取活动信息
+		VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupApplyBaseInfo().getVipGroupActivityId());
 		//判断课程安排是否超出范围
-		if(Objects.nonNull(vipGroupActivity.getCoursesEndTime())||Objects.nonNull(vipGroupActivity.getCoursesStartTime())){
+		if(Objects.nonNull(vipGroupActivity)&&(Objects.nonNull(vipGroupActivity.getCoursesEndTime())||Objects.nonNull(vipGroupActivity.getCoursesStartTime()))){
 			if(latestCourseSchedule.getEndClassTime().after(vipGroupActivity.getCoursesEndTime())
 					||firstCourseSchedule.getStartClassTime().before(vipGroupActivity.getCoursesStartTime())){
 				throw new BizException("课时安排时间超出范围!");
@@ -267,47 +268,23 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 		if(Objects.isNull(vipGroupCategory)){
 			throw new BizException("课程形式不存在");
 		}
-
-		List<Integer> canBuyStudentIds = Arrays.stream(vipGroupApplyBaseInfoDto.getStudentIdList().split(",")).map(e -> Integer.valueOf(e)).collect(Collectors.toList());
-
 		List<String> studentNames = studentDao.getStudentNames(canBuyStudentIds);
 
 		//生成vip课信息
 		List<String> bySubIds = subjectDao.findBySubIds(vipGroupApplyBaseInfoDto.getSubjectIdList());
-		StringBuffer className=new StringBuffer(StringUtils.join(bySubIds,","));
-		className.append(vipGroupCategory.getName());
+		StringBuffer className=new StringBuffer();
+		if(Objects.isNull(vipGroupCategory.getMusicTheory())||!vipGroupCategory.getMusicTheory()){
+			className.append(StringUtils.join(bySubIds,","));
+			className.append(vipGroupCategory.getName());
+		}else{
+			className.append("乐理课•");
+		}
 		className.append(StringUtils.join(studentNames, ","));
 		vipGroupApplyBaseInfoDto.setName(className.toString());
 
 		//计算课程相关费用信息
 		Map<String, BigDecimal> costInfo = countVipGroupPredictFee(vipGroupApplyBaseInfoDto,
-				vipGroupApplyBaseInfoDto.getUserId(),
-				vipGroupApplyBaseInfoDto.getOnlineClassesUnitPrice(),
-				vipGroupApplyBaseInfoDto.getOfflineClassesUnitPrice());
-
-//		BigDecimal offlineClassNum=new BigDecimal(vipGroupApplyBaseInfoDto.getOfflineClassesNum());
-//		BigDecimal onlineClassNum=new BigDecimal(vipGroupApplyBaseInfoDto.getOnlineClassesNum());
-//
-//		if(vipGroupActivity.getType().equals(VipGroupActivityTypeEnum.GIVE_CLASS)){
-//			if(vipGroupApplyBaseInfoDto.getGiveTeachMode()==TeachModeEnum.OFFLINE){
-//				if(new BigDecimal(totalClassTimes).compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))>-1){
-//					offlineClassNum=offlineClassNum.subtract(new BigDecimal(vipGroupActivity.getAttribute2()));
-//				}
-//			}else if(vipGroupApplyBaseInfoDto.getGiveTeachMode()==TeachModeEnum.ONLINE){
-//				if(new BigDecimal(totalClassTimes).compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))>-1){
-//					onlineClassNum=onlineClassNum.subtract(new BigDecimal(vipGroupActivity.getAttribute2()));
-//				}
-//			}else{
-//				throw new BizException("请指定赠送课程类型!");
-//			}
-//		}
-
-//		BigDecimal tempFee = costInfo.get("totalPrice").multiply(new BigDecimal(0.6));
-//		BigDecimal totalSalary = vipGroupApplyBaseInfoDto.getOfflineTeacherSalary().multiply(offlineClassNum)
-//				.add(vipGroupApplyBaseInfoDto.getOnlineTeacherSalary().multiply(onlineClassNum));
-//		if(totalSalary.compareTo(tempFee)>0){
-//			throw new BizException("教师总课酬不能高于课程总价60%");
-//		}
+				vipGroupApplyBaseInfoDto.getUserId());
 
         vipGroupApplyBaseInfoDto.setAuditStatus(AuditStatusEnum.PASS);
 
@@ -324,6 +301,11 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 		}else{
 			vipGroupApplyBaseInfoDto.setStatus(VipGroupStatusEnum.APPLYING);
 		}
+		if(CollectionUtils.isEmpty(vscps)){
+			for (Integer canBuyStudentId : canBuyStudentIds) {
+				vscps.add(new VipGroupStudentCoursePrice(canBuyStudentId, vipGroupApplyBaseInfoDto.getOfflineClassesUnitPrice(), vipGroupApplyBaseInfoDto.getOfflineClassesUnitPrice(), vipGroupApplyBaseInfoDto.getTotalPrice()));
+			}
+		}
         Teacher teacher = teacherService.get(vipGroupApplyBaseInfoDto.getUserId());
 		if(Objects.isNull(teacher)){
 		    throw new BizException("教师不存在");
@@ -360,6 +342,9 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 		vipGroupDao.insert(vipGroupApplyBaseInfoDto);
 
+		vscps.forEach(e->e.setVipGroupId(vipGroupApplyBaseInfoDto.getId()));
+		vipGroupStudentCoursePriceDao.batchInsert(vscps);
+
         vipGroup.getVipGroupApplyBaseInfo().setId(vipGroupApplyBaseInfoDto.getId());
 
 		//创建班级信息
@@ -948,9 +933,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
     @Override
     public <K extends VipGroup> Map<String,BigDecimal> countVipGroupPredictFee(K vipGroup,
-																			   Integer teacherId,
-																			   BigDecimal onlineClassesUnitPrice,
-																			   BigDecimal offlineClassesUnitPrice){
+																			   Integer teacherId){
 
 		if(Objects.isNull(teacherId)){
 			throw new BizException("请指定教师");
@@ -962,7 +945,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 		VipGroupCategory vipGroupCategory = vipGroupCategoryDao.get(vipGroup.getVipGroupCategoryId().intValue());
 		if(Objects.isNull(vipGroupCategory)){
-			throw new BizException("未找到课程形式");
+			throw new BizException("课程形式不存在");
 		}
 
 		TeacherDefaultVipGroupSalary teacherDefaultVipGroupSalary = teacherDefaultVipGroupSalaryDao.findByTeacherAndCategory(teacherId,
@@ -972,172 +955,181 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			throw new BizException("请设置教师课酬");
 		}
 
-		if(Objects.isNull(vipGroup.getVipGroupActivityId())){
-			throw new BizException("请指定活动方案");
-		}
-
-		VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId().intValue());
-
-		if(Objects.isNull(vipGroupActivity)){
-			throw new BizException("指定的活动方案不存在");
+		if(Objects.isNull(teacherDefaultVipGroupSalary)||Objects.isNull(teacherDefaultVipGroupSalary.getOfflineClassesSalary())){
+			throw new BizException("请设置教师VIP课课酬");
 		}
 
-		VipGroupSalarySettlementDto vipGroupSalarySettlementDto = JSON.parseObject(vipGroupActivity.getSalarySettlementJson(), VipGroupSalarySettlementDto.class);
-
-		if(Objects.isNull(vipGroupSalarySettlementDto)){
-			throw new BizException("课酬结算方案错误");
-		}
+		VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId());
 
 		Map<String,BigDecimal> results=new HashMap<>(1);
 
-		BigDecimal offlineClassNum=new BigDecimal(vipGroup.getOfflineClassesNum());
-		BigDecimal onlineClassNum=new BigDecimal(vipGroup.getOnlineClassesNum());
-		onlineClassesUnitPrice=Objects.isNull(onlineClassesUnitPrice)?vipGroup.getOnlineClassesUnitPrice():onlineClassesUnitPrice;
-		if(Objects.isNull(onlineClassesUnitPrice)){
-			onlineClassesUnitPrice = BigDecimal.ZERO;
-		}
-		BigDecimal onlineVipGroupCharge = onlineClassesUnitPrice.multiply(onlineClassNum);
-		offlineClassesUnitPrice=Objects.isNull(offlineClassesUnitPrice)?vipGroup.getOfflineClassesUnitPrice():offlineClassesUnitPrice;
-		if(Objects.isNull(offlineClassesUnitPrice)){
-			offlineClassesUnitPrice = BigDecimal.ZERO;
+		int normalStudentNum = 0;
+		if(Objects.nonNull(vipGroup.getId())){
+			normalStudentNum = classGroupStudentMapperDao.countGroupNormalStudentNum(GroupType.VIP, vipGroup.getId().toString());
 		}
-		BigDecimal offlineVipGroupCharge = offlineClassesUnitPrice.multiply(offlineClassNum);
-		BigDecimal totalClassNum=offlineClassNum.add(onlineClassNum);
-		BigDecimal teacherOnlineSalary=null,teacherOfflineSalary=null;
 
-		if(Objects.isNull(vipGroupActivity.getType())){
-			throw new BizException("此活动未设置活动类型");
-		}
+		if(Objects.nonNull(vipGroupActivity)){
+			VipGroupSalarySettlementDto vipGroupSalarySettlementDto = JSON.parseObject(vipGroupActivity.getSalarySettlementJson(), VipGroupSalarySettlementDto.class);
 
-		//课程购买费用计算
-		BigDecimal totalPrice;
-		switch (vipGroupActivity.getType()){
-			case BASE_ACTIVITY:
-				totalPrice=onlineVipGroupCharge.add(offlineVipGroupCharge);
-				break;
-			case DISCOUNT:
-				BigDecimal discount=new BigDecimal(vipGroupActivity.getAttribute1());
-				totalPrice=onlineVipGroupCharge.add(offlineVipGroupCharge);
-				totalPrice=totalPrice.multiply(discount).divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
-				break;
-			case GIVE_CLASS:
-				if(totalClassNum.compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))<0){
+			if(Objects.isNull(vipGroupSalarySettlementDto)){
+				throw new BizException("课酬结算方案错误");
+			}
 
-				}else if(vipGroup.getGiveTeachMode()==TeachModeEnum.OFFLINE){
-					if(totalClassNum.compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))>-1){
-						offlineClassNum=offlineClassNum.subtract(new BigDecimal(vipGroupActivity.getAttribute2()));
-					}
-					offlineVipGroupCharge = offlineClassesUnitPrice.multiply(offlineClassNum);
-				}else if(vipGroup.getGiveTeachMode()==TeachModeEnum.ONLINE){
-					if(totalClassNum.compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))>-1){
-						onlineClassNum=onlineClassNum.subtract(new BigDecimal(vipGroupActivity.getAttribute2()));
-					}
-					onlineVipGroupCharge = onlineClassesUnitPrice.multiply(onlineClassNum);
-				}else{
-					throw new BizException("请指定赠送课程类型!");
-				}
-				totalPrice=onlineVipGroupCharge.add(offlineVipGroupCharge);
-				break;
-			default:
-				throw new BizException("活动类型错误!");
-		}
+			BigDecimal offlineClassNum=new BigDecimal(vipGroup.getOfflineClassesNum());
+			BigDecimal onlineClassNum=new BigDecimal(vipGroup.getOnlineClassesNum());
+			BigDecimal onlineClassesUnitPrice=vipGroup.getOnlineClassesUnitPrice();
+			if(Objects.isNull(onlineClassesUnitPrice)){
+				throw new BizException("课程单价异常");
+			}
+			BigDecimal onlineVipGroupCharge = onlineClassesUnitPrice.multiply(onlineClassNum);
 
-		results.put("totalPrice",totalPrice.setScale(0,BigDecimal.ROUND_CEILING));
+			BigDecimal offlineClassesUnitPrice=vipGroup.getOfflineClassesUnitPrice();
+			if(Objects.isNull(offlineClassesUnitPrice)){
+				throw new BizException("课程单价异常");
+			}
+			BigDecimal offlineVipGroupCharge = offlineClassesUnitPrice.multiply(offlineClassNum);
+			BigDecimal totalClassNum=offlineClassNum.add(onlineClassNum);
+			BigDecimal teacherOnlineSalary=null,teacherOfflineSalary=null;
+
+			//课程购买费用计算
+			BigDecimal totalPrice;
+			switch (vipGroupActivity.getType()){
+				case BASE_ACTIVITY:
+					totalPrice=onlineVipGroupCharge.add(offlineVipGroupCharge);
+					break;
+				case DISCOUNT:
+					BigDecimal discount=new BigDecimal(vipGroupActivity.getAttribute1());
+					totalPrice=onlineVipGroupCharge.add(offlineVipGroupCharge);
+					totalPrice=totalPrice.multiply(discount).divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
+					break;
+				case GIVE_CLASS:
+					if(totalClassNum.compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))<0){
+
+					}else if(vipGroup.getGiveTeachMode()==TeachModeEnum.OFFLINE){
+						if(totalClassNum.compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))>-1){
+							offlineClassNum=offlineClassNum.subtract(new BigDecimal(vipGroupActivity.getAttribute2()));
+						}
+						offlineVipGroupCharge = offlineClassesUnitPrice.multiply(offlineClassNum);
+					}else if(vipGroup.getGiveTeachMode()==TeachModeEnum.ONLINE){
+						if(totalClassNum.compareTo(new BigDecimal(vipGroupActivity.getAttribute1()))>-1){
+							onlineClassNum=onlineClassNum.subtract(new BigDecimal(vipGroupActivity.getAttribute2()));
+						}
+						onlineVipGroupCharge = onlineClassesUnitPrice.multiply(onlineClassNum);
+					}else{
+						throw new BizException("请指定赠送课程类型!");
+					}
+					totalPrice=onlineVipGroupCharge.add(offlineVipGroupCharge);
+					break;
+				default:
+					throw new BizException("活动类型错误!");
+			}
 
-		int normalStudentNum = 0;
-		if(Objects.nonNull(vipGroup.getId())){
-			normalStudentNum = classGroupStudentMapperDao.countGroupNormalStudentNum(GroupType.VIP, vipGroup.getId().toString());
-		}
+			results.put("totalPrice",totalPrice.setScale(0,BigDecimal.ROUND_CEILING));
 
-//		if(JobNatureEnum.PART_TIME.equals(teacher.getJobNature())){
-//			BigDecimal ots = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
-//			BigDecimal ofts = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
-//			if(normalStudentNum>0&&normalStudentNum!=vipGroupCategory.getStudentNum()){
-//				ots = ots.divide(new BigDecimal(vipGroupCategory.getStudentNum()),CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
-//				ofts = ofts.divide(new BigDecimal(vipGroupCategory.getStudentNum()),CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
-//			}
-//
-//			results.put("onlineTeacherSalary", ots);
-//			results.put("offlineTeacherSalary", ofts);
-//			return results;
-//		}
+			if(vipGroup instanceof VipGroupApplyBaseInfoDto && !CollectionUtils.isEmpty(((VipGroupApplyBaseInfoDto)vipGroup).getVipGroupStudentCoursePrices())){
+				for (VipGroupStudentCoursePrice vscp : ((VipGroupApplyBaseInfoDto)vipGroup).getVipGroupStudentCoursePrices()) {
+					if(Objects.isNull(vscp.getOnlineClassesUnitPrice())||Objects.isNull(vscp.getOfflineClassesUnitPrice())){
+						throw new BizException("请设置课程单价");
+					}
+					vscp.setPaymentPrice(vscp.getOfflineClassesUnitPrice().multiply(new BigDecimal(vipGroup.getOfflineClassesNum())).add(vscp.getOnlineClassesUnitPrice().multiply(new BigDecimal(vipGroup.getOnlineClassesNum()))));
+					vipGroup.setTotalPrice(vipGroup.getTotalPrice().add(vscp.getPaymentPrice()));
+					results.put(vscp.getStudentId().toString(), vscp.getPaymentPrice());
+				}
+			}
 
-		//教师课酬线上单课酬计算
-		if(Objects.nonNull(vipGroupSalarySettlementDto.getOnlineSalarySettlement())){
-			if(Objects.isNull(teacherOnlineSalary)){
-				switch (vipGroupSalarySettlementDto.getOnlineSalarySettlement().getSalarySettlementType()){
-					case TEACHER_DEFAULT:
-						if(Objects.isNull(teacherDefaultVipGroupSalary)||Objects.isNull(teacherDefaultVipGroupSalary.getOfflineClassesSalary())){
-							teacherOnlineSalary=new BigDecimal(0);
-						}else{
+			//教师课酬线上单课酬计算
+			if(Objects.nonNull(vipGroupSalarySettlementDto.getOnlineSalarySettlement())){
+				if(Objects.isNull(teacherOnlineSalary)){
+					switch (vipGroupSalarySettlementDto.getOnlineSalarySettlement().getSalarySettlementType()){
+						case TEACHER_DEFAULT:
 							teacherOnlineSalary=teacherDefaultVipGroupSalary.getOfflineClassesSalary();
-						}
-						results.put("onlineTeacherSalary",teacherOnlineSalary.setScale(0, BigDecimal.ROUND_HALF_UP));
-						break;
-					case RATIO_DISCOUNT:
-						results.put("onlineTeacherSalary",totalPrice.multiply(new BigDecimal(vipGroupCategory.getStudentNum()))
-								.divide(totalClassNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN)
-								.multiply(vipGroupSalarySettlementDto.getOnlineSalarySettlement().getSettlementValue())
-								.divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN)
-								.setScale(0,BigDecimal.ROUND_HALF_UP));
+							results.put("onlineTeacherSalary",teacherOnlineSalary.setScale(0, BigDecimal.ROUND_HALF_UP));
+							break;
+						case RATIO_DISCOUNT:
+							results.put("onlineTeacherSalary",totalPrice.multiply(new BigDecimal(vipGroupCategory.getStudentNum()))
+									.divide(totalClassNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN)
+									.multiply(vipGroupSalarySettlementDto.getOnlineSalarySettlement().getSettlementValue())
+									.divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN)
+									.setScale(0,BigDecimal.ROUND_HALF_UP));
 
-						break;
-					case FIXED_SALARY:
-						results.put("onlineTeacherSalary",vipGroupSalarySettlementDto.getOnlineSalarySettlement().getSettlementValue().setScale(0, BigDecimal.ROUND_HALF_UP));
-						break;
-					default:
-						throw new BizException("未指定课酬结算标准!");
-				}
+							break;
+						case FIXED_SALARY:
+							results.put("onlineTeacherSalary",vipGroupSalarySettlementDto.getOnlineSalarySettlement().getSettlementValue().setScale(0, BigDecimal.ROUND_HALF_UP));
+							break;
+						default:
+							throw new BizException("未指定课酬结算标准!");
+					}
 
+				}
 			}
-		}
 
-		//教师线下单课酬计算
-		if(Objects.nonNull(vipGroupSalarySettlementDto.getOfflineSalarySettlement())){
-			if(Objects.isNull(teacherOfflineSalary)){
-				switch (vipGroupSalarySettlementDto.getOfflineSalarySettlement().getSalarySettlementType()){
-					case TEACHER_DEFAULT:
-						if(Objects.isNull(teacherDefaultVipGroupSalary)||Objects.isNull(teacherDefaultVipGroupSalary.getOfflineClassesSalary())){
-							teacherOfflineSalary=new BigDecimal(0);
-						}else{
+			//教师线下单课酬计算
+			if(Objects.nonNull(vipGroupSalarySettlementDto.getOfflineSalarySettlement())){
+				if(Objects.isNull(teacherOfflineSalary)){
+					switch (vipGroupSalarySettlementDto.getOfflineSalarySettlement().getSalarySettlementType()){
+						case TEACHER_DEFAULT:
 							teacherOfflineSalary=teacherDefaultVipGroupSalary.getOfflineClassesSalary();
-						}
-						results.put("offlineTeacherSalary",teacherOfflineSalary.setScale(0, BigDecimal.ROUND_HALF_UP));
-						break;
-					case RATIO_DISCOUNT:
-						results.put("offlineTeacherSalary",totalPrice.multiply(new BigDecimal(vipGroupCategory.getStudentNum())).divide(totalClassNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(vipGroupSalarySettlementDto.getOfflineSalarySettlement().getSettlementValue()).divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).setScale(0,BigDecimal.ROUND_HALF_UP));
+							results.put("offlineTeacherSalary",teacherOfflineSalary.setScale(0, BigDecimal.ROUND_HALF_UP));
+							break;
+						case RATIO_DISCOUNT:
+							results.put("offlineTeacherSalary",totalPrice.multiply(new BigDecimal(vipGroupCategory.getStudentNum())).divide(totalClassNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(vipGroupSalarySettlementDto.getOfflineSalarySettlement().getSettlementValue()).divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).setScale(0,BigDecimal.ROUND_HALF_UP));
 
-						break;
-					case FIXED_SALARY:
-						results.put("offlineTeacherSalary",vipGroupSalarySettlementDto.getOfflineSalarySettlement().getSettlementValue().setScale(0, BigDecimal.ROUND_HALF_UP));
-						break;
-					default:
-						throw new BizException("未指定课酬结算标准!");
+							break;
+						case FIXED_SALARY:
+							results.put("offlineTeacherSalary",vipGroupSalarySettlementDto.getOfflineSalarySettlement().getSettlementValue().setScale(0, BigDecimal.ROUND_HALF_UP));
+							break;
+						default:
+							throw new BizException("未指定课酬结算标准!");
+					}
 				}
 			}
-		}
 
-		BigDecimal ots = results.get("onlineTeacherSalary");
-		if(Objects.isNull(ots)){
-			ots = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
-		}
-		if(Objects.isNull(ots)){
-			ots = BigDecimal.ZERO;
-		}
-		BigDecimal ofts = results.get("offlineTeacherSalary");
-		if(Objects.isNull(ofts)){
-			ofts = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
-		}
-		if(Objects.isNull(ofts)){
-			ofts = BigDecimal.ZERO;
+			BigDecimal ots = results.get("onlineTeacherSalary");
+			if(Objects.isNull(ots)){
+				ots = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
+			}
+			if(Objects.isNull(ots)){
+				ots = BigDecimal.ZERO;
+			}
+			BigDecimal ofts = results.get("offlineTeacherSalary");
+			if(Objects.isNull(ofts)){
+				ofts = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
+			}
+			if(Objects.isNull(ofts)){
+				ofts = BigDecimal.ZERO;
+			}
+			if(Objects.nonNull(vipGroup.getStatus())&&normalStudentNum!=vipGroupCategory.getStudentNum()){
+				ots = ots.divide(new BigDecimal(vipGroupCategory.getStudentNum()),CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
+				ofts = ofts.divide(new BigDecimal(vipGroupCategory.getStudentNum()),CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
+			}
+
+			results.put("onlineTeacherSalary", ots);
+			results.put("offlineTeacherSalary", ofts);
 		}
-		if(Objects.nonNull(vipGroup.getStatus())&&normalStudentNum!=vipGroupCategory.getStudentNum()){
-			ots = ots.divide(new BigDecimal(vipGroupCategory.getStudentNum()),CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
-			ofts = ofts.divide(new BigDecimal(vipGroupCategory.getStudentNum()),CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
+
+		if(Objects.isNull(vipGroupActivity)||vipGroupCategory.getMusicTheory()){
+			BigDecimal ots = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
+			BigDecimal ofts = teacherDefaultVipGroupSalary.getOfflineClassesSalary();
+			if(Objects.nonNull(vipGroup.getStatus())&&normalStudentNum!=vipGroupCategory.getStudentNum()){
+				ots = ots.multiply(new BigDecimal(normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
+				ofts = ofts.multiply(new BigDecimal(normalStudentNum>5?5:normalStudentNum)).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_HALF_UP);
+			}
+			results.put("totalPrice",vipGroup.getTotalPrice());
+			results.put("onlineTeacherSalary",ots);
+			results.put("offlineTeacherSalary",ofts);
 		}
 
-		results.put("onlineTeacherSalary", ots);
-		results.put("offlineTeacherSalary", ofts);
+		if(vipGroup instanceof VipGroupApplyBaseInfoDto&&!CollectionUtils.isEmpty(((VipGroupApplyBaseInfoDto)vipGroup).getVipGroupStudentCoursePrices())){
+			vipGroup.setTotalPrice(new BigDecimal(0));
+			for (VipGroupStudentCoursePrice vscp : ((VipGroupApplyBaseInfoDto)vipGroup).getVipGroupStudentCoursePrices()) {
+				if(Objects.isNull(vscp.getOnlineClassesUnitPrice())||Objects.isNull(vscp.getOfflineClassesUnitPrice())){
+					throw new BizException("请设置课程单价");
+				}
+				vscp.setPaymentPrice(vscp.getOfflineClassesUnitPrice().multiply(new BigDecimal(vipGroup.getOfflineClassesNum())).add(vscp.getOnlineClassesUnitPrice().multiply(new BigDecimal(vipGroup.getOnlineClassesNum()))));
+				vipGroup.setTotalPrice(vipGroup.getTotalPrice().add(vscp.getPaymentPrice()));
+				results.put(vscp.getStudentId().toString(), vscp.getPaymentPrice());
+			}
+		}
 
         return results;
     }
@@ -2085,7 +2077,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 				classGroupTeacherMapperDao.insert(classGroupTeacherMapper);
 			}
 
-			Map<String, BigDecimal> salaryMap = countVipGroupPredictFee(vipGroup, vipGroup.getUserId(), null, null);
+			Map<String, BigDecimal> salaryMap = countVipGroupPredictFee(vipGroup, vipGroup.getUserId());
 
 			//创建老师单节课课酬信息
 			courseScheduleTeacherSalaryService.createCourseScheduleTeacherVipSalary(vipGroup,
@@ -2736,7 +2728,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 		courseScheduleService.batchAddCourseSchedule(vipGroupApplyDto.getCourseSchedules());
 
-		Map<String, BigDecimal> map = countVipGroupPredictFee(vipGroup, vipGroup.getUserId(), null, null);
+		Map<String, BigDecimal> map = countVipGroupPredictFee(vipGroup, vipGroup.getUserId());
 
 		BigDecimal teacherSalary=BigDecimal.ZERO;
 
@@ -2806,7 +2798,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 
 	@Override
 	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-	public void addVipGroupStudents(Long vipGroupId, List<Integer> studentIds) {
+	public void addVipGroupStudents(Long vipGroupId, List<Integer> studentIds, Map<Integer, VipGroupStudentCoursePrice> studentCoursePriceMap) {
 		if(CollectionUtils.isEmpty(studentIds)){
 			throw new BizException("请选择学生");
 		}
@@ -2857,7 +2849,7 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			if(courseNum==0){
 				courseScheduleService.batchAddCourseSchedule(courseSchedules);
 
-				Map<String, BigDecimal> salaryMap = countVipGroupPredictFee(vipGroup, vipGroup.getUserId(), null, null);
+				Map<String, BigDecimal> salaryMap = countVipGroupPredictFee(vipGroup, vipGroup.getUserId());
 
 				//创建老师单节课课酬信息
 				courseScheduleTeacherSalaryService.createCourseScheduleTeacherVipSalary(vipGroup,
@@ -2933,7 +2925,6 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId().intValue());
 		}
 
-		BigDecimal surplusCourseNum = new BigDecimal(surplusCourses.size());
 		BigDecimal surplusCoursesPrice=new BigDecimal(0);
 		boolean hasGiveClass=false;
 		int onlineCourseTimes=0,
@@ -2947,7 +2938,6 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			&&surplusCourses.size()>=Integer.parseInt(vipGroupActivity.getAttribute1())){
 			hasGiveClass=true;
 			giveClassTimes=Integer.parseInt(vipGroupActivity.getAttribute2());
-			surplusCourseNum=surplusCourseNum.subtract(new BigDecimal(giveClassTimes));
 			Map<TeachModeEnum, List<CourseSchedule>> teachModeCourseMap = surplusCourses.stream()
 					.collect(Collectors.groupingBy(CourseSchedule::getTeachMode));
 			List<CourseSchedule> onlineCourses=teachModeCourseMap.get(TeachModeEnum.ONLINE);
@@ -2959,48 +2949,56 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 				offlineCourseTotalTimes=offlineCourses.size();
 			}
 		}
-		for (int i=0;i<surplusCourses.size();i++) {
-			CourseSchedule courseSchedule=surplusCourses.get(i);
-			if(courseSchedule.getTeachMode().equals(TeachModeEnum.OFFLINE)){
-				offlineCourseTimes+=1;
-			}else if(courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE)){
-				onlineCourseTimes+=1;
-			}
-			if(hasGiveClass
-					&&vipGroup.getGiveTeachMode() == courseSchedule.getTeachMode()){
-				if(courseSchedule.getTeachMode().equals(TeachModeEnum.OFFLINE)
-					&&offlineCourseTimes>(offlineCourseTotalTimes-giveClassTimes)){
-					continue;
-				}
 
+		//生成学生单课缴费信息
+		for (Integer studentId:studentIds) {
+			offlineCourseTimes=0;
+			onlineCourseTimes=0;
+			surplusCoursesPrice=new BigDecimal(0);
+
+			if(studentCoursePriceMap.containsKey(studentId)){
+				VipGroupStudentCoursePrice vipGroupStudentCoursePrice = studentCoursePriceMap.get(studentId);
+				vipGroup.setOfflineClassesUnitPrice(vipGroupStudentCoursePrice.getOfflineClassesUnitPrice());
+				vipGroup.setOnlineClassesUnitPrice(vipGroupStudentCoursePrice.getOnlineClassesUnitPrice());
+			}
+
+
+			for (int i=0;i<surplusCourses.size();i++) {
+				CourseSchedule courseSchedule=surplusCourses.get(i);
+				if(courseSchedule.getTeachMode().equals(TeachModeEnum.OFFLINE)){
+					offlineCourseTimes+=1;
+				}else if(courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE)){
+					onlineCourseTimes+=1;
+				}
 				if(hasGiveClass
 						&&vipGroup.getGiveTeachMode() == courseSchedule.getTeachMode()){
-					if(courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE)
-							&&onlineCourseTimes>(onlineCourseTotalTimes-giveClassTimes)){
+					if(courseSchedule.getTeachMode().equals(TeachModeEnum.OFFLINE)
+							&&offlineCourseTimes>(offlineCourseTotalTimes-giveClassTimes)){
 						continue;
 					}
+
+					if(hasGiveClass
+							&&vipGroup.getGiveTeachMode() == courseSchedule.getTeachMode()){
+						if(courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE)
+								&&onlineCourseTimes>(onlineCourseTotalTimes-giveClassTimes)){
+							continue;
+						}
+					}
+				}
+				if(courseSchedule.getTeachMode().equals(TeachModeEnum.OFFLINE)){
+					surplusCoursesPrice=surplusCoursesPrice.add(vipGroup.getOfflineClassesUnitPrice());
+				}else if(courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE)){
+					surplusCoursesPrice=surplusCoursesPrice.add(vipGroup.getOnlineClassesUnitPrice());
 				}
 			}
-			if(courseSchedule.getTeachMode().equals(TeachModeEnum.OFFLINE)){
-				surplusCoursesPrice=surplusCoursesPrice.add(vipGroup.getOfflineClassesUnitPrice());
-			}else if(courseSchedule.getTeachMode().equals(TeachModeEnum.ONLINE)){
-				surplusCoursesPrice=surplusCoursesPrice.add(vipGroup.getOnlineClassesUnitPrice());
-			}
-		}
 
-        BigDecimal discount=null;
-		if(Objects.nonNull(vipGroupActivity)&&vipGroupActivity.getType().equals(VipGroupActivityTypeEnum.DISCOUNT)){
-            discount=new BigDecimal(vipGroupActivity.getAttribute1()).divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
-            surplusCoursesPrice=surplusCoursesPrice.multiply(discount).setScale(CommonConstants.DECIMAL_FINAL_PLACE,BigDecimal.ROUND_HALF_UP);
-        }
-
-		//生成学生单课缴费信息
-		for (Integer studentId:studentIds) {
-			SysUserCashAccount sysUserCashAccount = sysUserCashAccountService.get(studentId);
-			if(sysUserCashAccount.getCourseBalance().compareTo(surplusCoursesPrice)<0){
-				throw new BizException("存在课程余额不足的学生");
+			BigDecimal discount=null;
+			if(Objects.nonNull(vipGroupActivity)&&vipGroupActivity.getType().equals(VipGroupActivityTypeEnum.DISCOUNT)){
+				discount=new BigDecimal(vipGroupActivity.getAttribute1()).divide(new BigDecimal(100), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
+				surplusCoursesPrice=surplusCoursesPrice.multiply(discount).setScale(CommonConstants.DECIMAL_FINAL_PLACE,BigDecimal.ROUND_HALF_UP);
 			}
-//			courseScheduleStudentPaymentService.createCourseScheduleStudentPaymentForVipGroup(vipGroupId,studentId);
+
+			sysUserCashAccountService.subtractFromCourseBalanceAndBalance(studentId,surplusCoursesPrice,PlatformCashAccountDetailTypeEnum.PAY_FEE, "后台添加学员扣减账户金额");
 
 			List<CourseScheduleStudentPayment> courseScheduleStudentPayments=new ArrayList<>();
 
@@ -3046,8 +3044,6 @@ public class VipGroupServiceImpl extends BaseServiceImpl<Long, VipGroup> impleme
 			}
 			courseScheduleStudentPaymentDao.batchInsert(courseScheduleStudentPayments);
 
-			sysUserCashAccountService.updateCourseBalance(studentId,sysUserCashAccount.getCourseBalance().subtract(surplusCoursesPrice),PlatformCashAccountDetailTypeEnum.PAY_FEE, surplusCoursesPrice.negate(), "后台添加学员扣除课程余额");
-
 			//创建班级学生关联记录
 			ClassGroupStudentMapper classGroupStudentMapper;
 

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

@@ -0,0 +1,22 @@
+package com.ym.mec.biz.service.impl;
+
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice;
+import com.ym.mec.biz.service.VipGroupStudentCoursePriceService;
+import com.ym.mec.biz.dal.dao.VipGroupStudentCoursePriceDao;
+import org.springframework.stereotype.Service;
+
+@Service
+public class VipGroupStudentCoursePriceServiceImpl extends BaseServiceImpl<Long, VipGroupStudentCoursePrice> implements VipGroupStudentCoursePriceService {
+	
+	@Autowired
+	private VipGroupStudentCoursePriceDao vipGroupStudentCoursePriceDao;
+
+	@Override
+	public BaseDAO<Long, VipGroupStudentCoursePrice> getDAO() {
+		return vipGroupStudentCoursePriceDao;
+	}
+	
+}

+ 14 - 0
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -3072,6 +3072,13 @@
         </foreach>
     </update>
 
+    <update id="cleanCoursMergeId">
+        UPDATE course_schedule SET new_course_id_=NULL WHERE id_ IN
+        <foreach collection="courseIds" item="courseId" separator="," open="(" close=")">
+            #{courseId}
+        </foreach>
+    </update>
+
     <select id="getStudentCourseScheduleNum" resultMap="com.ym.mec.biz.dal.dao.PracticeGroupDao.courseGroupExport">
         SELECT COUNT(*) total_class_times_,cssp.user_id_ student_id_
         FROM course_schedule_student_payment cssp
@@ -3379,6 +3386,13 @@
     <select id="countCourseMergeTime" resultType="int">
         SELECT COUNT(id_) FROM course_schedule WHERE new_course_id_=#{courseId}
     </select>
+
+    <select id="findByMainMergeCourse" resultMap="CourseSchedule">
+        SELECT
+        <include refid="resultSql"/>
+        FROM course_schedule cs WHERE new_course_id_=#{mainMergeCourseId}
+    </select>
+
     <select id="querySubCourseNumMap" resultType="java.util.Map">
         SELECT cs.type_ 'key',COUNT(CASE WHEN (CONCAT(cs.class_date_,' ',cs.start_class_time_) > NOW()) THEN 1 ELSE NULL END) 'value' FROM course_schedule cs
         WHERE cs.class_group_id_ = #{classGroupId}

+ 19 - 9
mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

@@ -20,6 +20,7 @@
 		<result column="settlement_time_" property="settlementTime" />
 		<result column="class_group_id_" property="classGroupId" />
 		<result column="batch_no_" property="batchNo"/>
+		<result column="be_merged_" property="beMerged"/>
 	</resultMap>
 
 	<resultMap type="com.ym.mec.biz.dal.dto.StudentCourseTimesDto" id="studentCourseTimesDto">
@@ -47,23 +48,18 @@
 
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		<!--
-		<selectKey resultClass="int" keyProperty="id" >
-		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL
-		</selectKey>
-		-->
 		INSERT INTO course_schedule_student_payment (id_,group_type_,music_group_id_,course_schedule_id_,user_id_,
-			original_price_,expect_price_,actual_price_,create_time_,update_time_,settlement_time_,class_group_id_,batch_no_)
+			original_price_,expect_price_,actual_price_,create_time_,update_time_,settlement_time_,class_group_id_,batch_no_,be_merged_)
 		VALUES(#{id},#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{courseScheduleId},#{userId},
-			#{originalPrice},#{expectPrice},#{actualPrice},#{createTime},NOW(),#{settlementTime},#{classGroupId},#{batchNo})
+			#{originalPrice},#{expectPrice},#{actualPrice},#{createTime},NOW(),#{settlementTime},#{classGroupId},#{batchNo},#{beMerged})
 	</insert>
     <insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id_">
 		INSERT INTO course_schedule_student_payment (id_,group_type_,music_group_id_,course_schedule_id_,user_id_,expect_price_,
-				original_price_,actual_price_,create_time_,update_time_,settlement_time_,class_group_id_,batch_no_)
+				original_price_,actual_price_,create_time_,update_time_,settlement_time_,class_group_id_,batch_no_,be_merged_)
 		VALUE
 		<foreach collection="list" item="data" separator=",">
 			(#{data.id},#{data.groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{data.musicGroupId},#{data.courseScheduleId},#{data.userId},#{data.expectPrice},
-			#{data.originalPrice},#{data.actualPrice},now(),now(),#{data.settlementTime},#{data.classGroupId},#{data.batchNo})
+			#{data.originalPrice},#{data.actualPrice},now(),now(),#{data.settlementTime},#{data.classGroupId},#{data.batchNo},#{data.beMerged})
 		</foreach>
     </insert>
 
@@ -104,6 +100,9 @@
 			<if test="originalPrice != null">
 				original_price_ = #{originalPrice},
 			</if>
+			<if test="beMerged != null">
+				be_merged_ = #{beMerged},
+			</if>
 				update_time_ = NOW()
 		</set> WHERE id_ = #{id}
 	</update>
@@ -145,6 +144,9 @@
 				<if test="courseScheduleStudentPayment.originalPrice != null">
 					original_price_ = #{courseScheduleStudentPayment.originalPrice},
 				</if>
+				<if test="courseScheduleStudentPayment.beMerged != null">
+					be_merged_ = #{courseScheduleStudentPayment.beMerged},
+				</if>
 				update_time_ = NOW()
 			</set> WHERE id_ = #{courseScheduleStudentPayment.id}
 		</foreach>
@@ -632,6 +634,7 @@
 		WHERE
 			cssp.batch_no_ IS NOT NULL
 			AND cs.id_ IS NOT NULL
+			AND (cs.new_course_id_ IS NULL OR cs.new_course_id_=cs.id_)
 			AND ((cs.status_ IN ('OVER', 'UNDERWAY') AND (cssp.actual_price_ IS NULL OR cssp.actual_price_ &lt; cssp.expect_price_))
 			OR ( cs.status_ = 'NOT_START' AND cssp.actual_price_ IS NOT NULL AND cssp.actual_price_ &gt; 0))
 			<if test="groupIds!=null and groupIds.size()>0">
@@ -700,4 +703,11 @@
 		  AND (cs.del_flag_ != 1 OR cs.del_flag_ IS NULL)
 		ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_) DESC LIMIT 1
 	</select>
+
+	<select id="findByMainMergedCourse" resultMap="CourseScheduleStudentPayment">
+		SELECT cssp.*
+			FROM course_schedule_student_payment cssp
+			LEFT JOIN course_schedule cs ON cssp.course_schedule_id_=cs.id_
+		WHERE cs.new_course_id_=#{mainMergeCourseId}
+	</select>
 </mapper>

+ 6 - 3
mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml

@@ -274,7 +274,7 @@
 				AND su.lock_flag_ = 0
 			</if>
 		  	<if test="isDemission!=null">
-				AND (su.lock_flag_ = 1 OR t.demission_date_ IS NOT NULL)
+				AND (su.lock_flag_ = 1 OR t.demission_date_&lt;NOW())
 			</if>
 			AND t.organ_id_ IS NOT NULL
 			<if test="jobNature!=null">
@@ -342,7 +342,7 @@
 	<select id="getStudentConversionData" resultMap="IndexBaseMonthData">
 		SELECT
 			cs.organ_id_,
-			CONCAT( '2020-01', '-01' ) month_,
+			CONCAT( #{month}, '-01' ) month_,
 			COUNT( DISTINCT m.user_id_ ) total_num_,
 			COUNT( DISTINCT m.user_id_ ) activate_num_,
 			COUNT( DISTINCT m.user_id_ ) percent_
@@ -427,8 +427,11 @@
 			mg.del_flag_ = 0
 			AND mg.organ_id_ IS NOT NULL
 			AND mg.status_ = 'PROGRESS'
+			<if test="paymentStatus==null">
+				AND sr.music_group_status_ IN ('APPLY', 'NORMAL')
+			</if>
 			<if test="paymentStatus!=null">
-				AND sr.music_group_status_ = 'NORMAL'
+				AND sr.music_group_status_ IN ('NORMAL')
 				AND sr.payment_status_ = #{paymentStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
 			</if>
 			AND DATE_FORMAT( sr.create_time_, '%Y-%m' ) &lt;= #{month}

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

@@ -12,6 +12,7 @@
 		<result column="update_time_" property="updateTime" />
 		<result column="single_class_minutes_" property="singleClassMinutes" />
 		<result column="student_num_" property="studentNum" />
+		<result column="music_theory_" property="musicTheory" />
 		<result column="online_classes_unit_price_" property="onlineClassesUnitPrice" />
 		<result column="offline_classes_unit_price_" property="offlineClassesUnitPrice" />
 	</resultMap>
@@ -53,11 +54,9 @@
 	<!-- 向数据库增加一条记录 -->
 	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.VipGroupCategory"
 		useGeneratedKeys="true" keyColumn="id" keyProperty="id">
-		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
-			AS ID FROM DUAL </selectKey> -->
 		INSERT INTO vip_group_category
-		(id_,name_,del_flag_,create_time_,update_time_,single_class_minutes_,student_num_)
-		VALUES(#{id},#{name},#{delFlag},#{createTime},NOW(),#{singleClassMinutes},#{studentNum})
+		(id_,name_,del_flag_,create_time_,update_time_,single_class_minutes_,student_num_,music_theory_)
+		VALUES(#{id},#{name},#{delFlag},#{createTime},NOW(),#{singleClassMinutes},#{studentNum},#{musicTheory})
 	</insert>
 
 	<!-- 根据主键查询一条记录 -->
@@ -73,9 +72,6 @@
 			<if test="id != null">
 				id_ = #{id},
 			</if>
-			<if test="updateTime != null">
-				update_time_ = NOW(),
-			</if>
 			<if test="singleClassMinutes != null">
 				single_class_minutes_ = #{singleClassMinutes},
 			</if>
@@ -85,6 +81,10 @@
 			<if test="createTime != null">
 				create_time_ = #{createTime},
 			</if>
+			<if test="musicTheory != null">
+				music_theory_ = #{musicTheory},
+			</if>
+				update_time_ = NOW(),
 		</set>
 		WHERE id_ = #{id}
 	</update>

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

@@ -352,6 +352,7 @@
             AND status_='SUCCESS') = 0
             AND vg.organ_id_ = #{organId} AND IF(vg.student_id_list_ IS NULL,1,FIND_IN_SET(#{userId},
             vg.student_id_list_))
+            AND vg.vip_group_activity_id_ IS NOT NULL
             <if test="subjectId!=null">
                 AND FIND_IN_SET(#{subjectId},cg.subject_id_list_)
             </if>
@@ -552,10 +553,12 @@
 
     <select id="findHaveCourseBalanceStudents" resultMap="vipGroupStudentDto">
         SELECT
-        su.id_,
-        su.username_,
-        su.phone_,
-        suca.course_balance_
+            su.id_,
+            su.username_,
+            su.phone_,
+            suca.course_balance_,
+            suca.balance_ balance,
+            (suca.course_balance_+suca.balance_) allBalance
         FROM
         sys_user_cash_account suca
         LEFT JOIN sys_user su ON suca.user_id_=su.id_

+ 93 - 0
mec-biz/src/main/resources/config/mybatis/VipGroupStudentCoursePriceMapper.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+这个文件是自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<mapper namespace="com.ym.mec.biz.dal.dao.VipGroupStudentCoursePriceDao">
+
+	<resultMap type="com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice" id="VipGroupStudentCoursePrice">
+		<result column="id_" property="id" />
+		<result column="vip_group_id_" property="vipGroupId" />
+		<result column="student_id_" property="studentId" />
+		<result column="online_classes_unit_price_" property="onlineClassesUnitPrice" />
+		<result column="offline_classes_unit_price_" property="offlineClassesUnitPrice" />
+		<result column="payment_price_" property="paymentPrice" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="VipGroupStudentCoursePrice" >
+		SELECT * FROM vip_group_student_course_price WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="VipGroupStudentCoursePrice">
+		SELECT * FROM vip_group_student_course_price ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!--
+		<selectKey resultClass="int" keyProperty="id" > 
+		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
+		</selectKey>
+		-->
+		INSERT INTO vip_group_student_course_price (vip_group_id_,student_id_,online_classes_unit_price_,offline_classes_unit_price_,payment_price_)
+		VALUES(#{vipGroupId},#{studentId},#{onlineClassesUnitPrice},#{offlineClassesUnitPrice},#{paymentPrice})
+	</insert>
+
+	<insert id="batchInsert" parameterType="com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		INSERT INTO vip_group_student_course_price (vip_group_id_,student_id_,online_classes_unit_price_,offline_classes_unit_price_,payment_price_)
+		VALUE
+		<foreach collection="datas" item="data" separator=",">
+			(#{data.vipGroupId},#{data.studentId},#{data.onlineClassesUnitPrice},#{data.offlineClassesUnitPrice},#{data.paymentPrice})
+		</foreach>
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.ym.mec.biz.dal.entity.VipGroupStudentCoursePrice">
+		UPDATE vip_group_student_course_price <set>
+		<if test="vipGroupId != null">
+			vip_group_id_ = #{vipGroupId},
+		</if>
+		<if test="id != null">
+			id_ = #{id},
+		</if>
+		<if test="offlineClassesUnitPrice != null">
+			offline_classes_unit_price_ = #{offlineClassesUnitPrice},
+		</if>
+		<if test="onlineClassesUnitPrice != null">
+			online_classes_unit_price_ = #{onlineClassesUnitPrice},
+		</if>
+		<if test="studentId != null">
+			student_id_ = #{studentId},
+		</if>
+		<if test="paymentPrice != null">
+			payment_price_ = #{paymentPrice},
+		</if>
+	</set> WHERE id_ = #{id}
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete" >
+		DELETE FROM vip_group_student_course_price WHERE id_ = #{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="VipGroupStudentCoursePrice" parameterType="map">
+		SELECT * FROM vip_group_student_course_price ORDER BY id_ <include refid="global.limit"/>
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM vip_group_student_course_price
+	</select>
+
+    <select id="getVipGroupStudentCoursePrice" resultMap="VipGroupStudentCoursePrice">
+		SELECT * FROM vip_group_student_course_price
+		WHERE vip_group_id_=#{vipGroupId}
+		  <if test="studentId!=null">
+			  AND student_id_=#{studentId}
+		  </if>
+	</select>
+</mapper>

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

@@ -117,7 +117,7 @@ public class TeacherVipGroupController extends BaseController {
 		}
 
 		vipGroupService.createVipGroup(vipGroupApplyDto);
-		vipGroupService.addVipGroupStudents(vipGroupApplyDto.getVipGroupApplyBaseInfo().getId(), studentIds);
+		vipGroupService.addVipGroupStudents(vipGroupApplyDto.getVipGroupApplyBaseInfo().getId(), studentIds, new HashMap<>());
 		return succeed();
 	}
 

+ 15 - 0
mec-web/src/main/java/com/ym/mec/web/controller/CourseScheduleController.java

@@ -102,6 +102,9 @@ public class CourseScheduleController extends BaseController {
     @PostMapping("/batchAddCourseSchedule")
     @PreAuthorize("@pcs.hasPermissions('courseSchedule/batchAddCourseSchedule')")
     public Object batchAddCourseSchedule(@RequestBody CreateCourseScheduleDto createCourseScheduleDto){
+        if(true){
+            return failed("暂不支持此操作");
+        }
         if(Objects.isNull(createCourseScheduleDto.getMusicGroupID())){
             throw new BizException("请指定乐团");
         }
@@ -228,6 +231,18 @@ public class CourseScheduleController extends BaseController {
         return succeed();
     }
 
+    @ApiOperation(value = "合并课程还原")
+    @PreAuthorize("@pcs.hasPermissions('courseSchedule/mergeCourseSplit','system')")
+    @PostMapping(value = "/mergeCourseSplit",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public HttpResponseResult mergeCourseSplit(Long mainCourseId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        courseScheduleService.mergeCourseSplit(mainCourseId, sysUser.getId());
+        return succeed();
+    }
+
     @ApiOperation(value = "根据班级列表调整课程")
     @PreAuthorize("@pcs.hasPermissions('courseSchedule/classGroupTeacherAdjust','system')")
     @PostMapping(value = "/classGroupTeacherAdjust")

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

@@ -25,10 +25,12 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.ui.ModelMap;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Author Joburgess
@@ -166,18 +168,15 @@ public class VipGroupManageController extends BaseController {
     }
 
     @ApiOperation(value = "添加vip课学员")
-    @GetMapping(value = "/addVipGroupStudents")
+    @PostMapping(value = "/addVipGroupStudents")
     @PreAuthorize("@pcs.hasPermissions('vipGroupManage/addVipGroupStudents')")
-    public Object addVipGroupStudents(Long vipGroupId, String studentIds){
-        if(StringUtils.isBlank(studentIds)){
+    public Object addVipGroupStudents(@RequestBody List<VipGroupStudentCoursePrice> studentCoursePrices){
+        if(CollectionUtils.isEmpty(studentCoursePrices)){
             throw new BizException("请指定学员");
         }
-        List<Integer> ids=new ArrayList<>();
-        String[] split = studentIds.split(",");
-        for (String s : split) {
-            ids.add(Integer.parseInt(s));
-        }
-        vipGroupService.addVipGroupStudents(vipGroupId,ids);
+        List<Integer> ids=studentCoursePrices.stream().map(VipGroupStudentCoursePrice::getStudentId).collect(Collectors.toList());
+        Map<Integer, VipGroupStudentCoursePrice> studentCoursePriceMap = studentCoursePrices.stream().collect(Collectors.toMap(VipGroupStudentCoursePrice::getStudentId, v->v, (v1, v2)->v1));
+        vipGroupService.addVipGroupStudents(studentCoursePrices.get(0).getVipGroupId(), ids, studentCoursePriceMap);
         return succeed();
     }
 
@@ -299,11 +298,8 @@ public class VipGroupManageController extends BaseController {
     @ApiOperation("课酬总费用")
     @PostMapping("/getVipGroupCostCount")
     @PreAuthorize("@pcs.hasPermissions('vipGroupManage/getVipGroupCostCount')")
-    public Object getVipGroupCostCount(VipGroupApplyBaseInfoDto vipGroup){
-        Map results = vipGroupService.countVipGroupPredictFee(vipGroup,
-                vipGroup.getUserId(),
-                vipGroup.getOnlineClassesUnitPrice(),
-                vipGroup.getOfflineClassesUnitPrice());
+    public Object getVipGroupCostCount(@RequestBody VipGroupApplyBaseInfoDto vipGroup){
+        Map results = vipGroupService.countVipGroupPredictFee(vipGroup,vipGroup.getUserId());
         return succeed(results);
     }