|
@@ -0,0 +1,141 @@
|
|
|
|
|
+package com.sckw.transport.task;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.google.common.collect.Lists;
|
|
|
|
|
+import com.sckw.core.exception.BusinessException;
|
|
|
|
|
+import com.sckw.core.model.enums.CarWaybillV1Enum;
|
|
|
|
|
+import com.sckw.core.model.enums.LogisticsOrderV1Enum;
|
|
|
|
|
+import com.sckw.transport.model.KwtLogisticsOrder;
|
|
|
|
|
+import com.sckw.transport.model.KwtWaybillOrderSubtask;
|
|
|
|
|
+import com.sckw.transport.repository.KwtLogisticsOrderRepository;
|
|
|
|
|
+import com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
+
|
|
|
|
|
+import java.lang.constant.Constable;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @desc: 物流订单自动完成定时任务
|
|
|
|
|
+ * @desc: 查询状态为"完结中"的物流订单,如果该订单下的所有运单状态都是"已完成",则将物流订单状态更新为"已完成"
|
|
|
|
|
+ * @author: cxf
|
|
|
|
|
+ * @date: 2025-01-XX
|
|
|
|
|
+ */
|
|
|
|
|
+@Component
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
|
|
+public class LogisticsOrderCompletionTask {
|
|
|
|
|
+
|
|
|
|
|
+ private final KwtLogisticsOrderRepository logisticsOrderRepository;
|
|
|
|
|
+ private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 定时任务:每5分钟执行一次
|
|
|
|
|
+ * cron表达式:0 0/5 * * * ? 表示每5分钟执行一次
|
|
|
|
|
+ * 可以根据实际需求调整执行频率
|
|
|
|
|
+ */
|
|
|
|
|
+ @Scheduled(cron = "0 0/5 * * * ?")
|
|
|
|
|
+ public void process() {
|
|
|
|
|
+ log.info("物流订单自动完成定时任务开始...");
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 查询状态为"完结中"的物流订单
|
|
|
|
|
+ List<KwtLogisticsOrder> nearingCompletionOrders = logisticsOrderRepository.list(
|
|
|
|
|
+ new LambdaQueryWrapper<KwtLogisticsOrder>()
|
|
|
|
|
+ .eq(KwtLogisticsOrder::getStatus, LogisticsOrderV1Enum.NEARING_COMPLETION.getCode())
|
|
|
|
|
+ .eq(KwtLogisticsOrder::getDelFlag, 0)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (CollectionUtils.isEmpty(nearingCompletionOrders)) {
|
|
|
|
|
+ log.info("没有状态为'完结中'的物流订单需要处理");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("查询到{}条状态为'完结中'的物流订单", nearingCompletionOrders.size());
|
|
|
|
|
+
|
|
|
|
|
+ // 提取物流订单ID列表
|
|
|
|
|
+ List<Long> logisticOrderIds = nearingCompletionOrders
|
|
|
|
|
+ .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<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 遍历每个物流订单及其关联的运单子任务
|
|
|
|
|
+ for (Map.Entry<Long, List<KwtWaybillOrderSubtask>> entry : logOrderSubtasksMap.entrySet()) {
|
|
|
|
|
+ Long logOrderId = entry.getKey();
|
|
|
|
|
+ List<KwtWaybillOrderSubtask> subtaskList = entry.getValue();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 如果没有运单,跳过
|
|
|
|
|
+ if (CollectionUtils.isEmpty(subtaskList)) {
|
|
|
|
|
+ log.warn("物流订单[{}]下没有运单,跳过处理", logOrderId);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查所有运单状态是否都是"已完成"(COMPLETED)和已取消(CANCELLED)
|
|
|
|
|
+
|
|
|
|
|
+ List<Integer> statusList = Arrays.asList(CarWaybillV1Enum.COMPLETED.getCode(), CarWaybillV1Enum.CANCELLED.getCode());
|
|
|
|
|
+ boolean allCompleted = subtaskList.stream()
|
|
|
|
|
+ .allMatch(subtask -> statusList.contains(subtask.getStatus()));
|
|
|
|
|
+
|
|
|
|
|
+ if (allCompleted) {
|
|
|
|
|
+ // 更新物流订单状态为"已完成"
|
|
|
|
|
+ KwtLogisticsOrder updateOrder = new KwtLogisticsOrder();
|
|
|
|
|
+ updateOrder.setId(logOrderId);
|
|
|
|
|
+ updateOrder.setStatus(LogisticsOrderV1Enum.COMPLETED.getCode());
|
|
|
|
|
+ updateOrder.setUpdateTime(new Date());
|
|
|
|
|
+ // 定时任务更新,updateBy 可以设置为系统用户或0
|
|
|
|
|
+ updateOrder.setUpdateBy(0L);
|
|
|
|
|
+ updateLogisticOrders.add(updateOrder);
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 存在未完成的运单,记录日志
|
|
|
|
|
+ long completedCount = subtaskList.stream()
|
|
|
|
|
+ .filter(subtask -> Objects.equals(subtask.getStatus(), CarWaybillV1Enum.COMPLETED.getCode()))
|
|
|
|
|
+ .count();
|
|
|
|
|
+ log.debug("物流订单下还有未完成的运单,已完成运单数:{}/{},订单ID:{}",
|
|
|
|
|
+ completedCount, subtaskList.size(), logOrderId);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理物流订单时发生异常,订单ID:{}", logOrderId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有需要更新的物流订单,则直接返回
|
|
|
|
|
+ if (CollectionUtils.isEmpty(updateLogisticOrders)){
|
|
|
|
|
+ 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());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.error("物流订单自动完成定时任务结束,物流订单状态更新失败,订单ID:{},失败:{}条", JSON.toJSONString(logOrderIds), logOrderIds.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("物流订单自动完成定时任务执行异常", e);
|
|
|
|
|
+ throw new BusinessException("物流订单自动完成定时任务执行异常", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|