diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java index 8e658f82..0096fa1b 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java @@ -580,11 +580,15 @@ public class HaiAnWmsMessageServiceImpl implements HaiAnWmsMessageService { // 2. 构建海安回调扫描记录:保持与老receivePalletRfidScanCallback字段语义一致 - rqrq HaiAnWcsCallbackPalletScan callback = new HaiAnWcsCallbackPalletScan(); + // 显式设置接收/创建/更新时间:全局填充器只处理createdDate/updatedDate,不填At字段;避免空时间参数绑定导致SQL Server datetime2写入失败 - rqrq + Date receivedAt = new Date(); + callback.setCreatedAt(receivedAt); + callback.setUpdatedAt(receivedAt); callback.setSite(site); callback.setPalletId(data.getPalletBarcode().trim()); callback.setTaskNo(data.getTaskNo().trim()); callback.setItemNo(String.valueOf(data.getItemNo())); - callback.setWcsScanTime(new Date()); + callback.setWcsScanTime(receivedAt); callback.setWcsBarcodeList(JSONObject.toJSONString(wcsBarcodeList)); callback.setWcsTotalQuantity(wcsBarcodeList.size()); callback.setSoreType(data.getSoreType()); diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnPalletScanCallbackTaskServiceImpl.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnPalletScanCallbackTaskServiceImpl.java index d87cf98c..de8a16d4 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnPalletScanCallbackTaskServiceImpl.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/service/impl/HaiAnPalletScanCallbackTaskServiceImpl.java @@ -19,6 +19,7 @@ import com.gaotao.modules.autoWareHourceHaian.service.HaiAnPalletOperationLogSer import com.gaotao.modules.autoWareHourceHaian.service.HaiAnPalletScanCallbackTaskService; import com.gaotao.modules.autoWareHourceHaian.service.HaiAnWcsCallbackPalletScanService; import com.gaotao.modules.autoWareHourceHaian.service.HaiAnWmsWcsInventoryDiscrepancyService; +import com.gaotao.modules.autoWareHourceHaian.staticData.HaiAnAssembleTypeStaticData; import com.gaotao.modules.autoWareHourceHaian.staticData.HaiAnOperatorStaticData; import com.gaotao.modules.autoWareHourceHaian.staticData.HaiAnStatusStaticData; import lombok.extern.slf4j.Slf4j; @@ -33,7 +34,9 @@ import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -64,7 +67,7 @@ public class HaiAnPalletScanCallbackTaskServiceImpl implements HaiAnPalletScanCa /** * @author rqrq - * @Description 消费“被分拣回传”回调:先抢占记录,再对比WMS与WCS标签差异并落海安差异表 - rqrq + * @Description 消费“被分拣回传”:抢占后对账,气胀轴/抱箱同步剩余标签格位和层数;仅操作海安表,位置校验或更新失败时整条回调事务回滚 - rqrq * @param callback 海安回调记录 - rqrq * @throws Exception 回调处理失败时抛出异常,由调度层记录失败统计 - rqrq */ @@ -106,6 +109,15 @@ public class HaiAnPalletScanCallbackTaskServiceImpl implements HaiAnPalletScanCa Set extraBarcodes = new LinkedHashSet(wcsSet); extraBarcodes.removeAll(wmsSet); + // 气胀轴/抱箱回传包含源盘剩余标签的位置;仅更新双方共有标签,人工分拣仍沿用原对账逻辑 - rqrq + if (HaiAnAssembleTypeStaticData.SORE_TYPE_AIR_SHAFT.equals(callback.getSoreType()) + || HaiAnAssembleTypeStaticData.SORE_TYPE_BOX.equals(callback.getSoreType())) { + Set remainingSerialNos = new LinkedHashSet(wmsSet); + remainingSerialNos.retainAll(wcsSet); + // 以回调工厂和源盘为更新边界;缺位置或SQL失败抛出异常,调用标记及明细变更一起回滚 - rqrq + updateRemainingDetailPositions(callback, site, palletId, remainingSerialNos); + } + // 3. 无论是否有差异都写追溯记录,保持现场核对链路完整可查 - rqrq HaiAnWmsWcsInventoryDiscrepancy discrepancy = new HaiAnWmsWcsInventoryDiscrepancy(); discrepancy.setSite(site); @@ -139,6 +151,58 @@ public class HaiAnPalletScanCallbackTaskServiceImpl implements HaiAnPalletScanCa } } + /** + * @Description 按原始回传同步源盘剩余标签位置,仅更新haian_pallet_detail;空盘跳过,位置缺失或冲突抛异常,由外层事务整体回滚 - rqrq + * @param callback 海安扫描回调,jsonStr保存WCS传入的格位、层数 - rqrq + * @param site 回调所属工厂,必须与原始报文一致 - rqrq + * @param palletId 被分拣源盘号,防止更新已转入目标盘的标签 - rqrq + * @param remainingSerialNos 当前源盘账面标签与WCS回传标签的交集 - rqrq + */ + private void updateRemainingDetailPositions(HaiAnWcsCallbackPalletScan callback, String site, + String palletId, Set remainingSerialNos) { + if (remainingSerialNos.isEmpty()) { + return; + } + // 解析已保存的回调正文以取得位置;正文损坏时中断,禁止仅凭条码列表猜测格位 - rqrq + HaiAnPickingFeedbackRequest request = JSONObject.parseObject(callback.getJsonStr(), HaiAnPickingFeedbackRequest.class); + if (request == null || !site.equals(normalizeText(request.getSite())) + || !palletId.equals(normalizeText(request.getPalletBarcode()))) { + throw new RuntimeException("被分拣回传位置更新失败:原始报文工厂或源盘不匹配,site=" + site + ",palletId=" + palletId); + } + Map positions = new LinkedHashMap(); + if (request.getCargoInfos() != null) { + for (HaiAnPickingFeedbackCargoInfo cargoInfo : request.getCargoInfos()) { + if (cargoInfo == null || cargoInfo.getProductInfos() == null) { + continue; + } + for (HaiAnPickingFeedbackProductInfo productInfo : cargoInfo.getProductInfos()) { + String serialNo = productInfo == null ? null : normalizeText(productInfo.getSerialNo()); + if (!remainingSerialNos.contains(serialNo)) { + continue; + } + if (cargoInfo.getPosition() == null || cargoInfo.getLayer() == null) { + throw new RuntimeException("被分拣回传缺少格位或层数,palletId=" + palletId + ",serialNo=" + serialNo); + } + HaiAnPickingFeedbackCargoInfo previous = positions.get(serialNo); + if (previous != null && (!previous.getPosition().equals(cargoInfo.getPosition()) + || !previous.getLayer().equals(cargoInfo.getLayer()))) { + throw new RuntimeException("被分拣回传同一标签存在冲突位置,palletId=" + palletId + ",serialNo=" + serialNo); + } + positions.put(serialNo, cargoInfo); + } + } + } + for (String serialNo : remainingSerialNos) { + HaiAnPickingFeedbackCargoInfo position = positions.get(serialNo); + if (position == null) { + throw new RuntimeException("被分拣回传剩余标签缺少位置明细,palletId=" + palletId + ",serialNo=" + serialNo); + } + // 海安Mapper按site+palletId+serialNo更新haian_pallet_detail的position/layer及wcs_flag=1;SQL失败由外层事务回滚 - rqrq + haiAnPdaAutoWarehouseMapper.updatePalletDetailPosition( + site, palletId, serialNo, String.valueOf(position.getPosition()), position.getLayer()); + } + } + /** * @author rqrq * @Description 消费“自动分拣”回调:执行增量扫入扫出、empty_flag回写、任务状态联动(不触发endFlag自动发起任务) - rqrq