Pārlūkot izejas kodu

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

chenxiaofei 2 nedēļas atpakaļ
vecāks
revīzija
e7ffb6b02c

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

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

+ 13 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderRepository.java

@@ -126,6 +126,18 @@ public class KwtWaybillOrderRepository extends ServiceImpl<KwtWaybillOrderMapper
                 .last("limit 1"));
     }
 
+    /**
+     * 根据物流运单编号模糊查询运单列表。
+     *
+     * @param wOrderNo 物流运单编号关键字
+     * @return 运单列表
+     */
+    public List<KwtWaybillOrder> queryListByWOrderNo(String wOrderNo) {
+        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
+                .eq(KwtWaybillOrder::getDelFlag, 0)
+                .like(StringUtils.isNotBlank(wOrderNo), KwtWaybillOrder::getWOrderNo, wOrderNo));
+    }
+
     public List<KwtWaybillOrder> queryWaybillOrderByEntId(Long entId) {
         return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
                 .eq(KwtWaybillOrder::getDelFlag,0)
@@ -341,4 +353,4 @@ public class KwtWaybillOrderRepository extends ServiceImpl<KwtWaybillOrderMapper
         return page(page,wrapper);
     }
 
-}
+}

+ 146 - 3
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java

@@ -2997,7 +2997,7 @@ public class KwtWaybillOrderV1Service {
 
     public PageDataResult<WaybillOrderResp> findBillOrderListPage(WaybillOrderReq req) {
         log.info("查询订单列表请求参数:{}", JSON.toJSONString(req));
-
+        applyAgentKeywordCondition(req);
         // 处理状态参数
         Integer status = parseStatus(req.getStatus());
 
@@ -3230,7 +3230,8 @@ public class KwtWaybillOrderV1Service {
     private boolean shouldReturnEmptyResultForWaybill(WaybillOrderReq req, Set<Long> billOrderIds) {
         boolean hasWaybillFilter = Stream.of(
                         req.getWaybillNo(), req.getTruckNo(), req.getDriverName(), req.getPhone(),
-                        req.getLoadStartTime(), req.getLoadEndTime(), req.getUnloadStartTime(), req.getUnloadEndTime())
+                        req.getLoadStartTime(), req.getLoadEndTime(), req.getUnloadStartTime(), req.getUnloadEndTime(),
+                        req.getKeywords())
                 .anyMatch(StringUtils::isNotBlank);
 
         return CollectionUtils.isEmpty(billOrderIds) && hasWaybillFilter;
@@ -4185,6 +4186,144 @@ public class KwtWaybillOrderV1Service {
         }
     }
 
+
+    /**
+     * 处理运单列表关键字段中的代理关键字。
+     * <p>
+     * 业务逻辑:
+     * 1. 检查请求参数及关键字是否包含“代理”语义。
+     * 2. 若包含,则将请求对象的代理标识设置为“是”(Global.YES)。
+     * 3. 清空关键字字段,避免后续模糊查询将“代理”作为普通文本匹配,导致数据过滤错误。
+     * </p>
+     *
+     * @param req 运单分页查询请求对象
+     */
+    static void applyAgentKeywordCondition(WaybillOrderReq req) {
+        // 参数校验:请求为空、关键字为空或不包含“代理”字样,直接返回
+        if (Objects.isNull(req)
+                || StringUtils.isBlank(req.getKeywords())
+                || !req.getKeywords().contains("代理")) {
+            return;
+        }
+        
+        log.debug("检测到关键字包含'代理',设置代理标识并清空关键字");
+        // 设置代理标识为真
+        req.setAgentFlag(Global.YES);
+        // 清空关键字,防止后续作为普通文本进行模糊匹配
+        req.setKeywords(null);
+    }
+
+    /**
+     * 根据关键字段过滤运单ID。
+     * <p>
+     * 业务逻辑:
+     * 1. 支持通过物流运单编号和商品名称进行检索。
+     * 2. 运单编号与商品名称之间的检索条件为 OR 关系(并集)。
+     * 3. 关键字检索结果与原有其他筛选条件(如时间、车辆等)的结果为 AND 关系(交集)。
+     * </p>
+     *
+     * @param req                             运单分页查询请求
+     * @param billOrderIds                    已由原有非关键字条件筛选出的运单ID集合
+     * @param hasBillOrderRestrictedCondition 标记是否已经应用了其他限制条件(用于判断初始集合是否为空时的处理逻辑)
+     * @return 最终过滤后的运单ID集合
+     */
+    private Set<Long> applyKeywordFilterToBillOrderIds(WaybillOrderReq req,
+                                                        Set<Long> billOrderIds,
+                                                        boolean hasBillOrderRestrictedCondition) {
+        // 若无请求或无关键字,直接返回原有ID集合
+        if (Objects.isNull(req) || StringUtils.isBlank(req.getKeywords())) {
+            return billOrderIds;
+        }
+        
+        log.debug("开始执行关键字过滤,关键字: {}", req.getKeywords());
+        
+        // 1. 查询命中关键字的运单ID集合
+        Set<Long> keywordBillOrderIds = queryBillOrderIdsByKeywords(req.getKeywords());
+        log.debug("关键字查询到的运单ID数量: {}", CollectionUtils.isEmpty(keywordBillOrderIds) ? 0 : keywordBillOrderIds.size());
+        
+        // 2. 合并结果(取交集或并集,取决于是否有其他限制条件)
+        return mergeKeywordBillOrderIds(billOrderIds, keywordBillOrderIds, hasBillOrderRestrictedCondition);
+    }
+
+    /**
+     * 查询关键字段命中的运单ID。
+     * <p>
+     * 检索策略:
+     * 1. 通过运单号模糊查询主运单ID。
+     * 2. 通过商品名称查询关联的物流订单,进而找到关联的子运单及主运单ID。
+     * 3. 两者结果取并集。
+     * </p>
+     *
+     * @param keywords 搜索关键字(运单号或商品名)
+     * @return 命中的运单ID集合
+     */
+    private Set<Long> queryBillOrderIdsByKeywords(String keywords) {
+        Set<Long> keywordBillOrderIds = Sets.newLinkedHashSet();
+        
+        // 1. 根据运单号模糊查询
+        List<KwtWaybillOrder> waybillOrders = kwtWaybillOrderRepository.queryListByWOrderNo(keywords);
+        if (CollectionUtils.isNotEmpty(waybillOrders)) {
+            Set<Long> orderIdsByNo = waybillOrders.stream()
+                    .map(KwtWaybillOrder::getId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            keywordBillOrderIds.addAll(orderIdsByNo);
+            log.debug("通过运单号查询到ID数量: {}", orderIdsByNo.size());
+        }
+        
+        // 2. 根据商品名称查询
+        // 先获取包含该商品的物流订单ID
+        Set<Long> logOrderIdsByGoods = getLogOrderIdsByGoodsName(keywords);
+        if (CollectionUtils.isNotEmpty(logOrderIdsByGoods)) {
+            // 再根据物流订单ID查询对应的子运单,从而获取主运单ID
+            List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByLogIds(new ArrayList<>(logOrderIdsByGoods));
+            if (CollectionUtils.isNotEmpty(subtasks)) {
+                Set<Long> orderIdsByGoods = subtasks.stream()
+                        .map(KwtWaybillOrderSubtask::getWOrderId)
+                        .filter(Objects::nonNull)
+                        .collect(Collectors.toSet());
+                keywordBillOrderIds.addAll(orderIdsByGoods);
+                log.debug("通过商品名称查询到ID数量: {}", orderIdsByGoods.size());
+            }
+        }
+        
+        return keywordBillOrderIds;
+    }
+
+    /**
+     * 合并关键字段命中的运单ID。
+     * <p>
+     * 合并逻辑:
+     * 1. 若关键字查询结果为空,返回空集合(表示无匹配数据)。
+     * 2. 若原有条件未限制范围(hasBillOrderRestrictedCondition=false)且原有ID集合为空,则直接返回关键字查询结果。
+     * 3. 否则,取原有ID集合与关键字ID集合的交集,确保同时满足所有筛选条件。
+     * </p>
+     *
+     * @param billOrderIds                    原有条件命中的运单ID集合
+     * @param keywordBillOrderIds             关键字段命中的运单ID集合
+     * @param hasBillOrderRestrictedCondition 是否存在原有运单ID范围限制(如已按时间、车辆等筛选过)
+     * @return 合并后的运单ID集合
+     */
+    static Set<Long> mergeKeywordBillOrderIds(Set<Long> billOrderIds,
+                                              Set<Long> keywordBillOrderIds,
+                                              boolean hasBillOrderRestrictedCondition) {
+        // 如果关键字没查到任何数据,整体结果为空
+        if (CollectionUtils.isEmpty(keywordBillOrderIds)) {
+            return Sets.newHashSet();
+        }
+        
+        // 如果之前没有施加其他限制条件,且之前的ID集合也为空,说明这是第一个有效过滤条件,直接返回关键字结果
+        if (CollectionUtils.isEmpty(billOrderIds) && !hasBillOrderRestrictedCondition) {
+            return Sets.newHashSet(keywordBillOrderIds);
+        }
+        
+        // 取交集:保留既在原有结果中,又命中关键字的ID
+        Set<Long> result = Sets.newHashSet(billOrderIds);
+        result.retainAll(keywordBillOrderIds);
+        log.debug("关键字过滤合并完成,最终ID数量: {}", result.size());
+        return result;
+    }
+
     @NotNull
     private Set<Long> getBillOrderIds(WaybillOrderReq req) {
         Set<Long> billOrderIds = Sets.newHashSet();
@@ -4250,7 +4389,11 @@ public class KwtWaybillOrderV1Service {
                 billOrderIds.addAll(billOrderIds2);
             }
         }
-        return billOrderIds;
+        boolean hasBillOrderRestrictedCondition = Stream.of(
+                req.getWaybillNo(), req.getTruckNo(), req.getDriverName(), req.getPhone(),
+                req.getLoadStartTime(), req.getLoadEndTime(), req.getUnloadStartTime(), req.getUnloadEndTime()
+        ).anyMatch(StringUtils::isNotBlank);
+        return applyKeywordFilterToBillOrderIds(req, billOrderIds, hasBillOrderRestrictedCondition);
     }
 
     private static Date getStartDate(String date) {

+ 62 - 0
sckw-modules/sckw-transport/src/test/java/com/sckw/transport/service/KwtWaybillOrderV1ServiceTest.java

@@ -1,6 +1,7 @@
 package com.sckw.transport.service;
 
 import com.sckw.system.api.model.dto.res.EntTypeResDto;
+import com.sckw.transport.model.param.WaybillOrderReq;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -58,4 +59,65 @@ public class KwtWaybillOrderV1ServiceTest {
 
         Assert.assertTrue(result.isEmpty());
     }
+
+    /**
+     * keywords包含“代理”时,应转换为代理属性过滤并清空关键字段。
+     */
+    @Test
+    public void applyAgentKeywordConditionWhenKeywordsContainsAgent() {
+        WaybillOrderReq req = new WaybillOrderReq();
+        req.setKeywords("代理");
+
+        KwtWaybillOrderV1Service.applyAgentKeywordCondition(req);
+
+        Assert.assertEquals(Integer.valueOf(1), req.getAgentFlag());
+        Assert.assertNull(req.getKeywords());
+    }
+
+    /**
+     * keywords不包含“代理”时,应保留原关键字段。
+     */
+    @Test
+    public void applyAgentKeywordConditionWhenKeywordsNotContainsAgent() {
+        WaybillOrderReq req = new WaybillOrderReq();
+        req.setKeywords("煤炭");
+
+        KwtWaybillOrderV1Service.applyAgentKeywordCondition(req);
+
+        Assert.assertNull(req.getAgentFlag());
+        Assert.assertEquals("煤炭", req.getKeywords());
+    }
+
+    /**
+     * 无原有运单ID范围限制时,关键字段命中的ID作为最终范围。
+     */
+    @Test
+    public void mergeKeywordBillOrderIdsWhenNoRestrictedCondition() {
+        Set<Long> result = KwtWaybillOrderV1Service.mergeKeywordBillOrderIds(
+                Set.of(), Set.of(1001L, 1002L), false);
+
+        Assert.assertEquals(Set.of(1001L, 1002L), result);
+    }
+
+    /**
+     * 已存在原有运单ID范围限制时,关键字段命中的ID与原范围取交集。
+     */
+    @Test
+    public void mergeKeywordBillOrderIdsWhenHasRestrictedCondition() {
+        Set<Long> result = KwtWaybillOrderV1Service.mergeKeywordBillOrderIds(
+                Set.of(1001L, 1002L), Set.of(1002L, 1003L), true);
+
+        Assert.assertEquals(Set.of(1002L), result);
+    }
+
+    /**
+     * 关键字段无命中时,返回空范围,避免后续查询全量。
+     */
+    @Test
+    public void mergeKeywordBillOrderIdsWhenKeywordNotMatched() {
+        Set<Long> result = KwtWaybillOrderV1Service.mergeKeywordBillOrderIds(
+                Set.of(1001L), Set.of(), true);
+
+        Assert.assertTrue(result.isEmpty());
+    }
 }