From d36fe7037469589dbd7585f9d7ec9abf123c541a 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: Fri, 4 Sep 2026 10:37:51 +0800 Subject: [PATCH] 1 --- .../entity/HaiAnInventoryMatchResult.java | 6 + ...IssueNotifyPushTransactionServiceImpl.java | 4 +- .../HaiAnSearchIssureNotifyServiceImpl.java | 165 ++++++++++++++---- src/main/resources/application.yml | 2 +- 4 files changed, 144 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/entity/HaiAnInventoryMatchResult.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/entity/HaiAnInventoryMatchResult.java index 01bdebf8..a379ba62 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/entity/HaiAnInventoryMatchResult.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/entity/HaiAnInventoryMatchResult.java @@ -19,6 +19,12 @@ public class HaiAnInventoryMatchResult { private String site; /** 领料申请单号,来自海安申请单主键范围 - rqrq */ private String notifyNo; + /** 预览行类型,MATERIAL表示物料汇总,SPECIFIED表示该物料下的指定明细;仅接口展示使用且不落库 - rqrq */ + private String displayRowType; + /** 指定内容,按“标签:编号”或“批次:编号”展示;仅指定明细预览行有效且不落库 - rqrq */ + private String specifiedContent; + /** 合并后的匹配标签号,按匹配顺序使用顿号分隔;仅预览展示使用且不落库 - rqrq */ + private String matchedSerialNos; /** 事件类型,SUMMARY/MATCH/FAILURE,仅供前端分辨汇总和明细 - rqrq */ private String eventType; /** 订单层行号,关联haian_SOIssueNotifyOrderList.item_no - rqrq */ diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnIssueNotifyPushTransactionServiceImpl.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnIssueNotifyPushTransactionServiceImpl.java index 8b43c7ac..aa18dc2f 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnIssueNotifyPushTransactionServiceImpl.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnIssueNotifyPushTransactionServiceImpl.java @@ -86,7 +86,7 @@ public class HaiAnIssueNotifyPushTransactionServiceImpl implements HaiAnIssueNot // 重新读取目标区域映射,WCS报文使用wcs_area_code,海安任务保存业务area_id - rqrq HaiAnAreaOption area = haiAnSearchIssureNotifyMapper.getIssueTargetArea(site, order.getProductionArea()); if (area == null || StringUtils.isBlank(area.getWcsAreaCode())) { - throw new RuntimeException("订单" + order.getSoorderNo() + "目标区域未配置WCS编码"); + throw new RuntimeException("订单" + order.getSoorderNo() + "目标区域未配置WCS库位编码"); } String targetAreaWcsCode = area.getWcsAreaCode().trim(); String businessArea = StringUtils.defaultString(order.getProductionArea()).trim(); @@ -94,7 +94,7 @@ public class HaiAnIssueNotifyPushTransactionServiceImpl implements HaiAnIssueNot // 重新检查任务幂等记录,防止两个确认请求同时为同一订单创建WCS任务 - rqrq int existingTaskCount = haiAnSearchIssureNotifyMapper.countExistingIssueTask(site, notifyNo, order.getItemNo()); if (existingTaskCount > 0) { - throw new RuntimeException("订单" + order.getSoorderNo() + "已经存在海安领料任务"); + throw new RuntimeException("订单" + order.getSoorderNo() + "已经存在领料任务"); } List actualMatches = filterActualMatches(matchRows, order.getItemNo()); diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnSearchIssureNotifyServiceImpl.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnSearchIssureNotifyServiceImpl.java index 9bc0b909..66c3d0c3 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnSearchIssureNotifyServiceImpl.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnSearchIssureNotifyServiceImpl.java @@ -429,7 +429,6 @@ public class HaiAnSearchIssureNotifyServiceImpl implements HaiAnSearchIssureNoti enrichOrderFields(row, order, area); row.setOrderSatisfactionStatus(inventoryComplete && targetAreaValid ? "COMPLETE" : "INCOMPLETE"); } - copySummaryQuantities(orderRows, summaryRows); if (!targetAreaValid) { HaiAnInventoryMatchResult targetFailure = createFailureRow(order, "TARGET_AREA", "业务目标区域未配置或缺少wcs_area_code", "TARGET_AREA"); enrichOrderFields(targetFailure, order, area); @@ -496,9 +495,144 @@ public class HaiAnSearchIssureNotifyServiceImpl implements HaiAnSearchIssureNoti response.setInventoryShortageOrderCount(shortageCount); response.setTargetAreaFailureOrderCount(targetAreaFailureCount); response.setSummaryMessage("共" + orders.size() + "个订单,库存完整" + completeCount + "个,可推送" + pushableCount + "个"); + // 将内部标签事件压缩成物料汇总和指定明细两类预览行,避免把推送所需的托盘级技术字段暴露给页面 - rqrq + response.setRows(buildCompactPreviewRows(rows)); return response; } + /** + * @author rqrq + * @Description 将标签级匹配事件整理成紧凑预览:物料行显示总需求/总匹配,指定行显示本条指定需求/匹配,标签按格合并 - rqrq + */ + private List buildCompactPreviewRows(List sourceRows) { + List compactRows = new ArrayList(); + if (sourceRows == null || sourceRows.isEmpty()) { + return compactRows; + } + for (HaiAnInventoryMatchResult summary : sourceRows) { + if (summary == null || !"SUMMARY".equalsIgnoreCase(StringUtils.defaultString(summary.getEventType()).trim())) { + continue; + } + HaiAnInventoryMatchResult materialRow = copyPreviewBase(summary); + materialRow.setDisplayRowType("MATERIAL"); + materialRow.setEventType("SUMMARY"); + LinkedHashSet materialSerialNos = new LinkedHashSet(); + Map specifiedRows = new LinkedHashMap(); + Map> specifiedSerialNos = new LinkedHashMap>(); + + for (HaiAnInventoryMatchResult event : sourceRows) { + if (!sameMaterial(summary, event)) { + continue; + } + boolean matchedEvent = isMatchedEvent(event); + if (matchedEvent && StringUtils.isNotBlank(event.getSerialNo())) { + materialSerialNos.add(event.getSerialNo().trim()); + } + if (event.getAllocSeq() == null) { + continue; + } + HaiAnInventoryMatchResult specifiedRow = specifiedRows.get(event.getAllocSeq()); + if (specifiedRow == null) { + specifiedRow = createSpecifiedPreviewRow(summary, event); + specifiedRows.put(event.getAllocSeq(), specifiedRow); + specifiedSerialNos.put(event.getAllocSeq(), new LinkedHashSet()); + } + if (matchedEvent) { + BigDecimal eventQty = event.getEventMatchedQty() == null ? BigDecimal.ZERO : event.getEventMatchedQty(); + specifiedRow.setMatchedQty(specifiedRow.getMatchedQty().add(eventQty)); + if (StringUtils.isNotBlank(event.getSerialNo())) { + specifiedSerialNos.get(event.getAllocSeq()).add(event.getSerialNo().trim()); + } + } + if (StringUtils.isNotBlank(event.getFailureCode()) && StringUtils.isBlank(specifiedRow.getFailureCode())) { + specifiedRow.setMatchStatus("FAILED"); + specifiedRow.setFailureCode(event.getFailureCode()); + specifiedRow.setFailureMessage(event.getFailureMessage()); + } + } + + materialRow.setMatchedSerialNos(joinSerialNos(materialSerialNos)); + compactRows.add(materialRow); + for (Map.Entry entry : specifiedRows.entrySet()) { + entry.getValue().setMatchedSerialNos(joinSerialNos(specifiedSerialNos.get(entry.getKey()))); + compactRows.add(entry.getValue()); + } + } + return compactRows; + } + + /** + * @author rqrq + * @Description 复制前端预览需要的物料字段,明确排除托盘、位置、批次日期等推送内部字段 - rqrq + */ + private HaiAnInventoryMatchResult copyPreviewBase(HaiAnInventoryMatchResult source) { + HaiAnInventoryMatchResult target = new HaiAnInventoryMatchResult(); + target.setSite(source.getSite()); + target.setNotifyNo(source.getNotifyNo()); + target.setItemNo(source.getItemNo()); + target.setSoorderNo(source.getSoorderNo()); + target.setBomItemNo(source.getBomItemNo()); + target.setPartNo(source.getPartNo()); + target.setRequiredQty(source.getRequiredQty()); + target.setMatchedQty(source.getMatchedQty() == null ? BigDecimal.ZERO : source.getMatchedQty()); + target.setMatchStatus(source.getMatchStatus()); + target.setFailureCode(source.getFailureCode()); + target.setFailureMessage(source.getFailureMessage()); + target.setSpecifiedBlocked(source.getSpecifiedBlocked()); + target.setOrderSatisfactionStatus(source.getOrderSatisfactionStatus()); + target.setProductionArea(source.getProductionArea()); + target.setAreaDesc(source.getAreaDesc()); + target.setTargetAreaWcsCode(source.getTargetAreaWcsCode()); + return target; + } + + /** + * @author rqrq + * @Description 创建指定明细预览行,保留父物料键供排序和着色,页面负责将父级字段显示为空形成展开效果 - rqrq + */ + private HaiAnInventoryMatchResult createSpecifiedPreviewRow(HaiAnInventoryMatchResult summary, + HaiAnInventoryMatchResult event) { + HaiAnInventoryMatchResult row = copyPreviewBase(summary); + row.setDisplayRowType("SPECIFIED"); + row.setEventType("SPECIFIED"); + row.setAllocSeq(event.getAllocSeq()); + row.setAllocType(event.getAllocType()); + row.setRequiredQty(event.getRequiredQty() == null ? BigDecimal.ZERO : event.getRequiredQty()); + row.setMatchedQty(BigDecimal.ZERO); + row.setMatchStatus("MATCHED"); + row.setFailureCode(null); + row.setFailureMessage(null); + if ("BATCH".equalsIgnoreCase(StringUtils.defaultString(event.getAllocType()).trim())) { + row.setSpecifiedContent("批次:" + StringUtils.defaultString(event.getBatchNo())); + } else { + row.setSpecifiedContent("标签:" + StringUtils.defaultString(event.getSerialNo())); + } + return row; + } + + /** + * @author rqrq + * @Description 判断事件是否属于同一订单物料行,防止相同物料编码跨BOM行合并标签 - rqrq + */ + private boolean sameMaterial(HaiAnInventoryMatchResult summary, HaiAnInventoryMatchResult event) { + return summary != null && event != null + && summary.getItemNo() != null && event.getItemNo() != null + && summary.getItemNo().compareTo(event.getItemNo()) == 0 + && sameText(summary.getBomItemNo(), event.getBomItemNo()) + && sameText(summary.getPartNo(), event.getPartNo()); + } + + /** + * @author rqrq + * @Description 按匹配顺序合并标签号,空集合返回空文本避免页面显示null - rqrq + */ + private String joinSerialNos(Set serialNos) { + if (serialNos == null || serialNos.isEmpty()) { + return ""; + } + return StringUtils.join(serialNos.iterator(), "、"); + } + /** * @author rqrq * @Description 创建统一失败事件,保证前端能定位失败阶段和订单 - rqrq @@ -533,35 +667,6 @@ public class HaiAnSearchIssureNotifyServiceImpl implements HaiAnSearchIssureNoti row.setTargetAreaWcsCode(area == null ? null : area.getWcsAreaCode()); } - /** - * @author rqrq - * @Description 将物料summary数量复制到标签事件,保证前端查看任一匹配标签时仍能看到需求和差额 - rqrq - */ - private void copySummaryQuantities(List orderRows, - List summaryRows) { - for (HaiAnInventoryMatchResult row : orderRows) { - if (row == null || "SUMMARY".equalsIgnoreCase(StringUtils.defaultString(row.getEventType()).trim())) { - continue; - } - HaiAnInventoryMatchResult summary = null; - for (HaiAnInventoryMatchResult candidate : summaryRows) { - if (sameText(row.getBomItemNo(), candidate.getBomItemNo()) - && sameText(row.getPartNo(), candidate.getPartNo())) { - summary = candidate; - break; - } - } - if (summary != null) { - row.setRequiredQty(summary.getRequiredQty()); - row.setSpecifiedQty(summary.getSpecifiedQty()); - row.setSpecifiedMatchedQty(summary.getSpecifiedMatchedQty()); - row.setFallbackMatchedQty(summary.getFallbackMatchedQty()); - row.setMatchedQty(summary.getMatchedQty()); - row.setShortageQty(summary.getShortageQty()); - } - } - } - /** * @author rqrq * @Description 比较SQL返回的可空文本,避免BOM或物料为空时复制错物料汇总 - rqrq diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a2723811..e50f6295 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -197,7 +197,7 @@ agv: max-task-num: 10 interface: - haianWarehouse: false + haianWarehouse: true # 看板推送任务配置 dashboard: