|
@@ -6,19 +6,24 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
|
|
|
import com.yonge.cooleshow.auth.api.entity.SysUser;
|
|
|
+import com.yonge.cooleshow.biz.dal.constant.SysConfigConstant;
|
|
|
import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
|
|
|
+import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
|
|
|
import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
|
|
|
+import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
|
|
|
+import com.yonge.cooleshow.biz.dal.entity.HolidaysFestivals;
|
|
|
import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
|
|
|
-import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
|
|
|
import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
|
|
|
+import com.yonge.cooleshow.biz.dal.service.HolidaysFestivalsService;
|
|
|
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
|
|
|
import com.yonge.cooleshow.biz.dal.support.PageUtil;
|
|
|
import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
|
|
|
-import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
|
|
|
import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
|
|
|
import com.yonge.cooleshow.common.exception.BizException;
|
|
|
import com.yonge.cooleshow.common.page.PageInfo;
|
|
|
import com.yonge.toolset.utils.date.DateUtil;
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -29,10 +34,7 @@ import org.springframework.validation.annotation.Validated;
|
|
|
import javax.validation.Valid;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.temporal.TemporalAdjusters;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Optional;
|
|
|
+import java.util.*;
|
|
|
import java.util.function.Function;
|
|
|
|
|
|
/**
|
|
@@ -50,7 +52,9 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
|
|
|
@Autowired
|
|
|
private SysUserFeignService sysUserFeignService;
|
|
|
@Autowired
|
|
|
- private CourseGroupService courseGroupService;
|
|
|
+ private HolidaysFestivalsService holidaysFestivalsService;
|
|
|
+ @Autowired
|
|
|
+ private SysConfigService sysConfigService;
|
|
|
|
|
|
@Override
|
|
|
public CourseScheduleDao getDao() {
|
|
@@ -127,19 +131,18 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 查询这个课程列表中时间是否有重叠
|
|
|
- * <p>案例:1
|
|
|
- * <p>已有9:00~ 10:00 课程
|
|
|
+ * 检查传入时间列表的时间是否与新增课程时间有交集
|
|
|
+ * <p>案例1:
|
|
|
+ * <p>list列表
|
|
|
+ * <p> 8:00 ~ 09:00 课程
|
|
|
+ * <p> 9:00 ~ 10:00 课程
|
|
|
* <p>新增课程 09:10~ 09:40
|
|
|
* <p>返回 true
|
|
|
*
|
|
|
- * <p>案例:2
|
|
|
- * <p>已有9:00~ 10:00 课程
|
|
|
- * <p>新增课程 08:45~ 09:40
|
|
|
- * <p>返回 true
|
|
|
- *
|
|
|
- * <p>案例:3
|
|
|
- * <p>已有9:00~ 10:00 课程
|
|
|
+ * <p>案例2:
|
|
|
+ * <p>list列表
|
|
|
+ * <p> 8:00 ~ 09:00 课程
|
|
|
+ * <p> 9:00 ~ 10:00 课程
|
|
|
* <p>新增课程 10:00~ 10:40
|
|
|
* <p>返回 false
|
|
|
*
|
|
@@ -148,7 +151,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
|
|
|
* @param endTimeFun 获取现课程结束时间
|
|
|
* @param startTime 新增课程开始时间
|
|
|
* @param endTime 新增课程结束时间
|
|
|
- * @return true 被占用 false 没有被占用
|
|
|
+ * @return true 有交集 false 没有交集
|
|
|
*/
|
|
|
public <T> boolean checkCourseTime(List<T> list, Function<T, Date> startTimeFun, Function<T, Date> endTimeFun,
|
|
|
Date startTime, Date endTime) {
|
|
@@ -210,13 +213,207 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 课程日历
|
|
|
+ * 创建直播课时选课时的日历
|
|
|
+ * <P>主要查询该老师目前的课程时间
|
|
|
+ * <P>根据传入的单课时时长将时间分片后来匹配数据库中课程时间,得到每日空余时间
|
|
|
+ *
|
|
|
+ * @param param 传入参数
|
|
|
+ * <p> - teacherId 老师id
|
|
|
+ * <p> - year 年
|
|
|
+ * <p> - month 月
|
|
|
+ * <p> - day 日
|
|
|
+ * <p> - singleCourseMinutes 单课时时长(包含休息时间)
|
|
|
+ * @return 返回传入时间当月每日的剩余时间段
|
|
|
+ */
|
|
|
+ public List<CourseCalendarEntity> createLiveCourseCalendar(Map<String, Object> param) {
|
|
|
+ //校验数据
|
|
|
+ Long teacherId = WrapperUtil.toLong(param, "teacherId", "老师id不能为空!");
|
|
|
+ Integer year = WrapperUtil.toInt(param, "year", "日历的时间年份不能为空!");
|
|
|
+ Integer month = WrapperUtil.toInt(param, "month", "日历的时间月份不能为空!");
|
|
|
+ Integer day = WrapperUtil.toInt(param, "month", "日历的时间日期不能为空!");
|
|
|
+ Integer singleCourseMinutes = WrapperUtil.toInt(param, "singleCourseMinutes", "单课时时长不能为空!");
|
|
|
+
|
|
|
+ //传入的日期+1天开始
|
|
|
+ LocalDate firstDay = LocalDate.of(year, month, day).plusDays(1L);
|
|
|
+ //根据firstDay计算出该月的最后一天
|
|
|
+ LocalDate lastDay = firstDay.with(TemporalAdjusters.lastDayOfMonth());
|
|
|
+ //获取老师的课程 key:日期-年月日 value:课程时间-开始时间,结束时间
|
|
|
+ Map<String, List<CourseTimeEntity>> nowCourseMap = getTeacherCourseTime(teacherId, firstDay.toString(), lastDay.toString());
|
|
|
+ //储存节假日数据,避免重复查询
|
|
|
+ Map<Integer, List<String>> holidayMap = new HashMap<>();
|
|
|
+ //生成日历数据
|
|
|
+ List<CourseCalendarEntity> courseCalendarEntities = generateCourseData(firstDay, lastDay, singleCourseMinutes);
|
|
|
+ courseCalendarEntities.forEach(calendarEntity -> {
|
|
|
+ //获取课程数据,并剔除交集时间段数据,
|
|
|
+ List<CourseTimeEntity> nowCourse = nowCourseMap.get(calendarEntity.getDate());
|
|
|
+ if (CollectionUtils.isEmpty(nowCourse)) {
|
|
|
+ //当日没课
|
|
|
+ calendarEntity.setFullCourse(0);// 0:未满 1满
|
|
|
+ } else {
|
|
|
+ //将日历时间与课程时间进行对比,如果有交集则将日历的时间数据删除
|
|
|
+ Iterator<CourseTimeEntity> iterator = calendarEntity.getCourseTime().iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ CourseTimeEntity next = iterator.next();
|
|
|
+ boolean flag = checkCourseTime(nowCourse, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime, next.getStartTime(), next.getEndTime());
|
|
|
+ if (flag) {
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //如果日历时间集合数据删没了,那么就证明当天课程已经满了 0:未满 1满
|
|
|
+ if (CollectionUtils.isEmpty(calendarEntity.getCourseTime())) {
|
|
|
+ calendarEntity.setFullCourse(1);
|
|
|
+ } else {
|
|
|
+ calendarEntity.setFullCourse(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //获取节假日信息
|
|
|
+ int calendarYear = LocalDate.parse(calendarEntity.getDate()).getYear();
|
|
|
+ List<String> holiday = Optional.of(calendarYear)
|
|
|
+ .map(holidayMap::get)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .orElseGet(() -> {
|
|
|
+ List<String> list = getHoliday(calendarYear);
|
|
|
+ holidayMap.put(calendarYear, list);
|
|
|
+ return list;
|
|
|
+ });
|
|
|
+ //是否是节假日 0:不是 1是
|
|
|
+ calendarEntity.setHoliday(holiday.contains(calendarEntity.getDate()) ? 1 : 0);
|
|
|
+ });
|
|
|
+
|
|
|
+ return courseCalendarEntities;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取老师的课程时间数据
|
|
|
*
|
|
|
* @param teacherId 老师id
|
|
|
- * @param date 年月日 yyyy-MM-dd 都是1号
|
|
|
+ * @param startDate 开始时间
|
|
|
+ * @param endDate 结束时间
|
|
|
+ * @return key:日期-年月日 value:课程时间-开始时间,结束时间
|
|
|
*/
|
|
|
- public void courseCalendar(Long teacherId, String date) {
|
|
|
+ private Map<String, List<CourseTimeEntity>> getTeacherCourseTime(Long teacherId, String startDate, String endDate) {
|
|
|
+ //查询该老师指定时间段的课程
|
|
|
+ List<CourseSchedule> courseList = this.list(Wrappers.<CourseSchedule>lambdaQuery()
|
|
|
+ .eq(CourseSchedule::getTeacherId, teacherId)
|
|
|
+ .ge(CourseSchedule::getClassDate, startDate)
|
|
|
+ .le(CourseSchedule::getClassDate, endDate)
|
|
|
+ );
|
|
|
+ //老师课程 key:日期-年月日 value:课程
|
|
|
+ Map<String, List<CourseTimeEntity>> nowCourse = new HashMap<>();
|
|
|
+ if (CollectionUtils.isNotEmpty(courseList)) {
|
|
|
+ WrapperUtil.groupList(courseList, CourseSchedule::getClassDate)
|
|
|
+ .forEach((k, v) -> {
|
|
|
+ List<CourseTimeEntity> value = new ArrayList<>();
|
|
|
+ v.forEach(course -> {
|
|
|
+ CourseTimeEntity courseTimeEntity = new CourseTimeEntity();
|
|
|
+ courseTimeEntity.setStartTime(course.getStartTime());
|
|
|
+ courseTimeEntity.setEndTime(course.getEndTime());
|
|
|
+ value.add(courseTimeEntity);
|
|
|
+ });
|
|
|
+ nowCourse.put(DateUtil.dateToString(k), value);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return nowCourse;
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据开始日期 结束日期 单结课时长 生成一个周期的每日课程时间数据
|
|
|
+ *
|
|
|
+ * @param firstDay 开始日期年月日
|
|
|
+ * @param lastDay 最后一天的日期年月日
|
|
|
+ * @param singleCourseMinutes 单结课时长
|
|
|
+ */
|
|
|
+ public List<CourseCalendarEntity> generateCourseData(LocalDate firstDay, LocalDate lastDay, Integer singleCourseMinutes) {
|
|
|
+ //获取上课的最早时间和最晚时间,将每日时间切片
|
|
|
+ String sysStartTime = sysConfigService.findConfigValue(SysConfigConstant.COURSE_START_SETTING);
|
|
|
+ String sysEndTime = sysConfigService.findConfigValue(SysConfigConstant.COURSE_END_SETTING);
|
|
|
+ if (StringUtils.isBlank(sysStartTime) || StringUtils.isBlank(sysEndTime)) {
|
|
|
+ throw new BizException("未查询到平台设置的每日最早上/最晚上课时间设置!");
|
|
|
+ }
|
|
|
+ //每日最早上课时间
|
|
|
+ Date dayStartTime = DateUtil.toDateTime(firstDay + " " + sysStartTime + ":00");
|
|
|
+ //每日最晚下课时间
|
|
|
+ Date dayEndTime = DateUtil.toDateTime(firstDay + " " + sysEndTime + ":00");
|
|
|
+ //每日日期数据
|
|
|
+ List<CourseCalendarEntity> list = new ArrayList<>();
|
|
|
+ //生成每日课程时间段 -根据单节课时长 及每日最早最晚时间 生成一天的时间切片
|
|
|
+ List<CourseTimeEntity> dayTime = generateDayTime(singleCourseMinutes, dayStartTime, dayEndTime);
|
|
|
+ int addDay = 0;
|
|
|
+ //获取每日日期数据
|
|
|
+ while (firstDay.isBefore(lastDay) || firstDay.isEqual(lastDay)) {
|
|
|
+ CourseCalendarEntity entity = new CourseCalendarEntity();
|
|
|
+ List<CourseTimeEntity> times = new ArrayList<>();
|
|
|
+ //获取当前日期
|
|
|
+ entity.setDate(firstDay.toString());
|
|
|
+ int finalAddDay = addDay;
|
|
|
+ dayTime.forEach(time -> {
|
|
|
+ CourseTimeEntity courseTimeEntity = new CourseTimeEntity();
|
|
|
+ courseTimeEntity.setStartTime(DateUtil.addDays(time.getStartTime(), finalAddDay));
|
|
|
+ courseTimeEntity.setEndTime(DateUtil.addDays(time.getEndTime(), finalAddDay));
|
|
|
+ times.add(courseTimeEntity);
|
|
|
+ });
|
|
|
+ entity.courseTime(times);
|
|
|
+ list.add(entity);
|
|
|
+ firstDay = firstDay.plusDays(1L);
|
|
|
+ addDay++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成每日课程时间段数据
|
|
|
+ * <p>根据单节课时长 及每日最早最晚时间 生成一天的时间切片
|
|
|
+ *
|
|
|
+ * @param singleCourseMinutes 单节课时长
|
|
|
+ * @param startTime 每日最早上课时间
|
|
|
+ * @param endTime 每日最晚下课时间
|
|
|
+ */
|
|
|
+ public List<CourseTimeEntity> generateDayTime(Integer singleCourseMinutes, Date startTime, Date endTime) {
|
|
|
+ List<CourseTimeEntity> result = new ArrayList<>();
|
|
|
+ //划分每日课程时间
|
|
|
+ Date edate = startTime;
|
|
|
+ boolean flag = true;
|
|
|
+ while (flag) {
|
|
|
+ if (edate.getTime() > endTime.getTime()) {
|
|
|
+ flag = false;
|
|
|
+ } else {
|
|
|
+ CourseTimeEntity timeEntity = new CourseTimeEntity();
|
|
|
+ timeEntity.setStartTime(edate);
|
|
|
+ //加时间得到课程结束时间
|
|
|
+ edate = DateUtil.addMinutes(edate, singleCourseMinutes);
|
|
|
+ timeEntity.setEndTime(edate);
|
|
|
+ result.add(timeEntity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ result.remove(result.size() - 1);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据年份获取当年节假日
|
|
|
+ *
|
|
|
+ * @param year 年
|
|
|
+ * @return 年月日
|
|
|
+ */
|
|
|
+ private List<String> getHoliday(int year) {
|
|
|
+ HolidaysFestivals holidaysFestivals = holidaysFestivalsService.queryByYear(year);
|
|
|
+ if (Objects.isNull(holidaysFestivals)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(holidaysFestivals.getHolidaysFestivalsJson())) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ return WrapperUtil.toList(holidaysFestivals.getHolidaysFestivalsJson());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成陪练课日历
|
|
|
+ */
|
|
|
+ public void generatePracticeCourseCalender() {
|
|
|
+ //todo 注意:如果是陪练课的日历需要查询老师设置的陪练课时间有哪些,不能直接根据时间段来
|
|
|
+ //获取周 int value = calendarDay.getDayOfWeek().getValue();
|
|
|
}
|
|
|
|
|
|
private SysUser getSysUser() {
|