Kaynağa Gözat

Merge remote-tracking branch 'origin/dev_20260131_youshen430' into dev_20260131_youshen430

xucaiqin 3 hafta önce
ebeveyn
işleme
cbcdc39fcd
27 değiştirilmiş dosya ile 1416 ekleme ve 218 silme
  1. 2 1
      sckw-auth/src/main/java/com/sckw/auth/service/impl/AuthServiceImpl.java
  2. 1 1
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/enums/CarWaybillV1Enum.java
  3. 15 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/enterpriseApp/AppGatekeeperController.java
  4. 14 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/enterpriseApp/AppWayBillController.java
  5. 1 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dubbo/TransportServiceImpl.java
  6. 7 3
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/AbstractWaybillOrderHandler.java
  7. 108 33
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/ComeIntoHandler.java
  8. 1 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/EmptyLoadLeaveHandler.java
  9. 6 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/LiftRodReleaseHandler.java
  10. 102 7
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/TakingOrderHandler.java
  11. 4 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java
  12. 15 2
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingWeighHandler.java
  13. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtWaybillOrder.java
  14. 2 2
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/enuma/WaybillTimelinePhaseEnum.java
  15. 6 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/LogisticsOrderResp.java
  16. 20 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/WaybillOrderStatusResp.java
  17. 34 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/WaybillOrderWeighImageParam.java
  18. 12 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/forklift/reponse/GatekeeperOrderResp.java
  19. 29 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/forklift/request/GatekeeperOrderIsPassParam.java
  20. 13 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/WaybillOrderDetailResp.java
  21. 7 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtForkliftWaybillOrderRepository.java
  22. 7 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderRepository.java
  23. 59 31
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java
  24. 76 39
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java
  25. 93 18
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/ForkliftOrderService.java
  26. 366 33
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/GatekeeperOrderService.java
  27. 411 45
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/WaybillOrderService.java

+ 2 - 1
sckw-auth/src/main/java/com/sckw/auth/service/impl/AuthServiceImpl.java

@@ -668,7 +668,8 @@ public class AuthServiceImpl implements IAuthService {
         }
         
         // 清除当前登录用户的token缓存(如果存在)
-        clearCurrentUserToken(clientType, deviceId);
+        // todo - 可以考虑只清除当前设备的token缓存,保留其他设备的登录状态 清除缓存这块产品说暂时先不要,以后单独登录在加
+       // clearCurrentUserToken(clientType, deviceId);
         
         // 构建LoginBase对象(使用新的deviceId)
         LoginBase loginBase = buildLoginBaseFromTokenInfo(targetTokenInfoMap);

+ 1 - 1
sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/enums/CarWaybillV1Enum.java

@@ -87,7 +87,7 @@ public enum CarWaybillV1Enum {
     /**
      * 卸货已放行待离场 (只有友盛在用)  弃用
      */
-    UNLOADING_RELEASED_WAIT_LEAVE(22, "卸货已放行待离场"),
+//    UNLOADING_RELEASED_WAIT_LEAVE(22, "卸货已放行待离场"),
 
     /**
      * 已卸货

+ 15 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/enterpriseApp/AppGatekeeperController.java

@@ -4,6 +4,7 @@ package com.sckw.transport.controller.enterpriseApp;
 import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.transport.model.param.forklift.reponse.GatekeeperOrderResp;
+import com.sckw.transport.model.param.forklift.request.GatekeeperOrderIsPassParam;
 import com.sckw.transport.model.param.forklift.request.GatekeeperOrderPassParam;
 import com.sckw.transport.model.param.forklift.request.GatekeeperOrderQueryParam;
 import com.sckw.transport.model.vo.StatisticsWaybillResp;
@@ -70,4 +71,18 @@ public class AppGatekeeperController {
         return BaseResult.success();
     }
 
+
+    /**
+     * 是否放行
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "放行", description = "放行")
+    @PostMapping("/isPass")
+    public BaseResult isPass(@RequestBody @Valid GatekeeperOrderIsPassParam param){
+        Boolean isPass = gatekeeperOrderService.checkIsPass(param);
+        return BaseResult.success(isPass);
+    }
+
 }

+ 14 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/enterpriseApp/AppWayBillController.java

@@ -416,4 +416,18 @@ public class AppWayBillController {
     }
 
 
+    /**
+     * 推送过磅图片
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "推送过磅图片", description = "推送过磅图片")
+    @PostMapping("/weighImage")
+    public BaseResult weighImage(@RequestBody @Valid WaybillOrderWeighImageParam param){
+        waybillOrderService.weighImage(param);
+        return BaseResult.success();
+    }
+
+
 }

+ 1 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dubbo/TransportServiceImpl.java

@@ -175,7 +175,7 @@ public class TransportServiceImpl implements TransportRemoteService {
             CarWaybillV1Enum.UNLOADING_POINT.getCode(),
             CarWaybillV1Enum.UNLOADING_WAIT_LEAVE.getCode(),
             CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode(),
-            CarWaybillV1Enum.UNLOADING_RELEASED_WAIT_LEAVE.getCode(),
+//            CarWaybillV1Enum.UNLOADING_RELEASED_WAIT_LEAVE.getCode(),
 
             CarWaybillV1Enum.REVIEW_REJECTION.getCode()
     );

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

@@ -113,7 +113,10 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
 
             log.info("{}处理完成", getProcessName());
             return handlerResult;
-        } finally {
+        } catch (Exception e) {
+            log.error("运单处理器异常!", e);
+            throw new BusinessPlatfromException(ErrorCodeEnum.SYSTEM_ERROR, e.getMessage());
+        }  finally {
             // 确保清理线程上下文,防止内存泄漏
             BusinessContext.clear();
         }
@@ -125,7 +128,8 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
         if (param == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "参数不能为空");
         }
-        if (!(param instanceof WaybillOrderCancelParam || param instanceof WaybillOrderCmeIntoWeighParam || param instanceof WaybillOrderUnloadingWeighParam)) {
+        if (!(param instanceof WaybillOrderCancelParam || param instanceof WaybillOrderCmeIntoWeighParam
+                || param instanceof WaybillOrderUnloadingWeighParam ||  param instanceof WaybillOrderReplenishParam)) {
             if (StringUtils.isBlank(param.getLng()) || StringUtils.isBlank(param.getLat())) {
                 throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "未获取到定位,请重启app后再次操作");
             }
@@ -136,7 +140,7 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
         }
         // 过磅校验
         if (param instanceof WaybillOrderCmeIntoWeighParam || param instanceof WaybillOrderUnloadingWeighParam) {
-            if (param.getWeighbridgeId() == null || param.getWeighbridgeName() == null || param.getWeighUrl() == null) {
+            if (param.getWeighbridgeId() == null || param.getWeighbridgeName() == null) {
                 throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "地磅信息不能为空");
             }
         }

+ 108 - 33
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/ComeIntoHandler.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessPlatfromException;
+import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.enums.*;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.DateUtils;
@@ -290,40 +291,97 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
         if (waybillSubtask.getEntrustAmount() == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.SYSTEM_ERROR, "[称重过磅]子运单任务量信息缺失!");
         }
+        //任务量
+        BigDecimal entrustAmount = waybillSubtask.getEntrustAmount();
+        //法定载重
+        BigDecimal truckStandardLoad = getTruckStandardLoad(param.getTruckNo());
 
+        // 校验铲车司机
         KwtForkliftWaybillOrder forklift = forkliftWaybillOrderRepository.queryForkliftWaybillOrderByWOrderId(waybillOrder.getId());
+
+        //1. 铲车司机已接单,运单什么都不展示
         if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.ORDER_TAKING.getCode())) {
             //如果铲车司机已接单,则二次过磅的时候,直接返回,不走其它流程
             return;
         }
 
-        BigDecimal entrustAmount = waybillSubtask.getEntrustAmount();
-        //场景一:净重<-0.5
-        if (loadAmount.compareTo(BigDecimal.valueOf(-0.5)) < 0) {
-            return;
-        }
-        //场景二:空载离场,-0.5<=净重<=0.5
-        if (loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0) {
-            waybillOrder.setTargetStatus(1);
-            return;
-        }
-        // 非空载情况,必须校验是否完成装载
-        if (!Objects.equals(CarWaybillV1Enum.EXIT_COMPLETED.getCode(), waybillOrder.getStatus())
-                && !Objects.equals(CarWaybillV1Enum.REPLENISH_FINISH.getCode(), waybillOrder.getStatus())
-                && !Objects.equals(CarWaybillV1Enum.WAIT_LEAVE.getCode(), waybillOrder.getStatus())
-                && !Objects.equals(CarWaybillV1Enum.UNLOADING.getCode(), waybillOrder.getStatus())) {
-            return;
+        //2. 铲车司机待接单,只分为“空载离场”和“其它情况”(什么不展示)
+        if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.PENDING_ORDERS.getCode())) {
+            //场景一. 空载离场,-0.5<=净重<=0.5
+            if (loadAmount.compareTo(BigDecimal.valueOf(-0.5)) >= 0 && loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0) {
+                waybillOrder.setTargetStatus(1);
+                return;
+            } else {
+                //场景二.非空载离场,什么都不展示
+                return;
+            }
         }
 
-        //法定载重
-        BigDecimal truckStandardLoad = getTruckStandardLoad(param.getTruckNo());
-        // 场景三:超载流程, 净重>任务量或者毛重>法定载重
-        if (loadAmount.compareTo(entrustAmount) > 0 || param.getWeighAmount().compareTo(truckStandardLoad) > 0) {
-            waybillOrder.setTargetStatus(3);
+        //3.铲车司机完成装载,是什么流程就是什么流程,按照最新一次过磅为准
+        if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.COMPLETED.getCode())) {
+            //场景一:净重<-0.5,什么不展示
+            if (loadAmount.compareTo(BigDecimal.valueOf(-0.5)) < 0) {
+                return;
+            }
+
+            //场景二:空载离场,-0.5<=净重<=0.5
+            if (loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0) {
+                waybillOrder.setTargetStatus(1);
+                return;
+            }
+
+            // 场景三:超载流程, 净重>任务量或者毛重>法定载重
+            if (loadAmount.compareTo(entrustAmount) > 0 || param.getWeighAmount().compareTo(truckStandardLoad) > 0) {
+                waybillOrder.setTargetStatus(3);
+                return;
+            }
+            // 场景四:正常流程,0.5<净重<=任务量
+            waybillOrder.setTargetStatus(2);
         }
 
-        // 场景四:正常流程,0.5<净重<=任务量
-        waybillOrder.setTargetStatus(2);
+
+//        //场景一:净重<-0.5
+//        if (loadAmount.compareTo(BigDecimal.valueOf(-0.5)) < 0) {
+//            return;
+//        }
+//        //场景二:空载离场,-0.5<=净重<=0.5
+//        if (loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0) {
+//            waybillOrder.setTargetStatus(1);
+//            return;
+//        }
+//
+//        if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.PENDING_ORDERS.getCode())) {
+//            //如果铲车司机未接单,则二次过磅的时候,非空载情况,必须校验是否完成装载
+//            //场景:铲车未接单,司机第一次空载离场,第二次空载离场,还是展示空载,其它什么不展示。(就是没有完成装货就什么都不展示)
+//            if (!Objects.equals(CarWaybillV1Enum.EXIT_COMPLETED.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.REPLENISH_FINISH.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.WAIT_LEAVE.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.UNLOADING.getCode(), waybillOrder.getStatus())) {
+//                //什么不展示
+//                return;
+//            }
+//        } else {
+//            //如果铲车司机完成装载,则二次过磅的时候,已最新的一次称重为准
+//            //场景:铲车未接单,司机第一次空载离场,然后铲车装货完成。 二次过磅,是什么流程就是什么流程
+//            if (!Objects.equals(CarWaybillV1Enum.EXIT_COMPLETED.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.REPLENISH_FINISH.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.WAIT_LEAVE.getCode(), waybillOrder.getStatus())
+//                    && !Objects.equals(CarWaybillV1Enum.UNLOADING.getCode(), waybillOrder.getStatus())) {
+//                return;
+//            }
+//        }
+//
+//        //法定载重
+//        BigDecimal truckStandardLoad = getTruckStandardLoad(param.getTruckNo());
+//        // 场景三:超载流程, 净重>任务量或者毛重>法定载重
+//        if (loadAmount.compareTo(entrustAmount) > 0 || param.getWeighAmount().compareTo(truckStandardLoad) > 0) {
+//            waybillOrder.setTargetStatus(3);
+//            return;
+//        }
+//
+//        // 场景四:正常流程,0.5<净重<=任务量
+//        waybillOrder.setTargetStatus(2);
 
     }
 
@@ -351,17 +409,34 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
         // 校验是否第一次过磅
         if (checkIsFirst(waybillOrder)) {
             status = CarWaybillV1Enum.REFUSE_TRAFFIC.getCode();
-        } else {
-            if (waybillOrder.getTargetStatus() == null) {
-                return;
-            }
-            status = switch (waybillOrder.getTargetStatus()) {
-                case 1 -> CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode();
-                case 2 -> CarWaybillV1Enum.WAIT_LEAVE.getCode();
-                case 3 -> CarWaybillV1Enum.UNLOADING.getCode();
-                default -> -1;
-            };
+            updateOrderStatus(waybillOrder, status);
+            return;
         }
+        // 后续过磅,只更新label
+        if (waybillOrder.getTargetStatus() == null) {
+            waybillOrder.setLabel(Global.NUMERICAL_ONE);
+            waybillOrderRepository.updateById(waybillOrder);
+            return;
+
+        }
+
+        waybillOrder.setLabel(Global.NUMERICAL_ZERO);
+        status = switch (waybillOrder.getTargetStatus()) {
+            case 1 -> CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode();
+            case 2 -> CarWaybillV1Enum.WAIT_LEAVE.getCode();
+            case 3 -> CarWaybillV1Enum.UNLOADING.getCode();
+            default -> -1;
+        };
+
+        updateOrderStatus(waybillOrder, status);
+    }
+
+    /**
+     * 修改运单状态
+     * @param waybillOrder
+     * @param status
+     */
+    private void updateOrderStatus(KwtWaybillOrder waybillOrder, Integer status) {
         // 1. 修改运单状态
         waybillOrder.setStatus(status);
         waybillOrderRepository.updateById(waybillOrder);

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

@@ -104,6 +104,7 @@ public class EmptyLoadLeaveHandler extends AbstractWaybillOrderHandler<WaybillOr
     protected void getStatus(KwtWaybillOrder waybillOrder) {
         // 1. 修改运单状态
         waybillOrder.setStatus(CarWaybillV1Enum.WAIT_RELEASE.getCode());
+        waybillOrder.setRemark("空载离场");
         waybillOrderRepository.updateById(waybillOrder);
 
         // 2. 修改子运单状态

+ 6 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/LiftRodReleaseHandler.java

@@ -105,6 +105,12 @@ public class LiftRodReleaseHandler extends AbstractWaybillOrderHandler<WaybillOr
      * @param waybillOrder
      */
     private void creatGatekeeperUnLoadingOrder(KwtWaybillOrder waybillOrder) {
+        // 只有原矿运输的才会新增卸货门卫订单
+        KwtLogisticsOrder logisticsOrder = getLogisticsOrder(waybillOrder.getLOrderId());
+        if (!Objects.equals(1, logisticsOrder.getOrderType())) {
+            return;
+        }
+
         RTruckVo truck = remoteFleetService.findTruckByTruckNo(waybillOrder.getTruckNo());
         if (truck == null || !Objects.equals(truck.getStatus(), 0)) {
             throw new BusinessPlatfromException(ErrorCodeEnum.TRUCK_STATUS_ERROR, "当前车辆非正常状态,不能接单!");

+ 102 - 7
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/TakingOrderHandler.java

@@ -66,6 +66,27 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
             CarWaybillV1Enum.REVIEW_REJECTION.getCode()
     );
 
+    // 定义禁止运单接单的状态集合
+    private static final List<Integer> RAW_ORE_FORBIDDEN_STATUSES = Arrays.asList(
+            CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
+            CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
+            CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
+            CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(),
+            CarWaybillV1Enum.WAIT_LEAVE.getCode(),
+            CarWaybillV1Enum.UNLOADING.getCode(),
+            CarWaybillV1Enum.WAIT_RELEASE.getCode(),
+            CarWaybillV1Enum.REPLENISHING.getCode(),
+            CarWaybillV1Enum.REPLENISH_FINISH.getCode(),
+            CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode(),
+            CarWaybillV1Enum.WAIT_LOADING.getCode(),
+
+            CarWaybillV1Enum.UNLOADING_POINT.getCode(),
+            CarWaybillV1Enum.UNLOADING_WAIT_LEAVE.getCode(),
+            CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode(),
+
+            CarWaybillV1Enum.REVIEW_REJECTION.getCode()
+    );
+
 
     @Override
     protected KwtWaybillOrder getWaybillOrder(OrderCirculateTakingQueryParam param) {
@@ -87,7 +108,7 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
         // 5.校验车辆
         RTruckVo truck = checkTruck(param);
         // 6.校验车辆是否已有未完成运单
-        checkTruckUnfinished(param);
+        checkTruckUnfinished(param, logOrder);
 
         // 存储到线程上下文
         BusinessContext.set("logOrder", logOrder);
@@ -106,7 +127,7 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
         RTruckVo truck = BusinessContext.get("truck");
 
         // 计算任务量(含接单校验)
-        BigDecimal truckLoadVolume = queryCurTruckLoadVolume(truck, tradeOrder);
+        BigDecimal truckLoadVolume = queryCurTruckLoadVolume(truck, tradeOrder, logOrder);
 
         //1、生成物流运单
         KwtWaybillOrder waybillOrder = createWaybillOrder(param, driver, truck, logOrder);
@@ -215,6 +236,10 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
      * @return
      */
     private OrderDetailVo checkTradeOrder(OrderCirculateTakingQueryParam param, KwtLogisticsOrder logOrder) {
+        // 原矿运输没有贸易订单
+        if (Objects.equals(1, logOrder.getOrderType())) {
+            return new OrderDetailVo();
+        }
         OrderDetailVo orderDetail = tradeOrderInfoService.queryByTradeOrderId(logOrder.getTOrderId());
         if (orderDetail == null || orderDetail.getStatus() == Global.NUMERICAL_ONE) {
             throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_STATUS_ERROR, "当前物流订单的交易订单已锁定");
@@ -276,8 +301,15 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
      * 校验车辆是否已有未完成运单(不可继续接单状态:已接单、已入场、已装货、已离场、审核驳回)
      * @param param
      */
-    private void checkTruckUnfinished(OrderCirculateTakingQueryParam param) {
-        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
+    private void checkTruckUnfinished(OrderCirculateTakingQueryParam param, KwtLogisticsOrder logOrder) {
+        // 原矿运输
+        List<KwtWaybillOrder> wbOrderByTruckNo;
+        if (Objects.equals(1, logOrder.getOrderType())) {
+            wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), RAW_ORE_FORBIDDEN_STATUSES);
+        } else {
+            // 正常流程
+            wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
+        }
         if (CollectionUtils.isNotEmpty(wbOrderByTruckNo)) {
             throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_UNFINISHED, "当前车辆有未完成的状态,不可继续接单");
         }
@@ -295,7 +327,7 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
      *
      * @param truckNo
      */
-    private BigDecimal queryCurTruckLoadVolume(RTruckVo truckNo, OrderDetailVo tradeOrder) {
+    private BigDecimal queryCurTruckLoadVolume(RTruckVo truckNo, OrderDetailVo tradeOrder, KwtLogisticsOrder logOrder) {
         log.info("开始计算当前车辆任务量!");
         //核定载重
         BigDecimal actualWeight = truckNo.getLegalLoad();
@@ -314,8 +346,8 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
             log.info("车辆无皮重,按80%核定载重计算,车辆任务量:{}", loadVolume);
         }
 
-        //订单余量
-        BigDecimal remainingAmount = getRemainingAmount(tradeOrder);
+        //订单余量:区分正常流程和原矿运输
+        BigDecimal remainingAmount = Objects.equals(1, logOrder.getOrderType()) ? getRawOreSupAmount(logOrder) : getRemainingAmount(tradeOrder);
 
         // 最终接取的任务量
         BigDecimal taskAmount;
@@ -383,6 +415,69 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
         return remainingAmount;
     }
 
+
+    /**
+     * 计算贸易订单余量
+     * 逻辑:贸易订单总量 - (所有关联物流订单下,非取消/完成状态的子运单委托量 + 对应计费模式的磅单量)
+     *
+     * @return 订单余量,保留两位小数
+     */
+    private BigDecimal getRawOreSupAmount(KwtLogisticsOrder order) {
+        log.debug("开始计算物流订单余量,param: {}", JSON.toJSONString(order));
+
+        // 1. 获取贸易订单总货物量
+        BigDecimal tradeAmount = order.getAmount();
+        log.debug("物流订单[{}]总货物量: {}", order.getId(), tradeAmount);
+
+        Long logOrderId = order.getId();
+        // 获取当前物流订单下的所有子运单
+        List<KwtWaybillOrderSubtask> waybillOrderSubtasks = waybillOrderSubtaskRepository.queryByLogId(logOrderId);
+
+        if (CollectionUtils.isEmpty(waybillOrderSubtasks)) {
+            BigDecimal tradeTotalAmount = tradeAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount;
+            BigDecimal bigDecimal = tradeTotalAmount.setScale(2, RoundingMode.HALF_UP);
+            log.debug("物流订单[{}]无子运单,跳过, 最终余量: {}",logOrderId, bigDecimal);
+            return bigDecimal;
+        }
+
+        // 定义需要剔除的状态:已取消、已完成、空载(这些状态下的运单不再占用当前可接单的余量,或者其量已结算)
+        // 注意:具体业务逻辑中,通常“进行中”的运单会占用余量。这里根据原代码逻辑,剔除CANCELLED和COMPLETED。
+        //      空载待离场,实际装货量接近0,所以也要剔除
+        List<Integer> excludeStatusList = Arrays.asList(CarWaybillV1Enum.CANCELLED.getCode(), CarWaybillV1Enum.COMPLETED.getCode()
+                , CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode());
+
+        // 4. 计算子运单委托量合计(仅统计未取消/未完成/空载的有效子运单)
+        BigDecimal entrustAmount = waybillOrderSubtasks.stream()
+                .filter(Objects::nonNull)
+                .filter(subtask -> !excludeStatusList.contains(subtask.getStatus()))
+                .map(KwtWaybillOrderSubtask::getEntrustAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+        log.debug("物流订单[{}]子运单委托量合计: {}", logOrderId, entrustAmount);
+
+        // 5. 计算运单已完成的合计量
+        BigDecimal totalLoadAmount = order.getTotalLoadAmount();
+        totalLoadAmount = totalLoadAmount == null || totalLoadAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : totalLoadAmount;
+        log.debug("物流订单[{}]有完成的运单实际装货量合计: {}", logOrderId, totalLoadAmount);
+
+        // 累加到总占用量
+        BigDecimal usedAmount = entrustAmount.add(totalLoadAmount);
+
+        log.debug("物流订单[{}]总占用量: {}", logOrderId, usedAmount);
+
+        // 6. 计算余量:贸易订单总量 - 已占用量
+        // 如果计算结果小于等于0,则余量为0,避免负数
+        BigDecimal surplus = tradeAmount.subtract(usedAmount);
+        BigDecimal finalSurplus = surplus.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : surplus;
+
+        // 保留两位小数,四舍五入
+        BigDecimal result = finalSurplus.setScale(2, RoundingMode.HALF_UP);
+        log.debug("物流订单[{}]最终余量: {}", logOrderId, result);
+
+        return result;
+    }
+
     /**
      * 创建物流运单
      *

+ 4 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java

@@ -247,6 +247,10 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
      * 更新贸易订单装货量
      */
     private void updateTradeOrder(KwtLogisticsOrder logisticsOrder, BigDecimal loadAmount) {
+        // 原矿运输没有贸易订单
+        if (Objects.equals(1, logisticsOrder.getOrderType())) {
+            return;
+        }
         //贸易订单装货量累加
         TradeOrderSettlePara tradeOrderSettlePara = new TradeOrderSettlePara();
         tradeOrderSettlePara.setTOrderId(logisticsOrder.getTOrderId());

+ 15 - 2
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingWeighHandler.java

@@ -166,7 +166,7 @@ public class UnloadingWeighHandler extends AbstractWaybillOrderHandler<WaybillOr
         }
 
         // 1.填充运单卸货单皮重、净重
-        updateTareAmount(param, takeTicket);
+        updateTareAmount(param, waybillOrder, takeTicket);
 
         // 2.创建卸货过磅记录
         createWeighbridges(waybillOrder);
@@ -177,7 +177,7 @@ public class UnloadingWeighHandler extends AbstractWaybillOrderHandler<WaybillOr
      * @param param
      * @param takeTicket
      */
-    private void updateTareAmount(WaybillOrderUnloadingWeighParam param, KwtWaybillOrderTicket takeTicket) {
+    private void updateTareAmount(WaybillOrderUnloadingWeighParam param, KwtWaybillOrder waybillOrder, KwtWaybillOrderTicket takeTicket) {
         //皮重
         BigDecimal tareAmount = param.getWeighAmount();
         //毛重
@@ -188,8 +188,21 @@ public class UnloadingWeighHandler extends AbstractWaybillOrderHandler<WaybillOr
         takeTicket.setTareAmount(tareAmount);
         takeTicket.setAmount(unloadAmount);
         waybillOrderTicketRepository.updateById(takeTicket);
+
+        //2.更新子运单卸货量
+        updateWaybillOrderSubtask(waybillOrder, unloadAmount);
     }
 
+    /**
+     * 更新子运单卸货量
+     * @param waybill
+     */
+    private void updateWaybillOrderSubtask(KwtWaybillOrder waybill, BigDecimal unloadAmount) {
+        KwtWaybillOrderSubtask subtask = getWaybillSubtask(waybill.getId());
+        subtask.setUnloadAmount(unloadAmount);
+        subtask.setUnloadTime(new Date());
+        waybillOrderSubtaskRepository.updateById(subtask);
+    }
 
 
     @Override

+ 5 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtWaybillOrder.java

@@ -177,6 +177,11 @@ public class KwtWaybillOrder implements Serializable {
      */
     private Integer dispatchWay;
 
+    /**
+     * 标签
+     */
+    private Integer label;
+
     //用于存储动态状态
     @TableField(exist = false)
     private Integer targetStatus;

+ 2 - 2
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/enuma/WaybillTimelinePhaseEnum.java

@@ -36,8 +36,8 @@ public enum WaybillTimelinePhaseEnum {
                     CarWaybillV1Enum.WAIT_LOADING,
                     CarWaybillV1Enum.UNLOADING_POINT,
                     CarWaybillV1Enum.UNLOADING_WAIT_LEAVE,
-                    CarWaybillV1Enum.UNLOADING_WAIT_RELEASE,
-                    CarWaybillV1Enum.UNLOADING_RELEASED_WAIT_LEAVE
+                    CarWaybillV1Enum.UNLOADING_WAIT_RELEASE
+//                    CarWaybillV1Enum.UNLOADING_RELEASED_WAIT_LEAVE
             )),
 
     UNLOADED(25, "已卸货",

+ 6 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/LogisticsOrderResp.java

@@ -199,4 +199,10 @@ public class LogisticsOrderResp implements Serializable {
     @Schema(description = "订单余量")
     private BigDecimal remainingAmount;
 
+    /**
+     * 订单类型
+     */
+    @Schema(description = "订单类型(1-原矿转运)")
+    private Integer orderType;
+
 }

+ 20 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/WaybillOrderStatusResp.java

@@ -1,12 +1,13 @@
 package com.sckw.transport.model.param;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotBlank;
 import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * @author :chenXiaoFei
@@ -216,4 +217,22 @@ public class WaybillOrderStatusResp implements Serializable {
      */
     @Schema(description = "备注(是否空载离场)")
     private String remark;
+
+    /**
+     * 订单类型
+     */
+    @Schema(description = "订单类型(1-原矿转运)")
+    private Integer orderType;
+
+    /**
+     * 更新时间
+     */
+    @Schema(description = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    /**
+     * 标签
+     */
+    private Integer label;
 }

+ 34 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/WaybillOrderWeighImageParam.java

@@ -0,0 +1,34 @@
+package com.sckw.transport.model.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author :donglang
+ * @version :1.0
+ * @description : 车辆过磅入参信息
+ * @create :2025-11-13 08:59:00
+ */
+@Data
+public class WaybillOrderWeighImageParam extends WaybillOrderProcessParam implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1038619782660342061L;
+
+    /**
+     * 车辆号
+     */
+    @Schema(description = "车辆号")
+    private String truckNo;
+
+    /**
+     * 称重重量(毛重/皮重)
+     */
+    @Schema(description = "称重重量")
+    private List<String> weighImageList;
+
+}

+ 12 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/forklift/reponse/GatekeeperOrderResp.java

@@ -203,6 +203,18 @@ public class GatekeeperOrderResp implements Serializable {
     @Schema(description = "备注")
     private String remark;
 
+    /**
+     * 订单类型
+     */
+    @Schema(description = "订单类型")
+    private Integer orderType;
+
+    /**
+     * 订单类型
+     */
+    @Schema(description = "订单类型")
+    private String orderTypeDesc;
+
 
 
 }

+ 29 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/forklift/request/GatekeeperOrderIsPassParam.java

@@ -0,0 +1,29 @@
+package com.sckw.transport.model.param.forklift.request;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author :donglang
+ * @version :1.0
+ * @description :
+ * @create :2026-01-05 08:59:00
+ */
+@Data
+public class GatekeeperOrderIsPassParam implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -767569553526384839L;
+
+    /**
+     * 车牌号
+     */
+    @Schema(description = "车牌号")
+    @NotBlank(message = "车牌号不能为空")
+    private String truckNo;
+
+}

+ 13 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/WaybillOrderDetailResp.java

@@ -110,10 +110,16 @@ public class WaybillOrderDetailResp implements Serializable {
     @Schema(description = "任务量")
     private String taskVolume;
 
+    /**
+     * 任务量(不带单位)
+     */
+    @Schema(description = "任务量(不带单位)")
+    private BigDecimal taskNum;
+
     /**
      * 装货量(不带单位)
      */
-    @Schema(description = "(不带单位)")
+    @Schema(description = "装货量(不带单位)")
     private BigDecimal loadingNetWeight;
 
     /**
@@ -247,6 +253,12 @@ public class WaybillOrderDetailResp implements Serializable {
      */
     @Schema(description = "单据信息")
     private BillInfo billInfo;
+
+    /**
+     * 标签
+     */
+    private Integer label;
+
     /**
      * 运单id列表
      */

+ 7 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtForkliftWaybillOrderRepository.java

@@ -65,6 +65,13 @@ public class KwtForkliftWaybillOrderRepository extends ServiceImpl<KwtForkliftWa
                 .last("limit 1"));
     }
 
+    public List<KwtForkliftWaybillOrder> queryForkliftWaybillOrdersByWOrderId(Long wOrderId) {
+        return list(Wrappers.<KwtForkliftWaybillOrder>lambdaQuery()
+                .eq(KwtForkliftWaybillOrder::getWOrderId, wOrderId)
+                .orderByDesc(KwtForkliftWaybillOrder::getId)
+                .orderByDesc(KwtForkliftWaybillOrder::getCreateTime));
+    }
+
 
 
 

+ 7 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderRepository.java

@@ -358,4 +358,11 @@ public class KwtWaybillOrderRepository extends ServiceImpl<KwtWaybillOrderMapper
         return page(page,wrapper);
     }
 
+    public List<KwtWaybillOrder> findWbOrderByTruckNo(String truckNo) {
+        return list(Wrappers.<KwtWaybillOrder>lambdaQuery()
+                .eq(KwtWaybillOrder::getDelFlag,0)
+                .eq(KwtWaybillOrder::getTruckNo,truckNo)
+                .orderByDesc(KwtWaybillOrder::getId));
+    }
+
 }

+ 59 - 31
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java

@@ -3220,19 +3220,8 @@ public class KwtLogisticsConsignmentService {
         BigDecimal unloadAmount = BigDecimal.ZERO;
         //用于计算
         BigDecimal totalAmount = BigDecimal.ZERO;
-        if (org.apache.commons.lang3.StringUtils.equals(kwtLogisticsOrder.getBillingMode(),
-                DictEnum.CHARGING_TYPE_1.getValue())) {
-            loadAmount = subtasks.stream().filter(x->Objects.nonNull(x.getLoadAmount()))
-                    .map(KwtWaybillOrderSubtask::getLoadAmount)
-                    .reduce(BigDecimal.ZERO, BigDecimal::add);
-            transportPrice = Objects.nonNull(kwtLogisticsOrder.getPrice()) ? loadAmount.multiply(kwtLogisticsOrder.getPrice()) :
-                    BigDecimal.ZERO;
-           // logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
-            logisticsOrderResp.setUnloadAmount("-");
-           // logisticsOrderResp.setActualTransportPrice(transportPrice.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);
-
-        } else if (org.apache.commons.lang3.StringUtils.equals(kwtLogisticsOrder.getBillingMode(),
-                DictEnum.CHARGING_TYPE_2.getValue())) {
+        if (Objects.equals(kwtLogisticsOrder.getOrderType(),1)){
+            log.info("订单类型为1,原矿转运");
             loadAmount = subtasks.stream().filter(x->Objects.nonNull(x.getLoadAmount()))
                     .map(KwtWaybillOrderSubtask::getLoadAmount)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
@@ -3242,11 +3231,39 @@ public class KwtLogisticsConsignmentService {
             transportPrice = Objects.nonNull(kwtLogisticsOrder.getPrice()) ? unloadAmount.multiply(kwtLogisticsOrder.getPrice()) :
                     BigDecimal.ZERO;
 
-           // logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
-            logisticsOrderResp.setUnloadAmount(unloadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
-            //logisticsOrderResp.setActualTransportPrice(transportPrice.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);
+            // logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
+            logisticsOrderResp.setUnloadAmount(unloadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() +"吨");
+            logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() +"吨");
+        }else {
+            log.info("订单类型不为1,普通订单");
+            if (org.apache.commons.lang3.StringUtils.equals(kwtLogisticsOrder.getBillingMode(),
+                    DictEnum.CHARGING_TYPE_1.getValue())) {
+                loadAmount = subtasks.stream().filter(x->Objects.nonNull(x.getLoadAmount()))
+                        .map(KwtWaybillOrderSubtask::getLoadAmount)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                transportPrice = Objects.nonNull(kwtLogisticsOrder.getPrice()) ? loadAmount.multiply(kwtLogisticsOrder.getPrice()) :
+                        BigDecimal.ZERO;
+                // logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
+                logisticsOrderResp.setUnloadAmount("-");
+                // logisticsOrderResp.setActualTransportPrice(transportPrice.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);
+
+            } else if (org.apache.commons.lang3.StringUtils.equals(kwtLogisticsOrder.getBillingMode(),
+                    DictEnum.CHARGING_TYPE_2.getValue())) {
+                loadAmount = subtasks.stream().filter(x->Objects.nonNull(x.getLoadAmount()))
+                        .map(KwtWaybillOrderSubtask::getLoadAmount)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                unloadAmount = subtasks.stream().filter(x->Objects.nonNull(x.getUnloadAmount()))
+                        .map(KwtWaybillOrderSubtask::getUnloadAmount)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                transportPrice = Objects.nonNull(kwtLogisticsOrder.getPrice()) ? unloadAmount.multiply(kwtLogisticsOrder.getPrice()) :
+                        BigDecimal.ZERO;
+
+                // logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
+                logisticsOrderResp.setUnloadAmount(unloadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
+                //logisticsOrderResp.setActualTransportPrice(transportPrice.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);
+            }
+            logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
         }
-        logisticsOrderResp.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + kwtLogisticsOrder.getUnit());
         logisticsOrderResp.setActualTransportPrice(transportPrice.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);
 //        logisticsOrderResp.setActualTransportPrice(actualTransportPrice.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);
 //        logisticsOrderResp.setLoadAmount((Objects.nonNull(kwtLogisticsOrder.getLoadAmount()) ?
@@ -3516,24 +3533,35 @@ public class KwtLogisticsConsignmentService {
         BigDecimal totalCarriageCost = BigDecimal.ZERO;
         //用于计算
         BigDecimal totalAmount = BigDecimal.ZERO;
-        if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(),
-                DictEnum.CHARGING_TYPE_1.getValue())) {
-            totalCarriageCost = Objects.nonNull(logisticsOrder.getPrice()) ? loadAmount.multiply(logisticsOrder.getPrice()) :
-                    BigDecimal.ZERO;
-            performanceInfoVO.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
-            performanceInfoVO.setUnloadAmount("-");
-            BigDecimal surplusAmount = tradeAmount.subtract(orderAmount.add(loadAmount)).compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount.subtract(orderAmount.add(loadAmount));
-            performanceInfoVO.setSurplusAmount(surplusAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
-
-        } else if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(),
-                DictEnum.CHARGING_TYPE_2.getValue())) {
+        if (Objects.equals(logisticsOrder.getOrderType(), 1)){
+            log.info("物流单类型为1,原矿转运");
             totalCarriageCost = Objects.nonNull(logisticsOrder.getPrice()) ? unloadAmount.multiply(logisticsOrder.getPrice()) :
                     BigDecimal.ZERO;
-            performanceInfoVO.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
-            performanceInfoVO.setUnloadAmount(unloadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
+            performanceInfoVO.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + "吨");
+            performanceInfoVO.setUnloadAmount(unloadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + "吨");
             BigDecimal surplusAmount = tradeAmount.subtract(orderAmount.add(unloadAmount)).compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount.subtract(orderAmount.add(unloadAmount));
-            performanceInfoVO.setSurplusAmount(surplusAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
+            performanceInfoVO.setSurplusAmount(surplusAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + "吨");
+        }else {
+            log.info("物流单类型不为1,普通物流");
+            if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(),
+                    DictEnum.CHARGING_TYPE_1.getValue())) {
+                totalCarriageCost = Objects.nonNull(logisticsOrder.getPrice()) ? loadAmount.multiply(logisticsOrder.getPrice()) :
+                        BigDecimal.ZERO;
+                performanceInfoVO.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
+                performanceInfoVO.setUnloadAmount("-");
+                BigDecimal surplusAmount = tradeAmount.subtract(orderAmount.add(loadAmount)).compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount.subtract(orderAmount.add(loadAmount));
+                performanceInfoVO.setSurplusAmount(surplusAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
+
+            } else if (org.apache.commons.lang3.StringUtils.equals(logisticsOrder.getBillingMode(),
+                    DictEnum.CHARGING_TYPE_2.getValue())) {
+                totalCarriageCost = Objects.nonNull(logisticsOrder.getPrice()) ? unloadAmount.multiply(logisticsOrder.getPrice()) :
+                        BigDecimal.ZERO;
+                performanceInfoVO.setLoadAmount(loadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
+                performanceInfoVO.setUnloadAmount(unloadAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
+                BigDecimal surplusAmount = tradeAmount.subtract(orderAmount.add(unloadAmount)).compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount.subtract(orderAmount.add(unloadAmount));
+                performanceInfoVO.setSurplusAmount(surplusAmount.setScale(2, RoundingMode.HALF_UP).toPlainString() + logisticsOrder.getUnit());
 
+            }
         }
         String priceUnit = Optional.ofNullable(kwpGoods).map(KwpGoods::getPriceUnit).orElse("");
         performanceInfoVO.setTotalCarriageCost(totalCarriageCost.setScale(2, RoundingMode.HALF_UP).toPlainString() + priceUnit);

+ 76 - 39
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java

@@ -4266,11 +4266,18 @@ public class KwtWaybillOrderV1Service {
         CompletableFuture<KwtLogisticsOrderGoods> goodsFuture = CompletableFuture.supplyAsync(() ->
                 kwtLogisticsOrderGoodsRepository.queryByLogOrderId(logOrder.getId()),traceTaskExecutor);
 
-        CompletableFuture<OrderDetailVo> orderDetailFuture = CompletableFuture.supplyAsync(() ->
-                getOrderDetail(logOrder.getTOrderId()),traceTaskExecutor).exceptionally(ex -> {
-            log.error("异步任务执行失败", ex);
-            throw new BusinessException("查询订单详情失败");
-        });
+        CompletableFuture<OrderDetailVo> orderDetailFuture;
+        //1.正常流程
+        if (!Objects.equals(1, logOrder.getOrderType())) {
+            orderDetailFuture = CompletableFuture.supplyAsync(() ->
+                    getOrderDetail(logOrder.getTOrderId()),traceTaskExecutor).exceptionally(ex -> {
+                log.error("异步任务执行失败", ex);
+                throw new BusinessException("查询订单详情失败");
+            });
+        } else {
+            //2.原矿运输
+            orderDetailFuture = CompletableFuture.completedFuture(null);
+        }
 
         CompletableFuture<List<KwtLogisticsOrderUnit>> unitFuture = CompletableFuture.supplyAsync(() ->
                 kwtLogisticsOrderUnitRepository.queryByLOrderId(logOrder.getId()),traceTaskExecutor);
@@ -4282,33 +4289,49 @@ public class KwtWaybillOrderV1Service {
                 kwtWaybillOrderSubtaskRepository.queryByLogId(logOrder.getId()),traceTaskExecutor);
 
 
-        CompletableFuture<TradeContractGoodsDto> contractFuture =
-                goodsFuture.thenCompose(goods -> {
-                    Long goodsId = Optional.ofNullable(goods)
-                            .map(KwtLogisticsOrderGoods::getGoodsId)
-                            .orElse(null);
-                    log.debug("开始查询合同信息,贸易订单ID: {}, 商品ID: {}", logOrder.getTOrderId(), goodsId);
-
-                    return CompletableFuture
-                            .supplyAsync(
-                                    () -> tradeOrderInfoService.queryByContractByTradeOrderId(logOrder.getTOrderId()), traceTaskExecutor)
-                            .thenCompose(tradeOrderInfo -> {
-                                log.debug("贸易订单合同信息查询完成,合同ID: {}", tradeOrderInfo.getContractId());
-                                return CompletableFuture.supplyAsync(
-                                        () -> remoteContractService.queryContractGoodsByContractId(tradeOrderInfo.getContractId(), goodsId), traceTaskExecutor
-                                );
-                            });
-                }).exceptionally(ex -> {
-                    log.error("异步任务执行失败", ex);
-                    throw new BusinessException("查询合同信息失败");
-                });
+        CompletableFuture<TradeContractGoodsDto> contractFuture;
+        //1.正常流程
+        if (!Objects.equals(1, logOrder.getOrderType())) {
+            contractFuture =
+                    goodsFuture.thenCompose(goods -> {
+                        Long goodsId = Optional.ofNullable(goods)
+                                .map(KwtLogisticsOrderGoods::getGoodsId)
+                                .orElse(null);
+                        log.debug("开始查询合同信息,贸易订单ID: {}, 商品ID: {}", logOrder.getTOrderId(), goodsId);
+
+                        return CompletableFuture
+                                .supplyAsync(
+                                        () -> tradeOrderInfoService.queryByContractByTradeOrderId(logOrder.getTOrderId()), traceTaskExecutor)
+                                .thenCompose(tradeOrderInfo -> {
+                                    log.debug("贸易订单合同信息查询完成,合同ID: {}", tradeOrderInfo.getContractId());
+                                    return CompletableFuture.supplyAsync(
+                                            () -> remoteContractService.queryContractGoodsByContractId(tradeOrderInfo.getContractId(), goodsId), traceTaskExecutor
+                                    );
+                                });
+                    }).exceptionally(ex -> {
+                        log.error("异步任务执行失败", ex);
+                        throw new BusinessException("查询合同信息失败");
+                    });
+        } else {
+            //2.原矿运输
+            contractFuture = CompletableFuture.completedFuture(null);
+        }
+
         // 等待所有并行查询完成
         log.debug("等待所有并行查询完成");
-        CompletableFuture.allOf(
-                truckFuture, fleetFuture, addressFuture, ticketFuture, userFuture,
-                goodsFuture, orderDetailFuture, unitFuture, nodeFuture, waybillSubtaskFuture,
-                contractFuture
-        ).join();
+        try {
+            CompletableFuture.allOf(
+                    truckFuture, fleetFuture, addressFuture, ticketFuture, userFuture,
+                    goodsFuture, orderDetailFuture, unitFuture, nodeFuture, waybillSubtaskFuture,
+                    contractFuture
+            ).get(30, TimeUnit.SECONDS);
+
+        } catch (Exception e) {
+            // 超时会抛出 TimeoutException
+            // 任意任务失败会抛出 ExecutionException
+            // 中断会抛出 InterruptedException
+            throw new RuntimeException("批量异步任务执行失败/超时", e);
+        }
         log.debug("所有并行查询完成");
 
         // 获取查询结果
@@ -4425,7 +4448,7 @@ public class KwtWaybillOrderV1Service {
         KwpGoods kwpGoods = getKwpGoods(goods);
 
         // 处理合同采购单位
-        List<TradeContractUnitDto> tradeContractUnitDtos = getTradeContractUnits(orderDetailVo);
+        List<TradeContractUnitDto> tradeContractUnitDtos = getTradeContractUnits(orderDetailVo, logOrder);
 
         // 处理地址信息
         Map<String, KwtLogisticsOrderAddress> keyAndAddressMap = processAddresses(kwtWaybillOrderAddresses);
@@ -4472,7 +4495,11 @@ public class KwtWaybillOrderV1Service {
     /**
      * 获取合同采购单位信息
      */
-    private List<TradeContractUnitDto> getTradeContractUnits(OrderDetailVo orderDetailVo) {
+    private List<TradeContractUnitDto> getTradeContractUnits(OrderDetailVo orderDetailVo, KwtLogisticsOrder logOrder) {
+        //原矿运输没有贸易订单
+        if (Objects.equals(1, logOrder.getOrderType())) {
+            return Lists.newArrayList();
+        }
         if (Objects.nonNull(orderDetailVo) && Objects.nonNull(orderDetailVo.getContractInfo())
             && Objects.nonNull(orderDetailVo.getContractInfo().getContractId())) {
             log.debug("查询合同单位信息,合同ID: {}", orderDetailVo.getContractInfo().getContractId());
@@ -4604,6 +4631,7 @@ public class KwtWaybillOrderV1Service {
         resp.setPriceType(String.valueOf(logOrder.getBillingMode()));
         resp.setPriceTypeDesc(DictEnum.getLabel(DictTypeEnum.CHARGING_TYPE.getType(), logOrder.getBillingMode()));
         resp.setRemark(billOrder.getRemark());
+        resp.setLabel(billOrder.getLabel());
         // 票据信息
         String shipmentTicketKey = subtask.getWOrderId() + "-" + AddressTypeEnum.SHIPMENT.getCode();
         KwtWaybillOrderTicket tareAmountTicket = ticketMap.getOrDefault(shipmentTicketKey, new KwtWaybillOrderTicket());
@@ -4666,6 +4694,7 @@ public class KwtWaybillOrderV1Service {
         resp.setUnloadLongitude(unLoadAdd.getLng());
         //装货净重
         resp.setLoadingNetWeight(subtask.getLoadAmount());
+        resp.setTaskNum(subtask.getEntrustAmount());
         // 数量信息
         String unit = subtask.getUnit();
         resp.setTaskVolume(formatAmount(subtask.getEntrustAmount()) + unit);
@@ -4680,17 +4709,25 @@ public class KwtWaybillOrderV1Service {
         resp.setTransEntName(transEnt.getFirmName());
         resp.setCarrierEntName(carrierEnt.getFirmName());
 
-        // 供应商信息
-        if (!CollectionUtils.isEmpty(tradeContractUnitDtos)) {
-            tradeContractUnitDtos.stream()
-                    .filter(x -> org.apache.commons.lang3.StringUtils.equals(x.getUnitType(), String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())))
-                    .findFirst()
-                    .ifPresent(x -> resp.setSupplyEntName(x.getFirmName()));
+
+        //1.正常流程
+        if (!Objects.equals(1, logOrder.getOrderType())) {
+            // 供应商信息
+            if (!CollectionUtils.isEmpty(tradeContractUnitDtos)) {
+                tradeContractUnitDtos.stream()
+                        .filter(x -> org.apache.commons.lang3.StringUtils.equals(x.getUnitType(), String.valueOf(CooperateTypeEnum.SUPPLIER.getCode())))
+                        .findFirst()
+                        .ifPresent(x -> resp.setSupplyEntName(x.getFirmName()));
+            }
+        } else {
+            //2.原矿运输
+            resp.setSupplyEntName(transEnt.getFirmName());
         }
 
         // 状态信息
         resp.setStatus(subtask.getStatus());
-        resp.setStatusDesc(CarWaybillV1Enum.geDesc(subtask.getStatus()));
+        resp.setStatusDesc(Objects.equals(subtask.getStatus(), CarWaybillV1Enum.COMPLETED.getCode())
+                && Objects.equals(subtask.getRemark(), "空载离场") ? "空载完成" : CarWaybillV1Enum.geDesc(subtask.getStatus()));
         resp.setLegalLoad(Objects.isNull( truck)  ? null:truck.getLegalLoad());
 
         // 计算装货完成率

+ 93 - 18
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/ForkliftOrderService.java

@@ -10,6 +10,7 @@ import com.sckw.core.common.enums.enums.DictTypeEnum;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.model.constant.Global;
+import com.sckw.core.model.enums.CarWaybillV1Enum;
 import com.sckw.core.model.enums.ForkliftStatusEnum;
 import com.sckw.core.model.enums.LoadingTypeEnum;
 import com.sckw.core.utils.CollectionUtils;
@@ -305,20 +306,38 @@ public class ForkliftOrderService {
             return Collections.emptyList();
         }
         Map<Long, KwtLogisticsOrder> logisticsOrderMap = logisticsOrder.stream().collect(Collectors.toMap(KwtLogisticsOrder::getId, Function.identity(), (x, y) -> x));
-        Set<Long> tOrderIds = logisticsOrder.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
 
-        //查询贸易订单企业信息
-        List<OrderUnitInfoDetailVO> orderUnitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tOrderIds);
-        if (CollectionUtils.isEmpty(orderUnitInfoDetailVOS)) {
-            log.info("【铲车】无订单企业信息,物流订单id:{}", JSON.toJSONString(lOrderIds));
-            return Collections.emptyList();
+        // 按照order_type区分“正常订单”和“原矿运输订单”
+        Map<Boolean, List<KwtLogisticsOrder>> partitionedMap = logisticsOrder.stream()
+                .collect(Collectors.partitioningBy(order -> Integer.valueOf(1).equals(order.getOrderType())));
+        List<KwtLogisticsOrder> typeNullList = partitionedMap.get(false);
+        List<KwtLogisticsOrder> typeOneList = partitionedMap.get(true);
+        log.info("正常流程订单信息: {},数量:{}, 原矿运输订单信息: {},数量:{}",  JSON.toJSONString(typeNullList), typeNullList.size(),
+                JSON.toJSONString(typeOneList), typeOneList.size());
+
+        List<ForkliftOrderResp> forkliftOrderRespList = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(typeNullList)) {
+            //组装正常流程铲车订单数据
+            Set<Long> lOrderId = typeNullList.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
+            List<ForkliftOrderResp> forkliftOrders = records.stream()
+                    .filter(x -> lOrderId.contains(x.getLOrderId()))
+                    .map(forkliftOrder -> buildForkliftOrderResp(forkliftOrder, waybillOrderMap,
+                            waybillOrderTicketMap, logisticsOrderMap, typeNullList, Boolean.FALSE)).collect(Collectors.toList());
+            forkliftOrderRespList.addAll(forkliftOrders);
         }
-        Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit = orderUnitInfoDetailVOS.stream().collect(Collectors.toMap(unit -> unit.getTOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));
 
-        //组装铲车订单数据
-        return records.stream()
-                .map(forkliftOrder -> buildForkliftOrderResp(forkliftOrder, waybillOrderMap, waybillOrderTicketMap, logisticsOrderMap, tradeOrderAndUnit))
-                .collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(typeOneList)) {
+            //组装铲车订单数据
+            Set<Long> lOrderId = typeOneList.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
+            List<ForkliftOrderResp> rawOreForkliftOrders = records.stream()
+                    .filter(x -> lOrderId.contains(x.getLOrderId()))
+                    .map(forkliftOrder -> buildForkliftOrderResp(forkliftOrder, waybillOrderMap,
+                            waybillOrderTicketMap, logisticsOrderMap, typeOneList, Boolean.TRUE)).collect(Collectors.toList());
+            forkliftOrderRespList.addAll(rawOreForkliftOrders);
+        }
+
+
+        return forkliftOrderRespList;
     }
 
 
@@ -332,7 +351,9 @@ public class ForkliftOrderService {
                                                      Map<Long, KwtWaybillOrder> waybillOrderMap,
                                                      Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap,
                                                      Map<Long, KwtLogisticsOrder> logisticsOrderMap,
-                                                     Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit) {
+                                                     List<KwtLogisticsOrder> logisticsOrder,
+                                                     Boolean isRawOre) {
+        log.info("开始{}铲车订单查询,param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(forkliftOrder));
         ForkliftOrderResp forklift = new ForkliftOrderResp();
         forklift.setId(forkliftOrder.getId());
         forklift.setForkliftOrderNo(forkliftOrder.getFOrderNo());
@@ -362,17 +383,28 @@ public class ForkliftOrderService {
         forklift.setName(waybillOrder.getDriverName());
         forklift.setPhone(waybillOrder.getDriverPhone());
 
-        //采购企业信息
-        KwtLogisticsOrder logisticsOrder = logisticsOrderMap.getOrDefault(waybillOrder.getLOrderId(), new KwtLogisticsOrder());
-        OrderUnitInfoDetailVO orderUnit = tradeOrderAndUnit.getOrDefault(logisticsOrder.getTOrderId() + "-" + 1, new OrderUnitInfoDetailVO());
-        forklift.setPrEntId(orderUnit.getEntId());
-        forklift.setPrEntName(orderUnit.getFirmName());
-
         //装卸货信息
         KwtWaybillOrderTicket ticket = waybillOrderTicketMap.getOrDefault(forkliftOrder.getWOrderId() + "-" + 1, new KwtWaybillOrderTicket());
         forklift.setTareAmount(ticket.getTareAmount());
         forklift.setGrossAmount(ticket.getGrossAmount());
 
+        // 采购企业信息:正常逻辑,需查询贸易订单
+        if (!isRawOre) {
+            Set<Long> tOrderIds = logisticsOrder.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
+            //查询贸易订单企业信息
+            List<OrderUnitInfoDetailVO> orderUnitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tOrderIds);
+            if (CollectionUtils.isNotEmpty(orderUnitInfoDetailVOS)) {
+                Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit = orderUnitInfoDetailVOS.stream()
+                        .collect(Collectors.toMap(unit -> unit.getTOrderId() + "-" + unit.getUnitType(),
+                                Function.identity(), (x, y) -> x));
+
+                KwtLogisticsOrder logisticsOrder2 = logisticsOrderMap.getOrDefault(waybillOrder.getLOrderId(), new KwtLogisticsOrder());
+                OrderUnitInfoDetailVO orderUnit = tradeOrderAndUnit.getOrDefault(logisticsOrder2.getTOrderId() + "-" + 1, new OrderUnitInfoDetailVO());
+                forklift.setPrEntId(orderUnit.getEntId());
+                forklift.setPrEntName(orderUnit.getFirmName());
+            }
+        }
+        log.info("{}铲车订单查询结束,param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(forklift));
         return forklift;
     }
 
@@ -663,11 +695,54 @@ public class ForkliftOrderService {
         forkliftWaybillOrder.setForkliftAcceptTime(new Date());
         forkliftWaybillOrderRepository.updateById(forkliftWaybillOrder);
 
+        //修改司机状态
+        updateWaybillOrder(forkliftWaybillOrder);
+
         // 创建司机日志记录
         creatWaybillOrderNode(param, forkliftWaybillOrder);
         log.info("铲车接单成功,订单ID:{}", forkliftWaybillOrder.getWOrderId());
     }
 
+    /**
+     * 修改司机状态
+     * @param forkliftWaybillOrder
+     */
+    private void updateWaybillOrder(KwtForkliftWaybillOrder forkliftWaybillOrder) {
+        // 修改运单状态
+        updateWaybillStatus(forkliftWaybillOrder);
+
+        // 修改子运单状态
+        updateWaybillSubtaskStatus(forkliftWaybillOrder);
+    }
+
+
+    /**
+     * 修改运单状态
+     * @param forkliftWaybillOrder
+     */
+    private void updateWaybillStatus(KwtForkliftWaybillOrder forkliftWaybillOrder) {
+        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(forkliftWaybillOrder.getWOrderId());
+        if (waybillOrder == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "当前运单数据不存在!");
+        }
+
+        waybillOrder.setStatus(CarWaybillV1Enum.REFUSE_TRAFFIC.getCode());
+        waybillOrderRepository.updateById(waybillOrder);
+    }
+
+    /**
+     * 修改子运单状态
+     * @param forkliftWaybillOrder
+     */
+    private void updateWaybillSubtaskStatus(KwtForkliftWaybillOrder forkliftWaybillOrder) {
+        KwtWaybillOrderSubtask waybillSubtask = waybillOrderSubtaskRepository.queryByWOrderId(forkliftWaybillOrder.getWOrderId());
+        if (waybillSubtask == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单!");
+        }
+        waybillSubtask.setStatus(CarWaybillV1Enum.REFUSE_TRAFFIC.getCode());
+        waybillOrderSubtaskRepository.updateById(waybillSubtask);
+    }
+
     /**
      * 创建日子轨迹记录
      * @param param

+ 366 - 33
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/GatekeeperOrderService.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
 import com.sckw.contract.api.RemoteContractService;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessPlatfromException;
@@ -16,6 +17,8 @@ import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.DateUtils;
 import com.sckw.core.utils.StringUtils;
 import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.fleet.api.RemoteFleetService;
+import com.sckw.fleet.api.model.vo.RTruckVo;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
 import com.sckw.order.api.model.OrderUnitInfoDetailVO;
 import com.sckw.product.api.dubbo.GoodsInfoService;
@@ -23,6 +26,7 @@ import com.sckw.system.api.RemoteSystemService;
 import com.sckw.transport.model.*;
 import com.sckw.transport.model.enuma.WeighbridgeTypeEnum;
 import com.sckw.transport.model.param.forklift.reponse.GatekeeperOrderResp;
+import com.sckw.transport.model.param.forklift.request.GatekeeperOrderIsPassParam;
 import com.sckw.transport.model.param.forklift.request.GatekeeperOrderPassParam;
 import com.sckw.transport.model.param.forklift.request.GatekeeperOrderQueryParam;
 import com.sckw.transport.model.vo.StatisticsWaybillResp;
@@ -32,8 +36,11 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -73,6 +80,9 @@ public class GatekeeperOrderService {
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     GoodsInfoService goodsInfoService;
 
+    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
+    protected RemoteFleetService remoteFleetService;
+
 
     @Autowired
     WaybillOrderService waybillOrderService;
@@ -270,7 +280,9 @@ public class GatekeeperOrderService {
      * @return
      */
     private List<GatekeeperOrderResp> getGatekeeperOrderPageResult(List<KwtGatekeeperWaybillOrder> records) {
-        Set<Long> wOrderIds = records.stream().map(KwtGatekeeperWaybillOrder::getWOrderId).filter(Objects::nonNull).collect(Collectors.toSet());
+        log.info("开始门卫订单查询,param:{}", JSON.toJSONString(records));
+        Set<Long> wOrderIds = records.stream().map(KwtGatekeeperWaybillOrder::getWOrderId)
+                .filter(Objects::nonNull).collect(Collectors.toSet());
         //查询运单
         List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.queryByBillOrderIds(wOrderIds);
         if (CollectionUtils.isEmpty(waybillOrders)) {
@@ -279,7 +291,9 @@ public class GatekeeperOrderService {
         }
         Map<Long, KwtWaybillOrder> waybillOrderMap = waybillOrders.stream()
                 .collect(Collectors.toMap(KwtWaybillOrder::getId, Function.identity(), (x, y) -> x));
-        Set<Long> lOrderIds = waybillOrders.stream().map(KwtWaybillOrder::getLOrderId).collect(Collectors.toSet());
+
+        Set<Long> lOrderIds = waybillOrders.stream().map(KwtWaybillOrder::getLOrderId)
+                .filter(Objects::nonNull).collect(Collectors.toSet());
 
         //查询运单装卸货
         List<KwtWaybillOrderTicket> waybillOrderTickets = waybillOrderTicketRepository.queryByWOrderIds(new ArrayList<>(wOrderIds));
@@ -296,21 +310,53 @@ public class GatekeeperOrderService {
             log.info("【门卫】无物流订单信息,物流订单id:{}", JSON.toJSONString(lOrderIds));
             return Collections.emptyList();
         }
-        Map<Long, KwtLogisticsOrder> logisticsOrderMap = logisticsOrder.stream().collect(Collectors.toMap(KwtLogisticsOrder::getId, Function.identity(), (x, y) -> x));
-        Set<Long> tOrderIds = logisticsOrder.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
 
-        //查询贸易订单企业信息
-        List<OrderUnitInfoDetailVO> orderUnitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tOrderIds);
-        if (CollectionUtils.isEmpty(orderUnitInfoDetailVOS)) {
-            log.info("【门卫】无订单企业信息,物流订单id:{}", JSON.toJSONString(lOrderIds));
-            return Collections.emptyList();
+        // 按照order_type区分“正常订单”和“原矿运输订单”
+        Map<Boolean, List<KwtLogisticsOrder>> partitionedMap = logisticsOrder.stream()
+                .collect(Collectors.partitioningBy(order -> Integer.valueOf(1).equals(order.getOrderType())));
+
+        List<KwtLogisticsOrder> typeNullList = partitionedMap.get(false);
+        List<KwtLogisticsOrder> typeOneList = partitionedMap.get(true);
+        log.info("正常流程订单信息: {},数量:{}, 原矿运输订单信息: {},数量:{}",  JSON.toJSONString(typeNullList), typeNullList.size(),
+                JSON.toJSONString(typeOneList), typeOneList.size());
+
+        List<GatekeeperOrderResp> resultList = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(typeNullList)) {
+            Set<Long> tOrderIds = typeNullList.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
+            List<OrderUnitInfoDetailVO> orderUnitVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tOrderIds);
+            if (CollectionUtils.isEmpty(orderUnitVOS)) {
+                log.info("【门卫】无贸易订单企业信息,贸易订单id:{}", JSON.toJSONString(tOrderIds));
+                return Collections.emptyList();
+            }
+            //查询贸易订单企业信息
+            Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit = orderUnitVOS.stream().collect(Collectors
+                    .toMap(unit -> unit.getTOrderId() + "-" + unit.getUnitType(),
+                            Function.identity(), (x, y) -> x));
+
+            //组装正常流程门卫订单数据
+            Set<Long> lOrderId = typeNullList.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
+            List<GatekeeperOrderResp> gatekeeperOrderResp = records.stream()
+                    .filter(x -> lOrderId.contains(x.getLOrderId()))
+                    .map(gatekeeperWaybillOrder -> buildGatekeeperOrderResp(gatekeeperWaybillOrder,
+                            waybillOrderMap, waybillOrderTicketMap, typeNullList, tradeOrderAndUnit, Boolean.FALSE))
+                    .collect(Collectors.toList());
+            resultList.addAll(gatekeeperOrderResp);
         }
-        Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit = orderUnitInfoDetailVOS.stream().collect(Collectors.toMap(unit -> unit.getTOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));
 
-        //组装铲车订单数据
-        return records.stream()
-                .map(gatekeeperWaybillOrder -> buildGatekeeperOrderResp(gatekeeperWaybillOrder, waybillOrderMap, waybillOrderTicketMap, logisticsOrderMap, tradeOrderAndUnit))
-                .collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(typeOneList)) {
+            //组装原矿运输门卫订单数据
+            Set<Long> lOrderId = typeOneList.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
+            List<GatekeeperOrderResp> rawOreGatekeeperOrderResp = records.stream()
+                    .filter(x -> lOrderId.contains(x.getLOrderId()))
+                    .map(gatekeeperWaybillOrder -> buildGatekeeperOrderResp(gatekeeperWaybillOrder,
+                            waybillOrderMap, waybillOrderTicketMap, typeOneList, Collections.emptyMap(), Boolean.TRUE))
+                    .collect(Collectors.toList());
+            resultList.addAll(rawOreGatekeeperOrderResp);
+        }
+
+        log.info("门卫订单查询结束,result:{}", JSON.toJSONString(resultList));
+        return resultList;
+
     }
 
     /**
@@ -321,11 +367,12 @@ public class GatekeeperOrderService {
      * @return
      */
     private GatekeeperOrderResp buildGatekeeperOrderResp(KwtGatekeeperWaybillOrder gatekeeperWaybillOrder,
-                                                     Map<Long, KwtWaybillOrder> waybillOrderMap,
-                                                     Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap,
-                                                     Map<Long, KwtLogisticsOrder> logisticsOrderMap,
-                                                     Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit) {
-
+                                                         Map<Long, KwtWaybillOrder> waybillOrderMap,
+                                                         Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap,
+                                                         List<KwtLogisticsOrder> logisticsOrder,
+                                                         Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit,
+                                                         boolean isRawOre) {
+        log.info("开始{}门卫订单查询,param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(gatekeeperWaybillOrder));
         GatekeeperOrderResp gatekeeper = new GatekeeperOrderResp();
         gatekeeper.setId(gatekeeperWaybillOrder.getId());
         gatekeeper.setEntId(gatekeeperWaybillOrder.getEntId());
@@ -358,18 +405,26 @@ public class GatekeeperOrderService {
         gatekeeper.setPhone(waybillOrder.getDriverPhone());
         gatekeeper.setIdCard(waybillOrder.getDriverIdcard());
 
-        //采购企业信息
-        KwtLogisticsOrder logisticsOrder = logisticsOrderMap.getOrDefault(waybillOrder.getLOrderId(), new KwtLogisticsOrder());
-        OrderUnitInfoDetailVO orderUnit = tradeOrderAndUnit.getOrDefault(logisticsOrder.getTOrderId() + "-" + 1, new OrderUnitInfoDetailVO());
-        gatekeeper.setPrEntId(orderUnit.getEntId());
-        gatekeeper.setPrEntName(orderUnit.getFirmName());
-
-
         //装卸货信息
         KwtWaybillOrderTicket ticket = waybillOrderTicketMap.getOrDefault(gatekeeperWaybillOrder.getWOrderId() + "-" + 1, new KwtWaybillOrderTicket());
         gatekeeper.setTareAmount(ticket.getTareAmount());
         gatekeeper.setGrossAmount(ticket.getGrossAmount());
 
+        //获取当前物流订单
+        KwtLogisticsOrder logOrder = logisticsOrder.stream()
+                .filter(log -> Objects.equals(log.getId(), gatekeeperWaybillOrder.getLOrderId()))
+                .findFirst().orElse(new KwtLogisticsOrder());
+        // 正常流程
+        if (!isRawOre) {
+            //采购企业信息
+            OrderUnitInfoDetailVO orderUnit = tradeOrderAndUnit.getOrDefault(logOrder.getTOrderId() + "-" + 1, new OrderUnitInfoDetailVO());
+            gatekeeper.setPrEntId(orderUnit.getEntId());
+            gatekeeper.setPrEntName(orderUnit.getFirmName());
+        }
+        gatekeeper.setOrderType(logOrder.getOrderType());
+        gatekeeper.setOrderTypeDesc(Objects.equals(logOrder.getOrderType(), 1) ? "原矿运输" : "产品销售");
+
+        log.info("{}门卫订单查询结束,param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(gatekeeperWaybillOrder));
         return gatekeeper;
     }
 
@@ -402,6 +457,7 @@ public class GatekeeperOrderService {
      * @param gatekeeperOrderPageResult
      */
     private void sort(GatekeeperOrderQueryParam param, List<GatekeeperOrderResp> gatekeeperOrderPageResult) {
+        log.info("门卫订单拍寻,param:{}, order:{}", JSON.toJSONString(param), JSON.toJSONString(gatekeeperOrderPageResult));
         if (CollectionUtils.isEmpty(gatekeeperOrderPageResult)) {
             return;
         }
@@ -457,13 +513,13 @@ public class GatekeeperOrderService {
 
         //查询门卫订单
         List<KwtGatekeeperWaybillOrder> orderList = gatekeeperWaybillOrderRepository.list(wrapper);
+        log.info("查询门卫订单, size:{}", orderList.size());
         if (CollectionUtils.isEmpty(orderList)) {
             log.info("当前无门卫统计记录,统计结果为空");
             resp.setOrderStatusStatistics(buildDefaultStatusStatistics());
             return resp;
         }
-        List<GatekeeperOrderResp> gatekeeperOrderPageResult = getGatekeeperOrderPageResult(orderList);
-        resp.setOrderStatusStatistics(calculateStatusStatistics(gatekeeperOrderPageResult));
+        resp.setOrderStatusStatistics(calculateStatusStatistics(orderList));
         return resp;
 
     }
@@ -504,10 +560,11 @@ public class GatekeeperOrderService {
 
     /**
      * 计算运单状态统计
-     * @param gatekeeperOrderList
+     * @param orderList
      * @return
      */
-    private static List<StatisticsWaybillResp.OrderBillStatusStatistics> calculateStatusStatistics(List<GatekeeperOrderResp> gatekeeperOrderList) {
+    private static List<StatisticsWaybillResp.OrderBillStatusStatistics> calculateStatusStatistics(List<KwtGatekeeperWaybillOrder> orderList) {
+        log.info("开始统计计算,param:{}", JSON.toJSONString(orderList));
         //车辆停留超时配置
         double configHours = 2000;
 
@@ -520,8 +577,9 @@ public class GatekeeperOrderService {
         );
 
         // 按原始状态统计数量
-        Map<String, Long> statusCountMap = gatekeeperOrderList.stream()
+        Map<String, Long> statusCountMap = orderList.stream()
                 .collect(Collectors.groupingBy(va ->String.valueOf(va.getStatus()), Collectors.counting()));
+        log.info("按原始状态统计数量:{}", JSON.toJSONString(statusCountMap));
 
         // 进行状态聚合
         List<StatisticsWaybillResp.OrderBillStatusStatistics> aggregatedList = aggregateRules.entrySet().stream()
@@ -532,7 +590,7 @@ public class GatekeeperOrderService {
 
                     // 处理状态为4的异常车辆
                     if (Objects.equals(aggregateInfo[0],"4")) {
-                        totalNum = gatekeeperOrderList.stream().filter(order -> {
+                        totalNum = orderList.stream().filter(order -> {
                             // 1. 必须包含在定义的异常状态源中 (5,10,15)
                             if (!originalStatuses.contains(String.valueOf(order.getStatus()))) {
                                 return false;
@@ -550,6 +608,7 @@ public class GatekeeperOrderService {
                         totalNum = originalStatuses.stream()
                                 .mapToLong(status -> statusCountMap.getOrDefault(status, 0L))
                                 .sum();
+                        log.info("{}状态统计,num:{}", JSON.toJSONString(aggregateInfo[1]), totalNum);
                     }
 
                     // 构建聚合结果对象
@@ -561,6 +620,7 @@ public class GatekeeperOrderService {
                 })
                 .sorted(Comparator.comparing(StatisticsWaybillResp.OrderBillStatusStatistics::getOrderStatus))
                 .collect(Collectors.toList());
+        log.info("统计计算完成,result:{}", JSON.toJSONString(aggregatedList));
         return aggregatedList;
     }
 
@@ -571,12 +631,26 @@ public class GatekeeperOrderService {
      * @param param
      * @return
      */
+    @Transactional(rollbackFor = Exception.class)
     public void pass(GatekeeperOrderPassParam param) {
         log.info("门卫放行:{}", JSON.toJSONString(param));
         KwtGatekeeperWaybillOrder gatekeeper = gatekeeperWaybillOrderRepository.getById(param.getId());
         if (gatekeeper == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "当前门卫订单不存在!");
         }
+        //放行后 mock抬杆流程
+//        mockPass(param, gatekeeper);
+
+        //放行后直接抬杆离场
+        driverPass(param, gatekeeper);
+    }
+
+    /**
+     * 放行后 mock抬杆流程
+     * @param param
+     * @param gatekeeper
+     */
+    private void mockPass(GatekeeperOrderPassParam param, KwtGatekeeperWaybillOrder gatekeeper) {
         //1. 更改门卫状态为:已放行
         updateGatekeeperOrderStatus(gatekeeper, param);
 
@@ -705,7 +779,7 @@ public class GatekeeperOrderService {
             creatPassLogo(subtask, waybillOrder, remark3);
 
         }
-
+        log.info("[门卫放行]创建车辆运单-节点轨迹完成!");
     }
 
     /**
@@ -727,4 +801,263 @@ public class GatekeeperOrderService {
     }
 
 
+    /**
+     * 放行后直接离场
+     * @param param
+     * @param gatekeeper
+     */
+    private void driverPass(GatekeeperOrderPassParam param, KwtGatekeeperWaybillOrder gatekeeper) {
+        // 查询运单
+        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeper.getWOrderId());
+        if (waybillOrder == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "[门卫放行]当前运单数据不存在!");
+        }
+
+        //1. 计算是否空载离场
+        Boolean isEmptyLoadLeave = calculateEmptyLoad(waybillOrder);
+
+        //2. 更改门卫状态为:已离场
+        updateGatekeeperOrderStatus2(gatekeeper, param, isEmptyLoadLeave);
+
+        //3. 更改司机状态为:已离场
+        updateWaybillOrderStatus2(gatekeeper, param, waybillOrder, isEmptyLoadLeave);
+
+        //4. 创建门卫卸货订单
+        creatGatekeeperUnLoadingOrder(gatekeeper, waybillOrder);
+    }
+
+    /**
+     * 计算是否空载离场
+     * @param waybillOrder
+     * @return
+     */
+    private Boolean calculateEmptyLoad(KwtWaybillOrder waybillOrder) {
+        log.info("[门卫放行]计算是否空载离场:{}", JSON.toJSONString(waybillOrder));
+        //查询运单装卸货信息
+        KwtWaybillOrderTicket orderTicket = waybillOrderTicketRepository.queryByWOrderIdByIdAndType(waybillOrder.getId(), 1);
+        if (orderTicket == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在,无法记录皮重!");
+        }
+        BigDecimal loadAmount = orderTicket.getAmount();
+
+        //空载离场,净重<=0.5
+        boolean result = loadAmount != null && loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0;
+        log.info("[门卫放行]计算是否空载离场完成:{}", JSON.toJSONString(result));
+        return result;
+    }
+
+
+    /**
+     * 更改门卫状态为:已放行
+     * @param gatekeeper
+     */
+    private void updateGatekeeperOrderStatus2(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param, Boolean isEmptyLoadLeave) {
+        log.info("[门卫放行]更改门卫状态为已放行:{}", JSON.toJSONString(gatekeeper));
+        if (!GatekeeperStatusEnum.PENDING_RELEASE.getCode().equals(gatekeeper.getStatus())) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_STATUS_ERROR, "当前门卫订单状态异常,不能放行!");
+        }
+        //门卫放行后状态更改为:已离场/空载离场
+        GatekeeperStatusEnum targetStatus = isEmptyLoadLeave ? GatekeeperStatusEnum.EMPTY_EXITED : GatekeeperStatusEnum.EXITED;
+        gatekeeper.setStatus(targetStatus.getCode());
+        gatekeeper.setLeaveTime(new Date());
+        gatekeeper.setGatekeeperUserId(param.getGatekeeperUserId());
+        gatekeeper.setGatekeeperName(param.getGatekeeperName());
+        gatekeeper.setUpdateUser(param.getGatekeeperUserId());
+        gatekeeperWaybillOrderRepository.updateById(gatekeeper);
+        log.info("[门卫放行]更改门卫状态已放行完成!");
+    }
+
+    /**
+     * 更改司机状态为:已离场
+     * @param gatekeeper
+     */
+    private void updateWaybillOrderStatus2(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param,
+                                           KwtWaybillOrder waybillOrder, Boolean isEmptyLoadLeave) {
+        // 1. 修改运单状态:已离场
+        updateWaybillStatus2(gatekeeper, waybillOrder, isEmptyLoadLeave);
+
+        // 2. 修改子运单状态:已离场
+        updateWaybillSubtaskStatus2(gatekeeper, isEmptyLoadLeave);
+
+        // 3.创建运单轨迹日日志
+        creatWaybillOrderNode(gatekeeper, param);
+    }
+
+    /**
+     * 修改运单状态
+     * @param gatekeeper
+     */
+    private void updateWaybillStatus2(KwtGatekeeperWaybillOrder gatekeeper, KwtWaybillOrder waybillOrder,Boolean isEmptyLoadLeave) {
+        log.info("[门卫放行]更改运单状态为已离场/空载离场:{}", JSON.toJSONString(gatekeeper));
+        //装货单
+        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
+            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常,不能推进为已离场!");
+            }
+            // 校验状态:若是空载离场,运单状态为已完成
+            CarWaybillV1Enum status = isEmptyLoadLeave ? CarWaybillV1Enum.COMPLETED : CarWaybillV1Enum.WAIT_LOADING;
+            if (isEmptyLoadLeave) {
+                waybillOrder.setRemark("空载离场");
+            }
+            waybillOrder.setStatus(status.getCode());
+        } else {
+            //卸货单校验
+            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常,不能推进为已完成!");
+            }
+            waybillOrder.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
+        }
+        waybillOrderRepository.updateById(waybillOrder);
+        log.info("[门卫放行]更改运单状态为已离场/空载离场完成!");
+    }
+
+    /**
+     * 修改子运单状态
+     * @param gatekeeper
+     */
+    private void updateWaybillSubtaskStatus2(KwtGatekeeperWaybillOrder gatekeeper, Boolean isEmptyLoadLeave) {
+        log.info("[门卫放行]更改子运单状态为已离场/空载离场:{}", JSON.toJSONString(gatekeeper));
+        KwtWaybillOrderSubtask waybillSubtask = waybillOrderSubtaskRepository.queryByWOrderId(gatekeeper.getWOrderId());
+        if (waybillSubtask == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单!");
+        }
+        //装货单
+        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
+            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常,不能推进为已离场!");
+            }
+            // 校验状态:若是空载离场,运单状态为已完成
+            CarWaybillV1Enum status = isEmptyLoadLeave ? CarWaybillV1Enum.COMPLETED : CarWaybillV1Enum.WAIT_LOADING;
+            waybillSubtask.setStatus(status.getCode());
+        } else {
+            //卸货单校验
+            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常,不能推进为已完成!");
+            }
+            waybillSubtask.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
+        }
+        waybillOrderSubtaskRepository.updateById(waybillSubtask);
+        log.info("[门卫放行]更改子运单状态为已离场/空载离场完成!");
+    }
+
+
+    /**
+     * 创建卸货门卫订单
+     *
+     * @param waybillOrder
+     */
+    private void creatGatekeeperUnLoadingOrder(KwtGatekeeperWaybillOrder gatekeeperOrder, KwtWaybillOrder waybillOrder) {
+        log.info("[门卫放行]开始创建卸货门卫订单:{}", JSON.toJSONString(waybillOrder));
+        // 原矿卸货放行不需要创建门卫订单
+        if (Objects.equals(gatekeeperOrder.getType(), GatekeeperTypeEnum.UNLOADING.getCode())) {
+            log.info("[门卫放行]当前是卸货流程放行,不需要再次创建门卫订单:{}", JSON.toJSONString(gatekeeperOrder));
+            return;
+        }
+
+        // 只有原矿运输的才会新增卸货门卫订单
+        KwtLogisticsOrder logisticsOrder = getLogisticsOrder(waybillOrder.getLOrderId());
+        if (!Objects.equals(1, logisticsOrder.getOrderType())) {
+            log.info("[门卫放行]不需要创建卸货门卫订单:{}", JSON.toJSONString(logisticsOrder));
+            return;
+        }
+
+        RTruckVo truck = remoteFleetService.findTruckByTruckNo(waybillOrder.getTruckNo());
+        if (truck == null || !Objects.equals(truck.getStatus(), 0)) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.TRUCK_STATUS_ERROR, "当前车辆非正常状态,不能接单!");
+        }
+        //查询子运单
+        KwtWaybillOrderSubtask waybillSubtask = getWaybillSubtask(waybillOrder.getId());
+
+        try {
+            KwtGatekeeperWaybillOrder gatekeeper = new KwtGatekeeperWaybillOrder();
+            gatekeeper.setEntId(waybillOrder.getEntId());
+            gatekeeper.setWOrderId(waybillOrder.getId());
+            gatekeeper.setWOrderNo(waybillOrder.getWOrderNo());
+            gatekeeper.setLOrderId(waybillOrder.getLOrderId());
+            // 查询商品信息
+            KwtLogisticsOrderGoods orderGoods = logisticsOrderGoodsRepository.queryByLogOrderId(waybillOrder.getLOrderId());
+            if (orderGoods != null) {
+                gatekeeper.setGoodsId(orderGoods.getGoodsId());
+                gatekeeper.setGoodsName(orderGoods.getGoodsName());
+            }
+            gatekeeper.setWaybillAcceptTime(waybillOrder.getCreateTime());
+            gatekeeper.setType(GatekeeperTypeEnum.UNLOADING.getCode());
+            gatekeeper.setStatus(GatekeeperStatusEnum.PENDING_ENTRY.getCode());
+            gatekeeper.setWaybillAcceptTime(waybillOrder.getCreateTime());
+            gatekeeper.setTruckType(truck.getTruckType());
+            gatekeeper.setEntrustAmount(waybillSubtask.getEntrustAmount());
+            gatekeeper.setCarAxis(truck.getCarAxis());
+            gatekeeper.setLegalLoad(truck.getLegalLoad());
+            gatekeeper.setCreateTime(new Date());
+            gatekeeper.setCreateUser(waybillOrder.getDriverId());
+            gatekeeper.setUpdateUser(waybillOrder.getDriverId());
+
+            gatekeeperWaybillOrderRepository.save(gatekeeper);
+            log.debug("卸货门卫订单数据保存成功");
+        } catch (Exception e) {
+            log.error("保存卸货门卫订单数据失败!运单ID: {}, 异常信息:", waybillOrder.getId(), e);
+        }
+    }
+
+    /**
+     * 查询物流订单
+     */
+    protected KwtLogisticsOrder getLogisticsOrder(Long logOrderId) {
+        KwtLogisticsOrder logisticsOrder = logisticsOrderRepository.queryByLogisticsOrderId(logOrderId);
+        if (logisticsOrder == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_FOUND, "物流订单数据不存在!");
+        }
+        return logisticsOrder;
+    }
+
+    /**
+     * 查询子运单
+     */
+    protected KwtWaybillOrderSubtask getWaybillSubtask(Long waybillOrderId) {
+        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrderId);
+        if (subtask == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单!");
+        }
+        return subtask;
+    }
+
+    /**
+     * 校验是否可放行
+     * @param gatekeeper
+     */
+    public Boolean checkIsPass(GatekeeperOrderIsPassParam gatekeeper) {
+        log.info("校验是否可放行:{}", JSON.toJSONString(gatekeeper));
+        if (StringUtils.isBlank(gatekeeper.getTruckNo())) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "车牌号不能为空!");
+        }
+
+        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNo(gatekeeper.getTruckNo());
+        if (CollectionUtils.isEmpty(wbOrderByTruckNo)) {
+            return Boolean.FALSE;
+        }
+        // 获取最新的一条数据
+        KwtWaybillOrder waybillOrder = wbOrderByTruckNo.get(0);
+
+        List<KwtGatekeeperWaybillOrder> gatekeeperWaybillOrders = gatekeeperWaybillOrderRepository
+                .queryGatekeeperWaybillOrderByWOrderIds(Lists.newArrayList(waybillOrder.getId()));
+        if (CollectionUtils.isEmpty(gatekeeperWaybillOrders)) {
+            return Boolean.FALSE;
+        }
+        KwtGatekeeperWaybillOrder gatekeeperWaybillOrder = gatekeeperWaybillOrders.get(0);
+
+
+        // 定义运单可以可放行的状态集合
+        List<Integer> PASS_STATUSES = Arrays.asList(
+                GatekeeperStatusEnum.PENDING_ENTRY.getCode(),
+                GatekeeperStatusEnum.READY_RELEASE.getCode(),
+                GatekeeperStatusEnum.EXITED.getCode(),
+                GatekeeperStatusEnum.EMPTY_EXITED.getCode()
+        );
+
+        Boolean result = PASS_STATUSES.contains(gatekeeperWaybillOrder.getStatus()) ? Boolean.TRUE : Boolean.FALSE;
+        log.info("校验是否可放行完成,result:{}", JSON.toJSONString(result));
+        return result;
+    }
+
+
 }

+ 411 - 45
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/WaybillOrderService.java

@@ -17,7 +17,6 @@ import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.model.enums.UnitTypeEnum;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.DateUtils;
-import com.sckw.core.web.response.BaseResult;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.vo.RTruckVo;
@@ -35,9 +34,7 @@ import com.sckw.transport.model.vo.OrderTotalTakeVo;
 import com.sckw.transport.model.vo.StatisticsWaybillResp;
 import com.sckw.transport.repository.*;
 import com.sckw.transport.service.KwtWaybillOrderV1Service;
-import io.swagger.v3.oas.annotations.Operation;
 import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -46,8 +43,6 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -79,6 +74,7 @@ public class WaybillOrderService {
     private final KwtWaybillOrderAddressRepository waybillOrderAddressRepository;
     private final KwtWaybillOrderTicketRepository waybillOrderTicketRepository;
     private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
+    private final KwtWaybillOrderWeighbridgeRepository waybillOrderWeighbridgeRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     RemoteSystemService remoteSystemService;
@@ -135,7 +131,10 @@ public class WaybillOrderService {
             CarWaybillV1Enum.REPLENISHING.getCode(),
             CarWaybillV1Enum.REPLENISH_FINISH.getCode(),
             CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode(),
-            CarWaybillV1Enum.WAIT_LOADING.getCode());
+            CarWaybillV1Enum.WAIT_LOADING.getCode(),
+            CarWaybillV1Enum.UNLOADING_POINT.getCode(),
+            CarWaybillV1Enum.UNLOADING_WAIT_LEAVE.getCode(),
+            CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode());
 
     // 定义审核的状态集合
     private static final List<Integer> REVIEW = Arrays.asList(
@@ -229,8 +228,60 @@ public class WaybillOrderService {
             log.info("当前车辆无物流订单,truckNo:{}", param.getTruckNo());
             throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_STATUS_ERROR, "当前车辆无物流订单");
         }
-        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList = logOrderList.stream()
-                .collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));
+
+        // 按照order_type区分“正常订单”和“原矿运输订单”
+        Map<Boolean, List<KwtLogisticsOrder>> partitionedMap = logOrderList.stream()
+                .collect(Collectors.partitioningBy(order -> Integer.valueOf(1).equals(order.getOrderType())));
+
+        // 获取order_type=null的订单集合
+        List<KwtLogisticsOrder> typeNullList = partitionedMap.get(false);
+        log.info("正常流程的订单信息: {},数量:{}",  JSON.toJSONString(typeNullList), typeNullList.size());
+
+        // 获取order_type=1的订单集合
+        List<KwtLogisticsOrder> typeOneList = partitionedMap.get(true);
+        log.info("原矿运输的订单信息: {},数量:{}", JSON.toJSONString(typeOneList), typeOneList.size());
+
+        List<LogisticsOrderResp> orderList = new ArrayList<>();
+
+        // 正常流程
+        //1.查询正常流程物流运运单
+        if (CollectionUtils.isNotEmpty(typeNullList)) {
+            List<LogisticsOrderResp> normalOrderList = getLogisticsOrderResps(param, typeNullList, logOrderIdAndCirculateMap, rTruckVo);
+            orderList.addAll(normalOrderList);
+        }
+        if (CollectionUtils.isNotEmpty(typeOneList)) {
+            // 原矿运输
+            List<LogisticsOrderResp> rawOreOrdderList = getRawOreLogisticsOrderResps(param, typeOneList, logOrderIdAndCirculateMap, rTruckVo);
+            orderList.addAll(rawOreOrdderList);
+        }
+
+        //内存分页
+        List<List<LogisticsOrderResp>> pageList = Lists.partition(orderList, param.getPageSize());
+        List<LogisticsOrderResp> walletPageList = pageList.size() >= param.getPageNum() ?
+                pageList.get(param.getPageNum() - 1) : Collections.emptyList();
+
+        PageDataResult<LogisticsOrderResp> walletPageResponse = PageDataResult.success(param.getPageNum(), param.getPageSize(), (long) walletPageList.size(), walletPageList);
+        log.info("查询司机关联车辆的物流订单成功,resouce:{}", JSON.toJSONString(walletPageResponse));
+        return walletPageResponse;
+
+    }
+
+    /**
+     * 正常流程查询物流订单
+     * @param param
+     * @param logOrderList
+     * @param logOrderIdList
+     * @param logOrderIdAndCirculateMap
+     * @param rTruckVo
+     * @return
+     */
+    private List<LogisticsOrderResp> getLogisticsOrderResps(OrderCirculateQueryParam param, List<KwtLogisticsOrder> logOrderList,
+                                                            Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
+                                                            RTruckVo rTruckVo) {
+        log.info("开始查询正常流程物流订单,param:{}", JSON.toJSONString(param));
+        List<Long> logOrderIdList = logOrderList.stream().map(KwtLogisticsOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
+
+        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList = logOrderList.stream().collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));
 
         //物流id映射物流商品
         List<KwtLogisticsOrderGoods> logOrderGoods = logisticsOrderGoodsRepository.queryByLogOrderIds(logOrderIdList);
@@ -260,7 +311,7 @@ public class WaybillOrderService {
 
         //贸易订单id
         Set<Long> tradeOrderIds = logOrderList.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
-        
+
         //供应企业
         List<OrderUnitInfoDetailVO> orderUnitDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tradeOrderIds);
         if (CollectionUtils.isEmpty(orderUnitDetailVOS)) {
@@ -306,16 +357,83 @@ public class WaybillOrderService {
                     return checkCurTruckLoadVolume(rTruckVo, logisticsOrderResp.getRemainingAmount());
                 })
                 .collect(Collectors.toList());
+        log.info("查询正常流程物流订单结束,resouse:{}", JSON.toJSONString(ordderList));
+        return ordderList;
+    }
 
-        //内存分页
-        List<List<LogisticsOrderResp>> pageList = Lists.partition(ordderList, param.getPageSize());
-        List<LogisticsOrderResp> walletPageList = pageList.size() >= param.getPageNum() ?
-                pageList.get(param.getPageNum() - 1) : Collections.emptyList();
+    /**
+     * 原矿运输
+     * @param param
+     * @param logOrderList
+     * @param logOrderIdList
+     * @param logOrderIdAndCirculateMap
+     * @param rTruckVo
+     * @return
+     */
+    private List<LogisticsOrderResp> getRawOreLogisticsOrderResps(OrderCirculateQueryParam param, List<KwtLogisticsOrder> logOrderList,
+                                                                  Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
+                                                                  RTruckVo rTruckVo) {
+        log.info("开始查询原矿运输流程物流订单,param:{}", JSON.toJSONString(param));
+        List<Long> logOrderIdList = logOrderList.stream().map(KwtLogisticsOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
 
-        PageDataResult<LogisticsOrderResp> walletPageResponse = PageDataResult.success(param.getPageNum(), param.getPageSize(), (long) walletPageList.size(), walletPageList);
-        log.info("查询司机关联车辆的物流订单成功!");
-        return walletPageResponse;
+        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList = logOrderList.stream()
+                .collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));
+
+        //物流id映射物流商品
+        List<KwtLogisticsOrderGoods> logOrderGoods = logisticsOrderGoodsRepository.queryByLogOrderIds(logOrderIdList);
+        if (CollectionUtils.isEmpty(logOrderGoods)) {
+            log.info("当前车辆的物流订单无商品信息,truckNo:{}", param.getTruckNo());
+            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "当前车辆的物流订单无商品信息");
+        }
+        Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap = logOrderGoods.stream().collect(Collectors.toMap(KwtLogisticsOrderGoods::getLOrderId,
+                Function.identity(), (x, y) -> x));
+
+        //交易商品信息
+        List<Long> goodsIds = logOrderGoods.stream().map(KwtLogisticsOrderGoods::getGoodsId).distinct().collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(goodsIds)) {
+            log.info("物流订单无关联商品信息,logOrderId:{}", JSON.toJSONString(logOrderIdList));
+            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "物流订单无关联商品信息");
+        }
+        Map<Long, KwpGoods> goodsIdAndGoodsMap = goodsInfoService.getGoodsByIds(goodsIds);
+
+        //承运托运企业
+        List<KwtLogisticsOrderUnit> logOrderUnits = logisticsOrderUnitRepository.queryByLogOrderIds(logOrderIdList);
+        if (CollectionUtils.isEmpty(logOrderUnits)) {
+            log.info("物流订单无关联承运托运企业,logOrderId:{}", JSON.toJSONString(logOrderIdList));
+            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ENT, "物流订单无关联承运托运企业");
+        }
+        Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap = logOrderUnits.stream().collect(Collectors.toMap(
+                unit -> unit.getLOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));
+
+        //地址
+        Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap = getKwtLogisticsOrderAddressMap(logOrderIdList);
+
+        //子运单
+        List<KwtWaybillOrderSubtask> orderSubtaskList = waybillOrderSubtaskRepository.queryByLogIds(logOrderIdList);
+        if(CollectionUtils.isEmpty(orderSubtaskList)) {
+            orderSubtaskList = new ArrayList<>();
+        }
+        Map<Long, List<KwtWaybillOrderSubtask>> logOrderIdAndSubtaskMap = orderSubtaskList.stream()
+                .collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));
 
+        //查询字典
+        Map<String, Map<String, String>> dictValueAndDictResDtoMap = remoteSystemService.queryDictByType(
+                Arrays.asList(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
+
+        //组装数据
+        List<LogisticsOrderResp> ordderList = logOrderList.stream()
+                .map(order -> {
+                    return getRawOreLogisticsOrderResp(order, logOrderIdAndGoodsMap, goodsIdAndGoodsMap, logOrderIdAndUnitMap,
+                            logOrderIdAndAddressMap, logOrderIdAndCirculateMap,
+                            tradeIdAndLogOrderList, logOrderIdAndSubtaskMap, dictValueAndDictResDtoMap);
+                })
+                .filter(logisticsOrderResp -> {
+                    // 校验是否满足车辆任务量,满足才保留
+                    return checkCurTruckLoadVolume(rTruckVo, logisticsOrderResp.getRemainingAmount());
+                })
+                .collect(Collectors.toList());
+        log.info("查询原矿运输流程物流订单结束,resouse:{}", JSON.toJSONString(ordderList));
+        return ordderList;
     }
 
     /**
@@ -348,7 +466,7 @@ public class WaybillOrderService {
      * @param truckNo
      */
     private Boolean checkCurTruckLoadVolume(RTruckVo truckNo, BigDecimal remainingAmount) {
-        log.info("开始校验当前车辆任务量!");
+        log.info("开始校验当前车辆任务量!param:{}, 订单余量:{}", JSON.toJSONString(truckNo), JSON.toJSONString(remainingAmount));
         //核定载重
         BigDecimal actualWeight = truckNo.getLegalLoad();
         //首次皮重
@@ -392,7 +510,7 @@ public class WaybillOrderService {
     }
 
     /**
-     * 组装订单列表信息
+     * 组装正常流程订单列表信息
      * @param order
      * @param logOrderIdAndGoodsMap
      * @param goodsIdAndGoodsMap
@@ -468,6 +586,77 @@ public class WaybillOrderService {
         return orderResp;
     }
 
+    /**
+     * 组装原矿运输订单列表信息
+     * @param order
+     * @param logOrderIdAndGoodsMap
+     * @param goodsIdAndGoodsMap
+     * @param logOrderIdAndUnitMap
+     * @param tOrderIdAndUnitMap
+     * @param logOrderIdAndAddressMap
+     * @param logOrderIdAndCirculateMap
+     * @return
+     */
+    private LogisticsOrderResp getRawOreLogisticsOrderResp(KwtLogisticsOrder order, Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap,
+                                                     Map<Long, KwpGoods> goodsIdAndGoodsMap,
+                                                     Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap,
+                                                     Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap,
+                                                     Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
+                                                     Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList ,
+                                                     Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList,
+                                                     Map<String, Map<String, String>> dictValueAndDictResDtoMap) {
+        LogisticsOrderResp orderResp = new LogisticsOrderResp();
+        orderResp.setOrderType(order.getOrderType());
+        orderResp.setLogisticsOrderId(Optional.ofNullable(order.getId()).map(String::valueOf).orElse(null));
+        orderResp.setLogisticsOrderNo(order.getLOrderNo());
+        //商品
+        KwtLogisticsOrderGoods orderGoods = logOrderIdAndGoodsMap.getOrDefault(order.getId(), new KwtLogisticsOrderGoods());
+        KwpGoods goods = goodsIdAndGoodsMap.getOrDefault(orderGoods.getGoodsId(), new KwpGoods());
+        if (Objects.nonNull(goods)){
+            orderResp.setGoodsId(Optional.ofNullable(goods.getId()).map(String::valueOf).orElse(null));
+            Map<String, String> goodsTypeMap= dictValueAndDictResDtoMap.getOrDefault(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), new HashMap<>());
+            Map<String, String> goodsSpecMap= dictValueAndDictResDtoMap.getOrDefault(DictTypeEnum.GOODS_SPEC.getType(), new HashMap<>());
+            orderResp.setGoodsName(goods.getName()+"/"+goodsTypeMap.getOrDefault(goods.getGoodsType(),"")+"/"+goodsSpecMap.getOrDefault(goods.getSpec(), ""));
+        }
+
+        //供应企业
+        KwtLogisticsOrderUnit supplierEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + 1, new KwtLogisticsOrderUnit());
+        orderResp.setSupplierCompanyId(Optional.ofNullable(supplierEnt.getEntId()).map(String::valueOf).orElse(null));
+        orderResp.setSupplierCompanyName(supplierEnt.getFirmName());
+        //承运企业
+        KwtLogisticsOrderUnit carriageEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + 2, new KwtLogisticsOrderUnit());
+        orderResp.setCarriageCompanyId(Optional.ofNullable(carriageEnt.getEntId()).map(String::valueOf).orElse(null));
+        orderResp.setCarriageCompanyName(carriageEnt.getFirmName());
+
+        //装货地址
+        KwtLogisticsOrderAddress shipmentAddress = logOrderIdAndAddressMap.getOrDefault(order.getId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtLogisticsOrderAddress());
+        orderResp.setLoadAddress(shipmentAddress.getCityName()+shipmentAddress.getDetailAddress());
+        //卸货地址
+        KwtLogisticsOrderAddress takeAddress = logOrderIdAndAddressMap.getOrDefault(order.getId() + "-" + AddressTypeEnum.TAKE.getCode(), new KwtLogisticsOrderAddress());
+        orderResp.setUnloadAddress(takeAddress.getCityName()+takeAddress.getDetailAddress());
+        //装卸地之间距离
+        orderResp.setDistanceKm(order.getDistance());
+
+        //时间
+        orderResp.setStartTime(DateUtils.format(order.getStartTime(), DateUtils.DATE_PATTERN));
+        orderResp.setEndTime(DateUtils.format(order.getEndTime(), DateUtils.DATE_PATTERN));
+        KwtLogisticsOrderCirculate orderCirculate = logOrderIdAndCirculateMap.getOrDefault(order.getId(), new KwtLogisticsOrderCirculate());
+        orderResp.setSendTime(DateUtils.format(orderCirculate.getCreateTime(), DateUtils.DATE_TIME_PATTERN));
+
+        //派单人信息
+        UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(orderCirculate.getCreateBy());
+        orderResp.setSendOperator(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getName).orElse(null));
+        orderResp.setSendPhone(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getPhone).orElse(null));
+        orderResp.setStatus(Optional.ofNullable(order.getStatus()).map(String::valueOf).orElse(null));
+        orderResp.setStatusDesc(LogisticsOrderV1Enum.IN_TRANSIT.getCode().equals(order.getStatus()) ? "待接单" : "未知状态");
+        //设置余量
+        BigDecimal orderSurplus = getRawOreSupAmount(order, logisticsOrderIdAndSubtaskList);
+        orderResp.setOrderSurplus(orderSurplus.toPlainString());
+        orderResp.setRemainingAmount(orderSurplus);
+
+        return orderResp;
+    }
+
 
     /**
      * 查询司机关联车辆的物流运单
@@ -492,6 +681,7 @@ public class WaybillOrderService {
 
         //获取运单关联数据并返回结果
         List<WaybillOrderStatusResp> ordderList = getWaybillOrderRelevantData(param, records);
+        sort(param, ordderList);
         log.info("查询司机的物流运单成功!");
         return PageDataResult.success(param.getPageNum(), param.getPageSize(), waybillOrderList.getTotal() , ordderList);
     }
@@ -748,22 +938,72 @@ public class WaybillOrderService {
             log.info("当前车辆无物流订单,truckNo:{}", param.getTruckNo());
             throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_STATUS_ERROR, "当前车辆无物流订单");
         }
-        Map<Long, KwtLogisticsOrder> logOrderMap = logOrderList.stream().collect(Collectors.toMap(logOrder -> logOrder.getId(),
+
+        // 按照order_type区分“正常订单”和“原矿运输订单”
+        Map<Boolean, List<KwtLogisticsOrder>> partitionedMap = logOrderList.stream()
+                .collect(Collectors.partitioningBy(order -> Integer.valueOf(1).equals(order.getOrderType())));
+        List<KwtLogisticsOrder> typeNullList = partitionedMap.get(false);
+        List<KwtLogisticsOrder> typeOneList = partitionedMap.get(true);
+        log.info("正常流程订单信息: {},数量:{}, 原矿运输订单信息: {},数量:{}",  JSON.toJSONString(typeNullList), typeNullList.size(),
+                JSON.toJSONString(typeOneList), typeOneList.size());
+
+        List<WaybillOrderStatusResp> ordderList = new ArrayList<>();
+        //1.查询正常流程物流运运单
+        if (CollectionUtils.isNotEmpty(typeNullList)) {
+            List<WaybillOrderStatusResp> normalOrdderList = getWaybillOrderStatusResps(param, records, typeNullList,
+                    orderSubtaskList, wbOrderIdList, subtaskMap, logOrderIdAndCirculateMap, Boolean.FALSE);
+            ordderList.addAll(normalOrdderList);
+        }
+
+        //2.查询原矿运输物流运运单
+        if (CollectionUtils.isNotEmpty(typeOneList)) {
+            List<WaybillOrderStatusResp> rawOreOrdderList = getWaybillOrderStatusResps(param, records, typeOneList,
+                    orderSubtaskList,wbOrderIdList, subtaskMap, logOrderIdAndCirculateMap, Boolean.TRUE);
+            ordderList.addAll(rawOreOrdderList);
+        }
+
+        return ordderList;
+    }
+
+    /**
+     * 查询正常流程物流运单
+     * @param param
+     * @return
+     */
+    private List<WaybillOrderStatusResp> getWaybillOrderStatusResps(WaybillOrderQueryParam param, List<KwtWaybillOrder> records,
+                                                                    List<KwtLogisticsOrder> logOrderList,
+                                                                    List<KwtWaybillOrderSubtask> orderSubtaskList,
+                                                                    List<Long> wbOrderIdList,
+                                                                    Map<Long, KwtWaybillOrderSubtask> subtaskMap,
+                                                                    Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
+                                                                    boolean isRawOre) {
+        log.info("开始{}物流运单查询,param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(param));
+        List<Long> logOrderIdList = logOrderList.stream().map(KwtLogisticsOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
+        // 物流订单映射
+        Map<Long, KwtLogisticsOrder> logOrderMap = logOrderList.stream().collect(Collectors.toMap(KwtLogisticsOrder::getId,
                 Function.identity(), (x, y) -> x));
-        Set<Long> tradeIds = logOrderList.stream()
-                .map(KwtLogisticsOrder::getTOrderId)
-                .collect(Collectors.toSet());
-        //获取贸易订单
-        List<OrderDetailVo> orderDetailVos = tradeOrderInfoService.queryByTradeOrderIds(tradeIds);
-        if (CollectionUtils.isEmpty(orderDetailVos)) {
-            log.info("当前车辆的贸易订单无数据,truckNo:{}", param.getTruckNo());
-            throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_NOT_FOUND, "当前车辆的贸易订单数据不存在");
+
+        // 贸易订单相关(仅非原矿运输查询)
+        Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap;
+        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList;
+        if (!isRawOre) {
+            Set<Long> tradeIds = logOrderList.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
+            //获取贸易订单
+            List<OrderDetailVo> orderDetailVos = tradeOrderInfoService.queryByTradeOrderIds(tradeIds);
+            if (CollectionUtils.isEmpty(orderDetailVos)) {
+                log.info("当前车辆的贸易订单无数据,truckNo:{}", param.getTruckNo());
+                throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_NOT_FOUND, "当前车辆的贸易订单数据不存在");
+            }
+            tradeIdAndOrderDetailVoMap = orderDetailVos.stream().collect(Collectors.toMap(OrderDetailVo::getId,
+                    Function.identity(), (x, y) -> x));
+
+            tradeIdAndLogOrderList = logOrderList.stream().collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));
+        } else {
+            tradeIdAndOrderDetailVoMap = new HashMap<>();
+            tradeIdAndLogOrderList = new HashMap<>();
         }
-        Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap = orderDetailVos.stream()
-                    .collect(Collectors.toMap(OrderDetailVo::getId, Function.identity(), (x, y) -> x));
 
-        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList = logOrderList.stream()
-                .collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));
+        // 子任务分组
         Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList = orderSubtaskList.stream()
                 .collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));
 
@@ -785,7 +1025,6 @@ public class WaybillOrderService {
         }
         Map<Long, KwpGoods> goodsIdAndGoodsMap = goodsInfoService.getGoodsByIds(goodsIds);
 
-
         //承运托运企业
         List<KwtLogisticsOrderUnit> logOrderUnits = logisticsOrderUnitRepository.queryByLogOrderIds(logOrderIdList);
         if (CollectionUtils.isEmpty(logOrderUnits)) {
@@ -804,22 +1043,24 @@ public class WaybillOrderService {
             log.info("当前车辆无物流运单装卸货信息,truckNo:{}", param.getTruckNo());
             throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_TICKET, "当前车辆无物流运单装卸货信息");
         }
-        Map<String, KwtWaybillOrderTicket> ticketMap = orderTicketList.stream().collect(
-                Collectors.toMap(ticket -> ticket.getWOrderId() + "-" + ticket.getType(),
+        Map<String, KwtWaybillOrderTicket> ticketMap = orderTicketList.stream()
+                .collect(Collectors.toMap(ticket -> ticket.getWOrderId() + "-" + ticket.getType(),
                         Function.identity(), (x, y) -> x));
 
         //查询字典
         Map<String, Map<String, String>> dictValueAndDictResDtoMap = remoteSystemService.queryDictByType(
                 Arrays.asList(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
 
-        List<WaybillOrderStatusResp> ordderList = records.stream().map(
-                billOrder -> {
+        List<WaybillOrderStatusResp> orderList = records.stream()
+                .filter(record -> record.getLOrderId() != null && logOrderIdList.contains(record.getLOrderId()))
+                .map(billOrder -> {
                     return getWaybillOrderResp(billOrder, subtaskMap, logOrderMap, logOrderIdAndCirculateMap,
                             logOrderIdAndGoodsMap, logOrderIdAndUnitMap, logOrderIdAndAddressMap, ticketMap,
                             tradeIdAndOrderDetailVoMap,tradeIdAndLogOrderList,logisticsOrderIdAndSubtaskList,
                             dictValueAndDictResDtoMap, goodsIdAndGoodsMap);
                 }).collect(Collectors.toList());
-        return ordderList;
+        log.info("{}物流运单查询结束,result:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(orderList));
+        return orderList;
     }
 
 
@@ -848,6 +1089,8 @@ public class WaybillOrderService {
         wbOrderResp.setLogisticsOrderId(Optional.ofNullable(wbOrder.getLOrderId()).map(String::valueOf).orElse(null));
         wbOrderResp.setWaybillNo(wbOrder.getWOrderNo());
         wbOrderResp.setRemark(wbOrder.getRemark());
+        wbOrderResp.setLabel(wbOrder.getLabel());
+        wbOrderResp.setUpdateTime(wbOrder.getUpdateTime());
         //装货、卸货净重、任务量
         KwtWaybillOrderSubtask subtask = subtaskMap.getOrDefault(wbOrder.getId(), new KwtWaybillOrderSubtask());
         wbOrderResp.setLoadingNetWeight(subtask.getLoadAmount());
@@ -859,11 +1102,13 @@ public class WaybillOrderService {
         wbOrderResp.setLogisticsOrderNo(logOrder.getLOrderNo());
         wbOrderResp.setChargeType(logOrder.getBillingMode());
         wbOrderResp.setChargeTypeDesc(DictEnum.getLabel(DictTypeEnum.CHARGING_TYPE.getType(), logOrder.getBillingMode()));
+        wbOrderResp.setOrderType(logOrder.getOrderType());
+
         //设置余量
-        KwtLogisticsOrder order = logOrderMap.getOrDefault(wbOrder.getLOrderId(), new KwtLogisticsOrder());
-        BigDecimal supAmount = getSupAmount(order.getTOrderId(), tradeIdAndOrderDetailVoMap, tradeIdAndLogOrderList,
-                logisticsOrderIdAndSubtaskList);
+        BigDecimal supAmount = Objects.equals(1, logOrder.getOrderType()) ? getRawOreSupAmount(logOrder, logisticsOrderIdAndSubtaskList)
+                : getSupAmount(logOrder.getTOrderId(), tradeIdAndOrderDetailVoMap, tradeIdAndLogOrderList, logisticsOrderIdAndSubtaskList);
         wbOrderResp.setOrderSurplus(supAmount);
+
         //托运企业
         KwtLogisticsOrderUnit consignEnt = logOrderIdAndUnitMap.getOrDefault(wbOrder.getLOrderId() + "-" + UnitTypeEnum.CONSIGN.getCode(), new KwtLogisticsOrderUnit());
         wbOrderResp.setConsignCompanyId(Optional.ofNullable(consignEnt.getEntId()).map(String::valueOf).orElse(null));
@@ -924,7 +1169,11 @@ public class WaybillOrderService {
         } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.COMPLETION_LOADING.getCode())) {
             wbOrderResp.setStatusDesc("待审核");
         } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.COMPLETED.getCode())) {
-            wbOrderResp.setStatusDesc("已完成");
+            if (Objects.equals(subtask.getRemark(), "空载离场")) {
+                wbOrderResp.setStatusDesc("空载完成");
+            } else {
+                wbOrderResp.setStatusDesc("已完成");
+            }
         } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.REVIEW_REJECTION.getCode())) {
             wbOrderResp.setStatusDesc("待修改");
         } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.CANCELLED.getCode())) {
@@ -1021,6 +1270,75 @@ public class WaybillOrderService {
         return result;
     }
 
+
+    /**
+     * 计算贸易订单余量
+     * 逻辑:贸易订单总量 - (所有关联物流订单下,非取消/完成状态的子运单委托量 + 对应计费模式的磅单量)
+     *
+     * @param tradeOrderId                贸易订单ID
+     * @param tradeIdAndOrderDetailVoMap  贸易订单详情映射
+     * @param tradeIdAndLogOrderList      贸易订单关联的物流订单列表映射
+     * @param logisticsOrderIdAndSubtaskList 物流订单关联的子运单列表映射
+     * @param waybillOrderIdAndTicketList    运单ID关联的磅单列表映射
+     * @return 订单余量,保留两位小数
+     */
+    private BigDecimal getRawOreSupAmount(KwtLogisticsOrder order,
+                                          Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList) {
+        log.debug("开始计算物流订单余量,param: {}", JSON.toJSONString(order));
+
+        // 1. 获取贸易订单总货物量
+        BigDecimal tradeAmount = order.getAmount();
+        log.debug("物流订单[{}]总货物量: {}", order.getId(), tradeAmount);
+
+        Long logOrderId = order.getId();
+        // 获取当前物流订单下的所有子运单
+        List<KwtWaybillOrderSubtask> waybillOrderSubtasks = logisticsOrderIdAndSubtaskList.getOrDefault(logOrderId, Collections.emptyList());
+
+        if (CollectionUtils.isEmpty(waybillOrderSubtasks)) {
+            BigDecimal tradeTotalAmount = tradeAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount;
+            BigDecimal bigDecimal = tradeTotalAmount.setScale(2, RoundingMode.HALF_UP);
+            log.debug("物流订单[{}]无子运单,跳过, 最终余量: {}",logOrderId, bigDecimal);
+            return bigDecimal;
+        }
+
+        // 定义需要剔除的状态:已取消、已完成、空载(这些状态下的运单不再占用当前可接单的余量,或者其量已结算)
+        // 注意:具体业务逻辑中,通常“进行中”的运单会占用余量。这里根据原代码逻辑,剔除CANCELLED和COMPLETED。
+        //      空载待离场,实际装货量接近0,所以也要剔除
+        List<Integer> excludeStatusList = Arrays.asList(CarWaybillV1Enum.CANCELLED.getCode(), CarWaybillV1Enum.COMPLETED.getCode()
+                , CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode());
+
+        // 4. 计算子运单委托量合计(仅统计未取消/未完成/空载的有效子运单)
+        BigDecimal entrustAmount = waybillOrderSubtasks.stream()
+                .filter(Objects::nonNull)
+                .filter(subtask -> !excludeStatusList.contains(subtask.getStatus()))
+                .map(KwtWaybillOrderSubtask::getEntrustAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+        log.debug("物流订单[{}]子运单委托量合计: {}", logOrderId, entrustAmount);
+
+        // 5. 计算运单已完成的合计量
+        BigDecimal totalLoadAmount = order.getTotalLoadAmount();
+        totalLoadAmount = totalLoadAmount == null || totalLoadAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : totalLoadAmount;
+        log.debug("物流订单[{}]有完成的运单实际装货量合计: {}", logOrderId, totalLoadAmount);
+
+        // 累加到总占用量
+        BigDecimal usedAmount = entrustAmount.add(totalLoadAmount);
+
+        log.debug("物流订单[{}]总占用量: {}", logOrderId, usedAmount);
+
+        // 6. 计算余量:贸易订单总量 - 已占用量
+        // 如果计算结果小于等于0,则余量为0,避免负数
+        BigDecimal surplus = tradeAmount.subtract(usedAmount);
+        BigDecimal finalSurplus = surplus.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : surplus;
+
+        // 保留两位小数,四舍五入
+        BigDecimal result = finalSurplus.setScale(2, RoundingMode.HALF_UP);
+        log.debug("物流订单[{}]最终余量: {}", logOrderId, result);
+
+        return result;
+    }
+
     /**
      * 批量构建运单ID与磅单信息映射,供订单余量计算复用。
      */
@@ -1046,6 +1364,22 @@ public class WaybillOrderService {
                 .collect(Collectors.groupingBy(KwtWaybillOrderTicket::getWOrderId));
     }
 
+    /**
+     * 排序
+     * @param param
+     * @param gatekeeperOrderPageResult
+     */
+    private void sort(WaybillOrderQueryParam param, List<WaybillOrderStatusResp> ordderList) {
+        log.info("运单分页列表排序,param:{}, order:{}", JSON.toJSONString(param), JSON.toJSONString(ordderList));
+        if (CollectionUtils.isEmpty(ordderList)) {
+            return;
+        }
+        // 完成运单,根据时间倒叙排列
+        if (Objects.equals(3, param.getStatus())) {
+            ordderList.sort(Comparator.comparing(WaybillOrderStatusResp::getUpdateTime).reversed());
+        }
+    }
+
     /**
      * 运单统计
      * @param param
@@ -1294,10 +1628,6 @@ public class WaybillOrderService {
             throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "当前车辆没有可以称重过磅状态的运单");
         }
         param.setWaybillOrderId(wbOrderByTruckNo.get(0).getId());
-
-        //mock
-        param.setWeighbridgeName("测试名称");
-        param.setWeighUrl("chengdu.aliyuncs.com/kll/uploads/20251126/792a668bf5034ddc24d7a3dbe4ca88bf1764125000057.png");
         comeIntoHandler.handler(param);
     }
 
@@ -1405,6 +1735,42 @@ public class WaybillOrderService {
         unloadingHandler.handler(param);
     }
 
+    /**
+     * 过磅推送图片
+     * @param param
+     */
+    public void weighImage(WaybillOrderWeighImageParam param) {
+        if (StringUtils.isBlank(param.getTruckNo())){
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "车牌号不能为空!");
+        }
+        // 定义运单可以过磅的状态集合(无论山上山下地磅)
+        List<Integer> FORBIDDEN_STATUSES = Arrays.asList(
+                CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
+                CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
+                CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
+                CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(),
+                CarWaybillV1Enum.WAIT_LEAVE.getCode(),
+                CarWaybillV1Enum.UNLOADING.getCode(),
+                CarWaybillV1Enum.REPLENISHING.getCode(),
+                CarWaybillV1Enum.REPLENISH_FINISH.getCode(),
+                CarWaybillV1Enum.WAIT_LOADING.getCode(),
+                CarWaybillV1Enum.UNLOADING_POINT.getCode()
+        );
+        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
+        if (CollectionUtils.isEmpty(wbOrderByTruckNo)) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[过磅推送图片]当前车辆没有可以过磅称重状态的运单");
+        }
+        if (wbOrderByTruckNo.size() > 1) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[过磅推送图片]当前车辆过磅称重状态存在多条运单");
+        }
+        KwtWaybillOrder waybillOrder = wbOrderByTruckNo.get(0);
+        KwtWaybillOrderNode waybillOrderNode = waybillOrderNodeRepository.queryNodesByOrderId(waybillOrder.getId(), waybillOrder.getStatus());
+        if (waybillOrderNode == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[过磅推送图片]未查询运单节点数据");
+        }
+        waybillOrderNode.setWeighUrl(param.getWeighUrl());
+    }
+
 
 
 //    /**