Просмотр исходного кода

Merge branch 'master' into wrq_dev

wangrq 3 месяцев назад
Родитель
Сommit
26f762096b
26 измененных файлов с 550 добавлено и 179 удалено
  1. 2 1
      commons/src/main/java/com/jzg/commons/util/BuildDescUtils.java
  2. 45 2
      platform/src/main/java/com/jzg/controller/FileUploadController.java
  3. 2 0
      tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/api/build/ChengTaiAPIQuoteResultsVoBuild.java
  4. 23 2
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/component/HuaNongCrawlerRequestComponent.java
  5. 7 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/constant/enums/JiaYiXianProduct.java
  6. 35 1
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerDocumentsPrintRequestRequest.java
  7. 4 3
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerFindBusinessesRequestRequest.java
  8. 1 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/request/HuaNongCrawlerFtpDownloadRequestRequest.java
  9. 4 0
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/entity/response/HuaNongCrawlerFindBusinessesResponse.java
  10. 35 8
      tenant/insurance/quotation-huanong/src/main/java/com/jzg/quotation/huanong/crawler/service/impl/HuaNongCrawlerRequestImpl.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. 22 8
      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. 3 3
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  21. 13 1
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java
  22. 32 27
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/service/impl/TaiShanCrawlerRequestImpl.java
  23. 2 1
      tenant/organization/src/main/java/com/jzg/organization/mapper/ReceivableMapper.java
  24. 10 8
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java
  25. 20 21
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  26. 24 19
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

+ 2 - 1
commons/src/main/java/com/jzg/commons/util/BuildDescUtils.java

@@ -13,9 +13,10 @@ import java.util.stream.Collectors;
 public class BuildDescUtils {
 
 
-    public static String buildDesc(List<PtlAgreementUndwrtRulesAttr> linkList, List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList) {
+    public static String buildDesc(String companyId, List<PtlAgreementUndwrtRulesAttr> linkList, List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList) {
         StringBuilder desc = new StringBuilder();
         Map<String, PtlAgreementUndwrtRulesAttr> attrMap = undwrtRulesAttrList.stream()
+                .filter(attr -> "all".equals(attr.getCompanyIds()) || attr.getCompanyIds().equals(companyId))
                 .collect(Collectors.toMap(PtlAgreementUndwrtRulesAttr::getAttrCode, Function.identity()));
 
         for (PtlAgreementUndwrtRulesAttr link : linkList) {

+ 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("."));
     }

+ 2 - 0
tenant/insurance/quotation-chengtai/src/main/java/com/jzg/quotation/chengtai/api/build/ChengTaiAPIQuoteResultsVoBuild.java

@@ -100,6 +100,7 @@ public final class ChengTaiAPIQuoteResultsVoBuild {
             scoreVo.setCiClaims(premiumCalculationResponse.getCompRisk().getBasePart().getClaimsNum());
             if (null != premiumCalculationResponse.getCompRisk().getBasePart().getDiscount()) {
                 scoreVo.setJqAdjustRate(premiumCalculationResponse.getCompRisk().getBasePart().getDiscount().toString());
+                scoreVo.setCiClaims(premiumCalculationResponse.getCompRisk().getBasePart().getClaimsNum());
             }
         }
         if (null != premiumCalculationResponse.getCommRisk() && null != premiumCalculationResponse.getCommRisk().getBasePart()) {
@@ -107,6 +108,7 @@ public final class ChengTaiAPIQuoteResultsVoBuild {
             scoreVo.setSyRenewal(premiumCalculationResponse.getCommRisk().getBasePart().getRenewalFlag());
             if (null != premiumCalculationResponse.getCommRisk().getBasePart().getDiscount()){
                 scoreVo.setSyAdjustRate(premiumCalculationResponse.getCommRisk().getBasePart().getDiscount().toString());
+                scoreVo.setBiClaims(premiumCalculationResponse.getCommRisk().getBasePart().getClaimsNum());
             }
         }
         scoreVo.setLossRation(premiumCalculationResponse.getYztScore().getCentile().toString());

+ 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);
             });

+ 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 = "";

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

@@ -555,13 +555,26 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
     private QuoteVo handleQuoteErrors(String decryptData, QuoteVo q) {
         boolean hasError = decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag");
         if (!hasError) return q;
+        if (decryptData.contains("本机构并未配置此险种") || decryptData.contains("重复投保的其它公司") ||
+                (decryptData.contains("发生重复投保") && !decryptData.contains("终保日期"))) {
+            try {
+                throw new SystemException(MAPPER.readValue(decryptData, Map.class).get("erroeInfo").toString());
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+        }
 
-        boolean dup = decryptData.contains("发生重复投保") && decryptData.contains("终保日期");
-
-        if (dup) {
+        if (decryptData.contains("发生重复投保") && decryptData.contains("终保日期")) {
             q = handleDuplicateInsurance(decryptData, q);
             return q;
         }
+        if (decryptData.contains("erroeInfo") || decryptData.contains("errrorFlag")) {
+            try {
+                throw new SystemException(MAPPER.readValue(decryptData, Map.class).get("erroeInfo").toString());
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+        }
         return q;
     }
 
@@ -586,6 +599,8 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
 
     private HtCrawlerQuoteResponse.DataDTO resolveQuoteResponse(QuoteVo q, String decryptData, String mealid, String limitAmount,
                                                               HttpHeaders h, String personalInsuredJSON) throws Exception {
+        //单交不能重复投
+        if (decryptData.contains("存在有效交强险保单") || decryptData.contains("重复投保的其它公司")) throw new Exception(decryptData);
         HtCrawlerQuoteResponse.DataDTO data = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataDTO.class);
         if (data.getApplicationdto() != null) return data;
 
@@ -681,6 +696,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());
@@ -693,7 +709,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         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();
@@ -741,10 +757,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
             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;
+            throw new SystemException(e.getMessage());
         }
     }
 
@@ -1078,6 +1091,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
         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);
     }
 

+ 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);

+ 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);

+ 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);

+ 32 - 27
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/service/impl/TaiShanCrawlerRequestImpl.java

@@ -364,35 +364,40 @@ public class TaiShanCrawlerRequestImpl implements TaiShanCrawlerRequest {
      */
     @Override
     public void uploadImage(InsuranceUploadImageVo insuranceUploadImageVo) {
-        //获取归属信息
-        AttributionInformationVo attributionInformationVo = insuranceUploadImageVo.getOrder().getAttributionInformationVo();
-        TaiShanCrawlerConfigureParameters parameters = ConfigureParametersConversion.conversionEntity(TaiShanCrawlerConfigureParameters.class, attributionInformationVo.getConfigInfo());
-        HttpHeaders headers = taiShanCrawlerQuoteProcessService.getHeaders(attributionInformationVo.getUsername(), parameters.getComCode());
-        TaiShanCrawlerOrder taiShanCrawlerOrder = taiShanCrawlerOrderService.getByOrdersNo(insuranceUploadImageVo.getOrder().getOrdersNo());
-        // 上传影像文件请求参数
-        TaiShanCrawlerImageUploadRequest taiShanCrawlerImageUploadRequest = new TaiShanCrawlerImageUploadRequest();
-        taiShanCrawlerImageUploadRequest.setBiProposalNo(taiShanCrawlerOrder.getSyApplyNo());
-        taiShanCrawlerImageUploadRequest.setCiProposalNo(taiShanCrawlerOrder.getCiApplyNo());
-        taiShanCrawlerImageUploadRequest.setCompanyCode(parameters.getComCode());
-
-        List<TaiShanCrawlerImageUploadRequest.ImageNode> imageNodes = new LinkedList<>();
-        for (InsuranceImageVo imageVo : insuranceUploadImageVo.getImageVoList()) {
-            TaiShanCrawlerImageUploadRequest.ImageNode imageNode = new TaiShanCrawlerImageUploadRequest.ImageNode();
-            imageNode.setType(getImageType(imageVo.getImageCode()));
-            List<TaiShanCrawlerImageUploadRequest.ImageInfo> images = new ArrayList<>();
-            for (InsuranceImageVo.ImageDTO imageDTO : imageVo.getImageBase64List()) {
-                images.add(new TaiShanCrawlerImageUploadRequest.ImageInfo(imageDTO.getImageName(), imageDTO.getImageBase64Str()));
+        try {
+            //获取归属信息
+            AttributionInformationVo attributionInformationVo = insuranceUploadImageVo.getOrder().getAttributionInformationVo();
+            TaiShanCrawlerConfigureParameters parameters = ConfigureParametersConversion.conversionEntity(TaiShanCrawlerConfigureParameters.class, attributionInformationVo.getConfigInfo());
+            HttpHeaders headers = taiShanCrawlerQuoteProcessService.getHeaders(attributionInformationVo.getUsername(), parameters.getComCode());
+            TaiShanCrawlerOrder taiShanCrawlerOrder = taiShanCrawlerOrderService.getByOrdersNo(insuranceUploadImageVo.getOrder().getOrdersNo());
+            // 上传影像文件请求参数
+            TaiShanCrawlerImageUploadRequest taiShanCrawlerImageUploadRequest = new TaiShanCrawlerImageUploadRequest();
+            taiShanCrawlerImageUploadRequest.setBiProposalNo(taiShanCrawlerOrder.getSyApplyNo());
+            taiShanCrawlerImageUploadRequest.setCiProposalNo(taiShanCrawlerOrder.getCiApplyNo());
+            taiShanCrawlerImageUploadRequest.setCompanyCode(parameters.getComCode());
+
+            List<TaiShanCrawlerImageUploadRequest.ImageNode> imageNodes = new LinkedList<>();
+            for (InsuranceImageVo imageVo : insuranceUploadImageVo.getImageVoList()) {
+                TaiShanCrawlerImageUploadRequest.ImageNode imageNode = new TaiShanCrawlerImageUploadRequest.ImageNode();
+                imageNode.setType(getImageType(imageVo.getImageCode()));
+                List<TaiShanCrawlerImageUploadRequest.ImageInfo> images = new ArrayList<>();
+                for (InsuranceImageVo.ImageDTO imageDTO : imageVo.getImageBase64List()) {
+                    images.add(new TaiShanCrawlerImageUploadRequest.ImageInfo(imageDTO.getImageName(), imageDTO.getImageBase64Str()));
+                }
+                imageNode.setImages(images);
+                imageNodes.add(imageNode);
             }
-            imageNode.setImages(images);
-            imageNodes.add(imageNode);
+            taiShanCrawlerImageUploadRequest.setImageNodes(imageNodes);
+            taiShanCrawlerImageUploadRequest.setOperatorCode(parameters.getSaleCode());
+            taiShanCrawlerImageUploadRequest.setOperatorName(parameters.getSaleName());
+            taiShanCrawlerImageUploadRequest.setOrderNo(taiShanCrawlerOrder.getOrderNo());
+            taiShanCrawlerImageUploadRequest.setUploadFlag("D");
+            TaiShanCrawlerImageUploadResponse taiShanCrawlerImageUploadResponse = taiShanCrawlerRequestComponent.uploadImage(taiShanCrawlerImageUploadRequest, headers);
+            log.info("taiShanCrawlerImageUploadResponse对象的值:{}", JSON.toJSONString(taiShanCrawlerImageUploadResponse));
+        } catch (Exception e) {
+            log.error("泰山影像上传失败", e);
+            throw new RuntimeException("泰山影像上传失败: " + e.getMessage(), e);
         }
-        taiShanCrawlerImageUploadRequest.setImageNodes(imageNodes);
-        taiShanCrawlerImageUploadRequest.setOperatorCode(parameters.getSaleCode());
-        taiShanCrawlerImageUploadRequest.setOperatorName(parameters.getSaleName());
-        taiShanCrawlerImageUploadRequest.setOrderNo(taiShanCrawlerOrder.getOrderNo());
-        taiShanCrawlerImageUploadRequest.setUploadFlag("D");
-        TaiShanCrawlerImageUploadResponse taiShanCrawlerImageUploadResponse = taiShanCrawlerRequestComponent.uploadImage(taiShanCrawlerImageUploadRequest, headers);
-        log.info("taiShanCrawlerImageUploadResponse对象的值:{}", JSON.toJSONString(taiShanCrawlerImageUploadResponse));
     }
 
 

+ 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);
 
     /**
      * 查询

+ 10 - 8
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java

@@ -26,10 +26,7 @@ import com.jzg.commons.util.idgen.IdGenerate;
 import com.jzg.organization.mapper.PtlAgreementCostMapper;
 import com.jzg.organization.mapper.PtlAgreementCostRuleMapper;
 import com.jzg.organization.mapper.PtlAgreementCostTypeMapper;
-import com.jzg.organization.service.PtlAgreementCostRuleService;
-import com.jzg.organization.service.PtlAgreementCostService;
-import com.jzg.organization.service.PtlAgreementCostTypeService;
-import com.jzg.organization.service.PtlAgreementUndwrtRulesAttrService;
+import com.jzg.organization.service.*;
 import com.jzg.organization.state.CostState;
 import com.jzg.organization.state.listener.CostStateListener;
 import io.seata.spring.annotation.GlobalTransactional;
@@ -89,6 +86,9 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     @Autowired
     private PtlAgreementCostRuleMapper ptlAgreementCostRuleMapper;
 
+    @Autowired
+    private PtlAgreementService ptlAgreementService;
+
     /**
      * 报价配置/费用管理/新增费用
      *
@@ -117,6 +117,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                     log.info("新增费用的时候,需要指定关联的协议信息。ptlAgreemenCostAdd=[{}]", JSONUtil.toJsonStr(ptlAgreemenCostAdd));
                     return HttpResult.error("新增费用的时候,需要指定关联的协议信息");
                 }
+                PtlAgreement agreement = ptlAgreementService.getById(costAdd.getPtlAgreementId());
                 ptlAgreementCostAdd.setPtlAgreementId(costAdd.getPtlAgreementId());
                 ptlAgreementCostAdd.setProductId(costAdd.getProductId());
                 ptlAgreementCostAdd.setProductName(costAdd.getProductName());
@@ -127,7 +128,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
 //                    throw new SystemException("已存在相同且有效的费用规则,请检查");
 //                }
                 PtlAgreementCost ptlAgreementCost = BeanUtil.copyProperties(ptlAgreementCostAdd, PtlAgreementCost.class);
-                ptlAgreementCost.setCostRules(buildDescString(ptlAgreementCostAdd.getRuleConditions()));
+                ptlAgreementCost.setCostRules(buildDescString(agreement.getCompanyId(), ptlAgreementCostAdd.getRuleConditions()));
                 if (baseMapper.insert(ptlAgreementCost) <= 0) {
                     log.error("插入操作失败");
                     throw new RuntimeException(ReturnInformation.FAILURE_MESSAGE);
@@ -167,10 +168,11 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                 }
             }
         }
+        PtlAgreement agreement = ptlAgreementService.getById(ptlAgreementCostEnd.getPtlAgreementId());
         PtlAgreementCost ptlAgreementCost = BeanUtil.copyProperties(ptlAgreementCostEnd, PtlAgreementCost.class);
         // modify by lipf, 2026年5月22日11:28:34 设置为待审核状态
         ptlAgreementCost.setApproved(0);
-        ptlAgreementCost.setCostRules(buildDescString(ptlAgreementCostEnd.getRuleConditions()));
+        ptlAgreementCost.setCostRules(buildDescString(agreement.getCompanyId(), ptlAgreementCostEnd.getRuleConditions()));
         if (baseMapper.updateById(ptlAgreementCost) <= 0) {
             throw new RuntimeException(ReturnInformation.UPDATE_FAILED);
         }
@@ -196,11 +198,11 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     }
 
 
-    public String buildDescString(List<?> list){
+    public String buildDescString(String companyId, List<?> list){
         if (CollectionUtils.isEmpty(list)){
             return null;
         }
-        return BuildDescUtils.buildDesc(BeanUtil.copyToList(list, PtlAgreementUndwrtRulesAttr.class), agreementUndwrtRulesAttrService.getUndwrtRulesAttrList());
+        return BuildDescUtils.buildDesc(companyId, BeanUtil.copyToList(list, PtlAgreementUndwrtRulesAttr.class), agreementUndwrtRulesAttrService.getUndwrtRulesAttrList());
     }
 
     public boolean verify(PtlAgreementCostAdd ptlAgreementCostAdd){

+ 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