|
@@ -66,6 +66,7 @@ import java.time.*;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.temporal.TemporalAdjusters;
|
|
import java.time.temporal.TemporalAdjusters;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import static com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType.MUSIC_NETWORK;
|
|
import static com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType.MUSIC_NETWORK;
|
|
@@ -3925,6 +3926,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
|
|
courseAttendanceDetailHeadInfoDto.setLatestAttendanceTime(studentAttendanceDao.findLatestAttendanceDate(courseScheduleId));
|
|
courseAttendanceDetailHeadInfoDto.setLatestAttendanceTime(studentAttendanceDao.findLatestAttendanceDate(courseScheduleId));
|
|
courseAttendanceDetailHeadInfoDto.setLeaveStudentNum(studentAttendanceDao.getStudentNumByStatus(courseScheduleId, StudentAttendanceStatusEnum.LEAVE));
|
|
courseAttendanceDetailHeadInfoDto.setLeaveStudentNum(studentAttendanceDao.getStudentNumByStatus(courseScheduleId, StudentAttendanceStatusEnum.LEAVE));
|
|
courseAttendanceDetailHeadInfoDto.setTruantStudentNum(studentAttendanceDao.getStudentNumByStatus(courseScheduleId, StudentAttendanceStatusEnum.TRUANT));
|
|
courseAttendanceDetailHeadInfoDto.setTruantStudentNum(studentAttendanceDao.getStudentNumByStatus(courseScheduleId, StudentAttendanceStatusEnum.TRUANT));
|
|
|
|
+ courseAttendanceDetailHeadInfoDto.setLateStudentNum(studentAttendanceDao.getStudentNumByStatus(courseScheduleId, StudentAttendanceStatusEnum.LATE));
|
|
return courseAttendanceDetailHeadInfoDto;
|
|
return courseAttendanceDetailHeadInfoDto;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5982,12 +5984,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
|
|
if (courseSchedule.getTeachMode() == TeachModeEnum.OFFLINE) {
|
|
if (courseSchedule.getTeachMode() == TeachModeEnum.OFFLINE) {
|
|
throw new BizException("请前往线下教室");
|
|
throw new BizException("请前往线下教室");
|
|
}
|
|
}
|
|
-
|
|
|
|
- List<CourseScheduleWrapper.CourseScheduleTime> courseScheduleTimes = Lists.newArrayList();
|
|
|
|
- courseScheduleTimes.add(CourseScheduleWrapper.CourseScheduleTime.builder()
|
|
|
|
- .startTime(getDateTime(courseSchedule.getClassDate(), courseSchedule.getStartClassTime()).getMillis())
|
|
|
|
- .endTime(getDateTime(courseSchedule.getClassDate(), courseSchedule.getEndClassTime()).getMillis())
|
|
|
|
- .build());
|
|
|
|
|
|
+ // 课程开始时间
|
|
|
|
+ courseSchedule.setStartClassTime(getDateTime(courseSchedule.getClassDate(), courseSchedule.getStartClassTime()).toDate());
|
|
|
|
+ // 课程结束时间
|
|
|
|
+ courseSchedule.setEndClassTime(getDateTime(courseSchedule.getClassDate(), courseSchedule.getEndClassTime()).toDate());
|
|
|
|
|
|
// 是否是连堂课
|
|
// 是否是连堂课
|
|
String continueCourseTime = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME, courseSchedule.getTenantId());
|
|
String continueCourseTime = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME, courseSchedule.getTenantId());
|
|
@@ -5996,36 +5996,129 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
|
|
}
|
|
}
|
|
|
|
|
|
// 连堂课标准:同一个老师,同一天,同一课程组,连续上课
|
|
// 连堂课标准:同一个老师,同一天,同一课程组,连续上课
|
|
|
|
+ List<CourseSchedule> continuousCourse = courseScheduleDao.getTeacherContinuousCourse(courseSchedule.getClassGroupId(),
|
|
|
|
+ courseSchedule.getClassDate(), courseSchedule.getActualTeacherId());
|
|
|
|
+ for (CourseSchedule item : continuousCourse) {
|
|
|
|
+ // 设置开始时间
|
|
|
|
+ item.setStartClassTime(getDateTime(item.getClassDate(), item.getStartClassTime()).toDate());
|
|
|
|
+ // 设置结束时间
|
|
|
|
+ item.setEndClassTime(getDateTime(item.getClassDate(), item.getEndClassTime()).toDate());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 课程按开始时间排序
|
|
|
|
+ continuousCourse = continuousCourse.stream()
|
|
|
|
+ .sorted(Comparator.comparing(CourseSchedule::getStartClassTime))
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
|
|
|
+ // 以当前课程为分界线,分为两个集合
|
|
|
|
+ List<CourseSchedule> beforeCourse = Lists.newArrayList();
|
|
|
|
+ List<CourseSchedule> afterCourse = Lists.newArrayList();
|
|
|
|
|
|
|
|
+ CourseSchedule schedule;
|
|
|
|
+ for (CourseSchedule item : continuousCourse) {
|
|
|
|
+ if (item.getId().longValue() == courseSchedule.getId()) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
- CourseSchedule schedule = courseSchedule;
|
|
|
|
- // 如果当前课程是连堂课,那么获取第一节课的课程编号
|
|
|
|
- while (true) {
|
|
|
|
- String classDate = DateUtil.format(schedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
|
|
|
|
- String startClassTime = DateUtil.format(schedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
|
|
|
|
- schedule = courseScheduleDao.getFirstCourse(schedule.getClassGroupId(), classDate + " " + startClassTime, schedule.getActualTeacherId(), continueCourseTime);
|
|
|
|
- if (schedule != null) {
|
|
|
|
- courseScheduleTimes.add(CourseScheduleWrapper.CourseScheduleTime.builder()
|
|
|
|
- .startTime(getDateTime(schedule.getClassDate(), schedule.getStartClassTime()).getMillis())
|
|
|
|
- .endTime(getDateTime(schedule.getClassDate(), schedule.getEndClassTime()).getMillis())
|
|
|
|
- .build());
|
|
|
|
- } else {
|
|
|
|
- break;
|
|
|
|
|
|
+ schedule = JSON.parseObject(JSON.toJSONString(item), CourseSchedule.class);
|
|
|
|
+ if (item.getEndClassTime().getTime() <= courseSchedule.getStartClassTime().getTime()) {
|
|
|
|
+ beforeCourse.add(schedule);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (courseSchedule.getEndClassTime().getTime() <= item.getStartClassTime().getTime()) {
|
|
|
|
+ afterCourse.add(schedule);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (courseScheduleTimes.size() <= 1) {
|
|
|
|
|
|
+ // 当前课程之前连堂课
|
|
|
|
+ beforeCourse.add(JSON.parseObject(JSON.toJSONString(courseSchedule), CourseSchedule.class));
|
|
|
|
+ // 当前课程之后连堂课
|
|
|
|
+ afterCourse.add(0, JSON.parseObject(JSON.toJSONString(courseSchedule), CourseSchedule.class));
|
|
|
|
|
|
- // 定时任务更新课程状态为进行中,判断当前课程状态是否匹配
|
|
|
|
- if (CourseStatusEnum.NOT_START == courseSchedule.getStatus()) {
|
|
|
|
- throw new BizException("直播课暂未开启,请稍后重试");
|
|
|
|
|
|
+ // 课程前连堂状态
|
|
|
|
+ updateContinuousCourseStatus(continueCourseTime, beforeCourse);
|
|
|
|
+
|
|
|
|
+ List<CourseSchedule> newCourseSchedules = Lists.newArrayList();
|
|
|
|
+ // 课程连堂状态
|
|
|
|
+ if (beforeCourse.get(beforeCourse.size() - 1).getContinuousCourse()) {
|
|
|
|
+ List<CourseSchedule> collect = beforeCourse.stream()
|
|
|
|
+ .filter(CourseSchedule::getContinuousCourse)
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ if (CollectionUtils.isNotEmpty(collect)) {
|
|
|
|
+ newCourseSchedules.addAll(collect);
|
|
}
|
|
}
|
|
- if (CourseStatusEnum.OVER == courseSchedule.getStatus()) {
|
|
|
|
- throw new BizException("直播课已结束");
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 课程后连堂状态
|
|
|
|
+ updateContinuousCourseStatus(continueCourseTime, afterCourse);
|
|
|
|
+ if (afterCourse.get(0).getContinuousCourse()) {
|
|
|
|
+ List<CourseSchedule> collect = afterCourse.stream()
|
|
|
|
+ .filter(CourseSchedule::getContinuousCourse)
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ if (CollectionUtils.isNotEmpty(collect)) {
|
|
|
|
+
|
|
|
|
+ if (CollectionUtils.isEmpty(newCourseSchedules)) {
|
|
|
|
+ newCourseSchedules.addAll(collect);
|
|
|
|
+ } else {
|
|
|
|
+ newCourseSchedules.addAll(collect.subList(1, collect.size()));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ List<CourseScheduleWrapper.CourseScheduleTime> courseScheduleTimes = Lists.newArrayList();
|
|
|
|
+ if (CollectionUtils.isNotEmpty(newCourseSchedules)) {
|
|
|
|
+
|
|
|
|
+ // 连党课程信息
|
|
|
|
+ for (CourseSchedule item : newCourseSchedules) {
|
|
|
|
+ courseScheduleTimes.add(CourseScheduleWrapper.CourseScheduleTime.builder()
|
|
|
|
+ .startTime(item.getStartClassTime().getTime())
|
|
|
|
+ .endTime(item.getEndClassTime().getTime())
|
|
|
|
+ .build());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取连堂课第一节信息
|
|
|
|
+ courseSchedule = newCourseSchedules.get(0);
|
|
|
|
+
|
|
|
|
+ CourseSchedule finalCourseSchedule = courseSchedule;
|
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
|
+
|
|
|
|
+ List<Long> collect = newCourseSchedules.stream()
|
|
|
|
+ .map(CourseSchedule::getId)
|
|
|
|
+ .distinct().collect(Collectors.toList());
|
|
|
|
+ try {
|
|
|
|
+
|
|
|
|
+ // 关联直播间编号
|
|
|
|
+ courseScheduleDao.batchUpdateLiveRoomId(collect, finalCourseSchedule.getLiveRoomId());
|
|
|
|
+
|
|
|
|
+ collect = newCourseSchedules.subList(0, newCourseSchedules.size() - 1).stream()
|
|
|
|
+ .map(CourseSchedule::getId)
|
|
|
|
+ .distinct().collect(Collectors.toList());
|
|
|
|
+ // 更新连堂课状态
|
|
|
|
+ courseScheduleDao.batchUpdateContinuousCourse(collect, true);
|
|
|
|
+
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("getLiveCourseScheduleTime courseScheduleIds={}", collect, e);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ // 当前课程信息
|
|
|
|
+ courseScheduleTimes.add(CourseScheduleWrapper.CourseScheduleTime.builder()
|
|
|
|
+ .startTime(courseSchedule.getStartClassTime().getTime())
|
|
|
|
+ .endTime(courseSchedule.getEndClassTime().getTime())
|
|
|
|
+ .build());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 定时任务更新课程状态为进行中,判断当前课程状态是否匹配
|
|
|
|
+ if (CourseStatusEnum.NOT_START == courseSchedule.getStatus()) {
|
|
|
|
+ throw new BizException("直播课暂未开启,请稍后重试");
|
|
|
|
+ }
|
|
|
|
+ if (CourseStatusEnum.OVER == courseSchedule.getStatus()) {
|
|
|
|
+ throw new BizException("直播课已结束");
|
|
|
|
+ }
|
|
|
|
+
|
|
// 直播间配置
|
|
// 直播间配置
|
|
ImLiveBroadcastRoom liveBroadcastRoom = imLiveBroadcastRoomService.lambdaQuery()
|
|
ImLiveBroadcastRoom liveBroadcastRoom = imLiveBroadcastRoomService.lambdaQuery()
|
|
.eq(ImLiveBroadcastRoom::getRoomUid, courseSchedule.getLiveRoomId())
|
|
.eq(ImLiveBroadcastRoom::getRoomUid, courseSchedule.getLiveRoomId())
|
|
@@ -6050,6 +6143,39 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
+ * 更新当前课程连堂状态
|
|
|
|
+ * @param continueCourseTime 连堂时间间隔
|
|
|
|
+ * @param continuousCourse 连堂课程
|
|
|
|
+ */
|
|
|
|
+ private void updateContinuousCourseStatus(String continueCourseTime, List<CourseSchedule> continuousCourse) {
|
|
|
|
+
|
|
|
|
+ // continuousCourse对象相邻两个时间比较,如果时间间隔小于5分钟,那么合并为连堂课
|
|
|
|
+ DateTime startTime;
|
|
|
|
+ DateTime endTime;
|
|
|
|
+ for (int i = 0; i < continuousCourse.size(); i++) {
|
|
|
|
+ CourseSchedule current = continuousCourse.get(i);
|
|
|
|
+ CourseSchedule next = null;
|
|
|
|
+ if (i + 1 < continuousCourse.size()) {
|
|
|
|
+ next = continuousCourse.get(i + 1);
|
|
|
|
+ }
|
|
|
|
+ if (next != null) {
|
|
|
|
+
|
|
|
|
+ startTime = getDateTime(current.getClassDate(), current.getEndClassTime());
|
|
|
|
+ endTime = getDateTime(next.getClassDate(), next.getStartClassTime());
|
|
|
|
+ // 如果当前课程结束时间和下一节课开始时间间隔小于5分钟,那么合并时间
|
|
|
|
+ if (startTime.isBefore(endTime)
|
|
|
|
+ && startTime.plusMinutes(Integer.parseInt(continueCourseTime) + 1).isAfter(endTime)) {
|
|
|
|
+ // 上节连堂状态
|
|
|
|
+ current.setContinuousCourse(true);
|
|
|
|
+ // 下节连堂状态
|
|
|
|
+ next.setContinuousCourse(true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
* 课程开始时间
|
|
* 课程开始时间
|
|
* @param day 开始天
|
|
* @param day 开始天
|
|
* @param time 开始时间
|
|
* @param time 开始时间
|