package com.vincent.rsf.server.manager.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.server.api.controller.erp.params.InOutResultBatchPayload; import com.vincent.rsf.server.api.controller.erp.params.InOutResultReportParam; import com.vincent.rsf.server.manager.entity.AsnOrderLog; import com.vincent.rsf.server.manager.entity.CloudWmsNotifyLog; import com.vincent.rsf.server.manager.service.AsnOrderLogService; import com.vincent.rsf.server.manager.service.CloudWmsFeedbackResendService; import com.vincent.rsf.server.manager.service.CloudWmsNotifyLogService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; /** * 从历史云仓上报记录中取「最新一条」按明细维度去重后,复制请求体写入待发送队列。 */ @Slf4j @Service public class CloudWmsFeedbackResendServiceImpl implements CloudWmsFeedbackResendService { private static final int MAX_SCAN = 500; @Autowired private AsnOrderLogService asnOrderLogService; @Autowired private CloudWmsNotifyLogService cloudWmsNotifyLogService; @Autowired private ObjectMapper objectMapper; @Override public R resendInOutFeedbackByAsnOrderLogId(Long asnOrderLogId) { if (asnOrderLogId == null) { return R.error("参数不能为空"); } AsnOrderLog orderLog = asnOrderLogService.getById(asnOrderLogId); if (orderLog == null) { return R.error("历史单据不存在"); } String code = orderLog.getCode(); if (StringUtils.isBlank(code)) { return R.error("单据号为空,无法重发"); } String reportType = cloudWmsNotifyLogService.getReportTypeInOutResult(); LambdaQueryWrapper qw = new LambdaQueryWrapper() .eq(CloudWmsNotifyLog::getReportType, reportType) .and(w -> w.like(CloudWmsNotifyLog::getRequestBody, "\"orderNo\":\"" + code + "\"") .or() .like(CloudWmsNotifyLog::getBizRef, "orderNo=" + code)) .orderByDesc(CloudWmsNotifyLog::getId) .last("LIMIT " + MAX_SCAN); List candidates = cloudWmsNotifyLogService.list(qw); Map latestByLine = new LinkedHashMap<>(); for (CloudWmsNotifyLog row : candidates) { if (StringUtils.isBlank(row.getRequestBody())) { continue; } try { JsonNode root = objectMapper.readTree(row.getRequestBody()); if (root.has("lines") && root.get("lines").isArray() && root.get("lines").size() > 0) { InOutResultBatchPayload batch = objectMapper.readValue(row.getRequestBody(), InOutResultBatchPayload.class); if (batch.getLines() == null || batch.getLines().isEmpty()) { continue; } InOutResultReportParam first = batch.getLines().get(0); if (!code.equals(first.getOrderNo()) || !matchOrderType(orderLog.getType(), first.getInbound())) { continue; } latestByLine.putIfAbsent("batch_" + row.getId(), row); continue; } InOutResultReportParam p = objectMapper.readValue(row.getRequestBody(), InOutResultReportParam.class); if (p == null || !code.equals(p.getOrderNo())) { continue; } if (!matchOrderType(orderLog.getType(), p.getInbound())) { continue; } String sig = lineSignature(p); latestByLine.putIfAbsent(sig, row); } catch (Exception e) { continue; } } if (latestByLine.isEmpty()) { return R.error("未找到该单号对应的云仓入出库上报记录,无法重发"); } Date now = new Date(); int n = 0; for (CloudWmsNotifyLog src : latestByLine.values()) { CloudWmsNotifyLog copy = new CloudWmsNotifyLog() .setReportType(reportType) .setRequestBody(src.getRequestBody()) .setNotifyStatus(cloudWmsNotifyLogService.getNotifyStatusPending()) .setRetryCount(0) .setBizRef("manualResend,asnOrderLogId=" + asnOrderLogId + ",fromNotifyLogId=" + src.getId() + ",orderNo=" + code) .setCreateTime(now) .setUpdateTime(now) .setSendHold(0) .setSending(0); if (StringUtils.isNotBlank(src.getSourceOrderNo())) { copy.setSourceOrderNo(src.getSourceOrderNo()) .setInboundFlag(src.getInboundFlag()) .setWareHouseCode(src.getWareHouseCode()); } else { fillInOutRoutingFromBody(copy, src.getRequestBody()); } cloudWmsNotifyLogService.fillFromConfig(copy); if (cloudWmsNotifyLogService.save(copy)) { n++; } } return R.ok("已加入云仓重发队列 " + n + " 条,将由定时任务发送").add(n); } private void fillInOutRoutingFromBody(CloudWmsNotifyLog copy, String body) { if (StringUtils.isBlank(body)) { return; } try { JsonNode root = objectMapper.readTree(body); if (root.has("lines") && root.get("lines").isArray() && root.get("lines").size() > 0) { InOutResultReportParam first = objectMapper.treeToValue(root.get("lines").get(0), InOutResultReportParam.class); if (first != null) { boolean inb = first.getInbound() == null || Boolean.TRUE.equals(first.getInbound()); copy.setSourceOrderNo(first.getOrderNo()) .setInboundFlag(inb ? 1 : 0) .setWareHouseCode(first.getWareHouseId()); } return; } InOutResultReportParam p = objectMapper.readValue(body, InOutResultReportParam.class); if (p != null) { boolean inb = p.getInbound() == null || Boolean.TRUE.equals(p.getInbound()); copy.setSourceOrderNo(p.getOrderNo()) .setInboundFlag(inb ? 1 : 0) .setWareHouseCode(p.getWareHouseId()); } } catch (Exception ignored) { } } private static boolean matchOrderType(String asnType, Boolean inbound) { if (StringUtils.isBlank(asnType)) { return true; } boolean wantIn = "in".equalsIgnoreCase(asnType.trim()); if (inbound == null) { return true; } return wantIn == inbound; } private static String lineSignature(InOutResultReportParam p) { return String.join("|", String.valueOf(p.getOrderNo()), String.valueOf(p.getLineId()), String.valueOf(p.getMatNr()), String.valueOf(p.getLocId()), String.valueOf(p.getWareHouseId()), String.valueOf(p.getInbound()), String.valueOf(p.getQty()), String.valueOf(p.getBatch())); } }