Ver Fonte

演练/培训 计划下发逻辑处理

jingyuanchao há 1 ano atrás
pai
commit
4bec9e0e9b

+ 2 - 0
soc-common/soc-common-core/src/main/java/com/xunmei/common/core/domain/DateRange.java

@@ -2,11 +2,13 @@ package com.xunmei.common.core.domain;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 import lombok.ToString;
 
 import java.util.Date;
 
 @AllArgsConstructor
+@NoArgsConstructor
 @Data
 @ToString
 public class DateRange {

+ 157 - 17
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/drill/service/impl/CoreDrillTaskServiceImpl.java

@@ -1,6 +1,8 @@
 package com.xunmei.core.drill.service.impl;
 
 import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -25,6 +27,7 @@ import com.xunmei.common.core.domain.panel.vo.PanelListVo;
 import com.xunmei.common.core.domain.registerbook.domain.CoreRegisterBookPdf;
 import com.xunmei.common.core.domain.worktime.domain.SysWorkTime;
 import com.xunmei.common.core.domain.worktime.dto.WorkTimeDto;
+import com.xunmei.common.core.enums.CycleCommonEnum;
 import com.xunmei.common.core.enums.OrgTypeEnum;
 import com.xunmei.common.core.enums.RegisterBookType;
 import com.xunmei.common.core.enums.drill.*;
@@ -35,6 +38,7 @@ import com.xunmei.common.core.web.domain.AjaxResult;
 import com.xunmei.common.core.web.page.TableDataInfo;
 import com.xunmei.common.security.utils.DictUtils;
 import com.xunmei.common.security.utils.SecurityUtils;
+import com.xunmei.core.TaskCreatingServiceImplBase;
 import com.xunmei.core.drill.mapper.CoreDrillPlanMapper;
 import com.xunmei.core.drill.mapper.CoreDrillTaskMapper;
 import com.xunmei.core.drill.mapper.CoreDrillTaskToRoleMapper;
@@ -285,7 +289,7 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
         }
         CoreDrillTask finalCoreDrillTask = coreDrillTask;
         List<SysUser> userList = RemoteCallHandlerExecutor.executeRemoteCall(() ->
-                roleService.selectUserByRoleNameAndOrgId("网点负责人", finalCoreDrillTask.getOrgId(),0, SecurityConstants.INNER), ErrorMsgConstants.QUERY_USER_DATA_ERROR);
+                roleService.selectUserByRoleNameAndOrgId("网点负责人", finalCoreDrillTask.getOrgId(), 0, SecurityConstants.INNER), ErrorMsgConstants.QUERY_USER_DATA_ERROR);
         if (ObjectUtil.isNotEmpty(userList)) {
             coreDrillTask.setHostId(userList.get(0).getId());
         } else {
@@ -362,7 +366,7 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
     public void createTaskForNow(CoreDrillPlanDataVo plan, Date start, Date end) {
         if (plan.getPlanCycle() != 0) {
             //如果不是无周期的计划,那么需要查询出他的时间范围,且需要判断作息时间是否存在
-            DateRange dateRange = DateUtils.getStartAndEnd(new Date(), EduTrainingPlanCycleEnum.toCommonEnum(plan.getPlanCycle()));
+            DateRange dateRange = DateUtils.getStartAndEnd(new Date(), plan.getPlanCycle());
             start = dateRange.getStartTime();
             end = dateRange.getEndTime();
         } else {
@@ -370,8 +374,140 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
             start = DateUtil.beginOfDay(start).setField(DateField.MILLISECOND, 0);
             end = DateUtil.endOfDay(end).setField(DateField.MILLISECOND, 0);
         }
-        List<SysOrg> execOrgList = getExecOrgList(plan, start, end);
-        saveTaskAndRoleData(plan, start, end, execOrgList);
+        final List<SysOrg> orgList = getExecOrgList(plan.getPlanExecOrgList(), plan.getExecOrgType(), plan.getBelongOrgPath());
+        final List<SysWorkTime> workTimeList = getWorkTimeList(orgList, start, end);
+        if (workTimeList.isEmpty()) {
+            log.error("生成任务时,需要生成任务的机构均未营业,本次任务跳过!");
+            return;
+        }
+        //List<SysOrg> execOrgList = getExecOrgList(plan, start, end);
+        saveTaskAndRoleData(plan, start, end, orgList, workTimeList);
+    }
+
+    private List<SysWorkTime> getWorkTimeList(List<SysOrg> orgList, Date start, Date end) {
+        List<Long> orgIdList = orgList.stream().map(SysOrg::getId).collect(Collectors.toList());
+        String startTime = DateUtil.format(start, Constants.DAILY_FORMAT);
+        String endTime = DateUtil.format(end, Constants.DAILY_FORMAT);
+        WorkTimeDto workTimeDto = new WorkTimeDto();
+        workTimeDto.setOrgIdList(orgIdList);
+        workTimeDto.setStartTime(startTime);
+        workTimeDto.setEndTime(endTime);
+        return RemoteCallHandlerExecutor.executeRemoteCall(() ->
+                        workTimeService.findWorkTimeByRange(workTimeDto, SecurityConstants.FROM_SOURCE).getData(),
+                ErrorMsgConstants.QUERY_ORG_WORK_TIME_ERROR);
+    }
+
+    private List<SysOrg> getExecOrgList(List<CoreDrillPlanToExecOrg> planExecOrgList, Integer execOrgType, String belongOrgPath) {
+        if (ObjectUtil.isEmpty(planExecOrgList)) {
+            return RemoteCallHandlerExecutor.executeRemoteCall(() ->
+                            orgService.selectByOrgPathAndOrgType(belongOrgPath, execOrgType, SecurityConstants.INNER),
+                    ErrorMsgConstants.QUERY_ORG_DATA_ERROR);
+        } else {
+            List<Long> list = planExecOrgList.stream().map(CoreDrillPlanToExecOrg::getOrgId).collect(Collectors.toList());
+            return RemoteCallHandlerExecutor.executeRemoteCall(() ->
+                            orgService.selectOrgByIdList(list, SecurityConstants.INNER),
+                    ErrorMsgConstants.QUERY_ORG_DATA_ERROR);
+        }
+    }
+
+    /**
+     * 将当前周期开始结束时间,按频次拆分为多个时段。如果该时段歇业,则不包含该次,如返回次数1,3.
+     *
+     * @param frequency
+     * @param start
+     * @param end
+     * @param workTimes,为null则认为全是营业
+     * @return
+     */
+    private Map<Short, DateRange> splitTaskTime(Short frequency, CycleCommonEnum cycle, Date start, Date end, List<SysWorkTime> workTimes) {
+        boolean sameDay = DateUtil.isSameDay(start, end); //一天内按半小时分,
+
+        DateUnit dateUnit;
+        DateField dateField;
+        if (sameDay) {
+            dateField = DateField.MINUTE;
+            dateUnit = DateUnit.MINUTE;
+        } else {
+            dateField = DateField.DAY_OF_YEAR;
+            dateUnit = DateUnit.DAY;
+        }
+        double diff = DateUtil.between(start, end, dateUnit);
+        double seg = diff / frequency;
+        if (sameDay) {
+            seg = Math.round(seg / 30) * 30;
+        } else {
+            seg = Math.round(seg);
+            if (cycle == CycleCommonEnum.DAILY && frequency == 3) {
+                seg = 10;
+            }
+        }
+
+        DateTime segStart = new DateTime(start);
+
+        Map<Short, DateRange> r = new HashMap<>();
+        for (short i = 1; i <= frequency; i++) {
+            if (dateField == DateField.DAY_OF_YEAR) {
+                segStart.setField(DateField.HOUR, 0)
+                        .setField(DateField.MINUTE, 0)
+                        .setField(DateField.SECOND, 0)
+                        .setField(DateField.MILLISECOND, 0);
+            }
+            DateTime nextStart = DateUtil.offset(segStart, dateField, (int) (seg));
+            DateRange et = new DateRange();
+            et.setStartTime(segStart);
+            DateTime segEnd;
+            if (i == frequency) {
+                segEnd = new DateTime(end);
+            } else {
+                segEnd = nextStart;
+
+                if (dateField == DateField.DAY_OF_YEAR) {
+                    segEnd = DateUtil.offset(nextStart, DateField.SECOND, -1);
+                    segEnd.setField(DateField.HOUR_OF_DAY, 23).setField(DateField.MINUTE, 59).setField(DateField.SECOND, 59);
+                }
+                if (segEnd.after(end)) {
+                    segEnd = new DateTime(end);
+                }
+            }
+            segEnd.setField(DateField.MILLISECOND, 0);
+            et.setEndTime(segEnd);
+            segStart = nextStart;
+
+            if (segEnd.before(new Date())) {
+                continue;
+            }
+
+            if (workTimes == null || containCurrentCycle(workTimes, et.getStartTime(), et.getEndTime())) {
+                r.put(i, et);
+            }
+        }
+
+        return r;
+    }
+
+    /**
+     * 获取作息日期与当前周期是否有交集
+     *
+     * @param workTimes
+     * @param start
+     * @param end
+     * @return
+     */
+    private Boolean containCurrentCycle(List<SysWorkTime> workTimes, Date start, Date end) {
+        if (start.after(end)) {
+            return false;
+        }
+        Set<Long> timeValues = workTimes.stream().map(t -> t.getYmdDate().getTime()).collect(Collectors.toSet());
+        while (true) {
+            if (timeValues.contains(DateUtil.beginOfDay(start).getTime())) {
+                return true;
+            }
+
+            start = DateUtil.offset(start, DateField.DAY_OF_YEAR, 1);
+            if (start.equals(end) || start.after(end)) {
+                return false;
+            }
+        }
     }
 
     private List<SysOrg> getExecOrgList(CoreDrillPlanDataVo plan, Date start, Date end) {
@@ -401,38 +537,42 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
         List<Long> workOrgIdList = workTimeList.stream().filter(time -> ObjectUtil.equal(time.getIsEnable(), WORK))
                 .map(SysWorkTime::getOrgId).collect(Collectors.toList());
         return orgList.stream()
-                .filter(org -> workOrgIdList.contains(org.getId())||!OrgTypeEnum.YINGYE_WANGDIAN.getCode().equals(org.getType()))
+                .filter(org -> workOrgIdList.contains(org.getId()) || !OrgTypeEnum.YINGYE_WANGDIAN.getCode().equals(org.getType()))
                 .collect(Collectors.toList());
         // return orgList;
 
     }
 
-    private void saveTaskAndRoleData(CoreDrillPlanDataVo plan, Date start, Date end, List<SysOrg> orgList) {
+    private void saveTaskAndRoleData(CoreDrillPlanDataVo plan, Date start, Date end, List<SysOrg> orgList, List<SysWorkTime> workTimeList) {
         // List<CoreDrillPlanToRole> planRoleList = plan.getPlanRoleList();
         // List<CoreDrillTaskToRole> taskRoleList = new ArrayList<>();
         List<CoreDrillTask> taskList = new ArrayList<>();
-        Map<Integer, DateRange> dateRangeMap = DateUtils.splitDateRange(start, end, plan.getExecTimes());
+        // Map<Integer, DateRange> dateRangeMap = DateUtils.splitDateRange(start, end, plan.getExecTimes());
         //获取dateRangeMap中最大和最小的时间
-        Date maxDateRange = dateRangeMap.get(dateRangeMap.size()).getEndTime();
-        Date minDateRange = dateRangeMap.get(1).getStartTime();
         final List<Long> collect = orgList.stream().map(SysOrg::getId).collect(Collectors.toList());
         final List<CoreDrillTask> trainingTaskList = baseMapper.selectList(new LambdaQueryWrapper<CoreDrillTask>()
                 .in(CoreDrillTask::getOrgId, collect)
-                .ge(CoreDrillTask::getStartDate, minDateRange)
-                .le(CoreDrillTask::getEndDate, maxDateRange)
+                .ge(CoreDrillTask::getStartDate, start)
+                .le(CoreDrillTask::getEndDate, end)
                 .eq(CoreDrillTask::getPlanId, plan.getId())
                 .select(CoreDrillTask::getId, CoreDrillTask::getOrgId, CoreDrillTask::getStartDate, CoreDrillTask::getEndDate, CoreDrillTask::getPlanId)
         );
+        final Map<Long, List<SysWorkTime>> listMap = workTimeList.stream().collect(Collectors.groupingBy(SysWorkTime::getOrgId));
+
         for (SysOrg org : orgList) {
+            final List<SysWorkTime> sysWorkTimes = OrgTypeEnum.YINGYE_WANGDIAN.getCode().equals(org.getType()) ? listMap.get(org.getId()) : null;
+            final Map<Short, DateRange> rangeMap = splitTaskTime(plan.getExecTimes().shortValue(), DrillPlanCycleEnum.toCommonEnum(plan.getPlanCycle()), start, end, sysWorkTimes);
             int x = 0;
-            for (int i = 1; i <= plan.getExecTimes(); i++) {
-                final LocalDateTime time = DateUtils.toLocalDateTime(DateUtils.getPreciseTime(dateRangeMap.get(i).getEndTime()));
+            for (Map.Entry<Short, DateRange> rangeEntry : rangeMap.entrySet()) {
+                final Short key = rangeEntry.getKey();
+                final DateRange value = rangeEntry.getValue();
+                /*final LocalDateTime time = DateUtils.toLocalDateTime(DateUtils.getPreciseTime(value.getEndTime()));
                 if (time.isBefore(LocalDateTime.now())) {
                     //如果任务的结束时间 已经小于当前时间则没必要生成任务了,
                     //用于处理周期中生成多次任务,周期初的任务一经生成就无法执行(预期)的问题,
-                    log.warn("生成任务时,任务的结束时间已经小于当前时间,本次任务跳过,任务id:{},任务执行机构id:{},任务时间范围:{}-{}", plan.getId(), org.getId(), dateRangeMap.get(i).getStartTime(), dateRangeMap.get(i).getEndTime());
+                    log.warn("生成任务时,任务的结束时间已经小于当前时间,本次任务跳过,任务id:{},任务执行机构id:{},任务时间范围:{}-{}", plan.getId(), org.getId(), value.getStartTime(), value.getEndTime());
                     continue;
-                }
+                }*/
                 CoreDrillTask trainingTask = new CoreDrillTask();
                 trainingTask.setId(IdWorker.getId());
                 trainingTask.setCategory(plan.getCategory());
@@ -444,8 +584,8 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
                 } else {
                     trainingTask.setTitle(plan.getPlanName());
                 }
-                trainingTask.setStartDate(DateUtils.getPreciseTime(dateRangeMap.get(i).getStartTime()));
-                trainingTask.setEndDate(DateUtils.getPreciseTime(dateRangeMap.get(i).getEndTime()));
+                trainingTask.setStartDate(DateUtils.getPreciseTime(value.getStartTime()));
+                trainingTask.setEndDate(DateUtils.getPreciseTime(value.getEndTime()));
                 trainingTask.setPresetCase(null);
                 trainingTask.setDrillSituation(null);
                 trainingTask.setDrillStartTime(null);

+ 140 - 41
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/edu/service/impl/CoreEduTrainingTaskServiceImpl.java

@@ -2,6 +2,7 @@ package com.xunmei.core.edu.service.impl;
 
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -362,7 +363,7 @@ public class CoreEduTrainingTaskServiceImpl extends ServiceImpl<CoreEduTrainingT
 
     private Long getHostUserId(Long orgId) {
         List<SysUser> userList = RemoteCallHandlerExecutor.executeRemoteCall(() ->
-                roleService.selectUserByRoleNameAndOrgId("网点负责人", orgId,0, SecurityConstants.INNER), ErrorMsgConstants.QUERY_USER_DATA_ERROR);
+                roleService.selectUserByRoleNameAndOrgId("网点负责人", orgId, 0, SecurityConstants.INNER), ErrorMsgConstants.QUERY_USER_DATA_ERROR);
         if (ObjectUtil.isNotEmpty(userList)) {
             return userList.get(0).getId();
         } else {
@@ -422,25 +423,18 @@ public class CoreEduTrainingTaskServiceImpl extends ServiceImpl<CoreEduTrainingT
             start = DateUtil.beginOfDay(start).setField(DateField.MILLISECOND, 0);
             end = DateUtil.endOfDay(end).setField(DateField.MILLISECOND, 0);
         }
-        List<SysOrg> execOrgList = getExecOrgList(plan, start, end);
-        try {
-            saveTaskAndRoleData(plan, start, end, execOrgList);
-        } catch (Exception e) {
-            log.error("生成任务失败,{}", e.getMessage());
-            throw new RuntimeException(e);
+        final List<SysOrg> orgList = getExecOrgList(plan.getPlanExecOrgList(), plan.getExecOrgType(), plan.getBelongOrgPath());
+        final List<SysWorkTime> workTimeList = getWorkTimeList(orgList, start, end);
+        if (workTimeList.isEmpty()) {
+            log.error("生成任务时,需要生成任务的机构均未营业,本次任务跳过!");
+            return;
         }
+        saveTaskAndRoleData(plan, start, end, orgList, workTimeList);
+
     }
 
-    private List<SysOrg> getExecOrgList(CoreEduTrainingPlanDataVo plan, Date start, Date end) {
-        List<CoreEduTrainingPlanToExecOrg> planExecOrgList = plan.getPlanExecOrgList();
-        List<SysOrg> orgList;
-        if (ObjectUtil.isEmpty(planExecOrgList)) {
-            Integer orgType = plan.getExecOrgType();
-            orgList = RemoteCallHandlerExecutor.executeRemoteCall(() -> orgService.selectByOrgPathAndOrgType(plan.getBelongOrgPath(), orgType, SecurityConstants.INNER), ErrorMsgConstants.QUERY_ORG_DATA_ERROR);
-        } else {
-            List<Long> list = planExecOrgList.stream().map(CoreEduTrainingPlanToExecOrg::getOrgId).collect(Collectors.toList());
-            orgList = RemoteCallHandlerExecutor.executeRemoteCall(() -> orgService.selectOrgByIdList(list, SecurityConstants.INNER), ErrorMsgConstants.QUERY_ORG_DATA_ERROR);
-        }
+
+    private List<SysWorkTime> getWorkTimeList(List<SysOrg> orgList, Date start, Date end) {
         List<Long> orgIdList = orgList.stream().map(SysOrg::getId).collect(Collectors.toList());
         String startTime = DateUtil.format(start, Constants.DAILY_FORMAT);
         String endTime = DateUtil.format(end, Constants.DAILY_FORMAT);
@@ -448,59 +442,164 @@ public class CoreEduTrainingTaskServiceImpl extends ServiceImpl<CoreEduTrainingT
         workTimeDto.setOrgIdList(orgIdList);
         workTimeDto.setStartTime(startTime);
         workTimeDto.setEndTime(endTime);
-        List<SysWorkTime> workTimeList = RemoteCallHandlerExecutor.executeRemoteCall(() ->
-                        workTimeService.findWorkTimeByRange(workTimeDto, SecurityConstants.INNER).getData(),
+        return RemoteCallHandlerExecutor.executeRemoteCall(() ->
+                        workTimeService.findWorkTimeByRange(workTimeDto, SecurityConstants.FROM_SOURCE).getData(),
                 ErrorMsgConstants.QUERY_ORG_WORK_TIME_ERROR);
-        if (workTimeList.isEmpty()) {
-            log.error("生成任务时,需要生成任务的机构均未营业,本次任务跳过!");
-            return new ArrayList<>();
+    }
+
+    private List<SysOrg> getExecOrgList(List<CoreEduTrainingPlanToExecOrg> planExecOrgList, Integer execOrgType, String belongOrgPath) {
+        if (ObjectUtil.isEmpty(planExecOrgList)) {
+            return RemoteCallHandlerExecutor.executeRemoteCall(() ->
+                            orgService.selectByOrgPathAndOrgType(belongOrgPath, execOrgType, SecurityConstants.INNER),
+                    ErrorMsgConstants.QUERY_ORG_DATA_ERROR);
+        } else {
+            List<Long> list = planExecOrgList.stream().map(CoreEduTrainingPlanToExecOrg::getOrgId).collect(Collectors.toList());
+            return RemoteCallHandlerExecutor.executeRemoteCall(() ->
+                            orgService.selectOrgByIdList(list, SecurityConstants.INNER),
+                    ErrorMsgConstants.QUERY_ORG_DATA_ERROR);
+        }
+    }
+
+    /**
+     * 将当前周期开始结束时间,按频次拆分为多个时段。如果该时段歇业,则不包含该次,如返回次数1,3.
+     *
+     * @param frequency
+     * @param start
+     * @param end
+     * @param workTimes,为null则认为全是营业
+     * @return
+     */
+    private Map<Short, DateRange> splitTaskTime(Short frequency, CycleCommonEnum cycle, Date start, Date end, List<SysWorkTime> workTimes) {
+        boolean sameDay = DateUtil.isSameDay(start, end); //一天内按半小时分,
+
+        DateUnit dateUnit;
+        DateField dateField;
+        if (sameDay) {
+            dateField = DateField.MINUTE;
+            dateUnit = DateUnit.MINUTE;
+        } else {
+            dateField = DateField.DAY_OF_YEAR;
+            dateUnit = DateUnit.DAY;
+        }
+        double diff = DateUtil.between(start, end, dateUnit);
+        double seg = diff / frequency;
+        if (sameDay) {
+            seg = Math.round(seg / 30) * 30;
+        } else {
+            seg = Math.round(seg);
+            if (cycle == CycleCommonEnum.DAILY && frequency == 3) {
+                seg = 10;
+            }
         }
-        List<Long> workOrgIdList = workTimeList.stream().filter(time -> ObjectUtil.equal(time.getIsEnable(), WORK))
-                .map(SysWorkTime::getOrgId).collect(Collectors.toList());
-        return orgList.stream()
-                .filter(org -> workOrgIdList.contains(org.getId())||!OrgTypeEnum.YINGYE_WANGDIAN.getCode().equals(org.getType()))
-                .collect(Collectors.toList());
-        // return orgList;
 
+        DateTime segStart = new DateTime(start);
+
+        Map<Short, DateRange> r = new HashMap<>();
+        for (short i = 1; i <= frequency; i++) {
+            if (dateField == DateField.DAY_OF_YEAR) {
+                segStart.setField(DateField.HOUR, 0)
+                        .setField(DateField.MINUTE, 0)
+                        .setField(DateField.SECOND, 0)
+                        .setField(DateField.MILLISECOND, 0);
+            }
+            DateTime nextStart = DateUtil.offset(segStart, dateField, (int) (seg));
+            DateRange et = new DateRange();
+            et.setStartTime(segStart);
+            DateTime segEnd;
+            if (i == frequency) {
+                segEnd = new DateTime(end);
+            } else {
+                segEnd = nextStart;
+
+                if (dateField == DateField.DAY_OF_YEAR) {
+                    segEnd = DateUtil.offset(nextStart, DateField.SECOND, -1);
+                    segEnd.setField(DateField.HOUR_OF_DAY, 23).setField(DateField.MINUTE, 59).setField(DateField.SECOND, 59);
+                }
+                if (segEnd.after(end)) {
+                    segEnd = new DateTime(end);
+                }
+            }
+            segEnd.setField(DateField.MILLISECOND, 0);
+            et.setEndTime(segEnd);
+            segStart = nextStart;
+
+            if (segEnd.before(new Date())) {
+                continue;
+            }
+
+            if (workTimes == null || containCurrentCycle(workTimes, et.getStartTime(), et.getEndTime())) {
+                r.put(i, et);
+            }
+        }
+
+        return r;
+    }
+
+    /**
+     * 获取作息日期与当前周期是否有交集
+     *
+     * @param workTimes
+     * @param start
+     * @param end
+     * @return
+     */
+    private Boolean containCurrentCycle(List<SysWorkTime> workTimes, Date start, Date end) {
+        if (start.after(end)) {
+            return false;
+        }
+        Set<Long> timeValues = workTimes.stream().map(t -> t.getYmdDate().getTime()).collect(Collectors.toSet());
+        while (true) {
+            if (timeValues.contains(DateUtil.beginOfDay(start).getTime())) {
+                return true;
+            }
+
+            start = DateUtil.offset(start, DateField.DAY_OF_YEAR, 1);
+            if (start.equals(end) || start.after(end)) {
+                return false;
+            }
+        }
     }
 
-    private void saveTaskAndRoleData(CoreEduTrainingPlanDataVo plan, Date start, Date end, List<SysOrg> orgList) {
+
+    private void saveTaskAndRoleData(CoreEduTrainingPlanDataVo plan, Date start, Date end, List<SysOrg> orgList, List<SysWorkTime> workTimeList) {
         //List<CoreEduTrainingPlanToRole> planRoleList = plan.getPlanRoleList();
         List<CoreEduTrainingTask> taskList = new ArrayList<>();
         //List<CoreEduTrainingTaskToRole> taskRoleList = new ArrayList<>();
-        Map<Integer, DateRange> dateRangeMap = DateUtils.splitDateRange(start, end, plan.getExecTimes());
+        //Map<Integer, DateRange> dateRangeMap = DateUtils.splitDateRange(start, end, plan.getExecTimes());
         //获取dateRangeMap中最大和最小的时间
-        Date maxDateRange = dateRangeMap.get(dateRangeMap.size()).getEndTime();
-        Date minDateRange = dateRangeMap.get(1).getStartTime();
         final List<Long> collect = orgList.stream().map(SysOrg::getId).collect(Collectors.toList());
         Date date = new Date();
         final List<CoreEduTrainingTask> trainingTaskList = baseMapper.selectList(new LambdaQueryWrapper<CoreEduTrainingTask>()
                 .in(CoreEduTrainingTask::getOrgId, collect)
-                .ge(CoreEduTrainingTask::getStartDate, minDateRange)
-                .le(CoreEduTrainingTask::getEndDate, maxDateRange)
+                .ge(CoreEduTrainingTask::getStartDate, start)
+                .le(CoreEduTrainingTask::getEndDate, end)
                 .eq(CoreEduTrainingTask::getPlanId, plan.getId())
                 .select(CoreEduTrainingTask::getId, CoreEduTrainingTask::getOrgId, CoreEduTrainingTask::getStartDate, CoreEduTrainingTask::getEndDate, CoreEduTrainingTask::getPlanId)
         );
+        final Map<Long, List<SysWorkTime>> listMap = workTimeList.stream().collect(Collectors.groupingBy(SysWorkTime::getOrgId));
 
         for (SysOrg org : orgList) {
+            final List<SysWorkTime> sysWorkTimes = OrgTypeEnum.YINGYE_WANGDIAN.getCode().equals(org.getType()) ? listMap.get(org.getId()) : null;
+            final Map<Short, DateRange> rangeMap = splitTaskTime(plan.getExecTimes().shortValue(), EduTrainingPlanCycleEnum.toCommonEnum(plan.getPlanCycle()), start, end, sysWorkTimes);
             int x = 0;
-            for (int i = 1; i <= plan.getExecTimes(); i++) {
-                final LocalDateTime time = DateUtils.toLocalDateTime(DateUtils.getPreciseTime(dateRangeMap.get(i).getEndTime()));
+            for (Map.Entry<Short, DateRange> rangeEntry : rangeMap.entrySet()) {
+                final Short key = rangeEntry.getKey();
+                final DateRange value = rangeEntry.getValue();
+                /*final LocalDateTime time = DateUtils.toLocalDateTime(DateUtils.getPreciseTime(value.getEndTime()));
                 if (time.isBefore(LocalDateTime.now())) {
                     //如果任务的结束时间 已经小于当前时间则没必要生成任务了,
                     //用于处理周期中生成多次任务,周期初的任务一经生成就无法执行(预期)的问题,
-                    log.warn("生成任务时,任务的结束时间已经小于当前时间,本次任务跳过,任务id:{},任务执行机构id:{},任务时间范围:{}-{}", plan.getId(), org.getId(), dateRangeMap.get(i).getStartTime(), dateRangeMap.get(i).getEndTime());
+                    log.warn("生成任务时,任务的结束时间已经小于当前时间,本次任务跳过,任务id:{},任务执行机构id:{},任务时间范围:{}-{}", plan.getId(), org.getId(), value.getStartTime(), value.getEndTime());
                     continue;
-                }
-                DateRange dateRange = dateRangeMap.get(i);
+                }*/
                 CoreEduTrainingTask trainingTask = new CoreEduTrainingTask();
                 trainingTask.setId(IdWorker.getId());
                 trainingTask.setOrgId(org.getId());
                 trainingTask.setType(plan.getType());
                 trainingTask.setPlanId(plan.getId());
                 trainingTask.setPlanCycle(plan.getPlanCycle());
-                trainingTask.setStartDate(DateUtils.getPreciseTime(dateRange.getStartTime()));
-                trainingTask.setEndDate(DateUtils.getPreciseTime(dateRange.getEndTime()));
+                trainingTask.setStartDate(DateUtils.getPreciseTime(value.getStartTime()));
+                trainingTask.setEndDate(DateUtils.getPreciseTime(value.getEndTime()));
                 trainingTask.setContent(null);
                 if (plan.getExecTimes() > 1) {
                     x++;