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.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 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()); } /** * 生成入库找库位时的堆垛机优先顺序。 * *

处理规则: * 1. 先根据入库站点查询所属库区。 * 2. 先提取该库区内的堆垛机,并按可用空库位过滤不可用堆垛机。 * 3. 若当前库区没有满足条件的空库位,再补充其他库区的堆垛机。 * 4. 当 {@code locType1 = 1} 时,先返回低库位堆垛机,再把同批堆垛机的高库位追加到后面。 * 5. 对不存在、故障、不可入以及无空库位的堆垛机直接剔除。 * 6. 当物料为 {@code emptyPallet} 时,按空板入库优先规则重新排序。 * *

返回结果中的每一项格式为: * {@code {crnNo: 堆垛机号, locType1: 库位高低类型}} * * @param stationId 入库站点 * @param locType1 目标库位高低类型,1=低库位,2=高库位 * @param matnr 物料编码,传入 {@code emptyPallet} 时使用空板排序规则 * @return 按优先级排好序的堆垛机列表 */ public static List> getStationStorageAreaName(Integer stationId, Integer locType1, String matnr) { List> 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 preferredCrnNos = getAreaCrnNos(storageArea, rowLastno); List preferredAvailableCrnNos = getAvailableCrnNos(preferredCrnNos, locType1, emptyPallet, basCrnpService, locMastService); appendCrnLocTypeEntries(result, preferredAvailableCrnNos, locType1, locMastService); // 当前库区没有可用容量时,再补充其他库区堆垛机。 if (!hasAvailableCapacity(preferredCrnNos, locType1, basCrnpService, locMastService)) { List otherAreaCrnNos = getOtherAreaCrnNos(storageArea, rowLastno); List otherAvailableCrnNos = getAvailableCrnNos(otherAreaCrnNos, locType1, emptyPallet, basCrnpService, locMastService); appendCrnLocTypeEntries(result, otherAvailableCrnNos, locType1, locMastService); } return result; } private static void appendCrnLocTypeEntries(List> result, List 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> result, List 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 item = new LinkedHashMap<>(); item.put("crnNo", crnNo); item.put("locType1", targetLocType1.intValue()); result.add(item); } } private static boolean containsCrnLocType(List> result, Integer crnNo, Short locType1) { for (Map 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 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, 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, 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() .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 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, 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 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, 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 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 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; } //将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; } }