package com.zy.asrs.task.support; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.WrkMastService; import com.zy.common.entity.Parameter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigInteger; import java.util.List; import java.util.Objects; @Component public class OutboundBatchSeqReleaseGuard { public static final long OUTBOUND_CRN_COMPLETE_WRK_STS = 25L; public static final long OUTBOUND_STATION_COMPLETE_WRK_STS = 26L; public static final long OUTBOUND_TASK_COMPLETE_WRK_STS = 14L; public static final long OUTBOUND_ERP_REPORT_PENDING_WRK_STS = 17L; public static final long OUTBOUND_FINISHED_WRK_STS = 15L; private static final int OUTBOUND_IO_TYPE = 101; private static final int DEFAULT_STATUS25_THRESHOLD = 1; @Autowired private WrkMastService wrkMastService; public String validateReady(String userNo, String batchSeq) { if (Cools.isEmpty(batchSeq)) { return "出库进仓编号(batchSeq)为空,跳过下发, userNo=" + normalizeUserNo(userNo); } List rows = selectOutboundRows(userNo); if (rows == null || rows.isEmpty()) { return null; } boolean hasEarlierBatchSeq = false; String blockingBatchSeq = null; int status25Count = 0; for (WrkMast row : rows) { if (row == null) { continue; } if (Objects.equals(row.getWrkSts(), OUTBOUND_CRN_COMPLETE_WRK_STS)) { status25Count++; } String rowBatchSeq = normalizeBatchSeq(row.getBatchSeq()); if (Cools.isEmpty(rowBatchSeq) || compareBatchSeqNatural(rowBatchSeq, batchSeq) >= 0) { continue; } hasEarlierBatchSeq = true; if (!isReleaseStatus(row.getWrkSts()) && (blockingBatchSeq == null || compareBatchSeqNatural(rowBatchSeq, blockingBatchSeq) < 0)) { blockingBatchSeq = rowBatchSeq; } } if (blockingBatchSeq != null) { return "出库进仓编号未释放,暂停后续下发, userNo=" + normalizeUserNo(userNo) + ", blockingBatchSeq=" + blockingBatchSeq + ", nextBatchSeq=" + normalizeBatchSeq(batchSeq); } int threshold = getStatus25Threshold(); if (hasEarlierBatchSeq && status25Count >= threshold) { return "出库进仓编号25状态数量达到阀值,暂停后续下发, userNo=" + normalizeUserNo(userNo) + ", status25Count=" + status25Count + ", threshold=" + threshold + ", nextBatchSeq=" + normalizeBatchSeq(batchSeq); } return null; } public boolean isReleaseStatus(Long wrkSts) { return Objects.equals(wrkSts, OUTBOUND_CRN_COMPLETE_WRK_STS) || Objects.equals(wrkSts, OUTBOUND_STATION_COMPLETE_WRK_STS) || Objects.equals(wrkSts, OUTBOUND_TASK_COMPLETE_WRK_STS) || Objects.equals(wrkSts, OUTBOUND_ERP_REPORT_PENDING_WRK_STS) || Objects.equals(wrkSts, OUTBOUND_FINISHED_WRK_STS); } private List selectOutboundRows(String userNo) { EntityWrapper wrapper = new EntityWrapper<>(); if (Cools.isEmpty(userNo)) { wrapper.andNew().isNull("user_no").or().eq("user_no", ""); } else { wrapper.eq("user_no", userNo); } wrapper.eq("io_type", OUTBOUND_IO_TYPE); return wrkMastService.selectList(wrapper); } private int getStatus25Threshold() { Parameter parameter = Parameter.get(); if (parameter == null || Cools.isEmpty(parameter.getOutBatchSeqStatus25Threshold())) { return DEFAULT_STATUS25_THRESHOLD; } try { int threshold = Integer.parseInt(parameter.getOutBatchSeqStatus25Threshold().trim()); return threshold <= 0 ? DEFAULT_STATUS25_THRESHOLD : threshold; } catch (NumberFormatException ignored) { return DEFAULT_STATUS25_THRESHOLD; } } private static int compareBatchSeqNatural(String left, String right) { String safeLeft = normalizeBatchSeq(left); String safeRight = normalizeBatchSeq(right); int leftIndex = 0; int rightIndex = 0; while (leftIndex < safeLeft.length() && rightIndex < safeRight.length()) { char leftChar = safeLeft.charAt(leftIndex); char rightChar = safeRight.charAt(rightIndex); if (Character.isDigit(leftChar) && Character.isDigit(rightChar)) { int leftStart = leftIndex; int rightStart = rightIndex; while (leftIndex < safeLeft.length() && Character.isDigit(safeLeft.charAt(leftIndex))) { leftIndex++; } while (rightIndex < safeRight.length() && Character.isDigit(safeRight.charAt(rightIndex))) { rightIndex++; } String leftNumber = safeLeft.substring(leftStart, leftIndex); String rightNumber = safeRight.substring(rightStart, rightIndex); int compare = new BigInteger(leftNumber).compareTo(new BigInteger(rightNumber)); if (compare != 0) { return compare; } compare = Integer.compare(leftNumber.length(), rightNumber.length()); if (compare != 0) { return compare; } continue; } int compare = Character.compare(leftChar, rightChar); if (compare != 0) { return compare; } leftIndex++; rightIndex++; } return Integer.compare(safeLeft.length(), safeRight.length()); } private static String normalizeBatchSeq(String value) { return Cools.isEmpty(value) ? "" : value; } private static String normalizeUserNo(String value) { return Cools.isEmpty(value) ? "" : value; } }