Merge remote-tracking branch 'origin/test' into dev

# Conflicts:
#	AGENTS.md
#	scripts/AGENTS.md
#	scripts/admin-test-env-modules/README.md
#	scripts/agents-index-contract.ps1
This commit is contained in:
2026-09-04 16:03:09 +08:00
8 changed files with 60 additions and 7 deletions
@@ -306,7 +306,8 @@ public class UnifiedOrderQueryService {
order.getCustomerId(), order.getCustomerName(),
order.getChannelCode(), order.getChannelName(), Boolean.TRUE.equals(order.getChannelChanged()), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(),
order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), inbound.id(), inbound.version(), inbound.inboundCode(),
order.getExpectedShipDate(), displayedPackageCount(order, cargo, inbound), null, inbound.locationCodes(),
order.getExpectedShipDate(), displayedPackageCount(order, cargo, inbound), null,
distinctLocationCodes(inbound.locationCodes()),
order.getEstimatedVolumeCbm(), volumeCbm(cargo),
inbound.actualGrossWeightKg(), inbound.actualVolumeCbm(),
order.getExpectedArrivalAt() != null ? order.getExpectedArrivalAt() : inbound.expectedArrivalAt(), inbound.feeReviewStatus(),
@@ -333,7 +334,7 @@ public class UnifiedOrderQueryService {
order != null && Boolean.TRUE.equals(order.getChannelChanged()), inbound.warehouseId(),
inbound.warehouseName(), inbound.deliveryWarehouseId(), inbound.deliveryWarehouseName(),
inbound.id(), inbound.version(), inbound.inboundCode(), null,
displayedPackageCount(order, cargo, inbound), null, inbound.locationCodes(),
displayedPackageCount(order, cargo, inbound), null, distinctLocationCodes(inbound.locationCodes()),
order == null ? null : order.getEstimatedVolumeCbm(), volumeCbm(cargo),
inbound.actualGrossWeightKg(), inbound.actualVolumeCbm(),
order != null && order.getExpectedArrivalAt() != null ? order.getExpectedArrivalAt() : inbound.expectedArrivalAt(), inbound.feeReviewStatus(), inbound.companyName(),
@@ -408,6 +409,13 @@ public class UnifiedOrderQueryService {
return values.isEmpty() ? null : String.join(", ", values);
}
private String distinctLocationCodes(String locationCodes) {
if (!StringUtils.hasText(locationCodes)) return null;
LinkedHashSet<String> values = new LinkedHashSet<>(List.of(
StringUtils.tokenizeToStringArray(locationCodes, ",,、")));
return values.isEmpty() ? null : String.join("、", values);
}
private Integer totalQuantity(CargoSummary cargo) {
return cargo == null ? null : cargo.totalQuantity();
}
@@ -752,7 +752,7 @@ components:
expectedShipDate: {type: string, format: date, nullable: true}
totalPackageCount: {type: integer, nullable: true, description: 无入仓事实时为当前订单有效货物箱数合计;存在入仓业务单元后为该单元履约总箱数,拆分后不以父单原始箱数覆盖}
recommendedPalletType: {type: string, nullable: true, description: 当前无列表级权威事实时返回 null,不得返回固定托盘类型}
locationCodes: {type: string, nullable: true}
locationCodes: {type: string, nullable: true, description: "库位编码汇总;按首次出现顺序去重并使用中文顿号分隔"}
estimatedVolumeCbm: {type: number, nullable: true, description: 平台运营填写的预估体积,不得与客户下单或实测体积混用}
expectedVolumeCbm: {type: number, nullable: true, description: Order 客户下单货物体积合计,不得与平台预估或实测体积混用}
actualGrossWeightKg: {type: number, nullable: true, description: 仅 Firstleg 实测毛重;无实测时返回 null}
@@ -487,7 +487,7 @@ class UnifiedOrderQueryServiceTest {
assertThat(row.inboundCode()).isEqualTo("RK-77");
assertThat(row.channelCode()).isEqualTo("MATSON");
assertThat(row.recommendedPalletType()).isNull();
assertThat(row.locationCodes()).isEqualTo("A0-01, B2-03");
assertThat(row.locationCodes()).isEqualTo("A0-01、B2-03");
assertThat(row.companyName()).isEqualTo("测试客户有限公司");
assertThat(row.businessType()).isEqualTo("SEA_LCL");
assertThat(row.totalPalletCount()).isEqualTo(2);
@@ -512,6 +512,19 @@ class UnifiedOrderQueryServiceTest {
assertThat(row.totalNetWeightKg()).isNull();
}
@Test
void unifiedRowDeduplicatesLocationCodesInFirstSeenOrder() {
UnifiedOrderQuery query = query("INBOUNDED");
var summary = summary("INBOUNDED", null);
when(summary.inbound().locationCodes()).thenReturn("A0、 A0, A0,A0");
when(firstleg.page(eq("internal-token"), any())).thenReturn(
ApiResponse.success(new PageResult<>(List.of(summary), 1, 20, 1, 1)));
var row = service.page(null, query).records().get(0);
assertThat(row.locationCodes()).isEqualTo("A0");
}
@Test
void waitSplitFilterForwardsAndReturnsWaitSplitIndependently() {
UnifiedOrderQuery query = query("WAIT_SPLIT");