自动化立体仓库 - WMS系统
#
zwl
21 小时以前 27c184d7af2775a4d647348ee508f4de335df8fb
src/main/java/com/zy/asrs/utils/Utils.java
@@ -5,19 +5,31 @@
import com.core.common.Cools;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.RowLastno;
import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.RowLastnoService;
import com.zy.common.CodeBuilder;
import com.zy.common.entity.Parameter;
import com.zy.common.model.LocDetlDto;
import com.zy.common.properties.SlaveProperties;
import com.zy.common.service.CommonService;
import com.zy.system.service.UserService;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Locale;
/**
 * Created by vincent on 2020/8/27
@@ -33,6 +45,526 @@
        return (float) Arith.multiplys(2, f, 1);
    }
    public static int armStaNo(int armNo,int staNo) {
        switch (armNo){
            case 1:
                switch (staNo){
                    case 0:
                        return 7;
                    case 1:
                        return 8;
                    case 2:
                        return 101;
                    case 3:
                        return 102;
                    default:
                        return 0;
                }
            case 2:
                switch (staNo){
                    case 0:
                        return 5;
                    case 1:
                        return 6;
                    case 2:
                        return 101;
                    case 3:
                        return 102;
                    default:
                        return 0;
                }
            case 3:
                switch (staNo){
                    case 0:
                        return 3;
                    case 1:
                        return 4;
                    case 2:
                        return 101;
                    case 3:
                        return 102;
                    default:
                        return 0;
                }
            case 4:
                switch (staNo){
                    case 0:
                        return 1;
                    case 1:
                        return 2;
                    case 2:
                        return 101;
                    case 3:
                        return 102;
                    default:
                        return 0;
                }
            case 5:
                switch (staNo){
                    case 0:
                        return 11;
                    case 1:
                        return 12;
                    case 2:
                        return 101;
                    case 3:
                        return 102;
                    default:
                        return 0;
                }
            case 6:
                switch (staNo){
                    case 0:
                        return 13;
                    case 1:
                        return 14;
                    case 2:
                        return 101;
                    case 3:
                        return 102;
                    default:
                        return 0;
                }
            default:
                return 0;
        }
    }
    public static Integer getStationStorageArea(Integer stationId) {
        if (stationId == null || stationId <= 0) {
            return null;
        }
        BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
        BasDevp station = basDevpService.selectById(stationId);
        if (station == null) {
            return null;
        }
        return parseStorageArea(station.getArea());
    }
    /**
     * 生成入库找库位时的堆垛机优先顺序。
     *
     * <p>处理规则:
     * 1. 先根据入库站点查询所属库区。
     * 2. 先提取该库区内的堆垛机,并按可用空库位过滤不可用堆垛机。
     * 3. 若当前库区没有满足条件的空库位,再补充其他库区的堆垛机。
     * 4. 当 {@code locType1 = 1} 时,先返回低库位堆垛机,再把同批堆垛机的高库位追加到后面。
     * 5. 对不存在、故障、不可入以及无空库位的堆垛机直接剔除。
     * 6. 当物料为 {@code emptyPallet} 时,按空板入库优先规则重新排序。
     *
     * <p>返回结果中的每一项格式为:
     * {@code {crnNo: 堆垛机号, locType1: 库位高低类型}}
     *
     * @param stationId 入库站点
     * @param locType1 目标库位高低类型,1=低库位,2=高库位
     * @param matnr 物料编码,传入 {@code emptyPallet} 时使用空板排序规则
     * @return 按优先级排好序的堆垛机列表
     */
    public static List<Map<String, Integer>> getStationStorageAreaName(Integer stationId, Integer locType1, String matnr) {
        List<Map<String, Integer>> result = new ArrayList<>();
        // 先定位入库站点所属库区。
        Integer storageArea = getStationStorageArea(stationId);
        Integer whsType = GetWhsType(stationId);
        if (storageArea == null || whsType == null || whsType <= 0) {
            return result;
        }
        RowLastnoService rowLastnoService = SpringUtils.getBean(RowLastnoService.class);
        RowLastno rowLastno = rowLastnoService.selectById(whsType);
        if (rowLastno == null) {
            return result;
        }
        BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class);
        LocMastService locMastService = SpringUtils.getBean(LocMastService.class);
        boolean emptyPallet = "emptyPallet".equalsIgnoreCase(matnr);
        // 先取当前库区对应的堆垛机。
        List<Integer> preferredCrnNos = getAreaCrnNos(storageArea, rowLastno);
        List<Integer> preferredAvailableCrnNos = getAvailableCrnNos(preferredCrnNos, locType1, emptyPallet, basCrnpService, locMastService);
        appendCrnLocTypeEntries(result, preferredAvailableCrnNos, locType1, locMastService);
        // 当前库区没有可用容量时,再补充其他库区堆垛机。
        if (!hasAvailableCapacity(preferredCrnNos, locType1, basCrnpService, locMastService)) {
            List<Integer> otherAreaCrnNos = getOtherAreaCrnNos(storageArea, rowLastno);
            List<Integer> otherAvailableCrnNos = getAvailableCrnNos(otherAreaCrnNos, locType1, emptyPallet, basCrnpService, locMastService);
            appendCrnLocTypeEntries(result, otherAvailableCrnNos, locType1, locMastService);
        }
        return result;
    }
    private static void appendCrnLocTypeEntries(List<Map<String, Integer>> result, List<Integer> crnNos, Integer locType1, LocMastService locMastService) {
        Short normalizedLocType1 = normalizeLocType1(locType1);
        if (normalizedLocType1 == null) {
            appendCrnLocTypeEntries(result, crnNos, (short) 1, locMastService);
            appendCrnLocTypeEntries(result, crnNos, (short) 2, locMastService);
            return;
        }
        appendCrnLocTypeEntries(result, crnNos, normalizedLocType1, locMastService);
        if (normalizedLocType1 == 1) {
            appendCrnLocTypeEntries(result, crnNos, (short) 2, locMastService);
        }
    }
    private static void appendCrnLocTypeEntries(List<Map<String, Integer>> result, List<Integer> crnNos, Short targetLocType1, LocMastService locMastService) {
        if (targetLocType1 == null || Cools.isEmpty(crnNos)) {
            return;
        }
        for (Integer crnNo : crnNos) {
            if (!hasAvailableLoc(crnNo, targetLocType1, locMastService) || containsCrnLocType(result, crnNo, targetLocType1)) {
                continue;
            }
            Map<String, Integer> item = new LinkedHashMap<>();
            item.put("crnNo", crnNo);
            item.put("locType1", targetLocType1.intValue());
            result.add(item);
        }
    }
    private static boolean containsCrnLocType(List<Map<String, Integer>> result, Integer crnNo, Short locType1) {
        for (Map<String, Integer> item : result) {
            if (item == null) {
                continue;
            }
            if (crnNo.equals(item.get("crnNo")) && locType1.intValue() == item.get("locType1")) {
                return true;
            }
        }
        return false;
    }
    private static boolean hasAvailableCapacity(List<Integer> crnNos, Integer locType1, BasCrnpService basCrnpService, LocMastService locMastService) {
        return !getAvailableCrnNos(crnNos, locType1, false, basCrnpService, locMastService).isEmpty();
    }
    private static List<Integer> getAvailableCrnNos(List<Integer> candidateCrnNos, Integer locType1, boolean emptyPallet,
                                                     BasCrnpService basCrnpService, LocMastService locMastService) {
        LinkedHashSet<Integer> availableCrnNos = new LinkedHashSet<>();
        if (Cools.isEmpty(candidateCrnNos)) {
            return new ArrayList<>();
        }
        for (Integer crnNo : candidateCrnNos) {
            if (crnNo == null || !basCrnpService.checkSiteError(crnNo, true)) {
                continue;
            }
            if (!hasAvailableLocForRequest(crnNo, locType1, locMastService)) {
                continue;
            }
            availableCrnNos.add(crnNo);
        }
        List<Integer> result = new ArrayList<>(availableCrnNos);
        return result;
    }
    private static int compareEmptyPalletCrn(Integer leftCrnNo, Integer rightCrnNo, BasCrnpService basCrnpService) {
        int leftPriority = getEmptyPalletPriority(basCrnpService.selectById(leftCrnNo));
        int rightPriority = getEmptyPalletPriority(basCrnpService.selectById(rightCrnNo));
        if (leftPriority != rightPriority) {
            return Integer.compare(rightPriority, leftPriority);
        }
        return Integer.compare(leftCrnNo, rightCrnNo);
    }
    private static int getEmptyPalletPriority(BasCrnp basCrnp) {
        if (basCrnp == null) {
            return -1;
        }
        return "Y".equalsIgnoreCase(basCrnp.getEmpIn()) ? 1 : 0;
    }
    private static boolean hasAvailableLocForRequest(Integer crnNo, Integer locType1, LocMastService locMastService) {
        Short normalizedLocType1 = normalizeLocType1(locType1);
        if (normalizedLocType1 == null) {
            return hasAvailableLoc(crnNo, (short) 1, locMastService) || hasAvailableLoc(crnNo, (short) 2, locMastService);
        }
        if (hasAvailableLoc(crnNo, normalizedLocType1, locMastService)) {
            return true;
        }
        return normalizedLocType1 == 1 && hasAvailableLoc(crnNo, (short) 2, locMastService);
    }
    private static boolean hasAvailableLoc(Integer crnNo, Short locType1, LocMastService locMastService) {
        if (crnNo == null || locType1 == null) {
            return false;
        }
        return locMastService.selectCount(new EntityWrapper<LocMast>()
                .eq("crn_no", crnNo)
                .eq("loc_sts", "O")
                .eq("loc_type1", locType1)) > 0;
    }
    private static Short normalizeLocType1(Integer locType1) {
        if (locType1 == null || (locType1 != 1 && locType1 != 2)) {
            return null;
        }
        return locType1.shortValue();
    }
    private static List<Integer> getOtherAreaCrnNos(Integer preferredArea, RowLastno rowLastno) {
        LinkedHashSet<Integer> otherAreaCrnNos = new LinkedHashSet<>();
        for (int area = 1; area <= 3; area++) {
            if (preferredArea != null && preferredArea == area) {
                continue;
            }
            otherAreaCrnNos.addAll(getAreaCrnNos(area, rowLastno));
        }
        if (otherAreaCrnNos.isEmpty()) {
            otherAreaCrnNos.addAll(getAllCrnNos(rowLastno));
            otherAreaCrnNos.removeAll(getAreaCrnNos(preferredArea, rowLastno));
        }
        return new ArrayList<>(otherAreaCrnNos);
    }
    private static List<Integer> getAreaCrnNos(Integer area, RowLastno rowLastno) {
        LinkedHashSet<Integer> crnNos = new LinkedHashSet<>();
        RowLastno areaRowLastno = findAreaRowLastno(area, rowLastno);
        if (areaRowLastno == null) {
            return new ArrayList<>(crnNos);
        }
        Integer startCrnNo = resolveAreaStartCrnNo(areaRowLastno, rowLastno);
        Integer endCrnNo = resolveAreaEndCrnNo(areaRowLastno, rowLastno);
        if (startCrnNo != null && endCrnNo != null && startCrnNo <= endCrnNo) {
            for (int crnNo = startCrnNo; crnNo <= endCrnNo; crnNo++) {
                addAreaCrnNo(crnNos, crnNo, 1, endCrnNo);
            }
            for (int crnNo = areaRowLastno.getsCrnNo(); crnNo <= startCrnNo; crnNo++) {
                addAreaCrnNo(crnNos, crnNo, 1, endCrnNo);
            }
            Integer nextCrnQty = startCrnNo + 1;
            if (areaRowLastno.geteCrnNo() != null && nextCrnQty > areaRowLastno.geteCrnNo()) {
                nextCrnQty = areaRowLastno.getsCrnNo() == null ? 1 : areaRowLastno.getsCrnNo();
            }
            areaRowLastno.setCrnQty(nextCrnQty);
            SpringUtils.getBean(RowLastnoService.class).updateById(areaRowLastno);
        }
        if (crnNos.isEmpty()) {
            crnNos.addAll(getFallbackAreaCrnNos(area, rowLastno));
        }
        return new ArrayList<>(crnNos);
    }
    private static RowLastno findAreaRowLastno(Integer area, RowLastno defaultRowLastno) {
        if (area == null) {
            return defaultRowLastno;
        }
        RowLastnoService rowLastnoService = SpringUtils.getBean(RowLastnoService.class);
        List<RowLastno> typeMatched = rowLastnoService.selectList(new EntityWrapper<RowLastno>()
                .eq("type_id", area));
        if (!Cools.isEmpty(typeMatched)) {
            return typeMatched.get(0);
        }
        List<RowLastno> whsMatched = rowLastnoService.selectList(new EntityWrapper<RowLastno>()
                .eq("whs_type", area));
        if (!Cools.isEmpty(whsMatched)) {
            return whsMatched.get(0);
        }
        return defaultRowLastno;
    }
    private static Integer resolveAreaStartCrnNo(RowLastno areaRowLastno, RowLastno defaultRowLastno) {
        if (areaRowLastno != null && areaRowLastno.getCrnQty() != null && areaRowLastno.getCrnQty() > 0) {
            return areaRowLastno.getCrnQty();
        }
        if (areaRowLastno != null && areaRowLastno.getsCrnNo() != null && areaRowLastno.getsCrnNo() > 0) {
            return areaRowLastno.getsCrnNo();
        }
        if (defaultRowLastno != null && defaultRowLastno.getsCrnNo() != null && defaultRowLastno.getsCrnNo() > 0) {
            return defaultRowLastno.getsCrnNo();
        }
        return 1;
    }
    private static Integer resolveAreaEndCrnNo(RowLastno areaRowLastno, RowLastno defaultRowLastno) {
        if (areaRowLastno != null && areaRowLastno.geteCrnNo() != null && areaRowLastno.geteCrnNo() > 0) {
            return areaRowLastno.geteCrnNo();
        }
        return null;
    }
    private static void addAreaCrnNo(LinkedHashSet<Integer> crnNos, Integer crnNo, Integer startCrnNo, Integer endCrnNo) {
        if (crnNos == null || crnNo == null || startCrnNo == null || endCrnNo == null) {
            return;
        }
        if (crnNo < startCrnNo || crnNo > endCrnNo) {
            return;
        }
        crnNos.add(crnNo);
    }
    private static List<Integer> getAllCrnNos(RowLastno rowLastno) {
        List<Integer> crnNos = new ArrayList<>();
        if (rowLastno == null) {
            return crnNos;
        }
        int startCrnNo = rowLastno.getsCrnNo() == null ? 1 : rowLastno.getsCrnNo();
        int endCrnNo = rowLastno.geteCrnNo() == null ? startCrnNo + ((rowLastno.getCrnQty() == null ? 1 : rowLastno.getCrnQty()) - 1) : rowLastno.geteCrnNo();
        for (int crnNo = startCrnNo; crnNo <= endCrnNo; crnNo++) {
            crnNos.add(crnNo);
        }
        return crnNos;
    }
    private static List<Integer> getFallbackAreaCrnNos(Integer area, RowLastno rowLastno) {
        List<Integer> allCrnNos = getAllCrnNos(rowLastno);
        List<Integer> result = new ArrayList<>();
        if (Cools.isEmpty(allCrnNos) || area == null || area < 1 || area > 3) {
            return result;
        }
        int total = allCrnNos.size();
        int baseSize = total / 3;
        int remainder = total % 3;
        int startIndex = 0;
        for (int currentArea = 1; currentArea < area; currentArea++) {
            startIndex += baseSize + (currentArea <= remainder ? 1 : 0);
        }
        int currentSize = baseSize + (area <= remainder ? 1 : 0);
        int endIndex = Math.min(startIndex + currentSize, total);
        for (int index = startIndex; index < endIndex; index++) {
            result.add(allCrnNos.get(index));
        }
        return result;
    }
    private static List<Integer> mapRowsToCrnNos(RowLastno rowLastno, List<Integer> rows) {
        List<Integer> result = new ArrayList<>();
        if (rowLastno == null || Cools.isEmpty(rows)) {
            return result;
        }
        LinkedHashSet<Integer> orderedCrnNos = new LinkedHashSet<>();
        Integer rowSpan = getCrnRowSpan(rowLastno.getTypeId());
        if (rowSpan == null || rowSpan <= 0) {
            rowSpan = 2;
        }
        int startCrnNo = rowLastno.getsCrnNo() == null ? 1 : rowLastno.getsCrnNo();
        int endCrnNo = rowLastno.geteCrnNo() == null ? startCrnNo + ((rowLastno.getCrnQty() == null ? 1 : rowLastno.getCrnQty()) - 1) : rowLastno.geteCrnNo();
        int startRow = rowLastno.getsRow() == null ? 1 : rowLastno.getsRow();
        int endRow = rowLastno.geteRow() == null ? Integer.MAX_VALUE : rowLastno.geteRow();
        for (Integer row : rows) {
            if (row == null || row < startRow || row > endRow) {
                continue;
            }
            int crnNo = startCrnNo + (row - startRow) / rowSpan;
            if (crnNo >= startCrnNo && crnNo <= endCrnNo) {
                orderedCrnNos.add(crnNo);
            }
        }
        result.addAll(orderedCrnNos);
        return result;
    }
    private static Integer getCrnRowSpan(Integer typeId) {
        if (typeId == null) {
            return null;
        }
        switch (typeId) {
            case 1:
                return 4;
            case 2:
                return 2;
            default:
                return null;
        }
    }
    private static String getRun2AreaRowsConfig(Integer area) {
        Parameter parameter = Parameter.get();
        if (parameter == null || area == null) {
            return null;
        }
        switch (area) {
            case 1:
                return parameter.getRun2Area1Rows();
            case 2:
                return parameter.getRun2Area2Rows();
            case 3:
                return parameter.getRun2Area3Rows();
            default:
                return null;
        }
    }
    private static List<Integer> parseAreaRows(String configValue, RowLastno rowLastno) {
        List<Integer> rows = new ArrayList<>();
        if (rowLastno == null || Cools.isEmpty(configValue)) {
            return rows;
        }
        LinkedHashSet<Integer> orderedRows = new LinkedHashSet<>();
        String normalized = configValue.replace(",", ",")
                .replace(";", ";")
                .replace("、", ",")
                .replaceAll("\\s+", "");
        if (normalized.isEmpty()) {
            return rows;
        }
        for (String segment : normalized.split("[,;]")) {
            if (segment == null || segment.isEmpty()) {
                continue;
            }
            if (segment.contains("-")) {
                String[] rangeParts = segment.split("-", 2);
                Integer startRow = safeParseInt(rangeParts[0]);
                Integer endRow = safeParseInt(rangeParts[1]);
                if (startRow == null || endRow == null) {
                    continue;
                }
                int step = startRow <= endRow ? 1 : -1;
                for (int row = startRow; step > 0 ? row <= endRow : row >= endRow; row += step) {
                    addAreaRow(orderedRows, row, rowLastno);
                }
                continue;
            }
            addAreaRow(orderedRows, safeParseInt(segment), rowLastno);
        }
        rows.addAll(orderedRows);
        return rows;
    }
    private static void addAreaRow(LinkedHashSet<Integer> rows, Integer row, RowLastno rowLastno) {
        if (rows == null || row == null || rowLastno == null) {
            return;
        }
        if (row < rowLastno.getsRow() || row > rowLastno.geteRow()) {
            return;
        }
        rows.add(row);
    }
    private static Integer safeParseInt(String value) {
        if (Cools.isEmpty(value)) {
            return null;
        }
        try {
            return Integer.parseInt(value.trim());
        } catch (NumberFormatException ignored) {
            return null;
        }
    }
    private static Integer parseStorageArea(String area) {
        if (Cools.isEmpty(area)) {
            return null;
        }
        String normalized = area.trim();
        if (normalized.isEmpty()) {
            return null;
        }
        try {
            int areaNo = Integer.parseInt(normalized);
            return areaNo >= 1 && areaNo <= 3 ? areaNo : null;
        } catch (NumberFormatException ignored) {
        }
        String upper = normalized.toUpperCase(Locale.ROOT);
        if ("A".equals(upper) || "A区".equals(upper) || "A库".equals(upper) || "A库区".equals(upper)) {
            return 1;
        }
        if ("B".equals(upper) || "B区".equals(upper) || "B库".equals(upper) || "B库区".equals(upper)) {
            return 2;
        }
        if ("C".equals(upper) || "C区".equals(upper) || "C库".equals(upper) || "C库区".equals(upper)) {
            return 3;
        }
        return null;
    }
    public static String zerofill(String msg, Integer count) {
        if (msg.length() == count) {
            return msg;
@@ -121,9 +653,17 @@
     */
    public static String getShallowLoc(SlaveProperties slaveProperties, String deepLoc) {
        int row = getRow(deepLoc);
        int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount());
        int shallowRow = remainder == 1 ? (row + 1) : (row - 1);
        return zerofill(String.valueOf(shallowRow), 2) + deepLoc.substring(2);
        boolean deepLocLeft = isDeepLocLeft(slaveProperties, row);
        boolean deepLocRight = isDeepLocRight(slaveProperties, row);
        int targetRow;
        if (deepLocLeft) {
            targetRow = row + 1;
        } else if (deepLocRight) {
            targetRow = row - 1;
        } else {
            throw new RuntimeException(deepLoc + "不是浅库位,系统繁忙");
        }
        return zerofill(String.valueOf(targetRow), 2) + deepLoc.substring(2);
    }
    /**
@@ -139,30 +679,45 @@
     */
    public static String getDeepLoc(SlaveProperties slaveProperties, String shallowLoc) {
        int row = getRow(shallowLoc);
        int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount());
        boolean deepLocLeft = isDeepLocLeft(slaveProperties, row-1);
        boolean deepLocRight = isDeepLocRight(slaveProperties, row+1);
        int targetRow;
        if (remainder == 2) {
        if (deepLocLeft) {
            targetRow = row - 1;
        } else if (remainder == 3) {
        } else if (deepLocRight) {
            targetRow = row + 1;
        } else {
            throw new RuntimeException(shallowLoc + "不是浅库位,系统繁忙");
        }
        return zerofill(String.valueOf(targetRow), 2) + shallowLoc.substring(2);
    }
//    public static String getDeepLoc(SlaveProperties slaveProperties, String shallowLoc) {
//        int row = getRow(shallowLoc);
//        int remainder = (int) Arith.remainder(row, slaveProperties.getGroupCount());
//        int targetRow;
//        if (remainder == 2) {
//            targetRow = row - 1;
//        } else if (remainder == 3) {
//            targetRow = row + 1;
//        } else {
//            throw new RuntimeException(shallowLoc + "不是浅库位,系统繁忙");
//        }
//        return zerofill(String.valueOf(targetRow), 2) + shallowLoc.substring(2);
//    }
    /**
     * 获取 浅库位排对应的深库位排
     */
    public static Integer getDeepRow(SlaveProperties slaveProperties, Integer shallowRow) {
        int remainder = (int) Arith.remainder(shallowRow, slaveProperties.getGroupCount());
        boolean deepLocLeft = isDeepLocLeft(slaveProperties, shallowRow-1);
        boolean deepLocRight = isDeepLocRight(slaveProperties, shallowRow+1);
        int targetRow;
        if (remainder == 2) {
        if (deepLocLeft) {
            targetRow = shallowRow - 1;
        } else if (remainder == 3) {
        } else if (deepLocRight) {
            targetRow = shallowRow + 1;
        } else {
            throw new RuntimeException(shallowRow + "不是浅库位排,系统繁忙");
            throw new RuntimeException(shallowRow + "不是浅库位,系统繁忙");
        }
        return targetRow;
    }
@@ -229,10 +784,10 @@
    public static Integer GetWhsType(Integer sourceStaNo) {
        RowLastnoService rowLastnoService = SpringUtils.getBean(RowLastnoService.class);
        List<RowLastno> rowLastnos = rowLastnoService.selectList(new EntityWrapper<RowLastno>());
        for (RowLastno rowLastno:rowLastnos){
        for (RowLastno rowLastno : rowLastnos) {
            String[] staNoList = rowLastno.getStaNoList().split(";");
            for (String staNo : staNoList){
                if (staNo.equals(sourceStaNo.toString())){
            for (String staNo : staNoList) {
                if (staNo.equals(sourceStaNo.toString())) {
                    return rowLastno.getWhsType();
                }
            }
@@ -240,48 +795,39 @@
        return 0;
    }
    public static boolean BooleanWhsTypeStaIoType(Integer whsType) {  //查询相似物料开关
        if (whsType == 1 || whsType==3 || whsType==4) {
    public static boolean BooleanWhsTypeStaIoType(RowLastno rowLastno) {  //查询相似物料开关
        if (rowLastno.getBeSimilar().equals("Y")) {
            return true;
        }
        return false;
    }
    public static boolean BooleanWhsTypeSta(Integer whsType) {
        if (whsType == 1 || whsType == 2 || whsType == 5 || whsType==3 || whsType==4) {
    public static boolean BooleanWhsTypeSta(RowLastno rowLastno, Integer staDescId) {//站点路径更新
        if (rowLastno.getPointSwitch().equals("Y") && staDescId != 11 && staDescId != 111) {
            return true;
        }
        return false;
    }
    public static boolean BooleanWhsTypeSta(Integer whsType, Integer staDescId) {
        if ((whsType == 1 || whsType == 5 || whsType == 2 || whsType==3 || whsType==4) && staDescId != 11 && staDescId != 111) {
            return true;
        }
        return false;
    public static int RowCount(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(rowLastno, curRow, crnNumber)[0];
    }
    public static int RowCount(Integer whsType, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(whsType, curRow, crnNumber)[0];
    public static int getCurRow(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(rowLastno, curRow, crnNumber)[1];
    }
    public static int getCurRow(Integer whsType, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(whsType, curRow, crnNumber)[1];
    public static int getCrnNo(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(rowLastno, curRow, crnNumber)[2];
    }
    public static int getCrnNo(Integer whsType, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(whsType, curRow, crnNumber)[2];
    }
    public static int getNearRow(Integer whsType, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(whsType, curRow, crnNumber)[3];
    public static int getNearRow(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        return LocNecessaryParameters(rowLastno, curRow, crnNumber)[3];
    }
    //库位排号分配
    public static int[] LocNecessaryParameters(Integer whsType, Integer curRow, Integer crnNumber) {
        RowLastnoService rowLastnoService = SpringUtils.getBean(RowLastnoService.class);
        RowLastno rowLastno = rowLastnoService.selectById(whsType);
        switch (whsType){
    public static int[] LocNecessaryParameters(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        switch (rowLastno.getTypeId()) {
            case 1://经典双伸库位
                return LocNecessaryParametersDoubleExtension(rowLastno, curRow, crnNumber); //已完善
            case 2://经典单伸库位(2排货架)
@@ -292,6 +838,10 @@
                return LocNecessaryParametersDoubleExtension4(rowLastno, curRow, crnNumber); //未完善
            case 5://双工位单伸库位(4排货架)
                return LocNecessaryParametersDoubleExtension5(rowLastno, curRow, crnNumber); //已完善
            case 6://四向库(牛眼车)eg:光泰四向
                return LocNecessaryParametersDoubleExtension6(rowLastno, curRow, crnNumber); //已完善
            case 7://平库  CTU库
                return LocNecessaryParametersDoubleExtension7(rowLastno, curRow, crnNumber); //已完善
            default:
                return LocNecessaryParametersMove(rowLastno, curRow, crnNumber);//moveCrnNo
        }
@@ -303,35 +853,34 @@
        Integer sRow = rowLastno.getsRow();
        Integer sCrnNo = rowLastno.getsCrnNo();
        if (BooleanWhsTypeSta(rowLastno.getWhsType())) {
            necessaryParameters[0] = crnNumber; // 轮询次数
            //满板正常入库
            if (curRow.equals(crnNumber * 4 + sRow - 1)) {
                necessaryParameters[1] = sRow;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+1;    //nearRow  最浅库位排
            } else if (curRow.equals((crnNumber - 1) * 4 + sRow)) {
                necessaryParameters[1] = sRow+3;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+2;    //nearRow  最浅库位排
        necessaryParameters[0] = crnNumber; // 轮询次数
        //满板正常入库
        if (curRow.equals(crnNumber * 4 + sRow - 1)) {
            necessaryParameters[1] = sRow;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 1;    //nearRow  最浅库位排
        } else if (curRow.equals((crnNumber - 1) * 4 + sRow)) {
            necessaryParameters[1] = sRow + 3;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 2;    //nearRow  最浅库位排
        } else {
            curRow = curRow + 4;
            if (curRow < sRow || curRow > (crnNumber * 4 + sRow - 1)) {
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
            if ((curRow - (sRow-1)) % 4 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - (sRow-1)) / 4 + sCrnNo - 1;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
            } else if ((curRow - (sRow-1)-1) % 4 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - (sRow-1)-1) / 4 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
            } else {
                curRow = curRow + 4;
                if (curRow <  sRow || curRow > (crnNumber * 4 + sRow - 1)) {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                if ((curRow - sRow) % 4 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow + 2) / 4 + sCrnNo - 1;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
                } else if ((curRow - sRow + 1) % 4 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow + 1) / 4 + sCrnNo - 1;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
                } else {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
        }
        return necessaryParameters;
    }
@@ -339,14 +888,14 @@
    public static int[] LocNecessaryParametersMove(RowLastno rowLastno, Integer curRow, Integer moveCrnNo) {
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        necessaryParameters[0] = 2; // 轮询次数
        if (curRow.equals(moveCrnNo*4-2)){
            necessaryParameters[1] = curRow+2;    //curRow   最深库位排
        if (curRow.equals(moveCrnNo * 4 - 2)) {
            necessaryParameters[1] = curRow + 2;    //curRow   最深库位排
            necessaryParameters[2] = moveCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = curRow+1;    //nearRow  最浅库位排
        }else {
            necessaryParameters[1] = curRow-2;    //curRow   最深库位排
            necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
        } else {
            necessaryParameters[1] = curRow - 2;    //curRow   最深库位排
            necessaryParameters[2] = moveCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = curRow-1;    //nearRow  最浅库位排
            necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
        }
        return necessaryParameters;
    }
@@ -356,33 +905,31 @@
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        Integer sRow = rowLastno.getsRow();
        Integer sCrnNo = rowLastno.getsCrnNo();
        if (BooleanWhsTypeSta(rowLastno.getWhsType())) {
            necessaryParameters[0] = crnNumber; // 轮询次数
            //满板正常入库
            if (curRow.equals(crnNumber * 2 + sRow - 1)) {
                necessaryParameters[1] = sRow;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow;    //nearRow  最浅库位排
            } else if (curRow.equals((crnNumber - 1) * 2 + sRow)) {
                necessaryParameters[1] = sRow+1;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+1;    //nearRow  最浅库位排
        necessaryParameters[0] = crnNumber; // 轮询次数
        //满板正常入库
        if (curRow.equals(crnNumber * 2 + sRow - 1)) {
            necessaryParameters[1] = sRow;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow;    //nearRow  最浅库位排
        } else if (curRow.equals((crnNumber - 1) * 2 + sRow)) {
            necessaryParameters[1] = sRow + 1;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 1;    //nearRow  最浅库位排
        } else {
            curRow = curRow + 2;
            if (curRow < sRow || curRow > (crnNumber * 2 + sRow - 1)) {
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
            if ((curRow - sRow) % 2 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow) / 2 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow;    //nearRow  最浅库位排
            } else if ((curRow - sRow + 1) % 2 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow - 1) / 2 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow;    //nearRow  最浅库位排
            } else {
                curRow = curRow + 2;
                if (curRow <  sRow || curRow > (crnNumber * 2 + sRow - 1)) {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                if ((curRow - sRow) % 2 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow) / 2 + sCrnNo ;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow ;    //nearRow  最浅库位排
                } else if ((curRow - sRow + 1) % 2 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow - 1) / 2 + sCrnNo;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow ;    //nearRow  最浅库位排
                } else {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
        }
        return necessaryParameters;
@@ -393,72 +940,70 @@
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        Integer sRow = rowLastno.getsRow();
        Integer sCrnNo = rowLastno.getsCrnNo();
        if (BooleanWhsTypeSta(rowLastno.getWhsType())) {
            necessaryParameters[0] = crnNumber; // 轮询次数
            //满板正常入库
            if (curRow.equals(crnNumber * 3 + sRow - 1)) {
                necessaryParameters[1] = sRow;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow;    //nearRow  最浅库位排
            } else if (curRow.equals((crnNumber - 1) * 3 + sRow)) {
                necessaryParameters[1] = sRow+2;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+1;    //nearRow  最浅库位排
        necessaryParameters[0] = crnNumber; // 轮询次数
        //满板正常入库
        if (curRow.equals(crnNumber * 3 + sRow - 1)) {
            necessaryParameters[1] = sRow;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow;    //nearRow  最浅库位排
        } else if (curRow.equals((crnNumber - 1) * 3 + sRow)) {
            necessaryParameters[1] = sRow + 2;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 1;    //nearRow  最浅库位排
        } else {
            curRow = curRow + 3;
            if (curRow < sRow || curRow > (crnNumber * 3 + sRow - 1)) {
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
            if ((curRow - sRow) % 3 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow) / 3 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow;    //nearRow  最浅库位排
            } else if ((curRow - sRow + 1) % 3 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow - 2) / 3 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
            } else {
                curRow = curRow + 3;
                if (curRow <  sRow || curRow > (crnNumber * 3 + sRow - 1)) {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                if ((curRow - sRow) % 3 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow) / 3 + sCrnNo ;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow ;    //nearRow  最浅库位排
                } else if ((curRow - sRow + 1) % 3 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow - 2) / 3 + sCrnNo;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow-1 ;    //nearRow  最浅库位排
                } else {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
        }
        return necessaryParameters;
    }
    //经典单双伸库位  左双右单(小双大单)
    public static int[] LocNecessaryParametersDoubleExtension4(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        Integer sRow = rowLastno.getsRow();
        Integer sCrnNo = rowLastno.getsCrnNo();
        if (BooleanWhsTypeSta(rowLastno.getWhsType())) {
            necessaryParameters[0] = crnNumber; // 轮询次数
            //满板正常入库
            if (curRow.equals(crnNumber * 3 + sRow - 1)) {
                necessaryParameters[1] = sRow;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+1;    //nearRow  最浅库位排
            } else if (curRow.equals((crnNumber - 1) * 3 + sRow)) {
                necessaryParameters[1] = sRow+2;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+2;    //nearRow  最浅库位排
        Integer sRow = rowLastno.getsRow();//起始排号
        Integer sCrnNo = rowLastno.getsCrnNo();//起始堆垛机号
        necessaryParameters[0] = crnNumber; // 轮询次数
        //满板正常入库
        if (curRow.equals(crnNumber * 3 + sRow - 1)) {
            necessaryParameters[1] = sRow;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 1;    //nearRow  最浅库位排
        } else if (curRow.equals((crnNumber - 1) * 3 + sRow)) {
            necessaryParameters[1] = sRow + 2;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 2;    //nearRow  最浅库位排
        } else {
            curRow = curRow + 3;
            if (curRow < sRow || curRow > (crnNumber * 3 + sRow - 1)) {
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
            if ((curRow - sRow) % 3 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow) / 3 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
            } else if ((curRow - sRow + 1) % 3 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow - 2) / 3 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow;    //nearRow  最浅库位排
            } else {
                curRow = curRow + 3;
                if (curRow <  sRow || curRow > (crnNumber * 3 + sRow - 1)) {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                if ((curRow - sRow) % 3 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow) / 3 + sCrnNo ;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow + 1 ;    //nearRow  最浅库位排
                } else if ((curRow - sRow + 1) % 3 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow - 2) / 3 + sCrnNo;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow ;    //nearRow  最浅库位排
                } else {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
        }
        return necessaryParameters;
    }
@@ -467,35 +1012,101 @@
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        Integer sRow = rowLastno.getsRow();
        Integer sCrnNo = rowLastno.getsCrnNo();
        if (BooleanWhsTypeSta(rowLastno.getWhsType())) {
            necessaryParameters[0] = crnNumber; // 轮询次数
            //满板正常入库
            if (curRow.equals(crnNumber * 4 + sRow - 1)) {
                necessaryParameters[1] = sRow;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+1;    //nearRow  最浅库位排
            } else if (curRow.equals((crnNumber - 1) * 4 + sRow)) {
                necessaryParameters[1] = sRow+3;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = sRow+2;    //nearRow  最浅库位排
        necessaryParameters[0] = crnNumber; // 轮询次数
        //满板正常入库
        if (curRow.equals(crnNumber * 4 + sRow - 1)) {
            necessaryParameters[1] = sRow;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 1;    //nearRow  最浅库位排
        } else if (curRow.equals((crnNumber - 1) * 4 + sRow)) {
            necessaryParameters[1] = sRow + 3;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow + 2;    //nearRow  最浅库位排
        } else {
            curRow = curRow + 4;
            if (curRow < sRow || curRow > (crnNumber * 4 + sRow - 1)) {
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
            if ((curRow - sRow) % 4 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow + 2) / 4 + sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
            } else if ((curRow - sRow + 1) % 4 == 0) {
                necessaryParameters[1] = curRow;    //curRow   最深库位排
                necessaryParameters[2] = (curRow - sRow + 1) / 4 + sCrnNo - 1;     //crnNo     堆垛机号
                necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
            } else {
                curRow = curRow + 4;
                if (curRow <  sRow || curRow > (crnNumber * 4 + sRow - 1)) {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                if ((curRow - sRow) % 4 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow + 2) / 4 + sCrnNo - 1;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
                } else if ((curRow - sRow + 1) % 4 == 0) {
                    necessaryParameters[1] = curRow;    //curRow   最深库位排
                    necessaryParameters[2] = (curRow - sRow + 1) / 4 + sCrnNo - 1;     //crnNo     堆垛机号
                    necessaryParameters[3] = curRow - 1;    //nearRow  最浅库位排
                } else {
                    throw new CoolException("库位排号异常:排号:" + curRow);
                }
                throw new CoolException("库位排号异常:排号:" + curRow);
            }
        }
        return necessaryParameters;
    }
    //四向库(牛眼\光泰)
    public static int[] LocNecessaryParametersDoubleExtension6(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        Integer sRow = rowLastno.getsRow();//起始排号
        Integer offset = 4;//起始排号
        Integer sCrnNo = rowLastno.getsCrnNo();//起始堆垛机号
        necessaryParameters[0] = crnNumber; // 轮询次数
        curRow = curRow - offset;
        //满板正常入库
        switch (curRow){
            case 1:
                necessaryParameters[1] = 4;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = 7;    //nearRow  最浅库位排
                break;
            case 4:
                necessaryParameters[1] = 9;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = 12;    //nearRow  最浅库位排
                break;
            case 9:
                necessaryParameters[1] = 14;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = 14;    //nearRow  最浅库位排
                break;
            case 14:
                necessaryParameters[1] = 7;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = 4;    //nearRow  最浅库位排
                break;
            case 7:
                necessaryParameters[1] = 12;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = 9;    //nearRow  最浅库位排
                break;
            case 12:
                necessaryParameters[1] = 1;    //curRow   最深库位排
                necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
                necessaryParameters[3] = 2;    //nearRow  最浅库位排
                break;
            default:
                throw new CoolException("库位排号异常:排号:" + curRow);
        }
        necessaryParameters[1] = necessaryParameters[1] + offset;
        necessaryParameters[3] = necessaryParameters[3] + offset;
        return necessaryParameters;
    }
    //平库(光泰\CTU)
    public static int[] LocNecessaryParametersDoubleExtension7(RowLastno rowLastno, Integer curRow, Integer crnNumber) {
        int[] necessaryParameters = new int[]{0, 0, 0, 0};
        Integer sRow = rowLastno.getsRow();//起始排号
        Integer sCrnNo = rowLastno.getsCrnNo();//起始堆垛机号
        necessaryParameters[0] = crnNumber; // 轮询次数
        //满板正常入库
        if (curRow.equals(rowLastno.geteRow())){
            necessaryParameters[1] = sRow;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = sRow;    //nearRow  最浅库位排
        } else {
            necessaryParameters[1] = curRow + 1;    //curRow   最深库位排
            necessaryParameters[2] = sCrnNo;     //crnNo     堆垛机号
            necessaryParameters[3] = curRow + 1;    //nearRow  最浅库位排
        }
        return necessaryParameters;
    }
@@ -559,18 +1170,60 @@
     * 出库  false:pakin
     * */
    // 外侧方向的货位  优先入库方向 ===>> 反之
    public static List<String> getGroupOutLocCrn(Integer curRow,Integer nearRow,String locNo,boolean pakin){
    public static List<String> getGroupOutLocCrn(Integer curRow, Integer nearRow, String locNo, boolean pakin) {
        List<String> result = new ArrayList<>();
        if (pakin){
            for (int row = curRow;row<=nearRow;row++){
            for (int row = curRow;row>=nearRow;row--){
                result.add(zerofill(String.valueOf(row), 2) + locNo.substring(2));
            }
        }else {
            for (int row = curRow;row>=curRow;row--){
            for (int row = curRow;row<=nearRow;row++){
                result.add(zerofill(String.valueOf(row), 2) + locNo.substring(2));
            }
        }
        return result;
    }
    //将wms库位号转换成wcs库位号
    public static String WMSLocToWCSLoc(String locNo) {
        String row = locNo.substring(0, 2);
        int i = 0;
        for (char c : row.toCharArray()) {
            if (c == '0') {
                i++;
            }else {
                break;
            }
        }
        row = row.substring(i);
        int j = 0;
        String boy = locNo.substring(2, 5);
        for (char c : boy.toCharArray()) {
            if (c == '0') {
                j++;
            }else {
                break;
            }
        }
        boy = boy.substring(j);
        int k = 0;
        String lev = locNo.substring(5);
        for (char c : lev.toCharArray()) {
            if (c == '0') {
                k++;
            }else {
                break;
            }
        }
        lev = lev.substring(k);
        return row + "-" + boy + "-" + lev;
    }
}