Răsfoiți Sursa

权益包,出口留点比例功能提交

wanghao 6 luni în urmă
părinte
comite
cca5f5e8f8
21 a modificat fișierele cu 720 adăugiri și 25 ștergeri
  1. 5 0
      commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostAdd.java
  2. 6 0
      commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostEnd.java
  3. 17 3
      commons/src/main/java/com/jzg/commons/entity/orders/po/InsFeeOrderRecord.java
  4. 3 0
      commons/src/main/java/com/jzg/commons/entity/orders/vo/FeeAuditVo.java
  5. 22 0
      commons/src/main/java/com/jzg/commons/entity/po/InsFeeOrders.java
  6. 5 0
      commons/src/main/java/com/jzg/commons/entity/po/PtlAgreementCostType.java
  7. 16 0
      commons/src/main/java/com/jzg/commons/entity/vo/InsFeeOrdersVo.java
  8. 50 0
      commons/src/main/java/com/jzg/commons/entity/vo/PtlAgreementCostRatioVo.java
  9. 5 0
      commons/src/main/java/com/jzg/commons/entity/vo/PtlAgreementCostTypeVo.java
  10. 1 1
      consoleStatistics/src/main/java/com/jzg/console/service/impl/ReportCompanyDataManageServiceImpl.java
  11. 3 3
      consoleStatistics/src/main/resources/application-dev.yml
  12. 6 0
      gateway/src/main/resources/application-dev.yml
  13. 1 0
      platform/src/main/resources/application.yml
  14. 23 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java
  15. 138 4
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeAuditServiceImpl.java
  16. 23 7
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsFeeOrdersServiceImpl.java
  17. 20 5
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  18. 372 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/utils/LacalLiveTokenUtil.java
  19. 1 1
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/api/service/Impl/ZiJinApiRequestImpl.java
  20. 1 1
      tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/api/service/Impl/ZiJinOrderServiceImpl.java
  21. 2 0
      tenant/organization/src/main/resources/mapper/PtlAgreementCostMapper.xml

+ 5 - 0
commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostAdd.java

@@ -110,6 +110,11 @@ public class PtlAgreementCostAdd {
 
         @Schema(description = "留点比例")
         private BigDecimal keepPointRatio;
+        /**
+         * 出口留点比例
+         */
+        @Schema(description = "出口留点比例")
+        private BigDecimal exportKeepPointRatio;
 
     }
 

+ 6 - 0
commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostEnd.java

@@ -129,6 +129,12 @@ public class PtlAgreementCostEnd {
         @Schema(description = "留点比例")
         private BigDecimal keepPointRatio;
 
+        /**
+         * 出口留点比例
+         */
+        @Schema(description = "出口留点比例")
+        private BigDecimal exportKeepPointRatio;
+
     }
 
 }

+ 17 - 3
commons/src/main/java/com/jzg/commons/entity/orders/po/InsFeeOrderRecord.java

@@ -1,9 +1,8 @@
 package com.jzg.commons.entity.orders.po;
 
-import java.io.Serializable;
 import java.math.BigDecimal;
-import java.util.Date;
 
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.jzg.commons.core.base.BaseModel;
 import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
@@ -19,8 +18,10 @@ import lombok.NoArgsConstructor;
 @Schema(description = "订单费用调整记录表")
 @NoArgsConstructor
 public class InsFeeOrderRecord extends BaseModel {
+    @TableId(value = "id", type = IdType.AUTO)
+    @Schema(description = "主键")
+    private Long id;
 
-    @TableId(value = "order_no")
     @Schema(description = "订单号")
     private String orderNo;
 
@@ -69,6 +70,15 @@ public class InsFeeOrderRecord extends BaseModel {
     @Schema(description = "非车留点比例")
     private BigDecimal noKeepPointRatio;
 
+    @Schema(description = "交强险出口留点比例")
+    private BigDecimal jqExportKeepPointRatio;
+
+    @Schema(description = "商业险出口留点比例")
+    private BigDecimal syExportKeepPointRatio;
+
+    @Schema(description = "驾意险出口留点比例")
+    private BigDecimal jyExportKeepPointRatio;
+
 
     public InsFeeOrderRecord(PtlAgreementCostRatioVo param) {
         this.orderNo = param.getOrderNo();
@@ -90,5 +100,9 @@ public class InsFeeOrderRecord extends BaseModel {
         this.noAddThrowRadio = param.getJyAdditionalRatio();
         this.noKeepPointRatio = param.getJyKeepPointRatio();
 
+        this.jqExportKeepPointRatio = param.getJqExportKeepPointRatio();
+        this.syExportKeepPointRatio = param.getSyExportKeepPointRatio();
+        this.jyExportKeepPointRatio = param.getJyExportKeepPointRatio();
+
     }
 }

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

@@ -91,5 +91,8 @@ public class FeeAuditVo extends BaseModel {
     @Schema(description = "驳回原因")
     private String refuse;
 
+    @Schema(description = "权益金额")
+    private BigDecimal equityAmount;
+
 
 }

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

@@ -171,6 +171,28 @@ public class InsFeeOrders {
     @Schema(description = "驾意出口费用")
     private BigDecimal jyExportPremium;
 
+    /**
+     * 新增出口留点比例
+     */
+    @Schema(description = "交强险出口留点比例")
+    private BigDecimal jqExportKeepPointRatio;
+
+    @Schema(description = "商业险出口留点比例")
+    private BigDecimal syExportKeepPointRatio;
+
+    @Schema(description = "驾意险出口留点比例")
+    private BigDecimal jyExportKeepPointRatio;
+
+    @Schema(description = "交强险出口留点费用")
+    private BigDecimal jqExportKeepPointPremium;
+
+    @Schema(description = "商业险出口留点费用")
+    private BigDecimal syExportKeepPointPremium;
+
+    @Schema(description = "驾意险出口留点费用")
+    private BigDecimal jyExportKeepPointPremium;
+
+
     @Schema(description = "一级分销费")
     private BigDecimal firstDistributionFee;
 

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

@@ -28,6 +28,11 @@ public class PtlAgreementCostType extends BaseModel {
 
     private BigDecimal keepPointRatio;
 
+    /**
+     * 出口留点比例
+     */
+    private BigDecimal exportKeepPointRatio;
+
 
 
 }

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

@@ -5,6 +5,7 @@ import com.jzg.commons.entity.po.InsFeeOrders;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
 /**
@@ -93,6 +94,16 @@ public class InsFeeOrdersVo {
     @Schema(description = "驾意险加投费费费用")
     private String jyAdditionalPremium;
 
+
+    @Schema(description = "交强险出口留点费用")
+    private String jqExportKeepPointPremium;
+
+    @Schema(description = "商业险出口留点费用")
+    private String syExportKeepPointPremium;
+
+    @Schema(description = "驾意险出口留点费用")
+    private String jyExportKeepPointPremium;
+
     public InsFeeOrdersVo(InsFeeOrders insFeeOrders) {
         this.orderNo = insFeeOrders.getOrderNo();
         this.agreementId = insFeeOrders.getAgreementId();
@@ -120,5 +131,10 @@ public class InsFeeOrdersVo {
         this.jqAdditionalPremium = insFeeOrders.getJqAdditionalPremium() != null  ? insFeeOrders.getJqAdditionalPremium().toString() : "0.00";
         this.syAdditionalPremium = insFeeOrders.getSyAdditionalPremium() != null ? insFeeOrders.getSyAdditionalPremium().toString() : "0.00";
         this.jyAdditionalPremium = insFeeOrders.getJyAdditionalPremium() != null ? insFeeOrders.getJyAdditionalPremium().toString() : "0.00";
+
+
+        this.jqExportKeepPointPremium = insFeeOrders.getJqExportKeepPointPremium() != null ? insFeeOrders.getJqExportKeepPointPremium().toString() : "0.00";
+        this.syExportKeepPointPremium = insFeeOrders.getSyExportKeepPointPremium() != null ? insFeeOrders.getSyExportKeepPointPremium().toString() : "0.00";
+        this.jyExportKeepPointPremium = insFeeOrders.getJyExportKeepPointPremium() != null ? insFeeOrders.getJyExportKeepPointPremium().toString() : "0.00";
     }
 }

+ 50 - 0
commons/src/main/java/com/jzg/commons/entity/vo/PtlAgreementCostRatioVo.java

@@ -1,9 +1,11 @@
 package com.jzg.commons.entity.vo;
 
+import com.jzg.commons.entity.po.InsFeeOrders;
 import com.jzg.commons.entity.po.PtlAgreement;
 import com.jzg.commons.entity.po.PtlAgreementCostType;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -14,6 +16,7 @@ import java.util.List;
  */
 
 @Data
+@NoArgsConstructor
 public class PtlAgreementCostRatioVo {
     @Schema(description = "订单号")
     private String orderNo;
@@ -72,6 +75,15 @@ public class PtlAgreementCostRatioVo {
     @Schema(description = "非车险留点比例")
     private BigDecimal jyKeepPointRatio;
 
+    @Schema(description = "交强险出口留点比例")
+    private BigDecimal jqExportKeepPointRatio;
+
+    @Schema(description = "商业险出口留点比例")
+    private BigDecimal syExportKeepPointRatio;
+
+    @Schema(description = "驾意险出口留点比例")
+    private BigDecimal jyExportKeepPointRatio;
+
     public PtlAgreementCostRatioVo(List<PtlAgreementCostTypeVo> ptlAgreementCostTypeList, PtlAgreement ptlAgreement) {
         ptlAgreementCostTypeList.forEach(ptlAgreementCostType -> {
             switch (ptlAgreementCostType.getCostType()) {
@@ -81,19 +93,57 @@ public class PtlAgreementCostRatioVo {
                     this.jqExportRatio = ptlAgreementCostType.getExport();
                     this.jqFollowRatio = ptlAgreementCostType.getInlet().subtract(ptlAgreement.getJqEntranceFeeRatio() != null ? ptlAgreement.getJqEntranceFeeRatio() : BigDecimal.ZERO);
                     this.jqAdditionalRatio = ptlAgreementCostType.getAddThrow();
+                    this.jqExportKeepPointRatio = ptlAgreementCostType.getExportKeepPointRatio() != null ? ptlAgreementCostType.getExportKeepPointRatio() : BigDecimal.ZERO;
                 case "商业险":
                     this.syCommissionRatio = ptlAgreement.getSyEntranceFeeRatio() != null ? ptlAgreement.getSyEntranceFeeRatio() : BigDecimal.ZERO;
                     this.syInletRatio = ptlAgreementCostType.getInlet();
                     this.syExportRatio = ptlAgreementCostType.getExport();
                     this.syFollowRatio = ptlAgreementCostType.getInlet().subtract(ptlAgreement.getSyEntranceFeeRatio() != null ? ptlAgreement.getSyEntranceFeeRatio() : BigDecimal.ZERO);
                     this.syAdditionalRatio = ptlAgreementCostType.getAddThrow();
+                    this.syExportKeepPointRatio = ptlAgreementCostType.getExportKeepPointRatio() != null ? ptlAgreementCostType.getExportKeepPointRatio() : BigDecimal.ZERO;
                 case "驾意险":
                     this.jyCommissionRatio = ptlAgreement.getJyEntranceFeeRatio() != null ? ptlAgreement.getJyEntranceFeeRatio() : BigDecimal.ZERO;
                     this.jyInletRatio = ptlAgreementCostType.getInlet();
                     this.jyExportRatio = ptlAgreementCostType.getExport();
                     this.jyFollowRatio = ptlAgreementCostType.getInlet().subtract(ptlAgreement.getJyEntranceFeeRatio() != null ? ptlAgreement.getJyEntranceFeeRatio() : BigDecimal.ZERO);
                     this.jyAdditionalRatio = ptlAgreementCostType.getAddThrow();
+                    this.jyExportKeepPointRatio = ptlAgreementCostType.getExportKeepPointRatio() != null ? ptlAgreementCostType.getExportKeepPointRatio() : BigDecimal.ZERO;
             }
         });
     }
+
+    public PtlAgreementCostRatioVo(InsFeeOrders insFeeOrders) {
+        this.orderNo = insFeeOrders.getOrderNo();
+
+        // 交强险比例
+        this.jqCommissionRatio = insFeeOrders.getJqCommissionRatio() != null ? insFeeOrders.getJqCommissionRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jqInletRatio = insFeeOrders.getJqInletRatio() != null ? insFeeOrders.getJqInletRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jqFollowRatio = insFeeOrders.getJqFollowRatio() != null ? insFeeOrders.getJqFollowRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jqAdditionalRatio = insFeeOrders.getJqAdditionalRatio() != null ? insFeeOrders.getJqAdditionalRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jqKeepPointRatio = insFeeOrders.getJqKeepPointRatio() != null ? insFeeOrders.getJqKeepPointRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jqExportRatio = insFeeOrders.getJqExportRatio() != null ? insFeeOrders.getJqExportRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jqExportKeepPointRatio = insFeeOrders.getJqExportKeepPointRatio() != null ? insFeeOrders.getJqExportKeepPointRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+
+        // 商业险比例
+        this.syCommissionRatio = insFeeOrders.getSyCommissionRatio() != null ? insFeeOrders.getSyCommissionRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.syInletRatio = insFeeOrders.getSyInletRatio() != null ? insFeeOrders.getSyInletRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.syFollowRatio = insFeeOrders.getSyFollowRatio() != null ? insFeeOrders.getSyFollowRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.syAdditionalRatio = insFeeOrders.getSyAdditionalRatio() != null ? insFeeOrders.getSyAdditionalRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.syKeepPointRatio = insFeeOrders.getSyKeepPointRatio() != null ? insFeeOrders.getSyKeepPointRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.syExportRatio = insFeeOrders.getSyExportRatio() != null ? insFeeOrders.getSyExportRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.syExportKeepPointRatio = insFeeOrders.getSyExportKeepPointRatio() != null ? insFeeOrders.getSyExportKeepPointRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+
+        // 驾意险比例
+        this.jyCommissionRatio = insFeeOrders.getJyCommissionRatio() != null ? insFeeOrders.getJyCommissionRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jyInletRatio = insFeeOrders.getJyInletRatio() != null ? insFeeOrders.getJyInletRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jyFollowRatio = insFeeOrders.getJyFollowRatio() != null ? insFeeOrders.getJyFollowRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jyAdditionalRatio = insFeeOrders.getJyAdditionalRatio() != null ? insFeeOrders.getJyAdditionalRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jyKeepPointRatio = insFeeOrders.getJyKeepPointRatio() != null ? insFeeOrders.getJyKeepPointRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jyExportRatio = insFeeOrders.getJyExportRatio() != null ? insFeeOrders.getJyExportRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+        this.jyExportKeepPointRatio = insFeeOrders.getJyExportKeepPointRatio() != null ? insFeeOrders.getJyExportKeepPointRatio().multiply(new BigDecimal("100")) : BigDecimal.ZERO;
+    }
+
+
+
+
 }

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

@@ -28,6 +28,11 @@ public class PtlAgreementCostTypeVo{
 
     @Schema(description = "留点比例")
     private BigDecimal keepPointRatio;
+    /**
+     * 出口留点比例
+     */
+    @Schema(description = "出口留点比例")
+    private BigDecimal exportKeepPointRatio;
 
     @Schema(description = "手续费比例")
     private BigDecimal commission;

+ 1 - 1
consoleStatistics/src/main/java/com/jzg/console/service/impl/ReportCompanyDataManageServiceImpl.java

@@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.jzg.commons.entity.report.dto.ReportCompanyDataManageDto;
 import com.jzg.commons.entity.report.vo.ReportSearchCommonVo;
-import com.jzg.console.mapper.ReportCompanyDataManageMapper;;
+import com.jzg.console.mapper.ReportCompanyDataManageMapper;
 import com.jzg.console.service.ReportCompanyDataManageService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;

+ 3 - 3
consoleStatistics/src/main/resources/application-dev.yml

@@ -3,17 +3,17 @@ server:
 spring:
   cloud:
     nacos:
-      server-addr: 192.168.0.250:8848
+      server-addr: localhost:8848
       username: nacos
       password: nacos
       config:
         file-extension: yaml
         #namespace: 1096345e-2a2d-4307-8025-ee1b669e127b
-        namespace: 83c21527-44e1-4063-9ec5-b8812928237f
+        namespace: ba488f58-c785-49b4-9c02-b5d9b8a965a5
         group: DEFAULT_GROUP
       discovery:
         #namespace: 1096345e-2a2d-4307-8025-ee1b669e127b
-        namespace: 83c21527-44e1-4063-9ec5-b8812928237f
+        namespace: ba488f58-c785-49b4-9c02-b5d9b8a965a5
   config:
     import:
       - nacos:mysql

+ 6 - 0
gateway/src/main/resources/application-dev.yml

@@ -36,6 +36,7 @@ spring:
             - name: MultiPath
               args:
                 paths:
+                  - /menu/**
                   - /userRole/**
                   - /system/**
                   - /file/**
@@ -89,6 +90,11 @@ spring:
                   - /ptlAgreementDispatch/**
                   - /appManage/**
                   - /version/**
+                  - /amountAuditing/**
+                  - /account/**
+                  - /accountCard/**
+                  - /userAccount/**
+
 
         - id: summary_route
           uri: http://localhost:9898/

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

@@ -26,6 +26,7 @@ tenant:
   column: system_code
   filterTables:
   ignoreTables:
+    - sys_menu
     - sys_config
     - sys_user
     - sys_dict

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

@@ -413,6 +413,17 @@ public class QuoteVerificationAspect {
 
         BigDecimal jyExportPremium = insFeeOrders.getJyExportRatio().multiply(insFeeOrders.getJyPremium());
         insFeeOrders.setJyExportPremium(jyExportPremium);
+
+        // 计算出口留点费用
+        BigDecimal jqExportKeepRatioPremium = insFeeOrders.getJqExportKeepPointRatio().multiply(insFeeOrders.getJqPremium());
+        insFeeOrders.setJqExportKeepPointPremium(jqExportKeepRatioPremium);
+
+        BigDecimal syExportKeepRatioPremium = insFeeOrders.getSyExportKeepPointRatio().multiply(insFeeOrders.getSyPremium());
+        insFeeOrders.setSyExportKeepPointPremium(syExportKeepRatioPremium);
+
+        BigDecimal jyExportKeepRatioPremium = insFeeOrders.getJyExportKeepPointRatio().multiply(insFeeOrders.getJyPremium());
+        insFeeOrders.setJyExportKeepPointPremium(jyExportKeepRatioPremium);
+
     }
 
     /**
@@ -469,6 +480,18 @@ public class QuoteVerificationAspect {
                 ? convertPercent(jyCostType.getExport() != null ? jyCostType.getExport() : BigDecimal.ZERO)
                 : BigDecimal.ZERO);
 
+
+        // 出口留点比例
+        insFeeOrders.setJqExportKeepPointRatio(jqCostType != null
+                ? convertPercent(jqCostType.getExportKeepPointRatio() != null ? jqCostType.getExportKeepPointRatio() : BigDecimal.ZERO)
+                : BigDecimal.ZERO);
+        insFeeOrders.setSyExportKeepPointRatio(syCostType != null
+                ? convertPercent(syCostType.getExportKeepPointRatio() != null ? syCostType.getExportKeepPointRatio() : BigDecimal.ZERO)
+                : BigDecimal.ZERO);
+        insFeeOrders.setJyExportKeepPointRatio(jyCostType != null
+                ? convertPercent(jyCostType.getExportKeepPointRatio() != null ? jyCostType.getExportKeepPointRatio() : BigDecimal.ZERO)
+                : BigDecimal.ZERO);
+
     }
 
     /**

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

@@ -2,6 +2,8 @@ package com.jzg.quotation.summary.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -21,6 +23,8 @@ import com.jzg.commons.entity.po.SysUser;
 import com.jzg.commons.entity.po.SysUserAccount;
 import com.jzg.commons.entity.po.SysUserJzgInfo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteEchoVo;
+import com.jzg.commons.entity.rights.po.InsOrderRights;
+import com.jzg.commons.entity.rights.po.InsOrderRightsPackage;
 import com.jzg.commons.entity.vo.*;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.AssertionUtils;
@@ -30,9 +34,12 @@ import com.jzg.commons.util.idgen.IdGenerate;
 import com.jzg.quotation.commons.client.OrgClient;
 import com.jzg.quotation.commons.client.PlatformClient;
 import com.jzg.quotation.summary.mapper.InsFeeAuditMapper;
+import com.jzg.quotation.summary.mapper.InsOrderRightsMapper;
+import com.jzg.quotation.summary.mapper.InsOrderRightsPackageMapper;
 import com.jzg.quotation.summary.service.*;
 import com.jzg.quotation.summary.state.AuditState;
 import com.jzg.quotation.summary.state.listener.AuditStateListener;
+import com.jzg.quotation.summary.utils.LacalLiveTokenUtil;
 import lombok.RequiredArgsConstructor;
 import org.hibernate.validator.internal.util.stereotypes.Lazy;
 import org.redisson.api.RBucket;
@@ -43,11 +50,9 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.io.File;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -94,6 +99,13 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
     @Autowired
     private AuditStateListener auditStateListener;
 
+    @Autowired
+    private LacalLiveTokenUtil lacalLiveTokenUtil;
+    @Autowired
+    private InsOrderRightsMapper insOrderRightsMapper;
+    @Autowired
+    private InsOrderRightsPackageMapper insOrderRightsPackageMapper;
+
     private static final String ORDER_LOCK_PREFIX = "orderLock:";
 
 
@@ -108,6 +120,29 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
             param.setCompanyIdList(companyIdList);
         }
         Page<FeeAuditVo> page = baseMapper.queryPage(param.getPage(), param);
+        // 循环每条数据,查询 ins_fee_orders 并计算权益金额
+        if (CollUtil.isNotEmpty(page.getRecords())) {
+            for (FeeAuditVo feeAuditVo : page.getRecords()) {
+                // 查询订单的 ins_fee_orders 数据
+                InsFeeOrders insFeeOrders = feeOrdersService.getById(feeAuditVo.getOrderNo());
+                if (insFeeOrders != null) {
+                    // 权益金额 = (交强出口费用 + 商业出口费用 + 驾意出口费用) - (交强出口留点费用 + 商业出口留点费用 + 驾意出口留点费用)
+                    BigDecimal exportTotal = Optional.ofNullable(insFeeOrders.getJqExportPremium()).orElse(BigDecimal.ZERO)
+                            .add(Optional.ofNullable(insFeeOrders.getSyExportPremium()).orElse(BigDecimal.ZERO))
+                            .add(Optional.ofNullable(insFeeOrders.getJyExportPremium()).orElse(BigDecimal.ZERO));
+
+                    BigDecimal exportKeepPointTotal = Optional.ofNullable(insFeeOrders.getJqExportKeepPointPremium()).orElse(BigDecimal.ZERO)
+                            .add(Optional.ofNullable(insFeeOrders.getSyExportKeepPointPremium()).orElse(BigDecimal.ZERO))
+                            .add(Optional.ofNullable(insFeeOrders.getJyExportKeepPointPremium()).orElse(BigDecimal.ZERO));
+
+                    BigDecimal equityAmount = exportTotal.subtract(exportKeepPointTotal);
+                    feeAuditVo.setEquityAmount(equityAmount);
+                }else{
+                    feeAuditVo.setEquityAmount(BigDecimal.ZERO);
+                }
+            }
+        }
+
         return page;
     }
 
@@ -289,6 +324,105 @@ public class InsFeeAuditServiceImpl extends ServiceImpl<InsFeeAuditMapper, InsFe
             HttpResult<SysUserAccount> result = orgClient.accountGet(sysUserResult.getData().getId(), baseController.getToken());
             AssertionUtils.isFail(result.getCode() != 200,"获取用户账户失败!");
             userAccount = result.getData();
+
+            //计算出口费用减去实际花费的权益金额
+            try{
+                // 计算权益金额 = (出口费用总和) - (出口留点费用总和)
+                BigDecimal jqExportTotal = Optional.ofNullable(feeOrders.getJqExportPremium()).orElse(BigDecimal.ZERO);
+                BigDecimal syExportTotal = Optional.ofNullable(feeOrders.getSyExportPremium()).orElse(BigDecimal.ZERO);
+                BigDecimal jyExportTotal = Optional.ofNullable(feeOrders.getJyExportPremium()).orElse(BigDecimal.ZERO);
+                BigDecimal jqExportKeepPoint = Optional.ofNullable(feeOrders.getJqExportKeepPointPremium()).orElse(BigDecimal.ZERO);
+                BigDecimal syExportKeepPoint = Optional.ofNullable(feeOrders.getSyExportKeepPointPremium()).orElse(BigDecimal.ZERO);
+                BigDecimal jyExportKeepPoint = Optional.ofNullable(feeOrders.getJyExportKeepPointPremium()).orElse(BigDecimal.ZERO);
+                BigDecimal equityAmount = jqExportTotal.add(syExportTotal).add(jyExportTotal)
+                        .subtract(jqExportKeepPoint.add(syExportKeepPoint).add(jyExportKeepPoint));
+
+                // 权益金额大于 0,计算实际花费的权益金额并发放权益券
+                if (equityAmount.compareTo(BigDecimal.ZERO) > 0) {
+                    // 获取权益列表
+                    List<InsOrderRights> rightsList = insOrderRightsMapper.queryByOrderNo(param.getOrderNo());
+                    List<InsOrderRightsPackage> rightsPackageList = insOrderRightsPackageMapper.queryByOrderNo(param.getOrderNo());
+
+                    // 初始化变量
+                    BigDecimal rightsTotalAmount = BigDecimal.ZERO;
+                    BigDecimal rightsPackageTotalAmount = BigDecimal.ZERO;
+                    com.alibaba.fastjson2.JSONObject receiverDTO = new com.alibaba.fastjson2.JSONObject();
+                    JSONArray rightsRequest = new JSONArray();
+
+                    // 遍历权益单品,计算总金额并构建请求参数
+                    if (CollUtil.isNotEmpty(rightsList)) {
+                        for (InsOrderRights rights : rightsList) {
+                            // 提取接收人信息(取第一条有手机号的记录)
+                            if (StringUtils.isBlank(receiverDTO.getString("phone")) && StringUtils.isNotBlank(rights.getReceiverMobile())) {
+                                receiverDTO.put("phone", rights.getReceiverMobile());
+                                receiverDTO.put("receiverName", rights.getReceiverName());
+                                receiverDTO.put("remark", "车险订单权益赠送");
+                                receiverDTO.put("receiverAmountLimit", equityAmount);
+                            }
+                            // 累加金额
+                            BigDecimal amount = Optional.ofNullable(rights.getAmount()).orElse(BigDecimal.ZERO);
+                            Integer count = Optional.ofNullable(rights.getRightsCount()).orElse(0);
+                            rightsTotalAmount = rightsTotalAmount.add(amount.multiply(new BigDecimal(count)));
+
+                            // 构建权益单品请求参数
+                            JSONObject rightsItem = new JSONObject();
+                            rightsItem.put("rightsContentId", rights.getRightsInfoId());
+                            rightsItem.put("rightsCount", rights.getRightsCount());
+                            rightsItem.put("rightsType", 1);
+                            rightsRequest.add(rightsItem);
+                        }
+                    }
+
+                    // 遍历权益套餐,计算总金额并构建请求参数
+                    if (CollUtil.isNotEmpty(rightsPackageList)) {
+                        for (InsOrderRightsPackage pkg : rightsPackageList) {
+                            // 提取接收人信息(取第一条有手机号的记录)
+                            if (StringUtils.isBlank(receiverDTO.getString("phone")) && StringUtils.isNotBlank(pkg.getReceiverMobile())) {
+                                receiverDTO.put("phone", pkg.getReceiverMobile());
+                                receiverDTO.put("receiverName", pkg.getReceiverName());
+                                receiverDTO.put("remark", "车险订单权益赠送");
+                                receiverDTO.put("receiverAmountLimit", equityAmount);
+                            }
+
+                            // 累加金额
+                            BigDecimal packagePrice = Optional.ofNullable(pkg.getPackagePrice()).orElse(BigDecimal.ZERO);
+                            Integer count = Optional.ofNullable(pkg.getRightsCount()).orElse(0);
+                            rightsPackageTotalAmount = rightsPackageTotalAmount.add(packagePrice.multiply(new BigDecimal(count)));
+
+                            // 构建权益套餐请求参数
+                            JSONObject rightsItem = new JSONObject();
+                            rightsItem.put("rightsContentId", pkg.getRightsPackageId());
+                            rightsItem.put("rightsCount", pkg.getRightsCount());
+                            rightsItem.put("rightsType", 2);
+                            rightsRequest.add(rightsItem);
+                        }
+                    }
+
+                    // 计算权益总花费并校验
+                    BigDecimal totalAmount = rightsTotalAmount.add(rightsPackageTotalAmount);
+                    if (totalAmount.compareTo(equityAmount) > 0) {
+                        AssertionUtils.isFail(true, "权益金额不足!");
+                    }
+
+                    // 调用权益发放接口
+                    LacalLiveTokenUtil.RightsGrantResponse response = lacalLiveTokenUtil.apiGrant(
+                            receiverDTO, rightsRequest, "订单号:" + param.getOrderNo() + "权益赠送");
+
+                    // 处理响应结果
+                    if (response != null && Boolean.TRUE.equals(response.getSuccess())) {
+                        // 发放成功后扣除订单总应收保费
+                        feeOrders.setTotalReceivablePremium(
+                                feeOrders.getTotalReceivablePremium().subtract(totalAmount)
+                        );
+                    } else {
+                        AssertionUtils.isFail(true, "权益券下发失败");
+                    }
+                }
+            }
+            catch (Exception e) {
+                AssertionUtils.isFail(true, "权益券下发失败");
+            }
+
             if(Objects.isNull(userAccount)){
                 userAccount = new SysUserAccount();
                 // 新建账户

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

@@ -104,13 +104,18 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         BigDecimal syExportRatio = covertPercent(ptlAgreementCostRatioVo.getSyExportRatio());
         BigDecimal jyExportRatio = covertPercent(ptlAgreementCostRatioVo.getJyExportRatio());
 
+        // 出口留点比例
+        BigDecimal jqExportKeepPointRatio = covertPercent(ptlAgreementCostRatioVo.getJqExportKeepPointRatio());
+        BigDecimal syExportKeepPointRatio = covertPercent(ptlAgreementCostRatioVo.getSyExportKeepPointRatio());
+        BigDecimal jyExportKeepPointRatio = covertPercent(ptlAgreementCostRatioVo.getJyExportKeepPointRatio());
+
         List<CostTypeParam> typeParams = Arrays.asList(
                 new CostTypeParam("jq", jqPremium, jqCommissionRatio, jqFollowRatio, jqAddThrowRatio,
-                        jqKeepPointRatio, jqInletRatio, jqExportRatio),
+                        jqKeepPointRatio, jqInletRatio, jqExportRatio, jqExportKeepPointRatio),
                 new CostTypeParam("sy", syPremium, syCommissionRatio, syFollowRatio, syAddThrowRatio,
-                        syKeepPointRatio, syInletRatio, syExportRatio),
+                        syKeepPointRatio, syInletRatio, syExportRatio, syExportKeepPointRatio),
                 new CostTypeParam("jy", jyPremium, jyCommissionRatio, jyFollowRatio, jyAddThrowRatio,
-                        jyKeepPointRatio, jyInletRatio, jyExportRatio)
+                        jyKeepPointRatio, jyInletRatio, jyExportRatio, jyExportKeepPointRatio)
         );
         // 5. 根据协议类型计算费用
         boolean isPlatformAgreement = ptlAgreement.getAgreementType() == 1;
@@ -129,9 +134,10 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
             BigDecimal keepPoint = calculateFee(basePremium, param.keepPointRatio, SCALE);
             BigDecimal inlet = calculateFee(basePremium, param.inletRatio, SCALE);
             BigDecimal export = calculateFee(basePremium, param.exportRatio, SCALE);
+            BigDecimal exportKeepPoint = calculateFee(basePremium, param.exportKeepPointRatio, SCALE);
 
             // 5.3 设置费用到对象(通过反射或方法引用简化setter调用)
-            setFeeToOrder(insFeeOrders, param.typePrefix, commission, follow, addThrow, keepPoint, inlet, export);
+            setFeeToOrder(insFeeOrders, param.typePrefix, commission, follow, addThrow, keepPoint, inlet, export, exportKeepPoint);
 
             // 5.4 累加总应收/应付款
             totalReceivable = totalReceivable.add(inlet);
@@ -184,10 +190,11 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         BigDecimal keepPointRatio; // 留点比例
         BigDecimal inletRatio; // 入口比例
         BigDecimal exportRatio; // 出口比例
+        BigDecimal exportKeepPointRatio; // 出口留点比例
 
         public CostTypeParam(String typePrefix, BigDecimal premium, BigDecimal commissionRatio,
                              BigDecimal followRatio, BigDecimal addThrowRatio, BigDecimal keepPointRatio,
-                             BigDecimal inletRatio, BigDecimal exportRatio) {
+                             BigDecimal inletRatio, BigDecimal exportRatio, BigDecimal exportKeepPointRatio) {
             this.typePrefix = typePrefix;
             this.premium = premium;
             this.commissionRatio = commissionRatio;
@@ -196,21 +203,25 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
             this.keepPointRatio = keepPointRatio;
             this.inletRatio = inletRatio;
             this.exportRatio = exportRatio;
+            this.exportKeepPointRatio = exportKeepPointRatio;
         }
     }
     // 设置费用到订单对象(通过反射简化重复setter)
     private void setFeeToOrder(InsFeeOrders feeOrders, String prefix,
                                BigDecimal commission, BigDecimal follow, BigDecimal addThrow,
-                               BigDecimal keepPoint, BigDecimal inlet, BigDecimal export) throws ReflectiveOperationException {
+                               BigDecimal keepPoint, BigDecimal inlet, BigDecimal export, BigDecimal exportKeepPoint) throws ReflectiveOperationException {
         Class<?> clazz = InsFeeOrders.class;
-        // 利用反射调用setter方法(如setJqCommissionPremium)
+        // 利用反射调用 setter 方法(如 setJqCommissionPremium)
         setField(feeOrders, clazz, prefix + "CommissionPremium", commission);
         setField(feeOrders, clazz, prefix + "FollowPremium", follow);
         setField(feeOrders, clazz, prefix + "AdditionalPremium", addThrow);
         setField(feeOrders, clazz, prefix + "KeepPointPremium", keepPoint);
         setField(feeOrders, clazz, prefix + "ReceivablePremium", inlet);
         setField(feeOrders, clazz, prefix + "PayablePremium", export);
+        setField(feeOrders, clazz, prefix + "ExportKeepPointPremium", exportKeepPoint);
     }
+// ... existing code ...
+
 
     // 反射设置字段值
     private void setField(InsFeeOrders obj, Class<?> clazz, String fieldName, BigDecimal value) throws ReflectiveOperationException {
@@ -245,8 +256,13 @@ public class InsFeeOrdersServiceImpl extends ServiceImpl<InsFeeOrdersMapper, Ins
         insFeeOrders.setJqExportRatio(covertPercent(ptlAgreementCostRatioVo.getJqExportRatio()));
         insFeeOrders.setSyExportRatio(covertPercent(ptlAgreementCostRatioVo.getSyExportRatio()));
         insFeeOrders.setJyExportRatio(covertPercent(ptlAgreementCostRatioVo.getJyExportRatio()));
+        // 出口留点比例
+        insFeeOrders.setJqExportKeepPointRatio(covertPercent(ptlAgreementCostRatioVo.getJqExportKeepPointRatio()));
+        insFeeOrders.setSyExportKeepPointRatio(covertPercent(ptlAgreementCostRatioVo.getSyExportKeepPointRatio()));
+        insFeeOrders.setJyExportKeepPointRatio(covertPercent(ptlAgreementCostRatioVo.getJyExportKeepPointRatio()));
     }
 
+
     @Override
     public List<InsFeeOrders> getInsFeeOrdersList(InsFeeOrdersParam param) {
         return insFeeOrdersMapper.getInsFeeOrdersList(param);

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

@@ -315,9 +315,21 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
 
             // 税费信息
             VehicleAndVesselTaxVo vehicleAndVesselTax = ordersEnd.getVehicleAndVesselTaxVo();
-            InsOrdersTax insOrdersTax = BeanUtil.copyProperties(vehicleAndVesselTax, InsOrdersTax.class);
-            insOrdersTax.setOrderNo(quoteNo);
-            insOrdersTaxService.updateById(insOrdersTax);
+            if (vehicleAndVesselTax != null) {
+                InsOrdersTax insOrdersTax = BeanUtil.copyProperties(vehicleAndVesselTax, InsOrdersTax.class);
+                insOrdersTax.setOrderNo(quoteNo);
+                // 检查是否存在该记录
+                InsOrdersTax existingTax = insOrdersTaxService.getById(quoteNo);
+                if (existingTax != null) {
+                    // 存在则更新,只更新非空字段
+                    insOrdersTaxService.update(insOrdersTax,
+                            new LambdaUpdateWrapper<InsOrdersTax>()
+                                    .eq(InsOrdersTax::getOrderNo, quoteNo));
+                } else {
+                    // 不存在则插入
+                    insOrdersTaxService.save(insOrdersTax);
+                }
+            }
 
             // 交强险 险种信息
             RiskInfoVo ciRiskInfoVo = ordersEnd.getCiRiskInfoVo();
@@ -338,7 +350,9 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
 
             InsOrdersExternalPolicy ordersExternalPolicy = ordersEnd.getInsOrdersExternalPolicy();
             ordersExternalPolicy.setOrderNo(String.valueOf(quoteNo));
-            policyService.updateById(ordersExternalPolicy);
+            policyService.update(ordersExternalPolicy,
+                    new LambdaUpdateWrapper<InsOrdersExternalPolicy>()
+                            .eq(InsOrdersExternalPolicy::getOrderNo, String.valueOf(quoteNo)));
 
 
             // 返回成功信息,表示订单、车辆和用户信息修改成功
@@ -1120,7 +1134,8 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
             resultVo.setInsFeeOrders(new InsFeeOrdersVo(insFeeOrders));
             List<PtlAgreementCostTypeVo> ptlAgreementCostTypeList = orgClient.queryByCostId(insFeeOrders.getCostId());
             PtlAgreement ptlAgreement = orgClient.getByAgreementId(insOrdersVo.getInsOrders().getAgreementId(), baseController.getToken(), systemCode);
-            resultVo.setCostRatio(new PtlAgreementCostRatioVo(ptlAgreementCostTypeList, ptlAgreement));
+            //resultVo.setCostRatio(new PtlAgreementCostRatioVo(ptlAgreementCostTypeList, ptlAgreement));
+            resultVo.setCostRatio(new PtlAgreementCostRatioVo(insFeeOrders));
         }
         return resultVo;
     }

+ 372 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/utils/LacalLiveTokenUtil.java

@@ -0,0 +1,372 @@
+package com.jzg.quotation.summary.utils;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.jzg.commons.exception.SystemException;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.time.Duration;
+import java.util.List;
+
+/**
+ * 本地生活权益认证工具类
+ * 用于请求获取 token 并自动缓存到 Redis,支持过期自动刷新
+ *
+ * @author wh
+ * @date 2025-03-16
+ */
+@Slf4j
+@Component
+public class LacalLiveTokenUtil {
+
+    @Autowired
+    private  RedissonClient redissonClient;
+
+    @Autowired
+    private  RestTemplate restTemplate;
+
+    @Value("${localLive.base-url}")
+    private  String baseUrl;
+
+    @Value("${localLive.app-key}")
+    private  String appKey;
+
+    @Value("${localLive.app-secret}")
+    private  String appSecret;
+
+    private static final String TOKEN_PREFIX = "localLive:token:";
+    /**
+     * 获取 token 的 URL
+     */
+    private static final String TOKEN_URL = "/channel/api/rightsGrant/login";
+    /**
+     * 权益发放 URL
+     */
+    private static final String GRANT_URL = "/channel/api/rightsGrant/apiGrant";
+
+    /**
+     * Token 响应实体类
+     */
+    @Data
+    public static class TokenResponse {
+        private Integer code;
+        private String message;
+        private ResultDTO result;
+        private Boolean success;
+        private Long timestamp;
+
+        @Data
+        public static class ResultDTO {
+            private String expireTimeAt;
+            private String token;
+        }
+    }
+
+    /**
+     * Token 请求参数
+     */
+    @Data
+    public static class TokenRequest {
+        private String appKey;
+        private String appSecret;
+
+        public TokenRequest(String appKey, String appSecret) {
+            this.appKey = appKey;
+            this.appSecret = appSecret;
+        }
+    }
+
+
+    /**
+     * 权益发放请求参数
+     */
+    @Data
+    public static class RightsGrantRequest {
+        private ReceiverDTO receiverDTO;
+        private String remark;
+        private List<RightsItemDTO> rightsList;
+
+        @Data
+        public static class ReceiverDTO {
+            private String phone;
+            private String plateNo;
+            private String policyNo;
+            private Integer receiverAmountLimit;
+            private String receiverName;
+            private String remark;
+            private String vin;
+        }
+
+        @Data
+        public static class RightsItemDTO {
+            private String rightsContentId;
+            private Integer rightsCount;
+            private Integer rightsType;
+        }
+    }
+
+    /**
+     * 权益发放响应实体类
+     */
+    @Data
+    public static class RightsGrantResponse {
+        private Integer code;
+        private String message;
+        private String result;
+        private Boolean success;
+        private Long timestamp;
+    }
+
+
+    /**
+     * 获取 Token(带自动缓存和刷新)
+     *
+     * @return token
+     */
+    public String getToken() {
+        return getToken(baseUrl , appKey, appSecret, TOKEN_PREFIX);
+    }
+
+    /**
+     * 获取 Token(带自动缓存和刷新,自定义参数)
+     *
+     * @param requestUrl 请求 URL
+     * @param appKey appKey
+     * @param appSecret appSecret
+     * @param redisKeyPrefix Redis key 前缀
+     * @return token
+     */
+    public String getToken(String requestUrl, String appKey, String appSecret, String redisKeyPrefix) {
+        String redisKey = redisKeyPrefix + appKey;
+
+        // 尝试从 Redis 获取 token
+        RBucket<String> bucket = redissonClient.getBucket(redisKey);
+        String cachedToken = bucket.get();
+
+        if (cachedToken != null && !cachedToken.isEmpty()) {
+            log.info("从 Redis 缓存中获取 token: {}", redisKey);
+            return cachedToken;
+        }
+
+        // Redis 中没有,调用 HTTP 接口获取
+        log.info("Redis 缓存未命中,调用 HTTP 接口获取 token: {}", redisKey);
+        TokenResponse response = requestToken(requestUrl+TOKEN_URL, appKey, appSecret);
+
+        // 验证响应
+        if (response == null || !Boolean.TRUE.equals(response.getSuccess())
+                || response.getCode() != 200 || response.getResult() == null) {
+            String errorMsg = response != null ? response.getMessage() : "HTTP 请求失败";
+            log.error("获取 token 失败:{}", errorMsg);
+            throw new SystemException("获取 token 失败:" + errorMsg);
+        }
+
+        String token = response.getResult().getToken();
+        String expireTimeAt = response.getResult().getExpireTimeAt();
+
+        if (token == null || token.isEmpty()) {
+            log.error("获取 token 失败:返回的 token 为空");
+            throw new SystemException("获取 token 失败:返回的 token 为空");
+        }
+
+        // 计算过期时间并存储到 Redis
+        Duration ttl = calculateTTL(expireTimeAt);
+        bucket.set(token, ttl);
+
+        log.info("成功获取并缓存 token: {}, 过期时间:{}秒", redisKey, ttl.getSeconds());
+
+        return token;
+    }
+
+
+    /**
+     * 请求 Token 接口
+     *
+     * @param requestUrl 请求 URL
+     * @param appKey appKey
+     * @param appSecret appSecret
+     * @return TokenResponse
+     */
+    private TokenResponse requestToken(String requestUrl, String appKey, String appSecret) {
+        try {
+            // 构建请求头
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+
+            // 构建请求体
+            TokenRequest request = new TokenRequest(appKey, appSecret);
+            String requestBody = JSON.toJSONString(request);
+
+            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
+
+            log.info("请求 token 接口:{}, 请求参数:{}", requestUrl, requestBody);
+
+            // 发送 POST 请求
+            ResponseEntity<String> responseEntity = restTemplate.postForEntity(
+                    requestUrl, entity, String.class);
+
+            String responseBody = responseEntity.getBody();
+            log.info("token 接口响应:{}", responseBody);
+
+            // 解析响应
+            return JSON.parseObject(responseBody, TokenResponse.class);
+
+        } catch (Exception e) {
+            log.error("请求 token 接口异常:{}", requestUrl, e);
+            throw new SystemException("请求 token 接口异常:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 计算 TTL(单位:秒)
+     *
+     * @param expireTimeAt 过期时间字符串(格式:yyyy-MM-dd HH:mm:ss 或时间戳)
+     * @return TTL 时长
+     */
+    private Duration calculateTTL(String expireTimeAt) {
+        if (expireTimeAt == null || expireTimeAt.isEmpty()) {
+            // 默认 2 小时,提前 2 小时过期
+            return Duration.ofHours(2);
+        }
+        try {
+            // 尝试解析为时间戳
+            long timestamp = Long.parseLong(expireTimeAt);
+            long now = System.currentTimeMillis();
+            long ttlMillis = timestamp - now;
+
+            if (ttlMillis > 0) {
+                // 提前 2 小时(7200 秒)过期
+                long advanceExpirySeconds = Math.max(0, ttlMillis / 1000 - 7200);
+                return Duration.ofSeconds(advanceExpirySeconds);
+            }
+        } catch (NumberFormatException e) {
+            // 不是时间戳,尝试解析日期字符串
+            try {
+                java.time.LocalDateTime expireTime = java.time.LocalDateTime.parse(
+                        expireTimeAt.replace(" ", "T"),
+                        java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME
+                );
+                java.time.LocalDateTime now = java.time.LocalDateTime.now();
+                long ttlSeconds = java.time.Duration.between(now, expireTime).getSeconds();
+
+                if (ttlSeconds > 0) {
+                    // 提前 2 小时(7200 秒)过期
+                    long advanceExpirySeconds = Math.max(0, ttlSeconds - 7200);
+                    return Duration.ofSeconds(advanceExpirySeconds);
+                }
+            } catch (Exception ex) {
+                log.warn("解析过期时间失败,使用默认过期时间:{}", expireTimeAt);
+            }
+        }
+
+        // 默认提前 2 小时过期
+        return Duration.ofHours(2);
+    }
+
+    /**
+     * 手动删除缓存的 token
+     *
+     * @param redisKey Redis key
+     */
+    public void deleteToken(String redisKey) {
+        RBucket<String> bucket = redissonClient.getBucket(redisKey);
+        bucket.delete();
+        log.info("已删除缓存 token: {}", redisKey);
+    }
+
+
+
+    /**
+     * 强制刷新 token
+     */
+    public void refreshToken() {
+        String redisKey = TOKEN_PREFIX + appKey;
+        deleteToken(redisKey);
+        log.info("已清除 token 缓存,下次调用将重新获取");
+    }
+
+
+    /**
+     * 权益发放接口
+     *
+     * @param request 权益发放请求参数
+     * @return 权益发放响应
+     */
+    public RightsGrantResponse apiGrant(RightsGrantRequest request) {
+        // 先获取 token
+        String token = getToken();
+
+        // 构建请求 URL
+        String requestUrl = baseUrl;
+        requestUrl += GRANT_URL;
+
+        log.info("调用权益发放接口:{}, 请求参数:{}", requestUrl, JSON.toJSONString(request));
+
+        try {
+            // 构建请求头
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            headers.set("Authorization", token);
+
+            // 构建请求体
+            String requestBody = JSON.toJSONString(request);
+            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
+
+            // 发送 POST 请求
+            ResponseEntity<String> responseEntity = restTemplate.exchange(
+                    requestUrl,
+                    HttpMethod.POST,
+                    entity,
+                    String.class
+            );
+
+            String responseBody = responseEntity.getBody();
+            log.info("权益发放接口响应:{}", responseBody);
+
+            // 解析响应
+            RightsGrantResponse response = JSON.parseObject(responseBody, RightsGrantResponse.class);
+
+            // 验证响应
+            if (response == null || !Boolean.TRUE.equals(response.getSuccess())
+                    || response.getCode() != 200) {
+                String errorMsg = response != null ? response.getMessage() : "HTTP 请求失败";
+                log.error("权益发放失败:{}", errorMsg);
+                throw new SystemException("权益发放失败:" + errorMsg);
+            }
+
+            return response;
+
+        } catch (Exception e) {
+            log.error("调用权益发放接口异常:{}", requestUrl, e);
+            throw new SystemException("调用权益发放接口异常:" + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 权益发放接口(简化版,直接传入 JSON 对象)
+     *
+     * @param receiverDTO 接收人信息
+     * @param rightsList 权益列表
+     * @param remark 备注
+     * @return 权益发放响应
+     */
+    public RightsGrantResponse apiGrant(JSONObject receiverDTO, JSONArray rightsList, String remark) {
+        RightsGrantRequest request = new RightsGrantRequest();
+        request.setReceiverDTO(receiverDTO.toJavaObject(RightsGrantRequest.ReceiverDTO.class));
+        request.setRightsList(rightsList.toJavaList(RightsGrantRequest.RightsItemDTO.class));
+        request.setRemark(remark);
+        return apiGrant(request);
+    }
+
+
+
+}

+ 1 - 1
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/api/service/Impl/ZiJinApiRequestImpl.java

@@ -1,4 +1,4 @@
-package com.jzg.quotation.zijin.api.service.impl;
+package com.jzg.quotation.zijin.api.service.Impl;
 
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.entity.orders.po.InsOrdersCosts;

+ 1 - 1
tenant/insurance/quotation-zijin/src/main/java/com/jzg/quotation/zijin/api/service/Impl/ZiJinOrderServiceImpl.java

@@ -1,4 +1,4 @@
-package com.jzg.quotation.zijin.api.service.impl;
+package com.jzg.quotation.zijin.api.service.Impl;
 
 import com.jzg.commons.entity.quote.vo.QuoteVo;
 import com.jzg.quotation.zijin.api.entity.po.ZiJinApiOrder;

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

@@ -58,6 +58,7 @@
         <result column="export" property="export" jdbcType="DECIMAL"/>
         <result column="add_throw" property="addThrow" jdbcType="DECIMAL"/>
         <result column="keep_point_ratio" property="keepPointRatio" jdbcType="DECIMAL"/>
+        <result column="export_keep_point_ratio" property="exportKeepPointRatio" jdbcType="DECIMAL"/>
     </resultMap>
 
 
@@ -288,6 +289,7 @@
             tt.export,
             tt.add_throw,
             tt.keep_point_ratio,
+            tt.export_keep_point_ratio,
             CASE
                 WHEN tt.cost_type = '交强险' THEN pa.jq_entrance_fee_ratio
                 WHEN tt.cost_type = '商业险' THEN pa.sy_entrance_fee_ratio