Przeglądaj źródła

Merge branch 'master' of http://39.101.143.165:8090/785834757/jzg

lipf 3 miesięcy temu
rodzic
commit
4991cb179a
21 zmienionych plików z 523 dodań i 283 usunięć
  1. 2 2
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerRequestComponent.java
  2. 1 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerCarRequest.java
  3. 6 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerRequestImpl.java
  4. 7 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/build/GuoRenCrawlerQuoteResultsVoBuild.java
  5. 10 6
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/build/HuaNongCrawlerQuoteResultsVoBuild.java
  6. 57 2
      tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/constant/InsuranceKindCodeMapping.java
  7. 23 1
      tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/service/impl/RenBaoNewCrawlerRequestImpl.java
  8. 2 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/SummaryQuotationApplication.java
  9. 4 0
      tenant/insurance/quotation-summary/src/main/resources/logback-spring.xml
  10. 1 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/build/TkCrawlerQuoteResultsBuild.java
  11. 30 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/cache/RedisCacheUtil.java
  12. 108 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/po/TKCrawlerOrder.java
  13. 21 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/repository/TKCrawlerOrderRepository.java
  14. 33 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKCrawlerOrderService.java
  15. 16 20
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKHttpAPIService.java
  16. 58 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKCrawlerOrderServiceImpl.java
  17. 20 15
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKQuotationBaseServiceImpl.java
  18. 2 2
      tenant/insurance/quotation-taikang/src/test/java/com/jzg/quotation/taikang/crawler/TKHttpAPIServiceTest1.java
  19. 13 5
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java
  20. 104 87
      tenant/insurance/quotation-zhongan/src/main/java/com/jzg/quotation/zhongan/crawler/component/ZhongAnCrawlerCacheComponent.java
  21. 5 137
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/impl/ZiJinCrawlerRequestImpl.java

+ 2 - 2
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerRequestComponent.java

@@ -411,8 +411,8 @@ public class DaJiaCrawlerRequestComponent {
         }
         MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
         map.add("operatorCode",userCode);
-        String body = requestComponent.get(RequestUrl.POLICY_QUERY.getRequestUrl(daJiaCrawlerProperties.getBaseUrl()) + lastPolicyNo, map, "", String.class, headers);
-        String string1 = DESEncryption.decryptStrToObject(body, String.class);
+        DaJiaCrawlerBaseResponse response = requestComponent.get(RequestUrl.POLICY_QUERY.getRequestUrl(daJiaCrawlerProperties.getBaseUrl()) + lastPolicyNo, map, "", DaJiaCrawlerBaseResponse.class, headers);
+        String string1 = DESEncryption.decryptStrToObject(response.getResult(), String.class);
         log.info("返回数据:{}",string1);
     }
 }

+ 1 - 1
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerCarRequest.java

@@ -70,7 +70,7 @@ public class DaJiaCrawlerCarRequest implements Serializable {
         this.engineNo = carInfoVo.getEngineNo();
         this.vin = carInfoVo.getVinNo();
         this.licensePlateNo = carInfoVo.getLicenseNo();
-        this.queryMod = carInfoVo.getLicenseKindCode();
+        this.queryMod = "1";
         this.operatorCode = operatorCode;
     }
 

+ 6 - 1
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerRequestImpl.java

@@ -1,6 +1,7 @@
 package com.jzg.quotation.dajia.crawler.service.impl;
 
 
+import cn.hutool.core.collection.CollectionUtil;
 import com.alibaba.fastjson2.JSONObject;
 import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.po.SysUploadFiles;
@@ -151,8 +152,12 @@ public class DaJiaCrawlerRequestImpl implements DaJiaCrawlerRequest {
         ProposalInfoDTO proposalInfoDTO = buildingAttributionInformation.build(parameters, userCode, headers);
         // 2.0 车型查询
         DaJiaCrawlerCarRequest daJiaCrawlerCarRequest = new DaJiaCrawlerCarRequest(quoteVo.getCarInfoVo(), parameters.getLoginCompany(), parameters.getCDptCde(), userCode);
+        log.info("车型查询参数:{}",JSONObject.toJSONString(daJiaCrawlerCarRequest));
         DaJiaCrawlerCarResponse daJiaCrawlerCarResponse = daJiaCrawlerRequestComponent.car(daJiaCrawlerCarRequest, headers);
-
+        if (CollectionUtil.isEmpty(daJiaCrawlerCarResponse.getList())){
+            daJiaCrawlerCarRequest.setQueryMod("2");
+            daJiaCrawlerCarResponse = daJiaCrawlerRequestComponent.car(daJiaCrawlerCarRequest, headers);
+        }
         // 2.1 匹配最符合的车型
         DaJiaCrawlerCarResponse.ListDTO listDTO = CarModelsFilterUtils.to(daJiaCrawlerCarResponse.getList(), quoteVo.getCarInfoVo());
         // 2.2 计算车辆折旧价格

+ 7 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/build/GuoRenCrawlerQuoteResultsVoBuild.java

@@ -59,13 +59,19 @@ public final class GuoRenCrawlerQuoteResultsVoBuild {
         quoteResultsVo.getCosts().setVvTax(vvTax);
         quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.WAIT_AUDIT);
 
+
+        quoteVo.getCiRiskInfoVo().setStartDate(calculationPremium.getCi().getPrptitemkindList().get(0).getStartDate() + " 00:00:00");
+        quoteVo.getCiRiskInfoVo().setEndDate(calculationPremium.getCi().getPrptitemkindList().get(0).getEndDate() + " 00:00:00");
         quoteResultsVo.setCiRiskInfoVo(quoteVo.getCiRiskInfoVo());
-        quoteResultsVo.setBiRiskInfoVo(quoteVo.getBiRiskInfoVo());
 
         if (calculationPremium.getBi().getPrptitemkindList() != null) {
             List<KindInfoVo> kindInfoVo = buildKindInfoVo(quoteVo.getKindInfoVo(), calculationPremium.getBi().getPrptitemkindList());
+            quoteVo.getBiRiskInfoVo().setStartDate(calculationPremium.getBi().getPrptitemkindList().get(0).getStartDate() + " 00:00:00");
+            quoteVo.getBiRiskInfoVo().setEndDate(calculationPremium.getBi().getPrptitemkindList().get(0).getEndDate() + " 00:00:00");
             quoteResultsVo.setKindInfoVo(kindInfoVo);
         }
+        quoteResultsVo.setBiRiskInfoVo(quoteVo.getBiRiskInfoVo());
+
 
         QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
         scoreVo.setLossRation(calculationPremium.getBc().getAutoPriceOutputXOMRespVo().getStrBillELR2());

+ 10 - 6
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/build/HuaNongCrawlerQuoteResultsVoBuild.java

@@ -61,6 +61,8 @@ public final class HuaNongCrawlerQuoteResultsVoBuild {
                 quoteResultsVo.getCosts().setCiPremium(String.valueOf(contractDTO.getContractMain().getTotalPremium()));
                 quoteResultsVo.getCosts().setVvTax(String.valueOf(contractDTO.getTax().getSumTax()));
                 quoteResultsVo.setCiPolicyNumber(contractDTO1.getContractMain().getContractNo());
+                // 交强险出险次数
+                quoteResultsVo.getScoreVo().setCiClaims(contractDTO.getPlatFormMessage().getClaimTimes());
                 // 交强转续保标识(按RenewalEnum映射)
                 quoteResultsVo.getScoreVo().setJqRenewal(convertRenewalFlag(contractDTO.getContractMain().getRenewalFlag()));
             } else {
@@ -69,12 +71,14 @@ public final class HuaNongCrawlerQuoteResultsVoBuild {
                 buildRiskInfoVo(quoteVo.getBiRiskInfoVo(), contractDTO.getContractMain(), contractDTO.getPlatFormMessage(), false);
                 quoteResultsVo.getCosts().setBiPremium(String.valueOf(contractDTO.getContractMain().getTotalPremium()));
                 quoteResultsVo.setBiPolicyNumber(contractDTO1.getContractMain().getContractNo());
+                // 商业出险次数
+                quoteResultsVo.getScoreVo().setBiClaims(contractDTO.getPlatFormMessage().getClaimTimes());
                 // 商业转续保标识(按RenewalEnum映射)
                 quoteResultsVo.getScoreVo().setSyRenewal(convertRenewalFlag(contractDTO.getContractMain().getRenewalFlag()));
             }
         });
         //设置评分
-        quoteResultsVo.setScoreVo(buildScoreVo(huaNongCrawlerQuotedPriceResponse));
+        quoteResultsVo.setScoreVo(buildScoreVo(quoteResultsVo.getScoreVo(),huaNongCrawlerQuotedPriceResponse));
         quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.WAIT_AUDIT);
         quoteResultsVo.setCiRiskInfoVo(quoteVo.getCiRiskInfoVo());
         RiskInfoVo biRiskInfo = quoteVo.getBiRiskInfoVo();
@@ -87,8 +91,8 @@ public final class HuaNongCrawlerQuoteResultsVoBuild {
         return quoteResultsVo;
     }
 
-    private static QuoteResultsVo.ScoreVo buildScoreVo(HuaNongCrawlerQuotedPriceResponse huaNongCrawlerQuotedPriceResponse) {
-        QuoteResultsVo.ScoreVo scoreVo = new QuoteResultsVo.ScoreVo();
+    private static QuoteResultsVo.ScoreVo buildScoreVo(QuoteResultsVo.ScoreVo scoreVo, HuaNongCrawlerQuotedPriceResponse huaNongCrawlerQuotedPriceResponse) {
+
         HuaNongCrawlerQuotedPriceResponse.BusinessDataDTO businessData = huaNongCrawlerQuotedPriceResponse.getBusinessData();
 
         if (businessData == null) {
@@ -161,11 +165,11 @@ public final class HuaNongCrawlerQuoteResultsVoBuild {
         //    New(1,"新保"),
         //    Renewal(2,"续保"),
         //    Transfer(3,"转保");
-        if(renewalFlag.equals("0")){
+        if(renewalFlag.equals("1")){
             // 0 为转保
-            return "3";
-        }else{
             return "2";
+        }else{
+            return "3";
         }
 
     }

+ 57 - 2
tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/constant/InsuranceKindCodeMapping.java

@@ -153,8 +153,13 @@ public class InsuranceKindCodeMapping {
     private static final Map<String, String> KIND_NAME_MAP = new HashMap<>();
     private static final Map<String, String> KIND_ENERGY_NAME_MAP = new HashMap<>();
 
+    /** 反向映射:人保险种代码 → 掌柜鼎平台险种代码 */
+    private static final Map<String, String> REVERSE_KIND_CODE_MAP = new HashMap<>();
+    /** 人保险种代码 → 险种名称 */
+    private static final Map<String, String> RB_CODE_NAME_MAP = new HashMap<>();
+
     static {
-        // 初始化险种代码映射
+        // 初始化险种代码映射(平台 → 人保)
         KIND_CODE_MAP.put(KIND_A, CODE_A);
         KIND_CODE_MAP.put(KIND_B, CODE_B);
         KIND_CODE_MAP.put(KIND_D3, CODE_D3);
@@ -169,7 +174,22 @@ public class InsuranceKindCodeMapping {
         KIND_CODE_MAP.put(KIND_TY3, CODE_TY3);
         KIND_CODE_MAP.put(KIND_TY4, CODE_TY4);
 
-        // 初始化险种名称映射
+        // 初始化反向映射(人保 → 平台)
+        REVERSE_KIND_CODE_MAP.put(CODE_A, KIND_A);
+        REVERSE_KIND_CODE_MAP.put(CODE_B, KIND_B);
+        REVERSE_KIND_CODE_MAP.put(CODE_D3, KIND_D3);
+        REVERSE_KIND_CODE_MAP.put(CODE_D4, KIND_D4);
+        REVERSE_KIND_CODE_MAP.put(CODE_L, KIND_L);
+        REVERSE_KIND_CODE_MAP.put(CODE_BD, KIND_BD);
+        REVERSE_KIND_CODE_MAP.put(CODE_YBW1, KIND_YBW1);
+        REVERSE_KIND_CODE_MAP.put(CODE_YBW3, KIND_YBW3);
+        REVERSE_KIND_CODE_MAP.put(CODE_YBW2, KIND_YBW2);
+        REVERSE_KIND_CODE_MAP.put(CODE_TY1, KIND_TY1);
+        REVERSE_KIND_CODE_MAP.put(CODE_TY2, KIND_TY2);
+        REVERSE_KIND_CODE_MAP.put(CODE_TY3, KIND_TY3);
+        REVERSE_KIND_CODE_MAP.put(CODE_TY4, KIND_TY4);
+
+        // 初始化险种名称映射(平台 → 名称)
         KIND_NAME_MAP.put(KIND_A, NAME_A);
         KIND_NAME_MAP.put(KIND_B, NAME_B);
         KIND_NAME_MAP.put(KIND_D3, NAME_D3);
@@ -184,6 +204,21 @@ public class InsuranceKindCodeMapping {
         KIND_NAME_MAP.put(KIND_TY3, NAME_TY3);
         KIND_NAME_MAP.put(KIND_TY4, NAME_TY4);
 
+        // 初始化人保编码 → 名称映射
+        RB_CODE_NAME_MAP.put(CODE_A, NAME_A);
+        RB_CODE_NAME_MAP.put(CODE_B, NAME_B);
+        RB_CODE_NAME_MAP.put(CODE_D3, NAME_D3);
+        RB_CODE_NAME_MAP.put(CODE_D4, NAME_D4);
+        RB_CODE_NAME_MAP.put(CODE_L, NAME_L);
+        RB_CODE_NAME_MAP.put(CODE_BD, NAME_BD);
+        RB_CODE_NAME_MAP.put(CODE_YBW1, NAME_YBW1);
+        RB_CODE_NAME_MAP.put(CODE_YBW3, NAME_YBW3);
+        RB_CODE_NAME_MAP.put(CODE_YBW2, NAME_YBW2);
+        RB_CODE_NAME_MAP.put(CODE_TY1, NAME_TY1);
+        RB_CODE_NAME_MAP.put(CODE_TY2, NAME_TY2);
+        RB_CODE_NAME_MAP.put(CODE_TY3, NAME_TY3);
+        RB_CODE_NAME_MAP.put(CODE_TY4, NAME_TY4);
+
         // 初始化新能源险种名称映射
         KIND_ENERGY_NAME_MAP.put(KIND_A, ENERGY_NAME_A);
         KIND_ENERGY_NAME_MAP.put(KIND_B, ENERGY_NAME_B);
@@ -202,6 +237,26 @@ public class InsuranceKindCodeMapping {
         return KIND_CODE_MAP.getOrDefault(kindCode, kindCode);
     }
 
+    /**
+     * 根据人保险种代码获取掌柜鼎平台险种代码(反向映射)
+     *
+     * @param rbKindCode 人保险种代码(如"051050")
+     * @return 平台险种代码(如"A"),未匹配则返回原值
+     */
+    public static String getPlatformKindCode(String rbKindCode) {
+        return REVERSE_KIND_CODE_MAP.getOrDefault(rbKindCode, rbKindCode);
+    }
+
+    /**
+     * 根据人保险种代码获取险种名称
+     *
+     * @param rbKindCode 人保险种代码(如"051050")
+     * @return 险种名称(如"车损险"),未匹配则返回原值
+     */
+    public static String getKindNameByRbCode(String rbKindCode) {
+        return RB_CODE_NAME_MAP.getOrDefault(rbKindCode, rbKindCode);
+    }
+
     /**
      * 根据掌柜险种代码获取险种名称
      */

+ 23 - 1
tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/service/impl/RenBaoNewCrawlerRequestImpl.java

@@ -18,6 +18,7 @@ import com.jzg.quotation.commons.entity.GetCaptchaResponse;
 import com.jzg.quotation.commons.standard.conversion.ConfigureParametersConversion;
 import com.jzg.quotation.renbaonew.crawler.component.RenBaoNewCrawlerCacheComponent;
 import com.jzg.quotation.renbaonew.crawler.component.RenBaoNewCrawlerRequestComponent;
+import com.jzg.quotation.renbaonew.crawler.constant.InsuranceKindCodeMapping;
 import com.jzg.quotation.renbaonew.crawler.entity.RenBaoNewCrawlerConfigureParameters;
 import com.jzg.quotation.renbaonew.crawler.entity.bo.LoginInfoBO;
 import com.jzg.quotation.renbaonew.crawler.entity.response.*;
@@ -113,7 +114,7 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
         RenBaoNewCrawlerSaveResponse saveResponse = requestComponent.saveAsProposal(saveRequest, headers);
 
         // 4. 构建结果
-        QuoteResultsVo resultsVo = buildQuoteResultsVo(quoteVo, quoteRequest, saveResponse, headers, username);
+        QuoteResultsVo resultsVo = buildQuoteResultsVo(quoteVo, quoteRequest, quoteResponse, saveResponse, headers, username);
 
         // 5. 保存订单信息
         orderService.saveOrder(
@@ -726,6 +727,7 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
      * @return 报价结果VO
      */
     private QuoteResultsVo buildQuoteResultsVo(QuoteVo quoteVo, RenBaoNewCrawlerQuoteRequest quoteRequest,
+                                               RenBaoNewCrawlerQuoteResponse quoteResponse,
                                                RenBaoNewCrawlerSaveResponse saveResponse,
                                                HttpHeaders headers, String username) {
         QuoteResultsVo resultsVo = new QuoteResultsVo();
@@ -832,6 +834,26 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
             resultsVo.setCosts(costs);
         }
 
+        // 商业险种信息赋值:从报价响应的prpQitemKindVos中提取,人保kindCode转为平台编码
+        if (quoteResponse != null && quoteResponse.getData() != null
+                && quoteResponse.getData().getPrpQmain() != null
+                && quoteResponse.getData().getPrpQmain().getPrpQitemKindVos() != null) {
+            List<KindInfoVo> kindInfoVoList = new ArrayList<>();
+            for (RenBaoNewCrawlerQuoteResponse.PrpQitemKindVo item :
+                    quoteResponse.getData().getPrpQmain().getPrpQitemKindVos()) {
+                // 人保kindCode → 平台编码(如 051050 → A)
+                String platformKindCode = InsuranceKindCodeMapping.getPlatformKindCode(item.getKindCode());
+                for(KindInfoVo kindInfo :quoteVo.getKindInfoVo()){
+                    if(kindInfo.getKindCode().equals(platformKindCode)){
+                        kindInfo.setPremium(item.getPremium() != null ? String.valueOf(item.getPremium()) : null);
+                        kindInfo.setAmount(item.getAmount() != null ? String.valueOf(item.getAmount()) : null);
+                    }
+                }
+
+            }
+            resultsVo.setKindInfoVo(quoteVo.getKindInfoVo());
+        }
+
         // 获取评分
         if (!proposalNoDAA.isEmpty() || !proposalNoDZA.isEmpty()) {
             try {

+ 2 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/SummaryQuotationApplication.java

@@ -19,7 +19,8 @@ import org.springframework.scheduling.annotation.EnableAsync;
 @EnableConfigurationProperties(YcConfigurationProperties.class)
 @EnableMongoRepositories(
         basePackages = {
-                "com.jzg.quotation.**.repository"
+                "com.jzg.quotation.**.repository",
+                "com.jzg.quotation.**.crawler.repository"
         },
         repositoryBaseClass = SimpleMongoRepository.class // 强制同步模式
 )

+ 4 - 0
tenant/insurance/quotation-summary/src/main/resources/logback-spring.xml

@@ -6,6 +6,10 @@
         </encoder>
     </appender>
 
+    <!-- 屏蔽 MongoDB 驱动的 "Prematurely reached end of stream" 等连接池回收噪音日志 -->
+    <logger name="org.mongodb.driver" level="WARN"/>
+    <logger name="com.mongodb" level="WARN"/>
+
     <appender name="GRAYLOG" class="de.siegmar.logbackgelf.GelfTcpAppender">
         <graylogHost>192.168.5.250</graylogHost>
 <!--        <graylogHost>172.24.144.227</graylogHost>-->

+ 1 - 1
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/build/TkCrawlerQuoteResultsBuild.java

@@ -180,7 +180,7 @@ public class TkCrawlerQuoteResultsBuild {
         if (!StringUtils.hasText(renewalFlag)) {
             return null;
         }
-        if (renewalFlag.equals("0")) {
+        if ("0".equals(renewalFlag)) {
             return String.valueOf(RenewalEnum.Renewal.getCode());
         } else {
             return String.valueOf(RenewalEnum.Transfer.getCode());

+ 30 - 1
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/cache/RedisCacheUtil.java

@@ -5,10 +5,12 @@ import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.jzg.quotation.taikang.crawler.model.TKLoginSession;
 import com.jzg.quotation.taikang.crawler.model.api.PreciseInitResult;
+import com.jzg.quotation.taikang.crawler.model.entity.po.TKCrawlerOrder;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RBucket;
 import org.redisson.api.RedissonClient;
 import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
 
 import java.time.Duration;
 
@@ -18,6 +20,8 @@ public class RedisCacheUtil {
 
     private final RedissonClient redissonClient;
     private static final String SESSION = "SESSION";
+    public static String TAIKANG_ORDER_RESPONSE = "taikang:order:response:";
+    public static final long TAIKANG_ORDER_RESPONSE_TIME = 1L;
 
     public RedisCacheUtil(RedissonClient redissonClient) {
         this.redissonClient = redissonClient;
@@ -84,7 +88,7 @@ public class RedisCacheUtil {
     public void setCache(String cacheInfo, String key, String sign) {
         String response = JSONObject.toJSONString(cacheInfo);
         RBucket<String> bucket = redissonClient.getBucket(key + sign);
-        bucket.set(response, Duration.ofHours(3L));
+        bucket.set(response, Duration.ofDays(TAIKANG_ORDER_RESPONSE_TIME));
     }
 
     public String getCache(String key, String sign) {
@@ -92,5 +96,30 @@ public class RedisCacheUtil {
         return bucket1.get();
     }
 
+    /**
+     * 缓存订单信息
+     *
+     * @param orderNo   订单号
+     * @param order 报价请求信息
+     */
+    public void cacheOrderRequest(String orderNo, TKCrawlerOrder order) {
+        String responseStr = JSONObject.toJSONString(order);
+        redissonClient.getBucket(TAIKANG_ORDER_RESPONSE + orderNo).set(responseStr, Duration.ofDays(TAIKANG_ORDER_RESPONSE_TIME));
+    }
+
+    /**
+     * 获取订单报价信息
+     *
+     * @param orderNo 订单号
+     * @return 报价订单返回
+     */
+    public TKCrawlerOrder getOrderResponse(String orderNo) {
+        String o = (String) redissonClient.getBucket(TAIKANG_ORDER_RESPONSE + orderNo).get();
+        TKCrawlerOrder tiJinCrawlerOrder = JSON.parseObject(o, TKCrawlerOrder.class);
+        // if (ObjectUtils.isEmpty(tiJinCrawlerOrder)) {
+        //     throw new RuntimeException("订单信息不存在");
+        // }
+        return tiJinCrawlerOrder;
+    }
 
 }

+ 108 - 0
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/po/TKCrawlerOrder.java

@@ -0,0 +1,108 @@
+package com.jzg.quotation.taikang.crawler.model.entity.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.time.LocalDateTime;
+
+/**
+ * @description: 泰康财险爬虫订单实体
+ * @author:
+ * @date:
+ **/
+@Data
+@Document(collection = "taikang.crawler.order")
+@NoArgsConstructor
+@AllArgsConstructor
+public class TKCrawlerOrder {
+
+    /**
+     * MongoDB主键ID
+     */
+    @Id
+    private String id;
+
+    /**
+     * 系统内部订单号
+     */
+    private String ordersNo;
+
+    /**
+     * 泰康财险订单号(保司返回)
+     */
+    private String orderNo;
+
+    /**
+     * 业务唯一标识
+     */
+    private String busUniqueId;
+
+    /**
+     * 交强险投保单号
+     */
+    private String ciApplyNo;
+
+    /**
+     * 商业险投保单号
+     */
+    private String syApplyNo;
+
+    /**
+     * 非车投保单号
+     */
+    private String niApplyNumber;
+
+    /**
+     * 交强险保单号
+     */
+    private String ciPolicyNo;
+
+    /**
+     * 商业险保单号
+     */
+    private String biPolicyNo;
+
+    /**
+     * 非车险保单号
+     */
+    private String niPolicyNo;
+
+    /**
+     * 交强险保费
+     */
+    private String ciPremium;
+
+    /**
+     * 商业险保费
+     */
+    private String biPremium;
+
+    /**
+     * 总保费
+     */
+    private String totalPremium;
+
+    /**
+     * 报价是否成功
+     */
+    private Boolean quoteSuccess;
+
+    /**
+     * 错误信息
+     */
+    private String errorMsg;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+}

+ 21 - 0
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/repository/TKCrawlerOrderRepository.java

@@ -0,0 +1,21 @@
+package com.jzg.quotation.taikang.crawler.repository;
+
+import com.jzg.quotation.taikang.crawler.model.entity.po.TKCrawlerOrder;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+/**
+ * @description: 泰康财险爬虫订单仓库
+ * @author:
+ * @date:
+ **/
+public interface TKCrawlerOrderRepository extends MongoRepository<TKCrawlerOrder, String> {
+
+    /**
+     * 根据系统内部订单号查询紫金财险爬虫订单
+     *
+     * @param ordersNo
+     * @return TKCrawlerOrder
+     */
+    TKCrawlerOrder findByOrdersNo(String ordersNo);
+
+}

+ 33 - 0
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKCrawlerOrderService.java

@@ -0,0 +1,33 @@
+package com.jzg.quotation.taikang.crawler.service;
+
+import com.jzg.commons.entity.quote.vo.QuoteVo;
+import com.jzg.commons.entity.quote.vo.aggregated.UnderwritingResultsVo;
+import com.jzg.commons.entity.quote.vo.aggregated.UnderwritingVo;
+import com.jzg.quotation.taikang.crawler.model.entity.TKOrderData;
+import com.jzg.quotation.taikang.crawler.model.entity.po.TKCrawlerOrder;
+
+/**
+ * @description: 紫金财险爬虫订单服务
+ * @author:
+ * @date:
+ **/
+public interface TKCrawlerOrderService {
+
+    /**
+     * 保存紫金财险爬虫订单
+     *
+     * @param
+     * @param
+     * @param success
+     */
+    void save(UnderwritingVo underwritingVo, UnderwritingResultsVo underwritingResultsVo, String mainOrderId, boolean success);
+
+    /**
+     * 根据系统内部订单号查询紫金财险爬虫订单
+     *
+     * @param ordersNo
+     * @return TKCrawlerOrder
+     */
+    TKCrawlerOrder getByOrdersNo(String ordersNo);
+
+}

+ 16 - 20
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKHttpAPIService.java

@@ -204,9 +204,9 @@ public class TKHttpAPIService {
         param.setTplatLoginKey(tplatLoginKey);
 
         // 这3个参数不传也能正常得到数据,暂时不了解有什么影响
-        //param.setOrderManageFlag("null");
-        //param.setRequestId("");
-        //param.setCrossRenewalFlag("");
+        // param.setOrderManageFlag("null");
+        // param.setRequestId("");
+        // param.setCrossRenewalFlag("");
 
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.add("tkCarRequestToken", token);
@@ -267,7 +267,7 @@ public class TKHttpAPIService {
 
         CarTypeResult.Response response = client.request(HttpURL.carType, param, httpHeaders, CarTypeResult.Response.class);
 
-        //checkResponseUnknownField(response);
+        // checkResponseUnknownField(response);
 
         return response.getPassengerSeat();
     }
@@ -1149,9 +1149,9 @@ public class TKHttpAPIService {
     public String proposalDownload(String proposalNo) {
         ProposalDownloadParam param = new ProposalDownloadParam();
         param.setTplatformId(proposalNo);
-        //测试不传这两参数也可以
-        //param.setOrderId(null);
-        //param.setFromId(null);
+        // 测试不传这两参数也可以
+        // param.setOrderId(null);
+        // param.setFromId(null);
 
         StringResponse response = client.request(HttpURL.proposalDownload, param, null, StringResponse.class);
 
@@ -1169,7 +1169,7 @@ public class TKHttpAPIService {
     public String imageDownloadPolicy(String subPolicyNo) {
         ImageDownloadPolicyParam param = new ImageDownloadPolicyParam();
         param.setChannelCode("OffWeb");
-        //param.setInputData("2025-03-20 17:18:23");
+        // param.setInputData("2025-03-20 17:18:23");
         param.setSubPolicyNo(subPolicyNo);
 
         StringResponse response = client.request(HttpURL.imageDownloadPolicy, param, null, StringResponse.class);
@@ -1211,26 +1211,22 @@ public class TKHttpAPIService {
      * <p>
      * 不需要 token 也能查询
      *
-     * @param tplatformId
+     * @param session
      * @param proposalNo
      * @return
      */
-    public OrderCompleteAgentResult.OrderCompleteAgentResultEntity orderCompleteAgent(String token, String tplatformId, String proposalNo) {
+    public OrderCompleteAgentResult.OrderCompleteAgentResultEntity orderCompleteAgent(TKLoginSession session, String proposalNo) {
         OrderCompleteAgentParam param = new OrderCompleteAgentParam();
         param.setChannelCode("OffWeb");
         param.setFullProposalNo(proposalNo);
-        //param.setFromId("67107");
-        param.setTplatformId(tplatformId);
+        param.setFromId("67107");
+        param.setTplatformId(session.getTplatformId());
+        param.setTplatLoginKey(session.getTplatLoginKey());
         param.setPageNo(1);
-        param.setPageSizePerPage(1);
+        param.setPageSizePerPage(15);
 
-        HttpHeaders httpHeaders = null;
-
-        if (token != null) {
-            httpHeaders = new HttpHeaders();
-            // 没有 token 也能查询
-            httpHeaders.add("tkCarRequestToken", token);
-        }
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.add("tkcarrequesttoken", session.getToken());
 
         OrderCompleteAgentResult.Response response = client.request(HttpURL.orderCompleteAgent, param, httpHeaders, OrderCompleteAgentResult.Response.class);
 

+ 58 - 0
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKCrawlerOrderServiceImpl.java

@@ -0,0 +1,58 @@
+package com.jzg.quotation.taikang.crawler.service.impl;
+
+import com.jzg.commons.entity.quote.vo.aggregated.UnderwritingResultsVo;
+import com.jzg.commons.entity.quote.vo.aggregated.UnderwritingVo;
+import com.jzg.quotation.taikang.crawler.cache.RedisCacheUtil;
+import com.jzg.quotation.taikang.crawler.model.entity.po.TKCrawlerOrder;
+import com.jzg.quotation.taikang.crawler.repository.TKCrawlerOrderRepository;
+import com.jzg.quotation.taikang.crawler.service.TKCrawlerOrderService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+
+/**
+ * @description: 泰康财险爬虫订单服务实现
+ * @author:
+ * @date:
+ **/
+@Service
+@RequiredArgsConstructor
+public class TKCrawlerOrderServiceImpl implements TKCrawlerOrderService {
+
+    private final TKCrawlerOrderRepository tkCrawlerOrderRepository;
+    private final RedisCacheUtil redisCacheUtil;
+
+
+    /**
+     * 保存泰康财险爬虫订单
+     *
+     * @param underwritingVo
+     * @param underwritingResultsVo
+     * @param mainOrderId
+     * @param success
+     */
+    @Override
+    public void save(UnderwritingVo underwritingVo, UnderwritingResultsVo underwritingResultsVo, String mainOrderId, boolean success) {
+        TKCrawlerOrder order = new TKCrawlerOrder();
+        order.setOrdersNo(underwritingVo.getOrder().getOrdersNo());
+        order.setOrderNo(underwritingResultsVo.getCompanyOrderNo());
+        order.setBusUniqueId(mainOrderId);
+        order.setQuoteSuccess(success);
+        order.setErrorMsg(underwritingResultsVo.getUnderwritingResult());
+        order.setCiApplyNo(underwritingResultsVo.getJqApplyNo());
+        order.setCiPolicyNo(underwritingResultsVo.getJqPolicyno());
+        order.setSyApplyNo(underwritingResultsVo.getSyApplyNo());
+        order.setBiPolicyNo(underwritingResultsVo.getSyPolicyno());
+        order.setCreateTime(LocalDateTime.now());
+        order.setUpdateTime(LocalDateTime.now());
+        tkCrawlerOrderRepository.save(order);
+        // 缓存数据
+        redisCacheUtil.cacheOrderRequest(underwritingVo.getOrder().getOrdersNo(), order);
+    }
+
+    @Override
+    public TKCrawlerOrder getByOrdersNo(String ordersNo) {
+        return tkCrawlerOrderRepository.findByOrdersNo(ordersNo);
+    }
+}

+ 20 - 15
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKQuotationBaseServiceImpl.java

@@ -23,8 +23,10 @@ import com.jzg.quotation.taikang.crawler.model.entity.TKAreaInfoVo;
 import com.jzg.quotation.taikang.crawler.model.entity.TKCarAccident;
 import com.jzg.quotation.taikang.crawler.model.entity.TKInsureInfo;
 import com.jzg.quotation.taikang.crawler.model.entity.TKOrderData;
+import com.jzg.quotation.taikang.crawler.model.entity.po.TKCrawlerOrder;
 import com.jzg.quotation.taikang.crawler.repository.TKLoginSessionRepository;
 import com.jzg.quotation.taikang.crawler.repository.TKPreciseInitResultRepository;
+import com.jzg.quotation.taikang.crawler.service.TKCrawlerOrderService;
 import com.jzg.quotation.taikang.crawler.service.TKHttpAPIService;
 import com.jzg.quotation.taikang.crawler.service.TKQuotationBaseService;
 import com.jzg.quotation.taikang.crawler.service.TKSimpleService;
@@ -67,6 +69,10 @@ public class TKQuotationBaseServiceImpl implements TKQuotationBaseService {
     @Resource
     private RedisCacheUtil redisCacheUtil;
 
+    @Resource
+    private TKCrawlerOrderService tkCrawlerOrderService;
+
+
     private TKLoginSession loginSession(String username, String password) {
         // 缓存获取
         TKLoginSession session = redisCacheUtil.getSessionCache(username);
@@ -242,19 +248,15 @@ public class TKQuotationBaseServiceImpl implements TKQuotationBaseService {
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.PAY_PENDING);
             // 保司订单号
             underwritingResultsVo.setCompanyOrderNo(proposalNo);
-            // 支付连接
-//        underwritingResultsVo.setPaymentLink();
 
+            tkCrawlerOrderService.save(underwritingVo, underwritingResultsVo, preciseInitResult.getMainOrderId(), true);
         } else {
             underwritingResultsVo.setUnderwritingResult("核保失败");
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.AUDIT_FAIL);
+            tkCrawlerOrderService.save(underwritingVo, underwritingResultsVo, preciseInitResult.getMainOrderId(), false);
         }
 
-
         return underwritingResultsVo;
-
-        // 支付的二维码数据示例:https://car.tk.cn/ep/#/insureProcess/payUnion?orderID=WBPC202503121144127720000&proposalNo=00671071370142500000004363&turnFlag=0&isRetrans=1&userid=&fromId=67107&tkSignature=TKSIGNATURE&tplatformId=feda77e829d4dedbbd8b4e236bacfac5&isTPLATFlag=1&clientId=feda77e829d4dedbbd8b4e236bacfac5
-        // 包含的主要参数:orderID、proposalNo、fromId、tplatformId、clientId
     }
 
     @Override
@@ -275,8 +277,8 @@ public class TKQuotationBaseServiceImpl implements TKQuotationBaseService {
         CarCheckUploadFileParam param = new CarCheckUploadFileParam();
         // 泰康订单
         String orderID = redisCacheUtil.getCache(insuranceUploadImageVo.getOrder().getOrdersNo(), "DD");
-        // 泰康保单号
-        String proposalNo = redisCacheUtil.getCache(insuranceUploadImageVo.getOrder().getOrdersNo(), "HB");
+        // 泰康保单号, 现在获取不到,核保成功之后才会返回
+        // String proposalNo = redisCacheUtil.getCache(insuranceUploadImageVo.getOrder().getOrdersNo(), "HB");
 
         param.setChannelCode("OffWeb");
         param.setTplatformId(session.getTplatformId());
@@ -481,19 +483,21 @@ public class TKQuotationBaseServiceImpl implements TKQuotationBaseService {
     public DownloadPolicyResultVo downloadPolicy(DownloadPolicyVo orderBase) {
         AttributionInformationVo attributionInformationVo = orderBase.getOrder().getAttributionInformationVo();
         TKLoginSession session = loginSession(attributionInformationVo.getUsername(), attributionInformationVo.getPassword());
-        String token = session.getToken();
-        String tplatformId = session.getTplatformId();
         // 泰康保单号
-        String proposalNo = redisCacheUtil.getCache(orderBase.getOrder().getOrdersNo(), "HB");
+        TKCrawlerOrder tkCrawlerOrder = redisCacheUtil.getOrderResponse(orderBase.getOrder().getOrdersNo());
+        if (tkCrawlerOrder == null) {
+            tkCrawlerOrder = tkCrawlerOrderService.getByOrdersNo(orderBase.getOrder().getOrdersNo());
+        }
 
-        OrderCompleteAgentResult.OrderCompleteAgentResultEntity orderCompleteAgentResultEntity = httpService.orderCompleteAgent(token, tplatformId, proposalNo);
+        OrderCompleteAgentResult.OrderCompleteAgentResultEntity orderCompleteAgentResultEntity = httpService.orderCompleteAgent(session, tkCrawlerOrder.getOrderNo());
 
         if (orderCompleteAgentResultEntity == null) {
             return null;
         }
 
+        DownloadPolicyResultVo downloadPolicyResultVo = new DownloadPolicyResultVo();
         // 投保单,base64
-        String proposal = httpService.proposalDownload(proposalNo);
+        String proposal = httpService.proposalDownload(tkCrawlerOrder.getOrderNo());
 
         // 商业险子保单号BI
         String subPolicyNoBi = orderCompleteAgentResultEntity.getSubPolicyNoBi();
@@ -503,18 +507,19 @@ public class TKQuotationBaseServiceImpl implements TKQuotationBaseService {
             String policy = httpService.imageDownloadPolicy(subPolicyNoBi);
             // 获取发票下载地址 url
             String pdf = httpService.imageGetInvoiceURL(subPolicyNoBi, "PDF");
+            downloadPolicyResultVo.setSyUrl(pdf);
         }
 
         // 交强险子保单号CI
         String subPolicyNoCi = orderCompleteAgentResultEntity.getSubPolicyNoCi();
-
         if (subPolicyNoCi != null) {
             // 交强险子保单,base64格式
             String policy = httpService.imageDownloadPolicy(subPolicyNoCi);
             // 获取发票下载地址 url
             String pdf = httpService.imageGetInvoiceURL(subPolicyNoCi, "PDF");
+            downloadPolicyResultVo.setJqUrl(pdf);
         }
-        return null;
+        return downloadPolicyResultVo;
     }
 
     @Override

+ 2 - 2
tenant/insurance/quotation-taikang/src/test/java/com/jzg/quotation/taikang/crawler/TKHttpAPIServiceTest1.java

@@ -730,7 +730,7 @@ public class TKHttpAPIServiceTest1 {
         carInfo.setBrandName("奥迪FV7251FBCBG轿车");
         carInfo.setPurchasePrice("380000");
         carInfo.setExhaustScale("2498");
-        carInfo.setSeatFlag("1");
+        carInfo.setSeatFlag(1);
 
         TKCarModel TKCarModel = new TKCarModel();
         TKCarModel.setVehicleWeight(new BigDecimal("1800"));
@@ -1254,7 +1254,7 @@ public class TKHttpAPIServiceTest1 {
 
         long begin = System.currentTimeMillis();
 
-        OrderCompleteAgentResult.OrderCompleteAgentResultEntity orderCompleteAgentResult = httpService.orderCompleteAgent(null, tplatformId, no);
+        OrderCompleteAgentResult.OrderCompleteAgentResultEntity orderCompleteAgentResult = httpService.orderCompleteAgent(null, no);
 
         long end = System.currentTimeMillis();
 

+ 13 - 5
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java

@@ -14,6 +14,7 @@ import com.jzg.quotation.taishan.crawler.entity.response.TaiShanCrawlerQuotation
 import com.jzg.quotation.taishan.crawler.entity.response.TaiShanCrawlerRiskManagementResponse;
 import lombok.extern.slf4j.Slf4j;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -200,11 +201,18 @@ public class TaiShanCrawlerQuoteResultsVoBuild {
             // 设置车船税
             quoteResultsVo.getCosts().setVvTax(String.valueOf(saveResponse.getResult().getCompulsoryInsurance().getCarShipTax().getSumTax()));
         }
-        // 设置非车险(驾意险)保费
-//        QuotationResponse.DataDTO.UnAutoPremiumDTO unAutoPremium = quotationResponse.getData().getUnAutoPremium();
-//        if (saveResponse.getResult(). != null) {
-//            quoteResultsVo.getCosts().setNiPremium(unAutoPremium.getPremium());
-//        }
+        //设置非车险(驾意险)保费
+        if (Objects.nonNull(saveResponse.getResult().getDiInsurance())) {
+            quoteResultsVo.getCosts().setNiPremium(saveResponse.getResult().getDiInsurance().getPremium());
+        }
+        // 设置总费用
+        BigDecimal bi = StringUtils.hasText(quoteResultsVo.getCosts().getBiPremium()) ? new BigDecimal(quoteResultsVo.getCosts().getBiPremium()) : BigDecimal.ZERO;
+        BigDecimal ci = StringUtils.hasText(quoteResultsVo.getCosts().getCiPremium()) ? new BigDecimal(quoteResultsVo.getCosts().getCiPremium()) : BigDecimal.ZERO;
+        BigDecimal vv = StringUtils.hasText(quoteResultsVo.getCosts().getVvTax()) ? new BigDecimal(quoteResultsVo.getCosts().getVvTax()) : BigDecimal.ZERO;
+        BigDecimal ni = StringUtils.hasText(quoteResultsVo.getCosts().getNiPremium()) ? new BigDecimal(quoteResultsVo.getCosts().getNiPremium()) : BigDecimal.ZERO;
+
+        BigDecimal total = bi.add(ci).add(vv).add(ni);
+        quoteResultsVo.getCosts().setSumPremium(total.toPlainString());
     }
 
     private static String convertRenewalFlag(String renewalFlag) {

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

@@ -2,13 +2,17 @@ package com.jzg.quotation.zhongan.crawler.component;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jzg.commons.util.AssertionUtils;
 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.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
 import org.apache.hc.core5.net.URIBuilder;
 import org.apache.http.Header;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -26,6 +30,7 @@ import org.springframework.stereotype.Component;
 import java.net.URI;
 import java.time.Duration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -111,107 +116,119 @@ public class ZhongAnCrawlerCacheComponent {
         return JSON.parseObject(bucket1.get(), ZhongAnCrawlerPaymentResponse.ValueDTO.DatasDTO.InitInfoDTO.class);
     }
 
-    //登录
-    private static final CloseableHttpClient HTTP_CLIENT =HttpClients.custom().disableRedirectHandling().build(); // 关闭自动重定向
+    private static final OkHttpClient session = new OkHttpClient.Builder()
+            .followRedirects(false)
+            .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() : "";
-    }
+    private static final ObjectMapper objectMapper = new ObjectMapper();
     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", productId)
-                    .addParameter("isOpenByPC", "N")
-                    .addParameter("promotionScene", "16")
-                    .addParameter("bizContent", "")
-                    .addParameter("insurePlaceCode", "140100")
+            // ========== 第一步 POST 请求 ==========
+            Headers.Builder postHeaderBuilder = new Headers.Builder();
+            postHeaderBuilder.add("Accept-Language", "zh-CN,zh;q=0.9");
+            postHeaderBuilder.add("Connection", "keep-alive");
+            postHeaderBuilder.add("Content-Type", "application/json");
+            postHeaderBuilder.add("Host", "www.yuanqingtech.com");
+            postHeaderBuilder.add("Referer", "https://servicewechat.com/wx46d2e1aaa28335ea/47/page-frame.html");
+            postHeaderBuilder.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541a1f) XWEB/19921");
+            postHeaderBuilder.add("accessKey", "");
+            postHeaderBuilder.add("appCode", "");
+            postHeaderBuilder.add("channel", "");
+            postHeaderBuilder.add("openIdToken", "");
+            postHeaderBuilder.add("platform", "MINI_WECHAT");
+            postHeaderBuilder.add("t", "ios");
+            postHeaderBuilder.add("unionId", "");
+            postHeaderBuilder.add("wxSDKVersion", "3.16.1");
+            postHeaderBuilder.add("wxVersion", "4.1.10.31");
+            postHeaderBuilder.add("xweb_xhr", "1");
+            postHeaderBuilder.add("zaLoginCookieKey", "");
+
+            Headers postHeaders = postHeaderBuilder.build();
+
+            String urlPost = "https://www.yuanqingtech.com/dmapi/dm-innovation-front/api/config-info/findIssuingLink";
+
+            FirstReqData reqData = new FirstReqData();
+            reqData.setInviterAccountId(zhongAnId);
+            reqData.setActivityCode(productId);
+
+            String jsonBody = objectMapper.writeValueAsString(reqData);
+            RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
+            Request postReq = new Request.Builder()
+                    .url(urlPost)
+                    .headers(postHeaders)
+                    .post(body)
                     .build();
-            // 发送第一个请求,不跟随重定向
-            HttpGet get1 = buildGet(uri1);
-            CloseableHttpResponse resp1 = HTTP_CLIENT.execute(get1, context);
-            AssertionUtils.isEmpty(resp1, "第一次请求失败,请联系管理员");
-            String location1 = resp1.getFirstHeader("Location").getValue();
-            resp1.close();
-            // 发送第二个请求
-            HttpGet get2 = buildGet(new URI(location1));
-            CloseableHttpResponse resp2 = HTTP_CLIENT.execute(get2, context);
-            AssertionUtils.isEmpty(resp2, "第二次请求失败,请联系管理员");
-            String location2 = getLocationHeader(resp2);
-            resp2.close();
-            // 发送第三个请求
-            HttpGet get3 = buildGet(new URI(location2));
-            CloseableHttpResponse resp3 = HTTP_CLIENT.execute(get3, context);
-            AssertionUtils.isEmpty(resp3, "第三次请求失败,请联系管理员");
-            String location3 = resp3.getFirstHeader("Location").getValue();
-            resp3.close();
-            // 发送第四个请求
-            HttpGet get4 = buildGet(new URI(location3));
-            CloseableHttpResponse resp4 = HTTP_CLIENT.execute(get4, context);
-            AssertionUtils.isEmpty(resp4, "第四次请求失败,请联系管理员");
-            String location4 = resp4.getFirstHeader("Location").getValue();
-            resp4.close();
-            // 第五次请求,拿cookie
-            HttpGet get5 = buildGet(new URI(location4));
-            CloseableHttpResponse resp5 = HTTP_CLIENT.execute(get5, context);
-            AssertionUtils.isEmpty(resp5, "第五次请求失败,请联系管理员");
-            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()) {
+            Response postResp = session.newCall(postReq).execute();
+            String respBody = postResp.body().string();
+            postResp.close();
+
+            JsonNode root = objectMapper.readTree(respBody);
+            JsonNode valueNode = root.path("value");
+            if (!valueNode.isArray() || valueNode.size() == 0) {
                 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")
+            String linkUrl = valueNode.get(0).path("link").asText("");
+            Headers.Builder getHeaderBuilder = new Headers.Builder();
+            getHeaderBuilder.add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/wxpic,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
+            getHeaderBuilder.add("Accept-Encoding", "gzip, deflate, br");
+            getHeaderBuilder.add("Accept-Language", "zh-CN,zh;q=0.9");
+            getHeaderBuilder.add("Connection", "keep-alive");
+            getHeaderBuilder.add("Host", "c.zhongan.com");
+            getHeaderBuilder.add("Sec-Fetch-Dest", "document");
+            getHeaderBuilder.add("Sec-Fetch-Mode", "navigate");
+            getHeaderBuilder.add("Sec-Fetch-Site", "none");
+            getHeaderBuilder.add("Sec-Fetch-User", "?1");
+            getHeaderBuilder.add("Upgrade-Insecure-Requests", "1");
+            getHeaderBuilder.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541a1f) XWEB/19921 miniProgram/wx46d2e1aaa28335ea");
+
+            Headers getHeaders = getHeaderBuilder.build();
+            Request getReq = new Request.Builder()
+                    .url(linkUrl)
+                    .headers(getHeaders)
+                    .get()
                     .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);
+            Response getResp = session.newCall(getReq).execute();
+            String flowIdUrl = getResp.header("Location", "");
+            getResp.close();
+
+            Pattern flowPattern = Pattern.compile("flowId=(.*?)&");
+            Matcher flowMatcher = null;
+            if (flowIdUrl != null) {
+                flowMatcher = flowPattern.matcher(flowIdUrl);
+            }
+            String flowId = "";
+            if (flowMatcher.find()) {
+                flowId = flowMatcher.group(1);
+            }
+            String zaLoginCookieKey = "";
+            List<String> setCookieList = getResp.headers("Set-Cookie");
+            for (String cookie : setCookieList) {
+                Pattern cookiePattern = Pattern.compile("zaLoginCookieKey=(.*?);", Pattern.DOTALL);
+                Matcher cookieMatcher = cookiePattern.matcher(cookie);
+                if (cookieMatcher.find()) {
+                    zaLoginCookieKey = cookieMatcher.group(1);
+                }
+            }
+            cacheCookie(zaLoginCookieKey, flowId, zhongAnId);
+            return new LoginResult(200, "登录成功", zaLoginCookieKey, flowId);
         } catch (Exception e) {
             e.printStackTrace();
             return new LoginResult(400, "登录异常:" + e.getMessage(), null, null);
         }
     }
 
-
+    @Data
+    public static class FirstReqData {
+        private String bizOrigin = "CAR_ZYHS_XXSYTG";
+        private String inviterAccountId;
+        private String activityCode;
+        private BizParams bizParams = new BizParams();
+    }
+    @Data
+    public static class BizParams {
+        private final String insurePlaceCode = "140100";
+    }
 }

+ 5 - 137
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/impl/ZiJinCrawlerRequestImpl.java

@@ -836,20 +836,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         return baseInfo;
     }
 
-    /**
-     * 构建车主信息对象
-     *
-     * @return ZiJinCrawlerQuotationRequest.CarOwnerInfo
-     */
-//    private ZiJinCrawlerQuotationRequest.CarOwnerInfo buildCarOwnerInfo() {
-//        ZiJinCrawlerQuotationRequest.CarOwnerInfo carOwnerInfo = new ZiJinCrawlerQuotationRequest.CarOwnerInfo();
-//        carOwnerInfo.setCarOwner("王婧");//车主姓名
-//        carOwnerInfo.setOwnerIdentifyNumber("14092519990322002X");//车主证件号码
-//        carOwnerInfo.setOwnerIdentifyType("01");//车主证件类型(01-身份证)
-//        carOwnerInfo.setVehicleOwnerNature("1");//车主性质(1-个人)
-//        return carOwnerInfo;
-//    }
-
 
     /**
      * 构建车主信息对象
@@ -919,42 +905,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         }
     }
 
-//    /**
-//     * 构建被保险人列表
-//     *
-//     * @return List<ZiJinCrawlerQuotationRequest.InsuredList>
-//     */
-//    private List<ZiJinCrawlerQuotationRequest.InsuredList> buildInsuredList() {
-//        List<ZiJinCrawlerQuotationRequest.InsuredList> insuredList = new ArrayList<>();
-//
-//        // 第一个被保险人
-//        ZiJinCrawlerQuotationRequest.InsuredList insured1 = new ZiJinCrawlerQuotationRequest.InsuredList();
-//        insured1.setInsuredName("王婧");
-//        insured1.setInsuredNature("3");
-//        insured1.setIdentifyType("01");
-//        insured1.setIdentifyNumber("14092519990322002X");
-//        insured1.setSex("2");
-//        insured1.setInsuredType("1");
-//        insured1.setMobile("18840186946");
-//        insured1.setPostCode("030053");
-//        insured1.setInsuredFlag(2);
-//        insuredList.add(insured1);
-//
-//        // 第二个被保险人
-//        ZiJinCrawlerQuotationRequest.InsuredList insured2 = new ZiJinCrawlerQuotationRequest.InsuredList();
-//        insured2.setInsuredName("王婧");
-//        insured2.setInsuredNature("3");
-//        insured2.setIdentifyType("01");
-//        insured2.setIdentifyNumber("14092519990322002X");
-//        insured2.setSex("2");
-//        insured2.setInsuredType("1");
-//        insured2.setMobile("18840186946");
-//        insured2.setPostCode("030053");
-//        insured2.setInsuredFlag(1);
-//        insuredList.add(insured2);
-//        return insuredList;
-//    }
-
     /**
      * 构建被保险人列表
      *
@@ -1384,31 +1334,19 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
     private List<ZiJinCrawlerQuotationRequest.CarPolicySubInfoList> buildCarPolicySubInfoList(QuoteVo quoteVo) {
         List<ZiJinCrawlerQuotationRequest.CarPolicySubInfoList> carPolicySubInfoList = new ArrayList<>();
 
-        List<AccidentalDrivingVo> accidentalDrivings = quoteVo.getAccidentalDrivings();
-        if (CollectionUtils.isEmpty(accidentalDrivings)) {
+        if (CollectionUtils.isEmpty(quoteVo.getAccidentalDrivings())) {
             return carPolicySubInfoList;
         }
 
-        // for (AccidentalDrivingVo drivingInsurance : accidentalDrivings) {
-        //     String rideRiskCode = drivingInsurance.getRiskCode();
-        //     // 目前只支持 rideRiskCode == "0733"(紫金驾驶人意外伤害保险)
-        //     if (AccidentHealthInsuranceProductsEnum.ZIJIN_JIASHI_REN_ACCIDENT.getCode().equals(rideRiskCode)) {
-        //         carPolicySubInfoList.add(buildRideRisk0733(drivingInsurance));
-        //     }
-        //     // 其他风险代码暂未配置,Python中会抛出异常
-        //     // 这里暂时跳过,不抛出异常
-        // }
-
-        // 默认选中"0767"->"紫金驾乘人员人生意外保险"
         for (AccidentalDrivingVo accidentalDriving : quoteVo.getAccidentalDrivings()) {
             ZiJinCrawlerQuotationRequest.CarPolicySubInfoList carPolicySubInfo = new ZiJinCrawlerQuotationRequest.CarPolicySubInfoList();
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
             carPolicySubInfo.setInsureGradeNo("200000736004"); // 前端没传
-            carPolicySubInfo.setProductCode("0736");// 这个值前端传过来的是乱码200000736004%%0736%%%0
+            carPolicySubInfo.setProductCode(accidentalDriving.getProductCode());// 这个值前端传过来的是乱码200000736004%%0736%%%0
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
-            carPolicySubInfo.setRiskCode("0736"); // 完了要调整编码,是否要转换
-            carPolicySubInfo.setRiskName("全家安行保"); // 前端没传
-            carPolicySubInfo.setSumAmount(ObjectUtils.isEmpty(accidentalDriving.getSumAmount()) ? 2350000 : (int) Double.parseDouble(accidentalDriving.getSumAmount()));
+            carPolicySubInfo.setRiskCode(accidentalDriving.getRiskCode()); // 完了要调整编码,是否要转换
+            carPolicySubInfo.setRiskName(accidentalDriving.getProductName()); // 前端没传
+            carPolicySubInfo.setSumAmount(ObjectUtils.isEmpty(accidentalDriving.getSumAmount()) ? 0 : (int) Double.parseDouble(accidentalDriving.getSumAmount()));
             carPolicySubInfo.setQuantity(accidentalDriving.getQuantity() == 0 ? "0" : String.valueOf(accidentalDriving.getQuantity()));
             carPolicySubInfo.setIsUseInsured("1");
             carPolicySubInfo.setSumPremium(ObjectUtils.isEmpty(accidentalDriving.getPremium()) ? 0 : (int) Double.parseDouble(accidentalDriving.getPremium()));
@@ -1478,76 +1416,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
     }
 
 
-    /**
-     * 构建车辆信息对象
-     *
-     * @return ZiJinCrawlerQuotationRequest.VehicleInfo
-     */
-//    private ZiJinCrawlerQuotationRequest.VehicleInfo buildVehicleInfo() {
-//        ZiJinCrawlerQuotationRequest.VehicleInfo vehicleInfo = new ZiJinCrawlerQuotationRequest.VehicleInfo();
-//
-//        // 基础车辆信息
-//        vehicleInfo.setActualValue(73905.6);
-//        vehicleInfo.setAgreeActualValue(73905.6);
-//        vehicleInfo.setBrandName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setCarKindCode("A0");
-//        vehicleInfo.setCarKindDetailId("KA");
-//        vehicleInfo.setCarLoanFlag("1");
-//        vehicleInfo.setCertificateDate("2021-11-01");
-//        vehicleInfo.setChgOwnerFlag("1");
-//        vehicleInfo.setCompletekerbmass(1539);
-//        vehicleInfo.setEcdemicVehicleFlag("0");
-//        vehicleInfo.setEngineNo("DNSM9070392");
-//
-//        // 日期相关
-//        vehicleInfo.setEnrollDate("2021-11-01");
-//        vehicleInfo.setUpdateEnrollDate("2021-11-01");
-//        vehicleInfo.setIssueDate("2025-10-16");
-//        vehicleInfo.setMakeDate("2025-10-16");
-//        vehicleInfo.setMakeDateJQ("2025-10-16");
-//
-//        // 车辆技术参数
-//        vehicleInfo.setExhaustCapacity(1490);
-//        vehicleInfo.setFuelType("0");
-//        vehicleInfo.setFuelTypeJY("D1");
-//        vehicleInfo.setNewEnergyFlag("0");
-//        vehicleInfo.setPower("133");
-//        vehicleInfo.setModelEnergyType("D1");
-//
-//        // 牌照和车辆识别
-//        vehicleInfo.setLicenseColorCode("01");
-//        vehicleInfo.setLicenseKindCode("02");
-//        vehicleInfo.setLicenseNo("晋HJW581");
-//        vehicleInfo.setLoanVehicleFlag("0");
-//        vehicleInfo.setModelCode("RWD1598SQQ");
-//        vehicleInfo.setNoLicenseFlag("1");
-//        vehicleInfo.setVehicleId("1");
-//        vehicleInfo.setVinNo("LSJA24U69MS091895");
-//
-//        // 车辆分类和用途
-//        vehicleInfo.setSeatCount(5);
-//        vehicleInfo.setUseNatureCode("85");
-//        vehicleInfo.setOriCarKindName("K33");
-//        vehicleInfo.setPlatVehicleCode("CRWARJUC0001");
-//        vehicleInfo.setVehicleStyleUniqueId("800004584");
-//
-//        // 价格和商业信息
-//        vehicleInfo.setPurchasePrice("103800");
-//        vehicleInfo.setSale4SFlag("0");
-//        vehicleInfo.setOriPurchasePrice("103800");
-//        vehicleInfo.setIsInvokeJingYou("1");
-//
-//        // 型号名称
-//        vehicleInfo.setPrintVehicleModelName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setAliasName("荣威RX5 PLUS 330TGI 1.5T TST国潮智臻版");
-//        vehicleInfo.setOriBrandName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setOriModelName("荣威CSA6452NEAQ多用途乘用车");
-//        vehicleInfo.setPrintModelName("荣威CSA6452NEAQ多用途乘用车");
-//
-//        return vehicleInfo;
-//    }
-
-
     /**
      * 构建车辆信息对象
      *