Преглед изворни кода

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

xucaiqin пре 1 месец
родитељ
комит
2c59fb9b2f
15 измењених фајлова са 354 додато и 57 уклоњено
  1. 0 2
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/common/enums/enums/DictEnum.java
  2. 0 1
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/common/enums/enums/DictTypeEnum.java
  3. 29 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/common/enums/enums/DispatchingTypeEnum.java
  4. 53 12
      sckw-common/sckw-common-log/src/main/java/com/sckw/log/aspect/LogInfoAspect.java
  5. 6 5
      sckw-modules/sckw-contract/src/main/java/com/sckw/contract/service/operateService/KwcContractLogisticsService.java
  6. 15 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreDetailMapper.java
  7. 14 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/dao/KwfDriverScoreMapper.java
  8. 37 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java
  9. 43 0
      sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java
  10. 4 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/common/config/UrlConfigProperties.java
  11. 4 1
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/enuma/VehicleExceptionTypeEnum.java
  12. 10 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/CurrentTaskTraceReqVo.java
  13. 11 0
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/VehicleExceptionVo.java
  14. 74 14
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/VehicleExceptionService.java
  15. 54 22
      sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/kwfTruckTraceService.java

+ 0 - 2
sckw-common/sckw-common-core/src/main/java/com/sckw/core/common/enums/enums/DictEnum.java

@@ -97,8 +97,6 @@ public enum DictEnum {
     SETTLEMENT_WAY_2("settlement_way", "2", "线下结算"),
     LOAD_UNLOAD_WAY_1("load_unload_way", "1", "按装货量"),
     LOAD_UNLOAD_WAY_2("load_unload_way", "2", "按卸货量"),
-    DISPATCHING_TYPE_1("dispatching_type", "1", "手动派车"),
-    DISPATCHING_TYPE_2("dispatching_type", "2", "自动派车"),
     ;
 
     private final String type;

+ 0 - 1
sckw-common/sckw-common-core/src/main/java/com/sckw/core/common/enums/enums/DictTypeEnum.java

@@ -53,7 +53,6 @@ public enum DictTypeEnum {
     CONSIGNMENT_WAY("consignment_way", "托运方式"),
     SETTLEMENT_WAY(" settlement_way", "结算方式"),
     LOAD_UNLOAD_WAY("load_unload_way", "装卸方式"),
-    DISPATCHING_TYPE("dispatching_type", "派车方式"),
     GOODS_SPEC("goods_spec", "商品规格"),
     ;
 

+ 29 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/common/enums/enums/DispatchingTypeEnum.java

@@ -0,0 +1,29 @@
+package com.sckw.core.common.enums.enums;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  14:13
+ * @Description: 派车方式枚举类
+ */
+@Getter
+@AllArgsConstructor
+public enum DispatchingTypeEnum {
+    MANUAL(1,"手动派车"),
+    AUTO(2,"自动派车");
+
+    private final Integer value;
+    private final String label;
+
+    public static String getLabel(Integer value) {
+        for (DispatchingTypeEnum ele : DispatchingTypeEnum.values()) {
+            if (ele.getValue().equals(value)) {
+                return ele.getLabel();
+            }
+        }
+        return null;
+    }
+}

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

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

@@ -23,6 +23,7 @@ import com.sckw.contract.repository.KwcContractLogisticsUnitRepository;
 import com.sckw.contract.service.*;
 import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
+import com.sckw.core.common.enums.enums.DispatchingTypeEnum;
 import com.sckw.core.exception.BusinessException;
 import com.sckw.core.exception.SystemException;
 import com.sckw.core.model.constant.Global;
@@ -1181,7 +1182,7 @@ public class KwcContractLogisticsService {
                 String.valueOf( r.getSigningWay())));
         //设置派车方式和派车方式描述字段
         queryLogisticListResp.setDispatching(r.getDispatching());
-        queryLogisticListResp.setDispatchingDesc(DictEnum.getLabel(DictTypeEnum.DISPATCHING_TYPE.getType(),String.valueOf(r.getDispatching())));
+        queryLogisticListResp.setDispatchingDesc(DispatchingTypeEnum.getLabel(r.getDispatching()));
         queryLogisticListResp.setPerformedAmount(Objects.nonNull(r.getPerformedAmount())
                 ? r.getPerformedAmount().toPlainString() : null);
         List<KwcContractLogisticsGoods> goods = finalContractIdAndGoodsMap.get(r.getId());
@@ -1299,14 +1300,14 @@ public class KwcContractLogisticsService {
         saveLogisticListUnit(entIdList, baseInfo, saveContractLogistics.getId(), date,entCacheResDtoMap);
 
         //如果是自动派单合同需要初始化物流企业评分记录和评分记录明细
-        if(Objects.equals(Integer.parseInt(DictEnum.DISPATCHING_TYPE_2.getValue()), baseInfo.getDispatching())){
+        if(DispatchingTypeEnum.AUTO.getValue().equals(baseInfo.getDispatching())){
             logisticsScoreService.initLogisticsScore(baseInfo,entCacheResDtoMap);
         }
         return Boolean.TRUE;
     }
 
     private void checkAutoDispatchingContractEntType(LogisticListReq.TradeBaseInfo baseInfo,Map<Long, EntCacheResDto> entCacheResDtoMap) {
-        if (Objects.equals(Integer.parseInt(DictEnum.DISPATCHING_TYPE_2.getValue()), baseInfo.getDispatching())) {
+        if(DispatchingTypeEnum.AUTO.getValue().equals(baseInfo.getDispatching())){
             EntCacheResDto entCacheResDto = entCacheResDtoMap.get(baseInfo.getProvideEntId());
             if (entCacheResDto != null && !entCacheResDto.getEntTypes().contains(String.valueOf(EntTypeEnum.SUPPLIER.getCode()))) {
                 throw new BusinessException("自动派车合同的托运单位必须为供应商");
@@ -1318,7 +1319,7 @@ public class KwcContractLogisticsService {
         List<KwcContractLogisticsUnit> units = kwcContractLogisticsUnitRepository.queryByEntIdAndEntType(baseInfo.getPurchaseEntId(), EntTypeEnum.LOGISTICS4.getCode());
         if (CollectionUtils.isNotEmpty(units)) {
             Set<Long> contractIdList = units.stream().map(KwcContractLogisticsUnit::getContractId).collect(Collectors.toSet());
-            KwcContractLogistics kwcContractLogistics = kwcContractLogisticsRepository.queryBy(contractIdList,baseInfo.getStartTime(),baseInfo.getEndTime(),Integer.parseInt(DictEnum.DISPATCHING_TYPE_2.getValue()));
+            KwcContractLogistics kwcContractLogistics = kwcContractLogisticsRepository.queryBy(contractIdList,baseInfo.getStartTime(),baseInfo.getEndTime(),DispatchingTypeEnum.AUTO.getValue());
             if (Objects.nonNull(kwcContractLogistics)){
                 throw new BusinessException("当前物流企业在合同时间段内已存在自动派车合同");
             }
@@ -1511,7 +1512,7 @@ public class KwcContractLogisticsService {
 
         //派车方式
         tradeBaseInfo.setDispatching(logistics.getDispatching());
-        tradeBaseInfo.setDispatchingDesc(DictEnum.getLabel(DictTypeEnum.DISPATCHING_TYPE.getType(),String.valueOf(logistics.getDispatching())));
+        tradeBaseInfo.setDispatchingDesc(DispatchingTypeEnum.getLabel(logistics.getDispatching()));
 
         tradeBaseInfo.setStartTime(logistics.getStartTime());
         tradeBaseInfo.setCommonPrice(logistics.getCommonPrice());

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

@@ -0,0 +1,15 @@
+package com.sckw.fleet.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.fleet.model.KwfDriverScoreDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  18:06
+ * @Description: 司机评分明细Mapper接口
+ */
+@Mapper
+public interface KwfDriverScoreDetailMapper extends BaseMapper<KwfDriverScoreDetail> {
+
+}

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

@@ -0,0 +1,14 @@
+package com.sckw.fleet.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.fleet.model.KwfDriverScore;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  18:06
+ * @Description: 司机评分Mapper接口
+ */
+@Mapper
+public interface KwfDriverScoreMapper extends BaseMapper<KwfDriverScore> {
+}

+ 37 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScore.java

@@ -0,0 +1,37 @@
+package com.sckw.fleet.model;
+
+import java.math.BigDecimal;
+
+import com.sckw.core.model.base.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 司机评分对象 kwc_driver_score
+ * 
+ * @author tangyishan
+ * @date 2025-12-11  18:12
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class KwfDriverScore extends BaseModel
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 供应商企业id */
+    private Long providerEntId;
+
+    /** 物流企业id */
+    private Long logisticsEntId;
+
+    /** 司机id */
+    private Long driverId;
+
+    /** 供应商企业名称 */
+    private String providerEntName;
+
+    /** 司机评分 */
+    private BigDecimal score;
+}

+ 43 - 0
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/model/KwfDriverScoreDetail.java

@@ -0,0 +1,43 @@
+package com.sckw.fleet.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.sckw.core.model.base.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+
+/**
+ * @Author: tangyishan
+ * @CreateTime: 2025-12-11  18:12
+ * @Description: 司机评分明细
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class KwfDriverScoreDetail extends BaseModel {
+    private static final long serialVersionUID = 1L;
+
+    /** 评分主键id */
+    private Long scoreId;
+
+    /** 司机id */
+    private Long driverId;
+
+    /** 司机名字 */
+    private String driverName;
+
+    /** 行为 */
+    private String action;
+
+    /** 评分变动 */
+    private BigDecimal scoreChange;
+
+    /** 变动后评分 */
+    private BigDecimal score;
+
+    /** 物流企业名称 */
+    @TableField(exist = false)
+    private String logisticsEntName;
+}

+ 4 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/common/config/UrlConfigProperties.java

@@ -18,5 +18,9 @@ public class UrlConfigProperties {
      * API基础地址
      */
     private String apiBaseUrl;
+    /**
+     * 分钟
+     */
+    private Long minute;
 
 }

+ 4 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/enuma/VehicleExceptionTypeEnum.java

@@ -9,7 +9,10 @@ import lombok.Getter;
  */
 @Getter
 public enum VehicleExceptionTypeEnum {
-    
+    /**
+     * 正常
+     */
+    NORMAL(0, "正常"),
     /**
      * 车辆偏航
      */

+ 10 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/CurrentTaskTraceReqVo.java

@@ -43,6 +43,16 @@ public class CurrentTaskTraceReqVo implements Serializable {
          */
         @Schema(description = "定位时间")
         private String locationTime;
+        /**
+         * 状态
+         */
+        @Schema(description = "状态")
+        private String status;
+        /**
+         * 状态描述
+         */
+        @Schema(description = "状态描述")
+        private String statusDesc;
         /**
          * 耗时
          */

+ 11 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/vo/VehicleExceptionVo.java

@@ -130,4 +130,15 @@ public class VehicleExceptionVo {
      */
     @Schema(description = "卸货地址纬度")
     private String endLat;
+
+    /**
+     * 运单id
+     */
+    @Schema(description = "运单id")
+    private Long waybillId;
+    /**
+     * 运单号
+     */
+    @Schema(description = "运单号")
+    private String waybillNo;
 }

+ 74 - 14
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/VehicleExceptionService.java

@@ -1,5 +1,6 @@
 package com.sckw.transport.service;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -50,7 +51,15 @@ public class VehicleExceptionService {
      * @param req 查询请求
      * @return 分页结果
      */
+
+    /**
+     * 分页查询车辆异常图片信息
+     *
+     * @param req 查询请求参数
+     * @return 车辆异常图片分页结果
+     */
     public PageDataResult<VehicleExceptionVo> queryExceptionList(VehicleExceptionQueryReq req) {
+        log.info("分页查询车辆异常信息,参数:{}", JSON.toJSONString( req));
         // 分页查询异常图片数据
         IPage<KwtVehicleException> page = exceptionImageRepository.queryExceptionImagePage(
                 req.getEntId(),
@@ -60,65 +69,85 @@ public class VehicleExceptionService {
                 req.getPageSize()
         );
         
+        // 获取查询结果记录列表
         List<KwtVehicleException> records = page.getRecords();
+        // 如果记录为空,返回空的分页结果
         if (CollectionUtils.isEmpty(records)) {
             return PageDataResult.empty(req.getPageNum(), req.getPageSize());
         }
         
-        // 如果有定位状态筛选,需要查询车辆实时定位
+        // 如果有定位状态筛选条件,需要查询车辆实时定位状态
         Map<String, Integer> truckLocationStatusMap = new HashMap<>();
         if (req.getLocationStatus() != null) {
+            // 提取所有不重复的车牌号
             List<String> truckNos = records.stream()
                     .map(KwtVehicleException::getTruckNo)
                     .distinct()
                     .collect(Collectors.toList());
             
+            // 批量查询车辆定位状态
             truckLocationStatusMap = queryVehicleLocationStatus(truckNos);
         }
+        
+        // 提取所有不重复的运单ID
         List<Long> waybillOrderNos = records.stream()
                 .map(KwtVehicleException::getWOrderId)
                 .distinct()
                 .collect(Collectors.toList());
+        
+        // 初始化地址和运单信息Map
         Map<String, KwtLogisticsOrderAddress> logisticsOrderAddressMap = Maps.newHashMap();
         Map<Long, KwtWaybillOrderSubtask> waybillOrderSubtaskMap = Maps.newHashMap();
+        
+        // 如果存在运单ID,则查询相关运单和地址信息
         if (CollectionUtils.isNotEmpty(waybillOrderNos)){
-            //查询运单
+            // 查询运单信息
             List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByWOrderIds(waybillOrderNos);
             List<Long> logisticOrderIds = Lists.newArrayList();
+            
+            // 如果查询到运单信息,则提取物流订单ID
             if (CollectionUtils.isNotEmpty(subtasks)){
                 logisticOrderIds = subtasks.stream().map(KwtWaybillOrderSubtask::getLOrderId)
                         .distinct()
                         .collect(Collectors.toList());
+                // 构建运单ID到运单信息的映射关系
                 waybillOrderSubtaskMap = subtasks.stream()
                         .collect(Collectors.toMap(KwtWaybillOrderSubtask::getWOrderId, Function.identity(), (k1, k2) -> k1));
             }
+            
+            // 如果存在物流订单ID,则查询相关地址信息
             if (CollectionUtils.isNotEmpty(logisticOrderIds)){
-                //查询地址
+                // 查询地址信息
                 List<KwtLogisticsOrderAddress> logisticOrderAddresses = logisticsOrderAddressRepository.queryByLogOrderIds(logisticOrderIds);
+                // 构建物流订单ID+地址类型到地址信息的映射关系
                 logisticsOrderAddressMap = Optional.ofNullable(logisticOrderAddresses)
                         .orElse(List.of())
                         .stream().collect(Collectors.toMap(x -> x.getLOrderId() + "_" + x.getAddressType(), Function.identity(), (k1, k2) -> k1));
             }
         }
-        // 转换为VO
+        
+        // 将查询结果转换为VO对象
         final Map<String, Integer> finalLocationStatusMap = truckLocationStatusMap;
         Map<String, KwtLogisticsOrderAddress> finalLogisticsOrderAddressMap = logisticsOrderAddressMap;
         Map<Long, KwtWaybillOrderSubtask> finalWaybillOrderSubtaskMap = waybillOrderSubtaskMap;
+        
+        // 遍历异常图片记录,构建VO对象列表
         List<VehicleExceptionVo> voList = records.stream()
                 .map(image -> buildVehicleExceptionVo(image, finalLocationStatusMap,finalWaybillOrderSubtaskMap, finalLogisticsOrderAddressMap))
+                // 过滤掉空值
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
         
-        // 如果有定位状态筛选,过滤结果
+        // 如果有定位状态筛选条件再次过滤结果
         if (req.getLocationStatus() != null) {
             voList = voList.stream()
                     .filter(vo -> req.getLocationStatus().equals(vo.getLocationStatus()))
                     .collect(Collectors.toList());
         }
         
+        // 返回分页结果
         return PageDataResult.of(page, voList);
     }
-    
     /**
      * 构建车辆异常图片VO
      *
@@ -170,6 +199,8 @@ public class VehicleExceptionService {
         vo.setUnloadAddress(unLoadAdd.getDetailAddress());
         vo.setEndLng(unLoadAdd.getLng());
         vo.setEndLat(unLoadAdd.getLat());
+        vo.setWaybillId(subtask.getWOrderId());
+        vo.setWaybillNo(subtask.getWOrderNo());
         return vo;
     }
     
@@ -211,7 +242,15 @@ public class VehicleExceptionService {
         return locationStatusMap;
     }
 
+
+    /**
+     * 分页查询车辆异常监控列表
+     *
+     * @param req 查询请求参数
+     * @return 车辆异常监控分页结果
+     */
     public PageDataResult<VehicleExceptionVo> exceptionJkList(VehicleExceptionQueryReq req) {
+        log.info("分页查询车辆异常监控列表, req: {}", JSON.toJSONString( req));
         // 分页查询异常图片数据
         IPage<KwtVehicleException> page = exceptionImageRepository.queryExceptionImagePage1(
                 req.getEntId(),
@@ -221,62 +260,83 @@ public class VehicleExceptionService {
                 req.getPageSize()
         );
 
+        // 获取查询结果记录列表
         List<KwtVehicleException> records = page.getRecords();
+        // 如果记录为空,返回空的分页结果
         if (CollectionUtils.isEmpty(records)) {
             return PageDataResult.empty(req.getPageNum(), req.getPageSize());
         }
 
-        // 如果有定位状态筛选,需要查询车辆实时定位
+        // 如果有定位状态筛选条件,需要查询车辆实时定位状态
         Map<String, Integer> truckLocationStatusMap = new HashMap<>();
         if (req.getLocationStatus() != null) {
+            // 提取所有不重复的车牌号
             List<String> truckNos = records.stream()
                     .map(KwtVehicleException::getTruckNo)
                     .distinct()
                     .collect(Collectors.toList());
 
+            // 批量查询车辆定位状态
             truckLocationStatusMap = queryVehicleLocationStatus(truckNos);
         }
+        
+        // 提取所有不重复的运单ID
         List<Long> waybillOrderNos = records.stream()
                 .map(KwtVehicleException::getWOrderId)
                 .distinct()
                 .collect(Collectors.toList());
+        
+        // 初始化地址和运单信息Map
         Map<String, KwtLogisticsOrderAddress> logisticsOrderAddressMap = Maps.newHashMap();
         Map<Long, KwtWaybillOrderSubtask> waybillOrderSubtaskMap = Maps.newHashMap();
+        
+        // 如果存在运单ID,则查询相关运单和地址信息
         if (CollectionUtils.isNotEmpty(waybillOrderNos)){
-            //查询运单
+            // 查询运单信息
             List<KwtWaybillOrderSubtask> subtasks = waybillOrderSubtaskRepository.queryByWOrderIds(waybillOrderNos);
             List<Long> logisticOrderIds = Lists.newArrayList();
+            
+            // 如果查询到运单信息,则提取物流订单ID
             if (CollectionUtils.isNotEmpty(subtasks)){
-               logisticOrderIds = subtasks.stream().map(KwtWaybillOrderSubtask::getLOrderId)
-                       .distinct()
-                       .collect(Collectors.toList());
+                logisticOrderIds = subtasks.stream().map(KwtWaybillOrderSubtask::getLOrderId)
+                        .distinct()
+                        .collect(Collectors.toList());
+                // 构建运单ID到运单信息的映射关系
                 waybillOrderSubtaskMap = subtasks.stream()
                         .collect(Collectors.toMap(KwtWaybillOrderSubtask::getWOrderId, Function.identity(), (k1, k2) -> k1));
             }
+            
+            // 如果存在物流订单ID,则查询相关地址信息
             if (CollectionUtils.isNotEmpty(logisticOrderIds)){
-                //查询地址
+                // 查询地址信息
                 List<KwtLogisticsOrderAddress> logisticOrderAddresses = logisticsOrderAddressRepository.queryByLogOrderIds(logisticOrderIds);
+                // 构建物流订单ID+地址类型到地址信息的映射关系
                 logisticsOrderAddressMap = Optional.ofNullable(logisticOrderAddresses)
                         .orElse(List.of())
                         .stream().collect(Collectors.toMap(x -> x.getLOrderId() + "_" + x.getAddressType(), Function.identity(), (k1, k2) -> k1));
             }
         }
-        // 转换为VO
+        
+        // 将查询结果转换为VO对象
         final Map<String, Integer> finalLocationStatusMap = truckLocationStatusMap;
         Map<String, KwtLogisticsOrderAddress> finalLogisticsOrderAddressMap = logisticsOrderAddressMap;
         Map<Long, KwtWaybillOrderSubtask> finalWaybillOrderSubtaskMap = waybillOrderSubtaskMap;
+        
+        // 遍历异常图片记录,构建VO对象列表
         List<VehicleExceptionVo> voList = records.stream()
                 .map(image -> buildVehicleExceptionVo(image, finalLocationStatusMap, finalWaybillOrderSubtaskMap, finalLogisticsOrderAddressMap))
+                // 过滤掉空值
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
 
-        // 如果有定位状态筛选,过滤结果
+        // 如果有定位状态筛选条件再次过滤结果
         if (req.getLocationStatus() != null) {
             voList = voList.stream()
                     .filter(vo -> req.getLocationStatus().equals(vo.getLocationStatus()))
                     .collect(Collectors.toList());
         }
 
+        // 返回分页结果
         return PageDataResult.of(page, voList);
     }
 }

+ 54 - 22
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/kwfTruckTraceService.java

@@ -42,6 +42,7 @@ import com.sckw.transport.model.dto.TruckDto;
 import com.sckw.transport.api.feign.VehicleTraceClient;
 import com.sckw.transport.api.model.dto.VehicleDataDTO;
 import com.sckw.transport.api.model.dto.VehicleReturnData;
+import com.sckw.transport.model.enuma.ExceptionSortTypeEnum;
 import com.sckw.transport.model.enuma.VehicleExceptionTypeEnum;
 import com.sckw.transport.model.param.*;
 import com.sckw.transport.model.dto.GenerateTraceReq;
@@ -423,34 +424,42 @@ public class kwfTruckTraceService {
 
     /**
      * 查询当前任务的轨迹
-     * @param req 请求参数
-     * @return 响应参数
+     * @param req 请求参数,包含车辆编号和订单号等信息
+     * @return 当前任务轨迹信息,包括轨迹点列表和地址点列表
      */
     public CurrentTaskTraceReqVo queryCurrentTaskTrace(CurrentTaskTraceReq req) {
         log.info("查询当前任务轨迹参数:{}", req);
 
+        // 获取当前登录用户的企业ID
         Long entId = LoginUserHolder.getEntId();
         String wOrderNo = StringUtils.EMPTY ;
+        
+        // 如果请求中包含订单号,则直接使用;否则根据车牌号查询对应订单号
         if (StringUtils.isNotBlank(req.getOrderNo())){
             wOrderNo  = req.getOrderNo();
         }else {
             KwtWaybillOrder waybillOrder = kwtWaybillOrderRepository.findOneByTruckNo(req.getTruckNo(),entId);
             wOrderNo = Optional.ofNullable(waybillOrder).map(KwtWaybillOrder::getWOrderNo).orElse("");
         }
-        //查询数据中台获取轨迹
+        
+        // 查询数据中台获取轨迹数据
         List<VehicleReturnData> vehicleReturnDataList = getVehicleReturnDataList(wOrderNo);
 
         CurrentTaskTraceReqVo currentTaskTraceReqVo = new CurrentTaskTraceReqVo();
+        
+        // 如果轨迹数据不为空,则处理轨迹点信息
         if (CollectionUtils.isNotEmpty(vehicleReturnDataList)){
-            //组织返回数据
+            // 将VehicleReturnData转换为CurrentTaskTrace,并按时间排序
             List<CurrentTaskTraceReqVo.CurrentTaskTrace> currentTaskTraceList = vehicleReturnDataList.stream()
                     .map(kwfTruckTraceService::getCurrentTaskTrace)
                     .filter(x->StringUtils.isNotBlank(x.getLocationTime()))
                     .sorted(Comparator.comparing(CurrentTaskTraceReqVo.CurrentTaskTrace::getLocationTime))
                     .collect(Collectors.toList());
 
+            // 设置订单号
             currentTaskTraceReqVo.setOrderNo(vehicleReturnDataList.get(0).getWOrderNo());
 
+            // 计算相邻轨迹点之间的时间间隔(分钟)
             for (int i = 1; i < currentTaskTraceList.size(); i++) {
                 CurrentTaskTraceReqVo.CurrentTaskTrace current = currentTaskTraceList.get(i);
                 CurrentTaskTraceReqVo.CurrentTaskTrace previous = currentTaskTraceList.get(i - 1);
@@ -460,6 +469,8 @@ public class kwfTruckTraceService {
                 Duration duration = Duration.between(previousTime, currentTime);
                 current.setDuration(String.valueOf(duration.toMinutes()));
             }
+            
+            // 计算总时长(第一个点到最后一个点的时间差)
             CurrentTaskTraceReqVo.CurrentTaskTrace first = currentTaskTraceList.get(0);
             CurrentTaskTraceReqVo.CurrentTaskTrace last = currentTaskTraceList.get(currentTaskTraceList.size() - 1);
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -472,10 +483,12 @@ public class kwfTruckTraceService {
             currentTaskTraceReqVo.setCurrentTaskTraceList(currentTaskTraceList);
         }
 
-        //构造点位假数据
+        // 构造点位假数据(用于演示或测试)
         List<CurrentTaskTraceReqVo.CurrentAddress> addressList = getCurrentAddresses();
         // 将地址列表设置到 CurrentTaskTraceReqVo 对象中
         currentTaskTraceReqVo.setCurrentAddressList(addressList);
+        
+        // 计算地址点的总时长
         int sum = addressList.stream()
                 .filter(a -> StringUtils.isNotBlank(a.getDuration()))
                 .mapToInt(x -> Integer.parseInt(x.getDuration()))
@@ -526,19 +539,21 @@ public class kwfTruckTraceService {
     private List<VehicleReturnData> getVehicleReturnDataList(String wOrderNo) {
         VehicleDataDTO vehicleDataDTO = new VehicleDataDTO();
         vehicleDataDTO.setWOrderNo(wOrderNo);
-        String s;
+        
         try {
-             s = HttpUtil.postJson(urlConfigProperties.getApiBaseUrl()+ UrlConstants.QUERY_TRACE_URL, JSON.toJSONString(vehicleDataDTO), null);
+            // 使用 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) {
+                log.warn("查询任务轨迹返回空数据, 运单号: {}", wOrderNo);
+                return List.of();
+            }
+            return result.getData();
         } catch (Exception e) {
-            log.error("查询任务轨迹异常",e);
+            log.error("查询任务轨迹异常, 运单号: {}", wOrderNo, e);
             throw new BusinessException("查询任务轨迹异常");
         }
-        if (StringUtils.isBlank(s)){
-            return Collections.emptyList();
-        }
-        JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
-        String data = JSON.toJSONString(jsonObject.get("data"));
-        return JSON.parseArray(data, VehicleReturnData.class);
     }
 
     public VehicleReturnData getVehicleReturnData(String truckId) {
@@ -566,6 +581,16 @@ public class kwfTruckTraceService {
         currentTaskTrace.setLongitude(e.getLongitude());
         currentTaskTrace.setLatitude(e.getLatitude());
         currentTaskTrace.setLocationTime(Objects.isNull(e.getTs()) ? "" : DateUtils.format(e.getTs().toLocalDateTime(), DateUtils.DATE_TIME_PATTERN));
+        currentTaskTrace.setStatus(e.getStatus());
+        // 处理数据库状态值的兼容逻辑
+        int status = 0;
+        try {
+            status = Integer.parseInt(e.getStatus());
+        }catch (Exception ex){
+            log.info("状态码转换异常",ex);
+        }
+
+        currentTaskTrace.setStatusDesc(VehicleExceptionTypeEnum.getName(status));
         return currentTaskTrace;
     }
 
@@ -1062,7 +1087,8 @@ public class kwfTruckTraceService {
     private Map<String, VehicleLocationInfo> queryVehicleLocationBatch(List<String> truckNos) {
         Map<String, VehicleLocationInfo> locationInfoMap = new HashMap<>();
         LocalDateTime now = LocalDateTime.now();
-        LocalDateTime thirtyMinutesAgo = now.minusMinutes(30);
+        log.info("获取配置时间:{}", urlConfigProperties.getMinute());
+        LocalDateTime thirtyMinutesAgo = now.minusMinutes(urlConfigProperties.getMinute());
         if (CollectionUtils.isEmpty(truckNos)){
             return locationInfoMap;
         }
@@ -1291,38 +1317,44 @@ public class kwfTruckTraceService {
         return allEnt;
     }
 
+
     /**
      * 生成车辆轨迹数据
-     * @param req 生成轨迹请求
+     * @param req 生成轨迹请求参数
      */
     @Transactional(rollbackFor = Exception.class)
     public void generateTrace(GenerateTraceReq req) {
         log.info("生成车辆轨迹参数:{}", JSON.toJSONString(req));
         
-        // 校验当前位置格式
+        // 校验当前位置格式,必须为经度,纬度格式
         String[] location = req.getCurrentLocation().split(",");
         if (location.length != 2) {
             throw new BusinessException("当前位置格式错误,应为:经度,纬度");
         }
         
+        // 提取经度和纬度
         String longitude = location[0];
         String latitude = location[1];
 
+        // 根据运单号查询运单信息
         KwtWaybillOrder order = kwtWaybillOrderRepository.queryByWayOrderNo(req.getWayOrderNo());
         if (Objects.isNull(order)){
             throw new BusinessException("运单不存在");
         }
-        //查询子运单
+        
+        // 查询子运单信息
         KwtWaybillOrderSubtask subOrders = kwtWaybillOrderSubtaskRepository.queryByBillOrderId(order.getId());
         if (Objects.isNull(subOrders)){
             throw new BusinessException("子运单不存在");
         }
-        // 通过车牌id查询车队
+        
+        // 通过车牌ID查询所属车队信息
         RFleetVo fleetByTruckId = fleetService.findFleetByTruckId(order.getTruckId(), order.getEntId());
-        //查询物流订单号
+        
+        // 查询物流订单信息
         KwtLogisticsOrder logisticsOrder = kwtLogisticsOrderRepository.queryByLogisticsOrderId(subOrders.getLOrderId());
 
-        // 构造轨迹数据
+        // 构造要发送给数据中台的轨迹数据请求
         VehiclesTrajectoryReq vehiclesTrajectoryReq = getVehiclesTrajectoryReq(req, order, longitude, latitude, logisticsOrder, fleetByTruckId);
 
         try {
@@ -1334,7 +1366,7 @@ public class kwfTruckTraceService {
                 throw new BusinessException("生成轨迹失败:" + result.getMessage());
             }
             
-            // 如果有异常类型,同时保存到本地车辆异常表
+            // 如果请求中包含异常类型,则同时保存到本地车辆异常表
             saveException(req, order, longitude, latitude);
 
             log.info("生成车辆轨迹成功,运单号:{},车牌号:{}", req.getWayOrderNo(), req.getTruckNo());