From 8b2b0c0c65c75283fcd5728043969edd60ec5a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=86=9F=E5=90=B4=E5=BD=A6=E7=A5=96?= Date: Sat, 11 Oct 2025 14:24:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=88=E6=9D=BF=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IfsCallErrorLogController.java | 6 + .../api/service/IfsCallErrorLogService.java | 2 + .../impl/IfsCallErrorLogServiceImpl.java | 9 + .../impl/InventoryDiscrepancyServiceImpl.java | 321 +++++++++++++----- 4 files changed, 262 insertions(+), 76 deletions(-) diff --git a/src/main/java/com/gaotao/modules/api/controller/IfsCallErrorLogController.java b/src/main/java/com/gaotao/modules/api/controller/IfsCallErrorLogController.java index 70a6e97..d309a5d 100644 --- a/src/main/java/com/gaotao/modules/api/controller/IfsCallErrorLogController.java +++ b/src/main/java/com/gaotao/modules/api/controller/IfsCallErrorLogController.java @@ -124,4 +124,10 @@ public class IfsCallErrorLogController extends AbstractController { return R.error("重试失败:" + e.getMessage()); } } + @PostMapping("/closeRetry") + public R closeRetry(@RequestBody IfsCallErrorLogData data) { + String processedBy = getUser().getUsername(); + ifsCallErrorLogService.closeRetry(data.getId(), processedBy); + return R.ok(); + } } diff --git a/src/main/java/com/gaotao/modules/api/service/IfsCallErrorLogService.java b/src/main/java/com/gaotao/modules/api/service/IfsCallErrorLogService.java index 300dca5..045a5e0 100644 --- a/src/main/java/com/gaotao/modules/api/service/IfsCallErrorLogService.java +++ b/src/main/java/com/gaotao/modules/api/service/IfsCallErrorLogService.java @@ -75,4 +75,6 @@ public interface IfsCallErrorLogService extends IService { * @date 2025/10/08 */ boolean retryIfsCall(Long id, String processedBy); + + void closeRetry(Long id, String processedBy); } diff --git a/src/main/java/com/gaotao/modules/api/service/impl/IfsCallErrorLogServiceImpl.java b/src/main/java/com/gaotao/modules/api/service/impl/IfsCallErrorLogServiceImpl.java index 4f0d1bc..d6798a2 100644 --- a/src/main/java/com/gaotao/modules/api/service/impl/IfsCallErrorLogServiceImpl.java +++ b/src/main/java/com/gaotao/modules/api/service/impl/IfsCallErrorLogServiceImpl.java @@ -258,6 +258,15 @@ public class IfsCallErrorLogServiceImpl extends ServiceImpl wmsDetailList = wcsIntegrationMapper.getPalletDetailsData( - callback.getSite(), callback.getPalletId()); - - // 3. 提取WMS所有条码 - rqrq - List wmsBarcodeList = wmsDetailList.stream() - .map(PalletDetailData::getSerialNo) - .collect(Collectors.toList()); - - // 4. 解析WCS扫描的条码列表 - rqrq - List wcsBarcodeList = new ArrayList<>(); - if (callback.getWcsBarcodeList() != null && !callback.getWcsBarcodeList().isEmpty()) { - try { - JSONArray jsonArray = JSONArray.parseArray(callback.getWcsBarcodeList()); - for (int i = 0; i < jsonArray.size(); i++) { - wcsBarcodeList.add(jsonArray.getString(i)); + if(callback.getSoreType()==0) { + // 2. 从pallet_detail表查询WMS账面数据 - rqrq + List wmsDetailList = wcsIntegrationMapper.getPalletDetailsData( + callback.getSite(), callback.getPalletId()); + + // 3. 提取WMS所有条码 - rqrq + List wmsBarcodeList = wmsDetailList.stream() + .map(PalletDetailData::getSerialNo) + .collect(Collectors.toList()); + + // 4. 解析WCS扫描的条码列表 - rqrq + List wcsBarcodeList = new ArrayList<>(); + if (callback.getWcsBarcodeList() != null && !callback.getWcsBarcodeList().isEmpty()) { + try { + JSONArray jsonArray = JSONArray.parseArray(callback.getWcsBarcodeList()); + for (int i = 0; i < jsonArray.size(); i++) { + wcsBarcodeList.add(jsonArray.getString(i)); + } + } catch (Exception e) { + System.err.println("解析WCS条码列表失败 - rqrq:" + e.getMessage()); } - } catch (Exception e) { - System.err.println("解析WCS条码列表失败 - rqrq:" + e.getMessage()); } + + // 5. 对比整个栈板的差异(不按物料分组)- rqrq + Set wmsSet = new HashSet<>(wmsBarcodeList); + Set wcsSet = new HashSet<>(wcsBarcodeList); + + // WMS有但WCS没有的条码 - rqrq + Set missingBarcodes = new HashSet<>(wmsSet); + missingBarcodes.removeAll(wcsSet); + + // WCS有但WMS没有的条码 - rqrq + Set extraBarcodes = new HashSet<>(wcsSet); + extraBarcodes.removeAll(wmsSet); + + // 6. 生成一条差异记录(无论是否有差异都记录,便于追踪)- rqrq + WmsWcsInventoryDiscrepancy discrepancy = new WmsWcsInventoryDiscrepancy(); + discrepancy.setSite(callback.getSite()); + discrepancy.setCallbackId(callback.getId()); + discrepancy.setPalletId(callback.getPalletId()); + discrepancy.setTaskNo(callback.getTaskNo()); + discrepancy.setItemNo(callback.getItemNo()); + discrepancy.setOperationType("picking"); + discrepancy.setOperationTime(callback.getWcsScanTime()); + discrepancy.setPartNo(""); // 不再按物料分组,留空 - rqrq + + discrepancy.setWmsTotalQuantity(wmsBarcodeList.size()); + discrepancy.setWcsTotalQuantity(wcsBarcodeList.size()); + + discrepancy.setWmsBarcodeList(JSONObject.toJSONString(wmsBarcodeList)); + discrepancy.setWcsBarcodeList(JSONObject.toJSONString(wcsBarcodeList)); + discrepancy.setWmsMissingBarcodes(JSONObject.toJSONString(new ArrayList<>(missingBarcodes))); + discrepancy.setWcsExtraBarcodes(JSONObject.toJSONString(new ArrayList<>(extraBarcodes))); + + // 如果有差异,标记为待处理;无差异,标记为已处理 - rqrq + if (!missingBarcodes.isEmpty() || !extraBarcodes.isEmpty()) { + discrepancy.setStatus(0); // 待处理 - rqrq + discrepancy.setRemark("系统自动对账生成 - 发现差异"); + } else { + discrepancy.setStatus(2); // 已处理(无差异)- rqrq + discrepancy.setRemark("系统自动对账生成 - 无差异"); + } + + // 7. 插入差异记录(改为单条插入)- rqrq + List discrepancyList = new ArrayList<>(); + discrepancyList.add(discrepancy); + wmsWcsInventoryDiscrepancyMapper.batchInsert(discrepancyList); + + System.out.println("生成库存差异记录 - rqrq,栈板=" + callback.getPalletId() + + ",WMS条码数=" + wmsBarcodeList.size() + + ",WCS条码数=" + wcsBarcodeList.size() + + ",缺失=" + missingBarcodes.size() + + ",多余=" + extraBarcodes.size()); + + // 8. 更新回调记录状态为已完成 - rqrq + wcsCallbackPalletScanMapper.updateProcessStatus(callback.getId(), "COMPLETED", null); + + System.out.println("WCS回调扫描记录对账完成 - rqrq,palletId=" + callback.getPalletId() + + ",分拣方式=" + callback.getSoreType()); + } else if(callback.getSoreType()==1||callback.getSoreType()==2) { + // 自动分拣逻辑(气胀轴或抱箱)- rqrq + System.out.println("执行自动分拣逻辑 - rqrq,分拣方式=" + (callback.getSoreType()==1 ? "气胀轴" : "抱箱")); + + // 1. 解析jsonStr为PushPalletDetailDto对象 - rqrq + if (!StringUtils.hasText(callback.getJsonStr())) { + throw new Exception("jsonStr为空,无法解析栈板和明细信息"); + } + + com.gaotao.modules.api.entity.PushPalletDetailDto pushData = JSONObject.parseObject( + callback.getJsonStr(), + com.gaotao.modules.api.entity.PushPalletDetailDto.class + ); + + if (pushData == null) { + throw new Exception("jsonStr解析为PushPalletDetailDto失败"); + } + + String originalPalletId = pushData.getPalletBarcode(); + if (!StringUtils.hasText(originalPalletId)) { + throw new Exception("PushPalletDetailDto中未找到栈板编码(palletBarcode)"); + } + + System.out.println("解析成功 - rqrq,原栈板=" + originalPalletId + + ",taskNo=" + pushData.getTaskNo() + + ",itemNo=" + pushData.getItemNo()); + + // 2. 查询原栈板的pallet_detail数据(WMS账面)- rqrq + List wmsDetailList = wcsIntegrationMapper.getPalletDetailsData( + callback.getSite(), originalPalletId); + + // 提取WMS所有条码(当前账面)- rqrq + Set wmsSerialNoSet = wmsDetailList.stream() + .map(PalletDetailData::getSerialNo) + .collect(Collectors.toSet()); + + System.out.println("WMS当前明细数量 - rqrq:" + wmsDetailList.size() + "条"); + + // 3. 提取WCS回传的所有条码和位置信息 - rqrq + Map wcsSerialNoMap = new HashMap<>(); + int totalWcsCount = 0; + + List cargoInfos = pushData.getCargoInfos(); + if (cargoInfos != null && !cargoInfos.isEmpty()) { + for (com.gaotao.modules.api.entity.PalletStationVo cargoInfo : cargoInfos) { + Integer position = cargoInfo.getPosition(); + Integer layer = cargoInfo.getLayer(); + List productInfos = cargoInfo.getProductInfos(); + + if (productInfos != null && !productInfos.isEmpty()) { + for (com.gaotao.modules.api.entity.PalletStationDetailVo product : productInfos) { + totalWcsCount++; + String serialNo = product.getSerialNo(); + wcsSerialNoMap.put(serialNo, new PositionInfo( + String.valueOf(position), + layer, + product.getSku() + )); + } + } + } + } + + System.out.println("WCS回传明细总数 - rqrq:" + totalWcsCount + "条"); + + // 4. 找出被拿走的物料(WMS有但WCS没有的)- rqrq + Set removedSerialNos = new HashSet<>(wmsSerialNoSet); + removedSerialNos.removeAll(wcsSerialNoMap.keySet()); + + System.out.println("被拿走的物料数量 - rqrq:" + removedSerialNos.size() + "条"); + + // 5. 将拿走的物料转移到虚拟栈板"ZIDONGFENJIAN" - rqrq + String virtualPalletId = "ZIDONGFENJIAN"; + String virtualPosition = pushData.getTaskNo(); // position = taskNo + Integer virtualLayer = pushData.getItemNo(); // layer = itemNo + String username = "WCS"; + + for (String removedSerialNo : removedSerialNos) { + // 查找原明细信息(获取partNo)- rqrq + PalletDetailData originalDetail = wmsDetailList.stream() + .filter(d -> removedSerialNo.equals(d.getSerialNo())) + .findFirst() + .orElse(null); + + if (originalDetail == null) { + System.err.println("未找到原明细信息 - rqrq:serialNo=" + removedSerialNo); + continue; + } + + // 从原栈板删除 - rqrq + wcsIntegrationMapper.deletePalletDetailBySerialNo(callback.getSite(), removedSerialNo); + + // 添加到虚拟栈板 - rqrq + wcsIntegrationMapper.savePalletDetailNoValidation( + callback.getSite(), + virtualPalletId, + virtualPosition, + virtualLayer, + removedSerialNo, + originalDetail.getPartNo(), + username, + 1 // wcsFlag=1(待推送) + ); + + System.out.println("物料已转移到虚拟栈板 - rqrq:serialNo=" + removedSerialNo + + ",虚拟栈板=" + virtualPalletId + + ",position=" + virtualPosition + + ",layer=" + virtualLayer); + } + + // 6. 更新还在原栈板上的物料的position和layer - rqrq + Set remainingSerialNos = new HashSet<>(wmsSerialNoSet); + remainingSerialNos.retainAll(wcsSerialNoMap.keySet()); // WMS和WCS都有的 + + System.out.println("还在原栈板上的物料数量 - rqrq:" + remainingSerialNos.size() + "条,开始更新位置"); + + for (String remainingSerialNo : remainingSerialNos) { + PositionInfo newPosInfo = wcsSerialNoMap.get(remainingSerialNo); + + // 更新位置和层数 - rqrq + wcsIntegrationMapper.updatePalletDetailPosition( + callback.getSite(), + originalPalletId, + remainingSerialNo, + newPosInfo.position, + newPosInfo.layer, + "JiXieShouBi" + ); + + System.out.println("更新物料位置 - rqrq:serialNo=" + remainingSerialNo + + ",newPosition=" + newPosInfo.position + + ",newLayer=" + newPosInfo.layer); + } + + // 7. 更新空栈板标记(如果原栈板已无明细,则标记为空)- rqrq + if (remainingSerialNos.isEmpty()) { + wcsIntegrationMapper.updatePalletEmptyFlag(callback.getSite(), originalPalletId, "Y", username); + System.out.println("原栈板已空,更新empty_flag='Y' - rqrq"); + } else { + wcsIntegrationMapper.updatePalletEmptyFlag(callback.getSite(), originalPalletId, "N", username); + System.out.println("原栈板非空,更新empty_flag='N' - rqrq"); + } + + // 8. 更新回调记录状态为已完成 - rqrq + wcsCallbackPalletScanMapper.updateProcessStatus( + callback.getId(), + "COMPLETED", + "自动分拣处理完成,转移" + removedSerialNos.size() + "条,更新" + remainingSerialNos.size() + "条" + ); + + System.out.println("自动分拣处理完成 - rqrq,原栈板=" + originalPalletId + + ",转移到虚拟栈板=" + removedSerialNos.size() + "条" + + ",更新位置=" + remainingSerialNos.size() + "条"); } - // 5. 对比整个栈板的差异(不按物料分组)- rqrq - Set wmsSet = new HashSet<>(wmsBarcodeList); - Set wcsSet = new HashSet<>(wcsBarcodeList); - - // WMS有但WCS没有的条码 - rqrq - Set missingBarcodes = new HashSet<>(wmsSet); - missingBarcodes.removeAll(wcsSet); - - // WCS有但WMS没有的条码 - rqrq - Set extraBarcodes = new HashSet<>(wcsSet); - extraBarcodes.removeAll(wmsSet); - - // 6. 生成一条差异记录(无论是否有差异都记录,便于追踪)- rqrq - WmsWcsInventoryDiscrepancy discrepancy = new WmsWcsInventoryDiscrepancy(); - discrepancy.setSite(callback.getSite()); - discrepancy.setCallbackId(callback.getId()); - discrepancy.setPalletId(callback.getPalletId()); - discrepancy.setTaskNo(callback.getTaskNo()); - discrepancy.setItemNo(callback.getItemNo()); - discrepancy.setOperationType("picking"); - discrepancy.setOperationTime(callback.getWcsScanTime()); - discrepancy.setPartNo(""); // 不再按物料分组,留空 - rqrq - - discrepancy.setWmsTotalQuantity(wmsBarcodeList.size()); - discrepancy.setWcsTotalQuantity(wcsBarcodeList.size()); - - discrepancy.setWmsBarcodeList(JSONObject.toJSONString(wmsBarcodeList)); - discrepancy.setWcsBarcodeList(JSONObject.toJSONString(wcsBarcodeList)); - discrepancy.setWmsMissingBarcodes(JSONObject.toJSONString(new ArrayList<>(missingBarcodes))); - discrepancy.setWcsExtraBarcodes(JSONObject.toJSONString(new ArrayList<>(extraBarcodes))); - - // 如果有差异,标记为待处理;无差异,标记为已处理 - rqrq - if (!missingBarcodes.isEmpty() || !extraBarcodes.isEmpty()) { - discrepancy.setStatus(0); // 待处理 - rqrq - discrepancy.setRemark("系统自动对账生成 - 发现差异"); - } else { - discrepancy.setStatus(2); // 已处理(无差异)- rqrq - discrepancy.setRemark("系统自动对账生成 - 无差异"); - } - - // 7. 插入差异记录(改为单条插入)- rqrq - List discrepancyList = new ArrayList<>(); - discrepancyList.add(discrepancy); - wmsWcsInventoryDiscrepancyMapper.batchInsert(discrepancyList); - - System.out.println("生成库存差异记录 - rqrq,栈板=" + callback.getPalletId() - + ",WMS条码数=" + wmsBarcodeList.size() - + ",WCS条码数=" + wcsBarcodeList.size() - + ",缺失=" + missingBarcodes.size() - + ",多余=" + extraBarcodes.size()); - - // 8. 更新回调记录状态为已完成 - rqrq - wcsCallbackPalletScanMapper.updateProcessStatus(callback.getId(), "COMPLETED", null); - - System.out.println("WCS回调扫描记录对账完成 - rqrq,palletId=" + callback.getPalletId() - + ",分拣方式=" + callback.getSoreType()); - } catch (Exception e) { System.err.println("处理WCS回调扫描记录对账失败 - rqrq,palletId=" + callback.getPalletId() + ",错误:" + e.getMessage());