This commit is contained in:
2026-08-17 16:07:20 +08:00
parent 68d9216cb8
commit 75580c3585
9 changed files with 249 additions and 78 deletions
@@ -25,6 +25,10 @@ public class LoadingRepository {
return inbounds.find(tenantId, inboundId);
}
public LoadingInboundMapper.Snapshot findInboundForUpdate(long tenantId, long inboundId) {
return inbounds.findForUpdate(tenantId, inboundId);
}
public int completeLoading(long tenantId, long inboundId, long operatorId, int expectedVersion) {
return inbounds.completeLoading(tenantId, inboundId, operatorId, expectedVersion);
}
@@ -121,6 +121,24 @@ public class LoadingDeliveryService {
new LoadingActionResponse("LOADED", evidenceResponse(tenantId, inboundId)));
}
/**
* PDA settlement may increment the source version and may create a loaded fulfillment slice.
* Resolve and lock the canonical completion row after settlement, then retain optimistic locking
* with that current server version instead of reusing the pre-settlement task snapshot.
*/
public LoadingActionResponse completeAfterPdaSettlement(long tenantId, long inboundId,
long operatorId, String operatorName,
String key, String remark) {
CompletionTarget target = repository.completionTarget(tenantId, inboundId);
long completionInboundId = target == null ? inboundId : target.completionInboundId();
Snapshot current = repository.findInboundForUpdate(tenantId, completionInboundId);
if (current == null || current.version() == null) {
throw new BizException(ResultCode.CONFLICT, "PDA结算后的实装履约分片不存在,请刷新后重试");
}
return completeLoading(tenantId, inboundId, operatorId, operatorName, key,
new CompleteLoadingRequest(current.version(), remark));
}
/**
* Read-only preflight used before PDA settlement. The current plan may still be LOADING here;
* every external/business hard gate must pass before the PDA task is mutated.
@@ -33,7 +33,6 @@ import com.baiyue.firstleg.entity.LoadingPlanHistoryEntity;
import com.baiyue.firstleg.entity.InboundStatusHistoryEntity;
import com.baiyue.firstleg.loading.mapper.LoadingInboundMapper;
import com.baiyue.firstleg.loading.service.LoadingDeliveryService;
import com.baiyue.firstleg.loading.dto.LoadingRequests;
import com.baiyue.firstleg.loading.bridge.service.LoadingModelBridgeService;
import com.baiyue.firstleg.loading.bridge.dto.LoadingModelBridgeDtos.Link;
import com.baiyue.firstleg.mapper.InboundStatusHistoryMapper;
@@ -59,7 +58,6 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@@ -453,12 +451,10 @@ public class LoadingPickService {
.thenComparing(LoadingPickItemMapper.InboundOwner::inboundId))
.toList();
if (owners.isEmpty()) throw conflict("PDA任务未关联有效入库单");
Map<LoadingPickItemMapper.InboundOwner, LoadingInboundMapper.Snapshot> inboundSnapshots = new LinkedHashMap<>();
for (LoadingPickItemMapper.InboundOwner owner : owners) {
LoadingInboundMapper.Snapshot snapshot = repository.inboundForUpdate(owner.tenantId(), owner.inboundId());
if (snapshot == null) throw conflict("PDA任务关联入库单不存在");
loadingDeliveryService.requirePdaCompletionReady(owner.tenantId(), owner.inboundId());
inboundSnapshots.put(owner, snapshot);
}
truckAppointmentService.completeLoadingFromPda(task.getContainerBookingId(), taskId,
operatorId, operatorName);
@@ -472,12 +468,9 @@ public class LoadingPickService {
insertOperation(taskId, operationId, requestHash, "COMPLETE_LOADING", operatorId, operatorName);
loadingListService.finishFromPda(task.getLoadingPlanId(), taskId, operatorId, operatorName);
repository.syncInboundProjections(taskId, operatorId, operatorName);
for (Map.Entry<LoadingPickItemMapper.InboundOwner, LoadingInboundMapper.Snapshot> entry
: inboundSnapshots.entrySet()) {
LoadingPickItemMapper.InboundOwner owner = entry.getKey();
loadingDeliveryService.completeLoading(owner.tenantId(), owner.inboundId(), operatorId,
operatorName, "PDA-" + operationId + '-' + owner.inboundId(),
new LoadingRequests.CompleteLoadingRequest(entry.getValue().version(), remark));
for (LoadingPickItemMapper.InboundOwner owner : owners) {
loadingDeliveryService.completeAfterPdaSettlement(owner.tenantId(), owner.inboundId(), operatorId,
operatorName, "PDA-" + operationId + '-' + owner.inboundId(), remark);
}
return view(requiredTask(taskId), null);
}