瀏覽代碼

Merge branch 'master' into hlx

helixiao 1 年之前
父節點
當前提交
847f856a3d
共有 38 個文件被更改,包括 1454 次插入707 次删除
  1. 1 0
      commons/src/main/java/com/jzg/commons/constants/quote/enums/base/ExpenseRequestUrl.java
  2. 7 0
      commons/src/main/java/com/jzg/commons/entity/quote/vo/aggregated/InsuranceUploadImageVo.java
  3. 2 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerLoginServiceImpl.java
  4. 5 3
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/client/ChengTaiAPI.java
  5. 84 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/component/ChengTaiRequestCrawlerComponent.java
  6. 39 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/ChengTaiCrawlerConfigureParameters.java
  7. 53 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/request/ChengTaiCheckCaptchaRequest.java
  8. 23 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/request/ChengTaiGetCaptchaRequest.java
  9. 36 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/request/ChengTaiLoginRequest.java
  10. 68 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/response/ChengTaiCheckCaptchaResponse.java
  11. 59 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/response/ChengTaiGetCaptchaResponse.java
  12. 20 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/response/ChengTaiLoginResponse.java
  13. 14 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/properties/ChengTaiCrawlerProperties.java
  14. 39 157
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiAPIService.java
  15. 30 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiCrawlerQuoteProcessService.java
  16. 54 70
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiCrawlerRequestService.java
  17. 77 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/impl/ChengTaiCrawlerQuoteProcessServiceImpl.java
  18. 78 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/utils/CryptoUtils.java
  19. 44 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/utils/RSACipher.java
  20. 32 0
      tenant/insurance/quotation-chengtai/src/main/resources/certs/CFCA EV ROOT.crt
  21. 0 112
      tenant/insurance/quotation-chengtai/src/test/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiAPIServiceTest.java
  22. 59 11
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java
  23. 54 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/config/SslConfig.java
  24. 85 37
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/config/WebClientConfig.java
  25. 2 1
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/service/ExteriorUtilsRequest.java
  26. 5 4
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/service/impl/ExteriorUtilsRequestImpl.java
  27. 56 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/Base64ImageUtils.java
  28. 13 27
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/DateUtil.java
  29. 34 19
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/build/HbCrawlerQuoteResultVoBuild.java
  30. 41 11
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/component/HengBangCrawlerRequestComponent.java
  31. 3 1
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/constant/enums/RequestUrl.java
  32. 2 1
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerCalculationRequest.java
  33. 14 8
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerFileUploadRequest.java
  34. 4 1
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerQuoteimmediatelyRequest.java
  35. 128 26
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java
  36. 7 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  37. 182 182
      tenant/insurance/quotation-summary/src/test/java/com/jzg/quotation/taikang/crawler/service/ChengTaiCrawlerRequestServiceTest.java
  38. 0 33
      tenant/insurance/quotation-taikang/src/test/java/com/jzg/quotation/taikang/crawler/TaiKangHttpClientTest.java

+ 1 - 0
commons/src/main/java/com/jzg/commons/constants/quote/enums/base/ExpenseRequestUrl.java

@@ -16,6 +16,7 @@ public enum ExpenseRequestUrl {
     CAPTCHA_IDENTIFY("/identify/captcha", "验证码识别"),
     REINSURANCE_CAPTCHA_IDENTIFY("/reinsurance/captcha", "转保验证码识别"),
     SLIDER_IDENTIFY("/identify/slider", "滑块验证"),
+    SLIDER_MATCH("/identify/slide-match", "滑块验证"),
     ;
 
     private final String uri;

+ 7 - 0
commons/src/main/java/com/jzg/commons/entity/quote/vo/aggregated/InsuranceUploadImageVo.java

@@ -1,5 +1,7 @@
 package com.jzg.commons.entity.quote.vo.aggregated;
 
+import com.jzg.commons.entity.orders.po.InsOrdersCarInfo;
+import com.jzg.commons.entity.orders.po.InsOrdersCarUserInfo;
 import com.jzg.commons.entity.quote.vo.CarInfoVo;
 import com.jzg.commons.entity.quote.vo.base.OrderBase;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
@@ -39,6 +41,11 @@ public class InsuranceUploadImageVo implements Serializable {
      */
     private CarInfoVo carInfo;
 
+    /**
+     * 订单车辆人员信息
+     */
+    private List<InsOrdersCarUserInfo> insOrdersCarUserInfoList;
+
     public InsuranceUploadImageVo(OrderBase order, List<InsuranceImageVo> imageVoList) {
         this.order = order;
         this.imageVoList = imageVoList;

+ 2 - 1
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerLoginServiceImpl.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.ansheng.crawler.service.impl;
 
+import com.jzg.commons.constants.quote.enums.base.ExpenseRequestUrl;
 import com.jzg.commons.entity.quote.vo.identify.SliderCaptchaVo;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.quotation.ansheng.crawler.component.AnShengCrawlerCacheComponent;
@@ -44,7 +45,7 @@ public class AnShengCrawlerLoginServiceImpl implements AnShengCrawlerLoginServic
             AnShengCrawlerVerifyResponse.DataDTO dataDTO = anShengCrawlerRequestComponent.crawlerVerify(anShengCrawlerVerifyRequest, httpHeaders);
             // 滑块验证码识别
             AnShengCrawlerVerifyResponse.DataDTO.ImageVerificationDTO imageVerification = dataDTO.getImageVerification();
-            List<Integer> integers = exteriorUtilsRequest.sliderCaptchaIdentify(new SliderCaptchaVo(imageVerification.getOriginImage(), imageVerification.getShadeImage()));
+            List<Integer> integers = exteriorUtilsRequest.sliderCaptchaIdentify(ExpenseRequestUrl.SLIDER_IDENTIFY, new SliderCaptchaVo(imageVerification.getOriginImage(), imageVerification.getShadeImage()));
             // 验证验证码
             AnShengCrawlerCheckVerificationRequest anShengCrawlerCheckVerificationRequest = new AnShengCrawlerCheckVerificationRequest(integers.get(0)
                     .toString(), integers.get(1).toString(), imageVerification.getUserFlag(), username);

+ 5 - 3
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/client/ChengTaiAPI.java

@@ -4,7 +4,10 @@ import com.jzg.quotation.commons.standard.CrawlerRequestUrlStandard;
 
 public enum ChengTaiAPI implements CrawlerRequestUrlStandard {
 
-    Login("/api/upms/login", "登录"),
+    GET_CAPTCHA("/api/upms/captcha/get", "获取验证码"),
+    CHECK_CAPTCHA("/api/upms/captcha/check", "验证验证码"),
+
+    LOGIN("/api/upms/login", "登录"),
     System("/api/upms/system", "系统信息"),
     FindAreaConfig("/api/vehicle/base/findAreaConfig", ""),
     FindDictionaryOfRisk("/api/vehicle/base/findDictionary?type=RISK_TYPE", "查询险种"),
@@ -24,9 +27,8 @@ public enum ChengTaiAPI implements CrawlerRequestUrlStandard {
     GetPolicyModel("/api/vehicle/query/getPolicyModel", "获取详情"),
     Insure("/api/vehicle/query/payPageQuery/{uuid}/insure", "获取支付链接"),
     DownloadAddress("/api/vehicle/core/downloadAddress", "获取保单链接"),
-    HygeiaGet("/api/vehicle/core/hygeia/get", "获取意外险"),
+    HygeiaGet("/api/vehicle/core/hygeia/get", "获取意外险");
 
-    ;
 
     private final String uri;
 

+ 84 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/component/ChengTaiRequestCrawlerComponent.java

@@ -0,0 +1,84 @@
+package com.jzg.quotation.chengtai.crawler.component;
+
+import com.jzg.commons.exception.SystemException;
+import com.jzg.quotation.chengtai.crawler.client.ChengTaiAPI;
+import com.jzg.quotation.chengtai.crawler.model.request.ChengTaiCheckCaptchaRequest;
+import com.jzg.quotation.chengtai.crawler.model.request.ChengTaiGetCaptchaRequest;
+import com.jzg.quotation.chengtai.crawler.model.request.ChengTaiLoginRequest;
+import com.jzg.quotation.chengtai.crawler.model.response.ChengTaiCheckCaptchaResponse;
+import com.jzg.quotation.chengtai.crawler.model.response.ChengTaiGetCaptchaResponse;
+import com.jzg.quotation.chengtai.crawler.model.response.ChengTaiLoginResponse;
+import com.jzg.quotation.chengtai.crawler.properties.ChengTaiCrawlerProperties;
+import com.jzg.quotation.commons.component.RequestComponent;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+@RequiredArgsConstructor
+public class ChengTaiRequestCrawlerComponent {
+
+    private final RequestComponent requestComponent;
+
+    private final ChengTaiCrawlerProperties chengTaiCrawlerProperties;
+
+    public <Response> ResponseEntity<Response> requestBasePost(ChengTaiAPI requestUrl, Object body, Class<Response> responseClass, HttpHeaders headers) {
+        String url = chengTaiCrawlerProperties.getBaseUrl() + requestUrl.uri();
+        return requestComponent.objectPost(url, body, responseClass, headers);
+    }
+
+    public <Response> Response requestPost(ChengTaiAPI requestUrl, Object body, Class<Response> responseClass, HttpHeaders headers) {
+        return requestBasePost(requestUrl, body, responseClass, headers).getBody();
+    }
+
+    /**
+     * 获取公钥
+     *
+     * @param responseEntity 响应内容
+     * @return 公钥
+     */
+    public static <T> String getPublicKey(ResponseEntity<T> responseEntity) {
+        return Optional.ofNullable(responseEntity)
+                .map(ResponseEntity::getHeaders)
+                .map(x -> x.get("Publickey"))
+                .map(x -> x.get(0))
+                .orElseThrow(() -> new SystemException("获取公钥失败"));
+    }
+
+
+    /**
+     * 获取验证码
+     *
+     * @param request 请求内容
+     * @return 验证码
+     */
+    public ResponseEntity<ChengTaiGetCaptchaResponse> getCaptcha(ChengTaiGetCaptchaRequest request) {
+        return requestBasePost(ChengTaiAPI.GET_CAPTCHA, request, ChengTaiGetCaptchaResponse.class, new HttpHeaders());
+    }
+
+    /**
+     * 验证验证码
+     *
+     * @param request 验证码
+     * @return 验证结果
+     */
+    public ResponseEntity<ChengTaiCheckCaptchaResponse> checkCaptcha(ChengTaiCheckCaptchaRequest request) {
+        return requestBasePost(ChengTaiAPI.CHECK_CAPTCHA, request, ChengTaiCheckCaptchaResponse.class, new HttpHeaders());
+    }
+
+    /**
+     * 登录
+     *
+     * @param request 登录信息
+     * @return 登录结果
+     */
+    public ChengTaiLoginResponse login(ChengTaiLoginRequest request){
+        ResponseEntity<ChengTaiLoginResponse> response = requestComponent.formData(ChengTaiAPI.LOGIN.getRequestUrl(chengTaiCrawlerProperties.getBaseUrl()), request, ChengTaiLoginResponse.class, new HttpHeaders());
+        return response.getBody();
+    }
+
+
+}

+ 39 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/ChengTaiCrawlerConfigureParameters.java

@@ -0,0 +1,39 @@
+package com.jzg.quotation.chengtai.crawler.model;
+
+import com.jzg.quotation.commons.standard.ConfigureParameters;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+
+/**
+ * @ClassName ChengTaiCrawlerConfigureParameters
+ * @Description 诚泰财险【爬虫】配置参数
+ * @Author wenks
+ * @Date 2025/9/10 18:07
+ * @Version 1.0
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class ChengTaiCrawlerConfigureParameters implements ConfigureParameters {
+
+    @Serial
+    private static final long serialVersionUID = 5287255169924097167L;
+
+    /**
+     * 业务归属机构
+     */
+    private String deptCode;
+    /**
+     * 业务员
+     */
+    private String handlerCode;
+    /**
+     * 中介机构
+     */
+    private String agreementCode;
+
+}
+

+ 53 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/request/ChengTaiCheckCaptchaRequest.java

@@ -0,0 +1,53 @@
+package com.jzg.quotation.chengtai.crawler.model.request;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * @ClassName ChengTaiCheckCaptchaRequest
+ * @Description 诚泰财险校验验证码请求参数
+ * @Author wenks
+ * @Date 2025/9/9 16:43
+ * @Version 1.0
+ */
+@NoArgsConstructor
+@Data
+public class ChengTaiCheckCaptchaRequest implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 3187109115725104676L;
+
+    @JsonProperty("captchaType")
+    private String captchaType;
+
+    @JsonProperty("pointJson")
+    private String pointJson;
+
+    @JsonProperty("token")
+    private String token;
+
+    public ChengTaiCheckCaptchaRequest(String pointJson, String token) {
+        this.captchaType = "blockPuzzle";
+        this.pointJson = pointJson;
+        this.token = token;
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class NotchLocation{
+
+        private double x;
+
+        private int y;
+
+    }
+
+}

+ 23 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/request/ChengTaiGetCaptchaRequest.java

@@ -0,0 +1,23 @@
+package com.jzg.quotation.chengtai.crawler.model.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @ClassName ChengTaiGetCaptchaRequest
+ * @Description 诚泰财险获取验证码请求参数
+ * @Author wenks
+ * @Date 2025/9/9 15:40
+ * @Version 1.0
+ */
+@Data
+public class ChengTaiGetCaptchaRequest {
+
+    @JsonProperty("captchaType")
+    private String captchaType;
+
+    public ChengTaiGetCaptchaRequest() {
+        this.captchaType = "blockPuzzle";
+    }
+}

+ 36 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/request/ChengTaiLoginRequest.java

@@ -0,0 +1,36 @@
+package com.jzg.quotation.chengtai.crawler.model.request;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.quotation.chengtai.crawler.client.EncryptRSA;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @ClassName ChengTaiLoginRequest
+ * @Description 诚泰财险登录请求
+ * @Author wenks
+ * @Date 2025/9/9 16:56
+ * @Version 1.0
+ */
+@Data
+@AllArgsConstructor
+public class ChengTaiLoginRequest implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 2912851835581891383L;
+
+    @JsonProperty("username")
+    private String username;
+
+    @JsonProperty("password")
+    private String password;
+
+    @JsonProperty("captchaVerification")
+    private String captchaVerification;
+
+
+}

+ 68 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/response/ChengTaiCheckCaptchaResponse.java

@@ -0,0 +1,68 @@
+package com.jzg.quotation.chengtai.crawler.model.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * @ClassName ChengTaiCheckCaptchaResponse
+ * @Description 诚泰财险校验参数返回参数
+ * @Author wenks
+ * @Date 2025/9/9 16:43
+ * @Version 1.0
+ */
+@NoArgsConstructor
+@Data
+public class ChengTaiCheckCaptchaResponse implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 7356576829460089305L;
+
+    @JsonProperty("code")
+    private Integer code;
+
+    @JsonProperty("message")
+    private String message;
+
+    @JsonProperty("body")
+    private BodyDTO body;
+
+    @NoArgsConstructor
+    @Data
+    public static class BodyDTO {
+
+        @JsonProperty("repCode")
+        private String repCode;
+
+        @JsonProperty("repData")
+        private RepDataDTO repData;
+
+        @JsonProperty("repMsg")
+        private String repMsg;
+
+        @JsonProperty("success")
+        private Boolean success;
+
+        @NoArgsConstructor
+        @Data
+        public static class RepDataDTO {
+
+            @JsonProperty("captchaType")
+            private String captchaType;
+
+            @JsonProperty("pointJson")
+            private String pointJson;
+
+            @JsonProperty("token")
+            private String token;
+
+            @JsonProperty("result")
+            private Boolean result;
+
+        }
+    }
+}

+ 59 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/response/ChengTaiGetCaptchaResponse.java

@@ -0,0 +1,59 @@
+package com.jzg.quotation.chengtai.crawler.model.response;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @ClassName ChengTaiGetCaptchaResponse
+ * @Description 诚泰财险获取验证码返回结果
+ * @Author wenks
+ * @Date 2025/9/9 15:42
+ * @Version 1.0
+ */
+@NoArgsConstructor
+@Data
+public class ChengTaiGetCaptchaResponse {
+
+    @JsonProperty("code")
+    private Integer code;
+
+    @JsonProperty("message")
+    private String message;
+
+    @JsonProperty("body")
+    private BodyDTO body;
+
+    @NoArgsConstructor
+    @Data
+    public static class BodyDTO {
+
+        @JsonProperty("repCode")
+        private String repCode;
+
+        @JsonProperty("repData")
+        private RepDataDTO repData;
+
+        @JsonProperty("success")
+        private Boolean success;
+
+        @NoArgsConstructor
+        @Data
+        public static class RepDataDTO {
+
+            @JsonProperty("secretKey")
+            private String secretKey;
+
+            @JsonProperty("originalImageBase64")
+            private String originalImageBase64;
+
+            @JsonProperty("jigsawImageBase64")
+            private String jigsawImageBase64;
+
+            @JsonProperty("token")
+            private String token;
+
+        }
+    }
+}

+ 20 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/model/response/ChengTaiLoginResponse.java

@@ -0,0 +1,20 @@
+package com.jzg.quotation.chengtai.crawler.model.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@Data
+public class ChengTaiLoginResponse {
+
+    @JsonProperty("code")
+    private Integer code;
+
+    @JsonProperty("message")
+    private String message;
+
+    @JsonProperty("body")
+    private String body;
+
+}

+ 14 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/properties/ChengTaiCrawlerProperties.java

@@ -0,0 +1,14 @@
+package com.jzg.quotation.chengtai.crawler.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "chengtai.crawler")
+public class ChengTaiCrawlerProperties {
+
+    private String baseUrl;
+
+}

+ 39 - 157
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiAPIService.java

@@ -9,6 +9,7 @@ import com.jzg.quotation.chengtai.crawler.model.param.*;
 import com.jzg.quotation.chengtai.crawler.model.result.*;
 import com.jzg.quotation.commons.component.RequestComponent;
 import jakarta.annotation.Resource;
+import lombok.RequiredArgsConstructor;
 import org.apache.commons.collections4.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -25,152 +26,98 @@ import java.util.Map;
 import java.util.UUID;
 
 @Service
+@RequiredArgsConstructor
 public class ChengTaiAPIService {
-    private static final Logger logger = LoggerFactory.getLogger(ChengTaiAPIService.class);
 
-    @Resource
-    private RequestComponent requestComponent;
-
-    @Resource
-    private ChengTaiInsuranceItemService chengTaiInsuranceItemService;
-
-    public void setRequestComponent(RequestComponent requestComponent) {
-        this.requestComponent = requestComponent;
-    }
+    private final RequestComponent requestComponent;
 
     private <T> T post(ChengTaiAPI api, Object body, Class<T> resultClass, HttpHeaders headers) {
-//        headers.add(":authority", "b2b.champion-ic.com");
-//        headers.add(":method", "POST");
-//        headers.add(":path", api.uri());
-//        headers.add(":scheme", "https");
         if (headers != null) {
             headers.add("traceid", UUID.randomUUID().toString());
         }
-
         String paramString = JsonUtil.toJsonString(body);
-
         ResponseEntity<String> responseEntity = requestComponent.post(api.url(), paramString, String.class, headers);
-
         String responseEntityBody = responseEntity.getBody();
-
         T objcet = JsonUtil.readObjcet(responseEntityBody, resultClass);
-
         return objcet;
     }
 
     /**
      * 查询险种
      *
-     * @param token
-     * @return
+     * @param headers 请求头
+     * @return 险种
      */
-    public List<ChengTaiDictionary> findDictionaryOfRisk(String token) {
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
+    public List<ChengTaiDictionary> findDictionaryOfRisk(HttpHeaders headers) {
         ChengTaiFindDictionaryResult.Response result = post(ChengTaiAPI.FindDictionaryOfRisk, null, ChengTaiFindDictionaryResult.Response.class, headers);
-
         return result.getBody();
     }
 
     /**
      * 查询登录用户信息
      *
-     * @param token
-     * @return
+     * @param headers 请求头
+     * @return 登录用户信息
      */
-    public ChengTaiQueryLoginUserInfoResult queryLoginUserInfo(String token) {
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
+    public ChengTaiQueryLoginUserInfoResult queryLoginUserInfo(HttpHeaders headers) {
         ChengTaiQueryLoginUserInfoResult.Response result = post(ChengTaiAPI.QueryLoginUserInfo, null, ChengTaiQueryLoginUserInfoResult.Response.class, headers);
-
         return result.getBody();
     }
 
     /**
      * 查询登录用户可用的业务归属机构
      *
-     * @param token
-     * @return
+     * @param headers 请求头
+     * @return 业务归属机构
      */
-    public List<ChengTaiFindAttributionOrgByUserResult> findAttributionOrgByUser(String token) {
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
+    public List<ChengTaiFindAttributionOrgByUserResult> findAttributionOrgByUser(HttpHeaders headers) {
         ChengTaiFindAttributionOrgByUserResult.Response result = post(ChengTaiAPI.FindAttributionOrgByUser, null, ChengTaiFindAttributionOrgByUserResult.Response.class, headers);
-
         return result.getBody();
     }
 
-    public List<ChengTaiFindSaleManVoByDeptCodeResult> findSaleManVoByDeptCode(String token, String deptCode, String isOuter, List<String> riskCodes) {
+    public List<ChengTaiFindSaleManVoByDeptCodeResult> findSaleManVoByDeptCode(HttpHeaders headers, String deptCode, String isOuter, List<String> riskCodes) {
         ChengTaiFindSaleManVoByDeptCodeParam param = new ChengTaiFindSaleManVoByDeptCodeParam();
         param.setDeptCode(deptCode);
         param.setIsOuter(isOuter);
         param.setRiskCodes(riskCodes);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiFindSaleManVoByDeptCodeResult.Response result = post(ChengTaiAPI.FindSaleManVoByDeptCode, param, ChengTaiFindSaleManVoByDeptCodeResult.Response.class, headers);
-
         return result.getBody();
     }
 
-    public ChengTaiQueryRiskAuthorityResult queryRiskAuthority(String token, String saleCode, String subAgreementCode) {
+    public ChengTaiQueryRiskAuthorityResult queryRiskAuthority(HttpHeaders headers, String saleCode, String subAgreementCode) {
         Map<String, String> param = Maps.newHashMapWithExpectedSize(2);
-
         param.put("saleCode", saleCode);
         param.put("subAgreementCode", subAgreementCode);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiQueryRiskAuthorityResult.Response result = post(ChengTaiAPI.QueryRiskAuthority, param, ChengTaiQueryRiskAuthorityResult.Response.class, headers);
-
         return result.getBody();
     }
 
     /**
      * 查询务人员可用的中介协议和代理机构
      *
-     * @param token
+     * @param headers
      * @param saleCode
      * @param riskCodes
      * @return
      */
-    public ChengTaiFindCoreConferInfoByHandleCodeResult findCoreConferInfoByHandleCode(String token, String saleCode, List<String> riskCodes) {
+    public ChengTaiFindCoreConferInfoByHandleCodeResult findCoreConferInfoByHandleCode(HttpHeaders headers, String saleCode, List<String> riskCodes) {
         Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
-
         param.put("saleCode", saleCode);
         param.put("riskCodes", riskCodes);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiFindCoreConferInfoByHandleCodeResult.Response result = post(ChengTaiAPI.FindCoreConferInfoByHandleCode, null, ChengTaiFindCoreConferInfoByHandleCodeResult.Response.class, headers);
-
         return result.getBody();
     }
 
-    public ChengTaiQueryVehicleListResult queryVehicleList(String token) {
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
+    public ChengTaiQueryVehicleListResult queryVehicleList(HttpHeaders headers) {
         ChengTaiQueryVehicleListResult.Response result = post(ChengTaiAPI.QueryVehicleList, null, ChengTaiQueryVehicleListResult.Response.class, headers);
-
         if (result == null) {
             return null;
         }
-
         ChengTaiQueryVehicleListResult body = result.getBody();
-
         if (body == null) {
             return null;
         }
-
         List<ChengTaiJqxclassidDic> jqxclassidDic = body.getJqxclassidDic();
-
         if (CollectionUtils.isNotEmpty(jqxclassidDic)) {
             jqxclassidDic.forEach(jqxclassid -> {
                 String extdata = jqxclassid.getExtdata();
@@ -193,7 +140,7 @@ public class ChengTaiAPIService {
      * @param vinCode 车架号
      * @return
      */
-    public ChengTaiQueryCarInfoResult queryCarInfo(String token, String comCode, String plateNo, String vinCode) {
+    public ChengTaiQueryCarInfoResult queryCarInfo(HttpHeaders headers, String comCode, String plateNo, String vinCode) {
         if (plateNo == null || plateNo.isBlank()) {
             plateNo = "新车上牌";
         }
@@ -203,12 +150,7 @@ public class ChengTaiAPIService {
         param.put("comCode", comCode);
         param.put("plateNo", plateNo);
         param.put("vinCode", vinCode);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiQueryCarInfoResult.Response result = post(ChengTaiAPI.QueryCarInfo, param, ChengTaiQueryCarInfoResult.Response.class, headers);
-
         return result.getBody();
 
     }
@@ -216,22 +158,16 @@ public class ChengTaiAPIService {
     /**
      * 根据车牌号、车架号查询车型
      *
-     * @param token
+     * @param headers
      * @param modelCode 车型编号
      * @return
      */
-    public ChengTaiFindCarModelResult findCarModel(String token, String modelCode) {
+    public ChengTaiFindCarModelResult findCarModel(HttpHeaders headers, String modelCode) {
         Map<String, String> param = Maps.newHashMapWithExpectedSize(3);
-
         param.put("modelcode: ", modelCode);
         param.put("pageNo", "1");
         param.put("pageSize", "100");
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiFindCarModelResult.Response result = post(ChengTaiAPI.FindCarModel, param, ChengTaiFindCarModelResult.Response.class, headers);
-
         return result.getBody();
 
     }
@@ -239,75 +175,51 @@ public class ChengTaiAPIService {
     /**
      * 身份识别
      *
-     * @param token
      * @param applicant
      * @return
      */
-    public ChengTaiApplicant clientIdentify(String token, ChengTaiApplicant applicant) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
-
+    public ChengTaiApplicant clientIdentify(HttpHeaders headers, ChengTaiApplicant applicant) {
         ChengTaiClientIdentifyResult.Response response = post(ChengTaiAPI.ClientIdentify, applicant, ChengTaiClientIdentifyResult.Response.class, headers);
-
         return response.getBody();
     }
 
     /**
      * 保存
      *
-     * @param token
+     * @param headers
      * @param param
      * @return
      */
-    public ChengTaiSaveResult save(String token, ChengTaiPremiumcalParam param) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
-
+    public ChengTaiSaveResult save(HttpHeaders headers, ChengTaiPremiumcalParam param) {
         ChengTaiSaveResult.Response response = post(ChengTaiAPI.Save, param, ChengTaiSaveResult.Response.class, headers);
-
         return response.getBody();
     }
 
     /**
      * 保费计算
      *
-     * @param token
+     * @param headers
      * @param param
      * @return
      */
-    public ChengTaiPremiumcalResult premiumcal(String token, ChengTaiPremiumcalParam param) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
-
+    public ChengTaiPremiumcalResult premiumcal(HttpHeaders headers, ChengTaiPremiumcalParam param) {
         ChengTaiPremiumcalResult.Response result = post(ChengTaiAPI.Premiumcal, param, ChengTaiPremiumcalResult.Response.class, headers);
-
         return result.getBody();
     }
 
-    public ChengTaiSubmitResult submit(String token, ChengTaiPremiumcalParam param) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
-
+    public ChengTaiSubmitResult submit(HttpHeaders headers, ChengTaiPremiumcalParam param) {
         ChengTaiSubmitResult.Response result = post(ChengTaiAPI.Submit, param, ChengTaiSubmitResult.Response.class, headers);
-
         return result.getBody();
     }
 
     /**
      * 上传影像
      *
-     * @param token
+     * @param headers
      * @param param
      * @return
      */
-    public ChengTaiImageUploadResult imageUpload(String token, byte[] file, ChengTaiImageUploadParam param) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
+    public ChengTaiImageUploadResult imageUpload(HttpHeaders headers, byte[] file, ChengTaiImageUploadParam param) {
 
         MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
         formData.add("uploadVo", param);
@@ -319,11 +231,8 @@ public class ChengTaiAPIService {
         });
 
         ResponseEntity<String> responseEntity = requestComponent.formData(ChengTaiAPI.ImageUpload.url(), formData, String.class, headers);
-
         String responseEntityBody = responseEntity.getBody();
-
         ChengTaiImageUploadResult.Response result = JsonUtil.readObjcet(responseEntityBody, ChengTaiImageUploadResult.Response.class);
-
         return result.getBody();
     }
 
@@ -342,7 +251,7 @@ public class ChengTaiAPIService {
 
         param.add("captchaVerification", captcha);
 
-        ResponseEntity<String> responseEntity = requestComponent.form(ChengTaiAPI.Login.url(), param, String.class, null);
+        ResponseEntity<String> responseEntity = requestComponent.form(ChengTaiAPI.LOGIN.url(), param, String.class, null);
 
         String responseEntityBody = responseEntity.getBody();
 
@@ -358,15 +267,9 @@ public class ChengTaiAPIService {
 
     }
 
-    public ChengTaiSystemResult system(String token) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
-
+    public ChengTaiSystemResult system(HttpHeaders headers) {
         MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
-
         ChengTaiSystemResult.Response response = requestComponent.get(ChengTaiAPI.System.url(), param, null, ChengTaiSystemResult.Response.class, headers);
-
         List<ChengTaiSystemResult> body = response.getBody();
 
         if (body == null || body.isEmpty()) {
@@ -376,11 +279,7 @@ public class ChengTaiAPIService {
         return body.get(0);
     }
 
-    public boolean findAreaConfig(String token) {
-        HttpHeaders headers = new HttpHeaders();
-
-        headers.add("token", token);
-
+    public boolean findAreaConfig(HttpHeaders headers) {
         MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
         ChengTaiFindAreaConfigResult.Response response = requestComponent.get(ChengTaiAPI.FindAreaConfig.url(), param, null, ChengTaiFindAreaConfigResult.Response.class, headers);
 
@@ -404,17 +303,15 @@ public class ChengTaiAPIService {
     /**
      * 获取详情
      *
-     * @param token
+     * @param headers 请求头
      * @param orderId
      * @return
      */
-    public ChengTaiPremiumcalParam getPolicyModel(String token, String orderId) {
+    public ChengTaiPremiumcalParam getPolicyModel(HttpHeaders headers, String orderId) {
         MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
         param.add("orderId", orderId);
         param.add("businessType", "POLICY");
 
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
         ResponseEntity<ChengTaiGetPolicyModelResult.Response> form = requestComponent.form(ChengTaiAPI.GetPolicyModel.url(), param, ChengTaiGetPolicyModelResult.Response.class, headers);
 
         ChengTaiGetPolicyModelResult.Response response = form.getBody();
@@ -426,18 +323,13 @@ public class ChengTaiAPIService {
     /**
      * 获取支付链接
      *
-     * @param token
+     * @param headers 请求头
      * @param uuid
      * @return 就是多个值
      */
-    public List<ChengTaiInsureResult> insure(String token, String uuid) {
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
+    public List<ChengTaiInsureResult> insure(HttpHeaders headers, String uuid) {
         MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
-
         ChengTaiInsureResult.Response response = requestComponent.get(ChengTaiAPI.Insure.url().replace("{uuid}", uuid), param, null, ChengTaiInsureResult.Response.class, headers);
-
         return response.getBody();
 
     }
@@ -445,23 +337,18 @@ public class ChengTaiAPIService {
     /**
      * 获取保单下载链接
      *
-     * @param token
+     * @param headers 请求头
      * @param contractNo
      * @param policyUuid
      * @return
      */
-    public ChengTaiDownloadAddressResult downloadAddress(String token, String contractNo, String policyUuid, String expiryDate) {
+    public ChengTaiDownloadAddressResult downloadAddress(HttpHeaders headers, String contractNo, String policyUuid, String expiryDate) {
         ChengTaiDownloadAddressParam param = new ChengTaiDownloadAddressParam();
         param.setBusinessType("C");
         param.setPolicyUuid(policyUuid);
         param.setContractNo(contractNo);
         param.setValidDate(expiryDate);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiDownloadAddressResult.Response response = post(ChengTaiAPI.DownloadAddress, param, ChengTaiDownloadAddressResult.Response.class, headers);
-
         return response.getBody();
 
     }
@@ -469,22 +356,17 @@ public class ChengTaiAPIService {
     /**
      * 获取意外险
      *
-     * @param token
+     * @param headers 请求头
      * @return
      */
-    public List<ChengTaiAccidentInsurance> hygeiaGet(String token) {
+    public List<ChengTaiAccidentInsurance> hygeiaGet(HttpHeaders headers) {
         ChengTaiHygeiaGetParam param = new ChengTaiHygeiaGetParam();
         param.setComCode("0105");
         param.setSeat(5);
         param.setRiskCode("1158");
         param.setCarKindCode("A0");
         param.setUseNatureCode("8A");
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("token", token);
-
         ChengTaiHygeiaGetResult.Response response = post(ChengTaiAPI.HygeiaGet, param, ChengTaiHygeiaGetResult.Response.class, headers);
-
         return response.getBody();
 
     }

+ 30 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiCrawlerQuoteProcessService.java

@@ -0,0 +1,30 @@
+package com.jzg.quotation.chengtai.crawler.service;
+
+import org.springframework.http.HttpHeaders;
+
+/**
+ * @ClassName ChengTaiCrawlerQuoteProcessService
+ * @Description 诚泰财险报价过程需要的接口
+ * @Author wenks
+ * @Date 2025/9/9 15:29
+ * @Version 1.0
+ */
+public interface ChengTaiCrawlerQuoteProcessService {
+
+    /**
+     * 登录
+     *
+     * @param username 用户名
+     * @param password 密码
+     */
+    void login(String username, String password) throws Exception;
+
+
+    /**
+     * 获取token
+     *
+     * @return 请求头
+     */
+    HttpHeaders getTokenHeaders(String username, String password);
+
+}

+ 54 - 70
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiCrawlerRequestService.java

@@ -6,6 +6,9 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.jzg.commons.entity.quote.vo.*;
 import com.jzg.commons.entity.quote.vo.aggregated.*;
+import com.jzg.commons.entity.quote.vo.base.LoginBase;
+import com.jzg.commons.exception.SystemException;
+import com.jzg.quotation.chengtai.crawler.model.ChengTaiCrawlerConfigureParameters;
 import com.jzg.quotation.chengtai.crawler.model.entity.*;
 import com.jzg.quotation.chengtai.crawler.model.param.ChengTaiImageUploadParam;
 import com.jzg.quotation.chengtai.crawler.model.param.ChengTaiPremiumcalParam;
@@ -13,79 +16,62 @@ import com.jzg.quotation.chengtai.crawler.model.result.*;
 import com.jzg.quotation.chengtai.crawler.repository.ChengTaiLoginSessionRepository;
 import com.jzg.quotation.chengtai.crawler.repository.ChengTaiPremiumcalRepository;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
-import com.jzg.quotation.commons.service.QuotationApiBaseService;
-import jakarta.annotation.Resource;
+import com.jzg.quotation.commons.annotation.QuoteCrawlerService;
+import com.jzg.quotation.commons.constant.InsuranceCode;
+import com.jzg.quotation.commons.service.QuotationCrawlerBaseService;
+import com.jzg.quotation.commons.standard.conversion.ConfigureParametersConversion;
+import lombok.RequiredArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
+import org.springframework.http.HttpHeaders;
 
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
-@Service
-public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
-    @Resource
-    private ChengTaiAPIService chengTaiAPIService;
+@QuoteCrawlerService(value = InsuranceCode.INSURANCE_CHAC)
+@RequiredArgsConstructor
+public class ChengTaiCrawlerRequestService implements QuotationCrawlerBaseService {
 
-    @Resource
-    private ChengTaiLoginSessionRepository chengTaiLoginSessionRepository;
+    private final ChengTaiAPIService chengTaiAPIService;
 
-    @Resource
-    private ChengTaiPremiumcalRepository chengTaiPremiumcalRepository;
+    private final ChengTaiLoginSessionRepository chengTaiLoginSessionRepository;
 
-    private String username;
-    private String password;
+    private final ChengTaiPremiumcalRepository chengTaiPremiumcalRepository;
 
-    public String login() {
-        return login(username, password, null);
-    }
-
-
-    public String login(String username, String password, String captcha) {
-        ChengTaiSession session = chengTaiLoginSessionRepository.findById(username).orElse(null);
-
-        if (session != null) {
-            // 使用 system 接口验证一下 token 是否过期,如果过期置为 null,后面就会重新登录获取新 token。
-            boolean find = chengTaiAPIService.findAreaConfig(session.getToken());
-
-            if (!find) {
-                chengTaiLoginSessionRepository.delete(session);
-                session = null;
-            }
-        }
-
-        if (session == null) {
-            String token = chengTaiAPIService.login(username, password, captcha); // todo
-
-            session = new ChengTaiSession();
-            session.setToken(token);
-            session.setUsername(username);
+    private final ChengTaiCrawlerQuoteProcessService chengTaiCrawlerQuoteProcessService;
 
-            chengTaiLoginSessionRepository.save(session);
+    @Override
+    public void login(LoginBase loginBase)  {
+        try {
+            chengTaiCrawlerQuoteProcessService.login(loginBase.getUsername(), loginBase.getUsername());
+        }catch (Exception ignored){
+            throw new SystemException("登录失败");
         }
-
-        return session.getToken();
     }
 
     @Override
-    public QuoteResultsVo quote(QuoteVo quoteVo) throws JsonProcessingException {
-        String token = login();
-        List<String> riskCodes = Lists.newArrayList();
+    public QuoteResultsVo quote(QuoteVo quoteVo) throws Exception {
+        HttpHeaders httpHeaders = chengTaiCrawlerQuoteProcessService.getTokenHeaders(quoteVo.getOrder().getAttributionInformationVo().getUsername(), quoteVo.getOrder().getAttributionInformationVo().getPassword());
+
+        // 归属配置
+        AttributionInformationVo attributionInformationVo = quoteVo.getOrder().getAttributionInformationVo();
+        ChengTaiCrawlerConfigureParameters parameters = ConfigureParametersConversion.conversionEntity(ChengTaiCrawlerConfigureParameters.class, attributionInformationVo.getConfigInfo());
 
+        List<String> riskCodes = List.of("", "", "");
         // 当前登录人
-        ChengTaiQueryLoginUserInfoResult userInfoResult = chengTaiAPIService.queryLoginUserInfo(token);
+        ChengTaiQueryLoginUserInfoResult userInfoResult = chengTaiAPIService.queryLoginUserInfo(httpHeaders);
 
         // 查询可以使用的业务人员
-        List<ChengTaiFindSaleManVoByDeptCodeResult> saleManVoByDeptCode = chengTaiAPIService.findSaleManVoByDeptCode(token, userInfoResult.getComCode(), "false", riskCodes);
+        List<ChengTaiFindSaleManVoByDeptCodeResult> saleManVoByDeptCode = chengTaiAPIService.findSaleManVoByDeptCode(httpHeaders, userInfoResult.getComCode(), "false", riskCodes);
 
         // 默认使用第1个业务人员
         ChengTaiFindSaleManVoByDeptCodeResult saleManVo = saleManVoByDeptCode.get(0);
 
         // 查询务人员可用的中介协议和代理机构
-        ChengTaiFindCoreConferInfoByHandleCodeResult coreConferInfo = chengTaiAPIService.findCoreConferInfoByHandleCode(token, saleManVo.getUserCode(), riskCodes);
+        ChengTaiFindCoreConferInfoByHandleCodeResult coreConferInfo = chengTaiAPIService.findCoreConferInfoByHandleCode(httpHeaders, saleManVo.getUserCode(), riskCodes);
 
         // 查询务人员可用的业务信息
-        ChengTaiQueryRiskAuthorityResult queryRiskAuthorityResult = chengTaiAPIService.queryRiskAuthority(token, saleManVo.getUserCode(), coreConferInfo.getSolutionCode());
+        ChengTaiQueryRiskAuthorityResult queryRiskAuthorityResult = chengTaiAPIService.queryRiskAuthority(httpHeaders, saleManVo.getUserCode(), coreConferInfo.getSolutionCode());
 
         // 保存保险单数据1 业务人员
         ChengTaiAcciSaleInfo acciSaleInfo = buildChengTaiAcciSaleInfo(coreConferInfo, queryRiskAuthorityResult.getSalesRisks(), queryRiskAuthorityResult.getSubAgreements());
@@ -98,7 +84,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         applicant.setSignedbyOrig("0");
         applicant.setComCode("0105040012");
 
-        applicant = chengTaiAPIService.clientIdentify(token, applicant);
+        applicant = chengTaiAPIService.clientIdentify(httpHeaders, applicant);
 
         // 保存保险单数据3 被投保人
         ChengTaiInsured chengTaiInsured = buildChengTaiInsured(quoteVo.getOwnersInfo());
@@ -124,14 +110,13 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         // 保存保险单数据9
         ChengTaiSubmitReqBody chengTaiSubmitReqBody = buildChengTaiSubmitReqBody();
 
-
-        ChengTaiQueryVehicleListResult queryVehicleListResult = chengTaiAPIService.queryVehicleList(token);
+        ChengTaiQueryVehicleListResult queryVehicleListResult = chengTaiAPIService.queryVehicleList(httpHeaders);
 
         List<ChengTaiUseNature> useNatUreNameList = queryVehicleListResult.getUseNatUreNameList();
 
         ImmutableMap<String, ChengTaiUseNature> map = Maps.uniqueIndex(useNatUreNameList, ChengTaiUseNature::getType);
 
-        List<ChengTaiFindAttributionOrgByUserResult> attributionOrgByUser = chengTaiAPIService.findAttributionOrgByUser(token);
+        List<ChengTaiFindAttributionOrgByUserResult> attributionOrgByUser = chengTaiAPIService.findAttributionOrgByUser(httpHeaders);
 
         ChengTaiFindAttributionOrgByUserResult chengTaiFindAttributionOrgByUserResult = attributionOrgByUser.get(0);
 
@@ -139,7 +124,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         String plateNo = quoteVo.getCarInfoVo().getEngineNo(); // 车牌号
         String vinCode = quoteVo.getCarInfoVo().getVinNo(); // 车架号
 
-        ChengTaiQueryCarInfoResult queryCarInfoResult = chengTaiAPIService.queryCarInfo(token, comCode, plateNo, vinCode);
+        ChengTaiQueryCarInfoResult queryCarInfoResult = chengTaiAPIService.queryCarInfo(httpHeaders, comCode, plateNo, vinCode);
 
         List<ChengTaiQueryCarInfoResult.QueryCarModel> queryCarModels = queryCarInfoResult.getCarModelList();
 
@@ -147,7 +132,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
         ChengTaiCarFullData fullCarData = queryCarModel.getFullCarData();
 
-        ChengTaiFindCarModelResult carModel = chengTaiAPIService.findCarModel(token, fullCarData.getModelCode());
+        ChengTaiFindCarModelResult carModel = chengTaiAPIService.findCarModel(httpHeaders, fullCarData.getModelCode());
 
         List<ChengTaiCarModel> data = carModel.getData();
 
@@ -175,12 +160,11 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         param.setSubmitReqBody(chengTaiSubmitReqBody);
 
 
-        ChengTaiSaveResult save = chengTaiAPIService.save(token, param);
+        ChengTaiSaveResult save = chengTaiAPIService.save(httpHeaders, param);
 
         param = save.getModel();
 
-
-        ChengTaiPremiumcalResult premiumcalResult = chengTaiAPIService.premiumcal(token, param);
+        ChengTaiPremiumcalResult premiumcalResult = chengTaiAPIService.premiumcal(httpHeaders, param);
 
         param.setSunlightId(premiumcalResult.getSunlightId());
 
@@ -193,9 +177,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         // 折扣率
         BigDecimal discount = contractMain.getDiscount();
 
-
         // 保存到 mongo
-
         ChengTaiBiContract saveBiContract = param.getBiContract();
         ChengTaiCiContract saveCiContract = param.getCiContract();
         if (saveBiContract != null) {
@@ -660,13 +642,13 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
     @Override
     public UnderwritingResultsVo underwriting(UnderwritingVo underwritingVo) {
-        String token = login();
+        HttpHeaders httpHeaders = chengTaiCrawlerQuoteProcessService.getTokenHeaders(underwritingVo.getOrder().getAttributionInformationVo().getUsername(), underwritingVo.getOrder().getAttributionInformationVo().getPassword());
 
         String ordersNo = underwritingVo.getOrder().getOrdersNo();
 
         ChengTaiPremiumcalParam param = chengTaiPremiumcalRepository.findByOrdersNo(ordersNo);
 
-        ChengTaiSubmitResult result = chengTaiAPIService.submit(token, param);
+        ChengTaiSubmitResult result = chengTaiAPIService.submit(httpHeaders, param);
 
         ChengTaiSubmitResult.Head head = result.getHead();
 
@@ -688,7 +670,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
     @Override
     public PaymentLinkResultsVo getPaymentLink(PaymentLinkVo paymentLinkVo) throws JsonProcessingException {
-        String token = login();
+        HttpHeaders httpHeaders = chengTaiCrawlerQuoteProcessService.getTokenHeaders(paymentLinkVo.getOrder().getAttributionInformationVo().getUsername(), paymentLinkVo.getOrder().getAttributionInformationVo().getPassword());
 
         String ordersNo = paymentLinkVo.getOrder().getOrdersNo();
 
@@ -696,13 +678,13 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
         String orderId = param.getOrderId();
 
-        param = chengTaiAPIService.getPolicyModel(token, orderId);
+        param = chengTaiAPIService.getPolicyModel(httpHeaders, orderId);
 
         ChengTaiBusinessMain businessMain = param.getBusinessMain();
 
         String uuid = businessMain.getUuid();
 
-        List<ChengTaiInsureResult> insure = chengTaiAPIService.insure(token, uuid);
+        List<ChengTaiInsureResult> insure = chengTaiAPIService.insure(httpHeaders, uuid);
 
         if (insure == null || insure.isEmpty()) {
             return null;
@@ -722,7 +704,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
     @Override
     public void uploadImage(InsuranceUploadImageVo insuranceUploadImageVo) {
-        String token = login();
+        HttpHeaders httpHeaders = chengTaiCrawlerQuoteProcessService.getTokenHeaders(insuranceUploadImageVo.getOrder().getAttributionInformationVo().getUsername(), insuranceUploadImageVo.getOrder().getAttributionInformationVo().getPassword());
 
         String ordersNo = insuranceUploadImageVo.getOrder().getOrdersNo();
 
@@ -759,14 +741,14 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
                 param.setAppCode("CAR01");
                 param.setBusinessNo(businessNo); // todo
 
-                chengTaiAPIService.imageUpload(token, imageBytes, param);
+                chengTaiAPIService.imageUpload(httpHeaders, imageBytes, param);
             }
         }
     }
 
     @Override
     public DownloadPolicyResultVo downloadPolicy(DownloadPolicyVo downloadPolicyVo) {
-        String token = login();
+        HttpHeaders httpHeaders = chengTaiCrawlerQuoteProcessService.getTokenHeaders(downloadPolicyVo.getOrder().getAttributionInformationVo().getUsername(), downloadPolicyVo.getOrder().getAttributionInformationVo().getPassword());
 
         String ordersNo = downloadPolicyVo.getOrder().getOrdersNo();
 
@@ -774,7 +756,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
         String orderId = param.getOrderId();
 
-        param = chengTaiAPIService.getPolicyModel(token, orderId);
+        param = chengTaiAPIService.getPolicyModel(httpHeaders, orderId);
 
         ChengTaiCiContract ciContract = param.getCiContract();
         ChengTaiBiContract biContract = param.getBiContract();
@@ -791,7 +773,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         String policyUuid = contractMain.getPolicyUuid();
         String expiryDate = contractMain.getValidDate();
 
-        ChengTaiDownloadAddressResult chengTaiDownloadAddressResult = chengTaiAPIService.downloadAddress(token, contractNo, policyUuid, expiryDate);
+        ChengTaiDownloadAddressResult chengTaiDownloadAddressResult = chengTaiAPIService.downloadAddress(httpHeaders, contractNo, policyUuid, expiryDate);
 
         List<ChengTaiDownloadAddressResult.QueryResult> queryResults = chengTaiDownloadAddressResult.getQueryResults();
 
@@ -806,7 +788,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
     @Override
     public OrderStatusResultVo queryOrderState(OrderStatusVo orderBase) {
-        String token = login();
+        HttpHeaders httpHeaders = chengTaiCrawlerQuoteProcessService.getTokenHeaders(orderBase.getOrder().getAttributionInformationVo().getUsername(), orderBase.getOrder().getAttributionInformationVo().getPassword());
 
         String ordersNo = orderBase.getOrder().getOrdersNo();
 
@@ -814,7 +796,7 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
 
         String orderId = param.getOrderId();
 
-        param = chengTaiAPIService.getPolicyModel(token, orderId);
+        param = chengTaiAPIService.getPolicyModel(httpHeaders, orderId);
 
         ChengTaiCiContract ciContract = param.getCiContract();
         ChengTaiBiContract biContract = param.getBiContract();
@@ -833,4 +815,6 @@ public class ChengTaiCrawlerRequestService implements QuotationApiBaseService {
         System.out.println("状态为:" + underWriteInd);
         return null;
     }
+
+
 }

+ 77 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/crawler/service/impl/ChengTaiCrawlerQuoteProcessServiceImpl.java

@@ -0,0 +1,77 @@
+package com.jzg.quotation.chengtai.crawler.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.jzg.commons.constants.quote.enums.base.ExpenseRequestUrl;
+import com.jzg.commons.entity.quote.vo.identify.SliderCaptchaVo;
+import com.jzg.quotation.chengtai.crawler.component.ChengTaiRequestCrawlerComponent;
+import com.jzg.quotation.chengtai.crawler.model.request.ChengTaiCheckCaptchaRequest;
+import com.jzg.quotation.chengtai.crawler.model.request.ChengTaiGetCaptchaRequest;
+import com.jzg.quotation.chengtai.crawler.model.request.ChengTaiLoginRequest;
+import com.jzg.quotation.chengtai.crawler.model.response.ChengTaiCheckCaptchaResponse;
+import com.jzg.quotation.chengtai.crawler.model.response.ChengTaiGetCaptchaResponse;
+import com.jzg.quotation.chengtai.crawler.model.response.ChengTaiLoginResponse;
+import com.jzg.quotation.chengtai.crawler.service.ChengTaiCrawlerQuoteProcessService;
+import com.jzg.quotation.chengtai.utils.CryptoUtils;
+import com.jzg.quotation.chengtai.utils.RSACipher;
+import com.jzg.quotation.commons.service.ExteriorUtilsRequest;
+import com.jzg.quotation.commons.utils.Base64ImageUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class ChengTaiCrawlerQuoteProcessServiceImpl implements ChengTaiCrawlerQuoteProcessService {
+
+    private final ChengTaiRequestCrawlerComponent chengTaiRequestCrawlerComponent;
+
+    private final ExteriorUtilsRequest exteriorUtilsRequest;
+
+    @Override
+    public void login(String username, String password) throws Exception {
+        // 步骤一 获取验证码
+        ResponseEntity<ChengTaiGetCaptchaResponse> getCaptchaResponseResponseEntity = chengTaiRequestCrawlerComponent.getCaptcha(new ChengTaiGetCaptchaRequest());
+        ChengTaiGetCaptchaResponse.BodyDTO.RepDataDTO repDataDTO = Optional.of(getCaptchaResponseResponseEntity)
+                .map(ResponseEntity::getBody)
+                .map(ChengTaiGetCaptchaResponse::getBody)
+                .map(ChengTaiGetCaptchaResponse.BodyDTO::getRepData)
+                .orElseThrow(() -> new Exception("获取验证码失败"));
+
+        // 步骤二 获取滑动窗口的位置
+        SliderCaptchaVo sliderCaptchaVo = new SliderCaptchaVo(repDataDTO.getOriginalImageBase64(), repDataDTO.getJigsawImageBase64());
+        List<Integer> integers = exteriorUtilsRequest.sliderCaptchaIdentify(ExpenseRequestUrl.SLIDER_MATCH, sliderCaptchaVo);
+        String secretKey = repDataDTO.getSecretKey();
+
+        // 步骤三 校验验证码
+        Base64ImageUtils.ImageDimensions imageDimensions = Base64ImageUtils.getImageDimensions(repDataDTO.getOriginalImageBase64());
+        double i = 310.0 * (integers.get(0) - 1) / imageDimensions.getWidth();
+        ChengTaiCheckCaptchaRequest.NotchLocation notchLocation = new ChengTaiCheckCaptchaRequest.NotchLocation(i, 5);
+        String jsonString = JSON.toJSONString(notchLocation);
+        String encrypt = CryptoUtils.aesEncrypt(jsonString, secretKey);
+        ChengTaiCheckCaptchaRequest chengTaiCheckCaptchaRequest = new ChengTaiCheckCaptchaRequest(encrypt, repDataDTO.getToken());
+        ResponseEntity<ChengTaiCheckCaptchaResponse> chengTaiCheckCaptchaResponseResponseEntity = chengTaiRequestCrawlerComponent.checkCaptcha(chengTaiCheckCaptchaRequest);
+        String publicKey = ChengTaiRequestCrawlerComponent.getPublicKey(chengTaiCheckCaptchaResponseResponseEntity);
+
+        // 步骤四 登录
+        String pointJson = chengTaiCheckCaptchaResponseResponseEntity.getBody().getBody().getRepData().getPointJson();
+        String token = chengTaiCheckCaptchaResponseResponseEntity.getBody().getBody().getRepData().getToken();
+        String aesDecrypt = CryptoUtils.aesDecrypt(pointJson, secretKey);
+        String s = CryptoUtils.aesEncrypt(token + "---" + aesDecrypt, secretKey);
+        String encrypt1 = new RSACipher(publicKey).encrypt(password);
+        ChengTaiLoginRequest chengTaiLoginRequest = new ChengTaiLoginRequest(username, encrypt1, s);
+        ChengTaiLoginResponse login = chengTaiRequestCrawlerComponent.login(chengTaiLoginRequest);
+        System.out.println(login.getBody());
+    }
+
+    @Override
+    public HttpHeaders getTokenHeaders(String username, String password) {
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.set("token", "eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3NTc0OTM3OTQsImV4cCI6MTc1NzUwNDU5NCwicGF5bG9hZCI6IldkeHJsN3BjSjBYLWtObU9ZTGpxV2pQNjJaQk5ZLTl4eFNMT3pONExzY1Y5UzI0VXliS3E0ZzU3VGdQdi1vaWlGRFdiUXRmcFhNUTlNQjJYbEZoamJtdlBqLUxnLUUzMHA2UU9PNXdrWEFtUUNsLXAxMHVLN0dMMHFVSDA3MTJsdGhJakpuQjhqSFl5ajM0VXJwTFpKSFZWenRhMzNBY0VkaHVSdFFqMW5ONE8yanFia3IwM1JwcklOYnpMZTlTc2ExYVFCRjVaLXFaMzRFOVFqbDJUbXFTdDQwLTZzaTdZOWNKMVc5M1Z5c1djdGlmSlAwYmFCeGNQaGs1SWNVTEY4RGF4OHJvSl81UzNvazVnSjNJdnRfUkJFVlcyTjM4cWdxM2kyZV9qTEZyTEpvcjltRzNCTWx1OS1PUVJQSjRHYmlZYkhwZ3A4RlFQNnlodjNRTmhia0pIUllUd3Jwc3VvMTNIdkZ6UDl4Q1pkckZCY0lFZG9ublAtcVh0dVEtOHlmRlpGd3gySnkwcVVlSzlOVVpDcTF2SlFiYXhJcG11MW1CWmp3R3BPd0NiVjR3R3VleGRXOE1WYnRnakhZc3AifQ.pdPy8G3yhiaWHa6oAlycP5ncp3coKD0Slm6rM9nDN_IIlVFGOgJYxNvsjnZCv0qrb1xaL7LCbDLiPgZFrAZO5A");
+        return httpHeaders;
+    }
+
+}

+ 78 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/utils/CryptoUtils.java

@@ -0,0 +1,78 @@
+package com.jzg.quotation.chengtai.utils;
+
+import cn.hutool.crypto.symmetric.AES;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 加密工具类(基于 Hutool 封装)
+ */
+public class CryptoUtils {
+
+    // ==================== AES 工具方法(ECB 模式) ====================
+
+    /**
+     * AES-ECB-PKCS5Padding 加密(自动处理密钥为 16 字节)
+     *
+     * @param plainText 明文
+     * @param key       密钥(任意长度,自动补空格/截断为 16 字节)
+     * @return Base64 编码的密文
+     */
+    public static String aesEncrypt(String plainText, String key) {
+        try {
+            // 处理密钥:补空格到 16 字节,过长截断(与 Python ljust(16)[:16] 行为一致)
+            byte[] keyBytes = processAesKey(key.getBytes(StandardCharsets.UTF_8));
+
+            // 创建AES实例
+            AES aes = new AES("ECB", "PKCS5Padding", keyBytes);
+
+            // AES-ECB-PKCS5Padding 加密并 Base64 编码
+            return aes.encryptBase64(plainText, StandardCharsets.UTF_8);
+        } catch (Exception e) {
+            throw new RuntimeException("AES加密失败", e);
+        }
+    }
+
+    public static void main(String[] args) {
+        System.out.println(aesEncrypt("{\"x\":88,\"y\":5}", "kRiGHmDBQerYvzm4"));
+    }
+
+    /**
+     * AES-ECB-PKCS5Padding 解密(自动处理密钥为 16 字节)
+     *
+     * @param encryptedText Base64 编码的密文
+     * @param key           密钥(任意长度,自动补空格/截断为 16 字节)
+     * @return 原始明文
+     */
+    public static String aesDecrypt(String encryptedText, String key) {
+        try {
+            // 处理密钥(与加密逻辑一致)
+            byte[] keyBytes = processAesKey(key.getBytes(StandardCharsets.UTF_8));
+
+            // 创建AES实例
+            AES aes = new AES("ECB", "PKCS5Padding", keyBytes);
+
+            // Base64 解码后 AES 解密
+            return aes.decryptStr(encryptedText, StandardCharsets.UTF_8);
+        } catch (Exception e) {
+            throw new RuntimeException("AES解密失败", e);
+        }
+    }
+
+    /**
+     * 处理 AES 密钥(统一为 16 字节,不足补空格,过长截断)
+     * 与 Python 代码 `key.ljust(16)[:16]` 行为完全一致
+     */
+    private static byte[] processAesKey(byte[] originalKey) {
+        byte[] processedKey = new byte[16];
+        int copyLength = Math.min(originalKey.length, 16);
+        // 复制原始密钥的前 16 字节(或全部,若不足 16 字节)
+        System.arraycopy(originalKey, 0, processedKey, 0, copyLength);
+        // 不足 16 字节的部分用空格填充(与 Python `ljust(16)` 一致)
+        for (int i = copyLength; i < 16; i++) {
+            processedKey[i] = (byte) ' ';
+        }
+        return processedKey;
+    }
+
+}

+ 44 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/utils/RSACipher.java

@@ -0,0 +1,44 @@
+package com.jzg.quotation.chengtai.utils;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
+import cn.hutool.crypto.symmetric.AES;
+
+import java.nio.charset.StandardCharsets;
+
+public class RSACipher {
+
+    private final RSA rsa;
+
+    /**
+     * 从 PEM 格式公钥初始化(自动解析头尾标记)
+     * @param publicKeyPem PEM 格式公钥字符串(包含 -----BEGIN PUBLIC KEY----- 头尾)
+     */
+    public RSACipher(String publicKeyPem) {
+        try {
+            // 使用Hutool解析PEM格式公钥
+            this.rsa = new RSA(null, publicKeyPem);
+        } catch (Exception e) {
+            throw new RuntimeException("RSA公钥解析失败", e);
+        }
+    }
+
+    /**
+     * RSA 公钥加密(PKCS#1 v1.5 填充)
+     * @param plaintext 明文(长度限制:RSA 密钥 2048 位时最大 245 字节)
+     * @return Base64 编码的密文
+     */
+    public String encrypt(String plaintext) {
+        try {
+            // 如果 encryptBase64 方法不存在,则使用 encrypt + Base64 编码的方式
+            byte[] encryptedBytes = this.rsa.encrypt(plaintext, StandardCharsets.UTF_8, KeyType.PublicKey);
+            return Base64.encode(encryptedBytes);
+        } catch (Exception e) {
+            throw new RuntimeException("RSA加密失败", e);
+        }
+    }
+
+
+
+}

+ 32 - 0
tenant/insurance/quotation-chengtai/src/main/resources/certs/CFCA EV ROOT.crt

@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
+TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
+MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
+aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
+T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
+sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
+TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
+/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
+7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
+EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
+hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
+a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
+aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
+TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
+PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
+cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
+tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
+BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
+ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
+jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
+ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
+P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
+xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
+Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
+5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
+/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
+AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
+5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----

File diff suppressed because it is too large
+ 0 - 112
tenant/insurance/quotation-chengtai/src/test/java/com/jzg/quotation/chengtai/crawler/service/ChengTaiAPIServiceTest.java


+ 59 - 11
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java

@@ -3,19 +3,19 @@ package com.jzg.quotation.commons.component;
 
 import com.alibaba.fastjson2.JSON;
 import com.jzg.commons.exception.SystemException;
+import com.jzg.quotation.commons.config.WebClientConfig;
 import com.jzg.quotation.commons.utils.RequestObjectConversion;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.core.io.buffer.DataBuffer;
 import org.springframework.core.io.buffer.DataBufferUtils;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
 import org.springframework.stereotype.Component;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.reactive.function.BodyInserters;
 import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
@@ -47,6 +47,44 @@ public class RequestComponent {
      */
     private final WebClient webClient;
 
+    private final WebClientConfig webClientConfig;
+
+    /**
+     * 根据URL选择合适的WebClient(支持SSL)
+     *
+     * @param url 请求URL
+     * @return WebClient实例
+     */
+    private WebClient selectWebClient(String url) {
+        try {
+            if (url.contains("https://")) {
+                String domain = extractDomain(url);
+                if (webClientConfig != null) {
+                    return webClientConfig.createSecureWebClient(domain);
+                }
+            }
+        } catch (Exception e) {
+            log.warn("创建安全WebClient失败,使用默认WebClient", e);
+        }
+        return webClient;
+    }
+
+    /**
+     * 从URL中提取域名
+     *
+     * @param url URL地址
+     * @return 域名
+     */
+    private String extractDomain(String url) {
+        try {
+            String[] parts = url.replace("https://", "").replace("http://", "").split("/");
+            return parts[0].split(":")[0]; // 移除端口号
+        } catch (Exception e) {
+            log.warn("提取域名失败: {}", url, e);
+            return "default";
+        }
+    }
+
     /**
      * 设置请求头
      *
@@ -201,13 +239,21 @@ public class RequestComponent {
             log.debug("request body is {}", body);
         }
         body = Optional.ofNullable(body).orElse("");
-        return webClient.post()
-                .uri(url)
-                .headers(setHeaders(headers))
-                .body(BodyInserters.fromValue(body))
-                .retrieve()
-                .toEntity(responseClass)
-                .block();
+        WebClient webClient = selectWebClient(url);
+        try {
+            return webClient.post()
+                    .uri(url)
+                    .headers(setHeaders(headers))
+                    .body(BodyInserters.fromValue(body))
+                    .retrieve()
+                    .toEntity(responseClass)
+                    .block();
+        }catch (WebClientResponseException e) {
+            // 如果服务端返回非2xx状态码
+            System.err.println("状态码: " + e.getRawStatusCode());
+            System.err.println("响应体: " + e.getResponseBodyAsString());
+            throw e;
+        }
     }
 
     /**
@@ -304,6 +350,7 @@ public class RequestComponent {
      * @return 响应
      */
     public <Response> ResponseEntity<Response> formData(String url, MultiValueMap<String, Object> parts, Class<Response> responseClass, HttpHeaders headers) {
+        WebClient webClient = selectWebClient(url);
 //        String block = webClient.post()
 //                .uri(url)
 //                .headers(RequestComponent.setHeaders(headers))
@@ -518,7 +565,8 @@ public class RequestComponent {
     }
 
     public <Response> ResponseEntity<Response> form(String url, MultiValueMap<String, String> formData, Class<Response> responseClass, HttpHeaders headers) {
-        return WebClient.create()
+        WebClient selectWebClient = selectWebClient(url);
+        return selectWebClient
                 .post()
                 .uri(url)
                 .headers(RequestComponent.setHeaders(headers))

+ 54 - 0
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/config/SslConfig.java

@@ -0,0 +1,54 @@
+package com.jzg.quotation.commons.config;
+
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import org.springframework.util.ResourceUtils;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+
+public class SslConfig {
+
+    // 从 .crt 文件创建 X509TrustManager
+    public static X509TrustManager createTrustManager(String certPath) throws Exception {
+        // 加载 .crt 证书
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        File certFile = ResourceUtils.getFile(certPath);
+        FileInputStream fis = new FileInputStream(certFile);
+        Certificate cert = cf.generateCertificate(fis);
+        fis.close();
+
+        // 创建 KeyStore 并存储证书
+        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        keyStore.load(null, null); // 初始化空 KeyStore
+        keyStore.setCertificateEntry("server-cert", cert);
+
+        // 初始化 TrustManagerFactory
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        tmf.init(keyStore);
+
+        // 获取 X509TrustManager
+        TrustManager[] trustManagers = tmf.getTrustManagers();
+        for (TrustManager tm : trustManagers) {
+            if (tm instanceof X509TrustManager) {
+                return (X509TrustManager) tm;
+            }
+        }
+        throw new IllegalStateException("No X509TrustManager found");
+    }
+
+    // 构建 SslContext
+    public static SslContext buildSslContext(String certPath) throws Exception {
+        X509TrustManager trustManager = createTrustManager(certPath);
+        return SslContextBuilder.forClient().trustManager(trustManager)
+                // 若服务端证书主机名与实际域名不一致(如自签名),可禁用主机名验证(仅测试用)
+                // .hostnameVerifier((hostname, session) -> true)
+                .build();
+    }
+}

+ 85 - 37
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/config/WebClientConfig.java

@@ -1,14 +1,17 @@
 package com.jzg.quotation.commons.config;
 
 import io.netty.channel.ChannelOption;
+import io.netty.handler.ssl.SslContext;
 import io.netty.handler.timeout.ReadTimeoutHandler;
 import io.netty.handler.timeout.WriteTimeoutHandler;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.http.ssl.SSLContextBuilder;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.util.ResourceUtils;
 import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
 import org.springframework.web.reactive.function.client.ExchangeStrategies;
 import org.springframework.web.reactive.function.client.WebClient;
@@ -16,8 +19,11 @@ import org.springframework.web.util.DefaultUriBuilderFactory;
 import reactor.core.publisher.Mono;
 import reactor.netty.http.client.HttpClient;
 import reactor.netty.resources.ConnectionProvider;
+import reactor.netty.tcp.SslProvider;
 
 import java.time.Duration;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Map;
 
 /**
  * @description: WebClientCon 配置类
@@ -43,50 +49,92 @@ public class WebClientConfig {
 
     public static final int MAX_IN_MEMORY_SIZE = 10 * 1024 * 1024;
 
+    // 存储域名与证书路径的映射关系
+    private final Map<String, String> domainCertMap = new ConcurrentHashMap<>();
+
+    // 存储SSL上下文缓存
+    private final Map<String, SslContext> sslContextCache = new ConcurrentHashMap<>();
+
+    public WebClientConfig() {
+        // 初始化域名与证书映射关系
+        domainCertMap.put("champion-ic.com", "classpath:certs/CFCA EV ROOT.crt");
+    }
+
     @Bean
     public WebClient clientBuilder() {
+        // 配置默认HTTP客户端(无SSL)
+        ConnectionProvider connectionProvider = ConnectionProvider.builder("http").maxConnections(CONNECTION_PROVIDER_MAX_CONNECTIONS).maxIdleTime(CONNECTION_PROVIDER_MAX_IDLE_TIME).build();
+
+        HttpClient httpClient = HttpClient.create(connectionProvider).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, HTTPCLIENT_CONNECT_TIMEOUT_MILLIS).responseTimeout(HTTPCLIENT_RESPONSE_TIMEOUT).doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(READ_TIMEOUT)).addHandlerLast(new WriteTimeoutHandler(WRITE_TIMEOUT)));
+
+        // 构建WebClient实例
+        DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
+        factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
+        return WebClient.builder().exchangeStrategies(ExchangeStrategies.builder().codecs(clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().maxInMemorySize(MAX_IN_MEMORY_SIZE)).build()).uriBuilderFactory(factory).clientConnector(new ReactorClientHttpConnector(httpClient)).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).filter(ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
+            log.info("Client request: {}", clientRequest.url());
+            // 打印请求头信息
+            clientRequest.headers().forEach((key, values) -> {
+                log.info("请求头: {}: {}", key, values);
+            });
+            return Mono.just(clientRequest);
+        })).build();
+    }
+
+    /**
+     * 为特定域名创建带SSL认证的WebClient
+     *
+     * @param domain 域名
+     * @return WebClient实例
+     */
+    public WebClient createSecureWebClient(String domain) throws Exception {
         // 配置HTTP连接池
-        ConnectionProvider connectionProvider = ConnectionProvider
-                .builder("http")
-                .maxConnections(CONNECTION_PROVIDER_MAX_CONNECTIONS)
-                .maxIdleTime(CONNECTION_PROVIDER_MAX_IDLE_TIME)
-                .build();
-
-        // 配置HTTP客户端
-        HttpClient httpClient = HttpClient
-                .create(connectionProvider)
-                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, HTTPCLIENT_CONNECT_TIMEOUT_MILLIS)
-                .responseTimeout(HTTPCLIENT_RESPONSE_TIMEOUT)
-                .doOnConnected(conn ->
-                        conn
-                                .addHandlerLast(new ReadTimeoutHandler(READ_TIMEOUT))
-                                .addHandlerLast(new WriteTimeoutHandler(WRITE_TIMEOUT)));
+        ConnectionProvider connectionProvider = ConnectionProvider.builder("secure-" + domain).maxConnections(CONNECTION_PROVIDER_MAX_CONNECTIONS).maxIdleTime(CONNECTION_PROVIDER_MAX_IDLE_TIME).build();
+
+        // 获取域名对应的SSL上下文
+        SslContext sslContext = getSSLContextForDomain(domain);
+
+        // 配置带SSL的HTTP客户端
+        HttpClient httpClient = HttpClient.create(connectionProvider).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, HTTPCLIENT_CONNECT_TIMEOUT_MILLIS).responseTimeout(HTTPCLIENT_RESPONSE_TIMEOUT).secure(spec -> spec.sslContext(sslContext)).doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(READ_TIMEOUT)).addHandlerLast(new WriteTimeoutHandler(WRITE_TIMEOUT)));
+
         // 构建WebClient实例
         DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
         factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
-        return WebClient
-                .builder()
-                .exchangeStrategies(ExchangeStrategies.builder()
-                        .codecs(clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().maxInMemorySize(MAX_IN_MEMORY_SIZE))
-                        .build())
-                .uriBuilderFactory(factory)
-                .clientConnector(new ReactorClientHttpConnector(httpClient))
-                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
-                .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
-                .filter(ExchangeFilterFunction.ofRequestProcessor(
-                        clientRequest -> {
-                            log.info("Client request: {}", clientRequest.url());
-                            // 打印请求头信息
-                            clientRequest
-                                    .headers()
-                                    .forEach((key, values) -> {
-                                        log.info("请求头: {}: {}", key, values);
-                                    });
-                            return Mono.just(clientRequest);
-                        }
-                ))
-                .build();
+        return WebClient.builder().exchangeStrategies(ExchangeStrategies.builder().codecs(clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().maxInMemorySize(MAX_IN_MEMORY_SIZE)).build()).uriBuilderFactory(factory).clientConnector(new ReactorClientHttpConnector(httpClient)).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).filter(ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
+            log.info("Secure client request: {}", clientRequest.url());
+            // 打印请求头信息
+            clientRequest.headers().forEach((key, values) -> {
+                log.info("请求头: {}: {}", key, values);
+            });
+            return Mono.just(clientRequest);
+        })).build();
     }
 
+    /**
+     * 根据域名获取对应的SSL上下文
+     *
+     * @param domain 域名
+     * @return SSLContext实例
+     */
+    private SslContext getSSLContextForDomain(String domain) throws Exception {
+        // 先从缓存中获取
+        if (sslContextCache.containsKey(domain)) {
+            return sslContextCache.get(domain);
+        }
 
+        // 获取域名对应的证书路径
+        String certPath = domainCertMap.getOrDefault(domain, "classpath:certs/CFCA EV ROOT.crt");
+
+        try {
+            // 创建SSL上下文
+            SslContext sslContext = SslConfig.buildSslContext(certPath);
+
+            // 缓存SSL上下文
+            sslContextCache.put(domain, sslContext);
+
+            return sslContext;
+        } catch (Exception e) {
+            log.error("Failed to create SSL context for domain: {}, certPath: {}", domain, certPath, e);
+            throw e;
+        }
+    }
 }

+ 2 - 1
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/service/ExteriorUtilsRequest.java

@@ -1,6 +1,7 @@
 package com.jzg.quotation.commons.service;
 
 
+import com.jzg.commons.constants.quote.enums.base.ExpenseRequestUrl;
 import com.jzg.commons.entity.quote.vo.identify.ReinsuranceCaptchaVo;
 import com.jzg.commons.entity.quote.vo.identify.SliderCaptchaVo;
 
@@ -35,6 +36,6 @@ public interface ExteriorUtilsRequest {
      * @param sliderCaptchaVo 滑块验证码
      * @return 识别位置列表 [x, y]
      */
-    List<Integer> sliderCaptchaIdentify(SliderCaptchaVo sliderCaptchaVo);
+    List<Integer> sliderCaptchaIdentify(ExpenseRequestUrl expenseRequestUrl, SliderCaptchaVo sliderCaptchaVo);
 }
 

+ 5 - 4
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/service/impl/ExteriorUtilsRequestImpl.java

@@ -54,12 +54,13 @@ public class ExteriorUtilsRequestImpl implements ExteriorUtilsRequest {
     }
 
     @Override
-    public List<Integer> sliderCaptchaIdentify(SliderCaptchaVo sliderCaptchaVo) {
-        ExpenseRequestUrl captcha = ExpenseRequestUrl.SLIDER_IDENTIFY;
-        String url = ExpenseRequestUrl.getUrl(captchaRecognitionProperties.getUrl(), captcha.getUri());
-        R<List<Integer>> response = requestComponent.post(url, sliderCaptchaVo, captcha.getDescription(), new ParameterizedTypeReference<>() {
+    public List<Integer> sliderCaptchaIdentify(ExpenseRequestUrl expenseRequestUrl, SliderCaptchaVo sliderCaptchaVo) {
+        String url = ExpenseRequestUrl.getUrl(captchaRecognitionProperties.getUrl(), expenseRequestUrl.getUri());
+        R<List<Integer>> response = requestComponent.post(url, sliderCaptchaVo, expenseRequestUrl.getDescription(), new ParameterizedTypeReference<>() {
         }, new HttpHeaders());
         return response.getData();
     }
 
+
+
 }

+ 56 - 0
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/Base64ImageUtils.java

@@ -0,0 +1,56 @@
+package com.jzg.quotation.commons.utils;
+
+
+import com.jzg.commons.exception.SystemException;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Base64;
+
+public final class Base64ImageUtils {
+
+    /**
+     * 获取 Base64 图片的宽高
+     *
+     * @param base64Str Base64 图片字符串(可能包含前缀)
+     * @return 宽高数组 [width, height],失败返回 null
+     */
+    public static ImageDimensions getImageDimensions(String base64Str) {
+        try {
+            // 步骤1:去除 Base64 前缀(如果有)
+            String base64Data = base64Str.replaceAll("^data:image/[^;]+;base64,", "");
+
+            // 步骤2:Base64 解码为字节数组
+            byte[] imageBytes = Base64.getDecoder().decode(base64Data);
+
+            // 步骤3:通过 ImageIO 读取图片并获取宽高
+            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
+            if (image == null) {
+                throw new SystemException("无法识别的图片格式");
+            }
+            return new ImageDimensions(image.getWidth(), image.getHeight());
+
+        } catch (IllegalArgumentException e) {
+            throw new SystemException("Base64 解码失败:" + e.getMessage());
+        } catch (IOException e) {
+            throw new SystemException("读取图片失败:" + e.getMessage());
+        }
+    }
+
+    @Data
+    @AllArgsConstructor
+    public static class ImageDimensions {
+
+        private final int width;
+
+        private final int height;
+
+    }
+
+
+}

+ 13 - 27
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/DateUtil.java

@@ -402,38 +402,24 @@ public class DateUtil {
         return newDateStr;
     }
 
-    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-    private static final DateTimeFormatter OUTPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
+    private static final DateTimeFormatter INPUT_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
 
     /**
-     * 将 yyyy-MM-dd 转换为 UTC 时间字符串 (带毫秒 + Z)
-     * @param dateStr yyyy-MM-dd 格式字符串
-     * @param hour 小时
-     * @param minute 分钟
-     * @return UTC 时间字符串,例如:2025-08-20T16:00:00.000Z
+     * 将北京时间(yyyy-MM-dd HH:mm:ss)转换为UTC时间(ISO8601格式)
      */
-    public static String toUtc(String dateStr, int hour, int minute) {
-        LocalDate localDate = LocalDate.parse(dateStr, DATE_FORMATTER);
-        LocalDateTime localDateTime = localDate.atTime(hour, minute, 0);
-        Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
-        return OUTPUT_FORMATTER.format(instant.atOffset(ZoneOffset.UTC));
-    }
+    public static String toUtcDateTime(String beijingTime) {
+        // 解析输入的北京时间
+        LocalDateTime localDateTime = LocalDateTime.parse(beijingTime, INPUT_FORMAT);
 
-    /** 默认 00:00:00 */
-    public static String toUtc(String dateStr) {
-        return toUtc(dateStr, 0, 0);
-    }
+        // 指定时区为中国北京时间
+        ZonedDateTime beijingZoned = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
 
-    /**
-     * 将 yyyy-MM-dd HH:mm:ss 转换为 UTC 时间字符串 (带毫秒 + Z)
-     * @param datetimeStr yyyy-MM-dd HH:mm:ss 格式字符串
-     * @return UTC 时间字符串,例如:2025-08-20T16:00:00.000Z
-     */
-    public static String toUtcDateTime(String datetimeStr) {
-        LocalDateTime localDateTime = LocalDateTime.parse(datetimeStr, DATETIME_FORMATTER);
-        Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
-        return OUTPUT_FORMATTER.format(instant.atOffset(ZoneOffset.UTC));
+        // 转为UTC时区
+        ZonedDateTime utcZoned = beijingZoned.withZoneSameInstant(ZoneId.of("UTC"));
+
+        // 格式化为ISO8601字符串
+        return utcZoned.format(OUTPUT_FORMAT);
     }
 
     public static void main(String[] args) throws ParseException {

+ 34 - 19
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/build/HbCrawlerQuoteResultVoBuild.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.hengbang.crawler.build;
 
+import cn.hutool.core.collection.CollUtil;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.entity.quote.vo.KindInfoVo;
 import com.jzg.commons.entity.quote.vo.RiskInfoVo;
@@ -9,6 +10,7 @@ import com.jzg.quotation.hengbang.crawler.entity.response.HbCrawlerProposalRespo
 
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
@@ -41,33 +43,40 @@ public final class HbCrawlerQuoteResultVoBuild {
     public static RiskInfoVo buildCiInfo(HbCrawlerProposalResponse proposalResponse) {
         RiskInfoVo ciRiskInfoVo = new RiskInfoVo();
         HbCrawlerProposalResponse.ForceCarInsureRiskDTO forceCarInsureRisk = proposalResponse.getForceCarInsureRisk();
-        ciRiskInfoVo.setRiskCode(forceCarInsureRisk.getRiskcode());
-        ciRiskInfoVo.setStartDate(forceCarInsureRisk.getBegintime());
-        ciRiskInfoVo.setEndDate(forceCarInsureRisk.getEndtime());
+        if(Objects.nonNull(forceCarInsureRisk)){
+            ciRiskInfoVo.setRiskCode(forceCarInsureRisk.getRiskcode());
+            ciRiskInfoVo.setStartDate(forceCarInsureRisk.getBegintime());
+            ciRiskInfoVo.setEndDate(forceCarInsureRisk.getEndtime());
+        }
         return ciRiskInfoVo;
+
     }
 
     public static RiskInfoVo buildbiInfo(HbCrawlerProposalResponse proposalResponse) {
         RiskInfoVo biRiskInfoVo = new RiskInfoVo();
         HbCrawlerProposalResponse.BusiCarInsureRiskDTO busiCarInsureRisk = proposalResponse.getBusiCarInsureRisk();
-        biRiskInfoVo.setRiskCode(busiCarInsureRisk.getRiskcode());
-        biRiskInfoVo.setStartDate(busiCarInsureRisk.getBegintime());
-        biRiskInfoVo.setEndDate(busiCarInsureRisk.getEndtime());
+        if(Objects.nonNull(busiCarInsureRisk)){
+            biRiskInfoVo.setRiskCode(busiCarInsureRisk.getRiskcode());
+            biRiskInfoVo.setStartDate(busiCarInsureRisk.getBegintime());
+            biRiskInfoVo.setEndDate(busiCarInsureRisk.getEndtime());
+        }
         return biRiskInfoVo;
     }
 
     public static List<KindInfoVo> buildKindInfoList(HbCrawlerProposalResponse proposalResponse, QuoteVo quoteVo) {
         List<KindInfoVo> kindInfoVoList = quoteVo.getKindInfoVo();
-        List<HbCrawlerProposalResponse.CarInsureLiabilityDTO> carInsureLiabilityList = proposalResponse.getCarInsureLiabilityList();
-        Map<String, HbCrawlerProposalResponse.CarInsureLiabilityDTO> carInsureLiabilityDTOMap = carInsureLiabilityList.stream().collect(Collectors.toMap(HbCrawlerProposalResponse.CarInsureLiabilityDTO::getKindcode, carInsureLiabilityDTO -> carInsureLiabilityDTO));
-        kindInfoVoList.forEach(kindInfoVo -> {
-            HbCrawlerProposalResponse.CarInsureLiabilityDTO carInsureLiabilityDTO = carInsureLiabilityDTOMap.get(kindInfoVo.getKindCode());
-            kindInfoVo.setAmount(String.valueOf(carInsureLiabilityDTO.getLiabamt()));
-            kindInfoVo.setPremium(String.valueOf(carInsureLiabilityDTO.getLiabprm()));
-            kindInfoVo.setUnitAmount(carInsureLiabilityDTO.getUnitAmount());
-            kindInfoVo.setQuantity(String.valueOf(carInsureLiabilityDTO.getQuantity()));
-            kindInfoVo.setDeductibleRate(carInsureLiabilityDTO.getLiabrate());
-        });
+        if(CollUtil.isNotEmpty(kindInfoVoList)){
+            List<HbCrawlerProposalResponse.CarInsureLiabilityDTO> carInsureLiabilityList = proposalResponse.getCarInsureLiabilityList();
+            Map<String, HbCrawlerProposalResponse.CarInsureLiabilityDTO> carInsureLiabilityDTOMap = carInsureLiabilityList.stream().collect(Collectors.toMap(HbCrawlerProposalResponse.CarInsureLiabilityDTO::getKindcode, carInsureLiabilityDTO -> carInsureLiabilityDTO));
+            kindInfoVoList.forEach(kindInfoVo -> {
+                HbCrawlerProposalResponse.CarInsureLiabilityDTO carInsureLiabilityDTO = carInsureLiabilityDTOMap.get(kindInfoVo.getKindCode());
+                kindInfoVo.setAmount(String.valueOf(carInsureLiabilityDTO.getLiabamt()));
+                kindInfoVo.setPremium(String.valueOf(carInsureLiabilityDTO.getLiabprm()));
+                kindInfoVo.setUnitAmount(carInsureLiabilityDTO.getUnitAmount());
+                kindInfoVo.setQuantity(String.valueOf(carInsureLiabilityDTO.getQuantity()));
+                kindInfoVo.setDeductibleRate(carInsureLiabilityDTO.getLiabrate());
+            });
+        }
         return kindInfoVoList;
     }
 
@@ -77,9 +86,15 @@ public final class HbCrawlerQuoteResultVoBuild {
         //商业险数据
         HbCrawlerProposalResponse.BusiCarInsureRiskDTO busiCarInsureRisk = proposalResponse.getBusiCarInsureRisk();
         HbCrawlerProposalResponse.CarInsureShiptaxDTO carInsureShiptax = proposalResponse.getCarInsureShiptax();
-        quoteResultsVo.getCosts().setBiPremium(busiCarInsureRisk.getSumPremium());
-        quoteResultsVo.getCosts().setCiPremium(forceCarInsureRisk.getSumPremium());
-        quoteResultsVo.getCosts().setVvTax(carInsureShiptax.getSumtax());
+        if(Objects.nonNull(busiCarInsureRisk)){
+            quoteResultsVo.getCosts().setBiPremium(busiCarInsureRisk.getSumPremium());
+        }
+        if(Objects.nonNull(forceCarInsureRisk)){
+            quoteResultsVo.getCosts().setCiPremium(forceCarInsureRisk.getSumPremium());
+        }
+        if(Objects.nonNull(carInsureShiptax)){
+            quoteResultsVo.getCosts().setVvTax(carInsureShiptax.getSumtax());
+        }
         //设置非车保费
         quoteResultsVo.getCosts().setNiPremium(proposalResponse.getAccidentTotalPremium());
     }

+ 41 - 11
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/component/HengBangCrawlerRequestComponent.java

@@ -3,7 +3,6 @@ package com.jzg.quotation.hengbang.crawler.component;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.StringUtils;
@@ -18,15 +17,17 @@ import com.jzg.quotation.hengbang.crawler.entity.request.*;
 import com.jzg.quotation.hengbang.crawler.entity.response.*;
 import com.jzg.quotation.hengbang.crawler.properties.HengBangCrawlerProperties;
 import com.jzg.quotation.hengbang.crawler.utils.HengBangAESUtil;
+import jakarta.annotation.Resource;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RMap;
 import org.redisson.api.RedissonClient;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
 import org.springframework.stereotype.Component;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
 
 import javax.crypto.Cipher;
 import javax.crypto.spec.IvParameterSpec;
@@ -52,6 +53,8 @@ public class HengBangCrawlerRequestComponent {
 
     private final RequestComponent requestComponent;
 
+    private final RestTemplate restTemplate;
+
     /**
      * 验证码
      *
@@ -291,9 +294,15 @@ public class HengBangCrawlerRequestComponent {
             System.out.println(HengBangAESUtil.decryptStr(response.getHbEncD()));
             String resJson = HengBangAESUtil.decryptStr(response.getHbEncD());
             return JSONObject.parseObject(resJson).getString("message");
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new SystemException("加密解密异常!");
+        } catch (WebClientResponseException e) {
+            if(e.getStatusCode().equals(HttpStatusCode.valueOf(500))){
+                return JSONObject.parseObject(e.getMessage()).getString("detail");
+            }else{
+                throw new SystemException(e.getMessage());
+            }
+        }
+        catch (Exception e) {
+            throw new SystemException(e.getMessage());
         }
     }
 
@@ -353,13 +362,33 @@ public class HengBangCrawlerRequestComponent {
      *
      * @param plyappno
      * @param headers
+     * @param paramList
+     * @return
+     */
+    public String coreProposal(String plyappno, HttpHeaders headers, List<Map<String, String>> paramList) {
+        try {
+            ResponseEntity<String> responseEntity = requestComponent.objectPost(RequestUrl.SUBMIT.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + "/" +plyappno, paramList, String.class, headers);
+            return JSONObject.parseObject(responseEntity.getBody()).getString("message");
+        } catch (WebClientResponseException e) {
+            if(e.getStatusCode().equals(HttpStatusCode.valueOf(500))){
+                return JSONObject.parseObject(e.getMessage()).getString("detail");
+            }else{
+                throw new SystemException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * 获取核保信息
+     * @param plyappno
+     * @param headers
      * @return
      */
-    public HbCrawlerCoreProposalResponse coreProposal(String plyappno, HttpHeaders headers) {
-        Map<String, String> params = new HashMap<>();
-        params.put("plyappno", plyappno);
-        ResponseEntity<HbCrawlerCoreProposalResponse> responseEntity = requestComponent.objectPost(RequestUrl.SUBMIT.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + plyappno, params, HbCrawlerCoreProposalResponse.class, headers);
-        return responseEntity.getBody();
+    public HbCrawlerCoreProposalResponse coreProposalResult(String plyappno, HttpHeaders headers) {
+        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+        map.add("plyappno", plyappno);
+        HbCrawlerCoreProposalResponse response = requestComponent.get(RequestUrl.SUBMIT_RESULT.getRequestUrl(hbCrawlerProperties.getBaseUrl()), map, "", HbCrawlerCoreProposalResponse.class, headers);
+        return response;
     }
 
     /**
@@ -424,4 +453,5 @@ public class HengBangCrawlerRequestComponent {
                 .concat(plyappno), null, HbCrawlerPayUrlResponse.class, headers).getBody();
     }
 
+
 }

+ 3 - 1
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/constant/enums/RequestUrl.java

@@ -27,7 +27,9 @@ public enum RequestUrl implements CrawlerRequestUrlStandard {
 
     FILEBUFF_UPLOAD("/interflow/api/filebuff-upload/batch-folder?imgType=tihe&plyappno=", "上传影像"),
 
-    SUBMIT("/new-insure/api/carinsurenew/coreproposal", "提交核保"),
+    SUBMIT("/new-insure/api/carinsurenew/quoteToProposal", "提交核保"),
+
+    SUBMIT_RESULT("/new-insure/api/carinsurenew/coreproposal", "获取核保信息"),
 
     ORDER_STATE("/new-insure/api/carInsureMain/list", "查询投保单状态"),
 

+ 2 - 1
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerCalculationRequest.java

@@ -83,6 +83,7 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest{
             this.begintimeBi = DateUtil.toUtcDateTime(quoteVo.getBiRiskInfoVo().getStartDate());
             this.risktype = "2";
         }else{
+//            this.begintimeBi = DateUtil.toUtcDateTime(quoteVo.getCiRiskInfoVo().getStartDate());
             this.epersonliabilityList = new ArrayList<>();
         }
         if(Objects.nonNull(quoteVo.getCiRiskInfoVo())){
@@ -117,7 +118,7 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest{
         return epersonliabilityDTOList;
     }
 
-    private String outofwarrantytype;
+//    private String outofwarrantytype;
     private String clauseType;
     private List<String> ecarChargingPosts;
     private List<String> carInsureDevices;

+ 14 - 8
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerFileUploadRequest.java

@@ -6,6 +6,7 @@ import java.io.Serial;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @description: 恒邦财险 上传影像 请求参数
@@ -17,14 +18,12 @@ public class HbCrawlerFileUploadRequest extends HbBaseRequest{
     @Serial
     private static final long serialVersionUID = 781293083595362938L;
 
-    public HbCrawlerFileUploadRequest(String fileBuff, String fileType, String mark3, Integer fileNum) {
-        this.file_buff = fileBuff;
-        this.file_type = fileType;
+    public HbCrawlerFileUploadRequest(List<String> fileBuff, List<String> fileType, List<String> mark3, List<ExtJsonDTO.ExtArrDTO> fileNum) {
+        this.file_buff = fileBuff.stream().collect(Collectors.joining("||"));
+        this.file_type = fileType.stream().collect(Collectors.joining("||"));
         ExtJsonDTO extJsonDTO = new ExtJsonDTO();
-        extJsonDTO.setMark3(mark3);
-        List<ExtJsonDTO.ExtArrDTO> extArrDTOList = new ArrayList<>(fileNum);
-        extArrDTOList.add(new ExtJsonDTO.ExtArrDTO());
-        extJsonDTO.setExtArr(extArrDTOList);
+        extJsonDTO.setMark3(mark3.stream().collect(Collectors.joining(",")));
+        extJsonDTO.setExtArr(fileNum);
         this.ext_json = extJsonDTO;
     }
 
@@ -47,9 +46,16 @@ public class HbCrawlerFileUploadRequest extends HbBaseRequest{
         public static class ExtArrDTO implements Serializable {
             @Serial
             private static final long serialVersionUID = 4521445632452212652L;
-            private String ocrFlag = "0";
+            private String ocrFlag;
             private String name;
             private String id_number;
+            private String plate_no;
+            private String vin_code;
+            private String engine_no;
+            private String register_date;
+            private String issue_date;
+            private String owner;
         }
+
     }
 }

+ 4 - 1
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerQuoteimmediatelyRequest.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.jzg.commons.entity.quote.vo.CarInfoVo;
 import com.jzg.commons.entity.quote.vo.CustomerInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
+import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.hengbang.crawler.entity.HengBangCrawlerConfigureParameters;
 import com.jzg.quotation.hengbang.crawler.entity.dto.HbEncDTO;
 import com.jzg.quotation.hengbang.crawler.entity.response.HbCrawlerQueryCarResponse;
@@ -68,7 +69,7 @@ public class HbCrawlerQuoteimmediatelyRequest extends HbBaseRequest {
         carInsureItemDTO.setModelCode(contentDTO.getModelCode());
         carInsureItemDTO.setFamilyName(contentDTO.getFamilyName());
         carInsureItemDTO.setAttachNature(carInfoVo.getPropertyCode());
-        carInsureItemDTO.setCiModelCode(contentDTO.getCimodelCode());
+        carInsureItemDTO.setCiModelCode(StringUtils.isNotBlank(contentDTO.getCimodelCode())? contentDTO.getCimodelCode() : contentDTO.getCimodelCodeC());
         carInsureItemDTO.setPurchasePriceNotTax(Double.parseDouble(contentDTO.getPurchasePriceNotTax()));
         carInsureItemDTO.setStyleUniqueId(contentDTO.getVehicleStyleUniqueId());
         carInsureItemDTO.setCountyCode(ownersInfo.getCountyCode());
@@ -77,6 +78,8 @@ public class HbCrawlerQuoteimmediatelyRequest extends HbBaseRequest {
         carInsureItemDTO.setPostCode(ownersInfo.getCountyCode());
         carInsureItemDTO.setChgownerFlag(carInfoVo.isTransfer()? "1" : "0");
         carInsureItemDTO.setSpecialCarFlag("1");
+        carInsureItemDTO.setTotalTonCount("0.00");
+        carInsureItemDTO.setNoticeType(contentDTO.getNoticeType());
         this.carInsureItem = carInsureItemDTO;
         //设置被保人
         CarInsureRiskRelatedPartyDTO riskRelatedPartyDTO = new CarInsureRiskRelatedPartyDTO();

+ 128 - 26
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java

@@ -1,8 +1,12 @@
 package com.jzg.quotation.hengbang.crawler.service.Impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.crypto.digest.DigestUtil;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.jzg.commons.constants.ProductsType;
+import com.jzg.commons.constants.quote.enums.base.InsuranceImageEnum;
+import com.jzg.commons.entity.orders.po.InsOrdersCarUserInfo;
 import com.jzg.commons.entity.quote.vo.AttributionInformationVo;
 import com.jzg.commons.entity.quote.vo.CarInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
@@ -28,10 +32,12 @@ import com.jzg.quotation.hengbang.crawler.properties.HengBangCrawlerProperties;
 import com.jzg.quotation.hengbang.crawler.service.HbCrawlerOrderService;
 import com.jzg.quotation.hengbang.crawler.service.HengBangCrawlerRequest;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpHeaders;
 
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -124,12 +130,46 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
         AttributionInformationVo attributionInformationVo = underwritingVo.getOrder().getAttributionInformationVo();
         HttpHeaders headers = hbCrawlerRequestComponent.getHeaders(attributionInformationVo.getUsername(), attributionInformationVo.getPassword());
         HbCrawlerOrder hbCrawlerOrder = hbCrawlerOrderService.findByOrdersNo(underwritingVo.getOrder().getOrdersNo());
+        String productCode = underwritingVo.getInsOrders().getProductId();
+        List<Map<String, String>> paramList = new ArrayList<>();
+        if(productCode.equals(ProductsType.PT_0330.getCode())){
+            Map<String, String> params = new HashMap<>();
+            params.put("clauseCode","T001_1");
+            params.put("clauseContext","为更好地保障您的权益,请您在发生保险事故后保留出险第一现场,并立即致电24小时服务电话:956079。");
+            params.put("clauseName","第一现场报案");
+            params.put("riskCode","0801");
+            paramList.add(params);
+        } else if(productCode.equals(ProductsType.PT_034001.getCode())){
+            Map<String, String> params = new HashMap<>();
+            params.put("clauseCode","T001_1");
+            params.put("clauseContext","为更好地保障您的权益,请您在发生保险事故后保留出险第一现场,并立即致电24小时服务电话:956079。");
+            params.put("clauseName","第一现场报案");
+            params.put("riskCode","0808");
+            paramList.add(params);
+        } else{
+            Map<String, String> params1 = new HashMap<>();
+            params1.put("clauseCode","T001_1");
+            params1.put("clauseContext","为更好地保障您的权益,请您在发生保险事故后保留出险第一现场,并立即致电24小时服务电话:956079。");
+            params1.put("clauseName","第一现场报案");
+            params1.put("riskCode","0801");
+            paramList.add(params1);
+            Map<String, String> params2 = new HashMap<>();
+            params2.put("clauseCode","T001_1");
+            params2.put("clauseContext","为更好地保障您的权益,请您在发生保险事故后保留出险第一现场,并立即致电24小时服务电话:956079。");
+            params2.put("clauseName","第一现场报案");
+            params2.put("riskCode","0808");
+            paramList.add(params2);
+        }
 
-        HbCrawlerCoreProposalResponse coreProposalResponse = hbCrawlerRequestComponent.coreProposal(hbCrawlerOrder.getPlyappno(), headers);
-        hbCrawlerOrder.setCiProposalNo(coreProposalResponse.getEfcProposalNo());
-        hbCrawlerOrder.setBiProposalNo(coreProposalResponse.getBizProposalNo());
-        hbCrawlerOrderService.update(hbCrawlerOrder);
-        return null;
+        String message = hbCrawlerRequestComponent.coreProposal(hbCrawlerOrder.getPlyappno(), headers,paramList);
+        if("成功".equals(message)){
+            // 获取核保信息
+            HbCrawlerCoreProposalResponse response = hbCrawlerRequestComponent.coreProposalResult(hbCrawlerOrder.getPlyappno(), headers);
+            hbCrawlerOrder.setCiProposalNo(response.getEfcProposalNo());
+            hbCrawlerOrder.setBiProposalNo(response.getBizProposalNo());
+            hbCrawlerOrderService.update(hbCrawlerOrder);
+        }
+        return new UnderwritingResultsVo();
     }
 
     /**
@@ -161,36 +201,98 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
         HttpHeaders headers = hbCrawlerRequestComponent.getHeaders(attributionInformationVo.getUsername(), attributionInformationVo.getPassword());
         HbCrawlerOrder hbCrawlerOrder = hbCrawlerOrderService.findByOrdersNo(insuranceUploadImageVo.getOrder()
                 .getOrdersNo());
+
+        // 获取车主/投保人/被保人信息
+        List<InsOrdersCarUserInfo> userInfos = insuranceUploadImageVo.getInsOrdersCarUserInfoList();
+        InsOrdersCarUserInfo ownerInfo = userInfos.stream()
+                .filter(insOrdersCarUserInfo -> insOrdersCarUserInfo.getPolicyPersonType().equals(1))
+                .findFirst().orElse(null);
+        InsOrdersCarUserInfo policyHolderInfo = userInfos.stream()
+                .filter(insOrdersCarUserInfo -> insOrdersCarUserInfo.getPolicyPersonType().equals(2))
+                .findFirst().orElse(null);
+        InsOrdersCarUserInfo insuredHolder = userInfos.stream()
+                .filter(insOrdersCarUserInfo -> insOrdersCarUserInfo.getPolicyPersonType().equals(3))
+                .findFirst().orElse(null);
+        CarInfoVo carInfo = insuranceUploadImageVo.getCarInfo();
         //暂时将图片默认为01,06,09,投保业务-旧车-其他资料
         Integer fileNum = 0;
-        StringBuilder fileBuff = new StringBuilder();
-        StringBuilder fileType = new StringBuilder();
-        StringBuilder mark3 = new StringBuilder();
-        Integer mark3Num = 100;//恒邦规定从100开始
+        List<String> fileBuff = new ArrayList<>();
+        List<String> fileType = new ArrayList<>();
+        List<String> mark3 = new ArrayList<>();
+        List<HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO> extArrDTOS = new ArrayList<>();
+
+//        Integer mark3Num = 100;//恒邦规定从100开始
         List<InsuranceImageVo> imageVoList = insuranceUploadImageVo.getImageVoList();
-        if (imageVoList != null && !imageVoList.isEmpty()) {
+        if (CollUtil.isNotEmpty(imageVoList)) {
             for (InsuranceImageVo insuranceImageVo : imageVoList) {
                 List<InsuranceImageVo.ImageDTO> imageBase64List = insuranceImageVo.getImageBase64List();
-                if (imageBase64List != null && !imageBase64List.isEmpty()) {
-                    for (InsuranceImageVo.ImageDTO imageBase64 : imageBase64List) {
-                        if (!fileBuff.isEmpty()) {
-                            fileBuff.append("||");
-                        }
-                        fileBuff.append(imageBase64.getImageBase64Str());
-                        if (!fileType.isEmpty()) {
-                            fileType.append("||");
-                        }
-                        fileType.append(RequestConstant.IMAGE_TYPE);
-                        if (!mark3.isEmpty()) {
-                            mark3.append(",");
-                        }
-                        mark3.append(mark3Num++);
-                        fileNum += 1;
+                if(CollUtil.isNotEmpty(imageBase64List)){
+                    fileBuff.add("data:image/jpeg;base64," + imageBase64List.get(0).getImageBase64Str());
+                    if(InsuranceImageEnum.C02.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,03,投保业务-旧车-证件");
+                        mark3.add("6");
+                        HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO extArrDTO = new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO();
+                        extArrDTO.setOcrFlag("1");
+                        extArrDTO.setName(ownerInfo.getName());
+                        extArrDTO.setId_number(ownerInfo.getIdentifyNumber());
+                        extArrDTOS.add(extArrDTO);
+                    } else if(InsuranceImageEnum.C01.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,02,投保业务-旧车-行驶证");
+                        mark3.add("8");
+                        HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO extArrDTO = new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO();
+                        extArrDTO.setOcrFlag("1");
+                        extArrDTO.setPlate_no(carInfo.getLicenseNo());
+                        extArrDTO.setEngine_no(carInfo.getEngineNo());
+                        extArrDTO.setOwner(ownerInfo.getName());
+                        extArrDTO.setVin_code(carInfo.getVinNo());
+                        extArrDTO.setIssue_date(carInfo.getIssueDate());
+                        extArrDTO.setRegister_date(carInfo.getRegisterDate());
+                        extArrDTOS.add(extArrDTO);
+                    } else if(InsuranceImageEnum.D02.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,03,投保业务-旧车-证件");
+                        mark3.add("7");
+                        extArrDTOS.add(new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO());
+                    } else if(InsuranceImageEnum.D01.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,02,投保业务-旧车-行驶证");
+                        mark3.add("9");
+                        extArrDTOS.add(new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO());
+                    } else if(InsuranceImageEnum.C03.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,03,投保业务-旧车-证件");
+                        mark3.add("11");
+                        HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO extArrDTO = new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO();
+                        extArrDTO.setOcrFlag("1");
+                        extArrDTO.setName(policyHolderInfo.getName());
+                        extArrDTO.setId_number(policyHolderInfo.getIdentifyNumber());
+                        extArrDTOS.add(extArrDTO);
+                    } else if(InsuranceImageEnum.D03.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,03,投保业务-旧车-证件");
+                        mark3.add("12");
+                        HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO extArrDTO = new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO();
+                        extArrDTO.setOcrFlag("1");
+                        extArrDTO.setName(policyHolderInfo.getName());
+                        extArrDTO.setId_number(policyHolderInfo.getIdentifyNumber());
+                        extArrDTOS.add(extArrDTO);
+                    } else if(InsuranceImageEnum.C04.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,03,投保业务-旧车-证件");
+                        mark3.add("13");
+                        HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO extArrDTO = new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO();
+                        extArrDTO.setOcrFlag("1");
+                        extArrDTO.setName(insuredHolder.getName());
+                        extArrDTO.setId_number(insuredHolder.getIdentifyNumber());
+                        extArrDTOS.add(extArrDTO);
+                    } else if(InsuranceImageEnum.D04.getCode().equals(insuranceImageVo.getImageCode())){
+                        fileType.add("01,06,03,投保业务-旧车-证件");
+                        mark3.add("14");
+                        HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO extArrDTO = new HbCrawlerFileUploadRequest.ExtJsonDTO.ExtArrDTO();
+                        extArrDTO.setOcrFlag("1");
+                        extArrDTO.setName(insuredHolder.getName());
+                        extArrDTO.setId_number(insuredHolder.getIdentifyNumber());
+                        extArrDTOS.add(extArrDTO);
                     }
                 }
             }
         }
-        HbCrawlerFileUploadRequest fileUploadRequest = new HbCrawlerFileUploadRequest(fileBuff.toString(), fileType.toString(), mark3.toString(), fileNum);
+        HbCrawlerFileUploadRequest fileUploadRequest = new HbCrawlerFileUploadRequest(fileBuff, fileType, mark3, extArrDTOS);
         hbCrawlerRequestComponent.uploadImage(fileUploadRequest, headers, hbCrawlerOrder.getPlyappno());
     }
 

+ 7 - 2
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java

@@ -31,6 +31,7 @@ import com.jzg.commons.constants.quote.enums.base.QuoteRuleCategory;
 import com.jzg.commons.entity.quote.vo.orders.InsOrdersVo;
 import com.jzg.quotation.commons.service.QuotationBaseService;
 import com.jzg.quotation.commons.utils.SnowFlakeUtil;
+import com.jzg.quotation.hengbang.crawler.service.HengBangCrawlerRequest;
 import com.jzg.quotation.summary.aop.QuoteVerification;
 import com.jzg.quotation.summary.aop.OrderOperationLog;
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
@@ -138,9 +139,10 @@ public class UnifyOrderManager {
     private InsOrdersTrackService insOrdersTrackService;
 
     @Autowired
-    private ZhongMeiCrawlerRequest zhongMeiCrawlerRequest;
-
+    private HengBangCrawlerRequest hengBangCrawlerRequest;
 
+    @Autowired
+    private ZhongMeiCrawlerRequest zhongMeiCrawlerRequest;
 
 
     private String getSystemCode() {
@@ -406,6 +408,9 @@ public class UnifyOrderManager {
         if (byCompanyId.getData().isEmpty()) {
             AssertionUtils.isFail(true, "保司未配置协议");
         }
+
+        List<InsOrdersCarUserInfo> insOrdersCarUserInfos = insOrdersCarUserInfoService.getByOrderId(insuranceUploadImageVo.getOrder().getOrdersNo());
+        insuranceUploadImageVo.setInsOrdersCarUserInfoList(insOrdersCarUserInfos);
         insuranceUploadImageVo.getOrder().setAgreementId(byCompanyId.getData().get(0).getId());
         insuranceUploadImageVo.getOrder().setInsuranceCompanyCode(esmInsCompanyHttpResult.getData().getCompanyCode());
         insuranceUploadImageVo.getOrder().setInsuranceCompanyId(esmInsCompanyHttpResult.getData().getId());

+ 182 - 182
tenant/insurance/quotation-summary/src/test/java/com/jzg/quotation/taikang/crawler/service/ChengTaiCrawlerRequestServiceTest.java

@@ -1,182 +1,182 @@
-package com.jzg.quotation.taikang.crawler.service;
-
-import com.jzg.quotation.chengtai.crawler.JsonUtil;
-import com.jzg.quotation.chengtai.crawler.model.entity.ChengTaiBiContract;
-import com.jzg.quotation.chengtai.crawler.model.entity.ChengTaiCiContract;
-import com.jzg.quotation.chengtai.crawler.model.entity.ChengTaiContractMain;
-import com.jzg.quotation.chengtai.crawler.model.param.ChengTaiPremiumcalParam;
-import com.jzg.quotation.chengtai.crawler.model.result.ChengTaiDownloadAddressResult;
-import com.jzg.quotation.chengtai.crawler.model.result.ChengTaiInsureResult;
-import com.jzg.quotation.chengtai.crawler.model.result.ChengTaiSystemResult;
-import com.jzg.quotation.chengtai.crawler.service.ChengTaiAPIService;
-import com.jzg.quotation.chengtai.crawler.service.ChengTaiCrawlerRequestService;
-import com.jzg.quotation.summary.SummaryQuotationApplication;
-import jakarta.annotation.Resource;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.test.context.SpringBootTest;
-
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-@SpringBootTest(classes = {SummaryQuotationApplication.class})
-public class ChengTaiCrawlerRequestServiceTest {
-    private static final Logger logger = LoggerFactory.getLogger(ChengTaiCrawlerRequestServiceTest.class);
-
-    @Resource
-    private ChengTaiCrawlerRequestService chengTaiCrawlerRequestService;
-
-    @Resource
-    public ChengTaiAPIService chengTaiAPIService;
-
-    @BeforeAll
-    public static void befroe() {
-       // ChengTaiAPIHelper.initAPI("https://b2b.champion-ic.com");
-    }
-
-    @Test
-    public void login() {
-        String username = "0105B122";
-        String password = "Tqct@2024.";
-        String captcha = "2QVPHjQEJk/FLGkVXPgNndHmbd/ywg0/iZM+6WkEnTOWSiim4s9Ez9dUyvDBF/1S/dR8n4gabCJJ/iOq8b7HT1K1F0YOuOs/jffMBk/T9Cg=";
-
-        String token = chengTaiCrawlerRequestService.login(username, password, captcha);
-
-        assertNotNull(token);
-    }
-
-    @Test
-    public void system() {
-        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
-
-        ChengTaiSystemResult system = chengTaiAPIService.system(token);
-
-        assertNotNull(system);
-    }
-
-    @Test
-    public void getPolicyModel() {
-        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
-
-        String orderId = "1909779147122143234";
-
-        ChengTaiPremiumcalParam result = chengTaiAPIService.getPolicyModel(token, orderId);
-
-        assertNotNull(result);
-
-        System.out.println("==================================================");
-
-        System.out.println(JsonUtil.toJsonString(result));
-
-        System.out.println();
-        System.out.println();
-        System.out.println();
-
-
-        System.out.println(JsonUtil.toJsonString(result.getUnknownFields()));
-    }
-
-    @Test
-    public void insure() {
-        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
-
-        String uuid = "uXu-BI-WTN6M2kEpoZdaDQ";
-
-        List<ChengTaiInsureResult> result = chengTaiAPIService.insure(token, uuid);
-
-        assertNotNull(result);
-
-        System.out.println("==================================================");
-
-        System.out.println(JsonUtil.toJsonString(result));
-
-        System.out.println();
-        System.out.println();
-        System.out.println();
-
-
-        for (ChengTaiInsureResult  item : result) {
-            System.out.println(JsonUtil.toJsonString(item.getUnknownFields()));
-
-            System.out.println(item.getPayUrl());
-        }
-    }
-
-    @Test
-    public void downloadAddress() {
-        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
-
-        String contractNo = "6050400082120250005927";
-        String policyUuid = "8s3HUoSHRxeLvJcFa40T9g";
-        String expiryDate = "2026-04-10 00:00:00";
-
-        ChengTaiDownloadAddressResult result = chengTaiAPIService.downloadAddress(token, contractNo, policyUuid, expiryDate);
-
-        assertNotNull(result);
-        assertNotNull(result.getQueryResults());
-
-        System.out.println("==================================================");
-
-        System.out.println(JsonUtil.toJsonString(result));
-
-        System.out.println();
-        System.out.println();
-        System.out.println();
-
-        System.out.println(JsonUtil.toJsonString(result.getUnknownFields()));
-
-        List<ChengTaiDownloadAddressResult.QueryResult> queryResults = result.getQueryResults();
-
-        for (ChengTaiDownloadAddressResult.QueryResult item : queryResults) {
-            System.out.println(item.getDownLoadURL());
-        }
-    }
-
-    @Test
-    public void downloadAddress2() {
-        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
-
-        String orderId = "1909864837421408258";
-
-        ChengTaiPremiumcalParam param = chengTaiAPIService.getPolicyModel(token, orderId);
-
-        ChengTaiCiContract ciContract = param.getCiContract();
-        ChengTaiBiContract biContract = param.getBiContract();
-
-        ChengTaiContractMain contractMain = null;
-        if (ciContract != null) {
-            contractMain = ciContract.getContractMain();
-        }
-        if (contractMain == null && biContract != null) {
-            contractMain = biContract.getContractMain();
-        }
-
-        String contractNo = contractMain.getPolicyNo();
-        String policyUuid = contractMain.getPolicyUuid();
-        String expiryDate = contractMain.getValidDate();
-
-        ChengTaiDownloadAddressResult result = chengTaiAPIService.downloadAddress(token, contractNo, policyUuid, expiryDate);
-
-        assertNotNull(result);
-        assertNotNull(result.getQueryResults());
-
-        System.out.println("==================================================");
-
-        System.out.println(JsonUtil.toJsonString(result));
-
-        System.out.println();
-        System.out.println();
-        System.out.println();
-
-        System.out.println(JsonUtil.toJsonString(result.getUnknownFields()));
-
-        List<ChengTaiDownloadAddressResult.QueryResult> queryResults = result.getQueryResults();
-
-        for (ChengTaiDownloadAddressResult.QueryResult item : queryResults) {
-            System.out.println(item.getDownLoadURL());
-        }
-    }
-}
+//package com.jzg.quotation.taikang.crawler.service;
+//
+//import com.jzg.quotation.chengtai.crawler.JsonUtil;
+//import com.jzg.quotation.chengtai.crawler.model.entity.ChengTaiBiContract;
+//import com.jzg.quotation.chengtai.crawler.model.entity.ChengTaiCiContract;
+//import com.jzg.quotation.chengtai.crawler.model.entity.ChengTaiContractMain;
+//import com.jzg.quotation.chengtai.crawler.model.param.ChengTaiPremiumcalParam;
+//import com.jzg.quotation.chengtai.crawler.model.result.ChengTaiDownloadAddressResult;
+//import com.jzg.quotation.chengtai.crawler.model.result.ChengTaiInsureResult;
+//import com.jzg.quotation.chengtai.crawler.model.result.ChengTaiSystemResult;
+//import com.jzg.quotation.chengtai.crawler.service.ChengTaiAPIService;
+//import com.jzg.quotation.chengtai.crawler.service.ChengTaiCrawlerRequestService;
+//import com.jzg.quotation.summary.SummaryQuotationApplication;
+//import jakarta.annotation.Resource;
+//import org.junit.jupiter.api.BeforeAll;
+//import org.junit.jupiter.api.Test;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.boot.test.context.SpringBootTest;
+//
+//import java.util.List;
+//
+//import static org.junit.jupiter.api.Assertions.assertNotNull;
+//
+//@SpringBootTest(classes = {SummaryQuotationApplication.class})
+//public class ChengTaiCrawlerRequestServiceTest {
+//    private static final Logger logger = LoggerFactory.getLogger(ChengTaiCrawlerRequestServiceTest.class);
+//
+//    @Resource
+//    private ChengTaiCrawlerRequestService chengTaiCrawlerRequestService;
+//
+//    @Resource
+//    public ChengTaiAPIService chengTaiAPIService;
+//
+//    @BeforeAll
+//    public static void befroe() {
+//       // ChengTaiAPIHelper.initAPI("https://b2b.champion-ic.com");
+//    }
+//
+//    @Test
+//    public void login() {
+//        String username = "0105B122";
+//        String password = "Tqct@2024.";
+//        String captcha = "2QVPHjQEJk/FLGkVXPgNndHmbd/ywg0/iZM+6WkEnTOWSiim4s9Ez9dUyvDBF/1S/dR8n4gabCJJ/iOq8b7HT1K1F0YOuOs/jffMBk/T9Cg=";
+//
+//        String token = chengTaiCrawlerRequestService.login(username, password, captcha);
+//
+//        assertNotNull(token);
+//    }
+//
+//    @Test
+//    public void system() {
+//        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
+//
+//        ChengTaiSystemResult system = chengTaiAPIService.system(token);
+//
+//        assertNotNull(system);
+//    }
+//
+//    @Test
+//    public void getPolicyModel() {
+//        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
+//
+//        String orderId = "1909779147122143234";
+//
+//        ChengTaiPremiumcalParam result = chengTaiAPIService.getPolicyModel(token, orderId);
+//
+//        assertNotNull(result);
+//
+//        System.out.println("==================================================");
+//
+//        System.out.println(JsonUtil.toJsonString(result));
+//
+//        System.out.println();
+//        System.out.println();
+//        System.out.println();
+//
+//
+//        System.out.println(JsonUtil.toJsonString(result.getUnknownFields()));
+//    }
+//
+//    @Test
+//    public void insure() {
+//        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
+//
+//        String uuid = "uXu-BI-WTN6M2kEpoZdaDQ";
+//
+//        List<ChengTaiInsureResult> result = chengTaiAPIService.insure(token, uuid);
+//
+//        assertNotNull(result);
+//
+//        System.out.println("==================================================");
+//
+//        System.out.println(JsonUtil.toJsonString(result));
+//
+//        System.out.println();
+//        System.out.println();
+//        System.out.println();
+//
+//
+//        for (ChengTaiInsureResult  item : result) {
+//            System.out.println(JsonUtil.toJsonString(item.getUnknownFields()));
+//
+//            System.out.println(item.getPayUrl());
+//        }
+//    }
+//
+//    @Test
+//    public void downloadAddress() {
+//        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
+//
+//        String contractNo = "6050400082120250005927";
+//        String policyUuid = "8s3HUoSHRxeLvJcFa40T9g";
+//        String expiryDate = "2026-04-10 00:00:00";
+//
+//        ChengTaiDownloadAddressResult result = chengTaiAPIService.downloadAddress(token, contractNo, policyUuid, expiryDate);
+//
+//        assertNotNull(result);
+//        assertNotNull(result.getQueryResults());
+//
+//        System.out.println("==================================================");
+//
+//        System.out.println(JsonUtil.toJsonString(result));
+//
+//        System.out.println();
+//        System.out.println();
+//        System.out.println();
+//
+//        System.out.println(JsonUtil.toJsonString(result.getUnknownFields()));
+//
+//        List<ChengTaiDownloadAddressResult.QueryResult> queryResults = result.getQueryResults();
+//
+//        for (ChengTaiDownloadAddressResult.QueryResult item : queryResults) {
+//            System.out.println(item.getDownLoadURL());
+//        }
+//    }
+//
+//    @Test
+//    public void downloadAddress2() {
+//        String token = chengTaiCrawlerRequestService.login("0105B122", null, null);
+//
+//        String orderId = "1909864837421408258";
+//
+//        ChengTaiPremiumcalParam param = chengTaiAPIService.getPolicyModel(token, orderId);
+//
+//        ChengTaiCiContract ciContract = param.getCiContract();
+//        ChengTaiBiContract biContract = param.getBiContract();
+//
+//        ChengTaiContractMain contractMain = null;
+//        if (ciContract != null) {
+//            contractMain = ciContract.getContractMain();
+//        }
+//        if (contractMain == null && biContract != null) {
+//            contractMain = biContract.getContractMain();
+//        }
+//
+//        String contractNo = contractMain.getPolicyNo();
+//        String policyUuid = contractMain.getPolicyUuid();
+//        String expiryDate = contractMain.getValidDate();
+//
+//        ChengTaiDownloadAddressResult result = chengTaiAPIService.downloadAddress(token, contractNo, policyUuid, expiryDate);
+//
+//        assertNotNull(result);
+//        assertNotNull(result.getQueryResults());
+//
+//        System.out.println("==================================================");
+//
+//        System.out.println(JsonUtil.toJsonString(result));
+//
+//        System.out.println();
+//        System.out.println();
+//        System.out.println();
+//
+//        System.out.println(JsonUtil.toJsonString(result.getUnknownFields()));
+//
+//        List<ChengTaiDownloadAddressResult.QueryResult> queryResults = result.getQueryResults();
+//
+//        for (ChengTaiDownloadAddressResult.QueryResult item : queryResults) {
+//            System.out.println(item.getDownLoadURL());
+//        }
+//    }
+//}

File diff suppressed because it is too large
+ 0 - 33
tenant/insurance/quotation-taikang/src/test/java/com/jzg/quotation/taikang/crawler/TaiKangHttpClientTest.java


Some files were not shown because too many files changed in this diff