Selaa lähdekoodia

优化超时取消运单定时任务

donglang 16 tuntia sitten
vanhempi
commit
07d5692f61

+ 2 - 0
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/RemoteFleetService.java

@@ -121,6 +121,8 @@ public interface RemoteFleetService {
 
     TruckDispatchCoefficientVO findAutoTruckDispatchByEntId(Long entId);
 
+    List<TruckDispatchCoefficientVO> findAutoTruckDispatchByEntIds(List<Long> entIds);
+
     DriverConductRulesVO findDriverConductRulesByEntId(Long entId);
 
     List<RTruckVo> findTruckByEntIds(Long entId);

+ 5 - 1
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/RUpdateDriverScoreDto.java

@@ -6,6 +6,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serial;
+import java.io.Serializable;
 import java.math.BigDecimal;
 
 /**
@@ -16,8 +18,10 @@ import java.math.BigDecimal;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class RUpdateDriverScoreDto {
+public class RUpdateDriverScoreDto implements Serializable {
 
+    @Serial
+    private static final long serialVersionUID = -8763763480079554893L;
     /**
      * 供应商企业id
      */

+ 6 - 1
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/UpdateDriverScoreDto.java

@@ -6,6 +6,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serial;
+import java.io.Serializable;
 import java.math.BigDecimal;
 
 /**
@@ -16,7 +18,10 @@ import java.math.BigDecimal;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class UpdateDriverScoreDto {
+public class UpdateDriverScoreDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -4995959874726280406L;
 
     /** 供应商企业id */
     @NotNull(message = "供应商企业id不能为空")

+ 13 - 5
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dubbo/RemoteFleetServiceImpl.java

@@ -1,15 +1,11 @@
 package com.sckw.fleet.dubbo;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
-import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.utils.BeanUtils;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.StringUtils;
-import com.sckw.core.web.context.LoginUserHolder;
-import com.sckw.core.web.response.HttpResult;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.dto.RUpdateDriverScoreDto;
 import com.sckw.fleet.api.model.vo.*;
@@ -568,7 +564,11 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
         if (result == null) {
             return null;
         }
+        return getTruckDispatchCoefficientVO(result);
+    }
+
 
+    private TruckDispatchCoefficientVO getTruckDispatchCoefficientVO(KwfTruckDispatchCoefficient result) {
         TruckDispatchCoefficientVO rulesVO = new TruckDispatchCoefficientVO();
         rulesVO.setId(result.getId());
         rulesVO.setEntId(result.getEntId());
@@ -588,6 +588,14 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
         rulesVO.setCreateUser(result.getCreateUser());
         rulesVO.setUpdateUser(result.getUpdateUser());
         return rulesVO;
+    }
+
+    @Override
+    public List<TruckDispatchCoefficientVO> findAutoTruckDispatchByEntIds(List<Long> entIds) {
+        List<KwfTruckDispatchCoefficient> autoTruckDispatchByEntIds = truckDispatchCoefficientRepository.findAutoTruckDispatchByEntIds(entIds);
+        return autoTruckDispatchByEntIds.stream()
+                .map(this::getTruckDispatchCoefficientVO)
+                .collect(Collectors.toList());
 
     }
 
@@ -595,7 +603,7 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
     public DriverConductRulesVO findDriverConductRulesByEntId(Long entId) {
         KwfDriverConductRules result = driverConductRulesRepository.findDriverConductRulesByEntId(entId);
         if (result == null) {
-            return new DriverConductRulesVO();
+            return null;
         }
 
         DriverConductRulesVO rulesVO = new DriverConductRulesVO();

+ 42 - 7
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java

@@ -1,25 +1,29 @@
 package com.sckw.fleet.model;
 
-import java.math.BigDecimal;
-
-import com.sckw.core.model.base.BaseModel;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * 司机评分对象 kwc_driver_score
  * 
  * @author tangyishan
  * @date 2025-12-11  18:12
  */
-@EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
-public class KwfDriverScore extends BaseModel
-{
+public class KwfDriverScore implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 主键
+     */
+    private Long id;
+
     /** 供应商企业id */
     private Long providerEntId;
 
@@ -31,4 +35,35 @@ public class KwfDriverScore extends BaseModel
 
     /** 司机评分 */
     private BigDecimal score;
+
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    /**
+     * 删除标识(0正常/-1删除)
+     */
+    private Integer delFlag;
+
+
+
 }

+ 41 - 5
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java

@@ -1,24 +1,29 @@
 package com.sckw.fleet.model;
 
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.sckw.core.model.base.BaseModel;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * @Author: tangyishan
  * @CreateTime: 2025-12-11  18:12
  * @Description: 司机评分明细
  */
-@EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
-public class KwfDriverScoreDetail extends BaseModel {
+public class KwfDriverScoreDetail implements Serializable {
+
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 主键
+     */
+    private Long id;
+
     /** 评分主键id */
     private Long scoreId;
 
@@ -33,4 +38,35 @@ public class KwfDriverScoreDetail extends BaseModel {
 
     /** 变动后评分 */
     private BigDecimal score;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private Long updateBy;
+
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    /**
+     * 删除标识(0正常/-1删除)
+     */
+    private Integer delFlag;
+
+
+
 }

+ 1 - 1
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfDriverScoreRepository.java

@@ -19,7 +19,7 @@ public class KwfDriverScoreRepository extends ServiceImpl<KwfDriverScoreMapper,
 
     public KwfDriverScore findDriverScoreByEntIds(Long proEntId, Long logEntId, Long driverId) {
         return getOne(Wrappers.<KwfDriverScore>lambdaQuery()
-                .eq(BaseModel::getDelFlag,0)
+                .eq(KwfDriverScore::getDelFlag,0)
                 .eq(KwfDriverScore::getProviderEntId,proEntId)
                 .eq(KwfDriverScore::getLogisticsEntId,logEntId)
                 .eq(KwfDriverScore::getDriverId,driverId)

+ 7 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfTruckDispatchCoefficientRepository.java

@@ -6,6 +6,7 @@ import com.sckw.fleet.dao.KwfTruckDispatchCoefficientMapper;
 import com.sckw.fleet.model.KwfTruckDispatchCoefficient;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -21,4 +22,10 @@ public class KwfTruckDispatchCoefficientRepository extends ServiceImpl<KwfTruckD
                 .eq(Objects.nonNull(entId), KwfTruckDispatchCoefficient::getEntId, entId));
     }
 
+
+    public List<KwfTruckDispatchCoefficient> findAutoTruckDispatchByEntIds(List<Long> entIds) {
+        return list(Wrappers.<KwfTruckDispatchCoefficient>lambdaQuery()
+                .in(Objects.nonNull(entIds), KwfTruckDispatchCoefficient::getEntId, entIds));
+    }
+
 }

+ 1 - 2
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverScoreService.java

@@ -350,7 +350,6 @@ public class KwfDriverScoreService {
      * 修改司机评分
      * @param dto
      */
-    @Transactional(rollbackFor = Exception.class)
     public void updateDriverScore(RUpdateDriverScoreDto dto) {
         if (dto.getScore() == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "分数不能为空!");
@@ -361,7 +360,7 @@ public class KwfDriverScoreService {
         if (driverScore == null) {
             log.info("司机无评分, 需初始化司机分数,司机id:{}", dto.getDriverId());
             ContractLogisticsScoreVO logisticsScore = remoteContractService.findLogisticsScoreByEntId(dto.getSupEntId(), dto.getLogEntId());
-            if (logisticsScore == null) {
+            if (logisticsScore.getScore() == null || logisticsScore.getScore().compareTo(BigDecimal.ZERO) < 0) {
                 throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "修改司机分数,企业无评分!");
             }
             //初始化司机分数

+ 1 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/AbstractWaybillOrderHandler.java

@@ -249,7 +249,7 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
             return 0L;
         }
         //查询订单托运单位(自动派单订单承运单位只为供应商)
-        KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderUnitRepository.queryByLOrderIdAndUnitType(waybillOrder.getLOrderId(), 1);
+        KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderUnitRepository.queryByLOrderIdAndUnitType(waybillOrder.getLOrderId(), 2);
         if (logisticsOrderUnit == null || logisticsOrderUnit.getEntId() == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ENT, "未找到关联的物流订单托运企业(供应商)!");
         }

+ 164 - 56
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/task/LogisticsOrderCompletionTask.java

@@ -3,6 +3,8 @@ package com.sckw.transport.task;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.sckw.contract.api.RemoteContractService;
+import com.sckw.contract.api.feign.LogisticsScoreFeignService;
+import com.sckw.contract.api.model.dto.req.LogisticsScoreDetailFeignDto;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
 import com.sckw.core.exception.BusinessPlatfromException;
@@ -10,8 +12,9 @@ import com.sckw.core.model.enums.CarWaybillV1Enum;
 import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.utils.DateUtils;
 import com.sckw.fleet.api.RemoteFleetService;
+import com.sckw.fleet.api.model.dto.RUpdateDriverScoreDto;
+import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
 import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
-import com.sckw.transport.handler.CancelHandler;
 import com.sckw.transport.model.*;
 import com.sckw.transport.repository.*;
 import lombok.RequiredArgsConstructor;
@@ -19,6 +22,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -42,17 +47,19 @@ public class LogisticsOrderCompletionTask {
     private final KwtLogisticsOrderRepository logisticsOrderRepository;
     private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
     private final KwtWaybillOrderRepository waybillOrderRepository;
-    private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;
     private final KwtLogisticsOrderUnitRepository logisticsOrderUnitRepository;
+    private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;
     private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
-    protected RemoteFleetService remoteFleetService;
+    private RemoteFleetService remoteFleetService;
 
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private RemoteContractService remoteContractService;
 
-    private final CancelHandler cancelHandler;
+    @Autowired
+    LogisticsScoreFeignService logisticsScoreFeignService;
+
 
     /**
      * 定时任务:每5分钟执行一次
@@ -160,10 +167,8 @@ public class LogisticsOrderCompletionTask {
      * 可以根据实际需求调整执行频率
      */
     @Scheduled(cron = "${schedule.waybill-order-completion-cron}")
-    @Transactional(rollbackFor = Exception.class)
     public void processWaybillOrder() {
         log.info("超时取消运单定时任务开始...");
-
         try {
             // 查询状态为"已接单"的物流运单
             List<KwtWaybillOrder> waybillOrderOrders = waybillOrderRepository.list(
@@ -183,37 +188,23 @@ public class LogisticsOrderCompletionTask {
             //提取物流订单id
             Set<Long> logisticOrderIds = waybillOrderOrders.stream().map(KwtWaybillOrder::getLOrderId).collect(Collectors.toSet());
 
-            //物流订单和企业映射
-            List<KwtLogisticsOrderUnit> logisticsOrderUnits = logisticsOrderUnitRepository.queryByLOrderIdsAndUnitType(logisticOrderIds, 2);
+            //物流订单和合同映射
+//            List<KwtLogisticsOrderContract> logisticsOrderContracts = logisticsOrderContractRepository.queryByLogOrderIds(logisticOrderIds);
+//            Map<Long, KwtLogisticsOrderContract> logisticsOrderAndContractMap = logisticsOrderContracts.stream()
+//                    .collect(Collectors.toMap(KwtLogisticsOrderContract::getLOrderId, Function.identity(), (x, y) -> x));
+//
+//            Set<Long> contractIds = logisticsOrderContracts.stream().map(KwtLogisticsOrderContract::getContractId).collect(Collectors.toSet());
+//            remoteContractService.queryContractUnitByContractId()
+
+            List<KwtLogisticsOrderUnit> logisticsOrderUnits = logisticsOrderUnitRepository.queryByLOrderIdsAndUnitType(logisticOrderIds, 1);
             Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap = logisticsOrderUnits.stream()
                     .collect(Collectors.toMap(KwtLogisticsOrderUnit::getLOrderId, Function.identity(), (x, y) -> x));
             if (MapUtils.isEmpty(logisticsOrderAndUnitMap)) {
                 throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找的物流订单和企业映射信息!");
             }
 
-            //过滤超时的运单
-            List<KwtWaybillOrder> nearingCompletionOrders = new ArrayList<>();
-
-            for (Map.Entry<Long, List<KwtWaybillOrder>> entry : waybillOrderAndLogOrderMap.entrySet()) {
-                Long logisticOrderId = entry.getKey();
-                //物流运单
-                List<KwtWaybillOrder> waybillOrderList = entry.getValue();
-                //供应商企业信息
-                KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderAndUnitMap.get(logisticOrderId);
-                TruckDispatchCoefficientVO truckDispatchVO = remoteFleetService.findAutoTruckDispatchByEntId(logisticsOrderUnit.getEntId());
-                if (truckDispatchVO == null) {
-                    continue;
-                }
-                Integer driverTimeout = truckDispatchVO.getDriverTimeoutLimit();
-
-                for (KwtWaybillOrder waybillOrder : waybillOrderList) {
-                    Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(waybillOrder.getCreateTime(), new Date());
-                    if (timeDiffMinutes > driverTimeout.longValue()) {
-                        nearingCompletionOrders.add(waybillOrder);
-
-                    }
-                }
-            }
+            // 过滤超时的运单
+            List<KwtWaybillOrder> nearingCompletionOrders = getKwtWaybillOrders(waybillOrderAndLogOrderMap, logisticsOrderAndUnitMap);
 
             // 如果没有需要更新的物流运单,则直接返回
             if (CollectionUtils.isEmpty(nearingCompletionOrders)){
@@ -225,20 +216,12 @@ public class LogisticsOrderCompletionTask {
             for (KwtWaybillOrder waybillOrder : nearingCompletionOrders) {
                 try {
                     //执行取消运单
-                    processSingleWaybillOrder(waybillOrder);
+                    processSingleWaybillOrder(waybillOrder, logisticsOrderAndUnitMap);
+                    //异步处理
+                    handleCancelActions(waybillOrder, logisticsOrderAndUnitMap);
                     successOrders.add(waybillOrder);
                 } catch (Exception e) {
-                    log.error("处理运单失败,ID: {}", waybillOrder.getId(), e);
-                }
-            }
-
-            //事务提交后,批量解绑车辆
-            for (KwtWaybillOrder order : successOrders) {
-                try {
-                    remoteFleetService.unbindTruck(order.getEntId(), order.getDriverId());
-                    log.info("解绑车辆成功: 运单ID={}", order.getId());
-                } catch (Exception e) {
-                    log.error("解绑车辆失败,运单ID={}", order.getId(), e);
+                    log.error("处理运单ID:{} 失败", waybillOrder.getId(), e);
                 }
             }
 
@@ -249,24 +232,68 @@ public class LogisticsOrderCompletionTask {
         }
     }
 
+    /**
+     * 过滤超时的运单
+     * @param waybillOrderAndLogOrderMap
+     * @param logisticsOrderAndUnitMap
+     * @return
+     */
+    private List<KwtWaybillOrder> getKwtWaybillOrders(Map<Long, List<KwtWaybillOrder>> waybillOrderAndLogOrderMap,
+                                                      Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        //过滤超时的运单
+        List<KwtWaybillOrder> nearingCompletionOrders = new ArrayList<>();
+
+        //供应商企业id
+        List<Long> entIds = logisticsOrderAndUnitMap.values().stream().map(KwtLogisticsOrderUnit::getEntId).distinct().collect(Collectors.toList());
+        //查询自动派车系数
+        List<TruckDispatchCoefficientVO> dispatchList = remoteFleetService.findAutoTruckDispatchByEntIds(entIds);
+        Map<Long, TruckDispatchCoefficientVO> entIdToDispatchMap = dispatchList.stream().collect(
+                Collectors.toMap(TruckDispatchCoefficientVO::getEntId, Function.identity()));
+
+        for (Map.Entry<Long, List<KwtWaybillOrder>> entry : waybillOrderAndLogOrderMap.entrySet()) {
+            Long logisticOrderId = entry.getKey();
+            //物流运单
+            List<KwtWaybillOrder> waybillOrderList = entry.getValue();
+            //供应商企业信息
+            KwtLogisticsOrderUnit unit = logisticsOrderAndUnitMap.get(logisticOrderId);
+            //自动派车系数
+            TruckDispatchCoefficientVO truckDispatchVO = entIdToDispatchMap.get(unit.getEntId());
+            if (truckDispatchVO == null) {
+                continue;
+            }
+            //司机超时限制分钟数
+            Integer driverTimeout = truckDispatchVO.getDriverTimeoutLimit();
+            for (KwtWaybillOrder waybillOrder : waybillOrderList) {
+                Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(waybillOrder.getCreateTime(), new Date());
+                if (timeDiffMinutes > driverTimeout.longValue()) {
+                    nearingCompletionOrders.add(waybillOrder);
+                }
+            }
+        }
+        return nearingCompletionOrders;
+    }
 
     @Transactional(rollbackFor = Exception.class)
-    public void processSingleWaybillOrder(KwtWaybillOrder waybillOrder) {
-        //1.获取子运单任务量
-        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
-        if (subtask == null) {
-            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单!");
-        }
-        BigDecimal entrustAmount = subtask.getEntrustAmount();
+    public void processSingleWaybillOrder(KwtWaybillOrder waybillOrder, Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        try {
+            //1.获取子运单任务量
+            KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
+            if (subtask == null) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单!");
+            }
+            BigDecimal entrustAmount = subtask.getEntrustAmount();
 
-        //2.更新上游订单:更新物流订单运输量
-        updateLogOrder(waybillOrder, entrustAmount);
+            //2.更新上游订单:更新物流订单运输量
+            updateLogOrder(waybillOrder, entrustAmount);
 
-        //3. 更新状态
-        updateStatus(waybillOrder, subtask);
+            //3. 更新状态
+            updateStatus(waybillOrder, subtask);
 
-        //4. 生成节点轨迹
-        createNodeTrace(waybillOrder, subtask);
+            //4. 生成节点轨迹
+            createNodeTrace(waybillOrder, subtask);
+        } catch (Exception e) {
+            throw e; // 抛出异常,触发Seata全局回滚
+        }
 
     }
 
@@ -322,4 +349,85 @@ public class LogisticsOrderCompletionTask {
     }
 
 
+
+    @Async
+    public void handleCancelActions(KwtWaybillOrder waybillOrder, Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        try {
+            unbindTruck(waybillOrder);
+            checkArrivedLoadingPointTimeout(waybillOrder, logisticsOrderAndUnitMap);
+        } catch (Exception e) {
+            log.error("异步处理取消后动作失败", e);
+        }
+    }
+
+
+    /**
+     * 解绑车辆
+     * @param waybillOrder
+     */
+    private void unbindTruck(KwtWaybillOrder waybillOrder) {
+        remoteFleetService.unbindTruck(waybillOrder.getEntId(), waybillOrder.getDriverId());
+        log.info("解绑完成,解绑司机与车辆关系,运单id:{},企业id:{},司机id:{}", waybillOrder.getId(), waybillOrder.getEntId(), waybillOrder.getDriverId());
+    }
+
+    /**
+     * 司机超时到达装货点扣分
+     * @param waybillOrder
+     */
+    private void checkArrivedLoadingPointTimeout(KwtWaybillOrder waybillOrder, Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderAndUnitMap.get(waybillOrder.getLOrderId());
+        //供应商id
+        Long supEntId = logisticsOrderUnit.getEntId();
+        DriverConductRulesVO driverRulesVO = remoteFleetService.findDriverConductRulesByEntId(logisticsOrderUnit.getEntId());
+        if (driverRulesVO == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找到司机行为规则数据!");
+        }
+        Integer notOnTimeArrive = driverRulesVO.getNotOnTimeArriveScore();
+        if (notOnTimeArrive <= 0) {
+            log.warn("【司机未按时到场】司机扣分失败,企业{}的司机未按时到场分数配置异常,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机未按时到场】分数配置需大于0!");
+        }
+        //1、更新司机分数(减分)
+        notOnTimeArrive = -Math.abs(notOnTimeArrive);
+        updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), notOnTimeArrive, "司机未按时到场(超时)");
+
+        //2、更新企业分数(减分)
+        updateLogEntScore(waybillOrder, supEntId, notOnTimeArrive, "司机未按时到场");
+
+    }
+
+    /**
+     * 修改司机评分
+     * @param supeEntId
+     * @param entId
+     * @param driverId
+     * @param score
+     */
+    public void updateDriverScore(Long supeEntId, Long entId, Long driverId, Integer score, String action) {
+        RUpdateDriverScoreDto dto = new RUpdateDriverScoreDto();
+        dto.setSupEntId(supeEntId);
+        dto.setLogEntId(entId);
+        dto.setDriverId(driverId);
+        dto.setScore(BigDecimal.valueOf(score));
+        dto.setAction(action);
+
+        remoteFleetService.updateDriverScoreByEntId(dto);
+    }
+
+    /**
+     * 更新企业评分
+     * @param waybillOrder
+     * @param supplierId
+     * @param score
+     */
+    public void updateLogEntScore(KwtWaybillOrder waybillOrder, Long supplierId, Integer score, String remark) {
+        LogisticsScoreDetailFeignDto detailDto = new LogisticsScoreDetailFeignDto();
+        detailDto.setProviderEntId(supplierId);
+        detailDto.setLogisticsEntId(waybillOrder.getEntId());
+        detailDto.setInfluenceBy(waybillOrder.getDriverId());
+        detailDto.setAction(remark);
+        detailDto.setScoreChange(BigDecimal.valueOf(score));
+        logisticsScoreFeignService.updateLogisticsScore(detailDto);
+    }
+
 }