cl
6 天以前 4abcc3dfc43c5c9c58bdaf8bd85df129467a60ed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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<CloudWmsNotifyLog> qw = new LambdaQueryWrapper<CloudWmsNotifyLog>()
                .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<CloudWmsNotifyLog> candidates = cloudWmsNotifyLogService.list(qw);
        Map<String, CloudWmsNotifyLog> 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()));
    }
}