自动化立体仓库 - WMS系统
#
lty
18 小时以前 818cca1634b4cdee73b91ee65f9aa03407102cee
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -210,8 +210,10 @@
    /**
     * 检查正常库位前方是否堵塞(深库位规则:前方排是否有货或入库任务)
     *
     * 只对属于出库分组规则内的库位进行检查
     * 如果库位不在分组规则内,则视为不需要严格检查(返回 false,不触发补齐)
     * 判断依据:
     * 1. 只检查属于出库分组规则内的库位(通过分组的 rowList 确定范围)
     * 2. 前方 = 分组中索引大于当前库位的排(假设分组 rowList 已按出库顺序排列,大索引 = 前方更深)
     * 3. 堵塞条件:前方有货(F状态)或有入库任务
     *
     * @param normalMasts 需要检查的正常库位列表(已通过 isInNormalRule 过滤)
     * @return true = 前方有堵塞(需要补齐),false = 前方清空或无需检查
@@ -220,11 +222,25 @@
        if (normalMasts == null || normalMasts.isEmpty()) {
            return false;
        }
        // 获取出库分组配置(用于确认规则范围)
        // 获取出库分组配置
        List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrder();
        if (locGroupAscOrder == null || locGroupAscOrder.isEmpty()) {
            return false; // 无配置时默认不检查
        }
        // 假设所有 normalMasts 在同一个分组(常见情况,若多分组可循环处理)
        LocMast representative = normalMasts.get(0);
        LocGroupOrder group = locGroupAscOrder.stream()
                .filter(g -> g.getRowList() != null && g.getRowList().contains(representative.getRow1()))
                .findFirst()
                .orElse(null);
        if (group == null || group.getRowList() == null || group.getRowList().isEmpty()) {
            return false; // 不在任何分组,不检查
        }
        List<Integer> fullRows = group.getRowList(); // 分组内所有排号列表(按出库顺序排列)
        // 遍历每个正常库位
        for (LocMast lm : normalMasts) {
@@ -236,10 +252,17 @@
                continue;
            }
            // 深库位检查方向:假设 row 越大越深(前方是更大 row 的位置)
            // 你可以根据实际出库方向调整循环条件(例如从小 row 到大 row 或反之)
            for (int row = currentRow + 1; row <= 5; row++) { // 假设深库位范围到 5 排,可调整
                LocMast front = getLocMastByRow(row, bay1, lev1);
            // 在分组 rowList 中找到当前排的索引
            int currentIndex = fullRows.indexOf(currentRow);
            if (currentIndex < 0) {
                continue; // 当前排不在分组内,跳过
            }
            // 前方 = 分组中索引更大的位置(假设分组 rowList 从前到后排列,大索引 = 更深)
            // 如果你的分组列表是倒序的(从后到前),则需改为 currentIndex - 1 到 0
            for (int i = currentIndex + 1; i < fullRows.size(); i++) {
                Integer frontRow = fullRows.get(i);
                LocMast front = getLocMastByRow(frontRow, bay1, lev1);
                if (front == null) {
                    continue;
                }
@@ -249,12 +272,12 @@
                    return true;
                }
                // 有入库任务 → 堵塞
                WrkMast frontTask = wrkMastService.selectOne(
                        new EntityWrapper<WrkMast>()
                                .eq("source_loc_no", front.getLocNo())
                                .eq("io_type", 100) // 假设 100 为入库类型,可调整
                                .in("loc_sts", Arrays.asList("S", "Q")) // 支持 loc_sts 为 S 或 Q
                );
                if (frontTask != null) {
                    return true;
                }
@@ -501,101 +524,6 @@
                }
            } else {
                throw new CoolException(locNo + " 库位不是在库状态");
            }
        }
    }
    private void supplementBothSidesBlocked(
            List<LocMast> normalMasts,
            List<LocMast> supplementMasts,
            AtomicReference<Boolean> isLeftSideSupplement) {
        if (normalMasts.isEmpty()) {
            isLeftSideSupplement.set(true); // 默认左侧
            return;
        }
        // 假设所有 normalMasts 在同一 bay/lev(多组情况可循环处理)
        LocMast rep = normalMasts.get(0);
        Integer bay1 = rep.getBay1();
        Integer lev1 = rep.getLev1();
        if (bay1 == null || lev1 == null) {
            throw new CoolException("库位 bay1 或 lev1 为空,无法补齐前方");
        }
        // 找出选中段的最小/最大排号
        int minRow = normalMasts.stream()
                .mapToInt(LocMast::getRow1)
                .min()
                .orElseThrow(() -> new CoolException("正常库位列表为空,无法获取最小排号"));
        int maxRow = normalMasts.stream()
                .mapToInt(LocMast::getRow1)
                .max()
                .orElseThrow(() -> new CoolException("正常库位列表为空,无法获取最大排号"));
        // 假设深库位范围:1~5 排(可根据实际调整)
        final int MIN_ROW = 1;
        final int MAX_ROW = 5;
        // ---------------- 计算左侧(小排号方向,较浅位置)需要补多少 ----------------
        int leftCount = 0;
        List<LocMast> leftToAdd = new ArrayList<>();
        for (int r = minRow - 1; r >= MIN_ROW; r--) {
            LocMast loc = getLocMastByRow(r, bay1, lev1);
            if (loc == null) continue;
            // 只补空板(D状态)
            if ("D".equals(loc.getLocSts())) {
                leftCount++;
                leftToAdd.add(loc);
            }
            // 可选:遇到其他阻塞状态可停止(视业务需求)
            // else if ("F".equals(loc.getLocSts()) || "其他阻塞".equals(...)) break;
        }
        // ---------------- 计算右侧(大排号方向,更深位置)需要补多少 ----------------
        int rightCount = 0;
        List<LocMast> rightToAdd = new ArrayList<>();
        for (int r = maxRow + 1; r <= MAX_ROW; r++) {
            LocMast loc = getLocMastByRow(r, bay1, lev1);
            if (loc == null) continue;
            if ("D".equals(loc.getLocSts())) {
                rightCount++;
                rightToAdd.add(loc);
            }
            // else if (阻塞状态) break;
        }
        // ---------------- 选择补哪一边 ----------------
        List<LocMast> chosen;
        boolean chooseLeft;
        if (leftCount == 0 && rightCount == 0) {
            // 两侧都没空板可补 → 无法打通
            throw new CoolException("前方两侧均无空板可补充,无法打通出库路径");
        }
        if (leftCount <= rightCount) {
            // 左侧补更少(或相等默认左侧)
            chosen = leftToAdd;
            chooseLeft = true;
            log.info("选择补充左侧(小排方向),共 {} 个空板库位", leftCount);
        } else {
            chosen = rightToAdd;
            chooseLeft = false;
            log.info("选择补充右侧(大排方向),共 {} 个空板库位", rightCount);
        }
        // 设置标记(用于后续优先级调整)
        isLeftSideSupplement.set(chooseLeft);
        // 加入补充列表(去重)
        for (LocMast supp : chosen) {
            if (!supplementMasts.contains(supp) && !normalMasts.contains(supp)) {
                supplementMasts.add(supp);
            }
        }
    }