Forráskód Böngészése

安盛保单下载,车型折扣费用计算逻辑修改

xuqiang 3 hónapja
szülő
commit
dce4c16633
17 módosított fájl, 441 hozzáadás és 37 törlés
  1. 39 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/component/AnShengCrawlerRequestComponent.java
  2. 11 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/constant/enums/RequestUrl.java
  3. 5 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/po/AnShengCrawlerOrder.java
  4. 1 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/AnShengCrawlerCalculatePremiumApplyMessage.java
  5. 19 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/BdTokenResp.java
  6. 27 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/DownloadTokenResult.java
  7. 14 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/DragSliderResp.java
  8. 24 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/response/FileDownloadResp.java
  9. 4 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/AnShengCrawlerLoginService.java
  10. 1 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/AnShengCrawlerOrderService.java
  11. 3 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/AnShengCrawlerQuoteProcessService.java
  12. 112 6
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerLoginServiceImpl.java
  13. 2 1
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerOrderServiceImpl.java
  14. 8 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerQuoteProcessServiceImpl.java
  15. 74 23
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerRequestImpl.java
  16. 83 3
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/utils/CustomerNegotiatePriceUtils.java
  17. 14 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java

+ 39 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/component/AnShengCrawlerRequestComponent.java

@@ -334,6 +334,17 @@ public class AnShengCrawlerRequestComponent {
         return "";
     }
 
+
+    public InsuranceResponse newGsOrder(MultiValueMap<String, String> urlParams,String token) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("loginToken",token);
+        headers.add("User-Agent","Mozilla/5.0 (Linux; Android 5.1.1; VOG-AL00 Build/LMY48Z; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.100 Mobile Safari/537.36");
+
+        ResponseEntity<InsuranceResponse> response = requestComponent.post(requestComponent.buildUrl(RequestUrl.NEW_ORDER.getRequestUrl(anShengCrawlerProperties.getUrl()),urlParams),null, InsuranceResponse.class, headers);
+        return response.getBody();
+    }
+
+
     public PureRiskPremiumQueryResponse pureRiskPremiumQuery(InsuranceContractRequest insuranceContractRequest, HttpHeaders httpHeaders) {
         return post(RequestUrl.PURERISK_PREMIUM_QUERY, insuranceContractRequest, PureRiskPremiumQueryResponse.class, httpHeaders);
 
@@ -343,4 +354,32 @@ public class AnShengCrawlerRequestComponent {
         ResponseEntity<AnShengCrawlerSearchVehicleByVinResponse> responseEntity = requestComponent.formData(RequestUrl.SEARCHVEHICLE_BY_NAME.getRequestUrl(anShengCrawlerProperties.getUrl()), jsonObject, AnShengCrawlerSearchVehicleByVinResponse.class, headers);
         return responseEntity.getBody().getData();
     }
+
+    public String pdfUrl(JSONObject jsonData,String token) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("loginToken",token);
+        headers.add("User-Agent","Mozilla/5.0 (Linux; Android 5.1.1; VOG-AL00 Build/LMY48Z; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.100 Mobile Safari/537.36");
+        MultiValueMap<String, String> urlParams = new LinkedMultiValueMap<>();
+        urlParams.add("method", "query");
+        ResponseEntity<FileDownloadResp> response = requestComponent.post(requestComponent.buildUrl(RequestUrl.PDF_URL.getRequestUrl(anShengCrawlerProperties.getUrl()),urlParams),jsonData, FileDownloadResp.class, headers);
+        return response.getBody().getData();
+    }
+
+
+    public LoginResp downloadToken(MultiValueMap<String, String> formData,MultiValueMap<String, String> urlParams,HttpHeaders headers){
+        ResponseEntity<LoginResp> form = requestComponent.form(requestComponent.buildUrl(RequestUrl.NEW_GS_LOGIN.getRequestUrl(anShengCrawlerProperties.getUrl()), urlParams), formData, LoginResp.class, headers);
+        return form.getBody();
+    }
+
+
+    public BdTokenResp bdResp(MultiValueMap<String, String> formData,MultiValueMap<String, String> urlParams,HttpHeaders headers){
+        ResponseEntity<BdTokenResp> form = requestComponent.form(requestComponent.buildUrl(RequestUrl.NEW_GS_LOGIN.getRequestUrl(anShengCrawlerProperties.getUrl()), urlParams), formData, BdTokenResp.class, headers);
+        return form.getBody();
+    }
+
+    public DragSliderResp huaKuai(MultiValueMap<String, String> formData,HttpHeaders headers) {
+        DragSliderResp dragSliderResp = requestComponent.get(RequestUrl.NEW_GS_LOGIN.getRequestUrl(anShengCrawlerProperties.getUrl()), formData, "获取滑块验证码", DragSliderResp.class, headers);
+        log.info("滑块码:{}",JSONObject.toJSONString(dragSliderResp));
+        return dragSliderResp;
+    }
 }

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

@@ -40,7 +40,17 @@ public enum RequestUrl implements CrawlerRequestUrlStandard {
     QUERY_PRINT_PDF("/printportalapi/printportal/queryPrintpdf.do", "保单下载"),
     DOWNLOAD_PDF("/printportalapi/printportal/downloadPdf.do?policyNo=%s&policyType=6&channel=print&systemName=tpaic-ec&userName=tpaic-ec", "非车保单下载"),
     //   风险与保费查询
-    PURERISK_PREMIUM_QUERY("/portalapi/pureRiskPremiumQuery", "风险与保费查询")
+    PURERISK_PREMIUM_QUERY("/portalapi/pureRiskPremiumQuery", "风险与保费查询"),
+
+
+    //   获取PDF地址
+    PDF_URL("/astmobile/pdf.do", "获取PDF地址"),
+
+    //   获取订单
+    NEW_ORDER("/astmobile/newgsOrder.do", "获取订单"),
+
+    //   新归属登录
+    NEW_GS_LOGIN("/astmobile/newgsLogin.do", "归属登录")
 
 
     ;

+ 5 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/po/AnShengCrawlerOrder.java

@@ -23,6 +23,11 @@ public class AnShengCrawlerOrder {
     @Id
     private String id;
 
+    /**
+     * 车牌号
+     */
+    private String licenseNo;
+
     /**
      * 保险公司订单号
      */

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

@@ -40,7 +40,7 @@ public class AnShengCrawlerCalculatePremiumApplyMessage {
         String customerNegotiatePrice = CustomerNegotiatePriceUtils.calculateTheDepreciationValue(departmentPlanCode.getCode(), quoteVo.getCarInfoVo()
                         .getEnergyTypeCode(),
                 dataDTO.getCustomerNegotiatePrice(), riskInfoVo.getStartDate(), quoteVo.getCarInfoVo()
-                        .getRegisterDate());
+                        .getRegisterDate(),quoteVo.getCarInfoVo());
         String energyTypeCode = quoteVo.getCarInfoVo().getEnergyTypeCode();
         this.isTryCal = false;
         this.contracts = new ArrayList<>();

+ 19 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/BdTokenResp.java

@@ -0,0 +1,19 @@
+package com.jzg.quotation.ansheng.crawler.entity.request;
+
+
+import lombok.Data;
+
+/**
+ * 根据agentCode获取bdToken响应
+ */
+@Data
+public class BdTokenResp {
+    private String msg;
+    private Integer code;
+    private BdTokenData data;
+
+    @Data
+    public static class BdTokenData {
+        private String token;
+    }
+}

+ 27 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/DownloadTokenResult.java

@@ -0,0 +1,27 @@
+package com.jzg.quotation.ansheng.crawler.entity.request;
+
+
+import lombok.Data;
+
+/**
+ * 登录最终返回结果
+ */
+@Data
+public class DownloadTokenResult {
+    /**
+     * 状态码 200成功 400失败
+     */
+    private Integer code;
+    /**
+     * 提示信息
+     */
+    private String message;
+    /**
+     * 登录token
+     */
+    private String token;
+    /**
+     * 业务bdToken
+     */
+    private String bdToken;
+}

+ 14 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/DragSliderResp.java

@@ -0,0 +1,14 @@
+package com.jzg.quotation.ansheng.crawler.entity.request;
+
+
+import lombok.Data;
+
+/**
+ * 获取滑块验证码响应
+ */
+@Data
+public class DragSliderResp {
+    private String data;
+    private String msg;
+    private Integer code;
+}

+ 24 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/response/FileDownloadResp.java

@@ -0,0 +1,24 @@
+package com.jzg.quotation.ansheng.crawler.entity.response;
+
+
+import lombok.Data;
+
+@Data
+public class FileDownloadResp {
+
+    /**
+     * 响应码
+     */
+    private String code;
+
+    /**
+     * 响应信息
+     */
+    private String msg;
+
+    /**
+     * 文件下载地址
+     */
+    private String data;
+
+}

+ 4 - 1
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/AnShengCrawlerLoginService.java

@@ -1,6 +1,6 @@
 package com.jzg.quotation.ansheng.crawler.service;
 
-import org.springframework.http.HttpHeaders;
+import com.jzg.quotation.ansheng.crawler.entity.request.DownloadTokenResult;
 
 public interface AnShengCrawlerLoginService {
 
@@ -12,4 +12,7 @@ public interface AnShengCrawlerLoginService {
      */
     String login(String userName, String password);
 
+
+    DownloadTokenResult getObtainDownloadToken(String username, String password);
+
 }

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

@@ -16,7 +16,7 @@ public interface AnShengCrawlerOrderService {
      * 保存订单号
      * @param id 订单号
      */
-    void saveRecordingTime(String id);
+    void saveRecordingTime(String id,String licenseNo);
 
     /**
      * 保存订单

+ 3 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/AnShengCrawlerQuoteProcessService.java

@@ -1,6 +1,7 @@
 package com.jzg.quotation.ansheng.crawler.service;
 
 import com.jzg.commons.entity.quote.vo.AttributionInformationVo;
+import com.jzg.quotation.ansheng.crawler.entity.request.DownloadTokenResult;
 import com.jzg.quotation.ansheng.crawler.entity.response.AnShengCrawlerGetUserDetailResponse;
 import org.springframework.http.HttpHeaders;
 
@@ -24,4 +25,6 @@ public interface AnShengCrawlerQuoteProcessService {
     AnShengCrawlerGetUserDetailResponse.DataDTO.AgentDefineDTO getUserDetailResponse(String agreementId, HttpHeaders headers);
 
 
+    DownloadTokenResult obtainDownloadToken(AttributionInformationVo attributionInformationVo);
+
 }

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

@@ -5,20 +5,18 @@ import com.jzg.commons.entity.quote.vo.identify.SliderCaptchaVo;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.quotation.ansheng.crawler.component.AnShengCrawlerCacheComponent;
 import com.jzg.quotation.ansheng.crawler.component.AnShengCrawlerRequestComponent;
-import com.jzg.quotation.ansheng.crawler.entity.request.AnShengCrawlerCheckLoginRequest;
-import com.jzg.quotation.ansheng.crawler.entity.request.AnShengCrawlerCheckVerificationRequest;
-import com.jzg.quotation.ansheng.crawler.entity.request.AnShengCrawlerVerifyRequest;
+import com.jzg.quotation.ansheng.crawler.entity.request.*;
 import com.jzg.quotation.ansheng.crawler.entity.response.AnShengCrawlerVerifyResponse;
 import com.jzg.quotation.ansheng.crawler.service.AnShengCrawlerLoginService;
 import com.jzg.quotation.commons.service.ExteriorUtilsRequest;
-import com.jzg.quotation.commons.utils.CookieParseUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpHeaders;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
 
 import java.util.List;
-import java.util.Map;
 
 @Service
 @RequiredArgsConstructor
@@ -67,4 +65,112 @@ public class AnShengCrawlerLoginServiceImpl implements AnShengCrawlerLoginServic
         throw new SystemException("登录失败,请重新登录");
     }
 
+    @Override
+    public DownloadTokenResult getObtainDownloadToken(String username, String password) {
+        // 构建请求头
+        HttpHeaders headers = buildCommonHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+
+        // URL参数
+        MultiValueMap<String, String> urlParams = new LinkedMultiValueMap<>();
+        urlParams.add("method", "login");
+
+        // 表单参数
+        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+        formData.add("account", username);
+        formData.add("password", password);
+        formData.add("phone", "");
+        formData.add("agentCode", "");
+        formData.add("verificationCode", "");
+        formData.add("authenticationType", "1");
+        // 拼接滑块码
+        String dragCode = getHuaKuai();
+        formData.add("dragSliderCode", dragCode != null ? dragCode : "");
+        // 发起POST表单请求,使用项目已有的form请求方法
+        LoginResp loginResp = anShengCrawlerRequestComponent.downloadToken( formData, urlParams,headers);
+        if (loginResp == null) {
+            DownloadTokenResult result = new DownloadTokenResult();
+            result.setCode(400);
+            result.setMessage("登录响应为空");
+            return result;
+        }
+
+        // 判断登录是否成功
+        if ("成功".equals(loginResp.getMsg())) {
+            String token = loginResp.getToken();
+            String agentCode = loginResp.getData() != null ? loginResp.getData().getAgentCode() : "";
+
+            // 3. 二次请求:根据agentCode获取bdToken
+            HttpHeaders secondHeaders = new HttpHeaders();
+            secondHeaders.add("loginToken", token);
+            secondHeaders.add("User-Agent", buildUserAgent());
+
+            MultiValueMap<String, String> secondUrlParams = new LinkedMultiValueMap<>();
+            secondUrlParams.add("method", "getUserByAgentCode");
+
+            MultiValueMap<String, String> secondForm = new LinkedMultiValueMap<>();
+            secondForm.add("agentCode", agentCode);
+            secondForm.add("agentPersonCode", "");
+            String bdToken = "";
+            BdTokenResp bdResp = anShengCrawlerRequestComponent.bdResp(secondForm, secondUrlParams, headers);
+            if (bdResp != null && bdResp.getData() != null) {
+                bdToken = bdResp.getData().getToken();
+            }
+
+            // 组装成功返回
+            DownloadTokenResult success = new DownloadTokenResult();
+            success.setCode(200);
+            success.setMessage(loginResp.getMsg());
+            success.setToken(token);
+            success.setBdToken(bdToken);
+            return success;
+        } else {
+            // 登录失败
+            DownloadTokenResult fail = new DownloadTokenResult();
+            fail.setCode(400);
+            fail.setMessage(loginResp.getMsg());
+            return fail;
+        }
+    }
+
+
+
+    /**
+     * 1. GET 请求 获取滑块验证码 dragSliderCode
+     */
+    public String getHuaKuai() {
+        HttpHeaders headers = buildCommonHeaders();
+        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+        params.add("method", "getDragSliderCode");
+        DragSliderResp dragSliderResp = anShengCrawlerRequestComponent.huaKuai(params, headers);
+        return dragSliderResp.getData();
+    }
+
+
+    /**
+     * 构建公共请求头(复刻Python headers)
+     */
+    private HttpHeaders buildCommonHeaders() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Host", "apps.axa.cn");
+        headers.add("Pragma", "no-cache");
+        headers.add("Cache-Control", "no-cache");
+        headers.add("Accept", "application/json, text/plain, */*");
+        headers.add("Origin", "https://apps.axa.cn");
+        headers.add("loginToken", "");
+        headers.add("User-Agent", buildUserAgent());
+        headers.add("Referer", "https://apps.axa.cn/astmobilefront/index.html");
+        headers.add("Accept-Language", "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7");
+        headers.add("X-Requested-With", "com.axa.ast");
+        return headers;
+    }
+
+    private String buildUserAgent() {
+        return "Mozilla/5.0 (Linux; Android 9; MI 8 Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/72.0.3626.121 Mobile Safari/537.36";
+    }
+
+
+
+
+
 }

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

@@ -20,9 +20,10 @@ public class  AnShengCrawlerOrderServiceImpl implements AnShengCrawlerOrderServi
     }
 
     @Override
-    public void saveRecordingTime(String id){
+    public void saveRecordingTime(String id,String licenseNo){
         AnShengCrawlerOrder anShengCrawlerOrder = new AnShengCrawlerOrder();
         anShengCrawlerOrder.setId(id);
+        anShengCrawlerOrder.setLicenseNo(licenseNo);
         anShengCrawlerOrder.setRecordingTime(TimeProcessing.nowDateTime());
         anShengCrawlerOrderRepository.save(anShengCrawlerOrder);
     }

+ 8 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerQuoteProcessServiceImpl.java

@@ -5,6 +5,7 @@ import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.ansheng.crawler.component.AnShengCrawlerCacheComponent;
 import com.jzg.quotation.ansheng.crawler.component.AnShengCrawlerRequestComponent;
+import com.jzg.quotation.ansheng.crawler.entity.request.DownloadTokenResult;
 import com.jzg.quotation.ansheng.crawler.entity.response.AnShengCrawlerGetUserDetailResponse;
 import com.jzg.quotation.ansheng.crawler.service.AnShengCrawlerLoginService;
 import com.jzg.quotation.ansheng.crawler.service.AnShengCrawlerQuoteProcessService;
@@ -55,4 +56,11 @@ public class AnShengCrawlerQuoteProcessServiceImpl implements AnShengCrawlerQuot
         }, AnShengCrawlerGetUserDetailResponse.DataDTO.AgentDefineDTO.class, Duration.ofHours(AnShengCrawlerCacheComponent.AGENT_DEFINE_TIME));
     }
 
+    @Override
+    public DownloadTokenResult obtainDownloadToken(AttributionInformationVo attributionInformationVo) {
+        String username = attributionInformationVo.getUsername();
+        String password = attributionInformationVo.getPassword();
+        return anShengCrawlerLoginService.getObtainDownloadToken(username, password);
+    }
+
 }

+ 74 - 23
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerRequestImpl.java

@@ -33,7 +33,12 @@ import com.jzg.quotation.commons.utils.TimeProcessing;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpHeaders;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
 
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.time.Year;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -136,7 +141,6 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
         // 报价
         AnShengCrawlerCalculatePremiumApplyMessage crawlerCalculatePremiumApply = new AnShengCrawlerCalculatePremiumApplyMessage(quoteVo, dataDTO, userDetailResponse, departmentPlanCode, checkVehicleCodeSecretGenerate);
         log.info("安盛报价参数:{}", JSONObject.toJSONString(crawlerCalculatePremiumApply));
-
         InsuranceContractRequest insuranceContractRequest = new  InsuranceContractRequest(crawlerCalculatePremiumApply);
         PureRiskPremiumQueryResponse premiumQueryResponse = anShengCrawlerRequestComponent.pureRiskPremiumQuery(insuranceContractRequest, httpHeaders);
         PureRiskPremiumQueryResponse.TargetsBean targetsBean = premiumQueryResponse.getData().getContracts().get(0).getTargets().get(0);
@@ -176,7 +180,7 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
             // 缓存数据
             anShengCrawlerCacheComponent.cacheQuoteRequest(ordersNo, autoSpecialPromiseRequest);
         }
-        anShengCrawlerOrderService.saveRecordingTime(ordersNo);
+        anShengCrawlerOrderService.saveRecordingTime(ordersNo,quoteVo.getCarInfoVo().getLicenseNo());
         // 构造返回参数
         return AnShengCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(ordersNo, quoteVo, calculatePremiumApply);
     }
@@ -382,33 +386,80 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
     @Override
     public DownloadPolicyResultVo downloadPolicy(DownloadPolicyVo downloadPolicyVo) {
         DownloadPolicyResultVo downloadPolicyResultVo = new DownloadPolicyResultVo();
-
-        HttpHeaders httpHeaders = anShengCrawlerQuoteProcessService.getHttpHeaders(downloadPolicyVo.getOrder().getAttributionInformationVo());
         AnShengCrawlerOrder anShengCrawlerOrder = anShengCrawlerOrderService.getById(downloadPolicyVo.getOrder().getOrdersNo());
+        DownloadTokenResult obtainDownloadToken = anShengCrawlerQuoteProcessService.obtainDownloadToken(downloadPolicyVo.getOrder().getAttributionInformationVo());
+        // 缓存token,避免重复调用
+        String loginToken = obtainDownloadToken.getToken();
+        String bdToken = obtainDownloadToken.getBdToken();
+
+        MultiValueMap<String, String> urlParams = new LinkedMultiValueMap<>();
+        urlParams.add("method", "queryAll");
+        urlParams.add("loginToken", loginToken);
+        urlParams.add("orderStatus", "2");
+        //车牌
+        urlParams.add("searchValue", URLEncoder.encode(anShengCrawlerOrder.getLicenseNo(), StandardCharsets.UTF_8));
+        InsuranceResponse insuranceResponse = anShengCrawlerRequestComponent.newGsOrder(urlParams, loginToken);
+        if (!StringUtils.equals("成功", insuranceResponse.getMsg()) || CollectionUtil.isEmpty(insuranceResponse.getData())) {
+            throw new SystemException("暂无找到该车保单信息");
+        }
+        String currentYear = String.valueOf(Year.now().getValue());
+        for (InsuranceResponse.InsurancePolicy policy : insuranceResponse.getData()) {
+            if (policy == null) {
+                continue;
+            }
+            String applyDate = policy.getApplyDate();
 
-        // 交强保单和标志
-        Optional.ofNullable(anShengCrawlerOrder.getCiPolicyNo()).ifPresent(policyNo -> {
-            AnShengCrawlerQueryPrintPdfRequest queryPrintPdfCi = new AnShengCrawlerQueryPrintPdfRequest(policyNo, "6");
-            downloadPolicyResultVo.setJqUrl(anShengCrawlerRequestComponent.queryPrintPdf(queryPrintPdfCi, httpHeaders));
-
-            AnShengCrawlerQueryPrintPdfRequest queryPrintPdfCiBz = new AnShengCrawlerQueryPrintPdfRequest(policyNo, "2");
-            downloadPolicyResultVo.setJqFlagUrl(anShengCrawlerRequestComponent.queryPrintPdf(queryPrintPdfCiBz, httpHeaders));
-        });
-        // 商业保单和标志
-        Optional.ofNullable(anShengCrawlerOrder.getBiPolicyNo()).ifPresent(policyNo -> {
-            AnShengCrawlerQueryPrintPdfRequest queryPrintPdfCi = new AnShengCrawlerQueryPrintPdfRequest(policyNo, "6");
-            downloadPolicyResultVo.setSyUrl(anShengCrawlerRequestComponent.queryPrintPdf(queryPrintPdfCi, httpHeaders));
-        });
+            String productName = policy.getProductName();
+            String policyNo = policy.getPolicyNo();
+            String signExt = policy.getSignExt();
 
-        // 非车保单和标志
-        anShengCrawlerOrder.getNiInfos().forEach(niInfo -> {
-            Optional.ofNullable(niInfo.getNiPolicyNumber()).ifPresent(policyNo -> {
-                anShengCrawlerRequestComponent.downloadPdf(policyNo, httpHeaders);
-            });
-        });
+            String applyYear = "";
+            if (applyDate != null && applyDate.length() >= 4) {
+                applyYear = applyDate.substring(0, 4);
+            }
+            // 机动车辆交强险
+            if ("机动车辆交强险".equals(productName)) {
+                JSONObject mainJson = buildPdfJson(policyNo, "2", signExt, bdToken);
+                downloadPolicyResultVo.setJqUrl(anShengCrawlerRequestComponent.pdfUrl(mainJson, loginToken));
+                JSONObject flagJson = buildPdfJson(policyNo, "4", signExt, bdToken);
+                downloadPolicyResultVo.setJqFlagUrl(anShengCrawlerRequestComponent.pdfUrl(flagJson, loginToken));
+            }
+            // 机动车辆综合险保险
+            if ("机动车辆综合险保险".equals(productName)) {
+                JSONObject syJson = buildPdfJson(policyNo, "2", signExt, bdToken);
+                downloadPolicyResultVo.setSyUrl(anShengCrawlerRequestComponent.pdfUrl(syJson, loginToken));
+            }
+            // 其他险种且为当年投保
+            if (!"机动车辆综合险保险".equals(productName) && !"机动车辆交强险".equals(productName) && currentYear.equals(applyYear)) {
+                JSONObject otherJson = buildPdfJson(policyNo, "5", signExt, bdToken);
+                downloadPolicyResultVo.setJyUrl(anShengCrawlerRequestComponent.pdfUrl(otherJson, loginToken));
+            }
+        }
         return downloadPolicyResultVo;
     }
 
+
+    /**
+     * 通用构建PDF请求JSON
+     */
+    private JSONObject buildPdfJson(String policyNo, String printType, String signExt, String bdToken) {
+        return JSONObject.of(
+                "head", JSONObject.of(
+                        "requestType", "V113",
+                        "account", "",
+                        "password", "",
+                        "token", bdToken
+                ),
+                "requestInfo", JSONObject.of(
+                        "basePart", JSONObject.of(
+                                "policyNo", policyNo,
+                                "printType", printType,
+                                "sign", signExt
+                        )
+                )
+        );
+    }
+
     @Override
     public OrderStatusResultVo queryOrderState(OrderStatusVo orderStatusVo) {
         // 获取订单信息

+ 83 - 3
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/utils/CustomerNegotiatePriceUtils.java

@@ -1,6 +1,8 @@
 package com.jzg.quotation.ansheng.crawler.utils;
 
+import com.jzg.commons.entity.quote.vo.CarInfoVo;
 import com.jzg.commons.exception.SystemException;
+import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.ansheng.crawler.constant.enums.DepartmentPlanCode;
 import com.jzg.quotation.commons.utils.TimeProcessing;
 
@@ -20,11 +22,89 @@ public final class CustomerNegotiatePriceUtils {
                                                        String energyType,
                                                        String carPrice,
                                                        String warrantyTime,
-                                                       String registerDateTime) {
-        BigDecimal bigDecimal = calculateType(planCode, energyType, carPrice);
-        return calculateTheDepreciationValue(new BigDecimal(carPrice), TimeProcessing.dateTimeToDate(warrantyTime), registerDateTime, bigDecimal);
+                                                       String registerDateTime,
+                                                       CarInfoVo carInfoVo) {
+        BigDecimal bigDeqcimal = calculateType(planCode, energyType, carPrice);
+        BigDecimal v = calcMonthDepreciationNew(carInfoVo, Double.valueOf(carPrice), planCode);
+
+        return calculateTheDepreciationValue(new BigDecimal(carPrice), TimeProcessing.dateTimeToDate(warrantyTime), registerDateTime,v);
+    }
+
+    public static BigDecimal calcMonthDepreciationNew(CarInfoVo carInfoVo,Double newCarPrice,String planCode) {
+        String completeKerbMass = carInfoVo.getCompleteKerbMass();
+        String curbWeightStr  = String.valueOf((completeKerbMass == null || completeKerbMass.isEmpty()) ?  BigDecimal.ZERO : new BigDecimal(completeKerbMass).divide(new BigDecimal("1000")));
+        double t = 0.0;
+        String codeItemsName = carInfoVo.getCarKindCode();
+        String nature = carInfoVo.getCarNatureCode();
+        String seatStr = carInfoVo.getSeatCount();
+        if ("1".equals(nature)) {
+            // 非营业车辆
+            if ("1".equals(codeItemsName)) {
+                // 客车
+                double seatComs = 0;
+                if (seatStr != null && !seatStr.isEmpty()) {
+                    seatComs = Double.parseDouble(seatStr);
+                }
+                if (seatComs <= 9) {
+                    if ("113".equals(planCode)) {
+                        if ("0".equals(StringUtils.equals("109",planCode))) {
+                            // 新能源
+                            if (newCarPrice <= 100000) {
+                                t = 0.82;
+                            } else if (newCarPrice <= 200000) {
+                                t = 0.77;
+                            } else if (newCarPrice <= 300000) {
+                                t = 0.72;
+                            } else {
+                                t = 0.68;
+                            }
+                        } else {
+                            // 非新能源
+                            t = 0.63;
+                        }
+                    } else {
+                        t = 0.6;
+                    }
+                } else {
+                    // 座位>9
+                    t = 0.9;
+                }
+            } else if ("2".equals(codeItemsName)) {
+                t = 0.9;
+            } else if ("54".equals(codeItemsName)) {
+                t = 0.9;
+            } else if ("21".equals(codeItemsName)) {
+                t = 1.1;
+            }
+
+            // t为0默认0.9
+            if (t == 0) {
+                t = 0.9;
+            }
+        } else {
+            // 营业车辆 nature=2
+            if ("21".equals(codeItemsName)) {
+                t = 1.4;
+            } else if ("10".equals(codeItemsName)) {
+                t = 1.1;
+            } else if ("54".equals(codeItemsName)) {
+                t = 1.1;
+            } else if ("2".equals(codeItemsName)) {
+                if (curbWeightStr != null && !curbWeightStr.isEmpty()) {
+                    double curbWeight = Double.parseDouble(curbWeightStr);
+                    if (curbWeight <= 1.8) {
+                        t = 1.1;
+                    }
+                }
+            }
+            if (t == 0) {
+                t = 0.9;
+            }
+        }
+        return new BigDecimal(t).divide(new BigDecimal("100"));
     }
 
+
     private static BigDecimal calculateType(String planCode, String energyType, String carPrice) {
         BigDecimal type = BigDecimal.ZERO;
 

+ 14 - 0
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java

@@ -8,6 +8,7 @@ import com.jzg.quotation.commons.config.WebClientConfig;
 import com.jzg.quotation.commons.entity.CookiesRequest;
 import com.jzg.quotation.commons.utils.InsuranceLog;
 import com.jzg.quotation.commons.utils.RequestObjectConversion;
+import io.netty.handler.timeout.ReadTimeoutException;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.core.ParameterizedTypeReference;
@@ -33,6 +34,9 @@ import java.nio.file.Paths;
 import java.nio.file.StandardOpenOption;
 import java.util.Map;
 import java.util.Optional;
+import java.time.Duration;
+import java.util.Map;
+import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.regex.Pattern;
 
@@ -396,6 +400,16 @@ public class RequestComponent {
                     .body(BodyInserters.fromValue(body))
                     .retrieve()
                     .toEntity(String.class)
+                    .timeout(Duration.ofSeconds(60))
+                    .onErrorMap(ReadTimeoutException.class, ex ->
+                            new WebClientResponseException(
+                                    504,
+                                    "第三方接口读取超时:" + url,
+                                    HttpHeaders.EMPTY,
+                                    null,
+                                    null
+                            )
+                    )
                     .block();
             if (rawResponse == null) {
                 throw new WebClientResponseException(