Преглед на файлове

新增超时取消运单定时任务

donglang преди 12 часа
родител
ревизия
b9267cc7ba

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

@@ -661,7 +661,7 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
                 .eq(KwfTruckReport::getDelFlag, Global.NO)
                 .eq(KwfTruckReport::getStatus, Global.YES));
         if(truckReport == null) {
-            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "此司机无车辆解绑信息!");
+            return;
         }
         truckReport.setStatus(Global.NO);
         log.info("解绑车辆请求参数 :{}", truckReport);

+ 3 - 3
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfAutoDispatchService.java

@@ -84,9 +84,9 @@ public class KwfAutoDispatchService {
         KwfTruckDispatchCoefficient dispatchCoefficient = new KwfTruckDispatchCoefficient();
         dispatchCoefficient.setEntId(entId);
         dispatchCoefficient.setVehicleWorkHours(10);
-        dispatchCoefficient.setVehicleLoadingHours(1);
-        dispatchCoefficient.setVehicleUnloadingHours(1);
-        dispatchCoefficient.setDriverTimeoutLimit(2);
+        dispatchCoefficient.setVehicleLoadingHours(60);
+        dispatchCoefficient.setVehicleUnloadingHours(60);
+        dispatchCoefficient.setDriverTimeoutLimit(120);
         dispatchCoefficient.setVehicleAvgLoad(26);
         dispatchCoefficient.setVehicleAvgSpeed(50);
         dispatchCoefficient.setVehicleMaxTasks(3);

+ 2 - 3
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/CancelHandler.java

@@ -108,7 +108,7 @@ public class CancelHandler extends AbstractWaybillOrderHandler<WaybillOrderCance
         //查询运单运单信息
         KwtWaybillOrder waybillOrder = getWaybillOrder(wOrderId);
         remoteFleetService.unbindTruck(waybillOrder.getEntId(), waybillOrder.getDriverId());
-        log.info("运单完成,解绑司机与车辆关系,运单id:{},企业id:{},司机id:{}", wOrderId, waybillOrder.getEntId(), waybillOrder.getDriverId());
+        log.info("解绑完成,解绑司机与车辆关系,运单id:{},企业id:{},司机id:{}", wOrderId, waybillOrder.getEntId(), waybillOrder.getDriverId());
     }
 
     /**
@@ -166,7 +166,6 @@ public class CancelHandler extends AbstractWaybillOrderHandler<WaybillOrderCance
             log.warn("【司机违规取消运单】企业{}的司机违规取消运单分钟数/分数异常,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机违规取消运单】配置的分钟数/分数需大于0!");
         }
-        long cancelOrderInMillis = cancelOrderMinutes * 60 * 1000;
         //司机接单时间
         KwtWaybillOrderNode takingOrderNodes = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.PENDING_VEHICLE.getCode());
         Date takingOrderTime = takingOrderNodes.getCreateTime() != null ? takingOrderNodes.getCreateTime() : null;
@@ -176,7 +175,7 @@ public class CancelHandler extends AbstractWaybillOrderHandler<WaybillOrderCance
 
         // 计算两个时间的分钟差
         Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(takingOrderTime, cancelNodeTime);
-        if (timeDiffMinutes > cancelOrderInMillis) {
+        if (timeDiffMinutes > cancelOrderMinutes.longValue()) {
             log.info("【司机违规取消运单】超时!司机违规取消运单分钟数限制:" + cancelOrderMinutes + "分钟,实际:" + timeDiffMinutes + "分钟");
             //1、更新司机分数(减分)
             cancelOrderScore = -Math.abs(cancelOrderScore);

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

@@ -169,7 +169,6 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
             log.warn("【司机未按时到场】企业{}的司机超时限制配置异常,运单ID:{}", entId,wOrderId);
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机未按时到场】司机超时限制配置需大于0!");
         }
-        long driverTimeoutInMillis = driverTimeout * 60 * 1000;
         //司机接单时间
         KwtWaybillOrderNode takingOrderNodes = getNodesByOrderId(wOrderId, CarWaybillV1Enum.PENDING_VEHICLE.getCode());
         Date takingOrderTime = takingOrderNodes.getCreateTime() != null ? takingOrderNodes.getCreateTime() : null;
@@ -180,7 +179,7 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
         // 计算两个时间的分钟差
         Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(takingOrderTime, comeIntoTime);
         //超时
-        if (timeDiffMinutes > driverTimeoutInMillis) {
+        if (timeDiffMinutes > driverTimeout.longValue()) {
             log.info("司机到场耗时超时!司机超时限制:" + driverTimeout + "分钟,实际:" + timeDiffMinutes + "分钟");
             return true;
         }

+ 110 - 20
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/task/LogisticsOrderCompletionTask.java

@@ -12,11 +12,7 @@ import com.sckw.core.utils.DateUtils;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
 import com.sckw.transport.handler.CancelHandler;
-import com.sckw.transport.model.KwtLogisticsOrder;
-import com.sckw.transport.model.KwtLogisticsOrderUnit;
-import com.sckw.transport.model.KwtWaybillOrder;
-import com.sckw.transport.model.KwtWaybillOrderSubtask;
-import com.sckw.transport.model.param.WaybillOrderCancelParam;
+import com.sckw.transport.model.*;
 import com.sckw.transport.repository.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -25,7 +21,9 @@ import org.apache.commons.collections4.MapUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -46,6 +44,7 @@ public class LogisticsOrderCompletionTask {
     private final KwtWaybillOrderRepository waybillOrderRepository;
     private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;
     private final KwtLogisticsOrderUnitRepository logisticsOrderUnitRepository;
+    private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     protected RemoteFleetService remoteFleetService;
@@ -63,7 +62,7 @@ public class LogisticsOrderCompletionTask {
     @Scheduled(cron = "${schedule.logistics-order-completion-cron}")
     public void process() {
         log.info("物流订单自动完成定时任务开始...");
-        
+
         try {
             // 查询状态为"完结中"的物流订单
             List<KwtLogisticsOrder> nearingCompletionOrders = logisticsOrderRepository.list(
@@ -84,17 +83,17 @@ public class LogisticsOrderCompletionTask {
                     .stream()
                     .map(KwtLogisticsOrder::getId)
                     .collect(Collectors.toList());
-            
+
             // 根据物流订单ID查询相关运单子任务
             List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByLogIds(logisticOrderIds);
-            
+
             // 按照物流订单ID分组运单子任务
             Map<Long, List<KwtWaybillOrderSubtask>> logOrderSubtasksMap = Optional.ofNullable(subtasks)
                     .orElse(Collections.emptyList()).stream().collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));
-            
+
             // 准备需要更新的物流订单列表
             List<KwtLogisticsOrder> updateLogisticOrders = new ArrayList<>();
-            
+
             // 遍历每个物流订单及其关联的运单子任务
             logOrderSubtasksMap.forEach((logOrderId, subtaskList) -> {
                 try {
@@ -137,11 +136,11 @@ public class LogisticsOrderCompletionTask {
                 log.info("没有需要更新状态的物流订单");
                 return;
             }
-            
+
             // 批量更新物流订单状态
             boolean updated = logisticsOrderRepository.updateBatchById(updateLogisticOrders);
             Set<Long> logOrderIds = updateLogisticOrders.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
-            
+
             // 记录更新结果日志
             if (updated) {
                 log.info("物流订单自动完成定时任务结束,物流订单已更新为'已完成',订单ID:{},成功:{}条", JSON.toJSONString(logOrderIds), logOrderIds.size());
@@ -161,6 +160,7 @@ public class LogisticsOrderCompletionTask {
      * 可以根据实际需求调整执行频率
      */
     @Scheduled(cron = "${schedule.waybill-order-completion-cron}")
+    @Transactional(rollbackFor = Exception.class)
     public void processWaybillOrder() {
         log.info("超时取消运单定时任务开始...");
 
@@ -193,6 +193,7 @@ public class LogisticsOrderCompletionTask {
 
             //过滤超时的运单
             List<KwtWaybillOrder> nearingCompletionOrders = new ArrayList<>();
+
             for (Map.Entry<Long, List<KwtWaybillOrder>> entry : waybillOrderAndLogOrderMap.entrySet()) {
                 Long logisticOrderId = entry.getKey();
                 //物流运单
@@ -201,15 +202,15 @@ public class LogisticsOrderCompletionTask {
                 KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderAndUnitMap.get(logisticOrderId);
                 TruckDispatchCoefficientVO truckDispatchVO = remoteFleetService.findAutoTruckDispatchByEntId(logisticsOrderUnit.getEntId());
                 if (truckDispatchVO == null) {
-                    throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找到自动派车系数!");
+                    continue;
                 }
                 Integer driverTimeout = truckDispatchVO.getDriverTimeoutLimit();
-                long timestampInMillis = driverTimeout * 60 * 1000;
 
                 for (KwtWaybillOrder waybillOrder : waybillOrderList) {
                     Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(waybillOrder.getCreateTime(), new Date());
-                    if (timeDiffMinutes > timestampInMillis) {
+                    if (timeDiffMinutes > driverTimeout.longValue()) {
                         nearingCompletionOrders.add(waybillOrder);
+
                     }
                 }
             }
@@ -220,16 +221,105 @@ public class LogisticsOrderCompletionTask {
                 return;
             }
 
-            for (KwtWaybillOrder nearingCompletionOrder : nearingCompletionOrders) {
-                WaybillOrderCancelParam param = new WaybillOrderCancelParam();
-                param.setLogOrderId(nearingCompletionOrder.getLOrderId());
-                //执行取消接单
-                cancelHandler.handler(param);
+            List<KwtWaybillOrder> successOrders = new ArrayList<>();
+            for (KwtWaybillOrder waybillOrder : nearingCompletionOrders) {
+                try {
+                    //执行取消运单
+                    processSingleWaybillOrder(waybillOrder);
+                    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.info("查询到{}条状态为'已接单'的物流运单", nearingCompletionOrders.size());
         } catch (Exception e) {
             log.error("超时取消运单定时任务执行异常", e);
             throw new BusinessException("超时取消运单定时任务执行异常", e);
         }
     }
+
+
+    @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();
+
+        //2.更新上游订单:更新物流订单运输量
+        updateLogOrder(waybillOrder, entrustAmount);
+
+        //3. 更新状态
+        updateStatus(waybillOrder, subtask);
+
+        //4. 生成节点轨迹
+        createNodeTrace(waybillOrder, subtask);
+
+    }
+
+    /**
+     * 更新上游物流订单 - 减运输量
+     * @param waybillOrder
+     * @param entrustAmount
+     * @return
+     */
+    public KwtLogisticsOrder updateLogOrder(KwtWaybillOrder waybillOrder, BigDecimal entrustAmount) {
+        KwtLogisticsOrder logOrder = logisticsOrderRepository.queryByLogisticsOrderId(waybillOrder.getLOrderId());
+        if (logOrder == null) {
+            log.info("当前物流运单无关联物流订单数据:{}", waybillOrder.getLOrderId());
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_LOG_ORDER, "当前物流运单无关联物流订单数据!");
+        }
+        //取消接单的物流订单的总运输量不能为空
+        if (logOrder.getEntrustAmount() == null || logOrder.getEntrustAmount().compareTo(BigDecimal.ZERO) <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_AMOUNT_ERROR, "已接单物订单的总运单量不能为空或0!");
+        }
+        logOrder.setEntrustAmount(logOrder.getEntrustAmount().subtract(entrustAmount));
+        logisticsOrderRepository.updateById(logOrder);
+        log.info("更新上游物流订单运输量成功, 物流订单ID:{}", logOrder.getId());
+        return logOrder;
+    }
+
+    // 更新状态
+    public void updateStatus(KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask subtask) {
+        // 修改运单状态
+        waybillOrder.setStatus(CarWaybillV1Enum.CANCELLED.getCode());
+        waybillOrderRepository.updateById(waybillOrder);
+
+        //修改子运单状态
+        subtask.setStatus(CarWaybillV1Enum.CANCELLED.getCode());
+        waybillOrderSubtaskRepository.updateById(subtask);
+    }
+
+    // 生成节点轨迹
+    public void createNodeTrace(KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask subtask) {
+        if (waybillOrder == null) {
+            return;
+        }
+        KwtWaybillOrderNode node = new KwtWaybillOrderNode();
+        node.setWOrderId(waybillOrder.getId());
+        node.setWSubtaskId(subtask.getId());
+        node.setOrderStatus(waybillOrder.getStatus());
+        node.setTruckId(waybillOrder.getTruckId());
+        node.setTruckNo(waybillOrder.getTruckNo());
+        node.setDriverId(waybillOrder.getDriverId());
+        node.setDriverName(waybillOrder.getDriverName());
+        node.setRemark("司机[" + waybillOrder.getDriverName() + "]取消订单");
+        waybillOrderNodeRepository.save(node);
+        log.info("记录取消接单节点轨迹成功,节点ID:{}", node.getId());
+    }
+
+
 }