Qchen 4 месяцев назад
Родитель
Сommit
8fd4eae89b
24 измененных файлов с 1255 добавлено и 200 удалено
  1. 9 6
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java
  2. 34 1
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/build/ZhongAnCrawlerQuoteResultsVoBuild.java
  3. 33 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/client/LoginResult.java
  4. 111 1
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerCacheComponent.java
  5. 74 21
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerRequestComponent.java
  6. 33 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/constant/InsurePlaceCode.java
  7. 7 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/constant/ZhongAnRequestConstant.java
  8. 6 3
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/constant/enums/RequestUrl.java
  9. 1 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/dto/NonAutoInfoDto.java
  10. 22 1
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/po/ZhongAnCrawlerOrder.java
  11. 80 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerApplyAccommodationRequest.java
  12. 34 15
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerCacheCarQueryRequest.java
  13. 2 2
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerPolicyListRequest.java
  14. 44 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerQueryAccommodationRequest.java
  15. 39 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerQueryInitInfoRequest.java
  16. 22 18
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerQuoteRequest.java
  17. 4 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerUploadImageRequest.java
  18. 48 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerApplyAccommodationResponse.java
  19. 4 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerPolicyListResponse.java
  20. 315 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerQueryAccommodationResponse.java
  21. 57 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerQueryInitInfoResponse.java
  22. 14 0
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerQuoteResponse.java
  23. 259 131
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/service/Impl/ZhongAnCrawlerRequestImpl.java
  24. 3 1
      tenant/organization/src/main/resources/mapper/PtlSchemeMapper.xml

+ 9 - 6
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.commons.component;
 
+import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson2.JSON;
 import com.jzg.commons.constants.quote.enums.base.InsuranceEnum;
 import com.jzg.commons.exception.SystemException;
@@ -729,12 +730,12 @@ public class RequestComponent {
                 .block();
     }
 
-    public <Response> ResponseEntity<Response> formDataZhongAn(String url, Object body, Class<Response> responseClass, HttpHeaders headers) {
+    public <Response> ResponseEntity<Response> formDataZhongAn(String url, Object body, Class<Response> responseClass, HttpHeaders headers,String type) {
         MultiValueMap<String, Object> multiValueMap = RequestObjectConversion.convertMultiValueMap(body);
-        return formDatazhongan1(url, multiValueMap, responseClass, headers);
+        return formDatazhongan1(url, multiValueMap, responseClass, headers,type);
     }
 
-    public <Response> ResponseEntity<Response> formDatazhongan1(String url, MultiValueMap<String, Object> parts, Class<Response> responseClass, HttpHeaders headers) {
+    public <Response> ResponseEntity<Response> formDatazhongan1(String url, MultiValueMap<String, Object> parts, Class<Response> responseClass, HttpHeaders headers,String type) {
 
         return webClient.post()
                 .uri(url)
@@ -742,11 +743,12 @@ public class RequestComponent {
                 .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                 .body(BodyInserters.fromMultipartData(parts))
                 .retrieve()
-                .toEntity(responseClass).doOnNext(responseBody -> System.out.println("响应内容: " + responseBody.getBody()))
+                .toEntity(responseClass).doOnNext(responseBody -> InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 响应参数:{}",
+                        "爬虫" + type,url,JSONObject.toJSONString(responseBody)))
                 .block();
     }
 
-    public String formDataString(String url, Object body, HttpHeaders headers) {
+    public String formDataString(String url, Object body, HttpHeaders headers,String type) {
         MultiValueMap<String, Object> multiValueMap = RequestObjectConversion.convertMultiValueMap(body);
         BodyInserters.MultipartInserter multipartInserter = BodyInserters.fromMultipartData(multiValueMap);
         String block = webClient.post()
@@ -754,7 +756,8 @@ public class RequestComponent {
                 .headers(RequestComponent.setHeaders(headers))
                 .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                 .body(BodyInserters.fromMultipartData(multiValueMap))
-                .retrieve().bodyToMono(String.class).doOnNext(responseBody -> System.out.println("响应内容: " + responseBody)) // 打印响应
+                .retrieve().bodyToMono(String.class).doOnNext(responseBody -> InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 响应参数:{}",
+                        "爬虫" + type,url, JSONObject.parseObject(responseBody)))
                 .block();
 
 

+ 34 - 1
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/build/ZhongAnCrawlerQuoteResultsVoBuild.java

@@ -1,6 +1,8 @@
 package com.jzg.quotation.zhongan.crawler.build;
 
 import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.entity.quote.vo.KindInfoVo;
 import com.jzg.commons.entity.quote.vo.RiskInfoVo;
@@ -8,6 +10,7 @@ import com.jzg.commons.entity.quote.vo.aggregated.QuoteResultsVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.base.OrderBase;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerQuoteResponse;
+import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerUploadInitDateResponse;
 
 import java.util.List;
 import java.util.Map;
@@ -19,7 +22,7 @@ import java.util.stream.Collectors;
  * @date: 2025/5/12 17:19
  **/
 public class ZhongAnCrawlerQuoteResultsVoBuild {
-    public static QuoteResultsVo buildQuoteResultsVo(QuoteVo quoteVo, ZhongAnCrawlerQuoteResponse.ValueDTO.DataDTO dataDTO) {
+    public static QuoteResultsVo buildQuoteResultsVo(QuoteVo quoteVo, ZhongAnCrawlerQuoteResponse.ValueDTO.DataDTO dataDTO, ZhongAnCrawlerUploadInitDateResponse uploadInitDateResponse) {
         OrderBase orderBase = quoteVo.getOrder();
         QuoteResultsVo quoteResultsVo = new QuoteResultsVo();
         quoteResultsVo.setOrdersNo(orderBase.getOrdersNo());
@@ -31,6 +34,8 @@ public class ZhongAnCrawlerQuoteResultsVoBuild {
         List<ZhongAnCrawlerQuoteResponse.ValueDTO.DataDTO.VehiclePremiumDTO.VehicleCoverageListDTO> coverageDTOList = dataDTO.getVehiclePremium().getVehicleCoverageList();
         List<KindInfoVo> kindInfoVo = buildKindInfoVo(quoteVo.getKindInfoVo(), coverageDTOList);
         quoteResultsVo.setKindInfoVo(kindInfoVo);
+        // 评分
+        quoteResultsVo.setScoreVo(buildScoreVo(dataDTO));
 
         // 交强保费 车船税 商业保费
         buildPremium(quoteResultsVo, dataDTO);
@@ -64,6 +69,11 @@ public class ZhongAnCrawlerQuoteResultsVoBuild {
             if (coverageDTO.getProductId().equals(kind.getKindCode())) {
                 kind.setAmount(coverageDTO.getAmount());//设置保额
                 kind.setPremium(String.valueOf(coverageDTO.getTotalCoveragePremium()));//设置保费
+                // 服务次数
+                if (coverageDTO.getDutyAttributeValue() != null) {
+                    kind.setServiceTimes(coverageDTO.getDutyAttributeValue());
+                    kind.setDeductibleRate(coverageDTO.getDutyAttributeValue());
+                }
 //                kind.setUnitAmount(String.valueOf(coverageDTO.getUnitAmount()));//设置每座保额
 //                kind.setQuantity(String.valueOf(coverageDTO.ge()));//设置份数
             }
@@ -83,4 +93,27 @@ public class ZhongAnCrawlerQuoteResultsVoBuild {
         // 设置非车险(驾意险)保费,报价返回数据中不存在
         quoteResultsVo.getCosts().setNiPremium(String.valueOf(vehiclePremium.getNonTotalPremium()));
     }
+
+    public static QuoteResultsVo.ScoreVo buildScoreVo(ZhongAnCrawlerQuoteResponse.ValueDTO.DataDTO dataDTO) {
+        QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
+        scoreVo.setJqAdjustRate(dataDTO.getCompelDiscount());
+        scoreVo.setSyAdjustRate(dataDTO.getBusinessDiscount());
+        scoreVo.setJqRenewal("ZA".equals(dataDTO.getForceRenewalFlag()) ? "1" : "0");
+        scoreVo.setSyRenewal("ZA".equals(dataDTO.getBizRenewalFlag()) ? "1" : "0");
+        JSONArray scoreJson = new JSONArray();
+        scoreJson.add(new JSONObject()
+                .fluentPut("scoreName", "评分")
+                .fluentPut("scoreKey","policyGradePa")
+                .fluentPut("score", dataDTO.getPolicyGradePa()));
+        scoreJson.add(new JSONObject()
+                .fluentPut("scoreName", "鼎然分")
+                .fluentPut("scoreKey","dingRanScore")
+                .fluentPut("score", dataDTO.getDingRanScore()));
+        scoreJson.add(new JSONObject()
+                .fluentPut("scoreName", "自主定价率")
+                .fluentPut("scoreKey","selfPriceRatio")
+                .fluentPut("score", dataDTO.getSelfPriceRatio()));
+        scoreVo.setScoreJson(scoreJson);
+        return scoreVo;
+    }
 }

+ 33 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/client/LoginResult.java

@@ -0,0 +1,33 @@
+package com.jzg.quotation.zhongan.crawler.client;
+
+import lombok.Data;
+
+/**
+ * @author quchen
+ * @date 2026/5/6 15:03
+ */
+
+@Data
+public class LoginResult {
+    private int code;
+    private String message;
+    private String zaLoginCookieKey;
+    private String flowId;
+
+    public LoginResult(int code, String message, String zaLoginCookieKey, String flowId) {
+        this.code = code;
+        this.message = message;
+        this.zaLoginCookieKey = zaLoginCookieKey;
+        this.flowId = flowId;
+    }
+
+    public int getCode() {
+        return code;
+    }
+    public String getZaLoginCookieKey() {
+        return zaLoginCookieKey;
+    }
+    public String getFlowId() {
+        return flowId;
+    }
+}

+ 111 - 1
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerCacheComponent.java

@@ -2,19 +2,32 @@ package com.jzg.quotation.zhongan.crawler.component;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.jzg.quotation.zhongan.crawler.client.LoginResult;
+import com.jzg.quotation.zhongan.crawler.entity.request.ZhongAnCrawlerQueryInitInfoRequest;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerPaymentResponse;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerUploadInitDateResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.hc.core5.net.URIBuilder;
+import org.apache.http.Header;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import org.apache.poi.ss.formula.functions.T;
 import org.redisson.api.RBucket;
 import org.redisson.api.RMap;
 import org.redisson.api.RedissonClient;
+import org.springframework.http.HttpHeaders;
 import org.springframework.stereotype.Component;
 
+import java.net.URI;
 import java.time.Duration;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @Slf4j
 @Component
@@ -27,7 +40,7 @@ public class ZhongAnCrawlerCacheComponent {
      * 众安财险授权cookie
      */
     public static final String COOKIE = "cookie:";
-    public static final String ZHONGAN_COOKIE = "zhoangan:cookie:";
+    public static final String ZHONGAN_COOKIE = "zhongan:cookie:";
     /**
      * 众安财险登录后Id
      */
@@ -97,5 +110,102 @@ public class ZhongAnCrawlerCacheComponent {
         return JSON.parseObject(bucket1.get(), ZhongAnCrawlerPaymentResponse.ValueDTO.DatasDTO.InitInfoDTO.class);
     }
 
+    //登录
+    private static final CloseableHttpClient HTTP_CLIENT =HttpClients.custom().disableRedirectHandling().build(); // 关闭自动重定向
+
+    // 正则表达式 获取cookie、flowId
+    private static final Pattern ZA_COOKIE_PATTERN = Pattern.compile("zaLoginCookieKey=(.*?);");
+    private static final Pattern FLOW_ID_PATTERN = Pattern.compile("flowId=(.*?)&");
+
+    // 构造 GET 请求
+    private HttpGet buildGet(URI uri) {
+        HttpGet get = new HttpGet(uri);
+        get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36");
+        get.setHeader("Accept", "application/json, text/plain, */*");
+        return get;
+    }
+
+    // 获取重定向 Location
+    private String getLocationHeader(CloseableHttpResponse response) {
+        Header header = response.getLastHeader("Location");
+        return header != null ? header.getValue() : "";
+    }
+    public LoginResult loginCookieCache(String zhongAnId,String productId) {
+        HttpClientContext context = HttpClientContext.create();
+        try {
+            String firstUrl = "http://zhongan.bjhfbx.cn/subao-proxy-customer/api/redirectToCoopUserProductExclusivePage";
+            URI uri1 = new URIBuilder(firstUrl)
+                    .addParameter("coopUserId", zhongAnId)
+                    .addParameter("productId", "10805")
+                    .addParameter("isOpenByPC", "N")
+                    .addParameter("promotionScene", "16")
+                    .addParameter("bizContent", "")
+                    .addParameter("insurePlaceCode", "140100")
+                    .build();
+            // 发送第一个请求,不跟随重定向
+            HttpGet get1 = buildGet(uri1);
+            CloseableHttpResponse resp1 = HTTP_CLIENT.execute(get1, context);
+            String location1 = resp1.getFirstHeader("Location").getValue();
+            resp1.close();
+            // 发送第二个请求
+            HttpGet get2 = buildGet(new URI(location1));
+            CloseableHttpResponse resp2 = HTTP_CLIENT.execute(get2, context);
+            String location2 = getLocationHeader(resp2);
+            resp2.close();
+            // 发送第三个请求
+            HttpGet get3 = buildGet(new URI(location2));
+            CloseableHttpResponse resp3 = HTTP_CLIENT.execute(get3, context);
+            String location3 = resp3.getFirstHeader("Location").getValue();
+            resp3.close();
+            // 发送第四个请求
+            HttpGet get4 = buildGet(new URI(location3));
+            CloseableHttpResponse resp4 = HTTP_CLIENT.execute(get4, context);
+            String location4 = resp4.getFirstHeader("Location").getValue();
+            resp4.close();
+            // 第五次请求,拿cookie
+            HttpGet get5 = buildGet(new URI(location4));
+            CloseableHttpResponse resp5 = HTTP_CLIENT.execute(get5, context);
+            String location5 = resp5.getFirstHeader("Location").getValue();
+            // 提取 zaLoginCookieKey
+            String cookieKey = null;
+            if (resp5.getHeaders("Set-Cookie") != null) {
+                for (org.apache.http.Header h : resp5.getHeaders("Set-Cookie")) {
+                    Matcher m = ZA_COOKIE_PATTERN.matcher(h.getValue());
+                    if (m.find()) {
+                        cookieKey = m.group(1).trim();
+                        break;
+                    }
+                }
+            }
+            resp5.close();
+
+            if (cookieKey == null || cookieKey.isEmpty()) {
+                return new LoginResult(400, "账号错误", null, null);
+            }
+
+            // 提取 flowId
+            Matcher flowMatcher = FLOW_ID_PATTERN.matcher(location5);
+            String flowId = flowMatcher.find() ? flowMatcher.group(1).trim() : "";
+
+            String finalUrl = "https://c.zhongan.com/insure/index.html";
+            URI finalUri = new URIBuilder(finalUrl)
+                    .addParameter("flowId", flowId)
+                    .addParameter("i", "e")
+                    .addParameter("insurePlaceCode", "140100")
+                    .addParameter("newPage", "1")
+                    .build();
+
+            HttpGet finalGet = buildGet(finalUri);
+            finalGet.setHeader("Cookie", "zaLoginCookieKey=" + cookieKey);
+            CloseableHttpResponse finalResp = HTTP_CLIENT.execute(finalGet, context);
+            finalResp.close();
+            cacheCookie(cookieKey, flowId, zhongAnId);
+            return new LoginResult(200, "登录成功", cookieKey, flowId);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new LoginResult(400, "登录异常:" + e.getMessage(), null, null);
+        }
+    }
+
 
 }

+ 74 - 21
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerRequestComponent.java

@@ -1,9 +1,12 @@
 package com.jzg.quotation.zhongan.crawler.component;
 
+import com.alibaba.fastjson.JSON;
+import com.jzg.commons.constants.quote.enums.base.InsuranceEnum;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.commons.component.RequestComponent;
 import com.jzg.quotation.commons.constant.CacheConstant;
+import com.jzg.quotation.commons.utils.InsuranceLog;
 import com.jzg.quotation.commons.utils.RequestObjectConversion;
 import com.jzg.quotation.zhongan.crawler.constant.ZhongAnRequestConstant;
 import com.jzg.quotation.zhongan.crawler.constant.enums.RequestUrl;
@@ -93,8 +96,9 @@ public class ZhongAnCrawlerRequestComponent {
     public List<ZhongAnCrawlerCarQueryResponse.ValueDTO.DataDTO.ResultDTO.VehicleDTO> carQuery(ZhongAnCrawlerCarQueryRequest carQueryRequest, HttpHeaders headers) {
 
         List<ZhongAnCrawlerCarQueryResponse.ValueDTO.DataDTO.ResultDTO.VehicleDTO> vehicleDTOList = new ArrayList<>();
-
-        ZhongAnCrawlerCarQueryResponse carQueryResponse = requestComponent.formDataZhongAn(RequestUrl.CAR_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), carQueryRequest, ZhongAnCrawlerCarQueryResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫车辆查询接口",RequestUrl.CAR_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(carQueryRequest));
+        ZhongAnCrawlerCarQueryResponse carQueryResponse = requestComponent.formDataZhongAn(RequestUrl.CAR_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), carQueryRequest, ZhongAnCrawlerCarQueryResponse.class, headers,"车辆查询").getBody();
         List<ZhongAnCrawlerCarQueryResponse.ValueDTO.DataDTO.ResultDTO.VehicleDTO> vehicleList = carQueryResponse.getValue().getDatas().getResult().getVehicleList();
         vehicleDTOList.addAll(vehicleList);
 
@@ -109,7 +113,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerQuoteResponse quote(ZhongAnCrawlerQuoteRequest quoteRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.QUOTE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), quoteRequest, ZhongAnCrawlerQuoteResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫报价接口",RequestUrl.QUOTE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(quoteRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.QUOTE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), quoteRequest, ZhongAnCrawlerQuoteResponse.class, headers,"报价").getBody();
     }
 
     /**
@@ -119,7 +125,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @param headers
      */
     public String confirmQuote(ZhongAnCrawlerConfirmQuoteRequest confirmQuoteRequest, HttpHeaders headers) {
-       return requestComponent.formDataString(RequestUrl.CONFIRM_QUOTE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), confirmQuoteRequest, headers);
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫确认报价接口",RequestUrl.CONFIRM_QUOTE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(confirmQuoteRequest));
+       return requestComponent.formDataString(RequestUrl.CONFIRM_QUOTE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), confirmQuoteRequest, headers,"确认报价");
     }
 
     /**
@@ -130,7 +138,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerGetOrderResponse getOrder(ZhongAnCrawlerGetOrderRequest getOrderRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.GET_ORDER.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), getOrderRequest, ZhongAnCrawlerGetOrderResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫获取订单接口",RequestUrl.GET_ORDER.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(getOrderRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.GET_ORDER.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), getOrderRequest, ZhongAnCrawlerGetOrderResponse.class, headers,"获取订单信息").getBody();
     }
 
     /**
@@ -141,7 +151,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerConfirmOrderResponse confirmOrder(ZhongAnCrawlerConfirmOrderRequest confirmOrderRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.CONFIRM_ORDER.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), confirmOrderRequest, ZhongAnCrawlerConfirmOrderResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫确认订单接口",RequestUrl.CONFIRM_ORDER.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(confirmOrderRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.CONFIRM_ORDER.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), confirmOrderRequest, ZhongAnCrawlerConfirmOrderResponse.class, headers,"确认订单").getBody();
     }
 
     /**
@@ -152,7 +164,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerJyxUnderwritingResponse jyxUnderwriting(ZhongAnCrawlerJyxUnderwritingRequest jyxUnderwritingRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.JYX_UNDERWRITING.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), jyxUnderwritingRequest, ZhongAnCrawlerJyxUnderwritingResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫非车险提交核保接口",RequestUrl.JYX_UNDERWRITING.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(jyxUnderwritingRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.JYX_UNDERWRITING.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), jyxUnderwritingRequest, ZhongAnCrawlerJyxUnderwritingResponse.class, headers,"非车险提交核保").getBody();
     }
 
     /**
@@ -163,7 +177,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerUploadImageResponse uploadImage(ZhongAnCrawlerUploadImageRequest imageRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.UPLOAD_IMAGE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), imageRequest, ZhongAnCrawlerUploadImageResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫上传影像接口",RequestUrl.UPLOAD_IMAGE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(imageRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.UPLOAD_IMAGE.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), imageRequest, ZhongAnCrawlerUploadImageResponse.class, headers,"上传影像").getBody();
     }
 
     /**
@@ -174,7 +190,9 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerPaymentResponse payment(ZhongAnCrawlerPaymentRequest paymentRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.PAYMENT_LINK.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), paymentRequest, ZhongAnCrawlerPaymentResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫获取支付链接接口",RequestUrl.PAYMENT_LINK.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(paymentRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.PAYMENT_LINK.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), paymentRequest, ZhongAnCrawlerPaymentResponse.class, headers,"获取支付链接").getBody();
     }
 
     /**
@@ -185,35 +203,53 @@ public class ZhongAnCrawlerRequestComponent {
      * @return
      */
     public ZhongAnCrawlerDownloadPolicyResponse downloadPolicy(ZhongAnCrawlerDownloadPolicyRequest downloadPolicyRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫获取保单下载参数接口",RequestUrl.DOWNLOAD_POLICY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(downloadPolicyRequest));
         return requestComponent.objectPost(RequestUrl.DOWNLOAD_POLICY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), downloadPolicyRequest, ZhongAnCrawlerDownloadPolicyResponse.class, headers).getBody();
     }
 
     public ZhongAnCrawlerCacheCarQueryResponse cacheCarInfo(ZhongAnCrawlerCacheCarQueryRequest cacheCarQueryRequest, HttpHeaders headers) {
-       return requestComponent.formDataZhongAn(RequestUrl.CACHE_CAR_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), cacheCarQueryRequest,ZhongAnCrawlerCacheCarQueryResponse.class, headers).getBody();
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫缓存车辆查询接口",RequestUrl.CACHE_CAR_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(cacheCarQueryRequest));
+       return requestComponent.formDataZhongAn(RequestUrl.CACHE_CAR_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), cacheCarQueryRequest,ZhongAnCrawlerCacheCarQueryResponse.class, headers,"缓存车辆查询").getBody();
 
     }
 
-    public ZhongAnCrawlerQuoteBaseResponse quoteBaseInfo(ZhongAnCrawlerQuoteBaseRequest parameters, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.QUOTE_BASE_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), parameters,ZhongAnCrawlerQuoteBaseResponse.class, headers).getBody();
+    public ZhongAnCrawlerQuoteBaseResponse quoteBaseInfo(ZhongAnCrawlerQuoteBaseRequest zhongAnCrawlerQuoteBaseRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫报价前准备接口",RequestUrl.QUOTE_BASE_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(zhongAnCrawlerQuoteBaseRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.QUOTE_BASE_QUERY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), zhongAnCrawlerQuoteBaseRequest,ZhongAnCrawlerQuoteBaseResponse.class, headers,"报价前准备").getBody();
 
     }
 
     public String CacheInput(ZhongAnCrawlerCacheInputRequest cacheInputRequest, HttpHeaders headers) {
-        return requestComponent.formDataString(RequestUrl.CACHE_INPUT_KEY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), cacheInputRequest, headers);
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫校验key缓存",RequestUrl.CACHE_INPUT_KEY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(cacheInputRequest));
+        return requestComponent.formDataString(RequestUrl.CACHE_INPUT_KEY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), cacheInputRequest, headers, "校验key缓存");
+    }
+
+    public String initInfo(ZhongAnCrawlerQueryInitInfoRequest queryInitInfoRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫查询归属信息接口",RequestUrl.QUERY_INIT_INFO.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(queryInitInfoRequest));
+        return requestComponent.formDataString(RequestUrl.QUERY_INIT_INFO.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), queryInitInfoRequest, headers, "查询归属信息");
     }
 
     public String carVinQuery(ZhongAnCrawlerCarVinRequest carVinRequest, HttpHeaders headers) {
-        return requestComponent.formDataString(RequestUrl.CAR_VIN_KEY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), carVinRequest, headers);
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫车架查询接口",RequestUrl.CAR_VIN_KEY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(carVinRequest));
+        return requestComponent.formDataString(RequestUrl.CAR_VIN_KEY.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), carVinRequest, headers, "车架查询");
 
     }
 
     public String querySpecial(ZhongAnCrawlerQuerySpecialRequest querySpecialRequest, HttpHeaders headers) {
-        return requestComponent.formDataString(RequestUrl.QUERY_SPECIAL.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), querySpecialRequest, headers);
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫特约查询接口",RequestUrl.QUERY_SPECIAL.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(querySpecialRequest));
+        return requestComponent.formDataString(RequestUrl.QUERY_SPECIAL.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), querySpecialRequest, headers, "特约查询");
 
     }
 
     public String licenseSwitch(ZhongAnCrawlerLicenseSwitchRequest licenseSwitchRequest, HttpHeaders headers) {
-        return requestComponent.formDataString(RequestUrl.LICENCE_SEITCH.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), licenseSwitchRequest, headers);
+        return requestComponent.formDataString(RequestUrl.LICENCE_SEITCH.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), licenseSwitchRequest, headers, "车牌切换");
 
     }
 
@@ -222,19 +258,36 @@ public class ZhongAnCrawlerRequestComponent {
     }
 
     public ZhongAnCrawlerQueryDetailQueryResponse detailQuery(ZhongAnCrawlerQueryDetailQueryRequest detailQueryRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.QUERY_DETAIL.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), detailQueryRequest,ZhongAnCrawlerQueryDetailQueryResponse.class, headers).getBody();
+        return requestComponent.formDataZhongAn(RequestUrl.QUERY_DETAIL.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), detailQueryRequest,ZhongAnCrawlerQueryDetailQueryResponse.class, headers, "查询车辆型号详情").getBody();
     }
 
-    public ZhongAnCrawlerUploadInitDateResponse uploadInitDate(ZhongAnCrawlerUploadInitDateRequest uploadInitDateRequest, HttpHeaders headers) {
-        return requestComponent.formDataZhongAn(RequestUrl.UPLOAD_INIT_DATA.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), uploadInitDateRequest,ZhongAnCrawlerUploadInitDateResponse.class, headers).getBody();
+    public ZhongAnCrawlerUploadInitDateResponse uploadInitData(ZhongAnCrawlerUploadInitDateRequest uploadInitDateRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫上传初始化数据接口",RequestUrl.UPLOAD_INIT_DATA.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(uploadInitDateRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.UPLOAD_INIT_DATA.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), uploadInitDateRequest,ZhongAnCrawlerUploadInitDateResponse.class, headers, "上传初始数据").getBody();
     }
 
     public String markCompleted(ZhongAnCrawlerMarkRequest markRequest, HttpHeaders headers) {
-        return requestComponent.formDataString(RequestUrl.LICENCE_SEITCH.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), markRequest, headers);
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫影像提交接口",RequestUrl.MARK_COMPLETED.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(markRequest));
+        return requestComponent.formDataString(RequestUrl.MARK_COMPLETED.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), markRequest, headers,"影像提交");
     }
 
     public ZhongAnCrawlerPolicyListResponse policyList(ZhongAnCrawlerPolicyListRequest policyListRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫订单状态查询接口",RequestUrl.ORDER_LIST.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(policyListRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.ORDER_LIST.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), policyListRequest,ZhongAnCrawlerPolicyListResponse.class, headers, "查询订单列表").getBody();
+    }
+
+    public ZhongAnCrawlerApplyAccommodationResponse applyAccommodation(ZhongAnCrawlerApplyAccommodationRequest applyAccommodationRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫订单提交通融接口",RequestUrl.APPLY_ACCOMMODATION.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(applyAccommodationRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.APPLY_ACCOMMODATION.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), applyAccommodationRequest,ZhongAnCrawlerApplyAccommodationResponse.class, headers, "订单提交通融").getBody();
+    }
 
-        return requestComponent.formDataZhongAn(RequestUrl.ORDER_LIST.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), policyListRequest,ZhongAnCrawlerPolicyListResponse.class, headers).getBody();
+    public ZhongAnCrawlerQueryAccommodationResponse queryAccommodation(ZhongAnCrawlerQueryAccommodationRequest queryAccommodationRequest, HttpHeaders headers) {
+        InsuranceLog.infoLog(InsuranceEnum.ZAPA.getPinyin(), "\n\t---------> {} \n\t---------> URl: {} \n\t---------> 请求参数:{}",
+                "众安爬虫订单提交通融接口",RequestUrl.QUERY_ACCOMMODATION.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), JSON.toJSONString(queryAccommodationRequest));
+        return requestComponent.formDataZhongAn(RequestUrl.QUERY_ACCOMMODATION.getRequestUrl(zhongAnCrawlerProperties.getBaseUrl()), queryAccommodationRequest,ZhongAnCrawlerQueryAccommodationResponse.class, headers, "订单查询通融原因").getBody();
     }
 }

+ 33 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/constant/InsurePlaceCode.java

@@ -0,0 +1,33 @@
+package com.jzg.quotation.zhongan.crawler.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum InsurePlaceCode {
+    D("140400", "长治市",  "晋D"),
+    M("140800", "运城市",  "晋M"),
+    J("141100", "吕梁市",  "晋J"),
+    C("140300", "阳泉市", "晋C"),
+    K("140700", "晋中市", "晋K"),
+    L("141000", "临汾市",  "晋L"),
+    B("140200", "大同市",  "晋B"),
+    F("140600", "朔州市", "晋F"),
+    A("140100", "太原市", "晋A"),
+    E("140500", "晋城市", "晋E"),
+    H("140900", "忻州市", "晋H");
+    /**
+     * 城市编码
+     */
+    private final String code;
+
+    /**
+     * 城市全称
+     */
+    private final String name;
+    /**
+     * 车牌前缀
+     */
+    private final String extra;
+}

+ 7 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/constant/ZhongAnRequestConstant.java

@@ -10,6 +10,11 @@ public class ZhongAnRequestConstant {
 
     public static final String I_PARAM = "e";
 
+    /**
+     * 归属查询page参数
+     */
+    public static final String INIT_QUERY_PAGE = "/insureEntry";
+
     /**
      * 车型查询page参数
      */
@@ -39,6 +44,8 @@ public class ZhongAnRequestConstant {
 
     public static final String POLICY_LIST = "%2Forder%2FmyOrders";
 
+    public static final String TONG_RONG_QUERY_PAGE = "%2Ftongrong%2Fapply";
+
     /**
      * 保单下载地址
      */

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

@@ -15,12 +15,14 @@ public enum RequestUrl implements CrawlerRequestUrlStandard {
 
     CACHE_INPUT_KEY("/open/bmw/index_controller/cache_input_query.json","校验key缓存"),
 
+    QUERY_INIT_INFO("/open/bmw/query_controller/query_init_info.json","归属信息查询"),
+
     INIT_DATA_KEY("/open/common/init_data_controller/init_data.json","初始化"),
 
     CAR_VIN_KEY("/open/bmw/car_controller/query_car_info.json","车架查询"),
 
     CAR_QUERY("/open/bmw/car_controller/query_vehicle_model.json", "车型查询"),
-    QUERY_SPECIAL("/open/common/special_flag_controller/query_special_flag.json", "query_special_flag"),
+    QUERY_SPECIAL("/open/common/special_flag_controller/query_special_flag.json", "特约查询"),
 
     LICENCE_SEITCH("/open/bmw/index_controller/get_license_switch.json", "get_license_switch"),
 
@@ -28,8 +30,6 @@ public enum RequestUrl implements CrawlerRequestUrlStandard {
 
     QUERY_DETAIL("/open/bmw/car_controller/query_detail_vehicle_model.json", "缓存车辆信息不正确时,调用"),
 
-
-
     QUOTE_BASE_QUERY("/open/bmw/n/quote_controller/query_quote_base_info.json", "报价前准备接口"),
 
     QUOTE("/open/bmw/n/quote_controller/premium_trial.json", "报价"),
@@ -46,6 +46,9 @@ public enum RequestUrl implements CrawlerRequestUrlStandard {
     /**
      * 通融申请的影像上传还需补充
      */
+    QUERY_ACCOMMODATION("/open/bmw/n/accommodation_controller/query_accommodation.json","查询通融原因"),
+
+    APPLY_ACCOMMODATION("/open/bmw/n/accommodation_controller/apply_accommodation.json","申请通融"),
 
     PAYMENT_LINK("/open/newProcess/new_process_controller/qr_page_init_info.json", "获取支付链接"),
 

+ 1 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/dto/NonAutoInfoDto.java

@@ -21,6 +21,7 @@ public class NonAutoInfoDto {
     private String insuredFlag;
 
     @JsonProperty("combination")
+    // 0-快速 2-旗舰 3-尊享 4-豪华 5-至尊 6-标准
     private String combination;
 
 }

+ 22 - 1
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/po/ZhongAnCrawlerOrder.java

@@ -10,7 +10,7 @@ import org.springframework.data.mongodb.core.mapping.Document;
  * @date: 2025/5/14 10:32
  **/
 @Data
-@Document("huatai.crawler.order")
+@Document("zhongan.crawler.order")
 public class ZhongAnCrawlerOrder {
     @Id
     private String id;
@@ -29,4 +29,25 @@ public class ZhongAnCrawlerOrder {
      */
     private String policyId;
 
+    /**
+     * 校验code
+     */
+    private String checkCode;
+
+    /**
+     * 交强投保单号
+     */
+    private String jqApplyNo;
+
+    /**
+     * 商业投保单号
+     */
+    private String syApplyNo;
+
+    /**
+     * 报价Id
+     */
+    private String quoteId;
+
+
 }

+ 80 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerApplyAccommodationRequest.java

@@ -0,0 +1,80 @@
+package com.jzg.quotation.zhongan.crawler.entity.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.quotation.zhongan.crawler.entity.ZhongAnCrawlerConfigureParameters;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author quchen
+ * @date 2026/5/13 11:30
+ */
+
+@Data
+@NoArgsConstructor
+public class ZhongAnCrawlerApplyAccommodationRequest {
+    @JsonProperty("id")
+    private Long id;
+
+    @JsonProperty("quoteId")
+    private String quoteId;
+
+    @JsonProperty("phoneNo")
+    private String phoneNo;
+
+    @JsonProperty("applicationReasons")
+    private String applicationReasons;
+
+    @JsonProperty("auditStatus")
+    private String auditStatus;
+
+    /**
+     * 投保人身份证号码
+     */
+    @JsonProperty("identityNo")
+    private String identityNo;
+
+    @JsonProperty("fileMap")
+    private Map<String, String> fileMap;
+
+    @JsonProperty("orderNo")
+    private String orderNo;
+
+    @JsonProperty("location")
+    private String location;
+
+    @JsonProperty("flowId")
+    private String flowId;
+
+    @JsonProperty("page")
+    private String page;
+
+    @JsonProperty("i")
+    private String i;
+
+    @JsonProperty("flag")
+    private String flag;
+
+    public ZhongAnCrawlerApplyAccommodationRequest(Long id, String quoteId, String identityNo, String orderNo, ZhongAnCrawlerConfigureParameters parameters) {
+        this.id = id;
+        this.quoteId = quoteId;
+        this.phoneNo = "";
+        this.applicationReasons = "";
+        this.auditStatus = "1";
+        this.identityNo = identityNo;
+        this.orderNo = orderNo;
+        Map<String, String> fileMap = new HashMap<>();
+        fileMap.put("version","2");
+        this.fileMap = fileMap;
+        this.location = "";
+        this.flowId = parameters.getFlowId();
+        this.page = "%2Ftongrong%2Fapply";
+        this.flag = parameters.getFlag();
+        this.i = "e";
+    }
+
+}
+

+ 34 - 15
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerCacheCarQueryRequest.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.quotation.zhongan.crawler.constant.InsurePlaceCode;
 import com.jzg.quotation.zhongan.crawler.constant.ZhongAnRequestConstant;
 import com.jzg.quotation.zhongan.crawler.entity.ZhongAnCrawlerConfigureParameters;
 import com.jzg.quotation.zhongan.crawler.entity.response.ZhongAnCrawlerCarQueryResponse;
@@ -41,15 +42,17 @@ public class ZhongAnCrawlerCacheCarQueryRequest {
         CustomerInfoVo ownersInfo = quoteVo.getOwnersInfo();
         CarInfoVo carInfoVo = quoteVo.getCarInfoVo();
         //组装缓存车辆信息
-        this.insurePlaceCode = ownersInfo.getCityCode();
-        this.insurePlace = ownersInfo.getCity();
-        this.thirdOrgCode = "";
         this.vehicleLicencePlateNo = carInfoVo.getLicenseNo();
+        String cityCode = carInfoVo.getLicenseNo().substring(1, 2);
+        InsurePlaceCode insurePlaceCode = InsurePlaceCode.valueOf(cityCode);
+        this.insurePlaceCode = insurePlaceCode.getCode();
+        this.insurePlace = insurePlaceCode.getName();
+        this.thirdOrgCode = "";
         this.vehicleFrameNo = carInfoVo.getVinNo();
         this.vehicleEngineNo = carInfoVo.getEngineNo();
         this.vehicleRegisterDate = carInfoVo.getRegisterDate();
         this.vehicleClass = "carSwitch";
-        this.vehicleTypeSubclass = " ";
+        this.vehicleTypeSubclass = "";
         this.vehicleOwnerName = ownersInfo.getName();
         this.identifyType = "I";
         this.identifyNo = ownersInfo.getIdentifyNumber();
@@ -64,13 +67,13 @@ public class ZhongAnCrawlerCacheCarQueryRequest {
         this.brandCode = vehicleDTO.getBrandCode();
         this.vehicleName = vehicleDTO.getVehicleName();
         this.vehicleBrand = vehicleDTO.getBrandName();
-
-        this.vehicleModelName = vehicleDTO.getBrandName();
+        this.paVehicleType = "";
+        this.vehicleModelName = vehicleDTO.getVehicleName();
         this.vehicleModelCode = vehicleDTO.getVehicleCode();
         this.modelsJy = vehicleDTO.getVehicleCode();
-        this.vehicleCap = carInfoVo.getLimitLoad();
+        this.vehicleCap =carInfoVo.getLimitLoad();
         this.curbWeight = vehicleDTO.getFullWeight();
-        this.exhaustMeasure = vehicleDTO.getDisplacement();
+        this.exhaustMeasure = String.valueOf(vehicleDTO.getDisplacement());
         this.power = vehicleDTO.getPower();
         this.creator = vehicleDTO.getCompanyName();
         this.vehicleAcquisitionPrice = vehicleDTO.getPurchasePrice();
@@ -80,18 +83,21 @@ public class ZhongAnCrawlerCacheCarQueryRequest {
         this.taxType = vehicleDTO.getHfCode();
         this.syxClassid = vehicleDTO.getSyxClassid();
         this.vehicleType = "2";
-        this.modelEnergyType = "0";
-        this.fuelType = "D1";
+        this.modelEnergyType = carInfoVo.getEnergyTypeCode();
+        this.fuelType = vehicleDTO.getPowerTypeCode();
         this.desVehicleOwnerName = "";
+        if (carInfoVo.isTransfer()) {
+            this.isTransferCar = "1";
+            this.transferDate = carInfoVo.getTransferDate();
+        }
         this.applicantType = "PERSONAL";
         this.applicantUseAttribute = "03";
         this.useAttribute = "NONBUSINESS";
         this.subOwnershipAttribute = "";
         this.ownershipAttribute = "PER";
         this.vehicleLicenceType = "";
-        this.callVehicleModelLibraryFlag = 1;
-
-        this.vehicleModelDesc = vehicleName + " " + gearBoxType + " " + configName + " " + vehiclePassengerCap + "座" + "(" + vehicleAcquisitionPrice + "元)";
+        this.callVehicleModelLibraryFlag = "1";
+        this.vehicleModelDesc = vehicleName + " " + gearBoxType + " " + configName + " " + vehiclePassengerCap + "座" + "(" + vehicleAcquisitionPrice + "元)";
     }
 
     /**
@@ -309,7 +315,7 @@ public class ZhongAnCrawlerCacheCarQueryRequest {
      * 单位:L,例如:1.49
      */
     @JsonProperty("exhaustMeasure")
-    private Double exhaustMeasure;
+    private String exhaustMeasure;
 
     /**
      * 发动机功率
@@ -395,6 +401,19 @@ public class ZhongAnCrawlerCacheCarQueryRequest {
     @JsonProperty("desVehicleOwnerName")
     private String desVehicleOwnerName;
 
+    /**
+     * 是否过户车辆标识
+     * 例如:1表示为过户车
+     */
+    @JsonProperty("isTransferCar")
+    private String isTransferCar;
+
+    /**
+     * 过户日期
+     */
+    @JsonProperty("transferDate")
+    private String transferDate;
+
     /**
      * 申请人类型
      * 例如:PERSONAL表示个人
@@ -442,7 +461,7 @@ public class ZhongAnCrawlerCacheCarQueryRequest {
      * 例如:0表示未调用
      */
     @JsonProperty("callVehicleModelLibraryFlag")
-    private Integer callVehicleModelLibraryFlag;
+    private String callVehicleModelLibraryFlag;
 
 
 

+ 2 - 2
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerPolicyListRequest.java

@@ -40,14 +40,14 @@ public class ZhongAnCrawlerPolicyListRequest {
 
 
 
-    public ZhongAnCrawlerPolicyListRequest(String license,ZhongAnCrawlerConfigureParameters parameters) {
+    public ZhongAnCrawlerPolicyListRequest(String license,ZhongAnCrawlerConfigureParameters parameters,String status) {
 
         this.setFlowId(parameters.getFlowId());
         this.setPage(ZhongAnRequestConstant.POLICY_LIST);
         this.setFlag(parameters.getFlag());
         this.setI(ZhongAnRequestConstant.I_PARAM);
         this.setQueryConditon(license);
-        this.setStatus("1");
+        this.setStatus(status);
         this.setPageIndex("1");
         this.setQueryType("1");
     }

+ 44 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerQueryAccommodationRequest.java

@@ -0,0 +1,44 @@
+package com.jzg.quotation.zhongan.crawler.entity.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.quotation.zhongan.crawler.constant.ZhongAnRequestConstant;
+import com.jzg.quotation.zhongan.crawler.entity.ZhongAnCrawlerConfigureParameters;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author quchen
+ * @date 2026/5/12 18:01
+ */
+
+@NoArgsConstructor
+@Data
+public class ZhongAnCrawlerQueryAccommodationRequest {
+
+    @JsonProperty("flowId")
+    private String flowId;
+
+    @JsonProperty("page")
+    private String page;
+
+    @JsonProperty("flag")
+    private String flag;
+
+    @JsonProperty("i")
+    private String i;
+
+    @JsonProperty("checkCode")
+    private String checkCode;
+
+    @JsonProperty("quoteId")
+    private String quoteId;
+
+    public ZhongAnCrawlerQueryAccommodationRequest(String quoteId, ZhongAnCrawlerConfigureParameters parameters ){
+        this.setFlowId(parameters.getFlowId());
+        this.setPage(ZhongAnRequestConstant.TONG_RONG_QUERY_PAGE);
+        this.setFlag(parameters.getFlag());
+        this.setI(ZhongAnRequestConstant.I_PARAM);
+        this.setCheckCode("");
+        this.setQuoteId(quoteId);
+    }
+}

+ 39 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerQueryInitInfoRequest.java

@@ -0,0 +1,39 @@
+package com.jzg.quotation.zhongan.crawler.entity.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.quotation.zhongan.crawler.constant.ZhongAnRequestConstant;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+
+/**
+ * @author quchen
+ * @date 2026/5/9 10:04
+ */
+@NoArgsConstructor
+@Data
+public class ZhongAnCrawlerQueryInitInfoRequest {
+    @Serial
+    private static final long serialVersionUID = -1L;
+
+
+    @JsonProperty("flowId")
+    private String flowId;
+
+    @JsonProperty("page")
+    private String page;
+
+    @JsonProperty("flag")
+    private String flag;
+
+    @JsonProperty("i")
+    private String i;
+
+    public ZhongAnCrawlerQueryInitInfoRequest(String flowId) {
+        this.setFlowId(flowId);
+        this.setPage(ZhongAnRequestConstant.INIT_QUERY_PAGE);
+        this.setFlag("0");
+        this.setI(ZhongAnRequestConstant.I_PARAM);
+    }
+}

+ 22 - 18
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerQuoteRequest.java

@@ -93,31 +93,35 @@ public class ZhongAnCrawlerQuoteRequest{
         } else {
             this.addCompel = "0";
         }
-//        List<KindInfoVo> kindInfoVoList = quoteVo.getKindInfoVo();
-
-        List<ZhongAnCrawlerQuoteBaseResponse.ValueDTO.QuoteCoverageListDTO> quoteCoverageList = quoteBaseResponse.getValue().getQuoteCoverageList();
-
+        // 商业险险种
+        List<KindInfoVo> kindInfoVoList = quoteVo.getKindInfoVo();
+//        List<ZhongAnCrawlerQuoteBaseResponse.ValueDTO.QuoteCoverageListDTO> quoteCoverageList = quoteBaseResponse.getValue().getQuoteCoverageList();
         List<CoverageInfoDTO> coverageInfoDTOS = new ArrayList<>();
-
-        if (quoteCoverageList != null && quoteCoverageList.size() > 0) {
-            for (ZhongAnCrawlerQuoteBaseResponse.ValueDTO.QuoteCoverageListDTO quoteCoverage: quoteCoverageList) {
+        if (kindInfoVoList != null && kindInfoVoList.size() > 0) {
+            for (KindInfoVo kindInfo: kindInfoVoList) {
                 CoverageInfoDTO coverageInfoDTO = new CoverageInfoDTO();
-                coverageInfoDTO.setProductId(quoteCoverage.getProductId());
-                coverageInfoDTO.setAmount(quoteCoverage.getAmount());
+                coverageInfoDTO.setProductId(kindInfo.getKindCode());
+                coverageInfoDTO.setAmount(kindInfo.getAmount());
                 coverageInfoDTOS.add(coverageInfoDTO);
             }
         }
         this.coverageInfo = JSONObject.toJSONString(coverageInfoDTOS);
-
         List<NonAutoInfoDto> nonAutoInfoDtos = new ArrayList<>();
-        NonAutoInfoDto jtywxV24 = new NonAutoInfoDto("kp_jtywx_v24", "1", "6");
-        NonAutoInfoDto wjsGabV6 = new NonAutoInfoDto("wjs_gab_v6", "0", null);
-
-        nonAutoInfoDtos.add(jtywxV24);
-        nonAutoInfoDtos.add(wjsGabV6);
-
-        this.nonAutoInfo = JSONObject.toJSONString(nonAutoInfoDtos);
-
+        // 驾意险
+        if (quoteVo.getAccidentalDrivings() != null && quoteVo.getAccidentalDrivings().size() > 0) {
+
+            quoteVo.getAccidentalDrivings().forEach(accidentalDriving -> {
+                NonAutoInfoDto nonAutoInfoDto = new NonAutoInfoDto(accidentalDriving.getParentProductCode(), "1", accidentalDriving.getProductCode());
+                nonAutoInfoDtos.add(nonAutoInfoDto);
+            });
+            this.nonAutoInfo = JSONObject.toJSONString(nonAutoInfoDtos);
+        } else {
+            NonAutoInfoDto jtywxV24 = new NonAutoInfoDto("kp_jtywx_v24", "0", null);
+            NonAutoInfoDto wjsGabV6 = new NonAutoInfoDto("wjs_gab_v6", "0", null);
+            nonAutoInfoDtos.add(jtywxV24);
+            nonAutoInfoDtos.add(wjsGabV6);
+            this.nonAutoInfo = JSONObject.toJSONString(nonAutoInfoDtos);
+        }
     }
 
     /**

+ 4 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/request/ZhongAnCrawlerUploadImageRequest.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.zhongan.crawler.entity.request;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
 import com.jzg.quotation.zhongan.crawler.constant.ZhongAnRequestConstant;
@@ -48,11 +49,14 @@ public class ZhongAnCrawlerUploadImageRequest implements Serializable {
     private String imageType;
 
     @JsonProperty("fileItem")
+    @JSONField(serialize = false)
     private ByteArrayResource fileItem;
     @JsonProperty("orderNo")
     private String orderNo;
     @JsonProperty("policyId")
     private String policyId;
+    @JsonProperty("isSubmitAudit")
+    private String isSubmitAudit;
     @JsonProperty("page")
     private String page;
     @JsonProperty("flag")

+ 48 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerApplyAccommodationResponse.java

@@ -0,0 +1,48 @@
+package com.jzg.quotation.zhongan.crawler.entity.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author quchen
+ * @date 2026/5/13 11:37
+ */
+
+@Data
+@NoArgsConstructor
+public class ZhongAnCrawlerApplyAccommodationResponse {
+    @JsonProperty("additionalInfo")
+    private AdditionalInfoDTO additionalInfo;
+
+    @JsonProperty("errorCode")
+    private String errorCode;
+
+    @JsonProperty("errorMsg")
+    private String errorMsg;
+
+    @JsonProperty("success")
+    private Boolean success;
+
+    @JsonProperty("ruleMsgTips")
+    private String ruleMsgTips;
+
+    @JsonProperty("value")
+    private ValueDTO value;
+
+    @Data
+    @NoArgsConstructor
+    public static class AdditionalInfoDTO {
+    }
+    @Data
+    @NoArgsConstructor
+    public static class ValueDTO {
+        @JsonProperty("datas")
+        private DataDTO datas;
+
+        @Data
+        @NoArgsConstructor
+        public static class DataDTO {
+        }
+    }
+}

+ 4 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerPolicyListResponse.java

@@ -92,6 +92,10 @@ public class ZhongAnCrawlerPolicyListResponse extends ZhongAnCrawlerBaseResponse
                 private String zaFlag;
                 @JsonProperty("insurePayJyxFlag")
                 private String insurePayJyxFlag;
+                @JsonProperty("manualAuditStatus")
+                private String manualAuditStatus;
+                @JsonProperty("greenQuoteStatus")
+                private String greenQuoteStatus;
             }
 
         }

+ 315 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerQueryAccommodationResponse.java

@@ -0,0 +1,315 @@
+package com.jzg.quotation.zhongan.crawler.entity.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author quchen
+ * @date 2026/5/12 18:12
+ */
+
+@Data
+@NoArgsConstructor
+public class ZhongAnCrawlerQueryAccommodationResponse {
+
+        @JsonProperty("errorMsg")
+        private String errorMsg;
+
+        @JsonProperty("ruleMsgTips")
+        private String ruleMsgTips;
+
+        @JsonProperty("errorCode")
+        private String errorCode;
+
+        @JsonProperty("value")
+        private ValueDTO value;
+
+        @JsonProperty("additionalInfo")
+        private AdditionalInfoDTO additionalInfo;
+
+        @JsonProperty("success")
+        private Boolean success;
+
+        @Data
+        @NoArgsConstructor
+        public static class ValueDTO {
+            @JsonProperty("datas")
+            private DatasDTO datas;
+            @Data
+            @NoArgsConstructor
+            public static class DatasDTO {
+                @JsonProperty("showPowerOfAttorney")
+                private String showPowerOfAttorney;
+
+                @JsonProperty("accommodation")
+                private AccommodationDTO accommodation;
+
+                @JsonProperty("applicantName")
+                private String applicantName;
+
+                @JsonProperty("isOffLinePay")
+                private String isOffLinePay;
+
+                @Data
+                @NoArgsConstructor
+                public static class AccommodationDTO {
+                    @JsonProperty("id")
+                    private Long id;
+
+                    @JsonProperty("campaignId")
+                    private Long campaignId;
+
+                    @JsonProperty("insurePlace")
+                    private String insurePlace;
+
+                    @JsonProperty("insurePlaceCode")
+                    private String insurePlaceCode;
+
+                    @JsonProperty("vehicleLicencePlateNo")
+                    private String vehicleLicencePlateNo;
+
+                    @JsonProperty("vehicleFrameNo")
+                    private String vehicleFrameNo;
+
+                    @JsonProperty("auditStatus")
+                    private String auditStatus;
+
+                    @JsonProperty("quoteId")
+                    private Long quoteId;
+
+                    @JsonProperty("vehiclePolicyId")
+                    private Long vehiclePolicyId;
+
+                    @JsonProperty("quoteStatus")
+                    private String quoteStatus;
+
+                    @JsonProperty("orderNo")
+                    private String orderNo;
+
+                    @JsonProperty("phoneNo")
+                    private String phoneNo;
+
+                    @JsonProperty("nearbyAddress")
+                    private String nearbyAddress;
+
+                    @JsonProperty("applicationReasons")
+                    private String applicationReasons;
+
+                    @JsonProperty("underwritingErrorCode")
+                    private String underwritingErrorCode;
+
+                    @JsonProperty("creator")
+                    private String creator;
+
+                    @JsonProperty("gmtCreated")
+                    private Long gmtCreated;
+
+                    @JsonProperty("modifier")
+                    private String modifier;
+
+                    @JsonProperty("gmtModified")
+                    private Long gmtModified;
+
+                    @JsonProperty("isDeleted")
+                    private String isDeleted;
+
+                    @JsonProperty("identityNo")
+                    private String identityNo;
+
+                    @JsonProperty("rejectReason")
+                    private String rejectReason;
+
+                    @JsonProperty("attachementType")
+                    private List<String> attachementType;
+
+                    @JsonProperty("applyDate")
+                    private Long applyDate;
+
+                    @JsonProperty("noClaimAdjustRatio")
+                    private String noClaimAdjustRatio;
+
+                    @JsonProperty("transferFlag")
+                    private String transferFlag;
+
+                    @JsonProperty("loanVehicleFlag")
+                    private String loanVehicleFlag;
+
+                    @JsonProperty("auditTime")
+                    private Long auditTime;
+
+                    @JsonProperty("policyGrade")
+                    private String policyGrade;
+
+                    @JsonProperty("greenwayVerificationCode")
+                    private String greenwayVerificationCode;
+
+                    @JsonProperty("rulecenterErrorCode")
+                    private String rulecenterErrorCode;
+
+                    @JsonProperty("selfUnderwritErrorCode")
+                    private String selfUnderwritErrorCode;
+
+                    @JsonProperty("auditor")
+                    private String auditor;
+
+                    @JsonProperty("needGreenway")
+                    private String needGreenway;
+
+                    @JsonProperty("handleStatus")
+                    private String handleStatus;
+
+                    @JsonProperty("ruleGreenWayMaterial")
+                    private String ruleGreenWayMaterial;
+
+                    @JsonProperty("paOrgCode")
+                    private String paOrgCode;
+
+                    @JsonProperty("aiApproved")
+                    private String aiApproved;
+
+                    @JsonProperty("aiRejectReason")
+                    private String aiRejectReason;
+
+                    @JsonProperty("extraInfo")
+                    private String extraInfo;
+
+                    @JsonProperty("userId")
+                    private String userId;
+
+                    @JsonProperty("instantFlag")
+                    private String instantFlag;
+
+                    @JsonProperty("greenwayExtraInfo")
+                    private GreenwayExtraInfoDTO greenwayExtraInfo;
+
+                    @JsonProperty("vehicleOwner")
+                    private String vehicleOwner;
+
+                    @JsonProperty("auditLevel")
+                    private String auditLevel;
+
+                    @JsonProperty("selfPriceRatio")
+                    private String selfPriceRatio;
+
+                    @JsonProperty("materialUrl")
+                    private String materialUrl;
+
+                    @JsonProperty("errorCode")
+                    private String errorCode;
+
+                    @JsonProperty("file")
+                    private Map<String, Object> file;
+
+                    @JsonProperty("quoteIdStr")
+                    private String quoteIdStr;
+
+                    @JsonProperty("attachementFileList")
+                    private List<AttachementFileDTO> attachementFileList;
+
+                    @JsonProperty("campaignName")
+                    private String campaignName;
+
+                    @JsonProperty("coverageList")
+                    private List<String> coverageList;
+
+                    @JsonProperty("changeFeeSwitch")
+                    private String changeFeeSwitch;
+
+                    @JsonProperty("agentUserCode")
+                    private String agentUserCode;
+                }
+            }
+
+
+        }
+
+
+
+        @Data
+        @NoArgsConstructor
+        public static class GreenwayExtraInfoDTO {
+            @JsonProperty("orderType")
+            private String orderType;
+
+            @JsonProperty("bizEffectiveDate")
+            private Long bizEffectiveDate;
+
+            @JsonProperty("bizExpiryDate")
+            private Long bizExpiryDate;
+
+            @JsonProperty("compelEffectiveDate")
+            private Long compelEffectiveDate;
+
+            @JsonProperty("compelExpiryDate")
+            private Long compelExpiryDate;
+
+            @JsonProperty("vehicleAge")
+            private String vehicleAge;
+
+            @JsonProperty("vehicleType")
+            private String vehicleType;
+
+            @JsonProperty("partnerName")
+            private String partnerName;
+
+            @JsonProperty("auditors")
+            private String auditors;
+
+            @JsonProperty("errAuditLevelMap")
+            private Map<String, String> errAuditLevelMap;
+
+            @JsonProperty("orcSourceAndCompareTargetMap")
+            private Map<String, Object> orcSourceAndCompareTargetMap;
+
+            @JsonProperty("vehicleClass")
+            private String vehicleClass;
+
+            @JsonProperty("modelEnergyType")
+            private String modelEnergyType;
+
+            @JsonProperty("chargingPileFlag")
+            private String chargingPileFlag;
+
+            @JsonProperty("gist")
+            private String gist;
+
+            @JsonProperty("isQueryDutyTable")
+            private String isQueryDutyTable;
+
+            @JsonProperty("responsible")
+            private String responsible;
+
+            @JsonProperty("fakeFlag")
+            private Boolean fakeFlag;
+
+            @JsonProperty("xerrorMsgMap")
+            private Map<String, Object> xerrorMsgMap;
+        }
+
+        @Data
+        @NoArgsConstructor
+        public static class AttachementFileDTO {
+            @JsonProperty("type")
+            private String type;
+
+            @JsonProperty("typeName")
+            private String typeName;
+
+            @JsonProperty("address")
+            private String address;
+
+            @JsonProperty("encFileImageName")
+            private String encFileImageName;
+        }
+
+        @Data
+        @NoArgsConstructor
+        public static class AdditionalInfoDTO {
+        }
+}
+
+

+ 57 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerQueryInitInfoResponse.java

@@ -0,0 +1,57 @@
+package com.jzg.quotation.zhongan.crawler.entity.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+
+/**
+ * @author quchen
+ * @date 2026/5/9 10:07
+ */
+
+@Data
+@NoArgsConstructor
+public class ZhongAnCrawlerQueryInitInfoResponse {
+    @Serial
+    private static final long serialVersionUID = -1L;
+
+    @JsonProperty("errorMsg")
+    private String errorMsg;
+    @JsonProperty("ruleMsgTips")
+    private String ruleMsgTips;
+    @JsonProperty("errorCode")
+    private String errorCode;
+    @JsonProperty("value")
+    private ValueDTO value;
+    @JsonProperty("additionalInfo")
+    private AdditionalInfoDTO additionalInfo;
+    @JsonProperty("success")
+    private Boolean success;
+
+    @NoArgsConstructor
+    @Data
+    public static class ValueDTO {
+        @JsonProperty("datas")
+        private DatasDTO datas;
+
+        @Data
+        @NoArgsConstructor
+        public static class DatasDTO {
+            @JsonProperty("agentName")
+            private String agentName;
+
+            @JsonProperty("agentNoticeUrl")
+            private String agentNoticeUrl;
+
+            @JsonProperty("productModel")
+            private String productModel;
+        }
+    }
+    @NoArgsConstructor
+    @Data
+    public static class AdditionalInfoDTO {
+    }
+}
+

+ 14 - 0
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/entity/response/ZhongAnCrawlerQuoteResponse.java

@@ -100,6 +100,14 @@ public class ZhongAnCrawlerQuoteResponse extends ZhongAnCrawlerBaseResponse {
 
             private String policyGradePa;
 
+            private String policyGradeZa;
+
+            private String dingRanScore;
+
+            private String forceRenewalFlag;
+
+            private String bizRenewalFlag;
+
             private String isShowHolidayCoverage;
 
             private String trafficViolationRatio;
@@ -237,6 +245,8 @@ public class ZhongAnCrawlerQuoteResponse extends ZhongAnCrawlerBaseResponse {
                 @Serial
                 private static final long serialVersionUID = 2649602043794691117L;
                 private String PA;
+
+                private String ZA;
             }
 
             @Data
@@ -288,5 +298,9 @@ public class ZhongAnCrawlerQuoteResponse extends ZhongAnCrawlerBaseResponse {
         private String insureMessageF;
 
         private String insureMessageFCode;
+
+        private String insureMessage;
+
+        private String insureMessageCode;
     }
 }

+ 259 - 131
tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/service/Impl/ZhongAnCrawlerRequestImpl.java

@@ -1,15 +1,18 @@
 package com.jzg.quotation.zhongan.crawler.service.Impl;
 
+import cn.hutool.cache.Cache;
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.cache.CacheBuilder;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
-import com.jzg.commons.entity.po.SysUploadFiles;
+import com.jzg.commons.entity.orders.po.InsOrdersCarInfo;
+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;
 import com.jzg.commons.entity.quote.vo.aggregated.*;
 import com.jzg.commons.exception.SystemException;
-import com.jzg.commons.util.MinioUtils;
 import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.commons.annotation.QuoteCrawlerService;
 import com.jzg.quotation.commons.client.PlatformClient;
@@ -19,9 +22,8 @@ import com.jzg.commons.entity.quote.vo.base.OrderBase;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
 import com.jzg.quotation.commons.filter.CarModelsFilterUtils;
 import com.jzg.quotation.commons.standard.conversion.ConfigureParametersConversion;
-import com.jzg.quotation.commons.utils.HttpUtil;
-import com.jzg.quotation.zhongan.crawler.JsonUtil;
 import com.jzg.quotation.zhongan.crawler.build.ZhongAnCrawlerQuoteResultsVoBuild;
+import com.jzg.quotation.zhongan.crawler.client.LoginResult;
 import com.jzg.quotation.zhongan.crawler.component.ZhongAnCrawlerCacheComponent;
 import com.jzg.quotation.zhongan.crawler.component.ZhongAnCrawlerRequestComponent;
 import com.jzg.quotation.zhongan.crawler.constant.ZhongAnRequestConstant;
@@ -32,16 +34,19 @@ import com.jzg.quotation.zhongan.crawler.entity.response.*;
 import com.jzg.quotation.zhongan.crawler.service.ZhongAnCrawlerOrderService;
 import com.jzg.quotation.zhongan.crawler.service.ZhongAnCrawlerRequest;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpHeaders;
 
 import java.io.*;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Base64;
-import java.util.HashMap;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -51,6 +56,7 @@ import java.util.stream.Collectors;
  **/
 @QuoteCrawlerService(value = InsuranceCode.INSURANCE_ZAPA)
 @RequiredArgsConstructor
+@Slf4j
 public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
     private final ZhongAnCrawlerRequestComponent zhongAnCrawlerRequestComponent;
 
@@ -61,16 +67,44 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
     @Value("${zhongAn.id}")
     private String zhongAnId;
 
+    @Value("${zhongAn.productId}")
+    private String productId;
+
     private final PlatformClient platformClient;
 
+    @Autowired
+    private RedissonClient redissonClient;
+
     /**
      * 登录
      *
-     * @param loginBase 登录信息
+     * @param username 用户名
      */
-    @Override
-    public void login(LoginBase loginBase) {
 
+    private static final String COOKIE = "zaLoginCookieKey";
+    private static final String FLOWID = "flowId";
+    private static final String ZHONGAN_COOKIE = "zhongan:cookie:";
+
+    public LoginResult login(String zhongAnId, String productId) {
+        // 先从缓存取
+        Map<Object, Object> cacheMap = redissonClient.getMap(ZHONGAN_COOKIE + zhongAnId);
+        if (cacheMap != null && !cacheMap.isEmpty()) {
+            String zaLoginCookieKey = (String) cacheMap.get(COOKIE);
+            String flowId = (String) cacheMap.get(FLOWID);
+
+            System.out.println("[" + zhongAnId + "] 从 Redisson 缓存读取登录信息");
+            return new LoginResult(200, "缓存登录成功", zaLoginCookieKey, flowId);
+        }
+
+        // 缓存没有 执行登录
+        LoginResult result = zhongAnCrawlerCacheComponent.loginCookieCache(zhongAnId,productId);
+
+        // 登录成功 存缓存
+        if (result.getCode() == 200) {
+            zhongAnCrawlerCacheComponent.cacheCookie(result.getZaLoginCookieKey(), result.getFlowId(), zhongAnId);
+        }
+
+        return result;
     }
 
     /**
@@ -81,8 +115,8 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
      */
     @Override
     public QuoteResultsVo quote(QuoteVo quoteVo) {
-        //登录众安
-        loginCookieCache(zhongAnId);
+        // 检查登录
+        login(zhongAnId,productId);
         zhongAnCrawlerCacheComponent.setCache(quoteVo.getOwnersInfo().getIdentifyNumber(), quoteVo.getOrder().getOrdersNo() + ZhongAnCrawlerCacheComponent.IDENTIFY_NUMBER);
         CarInfoVo carInfoVo = quoteVo.getCarInfoVo();
         zhongAnCrawlerCacheComponent.setCache(carInfoVo.getLicenseNo(),quoteVo.getOrder().getOrdersNo()+ZhongAnCrawlerCacheComponent.LICENSE);
@@ -94,6 +128,9 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
         if (StringUtils.isEmpty(flowId)) {
             parameters.setFlowId(zhongAnCrawlerCacheComponent.getFlowId(zhongAnId));
         }
+        // 查询归属信息
+        ZhongAnCrawlerQueryInitInfoRequest queryInitInfoRequest = new ZhongAnCrawlerQueryInitInfoRequest(parameters.getFlowId());
+        String queryInitInfoResponse = zhongAnCrawlerRequestComponent.initInfo(queryInitInfoRequest, headers);
         //校验key,缓存
         ZhongAnCrawlerCacheInputRequest cacheInputRequest = new ZhongAnCrawlerCacheInputRequest(quoteVo, parameters);
         String cacheInput = zhongAnCrawlerRequestComponent.CacheInput(cacheInputRequest, headers);
@@ -116,9 +153,7 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
         ZhongAnCrawlerLicenseSwitchRequest licenseSwitchRequest = new ZhongAnCrawlerLicenseSwitchRequest(quoteVo, parameters);
         String licenseSwitch = zhongAnCrawlerRequestComponent.licenseSwitch(licenseSwitchRequest, headers);
 
-
         ZhongAnCrawlerCacheCarQueryRequest cacheCarQueryRequest = new ZhongAnCrawlerCacheCarQueryRequest(quoteVo, vehicleDTO, parameters);
-//        String cacheCarQueryResponse = zhongAnCrawlerRequestComponent.cacheCarInfo(cacheCarQueryRequest,headers);
         ZhongAnCrawlerCacheCarQueryResponse cacheCarQueryResponse = zhongAnCrawlerRequestComponent.cacheCarInfo(cacheCarQueryRequest, headers);
         if (cacheCarQueryResponse != null && StringUtils.isNotEmpty(cacheCarQueryResponse.getErrorMsg())) {
             if (cacheCarQueryResponse.getErrorCode().equals("A12512")) {
@@ -133,24 +168,42 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
                 if (cacheCarQueryResponse1 != null && StringUtils.isNotEmpty(cacheCarQueryResponse1.getErrorMsg())) {
                     throw new SystemException(cacheCarQueryResponse1.getErrorMsg());
                 }
-
             } else {
-
                 throw new SystemException(cacheCarQueryResponse.getErrorMsg());
             }
         }
 
         ZhongAnCrawlerQuoteBaseRequest quoteBaseRequest = new ZhongAnCrawlerQuoteBaseRequest(parameters);
         ZhongAnCrawlerQuoteBaseResponse quoteBaseResponse = zhongAnCrawlerRequestComponent.quoteBaseInfo(quoteBaseRequest, headers);
-//        ZhongAnCrawlerQuoteBaseResponse zhongAnCrawlerQuoteBaseResponse = JsonUtil.readObjcet(str, ZhongAnCrawlerQuoteBaseResponse.class);
 
         //报价
         ZhongAnCrawlerQuoteRequest quoteRequest = new ZhongAnCrawlerQuoteRequest(quoteVo, parameters, quoteBaseResponse);
         ZhongAnCrawlerQuoteResponse quoteResponse = zhongAnCrawlerRequestComponent.quote(quoteRequest, headers);
         if (quoteResponse != null && StringUtils.isNotEmpty(quoteResponse.getErrorMsg())) {
-            throw new SystemException(quoteResponse.getErrorMsg());
+            QuoteResultsVo quoteResultsVo = new QuoteResultsVo();
+            quoteResultsVo.setErrorMessage(quoteResponse.getErrorMsg());
+            quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.QUOTE_FAIL);
+            return quoteResultsVo;
+        }
+        // 处理重复投保
+        if (quoteResponse.getAdditionalInfo() != null) {
+            if (quoteResponse.getAdditionalInfo().getInsureMessageF() != null && quoteResponse.getAdditionalInfo().getInsureMessageF().contains("重复投保")) {
+                String jqExtractDate = jqExtractDate(quoteResponse);
+                if (jqExtractDate != null) {
+                    quoteRequest.setCompelInsEffectiveDate(jqExtractDate);
+                }
+                quoteResponse = zhongAnCrawlerRequestComponent.quote(quoteRequest, headers);
+                if (quoteResponse.getAdditionalInfo() != null && quoteResponse.getAdditionalInfo().getInsureMessage().contains("重复投保")) {
+                    String syExtractDate = syExtractDate(quoteResponse);
+                    if (syExtractDate != null) {
+                        quoteRequest.setEffectiveDate(syExtractDate);
+                    }
+                }
+                quoteResponse = zhongAnCrawlerRequestComponent.quote(quoteRequest, headers);
+            }
         }
 
+
         //确认报价
         ZhongAnCrawlerConfirmQuoteRequest confirmQuoteRequest = new ZhongAnCrawlerConfirmQuoteRequest(parameters);
         String s = zhongAnCrawlerRequestComponent.confirmQuote(confirmQuoteRequest, headers);
@@ -168,11 +221,12 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
         zhongAnCrawlerCacheComponent.setCache(dataDTO.getPolicyId(), quoteVo.getOrder().getOrdersNo() + ZhongAnCrawlerCacheComponent.POLICY_ID);
 
         //非车险提交核保
-        ZhongAnCrawlerJyxUnderwritingRequest jyxUnderwritingRequest = new ZhongAnCrawlerJyxUnderwritingRequest(parameters, getOrderResponse.getValue().getDatas().getQuoteId());
-        ZhongAnCrawlerJyxUnderwritingResponse jyxUnderwritingResponse = zhongAnCrawlerRequestComponent.jyxUnderwriting(jyxUnderwritingRequest, headers);
-
+        if (quoteVo.getAccidentalDrivings() != null && quoteVo.getAccidentalDrivings().size() > 0) {
+            ZhongAnCrawlerJyxUnderwritingRequest jyxUnderwritingRequest = new ZhongAnCrawlerJyxUnderwritingRequest(parameters, getOrderResponse.getValue().getDatas().getQuoteId());
+            ZhongAnCrawlerJyxUnderwritingResponse jyxUnderwritingResponse = zhongAnCrawlerRequestComponent.jyxUnderwriting(jyxUnderwritingRequest, headers);
+        }
         ZhongAnCrawlerUploadInitDateRequest zhongAnCrawlerUploadInitDateRequest = new ZhongAnCrawlerUploadInitDateRequest(dataDTO, parameters);
-        ZhongAnCrawlerUploadInitDateResponse uploadInitDateResponse = zhongAnCrawlerRequestComponent.uploadInitDate(zhongAnCrawlerUploadInitDateRequest, headers);
+        ZhongAnCrawlerUploadInitDateResponse uploadInitDateResponse = zhongAnCrawlerRequestComponent.uploadInitData(zhongAnCrawlerUploadInitDateRequest, headers);
         zhongAnCrawlerCacheComponent.setCache(uploadInitDateResponse.getValue().getDatas(), quoteVo.getOrder().getOrdersNo() + ZhongAnCrawlerCacheComponent.INITDATE);
 
 
@@ -180,68 +234,65 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
         zhongAnCrawlerOrder.setOrdersNo(quoteVo.getOrder().getOrdersNo());
         zhongAnCrawlerOrder.setOrderNo(dataDTO.getOrderNo());
         zhongAnCrawlerOrder.setPolicyId(dataDTO.getPolicyId());
+        zhongAnCrawlerOrder.setQuoteId(quoteResponse.getValue().getDatas().getQuoteId());
+        zhongAnCrawlerOrder.setCheckCode(uploadInitDateResponse.getValue().getDatas().getCheckCode());
+        // 交强投保单号
+        if (uploadInitDateResponse.getValue().getDatas().getCompelApplyNo() != null) {
+            zhongAnCrawlerOrder.setJqApplyNo(uploadInitDateResponse.getValue().getDatas().getCompelApplyNo());
+        }
+        // 商业投保单号
+        if (uploadInitDateResponse.getValue().getDatas().getBizApplyNo() != null) {
+            zhongAnCrawlerOrder.setSyApplyNo(uploadInitDateResponse.getValue().getDatas().getBizApplyNo());
+        }
         zhongAnCrawlerOrderService.save(zhongAnCrawlerOrder);
-        return ZhongAnCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo, quoteResponse.getValue().getDatas());
+        return ZhongAnCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo, quoteResponse.getValue().getDatas(),uploadInitDateResponse);
     }
 
-    //登录
-    private void loginCookieCache(String zhongAnId) {
-        try {
-
-            Map<String, String> params = new HashMap<>();
-            params.put("partnerChannelCode", "m18x462r");
-            params.put("partnerUserAccount", zhongAnId);
-            params.put("partnerChildChannelCode", "");
-            params.put("promotionNo", "0c033ab79c6847c0878342480aef76a1");
-            params.put("productId", "10676");
-            params.put("policySource", "40");
-            params.put("subaoBizContent", "");
-            params.put("insurerCode", "ZHONGANCAR");
-
-
-            Map<String, String> headers = new HashMap<>();
-            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36");
-            headers.put("Accept", "application/json, text/plain, */*");
-
-            // 发送第一个请求,不跟随重定向
-            String url = "https://www.cyouzai.com/busi-integration/channel/baoBiaoH5Redirect";
-            HttpURLConnection connection = HttpUtil.sendGetRequest(url, params, headers, false);
-            String firstLocation = connection.getHeaderField("Location");
-            connection.disconnect();
-
-            System.out.println(firstLocation);
-
-            // 发送第二个请求,不跟随重定向
-            connection = HttpUtil.sendGetRequest(firstLocation, null, headers, false);
-            String secondLocation = connection.getHeaderField("Location");
-            connection.disconnect();
-
-            // 发送第三个请求,不跟随重定向
-            connection = HttpUtil.sendGetRequest(secondLocation, null, headers, false);
-            Map<String, List<String>> responseHeaders = connection.getHeaderFields();
-            connection.disconnect();
-
-            // 提取zaLoginCookieKey
-            String zaLoginCookieKey = HttpUtil.extractZaLoginCookieKey(responseHeaders);
-            if (zaLoginCookieKey != null && !zaLoginCookieKey.isEmpty()) {
-                // 获取Location头
-                String thirdLocation = connection.getHeaderField("Location");
-
-                // 提取flowId
-                String flowId = HttpUtil.extractFlowId(thirdLocation);
-                //缓存数据
-                zhongAnCrawlerCacheComponent.cacheCookie(zaLoginCookieKey, flowId, zhongAnId);
-
-                System.out.println("key==" + zaLoginCookieKey + "------flowId=" + flowId);
-
-            } else {
-                throw new SystemException("未获取到-----zaLoginCookieKey");
-            }
-
-        } catch (Exception e) {
-            throw new SystemException("message", "请求发生错误: " + e.getMessage());
+    /**
+     * 交强险日期提取
+     */
+    private String jqExtractDate(ZhongAnCrawlerQuoteResponse quoteResponse) {
+        String insureMessageF = quoteResponse.getAdditionalInfo().getInsureMessageF();
+        // 1. 正则提取
+        String regex = "(\\d{4}年\\d{1,2}月\\d{1,2}日 \\d{1,2}:\\d{1,2}:\\d{1,2})";
+        Pattern pattern = Pattern.compile(regex);
+        Matcher matcher = pattern.matcher(insureMessageF);
+
+        String formatTime = null;
+        if (matcher.find()) {
+            String originTime = matcher.group(1); // 提取到的时间
+            formatTime = originTime
+                    .replace("年", "-")
+                    .replace("月", "-")
+                    .replace("日", "");
+        }
+        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-M-d HH:mm:ss");
+        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        if (formatTime != null) {
+            LocalDateTime dateTime = LocalDateTime.parse(formatTime, inputFormatter);
+            return dateTime.format(outputFormatter);
         }
+        return null;
+    }
 
+    /**
+     * 商业险日期提取
+     */
+    private String syExtractDate(ZhongAnCrawlerQuoteResponse quoteResponse) {
+        String insureMessage = quoteResponse.getAdditionalInfo().getInsureMessage();
+        String regex = "(\\d{4})年(\\d{1,2})月(\\d{1,2})日";
+        Matcher matcher = Pattern.compile(regex).matcher(insureMessage);
+        if (matcher.find()) {
+            int year = Integer.parseInt(matcher.group(1));
+            int month = Integer.parseInt(matcher.group(2));
+            int day = Integer.parseInt(matcher.group(3));
+
+            LocalDateTime dateTime = LocalDateTime.of(year, month, day, 0, 0, 0);
+
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            return dateTime.format(formatter);
+        }
+        return null;
     }
 
     /**
@@ -251,7 +302,8 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
      */
     @Override
     public UnderwritingResultsVo underwriting(UnderwritingVo underwritingVo) throws Exception {
-        loginCookieCache(zhongAnId);
+        // 检查登录
+        login(zhongAnId, productId);
         AttributionInformationVo attributionInformationVo = underwritingVo.getOrder().getAttributionInformationVo();
         ZhongAnCrawlerConfigureParameters parameters = ConfigureParametersConversion.conversionEntity(ZhongAnCrawlerConfigureParameters.class, attributionInformationVo.getConfigInfo());
         HttpHeaders headers = zhongAnCrawlerRequestComponent.getHeaders(zhongAnId);
@@ -259,25 +311,24 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
         if (StringUtils.isEmpty(flowId)) {
             parameters.setFlowId(zhongAnCrawlerCacheComponent.getFlowId(zhongAnId));
         }
-        String ordersNo = zhongAnCrawlerCacheComponent.getCache(underwritingVo.getOrder().getOrdersNo() + ZhongAnCrawlerCacheComponent.ORDER_NO);
-        ZhongAnCrawlerMarkRequest markRequest = new ZhongAnCrawlerMarkRequest(parameters, ordersNo);
-        String markCompleted = zhongAnCrawlerRequestComponent.markCompleted(markRequest, headers);
-
         ZhongAnCrawlerOrder zhongAnCrawlerOrder = zhongAnCrawlerOrderService.findByOrdersNo(underwritingVo.getOrder().getOrdersNo());
-
-        ZhongAnCrawlerUploadInitDateResponse.ValueDTO.DatasDTO initData = zhongAnCrawlerCacheComponent.getInitData(underwritingVo.getOrder().getOrdersNo() + ZhongAnCrawlerCacheComponent.INITDATE);
-        ZhongAnCrawlerPaymentRequest paymentRequest = new ZhongAnCrawlerPaymentRequest(zhongAnCrawlerOrder.getPolicyId(), initData.getCheckCode());
+        ZhongAnCrawlerMarkRequest markRequest = new ZhongAnCrawlerMarkRequest(parameters, zhongAnCrawlerOrder.getOrderNo());
+        String markCompleted = zhongAnCrawlerRequestComponent.markCompleted(markRequest, headers);
+        ZhongAnCrawlerPaymentRequest paymentRequest = new ZhongAnCrawlerPaymentRequest(zhongAnCrawlerOrder.getPolicyId(), zhongAnCrawlerOrder.getCheckCode());
         ZhongAnCrawlerPaymentResponse payment = zhongAnCrawlerRequestComponent.payment(paymentRequest, headers);
 
         UnderwritingResultsVo underwritingResultsVo = new UnderwritingResultsVo();
         underwritingResultsVo.setPaymentLink(payment.getValue().getDatas().getShareShortUrl());
         //核保结果
         underwritingResultsVo.setUnderwritingResult("核保成功");
-//        //核保状态
+        //核保状态
         underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.PAY_PENDING);
-//        //保司订单号
-        underwritingResultsVo.setCompanyOrderNo(ordersNo);
-
+        //保司订单号
+        underwritingResultsVo.setCompanyOrderNo(zhongAnCrawlerOrder.getOrderNo());
+        // 交强险投保单号
+        underwritingResultsVo.setJqApplyNo(zhongAnCrawlerOrder.getJqApplyNo());
+        // 商业投保单号
+        underwritingResultsVo.setSyApplyNo(zhongAnCrawlerOrder.getSyApplyNo());
         return underwritingResultsVo;
     }
 
@@ -288,7 +339,8 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
      */
     @Override
     public PaymentLinkResultsVo getPaymentLink(PaymentLinkVo paymentLinkVo) {
-        loginCookieCache(zhongAnId);
+        // 检查登录
+        login(zhongAnId,productId);
         PaymentLinkResultsVo paymentLinkResultsVo = new PaymentLinkResultsVo();
         OrderBase orderBase = paymentLinkVo.getOrder();
         //获取配置信息
@@ -317,7 +369,8 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
      */
     @Override
     public void uploadImage(InsuranceUploadImageVo insuranceUploadImageVo) {
-        loginCookieCache(zhongAnId);
+        // 检查登录
+        login(zhongAnId,productId);
         OrderBase orderBase = insuranceUploadImageVo.getOrder();
         AttributionInformationVo attributionInformationVo = orderBase.getAttributionInformationVo();
         //获取配置信息
@@ -369,10 +422,17 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
     private void extracted(ZhongAnCrawlerConfigureParameters parameters, HttpHeaders headers, ZhongAnCrawlerOrder zhongAnCrawlerOrder, String imageType, InsuranceImageVo.ImageDTO imageDTO) {
         ZhongAnCrawlerUploadImageRequest uploadImageRequest = new ZhongAnCrawlerUploadImageRequest(imageType, imageDTO, zhongAnCrawlerOrder.getOrderNo(), zhongAnCrawlerOrder.getPolicyId(), parameters);
         ZhongAnCrawlerUploadImageResponse uploadImageResponse = zhongAnCrawlerRequestComponent.uploadImage(uploadImageRequest, headers);
-        if (uploadImageResponse != null && StringUtils.isNotEmpty(uploadImageResponse.getErrorMsg())) {
-            throw new SystemException(uploadImageResponse.getErrorMsg());
+        if (uploadImageResponse != null && uploadImageResponse.getErrorMsg() != null && uploadImageResponse.getErrorMsg().contains("您上传的图片校验失败!请您确认是否要走人工审核")) {
+            uploadImageRequest.setIsSubmitAudit("1");
+            ZhongAnCrawlerUploadImageResponse uploadImageResponse1 = zhongAnCrawlerRequestComponent.uploadImage(uploadImageRequest, headers);
+            if (uploadImageResponse1 != null) {
+                if (uploadImageResponse1.getErrorMsg() != null && !uploadImageResponse1.getErrorMsg().isEmpty()) {
+                    throw new SystemException(uploadImageResponse1.getErrorMsg());
+                } else if (uploadImageResponse1.getSuccess()){
+                    log.info("上传影像成功");
+                }
+            }
         }
-
     }
 
     public  byte[] convert(String filePath) throws IOException {
@@ -391,9 +451,9 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
      */
     @Override
     public DownloadPolicyResultVo downloadPolicy(DownloadPolicyVo downloadPolicyVo) {
-        loginCookieCache(zhongAnId);
+        // 检查登录
+        login(zhongAnId,productId);
         OrderBase orderBase = downloadPolicyVo.getOrder();
-        AttributionInformationVo attributionInformationVo = orderBase.getAttributionInformationVo();
         //获取配置信息
         HttpHeaders headers = zhongAnCrawlerRequestComponent.getHeaders(zhongAnId);
 
@@ -423,7 +483,7 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
         String syUrl = ZhongAnRequestConstant.DOWNLOAD_POLICY_URL.replace(ZhongAnRequestConstant.ORDER_NO, orderNo)
                 .replace(ZhongAnRequestConstant.FILE_NAME, bizDTO.getDocumentName())
                 .replace(ZhongAnRequestConstant.DOCUMENT_URL, bizDTO.getDocumentUrl());
-        //获取交强保单信息
+        //获取驾意保单信息
         String jyUrl = ZhongAnRequestConstant.DOWNLOAD_POLICY_URL.replace(ZhongAnRequestConstant.ORDER_NO, orderNo)
                 .replace(ZhongAnRequestConstant.FILE_NAME, nonAutoDocumentInfo.getNonAutoPolicyName())
                 .replace(ZhongAnRequestConstant.DOCUMENT_URL, nonAutoDocumentInfo.getNonAutoPolicyUrl());
@@ -443,53 +503,121 @@ public class ZhongAnCrawlerRequestImpl implements ZhongAnCrawlerRequest {
      */
     @Override
     public OrderStatusResultVo queryOrderState(OrderStatusVo orderStatusVo) throws JsonProcessingException {
-        loginCookieCache(zhongAnId);
         AttributionInformationVo attributionInformationVo = orderStatusVo.getOrder().getAttributionInformationVo();
         //获取配置信息
         ZhongAnCrawlerConfigureParameters parameters = ConfigureParametersConversion.conversionEntity(ZhongAnCrawlerConfigureParameters.class, attributionInformationVo.getConfigInfo());
+        login(zhongAnId,productId);
         HttpHeaders headers = zhongAnCrawlerRequestComponent.getHeaders(zhongAnId);
         String flowId = parameters.getFlowId();
         if (StringUtils.isEmpty(flowId)) {
             parameters.setFlowId(zhongAnCrawlerCacheComponent.getFlowId(zhongAnId));
         }
-
-        String license = zhongAnCrawlerCacheComponent.getCache(orderStatusVo.getOrder().getOrdersNo() + ZhongAnCrawlerCacheComponent.LICENSE);
-        ZhongAnCrawlerPolicyListRequest policyListRequest = new ZhongAnCrawlerPolicyListRequest(license,parameters);
+        ZhongAnCrawlerOrder zhongAnCrawlerOrder = zhongAnCrawlerOrderService.findByOrdersNo(orderStatusVo.getOrder().getOrdersNo());
+        // 车牌号
+        String licenseNo = orderStatusVo.getCarInfo().getLicenseNo();
+        // 先查询是否存在待支付列表里
+        ZhongAnCrawlerPolicyListRequest policyListRequest = new ZhongAnCrawlerPolicyListRequest(licenseNo,parameters,"2");
         ZhongAnCrawlerPolicyListResponse response = zhongAnCrawlerRequestComponent.policyList(policyListRequest,headers);
+        OrderStatusResultVo orderStatusResultVo = new OrderStatusResultVo();
         if (!response.getSuccess()) {
             throw new SystemException(response.getErrorMsg());
-        }
-        List<ZhongAnCrawlerPolicyListResponse.ValueDTO.DatasDTO.policyListsDto> policyLists = response.getValue().getDatas().getPolicyLists();
-
-        OrderStatusResultVo orderStatusResultVo= new OrderStatusResultVo();
-        if (policyLists.size() >0) {
-            policyLists.forEach(s->{
-                if (s.getInsureTypeCode().equals("1")) {
-                    orderStatusResultVo.setSyPolicyno(s.getTpPolicyNo());
-                    orderStatusResultVo.setSyApplyNo(s.getApplyNo());
-                }else if (s.getInsureTypeCode().equals("2")) {
-                    orderStatusResultVo.setJqPolicyno(s.getTpPolicyNo());
-                    orderStatusResultVo.setJqApplyNo(s.getApplyNo());
-                }else if (s.getInsureTypeCode().equals("3")) {
-                    orderStatusResultVo.setJyPolicyno(s.getTpPolicyNo());
-                    orderStatusResultVo.setJyApplyNo(s.getApplyNo());
+        } else {
+            List<ZhongAnCrawlerPolicyListResponse.ValueDTO.DatasDTO.policyListsDto> policyLists = response.getValue().getDatas().getPolicyLists();
+            // 根据订单号获取记录
+            String orderNo = zhongAnCrawlerOrder.getOrderNo();
+            if (policyLists.size() > 0) {
+                for (ZhongAnCrawlerPolicyListResponse.ValueDTO.DatasDTO.policyListsDto policy : policyLists) {
+                    // 匹配当前订单号
+                    if (orderNo.equals(policy.getOrderNo())) {
+                        if (policy.getInsureTypeCode().equals("2")) {
+                            orderStatusResultVo.setJqApplyNo(policy.getApplyNo());
+                        } else if (policy.getInsureTypeCode().equals("1")) {
+                            orderStatusResultVo.setSyApplyNo(policy.getApplyNo());
+                        }
+                        if (StrUtil.isNotBlank(policy.getManualAuditStatus())) {
+                            // 人工审核通过 待支付
+                            if ("1".equals(policy.getManualAuditStatus()) || "3".equals(policy.getManualAuditStatus()) || "4".equals(policy.getManualAuditStatus())) {
+                                orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.PAY_PENDING);
+                            }
+                            // 质检中
+                            if ("2".equals(policy.getManualAuditStatus())) {
+                                orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.STAFF_PROCESS);
+                            }
+                        }
+                        // 人工核保
+                        if (StrUtil.isNotBlank(policy.getGreenQuoteStatus())) {
+                            if ("3".equals(policy.getGreenQuoteStatus())) {
+                                orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.AUDIT_FAIL);
+                                // 查看退回原因
+                                ZhongAnCrawlerQueryAccommodationRequest queryAccommodationRequest = new ZhongAnCrawlerQueryAccommodationRequest(zhongAnCrawlerOrder.getQuoteId(),parameters);
+                                ZhongAnCrawlerQueryAccommodationResponse queryAccommodationResponse = zhongAnCrawlerRequestComponent.queryAccommodation(queryAccommodationRequest,headers);
+                                if (queryAccommodationResponse.getSuccess()) {
+                                    ZhongAnCrawlerQueryAccommodationResponse.ValueDTO.DatasDTO.AccommodationDTO accommodationDTO = queryAccommodationResponse.getValue().getDatas().getAccommodation();
+                                    if (accommodationDTO.getErrorCode() != null) {
+                                        orderStatusResultVo.setOrderStatusStr(accommodationDTO.getErrorCode());
+                                        orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.AUDIT_FAIL);
+                                    }
+                                }
+                            }
+                            //
+                            if ("0".equals(policy.getGreenQuoteStatus())) {
+                                // 查看退回原因
+                                ZhongAnCrawlerQueryAccommodationRequest queryAccommodationRequest = new ZhongAnCrawlerQueryAccommodationRequest(zhongAnCrawlerOrder.getQuoteId(),parameters);
+                                ZhongAnCrawlerQueryAccommodationResponse queryAccommodationResponse = zhongAnCrawlerRequestComponent.queryAccommodation(queryAccommodationRequest,headers);
+                                Long id = queryAccommodationResponse.getValue().getDatas().getAccommodation().getId();
+                                String identityNo = orderStatusVo.getInsOrdersCarUserInfoList().stream()
+                                        .filter(insOrdersCarUserInfo -> insOrdersCarUserInfo.getPolicyPersonType() == 2)
+                                        .findFirst()
+                                        .map(InsOrdersCarUserInfo::getIdentifyNumber)
+                                        .orElse(null);
+                                // 提交通融
+                                ZhongAnCrawlerApplyAccommodationRequest applyAccommodationRequest = new ZhongAnCrawlerApplyAccommodationRequest(id,zhongAnCrawlerOrder.getQuoteId(),identityNo,zhongAnCrawlerOrder.getOrderNo(),parameters);
+                                ZhongAnCrawlerApplyAccommodationResponse applyAccommodationResponse = zhongAnCrawlerRequestComponent.applyAccommodation(applyAccommodationRequest,headers);
+                                if (applyAccommodationResponse.getSuccess()) {
+                                 orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.STAFF_PROCESS);
+                                 orderStatusResultVo.setOrderStatusStr("提交通融成功");
+                                }
+                            }
+                        }
+                    }
                 }
-                
-            });
-            ZhongAnCrawlerPolicyListResponse.ValueDTO.DatasDTO.policyListsDto policyListsDto = policyLists.get(0);
-            String policyStatus = policyListsDto.getPolicyStatus();
-            if (policyStatus == null) {
-                orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.QUOTE_FAIL);
-            }else {
-                if (policyStatus.equals("3")) {
-                    orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.PAY_PENDING);
-                }else if (policyStatus.equals("6")) {
-                    orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.UNDERWRITED);
+            }
+            // 如果待支付查不到订单 再去已支付列表查 有没有订单
+            if (policyLists.size() == 0) {
+                ZhongAnCrawlerPolicyListRequest policyListPayRequest = new ZhongAnCrawlerPolicyListRequest(licenseNo,parameters,"1");
+                ZhongAnCrawlerPolicyListResponse policyListPayResponse = zhongAnCrawlerRequestComponent.policyList(policyListPayRequest,headers);
+                if (policyListPayResponse.getSuccess()) {
+                    List<ZhongAnCrawlerPolicyListResponse.ValueDTO.DatasDTO.policyListsDto> policyPayLists = response.getValue().getDatas().getPolicyLists();
+                    if (policyPayLists.size() == 0) {
+                        orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.ORDER_CLOSE);
+                        orderStatusResultVo.setErrorMsg("未查询到订单信息");
+                    }
+                    if (policyPayLists.size() > 0) {
+                        for (ZhongAnCrawlerPolicyListResponse.ValueDTO.DatasDTO.policyListsDto policy : policyPayLists) {
+                            if (orderNo.equals(policy.getOrderNo())) {
+                                // 保单号
+                                if (policy.getInsureTypeCode().equals("2")) {
+                                    orderStatusResultVo.setJqPolicyno(policy.getTpPolicyNo());
+                                } else if (policy.getInsureTypeCode().equals("1")) {
+                                    orderStatusResultVo.setSyPolicyno(policy.getTpPolicyNo());
+                                } else if (policy.getInsureTypeCode().equals("3")) {
+                                    orderStatusResultVo.setJyPolicyno(policy.getTpPolicyNo());
+                                }
+                                orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.UNDERWRITED);
+                            } else {
+                                orderStatusResultVo.setOrderStatus(InsOrderStatusEnum.ORDER_CLOSE);
+                                orderStatusResultVo.setOrderStatusStr("订单不存在,或联系运营查询");
+                            }
+                        }
+                    }
                 }
             }
         }
+        return orderStatusResultVo;
+    }
 
+    @Override
+    public void login(LoginBase loginBase) {
 
-        return orderStatusResultVo;
     }
 }

+ 3 - 1
tenant/organization/src/main/resources/mapper/PtlSchemeMapper.xml

@@ -158,7 +158,8 @@
             jc.coverage,
             jc.premium,
             jc.risk_code,
-            jc.parent_product_code,
+            jc.parent_id,
+            jc1.product_code as parent_product_code,
             psidi.quantity,
             psidi.selected_status
         FROM
@@ -166,6 +167,7 @@
                 INNER JOIN ptl_scheme_info psi ON ps.id = psi.scheme_id
                 INNER JOIN ptl_scheme_insurance_driving_intention psidi ON psidi.scheme_info_id = psi.id
                 INNER JOIN jyx_config jc ON psidi.driving_intention_id = jc.id
+                INNER JOIN jyx_config jc1 on jc.parent_id = jc1.id
         WHERE
             ps.company_id = #{companyId}
         AND