| | |
| | | import com.zy.core.enums.WrkStsType; |
| | | import com.zy.core.model.StationObjModel; |
| | | import com.zy.core.model.protocol.StationProtocol; |
| | | import com.zy.core.move.StationMoveCoordinator; |
| | | import com.zy.core.move.StationMoveSession; |
| | | import com.zy.core.thread.StationThread; |
| | | import com.zy.core.utils.CrnOperateProcessUtils; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Component |
| | | public class InboundCrnMoveDispatchScheduler { |
| | |
| | | private final CommonService commonService; |
| | | private final BasCrnpService basCrnpService; |
| | | private final CrnOperateProcessUtils crnOperateProcessUtils; |
| | | private final StationMoveCoordinator stationMoveCoordinator; |
| | | |
| | | public InboundCrnMoveDispatchScheduler(WrkMastService wrkMastService, |
| | | BasStationService basStationService, |
| | | CommonService commonService, |
| | | BasCrnpService basCrnpService, |
| | | CrnOperateProcessUtils crnOperateProcessUtils, |
| | | StationMoveCoordinator stationMoveCoordinator) { |
| | | CrnOperateProcessUtils crnOperateProcessUtils) { |
| | | this.wrkMastService = wrkMastService; |
| | | this.basStationService = basStationService; |
| | | this.commonService = commonService; |
| | | this.basCrnpService = basCrnpService; |
| | | this.crnOperateProcessUtils = crnOperateProcessUtils; |
| | | this.stationMoveCoordinator = stationMoveCoordinator; |
| | | } |
| | | |
| | | @Scheduled(fixedDelay = 1000L) |
| | |
| | | |
| | | // 同堆垛机没有需要参与当前调度判断的出库任务时,优先直接到当前入库任务取货位等待。 |
| | | if (!hasBlockingOutboundTask(crnNo)) { |
| | | boolean dispatched = crnOperateProcessUtils.dispatchCrnMove(crnNo, inboundPickupLocNo); |
| | | boolean dispatched = crnOperateProcessUtils.dispatchCrnMove(crnNo, inboundPickupLocNo, true); |
| | | if (dispatched) { |
| | | News.info("检测到仅有入库任务,已触发堆垛机直接移动到入库任务取货位等待,工作号={},堆垛机号={},取货位={}", |
| | | wrkMast.getWrkNo(), crnNo, inboundPickupLocNo); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | StationMoveSession session = stationMoveCoordinator == null ? null : stationMoveCoordinator.loadSession(wrkMast.getWrkNo()); |
| | | if (!isInboundCrnMoveDispatchWindow(wrkMast, session)) { |
| | | return; |
| | | } |
| | | |
| | | boolean dispatched = crnOperateProcessUtils.dispatchCrnMove(crnNo, inboundPickupLocNo); |
| | | if (dispatched) { |
| | | News.info("入库任务即将到达取货位,已触发堆垛机预移车,工作号={},堆垛机号={},取货位={}", |
| | | wrkMast.getWrkNo(), crnNo, inboundPickupLocNo); |
| | | } else { |
| | | News.taskInfo(wrkMast.getWrkNo(), "当前存在阻塞入库预移车的出库任务,暂不触发堆垛机预移车"); |
| | | } |
| | | } |
| | | |
| | |
| | | return true; |
| | | } |
| | | |
| | | String activeBatch = resolveActiveOutboundBatch(pendingOutboundTasks); |
| | | if (Cools.isEmpty(activeBatch)) { |
| | | return true; |
| | | } |
| | | |
| | | return pendingOutboundTasks.stream() |
| | | .filter(this::isCrnMoveBlockingOutboundTask) |
| | | .filter(this::isBatchTaskWithSeq) |
| | | .anyMatch(task -> Objects.equals(activeBatch, task.getBatch())); |
| | | } |
| | | |
| | | private String resolveActiveOutboundBatch(List<WrkMast> pendingOutboundTasks) { |
| | | if (pendingOutboundTasks == null || pendingOutboundTasks.isEmpty()) { |
| | | return null; |
| | | } |
| | | Set<String> activeBatchSet = pendingOutboundTasks.stream() |
| | | .filter(this::isBatchTaskWithSeq) |
| | | .filter(task -> !Objects.equals(task.getWrkSts(), WrkStsType.NEW_OUTBOUND.sts)) |
| | | .map(WrkMast::getBatch) |
| | | .filter(batch -> !Cools.isEmpty(batch)) |
| | | .collect(Collectors.toSet()); |
| | | if (activeBatchSet.size() != 1) { |
| | | return null; |
| | | } |
| | | return activeBatchSet.iterator().next(); |
| | | .filter(crnOperateProcessUtils::canOutboundTaskExecuteInCurrentBatchWindow) |
| | | .findAny() |
| | | .isPresent(); |
| | | } |
| | | |
| | | private boolean isBatchTaskWithSeq(WrkMast wrkMast) { |
| | |
| | | && wrkMast.getBatchSeq() != null; |
| | | } |
| | | |
| | | private boolean isInboundCrnMoveDispatchWindow(WrkMast wrkMast, StationMoveSession session) { |
| | | if (wrkMast == null || session == null || !session.isActive() || wrkMast.getStaNo() == null) { |
| | | private boolean isCrnMoveBlockingOutboundTask(WrkMast wrkMast) { |
| | | if (wrkMast == null || wrkMast.getWrkSts() == null) { |
| | | return false; |
| | | } |
| | | List<Integer> fullPathStationIds = session.getFullPathStationIds(); |
| | | Integer currentStationId = session.getCurrentStationId(); |
| | | if (fullPathStationIds == null || fullPathStationIds.isEmpty() || currentStationId == null) { |
| | | return false; |
| | | } |
| | | int currentIndex = fullPathStationIds.lastIndexOf(currentStationId); |
| | | if (currentIndex < 0 || currentIndex >= fullPathStationIds.size() - 1) { |
| | | return false; |
| | | } |
| | | int remainingStationCount = fullPathStationIds.size() - currentIndex - 1; |
| | | if (remainingStationCount != 1) { |
| | | return false; |
| | | } |
| | | Integer nextStationId = fullPathStationIds.get(currentIndex + 1); |
| | | return Objects.equals(nextStationId, wrkMast.getStaNo()); |
| | | return Objects.equals(wrkMast.getWrkSts(), WrkStsType.NEW_OUTBOUND.sts) |
| | | || Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_RUN.sts) |
| | | || Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_MANUAL.sts); |
| | | } |
| | | } |