|  | @@ -6,6 +6,7 @@ import static com.ym.mec.biz.dal.enums.GroupType.MUSIC;
 | 
	
		
			
				|  |  |  import static com.ym.mec.biz.dal.enums.GroupType.PRACTICE;
 | 
	
		
			
				|  |  |  import static com.ym.mec.biz.dal.enums.GroupType.VIP;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.lang.reflect.InvocationTargetException;
 | 
	
		
			
				|  |  |  import java.math.BigDecimal;
 | 
	
		
			
				|  |  |  import java.time.Duration;
 | 
	
		
			
				|  |  |  import java.time.Instant;
 | 
	
	
		
			
				|  | @@ -31,11 +32,13 @@ import com.ym.mec.biz.dal.dto.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.entity.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.service.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.service.IdGeneratorService;
 | 
	
		
			
				|  |  | +import org.apache.commons.beanutils.BeanUtils;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Propagation;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  | +import org.springframework.transaction.interceptor.TransactionAspectSupport;
 | 
	
		
			
				|  |  |  import org.springframework.util.CollectionUtils;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSON;
 | 
	
	
		
			
				|  | @@ -1659,7 +1662,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | -    public ClassGroup classGroupAdjust(List<ClassGroup4MixDto> classGroup4MixDtos) {
 | 
	
		
			
				|  |  | +    public ClassGroup classGroupAdjust(List<ClassGroup4MixDto> classGroup4MixDtos){
 | 
	
		
			
				|  |  |          Date date = new Date();
 | 
	
		
			
				|  |  |          String musicGroupId = classGroup4MixDtos.get(0).getMusicGroupId();
 | 
	
		
			
				|  |  |          MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
 | 
	
	
		
			
				|  | @@ -1669,6 +1672,14 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |          if (classGroup4MixDtos.get(0).getCourseTimes().compareTo(0) <= 0) {
 | 
	
		
			
				|  |  |              throw new BizException("排课次数必须大于0");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        List<ClassGroup4MixDto> classGroup4MixDtosBackup = new ArrayList<>();
 | 
	
		
			
				|  |  | +        if(StringUtils.isNotEmpty(classGroup4MixDtos.get(0).getClassCourseMinute())){
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                BeanUtils.copyProperties(classGroup4MixDtosBackup, classGroup4MixDtos);
 | 
	
		
			
				|  |  | +            } catch (Exception e) {
 | 
	
		
			
				|  |  | +                throw new BizException("拷贝课程信息异常");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          Date entryDate = DateUtil.stringToDate(sysConfigDao.findByParamName(SysConfigService.TEACHER_ENTRY_DATE).getParanValue(), "yyyy-MM-dd");
 | 
	
		
			
				|  |  |          Integer schoolId = musicGroup.getSchoolId();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1778,26 +1789,34 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |          List<CourseSchedule> courseScheduleList = new ArrayList<>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        String classCourseMinute = null;
 | 
	
		
			
				|  |  |          for (ClassGroup4MixDto classGroup4MixDto : classGroup4MixDtos) {
 | 
	
		
			
				|  |  | +            List<CourseSchedule> courseSchedules = new ArrayList<>();
 | 
	
		
			
				|  |  |              if(classGroup4MixDto.getCourseTimeDtoList() == null || classGroup4MixDto.getCourseTimeDtoList().size() == 0){
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              //5、插入班级排课信息
 | 
	
		
			
				|  |  |              LocalDateTime now = LocalDate.parse(classGroup4MixDto.getStartDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if(!courseTypeMinutesMap.containsKey(classGroup4MixDto.getCourseType().getCode())){
 | 
	
		
			
				|  |  | -                throw new BizException("{}课程类型暂无剩余课程时长", classGroup4MixDto.getCourseType().getMsg());
 | 
	
		
			
				|  |  | +            //是否是合班后的自动排课
 | 
	
		
			
				|  |  | +            classCourseMinute = classGroup4MixDto.getClassCourseMinute();
 | 
	
		
			
				|  |  | +            if(StringUtils.isNotEmpty(classCourseMinute)){
 | 
	
		
			
				|  |  | +                Map<String, Integer> classCourseMinuteMap = JSON.parseObject(classCourseMinute, Map.class);
 | 
	
		
			
				|  |  | +                classGroup4MixDto.setCourseTimes(classCourseMinuteMap.get(classGroup4MixDto.getCourseType().getCode()));
 | 
	
		
			
				|  |  | +            }else {
 | 
	
		
			
				|  |  | +                if(!courseTypeMinutesMap.containsKey(classGroup4MixDto.getCourseType().getCode())){
 | 
	
		
			
				|  |  | +                    throw new BizException("{}课程类型暂无剩余课程时长", classGroup4MixDto.getCourseType().getMsg());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                Integer totalMinutes = courseTypeMinutesMap.get(classGroup4MixDto.getCourseType().getCode());
 | 
	
		
			
				|  |  | +                long courseDuration = Duration.between(LocalDateTime.parse(classGroup4MixDto.getStartDate() + " " + classGroup4MixDto.getCourseTimeDtoList().get(0).getStartClassTime() + ":00", formatter),
 | 
	
		
			
				|  |  | +                        LocalDateTime.parse(classGroup4MixDto.getStartDate() + " " + classGroup4MixDto.getCourseTimeDtoList().get(0).getEndClassTime() + ":00", formatter))
 | 
	
		
			
				|  |  | +                        .toMinutes();
 | 
	
		
			
				|  |  | +                classGroup4MixDto.setCourseTimes(totalMinutes/(int)courseDuration);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if(classGroup4MixDto.getCourseTimes()<=0){
 | 
	
		
			
				|  |  | +                    throw new BizException("{}课程类型剩余课程时长不足", classGroup4MixDto.getCourseType().getMsg());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            Integer totalMinutes = courseTypeMinutesMap.get(classGroup4MixDto.getCourseType().getCode());
 | 
	
		
			
				|  |  | -            long courseDuration = Duration.between(LocalDateTime.parse(classGroup4MixDto.getStartDate() + " " + classGroup4MixDto.getCourseTimeDtoList().get(0).getStartClassTime() + ":00", formatter),
 | 
	
		
			
				|  |  | -                    LocalDateTime.parse(classGroup4MixDto.getStartDate() + " " + classGroup4MixDto.getCourseTimeDtoList().get(0).getEndClassTime() + ":00", formatter))
 | 
	
		
			
				|  |  | -                    .toMinutes();
 | 
	
		
			
				|  |  | -            classGroup4MixDto.setCourseTimes(totalMinutes/(int)courseDuration);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if(classGroup4MixDto.getCourseTimes()<=0){
 | 
	
		
			
				|  |  | -                throw new BizException("{}课程类型剩余课程时长不足", classGroup4MixDto.getCourseType().getMsg());
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              int times = 0;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1856,8 +1875,9 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      courseSchedule.setTeacherId(teacherId);
 | 
	
		
			
				|  |  |                      courseSchedule.setActualTeacherId(teacherId);
 | 
	
		
			
				|  |  | -                    courseScheduleDao.insert(courseSchedule);
 | 
	
		
			
				|  |  | +//                    courseScheduleDao.insert(courseSchedule);
 | 
	
		
			
				|  |  |                      courseScheduleList.add(courseSchedule);
 | 
	
		
			
				|  |  | +                    courseSchedules.add(courseSchedule);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      times++;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1960,9 +1980,26 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  now = now.plusDays(1);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            //自动排课,校验冲突
 | 
	
		
			
				|  |  | +            if(courseSchedules.size() > 0 && StringUtils.isNotEmpty(classCourseMinute)){
 | 
	
		
			
				|  |  | +                try {
 | 
	
		
			
				|  |  | +                    courseScheduleService.checkNewCourseSchedules(courseSchedules, false);
 | 
	
		
			
				|  |  | +                }catch (BizException e){
 | 
	
		
			
				|  |  | +                    e.printStackTrace();
 | 
	
		
			
				|  |  | +                }finally {
 | 
	
		
			
				|  |  | +                    //如果出现冲突
 | 
	
		
			
				|  |  | +                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
 | 
	
		
			
				|  |  | +                    //排课开始时间加一周
 | 
	
		
			
				|  |  | +                    ClassGroup4MixDto group4MixDto = classGroup4MixDtosBackup.get(0);
 | 
	
		
			
				|  |  | +                    Date stringToDate = DateUtil.stringToDate(group4MixDto.getStartDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT);
 | 
	
		
			
				|  |  | +                    group4MixDto.setStartDate(DateUtil.format(DateUtil.addDays(stringToDate, 7),DateUtil.ISO_EXPANDED_DATE_FORMAT));
 | 
	
		
			
				|  |  | +//                    再次尝试排课
 | 
	
		
			
				|  |  | +                    classGroupAdjust(classGroup4MixDtosBackup);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if(courseScheduleList.size() > 0){
 | 
	
		
			
				|  |  | +        if(courseScheduleList.size() > 0 && StringUtils.isEmpty(classCourseMinute)){
 | 
	
		
			
				|  |  |              //检测新排课冲突
 | 
	
		
			
				|  |  |              courseScheduleService.checkNewCourseSchedules(courseScheduleList, false);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -3282,7 +3319,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
 | 
	
		
			
				|  |  | -    public void mergeClassSplitClassAffirm(MergeClassSplitClassAffirmDto mergeClassSplitClassAffirmDto) {
 | 
	
		
			
				|  |  | +    public void mergeClassSplitClassAffirm(MergeClassSplitClassAffirmDto mergeClassSplitClassAffirmDto) throws InvocationTargetException, IllegalAccessException {
 | 
	
		
			
				|  |  |          List<Integer> classGroupIds = mergeClassSplitClassAffirmDto.getClassGroupIds();
 | 
	
		
			
				|  |  |          if(classGroupIds == null || classGroupIds.size() == 0){
 | 
	
		
			
				|  |  |              throw new BizException("参数校验失败");
 | 
	
	
		
			
				|  | @@ -3333,35 +3370,55 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 | 
	
		
			
				|  |  |                  musicGroupPaymentCalenderService.create(calenderDto);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        //冻结所选班级的课程
 | 
	
		
			
				|  |  | -        List<Long> allLockCourseIds = courseScheduleDao.queryStudentNotStartByClassIdsAndStudentIds(classGroupIds,null);
 | 
	
		
			
				|  |  | -        courseScheduleDao.batchUpdateLockByClassGroupIds(allLockCourseIds,1);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          //记录申请信息
 | 
	
		
			
				|  |  |          MusicGroupStudentClassAdjust musicGroupStudentClassAdjust = new MusicGroupStudentClassAdjust();
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setBatchNo(batchNo);
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setBatchNo(batchNo);
 | 
	
		
			
				|  |  | -        musicGroupStudentClassAdjust.setCalenderStatus(status);
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setCourseFlag(false);
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setMusicGroupId(musicGroup.getId());
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setOperatorId(sysUser.getId());
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setNewClassGroupJson(JSON.toJSONString(classGroup4MixDtos));
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setClassGroupIds(JSON.toJSONString(classGroupIds));
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setStudentIds(JSON.toJSONString(studentIds));
 | 
	
		
			
				|  |  | +        //获取需要冻结的课程
 | 
	
		
			
				|  |  | +        List<Long> allLockCourseIds = courseScheduleDao.queryStudentNotStartByClassIdsAndStudentIds(classGroupIds,null);
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setAllLockCourseIds(JSON.toJSONString(allLockCourseIds));
 | 
	
		
			
				|  |  | +        //获取需要删除的课程
 | 
	
		
			
				|  |  |          List<Long> courseIds = courseScheduleDao.queryStudentNotStartByClassIdsAndStudentIds(classGroupIds,studentIds);
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setSubLockCourseIds(JSON.toJSONString(courseIds));
 | 
	
		
			
				|  |  |          //计算新增班级的可排课时长,总课次*默认时长  (用学员剩余的课程时长加上购买的时长,可能导致同一班级学员时长不一致)
 | 
	
		
			
				|  |  |          musicGroupStudentClassAdjust.setClassCourseMinute(JSON.toJSONString(findClassCourseMinuteMap(classGroupIds)));
 | 
	
		
			
				|  |  | -        musicGroupStudentClassAdjustDao.insert(musicGroupStudentClassAdjust);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //如果需要审核,校验参数配置
 | 
	
		
			
				|  |  | +        checkMergeClassSplitClassAffirmParam(classGroup4MixDtos);
 | 
	
		
			
				|  |  |          //如果缴费项目不需要审核,那么生成班级以及课表
 | 
	
		
			
				|  |  |          if(status != null && status != AUDITING){
 | 
	
		
			
				|  |  | -//            classGroupService.classGroupAdjust(classGroup4MixDtos);
 | 
	
		
			
				|  |  | +            ClassGroup4MixDto classGroup4MixDto = classGroup4MixDtos.get(0);
 | 
	
		
			
				|  |  | +            classGroup4MixDto.setClassCourseMinute(musicGroupStudentClassAdjust.getClassCourseMinute());
 | 
	
		
			
				|  |  | +            List<CourseTimeDto> courseTimeDtoList = classGroup4MixDto.getCourseTimeDtoList();
 | 
	
		
			
				|  |  | +            List<CourseTimeDto> courseTimeDtoListBackup = new ArrayList<>();
 | 
	
		
			
				|  |  | +            BeanUtils.copyProperties(courseTimeDtoListBackup, courseTimeDtoList);
 | 
	
		
			
				|  |  | +            //每种课程类型单独排课
 | 
	
		
			
				|  |  | +            for (CourseTimeDto courseTimeDto : courseTimeDtoListBackup) {
 | 
	
		
			
				|  |  | +                List<CourseTimeDto> courseTimeDtos = new ArrayList<>();
 | 
	
		
			
				|  |  | +                courseTimeDtos.add(courseTimeDto);
 | 
	
		
			
				|  |  | +                classGroup4MixDto.setCourseTimeDtoList(courseTimeDtos);
 | 
	
		
			
				|  |  | +                classGroupService.classGroupAdjust(classGroup4MixDtos);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            musicGroupStudentClassAdjust.setCourseFlag(true);
 | 
	
		
			
				|  |  | +            //排课完成后删除所选课程
 | 
	
		
			
				|  |  | +            courseScheduleDao.batchDeleteByCourseSchedules(courseIds);
 | 
	
		
			
				|  |  | +        }else {
 | 
	
		
			
				|  |  | +            //冻结班级
 | 
	
		
			
				|  |  | +            classGroupDao.batchUpdateLockByClassGroupIds(classGroupIds,1);
 | 
	
		
			
				|  |  | +            //冻结所选班级的课程
 | 
	
		
			
				|  |  | +            courseScheduleDao.batchUpdateLockByCourseIds(allLockCourseIds,1);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        //如果需要审核,校验参数配置
 | 
	
		
			
				|  |  | -        checkMergeClassSplitClassAffirmParam(classGroup4MixDtos);
 | 
	
		
			
				|  |  | +        musicGroupStudentClassAdjustDao.insert(musicGroupStudentClassAdjust);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    //审核通过后排课,删除指定课程,并解冻当前班级课程
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private void checkMergeClassSplitClassAffirmParam(List<ClassGroup4MixDto> classGroup4MixDtos){
 | 
	
		
			
				|  |  |          if (classGroup4MixDtos.get(0).getCourseTimes().compareTo(0) <= 0) {
 |