8 Commits 286df7e4ae ... 67c05b317e

Author SHA1 Message Date
  FanQun 67c05b317e 新增 swagger 3 2 years ago
  FanQun 4b99f001d1 新增 IT服务平台 警察叔叔身份证查询接口 和 查询行程码记录接口 2 years ago
  FanQun 74e5f312bc 新增 IT服务平台 警察叔叔身份证查询接口 和 查询行程码记录接口 2 years ago
  FanQun c65be2be7f 更新新的核酸接口 2 years ago
  FanQun 48229353e4 fastjson 更新到 1.2.83 2 years ago
  FanQun 89e3157170 容器换 Jetty 2 years ago
  FanQun e124293d4e 容器换 Jetty 2 years ago
  FanQun 65a8bc9c7c 普通核验接口异步处理,提高并发能力 2 years ago
27 changed files with 767 additions and 182 deletions
  1. 19 2
      pom.xml
  2. 1 4
      src/main/java/com/rshy/project/hy/aop/ExceptionAdvice.java
  3. 1 1
      src/main/java/com/rshy/project/hy/baseRe/BaseException.java
  4. 7 7
      src/main/java/com/rshy/project/hy/baseRe/Ret.java
  5. 123 0
      src/main/java/com/rshy/project/hy/config/SwaggerConfig.java
  6. 2 2
      src/main/java/com/rshy/project/hy/config/SwaggerConfiguration.java
  7. 82 0
      src/main/java/com/rshy/project/hy/config/SwaggerProperties.java
  8. 21 0
      src/main/java/com/rshy/project/hy/config/properties/PctsfzProperties.java
  9. 21 0
      src/main/java/com/rshy/project/hy/config/properties/PctxcmProperties.java
  10. 1 1
      src/main/java/com/rshy/project/hy/manager/RshyJkManager.java
  11. 47 53
      src/main/java/com/rshy/project/hy/manager/impl/RshyJkManagerImpl.java
  12. 12 0
      src/main/java/com/rshy/project/hy/model/constant/ItfwConstant.java
  13. 5 0
      src/main/java/com/rshy/project/hy/model/dto/NucleicAcidDTO.java
  14. 6 4
      src/main/java/com/rshy/project/hy/model/enums/NucleicAcidEnum.java
  15. 3 2
      src/main/java/com/rshy/project/hy/model/enums/PassStatusEnum.java
  16. 193 55
      src/main/java/com/rshy/project/hy/server/ItfwServer.java
  17. 1 0
      src/main/java/com/rshy/project/hy/server/dto/PcthsDTO.java
  18. 24 24
      src/main/java/com/rshy/project/hy/server/dto/PcthsResultDTO.java
  19. 22 0
      src/main/java/com/rshy/project/hy/server/dto/PctsfzParamDTO.java
  20. 39 0
      src/main/java/com/rshy/project/hy/server/dto/PctsfzResultDTO.java
  21. 24 0
      src/main/java/com/rshy/project/hy/server/dto/PctxcmParamDTO.java
  22. 37 0
      src/main/java/com/rshy/project/hy/server/dto/PctxcmResultDTO.java
  23. 4 0
      src/main/java/com/rshy/project/hy/server/dto/ResultDTO.java
  24. 26 18
      src/main/java/com/rshy/project/hy/web/controller/RshyController.java
  25. 19 1
      src/main/resources/application-local.yml
  26. 19 3
      src/main/resources/application-prod.yml
  27. 8 5
      src/main/resources/application.yml

+ 19 - 2
pom.xml

@@ -28,12 +28,29 @@
         <dependency>
             <groupId>com.github.xiaoymin</groupId>
             <artifactId>knife4j-spring-boot-starter</artifactId>
-            <version>2.0.7</version>
+            <version>3.0.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <!-- 去除Tomcat容器 -->
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- 增加Jetty容器 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jetty</artifactId>
         </dependency>
 
         <dependency>
@@ -119,7 +136,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.80</version>
+            <version>1.2.83</version>
         </dependency>
         <dependency>
             <groupId>junit</groupId>

+ 1 - 4
src/main/java/com/rshy/project/hy/aop/ExceptionAdvice.java

@@ -63,9 +63,6 @@ public class ExceptionAdvice {
     @ExceptionHandler(value = BaseException.class)
     public Ret<?> handle(BaseException e) {
         log.error(e.getMessage(), e);
-        if (e.getCode() != null) {
-            return Ret.error(e.getCode(), e.getMessage());
-        }
         return Ret.error(e.getCode(), e.getMessage());
     }
 
@@ -86,7 +83,7 @@ public class ExceptionAdvice {
     }
 
     @ExceptionHandler(HttpMessageNotReadableException.class)
-    public Ret<?> httperrMsgNotReadableExceptionHandler(HttpMessageNotReadableException e) {
+    public Ret<?> httpMsgNotReadableExceptionHandler(HttpMessageNotReadableException e) {
         log.error("参数格式错误:" + e.getMessage(), e);
         if (env.equals(EnvEnum.PRODUCT.getCode())) {
             return Ret.error(10001, "参数错误");

+ 1 - 1
src/main/java/com/rshy/project/hy/baseRe/BaseException.java

@@ -21,7 +21,7 @@ public class BaseException extends RuntimeException {
     /**
      * 错误明细,内部调试错误
      * <p>
-     * 和 {@link Ret#getDetailerrMsg()} 一致的设计
+     * 和 {@link Ret#getErrDetailMsg()} 一致的设计
      */
     private String detailerrMsg;
 

+ 7 - 7
src/main/java/com/rshy/project/hy/baseRe/Ret.java

@@ -33,7 +33,7 @@ public final class Ret<T> implements Serializable {
     /**
      * 错误明细,内部调试错误
      */
-    private String detailerrMsg;
+    private String errDetailMsg;
 
     /**
      * 返回数据
@@ -63,17 +63,17 @@ public final class Ret<T> implements Serializable {
         return error(code, errMsg, null);
     }
 
-    public static <T> Ret<T> error(Integer code, String errMsg, String detailerrMsg) {
+    public static <T> Ret<T> error(Integer code, String errMsg, String detailedMsg) {
         Assert.isTrue(!SUCCESSFUL_CODE.equals(code), "code 必须是错误的!");
         Ret<T> result = new Ret<>();
         result.errCode = code;
         result.errMsg = errMsg;
-        result.detailerrMsg = detailerrMsg;
+        result.errDetailMsg = detailedMsg;
         return result;
     }
 
-    public Ret<T> setDetailerrMsg(String detailerrMsg) {
-        this.detailerrMsg = detailerrMsg;
+    public Ret<T> setErrDetailMsg(String errDetailMsg) {
+        this.errDetailMsg = errDetailMsg;
         return this;
     }
 
@@ -105,7 +105,7 @@ public final class Ret<T> implements Serializable {
             return;
         }
         // 业务异常
-        throw new ServiceException(errCode, errMsg).setDetailerrMsg(detailerrMsg);
+        throw new ServiceException(errCode, errMsg).setDetailerrMsg(errDetailMsg);
     }
 
     public static <T> Ret<T> error(BaseException baseException) {
@@ -119,7 +119,7 @@ public final class Ret<T> implements Serializable {
                 "errCode=" + errCode +
                 ", data=" + data +
                 ", errMsg='" + errMsg + '\'' +
-                ", detailerrMsg='" + detailerrMsg + '\'' +
+                ", detailedMsg='" + errDetailMsg + '\'' +
                 '}';
     }
 

+ 123 - 0
src/main/java/com/rshy/project/hy/config/SwaggerConfig.java

@@ -0,0 +1,123 @@
+package com.rshy.project.hy.config;
+
+import io.swagger.models.auth.In;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.springframework.boot.SpringBootVersion;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * @author Simon.z
+ * @since 2020/12/30
+ */
+@Configuration
+@EnableOpenApi
+public class SwaggerConfig implements WebMvcConfigurer {
+    private final SwaggerProperties swaggerProperties;
+
+    public SwaggerConfig(SwaggerProperties swaggerProperties) {
+        this.swaggerProperties = swaggerProperties;
+    }
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.OAS_30).pathMapping("/")
+                // 定义是否开启swagger,false为关闭,可以通过变量控制
+                .enable(swaggerProperties.getEnable())
+                // 将api的元信息设置为包含在json ResourceListing响应中。
+                .apiInfo(apiInfo())
+                // 接口调试地址
+                .host(swaggerProperties.getTryHost())
+                // 选择哪些接口作为swagger的doc发布
+                .select()
+                .apis(RequestHandlerSelectors.any())
+                .paths(PathSelectors.any())
+                .build()
+                // 支持的通讯协议集合
+                .protocols(newHashSet("https", "http"))
+                // 授权信息设置,必要的header token等认证信息
+                .securitySchemes(securitySchemes())
+                // 授权信息全局应用
+                .securityContexts(securityContexts());
+    }
+
+    /**
+     * API 页面上半部分展示信息
+     *
+     * @return
+     */
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder().title(swaggerProperties.getApplicationName() + " Api Doc")
+                .description(swaggerProperties.getApplicationDescription())
+                .contact(new Contact("simple_box", null, "fq@heishitech.com"))
+                .version("Application Version: " + swaggerProperties.getApplicationVersion() + ", Spring Boot Version: " + SpringBootVersion.getVersion())
+                .build();
+    }
+
+    /**
+     * 设置授权信息
+     */
+    private List<SecurityScheme> securitySchemes() {
+        ApiKey apiKey = new ApiKey("BASE_TOKEN", "token", In.HEADER.toValue());
+        return Collections.singletonList(apiKey);
+    }
+
+    /**
+     * 授权信息全局应用
+     */
+    private List<SecurityContext> securityContexts() {
+        return Collections.singletonList(
+                SecurityContext.builder()
+                        .securityReferences(Collections.singletonList(
+                                new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{
+                                        new AuthorizationScope("global", "")})))
+                        .build()
+        );
+    }
+
+    @SafeVarargs
+    private final <T> Set<T> newHashSet(T... ts) {
+        if (ts.length > 0) {
+            return new LinkedHashSet<>(Arrays.asList(ts));
+        }
+        return null;
+    }
+
+    /**
+     * 通用拦截器排除swagger设置,所有拦截器都会自动加swagger相关的资源排除信息
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        try {
+            Field registrationsField = FieldUtils.getField(InterceptorRegistry.class, "registrations", true);
+            List<InterceptorRegistration> registrations = (List<InterceptorRegistration>) ReflectionUtils.getField(registrationsField, registry);
+            if (registrations != null) {
+                for (InterceptorRegistration interceptorRegistration : registrations) {
+                    interceptorRegistration
+                            .excludePathPatterns("/swagger**/**")
+                            .excludePathPatterns("/webjars/**")
+                            .excludePathPatterns("/v3/**")
+                            .excludePathPatterns("/doc.html");
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 2 - 2
src/main/java/com/rshy/project/hy/config/SwaggerConfiguration.java

@@ -9,8 +9,8 @@ import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spring.web.plugins.Docket;
 import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
 
-@Configuration
-@EnableSwagger2WebMvc
+//@Configuration
+//@EnableSwagger2WebMvc
 //@Configuration
 //@EnableSwagger2
 public class SwaggerConfiguration {

+ 82 - 0
src/main/java/com/rshy/project/hy/config/SwaggerProperties.java

@@ -0,0 +1,82 @@
+package com.rshy.project.hy.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Simon.z
+ * @since 2020/12/30
+ */
+@Component
+public class SwaggerProperties {
+
+    /**
+     * 是否开启swagger,生产环境一般关闭,所以这里定义一个变量
+     */
+    @Value("${swagger.enable}")
+    private Boolean enable;
+
+    /**
+     * 项目应用名
+     */
+    @Value("${swagger.application-name}")
+    private String applicationName;
+
+    /**
+     * 项目版本信息
+     */
+    @Value("${swagger.application-version}")
+    private String applicationVersion;
+
+    /**
+     * 项目描述信息
+     */
+    @Value("${swagger.application-description}")
+    private String applicationDescription;
+
+    /**
+     * 接口调试地址
+     */
+    @Value("${swagger.try-host}")
+    private String tryHost;
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public String getApplicationName() {
+        return applicationName;
+    }
+
+    public void setApplicationName(String applicationName) {
+        this.applicationName = applicationName;
+    }
+
+    public String getApplicationVersion() {
+        return applicationVersion;
+    }
+
+    public void setApplicationVersion(String applicationVersion) {
+        this.applicationVersion = applicationVersion;
+    }
+
+    public String getApplicationDescription() {
+        return applicationDescription;
+    }
+
+    public void setApplicationDescription(String applicationDescription) {
+        this.applicationDescription = applicationDescription;
+    }
+
+    public String getTryHost() {
+        return tryHost;
+    }
+
+    public void setTryHost(String tryHost) {
+        this.tryHost = tryHost;
+    }
+}

+ 21 - 0
src/main/java/com/rshy/project/hy/config/properties/PctsfzProperties.java

@@ -0,0 +1,21 @@
+package com.rshy.project.hy.config.properties;
+
+import com.rshy.project.hy.server.dto.PctsfzParamDTO;
+import com.rshy.project.hy.server.param.AgentApiParam;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Created by fanqun on 2022/5/30.
+ */
+@Data
+@Accessors(chain = true)
+@Configuration
+@ConfigurationProperties(prefix = "itfw.pctsfz")
+public class PctsfzProperties extends AgentApiParam {
+    private ItfwApiHeader header;
+
+    private PctsfzParamDTO query;
+}

+ 21 - 0
src/main/java/com/rshy/project/hy/config/properties/PctxcmProperties.java

@@ -0,0 +1,21 @@
+package com.rshy.project.hy.config.properties;
+
+import com.rshy.project.hy.server.dto.PctxcmParamDTO;
+import com.rshy.project.hy.server.param.AgentApiParam;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Created by fanqun on 2022/5/30.
+ */
+@Data
+@Accessors(chain = true)
+@Configuration
+@ConfigurationProperties(prefix = "itfw.pctxcm")
+public class PctxcmProperties extends AgentApiParam {
+    private ItfwApiHeader header;
+
+    private PctxcmParamDTO query;
+}

+ 1 - 1
src/main/java/com/rshy/project/hy/manager/RshyJkManager.java

@@ -18,7 +18,7 @@ public interface RshyJkManager {
      * @param rshyParam 核验参数
      * @return
      */
-    RshyVo getRshyInfo(RshyParam rshyParam);
+    Future<RshyVo> getRshyInfo(RshyParam rshyParam);
 
     /**
      * 人脸快速核验模式

+ 47 - 53
src/main/java/com/rshy/project/hy/manager/impl/RshyJkManagerImpl.java

@@ -26,15 +26,18 @@ import com.rshy.project.hy.server.vo.RshyVo;
 import com.rshy.project.hy.util.ObjectUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.DependsOn;
 import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.AsyncResult;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
@@ -48,20 +51,20 @@ import java.util.stream.Collectors;
 @Slf4j
 @DependsOn("itfwServer")
 public class RshyJkManagerImpl implements RshyJkManager {
-    @Autowired
+    @Resource
     private YituFaceServer yituFaceServer;
-    @Autowired
+    @Resource
     private ItfwServer itfwServer;
-    @Autowired
+    @Resource
     private VIIDServer viidServer;
-    @Autowired
+    @Resource
     private StringRedisTemplate stringRedisTemplate;
 
     @Override
-    //@Async("hstTaskExecutor")
-    public RshyVo getRshyInfo(RshyParam rshyParam) {
-        // timeout 转成毫秒 这里考虑到网络传输延时等原因,减去200ms
-        rshyParam.setTimeout((int) TimeUnit.MILLISECONDS.convert(rshyParam.getTimeout(), TimeUnit.SECONDS) - 200);
+    @Async("hstTaskExecutor")
+    public Future<RshyVo> getRshyInfo(RshyParam rshyParam) {
+        // timeout 转成毫秒 这里考虑到网络传输延时等原因,减去300ms
+        rshyParam.setTimeout((int) TimeUnit.MILLISECONDS.convert(rshyParam.getTimeout(), TimeUnit.SECONDS) - 300);
         int jkmTimeout = rshyParam.getTimeout();
         RshyVo rshyVo = new RshyVo();
         PctgkryDTO gkryDTO = new PctgkryDTO();
@@ -80,26 +83,28 @@ public class RshyJkManagerImpl implements RshyJkManager {
             }
         }
         if (jkmInfo == null) {
-            return rshyVo.setPassStatus(PassStatusEnum.NO_CODE).setSfzh(rshyParam.getSfzh()).setXm(rshyParam.getXm()).setWarning(PassStatusEnum.NO_CODE.getDesc())
-                    .setNucleic_acid(new NucleicAcidDTO().setStatus(NucleicAcidEnum.NO_DATA.getCode()).setResults(NucleicAcidEnum.NO_DATA.getDesc()));
+            return new AsyncResult<>(rshyVo.setPassStatus(PassStatusEnum.NO_HEALTH_CODE).setSfzh(rshyParam.getSfzh()).setXm(rshyParam.getXm()).setWarning(PassStatusEnum.NO_HEALTH_CODE.getDesc())
+                    .setNucleic_acid(new NucleicAcidDTO().set(NucleicAcidEnum.NO_DATA)));
         }
 
         rshyParam.setSfzh(jkmInfo.getId_num());
         rshyVo.setSfzh(jkmInfo.getId_num()).setXm(jkmInfo.getUser_name()).setHealthCode(jkmInfo.getColor_code_label()).setPhone(jkmInfo.getPn());
-        int jkmElapsedTime = (int) DateUtil.between(beginDate, DateTime.now(), DateUnit.MS);
-        System.out.println("健康码接口用时: " + jkmElapsedTime + "毫秒");
+        int jkmUsedTime = (int) DateUtil.between(beginDate, DateTime.now(), DateUnit.MS);
+        System.out.println("健康码接口用时: " + jkmUsedTime + "毫秒");
 
-        rshyParam.setTimeout(rshyParam.getTimeout() - jkmElapsedTime - 50);
+        rshyParam.setTimeout(rshyParam.getTimeout() - jkmUsedTime - 300);
         //剩余时间不到10ms,直接返回
         if (rshyParam.getTimeout() <= 10) {
-            return rshyVo;
+            return new AsyncResult<>(rshyVo);
         }
 
         AtomicReference<RshyVo> quickRshyVo = new AtomicReference<>(new RshyVo());
         List<Runnable> taskList = new ArrayList<Runnable>() {
             {
+                add(() -> resultDTO.setPctsfzResult(itfwServer.getPctsfz(rshyParam.getSfzh(), rshyParam.getTimeout())));
                 add(() -> resultDTO.setPctymDataDTOS(itfwServer.getPctym(rshyParam.getSfzh(), rshyParam.getTimeout())));
-                //add(() -> resultDTO.setPcthsResultDTO(itfwServer.getPcths(rshyParam.getSfzh(), rshyParam.getTimeout())));
+                add(() -> resultDTO.setPcthsResultDTO(itfwServer.getPcths(rshyParam.getSfzh(), rshyParam.getTimeout())));
+                add(() -> resultDTO.setPctxcmResultDTO(itfwServer.getPctxcm(rshyParam.getSfzh(), rshyParam.getTimeout())));
                 if (StrUtil.isBlank(rshyParam.getXm())) {   // 刷健康码或者手动输入身份证号码,获取证件照片
                     add(() -> resultDTO.setPctzjzpResultDTO(itfwServer.getPctzjzp(rshyParam.getSfzh(), rshyParam.getTimeout())));
                 }
@@ -142,8 +147,8 @@ public class RshyJkManagerImpl implements RshyJkManager {
 
         //核酸报告
         rshyVo.setNucleic_acid(nucleicAcid(resultDTO.getPcthsResultDTO()));
-        //行程卡(暂时没接口,默认0)
-        rshyVo.setTravel_card(0);
+        //行程卡
+        rshyVo.setTravel_card(resultDTO.getPctxcmResultDTO() != null && resultDTO.getPctxcmResultDTO().getData() != null && resultDTO.getPctxcmResultDTO().getData().getResult().size() > 0 ? 1 : 0);
         //性别 从身份证号码中获取
         rshyVo.setXb(SexEnum.codeOf(IdcardUtil.getGenderByIdCard(rshyVo.getSfzh())).getDesc());
         //出生日期 从身份证号码中获取
@@ -151,9 +156,10 @@ public class RshyJkManagerImpl implements RshyJkManager {
         rshyVo.setBirthday(DateUtil.format(date, "yyyy-M-d"));
         //不是刷身份证,取地址
         if (StrUtil.isBlank(rshyParam.getXm())) {
-            if (rshyVo.getVaccine() != 0) {
-                //有疫苗信息,从接种疫苗信息里取地址
-                rshyVo.setAddress(resultDTO.getPctymDataDTOS().get(rshyVo.getVaccine() - 1).getResidentialAddress());
+            if (resultDTO.getPctsfzResult() != null) {
+                //有警察叔叔身份证接口返回数据,取地址
+                rshyVo.setAddress(resultDTO.getPctsfzResult().getCZRKZZ());
+                rshyVo.setMz(resultDTO.getPctsfzResult().getCZRKMZ());
             } else {
                 //户籍省份 从身份证号码中获取
                 rshyVo.setAddress(IdcardUtil.getProvinceByIdCard(rshyVo.getSfzh()));
@@ -163,16 +169,13 @@ public class RshyJkManagerImpl implements RshyJkManager {
         String hcjg = resultDTO.getPctrchlDTO() == null ? "" : resultDTO.getPctrchlDTO().getHcjg();
 
 
-        //if (rshyVo.getNucleic_acid().getStatus() == 0) {
-        //    rshyVo.setPass(PassStatusEnum.NO_COMPLIANCE.getCode()).setTts(PassStatusEnum.NO_COMPLIANCE.getTts()).setDisplayMsg(PassStatusEnum.NO_COMPLIANCE.getDesc());
-        //}else {
-
-
-        //if (resultDTO.getPersonIdentifyDTO() != null && !rshyParam.getSfzh().equals(resultDTO.getPersonIdentifyDTO().getIdNumber())) {
-        //人证或者人码不符
-        //  rshyVo.setPassStatus(PassStatusEnum.NO_MATCHED).setWarning(PassStatusEnum.NO_MATCHED.getDesc()).setKind(PassStatusEnum.NO_MATCHED.getDesc());
-        //} else
-        if (PassStatusEnum.RED_CODE.getDesc().equalsIgnoreCase(jkmInfo.getColor_code_label())) {
+//        if (rshyVo.getNucleic_acid().getStatus() == 0) {
+//            rshyVo.setPassStatus(PassStatusEnum.NON_CONFORMANCE).setKind(PassStatusEnum.NON_CONFORMANCE.getDesc()).setWarning(PassStatusEnum.NON_CONFORMANCE.getDesc());
+//        } else
+        if (rshyVo.getTravel_card() != 0) {
+            //行程码到过中高风险地区
+            rshyVo.setPassStatus(PassStatusEnum.ABNORMAL_TRAVEL_CARD).setKind(PassStatusEnum.ABNORMAL_TRAVEL_CARD.getDesc());
+        } else if (PassStatusEnum.RED_CODE.getDesc().equalsIgnoreCase(jkmInfo.getColor_code_label())) {
             //红码
             rshyVo.setPass(PassStatusEnum.RED_CODE.getCode()).setTts(PassStatusEnum.RED_CODE.getTts()).setDisplayMsg(PassStatusEnum.RED_CODE.getDesc()).setWarning(PassStatusEnum.RED_CODE.getDesc()).setKind("健康码" + PassStatusEnum.RED_CODE.getDesc());
         } else if (PassStatusEnum.YELLOW_CODE.getDesc().equalsIgnoreCase(jkmInfo.getColor_code_label())) {
@@ -180,9 +183,7 @@ public class RshyJkManagerImpl implements RshyJkManager {
             rshyVo.setPassStatus(PassStatusEnum.YELLOW_CODE).setKind("健康码" + PassStatusEnum.YELLOW_CODE.getDesc()).setWarning(PassStatusEnum.YELLOW_CODE.getDesc());
         } else if (resultDTO.getPctgkryDTO().getPctztDTO() != null || StrUtil.containsAnyIgnoreCase(hcjg, RchljgEnum.CAPTURE.getDesc()) || StrUtil.containsAnyIgnoreCase(hcjg, RchljgEnum.INTERCEPT.getDesc())) {
             //在逃 或者 人车核录接口返回 抓捕或者拦截
-            rshyVo.setPassStatus(PassStatusEnum.NO_PASSING).setKind(kind(resultDTO)).setWarning(warning(resultDTO));//.setWarning("在逃人员:" + resultDTO.getPctgkryDTO().getPctztDTO().getJyaq()).setKind(resultDTO.getPctgkryDTO().getPctztDTO().getZtrylxmc());
-            //} else if (ObjectUtils.allFieldIsNULL(resultDTO.getPctgkryDTO()) || StrUtil.containsAnyIgnoreCase(hcjg, "通过")) {
-            //    rshyVo.setPass(PassStatusEnum.NORMAL_TRAFFIC.getCode()).setDisplayMsg(PassStatusEnum.NORMAL_TRAFFIC.getDesc()).setTts(PassStatusEnum.NORMAL_TRAFFIC.getTts());
+            rshyVo.setPassStatus(PassStatusEnum.NO_PASSING).setKind(kind(resultDTO)).setWarning(warning(resultDTO));
         } else if (!ObjectUtils.allFieldIsNULL(resultDTO.getPctgkryDTO()) || StrUtil.containsAnyIgnoreCase(hcjg, RchljgEnum.IN_DOUBT.getDesc())) {
             //七大类管控人员(在逃除外)和人车核录接口返回存疑人员
             rshyVo.setPassStatus(PassStatusEnum.RIGHT_WAY).setKind(kind(resultDTO)).setWarning(warning(resultDTO));
@@ -206,43 +207,36 @@ public class RshyJkManagerImpl implements RshyJkManager {
         }
 
         //System.out.println(JSONObject.toJSONString(resultDTO));
-        return rshyVo;
+        return new AsyncResult<>(rshyVo);
     }
 
     /**
      * 组装返回的核酸信息
+     *
      * @param pcthsResultDTO 第三方核酸接口返回数据
      * @return
      */
     private NucleicAcidDTO nucleicAcid(PcthsResultDTO pcthsResultDTO) {
         NucleicAcidDTO nucleicAcidDTO = new NucleicAcidDTO();
         if (pcthsResultDTO == null) {
-            nucleicAcidDTO.setStatus(NucleicAcidEnum.NO_SAMPLING.getCode()).setResults(NucleicAcidEnum.NO_SAMPLING.getDesc());
+            nucleicAcidDTO.setStatus(NucleicAcidEnum.NO_DATA.getCode()).setResults(NucleicAcidEnum.NO_DATA.getDesc());
             return nucleicAcidDTO;
         }
 
-        if (pcthsResultDTO.getSHE_RQSJ() != null) {
-            DateTime parse = DateUtil.parse(String.valueOf(Integer.valueOf(pcthsResultDTO.getSHE_RQSJ()) * 1000));
+        if (pcthsResultDTO.getYU_CJSJ() != null) {
+            DateTime parse = DateUtil.date(Long.parseLong(pcthsResultDTO.getYU_CJSJ()) * 1000);
+            log.info("最近一次核酸采样时间: {}", parse.toString());
             long betweenMs = DateUtil.betweenMs(parse, DateUtil.date());
-            //48h防疫规则
-            if (betweenMs > 48 * 60 * 60 * 1000) {
-                nucleicAcidDTO.setStatus(NucleicAcidEnum.NOT_CONFORM.getCode()).setResults(new StringBuilder("48小时之外已出结果,结果").append(pcthsResultDTO.getJGU_MC()).toString()).setTime(DateUtil.format(parse, "MM-dd HH:mm"));
-                return nucleicAcidDTO;
+            //72h防疫规则
+            if (betweenMs > 72 * 60 * 60 * 1000) {
+                nucleicAcidDTO.set(NucleicAcidEnum.NOT_CONFORM);
+            } else {
+                nucleicAcidDTO.set(NucleicAcidEnum.CONFORM);
             }
-
-            nucleicAcidDTO.setStatus(NucleicAcidEnum.CONFORM.getCode()).setResults(new StringBuilder("采样48h内 结果").append(pcthsResultDTO.getJGU_MC()).toString()).setTime(DateUtil.format(parse, "MM-dd HH:mm"));
-            return nucleicAcidDTO;
-        }
-
-        DateTime parse = DateUtil.parse(String.valueOf(Integer.valueOf(pcthsResultDTO.getCJSJ()) * 1000));
-        long betweenMs = DateUtil.betweenMs(parse, DateUtil.date());
-        //48h防疫规则
-        if (betweenMs > 48 * 60 * 60 * 1000) {
-            nucleicAcidDTO.setStatus(NucleicAcidEnum.NOT_CONFORM.getCode()).setResults("48小时之外未出结果");
             return nucleicAcidDTO;
         }
 
-        nucleicAcidDTO.setStatus(NucleicAcidEnum.CONFORM.getCode()).setResults("48小时之内未出结果");
+        nucleicAcidDTO.set(NucleicAcidEnum.NO_DATA_TIME);
         return nucleicAcidDTO;
     }
 

+ 12 - 0
src/main/java/com/rshy/project/hy/model/constant/ItfwConstant.java

@@ -93,4 +93,16 @@ public class ItfwConstant {
      */
     public static final String PCTZDRYDK_KEY = "itfw:pctzdrydk";
     public static final String PCTZDRYDK_STATUS_KEY = "itfw:pctzdrydk:status";
+
+    /**
+     * 查询行程码记录接口
+     */
+    public static final String PCTXCM_KEY = "itfw:pctxcm";
+    public static final String PCTXCM_STATUS_KEY = "itfw:pctxcm:status";
+
+    /**
+     * 警察叔叔身份证接口
+     */
+    public static final String PCTSFZ_KEY = "itfw:pctsfz";
+    public static final String PCTSFZ_STATUS_KEY = "itfw:pctsfz:status";
 }

+ 5 - 0
src/main/java/com/rshy/project/hy/model/dto/NucleicAcidDTO.java

@@ -1,5 +1,6 @@
 package com.rshy.project.hy.model.dto;
 
+import com.rshy.project.hy.model.enums.NucleicAcidEnum;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
@@ -20,4 +21,8 @@ public class NucleicAcidDTO {
 
     @ApiModelProperty("状态,是否符合当前防疫政策 1 符合 0 不符合")
     private Integer status;
+
+    public NucleicAcidDTO set(NucleicAcidEnum data) {
+        return this.setStatus(data.getCode()).setResults(data.getDesc());
+    }
 }

+ 6 - 4
src/main/java/com/rshy/project/hy/model/enums/NucleicAcidEnum.java

@@ -11,10 +11,12 @@ import lombok.Getter;
 @Getter
 @AllArgsConstructor
 public enum NucleicAcidEnum {
-    CONFORM(1, "符合"),
-    NOT_CONFORM(0, "不符合"),
-    NO_SAMPLING(0, "48h内未采样"),
-    NO_DATA(0, "无核酸采样数据");
+    CONFORM(1, "72h内已采样"),
+    SAMPLING(1, "72h内已采样"),
+    NOT_CONFORM(0, "72h内未采样"),
+    NO_SAMPLING(0, "72h内未采样"),
+    NO_DATA(0, "无核酸数据"),
+    NO_DATA_TIME(0, "无核酸采样时间数据");
 
     private Integer code;
 

+ 3 - 2
src/main/java/com/rshy/project/hy/model/enums/PassStatusEnum.java

@@ -18,11 +18,12 @@ public enum PassStatusEnum {
     GREEN_CODE(2, "绿码", "通过"),
     RED_CODE(3, "红码", "健康码异常"),
     YELLOW_CODE(3, "黄码", "健康码异常"),
-    NO_CODE(3, "无健康码", "健康码异常"),
+    NO_HEALTH_CODE(3, "无健康码", "健康码异常"),
+    ABNORMAL_TRAVEL_CARD(3, "行程码异常", "健康码异常"),
     //人证或人码不符
     NO_MATCHED(3, "人证(码)不符", "健康码异常"),
     //不符合防疫要求
-    NO_COMPLIANCE(3, "核酸未采集", "核酸48小时未采集");
+    NON_CONFORMANCE(3, "核酸未符合", "健康码异常");
 
     private Integer code;
     private String desc;

+ 193 - 55
src/main/java/com/rshy/project/hy/server/ItfwServer.java

@@ -21,7 +21,9 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Component;
 
+import java.util.Comparator;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -63,6 +65,10 @@ public class ItfwServer {
     @Autowired
     private PctzdrydkProperties pctzdrydkProperties;
     @Autowired
+    private PctsfzProperties pctsfzProperties;
+    @Autowired
+    private PctxcmProperties pctxcmProperties;
+    @Autowired
     private StringRedisTemplate stringRedisTemplate;
 
     /**
@@ -101,8 +107,6 @@ public class ItfwServer {
             cacheKey = idNum + ":" + ItfwConstant.BARCODE_KEY;
         }
 
-        System.out.println("cacheKey: " + cacheKey);
-
         String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
         if (StrUtil.isNotEmpty(cacheValue)) {
             log.info("健康码服务走缓存读取,响应内容: {}", cacheValue);
@@ -176,8 +180,9 @@ public class ItfwServer {
             return null;
         }
         log.info("重点人员服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
@@ -238,15 +243,16 @@ public class ItfwServer {
             return null;
         }
         log.info("人员劣迹服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         PctztVO pctztVO = JSON.parseObject(body, PctztVO.class);
         if (CollectionUtil.isEmpty(pctztVO.getData())) {
             stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(null), DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
             return null;
         }
 
-        PctztDTO pctztDTO = pctztVO.getData().stream().findFirst().get();
+        PctztDTO pctztDTO = pctztVO.getData().stream().findFirst().orElse(null);
         stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(pctztDTO), DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
         return pctztDTO;
     }
@@ -295,8 +301,9 @@ public class ItfwServer {
         }
 
         log.info("新的执法办案服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
@@ -355,8 +362,9 @@ public class ItfwServer {
             return null;
         }
         log.info("打防控信息服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
@@ -415,8 +423,9 @@ public class ItfwServer {
         }
 
         log.info("监所人员服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
@@ -477,8 +486,9 @@ public class ItfwServer {
         }
 
         log.info("吸毒人员服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
@@ -538,8 +548,9 @@ public class ItfwServer {
         }
 
         log.info("前科人员服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusValue);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
@@ -554,31 +565,6 @@ public class ItfwServer {
         return pctqkryDTO;
     }
 
-    /**
-     * 异常次数
-     *
-     * @param key
-     * @return
-     */
-    private Integer exceptionTimes(String key) {
-        String cacheKey = key + ":times";
-        int times = 1;
-        String timesStr = stringRedisTemplate.opsForValue().get(cacheKey);
-        if (timesStr == null) {
-            stringRedisTemplate.opsForValue().set(cacheKey, String.valueOf(times));//,DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
-        } else {
-            times = Integer.parseInt(timesStr) + 1;
-            if (times > WebConstant.TIMEOUT_TIMES) {
-                Set<String> keys = stringRedisTemplate.keys(cacheKey + "*");
-                stringRedisTemplate.delete(keys);
-            } else {
-                stringRedisTemplate.opsForValue().increment(cacheKey);
-            }
-        }
-
-        return times;
-    }
-
     /**
      * 人车核录
      *
@@ -626,8 +612,9 @@ public class ItfwServer {
         }
 
         log.info("人车核录服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
 
         if (StrUtil.isEmpty(body) || !StrUtil.containsAnyIgnoreCase(body, "datas")) {
             return null;
@@ -687,8 +674,9 @@ public class ItfwServer {
         }
 
         log.info("浙江省疫苗注射数据服务响应信息:{}", body);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
 
         if (StrUtil.isEmpty(body) || !StrUtil.containsAnyIgnoreCase(body, "datas")) {
             return null;
@@ -721,7 +709,7 @@ public class ItfwServer {
         BeanUtil.copyProperties(pcthsProperties, properties);
         properties.setQuery(new PcthsQueryDTO().setZjhm(idNumber));
         log.info("核酸接口数据服务请求入参:{}", JSON.toJSONString(properties));
-        String body = null;
+        String body;
 
         try {
             body = this.baseAgentApi(properties, timeout);
@@ -733,7 +721,7 @@ public class ItfwServer {
 
         log.info("核酸接口数据服务响应信息:{}", body);
 
-        if (StrUtil.isEmpty(body) || !StrUtil.containsAnyIgnoreCase(body, "datas")) {
+        if (StrUtil.isEmpty(body) || !StrUtil.containsAnyIgnoreCase(body, "data")) {
             return null;
         }
         PcthsVO pcthsVO = JSON.parseObject(body, PcthsVO.class);
@@ -741,8 +729,7 @@ public class ItfwServer {
             return null;
         }
 
-        PcthsResultDTO pcthsResultDTO = pcthsVO.getData().getResult().stream().findFirst().get();
-        return pcthsResultDTO;
+        return pcthsVO.getData().getResult().stream().max(Comparator.comparing(PcthsResultDTO::getYU_CJSJ)).orElse(null);
     }
 
 
@@ -796,8 +783,9 @@ public class ItfwServer {
             return null;
         }
         PctzjzpResultDTO pctzjzpResultDTO = JSON.parseObject(body, PctzjzpResultDTO.class);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        deleteKeys(cacheStatusKey);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         if (Integer.parseInt(pctzjzpResultDTO.getStatus()) != 200) {
             return null;
         }
@@ -854,13 +842,13 @@ public class ItfwServer {
         }
 
         log.info("杭州市重点人员底库数据查询接口服务响应信息:{}", body);
-
+        deleteKeys(cacheStatusKey);
         if (StrUtil.isEmpty(body)) {
             return null;
         }
         PctzdrydkResultDTO pctzdrydkResultDTO = JSON.parseObject(body, PctzdrydkResultDTO.class);
-        Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
-        stringRedisTemplate.delete(keys);
+        //Set<String> keys = stringRedisTemplate.keys(cacheStatusKey + "*");
+        //stringRedisTemplate.delete(keys);
         stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(pctzdrydkResultDTO), DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
         //if (pctzdrydkResultDTO.getErrCode() == 0 && pctzdrydkResultDTO.getTotal() == 0) {
         //    return null;
@@ -868,4 +856,154 @@ public class ItfwServer {
 
         return pctzdrydkResultDTO;
     }
+
+    /**
+     * 查询扫行程码记录接口数据服务
+     *
+     * @param idNumber
+     * @param timeout
+     */
+    public PctxcmResultDTO getPctxcm(String idNumber, Integer timeout) {
+        if (StringUtils.isBlank(idNumber)) {
+            log.warn("身份证号码为空");
+            return null;
+        }
+
+        String cacheKey = idNumber + ':' + ItfwConstant.PCTXCM_KEY;
+        String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
+        if (StrUtil.isNotEmpty(cacheValue)) {
+            log.info("查询扫行程码记录接口服务走缓存读取,响应内容: {}", cacheValue);
+            return JSON.parseObject(cacheValue, PctxcmResultDTO.class);
+        }
+
+        String cacheStatusKey = ItfwConstant.PCTXCM_STATUS_KEY;
+        String cacheStatusValue = stringRedisTemplate.opsForValue().get(cacheStatusKey);
+        if (StrUtil.isNotEmpty(cacheStatusValue)) {
+            return null;
+        }
+
+        PctxcmProperties properties = new PctxcmProperties();
+        BeanUtil.copyProperties(pctxcmProperties, properties);
+        properties.setQuery(new PctxcmParamDTO().setGmsfhm(idNumber));
+        log.info("查询扫行程码记录接口数据服务请求入参:{}", JSON.toJSONString(properties));
+        String body;
+
+        try {
+            body = this.baseAgentApi(properties, timeout);
+        } catch (Exception e) {
+            if (exceptionTimes(cacheStatusKey) > WebConstant.TIMEOUT_TIMES) {
+                stringRedisTemplate.opsForValue().set(cacheStatusKey, cacheStatusKey, WebConstant.STATUS_TIMEOUT, TimeUnit.MINUTES);
+            }
+
+            log.error("查询扫行程码记录接口数据服务接口异常:{}", e.getMessage());
+            //e.printStackTrace();
+            return null;
+        }
+
+        log.info("查询扫行程码记录接口数据服务响应信息:{}", body);
+        deleteKeys(cacheStatusKey);
+        if (StrUtil.isEmpty(body) || !StrUtil.containsAnyIgnoreCase(body, "data")) {
+            return null;
+        }
+        PctxcmResultDTO pctxcmResultDTO = JSON.parseObject(body, PctxcmResultDTO.class);
+        stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(pctxcmResultDTO), DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
+//        if (CollectionUtil.isEmpty(pctxcmResultDTO.getData().getResult())) {
+//            return null;
+//        }
+
+        return pctxcmResultDTO;
+    }
+
+    /**
+     * 警察叔叔身份证接口数据服务
+     *
+     * @param idNumber
+     * @param timeout
+     */
+    public PctsfzResultDTO.SfzResult getPctsfz(String idNumber, Integer timeout) {
+        if (StringUtils.isBlank(idNumber)) {
+            log.warn("身份证号码为空");
+            return null;
+        }
+        String cacheKey = idNumber + ':' + ItfwConstant.PCTSFZ_KEY;
+        String cacheValue = stringRedisTemplate.opsForValue().get(cacheKey);
+        if (StrUtil.isNotEmpty(cacheValue)) {
+            log.info("警察叔叔身份证接口服务走缓存读取,响应内容: {}", cacheValue);
+            PctsfzResultDTO pctsfzResultDTO = JSON.parseObject(cacheValue, PctsfzResultDTO.class);
+            assert pctsfzResultDTO != null;
+            return pctsfzResultDTO.getData().getResult().stream().max(Comparator.comparing(PctsfzResultDTO.SfzResult::getCZRKYXQXJZRQ)).orElse(null);
+        }
+
+        String cacheStatusKey = ItfwConstant.PCTSFZ_STATUS_KEY;
+        String cacheStatusValue = stringRedisTemplate.opsForValue().get(cacheStatusKey);
+        if (StrUtil.isNotEmpty(cacheStatusValue)) {
+            return null;
+        }
+
+        PctsfzProperties properties = new PctsfzProperties();
+        BeanUtil.copyProperties(pctsfzProperties, properties);
+        properties.setQuery(new PctsfzParamDTO().setCzrkgmsfhm(idNumber));
+        log.info("警察叔叔身份证接口数据服务请求入参:{}", JSON.toJSONString(properties));
+        String body;
+
+        try {
+            body = this.baseAgentApi(properties, timeout);
+        } catch (Exception e) {
+            if (exceptionTimes(cacheStatusKey) > WebConstant.TIMEOUT_TIMES) {
+                stringRedisTemplate.opsForValue().set(cacheStatusKey, cacheStatusKey, WebConstant.STATUS_TIMEOUT, TimeUnit.MINUTES);
+            }
+
+            log.error("警察叔叔身份证接口数据服务接口异常:{}", e.getMessage());
+            //e.printStackTrace();
+            return null;
+        }
+
+        log.info("警察叔叔身份证接口数据服务响应信息:{}", body);
+        deleteKeys(cacheStatusKey);
+        if (StrUtil.isEmpty(body) || !StrUtil.containsAnyIgnoreCase(body, "data")) {
+            return null;
+        }
+        PctsfzResultDTO pctsfzResultDTO = JSON.parseObject(body, PctsfzResultDTO.class);
+        if (CollectionUtil.isEmpty(pctsfzResultDTO.getData().getResult())) {
+            return null;
+        }
+        stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(pctsfzResultDTO));//, DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
+
+        return pctsfzResultDTO.getData().getResult().stream().max(Comparator.comparing(PctsfzResultDTO.SfzResult::getCZRKYXQXJZRQ)).orElse(null);
+    }
+
+    /**
+     * 异常次数
+     *
+     * @param key
+     * @return
+     */
+    private Integer exceptionTimes(String key) {
+        String cacheKey = key + ":times";
+        int times = 1;
+        String timesStr = stringRedisTemplate.opsForValue().get(cacheKey);
+        if (timesStr == null) {
+            stringRedisTemplate.opsForValue().set(cacheKey, String.valueOf(times));//,DateUtil.endOfDay(DateUtil.date()).getTime() - DateUtil.date().getTime(), TimeUnit.MILLISECONDS);
+        } else {
+            times = Integer.parseInt(timesStr) + 1;
+            if (times > WebConstant.TIMEOUT_TIMES) {
+                deleteKeys(cacheKey);
+            } else {
+                stringRedisTemplate.opsForValue().increment(cacheKey);
+            }
+        }
+
+        return times;
+    }
+
+    /**
+     * 删除redis 缓存
+     *
+     * @param key
+     */
+    private void deleteKeys(String key) {
+        Set<String> keys = stringRedisTemplate.keys(key + "*");
+        Optional.ofNullable(keys).ifPresent(k -> stringRedisTemplate.delete(k));
+    }
+
 }

+ 1 - 0
src/main/java/com/rshy/project/hy/server/dto/PcthsDTO.java

@@ -12,4 +12,5 @@ import java.util.List;
 @Data
 public class PcthsDTO {
     private List<PcthsResultDTO> result;
+    private int excuteTime;
 }

+ 24 - 24
src/main/java/com/rshy/project/hy/server/dto/PcthsResultDTO.java

@@ -9,30 +9,30 @@ import lombok.Data;
  */
 @Data
 public class PcthsResultDTO {
-    private String FHXTSJWYBSID;
-    private String SHE_RQSJ;
-    private String SJMGJBBM;
-    private String CYZJDM;
-    private String SJCJLYBM;
-    private String SJCJLYXTBZ;
-    private String XWBQBS;
-    private String SJC;
-    private String YL_JJIN_DM;
-    private String YAB_CJSJ;
-    private String YSXTJRZJ;
-    private String CYZJMC;
-    private String XXSC_PDBZ;
-    private String SJCJLYXT;
-    private String ZJHM;
-    private String CJSJ;
-    private String SJCJLYD;
-    private String GXSJ;
-    private String JGU_MC;
-    private String SJKHSBSF;
-    private String JY_YIY_MC;
+    //private String FHXTSJWYBSID;
+    //private String SHE_RQSJ;
+    //private String SJMGJBBM;
+    //private String CYZJDM;
+    //private String SJCJLYBM;
+    //private String SJCJLYXTBZ;
+    //private String XWBQBS;
+    //private String SJC;
+    //private String YL_JJIN_DM;
+    //private String YAB_CJSJ;
+    //private String YSXTJRZJ;
+    //private String CYZJMC;
+    //private String XXSC_PDBZ;
+    //private String SJCJLYXT;
+    //private String ZJHM;
+    private String YU_CJSJ;
+    //private String SJCJLYD;
+    //private String GXSJ;
+    //private String JGU_MC;
+    //private String SJKHSBSF;
+    //private String JY_YIY_MC;
     private String GMSFHM;
     private String XM;
-    private String YWBQBS;
-    private String PIC_ID;
-    private String SJCJLYBM1;
+    //private String YWBQBS;
+    //private String PIC_ID;
+    //private String SJCJLYBM1;
 }

+ 22 - 0
src/main/java/com/rshy/project/hy/server/dto/PctsfzParamDTO.java

@@ -0,0 +1,22 @@
+package com.rshy.project.hy.server.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author: fanqun
+ * @date: 2022/5/30 23:07
+ * @description:
+ */
+@Data
+@Accessors(chain = true)
+public class PctsfzParamDTO {
+    /**
+     * 身份证号码
+     */
+    private String czrkgmsfhm;
+
+    private Integer offSet = 0;
+
+    private Integer rowCount = 10;
+}

+ 39 - 0
src/main/java/com/rshy/project/hy/server/dto/PctsfzResultDTO.java

@@ -0,0 +1,39 @@
+package com.rshy.project.hy.server.dto;
+
+import com.alibaba.fastjson.JSON;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by fanqun on 2022/5/30.
+ */
+@Data
+@Accessors(chain = true)
+public class PctsfzResultDTO {
+
+    private int code;
+    private String msg;
+
+    private SfzData data;
+
+    @Data
+    public static class SfzData implements Serializable {
+        private List<SfzResult> result;
+        private int excuteTime;
+
+    }
+
+    @Data
+    public static class SfzResult implements Serializable {
+        private String CZRKGMSFHM;
+        private String CZRKXM;
+        private String CZRKQFJG;
+        private String CZRKMZ;
+        private String CZRKZZ;
+        private String CZRKYXQXJZRQ;
+    }
+
+}

+ 24 - 0
src/main/java/com/rshy/project/hy/server/dto/PctxcmParamDTO.java

@@ -0,0 +1,24 @@
+package com.rshy.project.hy.server.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author: fanqun
+ * @date: 2022/5/30 23:07
+ * @description:
+ */
+@Data
+@Accessors(chain = true)
+public class PctxcmParamDTO {
+    /**
+     * 身份证号码
+     */
+    private String gmsfhm;
+
+    private String sfdgzgfxqy_xxdm02 = "2";
+
+    private Integer offSet = 0;
+
+    private Integer rowCount = 10;
+}

+ 37 - 0
src/main/java/com/rshy/project/hy/server/dto/PctxcmResultDTO.java

@@ -0,0 +1,37 @@
+package com.rshy.project.hy.server.dto;
+
+import com.alibaba.fastjson.JSON;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by fanqun on 2022/5/30.
+ */
+@Data
+@Accessors(chain = true)
+public class PctxcmResultDTO {
+
+    private int code;
+    private String msg;
+
+    private XcmData data;
+
+    @Data
+    public static class XcmData implements Serializable {
+        private List<XcmResult> result;
+        private int excuteTime;
+
+    }
+
+    @Data
+    public static class XcmResult implements Serializable {
+        private String XG_RQSJ;
+        private String ZJHM;
+        private String GMSFHM;
+        private String SFDGZGFXQY_MC;
+    }
+
+}

+ 4 - 0
src/main/java/com/rshy/project/hy/server/dto/ResultDTO.java

@@ -36,9 +36,13 @@ public class ResultDTO {
 
     private PcthsResultDTO pcthsResultDTO;
 
+    private PctxcmResultDTO pctxcmResultDTO;
+
     private PersonIdentifyDTO personIdentifyDTO;
 
     private PctzjzpResultDTO pctzjzpResultDTO;
 
     private PctzdrydkResultDTO pctzdrydkResultDTO;
+
+    private PctsfzResultDTO.SfzResult pctsfzResult;
 }

+ 26 - 18
src/main/java/com/rshy/project/hy/web/controller/RshyController.java

@@ -10,6 +10,7 @@ import com.rshy.project.hy.baseRe.BaseException;
 import com.rshy.project.hy.baseRe.ResultCode;
 import com.rshy.project.hy.baseRe.Ret;
 import com.rshy.project.hy.manager.RshyJkManager;
+import com.rshy.project.hy.model.enums.PassStatusEnum;
 import com.rshy.project.hy.server.param.RshyParam;
 import com.rshy.project.hy.server.param.RshyQuickParam;
 import com.rshy.project.hy.server.vo.RshyVo;
@@ -18,13 +19,13 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * @ProjectName: rshy
@@ -40,9 +41,14 @@ import java.util.concurrent.TimeUnit;
 @RequestMapping("/rshy")
 @Slf4j
 public class RshyController {
-    @Autowired
+    @Resource
     private RshyJkManager rshyJkManager;
 
+    @GetMapping(value = "/version")
+    public String version() {
+        return "1.2.4.220524";
+    }
+
     @ApiOperation("普通核验模式")
     //@NoRepeatSubmit
     @PostMapping("getRyhyInfo")
@@ -62,19 +68,21 @@ public class RshyController {
 
 
         DateTime time1 = DateTime.now();
+
         log.info("普通核验接口请求参数:{}", JSON.toJSONString(rshyParam));
-        //RshyVo rshyVo = new RshyVo().setPassStatus(PassStatusEnum.NORMAL_TRAFFIC);
-        //try {
-        RshyVo rshyVo = rshyJkManager.getRshyInfo(rshyParam);
-        //rshyVo = future.get(rshyParam.getTimeout(), TimeUnit.MILLISECONDS);
-        //} catch (InterruptedException | ExecutionException e) {
-        //  log.error("普通核验接口异常: {}", e.getMessage());
-        //e.printStackTrace();
-        //} catch (TimeoutException e) {
-        //  log.error("普通核验接口异常: 等待超时");
-        //} catch (Exception e) {
-        // throw new BaseException();
-        //}
+        RshyVo rshyVo = new RshyVo().setPassStatus(PassStatusEnum.NORMAL_TRAFFIC);
+        try {
+            //RshyVo rshyVo = rshyJkManager.getRshyInfo(rshyParam);
+            Future<RshyVo> future = rshyJkManager.getRshyInfo(rshyParam);
+            rshyVo = future.get(rshyParam.getTimeout() * 1000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException | ExecutionException e) {
+            log.error("普通核验接口异常: {}", e.getMessage());
+            //e.printStackTrace();
+        } catch (TimeoutException e) {
+            log.error("普通核验接口异常: 等待超时");
+        } catch (Exception e) {
+            throw new BaseException();
+        }
         log.info("普通核验响应内容:{}", JSON.toJSONString(rshyVo));
 
         System.out.println("普通核验接口用时: " + DateUtil.between(time1, DateTime.now(), DateUnit.MS) + "毫秒\n");

+ 19 - 1
src/main/resources/application-local.yml

@@ -95,7 +95,16 @@ itfw:
       APP_KEY: 1618208939768204
       APP_SECRET: 9d98c9d9d14d4d298f4408c0338c1af5
     appCode: pcths
-    apiPath: /1642499133568
+    apiPath: /1653564781591
+    apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,5cf7f9ec93964f8a86e1a819dbb54c5b.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
+    method: GET
+  #查询行程码记录服务
+  pctxcm:
+    header:
+      APP_KEY: 1618208939768204
+      APP_SECRET: 9d98c9d9d14d4d298f4408c0338c1af5
+    appCode: pctxcm
+    apiPath: /1653564778214
     apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,5cf7f9ec93964f8a86e1a819dbb54c5b.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
     method: GET
   #证件照片服务
@@ -113,6 +122,15 @@ itfw:
     apiPath: /165275993242
     apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,5cf7f9ec93964f8a86e1a819dbb54c5b.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
     method: POST_BODY
+  #警察叔叔身份证服务
+  pctsfz:
+    header:
+      APP_KEY: 1618208939768204
+      APP_SECRET: 9d98c9d9d14d4d298f4408c0338c1af5
+    appCode: pctsfz
+    apiPath: /1653621114822
+    apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,b534d232ec6342009c27d0d9ab6259c7.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
+    method: GET
 
 #依图人脸检索第三方服务
 face:

+ 19 - 3
src/main/resources/application-prod.yml

@@ -22,8 +22,6 @@ spring:
         #最小等待连接中的数量,设0为没有限制
         min-idle: 5
 
-swagger:
-  enabled: true
 
 #公安网代理服务
 itfw:
@@ -99,7 +97,16 @@ itfw:
       APP_KEY: 1618208939768204
       APP_SECRET: 9d98c9d9d14d4d298f4408c0338c1af5
     appCode: pcths
-    apiPath: /1642499133568
+    apiPath: /1653564781591
+    apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,5cf7f9ec93964f8a86e1a819dbb54c5b.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
+    method: GET
+  #查询行程码记录服务
+  pctxcm:
+    header:
+      APP_KEY: 1618208939768204
+      APP_SECRET: 9d98c9d9d14d4d298f4408c0338c1af5
+    appCode: pctxcm
+    apiPath: /1653564778214
     apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,5cf7f9ec93964f8a86e1a819dbb54c5b.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
     method: GET
   #证件照片服务
@@ -117,6 +124,15 @@ itfw:
     apiPath: /165275993242
     apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,5cf7f9ec93964f8a86e1a819dbb54c5b.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
     method: POST_BODY
+  #警察叔叔身份证服务
+  pctsfz:
+    header:
+      APP_KEY: 1618208939768204
+      APP_SECRET: 9d98c9d9d14d4d298f4408c0338c1af5
+    appCode: pctsfz
+    apiPath: /1653621114822
+    apiConfig: 1618208939768204,9d98c9d9d14d4d298f4408c0338c1af5,b534d232ec6342009c27d0d9ab6259c7.apigateway.cn-deqing-zjzfy01-zjga01.hzs.zj,HTTPS
+    method: GET
 
 #依图人脸检索第三方服务
 face:

+ 8 - 5
src/main/resources/application.yml

@@ -24,12 +24,15 @@ mybatis-plus:
     map-underscore-to-camel-case: true
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 
-# Swagger配置
+# ===== 自定义swagger配置 ===== #
 swagger:
-  # 是否开启swagger
-  enabled: true
-  # 请求前缀
-  pathMapping:
+  enable: true
+  application-name: 智能证码通核验接口
+  application-version: 1.2.4
+  application-description: 智能证码通核验接口
+  try-host: http://localhost:${server.port}
+
+
 
 base:
   url: "http://10.118.128.114/agentProxy/agent/agentApi"