This commit is contained in:
2026-09-15 13:36:58 +08:00
parent 1bb69698de
commit f9649c44e9
44 changed files with 647 additions and 63 deletions
@@ -10,6 +10,7 @@ import com.baiyue.common.event.EventPayloadCanonicalizer;
import com.baiyue.common.event.EventPayloadHash;
import com.baiyue.common.event.EventTypes;
import com.baiyue.common.event.FirstLegLoadingPlanCompletedV2;
import com.baiyue.common.event.FirstLegLoadingPlanCompletedV3;
import com.baiyue.common.event.RegionCode;
import com.baiyue.firstleg.entity.InboundOutboxEntity;
import com.baiyue.firstleg.mapper.InboundOutboxMapper;
@@ -19,6 +20,7 @@ import com.baiyue.firstleg.mapper.LoadingCompletedEventMapper.PalletRow;
import com.baiyue.firstleg.mapper.LoadingCartonManifestMapper;
import com.baiyue.firstleg.mapper.LoadingPalletLabelMapper;
import com.baiyue.firstleg.mapper.LoadingCartonManifestMapper.LabelRow;
import com.baiyue.firstleg.loading.mapper.CabinetLoadingEvidenceMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -42,11 +44,12 @@ import java.util.Set;
/** 在装柜完成事务内按客户及可信客户名称快照写跨区业务 Outbox。 */
@Service
public class LoadingCompletedOutboxService {
private static final long HANDOVER_VERSION = 2L;
private static final long HANDOVER_VERSION = 3L;
@Resource private LoadingCompletedEventMapper snapshotMapper;
@Resource private LoadingCartonManifestMapper cartonManifestMapper;
@Resource private LoadingPalletLabelMapper palletLabelMapper;
@Resource private LoadingPalletLabelService palletLabelService;
@Resource private CabinetLoadingEvidenceMapper cabinetEvidenceMapper;
@Resource private InboundOutboxMapper outboxMapper;
@Resource private ObjectMapper objectMapper;
@@ -110,21 +113,42 @@ public class LoadingCompletedOutboxService {
.filter(item -> Objects.equals(item.getSourceInboundId(), value.get(0).getSourceInboundId())).toList(),
standardLabels.stream().filter(item -> Objects.equals(item.getInboundId(), value.get(0).getSourceInboundId())).toList(),
cartonMarks, palletManifests)).toList();
var payload = new FirstLegLoadingPlanCompletedV2(String.valueOf(first.getLoadingPlanId()),
var payload = new FirstLegLoadingPlanCompletedV3(String.valueOf(first.getLoadingPlanId()),
first.getPlanNo(), string(first.getContainerBookingId()),
ContainerNumbers.requireCanonical(first.getContainerNo()), first.getCabinetNo(),
string(first.getWarehouseId()), first.getWarehouseName(), iso(first.getEstimatedPortArrivalAt()),
iso(first.getActualPortArrivalAt()), iso(first.getEstimatedWarehouseArrivalAt()), orders);
iso(first.getActualPortArrivalAt()), iso(first.getEstimatedWarehouseArrivalAt()), orders,
loadingEvidence(first.getContainerBookingId()));
JsonNode payloadNode = objectMapper.valueToTree(payload);
String hash = EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(payloadNode));
String eventKey = "FIRSTLEG_LOADING_COMPLETED:" + first.getLoadingPlanId() + ':' + accountId + ':' + HANDOVER_VERSION;
String traceId = EventIdentifiers.newUuid();
return new EventEnvelope(EventIdentifiers.newUuid(), EventTypes.FIRST_LEG_LOADING_PLAN_COMPLETED, 2,
return new EventEnvelope(EventIdentifiers.newUuid(), EventTypes.FIRST_LEG_LOADING_PLAN_COMPLETED, 3,
Instant.now(), RegionCode.CN, RegionCode.OVERSEAS, String.valueOf(accountId), "LOADING_PLAN",
String.valueOf(first.getLoadingPlanId()), first.getAggregateVersion(), HANDOVER_VERSION,
traceId, eventKey, null, payloadNode, hash).requireValid();
}
private List<FirstLegLoadingPlanCompletedV3.LoadingEvidence> loadingEvidence(Long containerBookingId) {
if (containerBookingId == null || containerBookingId <= 0) {
throw new BizException(ResultCode.CONFLICT, "装柜计划缺少柜次,不能冻结装柜照片");
}
List<FirstLegLoadingPlanCompletedV3.LoadingEvidence> result = cabinetEvidenceMapper
.byContainer(containerBookingId).stream()
.filter(value -> Integer.valueOf(1).equals(value.getActiveFlag()) && "ACTIVE".equals(value.getStatus()))
.map(value -> new FirstLegLoadingPlanCompletedV3.LoadingEvidence(
value.getEvidenceType(), value.getFileId(), value.getFileName()))
.sorted(Comparator.comparing(FirstLegLoadingPlanCompletedV3.LoadingEvidence::evidenceType))
.toList();
Set<String> types = result.stream().map(FirstLegLoadingPlanCompletedV3.LoadingEvidence::evidenceType)
.collect(java.util.stream.Collectors.toSet());
if (result.size() != 5 || !types.equals(Set.of(
"PHOTO_STEP_1", "PHOTO_STEP_2", "PHOTO_STEP_3", "PHOTO_STEP_4", "SEAL"))) {
throw new BizException(ResultCode.CONFLICT, "国内装柜五类照片不完整,不能生成尾程交接事件");
}
return result;
}
private FirstLegLoadingPlanCompletedV2.Order order(List<Row> values, List<PalletRow> palletRows,
List<com.baiyue.firstleg.mapper.LoadingPalletLabelMapper.LabelRow> standardLabels,
Map<Long, List<String>> cartonMarks,