package com.dy.pipIrrWechat.irrigatePlan; import com.dy.common.webUtil.QueryConditionVo; import com.dy.common.webUtil.QueryResultVo; import com.dy.pipIrrGlobal.daoIr.*; import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper; import com.dy.pipIrrGlobal.pojoIr.IrIrrigatePlan; import com.dy.pipIrrGlobal.pojoIr.IrIrrigateSchedule; import com.dy.pipIrrGlobal.pojoIr.IrPlanOperate; import com.dy.pipIrrGlobal.pojoIr.IrPlanSchedule; import com.dy.pipIrrGlobal.voIr.*; import com.dy.pipIrrGlobal.voRm.VoIntakeVc; import com.dy.pipIrrWechat.command.CommandSv; import com.dy.pipIrrWechat.command.dto.AutomaticClose; import com.dy.pipIrrWechat.irrigatePlan.dto.PlanSimple; import com.dy.pipIrrWechat.irrigatePlan.enums.OperateTypeENUM; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.common.utils.PojoUtils; import org.apache.ibatis.annotations.Param; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; /** * @author ZhuBaoMin * @date 2025-02-20 15:27 * @LastEditTime 2025-02-20 15:27 * @Description */ @Slf4j @Service public class IrrigatePlanSv { @Autowired private IrIrrigatePlanMapper irrigatePlanMapper; @Autowired private IrPlanOperateMapper irPlanOperateMapper; @Autowired private IrIrrigateScheduleMapper irIrrigateScheduleMapper; @Autowired private IrOpeningScheduleMapper irOpeningScheduleMapper; @Autowired private IrIrrigateGroupMapper irIrrigateGroupMapper; @Autowired private IrIrrigateUnitMapper irIrrigateUnitMapper; @Autowired private IrPlanScheduleMapper irPlanScheduleMapper; @Autowired private IrGroupIntakeMapper irGroupIntakeMapper; @Autowired private IrIntakeOperateMapper irIntakeOperateMapper; @Autowired private RmCommandHistoryMapper rmdCommandHistoryMapper; @Autowired private CommandSv commandSv; /** * 添加灌溉计划 * @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(); Long operatorId = planSimple.getOperatorId(); Integer planState = irrigatePlanMapper.getPlanState(planId); if(planState == null) { Map map = new HashMap<>(); map.put("success", false); map.put("msg", "灌溉计划不存在"); map.put("content", null); return map; } if(planState != 1) { Map map = new HashMap<>(); map.put("success", false); map.put("msg", "灌溉计划非草稿状态,不允许删除"); map.put("content", null); return map; } try { irrigatePlanMapper.deleteByPrimaryKey(planId); // 添加灌溉计划操作记录 IrPlanOperate planOperate = new IrPlanOperate(); planOperate.setPlanId(planId); planOperate.setOperator(operatorId); planOperate.setOperateType(OperateTypeENUM.DELETE.getCode()); planOperate.setOperateTime(new Date()); addPlanOperate(planOperate); Map map = new HashMap<>(); map.put("success", true); map.put("msg", "灌溉项目删除成功"); map.put("content", null); return map; } catch (Exception e) { Map map = new HashMap<>(); map.put("success", false); map.put("msg", "灌溉项目删除失败"); map.put("content", null); return map; } } /** * 发布灌溉计划 * @param planSimple * @return */ public Map publishPlan(PlanSimple planSimple) { Long planId = planSimple.getPlanId(); Long operatorId = planSimple.getOperatorId(); Byte operateType = 1; if(irrigatePlanMapper.hasPlan_CurrentProject(planId) > 0) { Map map = new HashMap<>(); map.put("success", false); map.put("msg", "当前项目存在未完成的灌溉计划"); map.put("content", null); return map; } if(irrigatePlanMapper.hasPlan_OtherProject(planId) > 0) { Map map = new HashMap<>(); map.put("success", false); map.put("msg", "待发布计划的轮灌组在其他项目的灌溉计划中,且该计划尚未完成"); map.put("content", null); return map; } /** * 获取灌溉计划信息 * 更新灌溉计划起止时间及计划状态 */ VoPlanSimple plan = irrigatePlanMapper.getPlanSimple(planId); if(plan == null){ Map map = new HashMap<>(); map.put("success", false); map.put("msg", "您要发布的计划不存在,或该计划已发布"); map.put("content", null); return map; } Byte startupMode = plan.getStartupMode(); Integer duration = plan.getDuration(); Date planStartTime = plan.getPlanStartTime(); Date planStopTime = null; if(startupMode == 1){ planStartTime = new Date(); } LocalDateTime startTime = planStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime(); if(startupMode == 1){ // 测试阶段延后2分钟,正式发布为5分钟 startTime = startTime.plusMinutes(2); //startTime = startTime.plusMinutes(5); } planStartTime = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()); LocalDateTime stopTime = startTime.plusMinutes(duration); planStopTime = Date.from(stopTime.atZone(ZoneId.systemDefault()).toInstant()); // 根据计划ID更新计划信息(起止时间、计划状态) if(this.updatePlanTimes(planStartTime, planStopTime, planId) == 0) { Map map = new HashMap<>(); map.put("success", false); map.put("msg", "计划信息更新失败"); map.put("content", null); return map; } // 更新每个灌溉次序的开始时间 List schedules = getSchedulesByPlanId(planId); Date scheduleStartTime = null; Integer sort = 0; for(VoIrrigateSchedule schedule : schedules){ if(scheduleStartTime == null) { scheduleStartTime = planStartTime; } this.updateScheduleStartTime(schedule.getScheduleId(), scheduleStartTime); // 计算下一组的开始时间 LocalDateTime LocalscheduleStartTime = scheduleStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime(); LocalscheduleStartTime = LocalscheduleStartTime.plusMinutes(schedule.getDuration()); LocalscheduleStartTime = LocalscheduleStartTime.minusMinutes(2); scheduleStartTime = Date.from(LocalscheduleStartTime.atZone(ZoneId.systemDefault()).toInstant()); } // 添加灌溉计划操作记录 IrPlanOperate planOperate = new IrPlanOperate(); planOperate.setPlanId(planId); planOperate.setOperator(operatorId); planOperate.setOperateType(OperateTypeENUM.PUBLISH.getCode()); planOperate.setOperateTime(new Date()); if(addPlanOperate(planOperate) == 0){ Map map = new HashMap<>(); map.put("success", false); map.put("msg", "添加灌溉计划操作记录失败"); map.put("content", null); return map; } schedules = getSchedulesByPlanId(planId); for(VoIrrigateSchedule schedule : schedules) { Long groupId = schedule.getGroupId(); List intakeIds = getIntakeIdsByGroupId(groupId); for(Long intakeId : intakeIds) { if(schedule.getDuration() > 0) { // 今发布灌溉时长大于0的 AutomaticClose automaticClose = new AutomaticClose(); automaticClose.setIntakeId(intakeId); automaticClose.setPlannedOpenTime(schedule.getStartTime()); automaticClose.setMinutes(schedule.getDuration()); automaticClose.setOperator(operatorId); automaticClose.setOpenType(Byte.valueOf("1")); commandSv.planedOpenTimedClose(automaticClose, planId, operateType, schedule.getStartTime(), schedule.getDuration()); } } } Map map = new HashMap<>(); map.put("success", true); map.put("msg", "灌溉项目删除成功"); map.put("content", null); return map; } /** * 根据计划ID获取计划最新状态 * @param planId * @return */ public Integer getPlanLatestState(Long planId) { return irrigatePlanMapper.getPlanLatestState(planId); } /** * 根据计划ID获取待终止计划的结束时间:未删除、未终止、已发布、当前时间小于计划结束时间 * @param planId * @return */ public Date getToTerminatePlan(Long planId) { return irrigatePlanMapper.getToTerminatePlan(planId); } /** * 根据计划ID获取待终止的取水口ID(已发布开发命令,无论是否成功) * @param planId * @return */ public List getToTerminateIntakeIds(Long planId) { return irIntakeOperateMapper.getToTerminateIntakeIds(planId); } /** * 根据计划ID获取待终止的命令ID列表 * @param planId * @return */ public List getTerminateCommandIds(Long planId) { return irIntakeOperateMapper.getTerminateCommandIds(planId); } /** * 根据计划ID获取待终止的取水口列表(开阀成功的) * @param planId * @return */ public List getToTerminateIntakes(Long planId) { return irIntakeOperateMapper.getToTerminateIntakes(planId); } /** * 根据命令日志ID获取取水口及虚拟卡信息,终止灌溉计划时使用,用来执行远程关阀 * @param commandId * @return */ public VoIntakeVc getValveOpen(Long commandId) { return rmdCommandHistoryMapper.getValveOpen(commandId); } /** * 修改灌溉计划 * @param po * @return */ @Transactional(rollbackFor = Exception.class) public Integer updatePlan(IrIrrigatePlan po) { return irrigatePlanMapper.updateByPrimaryKeySelective(po); } /** * 获取未完成的计划列表,小程序计划列表页使用 * @return */ public List getNotCompletePlans() { return irrigatePlanMapper.getNotCompletePlans(); } /** * 获取已完成的计划列表,小程序计划列表页使用 * @return */ public QueryResultVo> getCompletedPlans(QueryConditionVo queryVo) { Map params = (Map) PojoUtils.generalize(queryVo) ; Long itemTotal = (long)irrigatePlanMapper.getCompletedPlansCount(params); QueryResultVo> rsVo = new QueryResultVo<>() ; rsVo.pageSize = queryVo.pageSize ; rsVo.pageCurr = queryVo.pageCurr ; rsVo.calculateAndSet(itemTotal, params); rsVo.obj = irrigatePlanMapper.getCompletedPlans(params); return rsVo ; } /** * 根据指定的计划ID获取启动模式 * @param planId * @return */ public Byte getStartupMode(Long planId) { return irrigatePlanMapper.getStartupMode(planId); } /** * 根据指定的条件获取计划列表 * @param queryVo * @return */ //public QueryResultVo> getIrrigatePlans(QoIrrigatePlan queryVo) { // Map params = (Map) PojoUtils.generalize(queryVo); // // Long itemTotal = irrigatePlanMapper.getIrrigatePlanCount(params); // // QueryResultVo> rsVo = new QueryResultVo<>(); // rsVo.pageSize = queryVo.pageSize; // rsVo.pageCurr = queryVo.pageCurr; // // rsVo.calculateAndSet(itemTotal, params); // rsVo.obj = irrigatePlanMapper.getIrrigatePlans(params); // return rsVo; //} /** * 添加灌溉计划操作记录 * @param po * @return */ @Transactional(rollbackFor = Exception.class) public Long addPlanOperate(IrPlanOperate po) { irPlanOperateMapper.insert(po); return po.getId(); } /** * 添加灌溉次序记录 * @param po * @return */ @Transactional(rollbackFor = Exception.class) public Long addIrrigateSchedule(IrIrrigateSchedule po) { irIrrigateScheduleMapper.insert(po); return po.getId(); } /** * 根据计划ID终止灌溉次序,将灌溉次序的当前状态改为已终止 * @param planId * @return */ @Transactional(rollbackFor = Exception.class) public Integer terminateSchedule(Long planId) { return irIrrigateScheduleMapper.terminateSchedule(planId); } /** * 根据计划ID获取灌溉次序记录 * @param planId * @return */ public List getSchedulesByPlanId(Long planId) { return irIrrigateScheduleMapper.getSchedulesByPlanId(planId); } /** * 根据组ID获取取水口ID集合 * @param groupId * @return */ public List getIntakeIdsByGroupId(Long groupId) { return irGroupIntakeMapper.getIntakeIdsByGroupId(groupId); } /** * 添加计划次序关联记录 * @param po * @return */ @Transactional(rollbackFor = Exception.class) public Long addPlanSchedule(IrPlanSchedule po) { irPlanScheduleMapper.insert(po); return po.getId(); } /** * 根据灌溉次序ID更新次序开始时间 * @param scheduleId * @param startTime * @return */ @Transactional(rollbackFor = Exception.class) public Integer updateScheduleStartTime(Long scheduleId, Date startTime) { return irIrrigateScheduleMapper.updateScheduleStartTime(scheduleId, startTime); } ///** // * 添加开阀计划 // * @param po // * @return // */ //public Long addOpeningSchedule(IrOpeningSchedule po) { // irOpeningScheduleMapper.insert(po); // return po.getId(); //} /** * 根据灌溉单元ID获取取水口ID * @param unitId * @return */ public Long getIntakeIdByUnitId(Long unitId) { return irIrrigateUnitMapper.getIntakeIdByUnitId(unitId); } /** * 根据计划ID获取计划发布结果 * @param planId * @return */ public VoPlanDetails getPublishResults(Long planId) { VoPlanDetails planDetails = irrigatePlanMapper.getPlanDetails(planId); if(planDetails == null){ return null; } Integer failureCount = Optional.ofNullable(irIntakeOperateMapper.getFailureCount(planId)).orElse(0); planDetails.setFailureCount(failureCount); Date terminateTime = Optional.ofNullable(irPlanOperateMapper.getTerminateTime(planId)).orElse(null); List groupResults = irIrrigateGroupMapper.getGroupResult(planId); if(groupResults == null || groupResults.size() == 0){ return null; } for (VoGroupResult groupResult : groupResults) { List intakeResults = irIntakeOperateMapper.getIntakeResult(planId, groupResult.getGroupId()); if(intakeResults != null) { groupResult.setPublishResult(intakeResults); } } planDetails.setGroups(groupResults); return planDetails; } /** * 根据计划ID获取计划终止操作结果 * @param planId * @return */ public VoPlanDetails getTerminateResults(Long planId) { // 获取计划终止时间 Date terminateTime = Optional.ofNullable(irPlanOperateMapper.getTerminateTime(planId)).orElse(null); VoPlanDetails planDetails = irrigatePlanMapper.getPlanDetails_terminate(planId, terminateTime); if(planDetails == null){ return null; } Integer failureCount = Optional.ofNullable(irIntakeOperateMapper.getFailureCount(planId)).orElse(0); planDetails.setFailureCount(failureCount); List groupResults = irIrrigateGroupMapper.getGroupResult_terminate(planId, terminateTime); if(groupResults == null || groupResults.size() == 0){ return null; } for (VoGroupResult groupResult : groupResults) { List intakeResults = irIntakeOperateMapper.getIntakeResult(planId, groupResult.getGroupId()); if(intakeResults != null) { groupResult.setPublishResult(intakeResults); } } planDetails.setGroups(groupResults); return planDetails; } @Transactional(rollbackFor = Exception.class) private Integer updatePlanTimes(Date planStartTime, Date planEndTime, Long planId){ return irrigatePlanMapper.updatePlanTimes(planStartTime, planEndTime, planId); } }