浏览代码

Merge branch 'master' of http://git.dayaedu.com/yonge/mec

yonge 5 年之前
父节点
当前提交
5e33fb47f0

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

@@ -1479,6 +1479,8 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
      */
     List<CourseGroupExportDto> getStudentCourseInfo(@Param("studentIds") Set<Integer> studentIds, @Param("groupType") GroupType groupType);
 
+    List<CourseGroupExportDto> getStudentVipCourseInfo(@Param("studentIds") Set<Integer> studentIds);
+
     /**
      * 获取上一次连堂课
      * @param classGroupId

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

@@ -29,7 +29,7 @@ public class CourseSchedule {
 
 		SINGLE("SINGLE", "单技课"), MIX("MIX", "合奏课"), HIGH("HIGH", "小班课"), VIP("VIP", "vip课"), DEMO("DEMO", "试听课"), COMPREHENSIVE("COMPREHENSIVE", "综合课"), PRACTICE(
 				"PRACTICE", "网管课"), ENLIGHTENMENT("ENLIGHTENMENT", "启蒙课"), TRAINING_SINGLE("TRAINING_SINGLE", "集训单技课"), TRAINING_MIX("TRAINING_MIX", "集训合奏课"), CLASSROOM(
-				"CLASSROOM", "课堂课"),COMM("COMM","对外课程"),HIGH_ONLINE("HIGH_ONLINE","线上基础技能课"),MUSIC_NETWORK("MUSIC_NETWORK","乐团网管课");
+				"CLASSROOM", "课堂课"),COMM("COMM","对外课程"),HIGH_ONLINE("HIGH_ONLINE","网络基础训练课"),MUSIC_NETWORK("MUSIC_NETWORK","乐团网管课");
 
 		private String code;
 

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

@@ -51,9 +51,20 @@ public class Organization {
 	@ApiModelProperty(value = "地址",required = false)
 	private String address;
 
+	@ApiModelProperty(value = "是否全职资源",required = false)
+	private Integer fullJobResource;
+
 	@ApiModelProperty(value = "子节点列表",required = false)
 	private List<Organization> organizations;
 
+	public Integer getFullJobResource() {
+		return fullJobResource;
+	}
+
+	public void setFullJobResource(Integer fullJobResource) {
+		this.fullJobResource = fullJobResource;
+	}
+
 	public String getAreaName() {
 		return areaName;
 	}

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

@@ -7,7 +7,7 @@ import com.ym.mec.common.enums.BaseEnum;
  */
 public enum ClassGroupTypeEnum implements BaseEnum<String, ClassGroupTypeEnum> {
 	NORMAL("NORMAL", "普通班级"), MIX("MIX", "合奏班级"), HIGH("HIGH", "提高班"), VIP("VIP", "vip课"), DEMO("DEMO", "试听课"), PRACTICE("PRACTICE", "网管课"), SNAP("SNAP",
-			"临时班级"), COMM("COMM", "对外课程"), HIGH_ONLINE("HIGH_ONLINE", "线上基础技能课"),MUSIC_NETWORK("MUSIC_NETWORK","乐团网管课");
+			"临时班级"), COMM("COMM", "对外课程"), HIGH_ONLINE("HIGH_ONLINE", "网络基础训练课"),MUSIC_NETWORK("MUSIC_NETWORK","乐团网管课");
 
 	private String code;
 

+ 2 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupStudentMapperServiceImpl.java

@@ -75,7 +75,7 @@ public class ClassGroupStudentMapperServiceImpl extends BaseServiceImpl<Long, Cl
         ClassGroup classGroup = classGroupService.get(classGroupId);
         Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(classGroupId);
         if (classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) && studentNum <= 3) {
-            throw new BizException(classGroup.getName()+"(线上基础技能课班级)人数不能少于3,请调整");
+            throw new BizException(classGroup.getName()+"(网络基础训练课班级)人数不能少于3,请调整");
         }
 
         ClassGroupStudentMapper classStudentMapper = findClassStudentMapperByUserIdAndClassGroupId(userId, classGroupId, "NORMAL");
@@ -203,7 +203,7 @@ public class ClassGroupStudentMapperServiceImpl extends BaseServiceImpl<Long, Cl
         Integer studentNum = classGroupStudentMapperDao.countClassGroupNormalStudentNum(classGroupId);
         if (classGroup.getType().equals(ClassGroupTypeEnum.HIGH_ONLINE) &&
                 ((studentNum + userIdStrSet.size()) < 3 || (studentNum + userIdStrSet.size()) > 5)) {
-            throw new BizException("线上基础技能课班级人数不能小于3大于5");
+            throw new BizException("网络基础训练课班级人数不能小于3大于5");
         }
 
         //1、班级关系添加

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

@@ -543,7 +543,7 @@ public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long
         if(!CollectionUtils.isEmpty(studentAttendances)){
             courseNormalStudentsMap =studentAttendances.stream()
                     .filter(studentAttendance -> StudentAttendanceStatusEnum.NORMAL.equals(studentAttendance.getStatus()))
-                    .collect(Collectors.groupingBy(StudentAttendance::getId, Collectors.counting()));
+                    .collect(Collectors.groupingBy(StudentAttendance::getCourseScheduleId, Collectors.counting()));
         }
 
         //课程对应乐团结算方式集合

+ 676 - 674
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentAttendanceServiceImpl.java

@@ -20,6 +20,7 @@ import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -32,693 +33,694 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
-public class StudentAttendanceServiceImpl extends BaseServiceImpl<Long, StudentAttendance>  implements StudentAttendanceService {
-
-	@Autowired
-	private StudentAttendanceDao studentAttendanceDao;
-	@Autowired
-	private MusicGroupStudentFeeDao studentFeeDao;
-	@Autowired
-	private CourseScheduleDao courseScheduleDao;
-	@Autowired
-	private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
-	@Autowired
-	private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
-	@Autowired
-	private ClassGroupDao classGroupDao;
-	@Autowired
-	private ClassGroupStudentMapperDao classGroupStudentMapperDao;
-	@Autowired
-	private SysUserFeignService sysUserFeignService;
-	@Autowired
-	private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
-	@Autowired
-	private MusicGroupQuitDao musicGroupQuitDao;
-	@Autowired
-	private SysMessageService sysMessageService;
-	@Autowired
-	private SysConfigDao sysConfigDao;
-	@Autowired
-	private SchoolDao schoolDao;
-	@Autowired
-	private SysConfigService sysConfigService;
-	@Autowired
-	private TeacherAttendanceDao teacherAttendanceDao;
-	@Autowired
-	private StudentDao studentDao;
-
-	@Override
-	public BaseDAO<Long, StudentAttendance> getDAO() {
-		return studentAttendanceDao;
-	}
-	private static final Logger log = LoggerFactory.getLogger(StudentAttendanceServiceImpl.class);
-
-	@Override
-	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-	public void addStudentAttendances(StudentAttendanceDto studentAttendanceInfos) {
-		List<StudentAttendance> studentAttendances=studentAttendanceInfos.getStudentAttendances();
-		SysUser sysUser = sysUserFeignService.queryUserInfo();
-		if(Objects.isNull(sysUser)){
-			throw new BizException("请登录");
-		}
-		studentDao.lockUser(sysUser.getId());
-		if(CollectionUtils.isEmpty(studentAttendances)){
-			throw new BizException("无点名信息");
-		}
-		Long courseScheduleId=studentAttendances.get(0).getCourseScheduleId();
-		CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId);
-		if(Objects.isNull(courseSchedule)){
-			throw new BizException("请指定课程");
-		}
-		if(TeachModeEnum.ONLINE.equals(courseSchedule.getTeachMode())){
-			throw new BizException("线上课程请进入房间授课");
-		}
-		Date date = new Date();
-		SysConfig attendanceTimeRange;
-		if(courseSchedule.getGroupType().equals(GroupType.MUSIC)){
-			attendanceTimeRange = sysConfigService.findByParamName(SysConfigService.ENABLE_STUDENT_ATTENDANCE_TIME_RANGE);
-		}else{
-			SysConfig beforeAttendanceTimeRange=sysConfigService.findByParamName(SysConfigService.ENABLE_STUDENT_ATTENDANCE_BEFOR_COURSE_START_TIME_RANGE_VIP);
-			int courseStartTime = DateUtil.minutesBetween(date, courseSchedule.getStartClassTime());
-			if(date.before(courseSchedule.getStartClassTime())&&courseStartTime>beforeAttendanceTimeRange.getParanValue(Integer.class)){
-				throw new BizException("VIP课开课前{}分钟禁止点名",beforeAttendanceTimeRange.getParanValue(Integer.class));
-			}
-			attendanceTimeRange = sysConfigService.findByParamName(SysConfigService.ENABLE_STUDENT_ATTENDANCE_TIME_RANGE_VIP);
-		}
-		int courseEndTime = DateUtil.minutesBetween(courseSchedule.getEndClassTime(), date);
-		if(date.after(courseSchedule.getEndClassTime())&&courseEndTime>attendanceTimeRange.getParanValue(Integer.class)){
-			throw new BizException("{}课结束{}分钟后禁止点名",
-					courseSchedule.getGroupType().equals(GroupType.MUSIC)?"乐团":"VIP",
-					attendanceTimeRange.getParanValue(Integer.class));
-		}
-		studentAttendanceDao.deleteStudentAttendancesByCourse(courseScheduleId);
-		int classTimes=courseScheduleDao.countClassTimes(courseSchedule.getClassGroupId().longValue(),courseSchedule.getStartClassTime());
-		studentAttendances.forEach(studentAttendance -> {
-			studentAttendance.setTeacherId(sysUser.getId());
-			studentAttendance.setCurrentClassTimes(classTimes+1);
-			StudentAttendance studentAttendanceInfo = studentAttendanceDao.getStudentAttendanceInfo(studentAttendance);
-			studentAttendanceInfo.setGroupType(courseSchedule.getGroupType());
-			studentAttendanceInfo.setMusicGroupId(courseSchedule.getMusicGroupId());
-			if (studentAttendance.getStatus() != StudentAttendanceStatusEnum.DROP_OUT) {
-				//判断是否为连续旷课
-				if(StudentAttendanceStatusEnum.TRUANT.equals(studentAttendance.getStatus())
-						||StudentAttendanceStatusEnum.LEAVE.equals(studentAttendance.getStatus())){
-					StudentAttendance studentLatestAttendanceInfo = studentAttendanceDao.getStudentLatestAttendanceInfo(studentAttendanceInfo);
-					if(Objects.nonNull(studentLatestAttendanceInfo)){
-						if(StudentAttendanceStatusEnum.TRUANT.equals(studentLatestAttendanceInfo.getStatus())
-								||StudentAttendanceStatusEnum.LEAVE.equals(studentLatestAttendanceInfo.getStatus())){
-							studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
-									studentAttendanceInfo.getMusicGroupId(),
-									YesOrNoEnum.YES.getCode());
-						}
-					}else{
-						studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
-								studentAttendanceInfo.getMusicGroupId(),
-								YesOrNoEnum.YES.getCode());
-					}
-				}else{
-					studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
-							studentAttendanceInfo.getMusicGroupId(),
-							YesOrNoEnum.NO.getCode());
-				}
-				if(studentAttendanceInfo.getStatus() == StudentAttendanceStatusEnum.NORMAL){
-					studentAttendanceInfo.setSignInTime(courseSchedule.getStartClassTime());
-					studentAttendanceInfo.setSignOutTime(courseSchedule.getEndClassTime());
-				}
-				studentAttendanceDao.insert(studentAttendanceInfo);
-			}else{
-				studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
-						studentAttendanceInfo.getMusicGroupId(),
-						YesOrNoEnum.NO.getCode());
-			}
-		});
-		//获取正常签到的学生信息
-		List<StudentAttendance> normal = studentAttendances.stream().filter(studentAttendance -> studentAttendance.getStatus() == StudentAttendanceStatusEnum.NORMAL).collect(Collectors.toList());
-		if(normal != null && normal.size() > 0){
-			Map<Integer,String> receivers = new HashMap<>();
-			normal.forEach(e->{
-				receivers.put(e.getUserId(),e.getUserId().toString());
-			});
-			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,MessageTypeEnum.STUDENT_PUSH_NAMES_ACHIEVE,
-					receivers,null,0,"2","STUDENT",DateUtil.format(new Date(),DateUtil.DATE_FORMAT_MIN));
-		}
-		Map<StudentAttendanceStatusEnum, List<StudentAttendance>> studentAttendanceGroupByStatus = studentAttendances.stream().collect(Collectors.groupingBy(StudentAttendance::getStatus));
-		Integer studentNum=studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL)==null?0:studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL).size();
-		Integer leaveStudentNum=studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE)==null?0:studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE).size();
-		courseSchedule.setStudentNum(studentNum);
-		courseSchedule.setLeaveStudentNum(leaveStudentNum);
-		courseScheduleDao.update(courseSchedule);
-
-		if(!courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.VIP)){
-			return;
-		}
-
-		if(StringUtils.isBlank(studentAttendanceInfos.getSignInLongitudeLatitude())){
-			throw new BizException("未获取到您的位置");
-		}
-
-		School school = schoolDao.get(courseSchedule.getSchoolId());
-
-		//是否在范围内
-		boolean isInScore = true;
-		if(Objects.nonNull(school)){
-			if(StringUtils.isBlank(school.getLongitudeLatitude())){
-				if(studentAttendanceInfos.getUpdate().equals(YesOrNoEnum.YES.getCode())){
-					school.setLongitudeLatitude(studentAttendanceInfos.getSignInLongitudeLatitude());
-					schoolDao.update(school);
-				}
-			}else{
-				SysConfig sysConfig = sysConfigService.findByParamName(SysConfigService.ATTENDANCE_RANGE);
-				double attendanceRange = Double.valueOf(sysConfig.getParanValue());
-				double distance = MapUtil.distance(studentAttendanceInfos.getSignInLongitudeLatitude(),
-						school.getLongitudeLatitude());
-				if(distance>attendanceRange){
-					isInScore=false;
-				}
-			}
-		}
-
-		TeacherAttendance teacherAttendance=teacherAttendanceDao.findByTeacherAttendanceInfo(sysUser.getId().longValue(),courseSchedule.getId());
-
-		teacherAttendance.setSignInLongitudeLatitude(studentAttendanceInfos.getSignInLongitudeLatitude());
-
-		if(Objects.isNull(teacherAttendance)){
-			teacherAttendance= new TeacherAttendance();
-			teacherAttendance.setTeacherId(sysUser.getId());
-			teacherAttendance.setCreateTime(date);
-		}
-
-		teacherAttendance.setSignInTime(courseSchedule.getStartClassTime());
-		teacherAttendance.setSignInStatus(YesOrNoEnum.YES);
-		teacherAttendance.setSignOutTime(courseSchedule.getEndClassTime());
-		teacherAttendance.setSignOutStatus(YesOrNoEnum.YES);
-		teacherAttendance.setCurrentClassTimes(classTimes + 1);
-		if(Objects.nonNull(teacherAttendance.getId())){
-			teacherAttendanceDao.update(teacherAttendance);
-		}else{
-			teacherAttendanceDao.insert(teacherAttendance);
-		}
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public void updateStudentAttendances(StudentAttendanceDto studentAttendanceInfo) {
-		if(Objects.isNull(studentAttendanceInfo.getCourseScheduleId())){
-			throw new BizException("请指定课程编号");
-		}
-		List<StudentAttendance> studentAttendances=studentAttendanceInfo.getStudentAttendances();
-		if(CollectionUtils.isEmpty(studentAttendances)){
-			throw new BizException("无点名信息");
-		}
-		CourseSchedule courseSchedule = courseScheduleDao.get(studentAttendanceInfo.getCourseScheduleId().longValue());
-		if(Objects.isNull(courseSchedule)){
-			throw new BizException("课程不存在");
-		}
-
-		List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findByCourseSchedule(studentAttendanceInfo.getCourseScheduleId());
-		if(!CollectionUtils.isEmpty(courseScheduleTeacherSalaries)&&Objects.nonNull(courseScheduleTeacherSalaries.get(0).getSettlementTime())){
-			throw new BizException("此课程已结算");
-		}
-
-		List<Integer> userIds = studentAttendances.stream().map(StudentAttendance::getUserId).collect(Collectors.toList());
-		studentAttendanceDao.deleteStudentAttendancesByCourseAndUsers(studentAttendanceInfo.getCourseScheduleId().longValue(),userIds);
-		for (StudentAttendance studentAttendance : studentAttendances) {
-			studentAttendance.setGroupType(courseSchedule.getGroupType());
-			studentAttendance.setMusicGroupId(courseSchedule.getMusicGroupId());
-			studentAttendance.setClassGroupId(courseSchedule.getClassGroupId());
-			studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
-			studentAttendance.setCourseScheduleId(courseSchedule.getId());
-		}
-		studentAttendanceDao.addStudentAttendances(studentAttendances);
-		List<StudentAttendance> allStudentAttendances = studentAttendanceDao.findByCourseId(studentAttendanceInfo.getCourseScheduleId());
-		Map<StudentAttendanceStatusEnum, List<StudentAttendance>> studentAttendanceGroupByStatus = allStudentAttendances.stream().collect(Collectors.groupingBy(StudentAttendance::getStatus));
-		Integer studentNum=studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL)==null?0:studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL).size();
-		Integer leaveStudentNum=studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE)==null?0:studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE).size();
-		courseSchedule.setStudentNum(studentNum);
-		courseSchedule.setLeaveStudentNum(leaveStudentNum);
-		courseScheduleDao.update(courseSchedule);
-	}
-
-	@Override
-	public Map<String, Object> getCurrentCourseStudents(QueryInfo queryInfo) {
-		Map<String,Object> result=new HashMap<>();
-
-		PageInfo<StudentAttendance> pageInfo = super.queryPage(queryInfo);
-
-		result.put("pageInfo",pageInfo);
-
-		List<StudentStatusCountUtilEntity> stringIntegerMap = studentAttendanceDao.countStudentStatus(((StudentAttendanceQueryInfo) queryInfo).getClassGroupId());
-
-		stringIntegerMap.forEach(studentStatusCount->{
-			switch (studentStatusCount.getStudentStatus()){
-				case LEAVE:
-					result.put("numberOfLeavePeoples",studentStatusCount.getNumberOfStudent());
-					break;
-				default:
-					break;
-
-			}
-		});
-
-		return result;
-	}
-
-	@Override
-	public PageInfo<StudentPersonalAttendanceDto> getStudentPersonalAttendances(QueryInfo queryInfo) {
-		PageInfo<StudentPersonalAttendanceDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<>();
-		MapUtil.populateMap(params, queryInfo);
-
-		List<StudentPersonalAttendanceDto> dataList = null;
-		int count = studentAttendanceDao.queryStudentPersonalAttendancesCount(params);
-		if (count > 0) {
-			pageInfo.setTotal(count);
-			params.put("offset", pageInfo.getOffset());
-			dataList = studentAttendanceDao.queryStudentPersonalAttendances(params);
-		}
-		if (count == 0) {
-			dataList = new ArrayList<>();
-		}
-		pageInfo.setRows(dataList);
-		return pageInfo;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public boolean leave(Integer userId, Long courseScheduleId, String remark) {
-
-		CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId);
-		if(courseSchedule == null){
-			throw new BizException("课程编号异常");
-		}
-
-		if(courseSchedule.getStatus() == CourseStatusEnum.OVER){
-			throw new BizException("课程已结束");
-		}
-
-		Date date = new Date();
-
-		int hours = 4;
-		String str = sysConfigDao.findConfigValue(SysConfigService.ADVANCE_LEAVE_HOURS);
-		if (StringUtils.isNotBlank(str)) {
-			hours = Integer.parseInt(str);
-		}
-
-		int earliestTimeForLeave = 168;
-		SysConfig earliestTimeForLeaveConfig = sysConfigService.findByParamName(SysConfigService.EARLIEST_TIME_FOR_LEAVE);
-		if(Objects.nonNull(earliestTimeForLeaveConfig)){
-			earliestTimeForLeave = Integer.parseInt(earliestTimeForLeaveConfig.getParanValue());
-		}
-
-		if(DateUtil.addHours(date, hours).after(courseSchedule.getStartClassTime())){
-			throw new BizException("开课{}小时之前才可以请假",hours);
-		}
-
-		if(DateUtil.addHours(date, 168).before(courseSchedule.getStartClassTime())){
-			throw new BizException("请在开课前{}天内请假",earliestTimeForLeave/24);
-		}
-
-		StudentAttendance studentAttendance  = studentAttendanceDao.findByStatusAndCourseScheduleId(userId,courseScheduleId.intValue());
-		if(Objects.isNull(studentAttendance)){
-			studentAttendance=new StudentAttendance();
-		}
-		studentAttendance.setClassGroupId(courseSchedule.getClassGroupId());
-		studentAttendance.setCourseScheduleId(courseScheduleId);
-		studentAttendance.setCreateTime(date);
-		studentAttendance.setCurrentClassTimes(0);
-		studentAttendance.setRemark(remark);
-		studentAttendance.setStatus(StudentAttendanceStatusEnum.LEAVE);
-		studentAttendance.setUserId(userId);
-		studentAttendance.setGroupType(courseSchedule.getGroupType());
-		studentAttendance.setMusicGroupId(courseSchedule.getMusicGroupId());
-
-		if(Objects.nonNull(studentAttendance.getId())){
-			studentAttendanceDao.update(studentAttendance);
-		}else{
-			studentAttendanceDao.insert(studentAttendance);
-		}
-
-		ClassGroupStudentMapper classGroupStudentMapper = classGroupStudentMapperDao.query(courseSchedule.getClassGroupId(), userId);
-		if(Objects.isNull(classGroupStudentMapper)){
-			throw new BizException("您不在此课程对应班级上");
-		}
-
-		Map<Integer,String> sendArgs=new HashMap<>();
-		sendArgs.put(courseSchedule.getActualTeacherId(),courseSchedule.getActualTeacherId() + "");
-		SysUser sysUser = sysUserFeignService.queryUserInfo();
-		//发送消息至老师
-		sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
-				MessageTypeEnum.TEACHER_PUSH_STUDENT_LEAVE,
-				sendArgs,
-				null,0,"1","TEACHER",DateUtil.getDate(courseSchedule.getClassDate()),DateUtil.getTime(courseSchedule.getStartClassTime()),courseSchedule.getName(),sysUser.getUsername());
-		return true;
-	}
-
-	@Override
-	public PageInfo statisticsList(CourseHomeworkQueryInfo queryInfo) {
-
-		if(Objects.isNull(queryInfo.getClassGroupId())){
-			throw new BizException("请指定班级");
-		}
-
-		PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<String, Object>();
-		MapUtil.populateMap(params, queryInfo);
-
-		List<StudentAttendanceStatisticsResponse> dataList = null;
-		int count = courseScheduleStudentPaymentDao.countStudentByClassGroup(params);
-		if (count > 0) {
-			pageInfo.setTotal(count);
-			params.put("offset", pageInfo.getOffset());
-			ClassGroup classGroup = classGroupDao.get(queryInfo.getClassGroupId().intValue());
-			if(Objects.isNull(classGroup)){
-				throw new BizException("班级不存在");
-			}
-			dataList = courseScheduleStudentPaymentDao.findStudentByClassGroup(params);
-			//学生编号列表
-			List<Integer> userIds = dataList.stream().map(StudentAttendanceStatisticsResponse::getUserId).collect(Collectors.toList());
-			//学生-旷课次数关联集合
-			List<Map<Integer, Integer>> continuousAbsenteeismTimesByUsersAndMusicGroup = musicGroupStudentFeeDao.findContinuousAbsenteeismTimesByUsersAndMusicGroup(classGroup.getMusicGroupId(), userIds);
-			Map<Integer,Integer> continuousAbsenteeismTimesWithUser=MapUtil.convertIntegerMap(continuousAbsenteeismTimesByUsersAndMusicGroup);
-			//学生签到记录列表
-			List<StudentAttendanceResponse> studentAttendances = studentAttendanceDao.findByClassGroupAndUsers(queryInfo.getClassGroupId(), userIds);
-			//学生签到状态统计列表
-			List<StudentAttendanceStatusCountDto> studentAttendanceStatusCountDtos = studentAttendanceDao.countStudentAttendanceStatus(queryInfo.getClassGroupId(), userIds);
-			Map<Integer, List<StudentAttendanceStatusCountDto>> studentAttendanceStatusCountDtosByUser = studentAttendanceStatusCountDtos.stream().collect(Collectors.groupingBy(StudentAttendanceStatusCountDto::getUserId));
-
-			if(!CollectionUtils.isEmpty(studentAttendances)){
-				//学生-签到记录关联集合
-				Map<Integer, List<StudentAttendanceResponse>> studentAttendanceByUser = studentAttendances.stream().collect(Collectors.groupingBy(StudentAttendanceResponse::getUserId));
-
-				dataList.forEach(student->{
-					//判断是否是连续签到
-					Integer continuousAbsenteeismTimes = continuousAbsenteeismTimesWithUser.get(student.getUserId());
-					if(Objects.nonNull(continuousAbsenteeismTimes)){
-						if(continuousAbsenteeismTimes>=3){
-							student.setTruant(true);
-						}
-					}
-					//当前学生的签到状态统计
-					List<StudentAttendanceStatusCountDto> currentStudentAttendanceStatusCountDtos = studentAttendanceStatusCountDtosByUser.get(student.getUserId());
-					if(!CollectionUtils.isEmpty(currentStudentAttendanceStatusCountDtos)){
-						Map<StudentAttendanceStatusEnum, Integer> statusAndNumMap = currentStudentAttendanceStatusCountDtos.stream().collect(Collectors.toMap(StudentAttendanceStatusCountDto::getStatus, StudentAttendanceStatusCountDto::getNum));
-						student.setNormalDay(statusAndNumMap.get(StudentAttendanceStatusEnum.NORMAL));
-						student.setTruantDay(statusAndNumMap.get(StudentAttendanceStatusEnum.TRUANT));
-						student.setLeaveDay(statusAndNumMap.get(StudentAttendanceStatusEnum.LEAVE));
-					}
-
-					//当前学生签到记录
-					List<StudentAttendanceResponse> studentAttendanceResps = studentAttendanceByUser.get(student.getUserId());
-					if(Objects.nonNull(studentAttendanceResps)){
-						student.setList(studentAttendanceResps);
-					}
-				});
-			}
-		}
-		if (count == 0) {
-			dataList = new ArrayList<>();
-		}
-		pageInfo.setRows(dataList);
-		return pageInfo;
-	}
-
-	@Override
-	public CourseScheduleResponse getStatisticsInfo(Integer classGroupId) {
-		if(Objects.isNull(classGroupId)){
-			throw new BizException("请指定班级");
-		}
-		ClassGroup classGroup = classGroupDao.get(classGroupId);
-		CourseScheduleResponse courseScheduleResp = new CourseScheduleResponse();
-		if (Objects.nonNull(classGroup)) {
-			if (Objects.nonNull(classGroup.getCurrentClassTimes()) && Objects.nonNull(classGroup.getTotalClassTimes())) {
-				courseScheduleResp.setAlreadyInClass(classGroup.getCurrentClassTimes() + "/" + classGroup.getTotalClassTimes());
-			}
-			if (Objects.nonNull(classGroup.getStudentNum())) {
-				courseScheduleResp.setStudentNum(classGroup.getStudentNum());
-			}
-			Date latestSignInDate = studentAttendanceDao.findLatestSignInDate(classGroupId);
-			if(Objects.nonNull(latestSignInDate)){
-				courseScheduleResp.setClassDate(DateUtil.format(latestSignInDate,DateUtil.DATE_FORMAT_MIN));
-				courseScheduleResp.setClassTime(DateUtil.date2Week(latestSignInDate));
-			}
-			courseScheduleResp.setLeagueNum(musicGroupQuitDao.countMusicGroupQuitNum(classGroup.getMusicGroupId()));
-		}
-		return courseScheduleResp;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
-	public void addStudentAttendanceRecord(Integer courseScheduleId, Integer userId, StudentAttendanceStatusEnum statusEnum,SignStatusEnum signStatusEnum) {
-		CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
-		ClassGroup classGroup = classGroupDao.findByCourseSchedule(courseScheduleId,0);
-		StudentAttendance studentAttendance = studentAttendanceDao.findByStatusAndCourseScheduleId(userId,courseScheduleId);
-		Date date = new Date();
-		if(studentAttendance == null){
-			studentAttendance = new StudentAttendance();
-			studentAttendance.setClassGroupId(classGroup.getId());
-			studentAttendance.setCourseScheduleId(courseScheduleId.longValue());
-			studentAttendance.setCurrentClassTimes(classGroup.getCurrentClassTimes() + 1);
-			studentAttendance.setGroupType(classGroup.getGroupType());
-			studentAttendance.setMusicGroupId(classGroup.getMusicGroupId());
-			studentAttendance.setUserId(userId);
-			studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
-			if(signStatusEnum == SignStatusEnum.SIGN_IN){
-				if(courseSchedule.getStudentNum() == null){
-					courseSchedule.setStudentNum(0);
-				}
-				courseSchedule.setStudentNum(courseSchedule.getStudentNum() + 1);
-			}
-			studentAttendanceDao.insert(studentAttendance);
-		}else {
-			studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
-			studentAttendance.setUpdateTime(date);
-		}
+public class StudentAttendanceServiceImpl extends BaseServiceImpl<Long, StudentAttendance> implements StudentAttendanceService {
+
+    @Autowired
+    private StudentAttendanceDao studentAttendanceDao;
+    @Autowired
+    private MusicGroupStudentFeeDao studentFeeDao;
+    @Autowired
+    private CourseScheduleDao courseScheduleDao;
+    @Autowired
+    private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
+    @Autowired
+    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
+    @Autowired
+    private ClassGroupDao classGroupDao;
+    @Autowired
+    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
+    @Autowired
+    private MusicGroupQuitDao musicGroupQuitDao;
+    @Autowired
+    private SysMessageService sysMessageService;
+    @Autowired
+    private SysConfigDao sysConfigDao;
+    @Autowired
+    private SchoolDao schoolDao;
+    @Autowired
+    private SysConfigService sysConfigService;
+    @Autowired
+    private TeacherAttendanceDao teacherAttendanceDao;
+    @Autowired
+    private StudentDao studentDao;
+
+    @Override
+    public BaseDAO<Long, StudentAttendance> getDAO() {
+        return studentAttendanceDao;
+    }
+
+    private static final Logger log = LoggerFactory.getLogger(StudentAttendanceServiceImpl.class);
+
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public void addStudentAttendances(StudentAttendanceDto studentAttendanceInfos) {
+        List<StudentAttendance> studentAttendances = studentAttendanceInfos.getStudentAttendances();
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw new BizException("请登录");
+        }
+        studentDao.lockUser(sysUser.getId());
+        if (CollectionUtils.isEmpty(studentAttendances)) {
+            throw new BizException("无点名信息");
+        }
+        Long courseScheduleId = studentAttendances.get(0).getCourseScheduleId();
+        CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId);
+        if (Objects.isNull(courseSchedule)) {
+            throw new BizException("请指定课程");
+        }
+        if (TeachModeEnum.ONLINE.equals(courseSchedule.getTeachMode())) {
+            throw new BizException("线上课程请进入房间授课");
+        }
+        Date date = new Date();
+        SysConfig attendanceTimeRange;
+        if (courseSchedule.getGroupType().equals(GroupType.MUSIC)) {
+            attendanceTimeRange = sysConfigService.findByParamName(SysConfigService.ENABLE_STUDENT_ATTENDANCE_TIME_RANGE);
+        } else {
+            SysConfig beforeAttendanceTimeRange = sysConfigService.findByParamName(SysConfigService.ENABLE_STUDENT_ATTENDANCE_BEFOR_COURSE_START_TIME_RANGE_VIP);
+            int courseStartTime = DateUtil.minutesBetween(date, courseSchedule.getStartClassTime());
+            if (date.before(courseSchedule.getStartClassTime()) && courseStartTime > beforeAttendanceTimeRange.getParanValue(Integer.class)) {
+                throw new BizException("VIP课开课前{}分钟禁止点名", beforeAttendanceTimeRange.getParanValue(Integer.class));
+            }
+            attendanceTimeRange = sysConfigService.findByParamName(SysConfigService.ENABLE_STUDENT_ATTENDANCE_TIME_RANGE_VIP);
+        }
+        int courseEndTime = DateUtil.minutesBetween(courseSchedule.getEndClassTime(), date);
+        if (date.after(courseSchedule.getEndClassTime()) && courseEndTime > attendanceTimeRange.getParanValue(Integer.class)) {
+            throw new BizException("{}课结束{}分钟后禁止点名",
+                    courseSchedule.getGroupType().equals(GroupType.MUSIC) ? "乐团" : "VIP",
+                    attendanceTimeRange.getParanValue(Integer.class));
+        }
+        studentAttendanceDao.deleteStudentAttendancesByCourse(courseScheduleId);
+        int classTimes = courseScheduleDao.countClassTimes(courseSchedule.getClassGroupId().longValue(), courseSchedule.getStartClassTime());
+        studentAttendances.forEach(studentAttendance -> {
+            studentAttendance.setTeacherId(sysUser.getId());
+            studentAttendance.setCurrentClassTimes(classTimes + 1);
+            StudentAttendance studentAttendanceInfo = studentAttendanceDao.getStudentAttendanceInfo(studentAttendance);
+            studentAttendanceInfo.setGroupType(courseSchedule.getGroupType());
+            studentAttendanceInfo.setMusicGroupId(courseSchedule.getMusicGroupId());
+            if (studentAttendance.getStatus() != StudentAttendanceStatusEnum.DROP_OUT) {
+                //判断是否为连续旷课
+                if (StudentAttendanceStatusEnum.TRUANT.equals(studentAttendance.getStatus())
+                        || StudentAttendanceStatusEnum.LEAVE.equals(studentAttendance.getStatus())) {
+                    StudentAttendance studentLatestAttendanceInfo = studentAttendanceDao.getStudentLatestAttendanceInfo(studentAttendanceInfo);
+                    if (Objects.nonNull(studentLatestAttendanceInfo)) {
+                        if (StudentAttendanceStatusEnum.TRUANT.equals(studentLatestAttendanceInfo.getStatus())
+                                || StudentAttendanceStatusEnum.LEAVE.equals(studentLatestAttendanceInfo.getStatus())) {
+                            studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
+                                    studentAttendanceInfo.getMusicGroupId(),
+                                    YesOrNoEnum.YES.getCode());
+                        }
+                    } else {
+                        studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
+                                studentAttendanceInfo.getMusicGroupId(),
+                                YesOrNoEnum.YES.getCode());
+                    }
+                } else {
+                    studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
+                            studentAttendanceInfo.getMusicGroupId(),
+                            YesOrNoEnum.NO.getCode());
+                }
+                if (studentAttendanceInfo.getStatus() == StudentAttendanceStatusEnum.NORMAL) {
+                    studentAttendanceInfo.setSignInTime(courseSchedule.getStartClassTime());
+                    studentAttendanceInfo.setSignOutTime(courseSchedule.getEndClassTime());
+                }
+                studentAttendanceDao.insert(studentAttendanceInfo);
+            } else {
+                studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
+                        studentAttendanceInfo.getMusicGroupId(),
+                        YesOrNoEnum.NO.getCode());
+            }
+        });
+        //获取正常签到的学生信息
+        List<StudentAttendance> normal = studentAttendances.stream().filter(studentAttendance -> studentAttendance.getStatus() == StudentAttendanceStatusEnum.NORMAL).collect(Collectors.toList());
+        if (normal != null && normal.size() > 0) {
+            Map<Integer, String> receivers = new HashMap<>();
+            normal.forEach(e -> {
+                receivers.put(e.getUserId(), e.getUserId().toString());
+            });
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_NAMES_ACHIEVE,
+                    receivers, null, 0, "2", "STUDENT", DateUtil.format(new Date(), DateUtil.DATE_FORMAT_MIN));
+        }
+        Map<StudentAttendanceStatusEnum, List<StudentAttendance>> studentAttendanceGroupByStatus = studentAttendances.stream().collect(Collectors.groupingBy(StudentAttendance::getStatus));
+        Integer studentNum = studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL) == null ? 0 : studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL).size();
+        Integer leaveStudentNum = studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE) == null ? 0 : studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE).size();
+        courseSchedule.setStudentNum(studentNum);
+        courseSchedule.setLeaveStudentNum(leaveStudentNum);
+        courseScheduleDao.update(courseSchedule);
+
+        if (!courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.VIP)) {
+            return;
+        }
+
+        if (StringUtils.isBlank(studentAttendanceInfos.getSignInLongitudeLatitude())) {
+            throw new BizException("未获取到您的位置");
+        }
+
+        School school = schoolDao.get(courseSchedule.getSchoolId());
+
+        //是否在范围内
+        boolean isInScore = true;
+        if (Objects.nonNull(school)) {
+            if (StringUtils.isBlank(school.getLongitudeLatitude())) {
+                if (studentAttendanceInfos.getUpdate().equals(YesOrNoEnum.YES.getCode())) {
+                    school.setLongitudeLatitude(studentAttendanceInfos.getSignInLongitudeLatitude());
+                    schoolDao.update(school);
+                }
+            } else {
+                SysConfig sysConfig = sysConfigService.findByParamName(SysConfigService.ATTENDANCE_RANGE);
+                double attendanceRange = Double.valueOf(sysConfig.getParanValue());
+                double distance = MapUtil.distance(studentAttendanceInfos.getSignInLongitudeLatitude(),
+                        school.getLongitudeLatitude());
+                if (distance > attendanceRange) {
+                    isInScore = false;
+                }
+            }
+        }
+
+        TeacherAttendance teacherAttendance = teacherAttendanceDao.findByTeacherAttendanceInfo(sysUser.getId().longValue(), courseSchedule.getId());
+
+        teacherAttendance.setSignInLongitudeLatitude(studentAttendanceInfos.getSignInLongitudeLatitude());
+
+        if (Objects.isNull(teacherAttendance)) {
+            teacherAttendance = new TeacherAttendance();
+            teacherAttendance.setTeacherId(sysUser.getId());
+            teacherAttendance.setCreateTime(date);
+        }
+
+        teacherAttendance.setSignInTime(courseSchedule.getStartClassTime());
+        teacherAttendance.setSignInStatus(YesOrNoEnum.YES);
+        teacherAttendance.setSignOutTime(courseSchedule.getEndClassTime());
+        teacherAttendance.setSignOutStatus(YesOrNoEnum.YES);
+        teacherAttendance.setCurrentClassTimes(classTimes + 1);
+        if (Objects.nonNull(teacherAttendance.getId())) {
+            teacherAttendanceDao.update(teacherAttendance);
+        } else {
+            teacherAttendanceDao.insert(teacherAttendance);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateStudentAttendances(StudentAttendanceDto studentAttendanceInfo) {
+        if (Objects.isNull(studentAttendanceInfo.getCourseScheduleId())) {
+            throw new BizException("请指定课程编号");
+        }
+        List<StudentAttendance> studentAttendances = studentAttendanceInfo.getStudentAttendances();
+        if (CollectionUtils.isEmpty(studentAttendances)) {
+            throw new BizException("无点名信息");
+        }
+        CourseSchedule courseSchedule = courseScheduleDao.get(studentAttendanceInfo.getCourseScheduleId().longValue());
+        if (Objects.isNull(courseSchedule)) {
+            throw new BizException("课程不存在");
+        }
+
+        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findByCourseSchedule(studentAttendanceInfo.getCourseScheduleId());
+        if (!CollectionUtils.isEmpty(courseScheduleTeacherSalaries) && Objects.nonNull(courseScheduleTeacherSalaries.get(0).getSettlementTime())) {
+            throw new BizException("此课程已结算");
+        }
+
+        List<Integer> userIds = studentAttendances.stream().map(StudentAttendance::getUserId).collect(Collectors.toList());
+        studentAttendanceDao.deleteStudentAttendancesByCourseAndUsers(studentAttendanceInfo.getCourseScheduleId().longValue(), userIds);
+        for (StudentAttendance studentAttendance : studentAttendances) {
+            studentAttendance.setGroupType(courseSchedule.getGroupType());
+            studentAttendance.setMusicGroupId(courseSchedule.getMusicGroupId());
+            studentAttendance.setClassGroupId(courseSchedule.getClassGroupId());
+            studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
+            studentAttendance.setCourseScheduleId(courseSchedule.getId());
+        }
+        studentAttendanceDao.addStudentAttendances(studentAttendances);
+        List<StudentAttendance> allStudentAttendances = studentAttendanceDao.findByCourseId(studentAttendanceInfo.getCourseScheduleId());
+        Map<StudentAttendanceStatusEnum, List<StudentAttendance>> studentAttendanceGroupByStatus = allStudentAttendances.stream().collect(Collectors.groupingBy(StudentAttendance::getStatus));
+        Integer studentNum = studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL) == null ? 0 : studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.NORMAL).size();
+        Integer leaveStudentNum = studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE) == null ? 0 : studentAttendanceGroupByStatus.get(StudentAttendanceStatusEnum.LEAVE).size();
+        courseSchedule.setStudentNum(studentNum);
+        courseSchedule.setLeaveStudentNum(leaveStudentNum);
+        courseScheduleDao.update(courseSchedule);
+    }
+
+    @Override
+    public Map<String, Object> getCurrentCourseStudents(QueryInfo queryInfo) {
+        Map<String, Object> result = new HashMap<>();
+
+        PageInfo<StudentAttendance> pageInfo = super.queryPage(queryInfo);
+
+        result.put("pageInfo", pageInfo);
+
+        List<StudentStatusCountUtilEntity> stringIntegerMap = studentAttendanceDao.countStudentStatus(((StudentAttendanceQueryInfo) queryInfo).getClassGroupId());
+
+        stringIntegerMap.forEach(studentStatusCount -> {
+            switch (studentStatusCount.getStudentStatus()) {
+                case LEAVE:
+                    result.put("numberOfLeavePeoples", studentStatusCount.getNumberOfStudent());
+                    break;
+                default:
+                    break;
+
+            }
+        });
+
+        return result;
+    }
+
+    @Override
+    public PageInfo<StudentPersonalAttendanceDto> getStudentPersonalAttendances(QueryInfo queryInfo) {
+        PageInfo<StudentPersonalAttendanceDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List<StudentPersonalAttendanceDto> dataList = null;
+        int count = studentAttendanceDao.queryStudentPersonalAttendancesCount(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            dataList = studentAttendanceDao.queryStudentPersonalAttendances(params);
+        }
+        if (count == 0) {
+            dataList = new ArrayList<>();
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean leave(Integer userId, Long courseScheduleId, String remark) {
+
+        CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId);
+        if (courseSchedule == null) {
+            throw new BizException("课程编号异常");
+        }
+
+        if (courseSchedule.getStatus() == CourseStatusEnum.OVER) {
+            throw new BizException("课程已结束");
+        }
+
+        Date date = new Date();
+
+        int hours = 4;
+        String str = sysConfigDao.findConfigValue(SysConfigService.ADVANCE_LEAVE_HOURS);
+        if (StringUtils.isNotBlank(str)) {
+            hours = Integer.parseInt(str);
+        }
+
+        int earliestTimeForLeave = 7;
+        SysConfig earliestTimeForLeaveConfig = sysConfigService.findByParamName(SysConfigService.EARLIEST_TIME_FOR_LEAVE);
+        if (Objects.nonNull(earliestTimeForLeaveConfig)) {
+            earliestTimeForLeave = Integer.parseInt(earliestTimeForLeaveConfig.getParanValue());
+        }
+
+        if (DateUtil.addHours(date, hours).after(courseSchedule.getStartClassTime())) {
+            throw new BizException("开课{}小时之前才可以请假", hours);
+        }
+
+        if (DateUtil.addDays(DateUtils.truncate(date, Calendar.DAY_OF_MONTH), earliestTimeForLeave).compareTo(courseSchedule.getClassDate())<=0) {
+            throw new BizException("请在开课前{}天内请假", earliestTimeForLeave);
+        }
+
+        StudentAttendance studentAttendance = studentAttendanceDao.findByStatusAndCourseScheduleId(userId, courseScheduleId.intValue());
+        if (Objects.isNull(studentAttendance)) {
+            studentAttendance = new StudentAttendance();
+        }
+        studentAttendance.setClassGroupId(courseSchedule.getClassGroupId());
+        studentAttendance.setCourseScheduleId(courseScheduleId);
+        studentAttendance.setCreateTime(date);
+        studentAttendance.setCurrentClassTimes(0);
+        studentAttendance.setRemark(remark);
+        studentAttendance.setStatus(StudentAttendanceStatusEnum.LEAVE);
+        studentAttendance.setUserId(userId);
+        studentAttendance.setGroupType(courseSchedule.getGroupType());
+        studentAttendance.setMusicGroupId(courseSchedule.getMusicGroupId());
+
+        if (Objects.nonNull(studentAttendance.getId())) {
+            studentAttendanceDao.update(studentAttendance);
+        } else {
+            studentAttendanceDao.insert(studentAttendance);
+        }
+
+        ClassGroupStudentMapper classGroupStudentMapper = classGroupStudentMapperDao.query(courseSchedule.getClassGroupId(), userId);
+        if (Objects.isNull(classGroupStudentMapper)) {
+            throw new BizException("您不在此课程对应班级上");
+        }
+
+        Map<Integer, String> sendArgs = new HashMap<>();
+        sendArgs.put(courseSchedule.getActualTeacherId(), courseSchedule.getActualTeacherId() + "");
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        //发送消息至老师
+        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
+                MessageTypeEnum.TEACHER_PUSH_STUDENT_LEAVE,
+                sendArgs,
+                null, 0, "1", "TEACHER", DateUtil.getDate(courseSchedule.getClassDate()), DateUtil.getTime(courseSchedule.getStartClassTime()), courseSchedule.getName(), sysUser.getUsername());
+        return true;
+    }
+
+    @Override
+    public PageInfo statisticsList(CourseHomeworkQueryInfo queryInfo) {
+
+        if (Objects.isNull(queryInfo.getClassGroupId())) {
+            throw new BizException("请指定班级");
+        }
+
+        PageInfo pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<String, Object>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List<StudentAttendanceStatisticsResponse> dataList = null;
+        int count = courseScheduleStudentPaymentDao.countStudentByClassGroup(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            ClassGroup classGroup = classGroupDao.get(queryInfo.getClassGroupId().intValue());
+            if (Objects.isNull(classGroup)) {
+                throw new BizException("班级不存在");
+            }
+            dataList = courseScheduleStudentPaymentDao.findStudentByClassGroup(params);
+            //学生编号列表
+            List<Integer> userIds = dataList.stream().map(StudentAttendanceStatisticsResponse::getUserId).collect(Collectors.toList());
+            //学生-旷课次数关联集合
+            List<Map<Integer, Integer>> continuousAbsenteeismTimesByUsersAndMusicGroup = musicGroupStudentFeeDao.findContinuousAbsenteeismTimesByUsersAndMusicGroup(classGroup.getMusicGroupId(), userIds);
+            Map<Integer, Integer> continuousAbsenteeismTimesWithUser = MapUtil.convertIntegerMap(continuousAbsenteeismTimesByUsersAndMusicGroup);
+            //学生签到记录列表
+            List<StudentAttendanceResponse> studentAttendances = studentAttendanceDao.findByClassGroupAndUsers(queryInfo.getClassGroupId(), userIds);
+            //学生签到状态统计列表
+            List<StudentAttendanceStatusCountDto> studentAttendanceStatusCountDtos = studentAttendanceDao.countStudentAttendanceStatus(queryInfo.getClassGroupId(), userIds);
+            Map<Integer, List<StudentAttendanceStatusCountDto>> studentAttendanceStatusCountDtosByUser = studentAttendanceStatusCountDtos.stream().collect(Collectors.groupingBy(StudentAttendanceStatusCountDto::getUserId));
+
+            if (!CollectionUtils.isEmpty(studentAttendances)) {
+                //学生-签到记录关联集合
+                Map<Integer, List<StudentAttendanceResponse>> studentAttendanceByUser = studentAttendances.stream().collect(Collectors.groupingBy(StudentAttendanceResponse::getUserId));
+
+                dataList.forEach(student -> {
+                    //判断是否是连续签到
+                    Integer continuousAbsenteeismTimes = continuousAbsenteeismTimesWithUser.get(student.getUserId());
+                    if (Objects.nonNull(continuousAbsenteeismTimes)) {
+                        if (continuousAbsenteeismTimes >= 3) {
+                            student.setTruant(true);
+                        }
+                    }
+                    //当前学生的签到状态统计
+                    List<StudentAttendanceStatusCountDto> currentStudentAttendanceStatusCountDtos = studentAttendanceStatusCountDtosByUser.get(student.getUserId());
+                    if (!CollectionUtils.isEmpty(currentStudentAttendanceStatusCountDtos)) {
+                        Map<StudentAttendanceStatusEnum, Integer> statusAndNumMap = currentStudentAttendanceStatusCountDtos.stream().collect(Collectors.toMap(StudentAttendanceStatusCountDto::getStatus, StudentAttendanceStatusCountDto::getNum));
+                        student.setNormalDay(statusAndNumMap.get(StudentAttendanceStatusEnum.NORMAL));
+                        student.setTruantDay(statusAndNumMap.get(StudentAttendanceStatusEnum.TRUANT));
+                        student.setLeaveDay(statusAndNumMap.get(StudentAttendanceStatusEnum.LEAVE));
+                    }
+
+                    //当前学生签到记录
+                    List<StudentAttendanceResponse> studentAttendanceResps = studentAttendanceByUser.get(student.getUserId());
+                    if (Objects.nonNull(studentAttendanceResps)) {
+                        student.setList(studentAttendanceResps);
+                    }
+                });
+            }
+        }
+        if (count == 0) {
+            dataList = new ArrayList<>();
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
+    }
+
+    @Override
+    public CourseScheduleResponse getStatisticsInfo(Integer classGroupId) {
+        if (Objects.isNull(classGroupId)) {
+            throw new BizException("请指定班级");
+        }
+        ClassGroup classGroup = classGroupDao.get(classGroupId);
+        CourseScheduleResponse courseScheduleResp = new CourseScheduleResponse();
+        if (Objects.nonNull(classGroup)) {
+            if (Objects.nonNull(classGroup.getCurrentClassTimes()) && Objects.nonNull(classGroup.getTotalClassTimes())) {
+                courseScheduleResp.setAlreadyInClass(classGroup.getCurrentClassTimes() + "/" + classGroup.getTotalClassTimes());
+            }
+            if (Objects.nonNull(classGroup.getStudentNum())) {
+                courseScheduleResp.setStudentNum(classGroup.getStudentNum());
+            }
+            Date latestSignInDate = studentAttendanceDao.findLatestSignInDate(classGroupId);
+            if (Objects.nonNull(latestSignInDate)) {
+                courseScheduleResp.setClassDate(DateUtil.format(latestSignInDate, DateUtil.DATE_FORMAT_MIN));
+                courseScheduleResp.setClassTime(DateUtil.date2Week(latestSignInDate));
+            }
+            courseScheduleResp.setLeagueNum(musicGroupQuitDao.countMusicGroupQuitNum(classGroup.getMusicGroupId()));
+        }
+        return courseScheduleResp;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public void addStudentAttendanceRecord(Integer courseScheduleId, Integer userId, StudentAttendanceStatusEnum statusEnum, SignStatusEnum signStatusEnum) {
+        CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
+        ClassGroup classGroup = classGroupDao.findByCourseSchedule(courseScheduleId, 0);
+        StudentAttendance studentAttendance = studentAttendanceDao.findByStatusAndCourseScheduleId(userId, courseScheduleId);
+        Date date = new Date();
+        if (studentAttendance == null) {
+            studentAttendance = new StudentAttendance();
+            studentAttendance.setClassGroupId(classGroup.getId());
+            studentAttendance.setCourseScheduleId(courseScheduleId.longValue());
+            studentAttendance.setCurrentClassTimes(classGroup.getCurrentClassTimes() + 1);
+            studentAttendance.setGroupType(classGroup.getGroupType());
+            studentAttendance.setMusicGroupId(classGroup.getMusicGroupId());
+            studentAttendance.setUserId(userId);
+            studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
+            if (signStatusEnum == SignStatusEnum.SIGN_IN) {
+                if (courseSchedule.getStudentNum() == null) {
+                    courseSchedule.setStudentNum(0);
+                }
+                courseSchedule.setStudentNum(courseSchedule.getStudentNum() + 1);
+            }
+            studentAttendanceDao.insert(studentAttendance);
+        } else {
+            studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
+            studentAttendance.setUpdateTime(date);
+        }
 //		Date signInTime = studentAttendance.getSignInTime();
-		//没有签到信息才会生成
-		if(signStatusEnum == SignStatusEnum.SIGN_IN && studentAttendance.getSignInTime() == null){
-			//判断是否在签到时间段内(课程开始前20~结束前)
+        //没有签到信息才会生成
+        if (signStatusEnum == SignStatusEnum.SIGN_IN && studentAttendance.getSignInTime() == null) {
+            //判断是否在签到时间段内(课程开始前20~结束前)
 //			int advanceSignMinutes = Integer.parseInt(sysConfigDao.findConfigValue(SysConfigService.ADVANCE_SIGN_IN_MINUTES));
 //			String classDate = DateUtil.format(courseSchedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
 //			String startClassTime = DateUtil.format(courseSchedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
 //			String endClassTime = DateUtil.format(courseSchedule.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-			//上课时间
+            //上课时间
 //			Date classStartDateTime = DateUtil.stringToDate(classDate + " " + startClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
 //			Date classEndDateTime = DateUtil.stringToDate(classDate + " " + endClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
 //			Date addMinutes = DateUtil.addMinutes(classStartDateTime, -60);
-			//课程结束前进入,算正常
-			studentAttendance.setStatus(statusEnum);
-			studentAttendance.setSignInTime(date);
+            //课程结束前进入,算正常
+            studentAttendance.setStatus(statusEnum);
+            studentAttendance.setSignInTime(date);
 
-			courseSchedule.setUpdateTime(date);
+            courseSchedule.setUpdateTime(date);
 //				courseSchedule.setStudentNum((courseSchedule.getStudentNum() == null?0:courseSchedule.getStudentNum()) + 1);
-			courseScheduleDao.update(courseSchedule);
+            courseScheduleDao.update(courseSchedule);
 			/*if(DateUtil.minutesBetween(addMinutes,date) >= 0 && DateUtil.minutesBetween(date,classEndDateTime) > 0){
 
 			}*/
-		}else if(signStatusEnum == SignStatusEnum.SIGN_OUT){
-			String classDate = DateUtil.format(courseSchedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
-			String startClassTime = DateUtil.format(courseSchedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-			String endClassTime = DateUtil.format(courseSchedule.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-			//上课时间
-			Date classStartDateTime = DateUtil.stringToDate(classDate + " " + startClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-			Date classEndDateTime = DateUtil.stringToDate(classDate + " " + endClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-			if(DateUtil.minutesBetween(classEndDateTime,date) >= 0){
-				String continueCourseTime = sysConfigDao.findConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME);
-				if(StringUtils.isEmpty(continueCourseTime)){
-					continueCourseTime = "5";
-				}
-				List<CourseSchedule> courseSchedules = new ArrayList<>();
-				CourseSchedule cs = courseSchedule;
-				while (true){
-					//获取当前课程的所有连堂课列表
-					String courseClassDate = DateUtil.format(cs.getClassDate(), DateUtil.DEFAULT_PATTERN);
-					String courseEndDateTime = DateUtil.format(cs.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-					cs = courseScheduleDao.queryRepairContinueCourse(cs,continueCourseTime,courseClassDate + " " + courseEndDateTime);
-					//存在连堂课
-					if(cs != null){
-						courseSchedules.add(cs);
-					}else {
-						break;
-					}
-				}
-				if(courseSchedules.size() > 0){
-					//获取总上课时长
-					int totalMinutes = DateUtil.minutesBetween(classStartDateTime, date);
-					//减去第一节课时长
-					int firstMinutes = courseScheduleDao.getSingleClassMinutes(courseScheduleId.longValue());
-					totalMinutes -= firstMinutes;
-					if(totalMinutes > 0){
-						String courseClassDate;
-						String courseStartDateTime;
-						String courseEndDateTime;
-						for (int i = 0; i < courseSchedules.size(); i++) {
-							courseClassDate = DateUtil.format(courseSchedules.get(i).getClassDate(), DateUtil.DEFAULT_PATTERN);
-							courseStartDateTime = DateUtil.format(courseSchedules.get(i).getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-							courseEndDateTime = DateUtil.format(courseSchedules.get(i).getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-							Date startDateTime = DateUtil.stringToDate(courseClassDate + " " + courseStartDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-							Date endDateTime = DateUtil.stringToDate(courseClassDate + " " + courseEndDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-							StudentAttendance byStatusAndCourseScheduleId = studentAttendanceDao.findByStatusAndCourseScheduleId(userId, courseSchedules.get(i).getId().intValue());
-							Date signOutTime = date;
-							if(date.before(startDateTime)){
-								continue;
-							}
-							if(i < courseSchedules.size() - 1 && date.after(endDateTime)){
-								//不是最后一节连堂课,并且签退时间大于课程结束时间,签退时间等于课程结束时间
-								signOutTime = endDateTime;
-							}
-							if(byStatusAndCourseScheduleId != null){
-								if(byStatusAndCourseScheduleId.getSignOutTime() != null){
-									continue;
-								}
-								if(byStatusAndCourseScheduleId.getSignInTime() != null){
-									startDateTime = null;
-								}
-								byStatusAndCourseScheduleId.setSignInTime(startDateTime);
-								byStatusAndCourseScheduleId.setSignOutTime(signOutTime);
-								byStatusAndCourseScheduleId.setStatus(statusEnum);
-								byStatusAndCourseScheduleId.setUpdateTime(date);
-								studentAttendanceDao.update(byStatusAndCourseScheduleId);
-							}else {
-								byStatusAndCourseScheduleId = new StudentAttendance();
-								byStatusAndCourseScheduleId.setSignOutTime(signOutTime);
-								byStatusAndCourseScheduleId.setStatus(statusEnum);
-								byStatusAndCourseScheduleId.setSignInTime(startDateTime);
-								byStatusAndCourseScheduleId.setUpdateTime(date);
-								byStatusAndCourseScheduleId.setUserId(userId);
-								byStatusAndCourseScheduleId.setTeacherId(courseSchedule.getActualTeacherId());
-								byStatusAndCourseScheduleId.setClassGroupId(courseSchedules.get(i).getClassGroupId());
-								byStatusAndCourseScheduleId.setCourseScheduleId(courseSchedules.get(i).getId());
-								byStatusAndCourseScheduleId.setMusicGroupId(courseSchedules.get(i).getMusicGroupId());
-								byStatusAndCourseScheduleId.setGroupType(courseSchedules.get(i).getGroupType());
-								byStatusAndCourseScheduleId.setCurrentClassTimes(classGroup.getCurrentClassTimes() + 1);
-								studentAttendanceDao.insert(byStatusAndCourseScheduleId);
-							}
-							if(studentAttendance.getSignOutTime() == null){
-								studentAttendance.setStatus(statusEnum);
-								studentAttendance.setSignOutTime(classEndDateTime);
-							}
-						}
-					}
-				}else {
-					studentAttendance.setStatus(statusEnum);
-					studentAttendance.setSignOutTime(date);
-				}
-				if(studentAttendance.getSignOutTime() == null){
-					studentAttendance.setStatus(statusEnum);
-					studentAttendance.setSignOutTime(date);
-				}
-			}else {
-				studentAttendance.setStatus(statusEnum);
-				studentAttendance.setSignOutTime(date);
-			}
-		}
-		studentAttendanceDao.update(studentAttendance);
-	}
-
-	@Override
-	public PageInfo<StudentAttendance> findStudentAttendance(QueryInfo queryInfo) {
-		PageInfo<StudentAttendance> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
-		Map<String, Object> params = new HashMap<>();
-		MapUtil.populateMap(params, queryInfo);
-
-		List<StudentAttendance> dataList = null;
-		int count = studentAttendanceDao.countStudentAttendance(params);
-		if (count > 0) {
-			pageInfo.setTotal(count);
-			params.put("offset", pageInfo.getOffset());
-			dataList = studentAttendanceDao.findStudentAttendance(params);
-		}
-		if (count == 0) {
-			dataList = new ArrayList<>();
-		}
-		pageInfo.setRows(dataList);
-		return pageInfo;
-	}
-
-	@Override
-	public void repairStudentAttendance(Integer month) {
-		//获取所有有老师考勤的课程记录,正常签退,当月线上课,有学员签到记录
-		List<CourseSchedule> courseScheduleList = courseScheduleDao.queryScheduleByAttendance(month);
-		//是否是连堂课
-		String continueCourseTime = sysConfigDao.findConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME);
-		if(StringUtils.isEmpty(continueCourseTime)){
-			continueCourseTime = "5";
-		}
-		Date date = new Date();
-		for (CourseSchedule courseSchedule : courseScheduleList) {
-			log.info("课程编号: {}",courseSchedule.getId());
-			//只会修复签到的学员考勤
-			List<StudentAttendance> byCourseId = studentAttendanceDao.findByCourseId(courseSchedule.getId());
-			if(byCourseId == null || byCourseId.size() == 0){
-				break;
-			}
-			List<CourseSchedule> courseSchedules = new ArrayList<>();
-			CourseSchedule cs = courseSchedule;
-			while (true){
-				//获取当前课程的所有连堂课列表
-				String courseClassDate = DateUtil.format(cs.getClassDate(), DateUtil.DEFAULT_PATTERN);
-				String courseEndDateTime = DateUtil.format(cs.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-				cs = courseScheduleDao.queryRepairContinueCourse(cs,continueCourseTime,courseClassDate + " " + courseEndDateTime);
-				//存在连堂课
-				if(cs != null){
-					courseSchedules.add(cs);
-				}else {
-					break;
-				}
-			}
+        } else if (signStatusEnum == SignStatusEnum.SIGN_OUT) {
+            String classDate = DateUtil.format(courseSchedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
+            String startClassTime = DateUtil.format(courseSchedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+            String endClassTime = DateUtil.format(courseSchedule.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+            //上课时间
+            Date classStartDateTime = DateUtil.stringToDate(classDate + " " + startClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+            Date classEndDateTime = DateUtil.stringToDate(classDate + " " + endClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+            if (DateUtil.minutesBetween(classEndDateTime, date) >= 0) {
+                String continueCourseTime = sysConfigDao.findConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME);
+                if (StringUtils.isEmpty(continueCourseTime)) {
+                    continueCourseTime = "5";
+                }
+                List<CourseSchedule> courseSchedules = new ArrayList<>();
+                CourseSchedule cs = courseSchedule;
+                while (true) {
+                    //获取当前课程的所有连堂课列表
+                    String courseClassDate = DateUtil.format(cs.getClassDate(), DateUtil.DEFAULT_PATTERN);
+                    String courseEndDateTime = DateUtil.format(cs.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+                    cs = courseScheduleDao.queryRepairContinueCourse(cs, continueCourseTime, courseClassDate + " " + courseEndDateTime);
+                    //存在连堂课
+                    if (cs != null) {
+                        courseSchedules.add(cs);
+                    } else {
+                        break;
+                    }
+                }
+                if (courseSchedules.size() > 0) {
+                    //获取总上课时长
+                    int totalMinutes = DateUtil.minutesBetween(classStartDateTime, date);
+                    //减去第一节课时长
+                    int firstMinutes = courseScheduleDao.getSingleClassMinutes(courseScheduleId.longValue());
+                    totalMinutes -= firstMinutes;
+                    if (totalMinutes > 0) {
+                        String courseClassDate;
+                        String courseStartDateTime;
+                        String courseEndDateTime;
+                        for (int i = 0; i < courseSchedules.size(); i++) {
+                            courseClassDate = DateUtil.format(courseSchedules.get(i).getClassDate(), DateUtil.DEFAULT_PATTERN);
+                            courseStartDateTime = DateUtil.format(courseSchedules.get(i).getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+                            courseEndDateTime = DateUtil.format(courseSchedules.get(i).getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+                            Date startDateTime = DateUtil.stringToDate(courseClassDate + " " + courseStartDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+                            Date endDateTime = DateUtil.stringToDate(courseClassDate + " " + courseEndDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+                            StudentAttendance byStatusAndCourseScheduleId = studentAttendanceDao.findByStatusAndCourseScheduleId(userId, courseSchedules.get(i).getId().intValue());
+                            Date signOutTime = date;
+                            if (date.before(startDateTime)) {
+                                continue;
+                            }
+                            if (i < courseSchedules.size() - 1 && date.after(endDateTime)) {
+                                //不是最后一节连堂课,并且签退时间大于课程结束时间,签退时间等于课程结束时间
+                                signOutTime = endDateTime;
+                            }
+                            if (byStatusAndCourseScheduleId != null) {
+                                if (byStatusAndCourseScheduleId.getSignOutTime() != null) {
+                                    continue;
+                                }
+                                if (byStatusAndCourseScheduleId.getSignInTime() != null) {
+                                    startDateTime = null;
+                                }
+                                byStatusAndCourseScheduleId.setSignInTime(startDateTime);
+                                byStatusAndCourseScheduleId.setSignOutTime(signOutTime);
+                                byStatusAndCourseScheduleId.setStatus(statusEnum);
+                                byStatusAndCourseScheduleId.setUpdateTime(date);
+                                studentAttendanceDao.update(byStatusAndCourseScheduleId);
+                            } else {
+                                byStatusAndCourseScheduleId = new StudentAttendance();
+                                byStatusAndCourseScheduleId.setSignOutTime(signOutTime);
+                                byStatusAndCourseScheduleId.setStatus(statusEnum);
+                                byStatusAndCourseScheduleId.setSignInTime(startDateTime);
+                                byStatusAndCourseScheduleId.setUpdateTime(date);
+                                byStatusAndCourseScheduleId.setUserId(userId);
+                                byStatusAndCourseScheduleId.setTeacherId(courseSchedule.getActualTeacherId());
+                                byStatusAndCourseScheduleId.setClassGroupId(courseSchedules.get(i).getClassGroupId());
+                                byStatusAndCourseScheduleId.setCourseScheduleId(courseSchedules.get(i).getId());
+                                byStatusAndCourseScheduleId.setMusicGroupId(courseSchedules.get(i).getMusicGroupId());
+                                byStatusAndCourseScheduleId.setGroupType(courseSchedules.get(i).getGroupType());
+                                byStatusAndCourseScheduleId.setCurrentClassTimes(classGroup.getCurrentClassTimes() + 1);
+                                studentAttendanceDao.insert(byStatusAndCourseScheduleId);
+                            }
+                            if (studentAttendance.getSignOutTime() == null) {
+                                studentAttendance.setStatus(statusEnum);
+                                studentAttendance.setSignOutTime(classEndDateTime);
+                            }
+                        }
+                    }
+                } else {
+                    studentAttendance.setStatus(statusEnum);
+                    studentAttendance.setSignOutTime(date);
+                }
+                if (studentAttendance.getSignOutTime() == null) {
+                    studentAttendance.setStatus(statusEnum);
+                    studentAttendance.setSignOutTime(date);
+                }
+            } else {
+                studentAttendance.setStatus(statusEnum);
+                studentAttendance.setSignOutTime(date);
+            }
+        }
+        studentAttendanceDao.update(studentAttendance);
+    }
+
+    @Override
+    public PageInfo<StudentAttendance> findStudentAttendance(QueryInfo queryInfo) {
+        PageInfo<StudentAttendance> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+        Map<String, Object> params = new HashMap<>();
+        MapUtil.populateMap(params, queryInfo);
+
+        List<StudentAttendance> dataList = null;
+        int count = studentAttendanceDao.countStudentAttendance(params);
+        if (count > 0) {
+            pageInfo.setTotal(count);
+            params.put("offset", pageInfo.getOffset());
+            dataList = studentAttendanceDao.findStudentAttendance(params);
+        }
+        if (count == 0) {
+            dataList = new ArrayList<>();
+        }
+        pageInfo.setRows(dataList);
+        return pageInfo;
+    }
+
+    @Override
+    public void repairStudentAttendance(Integer month) {
+        //获取所有有老师考勤的课程记录,正常签退,当月线上课,有学员签到记录
+        List<CourseSchedule> courseScheduleList = courseScheduleDao.queryScheduleByAttendance(month);
+        //是否是连堂课
+        String continueCourseTime = sysConfigDao.findConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME);
+        if (StringUtils.isEmpty(continueCourseTime)) {
+            continueCourseTime = "5";
+        }
+        Date date = new Date();
+        for (CourseSchedule courseSchedule : courseScheduleList) {
+            log.info("课程编号: {}", courseSchedule.getId());
+            //只会修复签到的学员考勤
+            List<StudentAttendance> byCourseId = studentAttendanceDao.findByCourseId(courseSchedule.getId());
+            if (byCourseId == null || byCourseId.size() == 0) {
+                break;
+            }
+            List<CourseSchedule> courseSchedules = new ArrayList<>();
+            CourseSchedule cs = courseSchedule;
+            while (true) {
+                //获取当前课程的所有连堂课列表
+                String courseClassDate = DateUtil.format(cs.getClassDate(), DateUtil.DEFAULT_PATTERN);
+                String courseEndDateTime = DateUtil.format(cs.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+                cs = courseScheduleDao.queryRepairContinueCourse(cs, continueCourseTime, courseClassDate + " " + courseEndDateTime);
+                //存在连堂课
+                if (cs != null) {
+                    courseSchedules.add(cs);
+                } else {
+                    break;
+                }
+            }
 
 //			List<BasicUserDto> students = courseScheduleStudentPaymentDao.findStudents(courseSchedule.getId());
-			if(courseSchedules.size() > 0) {
-				//获取当前课程老师总上课时长
-				int totalMinutes = teacherAttendanceDao.getTotalMinutes(courseSchedule.getId(),courseSchedule.getActualTeacherId());
-				int firstMinutes = courseScheduleDao.getSingleClassMinutes(courseSchedule.getId());
-				totalMinutes -= firstMinutes;
-				if (totalMinutes > 0) {
-					String courseClassDate;
-					String courseStartDateTime;
-					String courseEndDateTime;
-					for (CourseSchedule e:courseSchedules) {
-						//获取当前课程的单节课时长
-						int signClassMinutes = courseScheduleDao.getSingleClassMinutes(e.getId());
-						totalMinutes -= signClassMinutes;
-						if (totalMinutes >= 0) {
-							//补充签到签退时间
-							courseClassDate = DateUtil.format(e.getClassDate(), DateUtil.DEFAULT_PATTERN);
-							courseStartDateTime = DateUtil.format(e.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-							courseEndDateTime = DateUtil.format(e.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-							Date startDateTime = DateUtil.stringToDate(courseClassDate + " " + courseStartDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-							Date endDateTime = DateUtil.stringToDate(courseClassDate + " " + courseEndDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-							byCourseId.forEach(student->{
-								StudentAttendance byStatusAndCourseScheduleId = studentAttendanceDao.findByStatusAndCourseScheduleId(student.getUserId(), e.getId().intValue());
-								if(byStatusAndCourseScheduleId == null){
-									byStatusAndCourseScheduleId = new StudentAttendance();
-									byStatusAndCourseScheduleId.setSignOutTime(endDateTime);
-									byStatusAndCourseScheduleId.setStatus(StudentAttendanceStatusEnum.NORMAL);
-									byStatusAndCourseScheduleId.setSignInTime(startDateTime);
-									byStatusAndCourseScheduleId.setUpdateTime(date);
-									byStatusAndCourseScheduleId.setUserId(student.getUserId());
-									byStatusAndCourseScheduleId.setTeacherId(e.getActualTeacherId());
-									byStatusAndCourseScheduleId.setClassGroupId(e.getClassGroupId());
-									byStatusAndCourseScheduleId.setMusicGroupId(e.getMusicGroupId());
-									byStatusAndCourseScheduleId.setGroupType(e.getGroupType());
-									byStatusAndCourseScheduleId.setCourseScheduleId(e.getId());
-									studentAttendanceDao.insert(byStatusAndCourseScheduleId);
-								}
-							});
-						}
-					}
-				}
-			}
-		}
-	}
-
-	@Override
-	public StudentAttendance findByStatusAndCourseScheduleId(Long courseId, Integer userId) {
-		return studentAttendanceDao.findByStatusAndCourseScheduleId(userId,courseId.intValue());
-	}
-
-	@Override
-	public void cleanCourseStudentSignOut(Long courseId, Integer userId) {
-		studentAttendanceDao.cleanCourseStudentSignOut(courseId,userId);
-	}
+            if (courseSchedules.size() > 0) {
+                //获取当前课程老师总上课时长
+                int totalMinutes = teacherAttendanceDao.getTotalMinutes(courseSchedule.getId(), courseSchedule.getActualTeacherId());
+                int firstMinutes = courseScheduleDao.getSingleClassMinutes(courseSchedule.getId());
+                totalMinutes -= firstMinutes;
+                if (totalMinutes > 0) {
+                    String courseClassDate;
+                    String courseStartDateTime;
+                    String courseEndDateTime;
+                    for (CourseSchedule e : courseSchedules) {
+                        //获取当前课程的单节课时长
+                        int signClassMinutes = courseScheduleDao.getSingleClassMinutes(e.getId());
+                        totalMinutes -= signClassMinutes;
+                        if (totalMinutes >= 0) {
+                            //补充签到签退时间
+                            courseClassDate = DateUtil.format(e.getClassDate(), DateUtil.DEFAULT_PATTERN);
+                            courseStartDateTime = DateUtil.format(e.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+                            courseEndDateTime = DateUtil.format(e.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+                            Date startDateTime = DateUtil.stringToDate(courseClassDate + " " + courseStartDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+                            Date endDateTime = DateUtil.stringToDate(courseClassDate + " " + courseEndDateTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+                            byCourseId.forEach(student -> {
+                                StudentAttendance byStatusAndCourseScheduleId = studentAttendanceDao.findByStatusAndCourseScheduleId(student.getUserId(), e.getId().intValue());
+                                if (byStatusAndCourseScheduleId == null) {
+                                    byStatusAndCourseScheduleId = new StudentAttendance();
+                                    byStatusAndCourseScheduleId.setSignOutTime(endDateTime);
+                                    byStatusAndCourseScheduleId.setStatus(StudentAttendanceStatusEnum.NORMAL);
+                                    byStatusAndCourseScheduleId.setSignInTime(startDateTime);
+                                    byStatusAndCourseScheduleId.setUpdateTime(date);
+                                    byStatusAndCourseScheduleId.setUserId(student.getUserId());
+                                    byStatusAndCourseScheduleId.setTeacherId(e.getActualTeacherId());
+                                    byStatusAndCourseScheduleId.setClassGroupId(e.getClassGroupId());
+                                    byStatusAndCourseScheduleId.setMusicGroupId(e.getMusicGroupId());
+                                    byStatusAndCourseScheduleId.setGroupType(e.getGroupType());
+                                    byStatusAndCourseScheduleId.setCourseScheduleId(e.getId());
+                                    studentAttendanceDao.insert(byStatusAndCourseScheduleId);
+                                }
+                            });
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public StudentAttendance findByStatusAndCourseScheduleId(Long courseId, Integer userId) {
+        return studentAttendanceDao.findByStatusAndCourseScheduleId(userId, courseId.intValue());
+    }
+
+    @Override
+    public void cleanCourseStudentSignOut(Long courseId, Integer userId) {
+        studentAttendanceDao.cleanCourseStudentSignOut(courseId, userId);
+    }
 }

+ 28 - 8
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -3030,15 +3030,15 @@
 
     <select id="getVipGroupExport" resultMap="com.ym.mec.biz.dal.dao.PracticeGroupDao.courseGroupExport">
         SELECT cssp.user_id_ student_id_,
-        su.username_ student_name_,
-        o.name_ organ_name_,
-        GROUP_CONCAT(DISTINCT edut.`real_name_`) edu_teacher_name_,
-        GROUP_CONCAT(DISTINCT edut.`id_`) edu_teacher_ids_
+            su.username_ student_name_,
+            o.name_ organ_name_,
+            GROUP_CONCAT(DISTINCT edut.`real_name_`) edu_teacher_name_,
+            GROUP_CONCAT(DISTINCT edut.`id_`) edu_teacher_ids_
         FROM `course_schedule_student_payment` cssp
-        LEFT JOIN `vip_group` vg ON vg.`id_` = cssp.`music_group_id_` AND cssp.`group_type_` = 'VIP'
-        LEFT JOIN `organization` o ON o.`id_` = vg.`organ_id_`
-        LEFT JOIN `sys_user` su ON su.`id_` = cssp.`user_id_`
-        LEFT JOIN `sys_user` edut ON edut.`id_` = vg.`educational_teacher_id_`
+            LEFT JOIN `vip_group` vg ON vg.`id_` = cssp.`music_group_id_` AND cssp.`group_type_` = 'VIP'
+            LEFT JOIN `organization` o ON o.`id_` = vg.`organ_id_`
+            LEFT JOIN `sys_user` su ON su.`id_` = cssp.`user_id_`
+            LEFT JOIN `sys_user` edut ON edut.`id_` = vg.`educational_teacher_id_`
         WHERE cssp.`group_type_` = 'VIP'
         AND vg.group_status_!=3
         <if test="organIds != null and organIds != ''">
@@ -3063,6 +3063,26 @@
         AND (cs.del_flag_ IS NULL OR cs.del_flag_ =0)
         GROUP BY cssp.user_id_;
     </select>
+
+    <select id="getStudentVipCourseInfo" resultMap="com.ym.mec.biz.dal.dao.PracticeGroupDao.courseGroupExport">
+        SELECT MIN(concat(cs.`class_date_`,' ',cs.`start_class_time_` )) class_start_date_,
+        MAX(concat(cs.`class_date_`,' ',cs.`start_class_time_` )) class_end_date_,cssp.user_id_ student_id_,
+        GROUP_CONCAT(DISTINCT su.`real_name_`) teacher_name_,GROUP_CONCAT(DISTINCT cs.`actual_teacher_id_`) teacher_ids_
+        FROM course_schedule_student_payment cssp
+        LEFT JOIN course_schedule cs on cs.id_ = cssp.course_schedule_id_
+        LEFT JOIN sys_user su on cs.actual_teacher_id_ = su.id_
+        LEFT JOIN vip_group vg ON cssp.music_group_id_=vg.id_
+        WHERE cssp.user_id_ IN
+        <foreach collection="studentIds" separator="," open="(" close=")" item="studentId">
+            #{studentId}
+        </foreach>
+        AND cssp.group_type_ = 'VIP'
+        AND vg.group_status_!=3
+        AND (cs.is_lock_ IS NULL OR cs.is_lock_ =0)
+        AND (cs.del_flag_ IS NULL OR cs.del_flag_ =0)
+        GROUP BY cssp.user_id_;
+    </select>
+
     <select id="getLastCourse" resultMap="CourseSchedule">
         SELECT cs.* FROM course_schedule cs
         LEFT JOIN teacher_attendance ta ON cs.id_ = ta.course_schedule_id_ AND ta.teacher_id_ = cs.actual_teacher_id_

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

@@ -640,7 +640,7 @@
 		CASE WHEN cs.type_ = 'SINGLE' THEN '单技课' WHEN cs.type_ = 'MIX' THEN '合奏课' WHEN cs.type_ = 'HIGH' THEN '小班课'  WHEN cs.type_ = 'VIP' THEN 'vip课'
 		WHEN cs.type_ = 'DEMO' THEN '试听课'  WHEN cs.type_ = 'COMPREHENSIVE' THEN '综合课'  WHEN cs.type_ = 'PRACTICE' THEN '练习课'  WHEN cs.type_ = 'ENLIGHTENMENT' THEN '启蒙课'
 		WHEN cs.type_ = 'TRAINING_SINGLE' THEN '集训单技课'  WHEN cs.type_ = 'TRAINING_MIX' THEN '集训合奏课' WHEN cs.type_ = 'CLASSROOM' THEN '课堂课'
-		WHEN cs.type_ = 'COMM' THEN '对外课程'  WHEN cs.type_ = 'HIGH_ONLINE' THEN '线上基础技能课'  ELSE '乐团网管课' END courseScheduleType,
+		WHEN cs.type_ = 'COMM' THEN '对外课程'  WHEN cs.type_ = 'HIGH_ONLINE' THEN '网络基础训练课'  ELSE '乐团网管课' END courseScheduleType,
 		cs.class_date_ classDate,cs.start_class_time_ courseScheduleStartTime,cs.end_class_time_ courseScheduleEndTime,
 		ROUND((UNIX_TIMESTAMP(cs.end_class_time_)-UNIX_TIMESTAMP(cs.start_class_time_))/60) signCourseScheduleTime,
 		ts.actual_salary_ price,CASE WHEN s.name_ IS NULL THEN '网络教室' ELSE s.name_ END address,

+ 9 - 2
mec-biz/src/main/resources/config/mybatis/OrganizationMapper.xml

@@ -18,6 +18,7 @@
         <result column="linkman_" property="linkman"/>
         <result column="mobile_" property="mobile"/>
         <result column="address_" property="address"/>
+        <result column="full_job_resource_" property="fullJobResource"/>
     </resultMap>
 
     <!-- 根据主键查询一条记录 -->
@@ -33,8 +34,8 @@
     <!-- 向数据库增加一条记录 -->
     <insert id="insert" parameterType="com.ym.mec.biz.dal.entity.Organization" useGeneratedKeys="true" keyColumn="id"
             keyProperty="id">
-        INSERT INTO organization (id_,name_,area_id_,create_time_,update_time_,register_date_,linkman_,mobile_,address_)
-        VALUES(#{id},#{name},#{areaId},now(),now(),#{registerDate},#{linkman},#{mobile},#{address})
+        INSERT INTO organization (id_,name_,area_id_,create_time_,update_time_,register_date_,linkman_,mobile_,address_,full_job_resource_)
+        VALUES(#{id},#{name},#{areaId},now(),now(),#{registerDate},#{linkman},#{mobile},#{address},#{fullJobResource})
     </insert>
 
     <!-- 根据主键查询一条记录 -->
@@ -44,6 +45,9 @@
             <if test="delFlag != null">
                 del_flag_ = #{delFlag,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>
+            <if test="fullJobResource != null">
+                full_job_resource_ = #{fullJobResource},
+            </if>
             <if test="areaId != null">
                 area_id_ = #{areaId},
             </if>
@@ -76,6 +80,9 @@
 
     <sql id="queryPageSql">
         <where>
+            <if test="fullJobResource != null">
+                and o.full_job_resource_ = #{fullJobResource}
+            </if>
             <if test="delFlag != null">
                 and o.del_flag_ = #{delFlag,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
             </if>

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

@@ -806,7 +806,7 @@ public class ExportController extends BaseController {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (!sysUser.getIsSuperAdmin()) {
             Employee employee = employeeDao.get(sysUser.getId());
-            if (StringUtils.isEmpty(queryInfo.getRoutingOrganId()) && queryInfo.getOrderType().equals("3")) {
+            if (StringUtils.isEmpty(queryInfo.getRoutingOrganId()) && "3".equals(queryInfo.getOrderType())) {
                 queryInfo.setRoutingOrganId(employee.getOrganIdList());
             } else if (StringUtils.isEmpty(queryInfo.getOrganId())) {
                 queryInfo.setOrganId(employee.getOrganIdList());
@@ -1225,7 +1225,7 @@ public class ExportController extends BaseController {
         }
         OutputStream outputStream = response.getOutputStream();
         Set<Integer> studentIds = vipGroupExports.stream().map(CourseGroupExportDto::getStudentId).collect(Collectors.toSet());
-        List<CourseGroupExportDto> studentCourseInfos = courseScheduleDao.getStudentCourseInfo(studentIds, GroupType.VIP);
+        List<CourseGroupExportDto> studentCourseInfos = courseScheduleDao.getStudentVipCourseInfo(studentIds);
         List<CourseGroupExportDto> totalClassTimes = courseScheduleDao.getStudentCourseScheduleNum(studentIds, GroupType.VIP, null);
         List<CourseGroupExportDto> noStartClassTimes = courseScheduleDao.getStudentCourseScheduleNum(studentIds, GroupType.VIP, CourseStatusEnum.NOT_START);
         for (CourseGroupExportDto vipGroupExport : vipGroupExports) {
@@ -2063,7 +2063,7 @@ public class ExportController extends BaseController {
 
             String[] header = {"老师编号", "姓名", "分部", "工作类型", "在职状态", "老师状态", "1v1", "1v2", "1v3", "1v4", "1v5", "1v6", "1v7", "网管课", "单技课2.0", "合奏课2.0", "综合课2.0", "集训单技课2.0", "集训合奏课2.0",
                     "基础技能课2.0", "课堂课2.0", "单技课3.0", "合奏课3.0", "综合课3.0", "集训单技课3.0", "集训合奏课3.0",
-                    "基础技能课3.0", "课堂课3.0", "线上基础技能课1v3", "线上基础技能课1v4", "线上基础技能课1v5", "乐团网管课1v1"};
+                    "基础技能课3.0", "课堂课3.0", "网络基础训练课1v3", "网络基础训练课1v4", "网络基础训练课1v5", "乐团网管课1v1"};
             String[] body = {"userId", "realName", "organName", "jobNature", "demissionStatus", "status", "vip1", "vip2", "vip3", "vip4", "vip5", "vip6", "vip7",
                     "practiceSalary", "singleSalary2", "mixSalary2", "comprehensiveSalary2", "traningSigleSalary2", "traningMixSalary2", "highSalary2",
                     "classroomSalary2", "singleSalary", "mixSalary", "comprehensiveSalary", "traningSigleSalary", "traningMixSalary", "highSalary",

+ 0 - 13
mec-web/src/main/java/com/ym/mec/web/controller/OrganizationController.java

@@ -33,19 +33,6 @@ public class OrganizationController extends BaseController {
 		if (sysUser == null) {
 			return failed("用户信息获取失败");
 		}
-		/*if(!sysUser.getIsSuperAdmin()){
-			Employee employee = employeeDao.get(sysUser.getId());
-			if (StringUtils.isEmpty(queryInfo.getOrganId())) {
-				queryInfo.setOrganId(employee.getOrganIdList());
-			}else if(StringUtils.isEmpty(employee.getOrganIdList())){
-				return failed("用户所在分部异常");
-			}else {
-				List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
-				if(!list.containsAll(Arrays.asList(queryInfo.getOrganId().split(",")))){
-					return failed("非法请求");
-				}
-			}
-		}*/
         return succeed(organizationService.queryPage(queryInfo));
     }
 

+ 1 - 0
mec-web/src/main/resources/columnMapper.ini

@@ -1,5 +1,6 @@
 [商品导入模板]
 品牌 = brand
+货号 = sn
 商品名称 = name
 商品类型 = type
 商品分类 = goodsCategoryName

二进制
mec-web/src/main/resources/excelTemplate/商品导入模板.xls