Jelajahi Sumber

Merge branch 'dev_20251130' into dev_mvp3

xucaiqin 5 hari lalu
induk
melakukan
486d761bda
22 mengubah file dengan 487 tambahan dan 126 penghapusan
  1. 2 0
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/RemoteFleetService.java
  2. 5 1
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/RUpdateDriverScoreDto.java
  3. 6 1
      sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/UpdateDriverScoreDto.java
  4. 1 1
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/controller/KwcContractLogisticsScoreApiController.java
  5. 14 6
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dubbo/RemoteFleetServiceImpl.java
  6. 42 7
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java
  7. 41 5
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java
  8. 1 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfDriverScoreRepository.java
  9. 7 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfTruckDispatchCoefficientRepository.java
  10. 3 3
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfAutoDispatchService.java
  11. 3 3
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverScoreService.java
  12. 38 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/server/KwsEnterpriseServerController.java
  13. 9 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/KwsEnterpriseDao.java
  14. 7 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/service/KwsEnterpriseService.java
  15. 12 0
      sckw-modules/sckw-system/src/main/resources/mapper/KwsEnterpriseDao.xml
  16. 17 4
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/AbstractWaybillOrderHandler.java
  17. 8 17
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/CancelHandler.java
  18. 1 2
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/ComeIntoHandler.java
  19. 8 6
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/TakingOrderHandler.java
  20. 19 24
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/UnloadingHandler.java
  21. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/KwtWaybillOrder.java
  22. 238 45
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/task/LogisticsOrderCompletionTask.java

+ 2 - 0
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/RemoteFleetService.java

@@ -121,6 +121,8 @@ public interface RemoteFleetService {
 
     TruckDispatchCoefficientVO findAutoTruckDispatchByEntId(Long entId);
 
+    List<TruckDispatchCoefficientVO> findAutoTruckDispatchByEntIds(List<Long> entIds);
+
     DriverConductRulesVO findDriverConductRulesByEntId(Long entId);
 
     List<RTruckVo> findTruckByEntIds(Long entId);

+ 5 - 1
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/RUpdateDriverScoreDto.java

@@ -6,6 +6,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serial;
+import java.io.Serializable;
 import java.math.BigDecimal;
 
 /**
@@ -16,8 +18,10 @@ import java.math.BigDecimal;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class RUpdateDriverScoreDto {
+public class RUpdateDriverScoreDto implements Serializable {
 
+    @Serial
+    private static final long serialVersionUID = -8763763480079554893L;
     /**
      * 供应商企业id
      */

+ 6 - 1
sckw-modules-api/sckw-fleet-api/src/main/java/com/sckw/fleet/api/model/dto/UpdateDriverScoreDto.java

@@ -6,6 +6,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serial;
+import java.io.Serializable;
 import java.math.BigDecimal;
 
 /**
@@ -16,7 +18,10 @@ import java.math.BigDecimal;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class UpdateDriverScoreDto {
+public class UpdateDriverScoreDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -4995959874726280406L;
 
     /** 供应商企业id */
     @NotNull(message = "供应商企业id不能为空")

+ 1 - 1
sckw-modules/sckw-contract/src/main/java/com/sckw/contract/api/KwcContractLogisticsScoreApiController.java → sckw-modules/sckw-contract/src/main/java/com/sckw/contract/controller/KwcContractLogisticsScoreApiController.java

@@ -1,4 +1,4 @@
-package com.sckw.contract.api;
+package com.sckw.contract.controller;
 
 import com.sckw.contract.api.model.dto.req.LogisticsScoreDetailFeignDto;
 import com.sckw.contract.service.IKwcContractLogisticsScoreService;

+ 14 - 6
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dubbo/RemoteFleetServiceImpl.java

@@ -1,15 +1,11 @@
 package com.sckw.fleet.dubbo;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-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.utils.BeanUtils;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.StringUtils;
-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.dto.RUpdateDriverScoreDto;
 import com.sckw.fleet.api.model.vo.*;
@@ -568,7 +564,11 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
         if (result == null) {
             return null;
         }
+        return getTruckDispatchCoefficientVO(result);
+    }
+
 
+    private TruckDispatchCoefficientVO getTruckDispatchCoefficientVO(KwfTruckDispatchCoefficient result) {
         TruckDispatchCoefficientVO rulesVO = new TruckDispatchCoefficientVO();
         rulesVO.setId(result.getId());
         rulesVO.setEntId(result.getEntId());
@@ -588,6 +588,14 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
         rulesVO.setCreateUser(result.getCreateUser());
         rulesVO.setUpdateUser(result.getUpdateUser());
         return rulesVO;
+    }
+
+    @Override
+    public List<TruckDispatchCoefficientVO> findAutoTruckDispatchByEntIds(List<Long> entIds) {
+        List<KwfTruckDispatchCoefficient> autoTruckDispatchByEntIds = truckDispatchCoefficientRepository.findAutoTruckDispatchByEntIds(entIds);
+        return autoTruckDispatchByEntIds.stream()
+                .map(this::getTruckDispatchCoefficientVO)
+                .collect(Collectors.toList());
 
     }
 
@@ -595,7 +603,7 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
     public DriverConductRulesVO findDriverConductRulesByEntId(Long entId) {
         KwfDriverConductRules result = driverConductRulesRepository.findDriverConductRulesByEntId(entId);
         if (result == null) {
-            return new DriverConductRulesVO();
+            return null;
         }
 
         DriverConductRulesVO rulesVO = new DriverConductRulesVO();
@@ -661,7 +669,7 @@ public class RemoteFleetServiceImpl implements RemoteFleetService {
                 .eq(KwfTruckReport::getDelFlag, Global.NO)
                 .eq(KwfTruckReport::getStatus, Global.YES));
         if(truckReport == null) {
-            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "此司机无车辆解绑信息!");
+            return;
         }
         truckReport.setStatus(Global.NO);
         log.info("解绑车辆请求参数 :{}", truckReport);

+ 42 - 7
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java

@@ -1,25 +1,29 @@
 package com.sckw.fleet.model;
 
-import java.math.BigDecimal;
-
-import com.sckw.core.model.base.BaseModel;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * 司机评分对象 kwc_driver_score
  * 
  * @author tangyishan
  * @date 2025-12-11  18:12
  */
-@EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
-public class KwfDriverScore extends BaseModel
-{
+public class KwfDriverScore implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 主键
+     */
+    private Long id;
+
     /** 供应商企业id */
     private Long providerEntId;
 
@@ -31,4 +35,35 @@ public class KwfDriverScore extends BaseModel
 
     /** 司机评分 */
     private BigDecimal score;
+
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    /**
+     * 删除标识(0正常/-1删除)
+     */
+    private Integer delFlag;
+
+
+
 }

+ 41 - 5
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java

@@ -1,24 +1,29 @@
 package com.sckw.fleet.model;
 
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.sckw.core.model.base.BaseModel;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * @Author: tangyishan
  * @CreateTime: 2025-12-11  18:12
  * @Description: 司机评分明细
  */
-@EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
-public class KwfDriverScoreDetail extends BaseModel {
+public class KwfDriverScoreDetail implements Serializable {
+
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 主键
+     */
+    private Long id;
+
     /** 评分主键id */
     private Long scoreId;
 
@@ -33,4 +38,35 @@ public class KwfDriverScoreDetail extends BaseModel {
 
     /** 变动后评分 */
     private BigDecimal score;
+
+    /**
+     * 创建人
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private Long updateBy;
+
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    /**
+     * 删除标识(0正常/-1删除)
+     */
+    private Integer delFlag;
+
+
+
 }

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

@@ -19,7 +19,7 @@ public class KwfDriverScoreRepository extends ServiceImpl<KwfDriverScoreMapper,
 
     public KwfDriverScore findDriverScoreByEntIds(Long proEntId, Long logEntId, Long driverId) {
         return getOne(Wrappers.<KwfDriverScore>lambdaQuery()
-                .eq(BaseModel::getDelFlag,0)
+                .eq(KwfDriverScore::getDelFlag,0)
                 .eq(KwfDriverScore::getProviderEntId,proEntId)
                 .eq(KwfDriverScore::getLogisticsEntId,logEntId)
                 .eq(KwfDriverScore::getDriverId,driverId)

+ 7 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/repository/KwfTruckDispatchCoefficientRepository.java

@@ -6,6 +6,7 @@ import com.sckw.fleet.dao.KwfTruckDispatchCoefficientMapper;
 import com.sckw.fleet.model.KwfTruckDispatchCoefficient;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -21,4 +22,10 @@ public class KwfTruckDispatchCoefficientRepository extends ServiceImpl<KwfTruckD
                 .eq(Objects.nonNull(entId), KwfTruckDispatchCoefficient::getEntId, entId));
     }
 
+
+    public List<KwfTruckDispatchCoefficient> findAutoTruckDispatchByEntIds(List<Long> entIds) {
+        return list(Wrappers.<KwfTruckDispatchCoefficient>lambdaQuery()
+                .in(Objects.nonNull(entIds), KwfTruckDispatchCoefficient::getEntId, entIds));
+    }
+
 }

+ 3 - 3
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfAutoDispatchService.java

@@ -84,9 +84,9 @@ public class KwfAutoDispatchService {
         KwfTruckDispatchCoefficient dispatchCoefficient = new KwfTruckDispatchCoefficient();
         dispatchCoefficient.setEntId(entId);
         dispatchCoefficient.setVehicleWorkHours(10);
-        dispatchCoefficient.setVehicleLoadingHours(1);
-        dispatchCoefficient.setVehicleUnloadingHours(1);
-        dispatchCoefficient.setDriverTimeoutLimit(2);
+        dispatchCoefficient.setVehicleLoadingHours(60);
+        dispatchCoefficient.setVehicleUnloadingHours(60);
+        dispatchCoefficient.setDriverTimeoutLimit(120);
         dispatchCoefficient.setVehicleAvgLoad(26);
         dispatchCoefficient.setVehicleAvgSpeed(50);
         dispatchCoefficient.setVehicleMaxTasks(3);

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

@@ -350,7 +350,6 @@ public class KwfDriverScoreService {
      * 修改司机评分
      * @param dto
      */
-    @Transactional(rollbackFor = Exception.class)
     public void updateDriverScore(RUpdateDriverScoreDto dto) {
         if (dto.getScore() == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "分数不能为空!");
@@ -361,7 +360,7 @@ public class KwfDriverScoreService {
         if (driverScore == null) {
             log.info("司机无评分, 需初始化司机分数,司机id:{}", dto.getDriverId());
             ContractLogisticsScoreVO logisticsScore = remoteContractService.findLogisticsScoreByEntId(dto.getSupEntId(), dto.getLogEntId());
-            if (logisticsScore == null) {
+            if (logisticsScore.getScore() == null || logisticsScore.getScore().compareTo(BigDecimal.ZERO) < 0) {
                 throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "修改司机分数,企业无评分!");
             }
             //初始化司机分数
@@ -374,7 +373,8 @@ public class KwfDriverScoreService {
         BigDecimal scoreChange = dto.getScore();
 
         //3. 修改司机评分
-        driverScore.setScore(currentScore.add(scoreChange));
+        BigDecimal newScore = currentScore.add(scoreChange);
+        driverScore.setScore(newScore.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newScore);
         driverScoreRepository.updateById(driverScore);
 
         //4.新增司机评分明细

+ 38 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/server/KwsEnterpriseServerController.java

@@ -0,0 +1,38 @@
+package com.sckw.system.controller.server;
+
+import com.sckw.system.model.vo.res.EntInfo;
+import com.sckw.system.service.KwsEnterpriseService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+import java.util.List;
+
+
+/**
+ * 企业信息
+ *
+ * @author tangyishan
+ * @since 2026-01-09  15:43
+ */
+@RestController
+@RequestMapping("/server/kwsEnt")
+@Tag(name = "服务端企业信息相关接口")
+@Data
+public class KwsEnterpriseServerController {
+    @Autowired
+    private KwsEnterpriseService kwsEntService;
+
+    /**
+     * @return HttpResult
+     * @desc: 根据企业id列表查询企业信息
+     */
+    @PostMapping("queryEntInfos")
+    public List<EntInfo> queryEntInfos(@RequestBody List<Long> entIds) {
+        return kwsEntService.queryEntInfoByKeys(entIds);
+    }
+}

+ 9 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/KwsEnterpriseDao.java

@@ -67,6 +67,15 @@ public interface KwsEnterpriseDao extends BaseMapper<KwsEnterprise> {
      */
     List<KwsEnterprise> selectAllByKeys(@Param(value = "list") List<Long> list);
 
+    /**
+     * @param list 主键Ids
+     * @return KwsEnterprise
+     * @desc: 批量查
+     * @author: czh
+     * @date: 2023/6/19
+     */
+    List<EntInfo> queryEntInfoByKeys(@Param(value = "list") List<Long> list);
+
     /**
      * 查询
      *

+ 7 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/service/KwsEnterpriseService.java

@@ -242,6 +242,13 @@ public class KwsEnterpriseService {
         return checkKwsEnterpriseById(key);
     }
 
+    public List<EntInfo> queryEntInfoByKeys(List<Long> keys) {
+        if(CollectionUtils.isEmpty(keys)){
+            return Collections.emptyList();
+        }
+        return kwsEnterpriseDao.queryEntInfoByKeys(keys);
+    }
+
 
     /**
      * @param reqVo 分页入参

+ 12 - 0
sckw-modules/sckw-system/src/main/resources/mapper/KwsEnterpriseDao.xml

@@ -332,6 +332,18 @@
         </if>
     </select>
 
+    <select id="queryEntInfoByKeys" resultType="com.sckw.system.model.vo.res.EntInfo">
+        select id as entId, firm_name as entName
+        from kws_enterprise
+        where del_flag = 0
+        <if test="list != null and list.size() > 0">
+            and id in
+            <foreach collection="list" item="item" open="(" close=")" separator=",">
+                #{item}
+            </foreach>
+        </if>
+    </select>
+
     <select id="queryEntInfoByCityCodeAndEntTypesWithPage" resultType="com.sckw.system.model.KwsEnterprise">
         SELECT a.*
         FROM kws_enterprise a

+ 17 - 4
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/AbstractWaybillOrderHandler.java

@@ -9,6 +9,7 @@ import com.sckw.contract.api.model.dto.req.LogisticsScoreDetailFeignDto;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessPlatfromException;
 import com.sckw.core.model.enums.CarWaybillV1Enum;
+import com.sckw.core.model.enums.DispatchWayEnums;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.core.utils.StringUtils;
 import com.sckw.fleet.api.RemoteFleetService;
@@ -91,7 +92,7 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
             // 6. 生成节点轨迹
             createNodeTrace(param, waybillOrder);
             //7.自动派单计算分值
-            calculateAutoDispatchScore(param, waybillOrder);
+            calculateScore(param, waybillOrder);
             // 8. 后置处理
             OrderTakingResp handlerResult = afterProcess(param, waybillOrder);
 
@@ -182,6 +183,18 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
         return node;
     }
 
+    /**
+     * 计算自动派车的行为分数
+     * @param param
+     * @param waybillOrder
+     */
+    protected void calculateScore(T param, KwtWaybillOrder waybillOrder) {
+        if (!(param instanceof OrderCirculateTakingQueryParam) && DispatchWayEnums.AUTO_DISPATCH.getCode().equals(waybillOrder.getDispatchWay())) {
+            calculateAutoDispatchScore(param, waybillOrder);
+        }
+
+    }
+
     // //7.自动派单计算分值
     protected abstract void calculateAutoDispatchScore(T param, KwtWaybillOrder waybillOrder);
 
@@ -248,7 +261,7 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
         if (waybillOrder == null) {
             return 0L;
         }
-        //查询订单托运单位(自动派单订单承运单位只为供应商)
+        //查询订单托运单位
         KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderUnitRepository.queryByLOrderIdAndUnitType(waybillOrder.getLOrderId(), 1);
         if (logisticsOrderUnit == null || logisticsOrderUnit.getEntId() == null) {
             throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ENT, "未找到关联的物流订单托运企业(供应商)!");
@@ -258,7 +271,7 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
 
 
     /**
-     * 查询司机所在企业的派车系数
+     * 查询司机所在企业的供应商派车系数
      */
     protected TruckDispatchCoefficientVO getAutoTruckDispatchByEntId(Long entId) {
         TruckDispatchCoefficientVO truckDispatchVO = remoteFleetService.findAutoTruckDispatchByEntId(entId);
@@ -269,7 +282,7 @@ public abstract class AbstractWaybillOrderHandler<T extends WaybillOrderProcessP
     }
 
     /**
-     * 查询司机所在企业的司机行为规则
+     * 查询司机所在企业的供应商司机行为规则
      */
     protected DriverConductRulesVO getDriverConductRulesByEntId(Long entId) {
         DriverConductRulesVO driverRulesVO = remoteFleetService.findDriverConductRulesByEntId(entId);

+ 8 - 17
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/CancelHandler.java

@@ -1,13 +1,10 @@
 package com.sckw.transport.handler;
 
 
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
 import com.sckw.core.exception.BusinessPlatfromException;
-import com.sckw.core.model.constant.Global;
 import com.sckw.core.model.enums.CarWaybillV1Enum;
 import com.sckw.core.utils.DateUtils;
-import com.sckw.core.web.context.LoginUserHolder;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
 import com.sckw.order.api.model.OrderDetailVo;
@@ -28,7 +25,6 @@ import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.Objects;
-import java.util.Optional;
 
 /**
  * Author: donglang
@@ -108,7 +104,7 @@ public class CancelHandler extends AbstractWaybillOrderHandler<WaybillOrderCance
         //查询运单运单信息
         KwtWaybillOrder waybillOrder = getWaybillOrder(wOrderId);
         remoteFleetService.unbindTruck(waybillOrder.getEntId(), waybillOrder.getDriverId());
-        log.info("运单完成,解绑司机与车辆关系,运单id:{},企业id:{},司机id:{}", wOrderId, waybillOrder.getEntId(), waybillOrder.getDriverId());
+        log.info("解绑完成,解绑司机与车辆关系,运单id:{},企业id:{},司机id:{}", wOrderId, waybillOrder.getEntId(), waybillOrder.getDriverId());
     }
 
     /**
@@ -152,40 +148,35 @@ public class CancelHandler extends AbstractWaybillOrderHandler<WaybillOrderCance
      */
     @Override
     protected void calculateAutoDispatchScore(WaybillOrderCancelParam param, KwtWaybillOrder waybillOrder) {
-//        if (true) {
-//            //先不执行自动派单逻辑
-//            return;
-//        }
+        //供应商
+        Long supEntId = getSupplierId(waybillOrder);
         // 获取司机行为规则配置
-        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(waybillOrder.getEntId());
+        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(supEntId);
         //分数
         Integer cancelOrderScore = driverRulesVO.getIllegalCancelOrderScore();
         //分钟数
         Integer cancelOrderMinutes = driverRulesVO.getIllegalCancelOrderMinutes();
         if (cancelOrderScore <= 0 || cancelOrderMinutes<= 0) {
-            log.warn("【司机违规取消运单】企业{}的司机违规取消运单分钟数/分数异常,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
+            log.warn("【司机违规取消运单】企业{}的司机违规取消运单分钟数/分数异常,运单ID:{}", supEntId, waybillOrder.getId());
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机违规取消运单】配置的分钟数/分数需大于0!");
         }
-        long cancelOrderInMillis = cancelOrderMinutes * 60 * 1000;
         //司机接单时间
         KwtWaybillOrderNode takingOrderNodes = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.PENDING_VEHICLE.getCode());
-        Date takingOrderTime = takingOrderNodes.getCreateTime() != null ? takingOrderNodes.getCreateTime() : null;
+        Date takingOrderTime = takingOrderNodes.getCreateTime();
         //司机取消接单时间
         KwtWaybillOrderNode cancelNode = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.CANCELLED.getCode());
-        Date cancelNodeTime = cancelNode.getCreateTime() != null ? cancelNode.getCreateTime() : null;
+        Date cancelNodeTime = cancelNode.getCreateTime();
 
         // 计算两个时间的分钟差
         Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(takingOrderTime, cancelNodeTime);
-        if (timeDiffMinutes > cancelOrderInMillis) {
+        if (timeDiffMinutes > cancelOrderMinutes.longValue()) {
             log.info("【司机违规取消运单】超时!司机违规取消运单分钟数限制:" + cancelOrderMinutes + "分钟,实际:" + timeDiffMinutes + "分钟");
             //1、更新司机分数(减分)
             cancelOrderScore = -Math.abs(cancelOrderScore);
-            Long supEntId = getSupplierId(waybillOrder);
             updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), cancelOrderScore, "司机违规取消运单");
 
             //2、更新企业分数(减分)
             updateLogEntScore(waybillOrder, supEntId, cancelOrderScore, "司机违规取消运单");
-
         }
 
     }

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

@@ -169,7 +169,6 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
             log.warn("【司机未按时到场】企业{}的司机超时限制配置异常,运单ID:{}", entId,wOrderId);
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机未按时到场】司机超时限制配置需大于0!");
         }
-        long driverTimeoutInMillis = driverTimeout * 60 * 1000;
         //司机接单时间
         KwtWaybillOrderNode takingOrderNodes = getNodesByOrderId(wOrderId, CarWaybillV1Enum.PENDING_VEHICLE.getCode());
         Date takingOrderTime = takingOrderNodes.getCreateTime() != null ? takingOrderNodes.getCreateTime() : null;
@@ -180,7 +179,7 @@ public class ComeIntoHandler extends AbstractWaybillOrderHandler<WaybillOrderCme
         // 计算两个时间的分钟差
         Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(takingOrderTime, comeIntoTime);
         //超时
-        if (timeDiffMinutes > driverTimeoutInMillis) {
+        if (timeDiffMinutes > driverTimeout.longValue()) {
             log.info("司机到场耗时超时!司机超时限制:" + driverTimeout + "分钟,实际:" + timeDiffMinutes + "分钟");
             return true;
         }

+ 8 - 6
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/handler/TakingOrderHandler.java

@@ -10,10 +10,8 @@ import com.sckw.core.model.enums.AddressTypeEnum;
 import com.sckw.core.model.enums.CarWaybillV1Enum;
 import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.utils.CollectionUtils;
-import com.sckw.core.utils.StringUtils;
 import com.sckw.fleet.api.model.vo.RDriverVo;
 import com.sckw.fleet.api.model.vo.RTruckVo;
-import com.sckw.fleet.api.model.vo.TmsTruckAxleNumVO;
 import com.sckw.order.api.model.OrderDetailVo;
 import com.sckw.order.api.model.UpdateActualAmountParam;
 import com.sckw.transport.model.*;
@@ -97,7 +95,7 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
         BigDecimal truckLoadVolume = queryCurTruckLoadVolume(truck, tradeOrder);
 
         //1、生成物流运单
-        KwtWaybillOrder waybillOrder = createWaybillOrder(param, driver, truck);
+        KwtWaybillOrder waybillOrder = createWaybillOrder(param, driver, truck, logOrder);
 
         //2、生成物流子运单
         KwtWaybillOrderSubtask waybillOrderSubtask = createWaybillOrderSubtask(param, waybillOrder, truckLoadVolume);
@@ -314,7 +312,7 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
      *
      * @param param
      */
-    private KwtWaybillOrder createWaybillOrder(OrderCirculateTakingQueryParam param, RDriverVo driver, RTruckVo truckNo) {
+    private KwtWaybillOrder createWaybillOrder(OrderCirculateTakingQueryParam param, RDriverVo driver, RTruckVo truckNo, KwtLogisticsOrder logOrder) {
         log.info("生成物流运单,入参参数:{}", JSON.toJSONString(param));
         KwtWaybillOrder waybillOrder = new KwtWaybillOrder();
         waybillOrder.setEntId(param.getEntId());
@@ -331,6 +329,7 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
         waybillOrder.setTaskStartTime(new Date());
         waybillOrder.setCreateBy(param.getDriverId());
         waybillOrder.setUpdateBy(param.getDriverId());
+        waybillOrder.setDispatchWay(logOrder.getDispatchWay());
         waybillOrderRepository.save(waybillOrder);
         log.info("创建物流运单成功,运单ID:{}", waybillOrder.getId());
 
@@ -566,8 +565,11 @@ public class TakingOrderHandler extends AbstractWaybillOrderHandler<OrderCircula
 
     // 7. 绑定车辆
     private void driverBindTruck(KwtWaybillOrder waybillOrder) {
-        remoteFleetService.driverBindTruck(waybillOrder.getDriverId(), waybillOrder.getTruckId(), waybillOrder.getEntId());
-
+        try {
+            remoteFleetService.driverBindTruck(waybillOrder.getDriverId(), waybillOrder.getTruckId(), waybillOrder.getEntId());
+        } catch (Exception e) {
+            log.error("接单绑定车辆失败,此车辆已与此司机绑定!", e);
+        }
     }
 
 

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

@@ -279,10 +279,6 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
 
     @Override
     protected void calculateAutoDispatchScore(WaybillOrderUnloadParam param, KwtWaybillOrder waybillOrder) {
-//        if (true) {
-//            //先不执行自动派单逻辑
-//            return;
-//        }
         //查询运单装卸货地址
         List<KwtWaybillOrderAddress> addressList = waybillOrderAddressRepository.queryByWOrderId(waybillOrder.getId());
         if (CollectionUtils.isEmpty(addressList)) {
@@ -318,14 +314,16 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
     @NotNull
     private void checkFakeUnloadDistance(KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap) {
         log.info("校验司机是否虚假卸货:waybillOrderId:{}", waybillOrder.getId());
+        //供应商
+        Long supEntId = getSupplierId(waybillOrder);
         // 获取司机行为规则配置
-        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(waybillOrder.getEntId());
+        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(supEntId);
         //虚假卸货分数
         Integer fakeUnloadScore = driverRulesVO.getFakeUnloadScore();
         //虚假卸货偏离距离
         Integer distance = driverRulesVO.getFakeUnloadDistance();
         if (fakeUnloadScore <= 0 || distance <= 0) {
-            log.warn("【虚假卸货】企业{}的虚假卸货配置分数/偏差距离异常,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
+            log.warn("【虚假卸货】企业{}的虚假卸货配置分数/偏差距离异常,运单ID:{}", supEntId, waybillOrder.getId());
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【虚假卸货】配置分数/偏差距离需大于0!");
         }
         //运单应卸货地址
@@ -351,13 +349,10 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
             log.info("【虚假卸货】运单ID={},卸货地址偏差={}KM",waybillOrder.getId(), distanceKm);
             //1、更新司机分数(减分)
             fakeUnloadScore = -Math.abs(fakeUnloadScore);
-            Long supEntId = getSupplierId(waybillOrder);
             updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), fakeUnloadScore, "虚假卸货");
             //2、更新企业分数(减分)
             updateLogEntScore(waybillOrder, supEntId, fakeUnloadScore, "虚假卸货");
         }
-
-
     }
 
     /**
@@ -366,22 +361,22 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
      * @param addressMap  运单地址
      */
     protected void checkWaybillCompletionTimeout(KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap) {
+        Long supEntId = getSupplierId(waybillOrder);
         //查询司机行为规则配置
-        DriverConductRulesVO rulesVO = getDriverConductRulesByEntId(waybillOrder.getEntId());
+        DriverConductRulesVO rulesVO = getDriverConductRulesByEntId(supEntId);
         //严重超时倍数
         BigDecimal timeoutMultiple = rulesVO.getUnloadSeriousTimeoutMultiple();
         //严重超时分数
         Integer timeoutScore = rulesVO.getUnloadSeriousTimeoutScore();
         if (timeoutMultiple == null || timeoutMultiple.compareTo(BigDecimal.ZERO) <= 0 || timeoutScore <= 0) {
-            log.warn("【卸货严重超时】扣分失败,企业{}的司机卸货严重超时倍数/分数配置为空,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
+            log.warn("【卸货严重超时】扣分失败,企业{}的司机卸货严重超时倍数/分数配置为空,运单ID:{}", supEntId, waybillOrder.getId());
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【卸货严重超时】配置严重超时倍数/分数需大于0!");
         }
         //校验是否超时
-        Boolean timeOut = isTimeOut(waybillOrder, addressMap, timeoutMultiple);
+        Boolean timeOut = isTimeOut(supEntId, waybillOrder, addressMap, timeoutMultiple);
         if (timeOut) {
             //1、更新司机分数(减分)
             timeoutScore = -Math.abs(timeoutScore);
-            Long supEntId = getSupplierId(waybillOrder);
             updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), timeoutScore, "卸货严重超时");
             //2、更新企业分数(减分)
             updateLogEntScore(waybillOrder, supEntId, timeoutScore, "卸货严重超时");
@@ -394,12 +389,12 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
      * @param waybillOrder 运单
      * @param addressMap  运单地址
      */
-    protected Boolean isTimeOut(KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap, BigDecimal timeoutMultiple) {
+    protected Boolean isTimeOut(Long supEntId, KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap, BigDecimal timeoutMultiple) {
         log.info("校验司机运单完成是否超时:运单ID:{}", waybillOrder.getId());
         //运单总耗时
         Long orderTotalTimes = calOrderTotalTimes(waybillOrder);
         //平台配置的单趟总耗时
-        Integer singleTripTotalTimes = calSingleTripTotalTimes(waybillOrder, addressMap);
+        Integer singleTripTotalTimes = calSingleTripTotalTimes(supEntId, waybillOrder, addressMap);
         //计算超时阈值
         BigDecimal threshold = timeoutMultiple.compareTo(BigDecimal.ZERO) == 0 ?
                 new BigDecimal(singleTripTotalTimes) : timeoutMultiple.multiply(new BigDecimal(singleTripTotalTimes));
@@ -419,10 +414,10 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
     private Long calOrderTotalTimes(KwtWaybillOrder waybillOrder) {
         //司机接单时间
         KwtWaybillOrderNode takingOrderNodes = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.PENDING_VEHICLE.getCode());
-        Date takingOrderTime = takingOrderNodes.getCreateTime() != null ? takingOrderNodes.getCreateTime() : null;
+        Date takingOrderTime = takingOrderNodes.getCreateTime();
         //司机完成运单时间
         KwtWaybillOrderNode overOrderNodes = getNodesByOrderId(waybillOrder.getId(), CarWaybillV1Enum.COMPLETED.getCode());
-        Date overOrderTime = overOrderNodes.getCreateTime() != null ? overOrderNodes.getCreateTime() : null;
+        Date overOrderTime = overOrderNodes.getCreateTime();
         //运单总耗时(分钟)
         Long orderTotalTimes = DateUtils.calculateTimeDiffMinutes(takingOrderTime, overOrderTime);
         log.info("司机完成运单总耗时:{}", orderTotalTimes);
@@ -435,9 +430,9 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
      * @param addressMap
      * @return
      */
-    private Integer calSingleTripTotalTimes(KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap) {
+    private Integer calSingleTripTotalTimes(Long supEntId, KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap) {
         // 获取自动派单系数配置(单趟耗时 = 装货时间 + 卸货时间 + 运输时间 + 返回时间)
-        TruckDispatchCoefficientVO truckDispatchVO = getAutoTruckDispatchByEntId(waybillOrder.getEntId());
+        TruckDispatchCoefficientVO truckDispatchVO = getAutoTruckDispatchByEntId(supEntId);
         //装货时长
         Integer vehicleLoadingHours = truckDispatchVO.getVehicleLoadingHours();
         //卸货货时长
@@ -446,7 +441,7 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
         Integer vehicleAvgSpeed = truckDispatchVO.getVehicleAvgSpeed();
         if (vehicleLoadingHours <= 0 || vehicleUnloadingHours <= 0 || vehicleAvgSpeed <= 0) {
             log.warn("企业{}的司机装货时长/卸货时长/平均行驶速度配置数据异常(装货:{},卸货:{},速度:{}),运单ID:{}",
-                    waybillOrder.getEntId(), vehicleLoadingHours, vehicleUnloadingHours, vehicleAvgSpeed, waybillOrder.getId());
+                    supEntId, vehicleLoadingHours, vehicleUnloadingHours, vehicleAvgSpeed, waybillOrder.getId());
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "司机配置的装货时长/卸货时长/平均行驶速度需要大于0!");
         }
         //查询运单装卸货地址
@@ -491,14 +486,15 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
      * @param waybillOrder
      */
     private void checkContinuousUnload(KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderAddress> addressMap) {
+        Long supEntId = getSupplierId(waybillOrder);
         // 获取司机行为规则配置(连续准时卸货次数)
-        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(waybillOrder.getEntId());
+        DriverConductRulesVO driverRulesVO = getDriverConductRulesByEntId(supEntId);
         //连续卸货次数
         Integer continuousOnTimes = driverRulesVO.getContinuousOnTimeUnloadTimes();
         //连续卸货分数
         Integer continuousUnloadScore = driverRulesVO.getContinuousOnTimeUnloadScore();
         if (continuousOnTimes <= 0 || continuousUnloadScore <= 0) {
-            log.warn("【连续准时卸货】该司机无需加分,企业{}的连续按时到场配置次数/分数异常,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
+            log.warn("【连续准时卸货】该司机无需加分,企业{}的连续按时到场配置次数/分数异常,运单ID:{}", supEntId, waybillOrder.getId());
             throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【连续准时卸货】配置次数/分数需大于0!");
         }
 
@@ -513,7 +509,7 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
         List<Long> nodeIds = new ArrayList<>();
         for (KwtWaybillOrderNode orderNode : waybillOrderNodeList) {
             KwtWaybillOrder wOrder = getWaybillOrder(orderNode.getWOrderId());
-            Boolean timeOut = isTimeOut(wOrder, addressMap, BigDecimal.ZERO);
+            Boolean timeOut = isTimeOut(supEntId, wOrder, addressMap, BigDecimal.ZERO);
             if (timeOut) {
                 log.info("司机{}存在超时情况,运单id:{}", orderNode.getDriverId(), orderNode.getWOrderId());
                 return;
@@ -536,7 +532,6 @@ public class UnloadingHandler extends AbstractWaybillOrderHandler<WaybillOrderUn
         updateNode(waybillOrder, nodeIds, continuousCount, continuousUnloadScore);
 
         //2 .更新司机分数(加分)
-        Long supEntId = getSupplierId(waybillOrder);
         updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), continuousUnloadScore, "连续准时卸货");
 
         //3. 更新企业分数(加分)

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

@@ -171,4 +171,9 @@ public class KwtWaybillOrder implements Serializable {
 
     @TableField(exist = false)
     private String yearAndMonth;
+
+    /**
+     * 派车方式
+     */
+    private Integer dispatchWay;
 }

+ 238 - 45
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/task/LogisticsOrderCompletionTask.java

@@ -3,29 +3,33 @@ package com.sckw.transport.task;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.sckw.contract.api.RemoteContractService;
+import com.sckw.contract.api.feign.LogisticsScoreFeignService;
+import com.sckw.contract.api.model.dto.req.LogisticsScoreDetailFeignDto;
 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.enums.CarWaybillV1Enum;
+import com.sckw.core.model.enums.DispatchWayEnums;
 import com.sckw.core.model.enums.LogisticsOrderV1Enum;
 import com.sckw.core.utils.DateUtils;
 import com.sckw.fleet.api.RemoteFleetService;
+import com.sckw.fleet.api.model.dto.RUpdateDriverScoreDto;
+import com.sckw.fleet.api.model.vo.DriverConductRulesVO;
 import com.sckw.fleet.api.model.vo.TruckDispatchCoefficientVO;
-import com.sckw.transport.handler.CancelHandler;
-import com.sckw.transport.model.KwtLogisticsOrder;
-import com.sckw.transport.model.KwtLogisticsOrderUnit;
-import com.sckw.transport.model.KwtWaybillOrder;
-import com.sckw.transport.model.KwtWaybillOrderSubtask;
-import com.sckw.transport.model.param.WaybillOrderCancelParam;
+import com.sckw.transport.model.*;
 import com.sckw.transport.repository.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -44,16 +48,19 @@ public class LogisticsOrderCompletionTask {
     private final KwtLogisticsOrderRepository logisticsOrderRepository;
     private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
     private final KwtWaybillOrderRepository waybillOrderRepository;
-    private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;
     private final KwtLogisticsOrderUnitRepository logisticsOrderUnitRepository;
+    private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;
+    private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
-    protected RemoteFleetService remoteFleetService;
+    private RemoteFleetService remoteFleetService;
 
     @DubboReference(version = "1.0.0", group = "design", check = false)
     private RemoteContractService remoteContractService;
 
-    private final CancelHandler cancelHandler;
+    @Autowired
+    LogisticsScoreFeignService logisticsScoreFeignService;
+
 
     /**
      * 定时任务:每5分钟执行一次
@@ -63,7 +70,7 @@ public class LogisticsOrderCompletionTask {
     @Scheduled(cron = "${schedule.logistics-order-completion-cron}")
     public void process() {
         log.info("物流订单自动完成定时任务开始...");
-        
+
         try {
             // 查询状态为"完结中"的物流订单
             List<KwtLogisticsOrder> nearingCompletionOrders = logisticsOrderRepository.list(
@@ -84,17 +91,17 @@ public class LogisticsOrderCompletionTask {
                     .stream()
                     .map(KwtLogisticsOrder::getId)
                     .collect(Collectors.toList());
-            
+
             // 根据物流订单ID查询相关运单子任务
             List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByLogIds(logisticOrderIds);
-            
+
             // 按照物流订单ID分组运单子任务
             Map<Long, List<KwtWaybillOrderSubtask>> logOrderSubtasksMap = Optional.ofNullable(subtasks)
                     .orElse(Collections.emptyList()).stream().collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));
-            
+
             // 准备需要更新的物流订单列表
             List<KwtLogisticsOrder> updateLogisticOrders = new ArrayList<>();
-            
+
             // 遍历每个物流订单及其关联的运单子任务
             logOrderSubtasksMap.forEach((logOrderId, subtaskList) -> {
                 try {
@@ -137,11 +144,11 @@ public class LogisticsOrderCompletionTask {
                 log.info("没有需要更新状态的物流订单");
                 return;
             }
-            
+
             // 批量更新物流订单状态
             boolean updated = logisticsOrderRepository.updateBatchById(updateLogisticOrders);
             Set<Long> logOrderIds = updateLogisticOrders.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
-            
+
             // 记录更新结果日志
             if (updated) {
                 log.info("物流订单自动完成定时任务结束,物流订单已更新为'已完成',订单ID:{},成功:{}条", JSON.toJSONString(logOrderIds), logOrderIds.size());
@@ -163,12 +170,12 @@ public class LogisticsOrderCompletionTask {
     @Scheduled(cron = "${schedule.waybill-order-completion-cron}")
     public void processWaybillOrder() {
         log.info("超时取消运单定时任务开始...");
-
         try {
             // 查询状态为"已接单"的物流运单
             List<KwtWaybillOrder> waybillOrderOrders = waybillOrderRepository.list(
                     new LambdaQueryWrapper<KwtWaybillOrder>()
                             .eq(KwtWaybillOrder::getStatus, CarWaybillV1Enum.PENDING_VEHICLE.getCode())
+                            .eq(KwtWaybillOrder::getDispatchWay, DispatchWayEnums.AUTO_DISPATCH.getCode())
                             .eq(KwtWaybillOrder::getDelFlag, 0)
             );
             if (CollectionUtils.isEmpty(waybillOrderOrders)) {
@@ -184,35 +191,15 @@ public class LogisticsOrderCompletionTask {
             Set<Long> logisticOrderIds = waybillOrderOrders.stream().map(KwtWaybillOrder::getLOrderId).collect(Collectors.toSet());
 
             //物流订单和企业映射
-            List<KwtLogisticsOrderUnit> logisticsOrderUnits = logisticsOrderUnitRepository.queryByLOrderIdsAndUnitType(logisticOrderIds, 2);
+            List<KwtLogisticsOrderUnit> logisticsOrderUnits = logisticsOrderUnitRepository.queryByLOrderIdsAndUnitType(logisticOrderIds, 1);
             Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap = logisticsOrderUnits.stream()
                     .collect(Collectors.toMap(KwtLogisticsOrderUnit::getLOrderId, Function.identity(), (x, y) -> x));
             if (MapUtils.isEmpty(logisticsOrderAndUnitMap)) {
                 throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找的物流订单和企业映射信息!");
             }
 
-            //过滤超时的运单
-            List<KwtWaybillOrder> nearingCompletionOrders = new ArrayList<>();
-            for (Map.Entry<Long, List<KwtWaybillOrder>> entry : waybillOrderAndLogOrderMap.entrySet()) {
-                Long logisticOrderId = entry.getKey();
-                //物流运单
-                List<KwtWaybillOrder> waybillOrderList = entry.getValue();
-                //供应商企业信息
-                KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderAndUnitMap.get(logisticOrderId);
-                TruckDispatchCoefficientVO truckDispatchVO = remoteFleetService.findAutoTruckDispatchByEntId(logisticsOrderUnit.getEntId());
-                if (truckDispatchVO == null) {
-                    throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找到自动派车系数!");
-                }
-                Integer driverTimeout = truckDispatchVO.getDriverTimeoutLimit();
-                long timestampInMillis = driverTimeout * 60 * 1000;
-
-                for (KwtWaybillOrder waybillOrder : waybillOrderList) {
-                    Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(waybillOrder.getCreateTime(), new Date());
-                    if (timeDiffMinutes > timestampInMillis) {
-                        nearingCompletionOrders.add(waybillOrder);
-                    }
-                }
-            }
+            // 过滤超时的运单
+            List<KwtWaybillOrder> nearingCompletionOrders = getKwtWaybillOrders(waybillOrderAndLogOrderMap, logisticsOrderAndUnitMap);
 
             // 如果没有需要更新的物流运单,则直接返回
             if (CollectionUtils.isEmpty(nearingCompletionOrders)){
@@ -220,16 +207,222 @@ public class LogisticsOrderCompletionTask {
                 return;
             }
 
-            for (KwtWaybillOrder nearingCompletionOrder : nearingCompletionOrders) {
-                WaybillOrderCancelParam param = new WaybillOrderCancelParam();
-                param.setLogOrderId(nearingCompletionOrder.getLOrderId());
-                //执行取消接单
-                cancelHandler.handler(param);
+            List<KwtWaybillOrder> successOrders = new ArrayList<>();
+            for (KwtWaybillOrder waybillOrder : nearingCompletionOrders) {
+                try {
+                    //执行取消运单
+                    processSingleWaybillOrder(waybillOrder, logisticsOrderAndUnitMap);
+                    //异步处理
+                    handleCancelActions(waybillOrder, logisticsOrderAndUnitMap);
+                    successOrders.add(waybillOrder);
+                } catch (Exception e) {
+                    log.error("处理运单ID:{} 失败", waybillOrder.getId(), e);
+                }
             }
+
             log.info("查询到{}条状态为'已接单'的物流运单", nearingCompletionOrders.size());
         } catch (Exception e) {
             log.error("超时取消运单定时任务执行异常", e);
             throw new BusinessException("超时取消运单定时任务执行异常", e);
         }
     }
+
+    /**
+     * 过滤超时的运单
+     * @param waybillOrderAndLogOrderMap
+     * @param logisticsOrderAndUnitMap
+     * @return
+     */
+    private List<KwtWaybillOrder> getKwtWaybillOrders(Map<Long, List<KwtWaybillOrder>> waybillOrderAndLogOrderMap,
+                                                      Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        //过滤超时的运单
+        List<KwtWaybillOrder> nearingCompletionOrders = new ArrayList<>();
+
+        //供应商企业id
+        List<Long> entIds = logisticsOrderAndUnitMap.values().stream().map(KwtLogisticsOrderUnit::getEntId).distinct().collect(Collectors.toList());
+        //查询自动派车系数
+        List<TruckDispatchCoefficientVO> dispatchList = remoteFleetService.findAutoTruckDispatchByEntIds(entIds);
+        Map<Long, TruckDispatchCoefficientVO> entIdToDispatchMap = dispatchList.stream().collect(
+                Collectors.toMap(TruckDispatchCoefficientVO::getEntId, Function.identity()));
+
+        for (Map.Entry<Long, List<KwtWaybillOrder>> entry : waybillOrderAndLogOrderMap.entrySet()) {
+            Long logisticOrderId = entry.getKey();
+            //物流运单
+            List<KwtWaybillOrder> waybillOrderList = entry.getValue();
+            //供应商企业信息
+            KwtLogisticsOrderUnit unit = logisticsOrderAndUnitMap.get(logisticOrderId);
+            //自动派车系数
+            TruckDispatchCoefficientVO truckDispatchVO = entIdToDispatchMap.get(unit.getEntId());
+            if (truckDispatchVO == null) {
+                continue;
+            }
+            //司机超时限制分钟数
+            Integer driverTimeout = truckDispatchVO.getDriverTimeoutLimit();
+            for (KwtWaybillOrder waybillOrder : waybillOrderList) {
+                Long timeDiffMinutes = DateUtils.calculateTimeDiffMinutes(waybillOrder.getCreateTime(), new Date());
+                if (timeDiffMinutes > driverTimeout.longValue()) {
+                    nearingCompletionOrders.add(waybillOrder);
+                }
+            }
+        }
+        return nearingCompletionOrders;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public void processSingleWaybillOrder(KwtWaybillOrder waybillOrder, Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        try {
+            //1.获取子运单任务量
+            KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
+            if (subtask == null) {
+                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单!");
+            }
+            BigDecimal entrustAmount = subtask.getEntrustAmount();
+
+            //2.更新上游订单:更新物流订单运输量
+            updateLogOrder(waybillOrder, entrustAmount);
+
+            //3. 更新状态
+            updateStatus(waybillOrder, subtask);
+
+            //4. 生成节点轨迹
+            createNodeTrace(waybillOrder, subtask);
+        } catch (Exception e) {
+            throw e; // 抛出异常,触发Seata全局回滚
+        }
+
+    }
+
+    /**
+     * 更新上游物流订单 - 减运输量
+     * @param waybillOrder
+     * @param entrustAmount
+     * @return
+     */
+    public KwtLogisticsOrder updateLogOrder(KwtWaybillOrder waybillOrder, BigDecimal entrustAmount) {
+        KwtLogisticsOrder logOrder = logisticsOrderRepository.queryByLogisticsOrderId(waybillOrder.getLOrderId());
+        if (logOrder == null) {
+            log.info("当前物流运单无关联物流订单数据:{}", waybillOrder.getLOrderId());
+            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_LOG_ORDER, "当前物流运单无关联物流订单数据!");
+        }
+        //取消接单的物流订单的总运输量不能为空
+        if (logOrder.getEntrustAmount() == null || logOrder.getEntrustAmount().compareTo(BigDecimal.ZERO) <= 0) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_AMOUNT_ERROR, "已接单物订单的总运单量不能为空或0!");
+        }
+        logOrder.setEntrustAmount(logOrder.getEntrustAmount().subtract(entrustAmount));
+        logisticsOrderRepository.updateById(logOrder);
+        log.info("更新上游物流订单运输量成功, 物流订单ID:{}", logOrder.getId());
+        return logOrder;
+    }
+
+    // 更新状态
+    public void updateStatus(KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask subtask) {
+        // 修改运单状态
+        waybillOrder.setStatus(CarWaybillV1Enum.CANCELLED.getCode());
+        waybillOrderRepository.updateById(waybillOrder);
+
+        //修改子运单状态
+        subtask.setStatus(CarWaybillV1Enum.CANCELLED.getCode());
+        waybillOrderSubtaskRepository.updateById(subtask);
+    }
+
+    // 生成节点轨迹
+    public void createNodeTrace(KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask subtask) {
+        if (waybillOrder == null) {
+            return;
+        }
+        KwtWaybillOrderNode node = new KwtWaybillOrderNode();
+        node.setWOrderId(waybillOrder.getId());
+        node.setWSubtaskId(subtask.getId());
+        node.setOrderStatus(waybillOrder.getStatus());
+        node.setTruckId(waybillOrder.getTruckId());
+        node.setTruckNo(waybillOrder.getTruckNo());
+        node.setDriverId(waybillOrder.getDriverId());
+        node.setDriverName(waybillOrder.getDriverName());
+        node.setRemark("司机[" + waybillOrder.getDriverName() + "]取消订单");
+        waybillOrderNodeRepository.save(node);
+        log.info("记录取消接单节点轨迹成功,节点ID:{}", node.getId());
+    }
+
+
+
+    @Async
+    public void handleCancelActions(KwtWaybillOrder waybillOrder, Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        try {
+            unbindTruck(waybillOrder);
+            checkArrivedLoadingPointTimeout(waybillOrder, logisticsOrderAndUnitMap);
+        } catch (Exception e) {
+            log.error("异步处理取消后动作失败", e);
+        }
+    }
+
+
+    /**
+     * 解绑车辆
+     * @param waybillOrder
+     */
+    private void unbindTruck(KwtWaybillOrder waybillOrder) {
+        remoteFleetService.unbindTruck(waybillOrder.getEntId(), waybillOrder.getDriverId());
+        log.info("解绑完成,解绑司机与车辆关系,运单id:{},企业id:{},司机id:{}", waybillOrder.getId(), waybillOrder.getEntId(), waybillOrder.getDriverId());
+    }
+
+    /**
+     * 司机超时到达装货点扣分
+     * @param waybillOrder
+     */
+    private void checkArrivedLoadingPointTimeout(KwtWaybillOrder waybillOrder, Map<Long, KwtLogisticsOrderUnit> logisticsOrderAndUnitMap) {
+        KwtLogisticsOrderUnit logisticsOrderUnit = logisticsOrderAndUnitMap.get(waybillOrder.getLOrderId());
+        //供应商id
+        Long supEntId = logisticsOrderUnit.getEntId();
+        DriverConductRulesVO driverRulesVO = remoteFleetService.findDriverConductRulesByEntId(logisticsOrderUnit.getEntId());
+        if (driverRulesVO == null) {
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "未找到司机行为规则数据!");
+        }
+        Integer notOnTimeArrive = driverRulesVO.getNotOnTimeArriveScore();
+        if (notOnTimeArrive <= 0) {
+            log.warn("【司机未按时到场】司机扣分失败,企业{}的司机未按时到场分数配置异常,运单ID:{}", waybillOrder.getEntId(), waybillOrder.getId());
+            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "【司机未按时到场】分数配置需大于0!");
+        }
+        //1、更新司机分数(减分)
+        notOnTimeArrive = -Math.abs(notOnTimeArrive);
+        updateDriverScore(supEntId, waybillOrder.getEntId(), waybillOrder.getDriverId(), notOnTimeArrive, "司机未按时到场(超时)");
+
+        //2、更新企业分数(减分)
+        updateLogEntScore(waybillOrder, supEntId, notOnTimeArrive, "司机未按时到场");
+
+    }
+
+    /**
+     * 修改司机评分
+     * @param supeEntId
+     * @param entId
+     * @param driverId
+     * @param score
+     */
+    public void updateDriverScore(Long supeEntId, Long entId, Long driverId, Integer score, String action) {
+        RUpdateDriverScoreDto dto = new RUpdateDriverScoreDto();
+        dto.setSupEntId(supeEntId);
+        dto.setLogEntId(entId);
+        dto.setDriverId(driverId);
+        dto.setScore(BigDecimal.valueOf(score));
+        dto.setAction(action);
+
+        remoteFleetService.updateDriverScoreByEntId(dto);
+    }
+
+    /**
+     * 更新企业评分
+     * @param waybillOrder
+     * @param supplierId
+     * @param score
+     */
+    public void updateLogEntScore(KwtWaybillOrder waybillOrder, Long supplierId, Integer score, String remark) {
+        LogisticsScoreDetailFeignDto detailDto = new LogisticsScoreDetailFeignDto();
+        detailDto.setProviderEntId(supplierId);
+        detailDto.setLogisticsEntId(waybillOrder.getEntId());
+        detailDto.setInfluenceBy(waybillOrder.getDriverId());
+        detailDto.setAction(remark);
+        detailDto.setScoreChange(BigDecimal.valueOf(score));
+        logisticsScoreFeignService.updateLogisticsScore(detailDto);
+    }
+
 }