优化
This commit is contained in:
+47
-3
@@ -7,6 +7,8 @@ import com.baiyue.lastleg.dropship.dto.DropshipRequests;
|
||||
import com.baiyue.lastleg.dropship.service.DropshipOrderService;
|
||||
import com.baiyue.lastleg.inboundplan.entity.InboundPlanCarton;
|
||||
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanCartonMapper;
|
||||
import com.baiyue.lastleg.inboundplan.pda.entity.ContainerLoadingEvidence;
|
||||
import com.baiyue.lastleg.inboundplan.pda.mapper.ContainerLoadingEvidenceMapper;
|
||||
import com.baiyue.lastleg.inventory.command.dto.InventoryCommandRequests;
|
||||
import com.baiyue.lastleg.inventory.command.service.InventoryCommandService;
|
||||
import com.baiyue.lastleg.shipping.entity.ContainerShippingGate;
|
||||
@@ -46,12 +48,13 @@ public class LoadingCompletedConsumer {
|
||||
@Resource private InventoryCommandService inventory;
|
||||
@Resource private ContainerShippingGateMapper shippingGates;
|
||||
@Resource private LastlegSourcePalletMapper sourcePallets;
|
||||
@Resource private ContainerLoadingEvidenceMapper loadingEvidence;
|
||||
|
||||
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||
public int consume(EventEnvelope envelope) {
|
||||
envelope.requireValid();
|
||||
if (!EventTypes.FIRST_LEG_LOADING_PLAN_COMPLETED.equals(envelope.eventType())
|
||||
|| (envelope.eventVersion() != 1 && envelope.eventVersion() != 2))
|
||||
|| (envelope.eventVersion() != 1 && envelope.eventVersion() != 2 && envelope.eventVersion() != 3))
|
||||
throw new IllegalArgumentException("不支持的尾程交接事件");
|
||||
if (envelope.sourceRegion() != RegionCode.CN || envelope.targetRegion() != RegionCode.OVERSEAS)
|
||||
throw new IllegalArgumentException("尾程交接事件区域无效");
|
||||
@@ -64,7 +67,7 @@ public class LoadingCompletedConsumer {
|
||||
String sourceContainerBookingId = sourceContainerBookingId(envelope, payload);
|
||||
if(payload.orders()==null||payload.orders().isEmpty()) throw new IllegalArgumentException("事件没有入仓单");
|
||||
OwnerSnapshot owner = requireOwnerSnapshot(payload.orders(), envelope.tenantId());
|
||||
if (envelope.eventVersion() == 2) validateCartonSkuMappings(payload, envelope.payload());
|
||||
if (envelope.eventVersion() >= 2) validateCartonSkuMappings(payload, envelope.payload());
|
||||
freezeContainerIdentity(envelope, sourceContainerBookingId, containerNo);
|
||||
LastlegEventInbox existing=inboxMapper.selectById(envelope.eventId());
|
||||
if(existing!=null) {
|
||||
@@ -85,6 +88,8 @@ public class LoadingCompletedConsumer {
|
||||
return countOrders(envelope,containerNo);
|
||||
}
|
||||
|
||||
projectLoadingEvidence(envelope, sourceContainerBookingId);
|
||||
|
||||
// The loading-plan and container-shipping events are independent aggregate streams.
|
||||
// Seeding the shipping version from the loading-plan version makes a valid first node
|
||||
// (aggregateVersion=0) look stale whenever the loading plan has a higher version.
|
||||
@@ -100,6 +105,45 @@ public class LoadingCompletedConsumer {
|
||||
return payload.orders().size();
|
||||
}
|
||||
|
||||
private void projectLoadingEvidence(EventEnvelope envelope, String sourceContainerBookingId) {
|
||||
if (envelope.eventVersion() < 3) return;
|
||||
JsonNode values = envelope.payload().path("loadingEvidence");
|
||||
if (!values.isArray() || values.size() != 5) {
|
||||
throw new IllegalArgumentException("V3 尾程交接事件必须包含五类国内装柜照片");
|
||||
}
|
||||
Set<String> expected = Set.of("PHOTO_STEP_1", "PHOTO_STEP_2", "PHOTO_STEP_3", "PHOTO_STEP_4", "SEAL");
|
||||
Set<String> actual = new HashSet<>();
|
||||
for (JsonNode value : values) {
|
||||
String type = value.path("evidenceType").asText("").trim();
|
||||
long fileId = value.path("fileId").asLong(0);
|
||||
String fileName = value.path("fileName").asText("").trim();
|
||||
if (!expected.contains(type) || !actual.add(type) || fileId <= 0
|
||||
|| fileName.isBlank() || fileName.length() > 255) {
|
||||
throw new IllegalArgumentException("V3 尾程交接事件的国内装柜照片引用无效");
|
||||
}
|
||||
ContainerLoadingEvidence existing = loadingEvidence.find(sourceContainerBookingId, type);
|
||||
if (existing != null) {
|
||||
if (!Objects.equals(existing.getSourceFileId(), fileId)
|
||||
|| !Objects.equals(existing.getFileName(), fileName)) {
|
||||
throw new IllegalStateException("同一来源柜的国内装柜照片快照冲突");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ContainerLoadingEvidence row = new ContainerLoadingEvidence();
|
||||
row.setId(IdWorker.getId());
|
||||
row.setSourceContainerBookingId(sourceContainerBookingId);
|
||||
row.setEvidenceType(type); row.setSourceFileId(fileId); row.setFileName(fileName);
|
||||
row.setCreatedAt(LocalDateTime.now());
|
||||
try { loadingEvidence.insert(row); }
|
||||
catch (DuplicateKeyException duplicate) {
|
||||
ContainerLoadingEvidence raced = loadingEvidence.find(sourceContainerBookingId, type);
|
||||
if (raced == null || !Objects.equals(raced.getSourceFileId(), fileId)
|
||||
|| !Objects.equals(raced.getFileName(), fileName)) throw duplicate;
|
||||
}
|
||||
}
|
||||
if (!actual.equals(expected)) throw new IllegalArgumentException("V3 尾程交接事件的国内装柜照片类型不完整");
|
||||
}
|
||||
|
||||
private FirstLegLoadingPlanCompletedV1 parsePayload(EventEnvelope envelope) {
|
||||
try {
|
||||
ObjectMapper compatibleMapper = objectMapper.copy()
|
||||
@@ -134,7 +178,7 @@ public class LoadingCompletedConsumer {
|
||||
}
|
||||
|
||||
private String sourceContainerBookingId(EventEnvelope envelope, FirstLegLoadingPlanCompletedV1 payload) {
|
||||
String value = envelope.eventVersion() == 2
|
||||
String value = envelope.eventVersion() >= 2
|
||||
? envelope.payload().path("sourceContainerBookingId").asText(null)
|
||||
: payload.containerBookingId();
|
||||
if (value == null || value.isBlank() || value.trim().length() > 128) {
|
||||
|
||||
Reference in New Issue
Block a user