Jelajahi Sumber

提交修改app物流运单代理商

chenxiaofei 2 jam lalu
induk
melakukan
9d03a7bfd5

+ 12 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/WaybillOrderDetailResp.java

@@ -139,6 +139,18 @@ public class WaybillOrderDetailResp implements Serializable {
     @Schema(description = "供应单位")
     private String supplyEntName;
 
+    /**
+     * 代理单位ID
+     */
+    @Schema(description = "代理单位ID")
+    private String agentEntId;
+
+    /**
+     * 代理单位
+     */
+    @Schema(description = "代理单位")
+    private String agentFirmName;
+
     /**
      * 托运企业
      */

+ 40 - 4
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java

@@ -3443,44 +3443,80 @@ public class KwtLogisticsConsignmentService {
         return keywordLogOrderIds;
     }
 
+
     /**
-     * 根据贸易订单代理商名称模糊查询物流订单ID。
+     * 根据贸易订单代理商名称关键字查询关联的物流订单ID集合。
+     * <p>
+     * 业务逻辑链路:
+     * 1. 根据企业名称关键字查询贸易订单单位信息(远程调用)。
+     * 2. 筛选出单位为“收货单位/承运方”(unitType=2)的贸易订单ID。
+     * 3. 批量查询这些贸易订单的详情。
+     * 4. 在贸易订单详情中,进一步筛选出标记为“代理”且代理商名称包含关键字的贸易订单ID。
+     * 5. 根据筛选后的贸易订单ID,查询关联的物流订单ID并返回。
+     * </p>
      *
      * @param keywords 代理商名称关键字
-     * @return 命中的物流订单ID集合
+     * @return 命中的物流订单ID集合,若查询失败或无结果则返回空集合
      */
     private Set<Long> queryLogisticsOrderIdsByAgentFirmName(String keywords) {
+        // 1. 前置校验:关键字为空直接返回空集合
         if (org.apache.commons.lang3.StringUtils.isBlank(keywords)) {
+            log.debug("通过代理商名称查询物流订单:关键字为空,返回空集合");
             return Sets.newHashSet();
         }
+        
+        log.info("开始通过代理商名称关键字查询物流订单,keywords: {}", keywords);
+        
         try {
+            // 2. 远程调用:根据企业名称查询贸易订单单位信息
             List<OrderUnitInfoDetailVO> orderUnits = tradeOrderInfoService.queryOrderUnitInfByEntName(keywords);
+            
             if (org.apache.commons.collections4.CollectionUtils.isEmpty(orderUnits)) {
+                log.debug("通过代理商名称查询物流订单:未查询到匹配的贸易订单单位信息,keywords: {}", keywords);
                 return Sets.newHashSet();
             }
+            log.debug("通过代理商名称查询物流订单:查询到贸易订单单位信息数量: {}", orderUnits.size());
 
+            // 3. 过滤并提取贸易订单ID
+            // 业务规则:只关注 unitType 为 "2" (通常代表收货方/承运方相关角色) 的单位关联的贸易订单
             Set<Long> tradeOrderIds = orderUnits.stream()
                     .filter(Objects::nonNull)
                     .filter(unit -> Objects.equals(unit.getUnitType(), String.valueOf(NumberConstant.TWO)))
                     .map(OrderUnitInfoDetailVO::getTOrderId)
                     .filter(Objects::nonNull)
                     .collect(Collectors.toSet());
+            
             if (org.apache.commons.collections4.CollectionUtils.isEmpty(tradeOrderIds)) {
+                log.debug("通过代理商名称查询物流订单:过滤后未找到有效的贸易订单ID,keywords: {}", keywords);
                 return Sets.newHashSet();
             }
+            log.debug("通过代理商名称查询物流订单:提取到候选贸易订单ID数量: {}", tradeOrderIds.size());
 
+            // 4. 批量查询贸易订单详情
             List<OrderDetailVo> tradeOrderDetails = tradeOrderInfoService.queryByTradeOrderIds(tradeOrderIds);
+            
+            // 5. 二次过滤:从贸易订单详情中筛选出真正的代理订单
+            // 条件:订单标记为代理(agentFlag=YES) 且 代理商名称(agentFirmName)包含关键字
             Set<Long> agentTradeOrderIds = extractAgentTradeOrderIdsByAgentName(tradeOrderDetails, keywords);
+            
             if (org.apache.commons.collections4.CollectionUtils.isEmpty(agentTradeOrderIds)) {
+                log.debug("通过代理商名称查询物流订单:未找到符合代理条件的贸易订单,keywords: {}", keywords);
                 return Sets.newHashSet();
             }
+            log.debug("通过代理商名称查询物流订单:筛选出符合条件的代理贸易订单ID数量: {}", agentTradeOrderIds.size());
 
-            return logisticsOrderRepository.queryByTradeOrderIds(agentTradeOrderIds).stream()
+            // 6. 根据代理贸易订单ID查询关联的物流订单ID
+            Set<Long> resultLogOrderIds = logisticsOrderRepository.queryByTradeOrderIds(agentTradeOrderIds).stream()
                     .map(KwtLogisticsOrder::getId)
                     .filter(Objects::nonNull)
                     .collect(Collectors.toSet());
+            
+            log.info("通过代理商名称关键字查询物流订单完成,keywords: {}, 最终命中物流订单数量: {}", keywords, resultLogOrderIds.size());
+            return resultLogOrderIds;
+            
         } catch (Exception e) {
-            log.warn("通过代理商名称关键字查询物流订单失败,keywords={}", keywords, e);
+            // 异常捕获:防止因远程服务波动或数据异常导致主流程中断,记录警告日志并返回空集合
+            log.warn("通过代理商名称关键字查询物流订单发生异常,keywords: {}, 错误信息: {}", keywords, e.getMessage(), e);
             return Sets.newHashSet();
         }
     }

+ 148 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java

@@ -42,6 +42,7 @@ import com.sckw.fleet.api.model.vo.*;
 import com.sckw.mongo.model.SckwWaybillOrder;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.order.api.model.OrderDetailVo;
+import com.sckw.order.api.model.OrderUnitInfoDetailVO;
 import com.sckw.order.api.model.TradeOrderContractVo;
 import com.sckw.order.api.model.TradeOrderSettlePara;
 import com.sckw.payment.api.feign.PaymentFeignService;
@@ -4287,9 +4288,137 @@ public class KwtWaybillOrderV1Service {
             }
         }
         
+        // 通过贸易订单代理商名称关键字查询关联的运单ID
+        log.debug("开始通过代理商名称关键字查询运单ID,关键字: {}", keywords);
+        Set<Long> orderIdsByAgentFirmName = queryBillOrderIdsByAgentFirmName(keywords);
+        
+        // 如果查询到匹配的运单ID,则合并到结果集中
+        if (CollectionUtils.isNotEmpty(orderIdsByAgentFirmName)) {
+            keywordBillOrderIds.addAll(orderIdsByAgentFirmName);
+            log.info("通过贸易订单代理商名称[{}]查询到运单ID数量: {}", keywords, orderIdsByAgentFirmName.size());
+        } else {
+            log.debug("通过贸易订单代理商名称[{}]未查询到匹配的运单ID", keywords);
+        }
+
         return keywordBillOrderIds;
     }
 
+
+    /**
+     * 通过贸易订单代理商名称关键字查询关联的运单ID集合。
+     * <p>
+     * 业务逻辑链路:
+     * 1. 根据代理商名称关键字查询贸易订单单位信息(包含承运/代理单位)。
+     * 2. 筛选出类型为“代理/承运”(UnitType=2)的单位,提取对应的贸易订单ID。
+     * 3. 根据贸易订单ID查询贸易订单详情,并进一步过滤出代理商名称匹配且标记为代理的订单ID。
+     * 4. 根据贸易订单ID查询关联的物流订单ID。
+     * 5. 根据物流订单ID查询关联的子运单,最终提取主运单ID集合。
+     * </p>
+     *
+     * @param keywords 代理商名称关键字
+     * @return 匹配的运单ID集合,若查询失败或无数据则返回空集合
+     */
+    private Set<Long> queryBillOrderIdsByAgentFirmName(String keywords) {
+        // 参数校验:关键字为空直接返回空集合
+        if (org.apache.commons.lang3.StringUtils.isBlank(keywords)) {
+            log.debug("通过代理商名称查询运单:关键字为空,返回空集合");
+            return Sets.newHashSet();
+        }
+        
+        log.info("开始通过代理商名称关键字查询运单,keywords: {}", keywords);
+        
+        try {
+            // 1. 根据代理商名称查询贸易订单单位信息
+            List<OrderUnitInfoDetailVO> orderUnits = tradeOrderInfoService.queryOrderUnitInfByEntName(keywords);
+            if (CollectionUtils.isEmpty(orderUnits)) {
+                log.debug("通过代理商名称[{}]未查询到贸易订单单位信息", keywords);
+                return Sets.newHashSet();
+            }
+            log.debug("查询到贸易订单单位数量: {}", orderUnits.size());
+
+            // 2. 筛选单位为代理/承运类型(UnitType=2),并提取贸易订单ID
+            Set<Long> tradeOrderIds = orderUnits.stream()
+                    .filter(Objects::nonNull)
+                    .filter(unit -> Objects.equals(unit.getUnitType(), String.valueOf(NumberConstant.TWO)))
+                    .map(OrderUnitInfoDetailVO::getTOrderId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            
+            if (CollectionUtils.isEmpty(tradeOrderIds)) {
+                log.debug("通过代理商名称[{}]未筛选到有效的代理类型贸易订单ID", keywords);
+                return Sets.newHashSet();
+            }
+            log.debug("筛选到代理类型贸易订单ID数量: {}", tradeOrderIds.size());
+
+            // 3. 查询贸易订单详情,并二次过滤确认代理商名称匹配
+            List<OrderDetailVo> tradeOrderDetails = tradeOrderInfoService.queryByTradeOrderIds(tradeOrderIds);
+            Set<Long> agentTradeOrderIds = extractAgentTradeOrderIdsByAgentName(tradeOrderDetails, keywords);
+            
+            if (CollectionUtils.isEmpty(agentTradeOrderIds)) {
+                log.debug("通过代理商名称[{}]在贸易订单详情中未匹配到有效订单", keywords);
+                return Sets.newHashSet();
+            }
+            log.debug("二次过滤后匹配的贸易订单ID数量: {}", agentTradeOrderIds.size());
+
+            // 4. 根据贸易订单ID查询关联的物流订单
+            List<KwtLogisticsOrder> logisticsOrders = logisticsOrderRepository.queryByTradeOrderIds(agentTradeOrderIds);
+            if (CollectionUtils.isEmpty(logisticsOrders)) {
+                log.debug("贸易订单ID集合[{}]未关联到任何物流订单", agentTradeOrderIds);
+                return Sets.newHashSet();
+            }
+            log.debug("查询到关联的物流订单数量: {}", logisticsOrders.size());
+
+            // 5. 提取物流订单ID
+            Set<Long> logOrderIds = logisticsOrders.stream()
+                    .map(KwtLogisticsOrder::getId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            
+            if (CollectionUtils.isEmpty(logOrderIds)) {
+                log.warn("物流订单列表中ID为空,无法继续查询子运单");
+                return Sets.newHashSet();
+            }
+
+            // 6. 根据物流订单ID查询子运单,并提取主运单ID
+            List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByLogIds(new ArrayList<>(logOrderIds));
+            Set<Long> resultBillOrderIds = Optional.ofNullable(subtasks)
+                    .orElseGet(Collections::emptyList)
+                    .stream()
+                    .map(KwtWaybillOrderSubtask::getWOrderId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+            
+            log.info("通过代理商名称[{}]查询运单完成,最终匹配运单ID数量: {}", keywords, resultBillOrderIds.size());
+            return resultBillOrderIds;
+            
+        } catch (Exception e) {
+            // 异常捕获:记录警告日志,避免因远程服务波动导致主流程中断,返回空集合表示无匹配数据
+            log.warn("通过代理商名称关键字查询运单发生异常,keywords: {}, 错误信息: {}", keywords, e.getMessage(), e);
+            return Sets.newHashSet();
+        }
+    }
+
+    /**
+     * 从贸易订单详情中过滤代理商名称命中的代理订单ID。
+     *
+     * @param tradeOrderDetails 贸易订单详情集合
+     * @param keywords          代理商名称关键字
+     * @return 代理商名称命中的贸易订单ID集合
+     */
+    static Set<Long> extractAgentTradeOrderIdsByAgentName(List<OrderDetailVo> tradeOrderDetails, String keywords) {
+        if (CollectionUtils.isEmpty(tradeOrderDetails)
+                || org.apache.commons.lang3.StringUtils.isBlank(keywords)) {
+            return Sets.newHashSet();
+        }
+        return tradeOrderDetails.stream()
+                .filter(Objects::nonNull)
+                .filter(order -> Objects.equals(order.getAgentFlag(), Global.YES))
+                .filter(order -> org.apache.commons.lang3.StringUtils.contains(order.getAgentFirmName(), keywords))
+                .map(OrderDetailVo::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+    }
+
     /**
      * 合并关键字段命中的运单ID。
      * <p>
@@ -4851,7 +4980,7 @@ public class KwtWaybillOrderV1Service {
         log.info("运单详情查询完成,运单ID: {}", billOrder.getId());
         return getWaybillOrderDetailResp(subtask, billOrder, logOrder, truck, fleet, goods,
                 keyAndAddressMap, kwpGoods, logisticsOrderUnitMap, nodeList, userCacheResDto,
-                billOrders, ticketMap, dictValueAndDictResDtoMap, tradeContractUnitDtos,contractGoodsDto);
+                billOrders, ticketMap, dictValueAndDictResDtoMap, tradeContractUnitDtos, orderDetailVo, contractGoodsDto);
     }
 
     /**
@@ -4989,6 +5118,7 @@ public class KwtWaybillOrderV1Service {
                                                                     Map<String, KwtWaybillOrderTicket> ticketMap,
                                                                     Map<String, Map<String, String>> dictValueAndDictResDtoMap,
                                                                     List<TradeContractUnitDto> tradeContractUnitDtos,
+                                                                    OrderDetailVo orderDetailVo,
                                                                     TradeContractGoodsDto contractGoodsDto) {
         WaybillOrderDetailResp resp = new WaybillOrderDetailResp();
 
@@ -5075,6 +5205,7 @@ public class KwtWaybillOrderV1Service {
                     .findFirst()
                     .ifPresent(x -> resp.setSupplyEntName(x.getFirmName()));
         }
+        setAgentUnitInfo(resp, orderDetailVo);
 
         // 状态信息
         resp.setStatus(subtask.getStatus());
@@ -5118,6 +5249,22 @@ public class KwtWaybillOrderV1Service {
         return resp;
     }
 
+    /**
+     * 设置代理单位信息,仅代理贸易订单返回代理单位。
+     *
+     * @param resp          运单详情响应
+     * @param orderDetailVo 贸易订单详情
+     */
+    static void setAgentUnitInfo(WaybillOrderDetailResp resp, OrderDetailVo orderDetailVo) {
+        if (Objects.isNull(resp) || Objects.isNull(orderDetailVo)
+                || !Objects.equals(orderDetailVo.getAgentFlag(), Global.YES)) {
+            return;
+        }
+        resp.setAgentEntId(Objects.isNull(orderDetailVo.getAgentEntId())
+                ? null : String.valueOf(orderDetailVo.getAgentEntId()));
+        resp.setAgentFirmName(org.apache.commons.lang3.StringUtils.defaultString(orderDetailVo.getAgentFirmName()));
+    }
+
     /**
      * 格式化金额
      */

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

@@ -1,7 +1,9 @@
 package com.sckw.transport.service;
 
+import com.sckw.order.api.model.OrderDetailVo;
 import com.sckw.system.api.model.dto.res.EntTypeResDto;
 import com.sckw.transport.model.param.WaybillOrderReq;
+import com.sckw.transport.model.vo.WaybillOrderDetailResp;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -156,4 +158,64 @@ public class KwtWaybillOrderV1ServiceTest {
 
         Assert.assertTrue(result.isEmpty());
     }
+
+    /**
+     * 代理商名称关键字只命中真实代理贸易订单,避免普通企业名称误匹配。
+     */
+    @Test
+    public void extractAgentTradeOrderIdsByAgentNameOnlyMatchesAgentOrders() {
+        OrderDetailVo agentOrder = new OrderDetailVo();
+        agentOrder.setId(1001L);
+        agentOrder.setAgentFlag(1);
+        agentOrder.setAgentFirmName("测试代理商");
+
+        OrderDetailVo normalOrder = new OrderDetailVo();
+        normalOrder.setId(1002L);
+        normalOrder.setAgentFlag(0);
+        normalOrder.setAgentFirmName("测试代理商");
+
+        OrderDetailVo otherAgentOrder = new OrderDetailVo();
+        otherAgentOrder.setId(1003L);
+        otherAgentOrder.setAgentFlag(1);
+        otherAgentOrder.setAgentFirmName("其他单位");
+
+        Set<Long> result = KwtWaybillOrderV1Service.extractAgentTradeOrderIdsByAgentName(
+                List.of(agentOrder, normalOrder, otherAgentOrder), "代理商");
+
+        Assert.assertEquals(Set.of(1001L), result);
+    }
+
+    /**
+     * 运单详情仅在代理贸易订单场景返回代理单位信息。
+     */
+    @Test
+    public void setAgentUnitInfoWhenAgentOrder() {
+        WaybillOrderDetailResp resp = new WaybillOrderDetailResp();
+        OrderDetailVo orderDetailVo = new OrderDetailVo();
+        orderDetailVo.setAgentFlag(1);
+        orderDetailVo.setAgentEntId(2001L);
+        orderDetailVo.setAgentFirmName("测试代理单位");
+
+        KwtWaybillOrderV1Service.setAgentUnitInfo(resp, orderDetailVo);
+
+        Assert.assertEquals("2001", resp.getAgentEntId());
+        Assert.assertEquals("测试代理单位", resp.getAgentFirmName());
+    }
+
+    /**
+     * 非代理贸易订单不返回代理单位信息。
+     */
+    @Test
+    public void setAgentUnitInfoWhenNotAgentOrder() {
+        WaybillOrderDetailResp resp = new WaybillOrderDetailResp();
+        OrderDetailVo orderDetailVo = new OrderDetailVo();
+        orderDetailVo.setAgentFlag(0);
+        orderDetailVo.setAgentEntId(2001L);
+        orderDetailVo.setAgentFirmName("测试代理单位");
+
+        KwtWaybillOrderV1Service.setAgentUnitInfo(resp, orderDetailVo);
+
+        Assert.assertNull(resp.getAgentEntId());
+        Assert.assertNull(resp.getAgentFirmName());
+    }
 }