Explorar el Código

Merge remote-tracking branch 'origin/master'

Qchen hace 3 meses
padre
commit
dbd1609b5e
Se han modificado 41 ficheros con 824 adiciones y 429 borrados
  1. 1 1
      commons/src/main/java/com/jzg/commons/entity/quote/vo/KindInfoVo.java
  2. 45 2
      platform/src/main/java/com/jzg/controller/FileUploadController.java
  3. 23 2
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/component/HuaNongCrawlerRequestComponent.java
  4. 7 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/constant/enums/JiaYiXianProduct.java
  5. 35 1
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerDocumentsPrintRequestRequest.java
  6. 4 3
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerFindBusinessesRequestRequest.java
  7. 1 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerFtpDownloadRequestRequest.java
  8. 4 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/response/HuaNongCrawlerFindBusinessesResponse.java
  9. 35 8
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/service/impl/HuaNongCrawlerRequestImpl.java
  10. 2 2
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/component/HtCrawlerRequestComponent.java
  11. 14 7
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/Request/HtCrawlerQuoteRequest.java
  12. 1 1
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/Request/HtCrawlerSaveOneStepRequest.java
  13. 66 78
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/service/Impl/HuaTaiCrawlerRequestImpl.java
  14. 8 7
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/util/CookieUtils.java
  15. 173 34
      tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/service/impl/RenBaoNewCrawlerRequestImpl.java
  16. 50 13
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java
  17. 1 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLogAspect.java
  18. 17 10
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/AuditVerificationAspect.java
  19. 2 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java
  20. 4 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  21. 3 3
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  22. 1 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/build/TkCrawlerQuoteResultsBuild.java
  23. 1 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/api/PreciseInitResult.java
  24. 4 4
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKCiKindsVo.java
  25. 2 2
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKCommonPlanInfo.java
  26. 4 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKFlag.java
  27. 2 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKOther.java
  28. 2 3
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKHttpAPIService.java
  29. 131 133
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKSimpleService.java
  30. 13 1
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java
  31. 71 30
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/build/ZiJinCrawlerQuoteResultsVoBuild.java
  32. 6 3
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/build/ZiJinCrawlerSaveQuoteInfoRequestBuild.java
  33. 2 1
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/component/ZiJinCrawlerRequestComponent.java
  34. 1 1
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/entity/ZiJinCrawlerConfigureParameters.java
  35. 9 0
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/entity/request/ZiJinCrawlerSaveQuoteInfoRequest.java
  36. 3 1
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/ZiJinCrawlerOrderService.java
  37. 4 5
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/impl/ZiJinCrawlerOrderServiceImpl.java
  38. 26 28
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/impl/ZiJinCrawlerRequestImpl.java
  39. 2 1
      tenant/organization/src/main/java/com/jzg/organization/mapper/ReceivableMapper.java
  40. 20 21
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  41. 24 19
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

+ 1 - 1
commons/src/main/java/com/jzg/commons/entity/quote/vo/KindInfoVo.java

@@ -95,7 +95,7 @@ public class KindInfoVo implements Serializable {
 
     private List<OptionsDTO> options;
 
-    public KindInfoVo(String number, String number1, String number2, String number3, String number4, String number5, String number6, String number7, String number8, String number9,String number10) {
+    public KindInfoVo(String number, String number1, String number2, String number3, String number4, String number5, String number6, Integer number7, String number8, String number9,String number10) {
     }
 
     public KindInfoVo(String number, String number1, String number2, String number3, String number4, String number5, String number6, String number7, String number8, String number9) {

+ 45 - 2
platform/src/main/java/com/jzg/controller/FileUploadController.java

@@ -20,9 +20,11 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.net.URLConnection;
-import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
 
 /**
@@ -75,7 +77,9 @@ public class FileUploadController extends BaseController {
     public HttpResult<SysUploadFiles> uploadUrlFile(String urlString, String fileName) {
         SysUploadFiles sysUploadFiles = new SysUploadFiles();
         try {
-            URL url = new URL(URLDecoder.decode(urlString));
+            // Spring MVC 会自动 URL 解码,需重新编码含中文的 URL
+            String safeUrl = encodeUrlQuery(urlString);
+            URL url = new URL(safeUrl);
             URLConnection connection = url.openConnection();
             // 获取文件大小
             long contentLength = connection.getContentLengthLong();
@@ -101,6 +105,45 @@ public class FileUploadController extends BaseController {
     }
 
 
+    /**
+     * 对 URL 中的 query 参数进行编码(Spring @RequestParam 会自动解码,需在此重新编码中文等非ASCII字符)
+     */
+    private String encodeUrlQuery(String urlStr) {
+        try {
+            URL url = new URL(urlStr);
+            String query = url.getQuery();
+            if (query == null || query.isEmpty()) {
+                return urlStr;
+            }
+            // 逐个参数编码
+            StringBuilder encodedQuery = new StringBuilder();
+            String[] params = query.split("&");
+            for (int i = 0; i < params.length; i++) {
+                if (i > 0) {
+                    encodedQuery.append("&");
+                }
+                int eqIdx = params[i].indexOf('=');
+                if (eqIdx > 0) {
+                    String key = params[i].substring(0, eqIdx);
+                    String value = params[i].substring(eqIdx + 1);
+                    encodedQuery.append(URLEncoder.encode(key, StandardCharsets.UTF_8))
+                            .append("=")
+                            .append(URLEncoder.encode(value, StandardCharsets.UTF_8));
+                } else {
+                    encodedQuery.append(params[i]);
+                }
+            }
+            // 用 URI 重建 URL,确保路径和 query 都正确编码
+            int port = url.getPort();
+            String authority = port == -1 ? url.getHost() : url.getHost() + ":" + port;
+            URI uri = new URI(url.getProtocol(), authority, url.getPath(),
+                    encodedQuery.toString(), url.getRef());
+            return uri.toASCIIString();
+        } catch (Exception e) {
+            return urlStr; // 兜底返回原值
+        }
+    }
+
     private String getFileExtension(String fileName) {
         return fileName.substring(fileName.lastIndexOf("."));
     }

+ 23 - 2
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/component/HuaNongCrawlerRequestComponent.java

@@ -25,9 +25,13 @@ import org.springframework.web.reactive.function.BodyInserters;
 
 import java.io.IOException;
 import java.net.URI;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import static com.jzg.quotation.huanong.crawler.constant.enums.RequestUrl.*;
 
@@ -401,7 +405,14 @@ public class HuaNongCrawlerRequestComponent {
      */
     public String ftpDownload(HuaNongCrawlerFtpDownloadRequestRequest request, HttpHeaders headers) {
         HuaNongCrawlerFtpDownloadResponse response = post(FTP_DOWNLOAD, request, HuaNongCrawlerFtpDownloadResponse.class, headers);
-        return response.getDowloadURL().get(0).getDowloadURL();
+        String fileUrl = response.getDowloadURL().get(0).getDowloadURL();
+        // URL编码 on= 参数值(中文文件名需编码,否则后续下载时报400)
+        Matcher matcher = Pattern.compile("on=(.*?)\\.pdf").matcher(fileUrl);
+        if (matcher.find()) {
+            String matched = matcher.group(1);
+            fileUrl = fileUrl.replace(matched, URLEncoder.encode(matched, StandardCharsets.UTF_8));
+        }
+        return fileUrl;
     }
 
     /**
@@ -414,7 +425,17 @@ public class HuaNongCrawlerRequestComponent {
     public String documentsPrint(HuaNongCrawlerDocumentsPrintRequestRequest request, HttpHeaders headers) {
         HuaNongCrawlerDocumentsPrintResponse response = post(DOCUMENTS_PRINT, request, HuaNongCrawlerDocumentsPrintResponse.class, headers);
         String fileUrl = response.getFileUrl();
-        return fileUrl.replace(properties.getDocumentsPrintUrl(), properties.getFtpDownloadUrl());
+        return fileUrl;
+    }
+
+    /**
+     * CI交强险 DocumentsPrint 前置调用(与Python一致,下载交强保单前需先调用)
+     *
+     * @param request 交强险DocumentsPrint请求
+     * @param headers 请求头
+     */
+    public void documentsPrintForCi(HuaNongCrawlerDocumentsPrintRequestRequest request, HttpHeaders headers) {
+        post(DOCUMENTS_PRINT, request, HuaNongCrawlerDocumentsPrintResponse.class, headers);
     }
 
     /**

+ 7 - 0
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/constant/enums/JiaYiXianProduct.java

@@ -44,6 +44,13 @@ public enum JiaYiXianProduct {
             new CoverageConfig("F27047-5", "附加辅助金保险条款", "0094", "家庭辅助金", 0.02, "10", "20000", "2.0万元/座", true),
             new CoverageConfig("F27048-6", "附加救护车车费保险条款", "0095", "救护车费用", 0.1, "10", "2000", "0.2万元/座", true)
     )),
+    ANXIANG_50("091", "好运连连(50)", true, Arrays.asList(
+            new CoverageConfig("Z27096-1", "交通出行团体意外伤害保险C款条款", "0955", "必选责任:意外伤害身故保险责任", 0.06, "30000", "3.0万元/座", " ", false),
+            new CoverageConfig("Z27096-2", "交通出行团体意外伤害保险C款条款", "0956", "可选责任:意外伤害伤残保险责任", 0.04, "30000", "3.0万元/座", " ", false),
+            new CoverageConfig("F27002", "附加团体意外伤害医疗保险条款", "0008", "意外伤害医疗保险责任", 0.24, "1000", "0.1万元/座", "每次事故免赔300后80%比例赔付", false),
+            new CoverageConfig("F27001", "附加团体意外伤害住院津贴保险条款", "0032", "意外伤害住院津贴保险责任", 0.2, "10", "0.001万元/座", "10元/天/座", true)
+
+    )),
     ANXIANG_240("092", "好运连连(240)", true, Arrays.asList(
             new CoverageConfig("Z27096-1", "交通出行团体意外伤害保险C款条款", "0955", "必选责任:意外伤害身故保险责任", 0.06, "30000", "3.0万元/座", " ", false),
             new CoverageConfig("Z27096-2", "交通出行团体意外伤害保险C款条款", "0956", "可选责任:意外伤害伤残保险责任", 0.04, "30000", "3.0万元/座", " ", false),

+ 35 - 1
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerDocumentsPrintRequestRequest.java

@@ -79,7 +79,7 @@ public class HuaNongCrawlerDocumentsPrintRequestRequest implements HuaNongHeadRe
         this.printType = "";
         this.returnFlag = "0";
         this.startNo = "";
-        this.visaCode = "";
+        this.visaCode = "BB05550A2019E";
         this.endNo = "";
         this.accountInfo = "";
         this.currency = "RMB";
@@ -91,8 +91,42 @@ public class HuaNongCrawlerDocumentsPrintRequestRequest implements HuaNongHeadRe
         this.ip = "";
         this.visaType = "";
         this.isPreview = "0";
+        this.useNature = "8A";
         this.isMotoDownload = "0";
         this.isImg = 0;
     }
 
+    /**
+     * CI交强险 DocumentsPrint 前置调用构造(与Python hn_bddownload.py get_orderNo 一致)
+     *
+     * @param token         登录token
+     * @param contractNo    交强险保单号
+     * @param username      用户名
+     * @param loginComCode  登录机构代码
+     * @param businessType  业务类型(交强险传 "3")
+     * @param visaCode      签证代码(交强险传 "AB05016A32015A")
+     */
+    public HuaNongCrawlerDocumentsPrintRequestRequest(String token, String contractNo, String username, String loginComCode, String businessType, String visaCode) {
+        this.head = new HuaNongCrawlerRequestBaseHead(token);
+        this.policyType = "1";
+        this.printNoBegin = "";
+        this.printNoEnd = "";
+        this.businessType = businessType;
+        this.contractNo = List.of(contractNo);
+        this.printType = "";
+        this.returnFlag = "0";
+        this.startNo = "";
+        this.visaCode = visaCode;
+        this.endNo = "";
+        this.accountInfo = "";
+        this.currency = "RMB";
+        this.producerCode = "";
+        this.comCode = loginComCode;
+        this.userCode = username;
+        this.loginCom = loginComCode;
+        this.electronicPolicy = false;
+        this.ip = "";
+        this.isPreview = "0";
+    }
+
 }

+ 4 - 3
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerFindBusinessesRequestRequest.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.io.Serial;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -134,11 +135,11 @@ public class HuaNongCrawlerFindBusinessesRequestRequest implements HuaNongHeadRe
          * 投保单 2
          * 保单 4
          */
-        this.businessType = "2";
+        this.businessType = "4";
         this.policyNo = "";
         this.endorseNo = "";
         this.insuredName = "";
-        this.queryStatus = List.of("0");
+        this.queryStatus = new ArrayList<>();
         this.agreementNo = "";
         this.handlerCode = "";
         this.agentName = "";
@@ -161,7 +162,7 @@ public class HuaNongCrawlerFindBusinessesRequestRequest implements HuaNongHeadRe
                 "0515", "0507", "0520", "0521", "0522", "0523", "0509", "0506", "0510",
                 "0511", "0512", "0513", "2801", "0311", "0301", "1727", "1703", "0109",
                 "2742", "0306", "4001", "2780", "2781", "2784", "2782", "2783", "1980",
-                "1981", "2609", "2785", "2680"
+                "1981", "2609", "2785", "2680","0911"
         );
         this.hasSubFlag = true;
         this.endorType = "";

+ 1 - 0
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerFtpDownloadRequestRequest.java

@@ -60,6 +60,7 @@ public class HuaNongCrawlerFtpDownloadRequestRequest implements HuaNongHeadReque
 
         public FtpDowloadListDTO() {
             this.isMotoDownload = "0";
+            this.useNature = "8A";
             this.isVPN = "0";
             this.isBZDown = "0";
             this.isRelate = "0";

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

@@ -53,8 +53,12 @@ public class HuaNongCrawlerFindBusinessesResponse implements HuaNongHeadResponse
         private String comCode;
         @JsonProperty("contractNo1")
         private String contractNo1;
+        @JsonProperty("contractNo2")
+        private String contractNo2;
         @JsonProperty("contractNo3")
         private String contractNo3;
+        @JsonProperty("contractNo4")
+        private String contractNo4;
         @JsonProperty("contractNo5")
         private String contractNo5;
         @JsonProperty("contractNo6")

+ 35 - 8
tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/service/impl/HuaNongCrawlerRequestImpl.java

@@ -880,37 +880,64 @@ public class HuaNongCrawlerRequestImpl implements HuaNongCrawlerRequest {
         HuaNongCrawlerFtpDownloadRequestRequest huaNongCrawlerFtpDownloadRequest = new HuaNongCrawlerFtpDownloadRequestRequest(loginInfoDto.getToken());
         HuaNongCrawlerFtpDownloadRequestRequest.FtpDowloadListDTO ftpDowloadListDTO = new HuaNongCrawlerFtpDownloadRequestRequest.FtpDowloadListDTO();
         huaNongCrawlerFtpDownloadRequest.setFtpDowloadList(List.of(ftpDowloadListDTO));
+
+        // 投保单号获取保单号
+        String policyNo = StringUtils.hasText(order.getBiPolicyNumber()) ? order.getBiPolicyNumber() : order.getCiPolicyNumber();
+        HuaNongCrawlerFindBusinessesRequestRequest huaNongCrawlerFindBusinessesRequest
+                = new HuaNongCrawlerFindBusinessesRequestRequest(loginInfoDto.getToken(), loginInfoDto.getLoginComCode(), policyNo, order.getRecordingTime());
+        HuaNongCrawlerFindBusinessesResponse businesses = huaNongCrawlerRequestComponent.findBusinesses(huaNongCrawlerFindBusinessesRequest, httpHeaders);
+        // 与Python hn_state.py一致:遍历business按riskCode匹配contractNo字段
+        String ciNo = businesses.getBusiness().get(0).getContractNo6();
+        String biNo = businesses.getBusiness().get(0).getContractNo1();
+
         // 交强保单 标志
-        Optional.ofNullable(order.getCiPolicyNo())
+        Optional.ofNullable(order.getCiPolicyNumber())
                 .filter(s -> !s.isEmpty())
                 .ifPresent(ciPolicyNo -> {
+
+                    // DocumentsPrint 前置调用
+                    HuaNongCrawlerDocumentsPrintRequestRequest ciDocumentsPrintRequest =
+                            new HuaNongCrawlerDocumentsPrintRequestRequest(loginInfoDto.getToken(), ciNo, attributionInformationVo.getUsername(), loginInfoDto.getLoginComCode(), "3", "AB05016A32015A");
+                    huaNongCrawlerRequestComponent.documentsPrintForCi(ciDocumentsPrintRequest, httpHeaders);
+
                     // 交强保单
-                    ftpDowloadListDTO.setBiztype("4");
-                    ftpDowloadListDTO.setBusinessNo(ciPolicyNo);
+                    ftpDowloadListDTO.setBiztype("3");
+                    ftpDowloadListDTO.setBusinessNo(ciNo);
                     ftpDowloadListDTO.setRiskCode(Risk.RISK_0507.getRiskCode());
                     String ciPolicyUrl = huaNongCrawlerRequestComponent.ftpDownload(huaNongCrawlerFtpDownloadRequest, httpHeaders);
                     downloadPolicyResultVo.setJqUrl(ciPolicyUrl);
+                    // 交强险标志
                     ftpDowloadListDTO.setIsBZDown("1");
-                    // 商业标志
                     String ciSignUrl = huaNongCrawlerRequestComponent.ftpDownload(huaNongCrawlerFtpDownloadRequest, httpHeaders);
                     downloadPolicyResultVo.setJqFlagUrl(ciSignUrl);
 
                 });
         // 商业保单
-        Optional.ofNullable(order.getBiPolicyNo())
+        Optional.ofNullable(order.getBiPolicyNumber())
                 .filter(s -> !s.isEmpty())
                 .ifPresent(biPolicyNo -> {
                     // 商业保单
                     ftpDowloadListDTO.setIsBZDown("0");
-                    ftpDowloadListDTO.setBusinessNo(biPolicyNo);
+                    ftpDowloadListDTO.setBiztype("3");
+                    ftpDowloadListDTO.setBusinessNo(biNo);
+                    ftpDowloadListDTO.setRiskCode(Risk.RISK_0515.getRiskCode());
                     String biPolicyUrl = huaNongCrawlerRequestComponent.ftpDownload(huaNongCrawlerFtpDownloadRequest, httpHeaders);
                     downloadPolicyResultVo.setSyUrl(biPolicyUrl);
                 });
 
         // 非车险
         order.getNiInfos().forEach(niInfo -> {
-            Optional.ofNullable(niInfo.getNiPolicyNo()).ifPresent(niPolicyNo -> {
-                HuaNongCrawlerDocumentsPrintRequestRequest huaNongCrawlerDocumentsPrintRequest = new HuaNongCrawlerDocumentsPrintRequestRequest(loginInfoDto.getToken(), niPolicyNo, attributionInformationVo.getUsername(), loginInfoDto.getLoginComCode());
+            Optional.ofNullable(niInfo.getNiPolicyNumber()).ifPresent(niPolicyNo -> {
+                HuaNongCrawlerFindBusinessesRequestRequest niFindBusinessesRequest
+                        = new HuaNongCrawlerFindBusinessesRequestRequest(loginInfoDto.getToken(), loginInfoDto.getLoginComCode(), niPolicyNo, order.getRecordingTime());
+                HuaNongCrawlerFindBusinessesResponse niBusinesses = huaNongCrawlerRequestComponent.findBusinesses(niFindBusinessesRequest, httpHeaders);
+                // 与Python hn_state.py一致:NI(非0507/0510/0515)使用contractNo4
+                String niContractNo = Optional.ofNullable(niBusinesses.getBusiness())
+                        .filter(list -> !list.isEmpty())
+                        .map(list -> list.get(0).getContractNo4())
+                        .orElse(niPolicyNo);
+
+                HuaNongCrawlerDocumentsPrintRequestRequest huaNongCrawlerDocumentsPrintRequest = new HuaNongCrawlerDocumentsPrintRequestRequest(loginInfoDto.getToken(), niContractNo, attributionInformationVo.getUsername(), loginInfoDto.getLoginComCode());
                 String niPolicyUrl = huaNongCrawlerRequestComponent.documentsPrint(huaNongCrawlerDocumentsPrintRequest, httpHeaders);
                 downloadPolicyResultVo.setJyUrl(niPolicyUrl);
             });

+ 2 - 2
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/component/HtCrawlerRequestComponent.java

@@ -152,7 +152,7 @@ public class HtCrawlerRequestComponent {
      * @param headers
      * @return
      */
-    public HtCrawlerCarQueryResponse.DataDTO carQuery(HtCrawlerCarQueryRequest htCrawlerCarQueryRequest, HttpHeaders headers, CarInfoVo carInfoVo) throws Exception {
+    public HtCrawlerCarQueryResponse.DataDTO carQuery(HtCrawlerCarQueryRequest htCrawlerCarQueryRequest, HttpHeaders headers, CarInfoVo carInfoVo) {
         List<String> cookie = headers.get("Cookie");
         log.info("huatai_cookie:{}", cookie);
         ResponseEntity<HtCrawlerCarQueryResponse> carQueryResponseEntity = requestComponent.objectPostWithProxy(RequestUrl.CAR_QUERY.getRequestUrl(huaTaiCrawlerProperties.getBaseUrl()), htCrawlerCarQueryRequest, HtCrawlerCarQueryResponse.class, headers, proxyHostName, proxyPort);
@@ -182,7 +182,7 @@ public class HtCrawlerRequestComponent {
      * @return
      * @throws Exception
      */
-    public String quote(HtCrawlerQuoteRequest htCrawlerQuoteRequest, HttpHeaders headers) throws Exception {
+    public String quote(HtCrawlerQuoteRequest htCrawlerQuoteRequest, HttpHeaders headers) {
         headers.remove("Referer");
         headers.add("Referer", "https://cspxp.pc.ehuatai.com/htcsp/VehicleInfoEntryAction.do?cmd=saveOneStept");
         ResponseEntity<HtCrawlerQuoteResponse> responseEntity = requestComponent.objectPostWithProxy(RequestUrl.QUOTE_PRICE.getRequestUrl(huaTaiCrawlerProperties.getBaseUrl()), htCrawlerQuoteRequest, HtCrawlerQuoteResponse.class, headers, proxyHostName, proxyPort);

+ 14 - 7
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/Request/HtCrawlerQuoteRequest.java

@@ -84,7 +84,7 @@ public class HtCrawlerQuoteRequest implements Serializable {
             } else {
                 this.isInsureBusi = false;
             }
-            this.afloatValue = "";
+            this.afloatValue = "0.0";
             this.hastax = this.isInsureTraffic;
             this.mealid = StringUtils.isBlank(mealid) ? "" : mealid;
             List<CovListDTO> covListDTOS = getCovListDTOS(quoteVo, limitAmount);
@@ -177,8 +177,10 @@ public class HtCrawlerQuoteRequest implements Serializable {
             this.displacement = "";
             this.recommendList = null;
             this.pilingRecommendNo = "";
-            this.specialcarflag = quoteVo.getCarInfoVo().isTransfer() ? "1" : "";
-            this.transferdate = quoteVo.getCarInfoVo().getTransferDate() == null ? "" : quoteVo.getCarInfoVo().getTransferDate().toString();
+            //this.specialcarflag = quoteVo.getCarInfoVo().isTransfer() ? "1" : "";
+            //this.transferdate = quoteVo.getCarInfoVo().getTransferDate() == null ? "" : quoteVo.getCarInfoVo().getTransferDate().toString();
+            this.specialcarflag = "";
+            this.transferdate = "";
             this.riskcode = this.coveragecode;
             this.chgownerRisk = "";
             this.quoIsLastPlanRecommendNo = "";
@@ -219,14 +221,20 @@ public class HtCrawlerQuoteRequest implements Serializable {
                     covListDTO.setCoveragecode("1251");
                     covListDTO.setComcoveragecode(kindInfoVo.getKindCode());
                     covListDTO.setComcoveragename(kindInfoVo.getKindName());
-                    // 机动车损失保险
+                    // A机动车损失保险 B机动车第三者责任保险 D11机动车车上人员责任险(司机) D12机动车车上人员责任险(乘客)
                     if(kindInfoVo.getKindCode().equals("A")) {
                         covListDTO.setLimitamount(limitAmount);
                         covListDTO.setInsteadwalkdailylimitamount(limitAmount);
-                    } else {
+                    } else if (kindInfoVo.getKindCode().equals("SR")){
+                        covListDTO.setLimitamount("");
+                    }else {
                         covListDTO.setLimitamount(kindInfoVo.getAmount());
                         covListDTO.setInsteadwalkdailylimitamount(kindInfoVo.getAmount());
                     }
+                    if(!kindInfoVo.getKindCode().equals("A") && !kindInfoVo.getKindCode().equals("B") &&
+                            !kindInfoVo.getKindCode().equals("D11") && !kindInfoVo.getKindCode().equals("D12")) {
+                        covListDTO.setQuantity("");
+                    }
                     // PB附加医保外医疗费用责任险(三者) PD11附加医保外医疗费用责任险(司机)
                     // PD12附加医保外医疗费用责任险(乘客)SR附加机动车道路救援服务特约条款
                     if(kindInfoVo.getKindCode().equals("PB") || kindInfoVo.getKindCode().equals("PD11") ||
@@ -239,8 +247,7 @@ public class HtCrawlerQuoteRequest implements Serializable {
                     covListDTO.setEnddate(ciRiskInfoVo.getEndDate());
                     covListDTO.setIsdedu("1");
                     covListDTO.setKindpremiun("");
-                    covListDTO.setQuantity(kindInfoVo.getQuantity());
-                    covListDTO.setServiceTimes("");
+                    covListDTO.setServiceTimes(kindInfoVo.getKindCode().equals("SR") ? kindInfoVo.getServiceTimes() : "");
                     covListDTO.setServiceCode("");
                     covListDTO.setBilldate(ciRiskInfoVo.getStartDate());
 

+ 1 - 1
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/Request/HtCrawlerSaveOneStepRequest.java

@@ -430,7 +430,7 @@ public class HtCrawlerSaveOneStepRequest implements Serializable {
         this.isYD = "";
         this.comcodeByUserVo = this.fullComCode;
         this.newLicenseno = "engineSix";
-
+        //归属区分
         this.isTeamCarFlag = "";
         this.teamcarmodelcode = "";
         this.teamcarmodelname = "";

+ 66 - 78
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/service/Impl/HuaTaiCrawlerRequestImpl.java

@@ -107,6 +107,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     private static final Pattern PAT_MEAL_ID = Pattern.compile("\"mealid\":\"(.*?)\"");
     private static final Pattern LIMIT_AMOUNT = Pattern.compile("value=\"(.*?)\" id=\"js_actualvalue\"");
     private static final Pattern PAT_END_DATE = Pattern.compile("终保日期\\s*([^;]+)");
+    private static final Pattern RESPONSE_ERR = Pattern.compile("(\"infoName\"\\s*:\\s*\"([^\"]*)\",\\s*\"infomsg\"\\s*:\\s*\"([^\"]*)\"|\"erroeInfo\"\\s*:\\s*\"([^\"]*)\")",Pattern.DOTALL);
 
     private static final Set<String> SPECIAL_USERS = Set.of(
             "EA27000180", "EA27000401", "EA27000098", "EA27000076",
@@ -167,22 +168,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         return req.authenticate(dto, HtRequestConstant.REQUEST_NUMBER);
     }
 
-    // ====================== 重试工具 ======================
-    @FunctionalInterface
-    public interface RetryableTask<T> { T execute() throws Exception; }
-
-    private <T> T retry(RetryableTask<T> task, int max, long delay, String name) {
-        for (int i = 0; i < max; i++) {
-            try { return task.execute(); }
-            catch (Exception e) {
-                log.warn("{} 失败,第 {} 次重试", name, i + 1);
-                if (i + 1 >= max) throw new SystemException(name + " 失败,已重试 " + max + " 次", e.getMessage());
-                sleep(delay);
-            }
-        }
-        throw new SystemException(name + " 失败,已达到最大重试次数");
-    }
-
     private void sleep(long ms) {
         try { Thread.sleep(ms); }
         catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException("重试被中断", ie); }
@@ -215,7 +200,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
 
         Map<String, Object> res = decrypt(MAPPER.readValue(
                 post(props.getBaseUrl() + "/htcsp/VehicleInfoEntryAction.do?cmd=xbquery", buildJsonHeaders(cookie), postData),
-                HashMap.class));
+                Map.class));
         log.info("xbQuery result: {}", JSONObject.toJSONString(res));
 
         Map<String, Object> carmodel = (Map<String, Object>) res.get("carmodeldtojson");
@@ -262,17 +247,16 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         //带重试的获取报价编号、车型型号
         Map<String, Object> xbResult = retry(() -> {
             try { return xbQuery(dto.getUsername(), cookie, car); }
-            catch (Exception e) { refreshLogin(dto); throw e; }
+            catch (Exception e) { refreshLogin(dto); throw new SystemException(e.getMessage()); }
         }, MAX_RETRIES, RETRY_DELAY_MS, "预报价获取登录信息");
 
         String quotationNo = str(xbResult, "quotationNo");
         String modelcodexh = str(xbResult, "modelcodexh");
         //报价前预处理-保存车辆信息、过滤车型等处理
         PreResult pre = prepareQuote(attr, mmap, car, modelcodexh, cookie, quotationNo);
-        //带重试的报价
-        CoreResult core = executeQuoteWithRetry(quoteVo, quotationNo, dto, cookie, pre, gsInfo, attr);
-
-        if (!core.success()) throw new RuntimeException("报价失败,已达到最大重试次数");
+        //报价
+        CoreResult core = executeQuote(quoteVo, quotationNo, dto, cookie, pre, gsInfo, attr);
+        if (!core.success()) throw new SystemException("报价失败");
         //保存订单到MongoDB
         saveOrder(quoteVo, core);
         //组装费用
@@ -400,41 +384,23 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     }
 
     // ====================== 报价核心 ======================
-    private CoreResult executeQuoteWithRetry(QuoteVo quoteVo, String quotationNo, LoginDTO dto,
+    private CoreResult executeQuote(QuoteVo quoteVo, String quotationNo, LoginDTO dto,
                                              String cookie, PreResult pre,
                                              Map<String, Object> gsInfo, AttributionInformationVo attr) {
-        int retry = 0;
         String fcPrice = "";
         HtCrawlerQuoteResponse.DataDTO data = null;
 
-        while (retry < MAX_RETRIES) {
-            try {
-                if (retry > 0) { log.info("第 {} 次重试,重新开始报价流程...", retry + 1); sleep(SHORT_DELAY_MS); }
-
-                StepResult step = executeQuoteSteps(quoteVo, quotationNo, dto, cookie, pre, gsInfo);
-                data = step.data();
-
-                if (data.getApplicationdto() != null) {
-                    if (StringUtils.isNotBlank(step.personalInsuredJSON())) {
-                        fcPrice = fetchNoCarPremium(cookie, quotationNo, attr, step.personalInsuredJSON());
-                    }
-                    return new CoreResult(fcPrice, data, true);
-                }
-                log.warn("applicationdto 为 null,第 {} 次重试...", ++retry);
-            } catch (Exception e) {
-                if (e.getMessage() != null && e.getMessage().contains("重试次数已达上限")) throw wrap(e);
-                log.warn("报价异常,第 {} 次重试... 异常: {}", ++retry, e.getMessage());
-                if (retry >= MAX_RETRIES) throw new RuntimeException("报价重试次数已达上限: " + e.getMessage());
-                sleep(RETRY_DELAY_MS);
+        StepResult step = executeQuoteSteps(quoteVo, quotationNo, dto, cookie, pre, gsInfo);
+        data = step.data();
+        if (data.getApplicationdto() != null) {
+            if (StringUtils.isNotBlank(step.personalInsuredJSON())) {
+                fcPrice = fetchNoCarPremium(cookie, quotationNo, attr, step.personalInsuredJSON());
             }
+            return new CoreResult(fcPrice, data, true);
         }
         return new CoreResult(fcPrice, data, false);
     }
 
-    private RuntimeException wrap(Exception e) {
-        return e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
-    }
-
     private String fetchNoCarPremium(String cookie, String quotationNo,
                                      AttributionInformationVo attr, String personalInsuredJSON) {
         try {
@@ -456,7 +422,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     }
 
     private StepResult executeQuoteSteps(QuoteVo q, String quotationNo, LoginDTO dto,
-                                         String cookie, PreResult pre, Map<String, Object> gsInfo) throws Exception {
+                                         String cookie, PreResult pre, Map<String, Object> gsInfo) {
         HttpHeaders h = buildQuoteStep1Headers(cookie);
         HtCrawlerSaveOneStepRequest r = new HtCrawlerSaveOneStepRequest(q, pre.carDTO(), pre.params(), quotationNo, pre.dataDTO(), dto, gsInfo);
         String body = req.saveOneStept(r, h).getBody().toString();
@@ -555,12 +521,8 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     private QuoteVo handleQuoteErrors(String decryptData, QuoteVo q) {
         boolean hasError = decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag");
         if (!hasError) return q;
-
-        boolean dup = decryptData.contains("发生重复投保") && decryptData.contains("终保日期");
-
-        if (dup) {
-            q = handleDuplicateInsurance(decryptData, q);
-            return q;
+        if (decryptData.contains("发生重复投保") && decryptData.contains("终保日期") && !decryptData.contains("重复投保的其它公司")) {
+            return handleDuplicateInsurance(decryptData, q);
         }
         return q;
     }
@@ -585,13 +547,17 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     }
 
     private HtCrawlerQuoteResponse.DataDTO resolveQuoteResponse(QuoteVo q, String decryptData, String mealid, String limitAmount,
-                                                              HttpHeaders h, String personalInsuredJSON) throws Exception {
+                                                                HttpHeaders h, String personalInsuredJSON) {
+        if (!decryptData.contains("录入的校验码有误") && decryptData.contains("erroeInfo")) {
+            log.error("报价失败: {}", decryptData);
+            throw new SystemException(ERR_PREFIX + convertResponseMsg(decryptData));
+        }
         HtCrawlerQuoteResponse.DataDTO data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
         if (data.getApplicationdto() != null) return data;
 
         List<HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO> list =
                 data.getBasepartdtolist() != null ? data.getBasepartdtolist().getBasepartdto() : null;
-        if (list == null || list.isEmpty() || list.size() > 3) return data;
+        if (list == null || list.isEmpty()) return data;
 
         for (int i = 0; i < MAX_RETRIES; i++) {
             String basePartJSON = buildBasePartJSON(list);
@@ -615,15 +581,11 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
                 // 用新的 basePart 列表更新 list,下一轮循环会自动重新 buildBasePartJSON
                 list = result != null && result.getBasepartdtolist() != null
                         ? result.getBasepartdtolist().getBasepartdto() : null;
-                if (list == null || list.isEmpty() || list.size() > 3) {
+                if (list == null || list.isEmpty()) {
                     return result != null ? result : data;
                 }
                 continue;
             }
-
-            if (response.contains("erroeInfo")) {
-                throw new Exception(ERR_PREFIX + JSONObject.parseObject(response, HtCrawlerQuoteResponse.DataErrDTO.class).getErroeInfo());
-            }
             return result != null ? result : data;
         }
         return data;
@@ -634,7 +596,6 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         String basePartJSON = "";
         if (size == 1) {
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
-            log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
             String querrysequenceno = basePartDTO.getQuerrysequenceno();
             String autocheckcode = basePartDTO.getAutocheckcode();
             String riskfalg = "0".equals(querrysequenceno.substring(0, 1)) ? "0" : "1";
@@ -642,11 +603,9 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         }
         if (size == 2) {
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
-            log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
             String querrysequenceno = basePartDTO.getQuerrysequenceno();
             String autocheckcode = basePartDTO.getAutocheckcode();
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
-            log.info("buildBasePartJSON1: {}, {}", size, JSONObject.toJSONString(basePartDTO1));
             String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
             String autocheckcode1 = basePartDTO1.getAutocheckcode();
             basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
@@ -654,15 +613,12 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         }
         if (size == 3) {
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO = list.get(0);
-            log.info("buildBasePartJSON0: {}, {}", size, JSONObject.toJSONString(basePartDTO));
             String querrysequenceno = basePartDTO.getQuerrysequenceno();
             String autocheckcode = basePartDTO.getAutocheckcode();
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO1 = list.get(1);
-            log.info("buildBasePartJSON1: {}, {}", size, JSONObject.toJSONString(basePartDTO1));
             String querrysequenceno1 = basePartDTO1.getQuerrysequenceno();
             String autocheckcode1 = basePartDTO1.getAutocheckcode();
             HtCrawlerQuoteResponse.DataDTO.BasePartDTOListDTO.BasePartDTO basePartDTO2 = list.get(2);
-            log.info("buildBasePartJSON2: {}, {}", size, JSONObject.toJSONString(basePartDTO2));
             String querrysequenceno2 = basePartDTO2.getQuerrysequenceno();
             String autocheckcode2 = basePartDTO2.getAutocheckcode();
             basePartJSON = "[{'riskfalg':'0','checktype':2,'querysequenceno':'"+querrysequenceno1+"','checkcode':'"+autocheckcode1+"','answer':''}," +
@@ -681,6 +637,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         doLoginCookie(attr);
 
         HtCrawlerOrder order = orderService.findByOrdersNo(vo.getOrder().getOrdersNo());
+        if("N".equals(order.getCiCategory()) || "6C".equals(order.getCiCategory())) throw new SystemException("核保失败-------强制下发修改意见,1.N类、6C类业务,请确认业务类别后再提交核保。");
         vo.getOrder().setQuoteNo(order.getQuotationRelaNo());
 
         HtCrawlerSubmitRequest submit = new HtCrawlerSubmitRequest(vo, params, order.getCiCategory(), order.getBiCategory());
@@ -688,12 +645,12 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         Map<String, Object> map = MAPPER.readValue(res, Map.class);
 
         if (isUnderwritingFailed(order.getCiCategory(), map, res)) {
-            throw new SystemException("核保失败-------" + map.get("MSG"));
+            throw new SystemException("核保失败-------" + convertResponseMsg(map.get("MSG").toString()));
         }
         if (res.contains("起保时间不正确")) {
             throw new SystemException("起保时间不正确-------即时起保分钟数必须为00/15/30/45\n请重新选择起保时间!");
         }
-        if (res.contains("需转人工核保")) return handleManualUnderwriting(order, params);
+        if (res.contains("转人工")) return handleManualUnderwriting(order, params);
         if (res.contains("已通过核保未实收") || isPassHB(map)) return handlePassedUnderwriting(order, params, vo);
 
         UnderwritingResultsVo r = new UnderwritingResultsVo();
@@ -739,13 +696,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
             }
             int s = html.indexOf("原因"), e = html.lastIndexOf("。");
             throw new SystemException("审核未通过:" + (s >= 0 && e > s ? html.substring(s, e) : "审核未通过"));
-        } catch (SystemException se) { throw se; }
-        catch (Exception e) {
-            log.error("人工核保处理异常", e);
-            UnderwritingResultsVo r = new UnderwritingResultsVo();
-            r.setUnderwritingStatus(InsOrderStatusEnum.WAIT_AUDIT);
-            return r;
-        }
+        } catch (Exception e) { throw new SystemException(e.getMessage()); }
     }
 
     private UnderwritingResultsVo handlePassedUnderwriting(HtCrawlerOrder order, HtCrawlerConfigureParameters params, UnderwritingVo vo) {
@@ -833,7 +784,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-    private Map fetchUploadInitParam(String token) {
+    private Map<String, Object> fetchUploadInitParam(String token) {
         HttpHeaders h = new HttpHeaders();
         h.set(HtRequestConstant.COOKIE, req.getCookie());
         h.set("Accept", "application/json, text/plain, */*");
@@ -1061,6 +1012,22 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         });
     }
 
+    // ====================== 重试工具 ======================
+    @FunctionalInterface
+    public interface RetryableTask<T> { T execute() throws Exception; }
+
+    private <T> T retry(RetryableTask<T> task, int max, long delay, String name) {
+        for (int i = 0; i < max; i++) {
+            try { return task.execute(); }
+            catch (Exception e) {
+                log.warn("{} 失败,第 {} 次重试", name, i + 1);
+                if (i + 1 >= max) throw new SystemException(name + " 失败,已重试 " + max + " 次", e.getMessage());
+                sleep(delay);
+            }
+        }
+        throw new SystemException(name + " 失败,已达到最大重试次数");
+    }
+
     // ====================== HTTP 通用工具 ======================
     private String get(String url, HttpHeaders headers, MultiValueMap<String, String> params) {
         UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
@@ -1074,10 +1041,11 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
 
     @SuppressWarnings("unchecked")
     private Map<String, Object> exchangeForm(String url, Map<String, String> queryParams,
-                                               MultiValueMap<String, String> data, HttpHeaders headers) throws JsonProcessingException {
+                                             MultiValueMap<String, String> data, HttpHeaders headers) throws JsonProcessingException {
         UriComponentsBuilder b = UriComponentsBuilder.fromHttpUrl(url);
         if (queryParams != null) queryParams.forEach(b::queryParam);
         String body = RT.exchange(b.toUriString(), HttpMethod.POST, new HttpEntity<>(data, headers), String.class).getBody();
+        log.info("转人工响应结果,{}", body);
         return MAPPER.readValue(body, Map.class);
     }
 
@@ -1139,4 +1107,24 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         }
         return m;
     }
+    /**
+     * 提取 (infoName + infomsg) 或者 erroeInfo 拼接字符串
+     */
+    public static String convertResponseMsg(String responseStr) {
+        Matcher matcher = RESPONSE_ERR.matcher(responseStr);
+        StringBuilder sb = new StringBuilder();
+        while (matcher.find()) {
+            if (matcher.group(2) != null && matcher.group(3) != null) {
+                // 场景1:infoName + infomsg
+                String infoName = matcher.group(2).trim();
+                String infomsg = matcher.group(3).trim();
+                sb.append(infoName).append(":").append(infomsg).append("\n");
+            } else if (matcher.group(4) != null) {
+                // 场景2:erroeInfo 单独错误
+                sb.append(matcher.group(4).trim()).append("\n");
+            }
+        }
+        if (StringUtils.isBlank(sb)) sb.append(responseStr);
+        return sb.toString().trim();
+    }
 }

+ 8 - 7
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/util/CookieUtils.java

@@ -89,13 +89,14 @@ public class CookieUtils {
             this.bigIpCookie = (String) cookies.get("BIGipServerypKFOfHGLAALYYraCSdVMw");
 
             // 如果不是特殊账号,获取归属信息
-            if (!specialUsers.contains(username)) {
-                try {
-                    getGuishu(comCode, useridName, dlrCode, dlxyCode);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
+            //if (!specialUsers.contains(username)) {
+            //    try {
+            //        getGuishu(comCode, useridName, dlrCode, dlxyCode);
+            //    } catch (Exception e) {
+            //        e.printStackTrace();
+            //    }
+            //}
+            getGuishu(comCode, useridName, dlrCode, dlxyCode);
 
             Map<String, Object> resultMap = new HashMap<>();
             resultMap.put("code", 200);

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

@@ -1518,50 +1518,189 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
                 headers
         );
 
-        OrderStatusResultVo resultVo = new OrderStatusResultVo();
-
-        // 解析订单状态
-        String status = parseOrderStatus(checkResult);
-        resultVo.setOrderStatusStr(status);
-
-        // 解析投保单号和保单号
-        parsePolicyNumbers(checkResult, resultVo);
-
-        return resultVo;
-    }
-
-    /**
-     * 解析订单状态
-     */
-    private String parseOrderStatus(Map<String, Object> checkResult) {
-        if (checkResult == null || !checkResult.containsKey("data")) {
-            return "UNKNOWN";
+        // 校验查询结果
+        if (checkResult == null || !"Success".equals(checkResult.get("message"))) {
+            String errorMsg = checkResult != null ? (String) checkResult.get("statusText") : "查询订单响应为空";
+            throw new SystemException("查询订单异常: " + errorMsg);
         }
 
         Map<String, Object> data = (Map<String, Object>) checkResult.get("data");
         if (data == null || !data.containsKey("result")) {
-            return "UNKNOWN";
+            throw new SystemException("查询订单异常: 未查询到订单");
         }
 
         List<Map<String, Object>> itemList = (List<Map<String, Object>>) data.get("result");
         if (itemList == null || itemList.isEmpty()) {
-            return "NOT_FOUND";
+            throw new SystemException("未查询到订单");
+        }
+        if (itemList.size() > 2) {
+            throw new SystemException("查询订单异常");
         }
 
-        // 获取第一个订单的状态
-        Map<String, Object> firstItem = itemList.get(0);
-        String underWriteFlag = (String) firstItem.get("underWriteFlag");
-
-        // 状态映射:0-初始值, 1-通过, 2-不通过, 3-自动核保通过, 4-见费出单待缴费, 5-见费出单待缴费,
-        // 6-待同步, 7-自动待同步, 9-待核保, A-送见费失败, B-送见费失败, C-待取消, D-自动核保待转保单,
-        // E-人工核保待转保单, F-预核保转人工
-        return switch (underWriteFlag) {
-            case "1", "3" -> "APPROVED";
-            case "2" -> "REJECTED";
-            case "4", "5" -> "PAYMENT_PENDING";
-            case "9" -> "UNDERWRITING";
-            default -> "PROCESSING";
-        };
+        // 2. 提取交强/商业单号及驾意险单号(对应Python逻辑)
+        Map<String, Object> orderInfo = itemList.get(0);
+        String jqApplication = "";
+        String syApplication = "";
+        List<String> documentnolist = new ArrayList<>();
+        List<String> jyxBusinessNoList = new ArrayList<>();
+
+        for (Map<String, Object> item : itemList) {
+            String bNo = (String) item.get("businessNo");
+            if (bNo != null) {
+                if (bNo.contains("DZA")) {
+                    jqApplication = bNo;
+                    documentnolist.add(bNo);
+                } else if (bNo.contains("DAA")) {
+                    syApplication = bNo;
+                    documentnolist.add(bNo);
+                }
+            }
+        }
+
+        // 提取驾意险关联单号
+        if (orderInfo.containsKey("relationUPolicyInfolist")) {
+            List<Map<String, Object>> relationList = (List<Map<String, Object>>) orderInfo.get("relationUPolicyInfolist");
+            if (relationList != null) {
+                for (Map<String, Object> relItem : relationList) {
+                    String connectProposalNo = (String) relItem.get("connectProposalNo");
+                    if (connectProposalNo != null && !connectProposalNo.isEmpty()) {
+                        documentnolist.add(connectProposalNo);
+                        jyxBusinessNoList.add(connectProposalNo);
+                    }
+                }
+            }
+        }
+
+        // 3. 获取核保状态
+        String underWriteFlag = (String) orderInfo.get("underWriteFlag");
+        log.info("订单状态 underWriteFlag={}, jq={}, sy={}, jyx={}", underWriteFlag, jqApplication, syApplication, jyxBusinessNoList);
+
+        // 4. 根据状态处理
+        OrderStatusResultVo resultVo = new OrderStatusResultVo();
+        resultVo.setJqApplyNo(jqApplication);
+        resultVo.setSyApplyNo(syApplication);
+        resultVo.setJyApplyNo(jyxBusinessNoList.isEmpty() ? "" : String.join(",", jyxBusinessNoList));
+
+        // 状态为4或5:核保通过待缴费 → 获取支付链接
+        if ("4".equals(underWriteFlag) || "5".equals(underWriteFlag)) {
+            log.info("订单核保通过,获取支付链接");
+            // 构建支付请求
+            RenBaoNewCrawlerPayRequest payRequest = new RenBaoNewCrawlerPayRequest();
+            payRequest.setDocumentnolist(documentnolist);
+            payRequest.setUserCode(loginInfo.getUserCode());
+            payRequest.setComCode(loginInfo.getComCode());
+            payRequest.setPayType("");
+            payRequest.setPayFee("");
+            payRequest.setCurrency("");
+            payRequest.setLinkurlflag("1");
+            payRequest.setBrowseWay("");
+
+            // 带重试获取支付链接(对应Python的while循环)
+            int retryCount = 0;
+            while (true) {
+                RenBaoNewCrawlerPayResponse payResponse = requestComponent.getPayUrl(payRequest, headers);
+                if (payResponse != null && "Success".equals(payResponse.getMessage())) {
+                    String qrcodeimg = payResponse.getData() != null ? payResponse.getData().getQrcodeimg() : null;
+                    if (qrcodeimg == null || qrcodeimg.isEmpty()) {
+                        retryCount++;
+                        if (retryCount > 3) {
+                            String errMsg = payResponse.getData() != null ? payResponse.getData().getErrorMessage() : "支付二维码为空";
+                            throw new SystemException("提取支付异常," + errMsg);
+                        }
+                        log.info("支付二维码为空,重试 {}/3", retryCount);
+                        try {
+                            Thread.sleep(1000);
+                        } catch (InterruptedException e) {
+                            Thread.currentThread().interrupt();
+                        }
+                        continue;
+                    }
+                    // 成功获取支付链接
+                    resultVo.setPaymentLink(qrcodeimg);
+                    resultVo.setOrderStatus(InsOrderStatusEnum.PAY_PENDING);
+                    resultVo.setOrderStatusStr("待支付");
+                    log.info("获取支付链接成功");
+                } else {
+                    String errorMsg = payResponse != null ? payResponse.getStatusText() : "支付响应为空";
+                    throw new SystemException("提取支付异常," + errorMsg);
+                }
+                break;
+            }
+        }
+        // 状态为9:待核保
+        else if ("9".equals(underWriteFlag)) {
+            Map<String, Object> processInfo = requestComponent.getUndwrtProcessInfo(businessNo, headers);
+            if (processInfo != null && processInfo.containsKey("data")) {
+                Map<String, Object> processData = (Map<String, Object>) processInfo.get("data");
+                if (processData != null && processData.containsKey("underwritingInfos")) {
+                    List<Map<String, Object>> infos = (List<Map<String, Object>>) processData.get("underwritingInfos");
+                    if (infos != null && !infos.isEmpty()) {
+                        String msg = (String) infos.get(0).get("msg");
+                        resultVo.setErrorMsg(msg);
+                    }
+                }
+            }
+            resultVo.setOrderStatus(InsOrderStatusEnum.STAFF_PROCESS);
+            resultVo.setOrderStatusStr("待核保");
+        }
+        // 状态为2:不通过
+        else if ("2".equals(underWriteFlag)) {
+            StringBuilder errorMsg = new StringBuilder();
+            if (!jqApplication.isEmpty()) {
+                Map<String, Object> viewResult = requestComponent.viewUndwrt(jqApplication, loginInfo.getUserCode(), headers);
+                if (viewResult != null && viewResult.containsKey("data")) {
+                    List<Map<String, Object>> dataList = (List<Map<String, Object>>) viewResult.get("data");
+                    if (dataList != null && !dataList.isEmpty()) {
+                        String handleText = (String) dataList.get(0).get("handleText");
+                        errorMsg.append("交强返回:").append(handleText).append("; ");
+                    }
+                }
+            }
+            if (!syApplication.isEmpty()) {
+                Map<String, Object> viewResult = requestComponent.viewUndwrt(syApplication, loginInfo.getUserCode(), headers);
+                if (viewResult != null && viewResult.containsKey("data")) {
+                    List<Map<String, Object>> dataList = (List<Map<String, Object>>) viewResult.get("data");
+                    if (dataList != null && !dataList.isEmpty()) {
+                        String handleText = (String) dataList.get(0).get("handleText");
+                        errorMsg.append("商业返回:").append(handleText);
+                    }
+                }
+            }
+            resultVo.setErrorMsg(errorMsg.toString());
+            resultVo.setOrderStatus(InsOrderStatusEnum.AUDIT_FAIL);
+            resultVo.setOrderStatusStr("核保不通过");
+        }
+        // 状态为1或3:已通过
+        else if ("1".equals(underWriteFlag) || "3".equals(underWriteFlag)) {
+            resultVo.setOrderStatus(InsOrderStatusEnum.UNDERWRITED);
+            resultVo.setOrderStatusStr("已支付");
+        }
+        // 其他状态
+        else {
+            // 解析状态文本
+            String[][] statusMap = {
+                    {"0", "初始值"}, {"1", "通过"}, {"2", "不通过"}, {"3", "自动核保通过"},
+                    {"4", "见费出单待缴费"}, {"5", "见费出单待缴费"}, {"6", "待同步"},
+                    {"7", "自动待同步"}, {"9", "待核保"}, {"A", "送见费失败"},
+                    {"B", "送见费失败"}, {"C", "待取消"}, {"D", "自动核保待转保单"},
+                    {"E", "人工核保待转保单"}, {"F", "预核保转人工"}
+            };
+            String statusTxt = underWriteFlag;
+            for (String[] entry : statusMap) {
+                if (entry[0].equals(underWriteFlag)) {
+                    statusTxt = entry[1];
+                    break;
+                }
+            }
+            log.info("订单状态: {}", statusTxt);
+            resultVo.setOrderStatus(InsOrderStatusEnum.AUDIT_ING);
+            resultVo.setOrderStatusStr(statusTxt);
+        }
+
+        // 解析保单号(如果已有)
+        parsePolicyNumbers(checkResult, resultVo);
+
+        return resultVo;
     }
 
     /**

+ 50 - 13
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java

@@ -35,8 +35,38 @@ public class FactorMatch {
      */
     public static boolean judgements(List<PtlAgreementCostRule> ptlAgreementCostRuleList, List<RuleAttrMappingVo> ruleAttrMappingVoList,
                                      List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList, StringBuilder logs,  List<PtlAgreementUndwrtRulesDictLabal> undwrtRulesDictList) {
-        boolean useFlag = true;
-        for (PtlAgreementCostRule ptlAgreementProductCostsAttrLink : ptlAgreementCostRuleList) {
+        if (ptlAgreementCostRuleList == null || ptlAgreementCostRuleList.isEmpty()) {
+            return false;
+        }
+        // 按batch分组:不同batch之间为OR关系,同batch内为AND关系
+        Map<String, List<PtlAgreementCostRule>> batchMap = ptlAgreementCostRuleList.stream()
+                .collect(Collectors.groupingBy(rule -> rule.getBatch() != null ? rule.getBatch() : "default",
+                        LinkedHashMap::new, Collectors.toList()));
+
+        StringBuilder errorLogs = new StringBuilder();
+        for (Map.Entry<String, List<PtlAgreementCostRule>> entry : batchMap.entrySet()) {
+            List<PtlAgreementCostRule> batchRules = entry.getValue();
+            StringBuilder batchLogs = new StringBuilder();
+            boolean batchMatched = doJudgementsMatch(batchRules, ruleAttrMappingVoList, undwrtRulesAttrList,
+                    batchLogs, undwrtRulesDictList);
+            if (batchMatched) {
+                // OR关系:只要任一个batch匹配即通过
+                return true;
+            }
+            errorLogs.append(batchLogs);
+        }
+        // 所有batch都未匹配,输出错误日志
+        logs.append(errorLogs);
+        return false;
+    }
+
+    /**
+     * 判断一个batch内的规则是否全部匹配(AND关系)
+     */
+    private static boolean doJudgementsMatch(List<PtlAgreementCostRule> batchRules, List<RuleAttrMappingVo> ruleAttrMappingVoList,
+                                             List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList, StringBuilder logs,
+                                             List<PtlAgreementUndwrtRulesDictLabal> undwrtRulesDictList) {
+        for (PtlAgreementCostRule ptlAgreementProductCostsAttrLink : batchRules) {
             //查找规则中的 传值属性
             RuleAttrMappingVo ruleAttrMappingVo = ruleAttrMappingVoList.stream()
                     .filter(x -> x.getAttrCode().equals(ptlAgreementProductCostsAttrLink.getAttrCode()))
@@ -59,8 +89,9 @@ public class FactorMatch {
                     .findFirst()
                     .get();
 
+            boolean useFlag;
             if(!Objects.isNull(ruleAttrMappingVo.getValue())) {
-                useFlag = attrEqual(ptlAgreementProductCostsAttrLink, ptlAgreementUndwrtRulesAttr, ruleAttrMappingVo.getValue(),false);
+                useFlag = attrEqual(ptlAgreementProductCostsAttrLink, ptlAgreementUndwrtRulesAttr, ruleAttrMappingVo.getValue(), false);
             }else{
                 useFlag = false;
             }
@@ -97,14 +128,13 @@ public class FactorMatch {
                 logs.append("传入的值:" + (StrUtil.isNotBlank(val) ? val : ruleAttrMappingVo.getValue()) + "\n");
 
                 if (CollUtil.isNotEmpty(collect)) {
-//                    logs.append("<span style=\"color:red;\">规则匹配失败:" + collect.get(0).getAttrName() + "</span>\n");
                     logs.append("规则匹配失败:" + collect.get(0).getAttrName() + "\n");
                 }
 
                 return false;
             }
         }
-        return useFlag;
+        return true;
     }
 
 
@@ -119,8 +149,8 @@ public class FactorMatch {
                     .orElse(null);
             //如果查找不到 传值属性 直接费用对比失败
             if (ruleAttrMappingVo == null) {
-                log.info("传入的值找不到该属性:" + ptlAgreementProductCostsAttrLink.getAttrCode());
-                log.info("规则匹配失败:" + ptlAgreementProductCostsAttrLink.getAttrCode());
+                log.info("承保规则校验-属性未找到: attrCode={}", ptlAgreementProductCostsAttrLink.getAttrCode());
+                log.info("承保规则校验-规则匹配失败: attrCode={}", ptlAgreementProductCostsAttrLink.getAttrCode());
 
                 List<PtlAgreementUndwrtRulesAttr> collect = undwrtRulesAttrList.stream()
                         .filter(x -> x.getAttrCode().equals(ptlAgreementProductCostsAttrLink.getAttrCode()))
@@ -144,14 +174,20 @@ public class FactorMatch {
                 ptlAgreementCostRule.setOperator(ptlAgreementProductCostsAttrLink.getOperator());
                 ptlAgreementCostRule.setAttrCode(ptlAgreementProductCostsAttrLink.getAttrCode());
                 useFlag = attrEqual(ptlAgreementCostRule, ptlAgreementUndwrtRulesAttr, ruleAttrMappingVo.getValue(), true);
+                log.info("承保规则校验-单属性匹配: attrCode={}, attrType={}, 规则值(min={}, max={}, operator={}), 传入值={}, useFlag={}",
+                        ptlAgreementProductCostsAttrLink.getAttrCode(), ptlAgreementUndwrtRulesAttr.getAttrType(),
+                        ptlAgreementProductCostsAttrLink.getMin(), ptlAgreementProductCostsAttrLink.getMax(),
+                        ptlAgreementProductCostsAttrLink.getOperator(), ruleAttrMappingVo.getValue(), useFlag);
             }else{
                 useFlag = false;
+                log.info("承保规则校验-传入值为null: attrCode={}, useFlag=false", ptlAgreementProductCostsAttrLink.getAttrCode());
             }
 
-            if (!useFlag) {
-                log.info("检验的值:" + ptlAgreementProductCostsAttrLink.getMin());
-                log.info("传入的值:" + ruleAttrMappingVo.getValue());
-                log.info("规则匹配失败:" + ptlAgreementProductCostsAttrLink.getAttrCode());
+            if (useFlag) {
+                log.info("承保规则校验-条件命中! attrCode={}, 传入值={}, 规则min={}, max={}, operator={}",
+                        ptlAgreementProductCostsAttrLink.getAttrCode(), ruleAttrMappingVo.getValue(),
+                        ptlAgreementProductCostsAttrLink.getMin(), ptlAgreementProductCostsAttrLink.getMax(),
+                        ptlAgreementProductCostsAttrLink.getOperator());
 
                 List<PtlAgreementUndwrtRulesAttr> collect = undwrtRulesAttrList.stream()
                         .filter(x -> x.getAttrCode().equals(ptlAgreementProductCostsAttrLink.getAttrCode()))
@@ -173,10 +209,10 @@ public class FactorMatch {
                 }
                 if (ptlAgreementProductCostsAttrLink.getMin() != null) {
                     String min = codeToNameMap.getOrDefault(ptlAgreementProductCostsAttrLink.getMin(), StrUtil.EMPTY);
-                    logs.append("检验的值4:" + (StrUtil.isNotBlank(min) ? min : ptlAgreementProductCostsAttrLink.getMin()) + "\n");
+                    logs.append("检验的值:" + (StrUtil.isNotBlank(min) ? min : ptlAgreementProductCostsAttrLink.getMin()) + "\n");
                 } else {
                     String max = codeToNameMap.getOrDefault(ptlAgreementProductCostsAttrLink.getMax(), StrUtil.EMPTY);
-                    logs.append("检验的值5:" + (StrUtil.isNotBlank(max) ? max : ptlAgreementProductCostsAttrLink.getMax()) + "\n");
+                    logs.append("检验的值:" + (StrUtil.isNotBlank(max) ? max : ptlAgreementProductCostsAttrLink.getMax()) + "\n");
                 }
 
                 String val = codeToNameMap.getOrDefault(ruleAttrMappingVo.getValue(), StrUtil.EMPTY);
@@ -189,6 +225,7 @@ public class FactorMatch {
                 return false;
             }
         }
+        log.info("承保规则校验-所有条件均未命中, 规则组通过, useFlag={}", useFlag);
         return useFlag;
     }
 

+ 1 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLogAspect.java

@@ -109,7 +109,7 @@ public class OrderOperationLogAspect {
                 // 通过 SpEL 提取 入参
                 DownloadPolicyVo downloadPolicyVo = parser.parseExpression(log.orderSpEl()).getValue(context, DownloadPolicyVo.class);
                 result = joinPoint.proceed();
-                this.downloadLog("1988155511437271040",result,log);
+                this.downloadLog(downloadPolicyVo.getOrder().getOrdersNo(),result,log);
                 break;
             // 同步订单
             case 9:

+ 17 - 10
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/AuditVerificationAspect.java

@@ -159,38 +159,45 @@ public class AuditVerificationAspect {
 
         List<PtlAgreementUndwrtRulesDictLabal> undwrtRulesDictList = ptlNewAgreementClient.getUndwrtRulesDictList();
 
+        log.info("=== 承保规则校验开始, 规则组数={}, 传入属性数={} ===", ruleGroups == null ? 0 : ruleGroups.size(), ruleAttrMappingVoList.size());
+
         // 多条规则间为OR关系:只要任一条规则匹配即通过
         StringBuilder allErrorLogs = new StringBuilder();
         boolean anyRuleMatched = false;
 
+        int groupIndex = 0;
         for (List<PtlAgreementUndwrtRulesAttrLink> ptlAgreementUndwrtRulesNews : ruleGroups) {
+            groupIndex++;
             if (ptlAgreementUndwrtRulesNews == null || ptlAgreementUndwrtRulesNews.isEmpty()) {
+                log.info("规则组[{}]为空, 跳过", groupIndex);
                 continue;
             }
-            boolean ruleMatched = true;
             StringBuilder ruleLogs = new StringBuilder();
 
-            for (int i = 0; i < ruleAttrMappingVoList.size(); i++) {
-                //判断是否匹配
-                if (!FactorMatch.judgementsUnderwrite(ptlAgreementUndwrtRulesNews, ruleAttrMappingVoList, undwrtRulesAttrList, ruleLogs, undwrtRulesDictList)) {
-                    ruleMatched = false;
-                    break;
-                }else{
-                    //如果没有出现异常则清空匹配消息
-                    ruleLogs.delete(0,ruleLogs.length());
-                }
+            log.info("规则组[{}]开始匹配, 条件数={}", groupIndex, ptlAgreementUndwrtRulesNews.size());
+            // 打印规则组详情
+            for (PtlAgreementUndwrtRulesAttrLink link : ptlAgreementUndwrtRulesNews) {
+                log.info("  -> 条件: attrCode={}, min={}, max={}, operator={}", link.getAttrCode(), link.getMin(), link.getMax(), link.getOperator());
             }
 
+            // 直接判断该规则组是否匹配,无需循环调用
+            boolean ruleMatched = FactorMatch.judgementsUnderwrite(ptlAgreementUndwrtRulesNews, ruleAttrMappingVoList, undwrtRulesAttrList, ruleLogs, undwrtRulesDictList);
+
+            log.info("规则组[{}]匹配结果: ruleMatched={}, 错误日志=[{}]", groupIndex, ruleMatched, ruleLogs.toString());
+
             if (ruleMatched) {
                 anyRuleMatched = true;
+                log.info("规则组[{}]匹配成功, 订单通过!", groupIndex);
                 break; // OR关系:任一条规则通过即可
             }
             allErrorLogs.append(ruleLogs);
         }
 
         if (!anyRuleMatched) {
+            log.info("=== 承保规则校验失败, 所有规则组均未通过, 抛出异常 ===");
             throw new SystemException(allErrorLogs.toString());
         }
+        log.info("=== 承保规则校验通过 ===");
     }
 
 }

+ 2 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.summary.aop.aspect;
 
+import cn.hutool.core.collection.CollUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.jzg.commons.constants.quote.enums.quote.EnergyTypeCode;
@@ -99,7 +100,7 @@ public class QuoteVerificationAspect {
             // 设置默认的优先级
             agreementProductCosts = this.setPriorities(agreementProductCosts);
             log.info("过滤的费用列表:{}",JSONObject.toJSONString(agreementProductCosts));
-            if (!agreementProductCosts.isEmpty()) {
+            if (CollUtil.isNotEmpty(agreementProductCosts)) {
                 //遍历费用因子
                 String costId = verificationCosts(agreementProductCosts, logs, insOrdersOther, insOrdersCarInfo, insOrdersRisks,
                         insOrdersCarUserInfos, kindList, insOrdersCosts, insOrdersAccidentalDriving, insOrders);

+ 4 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java

@@ -391,6 +391,10 @@ public class UnifyOrderManager {
             log.error("车险报价异常", e);
             Throwable root = e.getCause() != null ? e.getCause() : e;
             String errMsg = root.getMessage() != null ? root.getMessage() : "系统异常,报价失败";
+            // 去除异常类名前缀
+            if (errMsg.matches("^[a-zA-Z0-9.]+Exception:.*")) {
+                errMsg = errMsg.substring(errMsg.indexOf(":") + 1).trim();
+            }
             try {
                 insOrdersService.orderAfterUpdateFailedQuote(ordersNo, errMsg);
             } catch (Exception ex) {

+ 3 - 3
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java

@@ -802,9 +802,9 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
                 ordersOther = new InsOrdersOther();
                 ordersOther.setOrderNo(ordersNo);
                 // 赔付率
-                ordersOther.setLossRation(new BigDecimal(quoteResponse.getScoreVo().getLossRation() != null ? quoteResponse.getScoreVo().getLossRation() : "0"));
-                ordersOther.setJqLossRation(new BigDecimal(quoteResponse.getScoreVo().getJqLossRation() != null ? quoteResponse.getScoreVo().getJqLossRation() : "0"));
-                ordersOther.setSyLossRation(new BigDecimal(quoteResponse.getScoreVo().getSyLossRation() != null ? quoteResponse.getScoreVo().getSyLossRation() : "0"));
+                ordersOther.setLossRation(new BigDecimal(StringUtils.isNotEmpty(quoteResponse.getScoreVo().getLossRation())  ? quoteResponse.getScoreVo().getLossRation() : "0"));
+                ordersOther.setJqLossRation(new BigDecimal(StringUtils.isNotEmpty(quoteResponse.getScoreVo().getJqLossRation()) ? quoteResponse.getScoreVo().getJqLossRation() : "0"));
+                ordersOther.setSyLossRation(new BigDecimal(StringUtils.isNotEmpty(quoteResponse.getScoreVo().getSyLossRation()) ? quoteResponse.getScoreVo().getSyLossRation() : "0"));
                 // 续保
                 ordersOther.setJqRenewal(quoteResponse.getScoreVo().getJqRenewal() != null ? Integer.parseInt(quoteResponse.getScoreVo().getJqRenewal()) : null);
                 ordersOther.setSyRenewal(quoteResponse.getScoreVo().getSyRenewal() != null ? Integer.parseInt(quoteResponse.getScoreVo().getSyRenewal()) : null);

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

@@ -109,7 +109,7 @@ public class TkCrawlerQuoteResultsBuild {
                 String platformKindName = tKCiKindsVo.getKindCName(); // 平台险种名称
                 String amount = tKCiKindsVo.getQuoteAmount().toString(); // 保额
                 String unitAmount = tKCiKindsVo.getUnitAmount().toString(); // 每座保额
-                String quantity = tKCiKindsVo.getQuantity(); // 座位数
+                Integer quantity = tKCiKindsVo.getQuantity(); // 座位数
                 String premium = tKCiKindsVo.getPremium().toString(); // 保费
                 String deductibleRate = null; // 附加绝对免赔率
                 String serviceTimes = null; // 服务次数

+ 1 - 1
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/api/PreciseInitResult.java

@@ -66,7 +66,7 @@ public class PreciseInitResult extends UnknownFieldEntity {
     /**
      * 佣金率
      */
-    private Integer commissionRateBI;
+    private BigDecimal commissionRateBI;
 
     /**
      * 佣金金额(以货币单位表示,例如元)

+ 4 - 4
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKCiKindsVo.java

@@ -63,7 +63,7 @@ public class TKCiKindsVo extends UnknownFieldEntity {
     /**
      * 免赔额列表
      */
-    private List<TKAmount> deductibleTKAmounts;
+    private List<TKAmount> deductibleAmounts;
 
     /**
      * 是否不计免赔标志
@@ -94,7 +94,7 @@ public class TKCiKindsVo extends UnknownFieldEntity {
      *
      * 否则为 “0”
      */
-    private String quantity;
+    private Integer quantity;
 
     /**
      * 报价金额
@@ -106,7 +106,7 @@ public class TKCiKindsVo extends UnknownFieldEntity {
      *
      * 当不投保时,这个字段的值好像是无意义的,有些传的是10000、有的传0、有的传2。
      */
-    private BigDecimal quoteAmount;
+    private String quoteAmount;
 
     /**
      * 报价金额中文
@@ -163,6 +163,6 @@ public class TKCiKindsVo extends UnknownFieldEntity {
     @Override
     protected void addChildUnknownFields() {
         addChildUnknownField("amounts", amounts);
-        addChildUnknownField("deductibleAmounts", deductibleTKAmounts);
+        addChildUnknownField("deductibleAmounts", deductibleAmounts);
     }
 }

+ 2 - 2
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKCommonPlanInfo.java

@@ -59,7 +59,7 @@ public class TKCommonPlanInfo extends UnknownFieldEntity {
         /**
          * 单位类型
          */
-        private Integer unitType;
+        private String unitType;
 
         /**
          * 标准保费
@@ -173,6 +173,6 @@ public class TKCommonPlanInfo extends UnknownFieldEntity {
         /**
          * 种类指示
          */
-        private Integer kindInd;
+        private String kindInd;
     }
 }

+ 4 - 0
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKFlag.java

@@ -133,4 +133,8 @@ public class TKFlag extends UnknownFieldEntity {
      * 是否员工内部车
      */
     private String isStaffCar;
+    /**
+     *
+     */
+    private String priceDifferFlag;
 }

+ 2 - 0
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/TKOther.java

@@ -92,4 +92,6 @@ public class TKOther extends UnknownFieldEntity {
      */
     private String vehicleOwnerMessage;
 
+    private String priceDifferFlag;
+
 }

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

@@ -607,8 +607,8 @@ public class TKHttpAPIService {
     public SaveBasicInfoResult saveBasicInfo(String token, SaveBasicInfoParam param) {
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.add("tkCarRequestToken", token);
-        // httpHeaders.add("carinsurflowid", "carInsur1780310645869550725");
-        // httpHeaders.add("carinsurorderid", param.getOrderID());
+        httpHeaders.add("carinsurflowid", "carInsur1780310645869550725");
+        httpHeaders.add("carinsurorderid", param.getOrderID());
 
         SaveBasicInfoResult.Response response = client.request(HttpURL.saveBasicInfo, param, httpHeaders, SaveBasicInfoResult.Response.class);
 
@@ -651,7 +651,6 @@ public class TKHttpAPIService {
         param.setTplatformId(tplatformId);
         param.setInitFlag("init");
         param.setTplatLoginKey(tplatLoginKey);
-        param.setOrderVersion("1");
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.add("tkCarRequestToken", token);
         httpHeaders.add("carinsurflowid", "carInsur1780302178294459227");

+ 131 - 133
tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKSimpleService.java

@@ -953,8 +953,7 @@ public class TKSimpleService {
      * @param session
      * @param mainOrderId
      */
-    public PreciseInitResult orderInit(TKLoginSession session,
-                                       String mainOrderId) {
+    public PreciseInitResult orderInit(TKLoginSession session, String mainOrderId) {
         PreciseInitResult preciseInitResult = httpService.preciseInitToInit(session.getToken(), session.getTplatformId(), session.getTplatLoginKey(), mainOrderId);
         if (preciseInitResult == null) {
             throw new RuntimeException("HttpService#preciseInitToInit 失败!");
@@ -982,160 +981,161 @@ public class TKSimpleService {
         String fromId = session.getFromid();
 
         // 险种选中标志
-        {
-            TKFlag flag = preciseInitParam.getFlag();
-            if (flag == null) {
-                flag = new TKFlag();
-                preciseInitParam.setFlag(flag);
-            }
-            flag.setVipWeekFlag("0");
-            flag.setQuoteLinkageFlag("0");
 
-            // 无商业险
-            if (CollectionUtils.isEmpty(commonQuoteVo.getKindInfoVo())) {
-                flag.setCiFlag("0");
-            }
-            // 无驾意险,经测试这个值无驾意险的时候请求还是传1,不用改变
-            if (CollectionUtils.isEmpty(commonQuoteVo.getAccidentalDrivings())) {
-                flag.setIsAccidentInsureFlag("0");
-            }
+        TKFlag flag = preciseInitParam.getFlag();
+        if (flag == null) {
+            flag = new TKFlag();
+            preciseInitParam.setFlag(flag);
+        }
+        flag.setVipWeekFlag("0");
+        flag.setQuoteLinkageFlag("0");
+        flag.setInstantInsureBZAllowed("0");
+        flag.setPriceDifferFlag("0");
+
+        // 无商业险
+        if (CollectionUtils.isEmpty(commonQuoteVo.getKindInfoVo())) {
+            flag.setCiFlag("0");
         }
+        // 无驾意险,经测试这个值无驾意险的时候请求还是传1,不用改变
+        // if (CollectionUtils.isEmpty(commonQuoteVo.getAccidentalDrivings())) {
+        //     flag.setIsAccidentInsureFlag("0");
+        // }
+
 
         // 其他参数
-        {
-            TKOther other = preciseInitParam.getOther();
-            if (other == null) {
-                other = new TKOther();
-                preciseInitParam.setOther(other);
-            }
-            other.setFromID(fromId);
-            other.setChannelCode("OffWeb");
+
+        TKOther other = preciseInitParam.getOther();
+        if (other == null) {
+            other = new TKOther();
+            preciseInitParam.setOther(other);
         }
+        other.setFromID(fromId);
+        other.setChannelCode("OffWeb");
 
         // 时间参数
         TKDateInfo date = preciseInitParam.getDate();
-        {
-            // 同步交强险
-            TKBzKindVo bzKindVo = preciseInitParam.getBzKindVo();
-            if (bzKindVo == null) {
-                bzKindVo = new TKBzKindVo();
-                preciseInitParam.setBzKindVo(bzKindVo);
-            }
-            bzKindVo.setIsSelect("1"); // 选择交纳交强险
-
-            // 同步交强险时间信息,从前端参数获取
-            RiskInfoVo commonCiRiskInfoVo = commonQuoteVo.getCiRiskInfoVo();
-            if (commonCiRiskInfoVo != null) {
-                // 交强险的时间
-                date.setStartDateBZ(commonCiRiskInfoVo.getStartDate());
-                date.setEndDateBZ(commonCiRiskInfoVo.getEndDate());
-            }
 
-            // 同步车船税
-            TKCarTaxInfo carTaxInfo = preciseInitParam.getCarTaxInfo();
-            if (carTaxInfo == null) {
-                carTaxInfo = new TKCarTaxInfo();
-                preciseInitParam.setCarTaxInfo(carTaxInfo);
-            }
+        // 同步交强险
+        TKBzKindVo bzKindVo = preciseInitParam.getBzKindVo();
+        if (bzKindVo == null) {
+            bzKindVo = new TKBzKindVo();
+            preciseInitParam.setBzKindVo(bzKindVo);
+        }
+        bzKindVo.setIsSelect("1"); // 选择交纳交强险
+
+        // 同步交强险时间信息,从前端参数获取
+        RiskInfoVo commonCiRiskInfoVo = commonQuoteVo.getCiRiskInfoVo();
+        if (commonCiRiskInfoVo != null) {
+            // 交强险的时间
+            date.setStartDateBZ(commonCiRiskInfoVo.getStartDate());
+            date.setEndDateBZ(commonCiRiskInfoVo.getEndDate());
+        }
 
-            // 同步车船税信息,从前端参数获取
-            VehicleAndVesselTaxVo vehicleAndVesselTax = commonQuoteVo.getVehicleAndVesselTaxVo();
-            if (vehicleAndVesselTax != null) {
-                // 车船税标志
-                String taxRelifFlag = vehicleAndVesselTax.getTaxRelifFlag();
-                // 转换为保司的参数
-                if (taxRelifFlag.equals("1")) {
-                    carTaxInfo.setTaxFlag("T");
-                } else if (taxRelifFlag.equals("2")) {
-                    carTaxInfo.setTaxFlag("E");
-                } else if (taxRelifFlag.equals("3")) {
-                    carTaxInfo.setTaxFlag("C");
-                } else if (taxRelifFlag.equals("4")) {
-                    carTaxInfo.setTaxFlag("P");
-                }
+        // 同步车船税
+        TKCarTaxInfo carTaxInfo = preciseInitParam.getCarTaxInfo();
+        if (carTaxInfo == null) {
+            carTaxInfo = new TKCarTaxInfo();
+            preciseInitParam.setCarTaxInfo(carTaxInfo);
+        }
+        // 同步车船税信息,从前端参数获取
+        VehicleAndVesselTaxVo vehicleAndVesselTax = commonQuoteVo.getVehicleAndVesselTaxVo();
+        if (vehicleAndVesselTax != null) {
+            // 车船税标志
+            String taxRelifFlag = vehicleAndVesselTax.getTaxRelifFlag();
+            // 转换为保司的参数
+            if (taxRelifFlag.equals("1")) {
+                carTaxInfo.setTaxFlag("T");
+            } else if (taxRelifFlag.equals("2")) {
+                carTaxInfo.setTaxFlag("E");
+            } else if (taxRelifFlag.equals("3")) {
+                carTaxInfo.setTaxFlag("C");
+            } else if (taxRelifFlag.equals("4")) {
+                carTaxInfo.setTaxFlag("P");
             }
         }
 
 
-        {
-            // 同步商业险时间信息,从前端参数获取
-            RiskInfoVo commonBiRiskInfoVo = commonQuoteVo.getBiRiskInfoVo();
-            if (commonBiRiskInfoVo != null) {
-                date.setStartDateCI(commonBiRiskInfoVo.getStartDate());
-                date.setEndDateCI(commonBiRiskInfoVo.getEndDate());
-            } else {
-                date.setStartDateCI(date.getStartDateCI());
-                date.setEndDateCI(date.getEndDateCI());
-            }
-
-            // 获取保司默认选中的商险信息
-            Map<String, TKCiKindsVo> tkCiKindsVoMap = new HashMap<>();
-            for (TKCiKindsVo tkCiKindVo : preciseInitParam.getCiKindsVo()) {
-                String isSelect = tkCiKindVo.getIsSelect();
-                BigDecimal premium = tkCiKindVo.getPremium();
+        // 同步商业险时间信息,从前端参数获取
+        RiskInfoVo commonBiRiskInfoVo = commonQuoteVo.getBiRiskInfoVo();
+        if (commonBiRiskInfoVo != null) {
+            date.setStartDateCI(commonBiRiskInfoVo.getStartDate());
+            date.setEndDateCI(commonBiRiskInfoVo.getEndDate());
+        } else {
+            date.setStartDateCI(date.getStartDateCI());
+            date.setEndDateCI(date.getEndDateCI());
+        }
 
-                if (isSelect != null && isSelect.equals("1") && premium != null && premium.compareTo(BigDecimal.ZERO) == 0) {
-                    continue;
-                }
+        // 获取保司默认选中的商险信息
+        Map<String, TKCiKindsVo> tkCiKindsVoMap = new HashMap<>();
+        for (TKCiKindsVo tkCiKindVo : preciseInitParam.getCiKindsVo()) {
+            String isSelect = tkCiKindVo.getIsSelect();
+            BigDecimal premium = tkCiKindVo.getPremium();
 
-                tkCiKindVo.setIsSelect("0");
-                tkCiKindVo.setQuoteAmount(BigDecimal.ZERO);
-                tkCiKindVo.setQuoteAmountCN("不投保");
-                tkCiKindVo.setPremium(BigDecimal.ZERO);
-                tkCiKindVo.setTotalPremium(BigDecimal.ZERO);
-                tkCiKindsVoMap.put(tkCiKindVo.getKindCode(), tkCiKindVo);
+            if (isSelect != null && isSelect.equals("1") && premium != null && premium.compareTo(BigDecimal.ZERO) == 0) {
+                continue;
             }
 
-            // 根据公司系统选择的险种进行覆盖
-            List<KindInfoVo> commonBiKindInfoVos = commonQuoteVo.getKindInfoVo();
-            if (CollectionUtils.isNotEmpty(commonBiKindInfoVos)) {
-                for (KindInfoVo commonBiKindInfoVo : commonBiKindInfoVos) {
-                    if (tkCiKindsVoMap.isEmpty() || tkCiKindsVoMap.get(commonBiKindInfoVo.getKindCode()) == null) {
-                        continue;
-                    }
-                    TKCiKindsVo tkCiKindVo = tkCiKindsVoMap.get(commonBiKindInfoVo.getKindCode());
-                    tkCiKindVo.setIsSelect("1");
-                    tkCiKindVo.setQuoteAmount(new BigDecimal(commonBiKindInfoVo.getAmount()));
-                    tkCiKindVo.setQuoteAmountCN(commonBiKindInfoVo.getAmount());
-                    tkCiKindVo.setUnitAmount(new BigDecimal(commonBiKindInfoVo.getUnitAmount()));
-                    tkCiKindVo.setUnitAmountCN(commonBiKindInfoVo.getUnitAmount());
-                    String quantity = commonBiKindInfoVo.getQuantity();
-                    String serviceTimes = commonBiKindInfoVo.getServiceTimes();
-                    if (StringUtils.isNotBlank(quantity)) {
-                        tkCiKindVo.setQuantity(quantity);
-                    } else if (StringUtils.isNotBlank(serviceTimes)) {
-                        tkCiKindVo.setQuantity(serviceTimes);
-                    }
+            tkCiKindVo.setBjSelect("0");
+            tkCiKindVo.setDeductibleAmount(BigDecimal.ZERO);
+            tkCiKindVo.setIsSelect("0");
+            tkCiKindVo.setQuantity(0);
+            tkCiKindVo.setQuoteAmountCN("不投保");
+            // tkCiKindVo.setQuoteAmount(BigDecimal.ZERO); // 不用管
+            // tkCiKindVo.setPremium(BigDecimal.ZERO); // 不用管
+            // tkCiKindVo.setTotalPremium(BigDecimal.ZERO);// 不用管
+            tkCiKindsVoMap.put(tkCiKindVo.getKindCode(), tkCiKindVo);
+        }
 
-                    String deductibleRate = commonBiKindInfoVo.getDeductibleRate();
-                    tkCiKindVo.setDeductibleAmount(null); // todo
+        // 根据公司系统选择的险种进行覆盖
+        List<KindInfoVo> commonBiKindInfoVos = commonQuoteVo.getKindInfoVo();
+        if (CollectionUtils.isNotEmpty(commonBiKindInfoVos)) {
+            for (KindInfoVo commonBiKindInfoVo : commonBiKindInfoVos) {
+                if (tkCiKindsVoMap.isEmpty() || tkCiKindsVoMap.get(commonBiKindInfoVo.getKindCode()) == null) {
+                    continue;
+                }
+                TKCiKindsVo tkCiKindVo = tkCiKindsVoMap.get(commonBiKindInfoVo.getKindCode());
+                tkCiKindVo.setIsSelect("1");
+                tkCiKindVo.setQuoteAmount(commonBiKindInfoVo.getAmount());
+                tkCiKindVo.setQuoteAmountCN(commonBiKindInfoVo.getAmount());
+                // tkCiKindVo.setUnitAmount(new BigDecimal(commonBiKindInfoVo.getUnitAmount()));
+                // tkCiKindVo.setUnitAmountCN(commonBiKindInfoVo.getUnitAmount());
+
+
+                String quantity = commonBiKindInfoVo.getQuantity();
+                String serviceTimes = commonBiKindInfoVo.getServiceTimes();
+                if (StringUtils.isNotBlank(quantity)) {
+                    tkCiKindVo.setQuantity(Integer.parseInt(quantity));
+                } else if (StringUtils.isNotBlank(serviceTimes)) {
+                    tkCiKindVo.setQuantity(Integer.parseInt(serviceTimes));
                 }
+
             }
         }
 
-        {
-            // 同步驾意险, 系统有选择驾意险进行匹配覆盖(泰康要求必须有驾意险)
-            Map<String, TKCarPlanInfo> carPlanInfoMap = Optional.ofNullable(preciseInitParam.getDriverAccidentVo().getCarPlanInfoList()).orElseGet(Collections::emptyList).stream().collect(Collectors.toMap(TKCarPlanInfo::getPlanCode, Function.identity()));
-            TKDriverAccidentVo driverAccidentVo = preciseInitParam.getDriverAccidentVo();// 泰康系统默认的驾意险信息
-            List<AccidentalDrivingVo> accidentalDrivings = commonQuoteVo.getAccidentalDrivings(); // 公司系统的驾意险参数
-            // 公司系统的驾意险参数为空证明没有选择驾意险
-            if (CollectionUtils.isNotEmpty(accidentalDrivings)) {
-                for (AccidentalDrivingVo accidentalDriving : accidentalDrivings) {
-                    if (carPlanInfoMap.isEmpty() || accidentalDriving.getRiskCode() == null) {
-                        continue;
-                    }
-                    TKCarPlanInfo tkCarPlanInfo = carPlanInfoMap.get(accidentalDriving.getProductCode());
-                    driverAccidentVo.setIsSelect("1");
-                    driverAccidentVo.setSelectPlanCode(tkCarPlanInfo.getPlanCode());
-                    driverAccidentVo.setQuoteAmountCN(tkCarPlanInfo.getPlanName());
-                    driverAccidentVo.setPremium(new BigDecimal(tkCarPlanInfo.getSumPremium()));
+
+        // 同步驾意险, 系统有选择驾意险进行匹配覆盖(泰康要求必须有驾意险)
+        Map<String, TKCarPlanInfo> carPlanInfoMap = Optional.ofNullable(preciseInitParam.getDriverAccidentVo().getCarPlanInfoList()).orElseGet(Collections::emptyList).stream().collect(Collectors.toMap(TKCarPlanInfo::getPlanCode, Function.identity()));
+        TKDriverAccidentVo driverAccidentVo = preciseInitParam.getDriverAccidentVo();// 泰康系统默认的驾意险信息
+        List<AccidentalDrivingVo> accidentalDrivings = commonQuoteVo.getAccidentalDrivings(); // 公司系统的驾意险参数
+        // 公司系统的驾意险参数为空证明没有选择驾意险
+        if (CollectionUtils.isNotEmpty(accidentalDrivings)) {
+            for (AccidentalDrivingVo accidentalDriving : accidentalDrivings) {
+                if (carPlanInfoMap.isEmpty() || accidentalDriving.getRiskCode() == null) {
+                    continue;
                 }
-            } else {
-                driverAccidentVo.setIsSelect("0");
-                driverAccidentVo.setQuantity(0);
-                driverAccidentVo.setQuantityCname("不投保");
-                driverAccidentVo.setPremium(BigDecimal.ZERO);
+                TKCarPlanInfo tkCarPlanInfo = carPlanInfoMap.get(accidentalDriving.getProductCode());
+                driverAccidentVo.setIsSelect("1");
+                driverAccidentVo.setSelectPlanCode(tkCarPlanInfo.getPlanCode());
+                driverAccidentVo.setQuoteAmountCN(tkCarPlanInfo.getPlanName());
+                driverAccidentVo.setPremium(new BigDecimal(tkCarPlanInfo.getSumPremium()));
             }
+        } else {
+            driverAccidentVo.setIsSelect("0");
+            driverAccidentVo.setQuantity(0);
+            driverAccidentVo.setQuantityCname("不投保");
+            driverAccidentVo.setPremium(BigDecimal.ZERO);
+            driverAccidentVo.setNonCarStartDate(null);
+            driverAccidentVo.setNonCarEndDate(null);
         }
 
         // 泰乐途, 默认不投保
@@ -1156,8 +1156,6 @@ public class TKSimpleService {
         preciseInitParam.setTplatLoginKey(tplatLoginKey);
         preciseInitParam.setOrderID(mainOrderId);
         preciseInitParam.setRiskType("0808");
-        // orderVersion = 1
-        preciseInitParam.setOrderVersion("1");
         PreciseInitResult preciseQuoteResult = httpService.preciseInitToQuote(session.getToken(), preciseInitParam);
 
         if (preciseQuoteResult == null) {

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

@@ -82,11 +82,23 @@ public class TaiShanCrawlerQuoteResultsVoBuild {
                     .fluentPut("scoreName","整单预期赔付率(GQ)")
                     .fluentPut("scoreKey","exRatio")
                     .fluentPut("exRatio", riskResponse.getResult().getExRatio()));
-
             scoreJson.add(new JSONObject()
                     .fluentPut("scoreName","风险评级(G)")
                     .fluentPut("scoreKey","pvalue")
                     .fluentPut("pvalue", riskResponse.getResult().getPvalue()));
+
+            scoreJson.add(new JSONObject()
+                    .fluentPut("scoreName","平台评分")
+                    .fluentPut("scoreKey","ptScore")
+                    .fluentPut("ptScore", riskResponse.getResult().getPtScore()));
+            scoreJson.add(new JSONObject()
+                    .fluentPut("scoreName","商业综合评分")
+                    .fluentPut("scoreKey","comPoints")
+                    .fluentPut("comPoints", riskResponse.getResult().getComPoints()));
+            scoreJson.add(new JSONObject()
+                    .fluentPut("scoreName","整体精算折扣")
+                    .fluentPut("scoreKey","entireActuaryDiscount")
+                    .fluentPut("entireActuaryDiscount", riskResponse.getResult().getEntireActuaryDiscount()));
         }
 
         quoteResultsVo.getScoreVo().setScoreJson(scoreJson);

+ 71 - 30
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/build/ZiJinCrawlerQuoteResultsVoBuild.java

@@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
+import com.jzg.commons.entity.po.InsFeeOrders;
+import com.jzg.commons.entity.quote.vo.ExpenseFactor;
 import com.jzg.commons.entity.quote.vo.KindInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.RiskInfoVo;
@@ -13,9 +15,11 @@ import com.jzg.commons.util.DateTimeUtils;
 import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.zijin.api.constant.enums.RiskCodeEnum;
 import com.jzg.quotation.zijin.crawler.entity.response.ZiJinCrawlerQuotationResponse;
+import com.jzg.quotation.zijin.crawler.entity.response.ZiJinCrawlerSaveProposalResponse;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.util.ObjectUtils;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -49,20 +53,20 @@ public class ZiJinCrawlerQuoteResultsVoBuild {
      * 处理报价结果
      *
      * @param ordersNo
-     * @param quoteVo
      * @param ziJinCrawlerQuotationResponse
+     * @param ziJinCrawlerSaveProposalResponse
      * @return QuoteResultsVo
      */
-    public static QuoteResultsVo buildQuoteResultsVo(String ordersNo, QuoteVo quoteVo, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse) {
+    public static QuoteResultsVo buildQuoteResultsVo(String ordersNo, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse, ZiJinCrawlerSaveProposalResponse ziJinCrawlerSaveProposalResponse) {
         QuoteResultsVo quoteResultsVo = new QuoteResultsVo();
         quoteResultsVo.setOrdersNo(ordersNo);
 
         if (ziJinCrawlerQuotationResponse.getItemKindList() != null) {
-            // 设置交强险信息
+            // 设置交强险投保时间信息
             quoteResultsVo.setCiRiskInfoVo(buildCiRiskInfoVo(ziJinCrawlerQuotationResponse));
-            // 设置商业险信息
+            // 设置商业险投保时间信息
             quoteResultsVo.setBiRiskInfoVo(buildBiRiskInfoVo(ziJinCrawlerQuotationResponse));
-            // 设置驾意险信息
+            // 设置驾意险投保时间信息
             // quoteResultsVo.setJyRiskInfoVo(buildJyRiskInfoVo(ziJinCrawlerQuotationResponse));
             // 设置险种明细列表
             quoteResultsVo.setKindInfoVo(buildKindInfoVoList(ziJinCrawlerQuotationResponse));
@@ -72,10 +76,19 @@ public class ZiJinCrawlerQuoteResultsVoBuild {
         buildPremium(quoteResultsVo, ziJinCrawlerQuotationResponse);
 
         // 设置投保单号
-        // if (ziJinCrawlerQuotationResponse.getBasePart() != null) {
-        //     quoteResultsVo.setCiPolicyNumber(ziJinCrawlerQuotationResponse.getBasePart().getProposalCheckNo());
-        //     quoteResultsVo.setBiPolicyNumber(ziJinCrawlerQuotationResponse.getBasePart().getProposalCheckNo());
-        // }
+        if (ziJinCrawlerSaveProposalResponse != null && ziJinCrawlerSaveProposalResponse.getData() != null) {
+            ZiJinCrawlerSaveProposalResponse.Data data = ziJinCrawlerSaveProposalResponse.getData();
+            quoteResultsVo.setCiPolicyNumber(data.getProposalNoCI());
+            quoteResultsVo.setBiPolicyNumber(data.getProposalNo());
+
+            // 费用信息
+            if (data.getFeeImformationDto() != null) {
+                InsFeeOrders insFeeOrders = new InsFeeOrders();
+                insFeeOrders.setJqCommissionPremium(new BigDecimal(data.getFeeImformationDto().getJqFeeRatio()));
+                insFeeOrders.setSyCommissionPremium(new BigDecimal(data.getFeeImformationDto().getSyFeeRatio()));
+                quoteResultsVo.setFeeOrders(insFeeOrders);
+            }
+        }
 
         // 设置警告消息(预核保消息)
         if (ziJinCrawlerQuotationResponse.getBasePart() != null) {
@@ -87,6 +100,16 @@ public class ZiJinCrawlerQuoteResultsVoBuild {
         // 设置评分
         quoteResultsVo.setScoreVo(ZiJinCrawlerQuoteResultsVoBuild.buildScoreVo(ziJinCrawlerQuotationResponse));
 
+        // 构建因子
+        // ZiJinCrawlerQuotationResponse.PriceInfoList priceInfo = ziJinCrawlerQuotationResponse.getPriceInfoList().get(0);
+        // ExpenseFactor expenseFactor = new ExpenseFactor(null, priceInfo.getEffectNameUPOne(), priceInfo.getEffectValueUPOne());
+        // ExpenseFactor expenseFactor2 = new ExpenseFactor(null, priceInfo.getEffectNameUPTwo(), priceInfo.getEffectValueUPTwo());
+        // ExpenseFactor expenseFactor3 = new ExpenseFactor(null, priceInfo.getEffectNameUPThree(), priceInfo.getEffectValueUPThree());
+        // ExpenseFactor expenseFactor4 = new ExpenseFactor(null, priceInfo.getEffectNameDownFour(), priceInfo.getEffectValueDownFour());
+        // ExpenseFactor expenseFactor5 = new ExpenseFactor(null, priceInfo.getEffectNameDownFive(), priceInfo.getEffectValueDownFive());
+        // ExpenseFactor expenseFactor6 = new ExpenseFactor(null, priceInfo.getEffectNameDownSix(), priceInfo.getEffectValueDownSix());
+        // quoteResultsVo.setExpenseFactors();
+
         // 设置报价状态:待核保
         quoteResultsVo.setQuoteStatusEnum(InsOrderStatusEnum.WAIT_AUDIT);
 
@@ -289,7 +312,7 @@ public class ZiJinCrawlerQuoteResultsVoBuild {
         scoreArray.add(new JSONObject()
                 .fluentPut("scoreName", "连续承保期间出险次数")
                 .fluentPut("scoreKey", "claimTimes")
-                .fluentPut("score", ciProfitDetailData  != null ? ciProfitDetailData.getClaimTimes() : null));
+                .fluentPut("score", ciProfitDetailData != null ? ciProfitDetailData.getClaimTimes() : null));
         scoreArray.add(new JSONObject()
                 .fluentPut("scoreName", "总折扣")
                 .fluentPut("scoreKey", "initialELR")
@@ -359,26 +382,44 @@ public class ZiJinCrawlerQuoteResultsVoBuild {
         scoreVo.setScoreJson(scoreArray);
 
         // 影响因子
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName", "NCD")// 升费因子名称
-                .fluentPut("scoreKey", "effectValueUPOne")
-                .fluentPut("score", priceInfo.getEffectValueUPOne()));// 因子比例
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName", "性别年龄")
-                .fluentPut("scoreKey", "effectValueUPTwo")
-                .fluentPut("score", priceInfo.getEffectValueUPTwo()));
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName", "车牌")
-                .fluentPut("scoreKey", "effectValueUPThree")
-                .fluentPut("score", priceInfo.getEffectValueUPThree()));
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName", "是否投保医保外用药")
-                .fluentPut("scoreKey", "effectValueDownFour")
-                .fluentPut("score", priceInfo.getEffectValueDownFour()));
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName", "平台分")
-                .fluentPut("scoreKey", "effectValueDownFive")
-                .fluentPut("score", priceInfo.getEffectValueDownFive()));
+        // 升费因子名称       // 因子比例
+        if (StringUtils.isNotEmpty(priceInfo.getEffectNameUPOne())) {
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName", priceInfo.getEffectNameUPOne())
+                    .fluentPut("scoreKey", "effectValueUPOne")
+                    .fluentPut("score", priceInfo.getEffectValueUPOne()));
+        }
+        if (StringUtils.isNotEmpty(priceInfo.getEffectNameUPTwo())) {
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName", priceInfo.getEffectNameUPTwo())
+                    .fluentPut("scoreKey", "effectValueUPTwo")
+                    .fluentPut("score", priceInfo.getEffectValueUPTwo()));
+        }
+        if (StringUtils.isNotEmpty(priceInfo.getEffectNameUPThree())) {
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName", priceInfo.getEffectNameUPThree())
+                    .fluentPut("scoreKey", "effectValueUPThree")
+                    .fluentPut("score", priceInfo.getEffectValueUPThree()));
+        }
+        // 降费因子名称       // 因子比例
+        if (StringUtils.isNotEmpty(priceInfo.getEffectNameDownFour())) {
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName", priceInfo.getEffectNameDownFour())
+                    .fluentPut("scoreKey", "effectValueDownFour")
+                    .fluentPut("score", priceInfo.getEffectValueDownFour()));
+        }
+        if (StringUtils.isNotEmpty(priceInfo.getEffectNameDownFive())) {
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName", priceInfo.getEffectNameDownFive())
+                    .fluentPut("scoreKey", "effectValueDownFive")
+                    .fluentPut("score", priceInfo.getEffectValueDownFive()));
+        }
+        if (StringUtils.isNotEmpty(priceInfo.getEffectNameDownSix())) {
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName", priceInfo.getEffectNameDownSix())
+                    .fluentPut("scoreKey", "effectValueDownSix")
+                    .fluentPut("score", priceInfo.getEffectValueDownSix()));
+        }
         scoreVo.setScoreJson(scoreArray);
         return scoreVo;
     }

+ 6 - 3
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/build/ZiJinCrawlerSaveQuoteInfoRequestBuild.java

@@ -32,17 +32,17 @@ public class ZiJinCrawlerSaveQuoteInfoRequestBuild {
      *
      * @return 构建完成的保存报价信息请求对象
      */
-    public ZiJinCrawlerSaveQuoteInfoRequest buildSaveQuoteInfoRequest(QuoteVo quoteVo, ZiJinCrawlerQuotationRequest ziJinCrawlerQuotationRequest, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse) {
+    public ZiJinCrawlerSaveQuoteInfoRequest buildSaveQuoteInfoRequest(QuoteVo quoteVo, String orderNo, ZiJinCrawlerQuotationRequest ziJinCrawlerQuotationRequest, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse) {
         ZiJinCrawlerSaveQuoteInfoRequest ziJinCrawlerSaveQuoteInfoRequest = new ZiJinCrawlerSaveQuoteInfoRequest();
 
         // 设置代理人代码
         ziJinCrawlerSaveQuoteInfoRequest.setAgentCode(ziJinCrawlerQuotationRequest.getBaseInfo().getAgentCode());
 
         // 设置订单ID
-        ziJinCrawlerSaveQuoteInfoRequest.setOrderId(ziJinCrawlerQuotationResponse.getOrderId());
+        ziJinCrawlerSaveQuoteInfoRequest.setOrderId(ziJinCrawlerQuotationRequest.getOrderId());
 
         // 设置订单号
-        ziJinCrawlerSaveQuoteInfoRequest.setOrderNo(ziJinCrawlerQuotationResponse.getOrderNo());
+        ziJinCrawlerSaveQuoteInfoRequest.setOrderNo(orderNo);
 
         // 设置基础信息
         ziJinCrawlerSaveQuoteInfoRequest.setBaseInfo(buildSaveBaseInfo(quoteVo, ziJinCrawlerQuotationRequest, ziJinCrawlerQuotationResponse));
@@ -184,6 +184,7 @@ public class ZiJinCrawlerSaveQuoteInfoRequestBuild {
                 .carLoanFlag(carInfo.getCarLoanFlag())
                 .certificateDate(carInfo.getCertificateDate() != null ? carInfo.getCertificateDate() : "")
                 .chgOwnerFlag(carInfo.getChgOwnerFlag())
+                .colorCode(carInfo.getColorCode())
                 // .completekerbmass(carInfo.getCompletekerbmass() != null ? Integer.parseInt(carInfo.getCompletekerbmass()) : 0)
                 .completekerbmass(carInfo.getCompletekerbmass())
                 .ecdemicVehicleFlag(carInfo.getEcdemicVehicleFlag() != null ? carInfo.getEcdemicVehicleFlag() : "0")
@@ -474,6 +475,8 @@ public class ZiJinCrawlerSaveQuoteInfoRequestBuild {
                 .handerCode(ziJinCrawlerQuotationRequest.getBaseInfo().getHanderCode())
                 .handerName(ziJinCrawlerQuotationRequest.getBaseInfo().getHanderName())
                 .calculateFlag(ziJinCrawlerQuotationRequest.getBaseInfo().getCalculateFlag())
+                // .proposalNo("1050AA140105260004G3")
+                // .proposalNoCI("10590A14010526000HG8") // todo: 需要找到这2个单号哪来的?没有回导致保存保单接口失败
                 .isCI(quoteVo.getCiRiskInfoVo() != null)
                 .isBI(quoteVo.getBiRiskInfoVo() != null)
                 .riskCodeEnum(ZiJinCrawlerSaveQuoteInfoRequest.BaseInfo.RiskCodeEnum.builder()

+ 2 - 1
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/component/ZiJinCrawlerRequestComponent.java

@@ -314,7 +314,8 @@ public class ZiJinCrawlerRequestComponent {
     public ZiJinCrawlerSaveProposalResponse saveProposal(ZiJinCrawlerSaveProposalRequest ziJinCrawlerSaveProposalRequest, HttpHeaders headers) throws IOException {
         String token = headers.getFirst("Authorization");
         HttpHeaders httpHeaders = setHttpHeaders(token);
-
+        httpHeaders.remove("Cache-Control");
+        log.info("请求header信息:{}", httpHeaders);
         String jsonString = JSON.toJSONString(ziJinCrawlerSaveProposalRequest);
         log.info("ziJinCrawlerSaveProposalRequest请求参数的值:{}", jsonString);
         ResponseEntity<ZiJinCrawlerSaveProposalResponse> responseEntity = requestComponent.post(RequestUrl.SAVE_PROPOSAL_ORDER.getRequestUrl(ziJinCrawlerProperties.getBaseUrl()), jsonString, ZiJinCrawlerSaveProposalResponse.class, httpHeaders);

+ 1 - 1
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/entity/ZiJinCrawlerConfigureParameters.java

@@ -39,7 +39,7 @@ public class ZiJinCrawlerConfigureParameters implements ConfigureParameters {
     /**
      * 代理code
      */
-    private String 代理code;
+    private String agentCode;
 
     /**
      * 渠道: 比如 个人代理

+ 9 - 0
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/entity/request/ZiJinCrawlerSaveQuoteInfoRequest.java

@@ -271,6 +271,12 @@ public class ZiJinCrawlerSaveQuoteInfoRequest implements Serializable {
         @JsonProperty("proposalCheckNo")
         private String proposalCheckNo;
 
+        @JsonProperty("proposalNo")
+        private String proposalNo;
+
+        @JsonProperty("proposalNoCI")
+        private String proposalNoCI;
+
         @JsonProperty("xbFlag")
         private String xbFlag;
 
@@ -936,6 +942,9 @@ public class ZiJinCrawlerSaveQuoteInfoRequest implements Serializable {
 
         @JsonProperty("modelEnergyType")
         private String modelEnergyType;
+
+        @JsonProperty("colorCode")
+        private String colorCode;
     }
 
     /**

+ 3 - 1
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/crawler/service/ZiJinCrawlerOrderService.java

@@ -14,14 +14,16 @@ public interface ZiJinCrawlerOrderService {
 
     /**
      * 保存紫金财险爬虫订单
+     *
      * @param quoteVo
      * @param ziJinCrawlerQuotationResponse
      * @param success
      */
-    void save(QuoteVo quoteVo, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse, ZiJinCrawlerSaveProposalResponse ziJinCrawlerSaveProposalResponse, String orderId, boolean success);
+    void save(QuoteVo quoteVo, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse, ZiJinCrawlerSaveProposalResponse ziJinCrawlerSaveProposalResponse, String orderNo, String orderId, boolean success);
 
     /**
      * 根据系统内部订单号查询紫金财险爬虫订单
+     *
      * @param ordersNo
      * @return ZiJinCrawlerOrder
      */

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

@@ -34,19 +34,18 @@ public class ZiJinCrawlerOrderServiceImpl implements ZiJinCrawlerOrderService {
      * @param success
      */
     @Override
-    public void save(QuoteVo quoteVo, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse, ZiJinCrawlerSaveProposalResponse ziJinCrawlerSaveProposalResponse, String orderId, boolean success) {
+    public void save(QuoteVo quoteVo, ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse, ZiJinCrawlerSaveProposalResponse ziJinCrawlerSaveProposalResponse, String orderNo, String orderId, boolean success) {
         ZiJinCrawlerOrder order = new ZiJinCrawlerOrder();
         order.setOrdersNo(quoteVo.getOrder().getOrdersNo());
-        order.setOrderNo(ObjectUtils.isEmpty(ziJinCrawlerQuotationResponse.getOrderNo()) ? ziJinCrawlerSaveProposalResponse.getData().getOrderNo() : ziJinCrawlerQuotationResponse.getOrderNo());
+        // 报价接口没有返回订单号, 报价保存方法save方法成功后返回订单号
+        order.setOrderNo(orderNo);
         order.setBusUniqueId(orderId);
         order.setQuoteSuccess(success);
-        if (success && ziJinCrawlerSaveProposalResponse != null) {
+        if (success) {
             order.setCiApplyNo(ziJinCrawlerSaveProposalResponse.getData().getProposalNoCI());
             order.setCiPolicyNo(ziJinCrawlerSaveProposalResponse.getData().getPolicyNoCI());
-            // order.setCiPremium(ziJinCrawlerQuotationResponse.getData().getTrafficPolicy().getPremium());
             order.setSyApplyNo(ziJinCrawlerSaveProposalResponse.getData().getProposalNo());
             order.setBiPolicyNo(ziJinCrawlerSaveProposalResponse.getData().getPolicyNo());
-            // order.setBiPremium(ziJinCrawlerQuotationResponse.getData().getBusinessPolicy().getPremium());
         }
 
         order.setCreateTime(LocalDateTime.now());

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

@@ -22,7 +22,6 @@ import com.jzg.quotation.commons.utils.DateTimeUtil;
 import com.jzg.quotation.commons.utils.TimeProcessing;
 import com.jzg.quotation.zijin.api.constant.enums.MotorVehicleInsuranceEnum;
 import com.jzg.quotation.zijin.api.constant.enums.RiskCodeEnum;
-import com.jzg.quotation.zijin.api.entity.request.UploadImageInfoListRequest;
 import com.jzg.quotation.zijin.crawler.build.ZiJinCrawlerQuoteRequestBuild;
 import com.jzg.quotation.zijin.crawler.build.ZiJinCrawlerQuoteResultsVoBuild;
 import com.jzg.quotation.zijin.crawler.build.ZiJinCrawlerSaveQuoteInfoRequestBuild;
@@ -181,7 +180,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
             }
             ziJinCrawlerQuotationRequest.setItemKindList(buildItemKindList(quoteVo, actualValue));
 
-            // 设置附加保单信息列表
+            // 设置附加保单信息列表(推荐产品、驾意险、健康险、责任险、家财险、企业财产险)
             ziJinCrawlerQuotationRequest.setCarPolicySubInfoList(buildCarPolicySubInfoList(quoteVo));
 
             // 设置车辆信息
@@ -201,8 +200,6 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
             log.info("ziJinCrawlerQuotationRequest参数:{}", JSON.toJSONString(ziJinCrawlerQuotationRequest));
             ZiJinCrawlerQuotationResponse ziJinCrawlerQuotationResponse = ziJinCrawlerRequestComponent.quotation(ziJinCrawlerQuotationRequest, headers);
             log.info("ziJinCrawlerQuotationResponse响应:{}", JSON.toJSONString(ziJinCrawlerQuotationResponse));
-            // 设置紫金财险爬虫订单号,后面保存到数据库中
-            ziJinCrawlerQuotationResponse.setOrderNo(ziJinCrawlerGetOrderNoResponse.getOrderNo());
 
             // 重复投保,延保
             if (ResponseCode.R_0002.getCode().equals(ziJinCrawlerQuotationResponse.getRtnCode()) && ziJinCrawlerQuotationResponse.getRtnMsg() != null && ziJinCrawlerQuotationResponse.getRtnMsg().contains("重复投保")) {
@@ -238,12 +235,12 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
 
             // 4.0 处理报价失败
             if (!ResponseCode.R_0000.getCode().equals(ziJinCrawlerQuotationResponse.getRtnCode())) {
-                ziJinCrawlerOrderService.save(quoteVo, ziJinCrawlerQuotationResponse, null, ziJinCrawlerQuotationRequest.getOrderId(), false);
+                ziJinCrawlerOrderService.save(quoteVo, ziJinCrawlerQuotationResponse, null, null, ziJinCrawlerQuotationRequest.getOrderId(), false);
                 return ZiJinCrawlerQuoteResultsVoBuild.buildQuoteFailResultsVo(ziJinCrawlerQuotationResponse);
             } else {
                 // 报价成功
                 // 保存报价信息
-                ZiJinCrawlerSaveQuoteInfoRequest ziJinCrawlerSaveQuoteInfoRequest = ziJinCrawlerSaveQuoteInfoRequestBuild.buildSaveQuoteInfoRequest(quoteVo, ziJinCrawlerQuotationRequest, ziJinCrawlerQuotationResponse);
+                ZiJinCrawlerSaveQuoteInfoRequest ziJinCrawlerSaveQuoteInfoRequest = ziJinCrawlerSaveQuoteInfoRequestBuild.buildSaveQuoteInfoRequest(quoteVo, ziJinCrawlerGetOrderNoResponse.getOrderNo(), ziJinCrawlerQuotationRequest, ziJinCrawlerQuotationResponse);
                 log.info("ziJinCrawlerSaveQuoteInfoRequest参数:{}", JSON.toJSONString(ziJinCrawlerSaveQuoteInfoRequest));
                 ZiJinCrawlerSaveQuoteInfoResponse ziJinCrawlerSaveQuoteInfoResponse = ziJinCrawlerRequestComponent.saveQuoteInformation(ziJinCrawlerSaveQuoteInfoRequest, headers);
                 log.info("ziJinCrawlerSaveQuoteInfoResponse响应:{}", JSON.toJSONString(ziJinCrawlerSaveQuoteInfoResponse));
@@ -256,8 +253,8 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
                 ZiJinCrawlerSaveProposalResponse ziJinCrawlerSaveProposalResponse = ziJinCrawlerRequestComponent.saveProposal(ziJinCrawlerSaveProposalRequest, headers);
                 log.info("ziJinCrawlerSaveProposalResponse参数的值:{}", JSON.toJSONString(ziJinCrawlerSaveProposalResponse));
 
-                ziJinCrawlerOrderService.save(quoteVo, ziJinCrawlerQuotationResponse, ziJinCrawlerSaveProposalResponse, ziJinCrawlerQuotationRequest.getOrderId(), true);
-                return ZiJinCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo.getOrder().getOrdersNo(), quoteVo, ziJinCrawlerQuotationResponse);
+                ziJinCrawlerOrderService.save(quoteVo, ziJinCrawlerQuotationResponse, ziJinCrawlerSaveProposalResponse, ziJinCrawlerSaveQuoteInfoResponse.getOrderNo(), ziJinCrawlerQuotationRequest.getOrderId(), true);
+                return ZiJinCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo.getOrder().getOrdersNo(), ziJinCrawlerQuotationResponse, ziJinCrawlerSaveProposalResponse);
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -292,7 +289,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
 
         UnderwritingResultsVo underwritingResultsVo = new UnderwritingResultsVo();
         // 核保成功
-        if ("0000".equals(ziJinCrawlerUnderwritingResponse.getRtnCode())) {
+        if ("0000" .equals(ziJinCrawlerUnderwritingResponse.getRtnCode())) {
             underwritingResultsVo.setUnderwritingStatus(InsOrderStatusEnum.PAY_PENDING);
             underwritingResultsVo.setJqApplyNo(ziJinCrawlerUnderwritingResponse.getData().getResultObj().getProposalNoCI());
             underwritingResultsVo.setSyApplyNo(ziJinCrawlerUnderwritingResponse.getData().getResultObj().getProposalNo());
@@ -342,7 +339,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
             log.info("ziJinCrawlerPaymentLinkResponse参数的值:{}", JSON.toJSONString(ziJinCrawlerPaymentLinkResponse));
             PaymentLinkResultsVo paymentLinkResultsVo = new PaymentLinkResultsVo();
             // 支付链接获取成功
-            if ("0000".equals(ziJinCrawlerPaymentLinkResponse.getRtnCode())) {
+            if ("0000" .equals(ziJinCrawlerPaymentLinkResponse.getRtnCode())) {
                 paymentLinkResultsVo.setPayLinkStatus(true);
                 paymentLinkResultsVo.setPaymentLink(ziJinCrawlerPaymentLinkResponse.getWechatUrl());
             } else {
@@ -435,7 +432,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
                 ZiJinCrawlerImageUploadResponse ziJinCrawlerImageUploadResponse = ziJinCrawlerRequestComponent.uploadImage(ziJinCrawlerImageUploadRequest, headers);
                 log.info("影像上传响应,订单号:{},响应:{}", ziJinCrawlerOrder.getOrderNo(), JSON.toJSONString(ziJinCrawlerImageUploadResponse));
 
-                if ("0000".equals(ziJinCrawlerImageUploadResponse.getRtnCode())) {
+                if ("0000" .equals(ziJinCrawlerImageUploadResponse.getRtnCode())) {
 
                     ZiJinCrawlerUploadImageInfoListRequest.ItemFileDataListDTO fileInfo = ZiJinCrawlerUploadImageInfoListRequest.ItemFileDataListDTO.builder()
                             .fileId(ziJinCrawlerImageUploadResponse.getFileId())
@@ -530,11 +527,11 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
             log.info("订单状态:{},中文含义:{}", orderStatus, ziJinCrawlerQueryOrderStatusResponse.getData().getContent().get(0).getOrderStatusCN());
             // 将保司返回的订单状态转换为系统定义的订单状态枚举类型
             InsOrderStatusEnum orderStatusEnum = null;
-            if ("5".equals(orderStatus)) {
+            if ("5" .equals(orderStatus)) {
                 orderStatusEnum = InsOrderStatusEnum.valueOf("ORDER_CLOSE");
                 orderStatus = orderStatusEnum.getCode();
             }
-            if ("9".equals(orderStatus)) {
+            if ("9" .equals(orderStatus)) {
                 orderStatusEnum = InsOrderStatusEnum.valueOf("AUDIT_FAIL");
                 orderStatus = orderStatusEnum.getCode();
             }
@@ -781,7 +778,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         ziJinCrawlerGetCarActualValueRequest.setUpdateEnrollDate(quoteVo.getCarInfoVo().getRegisterDate());
         ziJinCrawlerGetCarActualValueRequest.setPurchasePrice(quoteVo.getCarInfoVo().getPurchasePrice());
         ziJinCrawlerGetCarActualValueRequest.setSeatCount(Integer.valueOf(quoteVo.getCarInfoVo().getSeatCount()));
-        ziJinCrawlerGetCarActualValueRequest.setUseNatureCode("02".equals(quoteVo.getCarInfoVo().getCarNatureCode()) ? "85" : quoteVo.getCarInfoVo().getCarNatureCode());
+        ziJinCrawlerGetCarActualValueRequest.setUseNatureCode("02" .equals(quoteVo.getCarInfoVo().getCarNatureCode()) ? "85" : quoteVo.getCarInfoVo().getCarNatureCode());
         ziJinCrawlerGetCarActualValueRequest.setStartDate(quoteVo.getCiRiskInfoVo().getStartDate().substring(0, 10));
         ziJinCrawlerGetCarActualValueRequest.setNewEnergyFlag(quoteVo.getCarInfoVo().getEnergyTypeCode());
         ziJinCrawlerGetCarActualValueRequest.setModelEnergyType(ObjectUtils.isEmpty(quoteVo.getCarInfoVo().getModelEnergyType()) ? "D1" : quoteVo.getCarInfoVo().getModelEnergyType());
@@ -795,8 +792,8 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
      */
     private ZiJinCrawlerQuotationRequest.BaseInfo buildBaseInfo(QuoteVo quoteVo, ZiJinCrawlerConfigureParameters parameters, String operatorCode) {
         ZiJinCrawlerQuotationRequest.BaseInfo baseInfo = new ZiJinCrawlerQuotationRequest.BaseInfo();
-        baseInfo.setAgentCode(parameters.get代理code());
-        baseInfo.setAgreementNo(parameters.get代理code()+"-01");
+        baseInfo.setAgentCode(parameters.getAgentCode());
+        baseInfo.setAgreementNo(parameters.getAgentCode() + "-01");
         baseInfo.setBusinessNature("1");
         baseInfo.setComCode(parameters.getComCode());
         baseInfo.setComName(parameters.getComName());
@@ -881,7 +878,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
             // 证件类型映射,参考Python get_owner_i方法
             // 个人类型(1) -> vehicleOwnerNature="1"
             // 企业类型(2) -> vehicleOwnerNature="5"
-            if ("2".equals(personType)) {
+            if ("2" .equals(personType)) {
                 // 企业
                 carOwnerInfo.setVehicleOwnerNature("5");
                 // 企业证件类型映射
@@ -1019,7 +1016,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         // 证件类型映射
         String identifyType = customerInfo.getIdentifyType();
         String personType = customerInfo.getPersonType();
-        if ("2".equals(personType)) {
+        if ("2" .equals(personType)) {
             // 企业
             insuredItem.setIdentifyType(mapEnterpriseIdentifyType(identifyType));
         } else {
@@ -1029,12 +1026,12 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
 
         // 性别映射
         String gender = customerInfo.getGender();
-        insuredItem.setSex("男".equals(gender) ? "1" : "2");
+        insuredItem.setSex("男" .equals(gender) ? "1" : "2");
 
         // 根据车主性质设置投保人/被保人类型
         // 个人车主("1"): 投保人/被保人都是自然人
         // 企业车主("5"): 投保人是法人,被保人是自然人
-        if ("5".equals(vehicleOwnerNature) && insuredFlag == 2) {
+        if ("5" .equals(vehicleOwnerNature) && insuredFlag == 2) {
             // 企业车主的投保人
             insuredItem.setInsuredNature("4");// 4-法人或其他组织
             insuredItem.setInsuredType("2");
@@ -1406,14 +1403,15 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         for (AccidentalDrivingVo accidentalDriving : quoteVo.getAccidentalDrivings()) {
             ZiJinCrawlerQuotationRequest.CarPolicySubInfoList carPolicySubInfo = new ZiJinCrawlerQuotationRequest.CarPolicySubInfoList();
             carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
-            carPolicySubInfo.setInsureGradeNo("");
-            carPolicySubInfo.setProductCode(accidentalDriving.getProductCode());
+            carPolicySubInfo.setInsureGradeNo("200000736004"); // 前端没传
+            carPolicySubInfo.setProductCode("0736");// 这个值前端传过来的是乱码200000736004%%0736%%%0
+            carPolicySubInfo.setPlanName(accidentalDriving.getProductName());
             carPolicySubInfo.setRiskCode("0736"); // 完了要调整编码,是否要转换
-            carPolicySubInfo.setRiskName("全家安行保"); // 完了要调整成accidentalDriving.getRiskName(),看名称是否传了
-            carPolicySubInfo.setSumAmount(ObjectUtils.isEmpty(accidentalDriving.getSumAmount()) ? null : (int) Double.parseDouble(accidentalDriving.getSumAmount()));
+            carPolicySubInfo.setRiskName("全家安行保"); // 前端没传
+            carPolicySubInfo.setSumAmount(ObjectUtils.isEmpty(accidentalDriving.getSumAmount()) ? 2350000 : (int) Double.parseDouble(accidentalDriving.getSumAmount()));
             carPolicySubInfo.setQuantity(accidentalDriving.getQuantity() == 0 ? "0" : String.valueOf(accidentalDriving.getQuantity()));
             carPolicySubInfo.setIsUseInsured("1");
-            carPolicySubInfo.setSumPremium(ObjectUtils.isEmpty(accidentalDriving.getPremium()) ? null : (int) Double.parseDouble(accidentalDriving.getPremium()));
+            carPolicySubInfo.setSumPremium(ObjectUtils.isEmpty(accidentalDriving.getPremium()) ? 0 : (int) Double.parseDouble(accidentalDriving.getPremium()));
             carPolicySubInfoList.add(carPolicySubInfo);
         }
         return carPolicySubInfoList;
@@ -1630,7 +1628,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
 
         // 新能源标志, 0-燃油,1-新能源
         // carInfoVo.isNewEnergyMark() 这个字段前端没传无法判断
-        vehicleInfo.setNewEnergyFlag(EnergyTypeCode.ENERGY_TYPE_CODE_0.getCode().equals(carInfoVo.getEnergyTypeCode())? "0" : "1");
+        vehicleInfo.setNewEnergyFlag(EnergyTypeCode.ENERGY_TYPE_CODE_0.getCode().equals(carInfoVo.getEnergyTypeCode()) ? "0" : "1");
 
         vehicleInfo.setPower(carInfoVo.getPowerScale());
         vehicleInfo.setModelEnergyType(ObjectUtils.isEmpty(carInfoVo.getModelEnergyType()) ? ziJinCrawlerCarResponse.getVehicleModelInfoList().get(0).getPowerTypeCode() : carInfoVo.getModelEnergyType());
@@ -1652,7 +1650,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         vehicleInfo.setModelCode(modelCode);
 
         // 是否新车未上牌
-        vehicleInfo.setNoLicenseFlag("0".equals(carInfoVo.getIsRegistered()) ? "0" : "1");
+        vehicleInfo.setNoLicenseFlag("0" .equals(carInfoVo.getIsRegistered()) ? "0" : "1");
 
         vehicleInfo.setVehicleId("1");
         vehicleInfo.setVinNo(carInfoVo.getVinNo());
@@ -1661,7 +1659,7 @@ public class ZiJinCrawlerRequestImpl implements ZiJinCrawlerRequest {
         vehicleInfo.setSeatCount(ObjectUtils.isEmpty(carInfoVo.getSeatCount()) ? 0 : Integer.parseInt(carInfoVo.getSeatCount()));
 
         // 使用性质代码
-        vehicleInfo.setUseNatureCode("02".equals(quoteVo.getCarInfoVo().getCarNatureCode()) ? "85" : quoteVo.getCarInfoVo().getCarNatureCode());
+        vehicleInfo.setUseNatureCode("02" .equals(quoteVo.getCarInfoVo().getCarNatureCode()) ? "85" : quoteVo.getCarInfoVo().getCarNatureCode());
         vehicleInfo.setOriCarKindName(carInfoVo.getCarTypeCode());
 
         // 平台车辆代码

+ 2 - 1
tenant/organization/src/main/java/com/jzg/organization/mapper/ReceivableMapper.java

@@ -236,7 +236,8 @@ public interface ReceivableMapper extends BaseMapper<InsPlyIncome> {
     List<CalRes> querySettledAmount(@Param("systemCode") String systemCode,
                                     @Param("settledStartDate") String settledStartDate,
                                     @Param("settledEndDate") String settledEndDate,
-                                    @Param("agreementType") String agreementType);
+                                    @Param("agreementType") String agreementType,
+                                    @Param("invoiceTypes") List<String> invoiceTypes);
 
     /**
      * 查询

+ 20 - 21
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -777,8 +777,9 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 // 驾意险的总跟单费(jy_follow_premium)
                     jyFollowPremium;
             case "5" ->
-                // 交强的总手续费(jq_commission_premium) + 商业的总手续费(sy_commission_premium) + 交强的总跟单费(jq_follow_premium) + 商业的总跟单费(sy_follow_premium)
-                    jqCommissionPremium.add(syCommissionPremium).add(jqFollowPremium).add(syFollowPremium);
+                    // 现在平台不区分车险非车险了,所以都统计到一起
+                // 交强的总手续费(jq_commission_premium) + 商业的总手续费(sy_commission_premium) + 交强的总跟单费(jq_follow_premium) + 商业的总跟单费(sy_follow_premium) + 驾意险的总手续费(jy_commission_premium) + 驾意险的总跟单费(jy_follow_premium)
+                    jqCommissionPremium.add(syCommissionPremium).add(jqFollowPremium).add(syFollowPremium).add(jyCommissionPremium).add(jyFollowPremium);
             case "6" ->
                 // 驾意险的总手续费(jy_commission_premium) + 驾意险的总跟单费(jy_follow_premium)
                     jyCommissionPremium.add(jyFollowPremium);
@@ -1055,17 +1056,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             result.setSumPrice(null != invoicingVo.getReceivablePremium() ? invoicingVo.getReceivablePremium().toString() : null);
 
             // ============================结算逻辑============================
-            // 实际已经收了的金额
-            BigDecimal actualReceivedAmount = this.getInvoicingAmount(settlementVo.getInvoicingId());
-
-            // 所有需要结算的金额
-            BigDecimal allToSettlement = invoice.getReceivableSupervisePremium().add(invoice.getOverinflatedAmount());
-            // 剩余的金额
-            BigDecimal surplusPremium = allToSettlement.subtract(actualReceivedAmount);
-            log.info("invoiceId=[{}],一共需要结算的金额[{}],实际已经结算的金额[{}],本次计划结算的金额[{}]",
-                    settlementVo.getInvoicingId(), allToSettlement,actualReceivedAmount,settlementVo.getActualReceivedAmount());
             // 校验是否超出了剩余的金额
-            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
+//            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
 
             // 处理结算数据
             // 未完全结算完成
@@ -1507,7 +1499,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             log.info("invoiceId=[{}],一共需要结算的金额[{}],实际已经结算的金额[{}],本次计划结算的金额[{}]",
                     settlementVo.getInvoicingId(), allToSettlement,actualReceivedAmount,settlementVo.getActualReceivedAmount());
             // 校验是否超出了剩余的金额
-            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
+//            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
 
             // 处理结算数据
             // 未完全结算完成
@@ -1529,8 +1521,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 insPlyIncomeInvoiceSettlementFileMapper.insert(files);
             }
 
-            // 判断是否已经结算完成
-            if (surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) == 0) {
+            // 判断是否已经结算完成,剩余金额小于等于实收金额就算完成结算了
+            if (surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) <= 0) {
                 log.info("序号为[{}]的发票已经结算完成",insPlyIncomeInvoice.getId());
                 // 更新发票状态
                 insPlyIncomeInvoice.setStatus("1");
@@ -2268,6 +2260,12 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         if (null == followInvoicePageListVo || CollUtil.isEmpty(followInvoicePageListVo.getSearchList())){
             return CollUtil.newArrayList();
         }
+        if (StrUtil.isBlank(followInvoicePageListVo.getSearchList().stream().filter(search -> "signYear".equals(search.getName())).findAny().get().getSearch())){
+            return CollUtil.newArrayList();
+        }
+        if (!StrUtil.contains(followInvoicePageListVo.getSearchList().stream().filter(search -> "signYear".equals(search.getName())).findAny().get().getSearch(), ",")){
+            return CollUtil.newArrayList();
+        }
         FollowInvoicePageListVo.SearchVO searchYear = followInvoicePageListVo.getSearchList().stream().filter(search -> "signYear".equals(search.getName())).findFirst().orElse(new FollowInvoicePageListVo.SearchVO());
         Integer startYear = Integer.parseInt(searchYear.getSearch().split(",")[0]);
         Integer endYear = Integer.parseInt(searchYear.getSearch().split(",")[1]);
@@ -2482,7 +2480,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             log.info("invoiceId=[{}],一共需要结算的金额[{}],实际已经结算的金额[{}],本次计划结算的金额[{}]",
                     settlementVo.getInvoicingId(), allToSettlement,actualReceivedAmount,settlementVo.getActualReceivedAmount());
             // 校验是否超出了剩余的金额,判断 surplusPremium 是否 小于 实际到账金额
-            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
+//            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
 
             // 处理结算数据
             // 未完全结算完成
@@ -2504,8 +2502,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 insPlyIncomeInvoiceSettlementFileMapper.insert(files);
             }
 
-            // 判断是否已经结算完成
-            if (surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) == 0) {
+            // 判断是否已经结算完成,剩余金额小于等于实收金额就算完成结算了
+            if (surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) <= 0) {
                 log.info("序号为[{}]的发票已经结算完成",insPlyIncomeInvoice.getId());
                 // 更新发票状态
                 insPlyIncomeInvoice.setStatus("1");
@@ -3173,9 +3171,10 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         Map<String, BigDecimal> ptInvoicedAmountMap =calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
 
         // 结算费用 
-        calRes = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType());
-        Map<String, BigDecimal> sxfSettledAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getSxfSettlement, (o1,o2)->o1));
-        Map<String, BigDecimal> gdfSettledAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getGdfSettlement, (o1,o2)->o1));
+        List<CalRes> sxfList = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType(), CollUtil.newArrayList("1", "3"));
+        List<CalRes> gdfList = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType(), CollUtil.newArrayList("2", "4"));
+        Map<String, BigDecimal> sxfSettledAmountMap = CollUtil.isNotEmpty(sxfList) ? sxfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getSettlement, (o1,o2)->o1)) : new HashMap<>();
+        Map<String, BigDecimal> gdfSettledAmountMap = CollUtil.isNotEmpty(gdfList) ? gdfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getSettlement, (o1,o2)->o1)) : new HashMap<>();
 
         // 计算已开票和未开票
         for (String companyId : companyMap.keySet()) {

+ 24 - 19
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -1688,37 +1688,42 @@
     <select id="querySettledAmount" resultType="com.jzg.organization.entity.dto.CalRes">
         select
         a.company_id ,
-        sum(COALESCE(a.jq_supervise_costs_premiums, 0)+ COALESCE(a.sy_supervise_costs_premiums, 0)+ coalesce(a.jy_supervise_costs_proportion, 0 )) as sxf_settlement,
-        sum(COALESCE(a.jq_other_costs_premiums, 0)+ COALESCE(a.sy_other_costs_premiums, 0)+ coalesce(a.jy_other_costs_premiums, 0 )) as gdf_settlement
+        sum(COALESCE(a.actual_received_amount, 0)) as settlement
         from
         (
         select
         ipi.company_id ,
-        ipi.jq_supervise_costs_premiums,
-        ipi.sy_supervise_costs_premiums,
-        ipi.jy_supervise_costs_proportion,
-        ipi.jq_other_costs_premiums,
-        ipi.sy_other_costs_premiums,
-        ipi.jy_other_costs_premiums,
-        ipi.settlement_status ,
-        ipi.settlement_time
-        from
-        ins_ply_income ipi
+        COALESCE(ins.actual_received_amount, 0) as actual_received_amount
+        from ins_ply_income_invoice_settlement ins
+        inner join ins_ply_income_invoice inc
+        on ins.invoice_id = inc.id
+        AND inc.is_delete = 0
+        inner join ins_ply_income_invoice_link link
+        on link.invoice_id = inc.id
+        AND link.is_delete = 0
+        inner join ins_ply_income ipi
+        on link.income_id = ipi.id
+        AND ipi.is_delete = 0
         <where>
-            ipi.is_delete = 0
-            AND ipi.settlement_status = 1
-            <if test="settledStartDate != null and settledStartDate != ''">
-                AND ipi.settlement_time >= cast( '${settledStartDate}' as datetime)
+            ins.is_delete = 0
+            <if test="settledStartDate != null">
+                AND ins.receive_payment_date >= #{settledStartDate}
             </if>
-            <if test="settledEndDate != null and settledEndDate != ''">
-                AND ipi.settlement_time &lt; cast('${settledEndDate}' as datetime)
+            <if test="settledEndDate != null">
+                AND ins.receive_payment_date &lt; #{settledEndDate}
             </if>
             <if test="agreementType != null and agreementType != ''">
                 AND ipi.agreement_type = #{agreementType}
             </if>
+            <if test="invoiceTypes != null and invoiceTypes.size() > 0">
+                AND inc.invoice_type IN
+                <foreach collection="invoiceTypes" item="invoiceType" open="(" separator="," close=")">
+                    #{invoiceType}
+                </foreach>
+            </if>
         </where>
         ) a
-        group by  a.company_id
+        group by a.company_id
     </select>
     <select id="queryFollowIncome" resultType="com.jzg.commons.entity.finance.dto.InsPlyIncomeDto">
         SELECT