Просмотр исходного кода

提交630物流订单app输入代理的问题过滤相关逻辑

chenxiaofei 2 недель назад
Родитель
Сommit
7d8e8230ed

+ 5 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/QueryLogisticsOrderReq.java

@@ -37,6 +37,11 @@ public class QueryLogisticsOrderReq extends PageReq implements Serializable {
 
     @Schema(description = "贸易订单号")
     private String tradeOrderNo;
+    /**
+     * 关键字段查询:支持物流订单编号、商品名称、代理关键字。
+     */
+    @Schema(description = "关键字段查询:支持物流订单编号、商品名称、代理关键字")
+    private String keywords;
     /**
      * 商品名称
      */

+ 12 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderRepository.java

@@ -74,6 +74,18 @@ public class KwtLogisticsOrderRepository extends ServiceImpl<KwtLogisticsOrderMa
                 .last("limit 1"));
     }
 
+    /**
+     * 根据物流订单编号模糊查询物流订单列表。
+     *
+     * @param logisticsOrderNo 物流订单编号关键字
+     * @return 物流订单列表
+     */
+    public List<KwtLogisticsOrder> queryListByLogisticsOrderNo(String logisticsOrderNo) {
+        return list(Wrappers.<KwtLogisticsOrder>lambdaQuery()
+                .eq(KwtLogisticsOrder::getDelFlag, 0)
+                .like(StringUtils.isNotBlank(logisticsOrderNo), KwtLogisticsOrder::getLOrderNo, logisticsOrderNo));
+    }
+
     public List<KwtLogisticsOrder> queryByLogisticsOrderIds(List<Long> logisOrderIds) {
         return list(Wrappers.<KwtLogisticsOrder>lambdaQuery()
                 .eq(KwtLogisticsOrder::getDelFlag,0)

+ 137 - 2
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java

@@ -2352,7 +2352,7 @@ public class KwtLogisticsConsignmentService {
      */
     private boolean shouldReturnEmptyResult(Set<Long> logOrderIds, Set<Long> entList, QueryLogisticsOrderReq req) {
         return CollectionUtils.isEmpty(logOrderIds) &&
-                (!org.apache.commons.lang3.StringUtils.isAllBlank(req.getContractId(), req.getGoodsName(), req.getConsignCompanyId(), req.getCarriageCompanyId())
+                (!org.apache.commons.lang3.StringUtils.isAllBlank(req.getContractId(), req.getGoodsName(), req.getConsignCompanyId(), req.getCarriageCompanyId(), req.getKeywords())
                         || org.apache.commons.collections4.CollectionUtils.isNotEmpty(entList));
     }
 
@@ -3146,6 +3146,7 @@ public class KwtLogisticsConsignmentService {
 
     @NotNull
     private Set<Long> getLogOrderIds(QueryLogisticsOrderReq req, Set<Long> entList, Long allEnt) {
+        applyAgentKeywordCondition(req);
         Set<Long> logOrderIds = Sets.newHashSet();
         if (Objects.nonNull(allEnt)) {
             entList.add(allEnt);
@@ -3237,7 +3238,141 @@ public class KwtLogisticsConsignmentService {
             }
         }
 
-        return logOrderIds;
+        // 判断是否存在限制物流订单ID范围的条件(如企业列表、合同ID、商品名称)
+        // 如果存在这些条件,后续的关键字搜索必须与这些条件的结果取交集(AND关系)
+        boolean hasLogOrderIdRestrictedCondition = org.apache.commons.collections4.CollectionUtils.isNotEmpty(entList)
+                || StringUtils.isNotBlank(req.getContractId())
+                || StringUtils.isNotBlank(req.getGoodsName());
+        
+        log.debug("关键字过滤前置检查: hasLogOrderIdRestrictedCondition={}, 当前logOrderIds大小={}", 
+                hasLogOrderIdRestrictedCondition, logOrderIds.size());
+                
+        return applyKeywordFilterToLogOrderIds(req, logOrderIds, hasLogOrderIdRestrictedCondition);
+    }
+
+    /**
+     * 处理物流订单关键字段中的代理关键字。
+     * 业务规则:当keywords包含“代理”时,将其转换为代理属性过滤(agentFlag=1),并清空keywords。
+     * 原因:物流订单编号、商品名称等字段不存储“代理”语义,若继续参与模糊匹配会导致代理订单被错误过滤或漏选。
+     *
+     * @param req 物流订单分页查询请求
+     */
+    static void applyAgentKeywordCondition(QueryLogisticsOrderReq req) {
+        if (Objects.isNull(req)
+                || org.apache.commons.lang3.StringUtils.isBlank(req.getKeywords())
+                || !req.getKeywords().contains("代理")) {
+            return;
+        }
+        log.info("检测到关键字包含'代理',转换为代理标识过滤。原关键字: {}", req.getKeywords());
+        req.setAgentFlag(Global.YES);
+        req.setKeywords(null);
+    }
+
+    /**
+     * 根据关键字段过滤物流订单ID。
+     * 逻辑说明:
+     * 1. 关键字段支持物流订单编号和商品名称,这两类条件之间为 OR 关系。
+     * 2. 关键字搜索结果与原有筛选条件(企业、合同、商品等)之间为 AND 关系。
+     *
+     * @param req                         物流订单分页查询请求
+     * @param logOrderIds                 已经由原有条件筛选出的物流订单ID集合
+     * @param hasLogOrderIdRestrictedCondition 是否已经存在物流订单ID范围限制(即是否有其他AND条件)
+     * @return 过滤后的物流订单ID集合
+     */
+    private Set<Long> applyKeywordFilterToLogOrderIds(QueryLogisticsOrderReq req,
+                                                       Set<Long> logOrderIds,
+                                                       boolean hasLogOrderIdRestrictedCondition) {
+        // 如果没有关键字,直接返回原有的ID集合
+        if (Objects.isNull(req) || org.apache.commons.lang3.StringUtils.isBlank(req.getKeywords())) {
+            log.debug("无关键字过滤条件,直接返回原有物流订单ID集合");
+            return logOrderIds;
+        }
+
+        log.info("开始执行关键字过滤,关键字: {}, 原有ID数量: {}", req.getKeywords(), logOrderIds.size());
+        
+        // 查询命中关键字的物流订单ID集合
+        Set<Long> keywordLogOrderIds = queryLogisticsOrderIdsByKeywords(req.getKeywords());
+        log.debug("关键字搜索命中ID数量: {}", keywordLogOrderIds.size());
+        
+        // 合并结果
+        return mergeKeywordLogOrderIds(logOrderIds, keywordLogOrderIds, hasLogOrderIdRestrictedCondition);
+    }
+
+    /**
+     * 查询关键字段命中的物流订单ID。
+     * 搜索范围:
+     * 1. 物流订单编号 (LOrderNo)
+     * 2. 商品名称 (GoodsName)
+     * 两者结果为并集 (OR)。
+     *
+     * @param keywords 搜索关键字
+     * @return 命中的物流订单ID集合
+     */
+    private Set<Long> queryLogisticsOrderIdsByKeywords(String keywords) {
+        Set<Long> keywordLogOrderIds = Sets.newLinkedHashSet();
+        
+        // 1. 根据物流订单编号模糊查询
+        List<KwtLogisticsOrder> logisticsOrders = logisticsOrderRepository.queryListByLogisticsOrderNo(keywords);
+        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(logisticsOrders)) {
+            Set<Long> orderIds = logisticsOrders.stream()
+                    .map(KwtLogisticsOrder::getId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            keywordLogOrderIds.addAll(orderIds);
+            log.debug("通过订单号匹配到 {} 个订单", orderIds.size());
+        }
+        
+        // 2. 根据商品名称模糊查询
+        List<KwtLogisticsOrderGoods> logisticsOrderGoodsList = logisticsOrderGoodsRepository.queryByGoodsName(keywords);
+        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(logisticsOrderGoodsList)) {
+            Set<Long> goodsOrderIds = logisticsOrderGoodsList.stream()
+                    .map(KwtLogisticsOrderGoods::getLOrderId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            keywordLogOrderIds.addAll(goodsOrderIds);
+            log.debug("通过商品名称匹配到 {} 个订单", goodsOrderIds.size());
+        }
+        
+        return keywordLogOrderIds;
+    }
+
+    /**
+     * 合并关键字段命中的物流订单ID。
+     * 合并策略:
+     * 1. 如果关键字未命中任何数据,返回空集合(因为关键字是必填过滤项时,无命中即无结果)。
+     * 2. 如果原有条件未限制ID范围(即没有其他AND条件),则直接返回关键字命中的ID集合。
+     * 3. 如果原有条件已限制ID范围,则取交集(原有ID AND 关键字命中ID)。
+     *
+     * @param logOrderIds                 原有条件命中的物流订单ID集合
+     * @param keywordLogOrderIds          关键字段命中的物流订单ID集合
+     * @param hasLogOrderIdRestrictedCondition 是否存在原有物流订单ID范围限制
+     * @return 合并后的物流订单ID集合
+     */
+    static Set<Long> mergeKeywordLogOrderIds(Set<Long> logOrderIds,
+                                             Set<Long> keywordLogOrderIds,
+                                             boolean hasLogOrderIdRestrictedCondition) {
+        // 情况1:关键字未命中任何数据,返回空集合
+        if (org.apache.commons.collections4.CollectionUtils.isEmpty(keywordLogOrderIds)) {
+            log.debug("关键字未命中任何数据,返回空集合");
+            return Sets.newHashSet();
+        }
+        
+        // 情况2:原有条件未限制ID范围,且原有ID集合为空,直接返回关键字命中的ID
+        // 注意:这里假设如果hasLogOrderIdRestrictedCondition为false,说明用户只输入了关键字,没有其他筛选条件
+        if (org.apache.commons.collections4.CollectionUtils.isEmpty(logOrderIds) && !hasLogOrderIdRestrictedCondition) {
+            log.debug("无其他限制条件,直接返回关键字命中ID集合,数量: {}", keywordLogOrderIds.size());
+            return Sets.newHashSet(keywordLogOrderIds);
+        }
+        
+        // 情况3:取交集
+        // 只有同时满足原有条件和关键字条件的订单才保留
+        Set<Long> result = Sets.newHashSet(logOrderIds);
+        int beforeSize = result.size();
+        result.retainAll(keywordLogOrderIds);
+        log.debug("执行交集操作,原有ID数: {}, 关键字命中数: {}, 交集后剩余: {}", 
+                beforeSize, keywordLogOrderIds.size(), result.size());
+        
+        return result;
     }
 
     private Long getAllEnt(String entId) {

+ 74 - 0
sckw-modules/sckw-transport/src/test/java/com/sckw/transport/service/KwtLogisticsConsignmentServiceTest.java

@@ -0,0 +1,74 @@
+package com.sckw.transport.service;
+
+import com.sckw.transport.model.param.QueryLogisticsOrderReq;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Set;
+
+/**
+ * 物流订单分页查询关键字段单元测试。
+ */
+public class KwtLogisticsConsignmentServiceTest {
+
+    /**
+     * keywords包含“代理”时,应转换为代理属性过滤并清空关键字段。
+     */
+    @Test
+    public void applyAgentKeywordConditionWhenKeywordsContainsAgent() {
+        QueryLogisticsOrderReq req = new QueryLogisticsOrderReq();
+        req.setKeywords("代理");
+
+        KwtLogisticsConsignmentService.applyAgentKeywordCondition(req);
+
+        Assert.assertEquals(Integer.valueOf(1), req.getAgentFlag());
+        Assert.assertNull(req.getKeywords());
+    }
+
+    /**
+     * keywords不包含“代理”时,应保留原关键字段。
+     */
+    @Test
+    public void applyAgentKeywordConditionWhenKeywordsNotContainsAgent() {
+        QueryLogisticsOrderReq req = new QueryLogisticsOrderReq();
+        req.setKeywords("煤炭");
+
+        KwtLogisticsConsignmentService.applyAgentKeywordCondition(req);
+
+        Assert.assertNull(req.getAgentFlag());
+        Assert.assertEquals("煤炭", req.getKeywords());
+    }
+
+    /**
+     * 无原有物流订单ID范围限制时,关键字段命中的ID作为最终范围。
+     */
+    @Test
+    public void mergeKeywordLogOrderIdsWhenNoRestrictedCondition() {
+        Set<Long> result = KwtLogisticsConsignmentService.mergeKeywordLogOrderIds(
+                Set.of(), Set.of(1001L, 1002L), false);
+
+        Assert.assertEquals(Set.of(1001L, 1002L), result);
+    }
+
+    /**
+     * 已存在原有物流订单ID范围限制时,关键字段命中的ID与原范围取交集。
+     */
+    @Test
+    public void mergeKeywordLogOrderIdsWhenHasRestrictedCondition() {
+        Set<Long> result = KwtLogisticsConsignmentService.mergeKeywordLogOrderIds(
+                Set.of(1001L, 1002L), Set.of(1002L, 1003L), true);
+
+        Assert.assertEquals(Set.of(1002L), result);
+    }
+
+    /**
+     * 关键字段无命中时,返回空范围,避免后续查询全量。
+     */
+    @Test
+    public void mergeKeywordLogOrderIdsWhenKeywordNotMatched() {
+        Set<Long> result = KwtLogisticsConsignmentService.mergeKeywordLogOrderIds(
+                Set.of(1001L), Set.of(), true);
+
+        Assert.assertTrue(result.isEmpty());
+    }
+}