| | |
| | | /** |
| | | * 检查正常库位前方是否堵塞(深库位规则:前方排是否有货或入库任务) |
| | | * |
| | | * 只对属于出库分组规则内的库位进行检查 |
| | | * 如果库位不在分组规则内,则视为不需要严格检查(返回 false,不触发补齐) |
| | | * 判断依据: |
| | | * 1. 只检查属于出库分组规则内的库位(通过分组的 rowList 确定范围) |
| | | * 2. 前方 = 分组中索引大于当前库位的排(假设分组 rowList 已按出库顺序排列,大索引 = 前方更深) |
| | | * 3. 堵塞条件:前方有货(F状态)或有入库任务 |
| | | * |
| | | * @param normalMasts 需要检查的正常库位列表(已通过 isInNormalRule 过滤) |
| | | * @return true = 前方有堵塞(需要补齐),false = 前方清空或无需检查 |
| | |
| | | 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) { |
| | |
| | | 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; |
| | | } |
| | |
| | | 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; |
| | | } |
| | |
| | | } |
| | | } 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); |
| | | } |
| | | } |
| | | } |