| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | 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.enums.OrderType; |
| | | 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 java.util.*; |
| | | |
| | | /** |
| | | * 从历史云仓上报记录中取「最新一条」按明细维度去重后,复制请求体写入待发送队列。 |
| | | * 历史单触发云仓入出库上报:优先放行该单暂缓待办;若无则从历史云仓上报记录复制请求体入队。 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | |
| | | private ObjectMapper objectMapper; |
| | | |
| | | @Override |
| | | public R resendInOutFeedbackByAsnOrderLogId(Long asnOrderLogId) { |
| | | public R submitInOutCloudWmsByAsnOrderLogId(Long asnOrderLogId) { |
| | | if (asnOrderLogId == null) { |
| | | return R.error("参数不能为空"); |
| | | } |
| | |
| | | } |
| | | String code = orderLog.getCode(); |
| | | if (StringUtils.isBlank(code)) { |
| | | return R.error("单据号为空,无法重发"); |
| | | return R.error("单据号为空"); |
| | | } |
| | | boolean inbound = inboundFromOrderType(orderLog.getType()); |
| | | R flushR = cloudWmsNotifyLogService.manualFlushToNotifyByOrderCode(code.trim(), inbound); |
| | | Object flushCode = flushR.get("code"); |
| | | if (flushCode instanceof Number && ((Number) flushCode).intValue() == 200) { |
| | | return flushR; |
| | | } |
| | | return enqueueFromHistoricalNotifyLogs(asnOrderLogId, orderLog, code); |
| | | } |
| | | |
| | | private R enqueueFromHistoricalNotifyLogs(Long asnOrderLogId, AsnOrderLog orderLog, String code) { |
| | | String reportType = cloudWmsNotifyLogService.getReportTypeInOutResult(); |
| | | LambdaQueryWrapper<CloudWmsNotifyLog> qw = new LambdaQueryWrapper<CloudWmsNotifyLog>() |
| | | .eq(CloudWmsNotifyLog::getReportType, reportType) |
| | |
| | | if (StringUtils.isBlank(row.getRequestBody())) { |
| | | continue; |
| | | } |
| | | InOutResultReportParam p; |
| | | try { |
| | | p = objectMapper.readValue(row.getRequestBody(), InOutResultReportParam.class); |
| | | 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 (p == null || !code.equals(p.getOrderNo())) { |
| | | continue; |
| | | } |
| | | if (!matchOrderType(orderLog.getType(), p.getInbound())) { |
| | | continue; |
| | | } |
| | | String sig = lineSignature(p); |
| | | latestByLine.putIfAbsent(sig, row); |
| | | } |
| | | if (latestByLine.isEmpty()) { |
| | | return R.error("未找到该单号对应的云仓入出库上报记录,无法重发"); |
| | | return R.error("未找到该单号对应的云仓入出库上报记录"); |
| | | } |
| | | Date now = new Date(); |
| | | int n = 0; |
| | |
| | | .setRetryCount(0) |
| | | .setBizRef("manualResend,asnOrderLogId=" + asnOrderLogId + ",fromNotifyLogId=" + src.getId() + ",orderNo=" + code) |
| | | .setCreateTime(now) |
| | | .setUpdateTime(now); |
| | | cloudWmsNotifyLogService.fillFromConfig(copy); |
| | | if (cloudWmsNotifyLogService.save(copy)) { |
| | | .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()); |
| | | } |
| | | if (saveOrRefreshResendRow(copy, now)) { |
| | | n++; |
| | | } |
| | | } |
| | | return R.ok("已加入云仓重发队列 " + n + " 条,将由定时任务发送").add(n); |
| | | return R.ok("已加入云仓上报队列 " + n + " 条,将由定时任务发送").add(n); |
| | | } |
| | | |
| | | private static boolean inboundFromOrderType(String type) { |
| | | if (StringUtils.isBlank(type)) { |
| | | return true; |
| | | } |
| | | return OrderType.ORDER_IN.type.equalsIgnoreCase(type.trim()); |
| | | } |
| | | |
| | | /** |
| | | * 同请求体已有待发送或失败记录:更新为可自动调度;否则插入新待办。 |
| | | */ |
| | | private boolean saveOrRefreshResendRow(CloudWmsNotifyLog copy, Date now) { |
| | | int pending = cloudWmsNotifyLogService.getNotifyStatusPending(); |
| | | int fail = cloudWmsNotifyLogService.getNotifyStatusFail(); |
| | | LambdaQueryWrapper<CloudWmsNotifyLog> existQw = new LambdaQueryWrapper<CloudWmsNotifyLog>() |
| | | .eq(CloudWmsNotifyLog::getReportType, copy.getReportType()) |
| | | .eq(CloudWmsNotifyLog::getRequestBody, copy.getRequestBody()) |
| | | .in(CloudWmsNotifyLog::getNotifyStatus, pending, fail) |
| | | .orderByDesc(CloudWmsNotifyLog::getId) |
| | | .last("LIMIT 1"); |
| | | CloudWmsNotifyLog existing = cloudWmsNotifyLogService.getOne(existQw); |
| | | if (existing != null && existing.getId() != null) { |
| | | CloudWmsNotifyLog row = new CloudWmsNotifyLog().setId(existing.getId()); |
| | | cloudWmsNotifyLogService.fillFromConfig(row); |
| | | LambdaUpdateWrapper<CloudWmsNotifyLog> u = new LambdaUpdateWrapper<CloudWmsNotifyLog>() |
| | | .eq(CloudWmsNotifyLog::getId, existing.getId()) |
| | | .set(CloudWmsNotifyLog::getNotifyStatus, row.getNotifyStatus()) |
| | | .set(CloudWmsNotifyLog::getMaxRetryCount, row.getMaxRetryCount()) |
| | | .set(CloudWmsNotifyLog::getRetryIntervalSeconds, row.getRetryIntervalSeconds()) |
| | | .set(CloudWmsNotifyLog::getSendHold, 0) |
| | | .set(CloudWmsNotifyLog::getSending, 0) |
| | | .set(CloudWmsNotifyLog::getRetryCount, 0) |
| | | .set(CloudWmsNotifyLog::getBizRef, copy.getBizRef()) |
| | | .set(CloudWmsNotifyLog::getUpdateTime, now) |
| | | .set(CloudWmsNotifyLog::getLastNotifyTime, null) |
| | | .set(CloudWmsNotifyLog::getLastResponseBody, null); |
| | | if (StringUtils.isNotBlank(copy.getSourceOrderNo())) { |
| | | u.set(CloudWmsNotifyLog::getSourceOrderNo, copy.getSourceOrderNo()) |
| | | .set(CloudWmsNotifyLog::getInboundFlag, copy.getInboundFlag()) |
| | | .set(CloudWmsNotifyLog::getWareHouseCode, copy.getWareHouseCode()); |
| | | } |
| | | return cloudWmsNotifyLogService.update(u); |
| | | } |
| | | cloudWmsNotifyLogService.fillFromConfig(copy); |
| | | return cloudWmsNotifyLogService.save(copy); |
| | | } |
| | | |
| | | 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) { |