|
|
@@ -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());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|