浏览代码

Merge remote-tracking branch 'origin/master'

Qchen 2 月之前
父节点
当前提交
d1b923bbd3
共有 33 个文件被更改,包括 790 次插入 和 87 次删除
  1. 3 3
      commons/src/main/java/com/jzg/commons/config/OpenTelemetryConfig.java
  2. 7 0
      commons/src/main/java/com/jzg/commons/entity/dto/IncomeAndExpenseParam.java
  3. 46 0
      commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostBatchUpdateValidDateParam.java
  4. 36 0
      commons/src/main/java/com/jzg/commons/entity/dto/UpdateFeeRatioDTO.java
  5. 16 1
      commons/src/main/java/com/jzg/commons/entity/finance/dto/ReceiverSettlementReportDto.java
  6. 3 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/BatchModifyVo.java
  7. 5 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordQueryVo.java
  8. 3 0
      commons/src/main/java/com/jzg/commons/entity/po/InsFeeOrders.java
  9. 1 1
      commons/src/main/java/com/jzg/commons/entity/po/SysUserJzgInfo.java
  10. 6 0
      commons/src/main/java/com/jzg/commons/entity/quote/vo/aggregated/QuoteEchoVo.java
  11. 5 0
      commons/src/main/java/com/jzg/commons/entity/quote/vo/orders/InsOrdersVo.java
  12. 2 4
      commons/src/main/java/com/jzg/commons/entity/report/vo/FeeAuditSummaryParam.java
  13. 6 0
      commons/src/main/java/com/jzg/commons/entity/vo/InsFeeOrdersVo.java
  14. 10 0
      commons/src/main/java/com/jzg/commons/util/OrderComponts.java
  15. 2 5
      consoleStatistics/src/main/resources/mapper/ReportFeeAuditSummaryMapper.xml
  16. 2 2
      tenant/insurance/quotation-dajia/src/main/java/com/jzg/quotation/dajia/crawler/build/DaJiaCrawlerQuoteResultsVoBuild.java
  17. 85 8
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java
  18. 4 8
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLogAspect.java
  19. 17 6
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsOrdersController.java
  20. 23 5
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  21. 15 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsFeeOrdersService.java
  22. 154 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java
  23. 21 12
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  24. 4 1
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml
  25. 4 3
      tenant/organization/src/main/java/com/jzg/organization/aop/OrderOperationLogAspect.java
  26. 16 0
      tenant/organization/src/main/java/com/jzg/organization/controller/AgreementController.java
  27. 5 0
      tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementCostService.java
  28. 59 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java
  29. 35 2
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java
  30. 30 21
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  31. 2 1
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserAccountServiceImpl.java
  32. 9 3
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml
  33. 154 0
      修改出入口比例接口对接文档.md

+ 3 - 3
commons/src/main/java/com/jzg/commons/config/OpenTelemetryConfig.java

@@ -1,12 +1,12 @@
 package com.jzg.commons.config;
 
 import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
 import io.opentelemetry.sdk.OpenTelemetrySdk;
 import io.opentelemetry.sdk.resources.Resource;
 import io.opentelemetry.sdk.trace.SdkTracerProvider;
 import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
-import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
-import io.opentelemetry.api.common.Attributes;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -26,7 +26,7 @@ public class OpenTelemetryConfig {
 
         // Trace exporter
         OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter.builder()
-//                .setEndpoint("http://192.168.5.250:4317")
+//                .setEndpoint("http://192.168.1.250:4317")
                 .setEndpoint("http://172.24.144.227:4317")
                 .build();
 

+ 7 - 0
commons/src/main/java/com/jzg/commons/entity/dto/IncomeAndExpenseParam.java

@@ -31,4 +31,11 @@ public class IncomeAndExpenseParam {
     @Schema(description = "用户序号")
     private String userId;
 
+    public IncomeAndExpenseParam(String userId,String systemCode) {
+        this.systemCode = systemCode;
+        this.userId = userId;
+    }
+
+    public IncomeAndExpenseParam() {
+    }
 }

+ 46 - 0
commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostBatchUpdateValidDateParam.java

@@ -0,0 +1,46 @@
+package com.jzg.commons.entity.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 批量修改协议费用有效期参数
+ */
+@Data
+@Schema(description = "批量修改协议费用有效期参数")
+public class PtlAgreementCostBatchUpdateValidDateParam implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "协议费用ID列表(勾选的费用ID,优先级最高)")
+    private List<String> costIds;
+
+    @Schema(description = "协议ID(与报价类型组合筛选)")
+    private String ptlAgreementId;
+
+    @Schema(description = "承保规则ID(与协议ID、报价类型组合筛选)")
+    private String coverRuleId;
+
+    @Schema(description = "报价类型列表(如:0330=单交, 034001=单商, 034002=单三, 0330034002=交三, 0330034001=交商)")
+    private String costType;
+
+    @Schema(description = "生效时间(起)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "生效时间不能为空")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date effectiveTime;
+
+    @Schema(description = "失效时间(止)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "失效时间不能为空")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date failureTime;
+
+}

+ 36 - 0
commons/src/main/java/com/jzg/commons/entity/dto/UpdateFeeRatioDTO.java

@@ -0,0 +1,36 @@
+package com.jzg.commons.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author auto
+ * @date 2026/7/23
+ */
+@Data
+@Schema(description = "修改出入口比例DTO")
+public class UpdateFeeRatioDTO {
+
+    @Schema(description = "订单号", required = true)
+    private String orderNo;
+
+    @Schema(description = "交强险入口比例(0-100,服务端自动除以100)")
+    private BigDecimal jqInletRatio;
+
+    @Schema(description = "商业险入口比例(0-100,服务端自动除以100)")
+    private BigDecimal syInletRatio;
+
+    @Schema(description = "驾意险入口比例(0-100,服务端自动除以100)")
+    private BigDecimal jyInletRatio;
+
+    @Schema(description = "交强险出口比例(0-100,服务端自动除以100)")
+    private BigDecimal jqExportRatio;
+
+    @Schema(description = "商业险出口比例(0-100,服务端自动除以100)")
+    private BigDecimal syExportRatio;
+
+    @Schema(description = "驾意险出口比例(0-100,服务端自动除以100)")
+    private BigDecimal jyExportRatio;
+}

+ 16 - 1
commons/src/main/java/com/jzg/commons/entity/finance/dto/ReceiverSettlementReportDto.java

@@ -1,5 +1,6 @@
 package com.jzg.commons.entity.finance.dto;
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -14,48 +15,62 @@ import java.math.BigDecimal;
 @Data
 public class ReceiverSettlementReportDto {
     @Schema(description = "对接人")
+    @ExcelProperty("对接人")
     private String receiver;
 
     @Schema(description = "保险公司")
+    @ExcelProperty("保险公司")
     private String companyName;
 
     @Schema(description = "保险公司id")
+    @ExcelProperty("保险公司id")
     private String companyId;
 
     @Schema(description = "保险公司名称及父级的名称")
+    @ExcelProperty("保险公司名称及父级的名称")
     private String companyALlName;
 
     @Schema(description = "应收总计")
+    @ExcelProperty("应收总计")
     private String totalReceivable;
 
     @Schema(description = "应收手续费")
+    @ExcelProperty("应收手续费")
     private String superviseFee;
 
     @Schema(description = "应收跟单费")
+    @ExcelProperty("应收跟单费")
     private String followFee;
 
     @Schema(description = "已结算手续费")
+    @ExcelProperty("已结算手续费")
     private String settledSuperviseFee;
 
     @Schema(description = "已结算跟单费")
+    @ExcelProperty("已结算跟单费")
     private String settledFollowFee;
 
     @Schema(description = "已结算总计")
+    @ExcelProperty("已结算总计")
     private String settledAmount;
 
     @Schema(description = "未结算手续费")
+    @ExcelProperty("未结算手续费")
     private String unSettledSuperviseFee;
 
     @Schema(description = "未结算跟单费")
+    @ExcelProperty("未结算跟单费")
     private String unSettledFollowFee;
 
-
     @Schema(description = "未结算总计")
+    @ExcelProperty("未结算总计")
     private String unSettledAmount;
 
     @Schema(description = "已结算发票的发票号")
+    @ExcelProperty("已结算发票的发票号")
     private String invoiceIds;
 
     @Schema(description = "回款差额")
+    @ExcelProperty("回款差额")
     private BigDecimal totalPaymentDifference;
 }

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

@@ -51,6 +51,9 @@ public class BatchModifyVo {
     @Schema(description = "对接人姓名")
     private String contractUserName;
 
+    @Schema(description = "对接人手机号")
+    private String contractUserPhone;
+
     @Schema(description = "对接人手机号")
     private String contractPhone;
 

+ 5 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordQueryVo.java

@@ -26,6 +26,11 @@ public class InvoiceRecordQueryVo extends PageRequest {
      */
     private String invoiceType;
 
+    /**
+     * 开票号
+     */
+    private String invoiceNo;
+
     /**
      * 开票类型
      */

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

@@ -279,6 +279,9 @@ public class InsFeeOrders {
     @TableField(exist = false)
     private String licenseNo;
 
+    @Schema(description = "出入口比例是否已手动修改 0-未修改 1-已修改")
+    private Integer ratioModified;
+
     @Schema(description = "是否删除")
     @TableLogic
     private Integer isDelete;

+ 1 - 1
commons/src/main/java/com/jzg/commons/entity/po/SysUserJzgInfo.java

@@ -108,7 +108,7 @@ public class SysUserJzgInfo extends BaseModel implements Serializable {
     private String partnerLevel;
 
     @TableField(value = "type_attr")
-    @Schema(description = "用户类型:0个代,1渠道,2团队,3电销组")
+    @Schema(description = "用户类型:1.前线人员 2:后线人员 3:合伙人 4:工作室管理员 5:团队 6:个代 7:渠道 8 :电销")
     private String typeAttr;
 
     @TableField(value = "factor_verify")

+ 6 - 0
commons/src/main/java/com/jzg/commons/entity/quote/vo/aggregated/QuoteEchoVo.java

@@ -62,6 +62,10 @@ public class QuoteEchoVo extends QuoteVo {
         private String orderStatus;
         private String companyName;
         private String productsName;
+
+        private String dockingPerson;
+        private String dockingPersonPhone;
+
         /**
          * 协议id
          */
@@ -345,6 +349,8 @@ public class QuoteEchoVo extends QuoteVo {
         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()));

+ 5 - 0
commons/src/main/java/com/jzg/commons/entity/quote/vo/orders/InsOrdersVo.java

@@ -76,6 +76,11 @@ public class InsOrdersVo extends QuoteVo {
     @Schema(description = "订单类型")
     private String orderType;
 
+    @Schema(description = "对接人姓名")
+    private String dockingPerson;
+    @Schema(description = "对接人手机号")
+    private String dockingPersonPhone;
+
     @Schema(description = "录单时间")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime createTime;

+ 2 - 4
commons/src/main/java/com/jzg/commons/entity/report/vo/FeeAuditSummaryParam.java

@@ -7,6 +7,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 import java.time.LocalDate;
+import java.util.List;
 
 /**
  * 费用审核汇总统计请求参数
@@ -18,9 +19,6 @@ public class FeeAuditSummaryParam extends PageRequest {
 
     @Schema(description = "审核开始时间")
     @JsonFormat(pattern = "yyyy-MM-dd")
-    private LocalDate auditTimeStart;
+    private List<String> checkTime;
 
-    @Schema(description = "审核结束时间")
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    private LocalDate auditTimeEnd;
 }

+ 6 - 0
commons/src/main/java/com/jzg/commons/entity/vo/InsFeeOrdersVo.java

@@ -196,6 +196,9 @@ public class InsFeeOrdersVo {
     @Schema(description = "租户代码")
     private String systemCode;
 
+    @Schema(description = "出入口比例是否已手动修改 0-未修改 1-已修改")
+    private Integer ratioModified;
+
     /**
      * 出口费用是否需要扣减1%
      */
@@ -262,6 +265,9 @@ public class InsFeeOrdersVo {
         this.totalExportPremium = BigDecimalUtil.add(BigDecimalUtil.add(insFeeOrders.getJqExportPremium(),insFeeOrders.getSyExportPremium()),insFeeOrders.getJyExportPremium());
         //出口留点总费用
         this.totalExportKeepPointPremium = BigDecimalUtil.add(BigDecimalUtil.add(insFeeOrders.getJqExportKeepPointPremium(),insFeeOrders.getSyExportKeepPointPremium()),insFeeOrders.getJyExportKeepPointPremium());
+
+        //比例是否已修改标识
+        this.ratioModified = insFeeOrders.getRatioModified() != null ? insFeeOrders.getRatioModified() : 0;
     }
 
     public String convert2Str(BigDecimal num){

+ 10 - 0
commons/src/main/java/com/jzg/commons/util/OrderComponts.java

@@ -45,6 +45,16 @@ public class OrderComponts {
         nameMap.put("insFeeOrders.totalReceivablePremium","总应收费用");
         nameMap.put("insFeeOrders.totalPayablePremium","总应付费用");
         nameMap.put("insFeeOrders.totalExportPremium","总出口费用");
+
+        nameMap.put("costRatio.jqCommissionRatio","交强险手续费比例");
+        nameMap.put("costRatio.syCommissionRatio","商业险手续费比例");
+        nameMap.put("costRatio.jyCommissionRatio","驾意险手续费比例");
+        nameMap.put("insFeeOrders.jqCommissionPremium","交强险手续费费用");
+        nameMap.put("insFeeOrders.syCommissionPremium","商业险手续费费用");
+        nameMap.put("insFeeOrders.jyCommissionPremium","驾意险手续费费用");
+        nameMap.put("insFeeOrders.signTime","签单时间");
+        nameMap.put("order.dockingPerson","对接人姓名");
+        nameMap.put("order.dockingPersonPhone","对接人手机号");
         return nameMap;
     }
 

+ 2 - 5
consoleStatistics/src/main/resources/mapper/ReportFeeAuditSummaryMapper.xml

@@ -21,11 +21,8 @@
         LEFT JOIN ins_orders io ON ifa.order_no = io.id AND io.is_delete = 0
         <where>
             ifa.is_delete = 0
-            <if test="param.auditTimeStart != null">
-                AND (ifa.audit_time &gt;= #{param.auditTimeStart} OR ifa.audit_time IS NULL)
-            </if>
-            <if test="param.auditTimeEnd != null">
-                AND (ifa.audit_time &lt;= #{param.auditTimeEnd} OR ifa.audit_time IS NULL)
+            <if test="param.checkTime != null and  param.checkTime.size() > 0">
+                AND (ifa.audit_time BETWEEN #{param.checkTime[0]} AND #{param.checkTime[1]}} OR ifa.audit_time IS NULL)
             </if>
         </where>
         GROUP BY io.company_id, io.company_name

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

@@ -214,8 +214,8 @@ public final class DaJiaCrawlerQuoteResultsVoBuild {
             BusinessInsuranceDTO.CoefficientInfoDTO coefficientInfo1 = businessInsurance.getCoefficientInfo();
             scoreArray.add(new JSONObject()
                     .fluentPut("scoreName","商业险建议折扣")
-                    .fluentPut("scoreKey","entireDiscount")
-                    .fluentPut("score",coefficientInfo1.getEntireDiscount()));
+                    .fluentPut("scoreKey","pricingAdjustValue")
+                    .fluentPut("score",coefficientInfo1.getPricingAdjustValue()));
             scoreArray.add(new JSONObject()
                     .fluentPut("scoreName","商业险手续费")
                     .fluentPut("scoreKey","handFeeBi")

+ 85 - 8
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java

@@ -274,9 +274,18 @@ public class FactorMatch {
 
 
     private static boolean checkBoxEqual(PtlAgreementCostRule ptlAgreementCostRule, String value) {
+        if (ptlAgreementCostRule.getMin() == null || value == null) {
+            return false;
+        }
         String[] split = ptlAgreementCostRule.getMin().split(",");
         for (String sp : split) {
-            if (sp.equals(value)) {
+            if (sp.trim().equals(value.trim())) {
+                return true;
+            }
+            // 顺带支持是/否归一化
+            String n1 = normalizeYesNo(sp.trim());
+            String n2 = normalizeYesNo(value.trim());
+            if (!n1.equals(sp.trim()) && !n2.equals(value.trim()) && n1.equals(n2)) {
                 return true;
             }
         }
@@ -347,8 +356,21 @@ public class FactorMatch {
     }
 
     private static boolean selectEqual(PtlAgreementCostRule ptlAgreementCostRule, String value) {
-        if (ptlAgreementCostRule.getMin() != null && ptlAgreementCostRule.getMin().contains(value)) {
-            return true;
+        if (ptlAgreementCostRule.getMin() == null || value == null) {
+            return false;
+        }
+        // 修复:select 支持多选逗号分隔,所以正确做法是 split 后逐个 equals
+        String[] options = ptlAgreementCostRule.getMin().split(",");
+        for (String opt : options) {
+            if (opt.trim().equals(value.trim())) {
+                return true;
+            }
+            // 顺带支持是/否归一化
+            String n1 = normalizeYesNo(opt.trim());
+            String n2 = normalizeYesNo(value.trim());
+            if (!n1.equals(opt.trim()) && !n2.equals(value.trim()) && n1.equals(n2)) {
+                return true;
+            }
         }
         return false;
     }
@@ -358,15 +380,70 @@ public class FactorMatch {
         if ("NewEnergy".equals(ptlAgreementCostRule.getAttrCode())) {
             // 是否是新能源车
             boolean newEnergy = EnergyTypeCode.isNewEnergy(value);
-            if (newEnergy && ptlAgreementCostRule.getMin().equals("1")) {
+            if (newEnergy && "1".equals(normalizeYesNo(ptlAgreementCostRule.getMin()))) {
                 return true;
-            } else if (!newEnergy && ptlAgreementCostRule.getMin().equals("0")) {
+            } else if (!newEnergy && "0".equals(normalizeYesNo(ptlAgreementCostRule.getMin()))) {
                 return true;
             }
-        } else if (ptlAgreementCostRule.getMin().contains(value)) {
-            return true;
+            return false;
         }
-        return false;
+
+        // ========== 修复:归一化 是/否 类的 value ==========
+        String ruleValue = (ptlAgreementCostRule.getMin() != null) ? ptlAgreementCostRule.getMin() : ptlAgreementCostRule.getMax();
+        String normalizedRule = normalizeYesNo(ruleValue);
+        String normalizedValue = normalizeYesNo(value);
+
+        String operator = ptlAgreementCostRule.getOperator();
+        if (operator == null) operator = "1"; // 默认 等于
+
+        switch (operator) {
+            case "1": // 等于(默认)
+                // 修复1:先归一化后比较(解决 N/0、Y/1 不一致的问题)
+                if (normalizedRule != null && normalizedValue != null
+                        && !normalizedRule.equals(ruleValue) && !normalizedValue.equals(value)) {
+                    // 两个都经过归一化翻译了,直接比归一化后的值
+                    return normalizedRule.equals(normalizedValue);
+                }
+                // 修复2:用 equals 代替 contains(避免 "10".contains("0") 的误判)
+                return (ruleValue != null && ruleValue.equals(value))
+                        || (normalizedRule != null && normalizedRule.equals(normalizedValue));
+
+            case "2": // 不等于
+                if (normalizedRule != null && normalizedValue != null
+                        && !normalizedRule.equals(ruleValue) && !normalizedValue.equals(value)) {
+                    return !normalizedRule.equals(normalizedValue);
+                }
+                return ruleValue == null || !ruleValue.equals(value);
+
+            case "3": case "4": case "5": // 其他运算符(radio 一般用不上,兜底)
+                return inputNumberEqual(ptlAgreementCostRule, value);
+
+            default:
+                return (ruleValue != null && ruleValue.equals(value));
+        }
+    }
+
+    /**
+     * 归一化"是/否"类的值,把各种表达方式统一成 1/0
+     * 是: "1", "Y", "y", "是", "true", "TRUE", "True" -> "1"
+     * 否: "0", "N", "n", "否", "false", "FALSE", "False" -> "0"
+     * 其他值原样返回
+     */
+    private static String normalizeYesNo(String value) {
+        if (value == null) return null;
+        String v = value.trim();
+        if (v.isEmpty()) return v;
+        // 是否的"是"
+        if ("1".equals(v) || "Y".equalsIgnoreCase(v) || "true".equalsIgnoreCase(v)
+                || "是".equals(v) || "T".equalsIgnoreCase(v) || "YES".equalsIgnoreCase(v)) {
+            return "1";
+        }
+        // 是否的"否"
+        if ("0".equals(v) || "N".equalsIgnoreCase(v) || "false".equalsIgnoreCase(v)
+                || "否".equals(v) || "F".equalsIgnoreCase(v) || "NO".equalsIgnoreCase(v)) {
+            return "0";
+        }
+        return v;
     }
 
     public static boolean dateTimeEqual(PtlAgreementCostRule ptlAgreementCostRule, String value){

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

@@ -1,6 +1,7 @@
 package com.jzg.quotation.summary.aop;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.json.JSONConfig;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson2.JSON;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
@@ -83,6 +84,8 @@ public class OrderOperationLogAspect {
         }
         ExpressionParser parser = new SpelExpressionParser();
         Object result = null;
+        // 创建 JSONConfig 并设置日期格式, 会把LocalDate 和LocalDateTime 都转换为 包含时分秒的格式(后续有了更好的办法再优化)
+        JSONConfig jsonConfig = JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss");
         switch (log.optType().getCode()){
             // 创建订单
             case 0:
@@ -169,16 +172,9 @@ public class OrderOperationLogAspect {
                 QuoteEchoVo detailVoOld = insFeeAuditService.auditInfo(vo.getOrderNo());
                 result = joinPoint.proceed();
                 QuoteEchoVo detailVoNew = insFeeAuditService.auditInfo(vo.getOrderNo());
-                Map<String, List<String>> diffMap = JsonDiffUtil.compareJson(JSONUtil.toJsonStr(detailVoOld), JSONUtil.toJsonStr(detailVoNew), new HashSet<>());
+                Map<String, List<String>> diffMap = JsonDiffUtil.compareJson(JSONUtil.toJsonStr(detailVoOld,jsonConfig), JSONUtil.toJsonStr(detailVoNew,jsonConfig), new HashSet<>());
                 this.saveCostInfo(result,log, vo,diffMap);
                 break;
-            // 批量修改比例
-            case 16:
-                logger.info("批量修改比例.log.orderSpEl()=[{}]",log.orderSpEl());
-                BatchModifyVo batchModifyVo = parser.parseExpression(log.orderSpEl()).getValue(context, BatchModifyVo.class);
-                result = joinPoint.proceed();
-                this.batchModify(result,log, batchModifyVo);
-                break;
             // 设为疑问订单
             case 17:
                 logger.info("设置为疑问订单.log.orderSpEl()=[{}]",log.orderSpEl());

+ 17 - 6
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsOrdersController.java

@@ -11,6 +11,7 @@ import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.dto.InsOrdersParam;
 import com.jzg.commons.entity.dto.InsOrdersParamVO;
+import com.jzg.commons.entity.dto.UpdateFeeRatioDTO;
 import com.jzg.commons.entity.finance.vo.BatchModifyVo;
 import com.jzg.commons.entity.orders.po.InsOrders;
 import com.jzg.commons.entity.orders.po.InsOrdersCarInfo;
@@ -20,11 +21,7 @@ import com.jzg.commons.entity.po.InsFeeOrders;
 import com.jzg.commons.entity.quote.vo.KindInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteEchoVo;
-import com.jzg.commons.entity.quote.vo.orders.InsFeeCalculateRequest;
-import com.jzg.commons.entity.quote.vo.orders.InsFeeCalculateResponse;
-import com.jzg.commons.entity.quote.vo.orders.InsOrdersAdd;
-import com.jzg.commons.entity.quote.vo.orders.InsOrdersEnd;
-import com.jzg.commons.entity.quote.vo.orders.InsOrdersVo;
+import com.jzg.commons.entity.quote.vo.orders.*;
 import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
 import com.jzg.commons.request.RequestSingleParam;
 import com.jzg.quotation.summary.mapper.InsOrdersMapper;
@@ -46,7 +43,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.List;
+import java.util.Objects;
 
 @RestController
 @RequestMapping("/supplementOrder")
@@ -227,6 +225,19 @@ public class InsOrdersController extends BaseController {
         return insFeeOrdersService.calcCosts(ptlAgreementCostRatioVo);
     }
 
+    /**
+     * 修改出入口比例(交强/商业/驾意的入口和出口比例)
+     */
+    @Operation(summary = "修改出入口比例")
+    @PostMapping("/updateFeeRatio")
+    public HttpResult<InsFeeOrders> updateFeeRatio(@RequestBody UpdateFeeRatioDTO dto) {
+        log.info("修改出入口比例。dto=[{}]", JSONUtil.toJsonStr(dto));
+        InsFeeOrders result = insFeeOrdersService.updateFeeRatio(
+                dto.getOrderNo(), dto.getJqInletRatio(), dto.getSyInletRatio(), dto.getJyInletRatio(),
+                dto.getJqExportRatio(), dto.getSyExportRatio(), dto.getJyExportRatio());
+        return HttpResult.ok(result);
+    }
+
     @GetMapping("/changePerson")
     @Operation(summary = "更改对接人")
     public HttpResult changePerson(String orderNo,String name,String phone){

+ 23 - 5
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java

@@ -10,7 +10,6 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
@@ -39,7 +38,10 @@ import com.jzg.commons.entity.quote.vo.underwriting.SpecialAppointmentsVo;
 import com.jzg.commons.entity.rights.dto.InsOrderRightsDto;
 import com.jzg.commons.entity.rights.dto.InsOrderRightsInfoDto;
 import com.jzg.commons.entity.rights.dto.InsOrderRightsPackageDto;
-import com.jzg.commons.entity.vo.*;
+import com.jzg.commons.entity.vo.CompanyClauseVo;
+import com.jzg.commons.entity.vo.InsCompanyClauseVo;
+import com.jzg.commons.entity.vo.LotteryCountVO;
+import com.jzg.commons.entity.vo.UnifiedUserClientVO;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.exception.TokenExpireException;
 import com.jzg.commons.util.AssertionUtils;
@@ -52,8 +54,8 @@ import com.jzg.quotation.commons.service.QuotationCrawlerBaseService;
 import com.jzg.quotation.commons.utils.SnowFlakeUtil;
 import com.jzg.quotation.guoren.crawler.service.GuoRenCrawlerRequest;
 import com.jzg.quotation.summary.aop.AuditVerification;
-import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
 import com.jzg.quotation.summary.aop.QuoteVerification;
+import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
 import com.jzg.quotation.summary.async.AsyncGetPayLink;
 import com.jzg.quotation.summary.classifier.QuoteInfoParameterFilling;
 import com.jzg.quotation.summary.client.LocalLivingClient;
@@ -82,7 +84,6 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
-import javax.annotation.Resource;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -216,7 +217,7 @@ public class UnifyOrderManager {
     @Operation(summary = "获取报价号")
     @GetMapping("/getQuoteNo")
     public HttpResult getQuoteNo(@Schema(description = "车牌号") String licenseNo, @Schema(description = "车架号") String vinNo, @Schema(description = "发动机号") String engineNo) {
-        String quoteNo = String.valueOf(SnowFlakeUtil.getSnowFlakeId());
+        String quoteNo = SnowFlakeUtil.getSnowFlakeId();
         List<InsOrdersCarInfo> carInfos = insOrdersCarInfoService.list(new LambdaQueryWrapper<InsOrdersCarInfo>().eq(InsOrdersCarInfo::getLicenseNo, licenseNo)
                 .eq(InsOrdersCarInfo::getVinNo, vinNo)
                 .eq(InsOrdersCarInfo::getEngineNo, engineNo));
@@ -945,6 +946,7 @@ public class UnifyOrderManager {
         orderStatusVo.setInsOrdersAccidentalDriving(insOrdersAccidentalDriving);
         OrderStatusResultVo orderStatusResultVo = orderStatusService.queryOrderState(orderStatusVo);
         log.info("订单状态orderStatusResultVo=[{}]", JSONUtil.toJsonStr(orderStatusResultVo));
+
         // 保存状态查询结果
         insOrdersService.orderAfterUpdateOrderStatus(orderStatusVo.getOrder().getOrdersNo(), orderStatusResultVo);
         // 保存支付链接
@@ -956,6 +958,22 @@ public class UnifyOrderManager {
             doSomethingAfterUnderwited(insOrders);
         }
 
+        // 电销组订单状态已变更但比例未修改时,向前端提示
+        if (orderStatusResultVo.getOrderStatus() == InsOrderStatusEnum.UNDERWRITED) {
+            String queryUserId = insOrders.getRealQuoteUserId();
+            if (StrUtil.isNotBlank(queryUserId)) {
+                String systemCode = getSystemCode();
+                HttpResult<SysUserJzgInfo> userResult = orgClient.queryUserByUserId(queryUserId, systemCode);
+                if (userResult != null && userResult.getCode() == 200 && userResult.getData() != null
+                        && "8".equals(userResult.getData().getTypeAttr())) {
+                    InsFeeOrders feeOrders = insFeeOrdersService.getById(insOrders.getId());
+                    if (feeOrders == null || !Integer.valueOf(1).equals(feeOrders.getRatioModified())) {
+                        return HttpResult.ok("订单状态已更新,请修改出入口费用比例后发起财务审核");
+                    }
+                }
+            }
+        }
+
         return HttpResult.ok("状态刷新成功");
     }
 

+ 15 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsFeeOrdersService.java

@@ -42,4 +42,19 @@ public interface InsFeeOrdersService extends IService<InsFeeOrders> {
      * @date 2026/6/4 10:17
      */
     BigDecimal queryAllTotalReceivablePremiumByOrderNo(List<String> orderNos);
+
+    /**
+     * 修改出入口比例
+     *
+     * @param orderNo       订单号
+     * @param jqInletRatio  交强险入口比例
+     * @param syInletRatio  商业险入口比例
+     * @param jyInletRatio  驾意险入口比例
+     * @param jqExportRatio 交强险出口比例
+     * @param syExportRatio 商业险出口比例
+     * @param jyExportRatio 驾意险出口比例
+     * @return 更新后的费用记录
+     */
+    InsFeeOrders updateFeeRatio(String orderNo, BigDecimal jqInletRatio, BigDecimal syInletRatio, BigDecimal jyInletRatio,
+                                BigDecimal jqExportRatio, BigDecimal syExportRatio, BigDecimal jyExportRatio);
 }

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

@@ -35,7 +35,6 @@ import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
-import java.util.Objects;
 
 /**
  * @author quchen
@@ -487,6 +486,160 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         return insFeeOrdersMapper.getInsFeeOrderByOrderNo(orderNo);
     }
 
+    @Override
+    public InsFeeOrders updateFeeRatio(String orderNo, BigDecimal jqInletRatio, BigDecimal syInletRatio, BigDecimal jyInletRatio,
+                                       BigDecimal jqExportRatio, BigDecimal syExportRatio, BigDecimal jyExportRatio) {
+        final int SCALE = 5;
+
+        // 1. 查询订单费用记录
+        InsFeeOrders insFeeOrders = getFeeOrderByOrderNo(orderNo);
+        AssertionUtils.isFail(insFeeOrders == null, "根据订单号查询订单费用表查无数据,订单号:" + orderNo);
+
+        // 2. 获取关联数据用于费用重算
+        InsOrders insOrders = insOrdersService.getById(orderNo);
+        InsOrdersCosts insOrdersCosts = insOrdersCostsService.getById(insOrders.getId());
+        PtlAgreement ptlAgreement = orgClient.getByAgreementId(insOrders.getAgreementId());
+        Integer withTax = ptlAgreement.getWithTax();
+        BigDecimal taxFactor = BigDecimal.ONE;
+        if (withTax == 0) {
+            taxFactor = new BigDecimal("1.06");
+        }
+
+        // 保费
+        BigDecimal jqPremium = insOrdersCosts.getJqPremium() == null ? BigDecimal.ZERO : insOrdersCosts.getJqPremium();
+        BigDecimal syPremium = insOrdersCosts.getSyPremium() == null ? BigDecimal.ZERO : insOrdersCosts.getSyPremium();
+        BigDecimal jyPremium = insOrdersCosts.getJyPremium() == null ? BigDecimal.ZERO : insOrdersCosts.getJyPremium();
+
+        // 3. 更新出入口比例(前端传0-100,服务端除以100后保存)
+        // 入口比例变化时,同步调整手续费比例和跟单比例
+        if (jqInletRatio != null) {
+            adjustInletAndRelatedRatios(insFeeOrders, "jq", covertPercent(jqInletRatio));
+        }
+        if (syInletRatio != null) {
+            adjustInletAndRelatedRatios(insFeeOrders, "sy", covertPercent(syInletRatio));
+        }
+        if (jyInletRatio != null) {
+            adjustInletAndRelatedRatios(insFeeOrders, "jy", covertPercent(jyInletRatio));
+        }
+        if (jqExportRatio != null) {
+            insFeeOrders.setJqExportRatio(covertPercent(jqExportRatio));
+        }
+        if (syExportRatio != null) {
+            insFeeOrders.setSyExportRatio(covertPercent(syExportRatio));
+        }
+        if (jyExportRatio != null) {
+            insFeeOrders.setJyExportRatio(covertPercent(jyExportRatio));
+        }
+
+        // 4. 根据新的出入口比例重新计算留点比例和含分销出口比例
+        BigDecimal distributionRatio = BigDecimalUtil.divide(
+                BigDecimalUtil.add(insFeeOrders.getFirstDistributionRatio(),
+                        insFeeOrders.getSecondDistributionRatio(),
+                        insFeeOrders.getThirdDistributionRatio()),
+                new BigDecimal(100));
+
+        insFeeOrders.setJqExportRatioContainDistribution(BigDecimalUtil.add(insFeeOrders.getJqExportRatio(), distributionRatio));
+        insFeeOrders.setSyExportRatioContainDistribution(BigDecimalUtil.add(insFeeOrders.getSyExportRatio(), distributionRatio));
+        insFeeOrders.setJyExportRatioContainDistribution(BigDecimalUtil.add(insFeeOrders.getJyExportRatio(), distributionRatio));
+
+        BigDecimal jqKeepPointRatio = insFeeOrders.getJqInletRatio().divide(taxFactor, SCALE, RoundingMode.HALF_EVEN)
+                .add(insFeeOrders.getJqAdditionalRatio())
+                .subtract(BigDecimalUtil.add(insFeeOrders.getJqExportRatio(), distributionRatio));
+        BigDecimal syKeepPointRatio = insFeeOrders.getSyInletRatio().divide(taxFactor, SCALE, RoundingMode.HALF_EVEN)
+                .add(insFeeOrders.getSyAdditionalRatio())
+                .subtract(BigDecimalUtil.add(insFeeOrders.getSyExportRatio(), distributionRatio));
+        BigDecimal jyKeepPointRatio = insFeeOrders.getJyInletRatio().divide(taxFactor, SCALE, RoundingMode.HALF_EVEN)
+                .add(insFeeOrders.getJyAdditionalRatio())
+                .subtract(BigDecimalUtil.add(insFeeOrders.getJyExportRatio(), distributionRatio));
+
+        insFeeOrders.setJqKeepPointRatio(jqKeepPointRatio);
+        insFeeOrders.setSyKeepPointRatio(syKeepPointRatio);
+        insFeeOrders.setJyKeepPointRatio(jyKeepPointRatio);
+
+        // 5. 按险种重新计算所有费用
+        calculatePremiumByRule(insFeeOrders, "jq", jqPremium,
+                insFeeOrders.getJqCommissionRatio(), insFeeOrders.getJqInletRatio(), insFeeOrders.getJqFollowRatio(),
+                insFeeOrders.getJqAdditionalRatio(), insFeeOrders.getJqKeepPointRatio(), insFeeOrders.getJqExportRatio(),
+                insFeeOrders.getJqExportKeepPointRatio(), insFeeOrders.getJqExportRatioContainDistribution(),
+                withTax, taxFactor, SCALE);
+
+        calculatePremiumByRule(insFeeOrders, "sy", syPremium,
+                insFeeOrders.getSyCommissionRatio(), insFeeOrders.getSyInletRatio(), insFeeOrders.getSyFollowRatio(),
+                insFeeOrders.getSyAdditionalRatio(), insFeeOrders.getSyKeepPointRatio(), insFeeOrders.getSyExportRatio(),
+                insFeeOrders.getSyExportKeepPointRatio(), insFeeOrders.getSyExportRatioContainDistribution(),
+                withTax, taxFactor, SCALE);
+
+        calculatePremiumByRule(insFeeOrders, "jy", jyPremium,
+                insFeeOrders.getJyCommissionRatio(), insFeeOrders.getJyInletRatio(), insFeeOrders.getJyFollowRatio(),
+                insFeeOrders.getJyAdditionalRatio(), insFeeOrders.getJyKeepPointRatio(), insFeeOrders.getJyExportRatio(),
+                insFeeOrders.getJyExportKeepPointRatio(), insFeeOrders.getJyExportRatioContainDistribution(),
+                withTax, taxFactor, SCALE);
+
+        // 6. 重新统计总应收、总应付
+        BigDecimal totalPayable = insFeeOrders.getJqPayablePremium().add(insFeeOrders.getSyPayablePremium()).add(insFeeOrders.getJyPayablePremium());
+        BigDecimal totalReceivable = insFeeOrders.getJqReceivablePremium().add(insFeeOrders.getSyReceivablePremium()).add(insFeeOrders.getJyReceivablePremium());
+        insFeeOrders.setTotalPayablePremium(scale(totalPayable, SCALE));
+        insFeeOrders.setTotalReceivablePremium(scale(totalReceivable, SCALE));
+
+        // 7. 设置已修改标识
+        insFeeOrders.setRatioModified(1);
+
+        // 8. 保存到数据库
+        int updateCount = insFeeOrdersMapper.updateById(insFeeOrders);
+        AssertionUtils.isFail(updateCount <= 0, "修改出入口比例失败,订单号:" + orderNo);
+
+        log.info("修改出入口比例并重算费用成功,orderNo=[{}], jqInletRatio=[{}], syInletRatio=[{}], jyInletRatio=[{}], jqExportRatio=[{}], syExportRatio=[{}], jyExportRatio=[{}]",
+                orderNo, jqInletRatio, syInletRatio, jyInletRatio, jqExportRatio, syExportRatio, jyExportRatio);
+
+        return insFeeOrders;
+    }
+
+    /**
+     * 调整入口比例及关联的手续费比例和跟单比例
+     * 规则:手续费比例不能大于入口比例,跟单比例 = 入口比例 - 手续费比例
+     *
+     * @param insFeeOrders  费用订单
+     * @param type          险种类型 jq/sy/jy
+     * @param newInletRatio 新的入口比例(已除以100)
+     */
+    private void adjustInletAndRelatedRatios(InsFeeOrders insFeeOrders, String type, BigDecimal newInletRatio) {
+        switch (type) {
+            case "jq": {
+                insFeeOrders.setJqInletRatio(newInletRatio);
+                BigDecimal commissionRatio = insFeeOrders.getJqCommissionRatio();
+                if (newInletRatio.compareTo(commissionRatio) < 0) {
+                    insFeeOrders.setJqCommissionRatio(newInletRatio);
+                    insFeeOrders.setJqFollowRatio(BigDecimal.ZERO);
+                } else {
+                    insFeeOrders.setJqFollowRatio(newInletRatio.subtract(commissionRatio));
+                }
+                break;
+            }
+            case "sy": {
+                insFeeOrders.setSyInletRatio(newInletRatio);
+                BigDecimal commissionRatio = insFeeOrders.getSyCommissionRatio();
+                if (newInletRatio.compareTo(commissionRatio) < 0) {
+                    insFeeOrders.setSyCommissionRatio(newInletRatio);
+                    insFeeOrders.setSyFollowRatio(BigDecimal.ZERO);
+                } else {
+                    insFeeOrders.setSyFollowRatio(newInletRatio.subtract(commissionRatio));
+                }
+                break;
+            }
+            case "jy": {
+                insFeeOrders.setJyInletRatio(newInletRatio);
+                BigDecimal commissionRatio = insFeeOrders.getJyCommissionRatio();
+                if (newInletRatio.compareTo(commissionRatio) < 0) {
+                    insFeeOrders.setJyCommissionRatio(newInletRatio);
+                    insFeeOrders.setJyFollowRatio(BigDecimal.ZERO);
+                } else {
+                    insFeeOrders.setJyFollowRatio(newInletRatio.subtract(commissionRatio));
+                }
+                break;
+            }
+        }
+    }
+
     /**
      * 更新订单的可用金额,同时调整剩余金额
      * 更新前会校验:订单存在性、出口留点比例必须为0、新可用金额不能大于当前金额

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

@@ -36,11 +36,7 @@ import com.jzg.commons.entity.quote.vo.aggregated.QuoteEchoVo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteResultsVo;
 import com.jzg.commons.entity.quote.vo.aggregated.UnderwritingResultsVo;
 import com.jzg.commons.entity.quote.vo.image.InsuranceImageVo;
-import com.jzg.commons.entity.quote.vo.orders.InsFeeCalculateRequest;
-import com.jzg.commons.entity.quote.vo.orders.InsFeeCalculateResponse;
-import com.jzg.commons.entity.quote.vo.orders.InsOrdersAdd;
-import com.jzg.commons.entity.quote.vo.orders.InsOrdersEnd;
-import com.jzg.commons.entity.quote.vo.orders.InsOrdersVo;
+import com.jzg.commons.entity.quote.vo.orders.*;
 import com.jzg.commons.entity.rights.vo.InsOrderRightsInfoVo;
 import com.jzg.commons.entity.system.vo.SysSystemBusPermsVo;
 import com.jzg.commons.entity.vo.*;
@@ -52,7 +48,6 @@ import com.jzg.quotation.commons.client.OrgClient;
 import com.jzg.quotation.commons.client.PlatformClient;
 import com.jzg.quotation.commons.utils.BeanCopyUtil;
 import com.jzg.quotation.commons.utils.SnowFlakeUtil;
-import com.jzg.quotation.summary.aop.aspect.QuoteVerificationAspect;
 import com.jzg.quotation.summary.client.EsmInsCompanyClient;
 import com.jzg.quotation.summary.consumer.template.OrderMessageTemplate;
 import com.jzg.quotation.summary.entity.bo.DataValueBo;
@@ -1144,10 +1139,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
                 quoteVo.getOrder().getInsuranceCompanyCode(),
                 quoteVo.getCarInfoVo().getLicenseNo(),
                 quoteVo.getCarInfoVo().getVinNo());
-        boolean isExistsMainOrder = false;
-        if (Objects.nonNull(mainOrders)) {
-            isExistsMainOrder = true;
-        }
+        boolean isExistsMainOrder = Objects.nonNull(mainOrders);
         String mainOrderNo;
         // 如果订单号为0 则生成主订单
         if (!isExistsMainOrder) {
@@ -1666,8 +1658,25 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
                     baseController.getToken(), MessageCodeEnum.TEMPLATE_5);
         }
         if (orderStatusResultVo.getOrderStatus().equals(InsOrderStatusEnum.UNDERWRITED)) {
-            // 增加财务审核
-            insFeeAuditService.feeAuditAdd(insOrders,systemCode );
+            // 电销组业务员的订单变更为已承保时,检查出入口比例是否已修改,未修改则跳过财务审核
+            boolean skipFeeAudit = false;
+            String realQuoteUserId = insOrders.getRealQuoteUserId();
+            if (StrUtil.isNotBlank(realQuoteUserId)) {
+                HttpResult<SysUserJzgInfo> userResult = orgClient.queryUserByUserId(realQuoteUserId, systemCode);
+                if (userResult != null && userResult.getCode() == 200 && userResult.getData() != null
+                        && "8".equals(userResult.getData().getTypeAttr())) {
+                    InsFeeOrders feeOrders = insFeeOrdersMapper.selectOne(new LambdaQueryWrapper<InsFeeOrders>()
+                            .eq(InsFeeOrders::getOrderNo, insOrders.getId()));
+                    if (feeOrders == null || !Integer.valueOf(1).equals(feeOrders.getRatioModified())) {
+                        skipFeeAudit = true;
+                        log.info("电销组订单出入口比例未修改,跳过财务审核,订单号=[{}]", orderNo);
+                    }
+                }
+            }
+            if (!skipFeeAudit) {
+                // 增加财务审核
+                insFeeAuditService.feeAuditAdd(insOrders, systemCode);
+            }
             // 将父订单的保司id 和名称更新
             InsOrders baseInsOrders = insOrdersMapper.selectOne(new LambdaQueryWrapper<InsOrders>().eq(InsOrders::getId, insOrders.getParentId()));
             baseInsOrders.setCompanyId(insOrders.getCompanyId());

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

@@ -208,6 +208,8 @@
         <result property="auditName" column="audit_name" jdbcType="VARCHAR"/>
         <result property="errorMessage" column="error_message" jdbcType="VARCHAR"/>
         <result property="orderType" column="order_type" jdbcType="VARCHAR"/>
+        <result property="dockingPerson" column="docking_person" jdbcType="VARCHAR"/>
+        <result property="dockingPersonPhone" column="docking_person_phone" jdbcType="VARCHAR"/>
         <association property="insOrders" column="{id=id}" select="selectOrdersById"/>
         <association property="carInfoVo" column="{orderNo=id}" select="selectOrdersCarInfoByOrderNo"/>
         <association property="insOrdersOtherInfo" column="{orderNo=id}" select="selectOrdersOtherByOrderNo"/>
@@ -793,7 +795,8 @@
         WHEN 2 THEN '代客录单'
         WHEN 3 THEN '补录订单'
         ELSE ''
-        END AS order_type
+        END AS order_type,
+        docking_person , docking_person_phone
         from ins_orders
         <where>
             and is_delete = 0

+ 4 - 3
tenant/organization/src/main/java/com/jzg/organization/aop/OrderOperationLogAspect.java

@@ -1,6 +1,7 @@
 package com.jzg.organization.aop;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.json.JSONConfig;
 import cn.hutool.json.JSONUtil;
 import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.finance.vo.BatchModifyVo;
@@ -8,7 +9,6 @@ import com.jzg.commons.entity.orders.po.InsOrders;
 import com.jzg.commons.entity.orders.po.InsOrdersCarInfo;
 import com.jzg.commons.entity.orders.po.InsOrdersTrack;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteEchoVo;
-import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
 import com.jzg.commons.entity.vo.QuestionOrder;
 import com.jzg.commons.util.JsonDiffUtil;
 import com.jzg.commons.util.OrderComponts;
@@ -146,6 +146,8 @@ public class OrderOperationLogAspect {
             logger.info("批量修改没有传入订单号");
             return;
         }
+        // 创建 JSONConfig 并设置日期格式, 会把LocalDate 和LocalDateTime 都转换为 包含时分秒的格式(后续有了更好的办法再优化)
+        JSONConfig jsonConfig = JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss");
         for (String orderNo : orderNos) {
             InsOrdersTrack track = new InsOrdersTrack();
             track.setModule(log.module());
@@ -154,8 +156,7 @@ public class OrderOperationLogAspect {
             track.setOptContent(log.description());
             QuoteEchoVo detailVoOld = oldOrders.get(orderNo);
             QuoteEchoVo detailVoNew = newOrders.get(orderNo);
-            Map<String, List<String>> diffMap = JsonDiffUtil.compareJson(JSONUtil.toJsonStr(detailVoOld), JSONUtil.toJsonStr(detailVoNew), new HashSet<>());
-
+            Map<String, List<String>> diffMap = JsonDiffUtil.compareJson(JSONUtil.toJsonStr(detailVoOld,jsonConfig), JSONUtil.toJsonStr(detailVoNew,jsonConfig), new HashSet<>());
             if(CollUtil.isNotEmpty(diffMap)){
                 List<String> oldItems = new ArrayList<>();
                 List<String> newItems = new ArrayList<>();

+ 16 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/AgreementController.java

@@ -14,6 +14,7 @@ import com.jzg.commons.entity.vo.AgreementVo;
 import com.jzg.commons.entity.vo.UpAndDownVo;
 import com.jzg.commons.util.AssertionUtils;
 import com.jzg.organization.mapper.PtlAgreementMapper;
+import com.jzg.organization.service.PtlAgreementCostService;
 import com.jzg.organization.service.PtlAgreementDeptService;
 import com.jzg.organization.service.PtlAgreementService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -43,6 +44,9 @@ public class AgreementController extends BaseController {
     @Autowired
     private PtlAgreementDeptService agreementDeptService;
 
+    @Autowired
+    private PtlAgreementCostService ptlAgreementCostService;
+
     @Autowired
     BaseController baseController;
 
@@ -211,6 +215,18 @@ public class AgreementController extends BaseController {
         return HttpResult.ok("复制成功");
     }
 
+    /**
+     * 批量修改协议费用有效期
+     * @param param 参数
+     * @return HttpResult
+     */
+    @Operation(summary = "批量修改协议费用有效期(按报价类型筛选)")
+    @PostMapping("/agreementCostBatchUpdateValidDate")
+    public HttpResult<String> agreementCostBatchUpdateValidDate(
+            @Validated @RequestBody PtlAgreementCostBatchUpdateValidDateParam param) {
+        return ptlAgreementCostService.batchUpdateValidDate(param);
+    }
+
     /**
      * 外部协议添加
      * @param param

+ 5 - 0
tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementCostService.java

@@ -64,4 +64,9 @@ public interface PtlAgreementCostService extends IService<PtlAgreementCost> {
      */
     Boolean costCopy(PtlAgreementCostCopyParam costCopyParam);
 
+    /**
+     * 批量修改协议费用有效期
+     */
+    HttpResult<String> batchUpdateValidDate(PtlAgreementCostBatchUpdateValidDateParam param);
+
 }

+ 59 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jzg.commons.constants.Constants;
@@ -67,6 +68,9 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     @Resource
     private PtlAgreementUndwrtRulesAttrService agreementUndwrtRulesAttrService;
 
+    @Autowired
+    private PtlAgreementCostTypeService ptlAgreementCostTypeService;
+
     @Autowired
     RedissonClient redissonClient;
 
@@ -441,5 +445,60 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
         return true;
     }
 
+    @Override
+    public HttpResult<String> batchUpdateValidDate(PtlAgreementCostBatchUpdateValidDateParam param) {
+        // 1. 校验时间
+        if (param.getEffectiveTime() == null || param.getFailureTime() == null) {
+            return HttpResult.error("生效时间和失效时间不能为空");
+        }
+        if (param.getFailureTime().before(param.getEffectiveTime())
+                || param.getFailureTime().equals(param.getEffectiveTime())) {
+            return HttpResult.error("失效时间必须晚于生效时间");
+        }
+
+        List<String> finalCostIds;
+
+        // 2. 优先使用直接传入的 costIds
+        if (param.getCostIds() != null && !param.getCostIds().isEmpty()) {
+            finalCostIds = param.getCostIds();
+        } else if (param.getPtlAgreementId() != null && !param.getPtlAgreementId().isEmpty()) {
+            // 3. 否则根据协议ID + 承保规则ID + 报价类型筛选
+            LambdaQueryWrapper<PtlAgreementCost> costWrapper = new LambdaQueryWrapper<>();
+            costWrapper.eq(PtlAgreementCost::getPtlAgreementId, param.getPtlAgreementId());
+            if (param.getCoverRuleId() != null && !param.getCoverRuleId().isEmpty()) {
+                costWrapper.eq(PtlAgreementCost::getCoverRuleId, param.getCoverRuleId());
+            }
+            List<PtlAgreementCost> costs = this.list(costWrapper);
+            if (costs.isEmpty()) {
+                return HttpResult.ok("没有找到匹配的费用记录");
+            }
+            List<String> allCostIds = costs.stream().map(PtlAgreementCost::getId).toList();
+
+            // 如果指定了报价类型,进一步筛选
+            if (param.getCostType() != null && !param.getCostType().isEmpty()) {
+                LambdaQueryWrapper<PtlAgreementCostType> typeWrapper = new LambdaQueryWrapper<>();
+                typeWrapper.in(PtlAgreementCostType::getPtlAgreementCostId, allCostIds);
+                typeWrapper.eq(PtlAgreementCostType::getCostType, param.getCostType());
+                List<PtlAgreementCostType> types = ptlAgreementCostTypeService.list(typeWrapper);
+                finalCostIds = types.stream().map(PtlAgreementCostType::getPtlAgreementCostId).distinct().toList();
+            } else {
+                finalCostIds = allCostIds;
+            }
+        } else {
+            return HttpResult.error("请勾选要修改的费用,或传入协议ID进行筛选");
+        }
+
+        // 4. 批量更新有效期
+        LambdaUpdateWrapper<PtlAgreementCost> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.in(PtlAgreementCost::getId, finalCostIds);
+        updateWrapper.set(PtlAgreementCost::getEffectiveTime, param.getEffectiveTime());
+        updateWrapper.set(PtlAgreementCost::getFailureTime, param.getFailureTime());
+        boolean success = this.update(updateWrapper);
+
+        return success
+                ? HttpResult.ok("批量修改成功,共修改 " + finalCostIds.size() + " 条记录")
+                : HttpResult.error("批量修改失败");
+    }
+
 
 }

+ 35 - 2
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java

@@ -50,6 +50,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -694,10 +695,42 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
             });
         });
 
-        //自选方案
+        //自选方案 - 默认保额选最小
         SchemeResultVo.SchemeVo opSchemeVo = schemeInsuranceInfo.stream().filter(x -> !TextUtils.isEmpty(x.getSchemeType()) && x.getSchemeType().equals("2")).findFirst().orElse(null);
         if (Objects.nonNull(opSchemeVo)) {
-            schemeResultVo.setOptionalScheme(opSchemeVo.getInfos().get(0));
+            SchemeResultVo.SchemeInfoVo optionalSchemeInfo = opSchemeVo.getInfos().get(0);
+            if (optionalSchemeInfo.getKinds() != null) {
+                optionalSchemeInfo.getKinds().forEach(kind -> {
+                    if (!kind.getOptions().isEmpty()) {
+                        BigDecimal minVal = null;
+                        String minValueStr = kind.getOptions().get(0).getValue();
+                        for (SchemeResultVo.Option opt : kind.getOptions()) {
+                            String label = opt.getLabel();
+                            String value = opt.getValue();
+                            // 跳过"不投保"、"投保"、"0"等
+                            if ((label != null && (label.contains("不投") || label.contains("投保")))
+                                    || "0".equals(value) || "不投保".equals(value) || value == null || value.isEmpty()) {
+                                continue;
+                            }
+                            try {
+                                String clean = value.replaceAll("[^0-9.]", "");
+                                if (!clean.isEmpty()) {
+                                    BigDecimal num = new BigDecimal(clean);
+                                    if (minVal == null || num.compareTo(minVal) < 0) {
+                                        minVal = num;
+                                        minValueStr = value;
+                                    }
+                                }
+                            } catch (Exception ignored) {}
+                        }
+                        kind.setAmount(minValueStr);
+                        kind.setUnitAmount(minValueStr);
+                        kind.setServiceTimes(minValueStr);
+                        kind.setDeductibleRate(minValueStr);
+                    }
+                });
+            }
+            schemeResultVo.setOptionalScheme(optionalSchemeInfo);
         }
 
         //排除交强险的险种

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

@@ -3,6 +3,7 @@ package com.jzg.organization.service.impl;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.tree.Tree;
 import cn.hutool.core.lang.tree.TreeNodeConfig;
 import cn.hutool.core.lang.tree.TreeUtil;
@@ -756,6 +757,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     public List<FollowCompanyFeeVO> followCompanySuperviseSettlementReport(SettlementReportQueryVo settlementReportQueryVo) {
         log.info("私有协议-跟单结算记录-结算报表: settlementReportQueryVo=[{}]", JSONUtil.toJsonStr(settlementReportQueryVo));
         List<FollowCompanyFeeVO> resultList = new ArrayList<>();
+        String invoiceType = settlementReportQueryVo.getInvoiceType();
 
         // 1. 一次性获取保险公司全量Map,全局复用
         Map<String, EsmInsCompany> companyMap = getAllInsCompanyMap();
@@ -771,22 +773,25 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         }
 
         // 应收项为空时才去补充数据,不为空时不补充数据,补充数据是因为联查了invoice和settlement表,所以没开票和结算的数据会被过滤掉,才需要补充数据
-        List<InsPlyIncomeDto> incomeDtoList = CollUtil.newArrayList();
-        if (StrUtil.isBlank(settlementReportQueryVo.getInvoiceType())){
-            // 3. 查询额外其他费用收入数据,补充到结果集
-            incomeDtoList = queryFollowIncomeData(settlementReportQueryVo);
-            if (CollUtil.isEmpty(incomeDtoList)) {
-                return resultList;
-            }else{
-                // 如果JyPremium不为0,则设置发票类型为4
-                incomeDtoList.stream().forEach(item -> {
-                    if (StrUtil.isNotBlank(item.getJyPremium()) && !NumberUtil.equals(BigDecimal.ZERO, new BigDecimal(item.getJyPremium()))){
-                        item.setInvoiceType(InvoiceTypeEnum.FEE_4.getCode());
-                    }else{
-                        item.setInvoiceType(InvoiceTypeEnum.FEE_2.getCode());
-                    }
-                });
-                List<InsPlyIncomeDto> copyList = CollUtil.newArrayList();
+        List<InsPlyIncomeDto> incomeDtoList = queryFollowIncomeData(settlementReportQueryVo);
+        if (CollUtil.isEmpty(incomeDtoList)) {
+            return resultList;
+        }else{
+            // 如果JyPremium不为0,则设置发票类型为4
+            incomeDtoList.stream().forEach(item -> {
+                if (StrUtil.isNotBlank(item.getJyPremium()) && !NumberUtil.equals(BigDecimal.ZERO, new BigDecimal(item.getJyPremium()))){
+                    item.setInvoiceType(InvoiceTypeEnum.FEE_4.getCode());
+                }else{
+                    item.setInvoiceType(InvoiceTypeEnum.FEE_2.getCode());
+                }
+            });
+            // 过滤一下invoiceType等于请求接口入参的数据
+            incomeDtoList = incomeDtoList.stream()
+                    .filter(income -> StrUtil.isBlank(invoiceType)
+                            || invoiceType.equals(income.getInvoiceType()))
+                    .toList();
+            List<InsPlyIncomeDto> copyList = CollUtil.newArrayList();
+            if (CollUtil.isNotEmpty(incomeDtoList)){
                 // 如果有发票类型为4的,则复制一条4的数据,完全一致,但发票类型为2
                 incomeDtoList.stream().filter(item -> InvoiceTypeEnum.FEE_4.getCode().equals(item.getInvoiceType())).forEach(item -> {
                     InsPlyIncomeDto incomeDto = new InsPlyIncomeDto();
@@ -794,7 +799,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     incomeDto.setInvoiceType(InvoiceTypeEnum.FEE_2.getCode());
                     copyList.add(incomeDto);
                 });
-                incomeDtoList.addAll(copyList);
+                incomeDtoList = CollUtil.addAll(incomeDtoList, copyList).stream().toList();
             }
         }
 
@@ -978,7 +983,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         boolean noFilterCond = StrUtil.isBlank(status)
                 && (StrUtil.isBlank(invoiceStartTime) || StrUtil.isBlank(invoiceEndTime))
                 && (StrUtil.isBlank(settleStartTime) || StrUtil.isBlank(settleEndTime));
-        if (noFilterCond) {
+        if (noFilterCond || CollUtil.isEmpty(incomeList)) {
             return incomeList;
         }
 
@@ -1954,7 +1959,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             // 处理结算数据
             // 未完全结算完成
             InsPlyIncomeInvoiceSettlement settlement = new InsPlyIncomeInvoiceSettlement(invoice.getId(), settlementVo.getActualReceivedAmount(),
-                    DateTime.now(), settlementVo.getSettlementPaymentDifference(), settlementVo.getSettlementPaymentReason());
+                    DateUtil.parse(settlementVo.getReceivePaymentDate(), "yyyy-MM-dd HH:mm:ss"), settlementVo.getSettlementPaymentDifference(), settlementVo.getSettlementPaymentReason());
             insPlyIncomeInvoiceSettlementMapper.insert(settlement);
 
             if (CollectionUtils.isNotEmpty(settlementVo.getAttachmentIds())) {
@@ -2791,7 +2796,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             // 处理结算数据
             // 未完全结算完成
             InsPlyIncomeInvoiceSettlement settlement = new InsPlyIncomeInvoiceSettlement(settlementVo.getInvoicingId(), settlementVo.getActualReceivedAmount(),
-                    DateTime.now(), settlementVo.getSettlementPaymentDifference(), settlementVo.getSettlementPaymentReason());
+                    DateUtil.parse(settlementVo.getReceivePaymentDate(), "yyyy-MM-dd HH:mm:ss"), settlementVo.getSettlementPaymentDifference(), settlementVo.getSettlementPaymentReason());
             insPlyIncomeInvoiceSettlementMapper.insert(settlement);
 
             if (CollectionUtils.isNotEmpty(settlementVo.getAttachmentIds())) {
@@ -3687,6 +3692,9 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     @Transactional(rollbackFor = Exception.class)
     public boolean batchModify(BatchModifyVo batchModifyVo) {
         log.info("批量修改应收订单: batchModifyVo=[{}]", JSONUtil.toJsonStr(batchModifyVo));
+        if(StrUtil.isEmpty(batchModifyVo.getContractPhone())){
+            batchModifyVo.setContractPhone(batchModifyVo.getContractUserPhone());
+        }
         List<String> incomeIds = batchModifyVo.getIncomeIds();
         if (CollUtil.isEmpty(incomeIds)) {
             throw new ServiceException("请勾选要批量修改的应收订单");
@@ -4553,7 +4561,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             // 处理结算数据
             // 未完全结算完成
             InsPlyIncomeInvoiceSettlement settlement = new InsPlyIncomeInvoiceSettlement(settlementVo.getInvoicingId(), settlementVo.getActualReceivedAmount(),
-                    DateTime.now(), settlementVo.getSettlementPaymentDifference(), settlementVo.getSettlementPaymentReason());
+                    DateUtil.parse(settlementVo.getReceivePaymentDate(), "yyyy-MM-dd"), settlementVo.getSettlementPaymentDifference(), settlementVo.getSettlementPaymentReason());
             insPlyIncomeInvoiceSettlementMapper.insert(settlement);
 
             if (CollectionUtils.isNotEmpty(settlementVo.getAttachmentIds())) {
@@ -6300,6 +6308,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         BigDecimal subtract = BigDecimalUtil.subtract(settlementAmount, insPlyIncomeInvoice.getReceivableSupervisePremium());
         if (CollUtil.isNotEmpty(insPlyIncomeInvoiceSettlements)){
             if(subtract.compareTo(BigDecimal.ZERO) != 0){
+                // 点标识结清的时候不更新收款日期,和wwq确认过
                 InsPlyIncomeInvoiceSettlement insPlyIncomeInvoiceSettlement = insPlyIncomeInvoiceSettlements.get(0);
                 insPlyIncomeInvoiceSettlement.setSettlementPaymentDifference(subtract);
                 insPlyIncomeInvoiceSettlement.setSettlementPaymentReason(settlementPaymentReason);

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

@@ -314,6 +314,7 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
         }
         param.setCreateTimeStart(createTimeStart);
         param.setCreateTimeEnd(createTimeEnd);
+        List<IncomeAndExpenseList> recordsWithOutParam = sysAmountAuditingService.getIncomeAndExpense(new IncomeAndExpenseParam(param.getUserId(),param.getSystemCode()));
         List<IncomeAndExpenseList> allRecords = sysAmountAuditingService.getIncomeAndExpense(param);
         allRecords = allRecords.stream().peek(action->{
             if("0".equals(action.getStatus())){
@@ -363,7 +364,7 @@ public class SysUserAccountServiceImpl extends ServiceImpl<SysUserAccountMapper,
 
         // 按月份分组统计
         Map<String, IncomeAndExpenseVo.IncomeAndExpense> monthSummaryMap = new TreeMap<>(Collections.reverseOrder());
-        for (IncomeAndExpenseList record : allRecords) {
+        for (IncomeAndExpenseList record : recordsWithOutParam) {
             if (record.getCreateTime() == null) continue;
             // 获取月份(格式:yyyy-MM)
             String month = record.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM"));

+ 9 - 3
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -1506,6 +1506,9 @@
             <if test="invoiceRecordQueryVo.companyId != null and invoiceRecordQueryVo.companyId != ''">
                 AND ipii.company_id = #{invoiceRecordQueryVo.companyId}
             </if>
+            <if test="invoiceRecordQueryVo.invoiceNo != null and invoiceRecordQueryVo.invoiceNo != ''">
+                AND ipii.invoice_no like concat('%',#{invoiceRecordQueryVo.invoiceNo},'%')
+            </if>
             <if test="invoiceRecordQueryVo.invoiceType != null and invoiceRecordQueryVo.invoiceType != ''">
                 AND ipii.invoice_type = #{invoiceRecordQueryVo.invoiceType}
             </if>
@@ -1585,6 +1588,9 @@
             <if test="invoiceRecordQueryVo.recordId != null and invoiceRecordQueryVo.recordId != ''">
                 AND ipii.id = #{invoiceRecordQueryVo.recordId}
             </if>
+            <if test="invoiceRecordQueryVo.invoiceNo != null and invoiceRecordQueryVo.invoiceNo != ''">
+                AND ipii.invoice_no like concat('%',#{invoiceRecordQueryVo.invoiceNo},'%')
+            </if>
             <if test="invoiceRecordQueryVo.companyId != null and invoiceRecordQueryVo.companyId != ''">
                 AND ipii.company_id = #{invoiceRecordQueryVo.companyId}
             </if>
@@ -1881,7 +1887,7 @@
     <select id="getReceiverSettlementReport" resultType="com.jzg.commons.entity.finance.dto.ReceiverSettlementReportDto">
         SELECT
         ipi.contact_person AS receiver,
-        ipi.company_id,
+        -- ipi.company_id,
         SUM(COALESCE(ipi.jq_supervise_costs_premiums,0)  +COALESCE(ipi.sy_supervise_costs_premiums,0)  +COALESCE(ipi.jy_supervise_costs_premiums,0) ) AS superviseFee,
         SUM(COALESCE(ipi.jq_other_costs_premiums,0) + COALESCE(ipi.sy_other_costs_premiums,0) +COALESCE(ipi.jy_other_costs_premiums,0) ) AS followFee,
         SUM(
@@ -1923,8 +1929,8 @@
             </if>
         </where>
         GROUP BY
-        ipi.contact_person,
-        ipi.company_id
+        ipi.contact_person
+        -- ,ipi.company_id
     </select>
     <!-- 根据发票序号查询结算明细 lipf 2026年5月15日10:58:36 -->
     <select id="queryInvoiceSettlementByInvoiceId"

+ 154 - 0
修改出入口比例接口对接文档.md

@@ -0,0 +1,154 @@
+# 修改出入口比例接口对接文档
+
+## 1. 概述
+
+- **功能**:修改 `ins_fee_orders` 表中交强险、商业险、驾意险的入口比例和出口比例,并标记是否已手动修改。
+- **Base URL**:`{host}/supplementOrder`
+
+---
+
+## 2. 修改出入口比例
+
+### 2.1 接口信息
+
+| 项目             | 说明                              |
+|------------------|-----------------------------------|
+| **URL**          | `/supplementOrder/updateFeeRatio` |
+| **Method**       | `POST`                            |
+| **Content-Type** | `application/json`                |
+
+### 2.2 请求参数
+
+```json
+{
+  "orderNo": "OR2026072300001",
+  "jqInletRatio": 10,
+  "syInletRatio": 20,
+  "jyInletRatio": 5,
+  "jqExportRatio": 8,
+  "syExportRatio": 15,
+  "jyExportRatio": 3
+}
+```
+
+| 字段            | 类型       | 必填   | 说明                                                         |
+|-----------------|------------|--------|--------------------------------------------------------------|
+| `orderNo`       | String     | **是** | 订单号                                                       |
+| `jqInletRatio`  | BigDecimal | 否     | 交强险入口比例(0-100,服务端自动除以100,如传 10 表示 10%) |
+| `syInletRatio`  | BigDecimal | 否     | 商业险入口比例(0-100)                                      |
+| `jyInletRatio`  | BigDecimal | 否     | 驾意险入口比例(0-100)                                      |
+| `jqExportRatio` | BigDecimal | 否     | 交强险出口比例(0-100)                                      |
+| `syExportRatio` | BigDecimal | 否     | 商业险出口比例(0-100)                                      |
+| `jyExportRatio` | BigDecimal | 否     | 驾意险出口比例(0-100)                                      |
+
+> **说明**:6个比例字段均为可选,仅更新传入的非 `null` 值。前端传入 0-100 的百分比数值,服务端自动除以 100 后保存。
+
+### 2.3 返回结果
+
+#### 成功响应
+
+```json
+{
+  "code": 200,
+  "message": "success",
+  "data": {
+    "orderNo": "OR2026072300001",
+    "jqInletRatio": 0.10,
+    "syInletRatio": 0.20,
+    "jyInletRatio": 0.05,
+    "jqExportRatio": 0.08,
+    "syExportRatio": 0.15,
+    "jyExportRatio": 0.03,
+    "ratioModified": 1
+  }
+}
+```
+
+#### 失败响应
+
+```json
+{
+  "code": 500,
+  "message": "根据订单号查询订单费用表查无数据,订单号:OR2026072300001",
+  "data": null
+}
+```
+
+---
+
+## 3. 获取订单详情(含比例修改标识)
+
+### 3.1 接口信息
+
+| 项目       | 说明                              |
+|------------|-----------------------------------|
+| **URL**    | `/supplementOrder/getOrderDetail` |
+| **Method** | `GET`                             |
+
+### 3.2 请求参数
+
+| 参数       | 类型   | 必填   | 说明                                    |
+|------------|--------|--------|-----------------------------------------|
+| `ordersNo` | String | **是** | 订单号                                  |
+| `from`     | String | 否     | `share`=分享链接进入,其他=订单列表进入 |
+
+### 3.3 响应新增字段
+
+在 `data.insFeeOrders` 对象中新增字段:
+
+| 字段            | 类型    | 说明                                                     |
+|-----------------|---------|----------------------------------------------------------|
+| `ratioModified` | Integer | 出入口比例是否已手动修改<br>`0` - 未修改<br>`1` - 已修改 |
+
+#### 示例
+
+```json
+{
+  "code": 200,
+  "message": "success",
+  "data": {
+    "order": { "...": "..." },
+    "insFeeOrders": {
+      "orderNo": "OR2026072300001",
+      "jqPremium": "950.00",
+      "syPremium": "3000.00",
+      "jyPremium": "200.00",
+      "jqInletRatio": 0.10,
+      "syInletRatio": 0.20,
+      "jyInletRatio": 0.05,
+      "jqExportRatio": 0.08,
+      "syExportRatio": 0.15,
+      "jyExportRatio": 0.03,
+      "ratioModified": 1,
+      "...": "..."
+    },
+    "costRatio": { "...": "..." }
+  }
+}
+```
+
+---
+
+## 4. 处理逻辑说明
+
+1. **参数校验**:校验 `orderNo` 是否为空,查询 `ins_fee_orders` 表中是否存在该订单。
+2. **选择性更新**:仅更新请求中传入的非 `null` 比例字段,未传入的字段保持原值不变。
+3. **百分比转换**:前端传入 0-100 的数值,服务端调用 `covertPercent()` 除以 100 后保存(如前端传 10,保存为 0.10)。
+4. **关联比例联动**(入口比例变化时):
+    - 若新的入口比例 **小于** 手续费比例,则手续费比例强制调整为入口比例,跟单比例置为 0
+    - 若新的入口比例 **大于等于** 手续费比例,则跟单比例 = 入口比例 - 手续费比例
+5. **留点比例重算**:`留点比例 = 入口比例/税费因子 + 加投比例 - (出口比例 + 分销比例)`
+6. **含分销出口比例重算**:`含分销出口比例 = 出口比例 + 分销比例`
+7. **费用重算**:根据更新后的所有比例,调用 `calculatePremiumByRule` 重新计算每个险种的:
+    - 入口应收金额、手续费金额、跟单金额、加投金额、留点金额、出口金额、出口留点金额
+8. **汇总重算**:重新计算总应收金额 `totalReceivablePremium` 和总应付金额 `totalPayablePremium`
+9. **修改标识**:更新成功后自动将 `ratio_modified` 字段置为 `1`(已修改)。
+10. **返回数据**:返回完整的 `InsFeeOrders` 对象(含重算后的所有费用)。
+
+---
+
+## 5. 数据库变更
+
+```sql
+ALTER TABLE ins_fee_orders ADD COLUMN ratio_modified TINYINT DEFAULT 0 COMMENT '出入口比例是否已手动修改 0-未修改 1-已修改';
+```