Prechádzať zdrojové kódy

增加轨迹核验接口

15810770710@163.com 3 rokov pred
rodič
commit
c66fbe6d10

+ 37 - 1
src/main/java/info/aspirecn/iov/sjjh/action/VehicleAction.java

@@ -3,6 +3,7 @@ package info.aspirecn.iov.sjjh.action;
 import info.aspirecn.iov.sjjh.commons.lang.ChannelTypeHandleResponseObject;
 import info.aspirecn.iov.sjjh.commons.lang.Constant;
 import info.aspirecn.iov.sjjh.constant.Constants;
+import info.aspirecn.iov.sjjh.enums.VehicleHistoryPositionQueryType;
 import info.aspirecn.iov.sjjh.service.VehicleService;
 import info.aspirecn.rdc.aspirecloud.node.except.utils.ErrorUtils;
 import io.swagger.annotations.ApiOperation;
@@ -39,7 +40,42 @@ public class VehicleAction {
                 .getRequest();
 
         //调用service
-        ChannelTypeHandleResponseObject ret = vehicleService.vehicleHistoryPositionQuery(request, customBody, outTime);
+        ChannelTypeHandleResponseObject ret = vehicleService.vehicleHistoryPositionQuery(request, customBody, outTime,
+                VehicleHistoryPositionQueryType.VEHICLE_HISTORY_POSITION_QUERY.getValue());
+
+        //把接口参数、调用结果和是否收费放入访问日志中
+        if(ret.getCode() != Constant.SUCCESS) {
+            request.setAttribute(Constants.Charge_Log_ResponseCode, Constant.CHANNEL_LOG_ERROR_CODE);
+        } else {
+            request.setAttribute(Constants.Charge_Log_ResponseCode, Constant.CHANNEL_LOG_SUCCESS_CODE);
+        }
+        request.setAttribute(Constants.Charge_Log_Key, ret.getIsCharge());
+
+        try {
+            request.setAttribute(Constant.CHANNEL_LOG_QUERY,
+                    Base64.encodeBase64String(customBody.getBytes(Constants.ENCODING)));
+
+        } catch (Exception ex) {
+            ErrorUtils.captureException(ex);
+            log.error("vehicleHistoryPositionQuery.encodeBase64String.Exception={}", ex);
+        }
+
+        request.setAttribute(Constant.CHANNEL_TYPE_KEY,Constant.CHANNEL_TYPE_SYNC);
+        return ret;
+    }
+
+    @ApiOperation(value = "车辆线上线下一致性验证接口", notes = "")
+    @PostMapping(value = "/vehiclePositionConsistencyCheck.do")
+    public ChannelTypeHandleResponseObject vehiclePositionConsistencyCheck(
+            @ApiParam(value="通道ID")@RequestHeader(name="channelId")  String channelId,
+            @ApiParam(value="超时时间,单位:毫秒",example = "10000")@RequestParam(name = "outTime", required = true) int outTime,
+            @ApiParam(value="请求参数JSON串")@RequestParam(name = "customBody", required = true) String customBody) {
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
+                .getRequest();
+
+        //调用service
+        ChannelTypeHandleResponseObject ret = vehicleService.vehicleHistoryPositionQuery(request, customBody, outTime,
+                VehicleHistoryPositionQueryType.VEHICLE_POSITION_CONSISTENCY_CHECK.getValue());
 
         //把接口参数、调用结果和是否收费放入访问日志中
         if(ret.getCode() != Constant.SUCCESS) {

+ 1 - 3
src/main/java/info/aspirecn/iov/sjjh/constant/Constants.java

@@ -26,8 +26,6 @@ public class Constants {
     public static final String HMAC_SHA256 = "HmacSHA256";
     // 编码UTF-8
     public static final String ENCODING = "UTF-8";
-    // UserAgent
-    public static final String USER_AGENT = "demo/aliyun/java";
     // 换行符
     public static final String LF = "\n";
     // 串联符
@@ -56,5 +54,5 @@ public class Constants {
     public static final String NO_RESULT = "查询成功,查无结果";
     public static String Charge_Log_Key="isCharge";
     public static String Charge_Log_ResponseCode="respnoseCode";
-    public static String Charge_Log_Up_ResponseCode="upResponseCode";
+
 }

+ 17 - 0
src/main/java/info/aspirecn/iov/sjjh/enums/CommonEnumStatus.java

@@ -0,0 +1,17 @@
+package info.aspirecn.iov.sjjh.enums;
+
+import info.aspirecn.iov.sjjh.enums.base.EnumStatus;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum CommonEnumStatus implements EnumStatus {
+    /**
+     * 未知状态
+     */
+    UNKNOWN_STATUS(-1, "未知状态");
+
+    private Integer value;
+    private String desc;
+}

+ 19 - 0
src/main/java/info/aspirecn/iov/sjjh/enums/VehicleHistoryPositionQueryType.java

@@ -0,0 +1,19 @@
+package info.aspirecn.iov.sjjh.enums;
+
+import info.aspirecn.iov.sjjh.enums.base.EnumStatus;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author xusonglin
+ * @version V1.0
+ **/
+@Getter
+@AllArgsConstructor
+public enum VehicleHistoryPositionQueryType implements EnumStatus {
+    VEHICLE_HISTORY_POSITION_QUERY(1, "车辆轨迹核验"),
+    VEHICLE_POSITION_CONSISTENCY_CHECK(2, "车辆线上线下一致性验证");
+
+    private Integer value;
+    private String desc;
+}

+ 18 - 0
src/main/java/info/aspirecn/iov/sjjh/enums/base/EnumStatus.java

@@ -0,0 +1,18 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package info.aspirecn.iov.sjjh.enums.base;
+
+
+import info.aspirecn.iov.sjjh.util.EnumStatusUtils;
+
+public interface EnumStatus extends IEnumStatus<Integer> {
+
+    static EnumStatus getEnumStatus(Class<?> typeClass, int value) {
+        EnumStatus status = EnumStatusUtils.getStatusByValue(typeClass, value);
+        return status;
+    }
+
+}

+ 23 - 0
src/main/java/info/aspirecn/iov/sjjh/enums/base/IEnumStatus.java

@@ -0,0 +1,23 @@
+package info.aspirecn.iov.sjjh.enums.base;
+
+/**
+ * @description:
+ * @author: xusonglin
+ * @create: 2020/1/9 10:58
+ * @version: V1.0
+ **/
+public interface IEnumStatus<T> {
+    /**
+     * 获取枚举值
+     *
+     * @return 枚举值
+     */
+    T getValue();
+
+    /**
+     * 获取枚举描述
+     *
+     * @return 枚举描述
+     */
+    String getDesc();
+}

+ 2 - 1
src/main/java/info/aspirecn/iov/sjjh/service/VehicleService.java

@@ -1,6 +1,7 @@
 package info.aspirecn.iov.sjjh.service;
 
 import info.aspirecn.iov.sjjh.commons.lang.ChannelTypeHandleResponseObject;
+import info.aspirecn.iov.sjjh.enums.VehicleHistoryPositionQueryType;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -14,5 +15,5 @@ public interface VehicleService {
      * 车辆历史轨迹
      */
     ChannelTypeHandleResponseObject vehicleHistoryPositionQuery(HttpServletRequest request, String customBody,
-                                                                        int outTime);
+                                                                        int outTime, Integer type);
 }

+ 117 - 28
src/main/java/info/aspirecn/iov/sjjh/service/impl/VehicleServiceImpl.java

@@ -12,6 +12,7 @@ import info.aspirecn.iov.sjjh.entity.Response;
 import info.aspirecn.iov.sjjh.entity.VehicleHistoryPositionRequestParam;
 import info.aspirecn.iov.sjjh.entity.VehicleHistoryPositionResponse;
 import info.aspirecn.iov.sjjh.entity.geocoding.GeocodingResponseObject;
+import info.aspirecn.iov.sjjh.enums.VehicleHistoryPositionQueryType;
 import info.aspirecn.iov.sjjh.service.VehicleService;
 import info.aspirecn.iov.sjjh.util.DateUtil;
 import info.aspirecn.iov.sjjh.util.PostUtil;
@@ -45,7 +46,8 @@ public class VehicleServiceImpl implements VehicleService {
     private OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
 
     @Override
-    public ChannelTypeHandleResponseObject vehicleHistoryPositionQuery(HttpServletRequest request, String customBody, int outTime) {
+    public ChannelTypeHandleResponseObject vehicleHistoryPositionQuery(HttpServletRequest request, String customBody,
+                                                                       int outTime, Integer type) {
         ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
         ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
         ret.setCode(Constant.SUCCESS);
@@ -100,7 +102,15 @@ public class VehicleServiceImpl implements VehicleService {
             ErrorUtils.captureException(e);
             ret.setCode(Constant.FAIL);
         }
-        upstreamCode = setVehicleHistoryPositionQueryResponse(ret, response, requestParam);
+        if (type.equals(VehicleHistoryPositionQueryType.VEHICLE_HISTORY_POSITION_QUERY.getValue())) {
+            // 车辆轨迹核验
+            upstreamCode = setVehicleHistoryPositionQueryResponse(ret, response, requestParam);
+        } else {
+            // 车辆线上线下一致性验证
+            upstreamCode = setVehiclePositionConsistencyCheckResponse(ret, response, requestParam);
+        }
+
+
         request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
         return ret;
     }
@@ -116,7 +126,7 @@ public class VehicleServiceImpl implements VehicleService {
             upstreamCode = positionResponse.getResultCode();
             if (positionResponse.getResultCode().equals(Constants.RESULT_CODE_0)) {
                 if (positionResponse.getData() != null && positionResponse.getData().size() > 0) {
-                    String result = vehicleHistoryPositionQueryByBaidu(positionResponse.getData(), requestParam);
+                    String result = vehicleHistoryPositionQuery(positionResponse.getData(), requestParam);
                     if (StringUtils.isBlank(result)) {
                         JSONObject vehicleLocationInfo = new JSONObject();
                         vehicleLocationInfo.put("vehicleLocationInfo", positionResponse.getData());
@@ -152,7 +162,7 @@ public class VehicleServiceImpl implements VehicleService {
         return upstreamCode;
     }
 
-    private String vehicleHistoryPositionQueryByBaidu(List<VehicleHistoryPositionResponse.Data> positionList,
+    private String vehicleHistoryPositionQuery(List<VehicleHistoryPositionResponse.Data> positionList,
                                                     VehicleHistoryPositionRequestParam requestParam) {
         /**
          * 1、云雁调取A-到B+之间所有的车辆轨迹(每30秒有一个经纬度数据)。
@@ -237,32 +247,111 @@ public class VehicleServiceImpl implements VehicleService {
         }
     }
 
-    /**
-     * 校验省区划代码是否一致
-     */
-    private Boolean getGeocodingCheck(int outTime, String location,String adcode) {
-        try {
-            ObjectMapper objectMapper = new ObjectMapper();
-            String requestUrl = supplierConfig.getBaiduUrl() + "?ak="+ supplierConfig.getBaiduAk()
-                    + "&output=json&coordtype=wgs84ll&location=" + location;
-            Request okRequest = new Request.Builder().get().url(requestUrl).build();
-            OkHttpClient client = okHttpClient.newBuilder().connectTimeout(outTime, TimeUnit.MILLISECONDS)
-                    .readTimeout(outTime, TimeUnit.MILLISECONDS).writeTimeout(outTime, TimeUnit.MILLISECONDS).build();
-            okhttp3.Response response = client.newCall(okRequest).execute();
-            String responseContext = response.body().string();
-            GeocodingResponseObject responseObject = objectMapper.readValue(responseContext,
-                    GeocodingResponseObject.class);
-            log.info("supplier-vehicle.getGeocodingCheck.responseObject={}", responseContext);
-            if (responseObject!=null) {
-                if (responseObject.getStatus()==0&&adcode.equals(responseObject.getResult().getAddressComponent().getAdcode())) {
-                    return true;
+    private String setVehiclePositionConsistencyCheckResponse(ChannelTypeHandleResponseObject ret, Response response,
+                                                          VehicleHistoryPositionRequestParam requestParam) {
+        String upstreamCode = "";
+        log.info("supplier-vehicle.vehicleHistoryPositionCheck-responseStatus:{}", response.getStatusCode());
+        log.info("supplier-vehicle.vehicleHistoryPositionCheck-responseBody:{}", response.getBody());
+        if (response.getStatusCode() == Constants.STATUS_CODE_200) {
+            VehicleHistoryPositionResponse positionResponse = JSON.toJavaObject(JSON.parseObject(response.getBody()),
+                    VehicleHistoryPositionResponse.class);
+            upstreamCode = positionResponse.getResultCode();
+            if (positionResponse.getResultCode().equals(Constants.RESULT_CODE_0)) {
+                if (positionResponse.getData() != null && positionResponse.getData().size() > 0) {
+                    String result = vehiclePositionConsistencyCheck(positionResponse.getData(), requestParam);
+                    if (StringUtils.isBlank(result)) {
+                        ret.setResultCode(Constant.MATCH_CODE);
+                        ret.setResultBody(Constant.MATCH);
+                        ret.setResultDesc(Constant.QUERY_SUCCESS);
+                    } else {
+                        ret.setResultCode(Constant.UN_MATCH_CODE);
+                        ret.setResultBody(result);
+                        ret.setResultDesc(Constant.QUERY_SUCCESS);
+                    }
+                } else {
+                    ret.setResultCode(Constant.UN_FIND_NUM_CODE);
+                    ret.setResultBody(Constants.NO_RESULT);
+                    ret.setResultDesc(Constants.NO_RESULT);
+                }
+                ret.setIsCharge(Constant.IS_CHARGE);
+            } else if (positionResponse.getResultCode().equals(Constants.RESULT_CODE_110000)) {
+                ret.setResultCode(Constant.UN_FIND_NUM_CODE);
+                ret.setResultBody(Constants.NO_RESULT);
+                ret.setResultDesc(Constants.NO_RESULT);
+            } else {
+                ret.setResultCode(Constant.OTHER_ERROR_CODE);
+                ret.setResultBody(Constant.OTHER_ERROR);
+                ret.setResultDesc(Constant.OTHER_ERROR);
+            }
+        } else {
+            ret.setResultCode(Constant.OTHER_ERROR_CODE);
+            ret.setResultBody(Constant.OTHER_ERROR);
+            ret.setResultDesc(Constant.OTHER_ERROR);
+            upstreamCode += response.getStatusCode();
+        }
+        return upstreamCode;
+    }
+
+    private String vehiclePositionConsistencyCheck(List<VehicleHistoryPositionResponse.Data> positionList,
+                                               VehicleHistoryPositionRequestParam requestParam) {
+        /**
+         * 1、云雁调取A-到B+之间的车辆轨迹
+         * 2、将B点与B-到B+时间点内的行政区划代码做对比,得出比对结果一
+         *    将A点与A-到A+时间点内的行政区划代码做对比,得出比对结果二
+         * 3、核验结果有一个不一致的情况下返回不一致结果
+         * 4、核验结果一致的情况下一致结果
+         */
+        // A-
+        String startTimeA = DateUtil.addHours(requestParam.getStartTime(), supplierConfig.getReduceHours());
+        // B-
+        String startTimeB = DateUtil.addHours(requestParam.getEndTime(), supplierConfig.getReduceHours());
+
+        // 4小时*2=8小时(A-A+间隔),8小时*2=16个点(每半个小时取1个点)
+        int pointNumber = supplierConfig.getAddHours()*2*2;
+
+        List<String> checkTimeListA = new ArrayList<>();
+        String tempStartTime = startTimeA;
+        for (int i = 0; i < pointNumber+1; i++) {
+            checkTimeListA.add(tempStartTime);
+            tempStartTime = DateUtil.addMinutes(tempStartTime, 30);
+        }
+
+        List<String> checkTimeListB = new ArrayList<>();
+        tempStartTime = startTimeB;
+        for (int i = 0; i < pointNumber+1; i++) {
+            checkTimeListB.add(tempStartTime);
+            tempStartTime = DateUtil.addMinutes(tempStartTime, 30);
+        }
+
+        // todo 这个集合为了查看位置是否正确
+        List<VehicleHistoryPositionResponse.Data> verificationPositionListA = new ArrayList<>();
+        for (int i = 0; i < checkTimeListA.size()-1; i++) {
+            for (VehicleHistoryPositionResponse.Data position : positionList) {
+                if (Long.parseLong(position.getPositionTime()) > Long.parseLong(checkTimeListA.get(i))
+                        && Long.parseLong(position.getPositionTime()) <= Long.parseLong(checkTimeListA.get(i+1))) {
+                    verificationPositionListA.add(position);
+                    if (!requestParam.getLoadingCountrySubdivisionCode().equals(position.getPositionDescribe())) {
+                        return "loadingCountrySubdivisionCode";
+                    }
+                    break;
+                }
+            }
+        }
+
+        // todo 这个集合为了查看位置是否正确
+        List<VehicleHistoryPositionResponse.Data> verificationPositionListB = new ArrayList<>();
+        for (int i = 0; i < checkTimeListB.size()-1; i++) {
+            for (VehicleHistoryPositionResponse.Data position : positionList) {
+                if (Long.parseLong(position.getPositionTime()) > Long.parseLong(checkTimeListB.get(i))
+                        && Long.parseLong(position.getPositionTime()) <= Long.parseLong(checkTimeListB.get(i+1))) {
+                    verificationPositionListB.add(position);
+                    if (!requestParam.getReceiptCountrySubdivisionCode().equals(position.getPositionDescribe())) {
+                        return "receiptCountrySubdivisionCode";
+                    }
+                    break;
                 }
             }
-            return false;
-        } catch (Exception e) {
-            ErrorUtils.captureException(e);
-            log.info("supplier-vehicle.Exception.e={}", e);
         }
-        return false;
+        return "";
     }
 }

+ 41 - 0
src/main/java/info/aspirecn/iov/sjjh/util/EnumStatusUtils.java

@@ -0,0 +1,41 @@
+package info.aspirecn.iov.sjjh.util;
+
+import info.aspirecn.iov.sjjh.enums.CommonEnumStatus;
+import info.aspirecn.iov.sjjh.enums.base.EnumStatus;
+import lombok.NoArgsConstructor;
+
+
+@NoArgsConstructor
+public final class EnumStatusUtils {
+
+    public static EnumStatus getStatusByValue(Class<?> enums, Integer value) {
+        if (enums.isEnum()) {
+            Object[] statuses = enums.getEnumConstants();
+
+            for (Object o : statuses) {
+                EnumStatus status = (EnumStatus) o;
+                if (status.getValue().equals(value)) {
+                    return status;
+                }
+            }
+        }
+
+        return CommonEnumStatus.UNKNOWN_STATUS;
+    }
+
+    public static EnumStatus getStatusByDesc(Class<?> enums, String desc) {
+        if (enums.isEnum()) {
+            Object[] statuses = enums.getEnumConstants();
+
+            for (Object o : statuses) {
+                EnumStatus status = (EnumStatus) o;
+                if (status.getDesc().equals(desc)) {
+                    return status;
+                }
+            }
+        }
+
+        return CommonEnumStatus.UNKNOWN_STATUS;
+    }
+
+}