Explorar el Código

Merge remote-tracking branch 'origin/master'

Qchen hace 3 meses
padre
commit
1007f7fa76
Se han modificado 49 ficheros con 1272 adiciones y 296 borrados
  1. 3 0
      commons/src/main/java/com/jzg/commons/entity/finance/dto/ReceiverSettlementReportDto.java
  2. 14 11
      commons/src/main/java/com/jzg/commons/entity/finance/vo/BatchModifyVo.java
  3. 3 0
      commons/src/main/java/com/jzg/commons/entity/vo/IncomeAndExpenseVo.java
  4. 10 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/component/RequestComponent.java
  5. 25 0
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/DateUtil.java
  6. 43 48
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DaJiaCrawlerQuoteResultsVoBuild.java
  7. 2 2
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/component/DaJiaCrawlerRequestComponent.java
  8. 1 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/entity/request/DaJiaCrawlerCarRequest.java
  9. 6 1
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/service/impl/DaJiaCrawlerRequestImpl.java
  10. 2 2
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/component/HengBangCrawlerRequestComponent.java
  11. 95 46
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerCalculationRequest.java
  12. 1 0
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java
  13. 0 0
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/utils/HengBangAESUtil.java
  14. 1 1
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/entity/po/HtCrawlerOrder.java
  15. 57 2
      tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/constant/InsuranceKindCodeMapping.java
  16. 36 4
      tenant/insurance/quotation-renbaonew/src/main/java/com/jzg/quotation/renbaonew/crawler/service/impl/RenBaoNewCrawlerRequestImpl.java
  17. 2 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java
  18. 2 11
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java
  19. 4 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsFeeAuditService.java
  20. 59 6
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeAuditServiceImpl.java
  21. 32 19
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java
  22. 4 4
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  23. 4 0
      tenant/insurance/quotation-summary/src/main/resources/logback-spring.xml
  24. 2 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/build/TkCrawlerQuoteResultsBuild.java
  25. 30 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/cache/RedisCacheUtil.java
  26. 108 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/model/entity/po/TKCrawlerOrder.java
  27. 21 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/repository/TKCrawlerOrderRepository.java
  28. 33 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKCrawlerOrderService.java
  29. 16 21
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKHttpAPIService.java
  30. 2 1
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/TKSimpleService.java
  31. 58 0
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKCrawlerOrderServiceImpl.java
  32. 20 15
      tenant/insurance/quotation-taikang/src/main/java/com/jzg/quotation/taikang/crawler/service/impl/TKQuotationBaseServiceImpl.java
  33. 2 2
      tenant/insurance/quotation-taikang/src/test/java/com/jzg/quotation/taikang/crawler/TKHttpAPIServiceTest1.java
  34. 45 5
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/build/TaiShanCrawlerQuoteResultsVoBuild.java
  35. 51 1
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/component/TaiShanCrawlerRequestComponent.java
  36. 3 1
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/service/impl/TaiShanCrawlerQuoteProcessServiceImpl.java
  37. 2 2
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/service/impl/TaiShanCrawlerRequestImpl.java
  38. 4 3
      tenant/organization/src/main/java/com/jzg/organization/controller/MessageController.java
  39. 19 1
      tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java
  40. 2 2
      tenant/organization/src/main/java/com/jzg/organization/controller/SchemeController.java
  41. 2 1
      tenant/organization/src/main/java/com/jzg/organization/controller/UserAccountController.java
  42. 14 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/ReceivableMapper.java
  43. 1 1
      tenant/organization/src/main/java/com/jzg/organization/service/PtlSchemeService.java
  44. 18 1
      tenant/organization/src/main/java/com/jzg/organization/service/ReceivableService.java
  45. 10 1
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java
  46. 356 70
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  47. 1 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserAccountServiceImpl.java
  48. 2 0
      tenant/organization/src/main/resources/mapper/PtlAgreementCostMapper.xml
  49. 44 4
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/finance/dto/ReceiverSettlementReportDto.java

@@ -49,4 +49,7 @@ public class ReceiverSettlementReportDto {
 
     @Schema(description = "未结算总计")
     private String unSettledAmount;
+
+    @Schema(description = "已结算发票的发票号")
+    private String invoiceIds;
 }

+ 14 - 11
commons/src/main/java/com/jzg/commons/entity/finance/vo/BatchModifyVo.java

@@ -28,17 +28,17 @@ public class BatchModifyVo {
     @Schema(description = "商业手续费比例")
     private BigDecimal sySuperviseCostsProportion;
 
-//    @Schema(description = "驾意手续费比例")
-//    private BigDecimal jySuperviseCostsProportion;
-//
-//    @Schema(description = "交强跟单费比例")
-//    private BigDecimal jqOtherCostsProportion;
-//
-//    @Schema(description = "商业跟单费比例")
-//    private BigDecimal syOtherCostsProportion;
-//
-//    @Schema(description = "驾意跟单费比例")
-//    private BigDecimal jyOtherCostsProportion;
+    @Schema(description = "驾意手续费比例")
+    private BigDecimal jySuperviseCostsProportion;
+
+    @Schema(description = "交强跟单费比例")
+    private BigDecimal jqOtherCostsProportion;
+
+    @Schema(description = "商业跟单费比例")
+    private BigDecimal syOtherCostsProportion;
+
+    @Schema(description = "驾意跟单费比例")
+    private BigDecimal jyOtherCostsProportion;
 
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @Schema(description = "签单时间")
@@ -53,4 +53,7 @@ public class BatchModifyVo {
     @Schema(description = "对接人手机号")
     private String contractPhone;
 
+    @Schema(description = "修改标识 1-手续费 2-跟单费 3-驾意险 4-所有都改")
+    private String updateFlag;
+
 }

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/vo/IncomeAndExpenseVo.java

@@ -59,5 +59,8 @@ public class IncomeAndExpenseVo {
 
         @Schema(description = "银行卡号")
         private String bankCardNum;
+
+        @Schema(description = "驳回原因")
+        private String rejectReason;
     }
 }

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

@@ -291,6 +291,16 @@ public class RequestComponent {
                 .headers(setHeaders(headers))
                 .retrieve()
                 .toEntity(responseClass)
+                .timeout(Duration.ofSeconds(60))
+                .onErrorMap(ReadTimeoutException.class, ex ->
+                        new WebClientResponseException(
+                                504,
+                                "第三方接口读取超时:" + url,
+                                HttpHeaders.EMPTY,
+                                null,
+                                null
+                        )
+                )
                 .block();
     }
 

+ 25 - 0
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/DateUtil.java

@@ -419,6 +419,31 @@ public class DateUtil {
     private static final DateTimeFormatter INPUT_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
     private static final DateTimeFormatter OUTPUT_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
 
+    /**
+     * 获取投保日期的下一天0点(北京时间)并转为UTC ISO8601格式
+     * 驾意险起保日期默认为投保日期的下一天的0点
+     */
+    public static String getNextDayMidnightUtc() {
+        LocalDate tomorrow = LocalDate.now().plusDays(1);
+        String beijingTime = tomorrow.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00";
+        return toUtcDateTime(beijingTime);
+    }
+
+    /**
+     * 获取指定UTC日期时间的下一天0点(北京时间)并转为UTC ISO8601格式
+     * 驾意险不支持即时起保,需调整起保日期为主险投保日期的下一日0时
+     *
+     * @param utcDateTime 主险起保UTC时间(ISO8601格式,如 2026-07-04T16:00:00.000Z)
+     * @return 下一天北京时间0点对应的UTC ISO8601格式
+     */
+    public static String getNextDayMidnightUtc(String utcDateTime) {
+        ZonedDateTime utcZoned = ZonedDateTime.parse(utcDateTime, DateTimeFormatter.ISO_DATE_TIME);
+        ZonedDateTime beijingZoned = utcZoned.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
+        LocalDate nextDay = beijingZoned.toLocalDate().plusDays(1);
+        String beijingTime = nextDay.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00";
+        return toUtcDateTime(beijingTime);
+    }
+
     /**
      * 将北京时间(yyyy-MM-dd HH:mm:ss)转换为UTC时间(ISO8601格式)
      */

+ 43 - 48
tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DaJiaCrawlerQuoteResultsVoBuild.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.dajia.crawler.build;
 
+import cn.hutool.core.collection.CollectionUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
@@ -16,8 +17,11 @@ import com.jzg.quotation.dajia.crawler.entity.request.quote.BusinessInsuranceDTO
 import com.jzg.quotation.dajia.crawler.entity.request.quote.CompulsoryInsuranceDTO;
 import com.jzg.quotation.dajia.crawler.entity.response.DaJiaCrawlerOrderListRevisedResponse;
 import com.jzg.quotation.dajia.crawler.entity.response.DaJiaCrawlerSaveResponse;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.springframework.util.ObjectUtils;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -29,6 +33,8 @@ import java.util.stream.Collectors;
  **/
 public final class DaJiaCrawlerQuoteResultsVoBuild {
 
+    private static final Logger log = LogManager.getLogger(DaJiaCrawlerQuoteResultsVoBuild.class);
+
     private DaJiaCrawlerQuoteResultsVoBuild() {
         throw new IllegalStateException("Utility class");
     }
@@ -71,6 +77,7 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
         quoteResultsVo.setCiEndDate(compulsoryInsuranceProductInfo.getEndDate());
         quoteResultsVo.setBiStartDate(productInfo.getStartDate());
         quoteResultsVo.setBiEndDate(productInfo.getEndDate());
+        log.info("构建返回信息:{}",JSONObject.toJSONString(quoteResultsVo));
         return quoteResultsVo;
     }
 
@@ -156,9 +163,14 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
         BusinessInsuranceDTO businessInsurance = daJiaCrawlerSaveResponse.getBusinessInsurance(); // 商业险
         if (!ObjectUtils.isEmpty(compulsoryInsurance)) {
             scoreVo.setJqLossRation(StringUtils.isNotEmpty(compulsoryInsurance.getCoefficientInfo().getLossRatioCi()) ? compulsoryInsurance.getCoefficientInfo().getLossRatioCi() : null);
+            scoreVo.setCiClaims(String.valueOf(new BigDecimal(compulsoryInsurance.getCoefficientInfo().getLastPolicyNum()).intValue()));
+            scoreVo.setJqRenewal(compulsoryInsurance.getCoefficientInfo().getRenewalFrequency());
         }
-        if (!ObjectUtils.isEmpty(businessInsurance)) {
+        boolean sy = CollectionUtil.isNotEmpty(businessInsurance.getItemKinds());
+        if (sy) {
             scoreVo.setSyLossRation(StringUtils.isNotEmpty(businessInsurance.getCoefficientInfo().getLossRatioBi()) ? businessInsurance.getCoefficientInfo().getLossRatioBi() : null);
+            scoreVo.setBiClaims(String.valueOf(new BigDecimal(businessInsurance.getCoefficientInfo().getLastPolicyNum()).intValue()));
+            scoreVo.setSyRenewal(businessInsurance.getCoefficientInfo().getRenewalFrequency());
         }
         // 总赔付率 违章评分 高速风险分
         String carIllegalScore;
@@ -175,13 +187,9 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
         CompulsoryInsuranceDTO.CoefficientInfoDTO coefficientInfo = daJiaCrawlerSaveResponse.getCompulsoryInsurance().getCoefficientInfo();
         JSONArray scoreArray = new JSONArray();
         scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","交强定价评分")
-                .fluentPut("scoreKey","jqPubScores")
-                .fluentPut("score",compulsoryInsurance.getCoefficientInfo().getLossRatioCi()));
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","商业定价评分")
-                .fluentPut("scoreKey","syPubScores")
-                .fluentPut("score",businessInsurance.getCoefficientInfo().getLossRatioBi()));
+                .fluentPut("scoreName","交强类型评分")
+                .fluentPut("scoreKey","pubScores")
+                .fluentPut("score",compulsoryInsurance.getCoefficientInfo().getPubScores()));
         scoreArray.add(new JSONObject()
                 .fluentPut("scoreName","违章评分")
                 .fluentPut("scoreKey","carIllegalScore")
@@ -191,54 +199,41 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
                 .fluentPut("scoreKey","highwayScore")
                 .fluentPut("score",highwayScore));
         scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","醉酒驾驶行为违法次数")
-                .fluentPut("scoreKey","drunkTotalCoef")
-                .fluentPut("score",coefficientInfo.getDrunkTotalCoef()));
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","理赔调整系数")
-                .fluentPut("scoreKey","claimAdjustValue")
-                .fluentPut("score",coefficientInfo.getClaimAdjustValue()));
-        scoreVo.setScoreJson(scoreArray);
+                .fluentPut("scoreName","上年保单出险次数")
+                .fluentPut("scoreKey","lastPolicyNum")
+                .fluentPut("score",coefficientInfo.getLastPolicyNum()));
         scoreArray.add(new JSONObject()
                 .fluentPut("scoreName","交强险手续费")
                 .fluentPut("scoreKey","handFeeCi")
                 .fluentPut("score",coefficientInfo.getHandFeeCi()));
-        scoreVo.setScoreJson(scoreArray);
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","商业险手续费")
-                .fluentPut("scoreKey","handFeeBi")
-                .fluentPut("score",coefficientInfo.getHandFeeBi()));
-        scoreVo.setScoreJson(scoreArray);
         scoreArray.add(new JSONObject()
                 .fluentPut("scoreName","续保次数")
                 .fluentPut("scoreKey","renewalFrequency")
                 .fluentPut("score",coefficientInfo.getRenewalFrequency()));
-        scoreVo.setScoreJson(scoreArray);
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","违法调整系数")
-                .fluentPut("scoreKey","carIllegalScore")
-                .fluentPut("score",coefficientInfo.getCarIllegalScore()));
-        scoreVo.setScoreJson(scoreArray);
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","商业险连续承保年数")
-                .fluentPut("scoreKey","insureYears")
-                .fluentPut("score",coefficientInfo.getInsureYears()));
-        scoreVo.setScoreJson(scoreArray);
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","商业险建议折扣")
-                .fluentPut("scoreKey","suggestedDiscount")
-                .fluentPut("score",coefficientInfo.getSuggestedDiscount()));
-        scoreVo.setScoreJson(scoreArray);
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","无赔款优待系数")
-                .fluentPut("scoreKey","totalCoefNum")
-                .fluentPut("score",coefficientInfo.getTotalCoefNum()));
-        scoreVo.setScoreJson(scoreArray);
-        scoreArray.add(new JSONObject()
-                .fluentPut("scoreName","无赔优系数级别")
-                .fluentPut("scoreKey","claimAdjustLvl")
-                .fluentPut("score",coefficientInfo.getClaimAdjustLvl()));
-        scoreVo.setScoreJson(scoreArray);
+        if (sy){
+            BusinessInsuranceDTO.CoefficientInfoDTO coefficientInfo1 = businessInsurance.getCoefficientInfo();
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName","商业险建议折扣")
+                    .fluentPut("scoreKey","entireDiscount")
+                    .fluentPut("score",coefficientInfo1.getEntireDiscount()));
+            scoreVo.setScoreJson(scoreArray);
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName","商业险手续费")
+                    .fluentPut("scoreKey","handFeeBi")
+                    .fluentPut("score",coefficientInfo1.getHandFeeBi()));
+            scoreVo.setScoreJson(scoreArray);
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName","无赔款优待系数")
+                    .fluentPut("scoreKey","totalCoefNum")
+                    .fluentPut("score",coefficientInfo1.getTotalCoefNum()));
+            scoreVo.setScoreJson(scoreArray);
+            scoreArray.add(new JSONObject()
+                    .fluentPut("scoreName","商业类型评分")
+                    .fluentPut("scoreKey","pubScores")
+                    .fluentPut("score",coefficientInfo1.getPubScores()));
+            scoreVo.setScoreJson(scoreArray);
+         }
         return scoreVo;
     }
+
 }

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

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

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

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

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

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

+ 2 - 2
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/component/HengBangCrawlerRequestComponent.java

@@ -150,7 +150,7 @@ public class HengBangCrawlerRequestComponent {
         headers.set(HttpHeaders.ACCEPT, "*/*");
         headers.set(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencode;charset=utf-8");
         headers.set(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36");
-        headers.set(HttpHeaders.AUTHORIZATION, getAuthorization(username));
+        headers.set(HttpHeaders.AUTHORIZATION, RequestConstant.BEARER + getAuthorization(username));
         HbCrawlerQueryUserInfoResponse response = requestComponent.get(RequestUrl.QUERY_USER_INFO.getRequestUrl(hbCrawlerProperties.getBaseUrl()) + "/" + username, param, RequestUrl.QUERY_USER_INFO.getRequestDescription(), HbCrawlerQueryUserInfoResponse.class, headers);
         return response;
     }
@@ -298,7 +298,7 @@ public class HengBangCrawlerRequestComponent {
         req.setHbEncV("1");
         try {
             ObjectMapper mapper = new ObjectMapper();
-            mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
+            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
             String json = mapper.writeValueAsString(calculationRequest);
             log.info("提交报价数据请求参数: {}", json);
             req.setHbEncD(HengBangAESUtil.encryptStr(json));

+ 95 - 46
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerCalculationRequest.java

@@ -13,6 +13,7 @@ import lombok.Data;
 import java.io.Serial;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 
@@ -81,20 +82,27 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         this.clauseType = "2";
         List<KindInfoVo> kindInfoVoList = quoteVo.getKindInfoVo();
         this.risktype = "0";
-        this.begintimeBi = DateUtil.toUtcDateTime(quoteVo.getCiRiskInfoVo().getStartDate());
         if (Objects.nonNull(quoteVo.getCiRiskInfoVo())) {
             this.begintimeCi = DateUtil.toUtcDateTime(quoteVo.getCiRiskInfoVo().getStartDate());
-            this.begintimeAccident = DateUtil.toUtcDateTime(quoteVo.getCiRiskInfoVo().getStartDate());
             this.risktype = "1";
         }
         if (CollUtil.isNotEmpty(kindInfoVoList)) {
             this.epersonliabilityList = getEpersonliabilityList(kindInfoVoList, depreciationPrice);
             this.begintimeBi = DateUtil.toUtcDateTime(quoteVo.getBiRiskInfoVo().getStartDate());
-            this.begintimeAccident = DateUtil.toUtcDateTime(quoteVo.getBiRiskInfoVo().getStartDate());
             this.risktype = "2";
         } else {
             this.epersonliabilityList = new ArrayList<>();
         }
+        // 驾意险不支持即时起保,起保日期为主险投保日期的下一日0时(北京时间)
+        if ("2".equals(this.risktype) && this.begintimeBi != null) {
+            this.begintimeAccident = DateUtil.getNextDayMidnightUtc(this.begintimeBi);
+        } else if ("1".equals(this.risktype) && this.begintimeCi != null) {
+            this.begintimeAccident = DateUtil.getNextDayMidnightUtc(this.begintimeCi);
+        } else {
+            this.begintimeAccident = DateUtil.getNextDayMidnightUtc();
+        }
+        // 驾意险列表需在 accidentEpolicyFlag 之前赋值
+        this.accidentInsuranceList = getAccidentInsuranceList(quoteVo.getBiRiskInfoVo(), quoteVo.getAccidentalDrivings());
         this.plyappno = plyappno;
         this.ecarshiptaxPart = "投保人";
         this.taxonomyCode = "02";
@@ -102,14 +110,14 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         this.endtimeBi = "";
         this.endtimeCi = "";
         this.expdisc = "";
-        this.accidentEpolicyFlag = "Y";
+        // 有驾意险时传"Y",无驾意险时传""(与javadoc示例对齐)
+        this.accidentEpolicyFlag = this.accidentInsuranceList.isEmpty() ? "" : "Y";
         this.effectfLag = null;
         this.ecarChargingPosts = new ArrayList<>();
         this.carInsureDevices = new ArrayList<>();
         this.outofwarrantytype = "N";
         this.drivingtype = "";
         this.endtimeAccident = "";
-        this.accidentInsuranceList = getAccidentInsuranceList(quoteVo.getBiRiskInfoVo(), quoteVo.getAccidentalDrivings());
     }
 
     public List<EpersonliabilityDTO> getEpersonliabilityList(List<KindInfoVo> kindInfoVoList, String depreciationPrice) {
@@ -120,25 +128,58 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
             epersonliabilityDTO.setLiabname(kindInfoVo.getKindName());
             // kindcode "101"(机动车损失保险)的保额必须使用车辆折旧价(实际价值),
             // 否则保司会校验"协商价格范围建议在实际价值上下30%浮动"并拒绝
+            // 注意:正确请求中kindcode "101"/"102"/"115"不包含unitAmount/quantity字段
             if ("101".equals(kindInfoVo.getKindCode()) && depreciationPrice != null) {
-                epersonliabilityDTO.setLiabamt(depreciationPrice);
-                epersonliabilityDTO.setUnitAmount(depreciationPrice);
+                epersonliabilityDTO.setLiabamt(parseNumeric(depreciationPrice));
+            } else if (Arrays.asList("102", "115").contains(kindInfoVo.getKindCode())) {
+                epersonliabilityDTO.setLiabamt(parseNumeric(kindInfoVo.getAmount()));
             } else if (!"116".equals(kindInfoVo.getKindCode())) {
                 // kindcode "116"不需要liabamt和unitAmount
-                epersonliabilityDTO.setLiabamt(kindInfoVo.getAmount());
-                epersonliabilityDTO.setUnitAmount(kindInfoVo.getUnitAmount());
+                Object liabamt = parseNumeric(kindInfoVo.getAmount());
+                epersonliabilityDTO.setLiabamt(liabamt);
+                Object unitAmount = parseNumeric(kindInfoVo.getUnitAmount());
+                // "103"(司机)/"104"(乘客)在正确请求中必须有unitAmount,数据缺失时兜底为liabamt
+                if (unitAmount == null && Arrays.asList("103", "104").contains(kindInfoVo.getKindCode())) {
+                    unitAmount = liabamt;
+                }
+                epersonliabilityDTO.setUnitAmount(unitAmount);
             }
             if ("116".equals(kindInfoVo.getKindCode())) {
                 // 道路救援服务特约条款:只需要serviceTimes字段
                 epersonliabilityDTO.setServiceTimes(kindInfoVo.getServiceTimes() != null ? kindInfoVo.getServiceTimes() : "2");
             } else {
-                epersonliabilityDTO.setQuantity(kindInfoVo.getQuantity() != null ? kindInfoVo.getQuantity() : "4");
+                // kindInfoVo有quantity才设置,否则不传(避免默认值"4"篡改司机险等正确值)
+                // "103"(司机)正确请求中quantity=1,数据缺失时兜底
+                String qty = kindInfoVo.getQuantity();
+                if (qty != null) {
+                    epersonliabilityDTO.setQuantity(parseNumeric(qty));
+                } else if ("103".equals(kindInfoVo.getKindCode())) {
+                    epersonliabilityDTO.setQuantity(1);
+                }
             }
             epersonliabilityDTOList.add(epersonliabilityDTO);
         }
         return epersonliabilityDTOList;
     }
 
+    /**
+     * 将字符串解析为数值类型,确保Jackson序列化为数字而非字符串
+     */
+    private static Object parseNumeric(String value) {
+        if (value == null) {
+            return null;
+        }
+        try {
+            if (value.contains(".")) {
+                return new java.math.BigDecimal(value);
+            } else {
+                return Long.valueOf(value);
+            }
+        } catch (NumberFormatException e) {
+            return value;
+        }
+    }
+
     public List<AccidentInsuranceDTO> getAccidentInsuranceList(RiskInfoVo biRiskInfoVo, List<AccidentalDrivingVo> accidentalDrivings) {
         if (accidentalDrivings == null || accidentalDrivings.isEmpty()) {
             return new ArrayList<>();
@@ -154,23 +195,28 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         AccidentInsuranceDTO dto = new AccidentInsuranceDTO();
         dto.setNonriskcode(vo.getProductCode().split("_")[1]);
         dto.setProgramcode(vo.getProductCode());
-        dto.setProgramname(vo.getProductName());
-        if (biRiskInfoVo != null && StringUtils.isNotBlank(biRiskInfoVo.getStartDate()) && StringUtils.isNotBlank(biRiskInfoVo.getEndDate())) {
-            dto.setBegintime(DateUtil.toUtcDateTime(DateUtil.getCurrentDate(1) + " 00:00:00"));
-            dto.setEndtime(DateUtil.toUtcDateTime(DateUtil.getNextYearDateStrTranfer(DateUtil.getCurrentDate(1) + " 00:00:00")));
-        }
+        dto.setProgramname("1119险种5座非营运客车保额525000保费99.9(山西)");
         dto.setCompanycode("0107");
-        dto.setRelationcarowner("a");
-        dto.setSuminsured("525000");
-        dto.setSumgrosspremium(vo.getPremium());
         dto.setIfdefault(true);
         dto.setBuynum(vo.getQuantity());
+        List<GgriskprogramdetailsDTO> detailsList = getGgriskprogramdetailsList(vo.getProductCode().split("_")[1], vo.getProductCode());
+        dto.setGgriskprogramdetailslist(detailsList);
         dto.setGgriskprogramclauselist(getGgriskprogramclauseList(vo.getProductCode().split("_")[1], vo.getProductCode()));
-        dto.setGgriskprogramdetailslist(getGgriskprogramdetailsList(vo.getProductCode().split("_")[1], vo.getProductCode()));
         dto.setGgriskprogramdeductiblelist(new ArrayList<>());
         List<GgriskprogramparamlDTO> ggriskprogramparamlist = new ArrayList<>();
-        ggriskprogramparamlist.add(new GgriskprogramparamlDTO("2021-05-19T07:00:00.000+0000", "subsidy", "99.9", "0107_1119_003", "2021-05-19T07:00:00.000+0000", "1"));
+        ggriskprogramparamlist.add(new GgriskprogramparamlDTO("2021-05-19T07:00:00.000+0000", "subsidy", "99.9", vo.getProductCode(), "2021-05-19T07:00:00.000+0000", "1"));
         dto.setGgriskprogramparamlist(ggriskprogramparamlist);
+
+        // 根据硬编码明细汇总计算 suminsured/sumgrosspremium,保证父子级数据一致
+        java.math.BigDecimal totalSuminsured = java.math.BigDecimal.ZERO;
+        java.math.BigDecimal totalGrossPremium = java.math.BigDecimal.ZERO;
+        for (GgriskprogramdetailsDTO detail : detailsList) {
+            totalSuminsured = totalSuminsured.add(new java.math.BigDecimal(detail.getKindsuminsured().toString()));
+            totalGrossPremium = totalGrossPremium.add(new java.math.BigDecimal(detail.getKindgrosspremium().toString()));
+        }
+        dto.setSuminsured(totalSuminsured);
+        // sumgrosspremium 使用硬编码值 99.9(与保司正确请求一致),不与 vo.getPremium() 挂钩
+        dto.setSumgrosspremium(parseNumeric("99.9"));
         return dto;
     }
 
@@ -243,11 +289,11 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         detail1.setSerialno(1);
         detail1.setKindcode("1119066");
         detail1.setKindname("机动车辆驾乘意外伤害保险意外身故保险责任(2024款)");
-        detail1.setKindrate("0.098");
-        detail1.setKindunitinsured("50000");
-        detail1.setKindsuminsured("250000");
-        detail1.setKindunitpremium("4.9");
-        detail1.setKindgrosspremium("54");
+        detail1.setKindrate(parseNumeric("0.098"));
+        detail1.setKindunitinsured(parseNumeric("50000"));
+        detail1.setKindsuminsured(parseNumeric("250000"));
+        detail1.setKindunitpremium(parseNumeric("4.9"));
+        detail1.setKindgrosspremium(parseNumeric("24.5"));
         list.add(detail1);
 
         // 机动车辆驾乘意外伤害保险意外残疾保险责任(2024款)
@@ -257,11 +303,11 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         detail2.setSerialno(2);
         detail2.setKindcode("1119067");
         detail2.setKindname("机动车辆驾乘意外伤害保险意外残疾保险责任(2024款)");
-        detail2.setKindrate("0.09166");
-        detail2.setKindunitinsured("30000");
-        detail2.setKindsuminsured("240000");
-        detail2.setKindunitpremium("2.75");
-        detail2.setKindgrosspremium("22");
+        detail2.setKindrate(parseNumeric("0.039"));
+        detail2.setKindunitinsured(parseNumeric("50000"));
+        detail2.setKindsuminsured(parseNumeric("250000"));
+        detail2.setKindunitpremium(parseNumeric("1.95"));
+        detail2.setKindgrosspremium(parseNumeric("9.75"));
         list.add(detail2);
 
         // 附加机动车辆驾乘意外伤害医疗保险(2024款)
@@ -271,11 +317,11 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         detail3.setSerialno(3);
         detail3.setKindcode("1119065");
         detail3.setKindname("附加机动车辆驾乘意外伤害医疗保险(2024款)");
-        detail3.setKindrate("1.0001");
-        detail3.setKindunitinsured("3000");
-        detail3.setKindsuminsured("24000");
-        detail3.setKindunitpremium("3");
-        detail3.setKindgrosspremium("24");
+        detail3.setKindrate(parseNumeric("2.626"));
+        detail3.setKindunitinsured(parseNumeric("5000"));
+        detail3.setKindsuminsured(parseNumeric("25000"));
+        detail3.setKindunitpremium(parseNumeric("13.13"));
+        detail3.setKindgrosspremium(parseNumeric("65.65"));
         list.add(detail3);
 
         return list;
@@ -311,12 +357,13 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         private static final long serialVersionUID = 4972640996367640469L;
 
         private String kindcode;
-        private String liabamt;
+        // 使用Object类型确保liabamt序列化为数字而非字符串,匹配保司API期望的数字类型
+        private Object liabamt;
         private String liabname;
         private String model = "0";
-        private String quantity;
+        private Object quantity;
         private String serviceTimes;
-        private String unitAmount;
+        private Object unitAmount;
     }
 
     @Data
@@ -333,8 +380,9 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         private String programname;
         private String companycode;
         private String resourcetype;
-        private String suminsured;
-        private String sumgrosspremium;
+        // 使用Object类型确保序列化为数字而非字符串,匹配保司API期望的数字类型
+        private Object suminsured;
+        private Object sumgrosspremium;
         private String sumuwpricetaxtotal;
         private Boolean ifdefault;
         private String seatcount;
@@ -353,7 +401,7 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         private String risk1205field;
         private String risk1283items;
         private String drivingtype;
-        private String relationcarowner = "a";
+        private String relationcarowner;
     }
 
     @Data
@@ -407,11 +455,12 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         private Integer serialno;
         private String kindcode;
         private String kindname;
-        private String kindrate;
-        private String kindunitinsured;
-        private String kindsuminsured;
-        private String kindunitpremium;
-        private String kindgrosspremium;
+        // 使用Object类型确保序列化为数字,匹配保司API期望的数字类型
+        private Object kindrate;
+        private Object kindunitinsured;
+        private Object kindsuminsured;
+        private Object kindunitpremium;
+        private Object kindgrosspremium;
         private String itemDetailCode;
         private String itemDetailName;
         private String kindInd;

+ 1 - 0
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java

@@ -240,6 +240,7 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
                 .filter(e -> StrUtil.isNotEmpty(e.getProductCode()))
                 .forEach(e -> accidentList.add(HbCrawlerCalculationRequest.convertToAccidentInsuranceDTO(quoteVo.getBiRiskInfoVo(), e)));
         calculationRequest.setAccidentInsuranceList(accidentList);
+        calculationRequest.setAccidentEpolicyFlag(accidentList.isEmpty() ? "" : "Y");
     }
 
     // 重复投保提取时间

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/utils/HengBangAESUtil.java


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

@@ -30,7 +30,7 @@ public class HtCrawlerOrder {
     private String ciCategory;
 
     /**
-     * 核保额外需要的参数  交强评分
+     * 核保额外需要的参数  商业评分
      */
     private String biCategory;
 }

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

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

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

@@ -1,6 +1,8 @@
 package com.jzg.quotation.renbaonew.crawler.service.impl;
 
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.entity.quote.vo.*;
 import com.jzg.commons.entity.quote.vo.aggregated.*;
@@ -16,6 +18,7 @@ import com.jzg.quotation.commons.entity.GetCaptchaResponse;
 import com.jzg.quotation.commons.standard.conversion.ConfigureParametersConversion;
 import com.jzg.quotation.renbaonew.crawler.component.RenBaoNewCrawlerCacheComponent;
 import com.jzg.quotation.renbaonew.crawler.component.RenBaoNewCrawlerRequestComponent;
+import com.jzg.quotation.renbaonew.crawler.constant.InsuranceKindCodeMapping;
 import com.jzg.quotation.renbaonew.crawler.entity.RenBaoNewCrawlerConfigureParameters;
 import com.jzg.quotation.renbaonew.crawler.entity.bo.LoginInfoBO;
 import com.jzg.quotation.renbaonew.crawler.entity.response.*;
@@ -111,7 +114,7 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
         RenBaoNewCrawlerSaveResponse saveResponse = requestComponent.saveAsProposal(saveRequest, headers);
 
         // 4. 构建结果
-        QuoteResultsVo resultsVo = buildQuoteResultsVo(quoteVo, quoteRequest, saveResponse, headers, username);
+        QuoteResultsVo resultsVo = buildQuoteResultsVo(quoteVo, quoteRequest, quoteResponse, saveResponse, headers, username);
 
         // 5. 保存订单信息
         orderService.saveOrder(
@@ -724,6 +727,7 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
      * @return 报价结果VO
      */
     private QuoteResultsVo buildQuoteResultsVo(QuoteVo quoteVo, RenBaoNewCrawlerQuoteRequest quoteRequest,
+                                               RenBaoNewCrawlerQuoteResponse quoteResponse,
                                                RenBaoNewCrawlerSaveResponse saveResponse,
                                                HttpHeaders headers, String username) {
         QuoteResultsVo resultsVo = new QuoteResultsVo();
@@ -830,6 +834,26 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
             resultsVo.setCosts(costs);
         }
 
+        // 商业险种信息赋值:从报价响应的prpQitemKindVos中提取,人保kindCode转为平台编码
+        if (quoteResponse != null && quoteResponse.getData() != null
+                && quoteResponse.getData().getPrpQmain() != null
+                && quoteResponse.getData().getPrpQmain().getPrpQitemKindVos() != null) {
+            List<KindInfoVo> kindInfoVoList = new ArrayList<>();
+            for (RenBaoNewCrawlerQuoteResponse.PrpQitemKindVo item :
+                    quoteResponse.getData().getPrpQmain().getPrpQitemKindVos()) {
+                // 人保kindCode → 平台编码(如 051050 → A)
+                String platformKindCode = InsuranceKindCodeMapping.getPlatformKindCode(item.getKindCode());
+                for(KindInfoVo kindInfo :quoteVo.getKindInfoVo()){
+                    if(kindInfo.getKindCode().equals(platformKindCode)){
+                        kindInfo.setPremium(item.getPremium() != null ? String.valueOf(item.getPremium()) : null);
+                        kindInfo.setAmount(item.getAmount() != null ? String.valueOf(item.getAmount()) : null);
+                    }
+                }
+
+            }
+            resultsVo.setKindInfoVo(quoteVo.getKindInfoVo());
+        }
+
         // 获取评分
         if (!proposalNoDAA.isEmpty() || !proposalNoDZA.isEmpty()) {
             try {
@@ -839,6 +863,8 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
                     Map<String, Object> data = (Map<String, Object>) proposalInfo.get("data");
                     if (data != null) {
                         QuoteResultsVo.ScoreVo scoreVo = resultsVo.getScoreVo();
+                        JSONArray scoreJson = new JSONArray();
+
                         if (scoreVo == null) {
                             scoreVo = new QuoteResultsVo.ScoreVo();
                             resultsVo.setScoreVo(scoreVo);
@@ -846,13 +872,19 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
                         // 获取商业险评分
                         Map<String, Object> prpCmain = (Map<String, Object>) data.get("PrpCmain");
                         if (prpCmain != null && prpCmain.get("piccscore") != null) {
-                            scoreVo.setSyLossRation(prpCmain.get("piccscore").toString());
+                            scoreJson.add(new JSONObject()
+                                    .fluentPut("scoreName", "商业险评分")
+                                    .fluentPut("score", prpCmain.get("piccscore").toString()));
                         }
                         // 获取交强险评分
                         Map<String, Object> prpCmainCI = (Map<String, Object>) data.get("prpCmainCI");
                         if (prpCmainCI != null && prpCmainCI.get("piccscore") != null) {
-                            scoreVo.setJqLossRation(prpCmainCI.get("piccscore").toString());
+                            scoreJson.add(new JSONObject()
+                                    .fluentPut("scoreName", "交强险评分")
+                                    .fluentPut("score", prpCmainCI.get("piccscore").toString()));
                         }
+                        scoreVo.setScoreJson(scoreJson);
+                        resultsVo.setScoreVo(scoreVo);
                     }
                 }
             } catch (Exception e) {
@@ -909,7 +941,7 @@ public class RenBaoNewCrawlerRequestImpl implements RenBaoNewCrawlerRequest {
             throw new SystemException("查询订单异常");
         }
 
-        // ③ 提取交强/商业单号,以及驾意险信息 —  
+        // ③ 提取交强/商业单号,以及驾意险信息 —
         String syProposalNo = "";
         String jqProposalNo = "";
         List<Map<String, String>> unitNoCarDataList = new ArrayList<>();

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

@@ -358,7 +358,7 @@ public class QuoteVerificationAspect {
         BigDecimal exportPercent = convertPercent(costType.getExport());
 
         // 计算应收金额
-        BigDecimal taxablePremium = premium.multiply(taxFactor);
+        BigDecimal taxablePremium = premium.divide(taxFactor,5,RoundingMode.HALF_EVEN);
 
         // 计算应付金额(保费 * 出口比例,保留2位小数)
         BigDecimal payable = premium.multiply(exportPercent.setScale(5, RoundingMode.DOWN));
@@ -368,7 +368,7 @@ public class QuoteVerificationAspect {
         BigDecimal commission = taxablePremium.multiply(commissionRatio).setScale(5, RoundingMode.HALF_EVEN);
         BigDecimal follow = taxablePremium.multiply(followRatio).setScale(5, RoundingMode.HALF_EVEN);
         setCommission.accept(insFeeOrders, commission);
-        setFollow.accept(insFeeOrders, commission);
+        setFollow.accept(insFeeOrders, follow);
         // modify by lipf, 2026年6月16日15:35:09  加投比例,不需要根据平台/私有进行1.06的计算
 
         BigDecimal addAmount = premium.multiply(addThrowPercent).setScale(5, RoundingMode.HALF_EVEN);

+ 2 - 11
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java

@@ -139,19 +139,11 @@ public class InsFeeAuditController {
     @Operation(summary = "审核订单")
     public HttpResult<String> verifyOrder(@RequestBody VerifyOrderParam param){
         try{
-            insFeeAuditService.verifyOrder(param);
+            return insFeeAuditService.verifyOrder(param);
         }catch (Exception e){
             log.info("审核订单发生异常:param=[{}], e", JSONUtil.toJsonStr(param), e);
             return HttpResult.error(e.getMessage(),param.getOrderNo());
         }
-        // add by lipf ,2026年6月13日14:50:24 这里将orderNo 作为result的data传回去。 在记录订单轨迹的时候使用
-        if("1".equals(Objects.toString(param.getAuditStatus(),"") )){
-            return HttpResult.ok("订单审核成功",param.getOrderNo());
-        }else if("2".equals(Objects.toString(param.getAuditStatus(),""))){
-            return HttpResult.ok("订单审核驳回成功",param.getOrderNo());
-        }else{
-            return HttpResult.ok("订单审核状态不支持。"+param.getAuditStatus(),param.getOrderNo());
-        }
     }
 
     /**
@@ -196,8 +188,7 @@ public class InsFeeAuditController {
     @PostMapping("/saveCostInfo")
     @Operation(summary = "保存调整的费用")
     public HttpResult<String> saveCostInfo(@RequestBody PtlAgreementCostRatioVo param){
-        insFeeAuditService.saveCostInfo(param);
-        return HttpResult.ok();
+        return insFeeAuditService.saveCostInfo(param);
     }
 
     /**

+ 4 - 2
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsFeeAuditService.java

@@ -79,7 +79,7 @@ public interface InsFeeAuditService extends IService<InsFeeAudit> {
      * 审核订单
      * @param param
      */
-    void verifyOrder(VerifyOrderParam param);
+    HttpResult<String> verifyOrder(VerifyOrderParam param);
 
     /**
      * 设置为疑问订单
@@ -98,9 +98,11 @@ public interface InsFeeAuditService extends IService<InsFeeAudit> {
 
     /**
      * 保存调整的费用
+     *
      * @param param
+     * @return HttpResult<String> 费用调整的结果,可能保存失败
      */
-    void saveCostInfo(PtlAgreementCostRatioVo param);
+    HttpResult<String> saveCostInfo(PtlAgreementCostRatioVo param);
 
     /**
      * 导出订单审核列表

+ 59 - 6
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeAuditServiceImpl.java

@@ -56,6 +56,7 @@ import org.springframework.stereotype.Service;
 
 import java.io.File;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.util.*;
@@ -415,10 +416,10 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
      */
     @Override
     @GlobalTransactional(rollbackFor = Exception.class)
-    public void verifyOrder(VerifyOrderParam param) {
+    public HttpResult<String> verifyOrder(VerifyOrderParam param) {
         String systemCode = baseController.getSystemCode();
         String userId = baseController.getUserId();
-        log.info("订单费用审核.systemCode=[{}], param=[{}]",systemCode, JSONUtil.toJsonStr(param));
+        log.info("订单费用审核.systemCode=[{}],userId=[{}],param=[{}]",systemCode,userId, JSONUtil.toJsonStr(param));
         InsFeeAudit audit = this.getById(param.getOrderNo());
         if(audit == null){
             throw new ServiceException("要审核的订单不存在");
@@ -445,7 +446,6 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
         }
         InsFeeOrders feeOrders = null;
         SysUserAccount userAccount = null;
-        String jzgInfoId = null;
         if(param.getAuditStatus().equals(1)){
             StateResult stateFailResult = auditStateListener.statusChange(AuditState.AuditStateEnum.SUCCESS_AUDIT,audit.getAuditStatus()+"");
             audit.setAuditStatus(stateFailResult.getCurrentState());
@@ -518,6 +518,14 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
         }catch (Exception e){
             log.error("保存合伙人佣金计算异常:{}",e.getMessage(), e);
         }
+        // add by lipf ,2026年6月13日14:50:24 这里将orderNo 作为result的data传回去。 在记录订单轨迹的时候使用
+        if("1".equals(Objects.toString(param.getAuditStatus(),"") )){
+            return HttpResult.ok("订单审核成功",param.getOrderNo());
+        }else if("2".equals(Objects.toString(param.getAuditStatus(),""))){
+            return HttpResult.ok("订单审核驳回成功",param.getOrderNo());
+        }else{
+            return HttpResult.ok("订单审核状态不支持。"+param.getAuditStatus(),param.getOrderNo());
+        }
     }
 
     /**
@@ -811,8 +819,16 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
     }
 
     @Override
-    public void saveCostInfo(PtlAgreementCostRatioVo param) {
-        log.info("保存调整后的费用:param=[{}]", JSONUtil.toJsonStr(param));
+    public HttpResult<String> saveCostInfo(PtlAgreementCostRatioVo param) {
+        String systemCode = baseController.getSystemCode();
+        String userName = baseController.getUserName();
+        log.info("保存调整后的费用:systemCode=[{}], userName=[{}],param=[{}]", systemCode, userName, JSONUtil.toJsonStr(param));
+        // add by lipf, 2026年6月22日10:15:51 已经审核通过的订单不能在让调整费用,否则会造成费用不一致。 会影响很多地方
+        String orderNo = param.getOrderNo();
+        HttpResult<String> validateRes = this.validateOrderCheck(orderNo);
+        if(validateRes.isFail()){
+            return validateRes;
+        }
         try {
             feeOrdersService.calcCosts(param);
         } catch (ReflectiveOperationException e) {
@@ -821,7 +837,38 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
         }
         // 保存比例调整记录
         InsFeeOrderRecord record = new InsFeeOrderRecord(param);
-        recordService.updateById(record);
+        // modify by lipf 2026年6月23日11:08:26 解决原先没有插入数据的问题,并且调整了表结构(主键由order_no调整为id),来保证多次调整不会报错
+        recordService.save(record);
+        return HttpResult.ok();
+    }
+
+    /**
+     * 校验订单是否审核通过,如果审核通过,则不让修改费用
+     *
+     * @param orderNo 订单号
+     * @author lipf
+     * @date 2026/6/22 10:16
+     */
+    private HttpResult<String> validateOrderCheck(String orderNo) {
+        InsFeeAudit audit = this.getById(orderNo);
+        if(audit == null){
+            String msg = String.format("订单%s不存在审核记录,无法修改", orderNo);
+            log.info(msg);
+            return HttpResult.error(msg);
+        }
+        if(audit.getAuditStatus() > 0){
+            String msg;
+            if(1  ==  audit.getAuditStatus()){
+                msg = String.format("订单%s已经审核通过,无法修改",orderNo);
+            } else if(2  ==  audit.getAuditStatus()){
+                msg = String.format("订单%s已经审核驳回,无法修改",orderNo);
+            }else{
+                msg = String.format("订单%s不是未审核状态,无法修改",orderNo);
+            }
+            log.info(msg);
+            return HttpResult.error(msg);
+        }
+        return HttpResult.ok();
     }
 
     @Override
@@ -837,6 +884,12 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
     @Override
     public String exportAuditList(FeeAuditParam param) {
         List<FeeAuditVo> result = queryList(param);
+        for (FeeAuditVo feeAuditVo : result) {
+            feeAuditVo.setTotalPayablePremium(feeAuditVo.getTotalPayablePremium().setScale(2, RoundingMode.HALF_UP));
+            feeAuditVo.setJyPayablePremium(feeAuditVo.getJyPayablePremium().setScale(2, RoundingMode.HALF_UP));
+            feeAuditVo.setSyPayablePremium(feeAuditVo.getSyPayablePremium().setScale(2, RoundingMode.HALF_UP));
+            feeAuditVo.setJqPayablePremium(feeAuditVo.getJqPayablePremium().setScale(2, RoundingMode.HALF_UP));
+        }
 
         // 调用动态导出
         return exportBaseService.upLoadFile(

+ 32 - 19
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java

@@ -16,6 +16,7 @@ import com.jzg.commons.entity.po.PtlAgreement;
 import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.AssertionUtils;
+import com.jzg.commons.util.BigDecimalUtil;
 import com.jzg.commons.util.StringUtils;
 import com.jzg.quotation.commons.client.OrgClient;
 import com.jzg.quotation.summary.mapper.InsFeeOrdersMapper;
@@ -23,16 +24,14 @@ import com.jzg.quotation.summary.service.InsFeeOrdersService;
 import com.jzg.quotation.summary.service.InsOrdersCostsService;
 import com.jzg.quotation.summary.service.InsOrdersService;
 import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
 
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -60,15 +59,6 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
     private InsFeeOrdersMapper insFeeOrdersMapper;
 
 
-    private String getSystemCode() {
-        //如果是APP登录的话 则传递SystemCode的头部字段
-        if (baseController.getUserSystemCode().equals("APP")) {
-            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
-            return request.getHeader("system_code");
-        }
-        return baseController.getUserSystemCode();
-    }
-
     /**
      * 订单审核时调整费用
      *
@@ -161,7 +151,7 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
             Integer withTax, BigDecimal taxRate, int scale) {
 
         // 计算基数
-        BigDecimal base = BigDecimal.ZERO;
+        BigDecimal base;
         if (withTax == 0) {
             // 不含税:保费 / 1.06
             base = premium.divide(taxRate, scale, RoundingMode.HALF_EVEN);
@@ -171,8 +161,8 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         }
 
         // ===================== 按比例计算各项费用 =====================
-        BigDecimal commission = base.multiply(commissionRatio).setScale(scale, RoundingMode.HALF_EVEN);
         BigDecimal inlet = base.multiply(inletRatio).setScale(scale, RoundingMode.HALF_EVEN);
+        BigDecimal commission = base.multiply(commissionRatio).setScale(scale, RoundingMode.HALF_EVEN);
         BigDecimal follow = base.multiply(followRatio).setScale(scale, RoundingMode.HALF_EVEN);
 
         // 加投直接乘
@@ -180,8 +170,10 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         // 出口直接乘
         BigDecimal export = premium.multiply(exportRatio).setScale(scale, RoundingMode.HALF_EVEN);
         BigDecimal exportKeepPoint = premium.multiply(exportKeepPointRatio).setScale(scale, RoundingMode.HALF_EVEN);
-        // 留点比例直接乘, modify by lipf ,留点比例在infFeeOrder中计算得到。这里直接使用 2026年6月16日17:32:09
-        BigDecimal keepPoint = premium.multiply(keepPointRatio).setScale(scale, RoundingMode.HALF_EVEN);
+        // 留点比例直接乘, modify by lipf ,留点比例在infFeeOrder中计算得到。这里直接使用 2026年6月16日17:32:09, 为了保持金额一致,留点比例不适用百分比乘积,而是使用金额相减
+        // BigDecimal keepPoint = premium.multiply(keepPointRatio).setScale(scale, RoundingMode.HALF_EVEN);
+        BigDecimal keepPoint = BigDecimalUtil.subtract(BigDecimalUtil.add(inlet,addThrow),export);
+        log.info("计算留点:inlet=[{}],addThrow=[{}].export=[{}]", inlet, addThrow, export);
 
         // 赋值到实体(自动匹配 jq / sy / jy)
         if ("jq".equals(type)) {
@@ -192,7 +184,14 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
             insFeeOrders.setJqKeepPointPremium(keepPoint);
             insFeeOrders.setJqExportPremium(export);
             insFeeOrders.setJqExportKeepPointPremium(exportKeepPoint);
-            insFeeOrders.setJqPayablePremium(commission);
+            insFeeOrders.setJqPayablePremium(export);
+
+            // add by lipf, 2026年6月23日10:42:36  更新具体某个险种的出口费用的时候,同步更新总的出口费用
+            List<BigDecimal> exportAmount = new ArrayList<>();
+            exportAmount.add(insFeeOrders.getJqExportPremium());
+            exportAmount.add(insFeeOrders.getSyExportPremium());
+            exportAmount.add(insFeeOrders.getJyExportPremium());
+            insFeeOrders.setTotalPayablePremium(BigDecimalUtil.add(exportAmount));
         } else if ("sy".equals(type)) {
             insFeeOrders.setSyCommissionPremium(commission);
             insFeeOrders.setSyReceivablePremium(inlet);
@@ -201,7 +200,14 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
             insFeeOrders.setSyKeepPointPremium(keepPoint);
             insFeeOrders.setSyExportPremium(export);
             insFeeOrders.setSyExportKeepPointPremium(exportKeepPoint);
-            insFeeOrders.setSyPayablePremium(commission);
+            insFeeOrders.setSyPayablePremium(export);
+
+            // add by lipf, 2026年6月23日10:42:36  更新具体某个险种的出口费用的时候,同步更新总的出口费用
+            List<BigDecimal> exportAmount = new ArrayList<>();
+            exportAmount.add(insFeeOrders.getJqExportPremium());
+            exportAmount.add(insFeeOrders.getSyExportPremium());
+            exportAmount.add(insFeeOrders.getJyExportPremium());
+            insFeeOrders.setTotalPayablePremium(BigDecimalUtil.add(exportAmount));
         } else if ("jy".equals(type)) {
             insFeeOrders.setJyCommissionPremium(commission);
             insFeeOrders.setJyReceivablePremium(inlet);
@@ -210,7 +216,14 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
             insFeeOrders.setJyKeepPointPremium(keepPoint);
             insFeeOrders.setJyExportPremium(export);
             insFeeOrders.setJyExportKeepPointPremium(exportKeepPoint);
-            insFeeOrders.setJyPayablePremium(commission);
+            insFeeOrders.setJyPayablePremium(export);
+
+            // add by lipf, 2026年6月23日10:42:36  更新具体某个险种的出口费用的时候,同步更新总的出口费用
+            List<BigDecimal> exportAmount = new ArrayList<>();
+            exportAmount.add(insFeeOrders.getJqExportPremium());
+            exportAmount.add(insFeeOrders.getSyExportPremium());
+            exportAmount.add(insFeeOrders.getJyExportPremium());
+            insFeeOrders.setTotalPayablePremium(BigDecimalUtil.add(exportAmount));
         }
     }
 

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

@@ -1357,10 +1357,10 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
 //            PtlAgreement ptlAgreement = orgClient.getByAgreementId(insOrdersVo.getInsOrders().getAgreementId());
 //            resultVo.setCostRatio(new PtlAgreementCostRatioVo(ptlAgreementCostTypeList, ptlAgreement));
             resultVo.setCostRatio(new PtlAgreementCostRatioVo(insFeeOrders));
-            // add by lipf, 手动计算留点比例的费用 2026年6月11日11:31:39
-            insFeeOrders.setJqKeepPointPremium(BigDecimalUtil.divide( BigDecimalUtil.multiply(insFeeOrders.getJqPremium(),resultVo.getCostRatio().getJqKeepPointRatio()),new BigDecimal(100)));
-            insFeeOrders.setSyKeepPointPremium(BigDecimalUtil.divide(BigDecimalUtil.multiply(insFeeOrders.getSyPremium(),resultVo.getCostRatio().getSyKeepPointRatio()),new BigDecimal(100)));
-            insFeeOrders.setJyKeepPointPremium(BigDecimalUtil.divide(BigDecimalUtil.multiply(insFeeOrders.getJyPremium(),resultVo.getCostRatio().getJyKeepPointRatio()),new BigDecimal(100)));
+            // add by lipf, 手动计算留点比例的费用 2026年6月11日11:31:39. modify by lipf, 留点比例直接从ins_fee_orders中获取 2026年6月22日17:32:46
+//            insFeeOrders.setJqKeepPointPremium(BigDecimalUtil.divide( BigDecimalUtil.multiply(insFeeOrders.getJqPremium(),resultVo.getCostRatio().getJqKeepPointRatio()),new BigDecimal(100)));
+//            insFeeOrders.setSyKeepPointPremium(BigDecimalUtil.divide(BigDecimalUtil.multiply(insFeeOrders.getSyPremium(),resultVo.getCostRatio().getSyKeepPointRatio()),new BigDecimal(100)));
+//            insFeeOrders.setJyKeepPointPremium(BigDecimalUtil.divide(BigDecimalUtil.multiply(insFeeOrders.getJyPremium(),resultVo.getCostRatio().getJyKeepPointRatio()),new BigDecimal(100)));
             resultVo.setInsFeeOrders(new InsFeeOrdersVo(insFeeOrders));
         }
         //权益信息

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

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

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

@@ -137,8 +137,9 @@ public class TkCrawlerQuoteResultsBuild {
         // 设置总费用
         BigDecimal ci = premium.getJqPremium() == null ? BigDecimal.ZERO : premium.getJqPremium();
         BigDecimal bi = premium.getSyPremium() == null ? BigDecimal.ZERO : premium.getSyPremium();
+        BigDecimal jyx = premium.getJyxPremium() == null ? BigDecimal.ZERO : premium.getJyxPremium();
         BigDecimal vv = preciseInitResult.getCarTax().getSumPayment() == null ? BigDecimal.ZERO : preciseInitResult.getCarTax().getSumPayment();
-        BigDecimal total = ci.add(bi).add(vv);
+        BigDecimal total = ci.add(bi).add(jyx).add(vv);
         quoteResultsVo.getCosts().setSumPremium(total.toPlainString());
         // 折扣
         quoteResultsVo.getScoreVo().setJqAdjustRate(preciseInitResult.getCiDisCount() != null ? preciseInitResult.getCiDisCount().toString() : null);

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

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

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

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

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

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

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

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

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

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

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

@@ -1107,11 +1107,12 @@ public class TKSimpleService {
         // 公司系统的驾意险参数为空证明没有选择驾意险
         if (CollectionUtils.isNotEmpty(accidentalDrivings)) {
             for (AccidentalDrivingVo accidentalDriving : accidentalDrivings) {
-                if (carPlanInfoMap.isEmpty() || accidentalDriving.getRiskCode() == null) {
+                if (carPlanInfoMap.isEmpty() || accidentalDriving.getProductCode() == null) {
                     continue;
                 }
                 TKCarPlanInfo tkCarPlanInfo = carPlanInfoMap.get(accidentalDriving.getProductCode());
                 driverAccidentVo.setIsSelect("1");
+                driverAccidentVo.setQuantity(accidentalDriving.getQuantity());
                 driverAccidentVo.setSelectPlanCode(tkCarPlanInfo.getPlanCode());
                 driverAccidentVo.setQuoteAmountCN(tkCarPlanInfo.getPlanName());
                 driverAccidentVo.setPremium(new BigDecimal(tkCarPlanInfo.getSumPremium()));

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

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

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

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

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

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

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

@@ -8,10 +8,13 @@ import com.jzg.commons.entity.quote.vo.KindInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.RiskInfoVo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteResultsVo;
+import com.jzg.commons.util.StringUtils;
+import com.jzg.quotation.commons.constant.enums.quote.RenewalEnum;
 import com.jzg.quotation.taishan.crawler.entity.response.TaiShanCrawlerQuotationSaveResponse;
 import com.jzg.quotation.taishan.crawler.entity.response.TaiShanCrawlerRiskManagementResponse;
 import lombok.extern.slf4j.Slf4j;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -68,6 +71,24 @@ public class TaiShanCrawlerQuoteResultsVoBuild {
         }
 
         if(riskResponse != null && riskResponse.getResult() != null){
+            // 续保标识逻辑:renewalClass不为空时jq_renewalflag=1,否则=0;sy_renewalflag始终为空
+            String renewalClass = riskResponse.getResult().getRenewalClass();
+            String jqRenewalflag = (renewalClass != null && !renewalClass.isEmpty()) ? "1" : "0";
+            String syRenewalflag = "";
+//            scoreJson.add(new JSONObject()
+//                    .fluentPut("scoreName","交强续保标识")
+//                    .fluentPut("scoreKey","jq_renewalflag")
+//                    .fluentPut("jq_renewalflag", jqRenewalflag));
+//            scoreJson.add(new JSONObject()
+//                    .fluentPut("scoreName","商业续保标识")
+//                    .fluentPut("scoreKey","sy_renewalflag")
+//                    .fluentPut("sy_renewalflag", syRenewalflag));
+
+            // 交强续保
+            quoteResultsVo.getScoreVo().setJqRenewal(convertRenewalFlag(jqRenewalflag));
+            // 商业续保
+            quoteResultsVo.getScoreVo().setSyRenewal(convertRenewalFlag(syRenewalflag));
+
             scoreJson.add(new JSONObject()
                     .fluentPut("scoreName","泰山分")
                     .fluentPut("scoreKey","ctsScore")
@@ -180,10 +201,29 @@ public class TaiShanCrawlerQuoteResultsVoBuild {
             // 设置车船税
             quoteResultsVo.getCosts().setVvTax(String.valueOf(saveResponse.getResult().getCompulsoryInsurance().getCarShipTax().getSumTax()));
         }
-        // 设置非车险(驾意险)保费
-//        QuotationResponse.DataDTO.UnAutoPremiumDTO unAutoPremium = quotationResponse.getData().getUnAutoPremium();
-//        if (saveResponse.getResult(). != null) {
-//            quoteResultsVo.getCosts().setNiPremium(unAutoPremium.getPremium());
-//        }
+        //设置非车险(驾意险)保费
+        if (Objects.nonNull(saveResponse.getResult().getDiInsurance())) {
+            quoteResultsVo.getCosts().setNiPremium(saveResponse.getResult().getDiInsurance().getPremium());
+        }
+        // 设置总费用
+        BigDecimal bi = quoteResultsVo.getCosts().getBiPremium() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getBiPremium());
+        BigDecimal ci = quoteResultsVo.getCosts().getCiPremium() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getCiPremium());
+        BigDecimal vv = quoteResultsVo.getCosts().getVvTax() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getVvTax());
+        BigDecimal ni = quoteResultsVo.getCosts().getNiPremium() == null ? BigDecimal.ZERO : new BigDecimal(quoteResultsVo.getCosts().getNiPremium());
+
+        BigDecimal total = bi.add(ci).add(vv).add(ni);
+        quoteResultsVo.getCosts().setSumPremium(total.toPlainString());
+    }
+
+    private static String convertRenewalFlag(String renewalFlag) {
+        if (!StringUtils.hasText(renewalFlag)) {
+            return null;
+        }
+        // RenewalEnum 枚举值
+        if (renewalFlag.equals("0")) {
+            return String.valueOf(RenewalEnum.Renewal.getCode());
+        } else {
+            return String.valueOf(RenewalEnum.Transfer.getCode());
+        }
     }
 }

+ 51 - 1
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/component/TaiShanCrawlerRequestComponent.java

@@ -11,12 +11,13 @@ import com.jzg.quotation.taishan.crawler.properties.TaiShanCrawlerProperties;
 import com.jzg.quotation.commons.component.RequestComponent;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
-import org.springframework.util.ObjectUtils;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
 
 import java.util.Map;
 import java.util.Objects;
@@ -173,6 +174,55 @@ public class TaiShanCrawlerRequestComponent {
         return response;
     }
 
+    /**
+     * 车型查询(带登录状态检查)
+     *
+     * @param request
+     * @param headers
+     * @return TaiShanCrawlerCarResponse
+     */
+    public TaiShanCrawlerCarResponse queryCarModelsWithCheck(TaiShanCrawlerCarRequest request, HttpHeaders headers) {
+        // 1. 请求体 JSON
+        String jsonString = com.alibaba.fastjson.JSON.toJSONString(request);
+        log.info("车型搜索参数:{}", jsonString);
+        // 2. 执行 POST
+        ResponseEntity<String> responseEntity;
+        try {
+            responseEntity = requestComponent.post(
+                    RequestUrl.CAR.getRequestUrl(taiShanCrawlerProperties.getBaseUrl()),
+                    jsonString,
+                    String.class,
+                    headers);
+        } catch (WebClientResponseException e) {
+            // 检查是否是 500 错误且响应体为空(账号掉线)
+            if (e.getStatusCode().value() == 500 &&
+                    (e.getResponseBodyAsString() == null || e.getResponseBodyAsString().isEmpty())) {
+                log.error("账号掉线,请重新登录后重新报价");
+                throw new SystemException("账号掉线,请重新登录后重新报价");
+            }
+            throw e;
+        }
+        // 3. 获取响应
+        String responseBody = responseEntity.getBody();
+
+        // 3.1 检查500错误且响应体为空(账号掉线)
+        if (responseEntity.getStatusCode().value() == 500 &&
+                (responseBody == null || responseBody.isEmpty())) {
+            log.error("账号掉线,请重新登录后重新报价");
+            throw new SystemException("账号掉线,请重新登录后重新报价");
+        }
+
+        log.info("响应内容 {}", responseBody);
+        // 4. 反序列化
+        TaiShanCrawlerCarResponse response = com.alibaba.fastjson.JSON.parseObject(responseBody, TaiShanCrawlerCarResponse.class);
+
+        // 5. 判断返回码
+        if ("200".equals(response.getCode())) {
+            return response;
+        }
+        throw new SystemException(response.getMessage());
+    }
+
     /**
      * 获取车辆实际价值
      *

+ 3 - 1
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/service/impl/TaiShanCrawlerQuoteProcessServiceImpl.java

@@ -297,7 +297,9 @@ public class TaiShanCrawlerQuoteProcessServiceImpl implements TaiShanCrawlerQuot
     public HttpHeaders getHeaders(String username, String comCode) {
         //String authorization = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1ODI0MjEiLCJhdXRoIjoiUk9MRV9CVVNJTkVTUyIsInBhc3N3b3JkX2V4cGlyZSI6MTUsImV4cCI6MTc4MTY4NzIzMn0.ldWz9TMY4AJ75VE0Bk1mkzAXPC9jJNMIWL82n0kGHrBwASgGvBxO3fe7orHbCIowt0athoRn1zA9m5ZNnO7olg";
 
-        String authorization = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1ODI0MjEiLCJhdXRoIjoiUk9MRV9CVVNJTkVTUyIsInBhc3N3b3JkX2V4cGlyZSI6MTIsImV4cCI6MTc4MTk0MDMyMX0.rsR8yMmSsB5iOstJSToswargqTCFB5He37UydrlK_lKFsHVqtBL-EOAgls4YL4nKWvRtbSxxY6HZRczHFG0iRw";
+        //String authorization = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1ODI0MjEiLCJhdXRoIjoiUk9MRV9CVVNJTkVTUyIsInBhc3N3b3JkX2V4cGlyZSI6MTIsImV4cCI6MTc4MTk0MDMyMX0.rsR8yMmSsB5iOstJSToswargqTCFB5He37UydrlK_lKFsHVqtBL-EOAgls4YL4nKWvRtbSxxY6HZRczHFG0iRw";
+        String authorization = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1ODI0MjEiLCJhdXRoIjoiUk9MRV9CVVNJTkVTUyIsInBhc3N3b3JkX2V4cGlyZSI6NjIsImV4cCI6MTc4NDc2NzY0N30.6JLD1Cc4_Vhuh5qSJ-lnEQ5MsNskbn6MzFbgUXRyCwSZzVHCI7-jpU04Mo7kLq2rc8E2LVhWHgmjyYD0rYCIiQ";
+
         HttpHeaders httpHeaders = new HttpHeaders();
         
         httpHeaders.set("Accept", "application/json, text/plain, */*");

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

@@ -99,8 +99,8 @@ public class TaiShanCrawlerRequestImpl implements TaiShanCrawlerRequest {
         HttpHeaders headers = taiShanCrawlerQuoteProcessService.getHeaders(attributionInformationVo.getUsername(), parameters.getComCode());
         // 2.0 车型查询
         TaiShanCrawlerCarRequest taiShanCrawlerCarRequest = new TaiShanCrawlerCarRequest(quoteVo,parameters.getComCode());
-        //车型查询
-        TaiShanCrawlerCarResponse taiShanCrawlerCarResponse = taiShanCrawlerRequestComponent.queryCarModels(taiShanCrawlerCarRequest, headers);
+        //车型查询(带登录状态检查)
+        TaiShanCrawlerCarResponse taiShanCrawlerCarResponse = taiShanCrawlerRequestComponent.queryCarModelsWithCheck(taiShanCrawlerCarRequest, headers);
         // 2.1 获取相同的车型
         List<TaiShanCrawlerCarResponse.CarModelInfo> models = taiShanCrawlerCarResponse.getResult();
         TaiShanCrawlerCarResponse.CarModelInfo modelsDTO = CarModelsFilterUtils.to(models, quoteVo.getCarInfoVo());

+ 4 - 3
tenant/organization/src/main/java/com/jzg/organization/controller/MessageController.java

@@ -74,7 +74,8 @@ public class MessageController extends BaseController {
         String userName = getUserName();
         SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>()
                 .eq(SysUser::getMobile, userName));
-        return HttpResult.ok(messageService.getMessageCount(sysUser.getId()));
+        // userid 传手机号,因为消息发的都是手机号
+        return HttpResult.ok(messageService.getMessageCount(userName));
     }
 
     /**
@@ -92,7 +93,7 @@ public class MessageController extends BaseController {
         );
         if(StringUtils.isNotBlank(param.getId())){
             LambdaUpdateWrapper<SysMessageUser>  wrapper = new LambdaUpdateWrapper<>();
-            wrapper.eq(SysMessageUser::getUserId, info.getId())
+            wrapper.eq(SysMessageUser::getUserId, userName)
                     .eq(SysMessageUser::getMessageId, param.getId())
                     .set(SysMessageUser::getIsRead, 1);
             messageUserService.update(wrapper);
@@ -106,7 +107,7 @@ public class MessageController extends BaseController {
                 List<SysMessage> messages = messageService.list(wrapper);
                 List<String> messageIds = messages.stream().map(SysMessage::getId).collect(Collectors.toList());
                 LambdaUpdateWrapper<SysMessageUser> wrapper2 = new LambdaUpdateWrapper<>();
-                wrapper2.eq(SysMessageUser::getUserId, info.getId())
+                wrapper2.eq(SysMessageUser::getUserId, userName)
                         .in(SysMessageUser::getMessageId, messageIds)
                         .set(SysMessageUser::getIsRead, 1);
                 messageUserService.update(wrapper2);

+ 19 - 1
tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java

@@ -447,7 +447,7 @@ public class ReceivableController {
         try{
             List<String> orderNos = receivablePageIds.stream().map(InsPlyIncomeOrder::getOrderNo).distinct().toList();
             totalReceivablePremium = receivableService.queryAllTotalReceivablePremium(orderNos);
-            totalReceivablePremium = totalReceivablePremium.setScale(2, RoundingMode.HALF_DOWN);
+            totalReceivablePremium = totalReceivablePremium.setScale(5, RoundingMode.HALF_DOWN);
         }catch (Exception e){
             log.error("统计总的应收异常",e);
         }
@@ -573,6 +573,24 @@ public class ReceivableController {
         return HttpResult.ok(receivableService.deleteSettlementById(id) ? "删除成功":"删除失败");
     }
 
+    /**
+     * 删除平台结算记录
+     *
+     * @author lipf
+     * @date 2026/6/22 16:18
+     */
+    @DeleteMapping("/deletePlatformSettlementById/{id}")
+    @Operation(summary = "删除平台结算记录")
+    public HttpResult<String> deletePlatformSettlementById(@PathVariable String id){
+        return receivableService.deletePlatformSettlementById(id);
+    }
+
+    @DeleteMapping("/deleteFollowSettlementById/{id}")
+    @Operation(summary = "删除跟单结算记录")
+    public HttpResult<Boolean> deleteFollowSettlementById(@PathVariable String id) {
+        return HttpResult.ok(receivableService.deleteFollowSettlementById(id) ? "删除成功":"删除失败");
+    }
+
 
     @PostMapping("exportSuperviseSettlementExcel")
     @Operation(summary = "导出应收手续费结算记录excel文件")

+ 2 - 2
tenant/organization/src/main/java/com/jzg/organization/controller/SchemeController.java

@@ -107,8 +107,8 @@ public class SchemeController {
 
     @Operation(summary = "获取方案结果")
     @GetMapping("/getSchemeResult")
-    public HttpResult getSchemeResult(String companyId,String productId,String seatCount){
-         SchemeResultVo schemeResultVo = ptlSchemeService.getSchemeResult(companyId,productId,seatCount);
+    public HttpResult getSchemeResult(String companyId,String productId,String seatCount,String energyType,String vehicleType,String carnature){
+         SchemeResultVo schemeResultVo = ptlSchemeService.getSchemeResult(companyId,productId,seatCount,energyType,vehicleType,carnature);
         return HttpResult.ok(schemeResultVo);
     }
 

+ 2 - 1
tenant/organization/src/main/java/com/jzg/organization/controller/UserAccountController.java

@@ -9,6 +9,7 @@ import com.jzg.commons.entity.dto.IncomeAndExpenseParam;
 import com.jzg.commons.entity.dto.SysUserAccountPageParam;
 import com.jzg.commons.entity.dto.SysUserAccountParam;
 import com.jzg.commons.entity.po.SysUserAccount;
+import com.jzg.commons.entity.vo.IncomeAndExpenseVo;
 import com.jzg.commons.entity.vo.SysUserAccountVo;
 import com.jzg.commons.entity.vo.UserAccountStatisVo;
 import com.jzg.organization.service.SysUserAccountIncomeLogService;
@@ -91,7 +92,7 @@ public class UserAccountController {
 
     @Operation(summary = "收支记录")
     @PostMapping("/getIncomeAndExpense")
-    public HttpResult getIncomeAndExpense(@RequestBody IncomeAndExpenseParam param){
+    public HttpResult<List<IncomeAndExpenseVo>> getIncomeAndExpense(@RequestBody IncomeAndExpenseParam param){
         return HttpResult.ok(userAccountService.getIncomeAndExpense(param));
     }
 

+ 14 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/ReceivableMapper.java

@@ -204,6 +204,11 @@ public interface ReceivableMapper extends BaseMapper<InsPlyIncome> {
      */
     Map<String, Object> getJqSumReceivable(@Param("orderNos") List<String> orderNos);
 
+    /**
+     * 获取应收交强的总金额
+     */
+    Map<String, Object> getIncomeJqSumReceivable(@Param("orderNos") List<String> orderNos);
+
     /**
      * 获取开票记录
      */
@@ -258,4 +263,13 @@ public interface ReceivableMapper extends BaseMapper<InsPlyIncome> {
     List<InsPlyIncomeDto> queryFollowIncome(@Param("startYear") Integer startYear,
                                             @Param("endYear") Integer endYear,
                                             @Param("systemCode")  String systemCode);
+
+    /**
+     * 查询发票结算的金额
+     *
+     * @author lipf
+     * @date 2026/6/22 15:47
+     */
+    BigDecimal querySettledAmountByInvoiceIds(@Param("invoiceIdList") List<String> invoiceIdList);
+
 }

+ 1 - 1
tenant/organization/src/main/java/com/jzg/organization/service/PtlSchemeService.java

@@ -80,7 +80,7 @@ public interface PtlSchemeService extends IService<PtlScheme> {
      * @param productId
      * @return
      */
-    public SchemeResultVo getSchemeResult(String companyId,String productId,String seatCount);
+    public SchemeResultVo getSchemeResult(String companyId,String productId,String seatCount,String energyType,String vehicleType,String carnature);
 
     List<InsBusinessInsuranceVo> getBusinessInsuranceListByKindType(String kindCode);
 

+ 18 - 1
tenant/organization/src/main/java/com/jzg/organization/service/ReceivableService.java

@@ -426,10 +426,18 @@ public interface ReceivableService extends IService<InsPlyIncome> {
 
     /**
      * 删除结算记录
+     *
+     * @param settlementId
+     * @return
+     */
+    boolean deleteSettlementById(String settlementId);
+
+    /**
+     * 删除跟单结算记录
      * @param id
      * @return
      */
-    boolean deleteSettlementById(String id);
+    boolean deleteFollowSettlementById(String id);
 
     /**
      * 查询所有订单的应收总额
@@ -484,4 +492,13 @@ public interface ReceivableService extends IService<InsPlyIncome> {
      * @date 2026/6/11 9:33
      */
     int updateSettlementStatus(String invoiceId);
+
+    /**
+     * 平台协议结算
+     *
+     * @param id 平台协议结算记录的序号
+     * @author lipf
+     * @date 2026/6/22 11:40
+     */
+    HttpResult<String> deletePlatformSettlementById(String id);
 }

+ 10 - 1
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java

@@ -49,6 +49,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 
@@ -493,7 +494,7 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
     }
 
     @Override
-    public SchemeResultVo getSchemeResult(String companyId, String productId, String seatCount) {
+    public SchemeResultVo getSchemeResult(String companyId, String productId, String seatCount,String energyType,String vehicleType,String carnature) {
         log.info("根据保司Id和产品id查询协议信息。 companyId=[{}],productId=[{}]", companyId, productId);
         List<SchemeResultVo.SchemeVo> schemeInsuranceInfo = ptlSchemeMapper.getSchemeInsuranceInfo(companyId, productId);
         List<SchemeResultVo.SchemeVo> schemeDrivingInfo = ptlSchemeMapper.getSchemeDrivingInfo(companyId, productId);
@@ -584,6 +585,14 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
             optionalScheme.getKinds().removeIf(kind -> "J1".equals(kind.getKindCode()));
         }
 
+        //过滤 能源类型 使用性质 车辆种类
+        List<PtlScheme> ptlSchemes = ptlSchemeMapper.selectList(new LambdaQueryWrapper<PtlScheme>().
+                eq(PtlScheme::getCompanyId, companyId).eq(PtlScheme::getEnergyType, energyType).
+                like(PtlScheme::getCarnature, carnature).like(PtlScheme::getVehicleType, vehicleType).
+                eq(PtlScheme::getProductId, productId).eq(PtlScheme::getIsDelete, 0));
+        Map<String, PtlScheme> collectPtlSchemes = ptlSchemes.stream().collect(Collectors.toMap(PtlScheme::getId, Function.identity()));
+        AssertionUtils.isFail(collectPtlSchemes.isEmpty(), "没有可报价的方案配置信息");
+        schemeResultVo.getSchemes().stream().filter(s -> !collectPtlSchemes.containsKey(s.getId()));
         return schemeResultVo;
     }
 

+ 356 - 70
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -25,6 +25,7 @@ import com.jzg.commons.entity.finance.po.*;
 import com.jzg.commons.entity.finance.vo.*;
 import com.jzg.commons.entity.orders.po.InsOrderAdjust;
 import com.jzg.commons.entity.po.EsmInsCompany;
+import com.jzg.commons.entity.po.InsFeeOrders;
 import com.jzg.commons.entity.po.PtlAgreement;
 import com.jzg.commons.entity.po.SysUploadFiles;
 import com.jzg.commons.entity.quote.vo.orders.InsOrdersVo;
@@ -59,6 +60,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -200,6 +202,10 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      */
     @Override
     public HttpResult<List<ContractVO>> queryReceivableContact(InvoicingVo invoicingVo) {
+        List<String> incomeIds = invoicingVo.getIncomeIds();
+        if(CollUtil.isEmpty(incomeIds)){
+            return HttpResult.error("请勾选未结算的订单数据");
+        }
         List<InsPlyIncome> insPlyIncomes = baseMapper.queryIncomeByIds(invoicingVo);
         List<ContractVO> contractVOS = insPlyIncomes.stream().map(action -> new ContractVO(action.getContactPerson(), action.getContactPersonPhone())).distinct().toList();
         log.info("根据订单编号查询得到的对接人信息[{}]个", CollUtil.size(contractVOS));
@@ -763,8 +769,11 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 .map(String::trim)
                 .distinct() // 可选,去重
                 .collect(Collectors.toList());
+        // 根据tz要求将从ins_fee_order查费用信息改为从income表查
+        Map<String, Object> map = baseMapper.getIncomeJqSumReceivable(orderNos);
+
         // 修改后(返回总手续费 = 交强险+商业险+驾意险 手续费之和)
-        Map<String, Object> map = baseMapper.getJqSumReceivable(orderNos);
+//        Map<String, Object> map = baseMapper.getJqSumReceivable(orderNos);
         if(map == null){
             // 订单不存在的时候,直接返回0
             log.info("订单不存在。 orderNos=[{}]", JSONUtil.toJsonStr(orderNos));
@@ -1462,34 +1471,43 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         return importExcelResultVo;
     }
 
+
+    /**
+     * 平台协议结算
+     *
+     * @param settlementId 平台协议结算记录的序号
+     * @author lipf
+     * @date 2026/6/22 11:40
+     */
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteSettlementById(String id) {
-        log.info("私有协议-结算记录-删除: id=[{}]",id);
-        InsPlyIncomeInvoiceSettlement settlement = insPlyIncomeInvoiceSettlementMapper.selectById(id);
+    public HttpResult<String> deletePlatformSettlementById(String settlementId) {
+        log.info("平台删除结算记录。settlementId=[{}]",settlementId);
+        InsPlyIncomeInvoiceSettlement settlement = insPlyIncomeInvoiceSettlementMapper.selectById(settlementId);
         if(settlement == null){
+            log.info("平台删除结算记录.序号为[{}]的结算记录不存在", settlementId);
             throw new SystemException("结算记录不存在");
         }
         String invoiceId = settlement.getInvoiceId();
         if (StrUtil.isBlank(invoiceId)){
             throw new SystemException("结算记录id不存在");
         }
-        insPlyIncomeInvoiceMapper.update(null,
-                new LambdaUpdateWrapper<InsPlyIncomeInvoice>()
-                        .set(InsPlyIncomeInvoice::getStatus,"0").eq(InsPlyIncomeInvoice::getId,invoiceId));
-
+        insPlyIncomeInvoiceMapper.deleteById(invoiceId);
         // 查询中间表:使用 QueryWrapper,增加逻辑删除过滤
         LambdaQueryWrapper<InsPlyIncomeInvoiceLink> linkQueryWrapper = new LambdaQueryWrapper<>();
         linkQueryWrapper.eq(InsPlyIncomeInvoiceLink::getInvoiceId, invoiceId);
         linkQueryWrapper.eq(InsPlyIncomeInvoiceLink::getIsDelete, SETTLE_STATUS_RESET);
         List<InsPlyIncomeInvoiceLink> linkList = insPlyIncomeInvoiceLinkMapper.selectList(linkQueryWrapper);
 
+        if(CollUtil.isNotEmpty(linkList)){
+            for (InsPlyIncomeInvoiceLink insPlyIncomeInvoiceLink : linkList) {
+                insPlyIncomeInvoiceLinkMapper.deleteByInvoiceId(insPlyIncomeInvoiceLink.getInvoiceId());
+            }
+        }
         // 提取incomeId列表
-        List<String> incomeIdList = linkList.stream()
+        List<String> incomeIds = linkList.stream()
                 .map(InsPlyIncomeInvoiceLink::getIncomeId)
                 .distinct()
                 .collect(Collectors.toList());
-
         // 构造更新条件,增加主表逻辑删除过滤
         LambdaUpdateWrapper<InsPlyIncome> incomeUpdateWrapper = new LambdaUpdateWrapper<>();
         incomeUpdateWrapper.set(InsPlyIncome::getSettlementStatus, SETTLE_STATUS_RESET)
@@ -1498,10 +1516,89 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 .set(InsPlyIncome::getJySuperviseSettlement, SETTLE_STATUS_RESET)
                 .set(InsPlyIncome::getJyOtherSettlement, SETTLE_STATUS_RESET)
                 .eq(InsPlyIncome::getIsDelete, SETTLE_STATUS_RESET)
-                .in(InsPlyIncome::getId, incomeIdList);
+                .in(InsPlyIncome::getId, incomeIds);
 
         // 执行更新
         baseMapper.update(null, incomeUpdateWrapper);
+        insPlyIncomeInvoiceSettlementMapper.deleteById(settlementId);
+        return HttpResult.ok("删除结算记录成功");
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteSettlementById(String settlementId) {
+        log.info("私有协议-结算记录-删除: id=[{}]", settlementId);
+        InsPlyIncomeInvoiceSettlement settlement = insPlyIncomeInvoiceSettlementMapper.selectById(settlementId);
+        if(settlement == null){
+            log.info("序号为[{}]的结算记录不存在", settlementId);
+            throw new SystemException("结算记录不存在");
+        }
+        String invoiceId = settlement.getInvoiceId();
+        if (StrUtil.isBlank(invoiceId)){
+            throw new SystemException("结算记录id不存在");
+        }
+        insPlyIncomeInvoiceMapper.update(null,
+                new LambdaUpdateWrapper<InsPlyIncomeInvoice>()
+                        .set(InsPlyIncomeInvoice::getStatus,"0").eq(InsPlyIncomeInvoice::getId,invoiceId));
+
+        // 查询中间表:使用 QueryWrapper,增加逻辑删除过滤
+        LambdaQueryWrapper<InsPlyIncomeInvoiceLink> linkQueryWrapper = new LambdaQueryWrapper<>();
+        linkQueryWrapper.eq(InsPlyIncomeInvoiceLink::getInvoiceId, invoiceId);
+        linkQueryWrapper.eq(InsPlyIncomeInvoiceLink::getIsDelete, SETTLE_STATUS_RESET);
+        List<InsPlyIncomeInvoiceLink> linkList = insPlyIncomeInvoiceLinkMapper.selectList(linkQueryWrapper);
+
+        LambdaUpdateWrapper<InsPlyIncome> incomeUpdateWrapper = new LambdaUpdateWrapper<>();
+        if (CollUtil.isNotEmpty(linkList)){
+            // 提取incomeId列表
+            List<String> incomeIdList = linkList.stream()
+                    .map(InsPlyIncomeInvoiceLink::getIncomeId)
+                    .distinct()
+                    .collect(Collectors.toList());
+
+            // 构造更新条件,增加主表逻辑删除过滤
+            incomeUpdateWrapper.set(InsPlyIncome::getSettlementStatus, SETTLE_STATUS_RESET)
+                    .set(InsPlyIncome::getSuperviseSettlement, SETTLE_STATUS_RESET)
+                    .set(InsPlyIncome::getOtherSettlement, SETTLE_STATUS_RESET)
+                    .set(InsPlyIncome::getJySuperviseSettlement, SETTLE_STATUS_RESET)
+                    .set(InsPlyIncome::getJyOtherSettlement, SETTLE_STATUS_RESET)
+                    .eq(InsPlyIncome::getIsDelete, SETTLE_STATUS_RESET)
+                    .in(InsPlyIncome::getId, incomeIdList);
+            // 执行更新
+            baseMapper.update(null, incomeUpdateWrapper);
+        }
+        return insPlyIncomeInvoiceSettlementMapper.deleteById(settlementId) > 0;
+    }
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteFollowSettlementById(String id) {
+        log.info("私有协议-结算记录-删除: id=[{}]",id);
+        InsPlyIncomeInvoiceSettlement settlement = insPlyIncomeInvoiceSettlementMapper.selectById(id);
+        if(settlement == null){
+            throw new SystemException("结算记录不存在");
+        }
+        String invoiceId = settlement.getInvoiceId();
+        if (StrUtil.isBlank(invoiceId)){
+            throw new SystemException("结算记录id不存在");
+        }
+        insPlyIncomeInvoiceMapper.update(null,
+                new LambdaUpdateWrapper<InsPlyIncomeInvoice>()
+                        .set(InsPlyIncomeInvoice::getStatus,"0").eq(InsPlyIncomeInvoice::getId,invoiceId));
+
+        // 查询中间表:使用 QueryWrapper,增加逻辑删除过滤
+        LambdaQueryWrapper<InsPlyFollowInvoiceLink> linkQueryWrapper = new LambdaQueryWrapper<>();
+        linkQueryWrapper.eq(InsPlyFollowInvoiceLink::getInvoiceId, invoiceId);
+        linkQueryWrapper.eq(InsPlyFollowInvoiceLink::getIsDelete, SETTLE_STATUS_RESET);
+        List<InsPlyFollowInvoiceLink> linkList = insPlyFollowInvoiceLinkMapper.selectList(linkQueryWrapper);
+
+        if (CollUtil.isNotEmpty(linkList)){
+            // 删除中间表
+            List<String> followLinkIds = linkList.stream().map(InsPlyFollowInvoiceLink::getId).collect(Collectors.toList());
+            insPlyFollowInvoiceLinkMapper.deleteByIds(followLinkIds);
+
+            // 删除跟单表
+            List<String> followIds = linkList.stream().map(InsPlyFollowInvoiceLink::getFollowId).collect(Collectors.toList());
+            insFeeFollowOrderMapper.deleteByIds(followIds);
+        }
         return insPlyIncomeInvoiceSettlementMapper.deleteById(id) > 0;
     }
 
@@ -2166,68 +2263,243 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      * @date 2026/5/27 20:25
      */
     @Override
-    @Transactional
+    @Transactional(rollbackFor = Exception.class)
     public boolean batchModify(BatchModifyVo batchModifyVo) {
         log.info("批量修改应收订单: batchModifyVo=[{}]", JSONUtil.toJsonStr(batchModifyVo));
         List<String> incomeIds = batchModifyVo.getIncomeIds();
-        if(CollUtil.isEmpty(incomeIds)) {
+        if (CollUtil.isEmpty(incomeIds)) {
             throw new ServiceException("请勾选要批量修改的应收订单");
         }
-        List<String> insOrders = new ArrayList<>();
-        for (String incomeId : batchModifyVo.getIncomeIds()) {
-            InsPlyIncome insPlyIncomeSource = baseMapper.selectById(incomeId);
-            if(insPlyIncomeSource == null) {
-                log.info("批量修改应收订单。序号为[{}]的应收订单不存在", incomeId);
-                continue;
+
+        // 一次性查询所有需要修改的记录
+        List<InsPlyIncome> incomeList = baseMapper.selectBatchIds(incomeIds);
+        if (CollUtil.isEmpty(incomeList)) {
+            throw new ServiceException("未找到需要修改的应收订单");
+        }
+
+        // 收集订单号
+        List<String> orderNos = incomeList.stream()
+                .map(InsPlyIncome::getOrderNo)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 批量获取税率
+        Map<String, BigDecimal> taxRateMap = orderNos.stream()
+                .collect(Collectors.toMap(
+                        orderNo -> orderNo,
+                        this::obtainTaxRate,
+                        (v1, v2) -> v1 // 如果有重复,保留第一个
+                ));
+
+        // 准备批量更新的实体列表
+        List<InsPlyIncome> updateList = new ArrayList<>();
+
+        for (InsPlyIncome income : incomeList) {
+            BigDecimal taxRate = taxRateMap.getOrDefault(income.getOrderNo(), BigDecimal.ONE);
+            InsPlyIncome updateIncome = new InsPlyIncome();
+            updateIncome.setId(income.getId());
+
+            boolean hasUpdate = false;
+            String updateFlag = batchModifyVo.getUpdateFlag();
+
+            // 根据 updateFlag 处理不同的更新逻辑
+            if ("1".equals(updateFlag)) {
+                // 修改手续费
+                hasUpdate = handleSuperviseCosts(updateIncome, income, batchModifyVo, taxRate);
+            } else if ("2".equals(updateFlag)) {
+                // 修改跟单费
+                hasUpdate = handleOtherCosts(updateIncome, income, batchModifyVo, taxRate);
+            } else if ("3".equals(updateFlag)) {
+                // 修改驾意险费用
+                hasUpdate = handleJyCosts(updateIncome, income, batchModifyVo, taxRate);
+            } else if ("4".equals(updateFlag)) {
+                // 修改所有
+                boolean superviseUpdated = handleSuperviseCosts(updateIncome, income, batchModifyVo, taxRate);
+                boolean otherUpdated = handleOtherCosts(updateIncome, income, batchModifyVo, taxRate);
+                boolean jyUpdated = handleJyCosts(updateIncome, income, batchModifyVo, taxRate);
+                hasUpdate = superviseUpdated || otherUpdated || jyUpdated;
             }
-            insOrders.add(insPlyIncomeSource.getOrderNo());
-            BigDecimal taxRate = this.obtainTaxRate(insPlyIncomeSource.getOrderNo());
-            if (Objects.nonNull(batchModifyVo.getJqSuperviseCostsProportion()) && batchModifyVo.getJqSuperviseCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
-                // modify by lipf 2026年6月18日09:36:01 转换为百分比
-                BigDecimal jqSuperviseCostsProportion = BigDecimalUtil.divide(batchModifyVo.getJqSuperviseCostsProportion(), new BigDecimal(100)) ;
-                BigDecimal superviseReceivablePremium = BigDecimalUtil.divide(BigDecimalUtil.multiply(new BigDecimal(Objects.toString(insPlyIncomeSource.getJqPremium(),"0") ), jqSuperviseCostsProportion), taxRate) ;
-                BigDecimal jqReceivePremiun = BigDecimalUtil.add(superviseReceivablePremium, BigDecimalUtil.toZero(insPlyIncomeSource.getInsFeeOrders()  == null? null:  insPlyIncomeSource.getInsFeeOrders().getJqFollowPremium()));
-                baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
-                        .set(InsPlyIncome::getJqSuperviseCostsProportion, jqSuperviseCostsProportion)
-                        .set(InsPlyIncome::getJqSuperviseCostsPremiums, superviseReceivablePremium)
-                        .set(InsPlyIncome::getJqReceivablePremium,jqReceivePremiun)
-                        .in(InsPlyIncome::getId, batchModifyVo.getIncomeIds()));
-            }
-            if (Objects.nonNull(batchModifyVo.getSySuperviseCostsProportion()) && batchModifyVo.getSySuperviseCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
-                // modify by lipf 2026年6月18日09:36:01 转换为百分比
-                BigDecimal sySuperviseCostsProportion = BigDecimalUtil.divide(batchModifyVo.getSySuperviseCostsProportion(), new BigDecimal(100)) ;
-                BigDecimal sySuperviseReceivablePremium = BigDecimalUtil.divide(BigDecimalUtil.multiply(new BigDecimal(Objects.toString(insPlyIncomeSource.getSyPremium(),"0")), sySuperviseCostsProportion), taxRate) ;
-                BigDecimal syReceivePremiun = BigDecimalUtil.add(sySuperviseReceivablePremium, BigDecimalUtil.toZero(insPlyIncomeSource.getInsFeeOrders() != null? insPlyIncomeSource.getInsFeeOrders().getSyFollowPremium() : null));
-                baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
-                        .set(InsPlyIncome::getSySuperviseCostsProportion, sySuperviseCostsProportion)
-                        .set(InsPlyIncome::getSySuperviseCostsPremiums, sySuperviseReceivablePremium)
-                        .set(InsPlyIncome::getSyReceivablePremium,syReceivePremiun)
-                        .in(InsPlyIncome::getId, batchModifyVo.getIncomeIds()));
-            }
-            if (batchModifyVo.getSigningTime() != null){
-                baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
-                        .set(InsPlyIncome::getSigningTime, batchModifyVo.getSigningTime())
-                        .in(InsPlyIncome::getId, batchModifyVo.getIncomeIds()));
-
-            }
-            if(StrUtil.isNotEmpty(batchModifyVo.getContractUserName())){
-                baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
-                        .set(InsPlyIncome::getContactPerson, batchModifyVo.getContractUserName())
-                        .in(InsPlyIncome::getId, batchModifyVo.getIncomeIds()));
-
-            }
-            if(StrUtil.isNotEmpty(batchModifyVo.getContractPhone())){
-                baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
-                        .set(InsPlyIncome::getContactPersonPhone, batchModifyVo.getContractPhone())
-                        .in(InsPlyIncome::getId, batchModifyVo.getIncomeIds()));
-            }
-        }
-        batchModifyVo.setOrderNos(insOrders);
+
+            // 处理公共字段更新
+            if (batchModifyVo.getSigningTime() != null) {
+                updateIncome.setSigningTime(batchModifyVo.getSigningTime());
+                hasUpdate = true;
+            }
+            if (StrUtil.isNotEmpty(batchModifyVo.getContractUserName())) {
+                updateIncome.setContactPerson(batchModifyVo.getContractUserName());
+                hasUpdate = true;
+            }
+            if (StrUtil.isNotEmpty(batchModifyVo.getContractPhone())) {
+                updateIncome.setContactPersonPhone(batchModifyVo.getContractPhone());
+                hasUpdate = true;
+            }
+
+            if (hasUpdate) {
+                updateList.add(updateIncome);
+            }
+        }
+
+        // 批量更新
+        if (CollUtil.isNotEmpty(updateList)) {
+            this.updateBatchById(updateList);
+        }
+
+        // 更新关联订单
+        batchModifyVo.setOrderNos(orderNos);
         HttpResult<String> updateOrdersRes = insFeeOrdersClient.updateOrdersBatch(batchModifyVo);
         log.info("更新车险订单的结果:updateOrdersRes=[{}]", JSONUtil.toJsonStr(updateOrdersRes));
         return true;
     }
 
+    /**
+     * 处理手续费更新
+     */
+    private boolean handleSuperviseCosts(InsPlyIncome updateIncome, InsPlyIncome sourceIncome,
+                                         BatchModifyVo batchModifyVo, BigDecimal taxRate) {
+        boolean hasUpdate = false;
+
+        if (Objects.nonNull(batchModifyVo.getJqSuperviseCostsProportion()) &&
+                batchModifyVo.getJqSuperviseCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
+
+            BigDecimal proportion = batchModifyVo.getJqSuperviseCostsProportion().divide(new BigDecimal(100), 4, RoundingMode.HALF_UP);
+            BigDecimal premium = calculatePremium(sourceIncome.getJqPremium(), proportion, taxRate);
+            BigDecimal receivable = calculateReceivable(premium, sourceIncome.getInsFeeOrders(), "jqFollow");
+
+            updateIncome.setJqSuperviseCostsProportion(proportion.toString());
+            updateIncome.setJqSuperviseCostsPremiums(premium.toString());
+            updateIncome.setJqReceivablePremium(receivable.toString());
+            hasUpdate = true;
+        }
+
+        if (Objects.nonNull(batchModifyVo.getSySuperviseCostsProportion()) &&
+                batchModifyVo.getSySuperviseCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
+
+            BigDecimal proportion = batchModifyVo.getSySuperviseCostsProportion().divide(new BigDecimal(100), 4, RoundingMode.HALF_UP);
+            BigDecimal premium = calculatePremium(sourceIncome.getSyPremium(), proportion, taxRate);
+            BigDecimal receivable = calculateReceivable(premium, sourceIncome.getInsFeeOrders(), "syFollow");
+
+            updateIncome.setSySuperviseCostsProportion(proportion.toString());
+            updateIncome.setSySuperviseCostsPremiums(premium.toString());
+            updateIncome.setSyReceivablePremium(receivable.toString());
+            hasUpdate = true;
+        }
+
+        return hasUpdate;
+    }
+
+    /**
+     * 处理跟单费更新
+     */
+    private boolean handleOtherCosts(InsPlyIncome updateIncome, InsPlyIncome sourceIncome,
+                                     BatchModifyVo batchModifyVo, BigDecimal taxRate) {
+        boolean hasUpdate = false;
+
+        if (Objects.nonNull(batchModifyVo.getJqOtherCostsProportion()) &&
+                batchModifyVo.getJqOtherCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
+
+            BigDecimal proportion = batchModifyVo.getJqOtherCostsProportion().divide(new BigDecimal(100), 4, RoundingMode.HALF_UP);
+            BigDecimal premium = calculatePremium(sourceIncome.getJqPremium(), proportion, taxRate);
+            BigDecimal receivable = calculateReceivable(premium, sourceIncome.getInsFeeOrders(), "jqCommission");
+
+            updateIncome.setJqOtherCostsProportion(proportion.toString());
+            updateIncome.setJqOtherCostsPremiums(premium.toString());
+            updateIncome.setJqReceivablePremium(receivable.toString());
+            hasUpdate = true;
+        }
+
+        if (Objects.nonNull(batchModifyVo.getSyOtherCostsProportion()) &&
+                batchModifyVo.getSyOtherCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
+
+            BigDecimal proportion = batchModifyVo.getSyOtherCostsProportion().divide(new BigDecimal(100), 4, RoundingMode.HALF_UP);
+            BigDecimal premium = calculatePremium(sourceIncome.getSyPremium(), proportion, taxRate);
+            BigDecimal receivable = calculateReceivable(premium, sourceIncome.getInsFeeOrders(), "syCommission");
+
+            updateIncome.setSyOtherCostsProportion(proportion.toString());
+            updateIncome.setSyOtherCostsPremiums(premium.toString());
+            updateIncome.setSyReceivablePremium(receivable.toString());
+            hasUpdate = true;
+        }
+
+        return hasUpdate;
+    }
+
+    /**
+     * 处理驾意险费用更新
+     */
+    private boolean handleJyCosts(InsPlyIncome updateIncome, InsPlyIncome sourceIncome,
+                                  BatchModifyVo batchModifyVo, BigDecimal taxRate) {
+        boolean hasUpdate = false;
+
+        if (Objects.nonNull(batchModifyVo.getJySuperviseCostsProportion()) &&
+                batchModifyVo.getJySuperviseCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
+
+            BigDecimal proportion = batchModifyVo.getJySuperviseCostsProportion().divide(new BigDecimal(100));
+            BigDecimal premium = calculatePremium(sourceIncome.getJyPremium(), proportion, taxRate);
+            BigDecimal receivable = calculateReceivable(premium, sourceIncome.getInsFeeOrders(), "jyCommission");
+
+            updateIncome.setJySuperviseCostsProportion(proportion.toString());
+            updateIncome.setJySuperviseCostsPremiums(premium.toString());
+            updateIncome.setJyReceivablePremium(receivable.toString());
+            hasUpdate = true;
+        }
+
+        if (Objects.nonNull(batchModifyVo.getJyOtherCostsProportion()) &&
+                batchModifyVo.getJyOtherCostsProportion().compareTo(BigDecimal.ZERO) > 0) {
+
+            BigDecimal proportion = batchModifyVo.getJyOtherCostsProportion().divide(new BigDecimal(100));
+            BigDecimal premium = calculatePremium(sourceIncome.getJyPremium(), proportion, taxRate);
+            BigDecimal receivable = calculateReceivable(premium, sourceIncome.getInsFeeOrders(), "jyFollow");
+
+            updateIncome.setJyOtherCostsProportion(proportion.toString());
+            updateIncome.setJyOtherCostsPremiums(premium.toString());
+            updateIncome.setJyReceivablePremium(receivable.toString());
+            hasUpdate = true;
+        }
+
+        return hasUpdate;
+    }
+
+    /**
+     * 计算保费
+     */
+    private BigDecimal calculatePremium(String premiumStr, BigDecimal proportion, BigDecimal taxRate) {
+        BigDecimal premium = new BigDecimal(Objects.toString(premiumStr, "0"));
+        return premium.multiply(proportion).divide(taxRate, 2, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 计算应收金额
+     */
+    private BigDecimal calculateReceivable(BigDecimal premium, InsFeeOrders insFeeOrders, String type) {
+        BigDecimal followPremium = BigDecimal.ZERO;
+
+        if (insFeeOrders != null) {
+            switch (type) {
+                case "jqFollow":
+                    followPremium = BigDecimalUtil.toZero(insFeeOrders.getJqFollowPremium());
+                    break;
+                case "syFollow":
+                    followPremium = BigDecimalUtil.toZero(insFeeOrders.getSyFollowPremium());
+                    break;
+                case "jqCommission":
+                    followPremium = BigDecimalUtil.toZero(insFeeOrders.getJqCommissionPremium());
+                    break;
+                case "syCommission":
+                    followPremium = BigDecimalUtil.toZero(insFeeOrders.getSyCommissionPremium());
+                    break;
+                case "jyCommission":
+                    followPremium = BigDecimalUtil.toZero(insFeeOrders.getJyCommissionPremium());
+                    break;
+                case "jyFollow":
+                    followPremium = BigDecimalUtil.toZero(insFeeOrders.getJyFollowPremium());
+                    break;
+            }
+        }
+
+        return premium.add(followPremium);
+    }
+
     /**
      * 处理跟单费开票业务
      * 包含:创建发票主表记录、批量创建跟单订单明细、建立发票与明细的关联关系
@@ -2562,8 +2834,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         vo.setPartnerCompanyId(partnerCompanyId);
         vo.setReceivablePremium(receivable);
         vo.setInvoiced(invoiced);
-        // 未开票金额 = 应收保费 - 已开票金额
-        vo.setUninvoiced(receivable.subtract(invoiced));
+        vo.setUninvoiced(BigDecimal.ZERO);
 
         // --- 查询数据库获取对账信息 ---
         // 构造查询条件:年、月、合作方ID
@@ -2578,6 +2849,9 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             vo.setReconciliationAmount(dbOrder.getReconciliationAmount());
             vo.setFalselyIncreasedDifference(dbOrder.getFalselyIncreasedDifference());
             vo.setFalselyIncreasedReason(dbOrder.getFalselyIncreasedReason());
+            // 未开票金额 = 应收保费 - 已开票金额,这是原逻辑
+            // 现在按wwq的要求改成:未开票金额 = 对账金额 - 已开票金额
+            vo.setUninvoiced(dbOrder.getReconciliationAmount().subtract(invoiced));
         } else {
             // 数据库无记录,使用默认值或DTO里的值
             vo.setReconciliationAmount(null);
@@ -3312,8 +3586,6 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         Map<String, BigDecimal> sxfInvoicedAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
         calRes = baseMapper.queryInvoicedAmount(systemCode, List.of(2, 4), queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType());
         Map<String, BigDecimal> gdfInvoicedAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
-        calRes = baseMapper.queryInvoicedAmount(systemCode, List.of(4, 6), queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType());
-        Map<String, BigDecimal> ptInvoicedAmountMap =calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
 
         // 结算费用 
         List<CalRes> sxfList = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType(), CollUtil.newArrayList("1", "3"));
@@ -3329,13 +3601,14 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             companySuperviseSettlementReportDto.setSxfInvoicedAmount(Objects.toString(sxf,BigDecimal.ZERO+""));
             BigDecimal gdf = gdfInvoicedAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
             companySuperviseSettlementReportDto.setGdfInvoicedAmount(Objects.toString(gdf,BigDecimal.ZERO+""));
-            BigDecimal pt = ptInvoicedAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
-            companySuperviseSettlementReportDto.setPtInvoicedAmount(Objects.toString(pt,BigDecimal.ZERO+""));
+            // 平台就没有未结算的,只要结算就是已结算的
+            companySuperviseSettlementReportDto.setPtInvoicedAmount(companySuperviseSettlementReportDto.getTotalReceivable());
 
             CompanySuperviseSettlementReportDto dto;
             dto = companyMap.get(companyId);
             companySuperviseSettlementReportDto.setSxfUnInvoicedAmount(BigDecimalUtil.subtract(new BigDecimal(dto.getSuperviseFee()),sxf).toString());
             companySuperviseSettlementReportDto.setGdfUnInvoicedAmount(BigDecimalUtil.subtract(new BigDecimal(dto.getFollowFee()),gdf).toString());
+            companySuperviseSettlementReportDto.setPtUnInvoicedAmount(BigDecimal.ZERO.toString());
 
             BigDecimal sxfS = sxfSettledAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
             BigDecimal gdfS = gdfSettledAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
@@ -3563,6 +3836,18 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     action.setCompanyName(esmInsCompany.getNameSimple());
                 }
                 action.setCompanyALlName(allCompanyHierarchyPaths.get(action.getCompanyId()));
+                String invoiceIds = action.getInvoiceIds();
+                if(StrUtil.isNotEmpty(invoiceIds)){
+                    List<String> invoiceIdList = Arrays.asList(invoiceIds.split(","));
+                    log.info("invoiceIdList.size=[{}]", CollUtil.size(invoiceIdList));
+                    log.info("invoiceIdList=[{}]", JSONUtil.toJsonStr(invoiceIdList));
+                    BigDecimal amount = baseMapper.querySettledAmountByInvoiceIds(invoiceIdList);
+                    action.setSettledAmount(Objects.toString(amount,"0"));
+                    action.setUnSettledAmount(BigDecimalUtil.subtract(new BigDecimal(action.getTotalReceivable()),amount).toString());
+                }else{
+                    action.setSettledAmount("0");
+                    action.setUnSettledAmount(BigDecimalUtil.subtract(new BigDecimal(action.getTotalReceivable()),BigDecimal.ZERO).toString());
+                }
             }).toList();
             receiverSettlementReport.setRecords(records);
         }
@@ -3572,7 +3857,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     @Override
     public void exportReceiverSettlementReportExcel(Page page, SettlementReportQueryVo settlementReportQueryVo) {
         settlementReportQueryVo.setSystemCode(baseController.getSystemCode());
-        Page<ReceiverSettlementReportDto> receiverSettlementReport = baseMapper.getReceiverSettlementReport(page, settlementReportQueryVo);
+        // modify by lipf 2026年6月22日16:24:15 无法通过一个sql查询出所有要求的数据, 只能通过多个sql对数据进行聚合
+        Page<ReceiverSettlementReportDto> receiverSettlementReport = this.receiverSettlementReport(page, settlementReportQueryVo);
         List<ReceiverSettlementReportDto> receiverSettlementReportDtos = receiverSettlementReport.getRecords();
         EasyExcelUtils.exportForWeb(ServletUtils.getResponse(), ReceiverSettlementReportDto.class, receiverSettlementReportDtos, "对接人结算报表");
     }

+ 1 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserAccountServiceImpl.java

@@ -310,6 +310,7 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
             item.setCreateTime(auditing.getCreateTime());
             item.setStatus(auditing.getAuditingStatus().toString());
             item.setRemark("提现支出");
+            item.setRejectReason(auditing.getRejectReason());
             item.setBankName(auditing.getBankName());
             item.setUserName(userMap.getOrDefault(auditing.getUserId(), new SysUser()).getUsername());
             item.setBankCardNum(auditing.getBankCardNum());

+ 2 - 0
tenant/organization/src/main/resources/mapper/PtlAgreementCostMapper.xml

@@ -177,6 +177,8 @@
             <if test="productId != null">
                 AND c.product_id = #{productId}
             </if>
+            AND
+            NOW() BETWEEN c.effective_time AND c.failure_time
         </where>
     </select>
 

+ 44 - 4
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -1270,6 +1270,25 @@
         </where>
     </select>
 
+    <select id="getIncomeJqSumReceivable" resultType="java.util.Map">
+        SELECT
+        sum( jq_supervise_costs_premiums ) AS jqCommissionPremium,
+        sum( sy_supervise_costs_premiums ) AS syCommissionPremium,
+        sum( jy_supervise_costs_premiums ) AS jyCommissionPremium,
+        sum( jq_other_costs_premiums ) AS jqFollowPremium,
+        sum( sy_other_costs_premiums ) AS syFollowPremium,
+        sum( jy_other_costs_premiums ) AS jyFollowPremium
+        FROM
+        ins_ply_income
+        <where>
+            is_delete = 0
+            AND order_no IN
+            <foreach collection="orderNos" item="id" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </where>
+    </select>
+
     <select id="getInvoiceRecordList" resultType="com.jzg.commons.entity.finance.vo.InvoiceRecordResult">
         SELECT
         ipii.id,
@@ -1594,6 +1613,7 @@
         ORDER BY  eic.name
     </select>
 
+    <!-- invoice 表是income表  聚合得到的,因此,不能将income left jion invoide, 后对invoice的金额进行求和 2026年6月22日15:39:34  -->
     <select id="getReceiverSettlementReport" resultType="com.jzg.commons.entity.finance.dto.ReceiverSettlementReportDto">
         SELECT
         ipi.contact_person AS receiver,
@@ -1606,14 +1626,22 @@
         ) AS totalReceivable,
         --SUM(CASE WHEN ipii.`status` = 1 AND ipii.invoice_type in (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS settledSuperviseFee,
         -- SUM(CASE WHEN ipii.`status` = 1 AND ipii.invoice_type in (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS settledFollowFee,
-        SUM(CASE WHEN ipii.`status` = 1 AND ipii.invoice_type IN (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS settledAmount,
-        --SUM(CASE WHEN ipii.`status` = 0 AND ipii.invoice_type in (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS unSettledSuperviseFee
+        -- SUM(CASE WHEN ipii.`status` = 1 AND ipii.invoice_type IN (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS settledAmount,
+        -- SUM(CASE WHEN ipii.`status` = 0 AND ipii.invoice_type in (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS unSettledSuperviseFee
         -- ,SUM(CASE WHEN ipii.`status` = 0 AND ipii.invoice_type in (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS unSettledFollowFee,
-        SUM(CASE WHEN ipii.`status` = 0 AND ipii.invoice_type IN (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS unSettledAmount
+        -- SUM(CASE WHEN ipii.`status` = 0 AND ipii.invoice_type IN (5,6) THEN ipii.receivable_supervise_premium ELSE 0 END) AS unSettledAmount,
+        GROUP_CONCAT(distinct ipii.id) as invoice_ids
         FROM
         ins_ply_income ipi
         LEFT JOIN ins_ply_income_invoice_link ipil ON ipi.id = ipil.income_id AND ipil.is_delete = 0
-        LEFT JOIN ins_ply_income_invoice ipii ON ipil.invoice_id = ipii.id AND ipii.is_delete = 0
+        LEFT JOIN ins_ply_income_invoice ipii
+        ON ipil.invoice_id = ipii.id AND ipii.is_delete = 0
+        <if test="settlementReportQueryVo.invoiceTypes != null and settlementReportQueryVo.invoiceTypes.size() > 0" >
+            and ipii.invoice_type in
+            <foreach collection="settlementReportQueryVo.invoiceTypes" item="id" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </if>
         <where>
             ipi.is_delete = 0
             AND ipi.agreement_type = '1'
@@ -1781,5 +1809,17 @@
             </if>
         </where>
     </select>
+    <!-- 查询发票结算的金额 2026年6月22日15:48:33 lipf  -->
+    <select id="querySettledAmountByInvoiceIds" resultType="java.math.BigDecimal">
+        select sum(ipiis.actual_received_amount ) from ins_ply_income_invoice_settlement ipiis
+        <where>
+            <if test="invoiceIdList != null and invoiceIdList.size() > 0">
+                and ipiis.invoice_id in
+                <foreach collection="invoiceIdList" item="item" open="(" separator="," close=")">
+                    ${item}
+                </foreach>
+            </if>
+        </where>
+    </select>
 
 </mapper>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio