package com.zy.asrs.utils; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Arith; 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.Objects; import java.util.Locale; /** * Created by vincent on 2020/8/27 */ public class Utils { private static final DecimalFormat fmt = new DecimalFormat("##0.00"); public static float scale(Float f) { if (f == null || f == 0f || Float.isNaN(f)) { return 0f; } 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 List getStationStorageAreas(Integer stationId) { if (stationId == null || stationId <= 0) { return new ArrayList<>(); } BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); BasDevp station = basDevpService.selectById(stationId); if (station == null) { return new ArrayList<>(); } return parseStorageAreas(station.getArea()); } public static Integer getStationStorageArea(Integer stationId) { List storageAreas = getStationStorageAreas(stationId); if (Cools.isEmpty(storageAreas)) { return null; } return storageAreas.get(0); } /** * 生成入库找库位时的堆垛机优先顺序。 * *

当前语义已经切换为“站点第一优先池 + 第二优先池”的配置预览, * 不再沿用旧的 area 顺序。 * *

返回结果中的每一项格式为: * {@code {pool: 优先池编号, seq: 池内顺序, crnNo: 堆垛机号}} * * @param stationId 入库站点 * @param locType1 保留兼容参数,当前不参与排序 * @param matnr 保留兼容参数,当前不参与排序 * @return 按优先池顺序排好的堆垛机列表 */ public static List> getStationStorageAreaName(Integer stationId, Integer locType1, String matnr) { List> result = new ArrayList<>(); BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); BasDevp station = basDevpService.selectById(stationId); if (station == null) { return result; } appendCrnPoolEntries(result, 1, distinctCrnNos(station.getInFirstCrnCsv())); appendCrnPoolEntries(result, 2, distinctCrnNos(station.getInSecondCrnCsv())); return result; } public static List parseCrnNos(String csv) { List crnNos = new ArrayList<>(); if (Cools.isEmpty(csv)) { return crnNos; } String normalized = csv.replace(",", ",") .replace(";", ",") .replace("、", ",") .replaceAll("\\s+", ""); if (normalized.isEmpty()) { return crnNos; } for (String segment : normalized.split("[,;]")) { if (segment == null || segment.isEmpty()) { continue; } Integer crnNo = safeParseInt(segment); if (crnNo == null || crnNo <= 0) { throw new CoolException("堆垛机号格式错误:" + segment); } crnNos.add(crnNo); } return crnNos; } public static List distinctCrnNos(String csv) { return distinctCrnNos(parseCrnNos(csv)); } public static List distinctCrnNos(List crnNos) { List result = new ArrayList<>(); if (Cools.isEmpty(crnNos)) { return result; } LinkedHashSet orderedCrnNos = new LinkedHashSet<>(); for (Integer crnNo : crnNos) { if (crnNo == null || crnNo <= 0) { continue; } orderedCrnNos.add(crnNo); } result.addAll(orderedCrnNos); return result; } public static String normalizeCrnCsv(String csv) { return normalizeCrnCsv(parseCrnNos(csv)); } public static String normalizeCrnCsv(List crnNos) { return joinCrnNos(distinctCrnNos(crnNos)); } public static String joinCrnNos(List crnNos) { if (Cools.isEmpty(crnNos)) { return ""; } StringBuilder builder = new StringBuilder(); for (Integer crnNo : crnNos) { if (crnNo == null || crnNo <= 0) { continue; } if (builder.length() > 0) { builder.append(","); } builder.append(crnNo); } return builder.toString(); } private static void appendCrnPoolEntries(List> result, int pool, List crnNos) { if (result == null || Cools.isEmpty(crnNos)) { return; } int seq = 1; for (Integer crnNo : crnNos) { if (crnNo == null || crnNo <= 0) { continue; } Map item = new LinkedHashMap<>(); item.put("pool", pool); item.put("seq", seq++); item.put("crnNo", crnNo); result.add(item); } } public static List parseStorageAreas(String area) { List areas = new ArrayList<>(); if (Cools.isEmpty(area)) { return areas; } LinkedHashSet orderedAreas = new LinkedHashSet<>(); String normalized = area.replace(",", ",") .replace(";", ";") .replace("、", ",") .replaceAll("\\s+", ""); if (normalized.isEmpty()) { return areas; } for (String segment : normalized.split("[,;]")) { if (segment == null || segment.isEmpty()) { continue; } Integer areaNo = parseStorageArea(segment); if (areaNo != null) { orderedAreas.add(areaNo); } } areas.addAll(orderedAreas); return areas; } public static String formatStorageArea(Integer area) { if (area == null) { return ""; } switch (area) { case 1: return "A库区"; case 2: return "B库区"; case 3: return "C库区"; default: return String.valueOf(area); } } private static void appendCrnLocTypeEntries(List> result, List crnNos, Integer locType1, boolean emptyPallet, LocMastService locMastService, Integer area) { Short normalizedLocType1 = normalizeLocType1(locType1); if (normalizedLocType1 == null) { appendCrnLocTypeEntries(result, crnNos, (short) 1, emptyPallet, locMastService, area); appendCrnLocTypeEntries(result, crnNos, (short) 2, emptyPallet, locMastService, area); return; } appendCrnLocTypeEntries(result, crnNos, normalizedLocType1, emptyPallet, locMastService, area); if (normalizedLocType1 == 1) { appendCrnLocTypeEntries(result, crnNos, (short) 2, emptyPallet, locMastService, area); } } private static void appendCrnLocTypeEntries(List> result, List crnNos, Short targetLocType1, boolean emptyPallet, LocMastService locMastService, Integer area) { if (targetLocType1 == null || Cools.isEmpty(crnNos)) { return; } for (Integer crnNo : crnNos) { if (!hasAvailableLoc(crnNo, targetLocType1, emptyPallet, locMastService) || containsCrnLocType(result, area, crnNo, targetLocType1)) { continue; } Map item = new LinkedHashMap<>(); item.put("area", area); item.put("crnNo", crnNo); item.put("locType1", targetLocType1.intValue()); result.add(item); } } private static boolean containsCrnLocType(List> result, Integer area, Integer crnNo, Short locType1) { for (Map item : result) { if (item == null) { continue; } if (crnNo.equals(item.get("crnNo")) && locType1.intValue() == item.get("locType1") && Objects.equals(area, item.get("area"))) { return true; } } return false; } private static boolean hasAvailableCapacity(List crnNos, Integer locType1, BasCrnpService basCrnpService, LocMastService locMastService) { return !getAvailableCrnNos(crnNos, locType1, false, basCrnpService, locMastService).isEmpty(); } private static List getAvailableCrnNos(List candidateCrnNos, Integer locType1, boolean emptyPallet, BasCrnpService basCrnpService, LocMastService locMastService) { LinkedHashSet 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, emptyPallet, locMastService)) { continue; } availableCrnNos.add(crnNo); } List 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, boolean emptyPallet, LocMastService locMastService) { Short normalizedLocType1 = normalizeLocType1(locType1); if (normalizedLocType1 == null) { return hasAvailableLoc(crnNo, (short) 1, emptyPallet, locMastService) || hasAvailableLoc(crnNo, (short) 2, emptyPallet, locMastService); } if (hasAvailableLoc(crnNo, normalizedLocType1, emptyPallet, locMastService)) { return true; } return normalizedLocType1 == 1 && hasAvailableLoc(crnNo, (short) 2, emptyPallet, locMastService); } private static boolean hasAvailableLoc(Integer crnNo, Short locType1, boolean emptyPallet, LocMastService locMastService) { if (crnNo == null || locType1 == null) { return false; } EntityWrapper wrapper = new EntityWrapper(); 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) { if (locType1 == null || (locType1 != 1 && locType1 != 2)) { return null; } return locType1.shortValue(); } private static List getOtherAreaCrnNos(Integer preferredArea, RowLastno rowLastno) { LinkedHashSet 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 getAreaCrnNos(Integer area, RowLastno rowLastno) { LinkedHashSet crnNos = new LinkedHashSet<>(); RowLastno areaRowLastno = findAreaRowLastno(area, rowLastno); if (areaRowLastno == null) { return new ArrayList<>(crnNos); } Integer startCrnNo = resolveAreaStartCrnNo(areaRowLastno); List orderedCrnNos = getOrderedCrnNos(areaRowLastno, startCrnNo); if (!orderedCrnNos.isEmpty()) { crnNos.addAll(orderedCrnNos); } 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 typeMatched = rowLastnoService.selectList(new EntityWrapper() // .eq("type_id", area)); // if (!Cools.isEmpty(typeMatched)) { // return typeMatched.get(0); // } List whsMatched = rowLastnoService.selectList(new EntityWrapper() .eq("whs_type", area)); if (!Cools.isEmpty(whsMatched)) { return whsMatched.get(0); } return defaultRowLastno; } private static Integer resolveAreaStartCrnNo(RowLastno areaRowLastno) { if (areaRowLastno == null) { return null; } 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 (endCrnNo == null || endCrnNo < startCrnNo || currentRow == null || rowSpan == null || rowSpan <= 0) { return startCrnNo; } 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 List getOrderedCrnNos(RowLastno rowLastno, Integer startCrnNo) { List orderedCrnNos = new ArrayList<>(); if (rowLastno == null) { return orderedCrnNos; } 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; } for (int crnNo = first; crnNo <= end; crnNo++) { orderedCrnNos.add(crnNo); } for (int crnNo = start; crnNo < first; crnNo++) { orderedCrnNos.add(crnNo); } return orderedCrnNos; } private static List getAllCrnNos(RowLastno rowLastno) { List 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 getFallbackAreaCrnNos(Integer area, RowLastno rowLastno) { List allCrnNos = getAllCrnNos(rowLastno); List 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 mapRowsToCrnNos(RowLastno rowLastno, List rows) { List result = new ArrayList<>(); if (rowLastno == null || Cools.isEmpty(rows)) { return result; } LinkedHashSet 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 parseAreaRows(String configValue, RowLastno rowLastno) { List rows = new ArrayList<>(); if (rowLastno == null || Cools.isEmpty(configValue)) { return rows; } LinkedHashSet 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 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; } else if (msg.length() > count) { return msg.substring(0, 16); } else { StringBuilder msgBuilder = new StringBuilder(msg); for (int i = 0; i < count - msg.length(); i++) { msgBuilder.insert(0, "0"); } return msgBuilder.toString(); } } /** * 判断是否为深库位 */ public static boolean isDeepLoc(SlaveProperties slaveProperties, String locNo) { if (slaveProperties.isDoubleDeep()) { int row = getRow(locNo); return slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 判断是否为深库位 */ public static boolean isDeepLoc(SlaveProperties slaveProperties, Integer row) { if (slaveProperties.isDoubleDeep()) { return slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 判断是否为左深库位 */ public static boolean isDeepLocLeft(SlaveProperties slaveProperties, Integer row) { if (slaveProperties.isDoubleDeep()) { return slaveProperties.getDoubleLocsLeft().contains(row); } else { return false; } } /** * 判断是否为右深库位 */ public static boolean isDeepLocRight(SlaveProperties slaveProperties, Integer row) { if (slaveProperties.isDoubleDeep()) { return slaveProperties.getDoubleLocsRight().contains(row); } else { return false; } } /** * 判断是否为浅库位 */ public static boolean isShallowLoc(SlaveProperties slaveProperties, String locNo) { if (slaveProperties.isDoubleDeep()) { int row = getRow(locNo); return !slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 判断是否为浅库位 */ public static boolean isShallowLoc(SlaveProperties slaveProperties, Integer row) { if (slaveProperties.isDoubleDeep()) { return !slaveProperties.getDoubleLocs().contains(row); } else { return false; } } /** * 获取 深库位对应的浅库位号 */ public static String getShallowLoc(SlaveProperties slaveProperties, String deepLoc) { int row = getRow(deepLoc); 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); } /** * 获取 深库位排对应的浅库位排 */ public static Integer getShallowRow(SlaveProperties slaveProperties, Integer deepRow) { int remainder = (int) Arith.remainder(deepRow, slaveProperties.getGroupCount()); return remainder == 1 ? (deepRow + 1) : (deepRow - 1); } /** * 获取 浅库位对应的深库位号 */ public static String getDeepLoc(SlaveProperties slaveProperties, String shallowLoc) { int row = getRow(shallowLoc); boolean deepLocLeft = isDeepLocLeft(slaveProperties, row - 1); boolean deepLocRight = isDeepLocRight(slaveProperties, row + 1); int targetRow; if (deepLocLeft) { targetRow = row - 1; } 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) { boolean deepLocLeft = isDeepLocLeft(slaveProperties, shallowRow - 1); boolean deepLocRight = isDeepLocRight(slaveProperties, shallowRow + 1); int targetRow; if (deepLocLeft) { targetRow = shallowRow - 1; } else if (deepLocRight) { targetRow = shallowRow + 1; } else { throw new RuntimeException(shallowRow + "不是浅库位,系统繁忙"); } return targetRow; } /** * 通过库位号获取 排 */ public static int getRow(String locNo) { if (!Cools.isEmpty(locNo)) { return Integer.parseInt(locNo.substring(0, 2)); } throw new RuntimeException("库位解析异常"); } /** * 通过库位号获取 列 */ public static int getBay(String locNo) { if (!Cools.isEmpty(locNo)) { return Integer.parseInt(locNo.substring(2, 5)); } throw new RuntimeException("库位解析异常"); } /** * 通过库位号获取 层 */ public static int getLev(String locNo) { if (!Cools.isEmpty(locNo)) { return Integer.parseInt(locNo.substring(5, 7)); } throw new RuntimeException("库位解析异常"); } /** * 当检索到双深库位的浅库位时,如果深库位无货,则放入对应的深库位 */ public static void toDeepIfEmptyByShallow(String shallowLoc) { int row = getRow(shallowLoc); int remainder = (int) Arith.remainder(row, 4); int targetRow = 0; if (remainder == 2) { targetRow = row - 1; } else if (remainder == 3) { targetRow = row + 1; } else { throw new RuntimeException(shallowLoc + "不是浅库位,系统繁忙"); } String targetLoc = zerofill(String.valueOf(targetRow), 2) + shallowLoc.substring(2); } // public static void main(String[] args) { // SlaveProperties slaveProperties = new SlaveProperties(); // slaveProperties.setDoubleDeep(true); // List list = new ArrayList<>(); // list.add(1);list.add(4);list.add(5);list.add(8);list.add(9);list.add(12); // slaveProperties.setDoubleLocs(list); // slaveProperties.setGroupCount(4); // Integer deepRow = getDeepRow(slaveProperties, 6); // System.out.println(deepRow); // } public static Integer GetWhsType(Integer sourceStaNo) { RowLastnoService rowLastnoService = SpringUtils.getBean(RowLastnoService.class); List rowLastnos = rowLastnoService.selectList(new EntityWrapper()); for (RowLastno rowLastno : rowLastnos) { String[] staNoList = rowLastno.getStaNoList().split(";"); for (String staNo : staNoList) { if (staNo.equals(sourceStaNo.toString())) { return rowLastno.getWhsType(); } } } return 0; } public static boolean BooleanWhsTypeStaIoType(RowLastno rowLastno) { //查询相似物料开关 if (rowLastno.getBeSimilar().equals("Y")) { return true; } return false; } public static boolean BooleanWhsTypeSta(RowLastno rowLastno, Integer staDescId) {//站点路径更新 if (rowLastno.getPointSwitch().equals("Y") && 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 getCurRow(RowLastno rowLastno, Integer curRow, Integer crnNumber) { return LocNecessaryParameters(rowLastno, curRow, crnNumber)[1]; } public static int getCrnNo(RowLastno rowLastno, Integer curRow, Integer crnNumber) { return LocNecessaryParameters(rowLastno, curRow, crnNumber)[2]; } public static int getNearRow(RowLastno rowLastno, Integer curRow, Integer crnNumber) { return LocNecessaryParameters(rowLastno, curRow, crnNumber)[3]; } //库位排号分配 public static int[] LocNecessaryParameters(RowLastno rowLastno, Integer curRow, Integer crnNumber) { switch (rowLastno.getTypeId()) { case 1://经典双伸库位 return LocNecessaryParametersDoubleExtension(rowLastno, curRow, crnNumber); //已完善 case 2://经典单伸库位(2排货架) return LocNecessaryParametersDoubleExtension2(rowLastno, curRow, crnNumber); //已完善 case 3://经典单双伸库位 左单右双(小单大双) return LocNecessaryParametersDoubleExtension3(rowLastno, curRow, crnNumber); //未完善 case 4://经典单双伸库位 左双右单(小双大单) 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 } } //经典双伸库位 public static int[] LocNecessaryParametersDoubleExtension(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(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 { throw new CoolException("库位排号异常:排号:" + curRow); } } return necessaryParameters; } //经典双伸库位移库 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 最深库位排 necessaryParameters[2] = moveCrnNo; //crnNo 堆垛机号 necessaryParameters[3] = curRow + 1; //nearRow 最浅库位排 } else { necessaryParameters[1] = curRow - 2; //curRow 最深库位排 necessaryParameters[2] = moveCrnNo; //crnNo 堆垛机号 necessaryParameters[3] = curRow - 1; //nearRow 最浅库位排 } return necessaryParameters; } //经典单伸库位 public static int[] LocNecessaryParametersDoubleExtension2(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(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 { throw new CoolException("库位排号异常:排号:" + curRow); } } return necessaryParameters; } //经典单双伸库位 左单右双(小单大双) public static int[] LocNecessaryParametersDoubleExtension3(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(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 { 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();//起始堆垛机号 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 { throw new CoolException("库位排号异常:排号:" + curRow); } } return necessaryParameters; } //双工位单伸库位 public static int[] LocNecessaryParametersDoubleExtension5(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(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 { 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; } public static void main(String[] args) { List locS = new ArrayList(); String locNo = "0000102"; for (int i = 1; i < 16; i++) { String s = zerofill(String.valueOf(i), 2) + locNo.substring(2); LocMast locMast = new LocMast(); locMast.setLocNo(s); locS.add(locMast); } List innermostSideLoc = getInnermostSideLoc(locS); System.out.println(innermostSideLoc); } //转换为各自对应的深库位 public static List getInnermostSideLoc(List locS) { ArrayList listLocRBL = new ArrayList<>(); for (LocMast locMast : locS) { String innermostSideLocRBL = Utils.getInnermostSideLocRBL(locMast.getLocNo()); if (Cools.isEmpty(innermostSideLocRBL)) { continue; } if (!listLocRBL.contains(innermostSideLocRBL)) { listLocRBL.add(innermostSideLocRBL); } } return listLocRBL; } public static String getInnermostSideLocRBL(String locNo) { int row = Utils.getRow(locNo); if (row % 4 == 0 || (row + 3) % 4 == 0) { return zerofill(String.valueOf(row), 2) + locNo.substring(2); } else if ((row + 2) % 4 == 0) { return zerofill(String.valueOf(row - 1), 2) + locNo.substring(2); } else if ((row + 1) % 4 == 0) { return zerofill(String.valueOf(row + 1), 2) + locNo.substring(2); } return null; } public static String getInnermostSideLocLBR(String locNo) { int row = Utils.getRow(locNo); if (row % 4 == 0) { return zerofill(String.valueOf(row - 1), 2) + locNo.substring(2); } else if ((row + 3) % 4 == 0) { return zerofill(String.valueOf(row + 1), 2) + locNo.substring(2); } return null; } /* * 最深库位排号 : curRow * 最浅库位排号 : nearRow * 最浅库位号,用于锁定列、层 : nearRow * 入库 true:pakin * 出库 false:pakin * */ // 外侧方向的货位 优先入库方向 ===>> 反之 public static List getGroupOutLocCrn(Integer curRow, Integer nearRow, String locNo, boolean pakin) { List result = new ArrayList<>(); if (pakin) { for (int row = curRow; row >= nearRow; row--) { result.add(zerofill(String.valueOf(row), 2) + locNo.substring(2)); } } else { for (int row = curRow; row <= nearRow; row++) { result.add(zerofill(String.valueOf(row), 2) + locNo.substring(2)); } } return result; } //erp庫位轉換 public static String ERPLocToWMSLoc(String locNo) { String WmsLoc = locNo.substring(1); String[] split = locNo.split("-"); WmsLoc = split[0].substring(1) + split[1] + split[2]; return WmsLoc; } //将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; } }