优化
This commit is contained in:
@@ -13,6 +13,7 @@ public final class UnifiedOrderResponse {
|
||||
|
||||
public record Row(
|
||||
Long orderId, Long tenantId, String orderNo, String mainStatus, String nextAction,
|
||||
OrderRelationSummary relation,
|
||||
OrderStatus internalOrderStatus,
|
||||
Long customerId, String customerName, String channelName,
|
||||
Long receivingWarehouseId, String receivingWarehouseName,
|
||||
@@ -26,6 +27,9 @@ public final class UnifiedOrderResponse {
|
||||
LocalDateTime createdAt, LocalDateTime updatedAt
|
||||
) {}
|
||||
|
||||
public record OrderRelationSummary(String role, Long rootOrderId, Long parentOrderId,
|
||||
Integer splitSequence, Integer childCount) {}
|
||||
|
||||
public record Detail(Row summary, OrderDetailResponse order,
|
||||
List<TimelineEvent> timeline) {}
|
||||
|
||||
|
||||
@@ -226,6 +226,16 @@ public class OrderRepository {
|
||||
.in(OrderEntity::getId, orderIds));
|
||||
}
|
||||
|
||||
public List<OrderEntity> findChildrenByParentOrders(List<OrderEntity> parentOrders) {
|
||||
if (parentOrders.isEmpty()) return List.of();
|
||||
List<Long> tenantIds = parentOrders.stream().map(OrderEntity::getTenantId).distinct().toList();
|
||||
List<Long> parentOrderIds = parentOrders.stream().map(OrderEntity::getId).distinct().toList();
|
||||
return orderMapper.selectList(new LambdaQueryWrapper<OrderEntity>()
|
||||
.select(OrderEntity::getId, OrderEntity::getTenantId, OrderEntity::getParentOrderId)
|
||||
.in(OrderEntity::getTenantId, tenantIds)
|
||||
.in(OrderEntity::getParentOrderId, parentOrderIds));
|
||||
}
|
||||
|
||||
public List<OrderInternalNoteEntity> findNotesByOrderIds(Long tenantId, List<Long> orderIds) {
|
||||
if (orderIds.isEmpty()) return List.of();
|
||||
return noteMapper.selectList(new LambdaQueryWrapper<OrderInternalNoteEntity>()
|
||||
|
||||
@@ -57,8 +57,9 @@ public class UnifiedOrderQueryService {
|
||||
? Map.of()
|
||||
: summaries(tenantId, source.records().stream().map(OrderEntity::getId).toList());
|
||||
Map<Long, String> latestNotes = latestNotes(tenantId, source.records().stream().map(OrderEntity::getId).toList());
|
||||
Map<Long, Integer> childCounts = childCounts(source.records());
|
||||
List<UnifiedOrderResponse.Row> rows = source.records().stream()
|
||||
.map(order -> row(order, inboundByOrder.get(order.getId()), latestNotes.get(order.getId()))).toList();
|
||||
.map(order -> row(order, inboundByOrder.get(order.getId()), latestNotes.get(order.getId()), childCounts)).toList();
|
||||
return new PageResult<>(rows, source.page(), source.size(), source.total(), source.pages());
|
||||
}
|
||||
|
||||
@@ -71,7 +72,8 @@ public class UnifiedOrderQueryService {
|
||||
FirstlegUnifiedOrderClient.Detail inbound = order.getStatus() == OrderStatus.SUBMITTED
|
||||
? null : firstlegDetail(tenantId, orderId);
|
||||
String latestNote = orderDetail.internalNotes().isEmpty() ? null : orderDetail.internalNotes().get(0).getContent();
|
||||
UnifiedOrderResponse.Row summary = row(order, inbound == null ? null : inbound.summary(), latestNote);
|
||||
UnifiedOrderResponse.Row summary = row(order, inbound == null ? null : inbound.summary(), latestNote,
|
||||
childCounts(List.of(order)));
|
||||
List<UnifiedOrderResponse.TimelineEvent> timeline = new ArrayList<>();
|
||||
orderDetail.statusHistory().forEach(item -> timeline.add(new UnifiedOrderResponse.TimelineEvent(
|
||||
"ORDER", "STATUS", orderMainStatus(item.getToStatus()), item.getAction(), item.getReason(),
|
||||
@@ -105,8 +107,10 @@ public class UnifiedOrderQueryService {
|
||||
Map<Long, OrderEntity> orderById = orders.findByIds(tenantId, orderIds).stream()
|
||||
.collect(Collectors.toMap(OrderEntity::getId, Function.identity(), (left, right) -> left));
|
||||
Map<Long, String> latestNotes = latestNotes(tenantId, orderIds);
|
||||
Map<Long, Integer> childCounts = childCounts(List.copyOf(orderById.values()));
|
||||
List<UnifiedOrderResponse.Row> records = source.records().stream()
|
||||
.map(summary -> row(summary, orderById.get(summary.inbound().orderId()), latestNotes.get(summary.inbound().orderId())))
|
||||
.map(summary -> row(summary, orderById.get(summary.inbound().orderId()),
|
||||
latestNotes.get(summary.inbound().orderId()), childCounts))
|
||||
.toList();
|
||||
return new PageResult<>(records, source.page(), source.size(), source.total(), source.pages());
|
||||
}
|
||||
@@ -131,11 +135,33 @@ public class UnifiedOrderQueryService {
|
||||
OrderInternalNoteEntity::getOrderId, OrderInternalNoteEntity::getContent, (latest, ignored) -> latest));
|
||||
}
|
||||
|
||||
private UnifiedOrderResponse.Row row(OrderEntity order, FirstlegUnifiedOrderClient.Summary summary, String latestInternalNote) {
|
||||
private Map<Long, Integer> childCounts(List<OrderEntity> pageOrders) {
|
||||
if (pageOrders.isEmpty()) return Map.of();
|
||||
return orders.findChildrenByParentOrders(pageOrders).stream()
|
||||
.filter(child -> child.getParentOrderId() != null)
|
||||
.collect(Collectors.toMap(OrderEntity::getParentOrderId, ignored -> 1, Integer::sum));
|
||||
}
|
||||
|
||||
private UnifiedOrderResponse.OrderRelationSummary relation(OrderEntity order,
|
||||
Map<Long, Integer> childCounts) {
|
||||
if (order == null) return null;
|
||||
if (order.getParentOrderId() != null) {
|
||||
Long rootOrderId = order.getRootOrderId() == null ? order.getParentOrderId() : order.getRootOrderId();
|
||||
return new UnifiedOrderResponse.OrderRelationSummary(
|
||||
"CHILD", rootOrderId, order.getParentOrderId(), order.getSplitSequence(), 0);
|
||||
}
|
||||
int childCount = childCounts.getOrDefault(order.getId(), 0);
|
||||
return childCount == 0 ? null : new UnifiedOrderResponse.OrderRelationSummary(
|
||||
"PARENT", order.getId(), null, null, childCount);
|
||||
}
|
||||
|
||||
private UnifiedOrderResponse.Row row(OrderEntity order, FirstlegUnifiedOrderClient.Summary summary,
|
||||
String latestInternalNote, Map<Long, Integer> childCounts) {
|
||||
if (summary == null) {
|
||||
String mainStatus = orderMainStatus(order.getStatus());
|
||||
return new UnifiedOrderResponse.Row(order.getId(), order.getTenantId(), order.getOrderNo(), mainStatus,
|
||||
order.getStatus() == OrderStatus.SUBMITTED ? "APPROVE_ORDER" : null,
|
||||
relation(order, childCounts),
|
||||
order.getStatus(), order.getCustomerId(), order.getCustomerName(),
|
||||
order.getChannelName(), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(),
|
||||
order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), null, null,
|
||||
@@ -146,7 +172,8 @@ public class UnifiedOrderQueryService {
|
||||
}
|
||||
FirstlegUnifiedOrderClient.Inbound inbound = summary.inbound();
|
||||
return new UnifiedOrderResponse.Row(order.getId(), order.getTenantId(), order.getOrderNo(),
|
||||
summary.mainStatus(), summary.nextAction(), order.getStatus(), order.getCustomerId(), order.getCustomerName(),
|
||||
summary.mainStatus(), summary.nextAction(), relation(order, childCounts), order.getStatus(),
|
||||
order.getCustomerId(), order.getCustomerName(),
|
||||
order.getChannelName(), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(),
|
||||
order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), inbound.id(), inbound.version(), inbound.inboundCode(),
|
||||
order.getExpectedShipDate(), inbound.totalPackageCount(), "STANDARD", inbound.locationCodes(),
|
||||
@@ -157,10 +184,11 @@ public class UnifiedOrderQueryService {
|
||||
}
|
||||
|
||||
private UnifiedOrderResponse.Row row(FirstlegUnifiedOrderClient.Summary summary, OrderEntity order,
|
||||
String latestInternalNote) {
|
||||
String latestInternalNote, Map<Long, Integer> childCounts) {
|
||||
var inbound = summary.inbound();
|
||||
return new UnifiedOrderResponse.Row(inbound.orderId(), inbound.tenantId(), inbound.orderNo(),
|
||||
summary.mainStatus(), summary.nextAction(), parseOrderStatus(inbound.orderStatusSnapshot()),
|
||||
summary.mainStatus(), summary.nextAction(), relation(order, childCounts),
|
||||
parseOrderStatus(inbound.orderStatusSnapshot()),
|
||||
inbound.customerId(), inbound.customerName(), inbound.channelName(), inbound.warehouseId(),
|
||||
inbound.warehouseName(), inbound.deliveryWarehouseId(), inbound.deliveryWarehouseName(),
|
||||
inbound.id(), inbound.version(), inbound.inboundCode(), null, inbound.totalPackageCount(),
|
||||
|
||||
@@ -16,7 +16,8 @@ paths:
|
||||
才是 C04 loading/complete 的 expectedVersion,loadingVersion 当前等于 pickingVersion(兼容别名)。
|
||||
tenantId 省略时跨全部客户;mainStatus 省略时按订单创建时间分页,指定 PENDING_REVIEW 时由 Order 查询,
|
||||
指定其他主状态时由 Firstleg 精确分页。旧 /orders/first-leg 接口保持兼容。
|
||||
列表行同时返回 customerRemark(客户下单备注)和 latestInternalNote(最新一条平台内部备注)。
|
||||
列表行同时返回 customerRemark(客户下单备注)、latestInternalNote(最新一条平台内部备注)和
|
||||
relation(仅有关联时返回;PARENT 含 childCount,CHILD 含 rootOrderId、parentOrderId 与 splitSequence)。
|
||||
parameters:
|
||||
- {name: tenantId, in: query, required: false, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- $ref: '#/components/parameters/UnifiedKeyword'
|
||||
|
||||
@@ -41,6 +41,7 @@ class UnifiedOrderQueryServiceTest {
|
||||
void stubListEnrichmentQueries() {
|
||||
when(orders.findNotesByOrderIds(any(), any())).thenReturn(List.of());
|
||||
when(orders.findByIds(any(), any())).thenReturn(List.of());
|
||||
when(orders.findChildrenByParentOrders(any())).thenReturn(List.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -67,6 +68,7 @@ class UnifiedOrderQueryServiceTest {
|
||||
assertThat(row.inboundId()).isNull();
|
||||
assertThat(row.customerRemark()).isEqualTo("客户要求提货前联系");
|
||||
assertThat(row.latestInternalNote()).isEqualTo("客服已确认提货时间");
|
||||
assertThat(row.relation()).isNull();
|
||||
});
|
||||
verify(firstleg, never()).summaries(any(), any());
|
||||
}
|
||||
@@ -87,6 +89,35 @@ class UnifiedOrderQueryServiceTest {
|
||||
verify(firstleg, never()).summaries(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addsRelationSummaryOnlyForOrdersWithParentChildAssociations() {
|
||||
UnifiedOrderQuery query = query("PENDING_REVIEW");
|
||||
OrderEntity parent = order(OrderStatus.SUBMITTED);
|
||||
OrderEntity child = order(OrderStatus.SUBMITTED);
|
||||
child.setId(78L);
|
||||
child.setOrderNo("FL-77-1");
|
||||
child.setOrderRole("CHILD");
|
||||
child.setParentOrderId(77L);
|
||||
child.setRootOrderId(77L);
|
||||
child.setSplitSequence(1);
|
||||
when(orders.unifiedPage(eq(10001L), eq(query), eq(List.of(OrderStatus.SUBMITTED))))
|
||||
.thenReturn(new PageResult<>(List.of(parent, child), 1, 20, 2, 1));
|
||||
when(orders.findChildrenByParentOrders(List.of(parent, child))).thenReturn(List.of(child));
|
||||
|
||||
var result = service.page(10001L, query);
|
||||
|
||||
assertThat(result.records()).satisfiesExactly(
|
||||
row -> assertThat(row.relation()).satisfies(relation -> {
|
||||
assertThat(relation.role()).isEqualTo("PARENT");
|
||||
assertThat(relation.childCount()).isEqualTo(1);
|
||||
}),
|
||||
row -> assertThat(row.relation()).satisfies(relation -> {
|
||||
assertThat(relation.role()).isEqualTo("CHILD");
|
||||
assertThat(relation.rootOrderId()).isEqualTo(77L);
|
||||
assertThat(relation.splitSequence()).isEqualTo(1);
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
void allStatusInboundCodeFilterIncludesPendingOrdersFromOrderQuery() {
|
||||
UnifiedOrderQuery query = new UnifiedOrderQuery(
|
||||
|
||||
Reference in New Issue
Block a user