This commit is contained in:
2026-10-08 19:09:30 +08:00
parent 2c0f55d9b7
commit ed99ecba1c
17 changed files with 157 additions and 106 deletions
@@ -501,8 +501,6 @@ public class ReturnReceiptService {
public PdaReturnReceiptResponses.Confirmed confirm(PdaWarehouseIdentity identity, PdaReturnReceiptRequests.Confirm request) {
String key = text(request.idempotencyKey());
String requestHash = hash(request);
ReturnReceipt replay = receipts.findKey(identity.operatorKey(), key);
if (replay != null) return replayReceipt(replay, requestHash);
String startedBy = norm(request.startedBy());
if (!Set.of("RETURN_NO", "SKU").contains(startedBy)) throw badRequest("startedBy 必须为 RETURN_NO 或 SKU");
String trackingNo = text(request.trackingNo());
@@ -513,8 +511,8 @@ public class ReturnReceiptService {
if (order == null || !String.valueOf(identity.overseasWarehouseId()).equals(order.getOverseasWarehouseId())) {
throw notFound("当前绑定仓没有该退货单");
}
// Waiting for the order lock may allow the same request to commit. Use a
// current read, not the repeatable-read snapshot established by findKey.
// Lock the order before any consistent read: a snapshot opened before
// waiting would hide the winner's cartons when rendering replay labels.
ReturnReceipt concurrentReplay = receipts.lockKey(identity.operatorKey(), key);
if (concurrentReplay != null) {
if (!requestHash.equals(concurrentReplay.getRequestHash())) throw conflict("幂等键已用于不同的签收请求");