Bläddra i källkod

新增自动派单(贸易合同、物流合同、贸易订单、物流订单)

donglang 1 månad sedan
förälder
incheckning
e0f34201be
49 ändrade filer med 1409 tillägg och 75 borttagningar
  1. 49 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/enums/DispatchWayEnums.java
  2. 48 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/DateUtils.java
  3. 1 1
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/DistanceUtils.java
  4. 16 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/RemoteContractService.java
  5. 6 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractCommonInfoResDto.java
  6. 72 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/LogisticsEntDtoVO.java
  7. 6 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/TradeContractResDto.java
  8. 7 1
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/RemoteFleetService.java
  9. 35 0
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/vo/RDriverScoreVo.java
  10. 5 0
      sckw-modules-api/sckw-product-api/src/main/java/com/sckw/product/api/model/KwpGoods.java
  11. 15 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteSystemService.java
  12. 128 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/ActualDisPatchDto.java
  13. 105 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/SingleTripTotalTimeDto.java
  14. 16 0
      sckw-modules-api/sckw-transport-api/src/main/java/com/sckw/transport/api/model/param/AddLogisticOrderParam.java
  15. 5 0
      sckw-modules/sckw-contract/pom.xml
  16. 4 4
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dao/KwcContractLogisticsScoreMapper.java
  17. 22 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dubbo/RemoteContractServiceImpl.java
  18. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractTrade.java
  19. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/QueryListReqVo.java
  20. 6 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/QueryTradeReq.java
  21. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/SupplyContractTradeReq.java
  22. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/TradeBaseInfoReqVo.java
  23. 11 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/res/ContractDetailResp.java
  24. 8 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsGoodsRepository.java
  25. 9 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsRepository.java
  26. 27 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsScoreRepository.java
  27. 23 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsUnitRepository.java
  28. 2 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractTradeRepository.java
  29. 155 2
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractTradeService.java
  30. 57 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dubbo/RemoteFleetServiceImpl.java
  31. 30 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfDriverScoreRepository.java
  32. 7 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfTruckRepository.java
  33. 7 0
      sckw-modules/sckw-order/pom.xml
  34. 6 0
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/KwoTradeOrder.java
  35. 5 0
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/vo/req/ContractInfo.java
  36. 175 15
      sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java
  37. 1 1
      sckw-modules/sckw-product/src/main/java/com/sckw/product/service/KwpGoodsService.java
  38. 115 6
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteSystemServiceImpl.java
  39. 2 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dubbo/TransportServiceImpl.java
  40. 1 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java
  41. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtLogisticsOrder.java
  42. 12 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/AddLogisticOrderDTO.java
  43. 6 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/LogisticData.java
  44. 8 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderCirculateRepository.java
  45. 0 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderContractRepository.java
  46. 161 13
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtAcceptCarriageOrderService.java
  47. 0 9
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java
  48. 0 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java
  49. 2 17
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/WaybillOrderService.java

+ 49 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/enums/DispatchWayEnums.java

@@ -0,0 +1,49 @@
+package com.sckw.core.model.enums;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.EnumSet;
+
+/**
+ * Author: donglang
+ * Time: 2025-12-10
+ * Des: 派车方式枚举
+ * Version: 1.0
+ */
+
+@Getter
+@AllArgsConstructor
+public enum DispatchWayEnums {
+
+    /**
+     * 手动派单
+     */
+    MANUAL_DISPATCH(1,  "手动派单"),
+
+    /**
+     * 自动派单
+     */
+    AUTO_DISPATCH(2, "自动派单"),
+
+    ;
+
+    private final Integer code;
+
+    private final String desc;
+
+
+    public static String getDesc(Integer code) {
+        if (code == null) {
+            return null;
+        }
+        for (DispatchWayEnums dispatchWayEnums : EnumSet.allOf(DispatchWayEnums.class)) {
+            if (dispatchWayEnums.code.equals(code)) {
+                return dispatchWayEnums.desc;
+            }
+        }
+        return null;
+    }
+
+}

+ 48 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/DateUtils.java

@@ -1,7 +1,9 @@
 package com.sckw.core.utils;
 
 import cn.hutool.core.date.DateUtil;
+import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
+import com.sckw.core.exception.BusinessPlatfromException;
 
 import java.text.DateFormat;
 import java.text.ParseException;
@@ -12,6 +14,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
@@ -841,6 +844,51 @@ public class DateUtils extends DateUtil {
                 .collect(Collectors.toList());
     }
 
+    /**
+     * 计算两个时间之前的天数
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    public static long daysBetween(Date startTime, Date endTime) {
+        if (startTime == null || endTime == null) {
+            throw new IllegalArgumentException("时间参数不能为空");
+        }
+
+        // 转换为 LocalDate
+        LocalDate start = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+        LocalDate end = endTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+
+        // 计算日历天数差
+        return java.time.temporal.ChronoUnit.DAYS.between(start, end);
+    }
+
+    /**
+     * 计算两个时间的分钟差值
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @return
+     */
+    public Long calculateTimeDiffMinutes(Date startTime, Date endTime) {
+        // 校验
+        if (startTime == null || endTime == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR,
+                    "计算时间差失败:,startTime=[" + startTime + "], endTime=[" + endTime + "]");
+        }
+
+        // 计算时间戳差值(毫秒)
+        long diffMillis = endTime.getTime() - startTime.getTime();
+
+        long diffMinutes = TimeUnit.MILLISECONDS.toMinutes(diffMillis);
+
+        // 时间顺序异常提醒(结束时间早于开始时间)
+        if (diffMinutes < 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR,
+                    "时间顺序异常,结束时间早于开始时间,startTime=[" + startTime + "], endTime=[" + endTime + "], 差值:[" + diffMinutes + "]分钟");
+        }
+        return diffMinutes;
+    }
+
     public static void main(String[] args) {
         getPreviousMonthsExclusive(5).forEach(x->{
             System.out.println(x.toString());

+ 1 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/utils/DistanceUtils.java → sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/DistanceUtils.java

@@ -1,4 +1,4 @@
-package com.sckw.transport.utils;
+package com.sckw.core.utils;
 
 
 import java.math.BigDecimal;

+ 16 - 0
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/RemoteContractService.java

@@ -2,6 +2,7 @@ package com.sckw.contract.api;
 
 import com.sckw.contract.api.model.dto.res.*;
 import com.sckw.contract.api.model.vo.KwcContractLogisticsDto;
+import com.sckw.contract.api.model.vo.LogisticsEntDtoVO;
 import com.sckw.contract.api.model.vo.TradeContractGoodsDto;
 import com.sckw.contract.api.model.vo.TradeContractResDto;
 import com.sckw.contract.api.model.vo.TradeContractUnitDto;
@@ -107,5 +108,20 @@ public interface RemoteContractService {
 
     KwcContractLogisticsDto queryContractByContractId(Long contractId);
 
+    /**
+     * 查询自动派车的物流合同信息List
+     */
+    List<LogisticsEntDtoVO> queryValidAutoContractLogOrder(Long entId, Long goodsId);
+
+    /**
+     * 查询自动派车的物流合同信息
+     */
+    TradeContractUnitDto queryEntByContractId(Long contractId);
+
+    /**
+     * 根据合同查询物流企业
+     */
+    List<Long> queryEntByContractIds(List<Long> contractIds);
+
     List<TradeContractUnitDto> queryContractUnitByContractId(Long contractId);
 }

+ 6 - 0
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractCommonInfoResDto.java

@@ -57,4 +57,10 @@ public class ContractCommonInfoResDto implements Serializable {
      */
     private List<EntInfo> entInfoList;
 
+    /**
+     * 派车方式(1-手动派车、2-自动派车)
+     */
+    private Integer dispatchWay;
+
+
 }

+ 72 - 0
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/LogisticsEntDtoVO.java

@@ -0,0 +1,72 @@
+package com.sckw.contract.api.model.vo;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+@Getter
+@Setter
+@ToString
+public class LogisticsEntDtoVO {
+
+    /**
+     * 合同id
+     */
+    private Long contractId;
+
+    /**
+     * 合同编号
+     */
+    private String contractNo;
+
+    /**
+     * 承运单位不能为空
+     */
+    private Long entId;
+
+    /**
+     * 承运企业名称不能为空
+     */
+    private String entName;
+
+    /**
+     * 运输单价
+     */
+    private BigDecimal transportPrice;
+
+    /**
+     * 联系人ID
+     */
+    private Long contactsId;
+
+    /**
+     * 联系人姓名
+     */
+    private String contacts;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 运输企业评分
+     */
+    private BigDecimal score;
+
+    /**
+     * 开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 结束时间
+     */
+    private Date endTime;
+
+}

+ 6 - 0
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/TradeContractResDto.java

@@ -82,4 +82,10 @@ public class TradeContractResDto implements Serializable {
      * 贸易合同关联的企业信息
      */
     private List<TradeContractUnitDto> unitList;
+
+    /**
+     * 派车方式
+     */
+    @TableField("dispatch_way")
+    private Integer dispatchWay;
 }

+ 7 - 1
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/RemoteFleetService.java

@@ -103,7 +103,9 @@ public interface RemoteFleetService {
      */
     RFleetVo findFleetById(Long fleetId);
 
-    List<TmsTruckAxleNumVO> getCarAxisInfo(List<Integer> axleNumIds);
+    TmsTruckAxleNumVO getCarAxisInfo(Integer axleNumId);
+
+    List<TmsTruckAxleNumVO> getCarAxisInfoList(List<Integer> axleNumIds);
 
 
     List<RTruckVo> findTruckByTruckIds(List<Long> truckIds);
@@ -122,4 +124,8 @@ public interface RemoteFleetService {
 
     void updateDriverScore(Long entId, Long driverId, Integer score);
 
+    List<RTruckVo> findTruckByEntIds(Long entId);
+
+    List<RDriverScoreVo> findDriverScoreIdByEntIds(Long proEntId, Long entId, List<Long> driverIds);
+
 }

+ 35 - 0
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/vo/RDriverScoreVo.java

@@ -0,0 +1,35 @@
+package com.sckw.fleet.api.model.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * @author zk
+ * @desc 司机
+ * @date 2023/7/17 0017
+ */
+@Data
+public class RDriverScoreVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 8792177577104218416L;
+
+    /** 供应商企业id */
+    private Long providerEntId;
+
+    /** 物流企业id */
+    private Long logisticsEntId;
+
+    /** 司机id */
+    private Long driverId;
+
+    /** 供应商企业名称 */
+    private String providerEntName;
+
+    /** 司机评分 */
+    private BigDecimal score;
+
+}

+ 5 - 0
sckw-modules-api/sckw-product-api/src/main/java/com/sckw/product/api/model/KwpGoods.java

@@ -120,4 +120,9 @@ public class KwpGoods extends BaseModel implements Serializable {
     @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date shelfTime;
 
+    /**
+     * 轴数
+     */
+    private String carAxis;
+
 }

+ 15 - 0
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteSystemService.java

@@ -1,6 +1,8 @@
 package com.sckw.system.api;
 
 import com.sckw.core.web.response.result.PageDataResult;
+import com.sckw.system.api.model.dto.req.ActualDisPatchDto;
+import com.sckw.system.api.model.dto.req.SingleTripTotalTimeDto;
 import com.sckw.system.api.model.dto.res.*;
 
 import java.util.List;
@@ -292,4 +294,17 @@ public interface RemoteSystemService {
     KwsRoleDto queryByRoleIdAndEntId(Long currentRoleId);
 
     List<EntTypeResDto> queryEntTypeByIds(Set<Long> entIds);
+
+    /**
+     * 计算平台配置的运单单趟总耗时
+     * @param dto
+     * @return
+     */
+    Integer calSingleTripTotalTimes(SingleTripTotalTimeDto dto);
+
+    /**
+     * 计算平台配置贸易订单实际派车数
+     * @param dto
+     */
+    Integer getActualDisPatch(ActualDisPatchDto dto);
 }

+ 128 - 0
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/ActualDisPatchDto.java

@@ -0,0 +1,128 @@
+package com.sckw.system.api.model.dto.req;
+
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * Author: donglang
+ * Time: 2025-12-11
+ * Des: 平台配置的实际派车梳理查询参数
+ * Version: 1.0
+ */
+@Data
+public class ActualDisPatchDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -8552535107566268748L;
+
+    /**
+     * 贸易订单id
+     */
+    private Long tradeOrderId;
+
+    /**
+     * 托运企业id
+     */
+    private Long entId;
+
+    /**
+     * 开始日期
+     */
+    private Date startTime;
+
+    /**
+     * 结束日期
+     */
+    private Date endTime;
+
+    /**
+     * 运输单价
+     */
+    private BigDecimal amount;
+
+    /**
+     * 起点经度
+     */
+    private String lon1;
+
+    /**
+     * 起点维度
+     */
+    private String lat1;
+
+    /**
+     * 终点经度
+     */
+    private String lon2;
+
+    /**
+     * 终点维度
+     */
+    private String lat2;
+
+
+    /**
+     * 车辆工作时长
+     */
+    private Integer vehicleWorkHours;
+
+    /**
+     * 车辆装货时长
+     */
+    private Integer vehicleLoadingHours;
+
+    /**
+     * 车辆卸货时长
+     */
+    private Integer vehicleUnloadingHours;
+
+    /**
+     * 司机超时限制
+     */
+    private Integer driverTimeoutLimit;
+
+    /**
+     * 车辆平均载重
+     */
+    private Integer vehicleAvgLoad;
+
+    /**
+     * 车辆平均速度
+     */
+    private Integer vehicleAvgSpeed;
+
+    /**
+     * 车辆最大任务数
+     */
+    private Integer vehicleMaxTasks;
+
+    /**
+     * 司机接单限制
+     */
+    private Integer driverOrderLimit;
+
+    /**
+     * 场内车辆容量
+     */
+    private Integer yardVehicleCapacity;
+
+    /**
+     * 最大占比
+     */
+    private Integer maxRatio;
+
+    /**
+     * 缓冲系数
+     */
+    private BigDecimal bufferCoefficient;
+
+
+
+
+
+}

+ 105 - 0
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/SingleTripTotalTimeDto.java

@@ -0,0 +1,105 @@
+package com.sckw.system.api.model.dto.req;
+
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * Author: donglang
+ * Time: 2025-12-11
+ * Des: 平台配置的单趟总耗时查询参数
+ * Version: 1.0
+ */
+@Data
+public class SingleTripTotalTimeDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -8552535107566268748L;
+
+    /**
+     * 托运企业id
+     */
+    private Long entId;
+
+    /**
+     * 起点经度
+     */
+    private String lon1;
+
+    /**
+     * 起点维度
+     */
+    private String lat1;
+
+    /**
+     * 终点经度
+     */
+    private String lon2;
+
+    /**
+     * 终点维度
+     */
+    private String lat2;
+
+
+    /**
+     * 车辆工作时长
+     */
+    private Integer vehicleWorkHours;
+
+    /**
+     * 车辆装货时长
+     */
+    private Integer vehicleLoadingHours;
+
+    /**
+     * 车辆卸货时长
+     */
+    private Integer vehicleUnloadingHours;
+
+    /**
+     * 司机超时限制
+     */
+    private Integer driverTimeoutLimit;
+
+    /**
+     * 车辆平均载重
+     */
+    private Integer vehicleAvgLoad;
+
+    /**
+     * 车辆平均速度
+     */
+    private Integer vehicleAvgSpeed;
+
+    /**
+     * 车辆最大任务数
+     */
+    private Integer vehicleMaxTasks;
+
+    /**
+     * 司机接单限制
+     */
+    private Integer driverOrderLimit;
+
+    /**
+     * 场内车辆容量
+     */
+    private Integer yardVehicleCapacity;
+
+    /**
+     * 最大占比
+     */
+    private Integer maxRatio;
+
+    /**
+     * 缓冲系数
+     */
+    private BigDecimal bufferCoefficient;
+
+
+
+}

+ 16 - 0
sckw-modules-api/sckw-transport-api/src/main/java/com/sckw/transport/api/model/param/AddLogisticOrderParam.java

@@ -238,4 +238,20 @@ public class AddLogisticOrderParam implements Serializable {
     @NotNull(message = "计划发货时间不能为空")
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private LocalDate startTime;
+
+
+    /**
+     * 派车方式
+     */
+    @NotNull(message = "派车方式不能为空")
+    private Integer dispatchWay;
+
+    /**
+     * 平台实际派车数
+     */
+    @NotNull(message = "平台实际派车数")
+    private Integer actualDisPatch;
+
+
+
 }

+ 5 - 0
sckw-modules/sckw-contract/pom.xml

@@ -99,6 +99,11 @@
             <artifactId>sckw-transport-api</artifactId>
             <version>${basic.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-fleet-api</artifactId>
+            <version>${basic.version}</version>
+        </dependency>
         <dependency>
             <groupId>com.sckw</groupId>
             <artifactId>sckw-common-stream</artifactId>

+ 4 - 4
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dao/KwcContractLogisticsScoreMapper.java

@@ -1,12 +1,13 @@
 package com.sckw.contract.dao;
 
-import java.util.List;
-
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sckw.contract.model.dto.req.LogisticsScoreQueryDto;
 import com.sckw.contract.model.entity.KwcContractLogisticsScore;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 物流企业评分Mapper接口
  * 
@@ -14,8 +15,7 @@ import org.apache.ibatis.annotations.Param;
  * @date 2025-12-05
  */
 @Mapper
-public interface KwcContractLogisticsScoreMapper
-{
+public interface KwcContractLogisticsScoreMapper  extends BaseMapper<KwcContractLogisticsScore> {
     /**
      * 查询物流企业评分
      * 

+ 22 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dubbo/RemoteContractServiceImpl.java

@@ -255,6 +255,7 @@ public class RemoteContractServiceImpl implements RemoteContractService {
             tradeContractResDto.setId(kwcContractTrade.getId());
             tradeContractResDto.setContactName(kwcContractTrade.getName());
             tradeContractResDto.setContractNo(kwcContractTrade.getContractNo());
+            tradeContractResDto.setDispatchWay(kwcContractTrade.getDispatchWay());
             KwcContractTradeGoods kwcContractTradeGoods = kwcContractTradeGoodsMapper.selectOne(new LambdaQueryWrapper<KwcContractTradeGoods>()
                     .eq(KwcContractTradeGoods::getContractId, tradeContractId)
                     .eq(KwcContractTradeGoods::getGoodsId, goodsId)
@@ -343,6 +344,7 @@ public class RemoteContractServiceImpl implements RemoteContractService {
         contractCommonInfoResDto.setEntInfoList(entList);
         contractCommonInfoResDto.setStatus(kwcContractLogistics.getStatus());
         contractCommonInfoResDto.setStatusName(Objects.requireNonNull(ContractStatusEnum.getName(kwcContractLogistics.getStatus())).getName());
+        contractCommonInfoResDto.setDispatchWay(kwcContractLogistics.getDispatching());
         List<KwcContractLogisticsUnit> kwcContractLogisticsUnits = kwcContractLogisticsUnitService.queryByContractId(kwcContractLogistics.getId());
         if (CollectionUtils.isNotEmpty(kwcContractLogisticsUnits)) {
             for (KwcContractLogisticsUnit kwcContractLogisticsUnit : kwcContractLogisticsUnits) {
@@ -367,6 +369,7 @@ public class RemoteContractServiceImpl implements RemoteContractService {
         contractCommonInfoResDto.setEntInfoList(entList);
         contractCommonInfoResDto.setStatus(kwcContractTrade.getStatus());
         contractCommonInfoResDto.setStatusName(Objects.requireNonNull(ContractStatusEnum.getName(kwcContractTrade.getStatus())).getName());
+        contractCommonInfoResDto.setDispatchWay(kwcContractTrade.getDispatchWay());
         List<KwcContractLogisticsUnit> kwcContractLogisticsUnits = kwcContractLogisticsUnitService.queryByContractId(kwcContractTrade.getId());
         if (CollectionUtils.isNotEmpty(kwcContractLogisticsUnits)) {
             for (KwcContractLogisticsUnit kwcContractLogisticsUnit : kwcContractLogisticsUnits) {
@@ -378,4 +381,23 @@ public class RemoteContractServiceImpl implements RemoteContractService {
         }
         return contractCommonInfoResDto;
     }
+
+
+    @Override
+    public List<LogisticsEntDtoVO> queryValidAutoContractLogOrder(Long entId, Long goodsId) {
+        return kwcContractTradeService.queryValidAutoContractLogOrder(entId, goodsId);
+    }
+
+    @Override
+    public TradeContractUnitDto queryEntByContractId(Long contractId) {
+        return kwcContractTradeService.queryEntByContractId(contractId);
+    }
+
+
+    @Override
+    public List<Long> queryEntByContractIds(List<Long> contractIds) {
+        return kwcContractTradeService.queryEntByContractIds(contractIds);
+    }
+
+
 }

+ 7 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractTrade.java

@@ -162,4 +162,11 @@ public class KwcContractTrade implements Serializable {
      */
     @TableField("sign_time")
     private Date signTime;
+
+    /**
+     * 派车方式
+     */
+    @TableField("dispatch_way")
+    private Integer dispatchWay;
+
 }

+ 7 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/QueryListReqVo.java

@@ -117,4 +117,11 @@ public class QueryListReqVo extends PageReq implements Serializable {
     @Schema(description = "供应单位id")
     private String supplyEntId;
 
+    /**
+     * 派车方式
+     */
+    @Schema(description = "派车方式(1-手动派车、2-自动派车)")
+    private Integer dispatchWay;
+
+
 }

+ 6 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/QueryTradeReq.java

@@ -49,4 +49,10 @@ public class QueryTradeReq extends PageReq implements Serializable {
     private Integer status;
     @Schema(description = "企业id")
     private String entId;
+
+    /**
+     * 派车方式
+     */
+    @Schema(description = "派车方式")
+    private Integer dispatchWay;
 }

+ 7 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/SupplyContractTradeReq.java

@@ -152,6 +152,13 @@ public class SupplyContractTradeReq implements Serializable {
         @Schema(description = "结算方式")
         private Integer settlement;
 
+        /**
+         * 派车方式
+         */
+        @NotNull(message = "派车方式不能为空")
+        @Schema(description = "派车方式")
+        private Integer dispatchWay;
+
         /**
          * 托运方式
          */

+ 7 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/TradeBaseInfoReqVo.java

@@ -1,6 +1,7 @@
 package com.sckw.contract.model.vo.req;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Size;
@@ -93,6 +94,12 @@ public class TradeBaseInfoReqVo implements Serializable {
     @NotNull(message = "结算方式不能为空")
     private Integer settlement;
 
+    /**
+     * 派车方式
+     */
+    @Schema(description = "派车方式")
+    private Integer dispatchWay;
+
     /**
      * 托运方式
      */

+ 11 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/res/ContractDetailResp.java

@@ -164,6 +164,17 @@ public class ContractDetailResp implements Serializable {
         @Schema(description = "结算方式描述")
         private String settlementDesc;
 
+        /**
+         * 派车方式
+         */
+        @Schema(description = "派车方式")
+        private Integer dispatchWay;
+        /**
+         * 派车方式描述
+         */
+        @Schema(description = "派车方式描述")
+        private String dispatchWayDesc;
+
         /**
          * 托运方式
          */

+ 8 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsGoodsRepository.java

@@ -47,4 +47,12 @@ public class KwcContractLogisticsGoodsRepository extends ServiceImpl<KwcContract
                 .eq(KwcContractLogisticsGoods::getGoodsId,goodsId)
                 .in(KwcContractLogisticsGoods::getContractId,logTradeContractIds));
     }
+
+
+    public List<KwcContractLogisticsGoods> queryByContractIdsAndGoodId(List<Long> contractIds, Long goodId) {
+        return list(Wrappers.<KwcContractLogisticsGoods>lambdaQuery()
+                .in(KwcContractLogisticsGoods::getContractId,contractIds)
+                .eq(KwcContractLogisticsGoods::getGoodsId,goodId)
+                .eq(KwcContractLogisticsGoods::getDelFlag,0));
+    }
 }

+ 9 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsRepository.java

@@ -116,4 +116,13 @@ public class KwcContractLogisticsRepository extends ServiceImpl<KwcContractLogis
                         //.or(queryWrapper2->queryWrapper2.ge(KwcContractLogistics::getStartTime, endTime).isNull(KwcContractLogistics::getEndTime))
                 ));
     }
+
+
+    public List<KwcContractLogistics> queryByIdsAndDispatch(List<Long> ids) {
+        return list(Wrappers.<KwcContractLogistics>lambdaQuery()
+                .in(KwcContractLogistics::getId, ids)
+                .eq(KwcContractLogistics::getDispatching, 2)
+                .eq(KwcContractLogistics::getStatus, 0)
+                .eq(KwcContractLogistics::getDelFlag, 0));
+    }
 }

+ 27 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsScoreRepository.java

@@ -0,0 +1,27 @@
+package com.sckw.contract.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.contract.dao.KwcContractLogisticsScoreMapper;
+import com.sckw.contract.model.entity.KwcContractLogisticsScore;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author :chenXiaoFei
+ * @version :1.0
+ * @description : 物流合同企业评分接口
+ * @create :2025-11-06 10:24:00
+ */
+@Repository
+public class KwcContractLogisticsScoreRepository extends ServiceImpl<KwcContractLogisticsScoreMapper, KwcContractLogisticsScore> {
+
+    public KwcContractLogisticsScore queryScoredByEntId(Long proEntId, Long logEntId) {
+        return getOne(Wrappers.<KwcContractLogisticsScore>lambdaQuery()
+                .eq(KwcContractLogisticsScore::getProviderEntId, proEntId)
+                .eq(KwcContractLogisticsScore::getLogisticsEntId, logEntId)
+                .last("LIMIT 1"));
+    }
+
+
+
+}

+ 23 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsUnitRepository.java

@@ -70,4 +70,27 @@ public class KwcContractLogisticsUnitRepository extends ServiceImpl<KwcContractL
                 .eq(Objects.nonNull(entType),KwcContractLogisticsUnit::getUnitType, entType)
                 .in(KwcContractLogisticsUnit::getEntId, entIdList));
     }
+
+
+    public List<KwcContractLogisticsUnit> queryByEntIdAndType(Long entId) {
+        return list(Wrappers.<KwcContractLogisticsUnit>lambdaQuery()
+                .eq(KwcContractLogisticsUnit::getEntId, entId)
+                .eq(KwcContractLogisticsUnit::getUnitType, 3)
+                .eq(KwcContractLogisticsUnit::getDelFlag, 0));
+    }
+
+    public List<KwcContractLogisticsUnit> queryByContractIds(List<Long> tradeContractIds) {
+        return list(Wrappers.<KwcContractLogisticsUnit>lambdaQuery()
+                .eq(KwcContractLogisticsUnit::getDelFlag, 0)
+                .eq(KwcContractLogisticsUnit::getUnitType, 4)
+                .in(KwcContractLogisticsUnit::getContractId, tradeContractIds));
+    }
+
+    public KwcContractLogisticsUnit queryByLogContractIdUnit(Long tradeContractId) {
+        return getOne(Wrappers.<KwcContractLogisticsUnit>lambdaQuery()
+                .eq(KwcContractLogisticsUnit::getDelFlag, 0)
+                .eq(KwcContractLogisticsUnit::getUnitType, 4)
+                .eq(KwcContractLogisticsUnit::getContractId, tradeContractId)
+                .last("limit 1"));
+    }
 }

+ 2 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractTradeRepository.java

@@ -63,7 +63,7 @@ public class KwcContractTradeRepository extends ServiceImpl<KwcContractTradeMapp
 
     public List<KwcContractTrade> queryTradeListByPageList(String contractCode,
                                                          String contractName, String supplementCode,
-                                                            Set<Long> contractIds, Integer status, int pageNum, int pageSize) {
+                                                            Set<Long> contractIds, Integer status, Integer dispatchWay, int pageNum, int pageSize) {
         return list( Wrappers.<KwcContractTrade>lambdaQuery()
                 .eq(KwcContractTrade::getDelFlag, 0)
                 .like(StringUtils.isNotBlank(contractCode),KwcContractTrade::getContractNo, contractCode)
@@ -71,6 +71,7 @@ public class KwcContractTradeRepository extends ServiceImpl<KwcContractTradeMapp
                 .eq(Objects.nonNull(status),KwcContractTrade::getStatus, status)
                 .like(StringUtils.isNotBlank(supplementCode),KwcContractTrade::getContractPid, supplementCode)
                 .in(CollectionUtils.isNotEmpty(contractIds),KwcContractTrade::getId, contractIds)
+                .eq(Objects.nonNull(dispatchWay),KwcContractTrade::getDispatchWay, dispatchWay)
                 .orderByDesc(KwcContractTrade::getUpdateTime)
                 .orderByDesc(KwcContractTrade::getId));
 

+ 155 - 2
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractTradeService.java

@@ -13,6 +13,8 @@ import com.sckw.contract.api.model.dto.res.ContractLogisticsOrderResDto;
 import com.sckw.contract.api.model.dto.res.ContractTradeOrderDto;
 import com.sckw.contract.api.model.dto.res.ContractTradeOrderInfo;
 import com.sckw.contract.api.model.dto.res.LogisticsOrderDto;
+import com.sckw.contract.api.model.vo.LogisticsEntDtoVO;
+import com.sckw.contract.api.model.vo.TradeContractUnitDto;
 import com.sckw.contract.dao.KwcContractTradeMapper;
 import com.sckw.contract.model.dto.req.QueryListReqDto;
 import com.sckw.contract.model.dto.res.QueryListResDto;
@@ -27,7 +29,9 @@ import com.sckw.contract.service.KwcContractTradeTrackService;
 import com.sckw.contract.service.KwcContractTradeUnitService;
 import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
+import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
+import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.exception.SystemException;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.enums.*;
@@ -106,6 +110,7 @@ public class KwcContractTradeService {
     private final KwcContractLogisticsUnitRepository kwcContractLogisticsUnitRepository;
     private final KwcContractLogisticsGoodsRepository kwcContractLogisticsGoodsRepository;
     private final KwcContractLogisticsRepository contractLogisticsRepository;
+    private final KwcContractLogisticsScoreRepository contractLogisticsScoreRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private RemoteSystemService remoteSystemService;
@@ -168,6 +173,7 @@ public class KwcContractTradeService {
         queryTradeReq.setSupplementCode(reqVo.getSupplementCode());
         queryTradeReq.setPurchaseEntId(reqVo.getPurchaseEntId());
         queryTradeReq.setSupplyEntId(reqVo.getSupplyEntId());
+        queryTradeReq.setDispatchWay(reqVo.getDispatchWay());
         queryTradeReq.setStatus(reqVo.getStatus());
         queryTradeReq.setPageNum(reqVo.getPageNum());
         queryTradeReq.setPageSize(reqVo.getPageSize());
@@ -340,6 +346,13 @@ public class KwcContractTradeService {
                     throw new SystemException("采购数量超长!");
                 }
             }
+            //验证供应单位必须在贸易合同生效期内,且有包含该商品的自动派车的物流合同
+            checkLogContractTime(baseInfo, goodsInfo);
+        }
+        if (Objects.equals(DispatchWayEnums.MANUAL_DISPATCH.getCode(), baseInfo.getDispatchWay())) {
+            if (baseInfo.getConsignment() == null) {
+                throw new SystemException("派车方式为手动派单时,托运方式不能为空!");
+            }
         }
         KwcContractTrade kwcContractTrade = kwcContractTradeRepository.queryByContractNo(baseInfo.getContractCode());
         if (Objects.nonNull(kwcContractTrade)) {
@@ -347,6 +360,37 @@ public class KwcContractTradeService {
         }
     }
 
+    /**
+     * 校验供应单位必须在贸易合同生效期内,且有包含该商品的自动派车的物流合同
+     * @param baseInfo
+     * @param goodsInfo
+     */
+    private void checkLogContractTime(TradeBaseInfoReqVo baseInfo, List<TradeGoodsInfoReqVo> goodsInfo) {
+        if (Objects.equals(DispatchWayEnums.AUTO_DISPATCH.getCode(), baseInfo.getDispatchWay())) {
+            List<LogisticsEntDtoVO> logisticsEntDtoVOS = new ArrayList<>();
+            for (TradeGoodsInfoReqVo good : goodsInfo) {
+                List<LogisticsEntDtoVO> logistics = queryValidAutoContractLogOrder(baseInfo.getProvideEntId(), good.getGoodsId());
+                logisticsEntDtoVOS.addAll(logistics);
+            }
+            List<LogisticsEntDtoVO> filteredLogistics  = logisticsEntDtoVOS.stream()
+                    .filter(Objects::nonNull)
+                    .filter(log -> log.getStartTime() != null && log.getEndTime() != null)
+                    .filter(log -> {
+                        boolean startTimeOk  = log.getStartTime().after(baseInfo.getStartTime());
+                        boolean endTimeOk = baseInfo.getEndTime() == null || log.getEndTime().before(baseInfo.getEndTime());
+                        return startTimeOk && endTimeOk;
+                    }).collect(Collectors.toList());
+            if (CollectionUtils.isEmpty(filteredLogistics)) {
+                throw new SystemException("请供应商先签订包含贸易商品的自动派车物流合同。");
+            }
+            //结束时间最早的
+            LogisticsEntDtoVO logEndTimeMin = filteredLogistics.stream()
+                    .filter(log -> log.getEndTime() != null)
+                    .min(Comparator.comparing(LogisticsEntDtoVO::getEndTime)).orElse(new LogisticsEntDtoVO());
+            log.error("自动派车物流合同将在【{}】失效,将影响派车,请及时续签。", logEndTimeMin.getEndTime());
+        }
+    }
+
     private static boolean hasDuplicateGoodsId(List<TradeGoodsInfoReqVo> goodsInfo) {
         if (goodsInfo == null || goodsInfo.isEmpty()) {
             return false;
@@ -400,6 +444,7 @@ public class KwcContractTradeService {
         kwcContractTrade.setUnloadWay(baseInfo.getUnloadWay());
         kwcContractTrade.setSalesmanId(baseInfo.getSalesmanId());
         kwcContractTrade.setSalesmanPhone(baseInfo.getSalesmanPhone());
+        kwcContractTrade.setDispatchWay(baseInfo.getDispatchWay());
 
 
         BigDecimal amountTotal = new BigDecimal(Global.NUMERICAL_ZERO);
@@ -734,6 +779,7 @@ public class KwcContractTradeService {
         kwcContractTrade.setUnloadWay(baseInfo.getUnloadWay());
         kwcContractTrade.setSalesmanId(baseInfo.getSalesmanId());
         kwcContractTrade.setSalesmanPhone(baseInfo.getSalesmanPhone());
+        kwcContractTrade.setDispatchWay(baseInfo.getDispatchWay());
         List<TradeGoodsInfoReqVo> goodsInfo = reqVo.getGoodsInfo();
         BigDecimal amountTotal = new BigDecimal(Global.NUMERICAL_ZERO);
         if (CollectionUtils.isNotEmpty(goodsInfo)) {
@@ -1263,6 +1309,7 @@ public class KwcContractTradeService {
         kwcContractTrade.setUnloadWay(baseInfo.getUnloadWay());
         kwcContractTrade.setSalesmanId(baseInfo.getSalesmanId());
         kwcContractTrade.setSalesmanPhone(baseInfo.getSalesmanPhone());
+        kwcContractTrade.setDispatchWay(baseInfo.getDispatchWay());
 
 
         BigDecimal amountTotal = new BigDecimal(Global.NUMERICAL_ZERO);
@@ -1491,6 +1538,8 @@ public class KwcContractTradeService {
                 String.valueOf(kwcContractTrade.getUnloadWay())));
         tradeBaseInfo.setSalesmanId(kwcContractTrade.getSalesmanId());
         tradeBaseInfo.setSalesmanPhone(kwcContractTrade.getSalesmanPhone());
+        tradeBaseInfo.setDispatchWay(kwcContractTrade.getDispatchWay());
+        tradeBaseInfo.setDispatchWayDesc(Optional.ofNullable(kwcContractTrade.getDispatchWay()).map(DispatchWayEnums::getDesc).orElse(""));
         return tradeBaseInfo;
     }
 
@@ -1536,7 +1585,7 @@ public class KwcContractTradeService {
                 req.getContractCode(),
                 req.getContractName(),
                 req.getSupplementCode(),
-                contractIds, req.getStatus(), req.getPageNum(), req.getPageSize());
+                contractIds, req.getStatus(), req.getDispatchWay(), req.getPageNum(), req.getPageSize());
         // List<KwcContractTrade> records = page.getRecords();
         if (org.apache.commons.collections4.CollectionUtils.isEmpty(records)) {
             return Collections.emptyList();
@@ -1996,7 +2045,7 @@ public class KwcContractTradeService {
                 req.getContractCode(),
                 req.getContractName(),
                 req.getSupplementCode(),
-                contractIds, req.getStatus(), 0, 0);
+                contractIds, req.getStatus(), req.getDispatchWay(), 0, 0);
 
         // List<KwcContractTrade> kwcContractTrades = kwcContractTradeRepository.queryTradeListByPageList(LoginUserHolder.getEntId());
 
@@ -2081,5 +2130,109 @@ public class KwcContractTradeService {
     public List<Long> queryTradeContractInfo(Long contractId) {
         return kwcContractTradeMapper.selectByContract(contractId);
     }
+
+
+    /**
+     * 查询同产品和同托运企业是否存在自动派车合同
+     * @param entId 托运企业
+     * @param goodsId 商品id
+     * @return
+     */
+    public List<LogisticsEntDtoVO> queryValidAutoContractLogOrder(Long entId, Long goodsId) {
+        log.info("查询自动派车的物流合同,企业id:{}, 商品id:{}",entId, goodsId);
+        if (Objects.isNull(entId)) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "供应商企业id不能为空!");
+        }
+        if (Objects.isNull(goodsId)) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "商品id不能为空!");
+        }
+
+        //查询物流合同托运企业信息
+        List<KwcContractLogisticsUnit> contractLogisticsUnits = kwcContractLogisticsUnitRepository.queryByEntIdAndType(entId);
+        if (CollectionUtils.isEmpty(contractLogisticsUnits)) {
+            return null;
+        }
+        List<Long> unitContractIds = contractLogisticsUnits.stream().map(KwcContractLogisticsUnit::getContractId).distinct().collect(Collectors.toList());
+
+        //查询物流商品合同信息
+        List<KwcContractLogisticsGoods> contractLogisticsGoods = kwcContractLogisticsGoodsRepository.queryByContractIdsAndGoodId(unitContractIds, goodsId);
+        if (CollectionUtils.isEmpty(contractLogisticsGoods)) {
+            return null;
+        }
+        Map<Long, KwcContractLogisticsGoods> goodsMap = contractLogisticsGoods.stream().collect(Collectors
+                .toMap(KwcContractLogisticsGoods::getContractId, Function.identity(), (x, y) -> x));
+        List<Long> goodContractIds = contractLogisticsGoods.stream().map(KwcContractLogisticsGoods::getContractId).distinct().collect(Collectors.toList());
+
+        //查询自动派车物流合同
+        List<KwcContractLogistics> contractLogistics = contractLogisticsRepository.queryByIdsAndDispatch(goodContractIds);
+
+        return contractLogistics.stream()
+                .map(log ->
+                        getContractLogisticsList(log,  goodsMap,  entId))
+                .sorted(Comparator.comparing(LogisticsEntDtoVO::getScore).reversed())
+                .collect(Collectors.toList());
+    }
+
+    @NotNull
+    private LogisticsEntDtoVO getContractLogisticsList(KwcContractLogistics log, Map<Long, KwcContractLogisticsGoods> goodsMap,
+                                                       Long proEntId) {
+        LogisticsEntDtoVO vo = new LogisticsEntDtoVO();
+        vo.setContractId(log.getId());
+        vo.setContractNo(log.getContractNo());
+        vo.setStartTime(log.getStartTime());
+        vo.setEndTime(log.getEndTime());
+        //承运企业信息
+        TradeContractUnitDto unit = queryEntByContractId(log.getId());
+        vo.setEntId(unit.getEntId());
+        vo.setEntName(unit.getFirmName());
+        vo.setContactsId(unit.getContactsId());
+        vo.setContacts(unit.getContacts());
+        vo.setPhone(unit.getPhone());
+        //商品价格
+        KwcContractLogisticsGoods goods = goodsMap.getOrDefault(log.getId(), new KwcContractLogisticsGoods());
+        vo.setTransportPrice(goods.getPriceUnit() == null ? BigDecimal.ZERO : new BigDecimal(goods.getPriceUnit()));
+        //评分
+        KwcContractLogisticsScore entScore = queryEntScoreByEntId(proEntId, unit.getEntId());
+        vo.setScore(entScore.getScore());
+
+        return vo;
+    }
+
+
+    //查询物流合同物流企业信息
+    public TradeContractUnitDto queryEntByContractId(Long contractId) {
+        KwcContractLogisticsUnit unit = kwcContractLogisticsUnitRepository.queryByLogContractIdUnit(contractId);
+        if (unit == null) {
+            return new TradeContractUnitDto();
+        }
+        TradeContractUnitDto tradeContractUnitDto = new TradeContractUnitDto();
+        tradeContractUnitDto.setUnitType(String.valueOf(unit.getUnitType()));
+        tradeContractUnitDto.setEntId(unit.getEntId());
+        tradeContractUnitDto.setFirmName(unit.getFirmName());
+        tradeContractUnitDto.setContactsId(unit.getContactsId());
+        tradeContractUnitDto.setContacts(unit.getContacts());
+        tradeContractUnitDto.setPhone(unit.getPhone());
+        return tradeContractUnitDto;
+
+    }
+
+    //查询物流合同物流企业信息
+    public List<Long> queryEntByContractIds(List<Long> contractIds) {
+        List<KwcContractLogisticsUnit> contractLogisticsUnits = kwcContractLogisticsUnitRepository.queryByContractIds(contractIds);
+        if (CollectionUtils.isEmpty(contractLogisticsUnits)) {
+            return Collections.emptyList();
+        }
+        return contractLogisticsUnits.stream().map(KwcContractLogisticsUnit::getEntId).collect(Collectors.toList());
+    }
+
+    //查询物流企业评分数据
+    public KwcContractLogisticsScore queryEntScoreByEntId(Long proEntId, Long logEntId) {
+        KwcContractLogisticsScore entScore = contractLogisticsScoreRepository.queryScoredByEntId(proEntId, logEntId);
+        if (entScore == null) {
+            return new KwcContractLogisticsScore();
+        }
+        return entScore;
+    }
+
 }
 

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

@@ -49,6 +49,7 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
     private final KwfTruckDispatchCoefficientRepository truckDispatchCoefficientRepository;
     private final KwfDriverConductRulesRepository driverConductRulesRepository;
     private final KwfTruckAxleNumRepository truckAxleNumRepository;
+    private final KwfDriverScoreRepository driverScoreRepository;
 
     /**
      * @param driverIds 司机档案主键id,多个已逗号隔开
@@ -393,13 +394,34 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
         return fleetVo;
     }
 
+    /**
+     * 查询轴数
+     * @param axleNumId
+     * @return
+     */
+    @Override
+    public TmsTruckAxleNumVO getCarAxisInfo(Integer axleNumId) {
+        if (axleNumId == null) {
+            return new TmsTruckAxleNumVO();
+        }
+        //查询车辆关联司机信息
+        TmsTruckAxleNum axleNum = kwfTruckAxleNumRepository.getOneById(axleNumId);
+        if (axleNum == null) {
+            return new TmsTruckAxleNumVO();
+        }
+        TmsTruckAxleNumVO vo = new TmsTruckAxleNumVO();
+        vo.setId(axleNum.getId());
+        vo.setName(axleNum.getName());
+        return vo;
+    }
+
     /**
      * 查询轴数
      * @param axleNumIds
      * @return
      */
     @Override
-    public List<TmsTruckAxleNumVO> getCarAxisInfo(List<Integer> axleNumIds) {
+    public List<TmsTruckAxleNumVO> getCarAxisInfoList(List<Integer> axleNumIds) {
         //查询车辆关联司机信息
         List<TmsTruckAxleNum> axleNumList = kwfTruckAxleNumRepository.list(Wrappers.<TmsTruckAxleNum>lambdaQuery()
                 .eq(TmsTruckAxleNum::getStatus, 1)
@@ -589,4 +611,38 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
 
         driverRepository.updateById(driver);
     }
+
+    @Override
+    public List<RTruckVo> findTruckByEntIds(Long entId) {
+        List<KwfTruck> truckList = kwfTruckRepository.findTruckByEntIds(entId);
+        if(CollectionUtils.isEmpty(truckList)){
+            return new ArrayList<>();
+        }
+        return truckList.stream().map(this::getTruckVo).collect(Collectors.toList());
+    }
+
+
+    public List<RDriverScoreVo> findDriverScoreIdByEntIds(Long proEntId, Long logEntId, List<Long> driverIds) {
+        List<KwcDriverScore> driverScores = driverScoreRepository.findDriverScoreByEntIds(proEntId, logEntId, driverIds);
+        if(CollectionUtils.isEmpty(driverScores)){
+            return new ArrayList<>();
+        }
+        return driverScores.stream().map(this::getDriverScoreVo).collect(Collectors.toList());
+
+    }
+
+    /**
+     *  获取司机评分数据
+     * @param driverScore 车辆对象
+     * @return 车辆数据
+     */
+    private RDriverScoreVo getDriverScoreVo(KwcDriverScore driverScore) {
+        RDriverScoreVo vo = new RDriverScoreVo();
+        vo.setProviderEntId(driverScore.getProviderEntId());
+        vo.setLogisticsEntId(driverScore.getLogisticsEntId());
+        vo.setDriverId(driverScore.getDriverId());
+        vo.setProviderEntName(driverScore.getProviderEntName());
+        vo.setScore(driverScore.getScore());
+        return vo;
+    }
 }

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

@@ -0,0 +1,30 @@
+package com.sckw.fleet.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.core.model.base.BaseModel;
+import com.sckw.fleet.dao.KwfDriverScoreMapper;
+import com.sckw.fleet.model.KwcDriverScore;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+
+/**
+ * @author PC
+ * 司机评分
+ */
+@Repository
+public class KwfDriverScoreRepository extends ServiceImpl<KwfDriverScoreMapper, KwcDriverScore> {
+
+    public List<KwcDriverScore> findDriverScoreByEntIds(Long proEntId, Long logEntId, List<Long> driverIds) {
+        return list(Wrappers.<KwcDriverScore>lambdaQuery()
+                .eq(BaseModel::getDelFlag,0)
+                .eq(KwcDriverScore::getProviderEntId,proEntId)
+                .eq(KwcDriverScore::getLogisticsEntId,logEntId)
+                .in(KwcDriverScore::getDriverId,driverIds)
+                .orderByDesc(KwcDriverScore::getScore)
+                .orderByDesc(BaseModel::getId));
+    }
+
+}

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

@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckw.core.model.base.BaseModel;
 import com.sckw.fleet.dao.KwfTruckMapper;
 import com.sckw.fleet.model.KwfTruck;
-import com.sckw.fleet.model.KwfTruckRoute;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Repository;
 
@@ -150,4 +149,11 @@ public class KwfTruckRepository extends ServiceImpl<KwfTruckMapper, KwfTruck> {
                 .eq(Objects.nonNull(entId), KwfTruck::getEntId, entId)
                 .eq(Objects.nonNull(businessStatus), KwfTruck::getBusinessStatus, businessStatus));
     }
+
+    public List<KwfTruck> findTruckByEntIds(Long entId) {
+        return list(Wrappers.<KwfTruck>lambdaQuery()
+                .eq(BaseModel::getDelFlag,0)
+                .eq(KwfTruck::getEntId,entId)
+                .orderByDesc(BaseModel::getId));
+    }
 }

+ 7 - 0
sckw-modules/sckw-order/pom.xml

@@ -106,6 +106,13 @@
             <artifactId>sckw-transport-api</artifactId>
             <version>${basic.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-fleet-api</artifactId>
+            <version>${basic.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>com.sckw</groupId>
             <artifactId>sckw-manage-api</artifactId>

+ 6 - 0
sckw-modules/sckw-order/src/main/java/com/sckw/order/model/KwoTradeOrder.java

@@ -131,6 +131,12 @@ public class KwoTradeOrder extends BaseModel implements Serializable {
     @TableField("consignment_way")
     private Integer consignmentWay;
 
+    /**
+     * 派车方式方式
+     */
+    @TableField("dispatching")
+    private Integer dispatching;
+
 
 
 }

+ 5 - 0
sckw-modules/sckw-order/src/main/java/com/sckw/order/model/vo/req/ContractInfo.java

@@ -25,4 +25,9 @@ public class ContractInfo {
     private String contractSigningWay;
 
     private String contractStatus;
+
+    /**
+     * 派车方式
+     */
+    private Integer dispatchWay;
 }

+ 175 - 15
sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java

@@ -15,14 +15,18 @@ import com.github.pagehelper.PageInfo;
 import com.sckw.contract.api.RemoteContractService;
 import com.sckw.contract.api.model.dto.res.ContractCommonInfoResDto;
 import com.sckw.contract.api.model.vo.GoodsInfoDto;
+import com.sckw.contract.api.model.vo.LogisticsEntDtoVO;
 import com.sckw.contract.api.model.vo.TradeContractResDto;
 import com.sckw.contract.api.model.vo.TradeContractUnitDto;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
+import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
+import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.exception.CustomPromptException;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.constant.NumberConstant;
 import com.sckw.core.model.enums.*;
+import com.sckw.core.model.enums.DispatchWayEnums;
 import com.sckw.core.model.page.PageHelperUtil;
 import com.sckw.core.model.page.PageResult;
 import com.sckw.core.model.vo.TableBottom;
@@ -32,6 +36,10 @@ import com.sckw.core.utils.*;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
 import com.sckw.core.web.response.HttpResult;
+import com.sckw.fleet.api.RemoteFleetService;
+import com.sckw.fleet.api.model.vo.RTruckVo;
+import com.sckw.fleet.api.model.vo.TmsTruckAxleNumVO;
+import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
 import com.sckw.manage.api.RemoteManageService;
 import com.sckw.manage.api.model.dto.res.FindEntCooperateResVo;
 import com.sckw.mongo.model.SckwTradeOrder;
@@ -64,6 +72,7 @@ import com.sckw.stream.model.SckwBusSum;
 import com.sckw.stream.model.SckwMessage;
 import com.sckw.stream.model.UserInfo;
 import com.sckw.system.api.RemoteSystemService;
+import com.sckw.system.api.model.dto.req.ActualDisPatchDto;
 import com.sckw.system.api.model.dto.res.*;
 import com.sckw.transport.api.dubbo.TransportRemoteService;
 import com.sckw.transport.api.model.param.AddLogisticOrderParam;
@@ -117,6 +126,9 @@ public class KwoTradeOrderService {
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private TransportRemoteService transportRemoteService;
 
+    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
+    protected RemoteFleetService remoteFleetService;
+
     private final KwoTradeOrderMapper kwoTradeOrderMapper;
     private final StreamBridge streamBridge;
     private final KwoTradeOrderAddressService kwoTradeOrderAddressService;
@@ -784,15 +796,26 @@ public class KwoTradeOrderService {
         List<KwoTradeOrderTransport> list = kwoTradeOrderTransportService.queryList(id);
         if (CollUtil.isNotEmpty(list)) {
             Map<Long, ContractCommonInfoResDto> contractMap = remoteContractService.queryContractBaseInfo(list.stream().map(KwoTradeOrderTransport::getContractId).collect(Collectors.toList()));
-
+            //贸易合同派单方式
+            Integer dispatchWay = (detail.getContractInfo() == null || detail.getContractInfo().getDispatchWay() == null) ? 0 : detail.getContractInfo().getDispatchWay();
             List<ContractInfo> collect = list.stream().map(d -> {
                 ContractInfo contractInfo = new ContractInfo();
                 contractInfo.setContractId(d.getContractId());
                 contractInfo.setContractNo(d.getContractNo());
                 Optional.ofNullable(contractMap.get(d.getContractId())).ifPresent(c -> {
-                    contractInfo.setContractName(c.getContactName());
-                    contractInfo.setContractSigningWay(c.getSigningWayName());
-                    contractInfo.setContractStatus(c.getStatusName());
+                    // 新增:若贸易合同为自动派单,则需要过滤自动派单的物流合同
+                    if (Objects.equals(DispatchWayEnums.AUTO_DISPATCH.getCode(), dispatchWay)) {
+                        // 仅当合同自身也是自动派单类型时,才赋值字段
+                        if (Objects.equals(DispatchWayEnums.AUTO_DISPATCH.getCode(), c.getDispatchWay())) {
+                            contractInfo.setContractName(c.getContactName());
+                            contractInfo.setContractSigningWay(c.getSigningWayName());
+                            contractInfo.setContractStatus(c.getStatusName());
+                        }
+                    } else {
+                        contractInfo.setContractName(c.getContactName());
+                        contractInfo.setContractSigningWay(c.getSigningWayName());
+                        contractInfo.setContractStatus(c.getStatusName());
+                    }
                 });
                 return contractInfo;
             }).collect(Collectors.toList());
@@ -2122,6 +2145,22 @@ public class KwoTradeOrderService {
         if (Objects.isNull(tradeContractResDto)) {
             throw new BusinessException("贸易合同不存在");
         }
+
+        List<LogisticsEntDtoVO> contractLogisticsList = new ArrayList<>();
+        //自动派单校验: 判断当前有无包含该商品的有效自动派车物流合同
+        if (Objects.equals(DispatchWayEnums.AUTO_DISPATCH.getCode(), tradeContractResDto.getDispatchWay())) {
+            KwoTradeOrderUnit tradeOrderUnit = unitMap.get(String.valueOf(Global.NUMERICAL_TWO));
+            //查询满足自动派单的物流合同
+            contractLogisticsList = remoteContractService.queryValidAutoContractLogOrder(tradeOrderUnit.getEntId(), byOrderId.getId());
+            if (CollectionUtils.isEmpty(contractLogisticsList)) {
+                throw new BusinessException("未找到该商品有效的自动派车物流合同,请先签订自动派车物流合同");
+            }
+        } else {
+            List<LogisticsEntDto> logisticsContractId = tradeOrderAuditParam.getLogisticsContractList();
+            if (Objects.equals(tradeContractResDto.getConsignment(), 2) && CollUtil.isEmpty(logisticsContractId)) {
+                throw new BusinessException("卖方托运时,物流合同不能为空");
+            }
+        }
         List<LogisticsEntDto> logisticsContractId = tradeOrderAuditParam.getLogisticsContractList();
         if (Objects.equals(tradeContractResDto.getConsignment(), 2) && CollUtil.isEmpty(logisticsContractId)) {
             throw new BusinessException("卖方托运时,物流合同不能为空");
@@ -2173,8 +2212,9 @@ public class KwoTradeOrderService {
         }
         //下游新增物流订单
         AddLogisticOrderParam addLogisticOrderParam = new AddLogisticOrderParam();
-        if (Objects.equals(tradeContractResDto.getConsignment(), 2)) {
-            List<LogisticInfo> collect = logisticsContractId.stream().map(d -> {
+        if (DispatchWayEnums.AUTO_DISPATCH.getCode().equals(kwoTradeOrder.getDispatching())) {
+            // 自动派车物流合同
+            List<LogisticInfo> collect = contractLogisticsList.stream().map(d -> {
                 LogisticInfo logisticInfo = new LogisticInfo();
                 logisticInfo.setContractId(d.getContractId());
                 logisticInfo.setContractNo(d.getContractNo());
@@ -2198,20 +2238,23 @@ public class KwoTradeOrderService {
                 return logisticInfo;
             }).collect(Collectors.toList());
             addLogisticOrderParam.setLogisticInfo(collect);
-        } else {
-            List<KwoTradeOrderTransport> list = kwoTradeOrderTransportService.queryList(kwoTradeOrder.getId());
-            if (CollUtil.isNotEmpty(list)) {
-                //Map<Long, ContractCommonInfoResDto> contractMap = remoteContractService.queryContractBaseInfo(list.stream().map(KwoTradeOrderTransport::getContractId).collect(Collectors.toList()));
-                List<LogisticInfo> collect = list.stream().map(d -> {
+            addLogisticOrderParam.setDispatchWay(DispatchWayEnums.AUTO_DISPATCH.getCode());
+
+            //实际派车数
+            Integer actualDisPatch = getActualDisPatch(kwoTradeOrder, addressList);
+            addLogisticOrderParam.setActualDisPatch(actualDisPatch);
+
+        } else if (Objects.equals(tradeContractResDto.getConsignment(), 2)) {
+                List<LogisticInfo> collect = logisticsContractId.stream().map(d -> {
                     LogisticInfo logisticInfo = new LogisticInfo();
                     logisticInfo.setContractId(d.getContractId());
                     logisticInfo.setContractNo(d.getContractNo());
                     logisticInfo.setContractName("");
                     logisticInfo.setAcceptCompanyId(d.getEntId());
-                    logisticInfo.setAcceptContactPhone(d.getPhone());
+                    logisticInfo.setAcceptContactPhone("");
                     logisticInfo.setAcceptContacts(d.getContacts());
                     logisticInfo.setAcceptContactsId(d.getContactsId());
-                    logisticInfo.setAcceptCompany(d.getFirmName());
+                    logisticInfo.setAcceptCompany("");
                     logisticInfo.setPrice(d.getTransportPrice());
                     logisticInfo.setPriceType(0L);
                     logisticInfo.setAmount(new BigDecimal("0"));
@@ -2226,9 +2269,37 @@ public class KwoTradeOrderService {
                     return logisticInfo;
                 }).collect(Collectors.toList());
                 addLogisticOrderParam.setLogisticInfo(collect);
-            }
+            } else {
+                List<KwoTradeOrderTransport> list = kwoTradeOrderTransportService.queryList(kwoTradeOrder.getId());
+                if (CollUtil.isNotEmpty(list)) {
+                    //Map<Long, ContractCommonInfoResDto> contractMap = remoteContractService.queryContractBaseInfo(list.stream().map(KwoTradeOrderTransport::getContractId).collect(Collectors.toList()));
+                    List<LogisticInfo> collect = list.stream().map(d -> {
+                        LogisticInfo logisticInfo = new LogisticInfo();
+                        logisticInfo.setContractId(d.getContractId());
+                        logisticInfo.setContractNo(d.getContractNo());
+                        logisticInfo.setContractName("");
+                        logisticInfo.setAcceptCompanyId(d.getEntId());
+                        logisticInfo.setAcceptContactPhone(d.getPhone());
+                        logisticInfo.setAcceptContacts(d.getContacts());
+                        logisticInfo.setAcceptContactsId(d.getContactsId());
+                        logisticInfo.setAcceptCompany(d.getFirmName());
+                        logisticInfo.setPrice(d.getTransportPrice());
+                        logisticInfo.setPriceType(0L);
+                        logisticInfo.setAmount(new BigDecimal("0"));
+                        logisticInfo.setAmountUnit("");
+                        logisticInfo.setLoss(new BigDecimal("0"));
+                        logisticInfo.setPayment(0L);
+                        logisticInfo.setSigningWay(0);
+                        logisticInfo.setLossUnit("");
+                        logisticInfo.setRemark("");
+                        logisticInfo.setType(0);
+
+                        return logisticInfo;
+                    }).collect(Collectors.toList());
+                    addLogisticOrderParam.setLogisticInfo(collect);
+                }
 
-        }
+            }
         addLogisticOrderParam.setTradeOrderId(kwoTradeOrder.getId());
         addLogisticOrderParam.setTradeOrderNo(kwoTradeOrder.getTOrderNo());
         addLogisticOrderParam.setBillingMode(String.valueOf(kwoTradeOrder.getChargeType()));
@@ -2304,11 +2375,100 @@ public class KwoTradeOrderService {
         }
         addLogisticOrderParam.setEntId(LoginUserHolder.getEntId());
         addLogisticOrderParam.setUserId(LoginUserHolder.getUserId());
+        addLogisticOrderParam.setDispatchWay(DispatchWayEnums.MANUAL_DISPATCH.getCode());
         log.info("创建物流订单:{}", JSONObject.toJSONString(addLogisticOrderParam));
         transportRemoteService.addLogisticOrder(addLogisticOrderParam);
         return true;
     }
 
+    /**
+     * 实际派车数
+     * @param tradeOrder
+     * @param addressList
+     * @return
+     */
+    public Integer getActualDisPatch(KwoTradeOrder tradeOrder, List<KwoTradeOrderAddress> addressList) {
+        TruckDispatchCoefficientVO truckDispatchVO = remoteFleetService.findAutoTruckDispatchByEntId(tradeOrder.getEntId());
+        if (truckDispatchVO == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找到自动派车系数!");
+        }
+        ActualDisPatchDto dto = new ActualDisPatchDto();
+        dto.setTradeOrderId(tradeOrder.getId());
+        dto.setEntId(tradeOrder.getEntId());
+        dto.setStartTime(tradeOrder.getStartTime());
+        dto.setEndTime(tradeOrder.getEndTime());
+        dto.setAmount(tradeOrder.getAmount());
+        //司机行为规则
+        dto.setVehicleAvgLoad(truckDispatchVO.getVehicleAvgLoad());
+        dto.setBufferCoefficient(truckDispatchVO.getBufferCoefficient());
+        dto.setVehicleWorkHours(truckDispatchVO.getVehicleWorkHours());
+        dto.setVehicleLoadingHours(truckDispatchVO.getVehicleLoadingHours());
+        dto.setVehicleUnloadingHours(truckDispatchVO.getVehicleUnloadingHours());
+        dto.setVehicleAvgSpeed(truckDispatchVO.getVehicleAvgSpeed());
+
+        //查询贸易订单装卸货地址
+        Map<Integer, KwoTradeOrderAddress> addressMap = addressList.stream().collect(Collectors.toMap(
+                address -> StringUtils.isBlank(address.getAddressType()) ? 0 : Integer.valueOf(address.getAddressType()), Function.identity(), (x, y) -> x));
+        KwoTradeOrderAddress shipmentAddress = addressMap.getOrDefault(AddressTypeEnum.SHIPMENT.getCode(), new KwoTradeOrderAddress());
+        KwoTradeOrderAddress takeAddress = addressMap.getOrDefault(AddressTypeEnum.TAKE.getCode(), new KwoTradeOrderAddress());
+        dto.setLon1(shipmentAddress.getLng());
+        dto.setLat1(shipmentAddress.getLat());
+        dto.setLon2(takeAddress.getLng());
+        dto.setLat2(takeAddress.getLat());
+
+        //查询实际派车数
+        Integer actualDisPatch = remoteSystemService.getActualDisPatch(dto);
+        if (actualDisPatch == null || actualDisPatch <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "实际派车数量需大于0!");
+        }
+        return actualDisPatch;
+
+    }
+
+
+    /**
+     * 物流企业可派车
+     * @param byOrderId
+     * @param contractLogisticsList
+     * @return
+     */
+    public Integer getEntAvailableVehicle(KwoTradeOrderGoods byOrderId, List<LogisticsEntDtoVO> contractLogisticsList) {
+        List<Long> contractIds = contractLogisticsList.stream().map(LogisticsEntDtoVO::getContractId).collect(Collectors.toList());
+        //物流企业总运力
+        int sumAvailableVehicle = contractIds.stream()
+                .filter(Objects::nonNull)
+                .map(contractId -> getSignEntAvailableVehicle(byOrderId.getGoodsId(), contractId))
+                .mapToInt(num -> num == null ? 0 : num)
+                .sum();
+        return sumAvailableVehicle;
+    }
+
+    /**
+     * 单个物流企业满足轴数可派车
+     * @param goodId
+     * @param contractId
+     * @return
+     */
+    public Integer getSignEntAvailableVehicle(Long goodId, Long contractId) {
+        //查询商品轴数
+        KwpGoods goodsById = goodsInfoService.getGoodsById(goodId);
+        if (goodsById == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "物流运单装货地址有误!");
+        }
+        //商品轴数
+        TmsTruckAxleNumVO carAxisInfo = remoteFleetService.getCarAxisInfo(Optional.ofNullable(goodsById.getCarAxis()).map(Integer::valueOf).orElse(null));
+        //物流合同企业id
+        TradeContractUnitDto unitDto = remoteContractService.queryEntByContractId(contractId);
+
+        //当前物流企业总运力
+        List<RTruckVo> truckVoList = remoteFleetService.findTruckByEntIds(unitDto.getEntId());
+        return Math.toIntExact(truckVoList.stream()
+                .filter(Objects::nonNull)
+                .filter(truck -> Objects.equals(truck.getCarAxis(), String.valueOf(carAxisInfo.getId())))
+                .count());
+    }
+
+
     /**
      * 手动完结订单
      *

+ 1 - 1
sckw-modules/sckw-product/src/main/java/com/sckw/product/service/KwpGoodsService.java

@@ -451,7 +451,7 @@ public class KwpGoodsService {
             detail.setCarAxis(goods.getCarAxis());
             List<String> axleNumStrId = Arrays.asList(goods.getCarAxis().split(","));
             List<Integer> axleNumIds = axleNumStrId.stream().map(str -> Integer.parseInt(str.trim())).collect(Collectors.toList());
-            List<TmsTruckAxleNumVO> carAxisInfo = remoteFleetService.getCarAxisInfo(axleNumIds);
+            List<TmsTruckAxleNumVO> carAxisInfo = remoteFleetService.getCarAxisInfoList(axleNumIds);
             String carAxisName = carAxisInfo.stream().map(TmsTruckAxleNumVO::getName).collect(Collectors.joining(","));
             detail.setCarAxisName(carAxisName);
         }

+ 115 - 6
sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteSystemServiceImpl.java

@@ -4,16 +4,16 @@ import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+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.EntTypeEnum;
-
-import com.sckw.core.utils.BeanUtils;
-import com.sckw.core.utils.CollectionUtils;
-import com.sckw.core.utils.FileUtils;
-import com.sckw.core.utils.StringUtils;
+import com.sckw.core.utils.*;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.redis.utils.RedissonUtils;
 import com.sckw.system.api.RemoteSystemService;
+import com.sckw.system.api.model.dto.req.ActualDisPatchDto;
+import com.sckw.system.api.model.dto.req.SingleTripTotalTimeDto;
 import com.sckw.system.api.model.dto.res.*;
 import com.sckw.system.dao.KwsRoleDao;
 import com.sckw.system.dao.SysDictDao;
@@ -21,7 +21,6 @@ import com.sckw.system.model.*;
 import com.sckw.system.model.vo.res.FindAreaTreeResVo;
 import com.sckw.system.model.vo.res.KwsUserResVo;
 import com.sckw.system.repository.KwsEntTypeRepository;
-import com.sckw.system.repository.KwsEnterpriseRepository;
 import com.sckw.system.service.KwsUserService;
 import com.sckw.system.service.SysAreaService;
 import jakarta.annotation.Resource;
@@ -31,6 +30,8 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -968,4 +969,112 @@ public class RemoteSystemServiceImpl implements RemoteSystemService {
         return entTypeResDto;
     }
 
+    /**
+     * 计算平台配置的运单单趟总耗时
+     * 获取自动派单系数配置(单趟耗时 = 装货时间 + 卸货时间 + 运输时间 + 返回时间)
+     * @param dto
+     * @return
+     */
+    public Integer calSingleTripTotalTimes(SingleTripTotalTimeDto dto) {
+        //装货时长
+        Integer vehicleLoadingHours = dto.getVehicleLoadingHours();
+        //卸货货时长
+        Integer vehicleUnloadingHours = dto.getVehicleUnloadingHours();
+        //平均行驶速度
+        Integer vehicleAvgSpeed = dto.getVehicleAvgSpeed();
+        if (vehicleLoadingHours <= 0 || vehicleUnloadingHours <= 0 || vehicleAvgSpeed <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "司机配置的装货时长/卸货时长/平均行驶速度需要≥0!");
+        }
+
+        //应卸货地与实际卸货地之间距离
+        double twoPlaceDistanceKm = DistanceUtils.calculateDistance(
+                Optional.ofNullable(dto.getLon1()).map(Double::valueOf).orElse(null),
+                Optional.ofNullable(dto.getLat1()).map(Double::valueOf).orElse(null),
+                Optional.ofNullable(dto.getLon2()).map(Double::valueOf).orElse(null),
+                Optional.ofNullable(dto.getLat2()).map(Double::valueOf).orElse(null));
+        //运输时间/返回时间(小时) = 两地距离除以平均行驶速度
+        if (twoPlaceDistanceKm == 0.0 || Double.isNaN(twoPlaceDistanceKm)) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "物流运单装货地址有误!");
+        }
+        BigDecimal bdDividend = BigDecimal.valueOf(twoPlaceDistanceKm);
+        BigDecimal bdDivisor = BigDecimal.valueOf(vehicleAvgSpeed);
+        //运输时间小时
+        BigDecimal transportTimeHours = bdDividend.divide(bdDivisor, 4, RoundingMode.HALF_UP);
+        //运输时间分钟取整 = 往返时间
+        Integer transportTimeMinutes = transportTimeHours.multiply(BigDecimal.valueOf(60)).setScale(0, RoundingMode.HALF_UP).intValue();
+        //单趟总耗时
+        return vehicleLoadingHours + vehicleUnloadingHours + transportTimeMinutes + transportTimeMinutes;
+    }
+
+
+    /**
+     * 计算平台配置贸易订单实际派车数
+     * @param dto
+     * @return
+     */
+    @Override
+    public Integer getActualDisPatch(ActualDisPatchDto dto) {
+        //车辆平均载重
+        Integer vehicleAvgLoad = dto.getVehicleAvgLoad();
+        if (vehicleAvgLoad <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "车辆平均载重配置需大于0!");
+        }
+        //缓冲系数
+        BigDecimal bufferCoefficient = dto.getBufferCoefficient();
+        if (bufferCoefficient.compareTo(BigDecimal.ZERO) <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "缓冲系数配置需大于0!");
+        }
+        //工作时长
+        Integer vehicleWorkHours = dto.getVehicleWorkHours();
+        if (vehicleWorkHours <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "车辆工作时长配置需大于0!");
+        }
+        //订单天数
+        long daysBetween = DateUtils.daysBetween(dto.getStartTime(), dto.getEndTime());
+        //总运输时间 = 工作时长 * 订单天数
+        Long totalTransportationTime = vehicleWorkHours * daysBetween;
+        // 平台单趟耗时
+        Integer singleTripTotalTimes = getSingleTripTotalTimes(dto);
+        if (singleTripTotalTimes == null && singleTripTotalTimes <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "单车最大往返次数需大于0!");
+        }
+        //单车最大往返次数 = 总运输时间/单趟耗时
+        BigDecimal totalTimeBig = new BigDecimal(totalTransportationTime);
+        BigDecimal singleTripBig = new BigDecimal(singleTripTotalTimes);
+        BigDecimal roundTripBig = totalTimeBig.divide(singleTripBig, 2, RoundingMode.HALF_UP);
+        Integer maxRoundTripTimes = roundTripBig.setScale(0, RoundingMode.FLOOR).intValue();
+
+        //单车总运量 = 车辆平均载重 X 单车最大往返次数
+        int totalVehicle  = vehicleAvgLoad * maxRoundTripTimes;
+        BigDecimal totalVehicleBig = new BigDecimal(totalVehicle);
+        //所需车辆数 = 订单总量/单车总运量
+        BigDecimal vehiclesNum  = dto.getAmount().multiply(totalVehicleBig);
+
+        //实际派车 = 所需车辆数 X 缓冲系数(向上取整)
+        BigDecimal actualVehicleBig = vehiclesNum.multiply(bufferCoefficient);
+        Integer actualVehicle = actualVehicleBig.setScale(0, RoundingMode.FLOOR).intValue();
+        return actualVehicle;
+    }
+
+    /**
+     *  平台单趟耗时
+     * @param dto
+     * @return
+     */
+    private Integer getSingleTripTotalTimes(ActualDisPatchDto dto) {
+        SingleTripTotalTimeDto totalTimeDto = new SingleTripTotalTimeDto();
+        totalTimeDto.setEntId(dto.getEntId());
+        totalTimeDto.setLon1(dto.getLon1());
+        totalTimeDto.setLat1(dto.getLat1());
+        totalTimeDto.setLon2(dto.getLon2());
+        totalTimeDto.setLat2(dto.getLat2());
+        //行为规则
+        totalTimeDto.setVehicleLoadingHours(dto.getVehicleLoadingHours());
+        totalTimeDto.setVehicleUnloadingHours(dto.getVehicleUnloadingHours());
+        totalTimeDto.setVehicleAvgSpeed(dto.getVehicleAvgSpeed());
+        //计算运单单趟耗时
+        return calSingleTripTotalTimes(totalTimeDto);
+
+    }
+
 }

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

@@ -1300,6 +1300,8 @@ public class TransportServiceImpl implements TransportRemoteService {
         addLogisticOrderDTO.setBillingMode(param.getBillingMode());
         addLogisticOrderDTO.setStartTime(param.getStartTime());
         addLogisticOrderDTO.setEndTime(param.getEndTime());
+        addLogisticOrderDTO.setDispatchWay(param.getDispatchWay());
+        addLogisticOrderDTO.setActualDisPatch(param.getActualDisPatch());
         return addLogisticOrderDTO;
     }
 

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

@@ -7,13 +7,13 @@ import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.enums.AddressTypeEnum;
 import com.sckw.core.model.enums.CarWaybillV1Enum;
 import com.sckw.core.utils.CollectionUtils;
+import com.sckw.core.utils.DistanceUtils;
 import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
 import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
 import com.sckw.order.api.model.OrderDetailVo;
 import com.sckw.transport.model.*;
 import com.sckw.transport.model.param.WaybillOrderUnloadParam;
 import com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
-import com.sckw.transport.utils.DistanceUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.jetbrains.annotations.NotNull;

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

@@ -233,6 +233,11 @@ public class KwtLogisticsOrder implements Serializable {
      */
     private String bindStatus;
 
+    /**
+     * 派单方式(1-手动派单、2-自动派单)
+     */
+    private Integer dispatchWay;
+
     private static final long serialVersionUID = 1L;
 
     @TableField(exist = false)

+ 12 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/AddLogisticOrderDTO.java

@@ -236,4 +236,16 @@ public class AddLogisticOrderDTO implements Serializable {
     @NotNull(message = "计划发货时间不能为空")
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private LocalDate startTime;
+
+    /**
+     * 派车方式
+     */
+    @NotNull(message = "派车方式不能为空")
+    private Integer dispatchWay;
+
+    /**
+     * 平台实际派车数
+     */
+    @NotNull(message = "平台实际派车数")
+    private Integer actualDisPatch;
 }

+ 6 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/LogisticData.java

@@ -125,4 +125,10 @@ public  class LogisticData implements Serializable {
          */
         private Integer type;
 
+
+        /**
+         * 派车方式
+         */
+        private Integer dispatchWay;
+
     }

+ 8 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderCirculateRepository.java

@@ -74,4 +74,12 @@ public class KwtLogisticsOrderCirculateRepository extends ServiceImpl<KwtLogisti
         );
     }
 
+
+    public List<KwtLogisticsOrderCirculate> queryEffectiveOrderByTruckNo(String truckNo) {
+        return list(Wrappers.<KwtLogisticsOrderCirculate>lambdaQuery()
+                .eq(KwtLogisticsOrderCirculate::getTruckNo, truckNo)
+                .eq(KwtLogisticsOrderCirculate::getDelFlag,0));
+    }
+
+
 }

+ 0 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderContractRepository.java

@@ -6,7 +6,6 @@ import com.sckw.transport.dao.KwtLogisticsOrderContractMapper;
 import com.sckw.transport.model.KwtLogisticsOrderContract;
 import org.springframework.stereotype.Repository;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 

+ 161 - 13
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtAcceptCarriageOrderService.java

@@ -15,7 +15,9 @@ import com.sckw.contract.api.model.dto.res.ContractCommonInfoResDto;
 import com.sckw.core.common.enums.StringConstant;
 import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
+import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
+import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.constant.NumberConstant;
 import com.sckw.core.model.enums.*;
@@ -28,6 +30,8 @@ import com.sckw.excel.utils.DateUtil;
 import com.sckw.excel.utils.ValidUtil;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.vo.RTruckVo;
+import com.sckw.fleet.api.model.vo.TmsTruckAxleNumVO;
+import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
 import com.sckw.manage.api.RemoteManageService;
 import com.sckw.manage.api.model.dto.res.FindEntCooperateResVo;
 import com.sckw.mongo.enums.BusinessTypeEnum;
@@ -178,11 +182,16 @@ public class KwtAcceptCarriageOrderService {
     @Autowired
     public KwtLogisticsOrderLineFreightRateMapper lineFreightRateMapper;
 
+    @Autowired
+    public KwtLogisticsConsignmentService logisticsConsignmentService;
+
     private final KwtLogisticsOrderRepository logisticsOrderRepository;
     private final KwtLogisticsOrderGoodsRepository logisticsOrderGoodsRepository;
     private final KwtLogisticsOrderUnitRepository logisticsOrderUnitRepository;
     private final KwtLogisticsOrderContractRepository  logisticsOrderContractRepository;
     private final KwtLogisticsOrderAddressRepository  logisticsOrderAddressRepository;
+    private final KwtLogisticsOrderCirculateRepository logisticsOrderCirculateRepository;
+
 
 
     /**
@@ -3189,7 +3198,7 @@ public class KwtAcceptCarriageOrderService {
         /**保存新建数据*/
 
         List<LogisticData> logisticInfo = orderDTO.getLogisticInfo();
-        if (org.apache.commons.collections4.CollectionUtils.isEmpty(logisticInfo)){
+        if (CollectionUtils.isEmpty(logisticInfo)){
             throw new BusinessException("物流信息不能为空");
         }
         List<Long> contractIds = logisticInfo.stream()
@@ -3210,27 +3219,165 @@ public class KwtAcceptCarriageOrderService {
         List<KwtLogisticsOrderGoods> savelogOrderGoodsList = Lists.newArrayList();
         List<KwtLogisticsOrderContract> saveContractList = Lists.newArrayList();
         List<KwtLogisticsOrderUnit> savelogOrderUnitList = Lists.newArrayList();
-        logisticInfo.forEach(x->{
+        //实际派车数 20
+        Integer actualDisPatch = orderDTO.getActualDisPatch() == null ? 0 : orderDTO.getActualDisPatch();
+        //已派车辆数(累计已分配的车辆数)
+        Integer dispatched = 0;
+        for (LogisticData x : logisticInfo) {
             Long lOrderId = new IdWorker(NumberConstant.ONE).nextId();
-            //物流订单信息
-            setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList);
+            //自动派单
+            if (Objects.equals(DispatchWayEnums.AUTO_DISPATCH.getCode(), orderDTO.getDispatchWay())) {
+                // 剩余需派数
+                int remainNeedDispatch = actualDisPatch - dispatched;
+                if (remainNeedDispatch <= 0) {
+                    break;
+                }
+                //校验物流企业可派车辆
+                List<RTruckVo> signEntAvailableVehicle = getSignEntAvailableVehicle(orderDTO.getGoodsId(), x.getAcceptCompanyId());
+                if (CollectionUtils.isEmpty(signEntAvailableVehicle)) {
+                    continue;
+                }
 
-            //地址信息
-            setLogisticAddress(orderDTO, x, lOrderId, saveAddressList);
+                //截取车辆列表,最多保留剩余需派数的量
+                List<RTruckVo> actualUseVehicles = signEntAvailableVehicle.stream()
+                        .limit(remainNeedDispatch)
+                        .collect(Collectors.toList());
+                if (CollectionUtils.isEmpty(actualUseVehicles)) {
+                    continue;
+                }
+                // 计算本次实际派车数
+                int currentDispatch = actualUseVehicles.size();
+
+                // 累加已派数(兜底:不超实际需派数)
+                dispatched += currentDispatch;
+                dispatched = Math.min(dispatched, actualDisPatch);
+
+                //物流订单信息
+                setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList);
+                //地址信息
+                setLogisticAddress(orderDTO, x, lOrderId, saveAddressList);
+                //商品信息
+                setLogisticGoodsInfo(orderDTO, lOrderId, lOrderNo, savelogOrderGoodsList);
+                //物流订单与合同信息
+                setLogisticContractInfo(orderDTO, x, lOrderId, saveContractList);
+                //企业信息数据
+                setLogisticUnitInfo(orderDTO, x, lOrderId, savelogOrderUnitList);
+
+                //创建物流派单数据
+                setLogisticCirculateInfo(x, lOrderId, signEntAvailableVehicle);
 
-            //商品信息
-            setLogisticGoodsInfo(orderDTO, lOrderId, lOrderNo, savelogOrderGoodsList);
-            //物流订单与合同信息
-            setLogisticContractInfo(orderDTO,x, lOrderId, saveContractList);
-            //企业信息数据
-            setLogisticUnitInfo(orderDTO, x, lOrderId, savelogOrderUnitList);
+            } else {
+                //物流订单信息
+                setLogisticOrderInfo(orderDTO, x, lOrderId, lOrderNo, saveLogisticsOrderList);
+
+                //地址信息
+                setLogisticAddress(orderDTO, x, lOrderId, saveAddressList);
+
+                //商品信息
+                setLogisticGoodsInfo(orderDTO, lOrderId, lOrderNo, savelogOrderGoodsList);
+                //物流订单与合同信息
+                setLogisticContractInfo(orderDTO, x, lOrderId, saveContractList);
+                //企业信息数据
+                setLogisticUnitInfo(orderDTO, x, lOrderId, savelogOrderUnitList);
+            }
 
-        });
+        }
+        //校验派车总量,处理未达标场景
+        int unDispatched = actualDisPatch - dispatched;
+        if (unDispatched > 0) {
+            // 3.1 核心告警:记录未派足的情况
+            log.error("派车未完成!实际需派{}辆,仅派{}辆,缺{}辆无可用车辆", actualDisPatch, dispatched, unDispatched);
+        }
         
         // 批量保存并检查结果
         saveBatch(saveLogisticsOrderList, saveAddressList, savelogOrderGoodsList, saveContractList, savelogOrderUnitList, lOrderNo);
     }
 
+    /**
+     * 创建物流派单数据
+     * @param x
+     * @param lOrderId
+     * @param signEntAvailableVehicle
+     */
+    private void setLogisticCirculateInfo(LogisticData x, Long lOrderId, List<RTruckVo> signEntAvailableVehicle) {
+        DispatchCarReq req = new DispatchCarReq();
+        req.setEntId(String.valueOf(x.getAcceptCompanyId()));
+        req.setLogisticOrderId(String.valueOf(lOrderId));
+
+        List<DispatchCarReq.CarInfo> carInfoList = signEntAvailableVehicle.stream().map(ve -> {
+            DispatchCarReq.CarInfo carInfo = new DispatchCarReq.CarInfo();
+            carInfo.setTruckId(Optional.ofNullable(ve.getId()).map(String::valueOf).orElse(null));
+            carInfo.setTruckNo(ve.getTruckNo());
+            return carInfo;
+        }).collect(Collectors.toList());
+
+        req.setCarInfos(carInfoList);
+        logisticsConsignmentService.dispatchCar(req);
+    }
+
+    /**
+     * 单个物流企业满足轴数可派车
+     * @param goodId
+     * @param logEntId
+     * @return
+     */
+    public List<RTruckVo> getSignEntAvailableVehicle(Long goodId, Long logEntId) {
+
+        //查询商品轴数
+        KwpGoods goodsById = goodsInfoService.getGoodsById(goodId);
+        if (goodsById == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "物流运单装货地址有误!");
+        }
+        //商品轴数
+        TmsTruckAxleNumVO carAxisInfo = fleetService.getCarAxisInfo(Optional.ofNullable(goodsById.getCarAxis()).map(Integer::valueOf).orElse(null));
+        List<RTruckVo> truckVoList = fleetService.findTruckByEntIds(logEntId);
+        //过滤满足轴数的车辆
+        List<RTruckVo> truckVoFilterList = truckVoList.stream()
+                .filter(Objects::nonNull)
+                .filter(truck -> Objects.equals(truck.getCarAxis(), String.valueOf(carAxisInfo.getId())))
+                .collect(Collectors.toList());
+
+        //过滤满足车辆最大可派任务数的车辆
+        return truckVoFilterList.stream().filter(Objects::nonNull)
+                // 过滤已派单且生效中的车辆 + 校验最大可派任务数
+                .filter(this::isTruckAvailable)
+                .collect(Collectors.toList());
+    }
+
+
+    /**
+     * 校验车辆最大可派任务数是否满足要求
+     * @param truck
+     * @return
+     */
+    private boolean isTruckAvailable(RTruckVo truck) {
+        // 查询车辆对应的物流订单合同(按车辆编号)
+        String truckNo = truck.getTruckNo();
+        if (StringUtils.isEmpty(truckNo)) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "车辆无车牌数据!");
+        }
+        //查询派车订单
+        List<KwtLogisticsOrderCirculate> circulatesList = logisticsOrderCirculateRepository.queryEffectiveOrderByTruckNo(truckNo);
+        if (CollectionUtils.isEmpty(circulatesList)) {
+            return false;
+        }
+
+        Long entId = LoginUserHolder.getEntId();
+        TruckDispatchCoefficientVO truckDispatchVO = fleetService.findAutoTruckDispatchByEntId(entId);
+        if (truckDispatchVO == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找到自动派车系数!");
+        }
+        // 车辆最大可派任务数
+        Integer vehicleMaxTasks = truckDispatchVO.getVehicleMaxTasks();
+        if (vehicleMaxTasks <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "自动派单车辆最大任务数!");
+        }
+        //TODO 车辆最大可派任务数校验
+        boolean available = circulatesList.size() < vehicleMaxTasks;
+        return available;
+
+    }
+
     private void saveBatch(List<KwtLogisticsOrder> saveLogisticsOrderList, List<KwtLogisticsOrderAddress> saveAddressList, List<KwtLogisticsOrderGoods> savelogOrderGoodsList, List<KwtLogisticsOrderContract> saveContractList, List<KwtLogisticsOrderUnit> savelogOrderUnitList, String lOrderNo) {
         log.info("开始批量保存物流订单数据,订单数量:{},地址数量:{},商品数量:{},合同数量:{},单位数量:{}",
                 saveLogisticsOrderList.size(), saveAddressList.size(), savelogOrderGoodsList.size(),
@@ -3476,6 +3623,7 @@ public class KwtAcceptCarriageOrderService {
         kwtLogisticsOrder.setUpdateBy(orderDTO.getUserId());
         kwtLogisticsOrder.setUpdateTime(date);
         kwtLogisticsOrder.setBindStatus(String.valueOf(NumberConstant.ZERO));
+        kwtLogisticsOrder.setDispatchWay(orderDTO.getDispatchWay());
         saveLogisticsOrderList.add(kwtLogisticsOrder);
     }
 }

+ 0 - 9
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java

@@ -1,15 +1,12 @@
 package com.sckw.transport.service;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.google.common.collect.Lists;
@@ -18,12 +15,9 @@ import com.google.common.collect.Sets;
 import com.sckw.contract.api.RemoteContractService;
 import com.sckw.contract.api.model.dto.res.ContractCommonInfoResDto;
 import com.sckw.contract.api.model.vo.KwcContractLogisticsDto;
-import com.sckw.contract.api.model.vo.TradeContractResDto;
 import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
-import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessException;
-import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.constant.NumberConstant;
 import com.sckw.core.model.enums.*;
@@ -53,7 +47,6 @@ import com.sckw.stream.model.SckwBusSum;
 import com.sckw.system.api.RemoteSystemService;
 import com.sckw.system.api.model.dto.res.EntCacheResDto;
 import com.sckw.system.api.model.dto.res.SysDictResDto;
-import com.sckw.system.api.model.dto.res.UserCacheResDto;
 import com.sckw.transport.common.config.MessageUrlConfig;
 import com.sckw.transport.dao.*;
 import com.sckw.transport.model.*;
@@ -61,7 +54,6 @@ import com.sckw.transport.model.dto.*;
 import com.sckw.transport.model.param.*;
 import com.sckw.transport.model.vo.*;
 import com.sckw.transport.repository.*;
-import com.sckw.transport.utils.DistanceUtils;
 import io.seata.spring.annotation.GlobalTransactional;
 import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
@@ -75,7 +67,6 @@ import org.springframework.cloud.stream.function.StreamBridge;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
-import org.springframework.web.bind.annotation.RequestBody;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;

+ 0 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java

@@ -60,7 +60,6 @@ import com.sckw.transport.model.param.WaybillOrderReq;
 import com.sckw.transport.model.param.WaybillOrderResp;
 import com.sckw.transport.model.vo.*;
 import com.sckw.transport.repository.*;
-import com.sckw.transport.utils.DistanceUtils;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.validation.Valid;

+ 2 - 17
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/WaybillOrderService.java

@@ -6,9 +6,6 @@ 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.google.common.collect.Maps;
-import com.sckw.contract.api.RemoteContractService;
 import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
@@ -20,40 +17,28 @@ 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.context.LoginUserHolder;
+import com.sckw.core.utils.DistanceUtils;
 import com.sckw.core.web.response.result.PageDataResult;
 import com.sckw.fleet.api.RemoteFleetService;
-import com.sckw.fleet.api.model.vo.RDriverVo;
 import com.sckw.fleet.api.model.vo.RTruckVo;
-import com.sckw.order.api.dubbo.RemoteTradeOrderAmountService;
 import com.sckw.order.api.dubbo.TradeOrderInfoService;
-import com.sckw.order.api.model.OrderDetailVo;
 import com.sckw.order.api.model.OrderUnitInfoDetailVO;
-import com.sckw.order.api.model.UpdateActualAmountParam;
 import com.sckw.product.api.dubbo.GoodsInfoService;
 import com.sckw.product.api.model.KwpGoods;
-import com.sckw.redis.config.RedisLockUtil;
 import com.sckw.system.api.RemoteSystemService;
 import com.sckw.system.api.model.dto.res.UserCacheResDto;
-import com.sckw.transport.common.config.MessageUrlConfig;
-import com.sckw.transport.dao.*;
 import com.sckw.transport.handler.*;
 import com.sckw.transport.model.*;
 import com.sckw.transport.model.param.*;
-import com.sckw.transport.model.vo.OrderStatusStatisticsResp;
 import com.sckw.transport.model.vo.OrderTotalTakeVo;
 import com.sckw.transport.model.vo.StatisticsWaybillResp;
 import com.sckw.transport.repository.*;
 import com.sckw.transport.service.*;
-import com.sckw.transport.utils.DistanceUtils;
 import jakarta.annotation.Resource;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
-import org.jetbrains.annotations.NotNull;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cloud.stream.function.StreamBridge;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Service;
@@ -338,7 +323,7 @@ public class WaybillOrderService {
         orderResp.setConsignCompanyId(Optional.ofNullable(consignEnt.getEntId()).map(String::valueOf).orElse(null));
         orderResp.setConsignCompanyName(consignEnt.getFirmName());
         //承运企业
-        KwtLogisticsOrderUnit carriageEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + UnitTypeEnum.CONSIGN.getCode(), new KwtLogisticsOrderUnit());
+        KwtLogisticsOrderUnit carriageEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + UnitTypeEnum.CARRIAGE.getCode(), new KwtLogisticsOrderUnit());
         orderResp.setCarriageCompanyId(Optional.ofNullable(carriageEnt.getEntId()).map(String::valueOf).orElse(null));
         orderResp.setCarriageCompanyName(carriageEnt.getFirmName());
         //供应企业