feat: complete overseas pda warehouse operations

This commit is contained in:
2026-08-25 11:20:36 +08:00
parent 45a3b9adfd
commit 042d0b738a
69 changed files with 4679 additions and 4 deletions
@@ -0,0 +1,75 @@
package com.baiyue.lastleg.palletops.gateway;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;
import java.util.LinkedHashMap;
import java.util.Map;
@Component
public class HttpPalletPhysicalGateway implements PalletPhysicalGateway {
@Resource private RestClient.Builder restClientBuilder;
@Value("${baiyue.warehouse.base-url:http://127.0.0.1:9305}") private String baseUrl;
@Value("${baiyue.security.internal-service-token:}") private String internalToken;
private RestClient client;
@PostConstruct void initialize() { client = restClientBuilder.baseUrl(baseUrl).build(); }
@Override
public PalletReference resolve(String palletCode) {
ResolveEnvelope response = client.get().uri("/internal/v1/warehouse-pallets/resolve/{code}", palletCode)
.header("X-Internal-Service-Token", internalToken).retrieve()
.onStatus(HttpStatusCode::isError, (request, result) -> {
throw new IllegalArgumentException("Warehouse rejected pallet scan: HTTP " + result.getStatusCode());
}).body(ResolveEnvelope.class);
if (response == null || response.data() == null) throw new IllegalStateException("Warehouse returned no pallet");
return response.data();
}
@Override
public LocationReference resolveLocation(long warehouseId, long locationId) {
LocationEnvelope response = client.get().uri(uri -> uri
.path("/internal/v1/warehouse-resource-locks/locations/{locationId}")
.queryParam("warehouseId", warehouseId).build(locationId))
.header("X-Internal-Service-Token", internalToken).retrieve()
.onStatus(HttpStatusCode::isError, (request, result) -> {
throw new IllegalArgumentException("Warehouse rejected location lookup: HTTP " + result.getStatusCode());
}).body(LocationEnvelope.class);
if (response == null || response.data() == null) throw new IllegalStateException("Warehouse returned no location");
return response.data();
}
@Override
public Transition apply(long warehouseId, PalletReference pallet, String targetStatus, long targetLocationId,
String operationKey, String reason) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("warehouseId", warehouseId); body.put("expectedVersion", pallet.version());
body.put("targetStatus", targetStatus); body.put("targetLocationId", targetLocationId);
body.put("operationKey", operationKey); if (reason != null) body.put("reason", reason);
TransitionEnvelope response = client.post().uri("/internal/v1/pda-pallet-transitions/{id}", pallet.palletId())
.header("X-Internal-Service-Token", internalToken).body(body).retrieve()
.onStatus(HttpStatusCode::isError, (request, result) -> {
throw new IllegalStateException("Warehouse rejected pallet transition: HTTP " + result.getStatusCode());
}).body(TransitionEnvelope.class);
if (response == null || response.data() == null) throw new IllegalStateException("Warehouse returned no transition");
return response.data();
}
@Override
public void compensate(long warehouseId, Transition transition) {
client.post().uri("/internal/v1/pda-pallet-transitions/{id}/{key}/compensate",
transition.palletId(), transition.operationKey())
.header("X-Internal-Service-Token", internalToken).body(Map.of("warehouseId", warehouseId))
.retrieve().onStatus(HttpStatusCode::isError, (request, result) -> {
throw new IllegalStateException("Warehouse rejected pallet compensation: HTTP " + result.getStatusCode());
}).toBodilessEntity();
}
private record ResolveEnvelope(PalletReference data) { }
private record LocationEnvelope(LocationReference data) { }
private record TransitionEnvelope(Transition data) { }
}
@@ -0,0 +1,16 @@
package com.baiyue.lastleg.palletops.gateway;
public interface PalletPhysicalGateway {
PalletReference resolve(String palletCode);
LocationReference resolveLocation(long warehouseId, long locationId);
Transition apply(long warehouseId, PalletReference pallet, String targetStatus, long targetLocationId,
String operationKey, String reason);
void compensate(long warehouseId, Transition transition);
record PalletReference(long palletId, String palletCode, long warehouseId, long locationId,
String status, String fbaWarehouseCode, int version) { }
record LocationReference(long locationId, String locationCode, String locationType, String status) { }
record Transition(String operationKey, long palletId, String palletCode, long warehouseId,
String beforeStatus, String afterStatus, long beforeLocationId, long afterLocationId,
int beforeVersion, int afterVersion, String operationStatus, boolean replayed) { }
}