|  |  | 
 |  |  |     @Value("${wechat.irr.plan.planTerminateLimitMinutes:5}") | 
 |  |  |     private Integer planTerminateLimitMinutes; // 计划终止后限制发布新计划的时间间隔(分钟) | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 添加灌溉计划 | 
 |  |  |      * | 
 |  |  |      * @param po | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     @Transactional(rollbackFor = Exception.class) | 
 |  |  |     public Long addIrrigatePlan(IrIrrigatePlan po) { | 
 |  |  |         irrigatePlanMapper.insert(po); | 
 |  |  |         return po.getId(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 删除灌溉计划 | 
 |  |  |      * | 
 |  |  |      * @param planSimple | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     @Transactional(rollbackFor = Exception.class) | 
 |  |  |     public Map deletePlan(PlanSimple planSimple) { | 
 |  |  |         Long planId = planSimple.getPlanId(); | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 发布灌溉计划 | 
 |  |  |      * | 
 |  |  |      * @param planSimple | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     public Map publishPlan(PlanSimple planSimple) { | 
 |  |  |         Long planId = planSimple.getPlanId(); | 
 |  |  |         Long operatorId = planSimple.getOperatorId(); | 
 |  |  | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         /** | 
 |  |  |          * 获取灌溉计划信息 | 
 |  |  |          * 更新灌溉计划起止时间及计划状态 | 
 |  |  |          */ | 
 |  |  |         VoPlanSimple plan = irrigatePlanMapper.getPlanSimple(planId); | 
 |  |  |         if (plan == null) { | 
 |  |  |             Map map = new HashMap<>(); | 
 |  |  | 
 |  |  |         } | 
 |  |  |         planStartTime = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()); | 
 |  |  |          | 
 |  |  |         // 更新每个灌溉次序的开始时间并计算最后一组关阀时间 | 
 |  |  |         List<VoIrrigateSchedule> schedules = getSchedulesByPlanId(planId); | 
 |  |  |         Date scheduleStartTime = null; | 
 |  |  |         LocalDateTime lastScheduleEndTime = null; | 
 |  |  |         Integer sort = 0; | 
 |  |  |          | 
 |  |  |         // 第一次遍历:更新每个灌溉次序的开始时间 | 
 |  |  |         for (VoIrrigateSchedule schedule : schedules) { | 
 |  |  |             if (scheduleStartTime == null) { | 
 |  |  |                 scheduleStartTime = planStartTime; | 
 |  |  |             } | 
 |  |  |             this.updateScheduleStartTime(schedule.getScheduleId(), scheduleStartTime); | 
 |  |  |              | 
 |  |  |             // 计算当前次序的结束时间 | 
 |  |  |             LocalDateTime currentScheduleStartTime = scheduleStartTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); | 
 |  |  |             LocalDateTime currentScheduleEndTime = currentScheduleStartTime.plusMinutes(schedule.getDuration()); | 
 |  |  |              | 
 |  |  |             // 更新最后一组的结束时间 | 
 |  |  |             lastScheduleEndTime = currentScheduleEndTime; | 
 |  |  |              | 
 |  |  |             // 计算下一组的开始时间 | 
 |  |  |             LocalDateTime LocalscheduleStartTime = scheduleStartTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); | 
 |  |  |             LocalscheduleStartTime = LocalscheduleStartTime.plusMinutes(schedule.getDuration()); | 
 |  |  |             LocalscheduleStartTime = LocalscheduleStartTime.minusMinutes(preOpeningTime); | 
 |  |  |             scheduleStartTime = Date.from(LocalscheduleStartTime.atZone(ZoneId.systemDefault()).toInstant()); | 
 |  |  |  | 
 |  |  |             // 确保下一组的开始时间不早于计划开始时间 | 
 |  |  |             if (scheduleStartTime.before(planStartTime)) { | 
 |  |  |                 scheduleStartTime = planStartTime; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |          | 
 |  |  |         // 根据最后一组关阀时间设置计划结束时间 | 
 |  |  |         if (lastScheduleEndTime != null) { | 
 |  |  |             planStopTime = Date.from(lastScheduleEndTime.atZone(ZoneId.systemDefault()).toInstant()); | 
 |  |  |         } else { | 
 |  |  | 
 |  |  |             planStopTime = Date.from(stopTime.atZone(ZoneId.systemDefault()).toInstant()); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 根据计划ID更新计划信息(起止时间、计划状态) | 
 |  |  |         if (this.updatePlanTimes(planStartTime, planStopTime, planId) == 0) { | 
 |  |  |             Map map = new HashMap<>(); | 
 |  |  |             map.put("success", false); | 
 |  |  | 
 |  |  |             return map; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 添加灌溉计划操作记录 | 
 |  |  |         IrPlanOperate planOperate = new IrPlanOperate(); | 
 |  |  |         planOperate.setPlanId(planId); | 
 |  |  |         planOperate.setOperator(operatorId); | 
 |  |  | 
 |  |  |         for (VoIrrigateSchedule schedule : schedules) { | 
 |  |  |             Long groupId = schedule.getGroupId(); | 
 |  |  |             List<Long> intakeIds = getIntakeIdsByGroupId(groupId); | 
 |  |  |             if(intakeIds == null || intakeIds.size() <= 0) { | 
 |  |  |                 Map map = new HashMap<>(); | 
 |  |  |                 map.put("success", false); | 
 |  |  |                 map.put("msg", "当前轮灌组内没有有效的取水口"); | 
 |  |  |                 map.put("content", null); | 
 |  |  |                 return map; | 
 |  |  |             } | 
 |  |  |             for (Long intakeId : intakeIds) { | 
 |  |  |                 if (schedule.getDuration() > 0) { | 
 |  |  |                     // 今发布灌溉时长大于0的 | 
 |  |  | 
 |  |  |         return irIrrigateUnitMapper.getIntakeIdByUnitId(unitId); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 根据计划ID获取计划发布结果 | 
 |  |  |      * | 
 |  |  |      * @param planId | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     public VoPlanDetails getPublishResults(Long planId) { | 
 |  |  |         VoPlanDetails planDetails = irrigatePlanMapper.getPlanDetails(planId); | 
 |  |  |         if (planDetails == null) { | 
 |  |  | 
 |  |  |  | 
 |  |  |         planDetails.setGroups(groupResults); | 
 |  |  |         return planDetails; | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 根据计划ID获取计划终止操作结果 | 
 |  |  |      * | 
 |  |  |      * @param planId | 
 |  |  |      * @return | 
 |  |  |      */ | 
 |  |  |     public VoPlanDetails getTerminateResults(Long planId) { | 
 |  |  |         // 获取计划终止时间 | 
 |  |  |         Date terminateTime = Optional.ofNullable(irPlanOperateMapper.getTerminateTime(planId)).orElse(null); |