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

Merge remote-tracking branch 'origin/master'

wanghao 3 месяцев назад
Родитель
Сommit
6a40968c56
40 измененных файлов с 1414 добавлено и 94 удалено
  1. 17 2
      commons/src/main/java/com/jzg/commons/entity/dto/FeeAuditParam.java
  2. 50 0
      commons/src/main/java/com/jzg/commons/entity/finance/dto/InsFeeFollowOrderDto.java
  3. 23 0
      commons/src/main/java/com/jzg/commons/entity/finance/dto/InsPlyFollowInvoiceLinkDto.java
  4. 319 0
      commons/src/main/java/com/jzg/commons/entity/finance/dto/InsPlyIncomeDto.java
  5. 51 0
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsFeeFollowOrder.java
  6. 27 0
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyFollowInvoiceLink.java
  7. 1 1
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncomeInvoice.java
  8. 5 0
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncomeInvoiceLink.java
  9. 39 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoiceAndSettlementVo.java
  10. 42 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoicePageListVo.java
  11. 43 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoiceVo.java
  12. 55 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/InsFeeFollowOrderVo.java
  13. 27 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/InsPlyFollowInvoiceLinkVo.java
  14. 8 3
      commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordResult.java
  15. 1 0
      platform/src/main/resources/application.yml
  16. 13 19
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/component/GuoRenCrawlerRequestComponent.java
  17. 7 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/dto/CiInsureDemandDTO.java
  18. 1 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/dto/GuoRenBiDTO.java
  19. 1 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/dto/GuoRenCiDTO.java
  20. 6 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/request/GuoRenCrawlerProposalNoSaveRequest.java
  21. 1 1
      tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/service/impl/GuoRenCrawlerRequestImpl.java
  22. 5 2
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/entity/request/HbCrawlerCalculationRequest.java
  23. 1 0
      tenant/insurance/quotation-hengbang/src/main/java/com/jzg/quotation/hengbang/crawler/service/Impl/HengBangCrawlerRequestImpl.java
  24. 4 1
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/service/Impl/HuaTaiCrawlerRequestImpl.java
  25. 2 2
      tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/util/UploadUtil.java
  26. 6 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java
  27. 3 3
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  28. 3 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsOrdersService.java
  29. 3 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeAuditServiceImpl.java
  30. 7 5
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  31. 9 22
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsFeeAuditMapper.xml
  32. 64 0
      tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java
  33. 14 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/InsFeeFollowOrderMapper.java
  34. 13 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/InsPlyFollowInvoiceLinkMapper.java
  35. 0 8
      tenant/organization/src/main/java/com/jzg/organization/mapper/InsPlyIncomeInvoiceLinkMapper.java
  36. 12 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/ReceivableMapper.java
  37. 28 0
      tenant/organization/src/main/java/com/jzg/organization/service/ReceivableService.java
  38. 483 16
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  39. 19 0
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml
  40. 1 1
      tenant/organization/src/main/resources/mapper/SysUserJzgInfoBankCardMapper.xml

+ 17 - 2
commons/src/main/java/com/jzg/commons/entity/dto/FeeAuditParam.java

@@ -42,11 +42,11 @@ public class FeeAuditParam extends PageRequest {
 
     @Schema(description = "报价时间开始")
     @JsonFormat(pattern = "yyyy-MM-dd")
-    private LocalDateTime quotationTimeStart;
+    private LocalDate quotationTimeStart;
 
     @Schema(description = "报价时间结束")
     @JsonFormat(pattern = "yyyy-MM-dd")
-    private LocalDateTime quotationTimeEnd;
+    private LocalDate quotationTimeEnd;
 
     @Schema(description = "签单时间开始")
     @JsonFormat(pattern = "yyyy-MM-dd")
@@ -96,6 +96,21 @@ public class FeeAuditParam extends PageRequest {
     @Schema(description = "领取人")
     private String receiveUser;
 
+    /**
+     * 在订单审核-任务中心&我的审核,两个页面,调用的都是同一个接口 feeAudit/auditList
+     * 但是实际业务邀请中,
+     *      任务中心要求查看的是该租户下的所有的数据。
+     *      我的审核要求查看的是,指定用户领取后的数据。
+     *      ---
+     *      在任务中心,待领取tab页,需要查询所有未被领取的数据, 在我的审核tab页中,需要查询所有本人已经领取,但是未处理的数据
+     *      现在两个待领取的tab页,一个需要查询出所有未领取的数据,一个需要查询本人领取过的数据。 同时还不能对其他tab页的数据造成影响。
+     *      ---
+     *      allToReceive 表示 查询全部待领取,默认是false,查询的时候,不对receiveUser进行判断,
+     *      只有在任务中心-待审核 tab页面,会给他赋值 true, 此时,会要求专门查询 recieve_user 和 recieve_time 为空的
+     */
+    @Schema(description = "是否要查询全部待领取")
+    private boolean allTodoReceive;
+
     @Schema(description = "审核方式 1 人工审核 2 自动审核")
     private Integer auditType;
 

+ 50 - 0
commons/src/main/java/com/jzg/commons/entity/finance/dto/InsFeeFollowOrderDto.java

@@ -0,0 +1,50 @@
+package com.jzg.commons.entity.finance.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 保费跟踪订单 DTO
+ * 用于:前端接口入参、微服务feign远程调用
+ */
+@Data
+@Schema(description = "保费跟踪订单传输DTO")
+public class InsFeeFollowOrderDto extends PageRequest {
+
+    @Schema(description = "主键ID(修改时必传)")
+    private Long id;
+
+    @Schema(description = "年份")
+    private Integer year;
+
+    @Schema(description ="月份")
+    private Integer month;
+
+    @Schema(description = "保险公司ID")
+    private String companyId;
+
+    @Schema(description = "分支保险公司ID")
+    private String partnerCompanyId;
+
+    @Schema(description = "应收金额")
+    private BigDecimal receivablePremium;
+
+    @Schema(description = "签单时间")
+    private LocalDateTime signingTime;
+
+    @Schema(description = "已开票")
+    private BigDecimal invoiced;
+
+    @Schema(description = "未开票")
+    private BigDecimal uninvoiced;
+
+    @Schema(description = "本次开票金额")
+    private BigDecimal invoicedAmountTime;
+
+    @Schema(description = "系统编码")
+    private String systemCode;
+}

+ 23 - 0
commons/src/main/java/com/jzg/commons/entity/finance/dto/InsPlyFollowInvoiceLinkDto.java

@@ -0,0 +1,23 @@
+package com.jzg.commons.entity.finance.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 保单跟踪发票关联 DTO
+ * 用于:前端接口入参、feign远程调用
+ */
+@Data
+@Schema(description = "保单发票关联传输DTO")
+public class InsPlyFollowInvoiceLinkDto extends PageRequest {
+
+    @Schema(description = "主键ID(修改时必传)")
+    private Long id;
+
+    @Schema(description = "发票ID")
+    private Long invoiceId;
+
+    @Schema(description = "跟踪单ID")
+    private Long followId;
+}

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

@@ -0,0 +1,319 @@
+package com.jzg.commons.entity.finance.dto;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.jzg.commons.core.base.BaseModel;
+import com.jzg.commons.entity.po.InsFeeOrders;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.time.LocalDateTime;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class InsPlyIncomeDto extends BaseModel {
+    @Serial
+    private static final long serialVersionUID = 6161862008963938376L;
+
+    @ExcelIgnore
+    private String id;
+
+    @Schema(description = "订单号")
+    @ExcelProperty("订单号")
+    private String orderNo;
+
+    @Schema(description = "协议类型")
+    @ExcelProperty("协议类型")
+    private String agreementType;
+
+    @Schema(description = "机构")
+    @ExcelProperty("机构id")
+    private String deptId;
+
+    @Schema(description = "机构名称")
+    @ExcelProperty("机构名称")
+    private String deptName;
+
+    @Schema(description = "产品id")
+    @ExcelProperty("产品id")
+    private String productId;
+
+    @Schema(description = "产品名称")
+    @ExcelProperty("产品名称")
+    private String productName;
+
+    @Schema(description = "险种")
+    @ExcelProperty("险种")
+    private String riskCode;
+
+    @Schema(description = "签单时间")
+    //@TableField(exist = false)
+    @ExcelProperty("签单时间")
+    private LocalDateTime signingTime;
+
+    @Schema(description = "签单年份")
+    @TableField(exist = false)
+    private String signYear;
+
+    @Schema(description = "签单日期 yyyy-mm-dd 格式")
+    @TableField(exist = false)
+    private String signDate;
+
+    @Schema(description = "保司ID")
+    @ExcelProperty("保司ID")
+    private String companyId;
+
+    @Schema(description = "保司ID")
+    @ExcelProperty("保司ID")
+    private String companyName;
+
+    @Schema(description = "三级保司ID")
+    @ExcelProperty("三级保司ID")
+    private String partnerCompanyId;
+
+    @Schema(description = "三级保司名称")
+    @ExcelProperty("三级保司名称")
+    private String partnerCompanyName;
+
+    @Schema(description = "协议Id")
+    @ExcelProperty("协议Id")
+    private String agreementId;
+
+    @Schema(description = "协议名称")
+    @ExcelProperty("协议名称")
+    private String agreementName;
+
+    @Schema(description = "被保人")
+    @ExcelProperty("被保人")
+    private String insuredPerson;
+
+    @Schema(description = "车牌号")
+    @ExcelProperty("车牌号")
+    private String licenseNo;
+
+    @Schema(description = "车船税")
+    @ExcelProperty("车船税")
+    private String taxPremium;
+
+    @Schema(description = "交强保单号")
+    @ExcelProperty("交强保单号")
+    private String jqPolicyNo;
+
+    @Schema(description = "商业保单号")
+    @ExcelProperty("商业保单号")
+    private String syPolicyNo;
+
+    @Schema(description = "驾意保单号")
+    @ExcelProperty("驾意保单号")
+    private String jyPolicyNo;
+
+    @Schema(description = "交强保费")
+    @ExcelProperty("交强保费")
+    private String jqPremium;
+
+    @Schema(description = "商业保费")
+    @ExcelProperty("商业保费")
+    private String syPremium;
+
+    @Schema(description = "驾意保费")
+    @ExcelProperty("驾意保费")
+    private String jyPremium;
+
+    @Schema(description = "交强手续费")
+    @ExcelProperty("交强手续费")
+    private String jqSuperviseCostsPremiums;
+
+    @Schema(description = "交强手续费比例")
+    @ExcelProperty("交强手续费比例")
+    private String jqSuperviseCostsProportion;
+
+    @Schema(description = "商业手续费")
+    @ExcelProperty("商业手续费")
+    private String sySuperviseCostsPremiums;
+
+    @Schema(description = "商业手续费比例")
+    @ExcelProperty("商业手续费比例")
+    private String sySuperviseCostsProportion;
+
+    @Schema(description = "驾意手续费")
+    @ExcelProperty("驾意手续费")
+    private String jySuperviseCostsPremiums;
+
+    @Schema(description = "驾意手续费比例")
+    @ExcelProperty("驾意手续费比例")
+    private String jySuperviseCostsProportion;
+
+    @TableField(exist = false)
+    @Schema(description = "应收手续费")
+    @ExcelProperty("应收手续费")
+    private String superviseCostsPremiums;
+
+    @TableField(exist = false)
+    @Schema(description = "应收跟单费")
+    @ExcelProperty("应收跟单费")
+    private String otherCostsPremiums;
+
+    @Schema(description = "交强跟单费比例")
+    @ExcelProperty("交强跟单费比例")
+    private String jqOtherCostsProportion;
+
+    @Schema(description = "交强跟单费")
+    @ExcelProperty("交强跟单费")
+    private String jqOtherCostsPremiums;
+
+    @Schema(description = "商业跟单费比例")
+    @ExcelProperty("商业跟单费比例")
+    private String syOtherCostsProportion;
+
+    @Schema(description = "商业跟单费")
+    @ExcelProperty("商业跟单费")
+    private String syOtherCostsPremiums;
+
+    @Schema(description = "驾意跟单费比例")
+    @ExcelProperty("驾意跟单费比例")
+    private String jyOtherCostsProportion;
+
+    @Schema(description = "驾意跟单费")
+    @ExcelProperty("驾意跟单费")
+    private String jyOtherCostsPremiums;
+
+    @Schema(description = "交强应收费用")
+    @ExcelProperty("交强应收费用")
+    private String jqReceivablePremium;
+
+    @Schema(description = "商业应收费用")
+    @ExcelProperty("商业应收费用")
+    private String syReceivablePremium;
+
+    @Schema(description = "驾意应收费用")
+    @ExcelProperty("驾意应收费用")
+    private String jyReceivablePremium;
+
+    @TableField(exist = false)
+    @Schema(description = "总应收金额")
+    @ExcelProperty("总应收金额")
+    private String receivableAmount;
+
+    @Schema(description = "手续费是否已经结算")
+    @ExcelProperty("手续费是否已经结算")
+    private String superviseSettlement;
+
+    @Schema(description = "跟单费是否已经结算")
+    @ExcelProperty("跟单费是否已经结算")
+    private String otherSettlement;
+
+    @Schema(description = "驾意险手续费是否已经结算")
+    @ExcelProperty("驾意险手续费是否已经结算")
+    private String jySuperviseSettlement;
+
+    @Schema(description = "驾意跟单位是否已经结算")
+    @ExcelProperty("驾意跟单位是否已经结算")
+    private String jyOtherSettlement;
+
+    @Schema(description = "平台协议车险应收是否已经结算  0 未结算  1 结算")
+    @ExcelProperty("平台协议车险应收是否已经结算")
+    private String platformSuperviseSettlement;
+
+    @Schema(description = "平台协议非车险应收是否已经结算  0 未结算  1 结算")
+    @ExcelProperty("平台协议非车险应收是否已经结算")
+    private String platformOtherSettlement;
+
+    @Schema(description = "维护人工号")
+    @ExcelProperty("维护人工号")
+    private String leaderId;
+
+    @Schema(description = "维护人名称")
+    @ExcelProperty("维护人名称")
+    private String leaderName;
+
+    @Schema(description = "对接人")
+    @ExcelProperty("对接人")
+    private String contactPerson;
+
+    @Schema(description = "对接人手机号")
+    private String contactPersonPhone;
+
+    public String getDockingPerson(){
+        return this.contactPerson + "-" + this.contactPersonPhone;
+    }
+
+    @Schema(description = "系统code")
+    @ExcelProperty("系统code")
+    private String systemCode;
+
+    @Schema(description = "业务来源")
+    @ExcelProperty("业务来源")
+    private String businessSource;
+
+    @Schema(description = "结算时间")
+    private LocalDateTime settlementTime;
+
+    // 设置初始值为0, 未结算
+    @Schema(description = "结算状态(编码)")
+    @ExcelProperty("结算状态(编码)")
+    private String settlementStatus="0";
+
+    @TableField(exist = false)
+    @Schema(description = "结算状态(转义后)")
+    @ExcelProperty("结算状态(转义后)")
+    private String settlementStatusName;
+
+    @Schema(description = "增加类型")
+    @ExcelProperty("增加类型")
+    private String addType;
+
+    @TableField(exist = false)
+    @Schema(description = "交强起保日期")
+    @ExcelProperty("交强起保日期")
+    private String jqStartDate;
+
+    @TableField(exist = false)
+    @Schema(description = "商业起保日期")
+    @ExcelProperty("商业起保日期")
+    private String syStartDate;
+
+    @TableField(exist = false)
+    @Schema(description = "订单类型")
+    @ExcelProperty("订单类型")
+    private String orderType;
+
+    @TableField(exist = false)
+    @Schema(description = "订单类型(code)")
+    private String entryStatus;
+
+    @TableField(exist = false)
+    @Schema(description = "业务员类型 团队/渠道/电销/个代 5:团队 6:个代 7:渠道 8 :电销")
+    private String typeAttr;
+
+    @TableField(exist = false)
+    @Schema(description = "业务员类型 团队/渠道/电销/个代 5:团队 6:个代 7:渠道 8 :电销")
+    private String typeAttrName;
+
+    @TableField(exist = false)
+    @Schema(description = "实际签单用户手机号2")
+    private String realQuoteUserId;
+
+    @TableField(exist = false)
+    @Schema(description = "实际签单用户手机号")
+    private String realQuoteUserName;
+
+    @TableField(exist = false)
+    @Schema(description = "订单费用表")
+    private InsFeeOrders insFeeOrders;
+
+    @TableField(exist = false)
+    @Schema(description = "是否已经开票")
+    private String invoiceStatusName;
+
+    @TableField(exist = false)
+    @Schema(description = "订单关联的发票信息")
+    private String invoiceId;
+
+    @TableField(exist = false)
+    @Schema(description = "地区归属")
+    private String companyNameSimple;
+
+}

+ 51 - 0
commons/src/main/java/com/jzg/commons/entity/finance/po/InsFeeFollowOrder.java

@@ -0,0 +1,51 @@
+package com.jzg.commons.entity.finance.po;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 保费跟踪订单表 PO
+ */
+@Data
+@Schema(description = "保费跟踪订单表")
+@TableName("ins_fee_follow_order")
+public class InsFeeFollowOrder extends BaseModel {
+
+    @Schema(description = "主键ID")
+    private String id;
+
+    @Schema(description = "年份")
+    private Integer year;
+
+    @Schema(description = "月份")
+    private Integer month;
+
+    @Schema(description = "保险公司ID")
+    private String companyId;
+
+    @Schema(description = "分支保险公司ID")
+    private String partnerCompanyId;
+
+    @Schema(description = "应收金额")
+    private BigDecimal receivablePremium;
+
+    @Schema(description = "签单时间")
+    private LocalDateTime signingTime;
+
+    @Schema(description = "已开票金额")
+    private BigDecimal invoiced;
+
+    @Schema(description = "未开票金额")
+    private BigDecimal uninvoiced;
+
+    @Schema(description = "本次开票金额")
+    private BigDecimal invoicedAmountTime;
+
+    @Schema(description = "系统编码")
+    private String systemCode;
+
+}

+ 27 - 0
commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyFollowInvoiceLink.java

@@ -0,0 +1,27 @@
+package com.jzg.commons.entity.finance.po;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 保单跟踪发票关联表 PO
+ */
+@Data
+@Schema(description = "保单跟踪发票关联表")
+@TableName("ins_ply_follow_invoice_link")
+public class InsPlyFollowInvoiceLink extends BaseModel {
+
+    @Schema(description = "主键ID")
+    private String id;
+
+    @Schema(description = "发票ID")
+    private String invoiceId;
+
+    @Schema(description = "跟踪单ID")
+    private String followId;
+
+}

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

@@ -37,7 +37,7 @@ public class InsPlyIncomeInvoice extends BaseModel {
         return Objects.requireNonNullElse(this.overinflatedAmount, BigDecimal.ZERO);
     }
 
-    @Schema(description = "应收费用/开票金额")
+    @Schema(description = "开票金额")
     private BigDecimal receivableSupervisePremium;
 
     public BigDecimal getReceivableSupervisePremium(){

+ 5 - 0
commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncomeInvoiceLink.java

@@ -1,5 +1,6 @@
 package com.jzg.commons.entity.finance.po;
 
+import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.jzg.commons.core.base.BaseModel;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -21,4 +22,8 @@ public class InsPlyIncomeInvoiceLink{
     @Schema(description = "开票类型")
     private String invoiceType;
 
+    @Schema(description = "是否删除")
+    @TableLogic
+    private Integer isDelete;
+
 }

+ 39 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoiceAndSettlementVo.java

@@ -0,0 +1,39 @@
+package com.jzg.commons.entity.finance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+
+/**
+ * 结算Vo
+ */
+@Data
+@Schema(description = "开票并结算Vo")
+public class FollowInvoiceAndSettlementVo {
+
+    /**
+     * 开票的相关信息
+     */
+    private FollowInvoiceVo invoiceVO;
+
+    @Schema(description = "开票id")
+    private String invoicingId;
+
+    @Schema(description = "实收金额")
+    private BigDecimal actualReceivedAmount;
+
+    @Schema(description = "收款日期")
+    private String receivePaymentDate;
+
+    @Schema(description = "回款差额")
+    private BigDecimal paymentDifference;
+
+    @Schema(description = "差额原因")
+    private String paymentReason;
+
+    @Schema(description = "附加id")
+    private List<String> attachmentIds;
+}

+ 42 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoicePageListVo.java

@@ -0,0 +1,42 @@
+package com.jzg.commons.entity.finance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 保费跟踪订单表 VO
+ */
+@Data
+@Schema(description = "保费跟踪订单返回视图")
+public class FollowInvoicePageListVo implements Serializable {
+
+    // 逻辑判断符: "and" 或 "or"
+    private String logicJudge;
+
+    // 搜索条件列表
+    private List<SearchVO> searchList;
+
+    @Data
+    public static class SearchVO {
+        // 定义常量
+        public static final String companyId = "companyId";
+        public static final String signDate = "signDate";
+        public static final String ptlAgreement = "ptlAgreement";
+        public static final String orderType = "orderType";
+        public static final String signYear = "signYear";
+        public static final String licenseNo = "licenseNo";
+        public static final String jqPolicyNo = "jqPolicyNo";
+        public static final String syPolicyNo = "syPolicyNo";
+        public static final String contactPerson = "contactPersonPhone";
+
+        private String name;   // 条件名
+        private String type;   // 操作符: 等于, 包含, 大于等于 等
+        private String search; // 条件值
+    }
+
+}

+ 43 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowInvoiceVo.java

@@ -0,0 +1,43 @@
+package com.jzg.commons.entity.finance.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class FollowInvoiceVo implements Serializable {
+
+    private List<InsFeeFollowOrderVo> details;
+
+    private String companyId;
+
+    @Schema(description = "开票号/发票号")
+    private String invoiceNo;
+
+    @Schema(description = "开票类型")
+    private String invoiceType;
+
+    @Schema(description = "开票方")
+    @ExcelProperty(value = "开票方")
+    private String invoiceParty;
+
+    @Schema(description = "虚增金额")
+    private BigDecimal overinflatedAmount;
+
+    @Schema(description = "差额原因")
+    private String paymentReason;
+
+    @Schema(description = "应收费用/开票金额")
+    private BigDecimal receivableSupervisePremium;
+
+    @Schema(description = "税点")
+    private String taxPoint;
+
+    @Schema(description = "选择单条还是多条:0-单条,1-多条")
+    private String selectFlag;
+
+}

+ 55 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/InsFeeFollowOrderVo.java

@@ -0,0 +1,55 @@
+package com.jzg.commons.entity.finance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 保费跟踪订单表 VO
+ */
+@Data
+@Schema(description = "保费跟踪订单返回视图")
+public class InsFeeFollowOrderVo implements Serializable {
+
+    @Schema(description = "主键ID")
+    private Long id;
+
+    @Schema(description = "年份")
+    private Integer year;
+
+    @Schema(description = "月份")
+    private Integer month;
+
+    @Schema(description = "保险公司ID")
+    private String companyId;
+
+    @Schema(description = "保险公司名称")
+    private String companyName;
+
+    @Schema(description = "三级保险公司ID")
+    private String partnerCompanyId;
+
+    @Schema(description = "分支保险公司名称")
+    private String partnerCompanyName;
+
+    @Schema(description = "应收金额")
+    private BigDecimal receivablePremium;
+
+    @Schema(description = "签单时间")
+    private LocalDateTime signingTime;
+
+    @Schema(description = "已开票金额")
+    private BigDecimal invoiced;
+
+    @Schema(description = "未开票金额")
+    private BigDecimal uninvoiced;
+
+    @Schema(description = "本次开票金额")
+    private BigDecimal invoicedAmountTime;
+
+    @Schema(description = "创建时间")
+    private LocalDateTime createTime;
+}

+ 27 - 0
commons/src/main/java/com/jzg/commons/entity/finance/vo/InsPlyFollowInvoiceLinkVo.java

@@ -0,0 +1,27 @@
+package com.jzg.commons.entity.finance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 保单跟踪发票关联表 VO
+ */
+@Data
+@Schema(description = "保单跟踪发票关联返回视图")
+public class InsPlyFollowInvoiceLinkVo implements Serializable {
+
+    @Schema(description = "主键ID")
+    private Long id;
+
+    @Schema(description = "发票ID")
+    private Long invoiceId;
+
+    @Schema(description = "跟踪单ID")
+    private Long followId;
+
+    @Schema(description = "创建时间")
+    private LocalDateTime createTime;
+}

+ 8 - 3
commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordResult.java

@@ -38,7 +38,7 @@ public class InvoiceRecordResult extends PageRequest {
     /**
      * 保险公司名称及父级的名称,例如
      */
-    private String companyALlName;
+    private String companyAllName;
 
     /**
      * 开票方
@@ -71,15 +71,20 @@ public class InvoiceRecordResult extends PageRequest {
      */
     private String invoiceRiskTypeName;
     /**
-     * 应收费用
+     * 应收费用,现在当做开票金额使用
      */
     private BigDecimal receivableSupervisePremium;
 
     /**
-     * 开票金额
+     * 实收金额
      */
     private String actualReceivedAmount;
 
+    /**
+     * 开票金额
+     */
+    private String receivableAmount;
+
     /**
      * 税点
      */

+ 1 - 0
platform/src/main/resources/application.yml

@@ -69,6 +69,7 @@ tenant:
   ignoreFunction:
     - /userInfo/getUser
     - /menu/getSystemMenu
+    - /esmInsCompany/getChildCompanyId
 
 data-scope:
   tables:

+ 13 - 19
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/component/GuoRenCrawlerRequestComponent.java

@@ -178,9 +178,7 @@ public class GuoRenCrawlerRequestComponent {
     public GuoRenCrawlerGetLoginComInfoResponse getLoginComInfo(String username, String comCode, HttpHeaders httpHeaders) {
         String url = guoRenCrawlerProperties.getBaseUrl() + RequestUrl.GET_LOGIN_COM_INFO.getUri();
         GuoRenCrawlerGetLoginComInfoRequest guoRenCrawlerGetLoginComInfoRequest = new GuoRenCrawlerGetLoginComInfoRequest(username);
-        HttpRequest request = HttpRequest.post(url)
-                .header(httpHeaders)
-                .body(JSON.toJSONString(guoRenCrawlerGetLoginComInfoRequest));
+        HttpRequest request = HttpRequest.post(url).header(httpHeaders).body(JSON.toJSONString(guoRenCrawlerGetLoginComInfoRequest));
         HttpResponse httpResponse = request.execute();
         String body = httpResponse.body();
 
@@ -189,10 +187,11 @@ public class GuoRenCrawlerRequestComponent {
         if (body.trim().startsWith("[")) {
             getLoginComInfoResponseList = JSON.parseArray(body, GuoRenCrawlerGetLoginComInfoResponse.class);
         } else {
-            GuoRenCrawlerBaseResponse<List<GuoRenCrawlerGetLoginComInfoResponse>> response = JSON.parseObject(body, new TypeReference<>() {});
+            GuoRenCrawlerBaseResponse<List<GuoRenCrawlerGetLoginComInfoResponse>> response = JSON.parseObject(body, new TypeReference<>() {
+            });
             // 检查登录失效,返回特殊code码
             if (response != null && response.getResultCode() == 40301) {
-                throw new  TokenExpireException();
+                throw new TokenExpireException();
             }
             getLoginComInfoResponseList = response.getData();
         }
@@ -295,6 +294,9 @@ public class GuoRenCrawlerRequestComponent {
         GuoRenCrawlerGetCarPriceRequest getCarPriceRequest = new GuoRenCrawlerGetCarPriceRequest(queryCarModelData, prpTmainDTO, quoteVo, ownersAddr, relationShip);
         GuoRenCrawlerBaseResponse<List<GuoRenCrawlerGetCarPriceData>> request = request(RequestUrl.GET_CAR_PRICE, getCarPriceRequest, new ParameterizedTypeReference<>() {
         }, httpHeaders);
+        if (request.getResultCode() == 1) {
+            throw new SystemException(request.getResultMsg());
+        }
         return new GuoRenPrpTitemCarDTO(getCarPriceRequest, request.getData().get(0));
     }
 
@@ -306,7 +308,7 @@ public class GuoRenCrawlerRequestComponent {
      * @return 保费计算响应
      */
     public GuoRenCrawlerBaseResponse<GuoRenCrawlerCalculationPremiumData> calculationPremium(GuoRenCrawlerCalculationPremiumRequest crawlerCalculationPremiumRequest, HttpHeaders httpHeaders) {
-        GuoRenCrawlerBaseResponse<GuoRenCrawlerCalculationPremiumData>  request = request(RequestUrl.CALCULATION_PREMIUM, crawlerCalculationPremiumRequest, new ParameterizedTypeReference<>() {
+        GuoRenCrawlerBaseResponse<GuoRenCrawlerCalculationPremiumData> request = request(RequestUrl.CALCULATION_PREMIUM, crawlerCalculationPremiumRequest, new ParameterizedTypeReference<>() {
         }, httpHeaders);
         if (request.getResultCode() == 1 && !request.getResultMsg().contains("重复投保")) {
             throw new SystemException(request.getResultMsg());
@@ -323,8 +325,8 @@ public class GuoRenCrawlerRequestComponent {
      * @param httpHeaders               请求头
      * @return 投保单号
      */
-    public GuoRenCrawlerProposalNoSaveData proposalNoSave(GuoRenCrawlerCalculationPremiumRequest calculationPremiumRequest, GuoRenCrawlerCalculationPremiumData calculationPremium, HttpHeaders httpHeaders) {
-        GuoRenCrawlerProposalNoSaveRequest guoRenCrawlerProposalNoSaveRequest = new GuoRenCrawlerProposalNoSaveRequest(calculationPremium, calculationPremiumRequest);
+    public GuoRenCrawlerProposalNoSaveData proposalNoSave(QuoteVo quoteVo, GuoRenCrawlerCalculationPremiumRequest calculationPremiumRequest, GuoRenCrawlerCalculationPremiumData calculationPremium, HttpHeaders httpHeaders) {
+        GuoRenCrawlerProposalNoSaveRequest guoRenCrawlerProposalNoSaveRequest = new GuoRenCrawlerProposalNoSaveRequest(quoteVo, calculationPremium, calculationPremiumRequest);
         GuoRenCrawlerBaseResponse<GuoRenCrawlerProposalNoSaveData> request = request(RequestUrl.PROPOSAL_NO_SAVE, guoRenCrawlerProposalNoSaveRequest, new ParameterizedTypeReference<>() {
         }, httpHeaders);
         if (request.getResultCode() != 0) {
@@ -393,14 +395,7 @@ public class GuoRenCrawlerRequestComponent {
                     // 根据影像类型确定fileGroup
                     String fileGroup = getFileGroup(insuranceImageVo);
 
-                    Part[] parts = {
-                            filePart,
-                            new StringPart("businessType", "T"),
-                            new StringPart("businessNo", businessNo),
-                            new StringPart("operatorCode", operatorCode),
-                            new StringPart("comCode", comCode),
-                            new StringPart("fileGroup", fileGroup)
-                    };
+                    Part[] parts = {filePart, new StringPart("businessType", "T"), new StringPart("businessNo", businessNo), new StringPart("operatorCode", operatorCode), new StringPart("comCode", comCode), new StringPart("fileGroup", fileGroup)};
 
                     // 发送请求
                     String result = HttpUtil.sendPostFromFile(parts, url);
@@ -435,9 +430,8 @@ public class GuoRenCrawlerRequestComponent {
      */
     public GuoRenCrawlerSubmitUnderwriteData submitUnderwrite(String proposalNoCI, String proposalNoBI, String userCode, HttpHeaders httpHeaders) {
         GuoRenCrawlerSubmitUnderwriteRequest guoRenCrawlerSubmitUnderwriteRequest = new GuoRenCrawlerSubmitUnderwriteRequest(proposalNoCI, proposalNoBI, userCode);
-        GuoRenCrawlerBaseResponse<List<GuoRenCrawlerSubmitUnderwriteData>> response = request(RequestUrl.SUBMIT_UNDERWRITE, guoRenCrawlerSubmitUnderwriteRequest,
-                new ParameterizedTypeReference<>() {
-                }, httpHeaders);
+        GuoRenCrawlerBaseResponse<List<GuoRenCrawlerSubmitUnderwriteData>> response = request(RequestUrl.SUBMIT_UNDERWRITE, guoRenCrawlerSubmitUnderwriteRequest, new ParameterizedTypeReference<>() {
+        }, httpHeaders);
         return response.getData().get(0);
     }
 

+ 7 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/dto/CiInsureDemandDTO.java

@@ -1,6 +1,8 @@
 package com.jzg.quotation.guoren.crawler.entity.dto;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.commons.entity.quote.vo.CarInfoVo;
+import com.jzg.commons.entity.quote.vo.QuoteVo;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
@@ -417,9 +419,13 @@ public class CiInsureDemandDTO  implements Serializable {
     @JsonProperty("carOwner")
     private String carOwner;
 
-    public CiInsureDemandDTO(String demandNo, String checkCode) {
+    public CiInsureDemandDTO(String demandNo, String checkCode, QuoteVo quoteVo) {
         this.demandNo = demandNo;
         this.checkCode = checkCode;
+
+        CarInfoVo carInfoVo = quoteVo.getCarInfoVo();
+        this.seatCount = carInfoVo.getSeatCount();
+        this.tonCount = carInfoVo.getLimitLoad();
     }
 
 }

+ 1 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/dto/GuoRenBiDTO.java

@@ -126,7 +126,7 @@ public class GuoRenBiDTO {
             this.prpTmainRate = new GuoRenPrpTmainRateDTO();
         }
         this.prpTitemCar = prpTitemCar;
-        this.ciInsureDemand = new CiInsureDemandDTO("", "");
+        this.ciInsureDemand = new CiInsureDemandDTO("", "",quoteVo);
         this.ciInsureDemandPay = new ArrayList<>();
         this.ciInsureDemandWarningClaim = new ArrayList<>();
         this.prpTenGearAllocationFeeList = new ArrayList<>();

+ 1 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/dto/GuoRenCiDTO.java

@@ -136,7 +136,7 @@ public class GuoRenCiDTO {
         this.prptengageList = new ArrayList<>();
         this.prpDclause = new ArrayList<>();
         this.prpTitemCarExt = new PrpTitemCarExtDTO();
-        this.ciInsureDemand = new CiInsureDemandDTO("", "");
+        this.ciInsureDemand = new CiInsureDemandDTO("", "",quoteVo);
         this.ciInsureDemandPay = new ArrayList<>();
         this.ciInsureDemandLoss = new ArrayList<>();
         this.ciInsureDemandWarningClaim = new ArrayList<>();

+ 6 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/entity/request/GuoRenCrawlerProposalNoSaveRequest.java

@@ -1,6 +1,7 @@
 package com.jzg.quotation.guoren.crawler.entity.request;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.quotation.guoren.crawler.entity.dto.GuoRenBcDTO;
 import com.jzg.quotation.guoren.crawler.entity.response.GuoRenCrawlerCalculationPremiumData;
 import lombok.Data;
@@ -28,12 +29,16 @@ public class GuoRenCrawlerProposalNoSaveRequest implements Serializable {
     @JsonProperty("ci")
     private GuoRenCrawlerCalculationPremiumData.CiDTO ci;
 
-    public GuoRenCrawlerProposalNoSaveRequest(GuoRenCrawlerCalculationPremiumData guoRenCrawlerCalculationPremiumData, GuoRenCrawlerCalculationPremiumRequest calculationPremiumRequest) {
+    public GuoRenCrawlerProposalNoSaveRequest(QuoteVo quoteVo, GuoRenCrawlerCalculationPremiumData guoRenCrawlerCalculationPremiumData, GuoRenCrawlerCalculationPremiumRequest calculationPremiumRequest) {
         this.bc = calculationPremiumRequest.getBc();
         this.bc.setPrpTmain(guoRenCrawlerCalculationPremiumData.getBc().getPrpTmain());
         this.bc.getPrpTmain().setCaptcha("");
         this.bc.getPrpTmain().setEProposalFlag("1");
         this.basePartVo = calculationPremiumRequest.getBasePartVo();
+        guoRenCrawlerCalculationPremiumData.getCi().getCiInsureDemand().setTonCount(quoteVo.getCarInfoVo().getTonCount());
+        guoRenCrawlerCalculationPremiumData.getCi().getCiInsureDemand().setSeatCount(quoteVo.getCarInfoVo().getSeatCount());
+        guoRenCrawlerCalculationPremiumData.getBi().getCiInsureDemand().setTonCount(quoteVo.getCarInfoVo().getTonCount());
+        guoRenCrawlerCalculationPremiumData.getBi().getCiInsureDemand().setSeatCount(quoteVo.getCarInfoVo().getSeatCount());
         this.bi = guoRenCrawlerCalculationPremiumData.getBi();
         this.ci = guoRenCrawlerCalculationPremiumData.getCi();
     }

+ 1 - 1
tenant/insurance/quotation-guoren/src/main/java/com/jzg/quotation/guoren/crawler/service/impl/GuoRenCrawlerRequestImpl.java

@@ -132,7 +132,7 @@ public class GuoRenCrawlerRequestImpl implements GuoRenCrawlerRequest {
         // 投保验证码处理
         GuoRenCrawlerCalculationPremiumData calculationPremiumData = guoRenCrawlerQuoteProcessService.insuranceVerificationCodeProcessing(crawlerCalculationPremiumRequest, calculationPremium.getData(), headers);
         // 保存投保单号
-        GuoRenCrawlerProposalNoSaveData proposalNoSave = guoRenCrawlerRequestComponent.proposalNoSave(crawlerCalculationPremiumRequest, calculationPremiumData, headers);
+        GuoRenCrawlerProposalNoSaveData proposalNoSave = guoRenCrawlerRequestComponent.proposalNoSave(quoteVo, crawlerCalculationPremiumRequest, calculationPremiumData, headers);
         // 保存数据
         guoRenCrawlerOrderService.saveOrderInfo(quoteVo, proposalNoSave);
         return GuoRenCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo, calculationPremiumData, proposalNoSave);

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

@@ -1,6 +1,7 @@
 package com.jzg.quotation.hengbang.crawler.entity.request;
 
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.excel.util.StringUtils;
 import com.jzg.commons.entity.quote.vo.AccidentalDrivingVo;
 import com.jzg.commons.entity.quote.vo.KindInfoVo;
 import com.jzg.commons.entity.quote.vo.QuoteVo;
@@ -139,8 +140,10 @@ public class HbCrawlerCalculationRequest extends HbBaseRequest {
         dto.setNonriskcode(vo.getProductCode().split("_")[1]);
         dto.setProgramcode(vo.getProductCode());
         dto.setProgramname(vo.getProductName());
-        dto.setBegintime(DateUtil.toUtcDateTime(biRiskInfoVo.getStartDate()));
-        dto.setEndtime(DateUtil.toUtcDateTime(biRiskInfoVo.getEndDate()));
+        if (biRiskInfoVo != null && StringUtils.isNotBlank(biRiskInfoVo.getStartDate()) && StringUtils.isNotBlank(biRiskInfoVo.getEndDate())) {
+            dto.setBegintime(DateUtil.toUtcDateTime(biRiskInfoVo.getStartDate()));
+            dto.setEndtime(DateUtil.toUtcDateTime(biRiskInfoVo.getEndDate()));
+        }
         dto.setCompanycode("0107");
         dto.setRelationcarowner("a");
         dto.setSuminsured("525000");

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

@@ -151,6 +151,7 @@ public class HengBangCrawlerRequestImpl implements HengBangCrawlerRequest {
         HbCrawlerProposalResponse proposalResponse = null;
         // 脱保情况 重新赋值核心建议起保时间 二次报价
         if (errorMsg.contains("脱保")) {
+            calculationRequest.setOutofwarrantytype("N");
             resJson = hbCrawlerRequestComponent.getCalculationResult(calculationRequest, headers);
             errorMsg = JSONObject.parseObject(resJson).getString("message");
             status = JSONObject.parseObject(resJson).getString("status");

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

@@ -400,7 +400,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
 
         HtCrawlerQuoteResponse.DataDTO quoteResponseData = null;
 
-        maxRetries = 5;
+        maxRetries = 3;
         retryCount = 0;
         success = false;
 
@@ -480,6 +480,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
                 if(decryptData.contains("errrorFlag") && decryptData.contains("carChange")) {//请修改新车购置价
                     //重新获取车型
                     //throw new RuntimeException("请修改新车购置价/重新获取车型");
+                    retryCount = maxRetries + 1;
                     HtCrawlerQuoteResponse.DataErrDTO dataErr = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataErrDTO.class);
                     throw new RuntimeException("报价失败:"+dataErr.getErroeInfo().substring(dataErr.getErroeInfo().indexOf("中国")));
                 }
@@ -487,6 +488,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
                 if(decryptData.contains("erroeInfo") && decryptData.contains("投保查询校验信息不存在或已经校验成功")) {
                     //投保查询校验信息不存在或已经校验成功
                     //throw new RuntimeException("投保查询校验信息不存在或已经校验成功");
+                    retryCount = maxRetries + 1;
                     HtCrawlerQuoteResponse.DataErrDTO dataErr = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataErrDTO.class);
                     throw new RuntimeException("报价失败:"+dataErr.getErroeInfo().substring(dataErr.getErroeInfo().indexOf("中国")));
                 }
@@ -494,6 +496,7 @@ public class HuaTaiCrawlerRequestImpl implements HuaTaiCrawlerRequest {
                 if(decryptData.contains("erroeInfo") && decryptData.contains("起保日期必须在当前日期的30天范围内")) {
                     //投保查询校验信息不存在或已经校验成功
                     //throw new RuntimeException("起保日期必须在当前日期的30天范围内");
+                    retryCount = maxRetries + 1;
                     HtCrawlerQuoteResponse.DataErrDTO dataErr = JSONObject.parseObject(decryptData, HtCrawlerQuoteResponse.DataErrDTO.class);
                     throw new RuntimeException("报价失败:"+dataErr.getErroeInfo().substring(dataErr.getErroeInfo().indexOf("中国")));
                 }

+ 2 - 2
tenant/insurance/quotation-huatai/src/main/java/com/jzg/quotation/huatai/crawler/util/UploadUtil.java

@@ -119,7 +119,7 @@ public class UploadUtil {
         if (!tempDir.exists()) {
             tempDir.mkdirs();
         }
-        File originalFile = File.createTempFile(imagesPath + "huatai/" + "upload_temp_" + imgName, ".jpg", tempDir.getAbsoluteFile());
+        File originalFile = File.createTempFile(imagesPath + "huatai/" + "upload_temp_" + imgName, ".jpg", tempDir);
         try (FileOutputStream fos = new FileOutputStream(originalFile)) {
             fos.write(imageBytes);
         }
@@ -165,7 +165,7 @@ public class UploadUtil {
             img = resizedImg;
         }
 
-        File newFile = new File(imagesPath + "huatai/" + imgName + "new.jpg");
+        File newFile = File.createTempFile(imagesPath + "huatai/" + imgName + "new", ".jpg", tempDir);
         ImageIO.write(img, "jpg", newFile);
 
         int newWidth = img.getWidth();

+ 6 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java

@@ -38,11 +38,14 @@ public class InsFeeAuditController {
 
     /**
      * 订单列表分页
+     *
+     * 支持查询租户下的所有数据,或者租户下,指定业务员领取后的数据。
      * @return HttpResult<Page<FeeAuditVo>>
      */
     @PostMapping("/auditList")
     @Operation(summary = "订单审核列表分页")
     public HttpResult<Page<FeeAuditVo>> auditList(@RequestBody FeeAuditParam param){
+        log.info("订单审核列表分页=[{}]", JSONUtil.toJsonStr(param));
         param.setSystemCode(baseController.getUserSystemCode());
         Page<FeeAuditVo> result = insFeeAuditService.queryPage(param);
         return HttpResult.ok(result);
@@ -77,7 +80,9 @@ public class InsFeeAuditController {
     @GetMapping("/isLock")
     @Operation(summary = "判断领取按钮是否锁定")
     public HttpResult<Boolean> isLock(String orderNo){
-        return HttpResult.ok(insFeeAuditService.isLock(orderNo));
+        Boolean lock = insFeeAuditService.isLock(orderNo);
+        String msg = lock ? "订单已被领取":"";
+        return HttpResult.ok(msg, lock);
     }
 
     /**

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

@@ -236,11 +236,11 @@ public class UnifyOrderManager {
     @PostMapping("/quote")
     @QuoteVerification
     public HttpResult<QuoteResultsVo> quote(@RequestBody QuoteVo quoteVo) throws Exception {
-        log.info("进行车险报价:quoteVo=[{}]", JSONUtil.toJsonStr(quoteVo));
+        String systemCode = getSystemCode();
+        log.info("进行车险报价:systemCode=[{}],quoteVo=[{}]",systemCode, JSONUtil.toJsonStr(quoteVo));
         HttpResult<EsmInsCompany> esmInsCompanyHttpResult = platformClient.findById(quoteVo.getOrder().getInsuranceCompanyCode());
         log.info("车险报价:esmInsCompanyHttpResult=[{}]", JSONUtil.toJsonStr(esmInsCompanyHttpResult));
         AssertionUtils.isFail(esmInsCompanyHttpResult.getCode() != 200, esmInsCompanyHttpResult.getMsg());
-        String systemCode = getSystemCode();
         String companyName = CompanyConstants.getCompanyNameByCode(esmInsCompanyHttpResult.getData().getCompanyCode());
 
         log.info("查询保司配置的协议:systemCode=[{}],companyId=[{}]", systemCode, esmInsCompanyHttpResult.getData().getId());
@@ -267,7 +267,7 @@ public class UnifyOrderManager {
                 .getApiType(), sysQuoteConfigService, sysQuoteRedisService, platformClient, baseController);
 
         // 生成主订单及子订单  返回子订单id
-        String ordersNo = insOrdersService.generateOrders(quoteVo, companyName);
+        String ordersNo = insOrdersService.generateOrders(quoteVo, companyName,systemCode);
 
         // 添加车辆没有的参数: 车辆明细、
         QuoteInfoParameterFilling.setParameterSettings(quoteVo, esmInsCompanyHttpResult.getData().getCompanyCode());

+ 3 - 2
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/InsOrdersService.java

@@ -57,11 +57,12 @@ public interface InsOrdersService extends IService<InsOrders> {
     /**
      * 根据报价参数生成订单  返回订单号
      *
-     * @param quoteVo 报价信息
+     * @param quoteVo     报价信息
      * @param companyName 保险公司名称
+     * @param systemCode 租户代码
      * @return String
      */
-    String generateOrders(QuoteVo quoteVo, String companyName);
+    String generateOrders(QuoteVo quoteVo, String companyName, String systemCode);
 
 
     /**

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

@@ -387,7 +387,8 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
 
     @Override
     public void verifyOrder(VerifyOrderParam param) {
-        log.info("审核订单. param=[{}]", JSONUtil.toJsonStr(param));
+        String systemCode = baseController.getSystemCode();
+        log.info("审核订单.systemCode=[{}], param=[{}]",systemCode, JSONUtil.toJsonStr(param));
         InsFeeAudit audit = this.getById(param.getOrderNo());
         if(audit == null){
             throw new ServiceException("要审核的订单不存在");
@@ -537,6 +538,7 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
                 userAccount.setUserId(sysUserResult.getData().getId());
                 userAccount.setSumAmount(feeOrders.getTotalReceivablePremium());
                 userAccount.setSumAmountUnpaid(feeOrders.getTotalReceivablePremium());
+                userAccount.setSystemCode(systemCode);
             }else{
                 userAccount.setSumAmount(feeOrders.getTotalReceivablePremium().add(userAccount.getSumAmount()));
                 userAccount.setSumAmountUnpaid(feeOrders.getTotalReceivablePremium().add(userAccount.getSumAmount()));

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

@@ -978,11 +978,11 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
      */
     @Override
     @Transactional
-    public String generateOrders(QuoteVo quoteVo, String companyName) {
+    public String generateOrders(QuoteVo quoteVo, String companyName, String systemCode) {
         // 生成订单的条件
         // 1个保险公司只有一个主订单   不区分险种
         // 唯一性的判定标准:保险公司编号+ 车牌号 + 车架号
-        log.info("生成一个主订单和多个子订单:quoteVo=[{}],companyName=[{}]", JSONUtil.toJsonStr(quoteVo), companyName);
+        log.info("生成一个主订单和多个子订单:systemCode=[{}], quoteVo=[{}],companyName=[{}]",systemCode, JSONUtil.toJsonStr(quoteVo), companyName);
         InsOrders mainOrders = this.getMainOrders(
                 quoteVo.getOrder().getInsuranceCompanyCode(),
                 quoteVo.getCarInfoVo().getLicenseNo(),
@@ -995,13 +995,13 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
         // 如果订单号为0 则生成主订单
         if (!isExistsMainOrder) {
             // 生成主订单
-            mainOrderNo = this.saveBaseOrderorSubOrder(quoteVo, companyName, "0");
+            mainOrderNo = this.saveBaseOrderorSubOrder(quoteVo, companyName, "0",systemCode);
         } else {
             // 更新主订单
             mainOrderNo = this.updateMainOrders(quoteVo, mainOrders.getId(), companyName);
         }
         // 生成子订单
-        return this.saveBaseOrderorSubOrder(quoteVo, companyName, mainOrderNo);
+        return this.saveBaseOrderorSubOrder(quoteVo, companyName, mainOrderNo,systemCode );
     }
 
 
@@ -1011,11 +1011,13 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
      * @param quoteVo
      * @param companyName
      * @param mainOrderNo 主订单号
+     * @param systemCode
      * @return
      */
-    private String saveBaseOrderorSubOrder(QuoteVo quoteVo, String companyName, String mainOrderNo) {
+    private String saveBaseOrderorSubOrder(QuoteVo quoteVo, String companyName, String mainOrderNo, String systemCode) {
         // 保存主订单信息
         InsOrders insOrders = new InsOrders();
+        insOrders.setSystemCode(systemCode);
         // 生成主订单编号
         if ("0".equals(mainOrderNo)) {
             insOrders.setParentId("0");

+ 9 - 22
tenant/insurance/quotation-summary/src/main/resources/mapper/InsFeeAuditMapper.xml

@@ -80,17 +80,12 @@
         LEFT JOIN ins_orders_external_policy ioep on ioep.order_no = io.id AND ioep.is_delete=0
         <where>
             and ifa.is_delete=0 and ifa.system_code = #{param.systemCode}
-            <choose>
-                <when test="param.receiveUser != null and param.receiveUser != ''">
-                    and ifa.receive_user = #{param.receiveUser}
-                </when>
-                <when test="param.isProblem != null and param.isProblem == 1">
-                    and ifa.receive_user is NOT NULL
-                </when>
-                <otherwise>
-                    and ifa.receive_user is NULL
-                </otherwise>
-            </choose>
+            <if test="param.receiveUser != null and param.receiveUser != ''">
+                and ifa.receive_user = #{param.receiveUser}
+            </if>
+            <if test="param.allTodoReceive != null and param.allTodoReceive == true">
+                and ifa.receive_user is null
+            </if>
             <if test="param.auditType != null">
                 and ifa.audit_type = #{param.auditType}
             </if>
@@ -215,17 +210,9 @@
         LEFT JOIN ins_orders_external_policy ioep on ioep.order_no = io.id AND ioep.is_delete=0
         <where>
             and ifa.is_delete=0
-            <choose>
-                <when test="param.receiveUser != null and param.receiveUser != ''">
-                    and ifa.receive_user = #{param.receiveUser}
-                </when>
-                <when test="param.isProblem != null and param.isProblem == 1">
-                    and ifa.receive_user is NOT NULL
-                </when>
-                <otherwise>
-                    and ifa.receive_user is NULL
-                </otherwise>
-            </choose>
+            <if test="param.receiveUser != null and param.receiveUser != ''">
+                and ifa.receive_user = #{param.receiveUser}
+            </if>
             <if test="param.auditType != null">
                 and ifa.audit_type = #{param.auditType}
             </if>

+ 64 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java

@@ -224,6 +224,70 @@ public class ReceivableController {
         return HttpResult.error("开票失败");
     }
 
+    @GetMapping("/calculateTotalSum")
+    @Operation(summary = "计算相加的总数")
+    public HttpResult<String> calculateTotal(String sumList){
+        if (StrUtil.isBlank(sumList)){
+            return HttpResult.ok("参数不能为空", "0");
+        }
+        BigDecimal reduce = Arrays.asList(sumList.split(",")).stream().map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
+        return HttpResult.ok("计算成功", reduce.toString());
+    }
+
+    /**
+     * 跟单费开票的列表
+     * @param followInvoicePageListVo
+     * @return
+     */
+    @PostMapping("/followInvoicePageList")
+    @Operation(summary = "跟单费开票的列表")
+    public HttpResult<List<InsFeeFollowOrderVo>> followInvoicePageList(@RequestBody FollowInvoicePageListVo followInvoicePageListVo){
+        // 开票类型  1、手续费  2、跟单费  3、驾意险手续费 4、驾意险跟单费 5、平台应收-车险 6、平台应收-非车险
+        List<InsFeeFollowOrderVo> page = receivableService.followInvoicePageList(followInvoicePageListVo);
+        return HttpResult.ok(page);
+    }
+
+    /**
+     * 跟单费开票
+     * @param followInvoiceVo
+     * @return
+     */
+    @PostMapping("/followInvoicing")
+    @Operation(summary = "跟单费开票")
+    public HttpResult<InvoiceingResult> followInvoicing(@RequestBody FollowInvoiceVo followInvoiceVo){
+        // 开票类型  1、手续费  2、跟单费  3、驾意险手续费 4、驾意险跟单费 5、平台应收-车险 6、平台应收-非车险
+        InvoiceingResult invoiceingResult = receivableService.followInvoicing(followInvoiceVo);
+        if (Objects.nonNull(invoiceingResult)){
+            return HttpResult.ok("开票成功,发票编号是" + invoiceingResult.getInvoiceId() ,invoiceingResult);
+        }
+        return HttpResult.error("开票失败");
+    }
+
+
+    @PostMapping("/followSettlement")
+    @Operation(summary = "跟单费结算")
+    public HttpResult<String> followSettlement(@RequestBody SettlementVo settlementVo){
+        try{
+            boolean settlement = receivableService.followSettlement(settlementVo);
+            return settlement ? HttpResult.ok("结算成功") : HttpResult.error("结算失败");
+        }catch (Exception e){
+            log.error("结算失败",e);
+            return HttpResult.error(e.getMessage());
+        }
+    }
+
+    /**
+     * 跟单费开票并结算
+     *
+     * @author jk
+     * @date 2026/5/26 11:57
+     */
+    @PostMapping("/followInvoiceAndSettlement")
+    @Operation(summary = "跟单费开票并结算")
+    public HttpResult<String> followInvoiceAndSettlement(@RequestBody FollowInvoiceAndSettlementVo settlementVo){
+        return receivableService.followInvoiceAndSettlement(settlementVo);
+    }
+
     @PostMapping("otherInvoicing")
     @Operation(summary = "跟单费开票")
     public HttpResult<InvoiceingResult> otherInvoicing(@RequestBody InsPlyIncomeInvoiceVO invoicingVo){

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

@@ -0,0 +1,14 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jzg.commons.entity.finance.po.InsFeeFollowOrder;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 保费跟踪订单表 Mapper
+ */
+@Mapper
+public interface InsFeeFollowOrderMapper extends BaseMapper<InsFeeFollowOrder> {
+}

+ 13 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/InsPlyFollowInvoiceLinkMapper.java

@@ -0,0 +1,13 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jzg.commons.entity.finance.po.InsPlyFollowInvoiceLink;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 保单跟踪发票关联表 Mapper
+ */
+@Mapper
+public interface InsPlyFollowInvoiceLinkMapper extends BaseMapper<InsPlyFollowInvoiceLink> {
+
+}

+ 0 - 8
tenant/organization/src/main/java/com/jzg/organization/mapper/InsPlyIncomeInvoiceLinkMapper.java

@@ -9,12 +9,4 @@ import org.apache.ibatis.annotations.Param;
 @Mapper
 public interface InsPlyIncomeInvoiceLinkMapper extends BaseMapper<InsPlyIncomeInvoiceLink> {
 
-    /**
-     * 删除发票和订单的关联关系
-     *
-     * @author lipf
-     * @date 2026/5/29 14:29
-     */
-    @Delete("delete from ins_ply_income_invoice_link ipiil where ipiil.invoice_id = #{invoiceId}")
-    void deleteByInvoiceId(@Param("invoiceId") String invoiceId);
 }

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

@@ -6,6 +6,7 @@ import com.jzg.commons.entity.finance.dto.*;
 import com.jzg.commons.entity.finance.po.InsPlyIncome;
 import com.jzg.commons.entity.finance.po.InsPlyIncomeInvoiceLink;
 import com.jzg.commons.entity.finance.po.InsPlyIncomeInvoiceSettlement;
+import com.jzg.commons.entity.finance.po.InsPlyIncomeVO;
 import com.jzg.commons.entity.finance.vo.InvoiceRecordQueryVo;
 import com.jzg.commons.entity.finance.vo.InvoiceRecordResult;
 import com.jzg.commons.entity.finance.vo.InvoicingVo;
@@ -229,4 +230,15 @@ public interface ReceivableMapper extends BaseMapper<InsPlyIncome> {
     List<CalRes> querySettledAmount(@Param("systemCode") String systemCode,
                                                @Param("settledStartDate") String settledStartDate,
                                                @Param("settledEndDate") String settledEndDate);
+
+    /**
+     * 查询
+     * @param startYear
+     * @param endYear
+     * @param systemCode
+     * @return
+     */
+    List<InsPlyIncomeDto> queryFollowIncome(@Param("startYear") Integer startYear,
+                                            @Param("endYear") Integer endYear,
+                                            @Param("systemCode")  String systemCode);
 }

+ 28 - 0
tenant/organization/src/main/java/com/jzg/organization/service/ReceivableService.java

@@ -414,4 +414,32 @@ public interface ReceivableService extends IService<InsPlyIncome> {
      * @date 2026/6/4 10:15
      */
     BigDecimal queryAllTotalReceivablePremium(List<String> orderNos);
+
+    /**
+     * 跟单费开票的列表
+     * @param followInvoicePageListVo
+     * @return
+     */
+    List<InsFeeFollowOrderVo> followInvoicePageList(FollowInvoicePageListVo followInvoicePageListVo);
+
+    /**
+     * 跟单费开票
+     * @param followInvoiceVo
+     * @return
+     */
+    InvoiceingResult followInvoicing(FollowInvoiceVo followInvoiceVo);
+
+    /**
+     * 跟单费结算
+     * @param settlementVo
+     * @return
+     */
+    boolean followSettlement(SettlementVo settlementVo);
+
+    /**
+     * 跟单费开票并结算
+     * @param settlementVo
+     * @return
+     */
+    HttpResult<String> followInvoiceAndSettlement(FollowInvoiceAndSettlementVo settlementVo);
 }

+ 483 - 16
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -12,6 +12,7 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -92,6 +93,12 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     @Autowired
     private InsPlyIncomeInvoiceMapper insPlyIncomeInvoiceMapper;
 
+    @Autowired
+    private InsFeeFollowOrderMapper insFeeFollowOrderMapper;
+
+    @Autowired
+    private InsPlyFollowInvoiceLinkMapper insPlyFollowInvoiceLinkMapper;
+
     @Autowired
     private InsPlyIncomeInvoiceLinkMapper insPlyIncomeInvoiceLinkMapper;
 
@@ -531,9 +538,10 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean deleteInvoiceById(String id) {
         log.info("私有协议-开票记录-删除: id=[{}]",id);
-        insPlyIncomeInvoiceLinkMapper.deleteByInvoiceId(id);
+        insPlyIncomeInvoiceLinkMapper.deleteById(id);
         return insPlyIncomeInvoiceMapper.deleteById(id) > 0;
     }
 
@@ -854,38 +862,38 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     }
 
     @Override
-    public boolean updateIncomeSettlementStatus(String invoiceType, List<String> invoiceIds, LocalDateTime settlementTime) {
-        log.info("更新结算状态: invoiceType=[{}],invoiceIds=[{}],settlementTime=[{}]", invoiceType, JSONUtil.toJsonStr(invoiceIds), settlementTime);
-        if (CollectionUtils.isEmpty(invoiceIds)) {
+    public boolean updateIncomeSettlementStatus(String invoiceType, List<String> incomeIds, LocalDateTime settlementTime) {
+        log.info("更新结算状态: invoiceType=[{}],incomeIds=[{}],settlementTime=[{}]", invoiceType, JSONUtil.toJsonStr(incomeIds), settlementTime);
+        if (CollectionUtils.isEmpty(incomeIds)) {
             return false;
         }
         long result;
         final String number = "1";
         result = switch (invoiceType) {
             case number -> baseMapper.update(new LambdaUpdateWrapper<InsPlyIncome>()
-                    .in(InsPlyIncome::getId, invoiceIds)
+                    .in(InsPlyIncome::getId, incomeIds)
                     .set(InsPlyIncome::getSuperviseSettlement, number)
                     .set(InsPlyIncome::getSettlementTime,settlementTime)
             );
             case "2" -> baseMapper.update(new LambdaUpdateWrapper<InsPlyIncome>()
-                    .in(InsPlyIncome::getId, invoiceIds)
+                    .in(InsPlyIncome::getId, incomeIds)
                     .set(InsPlyIncome::getOtherSettlement, number)
                     .set(InsPlyIncome::getSettlementTime,settlementTime));
             case "3" -> baseMapper.update(new LambdaUpdateWrapper<InsPlyIncome>()
-                    .in(InsPlyIncome::getId, invoiceIds)
+                    .in(InsPlyIncome::getId, incomeIds)
                     .set(InsPlyIncome::getJySuperviseSettlement, number)
                     .set(InsPlyIncome::getSettlementTime,settlementTime));
             case "4" -> baseMapper.update(new LambdaUpdateWrapper<InsPlyIncome>()
-                    .in(InsPlyIncome::getId, invoiceIds)
+                    .in(InsPlyIncome::getId, incomeIds)
                     .set(InsPlyIncome::getJyOtherSettlement, number)
                     .set(InsPlyIncome::getSettlementTime,settlementTime));
             case "5" -> baseMapper.update(new LambdaUpdateWrapper<InsPlyIncome>()
-                    .in(InsPlyIncome::getId, invoiceIds)
+                    .in(InsPlyIncome::getId, incomeIds)
                     .set(InsPlyIncome::getPlatformSuperviseSettlement, number)
                     .set(InsPlyIncome::getSettlementTime,settlementTime)
                     .set(InsPlyIncome::getSettlementStatus, number));
             case "6" -> baseMapper.update(new LambdaUpdateWrapper<InsPlyIncome>()
-                    .in(InsPlyIncome::getId, invoiceIds)
+                    .in(InsPlyIncome::getId, incomeIds)
                     .set(InsPlyIncome::getPlatformOtherSettlement, number)
                     .set(InsPlyIncome::getSettlementTime,settlementTime)
                     .set(InsPlyIncome::getSettlementStatus, number));
@@ -894,6 +902,83 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         return result > 0;
     }
 
+    /**
+     * 更新结算状态
+     *
+     * @param invoiceType 发票类型
+     * @param incomeIds 收入ID列表(当invoiceType为2或4时,此参数可为空,改用年月等条件更新)
+     * @param settlementTime 结算时间
+     * @param systemCode 系统编码(invoiceType为2或4时必传)
+     * @param companyId 公司ID(invoiceType为2或4时必传)
+     * @return 是否更新成功
+     */
+    public boolean updateIncomeSettlementStatus(String invoiceType, List<String> incomeIds,
+                                                LocalDateTime settlementTime,
+                                                String systemCode, String companyId) {
+        log.info("更新结算状态: invoiceType=[{}], incomeIds=[{}], settlementTime=[{}], systemCode=[{}], companyId=[{}]",
+                invoiceType, JSONUtil.toJsonStr(incomeIds), settlementTime, systemCode, companyId);
+        final String number = "1";
+        long result = 0;
+        // 针对 invoiceType 为 2 或 4 的特殊逻辑:按签约年月、系统编码、公司ID进行批量更新
+        if ("2".equals(invoiceType) || "4".equals(invoiceType)) {
+            // 参数校验
+            if (settlementTime == null || StringUtils.isBlank(systemCode) || StringUtils.isBlank(companyId)) {
+                log.warn("invoiceType为2或4时,settlementTime、systemCode、companyId不能为空");
+                return false;
+            }
+
+            // 提取 settlementTime 的年份和月份
+            int year = settlementTime.getYear();
+            int month = settlementTime.getMonthValue();
+
+            // 构建 LambdaUpdateWrapper
+            LambdaUpdateWrapper<InsPlyIncome> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(InsPlyIncome::getSystemCode, systemCode)
+                    .eq(InsPlyIncome::getCompanyId, companyId)
+                    // 核心逻辑:匹配 signingTime 的年份和月份
+                    .apply("YEAR(signing_time) = {0} AND MONTH(signing_time) = {1}", year, month)
+                    .set(InsPlyIncome::getSettlementTime, settlementTime);
+
+            // 根据具体的 invoiceType 设置对应的结算字段
+            if ("2".equals(invoiceType)) {
+                wrapper.set(InsPlyIncome::getOtherSettlement, number);
+            } else {
+                wrapper.set(InsPlyIncome::getJyOtherSettlement, number);
+            }
+
+            result = baseMapper.update(null, wrapper);
+        } else {
+            // 其他类型保持原有的根据 ID 列表更新的逻辑
+            if (CollectionUtils.isEmpty(incomeIds)) {
+                return false;
+            }
+
+            result = switch (invoiceType) {
+                case "1" -> baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
+                        .in(InsPlyIncome::getId, incomeIds)
+                        .set(InsPlyIncome::getSuperviseSettlement, number)
+                        .set(InsPlyIncome::getSettlementTime, settlementTime));
+                case "3" -> baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
+                        .in(InsPlyIncome::getId, incomeIds)
+                        .set(InsPlyIncome::getJySuperviseSettlement, number)
+                        .set(InsPlyIncome::getSettlementTime, settlementTime));
+                case "5" -> baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
+                        .in(InsPlyIncome::getId, incomeIds)
+                        .set(InsPlyIncome::getPlatformSuperviseSettlement, number)
+                        .set(InsPlyIncome::getSettlementTime, settlementTime)
+                        .set(InsPlyIncome::getSettlementStatus, number));
+                case "6" -> baseMapper.update(null, new LambdaUpdateWrapper<InsPlyIncome>()
+                        .in(InsPlyIncome::getId, incomeIds)
+                        .set(InsPlyIncome::getPlatformOtherSettlement, number)
+                        .set(InsPlyIncome::getSettlementTime, settlementTime)
+                        .set(InsPlyIncome::getSettlementStatus, number));
+                default -> 0L;
+            };
+        }
+
+        return result > 0;
+    }
+
     /**
      * 开票并结算
      *
@@ -1402,8 +1487,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             // 实际已经收了的金额
             BigDecimal actualReceivedAmount = this.getInvoicingAmount(settlementVo.getInvoicingId());
 
-            // 所有需要结算的金额
-            BigDecimal allToSettlement = insPlyIncomeInvoice.getReceivableSupervisePremium().add(insPlyIncomeInvoice.getOverinflatedAmount());
+            // 所有需要结算的金额,开票金额
+            BigDecimal allToSettlement = insPlyIncomeInvoice.getReceivableSupervisePremium();
             // 剩余的金额
             BigDecimal surplusPremium = allToSettlement.subtract(actualReceivedAmount);
             log.info("invoiceId=[{}],一共需要结算的金额[{}],实际已经结算的金额[{}],本次计划结算的金额[{}]",
@@ -1452,7 +1537,6 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             log.error("结算异常. settlementVo=[{}]",JSONUtil.toJsonStr(settlementVo), e);
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             throw new RuntimeException(e.getMessage());
-            // return false;
         }
     }
 
@@ -2072,6 +2156,386 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         return true;
     }
 
+    /**
+     * 处理跟单费开票业务
+     * 包含:创建发票主表记录、批量创建跟单订单明细、建立发票与明细的关联关系
+     *
+     * @param vo 跟单开票请求参数
+     * @return 是否成功
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public InvoiceingResult followInvoicing(FollowInvoiceVo vo) {
+        // 校验明细列表,防止空列表导致无意义的数据库操作
+        InvoiceingResult result = new InvoiceingResult();
+        List<InsFeeFollowOrderVo> details = vo.getDetails();
+        if (CollUtil.isEmpty(details)) {
+            return result;
+        }
+
+        // 构建并保存发票主表信息
+        InsPlyIncomeInvoice invoice = buildInvoice(vo);
+
+        // 批量构建跟单订单明细和关联关系
+        List<InsFeeFollowOrder> orderList = new ArrayList<>(details.size());
+        List<InsPlyFollowInvoiceLink> links = new ArrayList<>(details.size());
+
+        for (InsFeeFollowOrderVo item : details) {
+            // 构建跟单订单明细
+            InsFeeFollowOrder order = new InsFeeFollowOrder();
+            BeanUtils.copyProperties(item, order);
+            order.setId(IdGenerate.nextId());
+            order.setSystemCode(baseController.getSystemCode());
+            // 如果选择了单条,则设置应收金额为开票金额
+            if ("0".equals(vo.getSelectFlag())){
+                order.setUninvoiced(order.getReceivablePremium().subtract(vo.getReceivableSupervisePremium()));
+                order.setInvoicedAmountTime(vo.getReceivableSupervisePremium());
+                order.setInvoiced(vo.getReceivableSupervisePremium());
+            }
+            orderList.add(order);
+
+            // 构建发票与订单的关联关系
+            InsPlyFollowInvoiceLink link = new InsPlyFollowInvoiceLink();
+            link.setId(IdGenerate.nextId());
+            link.setInvoiceId(invoice.getId());
+            link.setFollowId(order.getId());
+            links.add(link);
+        }
+
+        // 插入invoice表
+        insPlyIncomeInvoiceMapper.insert(invoice);
+        // 批量插入订单明细和关联关系,避免循环内单条插入导致的性能问题
+        // 注意:需确保 Mapper 中已配置对应的批量插入方法
+        insFeeFollowOrderMapper.insert(orderList);
+        insPlyFollowInvoiceLinkMapper.insert(links);
+
+        // 返回结果
+        result.setInvoiceId(invoice.getId());
+        result.setSumPrice(null != invoice.getReceivableSupervisePremium() ? invoice.getReceivableSupervisePremium().toString() : null);
+        return result;
+    }
+
+    /**
+     * 构建发票主表实体对象
+     */
+    private InsPlyIncomeInvoice buildInvoice(FollowInvoiceVo vo) {
+        InsPlyIncomeInvoice invoice = new InsPlyIncomeInvoice();
+        invoice.setId(IdGenerate.nextId());
+        invoice.setCompanyId(vo.getCompanyId());
+        // 发票类型:2-跟单费
+        invoice.setInvoiceType("2");
+        invoice.setInvoiceNo(vo.getInvoiceNo());
+        //  开票类型  1、手续费  2、跟单费  3、驾意险手续费 4、驾意险跟单费 5、平台应收-车险 6、平台应收-非车险
+        if("1".equals(vo.getInvoiceType()) || "2".equals(vo.getInvoiceType())){
+            invoice.setInvoiceRiskType("10");
+        }else if("5".equals(vo.getInvoiceType()) || "6".equals(vo.getInvoiceType())){
+            invoice.setInvoiceRiskType("30");
+        }else{
+            invoice.setInvoiceRiskType("20");
+        }
+        invoice.setInvoiceParty(vo.getInvoiceParty());
+        invoice.setOverinflatedAmount(vo.getOverinflatedAmount());
+        invoice.setPaymentReason(vo.getPaymentReason());
+        invoice.setReceivableSupervisePremium(vo.getReceivableSupervisePremium());
+        invoice.setTaxPoint(vo.getTaxPoint());
+        // 初始状态:0-待处理
+        invoice.setStatus("0");
+        return invoice;
+    }
+
+    /**
+     * 获取发票跟进分页列表数据
+     *
+     * @param followInvoicePageListVo
+     * @return 发票跟进VO列表
+     */
+    @Override
+    public List<InsFeeFollowOrderVo> followInvoicePageList(FollowInvoicePageListVo followInvoicePageListVo) {
+
+        if (null == followInvoicePageListVo || CollUtil.isEmpty(followInvoicePageListVo.getSearchList())){
+            return CollUtil.newArrayList();
+        }
+        FollowInvoicePageListVo.SearchVO searchYear = followInvoicePageListVo.getSearchList().stream().filter(search -> "signYear".equals(search.getName())).findFirst().orElse(new FollowInvoicePageListVo.SearchVO());
+        Integer startYear = Integer.parseInt(searchYear.getSearch().split(",")[0]);
+        Integer endYear = Integer.parseInt(searchYear.getSearch().split(",")[1]);
+
+        // 获取所有年份
+        List<Integer> yearList = new ArrayList<>();
+        if (startYear <= endYear) {
+            for (int year = startYear; year <= endYear; year++) {
+                yearList.add(year);
+            }
+        }
+
+        // 获取当前用户的系统编码
+        String systemCode = baseController.getUserSystemCode();
+
+        // 查询该年份下的所有跟进收入数据,并按合作方公司ID进行分组
+        List<InsPlyIncomeDto> incomes = baseMapper.queryFollowIncome(startYear, endYear, systemCode);
+
+        // ====================== 增加动态条件过滤 ======================
+        List<InsPlyIncomeDto> filterIncomes = new ArrayList<>();
+        if (CollUtil.isEmpty(followInvoicePageListVo.getSearchList())) {
+            filterIncomes = incomes;
+        } else {
+            List<FollowInvoicePageListVo.SearchVO> searchParams = followInvoicePageListVo.getSearchList();
+            if (CollUtil.isNotEmpty(searchParams)) {
+                Map<String, FollowInvoicePageListVo.SearchVO> searchVOMap = searchParams.stream()
+                        .filter(action -> StrUtil.isNotEmpty(action.getName()))
+                        .collect(Collectors.toMap(FollowInvoicePageListVo.SearchVO::getName, Function.identity(), (oldItem, newItem) -> oldItem));
+                Set<String> names = searchVOMap.keySet();
+
+                // 保险公司
+                Predicate<InsPlyIncomeDto> companyIdPredicate = insPlyIncome -> {
+                    if (!names.contains(FollowInvoicePageListVo.SearchVO.companyId)) {
+                        return true;
+                    }
+                    FollowInvoicePageListVo.SearchVO searchVO = searchVOMap.get(FollowInvoicePageListVo.SearchVO.companyId);
+                    String type = searchVO.getType();
+                    String search = searchVO.getSearch();
+                    if ("为空".equals(type) || "不为空".equals(type)) {
+                        return true;
+                    }
+                    if (StrUtil.isEmpty(search)) {
+                        return true;
+                    }
+                    if ("等于".equalsIgnoreCase(type) || "包含".equalsIgnoreCase(type)) {
+                        List<String> companyIds = Arrays.asList(search.split(","));
+                        return companyIds.contains(insPlyIncome.getCompanyId());
+                    }
+                    if ("不等于".equalsIgnoreCase(type) || "不包含".equalsIgnoreCase(type)) {
+                        List<String> companyIds = Arrays.asList(search.split(","));
+                        return !companyIds.contains(insPlyIncome.getCompanyId());
+                    }
+                    return true;
+                };
+                // 签单年份
+                Predicate<InsPlyIncomeDto> signYearPredicate = insPlyIncome -> {
+                    if (!names.contains(FollowInvoicePageListVo.SearchVO.signYear)) {
+                        return true;
+                    }
+                    FollowInvoicePageListVo.SearchVO searchVO = searchVOMap.get(FollowInvoicePageListVo.SearchVO.signYear);
+                    String type = searchVO.getType();
+                    String search = searchVO.getSearch();
+                    if ("为空".equals(type) || "不为空".equals(type)) {
+                        return true;
+                    }
+                    if (StrUtil.isEmpty(search)) {
+                        return true;
+                    }
+                    if ("等于".equalsIgnoreCase(type) || "包含".equalsIgnoreCase(type)) {
+                        List<String> signYears = Arrays.asList(search.split(","));
+                        return signYears.contains(insPlyIncome.getSignYear());
+                    }
+                    if ("不等于".equalsIgnoreCase(type) || "不包含".equalsIgnoreCase(type)) {
+                        List<String> signYears = Arrays.asList(search.split(","));
+                        return !signYears.contains(insPlyIncome.getSignYear());
+                    }
+                    return true;
+                };
+
+                // AND / OR 组合逻辑(和代码A完全一致)
+                if ("and".equalsIgnoreCase(followInvoicePageListVo.getLogicJudge())) {
+                    Predicate<InsPlyIncomeDto> and = companyIdPredicate.and(signYearPredicate);
+                    filterIncomes = incomes.stream().filter(and).toList();
+                } else if ("or".equalsIgnoreCase(followInvoicePageListVo.getLogicJudge())) {
+                    Predicate<InsPlyIncomeDto> or = companyIdPredicate.or(signYearPredicate);
+                    filterIncomes = incomes.stream().filter(or).toList();
+                }
+            }
+        }
+        // ======================条件过滤结束======================
+
+        // 按合作方分组(使用过滤后的数据)
+        Map<String, List<InsPlyIncomeDto>> groupMap = filterIncomes.stream()
+                .collect(Collectors.groupingBy(InsPlyIncomeDto::getPartnerCompanyId));
+
+        // 查询该年份下已开票的数据,并聚合为 [合作方ID_月份 -> 已开票金额] 的映射
+        Map<String, BigDecimal> invoicedMap = buildInvoicedMap(startYear, endYear);
+
+        // 遍历分组数据,组装最终的返回结果
+        List<InsFeeFollowOrderVo> result = new ArrayList<>();
+        for (Map.Entry<String, List<InsPlyIncomeDto>> entry : groupMap.entrySet()) {
+            String partnerCompanyId = entry.getKey();
+            List<InsPlyIncomeDto> list = entry.getValue();
+
+            // 过滤掉空列表,防止后续空指针异常
+            if (CollUtil.isEmpty(list)) {
+                continue;
+            }
+
+            // 计算该合作方每月的应收保费
+            Map<Integer, BigDecimal> monthReceivableMap = calculateMonthlyReceivable(list);
+
+            // 遍历12个月份,组装VO对象
+            InsPlyIncomeDto firstItem = list.get(0);
+            for (Integer year : yearList) {
+                for (int month = 1; month <= 12; month++) {
+                    InsFeeFollowOrderVo vo = buildFollowOrderVo(
+                            year, month, firstItem, partnerCompanyId,
+                            monthReceivableMap, invoicedMap
+                    );
+                    result.add(vo);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 构建已开票金额映射表
+     * 将已开票数据按 "合作方ID_月份" 进行聚合求和
+     */
+    private Map<String, BigDecimal> buildInvoicedMap(Integer startYear, Integer endYear) {
+        QueryWrapper<InsFeeFollowOrder> queryWrapper = new QueryWrapper<>();
+        queryWrapper.between("year", startYear, endYear);
+        List<InsFeeFollowOrder> invoicedList = insFeeFollowOrderMapper.selectList(queryWrapper);
+
+        return invoicedList.stream().collect(Collectors.groupingBy(
+                item -> item.getPartnerCompanyId() + "_" + item.getMonth(),
+                Collectors.reducing(
+                        BigDecimal.ZERO,
+                        InsFeeFollowOrder::getInvoiced,
+                        BigDecimal::add
+                )
+        ));
+    }
+
+    /**
+     * 计算单个月份的应收保费
+     * 避免在循环中重复创建BigDecimal对象,使用字符串构造或valueOf
+     */
+    private Map<Integer, BigDecimal> calculateMonthlyReceivable(List<InsPlyIncomeDto> list) {
+        return list.stream()
+                .filter(item -> item.getSigningTime() != null) // 防御性编程:过滤掉签约时间为空的数据
+                .collect(Collectors.groupingBy(
+                        item -> item.getSigningTime().getMonthValue(),
+                        Collectors.reducing(
+                                BigDecimal.ZERO,
+                                item -> {
+                                    // 优化点:将字符串转换为BigDecimal,避免在循环中频繁new对象
+                                    BigDecimal jqPremium = new BigDecimal(item.getJqReceivablePremium());
+                                    BigDecimal syPremium = new BigDecimal(item.getSyReceivablePremium());
+                                    return jqPremium.add(syPremium);
+                                },
+                                BigDecimal::add
+                        )
+                ));
+    }
+
+    /**
+     * 组装单个月的发票跟进VO对象
+     */
+    private InsFeeFollowOrderVo buildFollowOrderVo(Integer year, int month, InsPlyIncomeDto firstItem,
+                                                   String partnerCompanyId,
+                                                   Map<Integer, BigDecimal> monthReceivableMap,
+                                                   Map<String, BigDecimal> invoicedMap) {
+        // 获取当月应收保费,默认为0
+        BigDecimal receivable = monthReceivableMap.getOrDefault(month, BigDecimal.ZERO);
+        // 获取当月已开票金额,默认为0
+        BigDecimal invoiced = invoicedMap.getOrDefault(partnerCompanyId + "_" + month, BigDecimal.ZERO);
+
+        InsFeeFollowOrderVo vo = new InsFeeFollowOrderVo();
+        vo.setYear(year);
+        vo.setMonth(month);
+        vo.setCompanyName(firstItem.getCompanyName());
+        vo.setPartnerCompanyName(firstItem.getPartnerCompanyName());
+        vo.setCompanyId(firstItem.getCompanyId());
+        vo.setPartnerCompanyId(partnerCompanyId);
+        vo.setReceivablePremium(receivable);
+        vo.setInvoiced(invoiced);
+        // 未开票金额 = 应收保费 - 已开票金额
+        vo.setUninvoiced(receivable.subtract(invoiced));
+        return vo;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean followSettlement(SettlementVo settlementVo) {
+        log.info("结算:settlementVo=[{}].DateTimeFormatter", JSONUtil.toJsonStr(settlementVo));
+        AssertionUtils.isFail(StrUtil.isEmpty(settlementVo.getReceivePaymentDate()), "结算日期不能为空");
+        try {
+            // 获取应收的金额
+            InsPlyIncomeInvoice insPlyIncomeInvoice = insPlyIncomeInvoiceMapper.selectById(settlementVo.getInvoicingId());
+            AssertionUtils.isFail(Objects.isNull(insPlyIncomeInvoice), "发票数据不存在");
+            // 实际已经收了的金额
+            BigDecimal actualReceivedAmount = this.getInvoicingAmount(settlementVo.getInvoicingId());
+
+            // 所有需要结算的金额,开票金额
+            BigDecimal allToSettlement = insPlyIncomeInvoice.getReceivableSupervisePremium();
+            // 剩余的金额
+            BigDecimal surplusPremium = allToSettlement.subtract(actualReceivedAmount);
+            log.info("invoiceId=[{}],一共需要结算的金额[{}],实际已经结算的金额[{}],本次计划结算的金额[{}]",
+                    settlementVo.getInvoicingId(), allToSettlement,actualReceivedAmount,settlementVo.getActualReceivedAmount());
+            // 校验是否超出了剩余的金额,判断 surplusPremium 是否 小于 实际到账金额
+            AssertionUtils.isFail(surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) < 0, "已超出应收金额,请核对!");
+
+            // 处理结算数据
+            // 未完全结算完成
+            InsPlyIncomeInvoiceSettlement settlement = new InsPlyIncomeInvoiceSettlement(settlementVo.getInvoicingId(), settlementVo.getActualReceivedAmount(),
+                    DateTime.now(), settlementVo.getPaymentDifference(), settlementVo.getPaymentReason());
+            insPlyIncomeInvoiceSettlementMapper.insert(settlement);
+
+            if (CollectionUtils.isNotEmpty(settlementVo.getAttachmentIds())) {
+                log.info("结算的凭证是:settlementVo.getAttachmentIds()=[{}]", JSONUtil.toJsonStr(settlementVo.getAttachmentIds()));
+                // 添加发票附件
+                List<InsPlyIncomeInvoiceSettlementFile> files = new ArrayList<>();
+                for (String fileId : settlementVo.getAttachmentIds()) {
+                    InsPlyIncomeInvoiceSettlementFile file = new InsPlyIncomeInvoiceSettlementFile();
+                    file.setId(IdGenerate.nextId());
+                    file.setSettlementId(settlement.getId());
+                    file.setFileId(fileId);
+                    files.add(file);
+                }
+                insPlyIncomeInvoiceSettlementFileMapper.insert(files);
+            }
+
+            // 判断是否已经结算完成
+            if (surplusPremium.compareTo(settlementVo.getActualReceivedAmount()) == 0) {
+                log.info("序号为[{}]的发票已经结算完成",insPlyIncomeInvoice.getId());
+                // 更新发票状态
+                insPlyIncomeInvoice.setStatus("1");
+                insPlyIncomeInvoiceMapper.updateById(insPlyIncomeInvoice);
+                // 判断是需要更新哪个字段
+                this.updateIncomeSettlementStatus(insPlyIncomeInvoice.getInvoiceType(), null, LocalDateTime.now(),
+                        baseController.getSystemCode(), insPlyIncomeInvoice.getCompanyId());
+            }else{
+                log.info("invoiceId=[{}], 还剩[{}]钱没有结算",settlementVo.getInvoicingId(), surplusPremium.subtract(settlementVo.getActualReceivedAmount()));
+            }
+            return true;
+        } catch (Exception e) {
+            log.error("结算异常. settlementVo=[{}]",JSONUtil.toJsonStr(settlementVo), e);
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 跟单费开票并结算
+     *
+     * @param followInvoiceAndSettlementVo 跟单费开票信息和结算信息
+     * @author jk
+     * @date 2026/5/26 11:44
+     */
+    @Override
+    public HttpResult<String> followInvoiceAndSettlement(FollowInvoiceAndSettlementVo followInvoiceAndSettlementVo) {
+        log.info("跟单费开票并结算: settlementVo=[{}]", JSONUtil.toJsonStr(followInvoiceAndSettlementVo));
+        InvoiceingResult result = this.followInvoicing(followInvoiceAndSettlementVo.getInvoiceVO());
+        if (Objects.nonNull(result)){
+            SettlementVo settlementVo = new SettlementVo();
+            BeanUtils.copyProperties(followInvoiceAndSettlementVo, settlementVo);
+            settlementVo.setInvoicingId(result.getInvoiceId());
+            boolean settlement = this.followSettlement(settlementVo);
+            if(settlement){
+                return HttpResult.ok("跟单费开票并结算成功");
+            }else{
+                return HttpResult.error("跟单费开票成功但结算失败");
+            }
+        }
+        return HttpResult.error("跟单费开票失败");
+    }
 
 
     @Override
@@ -2117,14 +2581,17 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                         .filter(Objects::nonNull)
                         .reduce(BigDecimal.ZERO, BigDecimal::add);
                 BigDecimal receivableSupervisePremium = action.getReceivableSupervisePremium()  != null ? action.getReceivableSupervisePremium(): BigDecimal.ZERO;
-                BigDecimal overinflatedAmount = action.getOverinflatedAmount() != null? action.getOverinflatedAmount(): BigDecimal.ZERO;
-                BigDecimal remainSettlementAmount = receivableSupervisePremium.add(overinflatedAmount).subtract(settlementAmount);
+//                BigDecimal overinflatedAmount = action.getOverinflatedAmount() != null? action.getOverinflatedAmount(): BigDecimal.ZERO;
+                // 待结算金额 = 开票金额 - 已收金额
+                BigDecimal remainSettlementAmount = receivableSupervisePremium.subtract(settlementAmount);
                 // 设置已结算的金额
                 action.setSettlementAmount(settlementAmount);
                 // 设置待结算金额
                 action.setRemainSettlementAmount(remainSettlementAmount);
-                action.setCompanyALlName(allCompanyHierarchyPaths.get(Objects.toString(action.getCompanyId(),"")));
+                action.setCompanyAllName(allCompanyHierarchyPaths.get(Objects.toString(action.getCompanyId(),"")));
                 action.setSettlementStatus(settlementStatusName);
+                // 开票金额
+                action.setReceivableAmount(action.getReceivableSupervisePremium().subtract(action.getOverinflatedAmount()).toString());
             }).toList();
             invoiceRecordList.setRecords(records);
         }

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

@@ -1629,6 +1629,25 @@
         </where> ) a
         group by  a.company_id
     </select>
+    <select id="queryFollowIncome" resultType="com.jzg.commons.entity.finance.dto.InsPlyIncomeDto">
+        SELECT
+        a.*,
+        date(a.signing_time ) as sign_date,
+        year(a.signing_time) as sign_year,
+        b.partner_company_id,
+        (SELECT eic.name FROM esm_ins_company eic WHERE b.partner_company_id = eic.id) AS partnerCompanyName,
+        (SELECT eic.name FROM esm_ins_company eic WHERE a.company_id = eic.id) AS companyName
+        FROM ins_ply_income a
+        LEFT JOIN ptl_agreement b ON a.agreement_id = b.id
+        WHERE a.is_delete=0
+        AND a.agreement_type = 2
+        <if test="startYear != null and endYear != null">
+            AND YEAR(a.signing_time) BETWEEN #{startYear} AND #{endYear}
+        </if>
+        <if test="systemCode != null">
+            AND a.system_code = #{systemCode}
+        </if>
+    </select>
 
     <!--    <select id="getReceivableList" resultType="com.jzg.commons.entity.finance.po.InsPlyIncome">-->
 <!--        SELECT-->

+ 1 - 1
tenant/organization/src/main/resources/mapper/SysUserJzgInfoBankCardMapper.xml

@@ -63,7 +63,7 @@
         <if test="sysUserJzgInfoBankCardVo.applyTimeStart != null and sysUserJzgInfoBankCardVo.applyTimeEnd != null">
             and DATE_FORMAT(sujibc.apply_time, '%Y-%m-%d') between #{sysUserJzgInfoBankCardVo.applyTimeStart} AND #{sysUserJzgInfoBankCardVo.applyTimeEnd}
         </if>
-        <if test="sysUserJzgInfoBankCardVo.auditTimeStart != null and sysUserJzgInfoBankCardVo.auditTimeEnd == null">
+        <if test="sysUserJzgInfoBankCardVo.auditTimeStart != null and sysUserJzgInfoBankCardVo.auditTimeEnd != null">
             and DATE_FORMAT(sujibc.audit_time, '%Y-%m-%d') between #{sysUserJzgInfoBankCardVo.auditTimeStart} AND #{sysUserJzgInfoBankCardVo.auditTimeEnd}
         </if>
         <if test="sysUserJzgInfoBankCardVo.auditBy != null and sysUserJzgInfoBankCardVo.auditBy != ''">