自动化立体仓库 - WMS系统
zwl
3 天以前 2acfc2d2a0e956910c51bd996f443b3cb9bd3dc9
src/main/java/com/zy/asrs/utils/Utils.java
@@ -149,10 +149,11 @@
     * <p>处理规则:
     * 1. 先根据入库站点查询所属库区。
     * 2. 先提取该库区内的堆垛机,并按可用空库位过滤不可用堆垛机。
     * 3. 若当前库区没有满足条件的空库位,再补充其他库区的堆垛机。
     * 4. 当 {@code locType1 = 1} 时,先返回低库位堆垛机,再把同批堆垛机的高库位追加到后面。
     * 5. 对不存在、故障、不可入以及无空库位的堆垛机直接剔除。
     * 6. 当物料为 {@code emptyPallet} 时,按空板入库优先规则重新排序。
     * 3. 当 {@code locType1 = 1} 时,先返回低库位堆垛机,再把同批堆垛机的高库位追加到后面。
     * 4. 对不存在、故障、不可入以及无空库位的堆垛机直接剔除。
     *
     * <p>这里是只读排序工具,不再写回 {@code asr_row_lastno.crn_qty}。
     * {@code crn_qty} 在主数据里表示“堆垛机数量”,不能再被拿来当轮询游标,否则会把整仓配置写坏。
     *
     * <p>返回结果中的每一项格式为:
     * {@code {crnNo: 堆垛机号, locType1: 库位高低类型}}
@@ -183,35 +184,29 @@
        // 先取当前库区对应的堆垛机。
        List<Integer> preferredCrnNos = getAreaCrnNos(storageArea, rowLastno);
        List<Integer> preferredAvailableCrnNos = getAvailableCrnNos(preferredCrnNos, locType1, emptyPallet, basCrnpService, locMastService);
        appendCrnLocTypeEntries(result, preferredAvailableCrnNos, locType1, locMastService);
        appendCrnLocTypeEntries(result, preferredAvailableCrnNos, locType1, emptyPallet, 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) {
    private static void appendCrnLocTypeEntries(List<Map<String, Integer>> result, List<Integer> crnNos, Integer locType1, boolean emptyPallet, LocMastService locMastService) {
        Short normalizedLocType1 = normalizeLocType1(locType1);
        if (normalizedLocType1 == null) {
            appendCrnLocTypeEntries(result, crnNos, (short) 1, locMastService);
            appendCrnLocTypeEntries(result, crnNos, (short) 2, locMastService);
            appendCrnLocTypeEntries(result, crnNos, (short) 1, emptyPallet, locMastService);
            appendCrnLocTypeEntries(result, crnNos, (short) 2, emptyPallet, locMastService);
            return;
        }
        appendCrnLocTypeEntries(result, crnNos, normalizedLocType1, locMastService);
        appendCrnLocTypeEntries(result, crnNos, normalizedLocType1, emptyPallet, locMastService);
        if (normalizedLocType1 == 1) {
            appendCrnLocTypeEntries(result, crnNos, (short) 2, locMastService);
            appendCrnLocTypeEntries(result, crnNos, (short) 2, emptyPallet, locMastService);
        }
    }
    private static void appendCrnLocTypeEntries(List<Map<String, Integer>> result, List<Integer> crnNos, Short targetLocType1, LocMastService locMastService) {
    private static void appendCrnLocTypeEntries(List<Map<String, Integer>> result, List<Integer> crnNos, Short targetLocType1, boolean emptyPallet, LocMastService locMastService) {
        if (targetLocType1 == null || Cools.isEmpty(crnNos)) {
            return;
        }
        for (Integer crnNo : crnNos) {
            if (!hasAvailableLoc(crnNo, targetLocType1, locMastService) || containsCrnLocType(result, crnNo, targetLocType1)) {
            if (!hasAvailableLoc(crnNo, targetLocType1, emptyPallet, locMastService) || containsCrnLocType(result, crnNo, targetLocType1)) {
                continue;
            }
            Map<String, Integer> item = new LinkedHashMap<>();
@@ -247,7 +242,7 @@
            if (crnNo == null || !basCrnpService.checkSiteError(crnNo, true)) {
                continue;
            }
            if (!hasAvailableLocForRequest(crnNo, locType1, locMastService)) {
            if (!hasAvailableLocForRequest(crnNo, locType1, emptyPallet, locMastService)) {
                continue;
            }
            availableCrnNos.add(crnNo);
@@ -272,25 +267,30 @@
        return "Y".equalsIgnoreCase(basCrnp.getEmpIn()) ? 1 : 0;
    }
    private static boolean hasAvailableLocForRequest(Integer crnNo, Integer locType1, LocMastService locMastService) {
    private static boolean hasAvailableLocForRequest(Integer crnNo, Integer locType1, boolean emptyPallet, LocMastService locMastService) {
        Short normalizedLocType1 = normalizeLocType1(locType1);
        if (normalizedLocType1 == null) {
            return hasAvailableLoc(crnNo, (short) 1, locMastService) || hasAvailableLoc(crnNo, (short) 2, locMastService);
            return hasAvailableLoc(crnNo, (short) 1, emptyPallet, locMastService)
                    || hasAvailableLoc(crnNo, (short) 2, emptyPallet, locMastService);
        }
        if (hasAvailableLoc(crnNo, normalizedLocType1, locMastService)) {
        if (hasAvailableLoc(crnNo, normalizedLocType1, emptyPallet, locMastService)) {
            return true;
        }
        return normalizedLocType1 == 1 && hasAvailableLoc(crnNo, (short) 2, locMastService);
        return normalizedLocType1 == 1 && hasAvailableLoc(crnNo, (short) 2, emptyPallet, locMastService);
    }
    private static boolean hasAvailableLoc(Integer crnNo, Short locType1, LocMastService locMastService) {
    private static boolean hasAvailableLoc(Integer crnNo, Short locType1, boolean emptyPallet, 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;
        EntityWrapper<LocMast> wrapper = new EntityWrapper<LocMast>();
        wrapper.eq("crn_no", crnNo);
        wrapper.eq("loc_sts", "O");
        wrapper.eq("loc_type1", locType1);
        if (!emptyPallet) {
            wrapper.ne("loc_type2", 1);
        }
        return locMastService.selectCount(wrapper) > 0;
    }
    private static Short normalizeLocType1(Integer locType1) {
@@ -321,21 +321,10 @@
        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);
        Integer startCrnNo = resolveAreaStartCrnNo(areaRowLastno);
        List<Integer> orderedCrnNos = getOrderedCrnNos(areaRowLastno, startCrnNo);
        if (!orderedCrnNos.isEmpty()) {
            crnNos.addAll(orderedCrnNos);
        }
        if (crnNos.isEmpty()) {
@@ -362,34 +351,47 @@
        return defaultRowLastno;
    }
    private static Integer resolveAreaStartCrnNo(RowLastno areaRowLastno, RowLastno defaultRowLastno) {
        if (areaRowLastno != null && areaRowLastno.getCrnQty() != null && areaRowLastno.getCrnQty() > 0) {
            return areaRowLastno.getCrnQty();
    private static Integer resolveAreaStartCrnNo(RowLastno areaRowLastno) {
        if (areaRowLastno == null) {
            return null;
        }
        if (areaRowLastno != null && areaRowLastno.getsCrnNo() != null && areaRowLastno.getsCrnNo() > 0) {
            return areaRowLastno.getsCrnNo();
        Integer startCrnNo = areaRowLastno.getsCrnNo();
        Integer endCrnNo = areaRowLastno.geteCrnNo();
        Integer currentRow = areaRowLastno.getCurrentRow();
        Integer rowSpan = getCrnRowSpan(areaRowLastno.getTypeId());
        if (startCrnNo == null || startCrnNo <= 0) {
            return 1;
        }
        if (defaultRowLastno != null && defaultRowLastno.getsCrnNo() != null && defaultRowLastno.getsCrnNo() > 0) {
            return defaultRowLastno.getsCrnNo();
        if (endCrnNo == null || endCrnNo < startCrnNo || currentRow == null || rowSpan == null || rowSpan <= 0) {
            return startCrnNo;
        }
        return 1;
        int startRow = areaRowLastno.getsRow() == null ? 1 : areaRowLastno.getsRow();
        int offset = Math.max(currentRow - startRow, 0) / rowSpan;
        int resolvedCrnNo = startCrnNo + offset;
        if (resolvedCrnNo < startCrnNo || resolvedCrnNo > endCrnNo) {
            return startCrnNo;
        }
        return resolvedCrnNo;
    }
    private static Integer resolveAreaEndCrnNo(RowLastno areaRowLastno, RowLastno defaultRowLastno) {
        if (areaRowLastno != null && areaRowLastno.geteCrnNo() != null && areaRowLastno.geteCrnNo() > 0) {
            return areaRowLastno.geteCrnNo();
    private static List<Integer> getOrderedCrnNos(RowLastno rowLastno, Integer startCrnNo) {
        List<Integer> orderedCrnNos = new ArrayList<>();
        if (rowLastno == null) {
            return orderedCrnNos;
        }
        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;
        int start = rowLastno.getsCrnNo() == null ? 1 : rowLastno.getsCrnNo();
        int end = rowLastno.geteCrnNo() == null ? start + ((rowLastno.getCrnQty() == null ? 1 : rowLastno.getCrnQty()) - 1) : rowLastno.geteCrnNo();
        int first = startCrnNo == null ? start : startCrnNo;
        if (first < start || first > end) {
            first = start;
        }
        if (crnNo < startCrnNo || crnNo > endCrnNo) {
            return;
        for (int crnNo = first; crnNo <= end; crnNo++) {
            orderedCrnNos.add(crnNo);
        }
        crnNos.add(crnNo);
        for (int crnNo = start; crnNo < first; crnNo++) {
            orderedCrnNos.add(crnNo);
        }
        return orderedCrnNos;
    }
    private static List<Integer> getAllCrnNos(RowLastno rowLastno) {