优化
This commit is contained in:
@@ -4,7 +4,9 @@ import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/** Order service internal query for the product-level order line. */
|
||||
public record UnifiedInboundQuery(
|
||||
@@ -15,6 +17,18 @@ public record UnifiedInboundQuery(
|
||||
Long customerId,
|
||||
Long receivingWarehouseId,
|
||||
Long destinationWarehouseId,
|
||||
@Size(max = 64) String inboundCode,
|
||||
@Size(max = 32) String internalOrderStatus,
|
||||
LocalDate expectedArrivalDate,
|
||||
@Size(max = 32) String feeReviewStatus,
|
||||
@Size(max = 128) String channelName,
|
||||
@Size(max = 64) String containerNo,
|
||||
@Size(max = 64) String cabinetNo,
|
||||
LocalDate sailingDate,
|
||||
Boolean loaded,
|
||||
Boolean fullContainer,
|
||||
@Size(max = 32) String measurementReviewStatus,
|
||||
List<Long> candidateOrderIds,
|
||||
LocalDateTime createdFrom,
|
||||
LocalDateTime createdTo,
|
||||
@Min(1) long page,
|
||||
|
||||
@@ -110,6 +110,9 @@ public class InboundOrderRepository {
|
||||
.eq(query.tenantId() != null, InboundOrderEntity::getTenantId, query.tenantId())
|
||||
.in(processStatuses != null && !processStatuses.isEmpty(), InboundOrderEntity::getProcessStatus, processStatuses)
|
||||
.like(StringUtils.hasText(query.orderNo()), InboundOrderEntity::getOrderNo, query.orderNo())
|
||||
.like(StringUtils.hasText(query.inboundCode()), InboundOrderEntity::getInboundCode, query.inboundCode())
|
||||
.eq(StringUtils.hasText(query.internalOrderStatus()), InboundOrderEntity::getOrderStatusSnapshot,
|
||||
query.internalOrderStatus())
|
||||
.and(StringUtils.hasText(query.keyword()), nested -> nested
|
||||
.like(InboundOrderEntity::getOrderNo, query.keyword())
|
||||
.or().like(InboundOrderEntity::getInboundCode, query.keyword())
|
||||
@@ -117,6 +120,57 @@ public class InboundOrderRepository {
|
||||
.eq(query.customerId() != null, InboundOrderEntity::getCustomerId, query.customerId())
|
||||
.eq(query.receivingWarehouseId() != null, InboundOrderEntity::getWarehouseId, query.receivingWarehouseId())
|
||||
.eq(query.destinationWarehouseId() != null, InboundOrderEntity::getDeliveryWarehouseId, query.destinationWarehouseId())
|
||||
.ge(query.expectedArrivalDate() != null, InboundOrderEntity::getExpectedArrivalAt,
|
||||
query.expectedArrivalDate() == null ? null : query.expectedArrivalDate().atStartOfDay())
|
||||
.lt(query.expectedArrivalDate() != null, InboundOrderEntity::getExpectedArrivalAt,
|
||||
query.expectedArrivalDate() == null ? null : query.expectedArrivalDate().plusDays(1).atStartOfDay())
|
||||
.eq(StringUtils.hasText(query.channelName()), InboundOrderEntity::getChannelName, query.channelName())
|
||||
.eq(query.fullContainer() != null, InboundOrderEntity::getContainerMode,
|
||||
query.fullContainer() == null ? null : query.fullContainer() ? "FULL_CONTAINER" : "LCL")
|
||||
.and("UNRECORDED".equals(query.measurementReviewStatus()), nested -> nested
|
||||
.isNull(InboundOrderEntity::getMeasureReviewStatus)
|
||||
.or().eq(InboundOrderEntity::getMeasureReviewStatus, ""))
|
||||
.eq(StringUtils.hasText(query.measurementReviewStatus())
|
||||
&& !"UNRECORDED".equals(query.measurementReviewStatus()),
|
||||
InboundOrderEntity::getMeasureReviewStatus, query.measurementReviewStatus())
|
||||
.in(query.candidateOrderIds() != null && !query.candidateOrderIds().isEmpty(),
|
||||
InboundOrderEntity::getOrderId,
|
||||
query.candidateOrderIds() == null ? List.of() : query.candidateOrderIds())
|
||||
.apply("UNRECORDED".equals(query.feeReviewStatus()),
|
||||
"NOT EXISTS (SELECT 1 FROM fl_inbound_fee f WHERE f.tenant_id = fl_inbound_order.tenant_id "
|
||||
+ "AND f.inbound_id = fl_inbound_order.id)")
|
||||
.apply(StringUtils.hasText(query.feeReviewStatus()) && !"UNRECORDED".equals(query.feeReviewStatus()),
|
||||
"EXISTS (SELECT 1 FROM fl_inbound_fee f WHERE f.tenant_id = fl_inbound_order.tenant_id "
|
||||
+ "AND f.inbound_id = fl_inbound_order.id AND f.review_status = {0} "
|
||||
+ "AND NOT EXISTS (SELECT 1 FROM fl_inbound_fee newer "
|
||||
+ "WHERE newer.tenant_id = f.tenant_id AND newer.inbound_id = f.inbound_id "
|
||||
+ "AND (newer.fee_version > f.fee_version "
|
||||
+ "OR (newer.fee_version = f.fee_version AND newer.id > f.id))))",
|
||||
query.feeReviewStatus())
|
||||
.apply(StringUtils.hasText(query.containerNo()),
|
||||
"EXISTS (SELECT 1 FROM fl_inbound_transport_snapshot t "
|
||||
+ "WHERE t.tenant_id = fl_inbound_order.tenant_id AND t.inbound_id = fl_inbound_order.id "
|
||||
+ "AND t.container_no LIKE CONCAT('%', {0}, '%'))", query.containerNo())
|
||||
.apply(StringUtils.hasText(query.cabinetNo()),
|
||||
"EXISTS (SELECT 1 FROM fl_inbound_transport_snapshot t "
|
||||
+ "WHERE t.tenant_id = fl_inbound_order.tenant_id AND t.inbound_id = fl_inbound_order.id "
|
||||
+ "AND t.cabinet_no LIKE CONCAT('%', {0}, '%'))", query.cabinetNo())
|
||||
.apply(query.sailingDate() != null,
|
||||
"EXISTS (SELECT 1 FROM fl_inbound_transport_snapshot t "
|
||||
+ "WHERE t.tenant_id = fl_inbound_order.tenant_id AND t.inbound_id = fl_inbound_order.id "
|
||||
+ "AND t.sailing_at >= {0} AND t.sailing_at < {1})",
|
||||
query.sailingDate() == null ? null : query.sailingDate().atStartOfDay(),
|
||||
query.sailingDate() == null ? null : query.sailingDate().plusDays(1).atStartOfDay())
|
||||
.apply(Boolean.TRUE.equals(query.loaded()),
|
||||
"EXISTS (SELECT 1 FROM fl_inbound_transport_snapshot t "
|
||||
+ "WHERE t.tenant_id = fl_inbound_order.tenant_id AND t.inbound_id = fl_inbound_order.id "
|
||||
+ "AND COALESCE(TRIM(t.loading_status), '') <> '' "
|
||||
+ "AND t.loading_status NOT IN ('UNLOADED', 'PENDING'))")
|
||||
.apply(Boolean.FALSE.equals(query.loaded()),
|
||||
"NOT EXISTS (SELECT 1 FROM fl_inbound_transport_snapshot t "
|
||||
+ "WHERE t.tenant_id = fl_inbound_order.tenant_id AND t.inbound_id = fl_inbound_order.id "
|
||||
+ "AND COALESCE(TRIM(t.loading_status), '') <> '' "
|
||||
+ "AND t.loading_status NOT IN ('UNLOADED', 'PENDING'))")
|
||||
.ge(query.createdFrom() != null, InboundOrderEntity::getCreatedAt, query.createdFrom())
|
||||
.le(query.createdTo() != null, InboundOrderEntity::getCreatedAt, query.createdTo())
|
||||
.orderByDesc(InboundOrderEntity::getCreatedAt).orderByDesc(InboundOrderEntity::getId);
|
||||
|
||||
@@ -36,7 +36,8 @@ public class UnifiedInboundQueryService {
|
||||
|
||||
public PageResult<UnifiedInboundSummary> page(UnifiedInboundQuery query) {
|
||||
validate(query);
|
||||
if ("PENDING_REVIEW".equals(query.mainStatus())) {
|
||||
if ("PENDING_REVIEW".equals(query.mainStatus())
|
||||
|| query.candidateOrderIds() != null && query.candidateOrderIds().isEmpty()) {
|
||||
return new PageResult<>(List.of(), query.page(), query.size(), 0, 0);
|
||||
}
|
||||
Page<InboundOrderEntity> source = inbounds.pageUnifiedEntities(query, internalStatuses(query.mainStatus()));
|
||||
|
||||
+3
-1
@@ -53,7 +53,9 @@ class InternalInboundOrderReferenceControllerTest {
|
||||
@Test
|
||||
void unifiedQueryRequiresInternalTokenAndForwardsBatchRequest() {
|
||||
UnifiedInboundQuery request = new UnifiedInboundQuery(
|
||||
10001L, null, null, "WAIT_SPLIT", null, null, null, null, null, 1, 20);
|
||||
10001L, null, null, "WAIT_SPLIT", null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, 1, 20);
|
||||
when(unifiedQueryService.page(request)).thenReturn(new PageResult<>(List.of(), 1, 20, 0, 0));
|
||||
|
||||
assertThat(controller.unifiedPage("internal-token", request).data().records()).isEmpty();
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baiyue.firstleg.dto.InboundOrderQuery;
|
||||
import com.baiyue.firstleg.dto.UnifiedInboundQuery;
|
||||
import com.baiyue.firstleg.entity.InboundOrderEntity;
|
||||
import com.baiyue.firstleg.entity.InboundPalletAllocationEntity;
|
||||
import com.baiyue.firstleg.entity.InboundTransportSnapshotEntity;
|
||||
@@ -29,6 +30,9 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
@SpringJUnitConfig(InboundOrderRepository.class)
|
||||
class InboundOrderRepositoryTest {
|
||||
@MockBean private InboundOrderMapper orders;
|
||||
@@ -38,6 +42,34 @@ class InboundOrderRepositoryTest {
|
||||
@MockBean private InboundInternalNoteMapper notes;
|
||||
@MockBean private InboundStatusHistoryMapper histories;
|
||||
@Resource private InboundOrderRepository repository;
|
||||
@Test
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
void unifiedQueryPushesExpandedFiltersIntoDatabasePage() {
|
||||
TableInfoHelper.initTableInfo(
|
||||
new MapperBuilderAssistant(new MybatisConfiguration(), "test"), InboundOrderEntity.class);
|
||||
when(orders.selectPage(any(Page.class), any(Wrapper.class)))
|
||||
.thenReturn(new Page<InboundOrderEntity>(1, 20));
|
||||
UnifiedInboundQuery query = new UnifiedInboundQuery(
|
||||
10001L, null, null, "LOADING", 30001L, 40001L, 50001L,
|
||||
"RK-", "APPROVED", LocalDate.of(2026, 8, 6), "APPROVED", "美森",
|
||||
"MSCU", "CAB", LocalDate.of(2026, 8, 8), true, true, "UNRECORDED",
|
||||
List.of(77L, 78L), null, null, 1, 20);
|
||||
|
||||
repository.pageUnifiedEntities(query, List.of("LOADING"));
|
||||
|
||||
ArgumentCaptor<Wrapper<InboundOrderEntity>> captor = ArgumentCaptor.forClass(Wrapper.class);
|
||||
verify(orders).selectPage(any(Page.class), captor.capture());
|
||||
String sql = captor.getValue().getCustomSqlSegment();
|
||||
assertThat(sql).contains("inbound_code", "order_status_snapshot", "expected_arrival_at",
|
||||
"channel_name", "container_mode", "measure_review_status", "order_id IN",
|
||||
"fl_inbound_fee", "fl_inbound_transport_snapshot", "sailing_at", "loading_status");
|
||||
LambdaQueryWrapper<InboundOrderEntity> wrapper =
|
||||
(LambdaQueryWrapper<InboundOrderEntity>) captor.getValue();
|
||||
assertThat(wrapper.getParamNameValuePairs().values())
|
||||
.contains(10001L, 30001L, 40001L, 50001L, "%RK-%", "APPROVED", "美森",
|
||||
"MSCU", "CAB", 77L, 78L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
void shouldApplyTenantCompanyAndWarehouseFilters() {
|
||||
|
||||
Reference in New Issue
Block a user