Selaa lähdekoodia

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

donglang 1 kuukausi sitten
vanhempi
commit
928bbf298a
16 muutettua tiedostoa jossa 349 lisäystä ja 150 poistoa
  1. 53 12
      sckw-common/sckw-common-log/src/main/java/com/sckw/log/aspect/LogInfoAspect.java
  2. 2 2
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreDetailMapper.java
  3. 2 2
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreMapper.java
  4. 1 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java
  5. 1 1
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java
  6. 1 1
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/KwoTradeOrder.java
  7. 7 1
      sckw-modules/sckw-order/src/main/java/com/sckw/order/model/dto/OrderListResDTO.java
  8. 21 48
      sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java
  9. 10 4
      sckw-modules/sckw-order/src/main/resources/mapper/KwoTradeOrderMapper.xml
  10. 1 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/KwfTruckTraceController.java
  11. 18 4
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/KwfTruckTraceReplayReq.java
  12. 5 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/VehiclesTrajectoryReq.java
  13. 25 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/KwfTruckTraceReplayVo.java
  14. 2 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderRepository.java
  15. 23 20
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/VehicleExceptionService.java
  16. 177 51
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/kwfTruckTraceService.java

+ 53 - 12
sckw-common/sckw-common-log/src/main/java/com/sckw/log/aspect/LogInfoAspect.java

@@ -62,6 +62,7 @@ public class LogInfoAspect {
         Date startTime = new Date();
         String targetName = p.getTarget().getClass().getName();
         String methodName = p.getSignature().getName();
+        String callerMethodName = getCallerMethodName();
         Object[] args = p.getArgs();
         Stream<?> stream = ArrayUtils.isEmpty(args) ? Stream.empty() : Arrays.stream(args);
         List<Object> logArgs = stream
@@ -81,11 +82,23 @@ public class LogInfoAspect {
             Date endTime = new Date();
             long time = endTime.getTime() - startTime.getTime();
             Boolean slowRequest = (time > 1500L);
-            log.info("{}.{}," +
-                            "param={}," +
-                            "result={}," +
-                            "exception={}," +
-                            "[{}->{}],slowRequest{}=[{}]", targetName, methodName,
+
+            if (exception != null && !exception.isEmpty()) {
+                log.error("\nAPI调用异常 - {}.{} \n调用方 - {} \n参数:{} \n结果:{} \n异常:{} \n耗时:{}ms \n慢请求:{}",
+                        targetName, methodName, callerMethodName, param, JSON.toJSONString(result), exception, time, slowRequest);
+            } else if (slowRequest) {
+                log.warn("\nAPI慢请求 - {}.{} \n调用方 - {} \n参数:{} \n结果:{} \n耗时:{}ms \n慢请求:{}",
+                        targetName, methodName, callerMethodName, param, JSON.toJSONString(result), time, slowRequest);
+            } else {
+                log.info("\nAPI调用成功 - {}.{} \n调用方 - {} \n参数:{} \n结果:{} \n耗时:{}ms",
+                        targetName, methodName, callerMethodName, param, JSON.toJSONString(result), time);
+            }
+
+            // 原始详细日志保留为debug级别
+            log.debug("\n接口调用 - {}.{} \n调用方 - {}\nparam={}\nresult={}\nexception={}\n[{}->{}],slowRequest{}=[{}]",
+                    targetName,
+                    methodName,
+                    callerMethodName,
                     param,
                     JSON.toJSONString(result),
                     exception,
@@ -97,15 +110,44 @@ public class LogInfoAspect {
         return result;
     }
 
+    /**
+     * 获取调用方的方法名称
+     * @return 调用方方法名称
+     */
+    private String getCallerMethodName() {
+        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+        // 查找调用链中属于业务代码的部分
+        for (int i = 0; i < stackTrace.length; i++) {
+            StackTraceElement element = stackTrace[i];
+            // 找到LogInfoAspect类的调用点
+            if (element.getClassName().equals(LogInfoAspect.class.getName()) && 
+                ("cutController".equals(element.getMethodName()) || "around".equals(element.getMethodName()))) {
+                // 继续向上查找真正的调用者
+                for (int j = i + 1; j < stackTrace.length; j++) {
+                    StackTraceElement caller = stackTrace[j];
+                    // 排除Java内置类和框架类
+                    if (!caller.getClassName().startsWith("java.") && 
+                        !caller.getClassName().startsWith("org.springframework.") &&
+                        !caller.getClassName().startsWith("org.aspectj.") &&
+                        !caller.getClassName().equals(LogInfoAspect.class.getName())) {
+                        return caller.getClassName() + "." + caller.getMethodName();
+                    }
+                }
+            }
+        }
+        return "Unknown";
+    }
+
     @Pointcut("execution(* com.sckw.*.service..*.*(..))")
     public void cutService() {
     }
 
     @AfterThrowing(pointcut = "cutService()", throwing = "e")
-    public void doAfterThrowing(JoinPoint point, Throwable e) throws Throwable {
+public void doAfterThrowing(JoinPoint point, Throwable e) throws Throwable {
         Date startTime = new Date();
         String targetName = point.getTarget().getClass().getName();
         String methodName = point.getSignature().getName();
+        String callerMethodName = getCallerMethodName();
         //获取用户请求方法的参数并序列化为JSON格式字符串
         StringBuilder params = new StringBuilder();
         if (point.getArgs() != null && point.getArgs().length > 0) {
@@ -119,15 +161,14 @@ public class LogInfoAspect {
 
         Date endTime = new Date();
         long time = endTime.getTime() - startTime.getTime();
-        log.error("{}.{}," +
-                        "param={}," +
-                        "exception={}," +
-                        "[{}->{}]=[{}]", targetName, methodName,
+        log.error("\nSERVICE异常 - {}.{} \n调用方 - {} \n参数:{} \n异常:{} \n耗时:{}ms \n时间:[{}->{}]",
+                targetName, methodName,
+                callerMethodName,
                 params,
                 e.getMessage(),
+                time,
                 DateFormatUtils.format(startTime, TIME_PATTERN),
-                DateFormatUtils.format(endTime, TIME_PATTERN),
-                time);
+                DateFormatUtils.format(endTime, TIME_PATTERN));
     }
 
 }

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

@@ -1,7 +1,7 @@
 package com.sckw.fleet.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.sckw.fleet.model.KwcDriverScoreDetail;
+import com.sckw.fleet.model.KwfDriverScoreDetail;
 import org.apache.ibatis.annotations.Mapper;
 
 /**
@@ -10,6 +10,6 @@ import org.apache.ibatis.annotations.Mapper;
  * @Description: 司机评分明细Mapper接口
  */
 @Mapper
-public interface KwfDriverScoreDetailMapper extends BaseMapper<KwcDriverScoreDetail> {
+public interface KwfDriverScoreDetailMapper extends BaseMapper<KwfDriverScoreDetail> {
 
 }

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

@@ -1,7 +1,7 @@
 package com.sckw.fleet.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.sckw.fleet.model.KwcDriverScore;
+import com.sckw.fleet.model.KwfDriverScore;
 import org.apache.ibatis.annotations.Mapper;
 
 /**
@@ -10,5 +10,5 @@ import org.apache.ibatis.annotations.Mapper;
  * @Description: 司机评分Mapper接口
  */
 @Mapper
-public interface KwfDriverScoreMapper extends BaseMapper<KwcDriverScore> {
+public interface KwfDriverScoreMapper extends BaseMapper<KwfDriverScore> {
 }

+ 1 - 1
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwcDriverScore.java → sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
 @EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
-public class KwcDriverScore extends BaseModel
+public class KwfDriverScore extends BaseModel
 {
     private static final long serialVersionUID = 1L;
 

+ 1 - 1
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwcDriverScoreDetail.java → sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java

@@ -16,7 +16,7 @@ import java.math.BigDecimal;
 @EqualsAndHashCode(callSuper = true)
 @Data
 @Accessors(chain = true)
-public class KwcDriverScoreDetail extends BaseModel {
+public class KwfDriverScoreDetail extends BaseModel {
     private static final long serialVersionUID = 1L;
 
     /** 评分主键id */

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

@@ -67,7 +67,7 @@ public class KwoTradeOrder extends BaseModel implements Serializable {
     private BigDecimal price;
 
     /**
-     * 交易方式(预付款、货到付款)
+     * 签约方式 1线上  2线下
      */
     private String trading;
 

+ 7 - 1
sckw-modules/sckw-order/src/main/java/com/sckw/order/model/dto/OrderListResDTO.java

@@ -112,6 +112,9 @@ public class OrderListResDTO {
      * 实际交付量
      */
     private BigDecimal actualAmount;
+    private BigDecimal loadAmount;
+    private BigDecimal unloadAmount;
+    private String deliveryTypeLabel;
 
     /**
      * 计划开始时间
@@ -142,7 +145,10 @@ public class OrderListResDTO {
      */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date createTime;
-
+    /**
+     * 计费方式
+     */
+    private Integer chargeType;
     /**
      * 装货地址信息
      */

+ 21 - 48
sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java

@@ -18,6 +18,7 @@ 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;
@@ -681,7 +682,6 @@ public class KwoTradeOrderService {
             throw new BusinessException("不存在该订单!");
         }
         Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.TRADE_TYPE.getType(), DictTypeEnum.PICKUP_TYPE.getType(), DictTypeEnum.DELIVERY_TYPE.getType(), DictTypeEnum.TORDER_SOURCE.getType(), DictTypeEnum.TORDER_STATUS.getType(), DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.TAX_RATE.getType(), DictTypeEnum.TORDER_UNIT_TYPE.getType(), DictTypeEnum.TORDER_ADDRESS_TYPE.getType(), DictTypeEnum.ADDRESS_TYPE.getType(), DictTypeEnum.CONSIGNMENT_WAY.getType(), DictTypeEnum.CHARGING_TYPE.getType()));
-        Map<String, String> tradeMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
         Map<String, String> pickupMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
         Map<String, String> deleveryMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
         Map<String, String> sourceMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
@@ -693,7 +693,6 @@ public class KwoTradeOrderService {
         Map<String, String> consignmentWayMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
         Map<String, String> orderUnitMap, orderAddressMap, addressMap;
         if (CollUtil.isNotEmpty(dict)) {
-            tradeMap = dict.get(DictTypeEnum.TRADE_TYPE.getType());
             pickupMap = dict.get(DictTypeEnum.CONSIGNMENT_WAY.getType());
             deleveryMap = dict.get(DictTypeEnum.DELIVERY_TYPE.getType());
             sourceMap = dict.get(DictTypeEnum.TORDER_SOURCE.getType());
@@ -715,7 +714,17 @@ public class KwoTradeOrderService {
         OrderDetailRes detail = BeanUtil.copyProperties(order, OrderDetailRes.class);
         UserCacheResDto createUser = remoteSystemService.queryUserCacheById(detail.getCreateBy());
         EntCacheResDto ent = remoteSystemService.queryEntCacheById(detail.getEntId());
-        detail.setFirmName(Objects.isNull(ent) ? null : ent.getFirmName()).setCreateByName(Objects.isNull(createUser) ? null : createUser.getName()).setTradingLabel(CollUtil.isNotEmpty(tradeMap) ? tradeMap.get(detail.getTrading()) : null).setPickupTypeLabel(CollUtil.isNotEmpty(pickupMap) ? pickupMap.get(detail.getPickupType()) : null).setDeliveryTypeLabel(CollUtil.isNotEmpty(deleveryMap) ? deleveryMap.get(detail.getDeliveryType()) : null).setSourceLabel(CollUtil.isNotEmpty(sourceMap) ? sourceMap.get(detail.getSource()) : null).setStatusLabel(CollUtil.isNotEmpty(statusMap) ? statusMap.get(String.valueOf(detail.getStatus())) : null).setChargeTypeLabel(CollUtil.isNotEmpty(chargeTypeMap) ? chargeTypeMap.get(String.valueOf(detail.getChargeType())) : null).setConsignmentWayLabel(CollUtil.isNotEmpty(consignmentWayMap) ? consignmentWayMap.get(String.valueOf(detail.getConsignmentWay())) : null);
+        String trading = order.getTrading();
+        if (StrUtil.equals(trading, "1")) {
+            detail.setTradingLabel("线上支付");
+        } else {
+            detail.setTradingLabel("线下支付");
+        }
+        detail.setFirmName(Objects.isNull(ent) ? null : ent.getFirmName()).setCreateByName(Objects.isNull(createUser) ? null : createUser.getName());
+        detail.setPickupTypeLabel(CollUtil.isNotEmpty(pickupMap) ? pickupMap.get(detail.getPickupType()) : null).setDeliveryTypeLabel(CollUtil.isNotEmpty(deleveryMap) ? deleveryMap.get(detail.getDeliveryType()) : null);
+        detail.setSourceLabel(CollUtil.isNotEmpty(sourceMap) ? sourceMap.get(detail.getSource()) : null).setStatusLabel(CollUtil.isNotEmpty(statusMap) ? statusMap.get(String.valueOf(detail.getStatus())) : null);
+        detail.setChargeTypeLabel(CollUtil.isNotEmpty(chargeTypeMap) ? chargeTypeMap.get(String.valueOf(detail.getChargeType())) : null);
+        detail.setConsignmentWayLabel(DictEnum.getLabel(DictTypeEnum.CONSIGNMENT_WAY.getType(), String.valueOf(detail.getConsignmentWay())));
         if (Objects.equals(detail.getChargeType(), 1)) {//按装货量
             detail.setDealAmount(detail.getLoadAmount());
         } else {
@@ -736,16 +745,6 @@ public class KwoTradeOrderService {
                     detail.setDealMoney(NumberUtil.mul(orderGoods.getUnitPrice(), detail.getUnloadAmount()));
                 }
 
-                //商品辅助单位信息
-//                List<GoodsUnitDetailRes> assistUnit = kwoTradeOrderGoodsUnitService.findGoodsUnitDetail(id);
-//                if (CollUtil.isNotEmpty(assistUnit)) {
-//                    Map<String, String> finalUnitMap = unitMap;
-//                    assistUnit.forEach(e -> {
-//                        e.setFromUnitName(CollUtil.isNotEmpty(finalUnitMap) ? finalUnitMap.get(e.getFromUnit()) : null);
-//                        e.setToUnitName(CollUtil.isNotEmpty(finalUnitMap) ? finalUnitMap.get(e.getToUnit()) : null);
-//                    });
-//                }
-//                detail.setAssistUnit(assistUnit);
             }
         }
 
@@ -1601,13 +1600,13 @@ public class KwoTradeOrderService {
             deliveryMap = CollUtil.isNotEmpty(dict.get(DictTypeEnum.SETTLEMENT_WAY.getType())) ? dict.get(DictTypeEnum.SETTLEMENT_WAY.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
             pickupMap = CollUtil.isNotEmpty(dict.get(DictTypeEnum.CONSIGNMENT_WAY.getType())) ? dict.get(DictTypeEnum.CONSIGNMENT_WAY.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
             sourceMap = CollUtil.isNotEmpty(dict.get(DictTypeEnum.TORDER_SOURCE.getType())) ? dict.get(DictTypeEnum.TORDER_SOURCE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
+
         } else {
             tradeMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
             deliveryMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
             pickupMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
             sourceMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
         }
-
         list.forEach(e -> {
             //装货地址
             List<KwoTradeOrderAddress> loadAddresses = kwoTradeOrderAddressService.findByAddress(e.getTOrderId(), AddressTypeEnum.SHIPMENT.getCode());
@@ -1624,31 +1623,8 @@ public class KwoTradeOrderService {
             UserCacheResDto userCache = userMap.get(e.getCreateBy());
 
             OrderListResVO vo = BeanUtil.copyProperties(e, OrderListResVO.class);
-            vo.setStatusLabel(TradeOrderStatusEnum.getMsg(e.getStatus()))
-                    .setTradingLabel(tradeMap.get(e.getTrading()))
-                    .setTrading(tradeMap.get(e.getTrading()))
-                    .setDeliveryTypeLabel(deliveryMap.get(e.getDeliveryType()))
-                    .setDeliveryType(deliveryMap.get(e.getDeliveryType()))
-                    .setPickupTypeLabel(pickupMap.get(e.getPickupType()))
-                    .setSourceLabel(sourceMap.get(e.getSource()))
-                    .setSource(sourceMap.get(e.getSource()))
-                    .setContractName(Objects.isNull(contract) ? null : contract.getContactName())
-                    .setContractSigningWay(Objects.isNull(contract) ? null : contract.getSigningWayName())
-                    .setGoodsName(Objects.isNull(goods) ? null : goods.getName())
-                    .setGoodsSpec(Objects.isNull(goods) ? null : goods.getSpec())
-                    .setGoodsTaxRate(Objects.isNull(goods) ? null : goods.getTaxRate())
-                    .setGoodsThumb(Objects.isNull(goods) ? null : goods.getThumb())
-                    .setWaitEntrustAmount(setScale(getWaitEntrustAmount(e.getAmount(), e.getEntrustAmount())))
-                    .setActualPrice(actualAmount.multiply(unitPrice).setScale(2, RoundingMode.HALF_UP))
-                    .setUnitPrice(setScale(e.getUnitPrice()))
-                    .setPrice(setScale(e.getPrice()))
-                    .setUnit(e.getUnit())
-                    .setUnitLabel(unitType == null ? e.getUnit() : (unitType.get(e.getUnit()) == null ? e.getUnit() : unitType.get(e.getUnit()).getLabel()))
-                    .setAmount(setScale(vo.getAmount()))
-                    .setEntrustAmount(setScale(e.getEntrustAmount()))
-                    .setActualAmount(setScale(e.getActualAmount()))
-                    .setCreateByName(Objects.isNull(userCache) ? null : userCache.getName())
-            ;
+            vo.setStatusLabel(TradeOrderStatusEnum.getMsg(e.getStatus())).setTradingLabel(tradeMap.get(e.getTrading())).setTrading(tradeMap.get(e.getTrading())).setDeliveryType(deliveryMap.get(e.getDeliveryType())).setPickupTypeLabel(pickupMap.get(e.getPickupType())).setSourceLabel(sourceMap.get(e.getSource())).setSource(sourceMap.get(e.getSource())).setContractName(Objects.isNull(contract) ? null : contract.getContactName()).setContractSigningWay(Objects.isNull(contract) ? null : contract.getSigningWayName()).setGoodsName(Objects.isNull(goods) ? null : goods.getName()).setGoodsSpec(Objects.isNull(goods) ? null : goods.getSpec()).setGoodsTaxRate(Objects.isNull(goods) ? null : goods.getTaxRate()).setGoodsThumb(Objects.isNull(goods) ? null : goods.getThumb()).setWaitEntrustAmount(setScale(getWaitEntrustAmount(e.getAmount(), e.getEntrustAmount()))).setActualPrice(actualAmount.multiply(unitPrice).setScale(2, RoundingMode.HALF_UP)).setUnitPrice(setScale(e.getUnitPrice())).setPrice(setScale(e.getPrice())).setUnit(e.getUnit()).setUnitLabel(unitType == null ? e.getUnit() : (unitType.get(e.getUnit()) == null ? e.getUnit() : unitType.get(e.getUnit()).getLabel())).setAmount(setScale(vo.getAmount())).setEntrustAmount(setScale(e.getEntrustAmount())).setActualAmount(setScale(e.getActualAmount())).setCreateByName(Objects.isNull(userCache) ? null : userCache.getName());
+            vo.setDeliveryTypeLabel(DictEnum.getLabel(DictTypeEnum.LOAD_UNLOAD_WAY.getType(), String.valueOf(e.getChargeType())));
             loadAddress.ifPresent(d -> {
                 vo.setLoadName(d.getName());
                 vo.setLoadAddress(d.getCityName() + " " + d.getDetailAddress());
@@ -1675,11 +1651,7 @@ public class KwoTradeOrderService {
     public TradeOrderListSelectDTO buildSelectParam(TradeOrderListStatisticParam params) {
         TradeOrderListSelectDTO dto = BeanUtil.copyProperties(params, TradeOrderListSelectDTO.class);
         EntTypeResDto entTypeResDto = remoteSystemService.queryEntTypeById(LoginUserHolder.getEntId());
-        dto.setEntId(LoginUserHolder.getEntId())
-                .setManager(LoginUserHolder.isManager())
-                .setEntType(Objects.nonNull(entTypeResDto) ? entTypeResDto.getType() : null)
-                .setEntList(LoginUserHolder.getChildEntList())
-                .setIsMain(LoginUserHolder.getIsMain());
+        dto.setEntId(LoginUserHolder.getEntId()).setManager(LoginUserHolder.isManager()).setEntType(Objects.nonNull(entTypeResDto) ? entTypeResDto.getType() : null).setEntList(LoginUserHolder.getChildEntList()).setIsMain(LoginUserHolder.getIsMain());
         //装卸货地址
         String loadCode = params.getShippingAddressCode();
         if (StringUtils.isNotBlank(loadCode) && Objects.nonNull(params.getShippingAddressLevel())) {
@@ -2061,8 +2033,7 @@ public class KwoTradeOrderService {
         unitList.forEach(e -> {
             KwoTradeOrderUnit unit = BeanUtil.copyProperties(e, KwoTradeOrderUnit.class);
             unit.setId(new IdWorker(1).nextId());
-            unit.setTOrderId(order.getId())
-                    .setTOrderNo(order.getTOrderNo()).setTopEntId(e.getEntId());
+            unit.setTOrderId(order.getId()).setTOrderNo(order.getTOrderNo()).setTopEntId(e.getEntId());
             unit.setUnitType(StrUtil.equals(e.getUnitType(), "1") ? "2" : "1");//贸易合同和订单的单位类型相反
             list.add(unit);
         });
@@ -2095,12 +2066,14 @@ public class KwoTradeOrderService {
             throw new BusinessException("当前贸易订单不存在交易商品");
         }
         order.setUnit(goodsInfoDto.getUnit());
-        order.setPrice(goodsInfoDto.getPrice());
-        order.setTrading(String.valueOf(tradeContractResDto.getTrading()));
         order.setPickupType(String.valueOf(tradeContractResDto.getConsignment()));//来源于合同约束的托运方式
         order.setDeliveryType("");
+        order.setTrading(String.valueOf(tradeContractResDto.getSigningWay()));//签约方式
+        order.setPrice(NumberUtil.mul(tradeOrderParam.getAmount(), goodsInfoDto.getPrice()));//总金额
         order.setActualAmount(new BigDecimal("0"));
         order.setAssociateStatement(0);
+        order.setLoadAmount(new BigDecimal("0"));
+        order.setUnloadAmount(new BigDecimal("0"));
         order.setChargeType(tradeContractResDto.getUnloadWay());
         order.setConsignmentWay(tradeContractResDto.getConsignment());
         order.setEntId(LoginUserHolder.getEntId()).setTOrderNo(getOrderNo()).setAmount(tradeOrderParam.getAmount()).setStartTime(DateUtils.localDateToDateStart(tradeOrderParam.getStartTime())).setEndTime(DateUtils.localDateToDateEnd(tradeOrderParam.getEndTime())).setSource(OrderSourceEnum.PURCHASE.getType()).setStatus(TradeOrderStatusEnum.AUDIT.getCode()).setRemark(tradeOrderParam.getRemark());

+ 10 - 4
sckw-modules/sckw-order/src/main/resources/mapper/KwoTradeOrderMapper.xml

@@ -22,6 +22,9 @@
         <result column="entrustAmount" property="entrustAmount"/>
         <result column="actualAmount" property="actualAmount"/>
         <result column="startTime" property="startTime"/>
+        <result column="chargeType" property="chargeType"/>
+        <result column="unloadAmount" property="unloadAmount"/>
+        <result column="loadAmount" property="loadAmount"/>
         <result column="endTime" property="endTime"/>
         <result column="remark" property="remark"/>
         <result column="unit" property="unit"/>
@@ -61,6 +64,9 @@
         a.price          AS price,
         a.amount         AS amount,
         a.entrust_amount AS entrustAmount,
+        a.charge_type    AS chargeType,
+        a.load_amount    AS loadAmount,
+        a.unload_amount  AS unloadAmount,
         a.actual_amount  AS actualAmount,
         a.start_time     AS startTime,
         a.end_time       AS endTime,
@@ -458,14 +464,14 @@
                         <if test="query.entList != null and query.entList.size() > 0  and query.entType != null">
                             <if test="query.entType == 1">
                                 and
-                                e.top_ent_id in
+                                    e.top_ent_id in
                                 <foreach collection="query.entList" item="authUserId" open="(" close=")" separator=",">
                                     #{authUserId}
                                 </foreach>
                             </if>
                             <if test="query.entType == 2">
                                 and
-                                d.top_ent_id in
+                                    d.top_ent_id in
                                 <foreach collection="query.entList" item="authUserId" open="(" close=")" separator=",">
                                     #{authUserId}
                                 </foreach>
@@ -484,10 +490,10 @@
                     </if>
                 </when>
             </choose>
-            <if test="query.buyEntId !=null">
+            <if test="query.buyEntId != null">
                 and d.ent_id = #{query.buyEntId}
             </if>
-            <if test="query.saleEntId !=null">
+            <if test="query.saleEntId != null">
                 and e.ent_id = #{query.saleEntId}
             </if>
             <if test="query.status != null">

+ 1 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/KwfTruckTraceController.java

@@ -74,7 +74,7 @@ public class KwfTruckTraceController {
      */
     @PostMapping("/replay")
     @Operation(summary = "轨迹回放")
-    public BaseResult<PageDataResult<KwfTruckTraceReplayVo>> findPage(@RequestBody KwfTruckTraceReplayReq req )  {
+    public BaseResult<PageDataResult<KwfTruckTraceReplayVo>> findPage(@RequestBody @Valid KwfTruckTraceReplayReq req )  {
 
         return BaseResult.success( kwfTruckTraceService.findPage(req));
     }

+ 18 - 4
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/KwfTruckTraceReplayReq.java

@@ -2,6 +2,8 @@ package com.sckw.transport.model.param;
 
 import com.sckw.core.web.request.PageReq;
 import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -18,17 +20,29 @@ public class KwfTruckTraceReplayReq extends PageReq implements Serializable {
     @Serial
     private static final long serialVersionUID = -34385531213284288L;
     /**
-     * 任务创建时间下限
+     * 任务创建开始时间 yyyy-MM-dd
      */
-    @Schema(description = "任务创建时间下限")
+    @Schema(description = "任务创建开始时间 yyyy-MM-dd")
+    @NotBlank(message = "任务创建开始时间不能为空")
     private String startTime;
     /**
-     * 任务开始时间上限
+     * 任务创建结束时间 yyyy-MM-dd
      */
-    @Schema(description = "任务创建时间上限")
+    @Schema(description = "任务创建结束时间 yyyy-MM-dd")
+    @NotBlank(message = "任务创建结束时间不能为空")
     private String endTime;
     /**
      * 车牌号
      */
+    @Schema(description = "车牌号")
     private String truckNo;
+
+    @Schema(description = "承运单位ID")
+    private Long carrierEntId;
+    @Schema(description = "物流订单号")
+    private String logisticOrderNo;
+
+
+    @Schema(description = "排序类型(1-按时间排序,2-耗时排序,3-异常排序)", example = "1")
+    private Integer sortType = 1;
 }

+ 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;
     /**
      * 运单状态
      */

+ 25 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/KwfTruckTraceReplayVo.java

@@ -20,6 +20,11 @@ public class KwfTruckTraceReplayVo implements Serializable {
      */
     @Schema(description = "运单id")
     private Long orderId;
+    /**
+     * 物流订单号
+     */
+    @Schema(description = "物流订单号")
+    private String logOrderNo;
     /**
      * 运单编号
      */
@@ -35,6 +40,11 @@ public class KwfTruckTraceReplayVo implements Serializable {
      */
     @Schema(description = "司机手机号")
     private String phone;
+    /**
+     * 车牌号
+     */
+    @Schema(description = "车牌号")
+    private String truckNo;
     /**
      * 承运单位
      */
@@ -43,7 +53,7 @@ public class KwfTruckTraceReplayVo implements Serializable {
     /**
      * 状态
      */
-    @Schema(description = "状态")
+    @Schema(description = "状态 0-任务中 1-已结束")
     private String status;
 
     /**
@@ -82,4 +92,18 @@ public class KwfTruckTraceReplayVo implements Serializable {
      */
     @Schema(description = "告警记录数")
     private String warningCount;
+
+    @Schema(description = "异常数量")
+    private Integer exceptionCount;
+
+    @Schema(description = "任务耗时(分钟)")
+    private Long taskDuration;
+
+    @Schema(description = "任务进行中的实时经度")
+    private String longitude;
+    /**
+     * 任务进行中的实时纬度
+     */
+    @Schema(description = "任务进行中的实时纬度")
+    private String latitude;
 }

+ 2 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderRepository.java

@@ -53,12 +53,13 @@ public class KwtWaybillOrderRepository extends ServiceImpl<KwtWaybillOrderMapper
 
     }
 
-    public Page<KwtWaybillOrder> findPage(String truckNo,int pageNum, int pageSize, Date beforeDate, Date date) {
+    public Page<KwtWaybillOrder> findPage(Set<Long> wayOrderIds,String truckNo,int pageNum, int pageSize, Date beforeDate, Date date) {
         Page<KwtWaybillOrder> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                 .ge(KwtWaybillOrder::getCreateTime, beforeDate)
                 .le(KwtWaybillOrder::getCreateTime, date)
                 .eq(KwtWaybillOrder::getDelFlag, 0)
+                .in(CollectionUtils.isNotEmpty(wayOrderIds),KwtWaybillOrder::getLOrderId, wayOrderIds)
                 .eq(StringUtils.isNotBlank(truckNo),KwtWaybillOrder::getTruckNo, truckNo)
                 .orderByDesc(KwtWaybillOrder::getCreateTime);
         return page(page,wrapper);

+ 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

+ 177 - 51
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;
@@ -122,18 +124,18 @@ public class kwfTruckTraceService {
 
     public PageDataResult<KwfTruckTraceReplayVo> findPage(KwfTruckTraceReplayReq req) {
         log.info("查询历轨迹回放参数:{}", req);
-        if (StringUtils.isBlank(req.getTruckNo())){
+
+        Date startDate = getStartDate(req.getStartTime());
+        Date endDate = getEndDate(req.getEndTime());
+        // 前置条件:根据承运单位和托运单位筛选出符合条件的运单ID
+        MapVehicleQueryReq queryReq = new MapVehicleQueryReq();
+        queryReq.setCarrierEntId(req.getCarrierEntId());
+        queryReq.setLogisticOrderNo(req.getLogisticOrderNo());
+        Set<Long> wayOrderIds = getWayOrderIds(queryReq);
+        if (CollectionUtils.isEmpty(wayOrderIds) && (StringUtils.isNotBlank(req.getLogisticOrderNo()) || Objects.nonNull(req.getCarrierEntId()))) {
             return PageDataResult.empty(req.getPageNum(), req.getPageSize());
         }
-        Date date = new Date();
-        if (StringUtils.isNotBlank(req.getStartTime())){
-            date = DateUtils.formatDate(req.getStartTime());
-        }
-        Date beforeDate = DateUtils.addDateDays(date, -30);
-        if (StringUtils.isNotBlank(req.getEndTime())){
-            beforeDate = DateUtils.formatDate(req.getEndTime());
-        }
-        Page<KwtWaybillOrder> page = kwtWaybillOrderRepository.findPage(req.getTruckNo(),req.getPageNum(), req.getPageSize(), beforeDate, date);
+        Page<KwtWaybillOrder> page = kwtWaybillOrderRepository.findPage(wayOrderIds,req.getTruckNo(),req.getPageNum(), req.getPageSize(), startDate, endDate);
         List<KwtWaybillOrder> records = page.getRecords();
         if(CollectionUtils.isEmpty(page.getRecords())) {
             return PageDataResult.success(req.getPageNum(), req.getPageSize(),0L, null);
@@ -154,8 +156,19 @@ public class kwfTruckTraceService {
             worderNoAndWorderMap = waybillOrderSubtasks.stream()
                     .collect(Collectors.toMap(KwtWaybillOrderSubtask::getWOrderNo, Function.identity(), (k1, k2) -> k1));
         }
+        List<KwtLogisticsOrderUnit> logisticsOrderUnits = Lists.newArrayList();
+        Map<Long, KwtLogisticsOrder> logisticsOrderMap = Maps.newHashMap();
+        if (CollectionUtils.isNotEmpty(lOrderIds)){
+            //查询物流订单
+            List<KwtLogisticsOrder> logisticsOrders = kwtLogisticsOrderRepository.queryByLogisticsOrderIds(new ArrayList<>(lOrderIds));
+            logisticsOrderMap = Optional.ofNullable(logisticsOrders)
+                    .orElse(List.of())
+                    .stream()
+                    .collect(Collectors.toMap(KwtLogisticsOrder::getId, Function.identity(), (k1, k2) -> k1));
+            logisticsOrderUnits = kwtLogisticsOrderUnitRepository.queryByLOrderIdsAndUnitType(lOrderIds,2);
+        }
+
 
-        List<KwtLogisticsOrderUnit> logisticsOrderUnits = kwtLogisticsOrderUnitRepository.queryByLOrderIdsAndUnitType(lOrderIds,2);
         //物流订单id映射企业
         Map<Long, KwtLogisticsOrderUnit> lOrderIdAndLogisticsOrderUnitMap = logisticsOrderUnits.stream()
                 .collect(Collectors.toMap(KwtLogisticsOrderUnit::getLOrderId, Function.identity(), (k1, k2) -> k1));
@@ -169,13 +182,84 @@ public class kwfTruckTraceService {
         Map<Long, List<KwtWaybillOrderAddress>> wOrderIdAndAddressMap = orderAddresses.stream()
                 .collect(Collectors.groupingBy(KwtWaybillOrderAddress::getWOrderId));
 
+        // 批量查询运单轨迹数据,统计异常数量(通过alarmCode判断)
+        List<String> wOrderNos = records.stream()
+                .map(KwtWaybillOrder::getWOrderNo)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+        // 批量查询每个运单的轨迹数据
+        Map<String, Integer> exceptionCountMap = Maps.newHashMap();
+        Map<String,List<VehicleReturnData>> traceMap = Maps.newHashMap();
+        getTraceInfoList(wOrderNos, traceMap, exceptionCountMap);
+
+        // Map<String, Integer> exceptionCountMap = countExceptionsByTraceData(wOrderNos);
         Map<String, KwtWaybillOrderSubtask> finalWorderNoAndWorderMap = worderNoAndWorderMap;
+        Map<Long, KwtLogisticsOrder> finalLogisticsOrderMap = logisticsOrderMap;
         List<KwfTruckTraceReplayVo> kwfTruckTraceReplayVoList = records.stream()
-                .map(r -> getKwfTruckTraceReplayVo(r, idAndKwsEnterpriseMap, wOrderIdAndAddressMap, lOrderIdAndLogisticsOrderUnitMap, finalWorderNoAndWorderMap))
+                .map(r -> getKwfTruckTraceReplayVo(r, idAndKwsEnterpriseMap, wOrderIdAndAddressMap,
+                        lOrderIdAndLogisticsOrderUnitMap, finalWorderNoAndWorderMap,
+                        exceptionCountMap, finalLogisticsOrderMap,traceMap))
                 .collect(Collectors.toList());
+        // 根据排序类型进行排序
+        MapVehicleSortTypeEnum sortType = MapVehicleSortTypeEnum.getByCode(req.getSortType());
+        kwfTruckTraceReplayVoList = switch (sortType) {
+            case TIME_DESC ->
+                // 按任务开始时间倒序
+                    kwfTruckTraceReplayVoList.stream()
+                            .sorted(Comparator.comparing(KwfTruckTraceReplayVo::getTaskStartTime,
+                                    Comparator.nullsLast(Comparator.reverseOrder())))
+                            .collect(Collectors.toList());
+            case DURATION_DESC ->
+                // 按任务耗时倒序
+                    kwfTruckTraceReplayVoList.stream()
+                            .sorted(Comparator.comparing(KwfTruckTraceReplayVo::getTaskDuration,
+                                    Comparator.nullsLast(Comparator.reverseOrder())))
+                            .collect(Collectors.toList());
+            case EXCEPTION_COUNT_DESC ->
+                // 按异常数量倒序
+                    kwfTruckTraceReplayVoList.stream()
+                            .sorted(Comparator.comparing(KwfTruckTraceReplayVo::getExceptionCount,
+                                    Comparator.nullsLast(Comparator.reverseOrder())))
+                            .collect(Collectors.toList());
+        };
        return PageDataResult.of(page,kwfTruckTraceReplayVoList);
     }
 
+    private void getTraceInfoList(List<String> wOrderNos, Map<String,List<VehicleReturnData>> traceMap, Map<String, Integer> exceptionCountMap) {
+        if (CollectionUtils.isNotEmpty(wOrderNos)) {
+            for (String wOrderNo : wOrderNos) {
+                try {
+                    VehicleDataDTO vehicleDataDTO = new VehicleDataDTO();
+                    vehicleDataDTO.setWOrderNo(wOrderNo);
+
+                    // 调用Feign接口查询轨迹列表
+                    log.info("查询车辆数据中台请求轨迹数据:{}", JSON.toJSONString( vehicleDataDTO));
+                    BaseIotResult<List<VehicleReturnData>> result =
+                            vehicleTraceClient.queryVehicleDataList(vehicleDataDTO);
+                    log.info("查询车辆数据中台响应轨迹数据:{}", JSON.toJSONString( result));
+                    if (result != null && StringUtils.equals(result.getCode(), "0") && result.getData() != null) {
+                        List<VehicleReturnData> traceDataList = result.getData();
+                        traceMap.put(wOrderNo, traceDataList);
+                        // 统计alarmCode不为null且不为0的记录数量(表示有异常报警)
+                        int exceptionCount = (int) traceDataList.stream()
+                                .filter(data -> StringUtils.equals(data.getStatus(),"0"))
+                                .count();
+
+                        exceptionCountMap.put(wOrderNo, exceptionCount);
+                        log.debug("运单号: {}, 异常数量: {}", wOrderNo, exceptionCount);
+                    } else {
+                        log.warn("查询运单轨迹数据失败或返回空数据, 运单号: {}", wOrderNo);
+                        exceptionCountMap.put(wOrderNo, 0);
+                    }
+                } catch (Exception e) {
+                    log.error("查询运单轨迹数据异常, 运单号: {}", wOrderNo, e);
+                    exceptionCountMap.put(wOrderNo, 0);
+                }
+            }
+        }
+    }
+
     /**
      * 组织轨迹回访返回数据
      * @param waybillOrder 运单信息
@@ -186,17 +270,43 @@ public class kwfTruckTraceService {
     private static KwfTruckTraceReplayVo getKwfTruckTraceReplayVo(KwtWaybillOrder waybillOrder, Map<Long, KwsEnterpriseResDto> idAndKwsEnterpriseMap,
                                                                   Map<Long, List<KwtWaybillOrderAddress>> wOrderIdAndAddressMap
                                                                 ,Map<Long, KwtLogisticsOrderUnit> lOrderIdAndLogisticsOrderUnitMap
-                                                                ,Map<String, KwtWaybillOrderSubtask> worderNoAndWorderMap) {
+                                                                ,Map<String, KwtWaybillOrderSubtask> worderNoAndWorderMap,
+                                                                  Map<String, Integer> exceptionCountMap,
+                                                                  Map<Long, KwtLogisticsOrder> logisticsOrderMap,
+                                                                  Map<String,List<VehicleReturnData>> traceMap) {
 
         KwfTruckTraceReplayVo kwfTruckTraceReplay = new KwfTruckTraceReplayVo();
         kwfTruckTraceReplay.setOrderId(waybillOrder.getId());
         kwfTruckTraceReplay.setOrderNo(waybillOrder.getWOrderNo());
         kwfTruckTraceReplay.setDriverName(waybillOrder.getDriverName());
         kwfTruckTraceReplay.setPhone(waybillOrder.getDriverPhone());
+        kwfTruckTraceReplay.setTruckNo(waybillOrder.getTruckNo());
+        //已完成的状态
+        List<Integer> complatedStatusList = Arrays.asList(CarWaybillV1Enum.WAIT_UNLOADING.getCode(), CarWaybillV1Enum.APPROVAL_TREAT.getCode());
+        if (complatedStatusList.contains(waybillOrder.getStatus())){
+            kwfTruckTraceReplay.setStatus("1");
+            kwfTruckTraceReplay.setStatusDesc("已结束");
+            String endStartEndTime = DateUtils.format(waybillOrder.getUpdateTime(), DateUtils.DATE_TIME_PATTERN);
+            kwfTruckTraceReplay.setTaskEndTime(StringUtils.equals(endStartEndTime, CommonConstants.DATE_TIME) ? StringUtils.EMPTY: endStartEndTime);
+        }else {
+            kwfTruckTraceReplay.setStatus("0");
+            kwfTruckTraceReplay.setStatusDesc("任务中");
+            List<VehicleReturnData> data = traceMap.getOrDefault(waybillOrder.getWOrderNo(), new ArrayList<>());
+            if (CollectionUtils.isNotEmpty(data)){
+                VehicleReturnData vehicleReturnData = data.get(0);
+                kwfTruckTraceReplay.setLatitude(vehicleReturnData.getLatitude());
+                kwfTruckTraceReplay.setLongitude(vehicleReturnData.getLongitude());
+                String endStartEndTime = DateUtils.format(vehicleReturnData.getTs(), DateUtils.DATE_TIME_PATTERN);
+                kwfTruckTraceReplay.setTaskEndTime(StringUtils.equals(endStartEndTime, CommonConstants.DATE_TIME) ? StringUtils.EMPTY: endStartEndTime);
+            }
+
+        }
         kwfTruckTraceReplay.setStatus(String.valueOf(waybillOrder.getStatus()));
         kwfTruckTraceReplay.setStatusDesc(CarWaybillEnum.getName(waybillOrder.getStatus()));
         KwtWaybillOrderSubtask subtask = worderNoAndWorderMap.getOrDefault(waybillOrder.getWOrderNo(), new KwtWaybillOrderSubtask());
         kwfTruckTraceReplay.setRelationTaskNo(String.valueOf(subtask.getLOrderId()));
+        KwtLogisticsOrder logisticsOrder = logisticsOrderMap.getOrDefault(subtask.getLOrderId(), new KwtLogisticsOrder());
+        kwfTruckTraceReplay.setLogOrderNo(logisticsOrder.getLOrderNo());
         KwtLogisticsOrderUnit kwtLogisticsOrderUnit = lOrderIdAndLogisticsOrderUnitMap.getOrDefault(subtask.getLOrderId(), new KwtLogisticsOrderUnit());
         KwsEnterpriseResDto orDefault = idAndKwsEnterpriseMap.getOrDefault(kwtLogisticsOrderUnit.getEntId(), new KwsEnterpriseResDto());
         kwfTruckTraceReplay.setCarrier(orDefault.getFirmName());
@@ -210,13 +320,21 @@ public class kwfTruckTraceService {
             }
         });
 
-
-        String taskStartEndTime = DateUtils.format(waybillOrder.getTaskStartTime(), DateUtils.DATE_TIME_PATTERN);
+        Date startTime =  waybillOrder.getCreateTime();
+        String taskStartEndTime = DateUtils.format(startTime, DateUtils.DATE_TIME_PATTERN);
         kwfTruckTraceReplay.setTaskStartTime(StringUtils.equals(taskStartEndTime, CommonConstants.DATE_TIME) ? StringUtils.EMPTY: taskStartEndTime);
 
-        String endStartEndTime = DateUtils.format(waybillOrder.getTaskEndTime(), DateUtils.DATE_TIME_PATTERN);
-        kwfTruckTraceReplay.setTaskEndTime(StringUtils.equals(endStartEndTime, CommonConstants.DATE_TIME) ? StringUtils.EMPTY: endStartEndTime);
         kwfTruckTraceReplay.setWarningCount("");
+        // 从异常表查询该运单的异常数量
+        Integer exceptionCount = exceptionCountMap.getOrDefault(waybillOrder.getWOrderNo(), 0);
+        kwfTruckTraceReplay.setExceptionCount(exceptionCount);
+        // 计算任务耗时(分钟)
+        Date endTime = new Date();
+        if (Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.WAIT_UNLOADING.getCode())){
+            endTime = waybillOrder.getUpdateTime() != null ? waybillOrder.getUpdateTime() : new Date();
+        }
+        long duration = (endTime.getTime() - startTime.getTime()) / (1000 * 60);
+        kwfTruckTraceReplay.setTaskDuration(duration);
         return kwfTruckTraceReplay;
     }
 
@@ -721,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()
@@ -739,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();
@@ -762,7 +882,7 @@ public class kwfTruckTraceService {
                 if (vehicleData.getTs() == null) {
                     // 无GPS时间,设置为离线
                     truckLocationStatusMap.put(truckNo, 0);
-                    return truckLocationStatusMap;
+                    return;
                 }
 
                 // 30分钟内为在线
@@ -776,7 +896,7 @@ public class kwfTruckTraceService {
                 log.warn("查询车辆实时位置异常, 车牌号: {}", truckNo, e);
                 truckLocationStatusMap.put(truckNo, 0);
             }
-        }
+        });
         return truckLocationStatusMap;
     }
 
@@ -911,14 +1031,13 @@ 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()
                 .map(KwtWaybillOrder::getWOrderNo)
@@ -987,11 +1106,16 @@ public class kwfTruckTraceService {
     @NotNull
     private Set<Long> getWayOrderIds(MapVehicleQueryReq req) {
         Set<Long> wayOrderIds = Sets.newHashSet();
-        if (req.getConsignEntId() != null || req.getCarrierEntId() != null) {
+        List<Long> entIds = new ArrayList<>();
+        if (req.getConsignEntId() != null){
+            entIds.add(req.getConsignEntId());
+        }
+        if (req.getCarrierEntId() != null){
+            entIds.add(req.getCarrierEntId());
+        }
+        if (CollectionUtils.isNotEmpty(entIds)) {
             // 第一步:从物流订单单位表查询符合条件的物流订单ID
             // 同时有托运和承运单位条件,将企业ID和类型组合后批量查询
-            List<Long> entIds = Arrays.asList(req.getConsignEntId(), req.getCarrierEntId());
-
             List<KwtLogisticsOrderUnit> allUnits = kwtLogisticsOrderUnitRepository.list(
                     Wrappers.<KwtLogisticsOrderUnit>lambdaQuery()
                             .eq(KwtLogisticsOrderUnit::getDelFlag, 0)
@@ -1084,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) {
@@ -1127,7 +1251,7 @@ public class kwfTruckTraceService {
                 locationInfo.setLocationStatus(0);
                 locationInfoMap.put(truckNo, locationInfo);
             }
-        }
+        });
         
         return locationInfoMap;
     }
@@ -1215,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);
             
@@ -1428,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());