chenxiaofei 3 месяцев назад
Родитель
Сommit
7f5913eabf

+ 14 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/model/constant/UrlConstants.java

@@ -0,0 +1,14 @@
+package com.sckw.core.model.constant;
+
+
+public class UrlConstants {
+    /**
+     * 获取轨迹的请求路径
+     */
+    public static final String QUERY_TRACE_URL = "api/transfer/pageVehicleDataList";
+    /**
+     * 上报车辆轨迹接口
+     */
+    public static final String VEHICLE_TRAJECTORY = "api/transfer/saveVehicleData";
+
+}

+ 127 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/HttpUtil.java

@@ -0,0 +1,127 @@
+package com.sckw.core.utils;
+
+import com.sckw.core.exception.BusinessException;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+/**
+ * @author PC
+ */
+@Slf4j
+public class HttpUtil {
+
+    // 单例 OkHttpClient(推荐这样做,避免重复创建)
+    private static final OkHttpClient client = new OkHttpClient.Builder()
+            .connectTimeout(30, TimeUnit.SECONDS)
+            .readTimeout(60, TimeUnit.SECONDS)
+            .writeTimeout(60, TimeUnit.SECONDS)
+            .build();
+
+    private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
+
+    /**
+     * 同步 GET 请求
+     */
+    public static String get(String url, Map<String, String> headers) throws Exception {
+        Request.Builder builder = new Request.Builder().url(url);
+        addHeaders(builder, headers);
+
+        Request request = builder.build();
+        try (Response response = client.newCall(request).execute()) {
+            if (response.isSuccessful() && response.body() != null) {
+                log.info("同步 GET 响应结果:{}", response.body().string());
+                return response.body().string();
+            } else if (!response.isSuccessful()) {
+                throw new BusinessException("同步 GET 请求请求异常: " + response.code());
+            } else {
+                return "";
+            }
+        }
+    }
+
+    /**
+     * 异步 GET 请求
+     */
+    public static void getAsync(String url, Map<String, String> headers, Callback callback) {
+        Request.Builder builder = new Request.Builder().url(url);
+        addHeaders(builder, headers);
+
+        Request request = builder.build();
+        client.newCall(request).enqueue(callback);
+    }
+
+    /**
+     * 同步 POST - 表单请求
+     */
+    public static String postForm(String url, Map<String, String> formData, Map<String, String> headers) throws IOException {
+        FormBody.Builder formBuilder = new FormBody.Builder();
+        if (formData != null) {
+            for (Map.Entry<String, String> entry : formData.entrySet()) {
+                formBuilder.add(entry.getKey(), entry.getValue());
+            }
+        }
+
+        RequestBody body = formBuilder.build();
+        Request.Builder builder = new Request.Builder().url(url).post(body);
+        addHeaders(builder, headers);
+
+        Request request = builder.build();
+        try (Response response = client.newCall(request).execute()) {
+            if (response.isSuccessful() && response.body() != null) {
+                log.info("同步 POST - 表单响应结果:{}", response.body().string());
+                return response.body().string();
+            } else if (!response.isSuccessful()) {
+                throw new BusinessException("同步 POST - 表单请求异常: " + response.code());
+            } else {
+                return "";
+            }
+        }
+    }
+
+    /**
+     * 同步 POST - JSON 请求
+     */
+    public static String postJson(String url, String json, Map<String, String> headers) throws IOException {
+        RequestBody body = RequestBody.create(json, JSON);
+        Request.Builder builder = new Request.Builder().url(url).post(body);
+        addHeaders(builder, headers);
+
+        Request request = builder.build();
+        try (Response response = client.newCall(request).execute()) {
+            if (response.isSuccessful() && response.body() != null) {
+                log.info("同步 POST - JSON响应结果:{}", response.body().string());
+                return response.body().string();
+            } else if (!response.isSuccessful()) {
+                throw new BusinessException("同步 POST - JSON 请求异常: " + response.code());
+            } else {
+                return "";
+            }
+        }
+    }
+
+    /**
+     * 异步 POST - JSON
+     */
+    public static void postJsonAsync(String url, String json, Map<String, String> headers, Callback callback) {
+        RequestBody body = RequestBody.create(json, JSON);
+        Request.Builder builder = new Request.Builder().url(url).post(body);
+        addHeaders(builder, headers);
+
+        Request request = builder.build();
+        client.newCall(request).enqueue(callback);
+    }
+
+    /**
+     * 给请求添加 Header
+     */
+    private static void addHeaders(Request.Builder builder, Map<String, String> headers) {
+        if (headers != null) {
+            for (Map.Entry<String, String> entry : headers.entrySet()) {
+                builder.addHeader(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+}

+ 3 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/common/config/AmapProperties.java

@@ -4,6 +4,9 @@ import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 
+/**
+ * @author PC
+ */
 @Component
 @ConfigurationProperties(prefix = "amap")
 @Data

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

@@ -0,0 +1,22 @@
+package com.sckw.transport.common.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 通用URL配置类
+ * 用于从配置文件中读取和管理各种URL配置
+ * @author PC
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "url.config")
+public class UrlConfigProperties {
+    
+    /**
+     * API基础地址
+     */
+    private String apiBaseUrl;
+
+}

+ 33 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/controller/enterpriseApp/AppTraceController.java

@@ -0,0 +1,33 @@
+package com.sckw.transport.controller.enterpriseApp;
+
+import com.alibaba.fastjson.JSONObject;
+import com.sckw.core.web.response.BaseResult;
+import com.sckw.transport.model.param.VehiclesTrajectoryReq;
+import com.sckw.transport.service.kwfTruckTraceService;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * @author PC
+ * app端轨迹controller
+ */
+@Slf4j
+@RestController
+@RequestMapping("/appTraceController")
+@RequiredArgsConstructor
+public class AppTraceController {
+
+    private final kwfTruckTraceService kwfTruckTraceService;
+    /**
+     * 车辆轨迹上报
+     * @return  统计响应结果
+     */
+    @PostMapping(name = "车辆轨迹上报", path = "/vehicles/trajectory")
+    public BaseResult<Void> vehiclesTrajectory(@Valid  @RequestBody VehiclesTrajectoryReq req) {
+        log.info("企业app车辆轨迹上报 请求参数 :{}", JSONObject.toJSONString(req));
+        return BaseResult.success(kwfTruckTraceService.vehiclesTrajectory(req));
+    }
+}

+ 1 - 1
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/TruckDto.java

@@ -23,7 +23,7 @@ public class TruckDto implements Serializable {
      */
     private String truckNo;
     /**
-     * GPS状态
+     * GPS状态 (车速)
      */
     private String gpsStatus;
     /**

+ 31 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/VehicleDataDTO.java

@@ -0,0 +1,31 @@
+package com.sckw.transport.model.dto;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class VehicleDataDTO {
+
+    /**
+     * 运单号
+     */
+    private String wOrderNo;
+
+    /**
+     * 车牌
+     */
+    private String carNo;
+
+    /**
+     * 开始时
+     */
+    private LocalDateTime startTime;
+
+    /**
+     * 结束时间
+     */
+    private LocalDateTime endTime;
+
+}

+ 79 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/dto/VehicleReturnData.java

@@ -0,0 +1,79 @@
+package com.sckw.transport.model.dto;
+
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+
+/**
+ * @author PC
+ */
+@Data
+public class VehicleReturnData {
+
+    /**
+     * 时间戳
+     */
+    private LocalDateTime ts;
+    /**
+     * 车牌号
+     */
+    private String carNo;
+
+    /**
+     * 经度
+     */
+    private String longitude;
+
+    /**
+     * 纬度
+     */
+    private String latitude;
+
+    /**
+     * 车速(km/h)
+     */
+    private Float speed;
+
+    /**
+     * 行驶方向(角度)
+     */
+    private Integer direction;
+
+    /**
+     * 燃油液位(%)
+     */
+    private Float fuelLevel;
+
+    /**
+     * 里程数(km)
+     */
+    private Double mileage;
+
+    /**
+     * 发动机温度(℃)
+     */
+    private Float engineTemp;
+
+    /**
+     * 电池电压(V)
+     */
+    private Float batteryVoltage;
+
+    /**
+     * 车辆状态
+     */
+    private String status;
+
+    /**
+     * 运单号
+     */
+    private String wOrderNo;
+
+    /**
+     * 报警代码
+     */
+    private Integer alarmCode;
+
+}

+ 4 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/model/param/TruckInfoReq.java

@@ -21,4 +21,8 @@ public class TruckInfoReq implements Serializable {
      * 车牌号
      */
     private String truckNo;
+    /**
+     * 运单号
+     */
+    private String wOrderNo;
 }

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

@@ -0,0 +1,159 @@
+package com.sckw.transport.model.param;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * @author PC
+ */
+@Data
+public class VehiclesTrajectoryReq {
+    /**
+     * 车牌号
+     */
+    @NotBlank(message = "车牌号truckNo不能为空")
+    private String truckNo;
+
+    /**
+     * 经度
+     */
+    @NotBlank(message = "经度longitude不能为空")
+    private String longitude;
+
+    /**
+     * 纬度
+     */
+    @NotBlank(message = "纬度latitude不能为空")
+    private String latitude;
+
+    /**
+     * 车速(km/h)
+     */
+    @NotNull(message = "车速speed不能为空")
+    private Float speed;
+
+    /**
+     * GPS状态
+     */
+    private String gpsStatus;
+    /**
+     * 行驶方向(角度)
+     */
+    private Integer direction;
+
+    /**
+     * 燃油液位(%)
+     */
+    private Float fuelLevel;
+
+    /**
+     * 里程数(km)
+     */
+    private Double mileage;
+
+    /**
+     * 发动机温度(℃)
+     */
+    private Float engineTemp;
+
+    /**
+     * 电池电压(V)
+     */
+    private Float batteryVoltage;
+
+    /**
+     * 车辆状态
+     */
+    @NotBlank(message = "车辆状态status不能为空")
+    private String status;
+
+    /**
+     * 运单号
+     */
+    @NotBlank(message = "运单号wOrderNo不能为空")
+    private String wOrderNo;
+    /**
+     * 运单状态
+     */
+    @NotBlank(message = "关联订单号lOrderNo不能为空")
+    private String lOrderNo;
+
+    /**
+     * 报警代码
+     */
+    private Integer alarmCode;
+
+    /**
+     * 车辆信息
+     */
+    private VehicleDataVO vehicleDataVO;
+
+    @Data
+    @Valid
+    public static class VehicleDataVO {
+
+        /**
+         * 车牌
+         */
+        @NotBlank(message = "车牌carNo不能为空")
+        private String carNo;
+
+        /**
+         * 车队id
+         */
+        @NotBlank(message = "车队fleetId不能为空")
+        private String fleetId;
+
+        /**
+         * 车队名称
+         */
+        private String fleetName;
+
+        /**
+         * 设备唯一id
+         */
+        private String deviceId;
+
+        /**
+         * 设备名称
+         */
+        private String deviceName;
+
+        /**
+         * 区域ID
+         */
+        private String groupId;
+
+        /**
+         * 区域名称
+         */
+        private String groupName;
+
+        /**
+         * 业务ID
+         */
+        private String bizId;
+
+        /**
+         * 业务名称
+         */
+        private String bizName;
+
+        /**
+         * 项目ID
+         */
+        private String projectId;
+
+        /**
+         * 项目名称
+         */
+        private String projectName;
+
+        /**
+         * 租户id
+         */
+        private String tenantId;
+    }
+}

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

@@ -14,14 +14,14 @@ import java.util.List;
 public class CurrentTaskTraceReqVo implements Serializable {
     @Serial
     private static final long serialVersionUID = -8645240848510669952L;
+    /**
+     * 运单号
+     */
+    private String wOrderNo;
     List<CurrentTaskTrace> currentTaskTraceList;
 
     @Data
     public static class CurrentTaskTrace {
-        /**
-         * 运单号
-         */
-        private String wOrderNo;
         /**
          * 经度
          */

+ 22 - 0
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/repository/KwtWaybillOrderSubtaskRepository.java

@@ -0,0 +1,22 @@
+package com.sckw.transport.repository;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.core.model.base.BaseModel;
+import com.sckw.transport.dao.KwtWaybillOrderSubtaskMapper;
+import com.sckw.transport.model.KwtWaybillOrderSubtask;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author PC
+ */
+@Repository
+public class KwtWaybillOrderSubtaskRepository extends ServiceImpl<KwtWaybillOrderSubtaskMapper, KwtWaybillOrderSubtask> {
+    public KwtWaybillOrderSubtask findOneByWOrderNo(String wOrderNo) {
+       return getOne(Wrappers.<KwtWaybillOrderSubtask>lambdaQuery()
+                .eq(BaseModel::getDelFlag,0)
+                .eq(KwtWaybillOrderSubtask::getWOrderNo,wOrderNo)
+                .orderByDesc(KwtWaybillOrderSubtask::getId)
+                 .last("limit 1"));
+    }
+}

+ 168 - 36
sckw-modules/sckw-transport/src/main/java/com/sckw/transport/service/kwfTruckTraceService.java

@@ -6,10 +6,13 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.sckw.contract.api.RemoteContractService;
 import com.sckw.core.exception.BusinessException;
+import com.sckw.core.model.constant.UrlConstants;
 import com.sckw.core.model.enums.CarWaybillEnum;
 import com.sckw.core.model.page.PageResult;
 
+import com.sckw.transport.common.config.UrlConfigProperties;
 import com.sckw.core.utils.DateUtils;
+import com.sckw.core.utils.HttpUtil;
 import com.sckw.core.web.constant.CommonConstants;
 import com.sckw.fleet.api.RemoteFleetService;
 import com.sckw.fleet.api.model.vo.RTruckVo;
@@ -23,22 +26,30 @@ import com.sckw.system.api.RemoteSystemService;
 import com.sckw.system.api.model.dto.res.KwsEnterpriseResDto;
 import com.sckw.transport.model.KwtWaybillOrder;
 import com.sckw.transport.model.KwtWaybillOrderAddress;
+import com.sckw.transport.model.KwtWaybillOrderSubtask;
 import com.sckw.transport.model.dto.TruckDto;
+import com.sckw.transport.model.dto.VehicleDataDTO;
+import com.sckw.transport.model.dto.VehicleReturnData;
 import com.sckw.transport.model.param.CurrentTaskTraceReq;
 import com.sckw.transport.model.param.KwfTruckTraceReplayReq;
 import com.sckw.transport.model.param.TruckInfoReq;
+import com.sckw.transport.model.param.VehiclesTrajectoryReq;
 import com.sckw.transport.model.vo.CurrentTaskTraceReqVo;
 import com.sckw.transport.model.vo.KwfTruckTraceReplayVo;
 import com.sckw.transport.model.vo.TruckInfoVo;
 import com.sckw.transport.repository.KwtWaybillOrderAddressRepository;
 import com.sckw.transport.repository.KwtWaybillOrderRepository;
+import com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
+import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 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.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -52,6 +63,8 @@ import java.util.stream.Collectors;
 public class kwfTruckTraceService {
     private final KwtWaybillOrderRepository kwtWaybillOrderRepository;
     private final KwtWaybillOrderAddressRepository kwtWaybillOrderAddressRepository;
+    private final UrlConfigProperties urlConfigProperties;
+    private final KwtWaybillOrderSubtaskRepository kwtWaybillOrderSubtaskRepository;
 
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 8000)
     RemoteSystemService remoteSystemService;
@@ -114,19 +127,25 @@ public class kwfTruckTraceService {
        return PageResult.of(page,kwfTruckTraceReplayVoList);
     }
 
-
-    private static KwfTruckTraceReplayVo getKwfTruckTraceReplayVo(KwtWaybillOrder r, Map<Long, KwsEnterpriseResDto> idAndKwsEnterpriseMap, Map<Long, List<KwtWaybillOrderAddress>> wOrderIdAndAddressMap) {
+    /**
+     * 组织轨迹回访返回数据
+     * @param waybillOrder 运单信息
+     * @param idAndKwsEnterpriseMap 企业id映射企业信息map
+     * @param wOrderIdAndAddressMap 运单id映射地址map
+     * @return 轨迹回访返回数据
+     */
+    private static KwfTruckTraceReplayVo getKwfTruckTraceReplayVo(KwtWaybillOrder waybillOrder, Map<Long, KwsEnterpriseResDto> idAndKwsEnterpriseMap, Map<Long, List<KwtWaybillOrderAddress>> wOrderIdAndAddressMap) {
 
         KwfTruckTraceReplayVo kwfTruckTraceReplay = new KwfTruckTraceReplayVo();
-        kwfTruckTraceReplay.setWOrderId(r.getId());
-        kwfTruckTraceReplay.setWOrderNo(r.getWOrderNo());
-        kwfTruckTraceReplay.setDriverName(r.getDriverName());
-        kwfTruckTraceReplay.setPhone(r.getDriverPhone());
-        kwfTruckTraceReplay.setStatus(String.valueOf(r.getStatus()));
-        kwfTruckTraceReplay.setStatusDesc(CarWaybillEnum.getName(r.getStatus()));
-        KwsEnterpriseResDto orDefault = idAndKwsEnterpriseMap.getOrDefault(r.getEntId(), new KwsEnterpriseResDto());
+        kwfTruckTraceReplay.setWOrderId(waybillOrder.getId());
+        kwfTruckTraceReplay.setWOrderNo(waybillOrder.getWOrderNo());
+        kwfTruckTraceReplay.setDriverName(waybillOrder.getDriverName());
+        kwfTruckTraceReplay.setPhone(waybillOrder.getDriverPhone());
+        kwfTruckTraceReplay.setStatus(String.valueOf(waybillOrder.getStatus()));
+        kwfTruckTraceReplay.setStatusDesc(CarWaybillEnum.getName(waybillOrder.getStatus()));
+        KwsEnterpriseResDto orDefault = idAndKwsEnterpriseMap.getOrDefault(waybillOrder.getEntId(), new KwsEnterpriseResDto());
         kwfTruckTraceReplay.setCarrier(orDefault.getFirmName());
-        List<KwtWaybillOrderAddress> addressList = wOrderIdAndAddressMap.get(r.getId());
+        List<KwtWaybillOrderAddress> addressList = wOrderIdAndAddressMap.get(waybillOrder.getId());
         addressList.forEach(e -> {
             if (Objects.equals(e.getAddressType(),1)){
                 kwfTruckTraceReplay.setStartAddress(e.getDetailAddress());
@@ -136,27 +155,27 @@ public class kwfTruckTraceService {
             }
         });
 
-        kwfTruckTraceReplay.setRelationTaskNo(Objects.nonNull(r.getLOrderId()) ? String.valueOf(r.getLOrderId()) : "");
-//        if (Objects.equals(r.getStatus(), CarWaybillEnum.WAIT_LOADING.getCode())){
-//
-//        }
-        String taskStartEndTime = DateUtils.format(r.getTaskStartTime(), DateUtils.DATE_TIME_PATTERN);
+        kwfTruckTraceReplay.setRelationTaskNo(Objects.nonNull(waybillOrder.getLOrderId()) ? String.valueOf(waybillOrder.getLOrderId()) : "");
+
+        String taskStartEndTime = DateUtils.format(waybillOrder.getTaskStartTime(), DateUtils.DATE_TIME_PATTERN);
         kwfTruckTraceReplay.setTaskStartTime(StringUtils.equals(taskStartEndTime, CommonConstants.DATE_TIME) ? StringUtils.EMPTY: taskStartEndTime);
-//        if (Objects.equals(r.getStatus(),CarWaybillEnum.COMPLETION_UNLOADING.getCode())){
-//
-//        }
-        String endStartEndTime = DateUtils.format(r.getTaskEndTime(), DateUtils.DATE_TIME_PATTERN);
+
+        String endStartEndTime = DateUtils.format(waybillOrder.getTaskEndTime(), DateUtils.DATE_TIME_PATTERN);
         kwfTruckTraceReplay.setTaskEndTime(StringUtils.equals(endStartEndTime, CommonConstants.DATE_TIME) ? StringUtils.EMPTY: endStartEndTime);
         kwfTruckTraceReplay.setWarningCount("");
         return kwfTruckTraceReplay;
     }
 
+    /**
+     * 查询车辆实时位置信息
+     * @param req 查询参数
+     * @return 车辆实时位置信息
+     */
     public TruckInfoVo queryTruckInfo(TruckInfoReq req) {
         log.info("查询车辆实时位置信息参数:{}", req);
-        //todo cxf 查询当前位置 有可能没有任务则不查询td 查询redis
-        String location;
-        if (StringUtils.isNotBlank(req.getTruckNo())){
-            return getTruckInfoVo(req.getTruckNo());
+        //先查缓存 缓存没有 在查询数据中台 数据中台没有 则查询中交
+        if (StringUtils.isNotBlank(req.getTruckNo()) && StringUtils.isNotBlank(req.getTruckNo())){
+            return getTruckInfo(req.getTruckNo(),req.getWOrderNo());
         }
 
         //如果车牌为空那么查询车队的第一条数据 (从tab页面直接进来)
@@ -167,43 +186,156 @@ public class kwfTruckTraceService {
         if (Objects.isNull(dataFirstTruck) || Objects.isNull(dataFirstTruck.getTruckNo())){
             return new TruckInfoVo();
         }
-        return getTruckInfoVo(dataFirstTruck.getTruckNo());
+        return getTruckInfo(dataFirstTruck.getTruckNo(),"");
     }
 
-    private static TruckInfoVo getTruckInfoVo(String truckNo) {
-        String location = RedissonUtils.getString(CommonConstants.TRUCK_LOCATION + truckNo);
+    private TruckInfoVo getTruckInfo(String truckNo, String wOrderNo) {
+        //先查询缓存 如果缓存没有就查数据中台 数据中台没有就查中交
+        String location = RedissonUtils.getString(CommonConstants.TRUCK_LOCATION + truckNo+CommonConstants.UNDERSCORE+wOrderNo);
         if (StringUtils.isBlank(location)){
-            //todo cxf 查询中交运车辆位置
             return new TruckInfoVo();
         }
         TruckDto truckDto = JSON.parseObject(location, TruckDto.class);
         //如果运单号为空那么返回redis的数据 这个数据是app最后一次上报的数据
-        if (Objects.nonNull(truckDto) && StringUtils.isBlank(truckDto.getWOrderNo())){
-           return TruckInfoVo.toTruckInfoVo(truckDto);
+        if (Objects.nonNull(truckDto)){
+            return TruckInfoVo.toTruckInfoVo(truckDto);
         }
-        //如果车牌不为空直接查询 查缓存
-        if (StringUtils.isNotBlank(truckDto.getWOrderNo())){
-            //todo cxf 查询中交
-            return new TruckInfoVo();
+        //缓存没有则查询数据中台
+        List<VehicleReturnData> vehicleReturnData = getVehicleReturnData(wOrderNo);
+        if (CollectionUtils.isNotEmpty(vehicleReturnData)){
+            return buildTruckInfo(wOrderNo, vehicleReturnData);
         }
-        return null;
+        //todo 查询中交 如果数据中台没有数据则查询中交
+        return new TruckInfoVo();
+    }
+
+    /**
+     * 将数据中台的数据进行组织
+     * @param wOrderNo 运单号
+     * @param vehicleReturnData 中台数据
+     * @return 组织的数据
+     */
+    private TruckInfoVo buildTruckInfo(String wOrderNo, List<VehicleReturnData> vehicleReturnData) {
+        VehicleReturnData vehicleReturn = vehicleReturnData.get(0);
+        TruckInfoVo truckInfoVo = TruckInfoVo.getInstance();
+        truckInfoVo.setWOrderNo(vehicleReturn.getWOrderNo());
+        truckInfoVo.setTruckNo(vehicleReturn.getCarNo());
+        truckInfoVo.setGpsStatus(String.valueOf(vehicleReturn.getSpeed()));
+        truckInfoVo.setLongitude(vehicleReturn.getLongitude());
+        truckInfoVo.setLatitude(vehicleReturn.getLatitude());
+        truckInfoVo.setLocationTime(Objects.isNull(vehicleReturn.getTs())? "" : DateUtils.format(vehicleReturn.getTs(),DateUtils.DATE_TIME_PATTERN));
+        KwtWaybillOrderSubtask subtask = kwtWaybillOrderSubtaskRepository.findOneByWOrderNo(wOrderNo);
+        truckInfoVo.setLOrderNo(Objects.isNull(subtask) ? "" : String.valueOf(subtask.getLOrderId()));
+        truckInfoVo.setTaskAddress("");
+        return truckInfoVo;
     }
 
+    /**
+     * 查询当前任务的轨迹
+     * @param req 请求参数
+     * @return 响应参数
+     */
     public CurrentTaskTraceReqVo queryCurrentTaskTrace(CurrentTaskTraceReq req) {
         log.info("查询当前任务轨迹参数:{}", req);
         if (StringUtils.isBlank(req.getWOrderNo())){
             log.info("运单号为空没有任务,没有关联路线");
             return new CurrentTaskTraceReqVo();
         }
-        //cxf todo 查询车辆td数据库
-        return new CurrentTaskTraceReqVo();
+        //查询数据中台获取轨迹
+        List<VehicleReturnData> vehicleReturnDataList = getVehicleReturnData(req.getWOrderNo());
+        if (CollectionUtils.isEmpty(vehicleReturnDataList)){
+            return new CurrentTaskTraceReqVo();
+        }
+        //组织返回数据
+        List<CurrentTaskTraceReqVo.CurrentTaskTrace> currentTaskTraceList = vehicleReturnDataList.stream()
+                .map(kwfTruckTraceService::getCurrentTaskTrace)
+                .collect(Collectors.toList());
+        CurrentTaskTraceReqVo currentTaskTraceReqVo = new CurrentTaskTraceReqVo();
+        currentTaskTraceReqVo.setWOrderNo(vehicleReturnDataList.get(0).getWOrderNo());
+        currentTaskTraceReqVo.setCurrentTaskTraceList(currentTaskTraceList);
+        return currentTaskTraceReqVo;
     }
 
+    /**
+     * 查询数据中台获取轨迹
+     * @param wOrderNo 运单号
+     * @return 轨迹数据
+     */
+    private List<VehicleReturnData> getVehicleReturnData(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);
+        } catch (Exception e) {
+            log.error("查询任务轨迹异常",e);
+            throw new BusinessException("查询任务轨迹异常");
+        }
+        if (StringUtils.isBlank(s)){
+            return Collections.emptyList();
+        }
+        return JSON.parseArray(s, VehicleReturnData.class);
+    }
+
+    private static CurrentTaskTraceReqVo.CurrentTaskTrace getCurrentTaskTrace(VehicleReturnData e) {
+        CurrentTaskTraceReqVo.CurrentTaskTrace currentTaskTrace = new CurrentTaskTraceReqVo.CurrentTaskTrace();
+        currentTaskTrace.setLongitude(e.getLongitude());
+        currentTaskTrace.setLatitude(e.getLatitude());
+        currentTaskTrace.setLocationTime(Objects.isNull(e.getTs()) ? "" : DateUtils.format(e.getTs(), DateUtils.DATE_TIME_PATTERN));
+        return currentTaskTrace;
+    }
+
+    /**
+     * 查询车辆轨迹
+     * @param req 轨迹参数
+     * @return 轨迹数据
+     */
     public CurrentTaskTraceReqVo queryCurrentTruckTrace(CurrentTaskTraceReq req) {
+        log.info("查询车辆轨迹参数:{}", req);
         if (StringUtils.isBlank(req.getTruckNo())){
             throw  new BusinessException("车牌号不能为空");
         }
         //cxf todo 查询车辆td数据库
+
         return new CurrentTaskTraceReqVo();
     }
+
+    /**
+     * 上报车辆轨迹
+     * @param req 请求参数
+     * @return 响应参数
+     */
+    public Void vehiclesTrajectory(@Valid VehiclesTrajectoryReq req) {
+        try {
+            HttpUtil.postJson(urlConfigProperties.getApiBaseUrl()+ UrlConstants.VEHICLE_TRAJECTORY, JSON.toJSONString(req), null);
+        } catch (Exception e) {
+            log.error("app上报车辆轨迹异常",e);
+            throw new BusinessException("app上报车辆轨迹异常");
+        }
+        //先删除缓存
+        RedissonUtils.delete(CommonConstants.TRUCK_LOCATION + req.getTruckNo()+CommonConstants.UNDERSCORE+req.getWOrderNo());
+        //组织缓存数据
+        TruckDto truckDto = getTruckDto(req);
+        //放入缓存
+        RedissonUtils.add(CommonConstants.TRUCK_LOCATION + req.getTruckNo()+CommonConstants.UNDERSCORE+req.getWOrderNo(),JSON.toJSONString(truckDto));
+        return null;
+    }
+
+    /**
+     * 组织返回数据
+     * @param req 请求参数
+     * @return 缓存数据
+     */
+    private static TruckDto getTruckDto(VehiclesTrajectoryReq req) {
+        TruckDto truckDto = new TruckDto();
+        truckDto.setWOrderNo(req.getWOrderNo());
+        truckDto.setTruckNo(req.getTruckNo());
+        truckDto.setGpsStatus(String.valueOf(req.getSpeed()));
+        truckDto.setLongitude(req.getLongitude());
+        truckDto.setLatitude(req.getLatitude());
+        truckDto.setLocationTime(DateUtils.format(LocalDateTime.now(), DateUtils.DATE_TIME_PATTERN));
+        truckDto.setLOrderNo(req.getLOrderNo());
+        truckDto.setTaskAddress("");
+        return truckDto;
+    }
 }