소스 검색

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

# Conflicts:
#	sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java
#	sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteSystemServiceImpl.java
xucaiqin 1 개월 전
부모
커밋
84db4b8fa3
74개의 변경된 파일2500개의 추가작업 그리고 146개의 파일을 삭제
  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. 1 1
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/feign/LogisticsScoreFeignService.java
  6. 6 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/dto/res/ContractCommonInfoResDto.java
  7. 72 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/LogisticsEntDtoVO.java
  8. 6 0
      sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/model/vo/TradeContractResDto.java
  9. 10 0
      sckw-modules-api/sckw-fleet-api/pom.xml
  10. 7 1
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/RemoteFleetService.java
  11. 17 0
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/feign/DriverScoreFeignService.java
  12. 47 0
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/UpdateDriverScoreDto.java
  13. 35 0
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/vo/RDriverScoreVo.java
  14. 5 0
      sckw-modules-api/sckw-product-api/src/main/java/com/sckw/product/api/model/KwpGoods.java
  15. 15 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteSystemService.java
  16. 1 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteUserService.java
  17. 128 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/ActualDisPatchDto.java
  18. 66 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/KwsUserReqDto.java
  19. 105 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/req/SingleTripTotalTimeDto.java
  20. 16 0
      sckw-modules-api/sckw-transport-api/src/main/java/com/sckw/transport/api/model/param/AddLogisticOrderParam.java
  21. 5 0
      sckw-modules/sckw-contract/pom.xml
  22. 32 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/config/FeignConfig.java
  23. 4 4
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dao/KwcContractLogisticsScoreMapper.java
  24. 22 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/dubbo/RemoteContractServiceImpl.java
  25. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/entity/KwcContractTrade.java
  26. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/QueryListReqVo.java
  27. 6 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/QueryTradeReq.java
  28. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/SupplyContractTradeReq.java
  29. 7 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/req/TradeBaseInfoReqVo.java
  30. 11 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/model/vo/res/ContractDetailResp.java
  31. 8 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsGoodsRepository.java
  32. 9 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsRepository.java
  33. 27 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsScoreRepository.java
  34. 23 0
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractLogisticsUnitRepository.java
  35. 2 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/repository/KwcContractTradeRepository.java
  36. 35 13
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/impl/KwcContractLogisticsScoreServiceImpl.java
  37. 6 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractLogisticsService.java
  38. 155 2
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractTradeService.java
  39. 32 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/config/FeignConfig.java
  40. 33 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/controller/KwfDriverScoreController.java
  41. 4 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverMapper.java
  42. 62 4
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreDetailMapper.java
  43. 63 4
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreMapper.java
  44. 57 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dubbo/RemoteFleetServiceImpl.java
  45. 25 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/dto/DriverScoreDto.java
  46. 30 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfDriverScoreRepository.java
  47. 7 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfTruckRepository.java
  48. 264 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverScoreService.java
  49. 30 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverService.java
  50. 10 0
      sckw-modules/sckw-fleet/src/main/resources/mapper/KwfDriverMapper.xml
  51. 129 0
      sckw-modules/sckw-fleet/src/main/resources/mapper/KwfDriverScoreDetailMapper.xml
  52. 136 0
      sckw-modules/sckw-fleet/src/main/resources/mapper/KwfDriverScoreMapper.xml
  53. 7 0
      sckw-modules/sckw-order/pom.xml
  54. 6 0
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/KwoTradeOrder.java
  55. 5 0
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/vo/req/ContractInfo.java
  56. 175 15
      sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java
  57. 1 1
      sckw-modules/sckw-product/src/main/java/com/sckw/product/service/KwpGoodsService.java
  58. 115 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteSystemServiceImpl.java
  59. 19 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteUserServiceImpl.java
  60. 2 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/dubbo/TransportServiceImpl.java
  61. 3 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/ComeIntoHandler.java
  62. 1 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java
  63. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtLogisticsOrder.java
  64. 12 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/AddLogisticOrderDTO.java
  65. 6 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/LogisticData.java
  66. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/VehiclesTrajectoryReq.java
  67. 8 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderCirculateRepository.java
  68. 0 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtLogisticsOrderContractRepository.java
  69. 161 13
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtAcceptCarriageOrderService.java
  70. 0 9
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtLogisticsConsignmentService.java
  71. 1 2
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/KwtWaybillOrderV1Service.java
  72. 23 20
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/VehicleExceptionService.java
  73. 4 18
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/app/WaybillOrderService.java
  74. 35 30
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/kwfTruckTraceService.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);
 }

+ 1 - 1
sckw-modules-api/sckw-contract-api/src/main/java/com/sckw/contract/api/feign/LogisticsScoreFeignService.java

@@ -6,7 +6,7 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
-@FeignClient(name = "sckw-contract",path = "/api/logisticsScore")
+@FeignClient(name = "sckw-ng-contract",path = "/api/logisticsScore")
 public interface LogisticsScoreFeignService {
     /**
      * 系统修改物流企业评分

+ 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;
 }

+ 10 - 0
sckw-modules-api/sckw-fleet-api/pom.xml

@@ -21,5 +21,15 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-openfeign-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sckw</groupId>
+            <artifactId>sckw-common-core</artifactId>
+        </dependency>
     </dependencies>
 </project>

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

+ 17 - 0
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/feign/DriverScoreFeignService.java

@@ -0,0 +1,17 @@
+package com.sckw.fleet.api.feign;
+
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.fleet.api.model.dto.UpdateDriverScoreDto;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@FeignClient(name = "sckw-ng-fleet",path = "/driverScore")
+public interface DriverScoreFeignService {
+    /**
+     * 更新司机评分
+     */
+    @PostMapping("/update")
+    public BaseResult<Boolean> update(@Validated @RequestBody UpdateDriverScoreDto updateDriverScoreDto);
+}

+ 47 - 0
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/UpdateDriverScoreDto.java

@@ -0,0 +1,47 @@
+package com.sckw.fleet.api.model.dto;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  14:46
+ * @Description: 更新司机评分参数
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UpdateDriverScoreDto {
+
+    /** 供应商企业id */
+    @NotNull
+    private Long providerEntId;
+
+    /** 物流企业id */
+    @NotNull
+    private Long logisticsEntId;
+
+    /** 供应商企业名称 */
+    @NotBlank
+    private String providerEntName;
+
+    /** 变动评分 */
+    private BigDecimal scoreChange;
+
+    /** 物流企业评分 */
+    @NotNull
+    private BigDecimal logisticsEntScore;
+
+    /** 变动原因 */
+    @NotBlank
+    private String action;
+
+    /** 操作类型 1-初始化 2-修改评分 3-重置评分*/
+    @NotNull
+    private Integer operatorType;
+}

+ 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;
@@ -293,4 +295,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);
 }

+ 1 - 0
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteUserService.java

@@ -302,4 +302,5 @@ public interface RemoteUserService {
 
     List<Long> findEntListByUserId(Long userId);
 
+    void saveUser(KwsUserReqDto kwsUser);
 }

+ 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;
+
+
+
+
+
+}

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

@@ -0,0 +1,66 @@
+package com.sckw.system.api.model.dto.req;
+
+import com.sckw.core.model.base.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户
+ * @author zk
+ * @date 2023-05-31
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class KwsUserReqDto extends BaseModel {
+
+    /**
+     * 系统类型(1运营端、2企业开户)
+     */
+    private Integer systemType;
+    private Long entId;
+    /**
+     * 账号
+     */
+    private String account;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 用户名
+     */
+    private String name;
+
+    /**
+     * 手机号
+     */
+    private String phone;
+
+    /**
+     * 头像
+     */
+    private String photo;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 推送设备id
+     */
+    private String clientId;
+
+    /**
+     * 是否是企业管理(1是 0否)
+     */
+    private Integer isMain;
+
+    /**
+     * 盐
+     */
+    private String salt;
+
+}

+ 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>

+ 32 - 0
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/config/FeignConfig.java

@@ -0,0 +1,32 @@
+package com.sckw.contract.config;
+
+
+import com.sckw.core.model.constant.Global;
+import feign.RequestInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-12  16:10
+ * @Description: feign远程调用配置
+ */
+@Configuration
+public class FeignConfig {
+
+    @Bean("requestInterceptor")
+    public RequestInterceptor requestInterceptor() {
+        return requestTemplate -> {
+            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+            jakarta.servlet.http.HttpServletRequest request = attributes.getRequest();
+            String userInfoStrEncode = request.getHeader(Global.USER_INFO_STR_ENCODE);
+            String entInfoStrEncode = request.getHeader(Global.ENT_INFO_STR_ENCODE);
+            requestTemplate.header(Global.USER_INFO_STR_ENCODE, userInfoStrEncode);
+            requestTemplate.header(Global.ENT_INFO_STR_ENCODE, entInfoStrEncode);
+        };
+    }
+
+}

+ 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));
 

+ 35 - 13
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/impl/KwcContractLogisticsScoreServiceImpl.java

@@ -30,6 +30,8 @@ import com.sckw.core.utils.IdWorker;
 import com.sckw.core.utils.PageUtils;
 import com.sckw.core.web.config.CustomConfig;
 import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.fleet.api.feign.DriverScoreFeignService;
+import com.sckw.fleet.api.model.dto.UpdateDriverScoreDto;
 import com.sckw.redis.constant.RedisConstant;
 import com.sckw.redis.utils.RedissonUtils;
 import com.sckw.system.api.model.dto.res.EntCacheResDto;
@@ -59,6 +61,8 @@ public class KwcContractLogisticsScoreServiceImpl implements IKwcContractLogisti
     @Autowired
     private KwcContractLogisticsScoreDetailMapper kwcContractLogisticsScoreDetailMapper;
     @Autowired
+    private DriverScoreFeignService driverScoreFeignService;
+    @Autowired
     private CustomConfig customConfig;
 
     /**
@@ -247,11 +251,16 @@ public class KwcContractLogisticsScoreServiceImpl implements IKwcContractLogisti
                 detailDto.setStatus(NumberConstant.ONE);
                 initLogisticsScoreDetail(detailDto);
 
-                //todo tys初始化司机评分,需要传参供应企业id,物流企业id,评分变动,变动原因
-                logisticsScore.getProviderEntId();
-                logisticsScore.getLogisticsEntId();
-                logisticsScore.getScore();
-                detailDto.getAction();
+                //初始化司机评分,需要传参供应企业id,物流企业id,供应企业名称,评分变动,当前物流企业评分,变动原因
+                UpdateDriverScoreDto updateDriverScoreDto = new UpdateDriverScoreDto();
+                updateDriverScoreDto.setProviderEntId(logisticsScore.getProviderEntId());
+                updateDriverScoreDto.setLogisticsEntId(logisticsScore.getLogisticsEntId());
+                updateDriverScoreDto.setProviderEntName(LoginUserHolder.getEntName());
+                updateDriverScoreDto.setScoreChange(logisticsScore.getScore());
+                updateDriverScoreDto.setLogisticsEntScore(logisticsScore.getScore());
+                updateDriverScoreDto.setAction(detailDto.getAction());
+                updateDriverScoreDto.setOperatorType(1);
+                driverScoreFeignService.update(updateDriverScoreDto);
             }
         } finally {
             RedissonUtils.unlock(lockKey);
@@ -310,13 +319,16 @@ public class KwcContractLogisticsScoreServiceImpl implements IKwcContractLogisti
                     logisticsScoreDetail.setUpdateBy(LoginUserHolder.getUserId());
                     logisticsScoreDetail.setUpdateTime(new Date());
                     kwcContractLogisticsScoreDetailMapper.updateKwcContractLogisticsScoreDetail(logisticsScoreDetail);
-                    // todo tys更新司机评分 需要传参供应企业id,物流企业id,评分变动,变动原因
-                    logisticsScore.getProviderEntId();
-                    logisticsScore.getLogisticsEntId();
-                    logisticsScoreDetail.getScoreChange();
-                    logisticsScoreDetail.getAction();
-
-
+                    //修改司机评分,需要传参供应企业id,物流企业id,供应企业名称,评分变动,当前物流企业评分,变动原因
+                    UpdateDriverScoreDto updateDriverScoreDto = new UpdateDriverScoreDto();
+                    updateDriverScoreDto.setProviderEntId(logisticsScore.getProviderEntId());
+                    updateDriverScoreDto.setLogisticsEntId(logisticsScore.getLogisticsEntId());
+                    updateDriverScoreDto.setProviderEntName(LoginUserHolder.getEntName());
+                    updateDriverScoreDto.setScoreChange(logisticsScoreDetail.getScoreChange());
+                    updateDriverScoreDto.setLogisticsEntScore(logisticsScore.getScore());
+                    updateDriverScoreDto.setAction(logisticsScoreDetail.getAction());
+                    updateDriverScoreDto.setOperatorType(2);
+                    driverScoreFeignService.update(updateDriverScoreDto);
                 }
             }else{
                 throw new BusinessException("该评分已审批完成");
@@ -423,7 +435,17 @@ public class KwcContractLogisticsScoreServiceImpl implements IKwcContractLogisti
             kwcContractLogisticsScoreDetailMapper.insertKwcContractLogisticsScoreDetail(resetLogisticsScoreDetail);
             //4.清除待审核评分
             kwcContractLogisticsScoreDetailMapper.deleteKwcContractLogisticsScoreDetailByScoreId(logisticsScore.getId(),NumberConstant.ZERO);
-            //4.todo tys重置司机评分需要传参供应商企业id,物流企业id,重置评分,原因
+            //重置司机评分,需要传参供应企业id,物流企业id,供应企业名称,评分变动,当前物流企业评分,变动原因
+            UpdateDriverScoreDto updateDriverScoreDto = new UpdateDriverScoreDto();
+            updateDriverScoreDto.setProviderEntId(logisticsScore.getProviderEntId());
+            updateDriverScoreDto.setLogisticsEntId(logisticsScore.getLogisticsEntId());
+            updateDriverScoreDto.setProviderEntName(LoginUserHolder.getEntName());
+            updateDriverScoreDto.setScoreChange(resetLogisticsScoreDetail.getScoreChange());
+            updateDriverScoreDto.setLogisticsEntScore(logisticsScore.getScore());
+            updateDriverScoreDto.setAction(resetLogisticsScoreDetail.getAction());
+            updateDriverScoreDto.setOperatorType(3);
+            driverScoreFeignService.update(updateDriverScoreDto);
+
 
         } finally {
             RedissonUtils.unlock(lockKey);

+ 6 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractLogisticsService.java

@@ -1284,7 +1284,12 @@ public class KwcContractLogisticsService {
 
         saveContractLogistics.setStatus(ContractStatusEnum.SUBMIT.getCode());
         saveContractLogistics.setCreateBy(LoginUserHolder.getUserId());
-        saveContractLogistics.setCreateTime(date);
+        if (Objects.nonNull(req.getId())){
+            saveContractLogistics.setCreateTime(null);
+        }else {
+            saveContractLogistics.setCreateTime(date);
+        }
+
         saveContractLogistics.setUpdateBy(LoginUserHolder.getUserId());
         saveContractLogistics.setUpdateTime(date);
         saveContractLogistics.setCommonPrice(baseInfo.getCommonPrice());

+ 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;
+    }
+
 }
 

+ 32 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/config/FeignConfig.java

@@ -0,0 +1,32 @@
+package com.sckw.fleet.config;
+
+
+import com.sckw.core.model.constant.Global;
+import feign.RequestInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-12  16:10
+ * @Description: feign远程调用配置
+ */
+@Configuration
+public class FeignConfig {
+
+    @Bean("requestInterceptor")
+    public RequestInterceptor requestInterceptor() {
+         return requestTemplate -> {
+             ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+             jakarta.servlet.http.HttpServletRequest request = attributes.getRequest();
+             String userInfoStrEncode = request.getHeader(Global.USER_INFO_STR_ENCODE);
+             String entInfoStrEncode = request.getHeader(Global.ENT_INFO_STR_ENCODE);
+             requestTemplate.header(Global.USER_INFO_STR_ENCODE, userInfoStrEncode);
+             requestTemplate.header(Global.ENT_INFO_STR_ENCODE, entInfoStrEncode);
+         };
+    }
+
+}

+ 33 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/controller/KwfDriverScoreController.java

@@ -0,0 +1,33 @@
+package com.sckw.fleet.controller;
+
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.fleet.api.model.dto.UpdateDriverScoreDto;
+import com.sckw.fleet.service.KwfDriverScoreService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  11:24
+ * @Description: 司机评分
+ */
+@RestController
+@RequestMapping("/driverScore")
+public class KwfDriverScoreController {
+
+    @Autowired
+    private KwfDriverScoreService kwfDriverScoreService;
+
+    /**
+     * 更新司机评分
+     */
+    @PostMapping("/update")
+    public BaseResult<Boolean> update(@Validated @RequestBody UpdateDriverScoreDto updateDriverScoreDto) {
+        kwfDriverScoreService.update(updateDriverScoreDto);
+        return BaseResult.success();
+    }
+}

+ 4 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverMapper.java

@@ -55,6 +55,10 @@ public interface KwfDriverMapper extends BaseMapper<KwfDriver> {
      */
     List<Map<String, Object>> findList(Map<String, Object> params);
 
+
+
+    List<KwfDriver> findListByEntId(Long entId);
+
     /**
      * 查询
      * @param params

+ 62 - 4
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreDetailMapper.java

@@ -4,12 +4,70 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sckw.fleet.model.KwfDriverScoreDetail;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
- * @Author: tangyishan
- * @CreateTime: 2025-12-11  18:06
- * @Description: 司机评分明细Mapper接口
+ * 司机评分明细Mapper接口
+ * 
+ * @author tangyishan
+ * @date 2025-12-11
  */
 @Mapper
-public interface KwfDriverScoreDetailMapper extends BaseMapper<KwfDriverScoreDetail> {
+public interface KwfDriverScoreDetailMapper extends BaseMapper<KwfDriverScoreDetail>
+{
+    /**
+     * 查询司机评分明细
+     * 
+     * @param id 司机评分明细主键
+     * @return 司机评分明细
+     */
+    public KwfDriverScoreDetail selectKwfDriverScoreDetailById(Long id);
+
+    /**
+     * 查询司机评分明细列表
+     * 
+     * @param kwfDriverScoreDetail 司机评分明细
+     * @return 司机评分明细集合
+     */
+    public List<KwfDriverScoreDetail> selectKwfDriverScoreDetailList(KwfDriverScoreDetail kwfDriverScoreDetail);
+
+    /**
+     * 新增司机评分明细
+     * 
+     * @param kwfDriverScoreDetail 司机评分明细
+     * @return 结果
+     */
+    public int insertKwfDriverScoreDetail(KwfDriverScoreDetail kwfDriverScoreDetail);
+
+    /**
+     * 批量新增司机评分明细
+     *
+     * @param driverScoreDetails 司机评分明细
+     * @return 结果
+     */
+    public int insertBatch(List<KwfDriverScoreDetail> driverScoreDetails);
+
+    /**
+     * 修改司机评分明细
+     * 
+     * @param kwfDriverScoreDetail 司机评分明细
+     * @return 结果
+     */
+    public int updateKwfDriverScoreDetail(KwfDriverScoreDetail kwfDriverScoreDetail);
+
+    /**
+     * 删除司机评分明细
+     * 
+     * @param id 司机评分明细主键
+     * @return 结果
+     */
+    public int deleteKwfDriverScoreDetailById(Long id);
 
+    /**
+     * 批量删除司机评分明细
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteKwfDriverScoreDetailByIds(Long[] ids);
 }

+ 63 - 4
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreMapper.java

@@ -4,11 +4,70 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sckw.fleet.model.KwfDriverScore;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
- * @Author: tangyishan
- * @CreateTime: 2025-12-11  18:06
- * @Description: 司机评分Mapper接口
+ * 司机评分Mapper接口
+ * 
+ * @author tangyishan
+ * @date 2025-12-11
  */
 @Mapper
-public interface KwfDriverScoreMapper extends BaseMapper<KwfDriverScore> {
+public interface KwfDriverScoreMapper extends BaseMapper<KwfDriverScore>
+{
+    /**
+     * 查询司机评分
+     * 
+     * @param id 司机评分主键
+     * @return 司机评分
+     */
+    public KwfDriverScore selectKwfDriverScoreById(Long id);
+
+    /**
+     * 查询司机评分列表
+     * 
+     * @param kwfDriverScore 司机评分
+     * @return 司机评分集合
+     */
+    public List<KwfDriverScore> selectKwfDriverScoreList(KwfDriverScore kwfDriverScore);
+
+    /**
+     * 新增司机评分
+     * 
+     * @param KwfDriverScore 司机评分
+     * @return 结果
+     */
+    public int insertKwfDriverScore(List<KwfDriverScore> KwfDriverScore);
+
+    /**
+     *批量新增司机评分
+     *
+     * @param driverScores 司机评分
+     * @return 结果
+     */
+    public int insertBatch(List<KwfDriverScore> driverScores);
+
+    /**
+     * 批量修改司机评分
+     * 
+     * @param driverScores 司机评分
+     * @return 结果
+     */
+    public int updateScoreBatch(List<KwfDriverScore> driverScores);
+
+    /**
+     * 删除司机评分
+     * 
+     * @param id 司机评分主键
+     * @return 结果
+     */
+    public int deleteKwfDriverScoreById(Long id);
+
+    /**
+     * 批量删除司机评分
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteKwfDriverScoreByIds(Long[] ids);
 }

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

+ 25 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/dto/DriverScoreDto.java

@@ -0,0 +1,25 @@
+package com.sckw.fleet.model.dto;
+
+import lombok.Data;
+
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  20:09
+ * @Description: 司机评分参数
+ */
+@Data
+public class DriverScoreDto {
+    /**
+     * 主键
+     */
+    private Long id;
+    /** 供应商企业id */
+    private Long providerEntId;
+
+    /** 物流企业id */
+    private Long logisticsEntId;
+
+    /** 司机id */
+    private Long driverId;
+}

+ 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.KwfDriverScore;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+
+/**
+ * @author PC
+ * 司机评分
+ */
+@Repository
+public class KwfDriverScoreRepository extends ServiceImpl<KwfDriverScoreMapper, KwfDriverScore> {
+
+    public List<KwfDriverScore> findDriverScoreByEntIds(Long proEntId, Long logEntId, List<Long> driverIds) {
+        return list(Wrappers.<KwfDriverScore>lambdaQuery()
+                .eq(BaseModel::getDelFlag,0)
+                .eq(KwfDriverScore::getProviderEntId,proEntId)
+                .eq(KwfDriverScore::getLogisticsEntId,logEntId)
+                .in(KwfDriverScore::getDriverId,driverIds)
+                .orderByDesc(KwfDriverScore::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));
+    }
 }

+ 264 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverScoreService.java

@@ -0,0 +1,264 @@
+package com.sckw.fleet.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.sckw.core.utils.CollectionUtils;
+import com.sckw.core.utils.IdWorker;
+import com.sckw.core.web.context.LoginUserHolder;
+import com.sckw.fleet.api.model.dto.UpdateDriverScoreDto;
+import com.sckw.fleet.dao.KwfDriverMapper;
+import com.sckw.fleet.dao.KwfDriverScoreDetailMapper;
+import com.sckw.fleet.dao.KwfDriverScoreMapper;
+import com.sckw.fleet.model.KwfDriver;
+import com.sckw.fleet.model.KwfDriverScore;
+import com.sckw.fleet.model.KwfDriverScoreDetail;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  15:05
+ * @Description: 司机评分服务
+ */
+@Slf4j
+@Service
+public class KwfDriverScoreService {
+
+    @Autowired
+    private KwfDriverMapper kwfDriverMapper;
+    @Autowired
+    private KwfDriverScoreMapper kwfDriverScoreMapper;
+    @Autowired
+    private KwfDriverScoreDetailMapper kwfDriverScoreDetailMapper;
+
+    /**
+     * 更新司机评分
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void update(UpdateDriverScoreDto updateDriverScoreDto) {
+        log.info("进入KwfDriverScoreService.updateScore()方法,修改司机评分参数为:{}", JSON.toJSONString(updateDriverScoreDto));
+        //查询出当前物流企业的所有司机
+        List<KwfDriver> drivers= kwfDriverMapper.findListByEntId(updateDriverScoreDto.getLogisticsEntId());
+        if(CollectionUtils.isEmpty(drivers)){
+            //无司机,直接返回
+            return;
+        }
+        Map<Long, KwfDriver> driversMap = drivers.stream().collect(Collectors.toMap(KwfDriver::getId, v -> v));
+        //查询指定供应商,指定物流的下的所有司机的评分
+        KwfDriverScore driverScoreDto = new KwfDriverScore();
+        driverScoreDto.setProviderEntId(updateDriverScoreDto.getProviderEntId());
+        driverScoreDto.setLogisticsEntId(updateDriverScoreDto.getLogisticsEntId());
+        List<KwfDriverScore> kwfDriverScores = kwfDriverScoreMapper.selectKwfDriverScoreList(driverScoreDto).stream().filter(v-> driversMap.containsKey(v.getDriverId())).toList();
+        //对未进行评分初始化的司机进行初始化
+        KwfDriverScoreAndDetail kwfDriverScoreAndDetail = initDriverScore(updateDriverScoreDto, driversMap, kwfDriverScores);
+        //将刚初始化的评分记录放入司机评分集合中
+        if(kwfDriverScoreAndDetail != null){
+            kwfDriverScores.addAll(kwfDriverScoreAndDetail.getDriverScores());
+        }
+        //
+        //根据不同的操作类型调用不同的更新方法
+        if(Objects.equals(updateDriverScoreDto.getOperatorType(), 1)){
+//            initDriverScore(updateDriverScoreDto, driversMap,driverScoreMap);
+        }else if(Objects.equals(updateDriverScoreDto.getOperatorType(), 2)){
+            //修改司机评分
+            updateDriverScore(updateDriverScoreDto, driversMap,kwfDriverScores);
+        }else {
+            //重置司机评分
+            resetDriverScore(updateDriverScoreDto, driversMap,kwfDriverScores);
+        }
+    }
+
+
+    /**
+     * 初始化司机评分
+     */
+    private KwfDriverScoreAndDetail initDriverScore(UpdateDriverScoreDto updateDriverScoreDto, Map<Long, KwfDriver> driversMap,List<KwfDriverScore> kwfDriverScores){
+        List<Long> driverIds = kwfDriverScores.stream().map(KwfDriverScore::getDriverId).toList();
+        //找出没有评分记录的司机
+        List<KwfDriver> noScoreDrivers = driversMap.values().stream().filter(driver -> !driverIds.contains(driver.getId())).toList();
+        //所有司机均有评分,继承之前的评分,无需进行初始化
+        if(noScoreDrivers.isEmpty()){
+            return null;
+        }
+        //构建司机评分记录和评分明细集合
+        KwfDriverScoreAndDetail kwfDriverScoreAndDetail = buildDriverScoreInitRecord(updateDriverScoreDto, noScoreDrivers);
+        //批量插入评分记录
+        kwfDriverScoreMapper.insertBatch(kwfDriverScoreAndDetail.getDriverScores());
+        //批量插入评分明细
+        kwfDriverScoreDetailMapper.insertBatch(kwfDriverScoreAndDetail.getDriverScoreDetails());
+        return kwfDriverScoreAndDetail;
+    }
+
+    /**
+     * 修改司机评分
+     */
+    private void updateDriverScore(UpdateDriverScoreDto updateDriverScoreDto, Map<Long, KwfDriver> driversMap,List<KwfDriverScore> kwfDriverScores){
+        //driversMap-物流企业下所有司机,kwfDriverScores-指定供应商,指定物流的所有司机的评分
+        //深拷贝出新的司机评分集合
+        List<KwfDriverScore> kwfDriverScoresNew = JSON.parseObject(JSON.toJSONString(kwfDriverScores), new TypeReference<>() {});
+        //给所有司机进行改分,收集超额的分
+        BigDecimal min = new BigDecimal("0.00");
+        BigDecimal max = new BigDecimal("100.00");
+        BigDecimal exceedScore = new BigDecimal("0.00");
+        for (KwfDriverScore driverScore : kwfDriverScoresNew) {
+            BigDecimal score = driverScore.getScore();
+            BigDecimal resultScore = score.add(updateDriverScoreDto.getScoreChange());
+            if(resultScore.compareTo(min) < 0){
+                exceedScore = exceedScore.add(resultScore);
+                driverScore.setScore(new BigDecimal("0.00"));
+            }else if(resultScore.compareTo(max)>0){
+                exceedScore = exceedScore.add(resultScore.subtract(max));
+                driverScore.setScore(new BigDecimal("100.00"));
+            }else {
+                driverScore.setScore(resultScore);
+            }
+        }
+        //有超额的分,依次分配或扣减分数最低或做高的司机评分到平均分
+        if(exceedScore.compareTo(BigDecimal.ZERO) != 0){
+            //默认按照评分升序排序,如果是减分操作,则按照降序排序
+            Comparator<KwfDriverScore> comparator = Comparator.comparing(KwfDriverScore::getScore);
+            if(updateDriverScoreDto.getScoreChange().compareTo(BigDecimal.ZERO) < 0){
+                comparator = comparator.reversed();
+            }
+            kwfDriverScoresNew = kwfDriverScoresNew.stream().sorted(comparator).toList();
+            //分配超额的分,加分操作依次给最低的司机加到分均分,减分操作依次给最高分的司机减到分均分
+            for (KwfDriverScore kwfDriverScore : kwfDriverScoresNew) {
+                //超额的分已经分配完,退出循环
+                if(exceedScore.compareTo(BigDecimal.ZERO) == 0){
+                    break;
+                }
+                //计算当前司机最大可改的分
+                BigDecimal changeMaxScore = updateDriverScoreDto.getLogisticsEntScore().subtract(kwfDriverScore.getScore());
+                //计算司机实际可改的分
+                BigDecimal changeScore = exceedScore.abs().compareTo(changeMaxScore.abs()) < 0 ? exceedScore : changeMaxScore;
+                kwfDriverScore.setScore(kwfDriverScore.getScore().add(changeScore));
+                //计算剩余可分配的分
+                exceedScore = exceedScore.subtract(changeScore);
+            }
+        }
+        //构建司机评分记录和评分明细集合
+        KwfDriverScoreAndDetail kwfDriverScoreAndDetail = buildDriverScoreUpdateRecord(updateDriverScoreDto, driversMap, kwfDriverScores, kwfDriverScoresNew);
+        //批量更新评分记录
+        kwfDriverScoreMapper.updateScoreBatch(kwfDriverScoreAndDetail.getDriverScores());
+        //批量插入评分明细
+        kwfDriverScoreDetailMapper.insertBatch(kwfDriverScoreAndDetail.getDriverScoreDetails());
+    }
+
+    /**
+     * 重置司机评分
+     */
+    private void resetDriverScore(UpdateDriverScoreDto updateDriverScoreDto, Map<Long, KwfDriver> driversMap,List<KwfDriverScore> kwfDriverScores){
+        //driversMap-物流企业下所有司机,kwfDriverScores-指定供应商,指定物流的所有司机的评分
+        //构建司机评分记录和评分明细集合
+        KwfDriverScoreAndDetail kwfDriverScoreAndDetail = buildDriverScoreResetRecord(updateDriverScoreDto, driversMap, kwfDriverScores);
+        //批量更新评分记录
+        kwfDriverScoreMapper.updateScoreBatch(kwfDriverScoreAndDetail.getDriverScores());
+        //批量插入评分明细
+        kwfDriverScoreDetailMapper.insertBatch(kwfDriverScoreAndDetail.getDriverScoreDetails());
+    }
+
+    private KwfDriverScoreAndDetail buildDriverScoreInitRecord(UpdateDriverScoreDto updateDriverScoreDto,List<KwfDriver> drivers){
+        Date now = new Date();
+        //构建司机评分记录集合
+        List<KwfDriverScore> driverScores = new ArrayList<>();
+        List<KwfDriverScoreDetail> driverScoreDetails = new ArrayList<>();
+        IdWorker idWorker = new IdWorker(1L);
+        for (KwfDriver driver : drivers) {
+            long scoreId = idWorker.nextId();
+            //构建司机评分记录
+            KwfDriverScore driverScore = new KwfDriverScore();
+            driverScore.setId(scoreId);
+            driverScore.setProviderEntId(updateDriverScoreDto.getProviderEntId());
+            driverScore.setLogisticsEntId(updateDriverScoreDto.getLogisticsEntId());
+            driverScore.setDriverId(driver.getId());
+            driverScore.setProviderEntName(updateDriverScoreDto.getProviderEntName());
+            driverScore.setScore(updateDriverScoreDto.getLogisticsEntScore());
+            driverScore.setCreateBy(LoginUserHolder.getUserId());
+            driverScore.setCreateTime(now);
+            driverScore.setUpdateBy(LoginUserHolder.getUserId());
+            driverScore.setUpdateTime(now);
+            driverScores.add(driverScore);
+            //构建司机评分明细
+            KwfDriverScoreDetail scoreDetail = buildDriverScoreDetail(updateDriverScoreDto, driverScore, driver, new BigDecimal("0.00"));
+            driverScoreDetails.add(scoreDetail);
+        }
+
+        return new KwfDriverScoreAndDetail(driverScores, driverScoreDetails);
+    }
+
+    private KwfDriverScoreAndDetail buildDriverScoreUpdateRecord(UpdateDriverScoreDto updateDriverScoreDto,Map<Long, KwfDriver> driversMap,List<KwfDriverScore> kwfDriverScores,List<KwfDriverScore> kwfDriverScoresNew){
+        //原评分记录集合
+        Map<Long, KwfDriverScore> originDriverScoreMap = kwfDriverScores.stream().collect(Collectors.toMap(KwfDriverScore::getId, v -> v));
+        //构建司机评分记录集合
+        List<KwfDriverScoreDetail> driverScoreDetails = new ArrayList<>();
+        Date now = new Date();
+        for (KwfDriverScore driverScore : kwfDriverScoresNew) {
+            //更新评分记录更新信息
+            driverScore.setUpdateBy(LoginUserHolder.getUserId());
+            driverScore.setUpdateTime(now);
+            //构建司机评分明细信息
+            KwfDriverScore originDriverScore = originDriverScoreMap.get(driverScore.getDriverId());
+            KwfDriverScoreDetail scoreDetail = buildDriverScoreDetail(updateDriverScoreDto, driverScore, driversMap.get(driverScore.getDriverId()), originDriverScore.getScore());
+            driverScoreDetails.add(scoreDetail);
+        }
+
+        return new KwfDriverScoreAndDetail(kwfDriverScoresNew, driverScoreDetails);
+    }
+
+    private KwfDriverScoreAndDetail buildDriverScoreResetRecord(UpdateDriverScoreDto updateDriverScoreDto,Map<Long, KwfDriver> driversMap,List<KwfDriverScore> kwfDriverScores){
+        //构建司机评分记录集合
+        List<KwfDriverScoreDetail> driverScoreDetails = new ArrayList<>();
+        for (KwfDriverScore driverScore : kwfDriverScores) {
+            BigDecimal originDriverScore = driverScore.getScore();
+            //更新评分记录更新信息
+            driverScore.setScore(updateDriverScoreDto.getLogisticsEntScore());
+            driverScore.setUpdateBy(LoginUserHolder.getUserId());
+            driverScore.setUpdateTime(new Date());
+            //构建司机评分明细信息
+            KwfDriverScoreDetail scoreDetail = buildDriverScoreDetail(updateDriverScoreDto, driverScore, driversMap.get(driverScore.getDriverId()), originDriverScore);
+            driverScoreDetails.add(scoreDetail);
+        }
+
+        return new KwfDriverScoreAndDetail(kwfDriverScores, driverScoreDetails);
+    }
+
+
+    private KwfDriverScoreDetail buildDriverScoreDetail(UpdateDriverScoreDto updateDriverScoreDto,KwfDriverScore driverScore,KwfDriver driver,BigDecimal originDriverScore){
+        IdWorker idWorker = new IdWorker(1L);
+        Date now = new Date();
+        //构建司机评分明细信息
+        KwfDriverScoreDetail scoreDetail = new KwfDriverScoreDetail();
+        scoreDetail.setId(idWorker.nextId());
+        scoreDetail.setScoreId(driverScore.getId());
+        if(driver != null){
+            scoreDetail.setDriverId(driver.getId());
+            scoreDetail.setDriverName(driver.getName());
+        }
+        scoreDetail.setAction(updateDriverScoreDto.getAction());
+        BigDecimal scoreChange = driverScore.getScore().subtract(originDriverScore);
+        scoreDetail.setScoreChange(scoreChange);
+        scoreDetail.setScore(driverScore.getScore());
+        scoreDetail.setCreateBy(LoginUserHolder.getUserId());
+        scoreDetail.setCreateTime(now);
+        scoreDetail.setUpdateBy(LoginUserHolder.getUserId());
+        scoreDetail.setUpdateTime(now);
+        return scoreDetail;
+    }
+
+
+    @Data
+    @AllArgsConstructor
+    public static class KwfDriverScoreAndDetail{
+        List<KwfDriverScore> driverScores;
+        List<KwfDriverScoreDetail> driverScoreDetails;
+    }
+
+}

+ 30 - 1
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverService.java

@@ -38,6 +38,7 @@ import com.sckw.redis.constant.RedisConstant;
 import com.sckw.redis.utils.RedissonUtils;
 import com.sckw.system.api.RemoteSystemService;
 import com.sckw.system.api.RemoteUserService;
+import com.sckw.system.api.model.dto.req.KwsUserReqDto;
 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;
@@ -465,10 +466,38 @@ public class KwfDriverService {
 
         /**车队班组绑定**/
         driverFleetEdit(driver.getId(), params.getFleetId());
-
+        //同步信息到员工列表
+        userEdit(params);
         return HttpResult.ok(result.getMsg(), driver);
     }
 
+    private void userEdit(KwfDriverDto params) {
+        KwsUserReqDto kwsUserReqDto = new KwsUserReqDto();
+        //密码为空时,以登录名作为密码
+        String salt = PasswordUtils.generateSalt();
+        kwsUserReqDto.setSystemType(LoginUserHolder.getSystemType());
+        kwsUserReqDto.setEntId(LoginUserHolder.getEntId());
+        kwsUserReqDto.setAccount(params.getPhone());
+        String password  =  PasswordUtils.entryptPassword(params.getPhone() + PasswordUtils.md5(params.getPhone()), salt);
+        kwsUserReqDto.setPassword(password);
+        kwsUserReqDto.setName(params.getName());
+        kwsUserReqDto.setPhone(params.getPhone());
+        kwsUserReqDto.setPhoto("");
+        kwsUserReqDto.setEmail("");
+        kwsUserReqDto.setClientId("");
+        kwsUserReqDto.setIsMain(0);
+        kwsUserReqDto.setSalt(salt);
+        kwsUserReqDto.setRemark("司机管理");
+        kwsUserReqDto.setStatus(0);
+        kwsUserReqDto.setCreateBy(LoginUserHolder.getUserId());
+        Date date = new Date();
+        kwsUserReqDto.setCreateTime(date);
+        kwsUserReqDto.setUpdateBy(LoginUserHolder.getUserId());
+        kwsUserReqDto.setUpdateTime(date);
+        kwsUserReqDto.setDelFlag(0);
+        remoteUserService.saveUser(kwsUserReqDto);
+    }
+
     /**
      * @param params 参数
      * @desc 修改司机

+ 10 - 0
sckw-modules/sckw-fleet/src/main/resources/mapper/KwfDriverMapper.xml

@@ -279,6 +279,16 @@
         ORDER BY dr.create_time desc
     </select>
 
+    <select id="findListByEntId" resultType="com.sckw.fleet.model.KwfDriver" parameterType="java.util.Map" >
+        SELECT
+        dr.id, name, phone, idcard, total_complete totalComplete,
+        total_take totalTake, total_weight totalWeight, dre.ent_id entId
+        from kwf_driver dr
+        inner join kwf_driver_ent dre on dr.id = dre.driver_id
+        where dr.del_flag = 0 and dre.del_flag = 0
+        and dre.ent_id = #{entId, jdbcType=VARCHAR}
+    </select>
+
     <select id="findDriver" resultType="com.sckw.fleet.model.KwfDriver" parameterType="java.util.Map" >
         SELECT
             id, ent_id entId, name, phone, salt, password, idcard, total_complete totalComplete,

+ 129 - 0
sckw-modules/sckw-fleet/src/main/resources/mapper/KwfDriverScoreDetailMapper.xml

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sckw.fleet.dao.KwfDriverScoreDetailMapper">
+    
+    <resultMap type="com.sckw.fleet.model.KwfDriverScoreDetail" id="KwfDriverScoreDetailResult">
+        <result property="id"    column="id"    />
+        <result property="scoreId"    column="score_id"    />
+        <result property="driverId"    column="driver_id"    />
+        <result property="driverName"    column="driver_name"    />
+        <result property="action"    column="action"    />
+        <result property="scoreChange"    column="score_change"    />
+        <result property="score"    column="score"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectKwfDriverScoreDetailVo">
+        select id, score_id, driver_id, driver_name, action, score_change, score, create_by, create_time, update_by, update_time from kwf_driver_score_detail
+    </sql>
+
+    <select id="selectKwfDriverScoreDetailList" parameterType="com.sckw.fleet.model.KwfDriverScoreDetail" resultMap="KwfDriverScoreDetailResult">
+        <include refid="selectKwfDriverScoreDetailVo"/>
+        <where>  
+            <if test="scoreId != null "> and score_id = #{scoreId}</if>
+            <if test="driverId != null "> and driver_id = #{driverId}</if>
+            <if test="action != null  and action != ''"> and action = #{action}</if>
+        </where>
+    </select>
+    
+    <select id="selectKwfDriverScoreDetailById" parameterType="Long" resultMap="KwfDriverScoreDetailResult">
+        <include refid="selectKwfDriverScoreDetailVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertKwfDriverScoreDetail" parameterType="com.sckw.fleet.model.KwfDriverScoreDetail">
+        insert into kwf_driver_score_detail
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="scoreId != null">score_id,</if>
+            <if test="driverId != null">driver_id,</if>
+            <if test="driverName != null and driverName != ''">driver_name,</if>
+            <if test="action != null and action != ''">action,</if>
+            <if test="scoreChange != null">score_change,</if>
+            <if test="score != null">score,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="scoreId != null">#{scoreId},</if>
+            <if test="driverId != null">#{driverId},</if>
+            <if test="driverName != null and driverName != ''">#{driverName},</if>
+            <if test="action != null and action != ''">#{action},</if>
+            <if test="scoreChange != null">#{scoreChange},</if>
+            <if test="score != null">#{score},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <insert id="insertBatch">
+        insert into kwf_driver_score_detail
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="scoreId != null">score_id,</if>
+            <if test="driverId != null">driver_id,</if>
+            <if test="driverName != null and driverName != ''">driver_name,</if>
+            <if test="action != null and action != ''">action,</if>
+            <if test="scoreChange != null">score_change,</if>
+            <if test="score != null">score,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+        </trim>
+        values
+        <foreach collection="driverScoreDetails" item="scoreDetail" separator=",">
+            <trim prefix="(" suffix=")" suffixOverrides=",">
+                <if test="id != null">#{scoreDetail.id},</if>
+                <if test="scoreId != null">#{scoreDetail.scoreId},</if>
+                <if test="driverId != null">#{scoreDetail.driverId},</if>
+                <if test="driverName != null and driverName != ''">#{scoreDetail.driverName},</if>
+                <if test="action != null and action != ''">#{scoreDetail.action},</if>
+                <if test="scoreChange != null">#{scoreDetail.scoreChange},</if>
+                <if test="score != null">#{scoreDetail.score},</if>
+                <if test="createBy != null">#{scoreDetail.createBy},</if>
+                <if test="createTime != null">#{scoreDetail.createTime},</if>
+                <if test="updateBy != null">#{scoreDetail.updateBy},</if>
+                <if test="updateTime != null">#{scoreDetail.updateTime},</if>
+            </trim>
+        </foreach>
+    </insert>
+
+    <update id="updateKwfDriverScoreDetail" parameterType="com.sckw.fleet.model.KwfDriverScoreDetail">
+        update kwf_driver_score_detail
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="scoreId != null">score_id = #{scoreId},</if>
+            <if test="driverId != null">driver_id = #{driverId},</if>
+            <if test="driverName != null and driverName != ''">driver_name = #{driverName},</if>
+            <if test="action != null and action != ''">action = #{action},</if>
+            <if test="scoreChange != null">score_change = #{scoreChange},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteKwfDriverScoreDetailById" parameterType="Long">
+        delete from kwf_driver_score_detail where id = #{id}
+    </delete>
+
+    <delete id="deleteKwfDriverScoreDetailByIds" parameterType="String">
+        delete from kwf_driver_score_detail where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 136 - 0
sckw-modules/sckw-fleet/src/main/resources/mapper/KwfDriverScoreMapper.xml

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sckw.fleet.dao.KwfDriverScoreMapper">
+    
+    <resultMap type="com.sckw.fleet.model.KwfDriverScore" id="KwfDriverScoreResult">
+        <result property="id"    column="id"    />
+        <result property="providerEntId"    column="provider_ent_id"    />
+        <result property="logisticsEntId"    column="logistics_ent_id"    />
+        <result property="driverId"    column="driver_id"    />
+        <result property="providerEntName"    column="provider_ent_name"    />
+        <result property="score"    column="score"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectKwfDriverScoreVo">
+        select id, provider_ent_id, logistics_ent_id, driver_id, provider_ent_name, score, create_by, create_time, update_by, update_time from kwf_driver_score
+    </sql>
+
+    <select id="selectKwfDriverScoreList" parameterType="com.sckw.fleet.model.KwfDriverScore" resultMap="KwfDriverScoreResult">
+        <include refid="selectKwfDriverScoreVo"/>
+        <where>  
+            <if test="providerEntId != null "> and provider_ent_id = #{providerEntId}</if>
+            <if test="logisticsEntId != null "> and logistics_ent_id = #{logisticsEntId}</if>
+            <if test="driverId != null "> and driver_id = #{driverId}</if>
+        </where>
+    </select>
+    
+    <select id="selectKwfDriverScoreById" parameterType="Long" resultMap="KwfDriverScoreResult">
+        <include refid="selectKwfDriverScoreVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertKwfDriverScore" parameterType="com.sckw.fleet.model.KwfDriverScore">
+        insert into kwf_driver_score
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="providerEntId != null">provider_ent_id,</if>
+            <if test="logisticsEntId != null">logistics_ent_id,</if>
+            <if test="driverId != null">driver_id,</if>
+            <if test="providerEntName != null and providerEntName != ''">provider_ent_name,</if>
+            <if test="score != null">score,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="providerEntId != null">#{providerEntId},</if>
+            <if test="logisticsEntId != null">#{logisticsEntId},</if>
+            <if test="driverId != null">#{driverId},</if>
+            <if test="providerEntName != null and providerEntName != ''">#{providerEntName},</if>
+            <if test="score != null">#{score},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <insert id="insertBatch">
+        insert into kwf_driver_score
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="providerEntId != null">provider_ent_id,</if>
+            <if test="logisticsEntId != null">logistics_ent_id,</if>
+            <if test="driverId != null">driver_id,</if>
+            <if test="providerEntName != null and providerEntName != ''">provider_ent_name,</if>
+            <if test="score != null">score,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+        </trim>
+        values
+        <foreach collection="driverScores" item="driverScore" separator=",">
+            <trim prefix="(" suffix=")" suffixOverrides=",">
+                <if test="id != null">#{driverScore.id},</if>
+                <if test="providerEntId != null">#{driverScore.providerEntId},</if>
+                <if test="logisticsEntId != null">#{driverScore.logisticsEntId},</if>
+                <if test="driverId != null">#{driverScore.driverId},</if>
+                <if test="providerEntName != null and providerEntName != ''">#{driverScore.providerEntName},</if>
+                <if test="score != null">#{driverScore.score},</if>
+                <if test="createBy != null">#{driverScore.createBy},</if>
+                <if test="createTime != null">#{driverScore.createTime},</if>
+                <if test="updateBy != null">#{driverScore.updateBy},</if>
+                <if test="updateTime != null">#{driverScore.updateTime},</if>
+            </trim>
+        </foreach>
+    </insert>
+
+    <update id="updateKwfDriverScore" parameterType="com.sckw.fleet.model.KwfDriverScore">
+        update kwf_driver_score
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="providerEntId != null">provider_ent_id = #{providerEntId},</if>
+            <if test="logisticsEntId != null">logistics_ent_id = #{logisticsEntId},</if>
+            <if test="driverId != null">driver_id = #{driverId},</if>
+            <if test="providerEntName != null and providerEntName != ''">provider_ent_name = #{providerEntName},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+
+    <update id="updateScoreBatch">
+        <foreach collection="driverScores" item="driverScore" separator=";">
+            update kwf_driver_score
+            <set>
+                <if test="score != null">score = #{driverScore.score},</if>
+                <if test="updateBy != null">update_by = #{driverScore.updateBy},</if>
+                <if test="updateTime != null">update_time = #{driverScore.updateTime},</if>
+            </set>
+            WHERE id = #{driverScore.id}
+        </foreach>
+    </update>
+
+    <delete id="deleteKwfDriverScoreById" parameterType="Long">
+        delete from kwf_driver_score where id = #{id}
+    </delete>
+
+    <delete id="deleteKwfDriverScoreByIds" parameterType="String">
+        delete from kwf_driver_score where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 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,15 +15,19 @@ 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.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.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;
@@ -33,6 +37,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;
@@ -65,6 +73,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.RemoteUserService;
 import com.sckw.system.api.model.dto.res.*;
 import com.sckw.transport.api.dubbo.TransportRemoteService;
@@ -121,6 +130,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;
@@ -786,15 +798,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());
@@ -2098,6 +2121,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("卖方托运时,物流合同不能为空");
@@ -2149,8 +2188,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());
@@ -2174,20 +2214,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"));
@@ -2202,9 +2245,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()));
@@ -2280,11 +2351,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 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteSystemServiceImpl.java

@@ -5,8 +5,11 @@ 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.*;
 import com.sckw.core.utils.BeanUtils;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.FileUtils;
@@ -14,6 +17,8 @@ import com.sckw.core.utils.StringUtils;
 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;
@@ -30,6 +35,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;
 
@@ -976,4 +983,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);
+
+    }
+
 }

+ 19 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteUserServiceImpl.java

@@ -1,9 +1,11 @@
 package com.sckw.system.dubbo;
 
 import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.sckw.core.exception.SystemException;
+import com.sckw.core.model.base.BaseModel;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.page.PageHelperUtil;
 import com.sckw.core.model.page.PageResult;
@@ -468,6 +470,23 @@ public class RemoteUserServiceImpl implements RemoteUserService {
         return enterpriseIds;
     }
 
+    @Override
+    public void saveUser(KwsUserReqDto kwsUserReqDto) {
+        KwsUser kwsUser = new KwsUser();
+        BeanUtils.copyProperties(kwsUserReqDto, kwsUser);
+        KwsUser kwsUser1 = userDao.selectOne(Wrappers.<KwsUser>lambdaQuery()
+                .eq(KwsUser::getPhone, kwsUser.getPhone())
+                .eq(BaseModel::getDelFlag, 0)
+                .last("limit 1"));
+        if (Objects.isNull(kwsUser1)){
+            userDao.insert(kwsUser);
+        }else {
+            kwsUser.setId(kwsUser1.getId());
+            kwsUser.setCreateTime(null);
+            userDao.updateById(kwsUser);
+        }
+    }
+
     /**
      * 根据用户名查用户信息
      *

+ 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;
     }
 

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

@@ -97,10 +97,12 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
         node1.setRemark("车辆[" + waybillOrder.getTruckNo() + "]已到达装货点");
         waybillOrderNodeRepository.save(node1);
         log.info("记录【已装货】节点轨迹成功,节点ID:{}", node1.getId());
-
+        // 间隔5秒钟,防止时间相同
+        Date fiveSecondsLater = new Date(System.currentTimeMillis() + 5000);
         // 第二条:称重信息
         KwtWaybillOrderNode node2 = getWaybillOrderNode(param, waybillOrder);
         node2.setRemark("[" + param.getWeighbridgeName() + "]称重[" + param.getTareAmount() + "吨]");
+        node2.setCreateTime(fiveSecondsLater);
         waybillOrderNodeRepository.save(node2);
         log.info("记录【称重】节点轨迹成功,节点ID:{}", node2.getId());
     }

+ 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;
+
     }

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

@@ -100,6 +100,11 @@ public class VehiclesTrajectoryReq implements Serializable {
 
     @Schema(description = "运单号")
     private String wOrderNo ;
+    /**
+     * 运单号
+     */
+
+    private String wayOrderNo;
     /**
      * 运单状态
      */

+ 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;

+ 1 - 2
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;
@@ -3497,7 +3496,7 @@ public class KwtWaybillOrderV1Service {
         waybillOrderDetailResp.setDriverPhone(billOrder.getDriverPhone());
         waybillOrderDetailResp.setDriverIdCard(billOrder.getDriverIdcard());
         if (Objects.nonNull(kwpGoods)){
-            SysDictResDto sysDictResDto = dictValueAndDictResDtoMap.getOrDefault(goods.getGoodsType(), new SysDictResDto());
+            SysDictResDto sysDictResDto = dictValueAndDictResDtoMap.getOrDefault(kwpGoods.getGoodsType(), new SysDictResDto());
             waybillOrderDetailResp.setGoodsName(kwpGoods.getName()+ "/" +sysDictResDto.getLabel()+"/"+ kwpGoods.getSpec());
         }
         KwtWaybillOrderAddress loadAdd = keyAndAddressMap.getOrDefault(billOrder.getId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtWaybillOrderAddress());

+ 23 - 20
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/VehicleExceptionService.java

@@ -22,6 +22,7 @@ import com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
@@ -80,13 +81,13 @@ public class VehicleExceptionService {
         Map<String, Integer> truckLocationStatusMap = new HashMap<>();
         if (req.getLocationStatus() != null) {
             // 提取所有不重复的车牌号
-            List<String> truckNos = records.stream()
-                    .map(KwtVehicleException::getTruckNo)
-                    .distinct()
-                    .collect(Collectors.toList());
-            
+
+            Map<Long, String> truckIdAndTruckNoMap = records.stream()
+                    .filter(x->Objects.nonNull(x.getTruckId()))
+                    .collect(Collectors.toMap(KwtVehicleException::getTruckId, KwtVehicleException::getTruckNo, (k1, k2) -> k1));
+
             // 批量查询车辆定位状态
-            truckLocationStatusMap = queryVehicleLocationStatus(truckNos);
+            truckLocationStatusMap = queryVehicleLocationStatus(truckIdAndTruckNoMap);
         }
         
         // 提取所有不重复的运单ID
@@ -207,37 +208,40 @@ public class VehicleExceptionService {
     /**
      * 批量查询车辆定位状态
      *
-     * @param truckNos 车牌号列表
+     * @param truckIdAndTruckNoMap 车牌id列表
      * @return 车牌号与定位状态的映射
      */
-    private Map<String, Integer> queryVehicleLocationStatus(List<String> truckNos) {
+    private Map<String, Integer> queryVehicleLocationStatus(  Map<Long, String> truckIdAndTruckNoMap) {
         Map<String, Integer> locationStatusMap = new HashMap<>();
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime thirtyMinutesAgo = now.minusMinutes(30);
-        
-        for (String truckNo : truckNos) {
+        if (MapUtils.isEmpty(truckIdAndTruckNoMap)){
+            return locationStatusMap;
+        }
+        truckIdAndTruckNoMap.forEach((truckId, truckNo) -> {
             try {
                 VehicleDataDTO vehicleDataDTO = new VehicleDataDTO();
-                vehicleDataDTO.setCarNo(truckNo);
+                vehicleDataDTO.setCarNo(Objects.isNull(truckId) ? "0" : String.valueOf(truckId));
                 BaseIotResult<VehicleReturnData> result = vehicleTraceClient.queryRealTimeLocation(vehicleDataDTO);
                 // 默认离线
                 Integer locationStatus = 0;
-                
+
                 if (result != null && StringUtils.equals(result.getCode(), "0") && result.getData() != null) {
                     VehicleReturnData vehicleData = result.getData();
-                    
+
                     // 判断30分钟内有定位数据为在线
                     if (vehicleData.getTs() != null && vehicleData.getTs().toLocalDateTime().isAfter(thirtyMinutesAgo)) {
                         locationStatus = 1;
                     }
                 }
-                
+
                 locationStatusMap.put(truckNo, locationStatus);
             } catch (Exception e) {
                 log.warn("查询车辆定位状态异常, 车牌号: {}", truckNo, e);
                 locationStatusMap.put(truckNo, 0);
             }
-        }
+        });
+
         
         return locationStatusMap;
     }
@@ -271,13 +275,12 @@ public class VehicleExceptionService {
         Map<String, Integer> truckLocationStatusMap = new HashMap<>();
         if (req.getLocationStatus() != null) {
             // 提取所有不重复的车牌号
-            List<String> truckNos = records.stream()
-                    .map(KwtVehicleException::getTruckNo)
-                    .distinct()
-                    .collect(Collectors.toList());
+            Map<Long, String> truckIdAndTruckNoMap = records.stream()
+                    .filter(x->Objects.nonNull(x.getTruckId()))
+                    .collect(Collectors.toMap(KwtVehicleException::getTruckId, KwtVehicleException::getTruckNo, (k1, k2) -> k1));
 
             // 批量查询车辆定位状态
-            truckLocationStatusMap = queryVehicleLocationStatus(truckNos);
+            truckLocationStatusMap = queryVehicleLocationStatus(truckIdAndTruckNoMap);
         }
         
         // 提取所有不重复的运单ID

+ 4 - 18
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;
@@ -139,7 +124,8 @@ public class WaybillOrderService {
             CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
             CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
             CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
-            CarWaybillV1Enum.WAIT_LOADING.getCode());
+            CarWaybillV1Enum.WAIT_LOADING.getCode(),
+            CarWaybillV1Enum.WEIGHT_TRAFFIC.getCode());
 
     // 定义审核的状态集合
     private static final List<Integer> REVIEW = Arrays.asList(
@@ -338,7 +324,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());
         //供应企业

+ 35 - 30
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/kwfTruckTraceService.java

@@ -60,11 +60,13 @@ import com.sckw.transport.service.zj.VehicleCollectService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.stereotype.Service;
 
+import java.math.RoundingMode;
 import java.sql.Timestamp;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
@@ -837,13 +839,13 @@ public class kwfTruckTraceService {
         }
         
         // 获取所有车牌号列表,用于查询实时位置
-        List<String> truckNos = waybillOrders.stream()
-                .map(KwtWaybillOrder::getTruckNo)
-                .distinct()
-                .collect(Collectors.toList());
-        
+
+        Map<Long, String> truckIdTruckNoMap = waybillOrders.stream()
+                .filter(x->Objects.nonNull(x.getTruckId()))
+                .collect(Collectors.toMap(KwtWaybillOrder::getTruckId, KwtWaybillOrder::getTruckNo, (key1, key2) -> key1));
+
         // 批量查询实时位置状态(30分钟内有数据为在线)
-        Map<String, Integer> truckLocationStatusMap = getStringIntegerMap(truckNos);
+        Map<String, Integer> truckLocationStatusMap = getStringIntegerMap(truckIdTruckNoMap);
 
         // 转换为 VO 对象并根据状态筛选
         return waybillOrders.stream()
@@ -855,21 +857,23 @@ public class kwfTruckTraceService {
     }
 
     @NotNull
-    private Map<String, Integer> getStringIntegerMap(List<String> truckNos) {
+    private Map<String, Integer> getStringIntegerMap(Map<Long, String> truckIdTruckNoMap) {
         Map<String, Integer> truckLocationStatusMap = new HashMap<>();
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime thirtyMinutesAgo = now.minusMinutes(30);
-
-        for (String truckNo : truckNos) {
+        if (MapUtils.isEmpty(truckIdTruckNoMap)){
+            return truckLocationStatusMap;
+        }
+        truckIdTruckNoMap.forEach((truckId, truckNo) -> {
             try {
                 VehicleDataDTO vehicleDataDTO = new VehicleDataDTO();
-                vehicleDataDTO.setCarNo(truckNo);
+                vehicleDataDTO.setCarNo(Objects.isNull(truckId) ? "0" : String.valueOf(truckId));
                 BaseIotResult<VehicleReturnData> result = vehicleTraceClient.queryRealTimeLocation(vehicleDataDTO);
 
                 if (result == null || !Objects.equals(result.getCode(), "0") || result.getData() == null) {
                     // 无定位数据,设置为离线
                     truckLocationStatusMap.put(truckNo, 0);
-                    return truckLocationStatusMap;
+                    return;
                 }
 
                 VehicleReturnData vehicleData = result.getData();
@@ -878,7 +882,7 @@ public class kwfTruckTraceService {
                 if (vehicleData.getTs() == null) {
                     // 无GPS时间,设置为离线
                     truckLocationStatusMap.put(truckNo, 0);
-                    return truckLocationStatusMap;
+                    return;
                 }
 
                 // 30分钟内为在线
@@ -892,7 +896,7 @@ public class kwfTruckTraceService {
                 log.warn("查询车辆实时位置异常, 车牌号: {}", truckNo, e);
                 truckLocationStatusMap.put(truckNo, 0);
             }
-        }
+        });
         return truckLocationStatusMap;
     }
 
@@ -1027,13 +1031,12 @@ public class kwfTruckTraceService {
         }
         
         // 获取车牌号列表,查询定位信息
-        List<String> truckNos = waybillOrders.stream()
-                .map(KwtWaybillOrder::getTruckNo)
-                .distinct()
-                .collect(Collectors.toList());
-        
+        Map<Long, String> truckIdAndTruckNoMap = waybillOrders.stream()
+                .filter(x->Objects.nonNull(x.getTruckId()))
+                .collect(Collectors.toMap(KwtWaybillOrder::getTruckId, KwtWaybillOrder::getTruckNo, (k1, k2) -> k1));
+
         // 批量查询定位状态和位置信息
-        Map<String, VehicleLocationInfo> locationInfoMap = queryVehicleLocationBatch(truckNos);
+        Map<String, VehicleLocationInfo> locationInfoMap = queryVehicleLocationBatch(truckIdAndTruckNoMap);
 
         // 批量查询运单轨迹数据,统计异常数量(通过alarmCode判断)
         List<String> wOrderNos = waybillOrders.stream()
@@ -1205,32 +1208,32 @@ public class kwfTruckTraceService {
     /**
      * 批量查询车辆定位信息
      */
-    private Map<String, VehicleLocationInfo> queryVehicleLocationBatch(List<String> truckNos) {
+    private Map<String, VehicleLocationInfo> queryVehicleLocationBatch(Map<Long, String> truckIdAndTruckNoMap) {
         Map<String, VehicleLocationInfo> locationInfoMap = new HashMap<>();
         LocalDateTime now = LocalDateTime.now();
         log.info("获取配置时间:{}", urlConfigProperties.getMinute());
         LocalDateTime thirtyMinutesAgo = now.minusMinutes(urlConfigProperties.getMinute());
-        if (CollectionUtils.isEmpty(truckNos)){
+        if (MapUtils.isEmpty(truckIdAndTruckNoMap)){
             return locationInfoMap;
         }
-        for (String truckNo : truckNos) {
+        truckIdAndTruckNoMap.forEach((truckId, truckNo) -> {
             try {
                 VehicleDataDTO vehicleDataDTO = new VehicleDataDTO();
-                vehicleDataDTO.setCarNo(truckNo);
+                vehicleDataDTO.setCarNo(Objects.isNull(truckId) ? "0" : String.valueOf(truckId));
                 BaseIotResult<VehicleReturnData> result = vehicleTraceClient.queryRealTimeLocation(vehicleDataDTO);
                 log.info("查询车辆数据中台响应定位信息:{}", JSON.toJSONString( result));
                 VehicleLocationInfo locationInfo = new VehicleLocationInfo();
-                
+
                 if (result != null && StringUtils.equals(result.getCode(), "0") && result.getData() != null) {
                     VehicleReturnData vehicleData = result.getData();
-                    
+
                     // 判断定位状态
                     if (vehicleData.getTs() != null && vehicleData.getTs().toLocalDateTime().isAfter(thirtyMinutesAgo)) {
                         locationInfo.setLocationStatus(1);
                     } else {
                         locationInfo.setLocationStatus(0);
                     }
-                    
+
                     locationInfo.setLongitude(vehicleData.getLongitude());
                     locationInfo.setLatitude(vehicleData.getLatitude());
                     if (vehicleData.getTs() != null) {
@@ -1248,7 +1251,7 @@ public class kwfTruckTraceService {
                 locationInfo.setLocationStatus(0);
                 locationInfoMap.put(truckNo, locationInfo);
             }
-        }
+        });
         
         return locationInfoMap;
     }
@@ -1336,9 +1339,9 @@ public class kwfTruckTraceService {
             
             // 装货重量/任务量
             String loadWeight = String.format("%s%s / %s%s",
-                    subtask.getLoadAmount() != null ? subtask.getLoadAmount() : "0",
+                    subtask.getLoadAmount() != null ? subtask.getLoadAmount().setScale(2, RoundingMode.HALF_UP).toPlainString() : "0.00",
                     subtask.getUnit() != null ? subtask.getUnit() : "",
-                    subtask.getEntrustAmount() != null ? subtask.getEntrustAmount() : "0",
+                    subtask.getEntrustAmount() != null ? subtask.getEntrustAmount().setScale(2, RoundingMode.HALF_UP).toPlainString() : "0.00",
                     subtask.getUnit() != null ? subtask.getUnit() : "");
             vo.setLoadWeight(loadWeight);
             
@@ -1549,13 +1552,15 @@ public class kwfTruckTraceService {
         vehiclesTrajectoryReq.setEngineTemp(40.0f);
         vehiclesTrajectoryReq.setBatteryVoltage(30.0f);
         vehiclesTrajectoryReq.setStatus("0");
+        vehiclesTrajectoryReq.setAlarmCode("0");
         if (req.getExceptionType() != null){
             vehiclesTrajectoryReq.setStatus(String.valueOf(req.getExceptionType()));
         }
         vehiclesTrajectoryReq.setWOrderNo(req.getWayOrderNo());
+        vehiclesTrajectoryReq.setWayOrderNo(req.getWayOrderNo());
         vehiclesTrajectoryReq.setLOrderNo(Optional.ofNullable(logisticsOrder).map(KwtLogisticsOrder::getLOrderNo).orElse( ""));
         VehiclesTrajectoryReq.VehicleDataVO vehicleDataVO = new VehiclesTrajectoryReq.VehicleDataVO();
-        vehicleDataVO.setCarNo(req.getTruckNo());
+        vehicleDataVO.setCarNo(Objects.isNull(order.getTruckId()) ? "0" : String.valueOf(order.getTruckId()));
         if (fleetByTruckId != null){
             vehicleDataVO.setFleetId(Objects.nonNull(fleetByTruckId.getId())?fleetByTruckId.getId().toString():"");
             vehicleDataVO.setFleetName(fleetByTruckId.getName());