package com.dy.pipIrrWechat.irrigatePlan; import com.dy.common.webUtil.BaseResponse; import com.dy.common.webUtil.BaseResponseUtils; 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.VoIrrigateSchedule; import com.dy.pipIrrGlobal.voIr.VoPlanSimple; import com.dy.pipIrrGlobal.voIr.VoPlans; import com.dy.pipIrrWechat.command.CommandSv; import com.dy.pipIrrWechat.command.dto.AutomaticClose; import com.dy.pipIrrWechat.irrigatePlan.dto.IrrigatePlan; import com.dy.pipIrrWechat.irrigatePlan.dto.IrrigateSchedule; import com.dy.pipIrrWechat.irrigatePlan.dto.PlanSimple; import com.dy.pipIrrWechat.irrigatePlan.enums.OperateTypeENUM; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; import java.util.Objects; /** * @author ZhuBaoMin * @date 2025-02-20 15:27 * @LastEditTime 2025-02-20 15:27 * @Description */ @Slf4j @RestController @RequestMapping(path = "plan") @RequiredArgsConstructor public class IrrigatePlanCtrl { private final IrrigatePlanSv irrigatePlanSv; private final CommandSv commandSv; /** * 创建灌溉计划 * 1. 添加灌溉计划 * 2. 添加灌溉次序 * 3. 添加灌溉计划操作记录 * @param planAndSchedule * @param bindingResult * @return */ @PostMapping(path = "createPlan", consumes = MediaType.APPLICATION_JSON_VALUE) @Transactional(rollbackFor = Exception.class) public BaseResponse createPlan(@RequestBody @Valid IrrigatePlan planAndSchedule, BindingResult bindingResult){ if(bindingResult != null && bindingResult.hasErrors()){ return BaseResponseUtils.buildErrorMsg(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); } Long projectId = planAndSchedule.getProjectId(); Long operatorId = planAndSchedule.getOperatorId(); Byte startupMode = planAndSchedule.getStartupMode(); Date planStartTime = planAndSchedule.getPlanStartTime();; Date planStopTime = null; Integer duration = 0; for(IrrigateSchedule schedule : planAndSchedule.getSchedules()){ duration = duration + schedule.getDuration(); } if(startupMode == 2){ if(planStartTime == null) { return BaseResponseUtils.buildErrorMsg("自动启动模式必须指定计划启动时间"); } LocalDateTime startTime = planStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime(); LocalDateTime currentTime = LocalDateTime.now(); currentTime = currentTime.plusHours(8); if(!startTime.isAfter(currentTime)) { return BaseResponseUtils.buildErrorMsg("启动时间不能在8小时之内"); } } //if(startupMode == 1){ // planStartTime = new Date(); //} //LocalDateTime startTime = planStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime(); //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()); IrIrrigatePlan plan = new IrIrrigatePlan(); plan.setProjectId(projectId); plan.setPlanName(planAndSchedule.getPlanName()); plan.setStartupMode(startupMode); plan.setPlanStartTime(planStartTime); //plan.setPlanStopTime(planStopTime); plan.setDuration(duration); plan.setPlanState((byte)1); plan.setExecutingState((byte)1); plan.setDeleted(0L); Long planId = irrigatePlanSv.addIrrigatePlan(plan); if(planId == null) { return BaseResponseUtils.buildErrorMsg("创建灌溉计划失败"); } // 添加灌溉次序及计划次序关联表 //Date scheduleStartTime = null; Integer sort = 1; for(IrrigateSchedule schedule : planAndSchedule.getSchedules()){ IrIrrigateSchedule po = new IrIrrigateSchedule(); po.setGroupId(schedule.getGroupId()); //if(scheduleStartTime == null) { // scheduleStartTime = planStartTime; //} //po.setStartTime(scheduleStartTime); //// 计算下一组的开始时间 //LocalDateTime LocalscheduleStartTime = scheduleStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime(); //LocalscheduleStartTime = LocalscheduleStartTime.plusMinutes(schedule.getDuration()); //scheduleStartTime = Date.from(LocalscheduleStartTime.atZone(ZoneId.systemDefault()).toInstant()); po.setDuration(schedule.getDuration()); po.setCurrentState((byte)1); Long scheduleId = irrigatePlanSv.addIrrigateSchedule(po); if(scheduleId == null) { return BaseResponseUtils.buildErrorMsg("创建灌溉计划失败"); } IrPlanSchedule planSchedule = new IrPlanSchedule(); planSchedule.setPlanId(planId); planSchedule.setScheduleId(scheduleId); planSchedule.setSort(sort++); Long planScheduleId = irrigatePlanSv.addPlanSchedule(planSchedule); if(planScheduleId == null) { return BaseResponseUtils.buildErrorMsg("创建灌溉计划失败"); } } // 添加灌溉计划操作记录 IrPlanOperate planOperate = new IrPlanOperate(); planOperate.setPlanId(planId); planOperate.setOperator(operatorId); planOperate.setOperateType(OperateTypeENUM.CREATE.getCode()); planOperate.setOperateTime(new Date()); if(irrigatePlanSv.addPlanOperate(planOperate) == 0){ return BaseResponseUtils.buildErrorMsg("添加灌溉计划操作记录失败"); } return BaseResponseUtils.buildSuccess(); } /** * 获取未完成的计划列表,小程序计划列表页使用 * @return */ @GetMapping(path = "/getNotCompletePlans") public BaseResponse> getNotCompletePlans() { try { List res = irrigatePlanSv.getNotCompletePlans(); return BaseResponseUtils.buildSuccess(res); } catch (Exception e) { log.error("获取未完的计划异常", e); return BaseResponseUtils.buildException(e.getMessage()); } } /** * 获取已完成的计划列表,小程序计划列表页使用 * @return */ @GetMapping(path = "/getCompletedPlans") public BaseResponse> getCompletedPlans() { try { List res = irrigatePlanSv.getCompletedPlans(); return BaseResponseUtils.buildSuccess(res); } catch (Exception e) { log.error("获取项目记录异常", e); return BaseResponseUtils.buildException(e.getMessage()); } } /** * 发布灌溉计划 * 1. 修改灌溉计划状态为发布状态 * 2. 添加灌溉计划操作记录 * 3. 生成开阀计划 * @param planSimple * @param bindingResult * @return */ @PostMapping(path = "publishPlan", consumes = MediaType.APPLICATION_JSON_VALUE) @Transactional(rollbackFor = Exception.class) public BaseResponse publishPlan(@RequestBody @Valid PlanSimple planSimple, BindingResult bindingResult){ if(bindingResult != null && bindingResult.hasErrors()){ return BaseResponseUtils.buildErrorMsg(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); } Long planId = planSimple.getPlanId(); Long operatorId = planSimple.getOperatorId(); Byte operateType = 1; /** * 获取灌溉计划信息 * 更新灌溉计划起止时间及计划状态 */ VoPlanSimple plan = irrigatePlanSv.getPlanSimple(planId); if(plan == null){ return BaseResponseUtils.buildErrorMsg("您要发布的计划不存在,或该计划已发布"); } 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){ startTime = startTime.plusMinutes(1); //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()); if(irrigatePlanSv.updatePlanTimes(planStartTime, planStopTime, planId) == 0) { return BaseResponseUtils.buildErrorMsg("计划信息更新失败"); } // 更新每个灌溉次序的开始时间 List schedules = irrigatePlanSv.getSchedulesByPlanId(planId); Date scheduleStartTime = null; Integer sort = 0; for(VoIrrigateSchedule schedule : schedules){ if(scheduleStartTime == null) { scheduleStartTime = planStartTime; } irrigatePlanSv.updateScheduleStartTime(schedule.getScheduleId(), scheduleStartTime); // 计算下一组的开始时间 LocalDateTime LocalscheduleStartTime = scheduleStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime(); LocalscheduleStartTime = LocalscheduleStartTime.plusMinutes(schedule.getDuration()); 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(irrigatePlanSv.addPlanOperate(planOperate) == 0){ return BaseResponseUtils.buildErrorMsg("添加灌溉计划操作记录失败"); } schedules = irrigatePlanSv.getSchedulesByPlanId(planId); for(VoIrrigateSchedule schedule : schedules) { Long groupId = schedule.getGroupId(); List intakeIds = irrigatePlanSv.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()); } } } return BaseResponseUtils.buildSuccess(); } /** * 终止灌溉计划 * @param planSimple * @param bindingResult * @return */ @PostMapping(path = "terminatePlan", consumes = MediaType.APPLICATION_JSON_VALUE) @Transactional(rollbackFor = Exception.class) public BaseResponse terminatePlan(@RequestBody @Valid PlanSimple planSimple, BindingResult bindingResult){ if(bindingResult != null && bindingResult.hasErrors()){ return BaseResponseUtils.buildErrorMsg(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); } Long planId = planSimple.getPlanId(); Long operatorId = planSimple.getOperatorId(); Byte operateType = 2; // 生成终止开始时间、终止灌溉时长 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String terminateStartTimeStr = "2000-01-01 00:00:00"; Date terminateStartTime = Date.from(LocalDateTime.parse(terminateStartTimeStr, formatter).atZone(ZoneId.systemDefault()).toInstant()); Integer terminateDuration = 100000; // 获取可终止操作计划的灌溉开始时间 Date planStartTime = irrigatePlanSv.getToTerminatePlan(planId); if(planStartTime == null){ return BaseResponseUtils.buildErrorMsg("该计划不存在或不支持终止操作"); } // 终止计划 IrIrrigatePlan iIrrigatePlan = new IrIrrigatePlan(); iIrrigatePlan.setId(planId); iIrrigatePlan.setExecutingState((byte)3); if(irrigatePlanSv.updatePlan(iIrrigatePlan) == 0){ return BaseResponseUtils.buildErrorMsg("终止计划失败"); } // 终止灌溉次序 if(irrigatePlanSv.terminateSchedule(planId) == 0){ return BaseResponseUtils.buildErrorMsg("终止灌溉次序失败"); } // 添加终止操作记录 IrPlanOperate planOperate = new IrPlanOperate(); planOperate.setPlanId(planId); planOperate.setOperator(operatorId); planOperate.setOperateType(OperateTypeENUM.TERMINATE.getCode()); planOperate.setOperateTime(new Date()); if(irrigatePlanSv.addPlanOperate(planOperate) == 0){ return BaseResponseUtils.buildErrorMsg("添加终止操作记录失败"); } Date currentTime = new Date(); if(currentTime.before(planStartTime)){ // 取消开阀计划 List intakeIds = irrigatePlanSv.getToTerminateIntakeIds(planId); for(Long intakeId : intakeIds) { AutomaticClose automaticClose = new AutomaticClose(); automaticClose.setIntakeId(intakeId); automaticClose.setPlannedOpenTime(terminateStartTime); automaticClose.setMinutes(terminateDuration); automaticClose.setOperator(operatorId); automaticClose.setOpenType(Byte.valueOf("1")); commandSv.planedOpenTimedClose(automaticClose, planId, operateType, terminateStartTime, terminateDuration); } } else { // 执行远程关阀 } return BaseResponseUtils.buildSuccess(); } }