Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

wanghao 1 bulan lalu
induk
melakukan
4cdea33a89

+ 4 - 0
commons/src/main/java/com/jzg/commons/entity/finance/dto/InsPlyIncomeDto.java

@@ -316,6 +316,10 @@ public class InsPlyIncomeDto extends BaseModel {
     @Schema(description = "订单关联的发票信息")
     private String invoiceId;
 
+    @TableField(exist = false)
+    @Schema(description = "订单关联的发票信息")
+    private String invoiceIds;
+
     @TableField(exist = false)
     @Schema(description = "1-手续费, 2-跟单费, 3-驾意险手续费, 4-驾意险跟单费, 5-平台应收-车险, 6-平台应收-非车险")
     private String invoiceType;

+ 0 - 3
commons/src/main/java/com/jzg/commons/entity/orders/po/InsOrdersPolicy.java

@@ -4,9 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.jzg.commons.core.base.BaseModel;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import org.springframework.data.annotation.Id;
-
-import java.io.Serializable;
 
 @Data
 @Schema(description = "保险订单保单信息")

+ 209 - 207
commons/src/main/java/com/jzg/commons/entity/quote/vo/aggregated/QuoteEchoVo.java

@@ -51,71 +51,171 @@ public class QuoteEchoVo extends QuoteVo {
     private static final long serialVersionUID = 1928126868229420046L;
 
     /**
-     * OrderBase追加属性
+     * 订单数据库查询数据转 QuoteVo对象
+     * @param insOrdersVo
      */
-    @Data
-    private static class OrderBaseVo extends OrderBase{
-        @Serial
-        private static final long serialVersionUID = -9184896455541993138L;
+    public QuoteEchoVo(InsOrdersVo insOrdersVo){
+        if(Objects.isNull(this.getOrder())){
+            this.setOrder(new OrderBaseVo());
+        }
+        this.setOrdersNo(insOrdersVo.getId());
+        this.getOrder().setAgreementId(insOrdersVo.getInsOrders().getAgreementId());
+        this.getOrder().setAgreementName(insOrdersVo.getAgreementName());
+        this.getOrder().setAgreementOwnership(insOrdersVo.getAgreementOwnership());
+        this.getOrder().setAgreementType(insOrdersVo.getAgreementType());
+        this.getOrder().setOrdersNo(insOrdersVo.getId());
+        this.getOrder().setQuoteNo(insOrdersVo.getQuoteNo());
+        this.getOrder().setInsuranceCompanyCode(insOrdersVo.getCompanyId());
+        this.getOrder().setCompanyName(insOrdersVo.getCompanyName());
+        this.getOrder().setProductId(insOrdersVo.getProductId());
+        this.getOrder().setProductsName(insOrdersVo.getProductName());
+        this.getOrder().setOrderStatus(insOrdersVo.getInsOrders().getOrderStatus());
+        this.getOrder().setCreateBy(insOrdersVo.getCreateBy());
+        this.getOrder().setCreateTime(insOrdersVo.getCreateTime());
+        this.getOrder().setQuoteTime(insOrdersVo.getCreateTime());
+        this.getOrder().setSigningTime(insOrdersVo.getSigningTime());
+        this.getOrder().setPayTime(insOrdersVo.getPayTime());
+        this.getOrder().setOrderType(insOrdersVo.getOrderType());
+        this.getOrder().setEntryStatus(insOrdersVo.getEntryStatus());
+        this.getOrder().setDockingPerson (insOrdersVo.getDockingPerson());
+        this.getOrder().setDockingPersonPhone(insOrdersVo.getDockingPersonPhone());
+        if (Objects.nonNull(insOrdersVo.getSpecialInfoVo())) {
+            this.setCiSpecialInfoVo(insOrdersVo.getSpecialInfoVo().stream().filter(companyClauseVo -> companyClauseVo.getRiskCode().equals("0507")).collect(Collectors.toList()));
+            this.setBiSpecialInfoVo(insOrdersVo.getSpecialInfoVo().stream().filter(companyClauseVo -> companyClauseVo.getRiskCode().equals("0510")).collect(Collectors.toList()));
+        }
+        Salesman salesman = new Salesman();
+        if (!Objects.isNull(insOrdersVo.getSalesmanInfo())){
+            salesman.setName(insOrdersVo.getSalesmanInfo().getName());
+            salesman.setDeptName(insOrdersVo.getSalesmanInfo().getDeptName());
+            salesman.setTypeAttr(insOrdersVo.getSalesmanInfo().getTypeAttr());
+            salesman.setDeptId(insOrdersVo.getSalesmanInfo().getDeptId());
+            salesman.setMobile(insOrdersVo.getSalesmanInfo().getMobile());
+            salesman.setSystemCode(insOrdersVo.getSalesmanInfo().getSystemCode());
+            salesman.setSystemName(insOrdersVo.getSalesmanInfo().getSystemName());
+            salesman.setSystemShortName(insOrdersVo.getSalesmanInfo().getSystemShortName());
+            salesman.setRealQuoteUserManagerId(insOrdersVo.getSalesmanInfo().getRealQuoteUserManagerId());
+            salesman.setRealQuoteUserManagerUseName(insOrdersVo.getSalesmanInfo().getRealQuoteUserManagerUseName());
+        }
+        this.setSalesmanInfo(salesman);
+        this.setErrorMessage(insOrdersVo.getErrorMessage());
 
-        private Integer entryStatus;
+        //车辆信息处理
+        this.setCarInfoVo(insOrdersVo.getCarInfoVo());
+        if (Objects.nonNull(insOrdersVo.getCarInfoVo())) {
+            if (Objects.nonNull(insOrdersVo.getCarInfoVo().getRegisterDate()) && insOrdersVo.getCarInfoVo().getRegisterDate().contains(" ")) {
+                insOrdersVo.getCarInfoVo().setRegisterDate(insOrdersVo.getCarInfoVo().getRegisterDate().substring(0, insOrdersVo.getCarInfoVo().getRegisterDate().indexOf(" ")));
+            }
+            if (Objects.nonNull(insOrdersVo.getCarInfoVo().getIssueDate()) && insOrdersVo.getCarInfoVo().getIssueDate().contains(" ")) {
+                insOrdersVo.getCarInfoVo().setIssueDate(insOrdersVo.getCarInfoVo().getIssueDate().substring(0, insOrdersVo.getCarInfoVo().getIssueDate().indexOf(" ")));
+            }
+            if (Objects.nonNull(insOrdersVo.getCarInfoVo().getTransferDate()) && insOrdersVo.getCarInfoVo().getTransferDate().contains(" ")) {
+                insOrdersVo.getCarInfoVo().setTransferDate(insOrdersVo.getCarInfoVo().getTransferDate().substring(0, insOrdersVo.getCarInfoVo().getTransferDate().indexOf(" ")));
+            }
+        }
 
-        private String orderStatus;
-        private String companyName;
-        private String productsName;
+        // 批改信息处理
+        if(Objects.nonNull(insOrdersVo.getInsOrderAdjust())) {
+            InsOrderAdjustVo insOrderAdjustVo = new InsOrderAdjustVo();
+            BeanUtils.copyProperties(insOrdersVo.getInsOrderAdjust(), insOrderAdjustVo);
+            insOrderAdjustVo.setAdjustInfoList(insOrdersVo.getInsOrderAdjust().getAdjustInfoList());
+            this.insOrderAdjustVo = insOrderAdjustVo;
+        }
 
-        private String dockingPerson;
-        private String dockingPersonPhone;
+        //人员处理
+        this.setOwnersInfo(insOrdersVo.getOwnersInfo());
+        this.setPolicyHolderInfo(insOrdersVo.getPolicyHolderInfo());
+        this.setInsuredPersonInfo(insOrdersVo.getInsuredPersonInfo());
 
-        /**
-         * 方案ID
-         */
-        private String schemeId;
+        //险种处理
+        insOrdersVo.getInsOrdersRiskList().forEach(item->{
+            if(item.getRiskCode().equals(RiskCode.TRAFFIC.getCode())){
+                RiskInfoVo riskInfoVo = new RiskInfoVo();
+                riskInfoVo.setRiskCode(RiskCode.TRAFFIC.getCode());
+                // modify by lipf, 提高代码的健壮性 2026年6月2日18:57:09
+                riskInfoVo.setStartDate(item.getStartDate() != null ? item.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")): "");
+                riskInfoVo.setEndDate(item.getEndDate() != null ?  item.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+                riskInfoVo.setInstantFlag(item.getStartDate() != null && (item.getStartDate().getHour() != 0 || item.getStartDate().getMinute() != 0 || item.getStartDate().getSecond() != 0));
+                this.setCiRiskInfoVo(riskInfoVo);
+            }
+            if(item.getRiskCode().equals(RiskCode.BUSINESS.getCode())){
+                RiskInfoVo riskInfoVo = new RiskInfoVo();
+                riskInfoVo.setRiskCode(RiskCode.BUSINESS.getCode());
+                riskInfoVo.setStartDate(item.getStartDate() !=null ? item.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+                riskInfoVo.setEndDate(item.getEndDate() != null ? item.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+                riskInfoVo.setInstantFlag(item.getStartDate() != null && (item.getStartDate().getHour() != 0 || item.getStartDate().getMinute() != 0 || item.getStartDate().getSecond() != 0));
+                this.setBiRiskInfoVo(riskInfoVo);
+            }
+        });
+        // 添加交强险种信息
+        if(ProductsType.isContainDj(insOrdersVo.getProductId())){
+            KindInfoVo jqKindInfoVo = new KindInfoVo();
+            jqKindInfoVo.setKindCode("J1");
+            jqKindInfoVo.setKindName("机动车交通事故责任强制保险");
+            if(Objects.nonNull(insOrdersVo.getInsOrdersCosts().getJqPremium())) {
+                jqKindInfoVo.setPremium(insOrdersVo.getInsOrdersCosts().getJqPremium().toString());
+            }
+            jqKindInfoVo.setAmount("200000");
+            jqKindInfoVo.setServiceTimes("200000");
+            jqKindInfoVo.setUnitAmount("200000");
+            insOrdersVo.getKindInfoVo().add(0,jqKindInfoVo);
+        }
+        // 移除交强
+//        insOrdersVo.getKindInfoVo().removeIf(item -> "J1".equals(item.getKindCode()));
 
-        /**
-         * 协议id
-         */
-        private String agreementId;
-        private String agreementName;
-        private String agreementType;
+        this.setKindInfoVo(insOrdersVo.getKindInfoVo());
+        this.setAccidentalDrivings(insOrdersVo.getAccidentalDrivings());
+        this.setVehicleAndVesselTaxVo(insOrdersVo.getVehicleAndVesselTaxVo());
 
-        /**
-         * 协议归属
-         */
-        private String agreementOwnership;
+        //费用处理
+        this.costs = new OrdersCostsVo();
+        if(insOrdersVo.getInsOrdersCosts() != null){
+            this.costs.setCiPremium(insOrdersVo.getInsOrdersCosts().getJqPremium());
+            this.costs.setBiPremium(insOrdersVo.getInsOrdersCosts().getSyPremium());
+            this.costs.setNiPremium(insOrdersVo.getInsOrdersCosts().getJyPremium());
+            this.costs.setVvTax(insOrdersVo.getInsOrdersCosts().getTaxPremium());
+            this.costs.setSumPremium(insOrdersVo.getInsOrdersCosts().getSumPremium());
+            this.costs.setCiRatio(insOrdersVo.getInsOrdersCosts().getJqRatio());
+            this.costs.setBiRatio(insOrdersVo.getInsOrdersCosts().getSyRatio());
+            this.costs.setTotalAmount(insOrdersVo.getInsOrdersCosts().getTotalAmount());
+        }
 
-        private String createBy;
+        //保单号信息
+        this.policy = new OrdersPolicyVo();
+        if(insOrdersVo.getInsOrdersPolicy() != null){
+            this.policy.setCiApplyNumber(insOrdersVo.getInsOrdersPolicy().getJqApplyNo());
+            this.policy.setCiPolicyNumber(insOrdersVo.getInsOrdersPolicy().getJqPolicyNo());
+            this.policy.setBiApplyNumber(insOrdersVo.getInsOrdersPolicy().getSyApplyNo());
+            this.policy.setBiPolicyNumber(insOrdersVo.getInsOrdersPolicy().getSyPolicyNo());
+            this.policy.setNiApplyNumber(insOrdersVo.getInsOrdersPolicy().getJyApplyNo());
+            this.policy.setNiPolicyNumber(insOrdersVo.getInsOrdersPolicy().getJyPolicyNo());
+        }
+        if(insOrdersVo.getInsOrdersPdfUrl() != null){
+            this.policy.setCiPolicyUrl(insOrdersVo.getInsOrdersPdfUrl().getJqUrl());
+            this.policy.setBiPolicyUrl(insOrdersVo.getInsOrdersPdfUrl().getSyUrl());
+            this.policy.setNiPolicyUrl(insOrdersVo.getInsOrdersPdfUrl().getJyUrl());
+            this.policy.setCiPolicySignUrl(insOrdersVo.getInsOrdersPdfUrl().getJqSignUrl());
+        }
 
-        /**
-         * 这个方法不能删除, 在前端有用agreementName字段
-         */
-        public String getAgreementTypeName(){
-            if(StrUtil.isEmpty(this.agreementType)){
-                return StrUtil.EMPTY;
-            }
-            // 1、平台协议-平台结算 2、私有协议-自行结算 3、网销协议-自行结算
-            if("1".equals(this.agreementType)){
-                return "平台协议";
-            }else if("2".equals(this.agreementType)){
-                return "私有协议";
-            }else if("3".equals(this.agreementType)) {
-                return  "网销协议";
-            }else{
-                return this.agreementType;
-            }
+        //评分信息
+        this.scoreVo = new QuoteResultsVo.ScoreVo();
+//        this.scoreVo.setScore(insOrdersVo.getInsOrdersOtherInfo().getScore());
+//        this.scoreVo.setJqScore(insOrdersVo.getInsOrdersOtherInfo().getJqScore());
+//        this.scoreVo.setSyScore(insOrdersVo.getInsOrdersOtherInfo().getSyScore());
+//        this.scoreVo.setTpColorScore(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getTpColorScore()) ? null : insOrdersVo.getInsOrdersOtherInfo().getTpColorScore().toString());
+        this.scoreVo.setLossRation(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getLossRation()) ? null : insOrdersVo.getInsOrdersOtherInfo().getLossRation().toString());
+        this.scoreVo.setJqLossRation(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getJqLossRation()) ? null : insOrdersVo.getInsOrdersOtherInfo().getJqLossRation().toString());
+        this.scoreVo.setSyLossRation(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getSyLossRation()) ? null : insOrdersVo.getInsOrdersOtherInfo().getSyLossRation().toString());
+        this.scoreVo.setScoreJson(insOrdersVo.getInsOrdersOtherInfo().getScoreJson());
+
+        // 未匹配费用原因
+        if(Objects.nonNull(insOrdersVo.getInsOrdersOtherInfo())) {
+            this.setFeeNoDescription(insOrdersVo.getInsOrdersOtherInfo().getFeeNoDescription());
         }
 
-        /**
-         * 保司id
-         */
-        private String insuranceCompanyCode;
-        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-        private LocalDateTime createTime;
-        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-        private LocalDateTime quoteTime;
-        private String signingTime;
-        private String payTime;
-        private String orderType;
+        //驾意险存储
+        List<AccidentalDrivingVo> accidentalDrivings = insOrdersVo.getAccidentalDrivings();
+
+        this.setAccidentalDrivings(accidentalDrivings);
     }
 
     private OrderBaseVo order;
@@ -353,170 +453,72 @@ public class QuoteEchoVo extends QuoteVo {
     }
 
     /**
-     * 订单数据库查询数据转 QuoteVo对象
-     * @param insOrdersVo
+     * OrderBase追加属性
      */
-    public QuoteEchoVo(InsOrdersVo insOrdersVo){
-        if(Objects.isNull(this.getOrder())){
-            this.setOrder(new OrderBaseVo());
-        }
-        this.setOrdersNo(insOrdersVo.getId());
-        this.getOrder().setAgreementId(insOrdersVo.getInsOrders().getAgreementId());
-        this.getOrder().setAgreementName(insOrdersVo.getAgreementName());
-        this.getOrder().setAgreementOwnership(insOrdersVo.getAgreementOwnership());
-        this.getOrder().setAgreementType(insOrdersVo.getAgreementType());
-        this.getOrder().setOrdersNo(insOrdersVo.getId());
-        this.getOrder().setQuoteNo(insOrdersVo.getQuoteNo());
-        this.getOrder().setInsuranceCompanyCode(insOrdersVo.getCompanyId());
-        this.getOrder().setCompanyName(insOrdersVo.getCompanyName());
-        this.getOrder().setProductId(insOrdersVo.getProductId());
-        this.getOrder().setProductsName(insOrdersVo.getProductName());
-        this.getOrder().setOrderStatus(insOrdersVo.getInsOrders().getOrderStatus());
-        this.getOrder().setCreateBy(insOrdersVo.getCreateBy());
-        this.getOrder().setCreateTime(insOrdersVo.getCreateTime());
-        this.getOrder().setQuoteTime(insOrdersVo.getCreateTime());
-        this.getOrder().setSigningTime(insOrdersVo.getPayTime());
-        this.getOrder().setOrderType(insOrdersVo.getOrderType());
-        this.getOrder().setEntryStatus(insOrdersVo.getEntryStatus());
-        this.getOrder().setDockingPerson (insOrdersVo.getDockingPerson());
-        this.getOrder().setDockingPersonPhone(insOrdersVo.getDockingPersonPhone());
-        if (Objects.nonNull(insOrdersVo.getSpecialInfoVo())) {
-            this.setCiSpecialInfoVo(insOrdersVo.getSpecialInfoVo().stream().filter(companyClauseVo -> companyClauseVo.getRiskCode().equals("0507")).collect(Collectors.toList()));
-            this.setBiSpecialInfoVo(insOrdersVo.getSpecialInfoVo().stream().filter(companyClauseVo -> companyClauseVo.getRiskCode().equals("0510")).collect(Collectors.toList()));
-        }
-        Salesman salesman = new Salesman();
-        if (!Objects.isNull(insOrdersVo.getSalesmanInfo())){
-            salesman.setName(insOrdersVo.getSalesmanInfo().getName());
-            salesman.setDeptName(insOrdersVo.getSalesmanInfo().getDeptName());
-            salesman.setTypeAttr(insOrdersVo.getSalesmanInfo().getTypeAttr());
-            salesman.setDeptId(insOrdersVo.getSalesmanInfo().getDeptId());
-            salesman.setMobile(insOrdersVo.getSalesmanInfo().getMobile());
-            salesman.setSystemCode(insOrdersVo.getSalesmanInfo().getSystemCode());
-            salesman.setSystemName(insOrdersVo.getSalesmanInfo().getSystemName());
-            salesman.setSystemShortName(insOrdersVo.getSalesmanInfo().getSystemShortName());
-            salesman.setRealQuoteUserManagerId(insOrdersVo.getSalesmanInfo().getRealQuoteUserManagerId());
-            salesman.setRealQuoteUserManagerUseName(insOrdersVo.getSalesmanInfo().getRealQuoteUserManagerUseName());
-        }
-        this.setSalesmanInfo(salesman);
-        this.setErrorMessage(insOrdersVo.getErrorMessage());
-
-        //车辆信息处理
-        this.setCarInfoVo(insOrdersVo.getCarInfoVo());
-        if (Objects.nonNull(insOrdersVo.getCarInfoVo())) {
-            if (Objects.nonNull(insOrdersVo.getCarInfoVo().getRegisterDate()) && insOrdersVo.getCarInfoVo().getRegisterDate().contains(" ")) {
-                insOrdersVo.getCarInfoVo().setRegisterDate(insOrdersVo.getCarInfoVo().getRegisterDate().substring(0, insOrdersVo.getCarInfoVo().getRegisterDate().indexOf(" ")));
-            }
-            if (Objects.nonNull(insOrdersVo.getCarInfoVo().getIssueDate()) && insOrdersVo.getCarInfoVo().getIssueDate().contains(" ")) {
-                insOrdersVo.getCarInfoVo().setIssueDate(insOrdersVo.getCarInfoVo().getIssueDate().substring(0, insOrdersVo.getCarInfoVo().getIssueDate().indexOf(" ")));
-            }
-            if (Objects.nonNull(insOrdersVo.getCarInfoVo().getTransferDate()) && insOrdersVo.getCarInfoVo().getTransferDate().contains(" ")) {
-                insOrdersVo.getCarInfoVo().setTransferDate(insOrdersVo.getCarInfoVo().getTransferDate().substring(0, insOrdersVo.getCarInfoVo().getTransferDate().indexOf(" ")));
-            }
-        }
+    @Data
+    private static class OrderBaseVo extends OrderBase{
+        @Serial
+        private static final long serialVersionUID = -9184896455541993138L;
 
-        // 批改信息处理
-        if(Objects.nonNull(insOrdersVo.getInsOrderAdjust())) {
-            InsOrderAdjustVo insOrderAdjustVo = new InsOrderAdjustVo();
-            BeanUtils.copyProperties(insOrdersVo.getInsOrderAdjust(), insOrderAdjustVo);
-            insOrderAdjustVo.setAdjustInfoList(insOrdersVo.getInsOrderAdjust().getAdjustInfoList());
-            this.insOrderAdjustVo = insOrderAdjustVo;
-        }
+        private Integer entryStatus;
 
-        //人员处理
-        this.setOwnersInfo(insOrdersVo.getOwnersInfo());
-        this.setPolicyHolderInfo(insOrdersVo.getPolicyHolderInfo());
-        this.setInsuredPersonInfo(insOrdersVo.getInsuredPersonInfo());
+        private String orderStatus;
+        private String companyName;
+        private String productsName;
 
-        //险种处理
-        insOrdersVo.getInsOrdersRiskList().forEach(item->{
-            if(item.getRiskCode().equals(RiskCode.TRAFFIC.getCode())){
-                RiskInfoVo riskInfoVo = new RiskInfoVo();
-                riskInfoVo.setRiskCode(RiskCode.TRAFFIC.getCode());
-                // modify by lipf, 提高代码的健壮性 2026年6月2日18:57:09
-                riskInfoVo.setStartDate(item.getStartDate() != null ? item.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")): "");
-                riskInfoVo.setEndDate(item.getEndDate() != null ?  item.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
-                riskInfoVo.setInstantFlag(item.getStartDate() != null ? item.getStartDate().getHour() != 0 || item.getStartDate().getMinute() != 0 || item.getStartDate().getSecond() != 0: false);
-                this.setCiRiskInfoVo(riskInfoVo);
-            }
-            if(item.getRiskCode().equals(RiskCode.BUSINESS.getCode())){
-                RiskInfoVo riskInfoVo = new RiskInfoVo();
-                riskInfoVo.setRiskCode(RiskCode.BUSINESS.getCode());
-                riskInfoVo.setStartDate(item.getStartDate() !=null ? item.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
-                riskInfoVo.setEndDate(item.getEndDate() != null ? item.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
-                riskInfoVo.setInstantFlag(item.getStartDate() != null && (item.getStartDate().getHour() != 0 || item.getStartDate().getMinute() != 0 || item.getStartDate().getSecond() != 0));
-                this.setBiRiskInfoVo(riskInfoVo);
-            }
-        });
-        // 添加交强险种信息
-        if(ProductsType.isContainDj(insOrdersVo.getProductId())){
-            KindInfoVo jqKindInfoVo = new KindInfoVo();
-            jqKindInfoVo.setKindCode("J1");
-            jqKindInfoVo.setKindName("机动车交通事故责任强制保险");
-            if(Objects.nonNull(insOrdersVo.getInsOrdersCosts().getJqPremium())) {
-                jqKindInfoVo.setPremium(insOrdersVo.getInsOrdersCosts().getJqPremium().toString());
-            }
-            jqKindInfoVo.setAmount("200000");
-            jqKindInfoVo.setServiceTimes("200000");
-            jqKindInfoVo.setUnitAmount("200000");
-            insOrdersVo.getKindInfoVo().add(0,jqKindInfoVo);
-        }
-        // 移除交强
-//        insOrdersVo.getKindInfoVo().removeIf(item -> "J1".equals(item.getKindCode()));
+        private String dockingPerson;
+        private String dockingPersonPhone;
 
-        this.setKindInfoVo(insOrdersVo.getKindInfoVo());
-        this.setAccidentalDrivings(insOrdersVo.getAccidentalDrivings());
-        this.setVehicleAndVesselTaxVo(insOrdersVo.getVehicleAndVesselTaxVo());
+        /**
+         * 方案ID
+         */
+        private String schemeId;
 
-        //费用处理
-        this.costs = new OrdersCostsVo();
-        if(insOrdersVo.getInsOrdersCosts() != null){
-            this.costs.setCiPremium(insOrdersVo.getInsOrdersCosts().getJqPremium());
-            this.costs.setBiPremium(insOrdersVo.getInsOrdersCosts().getSyPremium());
-            this.costs.setNiPremium(insOrdersVo.getInsOrdersCosts().getJyPremium());
-            this.costs.setVvTax(insOrdersVo.getInsOrdersCosts().getTaxPremium());
-            this.costs.setSumPremium(insOrdersVo.getInsOrdersCosts().getSumPremium());
-            this.costs.setCiRatio(insOrdersVo.getInsOrdersCosts().getJqRatio());
-            this.costs.setBiRatio(insOrdersVo.getInsOrdersCosts().getSyRatio());
-            this.costs.setTotalAmount(insOrdersVo.getInsOrdersCosts().getTotalAmount());
-        }
+        /**
+         * 协议id
+         */
+        private String agreementId;
+        private String agreementName;
+        private String agreementType;
 
-        //保单号信息
-        this.policy = new OrdersPolicyVo();
-        if(insOrdersVo.getInsOrdersPolicy() != null){
-            this.policy.setCiApplyNumber(insOrdersVo.getInsOrdersPolicy().getJqApplyNo());
-            this.policy.setCiPolicyNumber(insOrdersVo.getInsOrdersPolicy().getJqPolicyNo());
-            this.policy.setBiApplyNumber(insOrdersVo.getInsOrdersPolicy().getSyApplyNo());
-            this.policy.setBiPolicyNumber(insOrdersVo.getInsOrdersPolicy().getSyPolicyNo());
-            this.policy.setNiApplyNumber(insOrdersVo.getInsOrdersPolicy().getJyApplyNo());
-            this.policy.setNiPolicyNumber(insOrdersVo.getInsOrdersPolicy().getJyPolicyNo());
-        }
-        if(insOrdersVo.getInsOrdersPdfUrl() != null){
-            this.policy.setCiPolicyUrl(insOrdersVo.getInsOrdersPdfUrl().getJqUrl());
-            this.policy.setBiPolicyUrl(insOrdersVo.getInsOrdersPdfUrl().getSyUrl());
-            this.policy.setNiPolicyUrl(insOrdersVo.getInsOrdersPdfUrl().getJyUrl());
-            this.policy.setCiPolicySignUrl(insOrdersVo.getInsOrdersPdfUrl().getJqSignUrl());
-        }
+        /**
+         * 协议归属
+         */
+        private String agreementOwnership;
 
-        //评分信息
-        this.scoreVo = new QuoteResultsVo.ScoreVo();
-//        this.scoreVo.setScore(insOrdersVo.getInsOrdersOtherInfo().getScore());
-//        this.scoreVo.setJqScore(insOrdersVo.getInsOrdersOtherInfo().getJqScore());
-//        this.scoreVo.setSyScore(insOrdersVo.getInsOrdersOtherInfo().getSyScore());
-//        this.scoreVo.setTpColorScore(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getTpColorScore()) ? null : insOrdersVo.getInsOrdersOtherInfo().getTpColorScore().toString());
-        this.scoreVo.setLossRation(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getLossRation()) ? null : insOrdersVo.getInsOrdersOtherInfo().getLossRation().toString());
-        this.scoreVo.setJqLossRation(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getJqLossRation()) ? null : insOrdersVo.getInsOrdersOtherInfo().getJqLossRation().toString());
-        this.scoreVo.setSyLossRation(Objects.isNull(insOrdersVo.getInsOrdersOtherInfo().getSyLossRation()) ? null : insOrdersVo.getInsOrdersOtherInfo().getSyLossRation().toString());
-        this.scoreVo.setScoreJson(insOrdersVo.getInsOrdersOtherInfo().getScoreJson());
+        private String createBy;
 
-        // 未匹配费用原因
-        if(Objects.nonNull(insOrdersVo.getInsOrdersOtherInfo())) {
-            this.setFeeNoDescription(insOrdersVo.getInsOrdersOtherInfo().getFeeNoDescription());
+        /**
+         * 这个方法不能删除, 在前端有用agreementName字段
+         */
+        public String getAgreementTypeName(){
+            if(StrUtil.isEmpty(this.agreementType)){
+                return StrUtil.EMPTY;
+            }
+            // 1、平台协议-平台结算 2、私有协议-自行结算 3、网销协议-自行结算
+            if("1".equals(this.agreementType)){
+                return "平台协议";
+            }else if("2".equals(this.agreementType)){
+                return "私有协议";
+            }else if("3".equals(this.agreementType)) {
+                return  "网销协议";
+            }else{
+                return this.agreementType;
+            }
         }
 
-        //驾意险存储
-        List<AccidentalDrivingVo> accidentalDrivings = insOrdersVo.getAccidentalDrivings();
-
-        this.setAccidentalDrivings(accidentalDrivings);
+        /**
+         * 保司id
+         */
+        private String insuranceCompanyCode;
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private LocalDateTime createTime;
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private LocalDateTime quoteTime;
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        private LocalDateTime signingTime;
+        private String payTime;
+        private String orderType;
     }
 
 

+ 4 - 0
commons/src/main/java/com/jzg/commons/entity/scheme/vo/SchemeRuleFilterVo.java

@@ -14,6 +14,10 @@ public class SchemeRuleFilterVo {
     @Schema(description = "产品id")
     private String productId;
 
+    // 获取方案需要添加保险公司id
+    @Schema(description = "保险公司")
+    private String companyId;
+
     @Valid
     @Schema(description =  "车辆信息")
     private CarInfoVo carInfo;

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

@@ -327,7 +327,7 @@ public class RuleAttrMappingVo {
         // 车牌地区
         ruleAttrMappingVoList.add(new RuleAttrMappingVo("LicenseArea", insOrdersCarInfo.getLicenseNo().substring(0, 1)));
         // 系数
-        ruleAttrMappingVoList.add(new RuleAttrMappingVo("CoefficientFactor", getCoefficient(insOrdersCarInfo, insOrdersCosts).toString()));
+        ruleAttrMappingVoList.add(new RuleAttrMappingVo("Coefficient", getCoefficient(insOrdersCarInfo, insOrdersCosts).toString()));
         // 商业是否有费用
         ruleAttrMappingVoList.add(new RuleAttrMappingVo("CiMessage", (insOrdersOther.getCiMessage() == null || "".equals(insOrdersOther.getCiMessage())) ? "0" : "1"));
 

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

@@ -408,6 +408,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
             insOrders.setOrderStatus(InsOrderStatusEnum.QUOTE_ING.getCode());
             insOrders.setEntryStatus(3);
             insOrders.setSystemCode(ordersAdd.getSystemCode());
+            insOrders.setPayTime(insOrders.getSigningTime());
             // 插入订单信息,如果插入失败,则返回错误信息
             int insertResult = insOrdersMapper.insert(insOrders);
             if (insertResult <= 0) {
@@ -503,7 +504,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
             ordersPolicy.setJyPolicyNo(ordersExternalPolicy.getNoPolicy());
             insOrdersPolicyService.updateByOrderNo(ordersPolicy);
 
-            insFeeAuditService.feeAuditAdd(insOrders, baseController.getSystemCode());
+
             // 发送订单状态变更消息
             this.orderStatusMessage(insOrders, insOrdersCarInfo, insOrdersCosts, baseController.getToken(), MessageCodeEnum.TEMPLATE_9);
             if (nullOrders) {
@@ -512,6 +513,10 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
                 insOrdersAdd.setInsOrders(orders);
                 saveOrders(insOrdersAdd);
             }
+            // modify by lipf , 2026年8月21日11:49:44 解决新车第一次报价的时候,费用审核有两条记录的bug
+            if (!nullOrders) {
+                insFeeAuditService.feeAuditAdd(insOrders, baseController.getSystemCode());
+            }
             // 返回成功信息,表示订单、车辆和用户信息保存成功
             return HttpResult.ok("保存成功");
 

+ 4 - 1
tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml

@@ -377,7 +377,10 @@
         from sys_upload_files
         <where>
             and is_delete = 0
-            and id in (${concatenated_string})
+            and id in
+            <foreach collection="concatenated_string.split(',')" item="item" open="(" separator="," close=")">
+                #{item}
+            </foreach>
         </where>
     </select>
 

+ 7 - 1
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerBrandNameQueryRequest.java

@@ -96,7 +96,13 @@ public class TaiPingCrawlerBrandNameQueryRequest {
             this.newCarFlag = false;
             this.licenseNo = carInfoVo.getLicenseNo();
         }
-        this.brandName = carInfoVo.getBrandName();
+        String brandName = carInfoVo.getBrandName();
+        if (brandName != null && brandName.contains("牌")) {
+            this.brandName = brandName.replaceAll("[\\u4e00-\\u9fa5]+牌", "").trim();
+        } else {
+            this.brandName = carInfoVo.getBrandName();
+        }
+//        this.brandName = carInfoVo.getBrandName();
         this.companyCode = parameters.getCompanyCode();
         this.frameNo = "";
         this.orderNo = orderNo;

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

@@ -106,9 +106,9 @@ public class SchemeController {
     }
 
     @Operation(summary = "获取方案结果")
-    @GetMapping("/getSchemeResult")
-    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);
+    @PostMapping("/getSchemeResult")
+    public HttpResult getSchemeResult(@RequestBody SchemeRuleFilterVo schemeRuleFilterVo){
+         SchemeResultVo schemeResultVo = ptlSchemeService.getSchemeResult(schemeRuleFilterVo);
         return HttpResult.ok(schemeResultVo);
     }
 

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

@@ -76,11 +76,10 @@ public interface PtlSchemeService extends IService<PtlScheme> {
 
     /**
      * 获取方案结果
-     * @param companyId
-     * @param productId
+     * @param schemeRuleFilterVo
      * @return
      */
-    public SchemeResultVo getSchemeResult(String companyId,String productId,String seatCount,String energyType,String vehicleType,String carnature);
+    public SchemeResultVo getSchemeResult(SchemeRuleFilterVo schemeRuleFilterVo);
 
     List<InsBusinessInsuranceVo> getBusinessInsuranceListByKindType(String kindCode);
 

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

@@ -739,7 +739,15 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
 
 
     @Override
-    public SchemeResultVo getSchemeResult(String companyId, String productId, String seatCount,String energyType,String vehicleType,String carnature) {
+    public SchemeResultVo getSchemeResult(SchemeRuleFilterVo schemeRuleFilterVo) {
+
+        String companyId = schemeRuleFilterVo.getCompanyId();
+        String productId = schemeRuleFilterVo.getProductId();
+        String seatCount = schemeRuleFilterVo.getCarInfo().getSeatCount();
+        String vehicleType = schemeRuleFilterVo.getCarInfo().getCarKindCode();
+        String energyType = schemeRuleFilterVo.getCarInfo().getEnergyTypeCode();
+        String carnature = schemeRuleFilterVo.getCarInfo().getCarNatureCode();
+
         log.info("根据保司Id和产品id查询协议信息。 companyId=[{}],productId=[{}]", companyId, productId);
         List<SchemeResultVo.SchemeVo> schemeInsuranceInfo = ptlSchemeMapper.getSchemeInsuranceInfo(companyId, productId);
         List<SchemeResultVo.SchemeVo> schemeDrivingInfo = ptlSchemeMapper.getSchemeDrivingInfo(companyId, productId);
@@ -776,6 +784,15 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
                         && scheme.getCarnature().contains(carnature))
                 .collect(Collectors.toList());
 
+        // 再次过滤方案  根据方案的规则条件
+        List<String> schemeIds = newSchemeList.stream().map(SchemeResultVo.SchemeVo::getId).collect(Collectors.toList());
+        List<PtlSchemeRulesAttrLink> ptlSchemeRulesAttrLinks = ptlSchemeRulesAttrLinkMapper.selectList(new LambdaQueryWrapper<PtlSchemeRulesAttrLink>().in(PtlSchemeRulesAttrLink::getSchemeId, schemeIds));
+        ValidateSchemeRuleVo validateSchemeRuleVo = new ValidateSchemeRuleVo();
+        validateSchemeRuleVo.builderQuoteVo(schemeRuleFilterVo, redissonClient);
+        validateSchemeRuleVo.setAttrLinks(ptlSchemeRulesAttrLinks);
+        HttpResult<List<String>> esmInsCompanyHttpResult = costsRuleClient.validateSchemeRule(validateSchemeRuleVo);
+        List<String> insSchemeIds = esmInsCompanyHttpResult.getData();
+        newSchemeList.removeIf(x -> !insSchemeIds.contains(x.getId()));
         schemeInsuranceInfo = newSchemeList;
 
         // 创建一个 Map,Key: info.id, Value: List<Driving>

+ 37 - 138
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -90,7 +90,6 @@ import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * @author tz
@@ -1145,93 +1144,6 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         return baseMapper.queryFollowIncome(incomeVo);
     }
 
-    /**
-     * 根据发票状态、开票时间、结算时间过滤收入数据
-     * 优化:嵌套anyMatch改为HashMapID映射匹配,O(n²) -> O(n)
-     */
-    private List<InsPlyIncomeDto>  filterIncomeByInvoiceAndSettleCondition(List<InsPlyIncomeDto> incomeList, SettlementReportQueryVo queryVo) {
-        log.info("对查询条件进行转义:queryVo=[{}]", JSONUtil.toJsonStr(queryVo));
-        String status = queryVo.getStatus();
-        String invoiceStartTime = queryVo.getInvoiceStartTime();
-        String invoiceEndTime = queryVo.getInvoiceEndTime();
-        String settleStartTime = queryVo.getSettlementStartTime();
-        String settleEndTime = queryVo.getSettlementEndTime();
-
-        // 无筛选条件,直接原数据返回
-        boolean noFilterCond = StrUtil.isBlank(status)
-                && (StrUtil.isBlank(invoiceStartTime) || StrUtil.isBlank(invoiceEndTime))
-                && (StrUtil.isBlank(settleStartTime) || StrUtil.isBlank(settleEndTime));
-        if (noFilterCond || CollUtil.isEmpty(incomeList)) {
-            return incomeList;
-        }
-
-        // 查询收入关联链路
-        List<String> incomeIds = incomeList.stream().map(InsPlyIncomeDto::getId).distinct().toList();
-        LambdaQueryWrapper<InsPlyIncomeInvoiceLink> linkWrapper = new LambdaQueryWrapper<>();
-        linkWrapper.in(InsPlyIncomeInvoiceLink::getIncomeId, incomeIds);
-        List<InsPlyIncomeInvoiceLink> linkList = insPlyIncomeInvoiceLinkMapper.selectList(linkWrapper);
-        if (CollUtil.isEmpty(linkList)) {
-            return new ArrayList<>(0);
-        }
-
-        // 链路ID映射
-        Map<String, InsPlyIncomeInvoiceLink> linkInvoiceIdMap = linkList.stream()
-                .collect(Collectors.toMap(InsPlyIncomeInvoiceLink::getInvoiceId, Function.identity(), (k1, k2) -> k1));
-        Set<String> linkInvoiceIds = linkInvoiceIdMap.keySet();
-
-        // 查询发票
-        LambdaQueryWrapper<InsPlyIncomeInvoice> invoiceWrapper = new LambdaQueryWrapper<>();
-        invoiceWrapper.in(InsPlyIncomeInvoice::getId, linkInvoiceIds);
-        if (StrUtil.isNotBlank(status)) {
-            invoiceWrapper.eq(InsPlyIncomeInvoice::getStatus, status);
-        }
-        boolean invoiceTimeCond = StrUtil.isNotBlank(invoiceStartTime) && StrUtil.isNotBlank(invoiceEndTime);
-        if (invoiceTimeCond) {
-            invoiceWrapper.between(InsPlyIncomeInvoice::getInvoiceTime, toStartDateTime(invoiceStartTime), toEndDateTime(invoiceEndTime));
-        }
-        invoiceWrapper.eq(InsPlyIncomeInvoice::getInvoiceType, queryVo.getInvoiceType());
-        List<InsPlyIncomeInvoice> invoiceList = insPlyIncomeInvoiceMapper.selectList(invoiceWrapper);
-        if ((StrUtil.isNotBlank(status) || invoiceTimeCond) && CollUtil.isEmpty(invoiceList)) {
-            return new ArrayList<>(0);
-        }
-
-        // 结算时间过滤
-        boolean settleTimeCond = StrUtil.isNotBlank(settleStartTime) && StrUtil.isNotBlank(settleEndTime);
-        if (settleTimeCond) {
-            Set<String> invoiceIdSet = invoiceList.stream().map(InsPlyIncomeInvoice::getId).collect(Collectors.toSet());
-            LambdaQueryWrapper<InsPlyIncomeInvoiceSettlement> settleWrapper = new LambdaQueryWrapper<>();
-            settleWrapper.in(InsPlyIncomeInvoiceSettlement::getInvoiceId, invoiceIdSet);
-            settleWrapper.between(InsPlyIncomeInvoiceSettlement::getCreateTime, toStartDateTime(settleStartTime), toEndDateTime(settleEndTime));
-            List<InsPlyIncomeInvoiceSettlement> settleList = insPlyIncomeInvoiceSettlementMapper.selectList(settleWrapper);
-            if (CollUtil.isEmpty(settleList)) {
-                return new ArrayList<>(0);
-            }
-            // 保留存在结算记录的发票
-            Set<String> validSettleInvoiceIds = settleList.stream()
-                    .map(InsPlyIncomeInvoiceSettlement::getInvoiceId)
-                    .collect(Collectors.toSet());
-            invoiceList = invoiceList.stream()
-                    .filter(invoice -> validSettleInvoiceIds.contains(invoice.getId()))
-                    .toList();
-        }
-
-        // 合法发票ID集合
-        Set<String> validInvoiceIds = invoiceList.stream()
-                .map(InsPlyIncomeInvoice::getId)
-                .collect(Collectors.toSet());
-        // 过滤合法链路
-        List<InsPlyIncomeInvoiceLink> validLinkList = linkList.stream()
-                .filter(link -> validInvoiceIds.contains(link.getInvoiceId()))
-                .toList();
-        Set<String> validIncomeIds = validLinkList.stream()
-                .map(InsPlyIncomeInvoiceLink::getIncomeId)
-                .collect(Collectors.toSet());
-
-        // 最终过滤收入数据
-        return incomeList.stream()
-                .filter(income -> validIncomeIds.contains(income.getId()))
-                .toList();
-    }
 
     /**
      * 将其他费用收入合并至结果集,不存在则新增VO
@@ -5485,8 +5397,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         // 用ins_ply_income的id关联查到ins_ply_income_invoice_link再关联到ins_ply_income_invoice_settlement,取出结算日期、结算人
         if (CollUtil.isNotEmpty(exportPlatFormReceivableVOS)) {
             //1.拿到所有incomeId集合
-            List<Long> incomeIdList = exportPlatFormReceivableVOS.stream()
-                    .map(item -> Long.valueOf(item.getId()))
+            List<String> incomeIdList = exportPlatFormReceivableVOS.stream()
+                    .map(ExportPlatFormReceivableVO::getId)
                     .collect(Collectors.toList());
 
             Map<String, InsPlyIncomeInvoiceSettlement> settlementMap = IncomeInvoiceLinkUtil.querySettlementByIncomeList(incomeIdList, insPlyIncomeInvoiceLinkMapper, insPlyIncomeInvoiceSettlementMapper);
@@ -5984,8 +5896,37 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 })
                 .toList();
         // 过滤数据
-        List<InsPlyIncomeDto> filterIncomeList = filterIncomeByInvoiceAndSettleCondition(dtoList, queryVo);
-        allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().filter(all -> filterIncomeList.stream().anyMatch(x -> x.getId().equals(all.getId()))).toList();
+        List<InsPlyIncomeDto> filterIncomeList = IncomeInvoiceLinkUtil.filterIncomeByInvoiceAndSettleCondition(
+                dtoList,
+                queryVo,
+                insPlyIncomeInvoiceLinkMapper,
+                insPlyIncomeInvoiceMapper,
+                insPlyIncomeInvoiceSettlementMapper
+        );
+        Map<String, List<String>> invoiceIdMap = IncomeInvoiceLinkUtil.queryIncomeToInvoiceIdMap(filterIncomeList.stream().map(InsPlyIncomeDto::getId).toList(), insPlyIncomeInvoiceLinkMapper);
+
+        // 给每个dto赋值逗号拼接的InvoiceIds
+        for (InsPlyIncomeDto incomeDto : filterIncomeList) {
+            String incomeId = incomeDto.getId();
+            List<String> invoiceIdList = invoiceIdMap.getOrDefault(incomeId, CollUtil.newArrayList());
+            if (CollUtil.isNotEmpty(invoiceIdList)) {
+                // 逗号拼接多个发票id
+                String invoiceIdsStr = String.join(",", invoiceIdList);
+                incomeDto.setInvoiceIds(invoiceIdsStr);
+            } else {
+                // 无关联发票,置空
+                incomeDto.setInvoiceIds(null);
+            }
+        }
+
+        // 根据结算状态过滤:0-已开票未结清 1-已结清 2-未开票
+        List<InsPlyIncomeDto> insPlyIncomeDtos = IncomeInvoiceLinkUtil.filterBySettlementStatus(filterIncomeList,
+                queryVo.getSettlementStatus(),
+                InsPlyIncomeDto::getInvoiceIds,
+                baseMapper);
+
+
+        allCompaniesIncomeDatas = allCompaniesIncomeDatas.stream().filter(all -> insPlyIncomeDtos.stream().anyMatch(x -> x.getId().equals(all.getId()))).toList();
 
         // 按公司ID分组聚合求和
         Map<String, List<CompanySuperviseSettlementReportDto>> groupByCompany = allCompaniesIncomeDatas.stream()
@@ -6482,31 +6423,10 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 }
             }
             // 根据结算状态过滤:0-已开票未结清 1-已结清 2-未开票
-            if(StrUtil.isNotEmpty(settlementReportQueryVo.getSettlementStatus())){
-                String settlementStatus = settlementReportQueryVo.getSettlementStatus();
-                if("2".equals(settlementStatus)){
-                    // 未开票:ins_ply_income_invoice没有数据
-                    records = records.stream().filter(action -> StrUtil.isEmpty(action.getInvoiceIds())).toList();
-                } else if("0".equals(settlementStatus)){
-                    // 已开票未结清:有发票数据,且存在status=0的发票
-                    records = records.stream().filter(action -> {
-                        if(StrUtil.isEmpty(action.getInvoiceIds())){
-                            return false;
-                        }
-                        List<String> invoiceIdList = Arrays.asList(action.getInvoiceIds().split(","));
-                        return baseMapper.countUnsettledInvoicesByInvoiceIds(invoiceIdList) > 0;
-                    }).toList();
-                } else if("1".equals(settlementStatus)){
-                    // 已结清:有发票数据,且所有发票status=1
-                    records = records.stream().filter(action -> {
-                        if(StrUtil.isEmpty(action.getInvoiceIds())){
-                            return false;
-                        }
-                        List<String> invoiceIdList = Arrays.asList(action.getInvoiceIds().split(","));
-                        return baseMapper.countUnsettledInvoicesByInvoiceIds(invoiceIdList) == 0;
-                    }).toList();
-                }
-            }
+            records = IncomeInvoiceLinkUtil.filterBySettlementStatus(records,
+                    settlementReportQueryVo.getSettlementStatus(),
+                    ReceiverSettlementReportDto::getInvoiceIds,
+                    baseMapper);
             receiverSettlementReport.setRecords(records);
         }
         return receiverSettlementReport;
@@ -6860,27 +6780,6 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         }
     }
 
-    /**
-     * yyyy-MM-dd 转当天起始 LocalDateTime
-     */
-    public static LocalDateTime toStartDateTime(String dateStr) {
-        if (StrUtil.isBlank(dateStr)){
-            return null;
-        }
-        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
-        return date.atStartOfDay();
-    }
-
-    /**
-     * yyyy-MM-dd 转当天结束 LocalDateTime
-     */
-    public static LocalDateTime toEndDateTime(String dateStr) {
-        if (StrUtil.isBlank(dateStr)){
-            return null;
-        }
-        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
-        return date.atTime(23, 59, 59, 999999999);
-    }
 
     // 递归获取所有子孙ID
     private List<String> getAllChildIdsOptimized(String parentId, Map<String, List<EsmInsCompany>> parentGroupMap) {

+ 236 - 16
tenant/organization/src/main/java/com/jzg/organization/utils/IncomeInvoiceLinkUtil.java

@@ -1,18 +1,25 @@
 package com.jzg.organization.utils;
 
 import cn.hutool.core.collection.CollUtil;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.*;
-import java.util.stream.Collectors;
-
 import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jzg.commons.entity.finance.dto.InsPlyIncomeDto;
+import com.jzg.commons.entity.finance.po.InsPlyIncomeInvoice;
 import com.jzg.commons.entity.finance.po.InsPlyIncomeInvoiceLink;
 import com.jzg.commons.entity.finance.po.InsPlyIncomeInvoiceSettlement;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jzg.commons.entity.finance.vo.SettlementReportQueryVo;
 import com.jzg.organization.mapper.InsPlyIncomeInvoiceLinkMapper;
+import com.jzg.organization.mapper.InsPlyIncomeInvoiceMapper;
 import com.jzg.organization.mapper.InsPlyIncomeInvoiceSettlementMapper;
+import com.jzg.organization.mapper.ReceivableMapper;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 public class IncomeInvoiceLinkUtil {
 
@@ -20,13 +27,13 @@ public class IncomeInvoiceLinkUtil {
     }
 
     /**
-     * 根据incomeId集合 查询应收开票结算
+     * 根据incomeId集合 查询应收开票结算的数据
      * @param incomeIdList 应收主表id集合
      * @param linkMapper link表mapper
      * @param settlementMapper settlement表mapper
      * @return key: invoiceId, value: settlement结算记录,旧值会被新值替换,按创建时间倒序
      */
-    public static Map<String, InsPlyIncomeInvoiceSettlement> querySettlementByIncomeList(List<Long> incomeIdList,
+    public static Map<String, InsPlyIncomeInvoiceSettlement> querySettlementByIncomeList(List<String> incomeIdList,
                                                                           InsPlyIncomeInvoiceLinkMapper linkMapper,
                                                                           InsPlyIncomeInvoiceSettlementMapper settlementMapper) {
         if (CollUtil.isEmpty(incomeIdList)) {
@@ -57,19 +64,44 @@ public class IncomeInvoiceLinkUtil {
                     .collect(Collectors.toMap(InsPlyIncomeInvoiceSettlement::getInvoiceId, s -> s, (exist, newVal) -> newVal));
         }
 
+        return settlementMap;
+    }
 
 
-        return settlementMap;
+    /**
+     * 根据应收id集合,获取 key:incomeId, value:对应多个invoiceId集合 的Map
+     * @param incomeIdList 应收主表id集合
+     * @param linkMapper link中间表mapper
+     * @return key:incomeId,value:该应收关联的发票id集合,无数据返回空Map,内部list不会为null
+     */
+    public static Map<String, List<String>> queryIncomeToInvoiceIdMap(List<String> incomeIdList,
+                                                                      InsPlyIncomeInvoiceLinkMapper linkMapper) {
+        if (CollUtil.isEmpty(incomeIdList)) {
+            return MapUtil.empty();
+        }
+        List<InsPlyIncomeInvoiceLink> invoiceLinkList = getInvoiceLinkList(incomeIdList, linkMapper);
+        if (CollUtil.isEmpty(invoiceLinkList)) {
+            return MapUtil.empty();
+        }
+
+        // 按incomeId分组,提取每个下的invoiceId,过滤null并去重
+        return invoiceLinkList.stream()
+                .collect(Collectors.groupingBy(
+                        InsPlyIncomeInvoiceLink::getIncomeId,
+                        Collectors.mapping(InsPlyIncomeInvoiceLink::getInvoiceId,
+                                Collectors.filtering(Objects::nonNull,
+                                        Collectors.toList()))
+                ));
     }
 
 
     /**
      * 根据incomeId获取invoiceLink的Map分组
-     * @param incomeIdList
-     * @param linkMapper
-     * @return
+     * @param incomeIdList incomeId的集合
+     * @param linkMapper ins_ply_income_invoice_link中间表的数据
+     * @return 按incomeId分组,一个income可能多条link
      */
-    public static Map<String, List<InsPlyIncomeInvoiceLink>> queryInvoiceLinkByIncomeId(List<Long> incomeIdList,
+    public static Map<String, List<InsPlyIncomeInvoiceLink>> queryInvoiceLinkByIncomeId(List<String> incomeIdList,
                                                                                    InsPlyIncomeInvoiceLinkMapper linkMapper) {
 
         List<InsPlyIncomeInvoiceLink> invoiceLinkList = getInvoiceLinkList(incomeIdList, linkMapper);
@@ -84,12 +116,200 @@ public class IncomeInvoiceLinkUtil {
     }
 
 
-    // 单纯获取InsPlyIncomeInvoiceLink的列表
-    public static List<InsPlyIncomeInvoiceLink> getInvoiceLinkList(List<Long> incomeIdList, InsPlyIncomeInvoiceLinkMapper linkMapper) {
+    /**
+     * 单纯获取InsPlyIncomeInvoiceLink的列表
+     */
+    public static List<InsPlyIncomeInvoiceLink> getInvoiceLinkList(List<String> incomeIdList, InsPlyIncomeInvoiceLinkMapper linkMapper) {
         // 1、查询link关联表
         LambdaQueryWrapper<InsPlyIncomeInvoiceLink> linkWrapper = new LambdaQueryWrapper<>();
         linkWrapper.in(InsPlyIncomeInvoiceLink::getIncomeId, incomeIdList);
         linkWrapper.eq(InsPlyIncomeInvoiceLink::getIsDelete, 0);
         return linkMapper.selectList(linkWrapper);
     }
+
+    /**
+     * 根据发票状态、开票时间、结算时间过滤收入数据
+     * 优化:嵌套anyMatch改为HashMapID映射匹配,O(n²) -> O(n)
+     *
+     * @param incomeList               待过滤收入dto列表
+     * @param queryVo                  查询条件
+     * @param incomeInvoiceLinkMapper  收入发票链路mapper
+     * @param incomeInvoiceMapper      发票mapper
+     * @param invoiceSettlementMapper  发票结算mapper
+     * @return 过滤之后收入数据
+     */
+    public static List<InsPlyIncomeDto> filterIncomeByInvoiceAndSettleCondition(
+            List<InsPlyIncomeDto> incomeList,
+            SettlementReportQueryVo queryVo,
+            InsPlyIncomeInvoiceLinkMapper incomeInvoiceLinkMapper,
+            InsPlyIncomeInvoiceMapper incomeInvoiceMapper,
+            InsPlyIncomeInvoiceSettlementMapper invoiceSettlementMapper
+    ) {
+
+        String status = queryVo.getStatus();
+        String invoiceStartTime = queryVo.getInvoiceStartTime();
+        String invoiceEndTime = queryVo.getInvoiceEndTime();
+        String settleStartTime = queryVo.getSettlementStartTime();
+        String settleEndTime = queryVo.getSettlementEndTime();
+
+        // 无筛选条件,直接原数据返回
+        boolean noFilterCond = StrUtil.isBlank(status)
+                && (StrUtil.isBlank(invoiceStartTime) || StrUtil.isBlank(invoiceEndTime))
+                && (StrUtil.isBlank(settleStartTime) || StrUtil.isBlank(settleEndTime));
+        if (noFilterCond || CollUtil.isEmpty(incomeList)) {
+            return incomeList;
+        }
+
+        // 查询收入关联链路
+        List<String> incomeIds = incomeList.stream()
+                .map(InsPlyIncomeDto::getId)
+                .distinct()
+                .toList();
+
+        LambdaQueryWrapper<InsPlyIncomeInvoiceLink> linkWrapper = new LambdaQueryWrapper<>();
+        linkWrapper.in(InsPlyIncomeInvoiceLink::getIncomeId, incomeIds);
+        List<InsPlyIncomeInvoiceLink> linkList = incomeInvoiceLinkMapper.selectList(linkWrapper);
+        if (CollUtil.isEmpty(linkList)) {
+            return new ArrayList<>(0);
+        }
+
+        // 链路ID映射
+        Map<String, InsPlyIncomeInvoiceLink> linkInvoiceIdMap = linkList.stream()
+                .collect(Collectors.toMap(InsPlyIncomeInvoiceLink::getInvoiceId,
+                        Function.identity(),
+                        (k1, k2) -> k1));
+        Set<String> linkInvoiceIds = linkInvoiceIdMap.keySet();
+
+        // 查询发票
+        LambdaQueryWrapper<InsPlyIncomeInvoice> invoiceWrapper = new LambdaQueryWrapper<>();
+        invoiceWrapper.in(InsPlyIncomeInvoice::getId, linkInvoiceIds);
+        if (StrUtil.isNotBlank(status)) {
+            invoiceWrapper.eq(InsPlyIncomeInvoice::getStatus, status);
+        }
+        boolean invoiceTimeCond = StrUtil.isNotBlank(invoiceStartTime) && StrUtil.isNotBlank(invoiceEndTime);
+        if (invoiceTimeCond) {
+            invoiceWrapper.between(InsPlyIncomeInvoice::getInvoiceTime,
+                    toStartDateTime(invoiceStartTime),
+                    toEndDateTime(invoiceEndTime));
+        }
+        invoiceWrapper.eq(InsPlyIncomeInvoice::getInvoiceType, queryVo.getInvoiceType());
+        List<InsPlyIncomeInvoice> invoiceList = incomeInvoiceMapper.selectList(invoiceWrapper);
+
+        if ((StrUtil.isNotBlank(status) || invoiceTimeCond) && CollUtil.isEmpty(invoiceList)) {
+            return new ArrayList<>(0);
+        }
+
+        // 结算时间过滤
+        boolean settleTimeCond = StrUtil.isNotBlank(settleStartTime) && StrUtil.isNotBlank(settleEndTime);
+        if (settleTimeCond) {
+            Set<String> invoiceIdSet = invoiceList.stream()
+                    .map(InsPlyIncomeInvoice::getId)
+                    .collect(Collectors.toSet());
+
+            LambdaQueryWrapper<InsPlyIncomeInvoiceSettlement> settleWrapper = new LambdaQueryWrapper<>();
+            settleWrapper.in(InsPlyIncomeInvoiceSettlement::getInvoiceId, invoiceIdSet);
+            settleWrapper.between(InsPlyIncomeInvoiceSettlement::getCreateTime,
+                    toStartDateTime(settleStartTime),
+                    toEndDateTime(settleEndTime));
+
+            List<InsPlyIncomeInvoiceSettlement> settleList = invoiceSettlementMapper.selectList(settleWrapper);
+            if (CollUtil.isEmpty(settleList)) {
+                return new ArrayList<>(0);
+            }
+            // 保留存在结算记录的发票
+            Set<String> validSettleInvoiceIds = settleList.stream()
+                    .map(InsPlyIncomeInvoiceSettlement::getInvoiceId)
+                    .collect(Collectors.toSet());
+
+            invoiceList = invoiceList.stream()
+                    .filter(invoice -> validSettleInvoiceIds.contains(invoice.getId()))
+                    .toList();
+        }
+
+        // 合法发票ID集合
+        Set<String> validInvoiceIds = invoiceList.stream()
+                .map(InsPlyIncomeInvoice::getId)
+                .collect(Collectors.toSet());
+
+        // 过滤合法链路
+        List<InsPlyIncomeInvoiceLink> validLinkList = linkList.stream()
+                .filter(link -> validInvoiceIds.contains(link.getInvoiceId()))
+                .toList();
+
+        Set<String> validIncomeIds = validLinkList.stream()
+                .map(InsPlyIncomeInvoiceLink::getIncomeId)
+                .collect(Collectors.toSet());
+
+        // 最终过滤收入数据
+        return incomeList.stream()
+                .filter(income -> validIncomeIds.contains(income.getId()))
+                .toList();
+    }
+
+
+    /**
+     * 结算状态内存过滤(无接口,函数式getter)
+     * 0-已开票未结清 1-已结清 2-未开票
+     *
+     * @param records           待过滤dto列表
+     * @param settlementStatus  结算状态:0/1/2
+     * @param getInvoiceIdFunc  获取invoiceIds的getter函数
+     * @param baseMapper        mapper,用于统计未结清发票数量
+     * @param <T>               任意类型
+     * @return 过滤后集合
+     */
+    public static <T> List<T> filterBySettlementStatus(
+            List<T> records,
+            String settlementStatus,
+            Function<T, String> getInvoiceIdFunc,
+            ReceivableMapper baseMapper
+    ) {
+        if (CollUtil.isEmpty(records) || StrUtil.isBlank(settlementStatus)) {
+            return records;
+        }
+        return records.stream().filter(action -> {
+            String invoiceIds = getInvoiceIdFunc.apply(action);
+            if ("2".equals(settlementStatus)) {
+                return StrUtil.isEmpty(invoiceIds);
+            } else if ("0".equals(settlementStatus)) {
+                if (StrUtil.isEmpty(invoiceIds)) {
+                    return false;
+                }
+                List<String> invoiceIdList = Arrays.asList(invoiceIds.split(","));
+                return baseMapper.countUnsettledInvoicesByInvoiceIds(invoiceIdList) > 0;
+            } else if ("1".equals(settlementStatus)) {
+                if (StrUtil.isEmpty(invoiceIds)) {
+                    return false;
+                }
+                List<String> invoiceIdList = Arrays.asList(invoiceIds.split(","));
+                return baseMapper.countUnsettledInvoicesByInvoiceIds(invoiceIdList) == 0;
+            }
+            return true;
+        }).toList();
+    }
+
+
+
+
+    /**
+     * yyyy-MM-dd 转当天起始 LocalDateTime
+     */
+    public static LocalDateTime toStartDateTime(String dateStr) {
+        if (StrUtil.isBlank(dateStr)){
+            return null;
+        }
+        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
+        return date.atStartOfDay();
+    }
+
+    /**
+     * yyyy-MM-dd 转当天结束 LocalDateTime
+     */
+    public static LocalDateTime toEndDateTime(String dateStr) {
+        if (StrUtil.isBlank(dateStr)){
+            return null;
+        }
+        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
+        return date.atTime(23, 59, 59, 999999999);
+    }
 }