feat(selfop): sync versioned owner and product directories

This commit is contained in:
2026-10-14 16:15:39 +08:00
parent 2b3b13913b
commit d311d9dc8d
47 changed files with 803 additions and 66 deletions
@@ -88,6 +88,24 @@ public class LingxingInternalController {
return ApiResponse.success(client.queryInventory(request, context(context)));
}
@PostMapping("/customers/query")
public ApiResponse<QueryPage<Customer>> customers(
@RequestHeader(value="X-Internal-Service-Token",required=false) String token,
@RequestHeader(value="X-Lingxing-Egress-Context",required=false) String context,
@Valid @RequestBody WarehouseQueryRequest request) {
tokenGuard.verify(token);
return ApiResponse.success(client.queryCustomers(request,context(context)));
}
@PostMapping("/products/query")
public ApiResponse<QueryPage<Product>> products(
@RequestHeader(value="X-Internal-Service-Token",required=false) String token,
@RequestHeader(value="X-Lingxing-Egress-Context",required=false) String context,
@Valid @RequestBody ProductQueryRequest request) {
tokenGuard.verify(token);
return ApiResponse.success(client.queryProducts(request,context(context)));
}
private EgressContext context(String header) {
if (header == null || header.isBlank() || header.length() > 2048 || !header.chars().allMatch(c -> c >= 32 && c <= 126))
throw invalidContext();
@@ -6,7 +6,7 @@ import java.time.Instant;
public final class LingxingEgressDtos {
private LingxingEgressDtos() { }
public enum CollectionMode { OFF, VALIDATION, BUSINESS }
public enum Operation { WAREHOUSES, OUTBOUND_QUERY, OUTBOUND_LOCATE, OUTBOUND_DETAIL, PRODUCT_INVENTORY }
public enum Operation { WAREHOUSES, OUTBOUND_QUERY, OUTBOUND_LOCATE, OUTBOUND_DETAIL, PRODUCT_INVENTORY, CUSTOMERS, PRODUCTS }
public record EgressContext(String sourceAccount, CollectionMode executionPurpose, String rootTaskId,
String sessionId, String attemptId, String exclusiveGrantId) {
public boolean wellFormed() {
@@ -19,6 +19,11 @@ public final class LingxingWmsDtos {
@Min(1) int current, @Min(1) @Max(100) int size) { }
public record WarehouseQueryRequest(@Min(1) int current, @Min(1) @Max(1000) int size) { }
public record ProductQueryRequest(@Min(1) int current, @Min(1) @Max(100) int size) { }
public record Customer(String customerCode, String customerName, String status) { }
public record Product(String customerCode, String sku, String productName,
BigDecimal length, BigDecimal width, BigDecimal height, String sizeUnit,
BigDecimal wmsLength, BigDecimal wmsWidth, BigDecimal wmsHeight, String wmsSizeUnit) { }
public record LocateRequest(@NotBlank @Size(max=128) String deliveryNo,
@Min(1) int current, @Min(1) @Max(1000) int size) { }
public record DetailRequest(@NotBlank @Size(max=64) String warehouseCode,
@@ -133,6 +133,24 @@ public final class LingxingWmsClient {
optionalText(data, "outboundTime"), lines, 200, clock.instant(), metadata);
}
public QueryPage<Customer> queryCustomers(WarehouseQueryRequest request, EgressContext context) {
if (request == null) throw badRequest();
validatePagination(request.current(), request.size(), 1000);
return execute("/openapi/v2/customer/list", pagination(request.current(), request.size()), context, Operation.CUSTOMERS,
(data, metadata) -> mappedPage(data, request.current(), request.size(), "current", "size", false, metadata,
row -> new Customer(requiredText(row,"customerCode",64), optionalText(row,"customerName"), optionalText(row,"status"))));
}
public QueryPage<Product> queryProducts(ProductQueryRequest request, EgressContext context) {
if (request == null) throw badRequest();
validatePagination(request.current(), request.size(), 100);
return execute("/openapi/v2/product/page", pagination(request.current(), request.size()), context, Operation.PRODUCTS,
(data, metadata) -> mappedPage(data, request.current(), request.size(), "current", "size", false, metadata,
row -> new Product(requiredText(row,"customerCode",64), requiredText(row,"sku",128), optionalText(row,"productName"),
quantity(row.get("length")),quantity(row.get("width")),quantity(row.get("height")),optionalText(row,"sizeUnit"),
quantity(row.get("wmsLength")),quantity(row.get("wmsWidth")),quantity(row.get("wmsHeight")),optionalText(row,"wmsSizeUnit"))));
}
public QueryPage<ProductStock> queryInventory(InventoryQueryRequest request, EgressContext context) {
if (request == null) throw badRequest();
requireInput(request.warehouseCode(), 64);