Browse Source

Merge remote-tracking branch 'origin/master'

Joburgess 5 years ago
parent
commit
b62f8ef07a

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

@@ -153,7 +153,7 @@ public interface CourseScheduleTeacherSalaryDao extends BaseDAO<Long, CourseSche
 	 * @author Joburgess
 	 * @date 2019/10/24
 	 */
-	List<Map<Integer, BigDecimal>> findCourseSubsidyByCourses(@Param("courseScheduleIds") List<Long> courseScheduleIds);
+	List<Map<Long, BigDecimal>> findCourseSubsidyByCourses(@Param("courseScheduleIds") List<Long> courseScheduleIds);
 
 	/**
 	 * 乐团详情--课酬调整--课程教师列表

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

@@ -33,7 +33,7 @@ public interface StudentAttendanceDao extends BaseDAO<Long, StudentAttendance> {
      * @param courseId:
      * @return java.util.List<com.ym.mec.biz.dal.entity.StudentAttendance>
      */
-    List<StudentAttendance> findByCourseId(@Param("courseId") Integer courseId);
+    List<StudentAttendance> findByCourseId(@Param("courseId") Long courseId);
 
     /**
      * @describe 根据课程删除对应的点名记录

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

@@ -137,6 +137,8 @@ public interface TeacherAttendanceDao extends BaseDAO<Long, TeacherAttendance> {
 	 * @return
 	 */
 	int deleteByMusicGroupId(@Param("musicGroupId")String musicGroupId, @Param("groupType")GroupType groupType);
+	
+	int deletebyCourseScheduleId(@Param("courseScheduleId") Long courseScheduleId);
 
 	/**
 	 * @describe 清空指定课程教师签到信息

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

@@ -29,4 +29,6 @@ public interface TeacherDefaultVipGroupSalaryDao extends BaseDAO<Long, TeacherDe
     void batchAdd(@Param("vipGroupSalaries") List<TeacherDefaultVipGroupSalary> teacherDefaultVipGroupSalaries);
     
     List<TeacherDefaultVipGroupSalary> queryByUserId(Integer userId);
+    
+    List<TeacherDefaultVipGroupSalary> queryByUserIdList(@Param("userIdList") List<Integer> userIdList);
 }

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

@@ -243,7 +243,7 @@ public interface VipGroupDao extends BaseDAO<Long, VipGroup> {
      * @author Joburgess
      * @date 2019/10/23
      */
-    VipGroup findByCourseSchedule(Integer courseScheduleId);
+    VipGroup findByCourseSchedule(Long courseScheduleId);
 
     /**
      * 查询vip课数目

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

@@ -14,15 +14,15 @@ public class StudentAttendanceDto {
 
     private Integer update;
 
-    private Integer courseScheduleId;
+    private Long courseScheduleId;
 
     private List<StudentAttendance> studentAttendances;
 
-    public Integer getCourseScheduleId() {
+    public Long getCourseScheduleId() {
         return courseScheduleId;
     }
 
-    public void setCourseScheduleId(Integer courseScheduleId) {
+    public void setCourseScheduleId(Long courseScheduleId) {
         this.courseScheduleId = courseScheduleId;
     }
 

+ 4 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java

@@ -6,13 +6,16 @@ import com.ym.mec.biz.dal.enums.CourseStatusEnum;
 import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.TeachModeEnum;
 import com.ym.mec.common.enums.BaseEnum;
+
 import io.swagger.annotations.ApiModelProperty;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
@@ -102,7 +105,7 @@ public class CourseSchedule {
 	private Integer actualTeacherId;
 
 	@ApiModelProperty(value = "助教编号列表")
-	private List<Integer> teachingTeacherIdList;
+	private List<Integer> teachingTeacherIdList = new ArrayList<Integer>();
 
 	/**  */
 	private java.util.Date createTime;

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

@@ -411,7 +411,7 @@ public class ClassGroupTeacherMapperServiceImpl extends BaseServiceImpl<Long, Cl
         Map<CourseSchedule.CourseScheduleType, List<TeacherDefaultMusicGroupSalary>> teacherDefaultMusicGroupSalariesGroupByCourseType = teacherDefaultMusicGroupSalaries.stream().collect(Collectors.groupingBy(TeacherDefaultMusicGroupSalary::getCourseScheduleType));
 
         //获取课程对应教学点补贴
-        List<Map<Integer, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
+        List<Map<Long, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
         Map<Integer, BigDecimal> courseSubsidyMap = MapUtil.convertIntegerMap(courseSubsidyByCourses);
 
         //课程对应乐团结算方式集合

+ 408 - 70
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -1,44 +1,136 @@
 package com.ym.mec.biz.service.impl;
 
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.collections.ListUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+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.util.CollectionUtils;
+
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.api.entity.SysUserRole;
-import com.ym.mec.biz.dal.dao.*;
-import com.ym.mec.biz.dal.dto.*;
-import com.ym.mec.biz.dal.entity.*;
-import com.ym.mec.biz.dal.enums.*;
+import com.ym.mec.biz.dal.dao.ClassGroupDao;
+import com.ym.mec.biz.dal.dao.ClassGroupStudentMapperDao;
+import com.ym.mec.biz.dal.dao.ClassGroupTeacherSalaryDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleComplaintsDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleModifyLogDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleTeacherSalaryDao;
+import com.ym.mec.biz.dal.dao.GroupDao;
+import com.ym.mec.biz.dal.dao.MusicGroupDao;
+import com.ym.mec.biz.dal.dao.PracticeGroupDao;
+import com.ym.mec.biz.dal.dao.StudentAttendanceDao;
+import com.ym.mec.biz.dal.dao.SubjectDao;
+import com.ym.mec.biz.dal.dao.SysConfigDao;
+import com.ym.mec.biz.dal.dao.TeacherAttendanceDao;
+import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dao.TeacherDefaultMusicGroupSalaryDao;
+import com.ym.mec.biz.dal.dao.TeacherDefaultVipGroupSalaryDao;
+import com.ym.mec.biz.dal.dao.VipGroupDao;
+import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
+import com.ym.mec.biz.dal.dto.CourseAttendanceDetailHeadInfoDto;
+import com.ym.mec.biz.dal.dto.CoursePostponeDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleEndDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleStudentDto;
+import com.ym.mec.biz.dal.dto.CourseTimeDto;
+import com.ym.mec.biz.dal.dto.CreateCourseScheduleDto;
+import com.ym.mec.biz.dal.dto.IntegerAndIntegerListDto;
+import com.ym.mec.biz.dal.dto.Mapper;
+import com.ym.mec.biz.dal.dto.StudentNameAndPhoneDto;
+import com.ym.mec.biz.dal.dto.TeacherAttendanceDto;
+import com.ym.mec.biz.dal.dto.TeacherBasicDto;
+import com.ym.mec.biz.dal.dto.TeacherClassCourseSchudeleDto;
+import com.ym.mec.biz.dal.dto.VipGroupApplyBaseInfoDto;
+import com.ym.mec.biz.dal.dto.VipGroupApplyDto;
+import com.ym.mec.biz.dal.dto.VipGroupCourseAdjustInfoDto;
+import com.ym.mec.biz.dal.entity.ClassGroup;
+import com.ym.mec.biz.dal.entity.ClassGroupStudentMapper;
+import com.ym.mec.biz.dal.entity.ClassGroupTeacherSalary;
+import com.ym.mec.biz.dal.entity.CourseGenerateDto;
+import com.ym.mec.biz.dal.entity.CourseSchedule;
+import com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType;
+import com.ym.mec.biz.dal.entity.CourseScheduleComplaints;
+import com.ym.mec.biz.dal.entity.CourseScheduleModifyLog;
+import com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment;
+import com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary;
+import com.ym.mec.biz.dal.entity.Group;
+import com.ym.mec.biz.dal.entity.MusicGroup;
+import com.ym.mec.biz.dal.entity.PracticeGroup;
+import com.ym.mec.biz.dal.entity.StudentAttendance;
+import com.ym.mec.biz.dal.entity.StudentCourseScheduleRecordDto;
+import com.ym.mec.biz.dal.entity.SysConfig;
+import com.ym.mec.biz.dal.entity.Teacher;
+import com.ym.mec.biz.dal.entity.TeacherAttendance;
+import com.ym.mec.biz.dal.entity.TeacherDefaultMusicGroupSalary;
+import com.ym.mec.biz.dal.entity.TeacherDefaultVipGroupSalary;
+import com.ym.mec.biz.dal.entity.VipGroup;
+import com.ym.mec.biz.dal.enums.AuditStatusEnum;
+import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
+import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
+import com.ym.mec.biz.dal.enums.CourseStatusEnum;
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.dal.enums.MessageTypeEnum;
+import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.ParamEnum;
+import com.ym.mec.biz.dal.enums.SalarySettlementTypeEnum;
+import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
+import com.ym.mec.biz.dal.enums.TeachModeEnum;
+import com.ym.mec.biz.dal.enums.TeachTypeEnum;
+import com.ym.mec.biz.dal.enums.VipGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.StudentCourseScheduleRecordQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
-import com.ym.mec.biz.service.*;
+import com.ym.mec.biz.service.ClassGroupService;
+import com.ym.mec.biz.service.ClassGroupTeacherMapperService;
+import com.ym.mec.biz.service.CourseScheduleService;
+import com.ym.mec.biz.service.CourseScheduleStudentPaymentService;
+import com.ym.mec.biz.service.CourseScheduleTeacherSalaryService;
+import com.ym.mec.biz.service.MusicGroupService;
+import com.ym.mec.biz.service.SysConfigService;
+import com.ym.mec.biz.service.SysMessageService;
+import com.ym.mec.biz.service.VipGroupService;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.jiari.JiaRiFeignService;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext.MessageSender;
+import com.ym.mec.util.collection.ListUtil;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
-import feign.codec.DecodeException;
-import org.apache.commons.collections.ListUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-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.util.CollectionUtils;
+import com.ym.mec.util.json.JsonUtil;
 
-import java.math.BigDecimal;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import feign.codec.DecodeException;
 
 @Service
 public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSchedule> implements CourseScheduleService {
@@ -68,6 +160,8 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
     @Autowired
     private TeacherDefaultVipGroupSalaryDao teacherDefaultVipGroupSalaryDao;
     @Autowired
+    private TeacherDefaultMusicGroupSalaryDao teacherDefaultMusicGroupSalaryDao;
+    @Autowired
     private ClassGroupTeacherMapperService classGroupTeacherMapperService;
     @Autowired
     private CourseScheduleStudentPaymentService courseScheduleStudentPaymentService;
@@ -1553,30 +1647,26 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
     @Transactional(rollbackFor = Exception.class)
     public void courseAdjust(List<CourseSchedule> newCourseSchedules) {
         Date now = new Date();
-        //课程信息处理
-        List<Long> courseScheduleIds = newCourseSchedules.stream()
-                .map(CourseSchedule::getId)
-                .distinct().collect(Collectors.toList());
-        List<CourseSchedule> oldCourseScheduleIds = courseScheduleDao.findByCourseScheduleIds(courseScheduleIds);
-        Map<Long, List<CourseSchedule>> oldCourseScheduleMap = oldCourseScheduleIds.stream()
-                .collect(Collectors.groupingBy(CourseSchedule::getId));
-        List<Map<Long, Integer>> courseSettlementMaps = courseScheduleTeacherSalaryDao.checkCoursesIsSettlement(courseScheduleIds);
-        Map<Long, Long> courseSettlementMap = MapUtil.convertIntegerMap(courseSettlementMaps);
-
-        newCourseSchedules.forEach(newCourseSchedule -> {
-            Long isSettlement = courseSettlementMap.get(newCourseSchedule.getId().longValue());
-            if (Objects.nonNull(isSettlement) && isSettlement > 0) {
-                throw new BizException("调整的课程中存在已结算的课程");
-            }
-            List<CourseSchedule> oldCourseSchedules = oldCourseScheduleMap.get(newCourseSchedule.getId());
-            oldCourseSchedules.sort(Comparator.comparing(CourseSchedule::getStartClassTime).reversed());
-            CourseSchedule oldCourseSchedule = oldCourseSchedules.get(0);
-            if (Objects.isNull(newCourseSchedule.getActualTeacherId())) {
-                newCourseSchedule.setActualTeacherId(oldCourseSchedule.getActualTeacherId());
-            }
-            if (Objects.isNull(newCourseSchedule.getSchoolId())) {
-                newCourseSchedule.setSchoolId(oldCourseSchedule.getSchoolId());
-            }
+		// 课程信息处理
+		List<Long> courseScheduleIds = newCourseSchedules.stream().map(CourseSchedule::getId).distinct().collect(Collectors.toList());
+        
+        //已结算的课不能调整
+        /*List<Map<Long, Integer>> courseSettlementMaps = courseScheduleTeacherSalaryDao.checkCoursesIsSettlement(courseScheduleIds);
+        if(courseSettlementMaps!=null && courseSettlementMaps.size()>0){
+        	throw new BizException("调整的课程中存在已结算的课程");
+        }*/
+		
+        //查询数据库中的课程信息
+        List<CourseSchedule> oldCourseScheduleList = courseScheduleDao.findByCourseScheduleIds(courseScheduleIds);
+        
+		Map<Long, CourseSchedule> oldCourseScheduleMap = oldCourseScheduleList.stream().collect(Collectors.toMap(CourseSchedule::getId, c -> c));
+		
+        for(CourseSchedule newCourseSchedule : newCourseSchedules){
+
+        	//获取数据库中的记录
+            CourseSchedule oldCourseSchedule = oldCourseScheduleMap.get(newCourseSchedule.getId());
+            
+            //课程是否已结算
             int settlementNum = courseScheduleTeacherSalaryDao.checkCourseIsSettlement(oldCourseSchedule.getId().intValue());
             if (settlementNum > 0) {
                 throw new BizException("{}[{}]{}-{}课程已结算的",
@@ -1587,23 +1677,61 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                         DateUtil.dateToString(oldCourseSchedule.getEndClassTime(),
                                 DateUtil.EXPANDED_DATE_TIME_FORMAT));
             }
-            int num = studentAttendanceDao.countStudentAttendenceNum(oldCourseSchedule.getId().intValue());
-            if (num > 0) {
-                throw new BizException("{}[{}] {}-{}课程已点名",
-                        oldCourseSchedule.getName(),
-                        oldCourseSchedule.getId(),
-                        DateUtil.dateToString(oldCourseSchedule.getStartClassTime(),
-                                DateUtil.EXPANDED_DATE_TIME_FORMAT),
-                        DateUtil.dateToString(oldCourseSchedule.getEndClassTime(),
-                                DateUtil.EXPANDED_DATE_TIME_FORMAT));
+            //学生已点名不能调整(请假可以调整)
+            List<StudentAttendance> studentAttendanceList = studentAttendanceDao.findByCourseId(oldCourseSchedule.getId());
+            
+            for(StudentAttendance studentAttendance : studentAttendanceList){
+            	if(studentAttendance.getStatus() != StudentAttendanceStatusEnum.LEAVE){
+            		throw new BizException("{}[{}] {}-{}课程已点名",
+                            oldCourseSchedule.getName(),
+                            oldCourseSchedule.getId(),
+                            DateUtil.dateToString(oldCourseSchedule.getStartClassTime(),
+                                    DateUtil.EXPANDED_DATE_TIME_FORMAT),
+                            DateUtil.dateToString(oldCourseSchedule.getEndClassTime(),
+                                    DateUtil.EXPANDED_DATE_TIME_FORMAT));
+            	}
             }
-            if (oldCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.VIP)) {
+
+            if(!CollectionUtils.isEmpty(newCourseSchedule.getTeachingTeacherIdList())){
+                if (newCourseSchedule.getTeachingTeacherIdList().contains(newCourseSchedule.getActualTeacherId())){
+                    throw new BizException("主教和助教不可重复");
+                }
+            }
+            
+            if(newCourseSchedule.getStatus() == oldCourseSchedule.getStatus() && newCourseSchedule.getStatus() == CourseStatusEnum.OVER){
+            	throw new BizException("已结束的课程需要调整课程状态");
+            }
+            
+			if (newCourseSchedule.getGroupType() == GroupType.VIP) {
+				if (newCourseSchedule.getTeachMode() != oldCourseSchedule.getTeachMode() && newCourseSchedule.getTeachMode() == TeachModeEnum.OFFLINE) {
+					throw new BizException("不允许将线上课调整为线下课");
+				}
+			}
+            
+            /*if (oldCourseSchedule.getType().equals(CourseSchedule.CourseScheduleType.VIP)) {
                 VipGroup vipGroup = vipGroupDao.get(Long.valueOf(oldCourseSchedule.getMusicGroupId()));
                 if(Objects.isNull(vipGroup)){
                     throw new BizException("课程不存在");
                 }
                 Date endClassTime = DateUtil.addMinutes(newCourseSchedule.getStartClassTime(), vipGroup.getSingleClassMinutes());
                 newCourseSchedule.setEndClassTime(endClassTime);
+            }*/
+
+            if (Objects.isNull(newCourseSchedule.getActualTeacherId())) {
+                newCourseSchedule.setActualTeacherId(oldCourseSchedule.getActualTeacherId());
+            }
+            if (Objects.isNull(newCourseSchedule.getSchoolId())) {
+                newCourseSchedule.setSchoolId(oldCourseSchedule.getSchoolId());
+            }
+            if (Objects.isNull(newCourseSchedule.getType())) {
+                newCourseSchedule.setType(oldCourseSchedule.getType());
+            }
+            if(Objects.isNull(newCourseSchedule.getStartClassTime())){
+                newCourseSchedule.setStartClassTime(oldCourseSchedule.getStartClassTime());
+            }
+            if(newCourseSchedule.getEndClassTime() == null){
+            	int minutes = DateUtil.minutesBetween(oldCourseSchedule.getStartClassTime(), oldCourseSchedule.getEndClassTime());
+            	newCourseSchedule.setEndClassTime(DateUtil.addMinutes(newCourseSchedule.getStartClassTime(), minutes));
             }
             if(Objects.isNull(newCourseSchedule.getClassGroupId())){
                 newCourseSchedule.setClassGroupId(oldCourseSchedule.getClassGroupId());
@@ -1614,12 +1742,6 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             if(Objects.isNull(newCourseSchedule.getClassDate())){
                 newCourseSchedule.setClassDate(oldCourseSchedule.getClassDate());
             }
-            if(Objects.isNull(newCourseSchedule.getStartClassTime())){
-                newCourseSchedule.setStartClassTime(oldCourseSchedule.getStartClassTime());
-            }
-            if(Objects.isNull(newCourseSchedule.getEndClassTime())){
-                newCourseSchedule.setEndClassTime(oldCourseSchedule.getEndClassTime());
-            }
             if (newCourseSchedule.getStartClassTime().after(now)) {
                 newCourseSchedule.setStatus(CourseStatusEnum.NOT_START);
             }
@@ -1629,16 +1751,232 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             if (newCourseSchedule.getEndClassTime().before(now)) {
                 newCourseSchedule.setStatus(CourseStatusEnum.OVER);
             }
-            if(!CollectionUtils.isEmpty(newCourseSchedule.getTeachingTeacherIdList())){
-                if (newCourseSchedule.getTeachingTeacherIdList().contains(newCourseSchedule.getActualTeacherId())){
-                    throw new BizException("主教和助教不可重复");
-                }
-            }
-        });
+        
+        }
+        
         //课程冲突检测
         checkNewCourseSchedules(newCourseSchedules, false);
-        //课程调整
-        classStartDateAdjust(newCourseSchedules);
+
+		Map<Long, List<TeacherAttendance>> teacherAttendanceMap = new HashMap<Long, List<TeacherAttendance>>();
+		// 查询老师的考勤
+		List<TeacherAttendance> teacherAttendances = teacherAttendanceDao.findTeacherIdByCourseSchedule(courseScheduleIds);
+
+		for (TeacherAttendance ta : teacherAttendances) {
+			List<TeacherAttendance> tas = teacherAttendanceMap.get(ta.getCourseScheduleId());
+			if (tas == null) {
+				tas = new ArrayList<TeacherAttendance>();
+			}
+			tas.add(ta);
+			teacherAttendanceMap.put(ta.getCourseScheduleId(), tas);
+		}
+
+		Date date = new Date();
+		Long courseScheduleId = null;
+		List<TeacherAttendance> insertTeacherAttendanceList = new ArrayList<TeacherAttendance>();
+		List<CourseScheduleTeacherSalary> insertCourseScheduleTeacherSalaryList = new ArrayList<CourseScheduleTeacherSalary>();
+
+		// 获取课程对应教学点补贴
+		List<Map<Long, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
+		Map<Integer, BigDecimal> courseSubsidyMap = MapUtil.convertIntegerMap(courseSubsidyByCourses);
+
+		// 课程对应乐团结算方式集合
+		List<Map<String, String>> musicGroupSettlementTypeByCourse = courseScheduleTeacherSalaryDao.findMusicGroupSettlementTypeByCourse(courseScheduleIds);
+		Map<String, String> musicGroupSettlementsMap = MapUtil.convertMybatisMap(musicGroupSettlementTypeByCourse);
+
+		Date entryDate = DateUtil.stringToDate(sysConfigDao.findByParamName(SysConfigService.TEACHER_ENTRY_DATE).getParanValue(), "yyyy-MM-dd");
+
+		List<CourseScheduleModifyLog> insertCourseScheduleModifyLogList = new ArrayList<CourseScheduleModifyLog>();
+
+		for (CourseSchedule newCourseSchedule : newCourseSchedules) {
+			courseScheduleId = newCourseSchedule.getId();
+			CourseSchedule oldCourseSchedule = oldCourseScheduleMap.get(courseScheduleId);
+
+			// 修改了主教/助教/课程状态,需修改考勤记录
+			List<TeacherAttendance> teacherAttendanceList = teacherAttendanceMap.get(courseScheduleId);
+
+			List<Integer> oldTeacherIdList = teacherAttendanceList.stream().map(TeacherAttendance::getTeacherId).distinct().collect(Collectors.toList());
+
+			List<Integer> newTeacherIdList = newCourseSchedule.getTeachingTeacherIdList();
+			newTeacherIdList.add(newCourseSchedule.getActualTeacherId());
+
+			if ((newCourseSchedule.getStatus() != oldCourseSchedule.getStatus() && newCourseSchedule.getStatus() == CourseStatusEnum.NOT_START)
+					|| !ListUtil.isEquals(oldTeacherIdList, newTeacherIdList)) {
+				// 清理原来考勤
+				teacherAttendanceDao.deletebyCourseScheduleId(courseScheduleId);
+
+				// 新增考勤
+				for (Integer teacherId : newTeacherIdList) {
+					TeacherAttendance ta = new TeacherAttendance();
+					ta.setClassGroupId(newCourseSchedule.getClassGroupId());
+					ta.setCourseScheduleId(courseScheduleId);
+					ta.setCreateTime(date);
+					ta.setGroupType(newCourseSchedule.getGroupType());
+					ta.setMusicGroupId(newCourseSchedule.getMusicGroupId());
+					ta.setTeacherId(teacherId);
+					insertTeacherAttendanceList.add(ta);
+				}
+			}
+
+			// 计算课程时长
+			int oldMinutes = DateUtil.minutesBetween(oldCourseSchedule.getStartClassTime(), oldCourseSchedule.getEndClassTime());
+			int newMinutes = DateUtil.minutesBetween(newCourseSchedule.getStartClassTime(), newCourseSchedule.getEndClassTime());
+
+			// 如果修改了老师、课程类型、课程时长、教学模式,需要修改课酬
+			if (!ListUtil.isEquals(oldTeacherIdList, newTeacherIdList) || newCourseSchedule.getType() != oldCourseSchedule.getType()
+					|| newCourseSchedule.getTeachMode() != oldCourseSchedule.getTeachMode() || oldMinutes != newMinutes) {
+
+				// 所有教师列表
+				List<Teacher> teachers = teacherDao.findByTeacherIds(newTeacherIdList);
+				Map<Integer, Teacher> teacherMap = teachers.stream().collect(Collectors.toMap(Teacher::getId, teacher -> teacher));
+
+				Map<Integer, Map<CourseScheduleType, TeacherDefaultMusicGroupSalary>> musicGroupSalaryMap = new HashMap<Integer, Map<CourseScheduleType, TeacherDefaultMusicGroupSalary>>();
+				// 所有老师默认乐团课酬
+				List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalaries = teacherDefaultMusicGroupSalaryDao.findByTeacher(newTeacherIdList);
+				for (TeacherDefaultMusicGroupSalary tdms : teacherDefaultMusicGroupSalaries) {
+					Map<CourseScheduleType, TeacherDefaultMusicGroupSalary> map = musicGroupSalaryMap.get(tdms.getUserId());
+					if (map == null) {
+						map = new HashMap<CourseSchedule.CourseScheduleType, TeacherDefaultMusicGroupSalary>();
+					}
+					map.put(tdms.getCourseScheduleType(), tdms);
+					musicGroupSalaryMap.put(tdms.getUserId(), map);
+				}
+
+				// 所有老师默认vip课酬
+				List<TeacherDefaultVipGroupSalary> teacherDefaultVipGroupSalaries = teacherDefaultVipGroupSalaryDao.queryByUserIdList(newTeacherIdList);
+				Map<Integer, Map<Integer, TeacherDefaultVipGroupSalary>> vipGroupSalaryMap = new HashMap<Integer, Map<Integer, TeacherDefaultVipGroupSalary>>();
+				for (TeacherDefaultVipGroupSalary tdvs : teacherDefaultVipGroupSalaries) {
+					Map<Integer, TeacherDefaultVipGroupSalary> map = vipGroupSalaryMap.get(tdvs.getUserId());
+					if (map == null) {
+						map = new HashMap<Integer, TeacherDefaultVipGroupSalary>();
+					}
+					map.put(tdvs.getVipGroupCategoryId(), tdvs);
+					vipGroupSalaryMap.put(tdvs.getUserId(), map);
+				}
+
+				VipGroup vipGroup = vipGroupDao.findByCourseSchedule(courseScheduleId);
+
+				// 删除课酬
+				List<Long> courseScheduleIdList = new ArrayList<Long>();
+				courseScheduleIdList.add(courseScheduleId);
+				courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(courseScheduleIdList);
+
+				for (Integer teacherId : newTeacherIdList) {
+					CourseScheduleTeacherSalary ts = new CourseScheduleTeacherSalary();
+					ts.setClassGroupId(newCourseSchedule.getClassGroupId());
+					ts.setCourseScheduleId(courseScheduleId);
+					ts.setCreateTime(date);
+					ts.setGroupType(newCourseSchedule.getGroupType());
+					ts.setMusicGroupId(newCourseSchedule.getMusicGroupId());
+					ts.setSubsidy(courseSubsidyMap.get(courseScheduleId));
+					if (teacherId == newCourseSchedule.getActualTeacherId().intValue()) {
+						ts.setTeacherRole(TeachTypeEnum.BISHOP);
+					} else {
+						ts.setTeacherRole(TeachTypeEnum.TEACHING);
+					}
+					ts.setUpdateTime(date);
+					ts.setUserId(teacherId);
+					// 重新生成课酬
+					if (newCourseSchedule.getGroupType() == GroupType.MUSIC) {
+						Map<CourseScheduleType, TeacherDefaultMusicGroupSalary> map = musicGroupSalaryMap.get(teacherId);
+						TeacherDefaultMusicGroupSalary tdms = map.get(newCourseSchedule.getType());
+						if (tdms != null) {
+							// 乐团结算方式
+							String settlementType = musicGroupSettlementsMap.get(courseScheduleId);
+							int unitMinutes = 30;
+							if (newCourseSchedule.getType() == CourseScheduleType.CLASSROOM) {
+								unitMinutes = 40;
+							} else if (newCourseSchedule.getType() == CourseScheduleType.HIGH) {
+								unitMinutes = 45;
+							}
+
+							// 如果当前教师是在指定日期之后入职的,则按照3.0的方式结算
+							Teacher teacher = teacherMap.get(teacherId);
+							if (Objects.nonNull(teacher.getEntryDate())
+									&& (teacher.getEntryDate().after(entryDate) || teacher.getEntryDate().getTime() == entryDate.getTime())) {
+								settlementType = SalarySettlementTypeEnum.GRADIENT_SALARY.getCode();
+							}
+							if (StringUtils.equals(settlementType, "TEACHER_DEFAULT")) {
+								if (ts.getTeacherRole() == TeachTypeEnum.BISHOP) {
+									ts.setExpectSalary(new BigDecimal(tdms.getMainTeacher30MinSalary().doubleValue() * newMinutes / unitMinutes));
+								} else {
+									ts.setExpectSalary(new BigDecimal(tdms.getAssistantTeacher30MinSalary().doubleValue() * newMinutes / unitMinutes));
+								}
+							} else if (StringUtils.equals(settlementType, "GRADIENT_SALARY")) {
+								if (ts.getTeacherRole() == TeachTypeEnum.BISHOP) {
+									ts.setExpectSalary(new BigDecimal(tdms.getMainTeacher90MinSalary().doubleValue() * newMinutes / unitMinutes));
+								} else {
+									ts.setExpectSalary(new BigDecimal(tdms.getAssistantTeacher90MinSalary().doubleValue() * newMinutes / unitMinutes));
+								}
+							}
+						}
+					} else if (newCourseSchedule.getGroupType() == GroupType.VIP) {
+						Map<Integer, TeacherDefaultVipGroupSalary> map = vipGroupSalaryMap.get(teacherId);
+						if (vipGroup == null) {
+							throw new BizException("课程[{}]记录存在异常,请联系管理员", courseScheduleId);
+						}
+						TeacherDefaultVipGroupSalary tdvs = map.get(vipGroup.getVipGroupCategoryId());
+						if (tdvs != null) {
+							if (newCourseSchedule.getTeachMode() == TeachModeEnum.OFFLINE) {
+								ts.setExpectSalary(tdvs.getOfflineClassesSalary());
+							} else {
+								ts.setExpectSalary(tdvs.getOfflineClassesSalary());
+							}
+						}
+					} else if (newCourseSchedule.getGroupType() == GroupType.PRACTICE) {
+						ts.setExpectSalary(new BigDecimal(30));
+					}
+					insertCourseScheduleTeacherSalaryList.add(ts);
+				}
+			}
+
+			// 调整日志
+			CourseScheduleModifyLog courseScheduleModifyLog = new CourseScheduleModifyLog();
+			courseScheduleModifyLog.setCourseScheduleId(courseScheduleId);
+			courseScheduleModifyLog.setCreateTime(date);
+			courseScheduleModifyLog.setCurrentCourseSchedule(JsonUtil.toJSONString(newCourseSchedule));
+			courseScheduleModifyLog.setPreviousCourseSchedule(JsonUtil.toJSONString(oldCourseSchedule));
+
+			SysUser sysUser = sysUserFeignService.queryUserInfo();
+			if (null == sysUser) {
+				throw new BizException("获取用户信息失败");
+			}
+
+			courseScheduleModifyLog.setOperatorId(sysUser.getId());
+
+			insertCourseScheduleModifyLogList.add(courseScheduleModifyLog);
+		}
+
+		if (insertTeacherAttendanceList.size() > 0) {
+			teacherAttendanceDao.batchInsert(insertTeacherAttendanceList);
+		}
+
+		if (insertCourseScheduleTeacherSalaryList.size() > 0) {
+			courseScheduleTeacherSalaryDao.batchInsert(insertCourseScheduleTeacherSalaryList);
+		}
+
+		if (insertCourseScheduleModifyLogList.size() > 0) {
+			courseScheduleModifyLogDao.batchInsert(insertCourseScheduleModifyLogList);
+		}
+
+		// 推送
+		try {
+			Set<Integer> teacherIds = newCourseSchedules.stream().map(e -> e.getActualTeacherId()).collect(Collectors.toSet());
+			if (teacherIds == null) {
+				teacherIds = new HashSet<>();
+			}
+			teacherIds.addAll(oldCourseScheduleList.stream().map(e -> e.getActualTeacherId()).collect(Collectors.toSet()));
+			Map<Integer, String> map = new HashMap<>(teacherIds.size());
+			teacherIds.removeAll(Collections.singleton(null));
+			teacherIds.forEach(e -> {
+				map.put(e, e.toString());
+			});
+			if (map != null && map.size() > 0) {
+				sysMessageService.batchSendMessage(MessageSender.JIGUANG, MessageTypeEnum.TEACHER_PUSH_COURSE_SCHEDULE_CHANGE_RESULT, map, null, 0, "7",
+						"TEACHER");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
     }
 
     @Override
@@ -1760,7 +2098,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                 }
 
                 if (teacherIsChange) {
-                    VipGroup byCourseSchedule = vipGroupDao.findByCourseSchedule(newCourseSchedule.getId().intValue());
+                    VipGroup byCourseSchedule = vipGroupDao.findByCourseSchedule(newCourseSchedule.getId());
 
                     BigDecimal onlineTeacherSalary = new BigDecimal(0), offlineTeacherSalary = new BigDecimal(0);
 

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

@@ -364,7 +364,7 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
             return;
         }
         //获取课程对应教学点补贴
-        List<Map<Integer, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
+        List<Map<Long, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
         Map<Integer, BigDecimal> courseSubsidyMap = MapUtil.convertIntegerMap(courseSubsidyByCourses);
 
         //课程编号与课程对应集合

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

@@ -381,4 +381,8 @@
 		DELETE ta FROM teacher_attendance ta LEFT JOIN course_schedule cs ON ta.course_schedule_id_ = cs.id_
 		WHERE ta.music_group_id_=#{musicGroupId} AND ta.group_type_=#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} and cs.status_ = 'NOT_START'
 	</delete>
+	
+    <delete id="deletebyCourseScheduleId">
+        DELETE from teacher_attendance WHERE course_schedule_id_=#{courseScheduleId}
+    </delete>
 </mapper>

+ 8 - 0
mec-biz/src/main/resources/config/mybatis/TeacherDefaultVipGroupSalaryMapper.xml

@@ -103,4 +103,12 @@
     <select id="queryByUserId" resultMap="TeacherDefaultVipGroupSalary">
 		SELECT * FROM teacher_default_vip_group_salary where user_id_ = #{userId} ORDER BY id_
 	</select>
+	
+    <select id="queryByUserIdList" resultMap="TeacherDefaultVipGroupSalary">
+		SELECT * FROM teacher_default_vip_group_salary where user_id_ IN
+		<foreach collection="userIdList" item="userId" open="(" close=")" separator=",">
+			#{userId}
+		</foreach>
+		 ORDER BY id_
+	</select>
 </mapper>

+ 74 - 9
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java

@@ -1,11 +1,35 @@
 package com.ym.mec.teacher.controller;
 
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.ClassGroupStudentMapperDao;
+import com.ym.mec.biz.dal.dao.StudentAttendanceDao;
 import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
 import com.ym.mec.biz.dal.dto.CourseScheduleDto;
 import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.SysConfig;
+import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
+import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
 import com.ym.mec.biz.dal.page.CourseHomeworkQueryInfo;
 import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
@@ -14,16 +38,11 @@ import com.ym.mec.biz.dal.page.StudentAttendanceQueryInfo;
 import com.ym.mec.biz.service.CourseScheduleService;
 import com.ym.mec.biz.service.StudentAttendanceService;
 import com.ym.mec.biz.service.SysConfigService;
+import com.ym.mec.biz.service.VipGroupService;
 import com.ym.mec.common.controller.BaseController;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.*;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.util.collection.MapUtil;
+import com.ym.mec.util.date.DateUtil;
 
 /**
  * @Author Joburgess
@@ -42,6 +61,14 @@ public class TeacherCourseScheduleController extends BaseController {
     private SysUserFeignService sysUserFeignService;
     @Autowired
     private SysConfigService sysConfigService;
+    
+    @Autowired
+    private VipGroupService vipGroupService;
+    
+    @Autowired
+    private StudentAttendanceDao studentAttendanceDao;
+    @Autowired
+    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
 
     @ApiOperation(value = "根据月份获取该月有课的日期")
     @GetMapping("/getCourseScheduleDateByMonth")
@@ -151,6 +178,44 @@ public class TeacherCourseScheduleController extends BaseController {
         if(Objects.isNull(oldCourseSchedule)){
             return failed("未找到指定课程");
         }
+        if(oldCourseSchedule.getGroupType() != GroupType.VIP){
+        	return failed("客户端只能调整VIP课");
+        }
+        Date now = new Date();
+        
+        //默认开课前4小时内,可调整,如果全员请假,可在当天24小时前调整
+        SysConfig advanceLeaveHoursConfig = sysConfigService.findByParamName(SysConfigService.ENABLE_TEACHER_COURSE_ADJUST_DEFAULT_HOURS);
+        Integer advanceLeaveHours=advanceLeaveHoursConfig.getParanValue(Integer.class);
+        
+        List<Long> newCourseScheduleIds = new ArrayList<Long>();
+        newCourseScheduleIds.add(oldCourseSchedule.getId());
+        List<Map<Long, Integer>> courseLeaveStudentNumMaps = studentAttendanceDao.countCourseLeaveStudentNumWithFourHoursAgo(newCourseScheduleIds, advanceLeaveHours);
+        Map<Long,Long> courseLeaveStudentNumMap = MapUtil.convertIntegerMap((courseLeaveStudentNumMaps));
+
+        List<Integer> classGroupIds = new ArrayList<Integer>();
+        classGroupIds.add(oldCourseSchedule.getClassGroupId());
+        List<Map<Integer, Integer>> classGroupStudentNumMaps = classGroupStudentMapperDao.countClassGroupsStudentNum(classGroupIds, ClassGroupStudentStatusEnum.NORMAL);
+        Map<Integer, Long> classGroupStudentNumMap = MapUtil.convertIntegerMap(classGroupStudentNumMaps);
+
+        Long normalStudentNum = classGroupStudentNumMap.get(oldCourseSchedule.getClassGroupId());
+        Long courseLeaveStudentNum = courseLeaveStudentNumMap.get(oldCourseSchedule.getId());
+        if(oldCourseSchedule.getGroupType().equals(GroupType.VIP)
+                &&Objects.nonNull(courseLeaveStudentNum)
+                &&Objects.nonNull(normalStudentNum)
+                &&courseLeaveStudentNum.intValue()==normalStudentNum.intValue()){
+            if(!DateUtil.isSameDay(now,oldCourseSchedule.getStartClassTime())&&now.after(oldCourseSchedule.getStartClassTime())){
+                throw new BizException("当前时间不可对相关课程进行调整");
+            }
+        }else{
+            if(DateUtil.addHours(now,advanceLeaveHours).after(oldCourseSchedule.getStartClassTime())){
+                throw new BizException("请在课程开始前{}小时进行调整",advanceLeaveHours);
+            }
+        }
+        
+        if (oldCourseSchedule.getGroupType().equals(GroupType.VIP)) {
+            vipGroupService.checkVipCourseIsInScore(Long.valueOf(oldCourseSchedule.getMusicGroupId()));
+        }
+        
         if(Objects.isNull(classDateAdjustDto.getClassGroupId())){
             classDateAdjustDto.setClassGroupId(oldCourseSchedule.getClassGroupId());
         }