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

Merge branch 'master' into wrq_dev

wangrq 2 месяцев назад
Родитель
Сommit
82367d24fd
39 измененных файлов с 951 добавлено и 251 удалено
  1. 50 0
      commons/src/main/java/com/jzg/commons/constants/InvoiceTypeEnum.java
  2. 4 0
      commons/src/main/java/com/jzg/commons/entity/account/po/SysUserAccountChangeLog.java
  3. 20 0
      commons/src/main/java/com/jzg/commons/entity/dto/GenerateQrcodeParam.java
  4. 20 0
      commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncome.java
  5. 3 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/FollowCompanyFeeVO.java
  6. 3 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/SettlementReportQueryVo.java
  7. 3 0
      commons/src/main/java/com/jzg/commons/entity/vo/InsOrdersOtherInfoVo.java
  8. 2 0
      commons/src/main/java/com/jzg/commons/entity/vo/RuleAttrMappingVo.java
  9. 1 0
      commons/src/main/java/com/jzg/commons/service/impl/OperatorTrajectoryServiceImpl.java
  10. 14 0
      commons/src/main/java/com/jzg/quotation/commons/constant/SpElMapping.java
  11. 0 1
      commons/src/main/java/com/jzg/quotation/commons/utils/SpElFieldExtractor.java
  12. 1 1
      commons/src/main/java/com/jzg/quotation/summary/aop/aspect/OrderOperationLog.java
  13. 2 0
      commons/src/main/java/com/jzg/quotation/summary/constants/QuoteNumberConstant.java
  14. 2 85
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/AnShengCrawlerCalculatePremiumApplyMessage.java
  15. 1 0
      tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerRequestImpl.java
  16. 9 13
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/client/LocalLivingClient.java
  17. 41 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/client/UnifiedAccountClient.java
  18. 9 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsFeeAuditController.java
  19. 1 3
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/InsOrderAdjustController.java
  20. 236 88
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java
  21. 178 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/entity/vo/LocalLivingActivityTableVO.java
  22. 100 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/entity/vo/LocalLivingLotteryActivityAwardVO.java
  23. 100 0
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/entity/vo/LocalLivingLotteryActivityVO.java
  24. 2 2
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/InsOrdersMapper.java
  25. 1 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  26. 3 1
      tenant/insurance/quotation-summary/src/main/resources/application-dev.yaml
  27. 4 4
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml
  28. 15 2
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/component/TaiShanCrawlerCacheComponent.java
  29. 2 1
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/component/TaiShanCrawlerRequestComponent.java
  30. 21 14
      tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/service/impl/TaiShanCrawlerRequestImpl.java
  31. 2 0
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Response/ZmCrawlerFindZfTaskResponse.java
  32. 5 0
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/Impl/ZhongMeiCrawlerRequestImpl.java
  33. 5 0
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/Impl/ZmCrawlerOrderServiceImpl.java
  34. 2 0
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/ZmCrawlerOrderService.java
  35. 1 0
      tenant/organization/src/main/java/com/jzg/organization/controller/InsFeeFollowOrderReconciliationController.java
  36. 12 2
      tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java
  37. 1 1
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserAccountIncomeLogMapper.java
  38. 66 23
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  39. 9 8
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

+ 50 - 0
commons/src/main/java/com/jzg/commons/constants/InvoiceTypeEnum.java

@@ -0,0 +1,50 @@
+package com.jzg.commons.constants;
+
+/**
+ * 费用类型枚举
+ */
+public enum InvoiceTypeEnum {
+
+    /** 1、手续费 */
+    FEE_1("1", "手续费"),
+    /** 2、跟单费 */
+    FEE_2("2", "跟单费"),
+    /** 3、驾意险手续费 */
+    FEE_3("3", "驾意险手续费"),
+    /** 4、驾意险跟单费 */
+    FEE_4("4", "驾意险跟单费"),
+    /** 5、平台应收-车险 */
+    FEE_5("5", "平台应收-车险"),
+    /** 6、平台应收-非车险 */
+    FEE_6("6", "平台应收-非车险");
+
+    // 编码(String类型)
+    private final String code;
+    // 名称(String类型)
+    private final String desc;
+
+    InvoiceTypeEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    /**
+     * 根据code获取枚举
+     */
+    public static InvoiceTypeEnum getByCode(String code) {
+        for (InvoiceTypeEnum value : values()) {
+            if (value.getCode().equals(code)) {
+                return value;
+            }
+        }
+        return null;
+    }
+}

+ 4 - 0
commons/src/main/java/com/jzg/commons/entity/account/po/SysUserAccountChangeLog.java

@@ -47,6 +47,10 @@ public class SysUserAccountChangeLog extends BaseModel {
     @Schema(description = "jzg_info表的序号")
     private String jzgInfoId;
 
+    @ExcelProperty("车牌号")
+    @Schema(description = "车牌号")
+    private String licenseNo;
+
     @ExcelProperty("操作前金额")
     @Schema(description = "操作前金额")
     private BigDecimal amountBefore;

+ 20 - 0
commons/src/main/java/com/jzg/commons/entity/dto/GenerateQrcodeParam.java

@@ -0,0 +1,20 @@
+package com.jzg.commons.entity.dto;
+
+import lombok.Data;
+
+/**
+ * 获取本地生活二维码参数实体
+ */
+@Data
+public class GenerateQrcodeParam {
+    /**
+     * 活动id
+     */
+    private String activityId;
+    /**
+     * 拼接参数(活动id,手机号,抽奖次数)
+     */
+    private String query;
+
+
+}

+ 20 - 0
commons/src/main/java/com/jzg/commons/entity/finance/po/InsPlyIncome.java

@@ -199,6 +199,26 @@ public class InsPlyIncome extends BaseModel {
     @ExcelProperty("总应收金额")
     private String receivableAmount;
 
+    @TableField(exist = false)
+    @Schema(description = "车险应收手续费")
+    @ExcelProperty("车险应收手续费")
+    private String carInsuranceSuperviseCostsPremiums;
+
+    @TableField(exist = false)
+    @Schema(description = "非车险应收手续费")
+    @ExcelProperty("非车险应收手续费")
+    private String nonCarInsuranceSuperviseCostsPremiums;
+
+    @TableField(exist = false)
+    @Schema(description = "车险应收跟单费")
+    @ExcelProperty("车险应收跟单费")
+    private String carInsuranceOtherCostsPremiums;
+
+    @TableField(exist = false)
+    @Schema(description = "非车险应收跟单费")
+    @ExcelProperty("非车险应收跟单费")
+    private String nonCarInsuranceOtherCostsPremiums;
+
     @Schema(description = "手续费是否已经结算")
     @ExcelIgnore
     private String superviseSettlement;

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

@@ -51,6 +51,9 @@ public class FollowCompanyFeeVO {
     /** 累计应收  totalReceivable */
     private BigDecimal totalReceivable;
 
+    /** 对账金额  totalReceivable */
+    private BigDecimal totalReconciliationAmount;
+
     /**
      * 开票记录id
      */

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

@@ -13,6 +13,9 @@ import java.util.List;
 
 @Data
 public class SettlementReportQueryVo extends PageRequest {
+    @Schema(description = "应收项/10车险20非车险30全部")
+    private String accountsReceivable;
+
     @Schema(description = "保险公司id")
     private String companyId;
 

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

@@ -100,6 +100,9 @@ public class InsOrdersOtherInfoVo {
     @Schema(description = "商业折扣")
     private BigDecimal syAdjustRate;
 
+    @Schema(description = "整单折扣")
+    private BigDecimal totalAdjustRate;
+
 //    @Schema(description = "太平绿黄红区间评分")
 //    private String tpColorScore;
 //

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

@@ -51,6 +51,8 @@ public class RuleAttrMappingVo {
 //        ruleAttrMappingVoList.add(new RuleAttrMappingVo("VehicleUseCode", VehicleUseCode.getByCode(insOrdersCarInfo.getVehicleUseCode())));
         ruleAttrMappingVoList.add(new RuleAttrMappingVo("VehicleUseCode", insOrdersCarInfo.getVehicleUseCode()));
         //车辆种类
+        ruleAttrMappingVoList.add(new RuleAttrMappingVo("CarKindCode", insOrdersCarInfo.getCarKindCode()));
+        //使用性质
         ruleAttrMappingVoList.add(new RuleAttrMappingVo("CarNatureCode", insOrdersCarInfo.getCarNatureCode()));
         //车辆类型
         ruleAttrMappingVoList.add(new RuleAttrMappingVo("CarTypeCode", insOrdersCarInfo.getCarTypeCode()));

+ 1 - 0
commons/src/main/java/com/jzg/commons/service/impl/OperatorTrajectoryServiceImpl.java

@@ -66,6 +66,7 @@ public class OperatorTrajectoryServiceImpl implements OperatorTrajectoryService
         lambdaQueryWrapper.like(StringUtils.isNotEmpty(logParam.getOperator()),OperatorTrajectory::getCreateBy,logParam.getOperator());
         lambdaQueryWrapper.like(StringUtils.isNotEmpty(logParam.getFunction()),OperatorTrajectory::getModuleName,logParam.getFunction());
         lambdaQueryWrapper.like(StringUtils.isNotEmpty(logParam.getContent()),OperatorTrajectory::getOperationContent,logParam.getContent());
+        lambdaQueryWrapper.orderByDesc(OperatorTrajectory::getCreateTime);
         if (CollectionUtils.isNotEmpty(logParam.getOperatingTime())) {
             List<LocalDate> dates = logParam.getOperatingTime();
             if (dates.size() >= 2) {

+ 14 - 0
commons/src/main/java/com/jzg/quotation/commons/constant/SpElMapping.java

@@ -0,0 +1,14 @@
+package com.jzg.quotation.commons.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SpElMapping {
+
+    private String fieldName;   // 最终生成日志的字段名,如 "orderId"
+    private String spel;        // SpEL 表达式,如 "#ret.data.orderId"
+}

+ 0 - 1
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/utils/SpElFieldExtractor.java → commons/src/main/java/com/jzg/quotation/commons/utils/SpElFieldExtractor.java

@@ -1,6 +1,5 @@
 package com.jzg.quotation.commons.utils;
 
-import com.alibaba.fastjson2.JSON;
 import com.jzg.quotation.commons.constant.SpElMapping;
 import org.springframework.expression.EvaluationContext;
 import org.springframework.expression.ExpressionParser;

+ 1 - 1
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/OrderOperationLog.java → commons/src/main/java/com/jzg/quotation/summary/aop/aspect/OrderOperationLog.java

@@ -1,4 +1,4 @@
-package com.jzg.quotation.summary.aop;
+package com.jzg.quotation.summary.aop.aspect;
 
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 

+ 2 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/constants/QuoteNumberConstant.java → commons/src/main/java/com/jzg/quotation/summary/constants/QuoteNumberConstant.java

@@ -93,6 +93,8 @@ public class QuoteNumberConstant {
         OPT_TYPE_12(12,"批改审核"),
         OPT_TYPE_13(13,"撤销批改"),
         OPT_TYPE_14(14,"订单审核"),
+        OPT_TYPE_15(15,"费用调整"),
+        OPT_TYPE_16(16,"批量修改比例"),
         ;
         private Integer code;
         private String desc;

+ 2 - 85
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/entity/request/AnShengCrawlerCalculatePremiumApplyMessage.java

@@ -168,89 +168,6 @@ public class AnShengCrawlerCalculatePremiumApplyMessage {
         }
 
 
-        /**
-         *
-
-
-         public PolicyCoveragesDTO(KindInfoVo kind) {
-         this.dutyCode = kind.getKindCode();
-         this.dutyChineseName = kind.getKindName();
-         this.insuredAmount = (StringUtils.equals(kind.getKindCode(),"STORRS") || StringUtils.equals(kind.getKindCode(),"NESTORR")) ? "" : kind.getUnitAmount() ;
-         this.equipmentInsureAmount = "";
-         this.premiumRate = "";
-         this.deductibleDiscount = "";
-         this.totalActualPremium = "";
-         this.deductionRate = "0";
-         this.serviceNum = StringUtils.isNotEmpty(kind.getServiceTimes()) ? kind.getServiceTimes() : "";
-         this.isTelpeson = (StringUtils.equals(kind.getKindCode(),"STORRS") || StringUtils.equals(kind.getKindCode(),"NESTORR")) ? "1" : "";
-         this.telPhone = "";
-         this.mileage = "";
-         this.setMeal = "";
-         this.fireMultiple = "";
-         this.allAmount = "";
-         this.riskPremum = "";
-         this.seats = kind.getQuantity();
-         this.deductible = "";
-         this.totalStandardPremium = 0;
-         this.addedValueTax = 0;
-         this.totalAgreePremium = 0;
-         this.totalNetPremium = 0;
-         this.newEquipmentList = new ArrayList<>();
-         this.chargingPostDataList = new ArrayList<>();
-         this.fullYearPremium = "";
-         this.dieAmount = "";
-         this.medicalAmount = "";
-         this.propertyAmount = "";
-         this.noFaultDieAmount = "";
-         this.noFaultMedicalAmount = "";
-         this.noFaultPropertyAmount = "";
-         this.basePremium = "";
-         }
-         }
-
-
-
-
-         PolicyCoveragesDTO dto = new PolicyCoveragesDTO();
-         dto.setDutyCode(StringUtils.equals("0",energyTypeCode) ? "STORRS" : "NESTORR");
-         dto.setDutyChineseName(StringUtils.equals("0",energyTypeCode) ? "道路救援服务特约条款" : "道路救援服务特约条款(新能源车)");
-         dto.setInsuredAmount("0");
-         dto.setEquipmentInsureAmount("");
-         dto.setPremiumRate("");
-         dto.setDeductibleDiscount("");
-         dto.setTotalActualPremium("");
-         dto.setDeductionRate("0");
-         dto.setServiceNum("2");
-         dto.setIsTelpeson("1");
-         dto.setTelPhone("");
-         dto.setMileage("");
-         dto.setSetMeal("");
-         dto.setFireMultiple("");
-         dto.setAllAmount("");
-         dto.setRiskPremum("");
-         dto.setSeats("");
-         dto.setDeductible("");
-         dto.setTotalStandardPremium(0);
-         dto.setAddedValueTax(0);
-         dto.setTotalAgreePremium(0);
-         dto.setTotalNetPremium(0);
-         dto.setNewEquipmentList(Lists.newArrayList());
-         dto.setChargingPostDataList(Lists.newArrayList());
-         dto.setFullYearPremium("");
-         dto.setDieAmount("");
-         dto.setMedicalAmount("");
-         dto.setPropertyAmount("");
-         dto.setNoFaultDieAmount("");
-         dto.setNoFaultMedicalAmount("");
-         dto.setNoFaultPropertyAmount("");
-         dto.setBasePremium("");
-
-
-
-         */
-
-
-
         public ContractsDTO(RiskInfoVo riskInfoVo, QuoteVo quoteVo, AnShengCrawlerSearchVehicleByVinResponse.DataDTO dataDTO,
                             String customerNegotiatePrice, AnShengCrawlerGetUserDetailResponse.DataDTO.AgentDefineDTO userDetailResponse,
                             String planCode, String productCode, String checkVehicleCodeSecret) {
@@ -1586,13 +1503,13 @@ public class AnShengCrawlerCalculatePremiumApplyMessage {
                 boolean b = StringUtils.equals(kind.getKindCode(), "STORRS") || StringUtils.equals(kind.getKindCode(), "NESTORR");
                 this.dutyCode = kind.getKindCode();
                 this.dutyChineseName = kind.getKindName();
-                this.insuredAmount = b ? "0" : kind.getUnitAmount();
+                this.insuredAmount = b ? "0" : kind.getAmount();
                 this.equipmentInsureAmount = "";
                 this.premiumRate = "";
                 this.deductibleDiscount = "";
                 this.totalActualPremium = "";
                 this.deductionRate = "0";
-                this.serviceNum = b ? kind.getServiceTimes() : "";
+                this.serviceNum = b ? kind.getAmount() : "";
                 this.isTelpeson = b ? "1" : "";
                 this.telPhone = "";
                 this.mileage = "";

+ 1 - 0
tenant/insurance/quotation-ansheng/src/main/java/com/jzg/quotation/ansheng/crawler/service/impl/AnShengCrawlerRequestImpl.java

@@ -535,6 +535,7 @@ public class AnShengCrawlerRequestImpl implements AnShengCrawlerRequest {
                     }
                 } else if ("0".equals(baseMark)) {
                     String reason = queryFailure(targetPolicyNos, httpHeaders);
+                    resultVo.setOrderStatus(InsOrderStatusEnum.AUDIT_FAIL);
                     resultVo.setErrorMsg(reason);
                 } else if ("1".equals(baseMark)) {
                     log.info("人工处理中,请稍等...");

+ 9 - 13
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/client/LocalLivingClient.java

@@ -1,10 +1,11 @@
 package com.jzg.quotation.summary.client;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.databind.JsonNode;
 import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.GenerateQrcodeParam;
 import com.jzg.commons.entity.dto.LotteryCounDTO;
 import com.jzg.commons.entity.dto.UnifiedUserCenterDTO;
-import com.jzg.commons.entity.vo.LotteryActivityVO;
 import com.jzg.commons.entity.vo.LotteryCountVO;
 import com.jzg.commons.entity.vo.UnifiedUserClientVO;
 import com.jzg.quotation.summary.entity.Result;
@@ -76,7 +77,7 @@ public interface LocalLivingClient {
      * @return 活动列表
      */
     @GetMapping("lottery/lotteryActivity/queryActivityList")
-    HttpResult<List<LotteryActivityVO>> queryActivityRules(@RequestParam("scene") Integer scene);
+    JsonNode queryActivityRules(@RequestParam("scene") Integer scene);
     /**
      * 添加用户抽奖次数
      *
@@ -86,18 +87,13 @@ public interface LocalLivingClient {
     @PostMapping("/localUserLotteryCount/add")
     HttpResult<LotteryCountVO> addLotteryCount(@RequestBody LotteryCounDTO lotteryCounDTO);
 
+
     /**
-     * 查询用户绑定
-     * @param unifiedUserCenterDTO
-     * @return
-     */
-    @PostMapping("/userApp/queryBind")
-    HttpResult<UnifiedUserClientVO> queryBind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
-    /**
-     * 添加用户绑定
-     * @param unifiedUserCenterDTO
+     * 获取小程序二维码
+     * @param param
      * @return
      */
-    @PostMapping("/userApp/bind")
-    HttpResult<UnifiedUserClientVO> bind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
+    @PostMapping("/lottery/lotteryActivity/generateQrcode")
+    Result<String> generateQrcode(@RequestBody GenerateQrcodeParam param);
+
 }

+ 41 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/client/UnifiedAccountClient.java

@@ -0,0 +1,41 @@
+package com.jzg.quotation.summary.client;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.LotteryCounDTO;
+import com.jzg.commons.entity.dto.UnifiedUserCenterDTO;
+import com.jzg.commons.entity.vo.LotteryCountVO;
+import com.jzg.commons.entity.vo.UnifiedUserClientVO;
+import com.jzg.quotation.summary.entity.Result;
+import com.jzg.quotation.summary.entity.dto.*;
+import com.jzg.quotation.summary.entity.vo.ChannelRightsPackageVO;
+import com.jzg.quotation.summary.entity.vo.ChannelRightsVO;
+import com.jzg.quotation.summary.utils.FeignConfig;
+import jakarta.validation.Valid;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 调用一账通client
+ */
+@FeignClient(value = "jeecg-boot", url = "${feign.client.unifiedAccountClient.url}" )
+public interface UnifiedAccountClient {
+
+    /**
+     * 查询用户绑定
+     * @param unifiedUserCenterDTO
+     * @return
+     */
+    @PostMapping("/userApp/queryBind")
+    HttpResult<UnifiedUserClientVO> queryBind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
+    /**
+     * 添加用户绑定
+     * @param unifiedUserCenterDTO
+     * @return
+     */
+    @PostMapping("/userApp/bind")
+    HttpResult<UnifiedUserClientVO> bind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
+}

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

@@ -12,7 +12,7 @@ import com.jzg.commons.entity.orders.vo.AuditCostInfoVo;
 import com.jzg.commons.entity.orders.vo.FeeAuditVo;
 import com.jzg.commons.entity.quote.vo.aggregated.QuoteEchoVo;
 import com.jzg.commons.entity.vo.PtlAgreementCostRatioVo;
-import com.jzg.quotation.summary.aop.OrderOperationLog;
+import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 import com.jzg.quotation.summary.service.InsFeeAuditService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -184,6 +184,14 @@ public class InsFeeAuditController {
      * 保存调整的费用
      * @return HttpResult<String>
      */
+    @OrderOperationLog(
+            module = "订单审核",
+            subModule = "我的审核",
+            optType = QuoteNumberConstant.QuoteOptType.OPT_TYPE_15,
+            description = "费用调整",
+            orderSpEl = "#quoteVo",
+            feedbackSpEl = "#ret.code + ' - ' + #ret.msg+ ' - ' + #ret.data"
+    )
     @PostMapping("/saveCostInfo")
     @Operation(summary = "保存调整的费用")
     public HttpResult<String> saveCostInfo(@RequestBody PtlAgreementCostRatioVo param){

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

@@ -8,15 +8,13 @@ import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.core.page.HttpResult;
 import com.jzg.commons.entity.dto.*;
 import com.jzg.commons.entity.orders.po.InsOrderAdjust;
-import com.jzg.commons.entity.orders.po.InsOrderAdjustInfo;
 import com.jzg.commons.entity.orders.po.InsOrders;
-import com.jzg.commons.entity.vo.AdjustAllRefundInfoVo;
 import com.jzg.commons.entity.vo.AdjustAllRefundVo;
 import com.jzg.commons.entity.vo.OrderAdjustVo;
 import com.jzg.commons.util.AssertionUtils;
 import com.jzg.commons.util.EasyExcelUtils;
 import com.jzg.commons.util.ServletUtils;
-import com.jzg.quotation.summary.aop.OrderOperationLog;
+import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 import com.jzg.quotation.summary.service.InsOrderAdjustInfoService;
 import com.jzg.quotation.summary.service.InsOrderAdjustService;

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

@@ -10,7 +10,12 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jzg.commons.constants.CompanyConstants;
 import com.jzg.commons.constants.InsuranceRisk;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
@@ -18,6 +23,7 @@ import com.jzg.commons.constants.quote.enums.base.QuoteRuleCategory;
 import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.core.base.StateResult;
 import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.GenerateQrcodeParam;
 import com.jzg.commons.entity.dto.LotteryCounDTO;
 import com.jzg.commons.entity.dto.MessageAddParam;
 import com.jzg.commons.entity.dto.UnifiedUserCenterDTO;
@@ -46,14 +52,18 @@ import com.jzg.quotation.commons.service.QuotationCrawlerBaseService;
 import com.jzg.quotation.commons.utils.SnowFlakeUtil;
 import com.jzg.quotation.guoren.crawler.service.GuoRenCrawlerRequest;
 import com.jzg.quotation.summary.aop.AuditVerification;
-import com.jzg.quotation.summary.aop.OrderOperationLog;
+import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
 import com.jzg.quotation.summary.aop.QuoteVerification;
 import com.jzg.quotation.summary.async.AsyncGetPayLink;
 import com.jzg.quotation.summary.classifier.QuoteInfoParameterFilling;
 import com.jzg.quotation.summary.client.LocalLivingClient;
+import com.jzg.quotation.summary.client.UnifiedAccountClient;
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 import com.jzg.quotation.summary.converter.QuoteInfoConverter;
+import com.jzg.quotation.summary.entity.Result;
 import com.jzg.quotation.summary.entity.po.QuoteRuleMapping;
+import com.jzg.quotation.summary.entity.vo.LocalLivingActivityTableVO;
+import com.jzg.quotation.summary.entity.vo.LocalLivingLotteryActivityVO;
 import com.jzg.quotation.summary.factory.CompanyFactory;
 import com.jzg.quotation.summary.service.*;
 import com.jzg.quotation.summary.state.listener.OrderStateListener;
@@ -72,6 +82,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
+import javax.annotation.Resource;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -168,14 +179,22 @@ public class UnifyOrderManager {
 
     @Autowired
     private LocalLivingClient localLivingClient;
+    @Autowired
+    private UnifiedAccountClient unifiedAccountClient;
+
+    @Autowired
+    private ObjectMapper objectMapper;
 
     @Value("${lottery.activity.scene:3}")
     private Integer lotteryScene;
 
+    @Value("${feign.client.jeecg-boot.url}")
+    private String LocalLivingUrl;
 
 
     //本地生活在一账通的固定平台ID
     private static final String CLIENT_ID = "bdsh-X9yZ1wV3uT5sR7qP9o";
+    private static final String JZG_CLIENT_ID = "jzg-7kP9xL2mN5vQ8zR1jW";
 
     private String getSystemCode() {
         //如果是APP登录的话 则传递SystemCode的头部字段
@@ -324,7 +343,7 @@ public class UnifyOrderManager {
             Throwable root = e.getCause() != null ? e.getCause() : e;
             String errMsg = root.getMessage() != null ? root.getMessage() : "系统异常,报价失败";
             // 去除异常类名前缀
-            if (errMsg.matches("^[a-zA-Z0-9.]+Exception:.*")) {
+            if (errMsg.matches("[a-zA-Z0-9.]+Exception:[\\s\\S]*")) {
                 errMsg = errMsg.substring(errMsg.indexOf(":") + 1).trim();
             }
             try {
@@ -340,9 +359,11 @@ public class UnifyOrderManager {
 
     /**
      * 记录规则完成
+     *
+     * @return true-本次新增记录;false-已存在记录,未新增
      */
-    private void completeRule(String tenantId, String userId, String userPhone, String activityId,
-                              String tableId, String qutNum, String qutLotteryNum, String qutLotteryMax, Integer status, Integer activityType) {
+    private boolean completeRule(String tenantId, String userId, String userPhone, String activityId,
+                                 String tableId, String qutNum, String qutLotteryNum, String qutLotteryMax, Integer status, Integer activityType) {
         SysUserActivityCompleteInRule exist = null;
         // 先查询是否已存在记录(防重入)
         if (9 != activityType) {
@@ -354,22 +375,23 @@ public class UnifyOrderManager {
         }
 
         if (exist != null) {
-            return;
+            return false;
         }
 
         SysUserActivityCompleteInRule record = new SysUserActivityCompleteInRule();
+        record.setId(IdWorker.getIdStr());
         record.setSystemCode(tenantId);
         record.setUserId(userId);
         record.setUserPhone(userPhone);
         record.setActivityType(activityType);
         record.setActivityId(activityId);
         record.setLocalActivityTableId(tableId);
-        //报价次数
+        // 报价规则中这里记录“触发发放时的当天报价次数”,避免 qutNum 固定为 1 时第二次报价被防重拦截。
         record.setRuleCompleteNum(qutNum);
-        //抽奖次数
+        // 本次实际新增的抽奖次数
         record.setLotteryNum(StrUtil.isNotBlank(qutLotteryNum)
                 ? Integer.parseInt(qutLotteryNum) : 0);
-        //报价用,今日抽奖最大次数
+        // 报价用,今日抽奖最大次数
         record.setLotteryMaxNum(StrUtil.isNotBlank(qutLotteryMax)
                 ? Integer.parseInt(qutLotteryMax) : 0);
         record.setStatus(status);
@@ -380,6 +402,7 @@ public class UnifyOrderManager {
 
         log.info("报价规则完成,tenantId={}, userId={}, activityId={}, qutNum={}, qutLotteryNum={}, qutLotteryMax={}",
                 tenantId, userId, activityId, qutNum, qutLotteryNum, qutLotteryMax);
+        return true;
     }
 
     /**
@@ -398,16 +421,16 @@ public class UnifyOrderManager {
     private void handleQuoteLotteryActivity(QuoteVo quoteVo) {
         try {
             // 远程调用活动列表
-            HttpResult<List<LotteryActivityVO>> result = localLivingClient.queryActivityRules(lotteryScene);
-            if (result == null || result.getCode() != 200 || result.getData() == null) {
-                log.error("统一报价,查询本地生活的活动列表异常");
+            List<LocalLivingLotteryActivityVO> activities = queryLotteryActivities(lotteryScene);
+            if (CollUtil.isEmpty(activities)) {
                 return;
             }
 
-            String tenantId = baseController.getUserSystemCode();
-            String userId = quoteVo.getOrder().getRealQuoteUserId();
+            String tenantId = baseController.getSystemCode();
+            String userId = baseController.getUserId();
+            String quoteUserId = quoteVo.getOrder().getRealQuoteUserId();
 
-            for (LotteryActivityVO activity : result.getData()) {
+            for (LocalLivingLotteryActivityVO activity : activities) {
                 // 检查活动是否有效(当前时间需在活动时间范围内)
                 if (LocalDate.now().isBefore(activity.getActivityStartTime())
                         || LocalDate.now().isAfter(activity.getActivityEndTime())) {
@@ -417,7 +440,7 @@ public class UnifyOrderManager {
                     continue;
                 }
 
-                for (LocalActivityTableVO table : activity.getLocalActivityTables()) {
+                for (LocalLivingActivityTableVO table : activity.getLocalActivityTables()) {
                     // 只处理 type=6 的报价规则
                     if (!"6".equals(table.getType())) {
                         continue;
@@ -428,13 +451,13 @@ public class UnifyOrderManager {
                     }
 
                     // 查询用户是否在一账通绑定过本地生活
-                    HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId, tenantId);
+                    HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId,quoteUserId, tenantId);
                     if (bindResult == null || bindResult.getCode() != 200 || bindResult.getData() == null) {
                         // 未绑定:统计报价次数,满足条件则存本地记录
-                        handleUnboundQuoteRule(tenantId, userId, activity, table);
+                        handleUnboundQuoteRule(tenantId, quoteUserId, activity, table);
                     } else {
                         // 已绑定:检查是否绑定了本地生活客户端,若绑定了则远程同步抽奖次数
-                        handleBoundQuoteRule(tenantId, userId, activity, table, bindResult.getData());
+                        handleBoundQuoteRule(tenantId, quoteUserId, activity, table, bindResult.getData());
                     }
                 }
             }
@@ -443,16 +466,39 @@ public class UnifyOrderManager {
         }
     }
 
+    /**
+     * 查询本地生活抽奖活动列表
+     */
+    private List<LocalLivingLotteryActivityVO> queryLotteryActivities(Integer lotteryScene) {
+        JsonNode response = localLivingClient.queryActivityRules(lotteryScene);
+        if (response == null) {
+            log.error("查询本地生活活动列表异常,返回为空");
+            return Collections.emptyList();
+        }
+        if (!response.path("success").asBoolean(false) || response.path("code").asInt() != 200) {
+            log.error("查询本地生活活动列表异常,response={}", response);
+            return Collections.emptyList();
+        }
+        JsonNode resultNode = response.get("result");
+        if (resultNode == null || !resultNode.isArray() || resultNode.isEmpty()) {
+            log.error("查询本地生活活动列表异常,result为空,response={}", response);
+            return Collections.emptyList();
+        }
+        return objectMapper.convertValue(resultNode, new TypeReference<List<LocalLivingLotteryActivityVO>>() {
+        });
+    }
+
     /**
      * 查询用户在一账通的绑定状态
      */
-    private HttpResult<UnifiedUserClientVO> queryUserBind(String userId, String tenantId) {
+    private HttpResult<UnifiedUserClientVO> queryUserBind(String userId,String userPhone, String tenantId) {
         UnifiedUserCenterDTO dto = new UnifiedUserCenterDTO();
         dto.setUserId(userId);
-        dto.setClientId(CLIENT_ID);
+        dto.setClientId(JZG_CLIENT_ID);
         dto.setTenantId(tenantId);
+        dto.setUserPhone(userPhone);
         try {
-            return localLivingClient.queryBind(dto);
+            return unifiedAccountClient.queryBind(dto);
         } catch (Exception e) {
             log.info("业务员报价,查询用户绑定一账通接口异常,userId:{},clientId:{},tenantId:{}", userId, CLIENT_ID, tenantId);
             log.error("业务员报价,查询用户绑定一账通接口异常", e);
@@ -461,28 +507,78 @@ public class UnifyOrderManager {
     }
 
     /**
-     * 处理未绑定用户的报价规则:统计报价次数,满足条件则存本地记录
+     * 处理未绑定用户的报价规则:统计当天报价次数,满足条件则存本地记录。
+     * <p>
+     * 规则示例:报价1次得1次抽奖机会,每天最多2次。
+     * count=1 时本次新增1次;count=2 时本次新增1次;count>=3 时达到上限,不再新增。
      */
     private void handleUnboundQuoteRule(String tenantId, String userId,
-                                         LotteryActivityVO activity, LocalActivityTableVO table) {
+                                         LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
         int count = insOrdersService.countQuoteNum(tenantId, userId,
-                activity.getActivityStartTime(), activity.getActivityEndTime());
-        if (count >= Integer.parseInt(table.getQutNum())
-                && count <= Integer.parseInt(table.getQutLotteryMax())) {
-            completeRule(tenantId, userId, null, activity.getId(),
-                    table.getId(), table.getQutNum(), table.getQutLotteryNum(),
-                    table.getQutLotteryMax(), YesNoEnum.NO.getCode(), 6);
-            log.info("业务员报价,满足条件插入记录,userId:{},clientId:{},tenantId:{}",
-                    userId, CLIENT_ID, tenantId);
-            // 发送抽奖次数下发通知消息
-            HttpResult<SysUserJzgInfo> sysUser = orgClient.queryUserByUserId(userId,tenantId);
+                LocalDate.now(), LocalDate.now());
+        int currentGrantNum = calculateCurrentQuoteLotteryNum(count, table);
+        if (currentGrantNum <= 0) {
+            return;
+        }
 
-            MessageAddParam param = new MessageAddParam();
-            param.setTitle("抽奖次数下发通知消息");
-            param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
-            param.setTplCode("template_13");
-            param.setReceive(List.of(sysUser.getData().getMobile()));
-            orgClient.messageAdd(param);
+        boolean inserted = completeRule(tenantId, userId, null, activity.getId(),
+                table.getId(), String.valueOf(count), String.valueOf(currentGrantNum),
+                table.getQutLotteryMax(), YesNoEnum.NO.getCode(), 6);
+        if (!inserted) {
+            return;
+        }
+        log.info("业务员报价,满足条件插入记录,userId:{},clientId:{},tenantId:{},count:{},currentGrantNum:{}",
+                userId, CLIENT_ID, tenantId, count, currentGrantNum);
+
+        // 发送抽奖次数下发通知消息,未绑定用户等绑定后再同步发放。
+        HttpResult<SysUserJzgInfo> sysUser = orgClient.queryUserByUserId(userId,tenantId);
+
+        MessageAddParam param = new MessageAddParam();
+        param.setTitle("抽奖次数下发通知消息");
+        param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
+        param.setTplCode("template_13");
+        param.setReceive(List.of(userId));
+        orgClient.messageAdd(param);
+    }
+
+    /**
+     * 计算本次报价应新增的抽奖次数。
+     * 计算方式:
+     * 1. 按当天报价次数计算“当前累计应得次数”:{@code (count / qutNum) * qutLotteryNum}。
+     * 2. 按上一次报价次数计算“上一次累计应得次数”:{@code ((count - 1) / qutNum) * qutLotteryNum}。
+     * 3. 两者都受每日上限 {@code qutLotteryMax} 限制。
+     * 4. 两者差值就是本次报价新增的抽奖次数。
+     * 示例:qutNum=1,qutLotteryNum=1,qutLotteryMax=2。
+     * count=1 返回1;count=2 返回1;count=3 返回0。
+     */
+    private int calculateCurrentQuoteLotteryNum(int count, LocalLivingActivityTableVO table) {
+        int qutNum = parsePositiveInt(table.getQutNum());
+        int qutLotteryNum = parsePositiveInt(table.getQutLotteryNum());
+        int qutLotteryMax = parsePositiveInt(table.getQutLotteryMax());
+        if (count <= 0 || qutNum <= 0 || qutLotteryNum <= 0 || qutLotteryMax <= 0) {
+            return 0;
+        }
+
+        // 当前报价次数下,今天累计最多应该获得多少次抽奖机会。
+        int currentTotal = Math.min((count / qutNum) * qutLotteryNum, qutLotteryMax);
+        // 本次报价之前,今天累计最多应该获得多少次抽奖机会。
+        int previousTotal = Math.min(((count - 1) / qutNum) * qutLotteryNum, qutLotteryMax);
+        // 差值就是本次新增次数;达到每日上限后差值为0,不再新增。
+        return Math.max(currentTotal - previousTotal, 0);
+    }
+
+    /**
+     * 解析正整数,空值或非法数字按0处理,避免活动配置异常影响主报价流程。
+     */
+    private int parsePositiveInt(String value) {
+        if (StrUtil.isBlank(value)) {
+            return 0;
+        }
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            log.warn("抽奖活动数字配置解析失败,value={}", value);
+            return 0;
         }
     }
 
@@ -490,7 +586,7 @@ public class UnifyOrderManager {
      * 处理已绑定用户的报价规则:先判断是否满足规则条件,满足后再远程同步抽奖次数并标记已同步
      */
     private void handleBoundQuoteRule(String tenantId, String userId,
-                                       LotteryActivityVO activity, LocalActivityTableVO table,
+                                       LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table,
                                        UnifiedUserClientVO bindData) {
         Map<String, List<UnifiedUserClientVO>> clientGroupMap = bindData.getUserClients()
                 .stream()
@@ -499,43 +595,49 @@ public class UnifyOrderManager {
             return;
         }
 
-        // 先判断是否满足规则条件
-        int qutLotteryNum = Integer.parseInt(table.getQutLotteryNum());
+        // 按当天报价次数计算本次应新增的抽奖次数,达到每日上限后不再新增。
         int count = insOrdersService.countQuoteNum(tenantId, userId,
-                activity.getActivityStartTime(), activity.getActivityEndTime());
-        if (count < Integer.parseInt(table.getQutNum()) || count > Integer.parseInt(table.getQutLotteryMax())) {
+                LocalDate.now(), LocalDate.now());
+        int currentGrantNum = calculateCurrentQuoteLotteryNum(count, table);
+        if (currentGrantNum <= 0) {
+            return;
+        }
+        // 防止同一次报价重复执行时重复远程发放;这里用当天报价次数作为防重维度。
+        SysUserActivityCompleteInRule exist = insOrdersService.selectByRule(
+                tenantId, userId, activity.getId(), String.valueOf(count), 6);
+        if (exist != null) {
             return;
         }
         HttpResult<SysUserJzgInfo> sysUser = orgClient.queryUserByUserId(userId,tenantId);
 
-        // 满足条件,远程调用抽奖次数增加接口
+        // 满足条件,远程调用抽奖次数增加接口,只发放本次新增次数。
         LotteryCounDTO lotteryCounDTO = new LotteryCounDTO();
         lotteryCounDTO.setAppUserId(userId);
         lotteryCounDTO.setActivityId(activity.getId());
-        lotteryCounDTO.setCount(qutLotteryNum);
+        lotteryCounDTO.setCount(currentGrantNum);
 
         HttpResult<LotteryCountVO> lotteryResult = null;
         try {
             lotteryResult = localLivingClient.addLotteryCount(lotteryCounDTO);
         } catch (Exception e) {
             log.info("业务员报价,远程调用本地生活抽奖次数增加接口异常,userId:{},count:{},tenantId:{}",
-                    userId, table.getQutLotteryNum(), tenantId);
+                    userId, currentGrantNum, tenantId);
             log.error("业务员报价,远程调用本地生活抽奖次数增加异常", e);
         }
 
         if (lotteryResult != null && lotteryResult.getData().getSuccess()) {
             completeRule(tenantId, userId, null, activity.getId(),
-                    table.getId(), table.getQutNum(), table.getQutLotteryNum(),
+                    table.getId(), String.valueOf(count), String.valueOf(currentGrantNum),
                     table.getQutLotteryMax(), YesNoEnum.YES.getCode(), 6);
-            log.info("业务员报价,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{}",
-                    userId, CLIENT_ID, tenantId);
+            log.info("业务员报价,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{},count:{},currentGrantNum:{}",
+                    userId, CLIENT_ID, tenantId, count, currentGrantNum);
 
             // 发送抽奖次数下发通知消息
             MessageAddParam param = new MessageAddParam();
             param.setTitle("抽奖次数下发通知消息");
             param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
             param.setTplCode("template_13");
-            param.setReceive(List.of(sysUser.getData().getMobile()));
+            param.setReceive(List.of(userId));
             orgClient.messageAdd(param);
         }
     }
@@ -843,7 +945,6 @@ public class UnifyOrderManager {
         //////////////////////////////////////////新增营销抽奖活动////////////////////////////////////////////////
         // 承保(客户)、出单(业务员)
         if (orderStatusResultVo.getOrderStatus() == InsOrderStatusEnum.UNDERWRITED) {
-            // TODO: 本地生活逻辑未调试通畅,暂时先注掉
             doSomethingAfterUnderwited(insOrders);
         }
         return HttpResult.ok("状态刷新成功");
@@ -919,16 +1020,34 @@ public class UnifyOrderManager {
      */
     private void doSomethingAfterUnderwited(InsOrders insOrders) {
         try {
-            HttpResult<List<LotteryActivityVO>> result = localLivingClient.queryActivityRules(lotteryScene);
-            if (result == null || result.getCode() != 200 || result.getData() == null) {
-                log.error("活动列表异常");
+            List<LocalLivingLotteryActivityVO> activities = queryLotteryActivities(lotteryScene);
+            if (CollUtil.isEmpty(activities)) {
                 return;
             }
 
-            String tenantId = baseController.getUserSystemCode();
-            String userId = insOrders.getRealQuoteUserId();
+            String tenantId = baseController.getSystemCode();
+            String userId = baseController.getUserId();
+            String quoteUserId = insOrders.getRealQuoteUserId();
+            // 业务员的相关活动
+            for (LocalLivingLotteryActivityVO activity : activities) {
+                // 检查活动是否有效(当前时间需在活动时间范围内)
+                if (LocalDate.now().isBefore(activity.getActivityStartTime())
+                        || LocalDate.now().isAfter(activity.getActivityEndTime())) {
+                    continue;
+                }
+                if (activity.getLocalActivityTables() == null) {
+                    continue;
+                }
 
-            for (LotteryActivityVO activity : result.getData()) {
+                for (LocalLivingActivityTableVO table : activity.getLocalActivityTables()) {
+                    if ("8".equals(table.getType())) {
+                        handleOrderRule(tenantId, userId,quoteUserId, activity, table);
+                    }
+                }
+            }
+            // 客户的相关活动
+            List<LocalLivingLotteryActivityVO> activities2 = queryLotteryActivities(4);
+            for (LocalLivingLotteryActivityVO activity : activities2) {
                 // 检查活动是否有效(当前时间需在活动时间范围内)
                 if (LocalDate.now().isBefore(activity.getActivityStartTime())
                         || LocalDate.now().isAfter(activity.getActivityEndTime())) {
@@ -938,15 +1057,14 @@ public class UnifyOrderManager {
                     continue;
                 }
 
-                for (LocalActivityTableVO table : activity.getLocalActivityTables()) {
+                for (LocalLivingActivityTableVO table : activity.getLocalActivityTables()) {
                     if ("9".equals(table.getType())) {
-                        handleUnderwritingRule(insOrders, activity, table);
-                    }
-                    if ("8".equals(table.getType())) {
-                        handleOrderRule(tenantId, userId, activity, table);
+                        handleUnderwritingRule(tenantId, userId,quoteUserId, insOrders, activity,table);
                     }
                 }
             }
+
+
         } catch (Exception e) {
             log.error("处理承保抽奖活动异常,不影响主承保流程", e);
         }
@@ -955,17 +1073,30 @@ public class UnifyOrderManager {
     /**
      * 处理 type=9 承保规则:按保费区间匹配,满足条件则存本地记录
      */
-    private void handleUnderwritingRule(InsOrders insOrders, LotteryActivityVO activity, LocalActivityTableVO table) {
-        Double totalFee = insOrdersService.queryTotalFee(insOrders.getInsOrderNo());
-        String userPhone = insOrdersService.queryCustomerPhone(insOrders.getInsOrderNo());
-        for (UnderwritingRuleVO rule : table.getUnderwritingRules()) {
+    private void handleUnderwritingRule(String tenantId,String userId,String quoteUserId,InsOrders insOrders, LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
+        Double totalFee = insOrdersService.queryTotalFee(insOrders.getId());
+        String userPhone = insOrdersService.queryCustomerPhone(insOrders.getId());
+        for (LocalLivingActivityTableVO.UnderwritingRule rule : table.getUnderwritingRules()) {
             BigDecimal fee = new BigDecimal(totalFee);
             if (fee.compareTo(rule.getUwMinPremium()) >= 0 && fee.compareTo(rule.getUwMaxPremium()) <= 0) {
-                completeRule(null, null, userPhone, activity.getId(),
+                completeRule(tenantId, quoteUserId, userPhone, activity.getId(),
                         table.getId(), rule.getUwMinPremium() + "-" + rule.getUwMaxPremium(),
                         rule.getUwLotteryNum(), null, YesNoEnum.NO.getCode(), 9);
                 log.info("客户承保,满足条件插入记录,userId:{},clientId:{},tenantId:{}",
                         insOrders.getRealQuoteUserId(), CLIENT_ID, baseController.getUserSystemCode());
+                GenerateQrcodeParam qparam = new GenerateQrcodeParam();
+                qparam.setActivityId(activity.getId());
+                qparam.setQuery("i="+activity.getId()+"&t=1&n="+rule.getUwLotteryNum());
+                Result<String> stringResult = localLivingClient.generateQrcode(qparam);
+                if(stringResult.isSuccess() && !stringResult.getResult().isEmpty()){
+
+                    MessageAddParam param = new MessageAddParam();
+                    param.setTitle("抽奖次数下发通知消息");
+                    param.setContent("{\"qrcode\":\"" + LocalLivingUrl+stringResult.getResult() + "\",\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"投保客户投保已获取奖励,点击为客户发放奖励\"}");
+                    param.setTplCode("template_14");
+                    param.setReceive(List.of(quoteUserId));
+                    orgClient.messageAdd(param);
+                }
             }
         }
     }
@@ -977,20 +1108,20 @@ public class UnifyOrderManager {
      * 1. 未绑定:统计出单次数,满足条件则存本地记录
      * 2. 已绑定:远程同步抽奖次数,成功后标记已同步
      */
-    private void handleOrderRule(String tenantId, String userId,
-                                  LotteryActivityVO activity, LocalActivityTableVO table) {
+    private void handleOrderRule(String tenantId, String userId, String quoteUserId,
+                                  LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
         // 只处理本租户的出单规则
         if (!tenantId.equals(table.getTenantId())) {
             return;
         }
 
-        HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId, tenantId);
+        HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId,quoteUserId, tenantId);
         if (bindResult == null || bindResult.getCode() != 200 || bindResult.getData() == null) {
             // 未绑定:统计出单次数,满足条件则存本地记录
-            handleUnboundOrderRule(tenantId, userId, activity, table);
+            handleUnboundOrderRule(tenantId, quoteUserId, activity, table);
         } else {
             // 已绑定:远程同步抽奖次数
-            handleBoundOrderRule(tenantId, userId, activity, table, bindResult.getData());
+            handleBoundOrderRule(tenantId, quoteUserId, activity, table, bindResult.getData());
         }
     }
 
@@ -998,17 +1129,28 @@ public class UnifyOrderManager {
      * 处理未绑定用户的出单规则
      */
     private void handleUnboundOrderRule(String tenantId, String userId,
-                                         LotteryActivityVO activity, LocalActivityTableVO table) {
+                                         LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
         int count = insOrdersService.countOrderNum(tenantId, userId,
                 activity.getActivityStartTime(), activity.getActivityEndTime());
-        for (OrderRuleVO orderRule : table.getOrderRules()) {
+        for (LocalLivingActivityTableVO.OrderRule orderRule : table.getOrderRules()) {
             if (count >= Integer.parseInt(orderRule.getOrdNum())) {
-                completeRule(tenantId, userId, null, activity.getId(),
+                boolean inserted = completeRule(tenantId, userId, null, activity.getId(),
                         table.getId(), orderRule.getOrdNum(),
                         String.valueOf(orderRule.getOrdLotteryNum()), null,
                         YesNoEnum.NO.getCode(), 8);
+                if(!inserted){
+                    break;
+                }
                 log.info("业务员出单,满足条件插入记录,userId:{},clientId:{},tenantId:{}",
                         userId, CLIENT_ID, tenantId);
+
+                MessageAddParam param = new MessageAddParam();
+                param.setTitle("抽奖次数下发通知消息");
+                param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
+                param.setTplCode("template_13");
+                param.setReceive(List.of(userId));
+                orgClient.messageAdd(param);
+
             }
         }
     }
@@ -1017,7 +1159,7 @@ public class UnifyOrderManager {
      * 处理已绑定用户的出单规则:先判断是否满足规则条件,满足后再远程同步抽奖次数并标记已同步
      */
     private void handleBoundOrderRule(String tenantId, String userId,
-                                       LotteryActivityVO activity, LocalActivityTableVO table,
+                                       LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table,
                                        UnifiedUserClientVO bindData) {
         Map<String, List<UnifiedUserClientVO>> clientGroupMap = bindData.getUserClients()
                 .stream()
@@ -1030,12 +1172,22 @@ public class UnifyOrderManager {
         int count = insOrdersService.countOrderNum(tenantId, userId,
                 activity.getActivityStartTime(), activity.getActivityEndTime());
         boolean anyMatch = false;
-        for (OrderRuleVO orderRule : table.getOrderRules()) {
+        boolean instare = false;
+        for (LocalLivingActivityTableVO.OrderRule orderRule : table.getOrderRules()) {
             if (count >= Integer.parseInt(orderRule.getOrdNum())) {
                 anyMatch = true;
+                instare = completeRule(tenantId, userId, null, activity.getId(),
+                        table.getId(), table.getQutNum(), table.getQutLotteryNum(),
+                        table.getQutLotteryMax(), YesNoEnum.YES.getCode(), 8);
+                log.info("业务员出单,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{}",
+                        userId, CLIENT_ID, tenantId);
                 break;
             }
         }
+        // 已完成的出单任务不走奖励
+        if(!instare){
+            return;
+        }
         if (!anyMatch) {
             return;
         }
@@ -1055,17 +1207,13 @@ public class UnifyOrderManager {
                     userId, table.getQutLotteryNum(), tenantId);
             log.error("业务员出单,远程调用本地生活抽奖次数增加异常", e);
         }
-
         if (lotteryResult != null && lotteryResult.getData().getSuccess()) {
-            for (OrderRuleVO orderRule : table.getOrderRules()) {
-                if (count >= Integer.parseInt(orderRule.getOrdNum())) {
-                    completeRule(tenantId, userId, null, activity.getId(),
-                            table.getId(), table.getQutNum(), table.getQutLotteryNum(),
-                            table.getQutLotteryMax(), YesNoEnum.YES.getCode(), 8);
-                    log.info("业务员出单,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{}",
-                            userId, CLIENT_ID, tenantId);
-                }
-            }
+            MessageAddParam param = new MessageAddParam();
+            param.setTitle("抽奖次数下发通知消息");
+            param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
+            param.setTplCode("template_13");
+            param.setReceive(List.of(userId));
+            orgClient.messageAdd(param);
         }
     }
     //return HttpResult.ok("状态刷新成功");

+ 178 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/entity/vo/LocalLivingActivityTableVO.java

@@ -0,0 +1,178 @@
+package com.jzg.quotation.summary.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+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;
+
+/**
+ * 本地生活活动规则
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LocalLivingActivityTableVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "ID")
+    private String id;
+
+    @Schema(description = "标题")
+    private String title;
+
+    @Schema(description = "说明")
+    private String instructions;
+
+    @Schema(description = "开始时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    @Schema(description = "结束时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+    @Schema(description = "用户类型")
+    private String userType;
+
+    @Schema(description = "用户等级ID")
+    private String userLevelId;
+
+    @Schema(description = "产品类型")
+    private String productType;
+
+    @Schema(description = "产品ID")
+    private String productId;
+
+    @Schema(description = "产品名称")
+    private String productName;
+
+    @Schema(description = "奖品类型")
+    private String awardType;
+
+    @Schema(description = "转盘ID")
+    private String turntableId;
+
+    @Schema(description = "积分数量")
+    private Integer pointNumber;
+
+    @Schema(description = "优惠券ID")
+    private String couponId;
+
+    @Schema(description = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @Schema(description = "更新人")
+    private String updateBy;
+
+    @Schema(description = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @Schema(description = "删除标识")
+    private Integer delFlag;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "类型 6-报价 7-签到 8-出单 9-承保")
+    private String type;
+
+    @Schema(description = "背景图")
+    private String backImage;
+
+    @Schema(description = "商户ID")
+    private String merchantId;
+
+    @Schema(description = "是否商品")
+    private String isProduct;
+
+    @Schema(description = "幸运转盘")
+    private String luckyWheel;
+
+    @Schema(description = "用户参与ID")
+    private String userParticipateId;
+
+    @Schema(description = "项目类型")
+    private String projectType;
+
+    @Schema(description = "报价次数")
+    private String qutNum;
+
+    @Schema(description = "报价获得抽奖次数")
+    private String qutLotteryNum;
+
+    @Schema(description = "报价最大抽奖次数")
+    private String qutLotteryMax;
+
+    @Schema(description = "签到规则列表")
+    private List<SignRule> signRules;
+
+    @Schema(description = "出单规则列表")
+    private List<OrderRule> orderRules;
+
+    @Schema(description = "承保规则列表")
+    private List<UnderwritingRule> underwritingRules;
+
+    @Schema(description = "租户ID")
+    private String tenantId;
+
+    @Schema(description = "租户名称")
+    private String tenantName;
+
+    /**
+     * 签到规则
+     */
+    @Data
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class SignRule implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        @Schema(description = "签到天数")
+        private String signNum;
+
+        @Schema(description = "签到获得抽奖次数")
+        private String signLotteryNum;
+    }
+
+    /**
+     * 出单规则
+     */
+    @Data
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class OrderRule implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        @Schema(description = "出单数量")
+        private String ordNum;
+
+        @Schema(description = "出单获得抽奖次数")
+        private String ordLotteryNum;
+    }
+
+    /**
+     * 承保规则
+     */
+    @Data
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class UnderwritingRule implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        @Schema(description = "最小保费")
+        private BigDecimal uwMinPremium;
+
+        @Schema(description = "最大保费")
+        private BigDecimal uwMaxPremium;
+
+        @Schema(description = "承保获得抽奖次数")
+        private String uwLotteryNum;
+    }
+}

+ 100 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/entity/vo/LocalLivingLotteryActivityAwardVO.java

@@ -0,0 +1,100 @@
+package com.jzg.quotation.summary.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 本地生活抽奖活动奖品
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LocalLivingLotteryActivityAwardVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "奖品ID")
+    private String id;
+
+    @Schema(description = "排序ID")
+    private Integer keyId;
+
+    @Schema(description = "活动ID")
+    private String activityId;
+
+    @Schema(description = "奖品类型")
+    private Integer awardType;
+
+    @Schema(description = "优惠券ID")
+    private String couponId;
+
+    @Schema(description = "优惠券名称")
+    private String couponName;
+
+    @Schema(description = "奖品图标")
+    private String icon;
+
+    @Schema(description = "中奖概率")
+    private Integer winningProbability;
+
+    @Schema(description = "兑换类型")
+    private Integer redemptionType;
+
+    @Schema(description = "活动链接")
+    private String activityUrl;
+
+    @Schema(description = "活动描述")
+    private String activityDescribe;
+
+    @Schema(description = "奖品名称")
+    private String awardName;
+
+    @Schema(description = "积分数量")
+    private Integer pointNum;
+
+    @Schema(description = "红包金额")
+    private BigDecimal redAmount;
+
+    @Schema(description = "操作提示")
+    private String operationPrompt;
+
+    @Schema(description = "截止时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime deadline;
+
+    @Schema(description = "创建人")
+    private String createBy;
+
+    @Schema(description = "更新人")
+    private String updateBy;
+
+    @Schema(description = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @Schema(description = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @Schema(description = "红包地址")
+    private String redAddress;
+
+    @Schema(description = "付费会员ID")
+    private String paidMemberId;
+
+    @Schema(description = "付费会员规则ID")
+    private String paidMemberRulesId;
+
+    @Schema(description = "付费会员规则开始时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime paidMemberRulesStartTime;
+
+    @Schema(description = "付费会员规则结束时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime paidMemberRulesEndTime;
+}

+ 100 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/entity/vo/LocalLivingLotteryActivityVO.java

@@ -0,0 +1,100 @@
+package com.jzg.quotation.summary.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 本地生活抽奖活动信息
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LocalLivingLotteryActivityVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "活动ID")
+    private String id;
+
+    @Schema(description = "活动名称")
+    private String activityName;
+
+    @Schema(description = "场景编码")
+    private Integer scene;
+
+    @Schema(description = "场景名称")
+    private String sceneName;
+
+    @Schema(description = "类型")
+    private Integer type;
+
+    @Schema(description = "活动开始时间")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate activityStartTime;
+
+    @Schema(description = "活动结束时间")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate activityEndTime;
+
+    @Schema(description = "参与规则")
+    private Integer participationRules;
+
+    @Schema(description = "活动背景图")
+    private String activityBackgroundImage;
+
+    @Schema(description = "海报背景图")
+    private String posterBackgroundImage;
+
+    @Schema(description = "活动链接")
+    private String activityUrl;
+
+    @Schema(description = "活动描述")
+    private String activityDescribe;
+
+    @Schema(description = "创建人")
+    private String createBy;
+
+    @Schema(description = "更新人")
+    private String updateBy;
+
+    @Schema(description = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @Schema(description = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @Schema(description = "最大人数")
+    private Integer maxPeople;
+
+    @Schema(description = "最大抽奖次数")
+    private Integer maxLuckyDraws;
+
+    @Schema(description = "活动二维码")
+    private String activityQr;
+
+    @Schema(description = "奖品列表")
+    private List<LocalLivingLotteryActivityAwardVO> lotteryActivityAwards;
+
+    @Schema(description = "产品规则列表")
+    private List<Object> lotteryActivityRulesProducts;
+
+    @Schema(description = "本地活动规则列表")
+    private List<LocalLivingActivityTableVO> localActivityTables;
+
+    @Schema(description = "公益积分规则列表")
+    private List<Object> gyyPointTables;
+
+    @Schema(description = "一账通地址")
+    private String oneAccountHost;
+
+    @Schema(description = "参与次数")
+    private Integer participateNum;
+}

+ 2 - 2
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/InsOrdersMapper.java

@@ -177,14 +177,14 @@ public interface InsOrdersMapper extends BaseMapper<InsOrders> {
     int countOrderNum(String systemCode, String realQuoteUserId, LocalDate activityStartTime, LocalDate activityEndTime);
     /**
      * 查询营销活动规则表中符合的规则记录
-     * @param tenantId
+     * @param systemCode
      * @param userId
      * @param activityId
      * @param qutNum
      * @param activityType
      * @return
      */
-    SysUserActivityCompleteInRule selectByRule(String tenantId, String userId, String activityId, String qutNum, Integer activityType);
+    SysUserActivityCompleteInRule selectByRule(@Param("systemCode") String systemCode, @Param("userId") String userId, @Param("activityId")String activityId, @Param("qutNum")String qutNum, @Param("activityType")Integer activityType);
     /**
      * 添加营销活动规则表中的符合规则记录
      * @param record

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

@@ -792,7 +792,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
                 ordersCosts.setJyPremium(niPremium);
                 ordersCosts.setTaxPremium(vvTax);
                 ordersCosts.setSumPremium(ciPremium.add(biPremium).add(niPremium).add(vvTax));
-                ordersCosts.setTaxPremium(ciPremium.add(biPremium).add(niPremium));
+                ordersCosts.setTotalAmount(ciPremium.add(biPremium).add(niPremium));
             } else {
                 BigDecimal bigDecimal = new BigDecimal("0.00");
                 ordersCosts.setJqPremium(bigDecimal);

+ 3 - 1
tenant/insurance/quotation-summary/src/main/resources/application-dev.yaml

@@ -262,7 +262,9 @@ feign:
     jzg-partner:
       url: http://localhost:8087/
     jeecg-boot:
-      url: https://test.baoxianzhanggui.com/locallive-java
+      url: https://life.baoxianzhanggui.com/locallive-pro-java
+    unifiedAccountClient:
+      url: http://test.baoxianzhanggui.com/user-api
 # 和生活服务平台约定的appkey、appSeCret,用于获取token
 live:
   service:

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

@@ -1609,12 +1609,12 @@
           AND io.create_time &gt;= CONCAT(#{activityStartTime},' 00:00:00')
           AND io.create_time &lt;= CONCAT(#{activityEndTime},' 23:59:59')
     </select>
-    <select id="selectByRule" resultType="com.jzg.commons.entity.po.SysUserActivityCompleteInRule">
+    <select id="selectByRule" resultType="com.jzg.commons.entity.po.SysUserActivityCompleteInRule" >
         SELECT *
         FROM sys_user_activity_complete_in_rule
         <where>
             and is_delete = 0
-            and tenant_id = #{tenantId}
+            and system_code = #{systemCode}
             and user_id = #{userId}
             and activity_id = #{activityId}
             and activity_type = #{activityType}
@@ -1639,7 +1639,7 @@
     <insert id="insertActivityCompleteInRule" parameterType="com.jzg.commons.entity.po.SysUserActivityCompleteInRule">
         INSERT INTO sys_user_activity_complete_in_rule (
             id,
-            tenant_id,
+            system_code,
             user_id,
             activity_type,
             activity_id,
@@ -1656,7 +1656,7 @@
             is_delete
         ) VALUES (
                      #{id},
-                     #{tenantId},
+                     #{systemCode},
                      #{userId},
                      #{activityType},
                      #{activityId},

+ 15 - 2
tenant/insurance/quotation-taishan/src/main/java/com/jzg/quotation/taishan/crawler/component/TaiShanCrawlerCacheComponent.java

@@ -1,7 +1,11 @@
 package com.jzg.quotation.taishan.crawler.component;
 
+import com.jzg.commons.exception.SystemException;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RBucket;
 import org.redisson.api.RedissonClient;
+import org.redisson.client.codec.StringCodec;
 import org.springframework.stereotype.Component;
 
 import java.time.Duration;
@@ -12,6 +16,7 @@ import java.util.Map;
  * @author: wenks
  * @date: 2025/3/31 15:15
  **/
+@Slf4j
 @Component
 @RequiredArgsConstructor
 public class TaiShanCrawlerCacheComponent {
@@ -54,7 +59,8 @@ public class TaiShanCrawlerCacheComponent {
      * @param authorization   登陆cookie
      */
     public void cacheAuthorization(String username, String authorization) {
-        redissonClient.getBucket(TS_LOGIN_AUTH + username).set(authorization, Duration.ofDays(TS_LOGIN_AUTH_TIME));
+        RBucket<String> bucket = redissonClient.getBucket(TS_LOGIN_AUTH + username, StringCodec.INSTANCE);
+        bucket.set(authorization, Duration.ofDays(TS_LOGIN_AUTH_TIME));
     }
 
 
@@ -65,7 +71,14 @@ public class TaiShanCrawlerCacheComponent {
      * @return 登录cookie
      */
     public String getAuthorization(String username) {
-        return (String) redissonClient.getBucket(TS_LOGIN_AUTH + username).get();
+        try {
+            RBucket<String> bucket = redissonClient.getBucket(TS_LOGIN_AUTH + username, StringCodec.INSTANCE);
+            return bucket.get();
+        } catch (Exception e) {
+            log.warn("泰山登录缓存读取失败,将重新登录,username={}", username, e);
+            redissonClient.getBucket(TS_LOGIN_AUTH + username).delete();
+            throw new SystemException("泰山登录缓存读取失败,请重新登录");
+        }
     }
 
 

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

@@ -315,7 +315,8 @@ public class TaiShanCrawlerRequestComponent {
         TaiShanCrawlerQuotationResponse response = post(RequestUrl.PRICE, request, TaiShanCrawlerQuotationResponse.class, headers);
 
         TaiShanCrawlerQuotationResponse.ResultDTO.ExceptionDTO exception = response.getResult().getException();
-        ResultEnum.verify(exception.getCode(), exception.getMsg());
+        String errorMessage = response.getResult() != null ? exception.getMsg() : response.getMessage();
+        ResultEnum.verify(exception.getCode(), errorMessage);
 
         // 通过状态码获取处理器处理
         ResponseMessageAbstractHandler responseMessageAbstractHandler =

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

@@ -184,22 +184,29 @@ public class TaiShanCrawlerRequestImpl implements TaiShanCrawlerRequest {
                 }
             }
             log.info("taiShanCrawlerQuotationSaveResponse参数的值:{}", JSON.toJSONString(taiShanCrawlerQuotationSaveResponse));
-            TaiShanCrawlerQuotationSaveResponse.Result.Exception saveException = taiShanCrawlerQuotationSaveResponse.getResult().getException();
-            if (saveException.getCode().equals("H1")){
-                TaiShanCrawlerOrder taiShanCrawlerOrder = new TaiShanCrawlerOrder();
-                taiShanCrawlerOrder.setOrdersNo(quoteVo.getOrder().getOrdersNo());
-                taiShanCrawlerOrderService.save(taiShanCrawlerQuotationSaveResponse, taiShanCrawlerOrder);
-                success = true;
-
-                //风险管控
-                String proposalNo = taiShanCrawlerQuotationSaveResponse.getResult().getCompulsoryInsurance().getProductInfo().getProposalNo();
-                TaiShanCrawlerRiskManagementRequest taiShanCrawlerRiskManagementRequest = new TaiShanCrawlerRiskManagementRequest(proposalNo);
-                taiShanCrawlerRiskManagementResponse = taiShanCrawlerRequestComponent.getRiskManagement(taiShanCrawlerRiskManagementRequest, headers);
-            }else{
-                errMsg = saveException.getMsg();
+            if (taiShanCrawlerQuotationSaveResponse.getResult() != null) {
+                TaiShanCrawlerQuotationSaveResponse.Result.Exception saveException = taiShanCrawlerQuotationSaveResponse.getResult().getException();
+                if (saveException.getCode().equals("H1")){
+                    TaiShanCrawlerOrder taiShanCrawlerOrder = new TaiShanCrawlerOrder();
+                    taiShanCrawlerOrder.setOrdersNo(quoteVo.getOrder().getOrdersNo());
+                    taiShanCrawlerOrderService.save(taiShanCrawlerQuotationSaveResponse, taiShanCrawlerOrder);
+                    success = true;
+
+                    //风险管控
+                    String proposalNo = taiShanCrawlerQuotationSaveResponse.getResult().getCompulsoryInsurance().getProductInfo().getProposalNo();
+                    TaiShanCrawlerRiskManagementRequest taiShanCrawlerRiskManagementRequest = new TaiShanCrawlerRiskManagementRequest(proposalNo);
+                    taiShanCrawlerRiskManagementResponse = taiShanCrawlerRequestComponent.getRiskManagement(taiShanCrawlerRiskManagementRequest, headers);
+                }else{
+                    errMsg = saveException.getMsg();
+                    throw new SystemException(errMsg);
+                }
+            }else {
+                errMsg = taiShanCrawlerQuotationSaveResponse.getMessage();
+                throw new SystemException(errMsg);
             }
         }else{
-            errMsg = exception.getMsg();
+            errMsg = taiShanCrawlerQuotationResponse.getResult() != null ? exception.getMsg() : taiShanCrawlerQuotationResponse.getMessage();
+            throw new SystemException(errMsg);
         }
         return TaiShanCrawlerQuoteResultsVoBuild.buildQuoteResultsVo(quoteVo,
                 taiShanCrawlerQuotationSaveResponse,

+ 2 - 0
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/Response/ZmCrawlerFindZfTaskResponse.java

@@ -26,6 +26,7 @@ public class ZmCrawlerFindZfTaskResponse extends BaseResponse {
         @Serial
         private static final long serialVersionUID = -5812750900019608663L;
 
+        private String personaccidentno;
         private String appliName;
         private String businessProgress;
         private String businessType;
@@ -45,6 +46,7 @@ public class ZmCrawlerFindZfTaskResponse extends BaseResponse {
         private String paymentMethod;
         private String plateNo;
         private String sAmount;
+        private String sContractNo;
         private String sPremiums;
         private String searchno;
         private String source;

+ 5 - 0
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/Impl/ZhongMeiCrawlerRequestImpl.java

@@ -422,7 +422,12 @@ public class ZhongMeiCrawlerRequestImpl implements ZhongMeiCrawlerRequest {
         //检查是否可以获取支付二维码
         if (zfTaskResponse.getBizTask() != null && !zfTaskResponse.getBizTask().isEmpty()) {
             String transSerialNo = zfTaskResponse.getBizTask().get(0).getTransactionNo();
+            ZmCrawlerFindZfTaskResponse.BizTaskDTO bizTaskDTO = zfTaskResponse.getBizTask().get(0);
             if (StringUtils.isEmpty(transSerialNo)) {
+                crawlerOrder.setJqContractNo(bizTaskDTO.getJContractNo());
+                crawlerOrder.setSyContractNo(bizTaskDTO.getSContractNo());
+                crawlerOrder.setJyContractNo(bizTaskDTO.getPersonaccidentno());
+                zmCrawlerOrderService.update(crawlerOrder);
                 //调试时,注意如何获取参数
                 ZmCrawlerOrderApplyRequest orderApplyRequest = new ZmCrawlerOrderApplyRequest(zmCrawlerConfigureParameters.getComCode(), userCode, crawlerOrder);
                 orderApplyRequest.setHead(head);

+ 5 - 0
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/Impl/ZmCrawlerOrderServiceImpl.java

@@ -63,4 +63,9 @@ public class ZmCrawlerOrderServiceImpl implements ZmCrawlerOrderService {
         return null;
     }
 
+    @Override
+    public ZmCrawlerOrder update(ZmCrawlerOrder zmCrawlerOrder) {
+        return zmCrawlerOrderReposiroty.save(zmCrawlerOrder);
+    }
+
 }

+ 2 - 0
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/service/ZmCrawlerOrderService.java

@@ -22,4 +22,6 @@ public interface ZmCrawlerOrderService {
      */
     ZmCrawlerOrder save(QuoteVo quoteVo, ZmCrawlerQuotedPriceResponse quotedPriceResponse);
 
+    ZmCrawlerOrder update(ZmCrawlerOrder zmCrawlerOrder);
+
 }

+ 1 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/InsFeeFollowOrderReconciliationController.java

@@ -43,6 +43,7 @@ public class InsFeeFollowOrderReconciliationController {
                 .eq("month", saveDTO.getMonth())
                 .eq("partner_company_id", saveDTO.getPartnerCompanyId())
                 .eq("system_code", baseController.getSystemCode())
+                .eq("invoice_type", saveDTO.getInvoiceType())
                 .last("LIMIT 1"); // 取一条即可,或者根据业务取最新的
         InsFeeFollowOrderReconciliation insFeeFollowOrderReconciliation = reconciliationService.getOne(insFeeFollowOrderReconciliationQueryWrapper);
 

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

@@ -15,6 +15,8 @@ import com.jzg.commons.entity.orders.po.InsOrderAdjust;
 import com.jzg.commons.request.RequestSingleParam;
 import com.jzg.commons.util.AssertionUtils;
 import com.jzg.organization.service.ReceivableService;
+import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
+import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.slf4j.Logger;
@@ -117,7 +119,7 @@ public class ReceivableController {
         if (null == data || CollUtil.isEmpty(data.getRecords())){
             return HttpResult.ok(BigDecimal.ZERO);
         }
-        BigDecimal reduce = data.getRecords().stream().map(income -> StrUtil.isNotBlank(income.getSuperviseCostsPremiums()) ? new BigDecimal(income.getSuperviseCostsPremiums()) : BigDecimal.ZERO)
+        BigDecimal reduce = data.getRecords().stream().map(income -> StrUtil.isNotBlank(income.getCarInsuranceSuperviseCostsPremiums()) ? new BigDecimal(income.getCarInsuranceSuperviseCostsPremiums()) : BigDecimal.ZERO)
                 .reduce(BigDecimal.ZERO, BigDecimal::add);
         return HttpResult.ok(reduce);
     }
@@ -196,7 +198,7 @@ public class ReceivableController {
         if (null == data || CollUtil.isEmpty(data.getRecords())){
             return HttpResult.ok(BigDecimal.ZERO);
         }
-        BigDecimal reduce = data.getRecords().stream().map(income -> StrUtil.isNotBlank(income.getOtherCostsPremiums()) ? new BigDecimal(income.getOtherCostsPremiums()) : BigDecimal.ZERO)
+        BigDecimal reduce = data.getRecords().stream().map(income -> StrUtil.isNotBlank(income.getCarInsuranceOtherCostsPremiums()) ? new BigDecimal(income.getCarInsuranceOtherCostsPremiums()) : BigDecimal.ZERO)
                 .reduce(BigDecimal.ZERO, BigDecimal::add);
         return HttpResult.ok(reduce);
     }
@@ -542,6 +544,14 @@ public class ReceivableController {
      * @author lipf
      * @date 2026/5/27 20:25
      */
+    @OrderOperationLog(
+            module = "私有协议应收",
+            subModule = "订单审核",
+            optType = QuoteNumberConstant.QuoteOptType.OPT_TYPE_16,
+            description = "费用调整",
+            orderSpEl = "#quoteVo",
+            feedbackSpEl = "#ret.code + ' - ' + #ret.msg+ ' - ' + #ret.data"
+    )
     @PostMapping("batchModify")
     @Operation(summary = "批量修改")
     public HttpResult<String> batchModify(@RequestBody BatchModifyVo batchModifyVo){

+ 1 - 1
tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserAccountIncomeLogMapper.java

@@ -20,6 +20,6 @@ public interface SysUserAccountIncomeLogMapper extends BaseMapper<SysUserAccount
      * @author lipf
      * @date 2026/6/8 17:25
      */
-    @Select("select * from sys_user_account_change_log a where a.user_id = #{ywyUserId} and a.create_time >= #{beginDate} and a.create_time < #{endDate} and a.is_delete = 0 order by a.create_time desc")
+    @Select("select ioci.license_no , a.* from sys_user_account_change_log a  left join ins_orders_car_info ioci on a.related_order_id = ioci.order_no where a.user_id = #{ywyUserId} and a.create_time >= #{beginDate} and a.create_time < #{endDate} and a.is_delete = 0 order by a.create_time desc")
     List<SysUserAccountChangeLog> queryYwyIORecs(String ywyUserId, LocalDate beginDate, LocalDate endDate);
 }

+ 66 - 23
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -16,6 +16,7 @@ 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;
+import com.jzg.commons.constants.InvoiceTypeEnum;
 import com.jzg.commons.constants.ProductsType;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
 import com.jzg.commons.core.base.BaseController;
@@ -327,8 +328,23 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         Page<InsPlyIncome> page = baseMapper.getReceivablePage(page1, receivableQueryVo);
         List<InsPlyIncomeOrder> res = page.getRecords().stream()
                 .map(action -> new InsPlyIncomeOrder(action.getId(), action.getOrderNo())).toList();
-        BigDecimal totalAmount = page.getRecords().stream()
-                .map(action -> new BigDecimal(Objects.toString(action.getReceivableAmount(), "0"))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        if (InvoiceTypeEnum.FEE_3.getCode().equals(receivableQueryVo.getInvoiceType())){
+            totalAmount = page.getRecords().stream()
+                    .map(action -> new BigDecimal(Objects.toString(action.getNonCarInsuranceSuperviseCostsPremiums(), "0"))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        } else if (InvoiceTypeEnum.FEE_4.getCode().equals(receivableQueryVo.getInvoiceType())){
+            totalAmount = page.getRecords().stream()
+                    .map(action -> new BigDecimal(Objects.toString(action.getNonCarInsuranceOtherCostsPremiums(), "0"))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        }else if (InvoiceTypeEnum.FEE_1.getCode().equals(receivableQueryVo.getInvoiceType())){
+            totalAmount = page.getRecords().stream()
+                    .map(action -> new BigDecimal(Objects.toString(action.getCarInsuranceSuperviseCostsPremiums(), "0"))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        }else if (InvoiceTypeEnum.FEE_2.getCode().equals(receivableQueryVo.getInvoiceType())){
+            totalAmount = page.getRecords().stream()
+                    .map(action -> new BigDecimal(Objects.toString(action.getCarInsuranceOtherCostsPremiums(), "0"))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        }else{
+            totalAmount = page.getRecords().stream()
+                    .map(action -> new BigDecimal(Objects.toString(action.getReceivableAmount(), "0"))).reduce(BigDecimal.ZERO, BigDecimal::add);
+        }
 
         InsPlyIncomeVO vo = new InsPlyIncomeVO(null, res,Objects.toString(totalAmount,"0"));
         log.info("获取私有/平台协议手续费应收列表的id集合。receivableQueryVo=[{}]. ids.size=[{}]", JSONUtil.toJsonStr(receivableQueryVo), CollUtil.size(res));
@@ -802,7 +818,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         Map<String, List<FollowCompanyFeeVO>> followGroupMap = followCompanyFeeVos.stream()
                 .collect(Collectors.groupingBy(this::buildGroupKey));
 
-        // 【核心优化】提前收集所有需要查询的ID,批量查询,彻底解决循环N+1
+        // 提前收集所有需要查询的ID,批量查询,彻底解决循环N+1
         Set<String> allFollowIds = new HashSet<>();
         Set<String> allSettlementIds = new HashSet<>();
         followGroupMap.values().forEach(list -> {
@@ -841,7 +857,12 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             BigDecimal receivablePremium = Optional.ofNullable(firstFollow)
                     .map(InsFeeFollowOrder::getReceivablePremium)
                     .orElse(BigDecimal.ZERO);
+            // 对账金额
+            BigDecimal reconciliationAmount = Optional.ofNullable(firstFollow)
+                    .map(InsFeeFollowOrder::getReconciliationAmount)
+                    .orElse(BigDecimal.ZERO);
             vo.setTotalReceivable(receivablePremium);
+            vo.setTotalReconciliationAmount(reconciliationAmount);
 
             // 已开票总额
             BigDecimal totalInvoiced = followIds.stream()
@@ -850,7 +871,8 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     .map(InsFeeFollowOrder::getInvoiced)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
             vo.setTotalInvoiced(totalInvoiced);
-            vo.setTotalUnInvoiced(receivablePremium.subtract(totalInvoiced));
+            // 根据需求,未开票总金额 = 对账金额 - 已开票金额
+            vo.setTotalUnInvoiced(reconciliationAmount.subtract(totalInvoiced));
 
             // 已结算总额
             BigDecimal totalSettlementAmount = settlementIds.stream()
@@ -1111,7 +1133,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 platformCompanyFeeVo.setTotalPaymentDifference(BigDecimal.ZERO);
             }
             //platformCompanyFeeVo.setTotalUnSettlementAmount(BigDecimalUtil.subtract(BigDecimalUtil.subtract(platformCompanyFeeVo.getTotalReceivable(),platformCompanyFeeVo.getTotalSettlementAmount()), platformCompanyFeeVo.getTotalPaymentDifference()));
-            platformCompanyFeeVo.setTotalUnSettlementAmount(BigDecimalUtil.subtract(platformCompanyFeeVo.getTotalReceivable(),platformCompanyFeeVo.getTotalSettlementAmount()));
+            platformCompanyFeeVo.setTotalUnSettlementAmount(BigDecimalUtil.subtract(platformCompanyFeeVo.getTotalReceivable(),BigDecimalUtil.subtract(platformCompanyFeeVo.getTotalSettlementAmount(),platformCompanyFeeVo.getTotalPaymentDifference())));
         }
         if (StrUtil.isNotBlank(settlementReportQueryVo.getStatus())){
             if ("1".equals(settlementReportQueryVo.getStatus())){
@@ -3971,12 +3993,31 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     if (StrUtil.isEmpty(search)) {
                         return true;
                     }
+                    List<String> companyIds = Arrays.asList(search.split(","));
+                    HttpResult parentIds = null;
+                    if (companyIds.size() <= 2){
+                        parentIds = esmInsCompanyClient.getParentIds(companyIds);
+                    }
                     if ("等于".equalsIgnoreCase(type) || "包含".equalsIgnoreCase(type)) {
-                        List<String> companyIds = Arrays.asList(search.split(","));
+                        if (null != parentIds && parentIds.isSuccess()){
+                            List<String> data = (List<String>) parentIds.getData();
+                            if (CollUtil.isNotEmpty(data) && data.contains(insPlyIncome.getPartnerCompanyId())){
+                                return true;
+                            }else{
+                                return false;
+                            }
+                        }
                         return companyIds.contains(insPlyIncome.getPartnerCompanyId());
                     }
                     if ("不等于".equalsIgnoreCase(type) || "不包含".equalsIgnoreCase(type)) {
-                        List<String> companyIds = Arrays.asList(search.split(","));
+                        if (null != parentIds && parentIds.isSuccess()){
+                            List<String> data = (List<String>) parentIds.getData();
+                            if (CollUtil.isNotEmpty(data) && !data.contains(insPlyIncome.getPartnerCompanyId())){
+                                return true;
+                            }else{
+                                return false;
+                            }
+                        }
                         return !companyIds.contains(insPlyIncome.getPartnerCompanyId());
                     }
                     return true;
@@ -4040,7 +4081,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 for (int month = 1; month <= 12; month++) {
                     InsFeeFollowOrderVo vo = buildFollowOrderVo(
                             year, month, firstItem, partnerCompanyId,
-                            monthReceivableMap, invoicedMap
+                            monthReceivableMap, invoicedMap, followInvoicePageListVo
                     );
                     result.add(vo);
                 }
@@ -4170,7 +4211,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     private InsFeeFollowOrderVo buildFollowOrderVo(Integer year, int month, InsPlyIncomeDto firstItem,
                                                    String partnerCompanyId,
                                                    Map<Integer, BigDecimal> monthReceivableMap,
-                                                   Map<String, BigDecimal> invoicedMap) {
+                                                   Map<String, BigDecimal> invoicedMap, FollowInvoicePageListVo followInvoicePageListVo) {
 
         String systemCode = baseController.getSystemCode();
         // 获取当月应收保费,默认为0
@@ -4196,6 +4237,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                 .eq("month", month)
                 .eq("partner_company_id", partnerCompanyId)
                 .eq("system_code", systemCode)
+                .eq("invoice_type", followInvoicePageListVo.getInvoiceType())
                 .last("LIMIT 1"); // 取一条即可,或者根据业务取最新的
         InsFeeFollowOrder dbOrder = insFeeFollowOrderMapper.selectOne(queryWrapper);
         if (dbOrder != null) {
@@ -4212,6 +4254,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     .eq("month", month)
                     .eq("partner_company_id", partnerCompanyId)
                     .eq("system_code", systemCode)
+                    .eq("invoice_type", followInvoicePageListVo.getInvoiceType())
                     .last("LIMIT 1"); // 取一条即可,或者根据业务取最新的
             InsFeeFollowOrderReconciliation insFeeFollowOrderReconciliation = insFeeFollowOrderReconciliationMapper.selectOne(insFeeFollowOrderReconciliationQueryWrapper);
             if (null != insFeeFollowOrderReconciliation){
@@ -5383,18 +5426,18 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         calRes = baseMapper.queryInvoicedAmount(systemCode, List.of(1, 3), queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType());
         Map<String, BigDecimal> sxfInvoicedAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
         Map<String, BigDecimal> sxfOverinflatedAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getOverinflatedAmount, (o1,o2)->o1));
-        calRes = baseMapper.queryInvoicedAmount(systemCode, List.of(2, 4), queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType());
-        Map<String, BigDecimal> gdfInvoicedAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
+//        calRes = baseMapper.queryInvoicedAmount(systemCode, List.of(2, 4), queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType());
+//        Map<String, BigDecimal> gdfInvoicedAmountMap = calRes.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getAmount, (o1,o2)->o1));
 
         // 结算费用 
         List<CalRes> sxfList = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType(), CollUtil.newArrayList("1", "3"));
-        List<CalRes> gdfList = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType(), CollUtil.newArrayList("2", "4"));
+        // List<CalRes> gdfList = baseMapper.querySettledAmount(systemCode, queryVo.getInvoiceStartTime(), queryVo.getInvoiceEndTime(), queryVo.getAgreementType(), CollUtil.newArrayList("2", "4"));
         Map<String, BigDecimal> sxfSettledAmountMap = CollUtil.isNotEmpty(sxfList) ? sxfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getSettlement, (o1,o2)->o1)) : new HashMap<>();
         // 手续费的回款差额汇总
         Map<String, BigDecimal> sxfSettledDiffAmountMap = CollUtil.isNotEmpty(sxfList) ? sxfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getOverinflatedAmount, (o1,o2)->o1)) : new HashMap<>();
-        Map<String, BigDecimal> gdfSettledAmountMap = CollUtil.isNotEmpty(gdfList) ? gdfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getSettlement, (o1,o2)->o1)) : new HashMap<>();
+        //Map<String, BigDecimal> gdfSettledAmountMap = CollUtil.isNotEmpty(gdfList) ? gdfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getSettlement, (o1,o2)->o1)) : new HashMap<>();
         // 跟单费的回款差额汇总
-        Map<String, BigDecimal> gdfSettledDiffAmountMap = CollUtil.isNotEmpty(gdfList) ? gdfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getOverinflatedAmount, (o1,o2)->o1)) : new HashMap<>();
+        //Map<String, BigDecimal> gdfSettledDiffAmountMap = CollUtil.isNotEmpty(gdfList) ? gdfList.stream().collect(Collectors.toMap(CalRes::getCompanyId, CalRes::getOverinflatedAmount, (o1,o2)->o1)) : new HashMap<>();
 
         // 计算已开票和未开票
         for (String companyId : companyMap.keySet()) {
@@ -5404,37 +5447,37 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             companySuperviseSettlementReportDto.setSxfInvoicedAmount(Objects.toString(sxf,BigDecimal.ZERO+""));
             BigDecimal sxfOverinflatedAmount = sxfOverinflatedAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
             companySuperviseSettlementReportDto.setTotalOverinflatedAmount(Objects.toString(sxfOverinflatedAmount,BigDecimal.ZERO+""));
-            BigDecimal gdf = gdfInvoicedAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
-            companySuperviseSettlementReportDto.setGdfInvoicedAmount(Objects.toString(gdf,BigDecimal.ZERO+""));
+//            BigDecimal gdf = gdfInvoicedAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
+            //companySuperviseSettlementReportDto.setGdfInvoicedAmount(Objects.toString(gdf,BigDecimal.ZERO+""));
             // 平台就没有未结算的,只要结算就是已结算的
             companySuperviseSettlementReportDto.setPtInvoicedAmount(companySuperviseSettlementReportDto.getTotalReceivable());
 
             CompanySuperviseSettlementReportDto dto;
             dto = companyMap.get(companyId);
             companySuperviseSettlementReportDto.setSxfUnInvoicedAmount(BigDecimalUtil.subtract(new BigDecimal(dto.getSuperviseFee()),BigDecimalUtil.subtract(sxf, new BigDecimal(dto.getTotalOverinflatedAmount()))).toString());
-            companySuperviseSettlementReportDto.setGdfUnInvoicedAmount(BigDecimalUtil.subtract(new BigDecimal(dto.getFollowFee()),BigDecimalUtil.subtract(gdf,new BigDecimal(dto.getTotalOverinflatedAmount()))).toString());
+            //companySuperviseSettlementReportDto.setGdfUnInvoicedAmount(BigDecimalUtil.subtract(new BigDecimal(dto.getFollowFee()),BigDecimalUtil.subtract(gdf,new BigDecimal(dto.getTotalOverinflatedAmount()))).toString());
             companySuperviseSettlementReportDto.setPtUnInvoicedAmount(BigDecimal.ZERO.toString());
 
             BigDecimal sxfS = sxfSettledAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
-            BigDecimal gdfS = gdfSettledAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
+            //BigDecimal gdfS = gdfSettledAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
             BigDecimal overinflatedAmount = sxfOverinflatedAmountMap.getOrDefault(companyId, BigDecimal.ZERO);
             companySuperviseSettlementReportDto.setSxfSettledAmount(Objects.toString(sxfS, BigDecimal.ZERO+""));
             companySuperviseSettlementReportDto.setSxfUnSettledAmount(BigDecimalUtil.subtract(sxf,BigDecimalUtil.add(sxfS,sxfSettledDiffAmountMap.getOrDefault(companyId, BigDecimal.ZERO))).toString());
             companySuperviseSettlementReportDto.setTotalOverinflatedAmount(Objects.toString(overinflatedAmount, BigDecimal.ZERO+""));
             companySuperviseSettlementReportDto.setSettlementPaymentDifference(Objects.toString(sxfSettledDiffAmountMap.getOrDefault(companyId, BigDecimal.ZERO)) );
 
-            companySuperviseSettlementReportDto.setGdfSettledAmount(Objects.toString(gdfS, BigDecimal.ZERO+""));
-            companySuperviseSettlementReportDto.setGdfUnSettledAmount(BigDecimalUtil.subtract(gdf,gdfS).toString());
+            //companySuperviseSettlementReportDto.setGdfSettledAmount(Objects.toString(gdfS, BigDecimal.ZERO+""));
+            //companySuperviseSettlementReportDto.setGdfUnSettledAmount(BigDecimalUtil.subtract(gdf,gdfS).toString());
 
             // 当起始日期有值的时候,计算的没有意义
             if(StrUtil.isNotEmpty(queryVo.getInvoiceStartTime())){
                 companySuperviseSettlementReportDto.setSxfUnInvoicedAmount("-");
-                companySuperviseSettlementReportDto.setGdfUnInvoicedAmount("-");
+                //companySuperviseSettlementReportDto.setGdfUnInvoicedAmount("-");
                 companySuperviseSettlementReportDto.setPtUnInvoicedAmount("-");
             }
             if(StrUtil.isNotEmpty(queryVo.getSettlementStartTime())){
                 companySuperviseSettlementReportDto.setSxfUnSettledAmount("-");
-                companySuperviseSettlementReportDto.setGdfUnSettledAmount("-");
+                // companySuperviseSettlementReportDto.setGdfUnSettledAmount("-");
             }
         }
         return new ArrayList<>(companyMap.values().stream().toList());
@@ -5684,7 +5727,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
                     InsPlyIncomeInvoiceSettlementVo insPlyIncomeInvoiceSettlementVo = baseMapper.querySettledAmountByInvoiceIds(invoiceIdList);
                     action.setSettledAmount(Objects.toString(insPlyIncomeInvoiceSettlementVo.getActualReceivedAmount(),"0"));
                     action.setTotalPaymentDifference(insPlyIncomeInvoiceSettlementVo.getSettlementPaymentDifference());
-                    action.setUnSettledAmount(BigDecimalUtil.subtract(new BigDecimal(action.getTotalReceivable()),insPlyIncomeInvoiceSettlementVo.getActualReceivedAmount()).toString());
+                    action.setUnSettledAmount(BigDecimalUtil.subtract(new BigDecimal(action.getTotalReceivable()),BigDecimalUtil.subtract(insPlyIncomeInvoiceSettlementVo.getActualReceivedAmount(),insPlyIncomeInvoiceSettlementVo.getSettlementPaymentDifference())).toString());
                 }else{
                     action.setSettledAmount("0");
                     action.setUnSettledAmount(BigDecimalUtil.subtract(new BigDecimal(action.getTotalReceivable()),BigDecimal.ZERO).toString());

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

@@ -230,6 +230,10 @@
         (COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) + COALESCE(ipi.jy_supervise_costs_premiums, 0)) AS superviseCostsPremiums,
         -- 3. 总应收跟单费 (修复了括号位置错误,并为最后一个字段补充了默认值 0)
         (COALESCE(ipi.jq_other_costs_premiums, 0) + COALESCE(ipi.sy_other_costs_premiums, 0) + COALESCE(ipi.jy_other_costs_premiums, 0)) AS otherCostsPremiums,
+        (COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0)) AS carInsuranceSuperviseCostsPremiums,
+        COALESCE(ipi.jy_supervise_costs_premiums, 0) AS nonCarInsuranceSuperviseCostsPremiums,
+        (COALESCE(ipi.jq_other_costs_premiums, 0) + COALESCE(ipi.sy_other_costs_premiums, 0)) AS carInsuranceOtherCostsPremiums,
+        COALESCE(ipi.jy_other_costs_premiums, 0) AS nonCarInsuranceOtherCostsPremiums,
         (COALESCE(ipi.jq_supervise_costs_proportion, 0) + COALESCE(ipi.jq_other_costs_proportion, 0)) AS jqTotalProportion,
         (COALESCE(ipi.sy_supervise_costs_proportion, 0) + COALESCE(ipi.sy_other_costs_proportion, 0)) AS syTotalProportion,
         (COALESCE(ipi.jy_supervise_costs_proportion, 0) + COALESCE(ipi.jy_other_costs_proportion, 0)) AS jyTotalProportion,
@@ -335,7 +339,7 @@
                 #{id}
             </foreach>
         </if>
-        <if test="receivableQueryVo.queryType!= null and (receivableQueryVo.queryType == 3 or receivableQueryVo.queryType == 4)">
+        <if test="receivableQueryVo.invoiceType!= null and (receivableQueryVo.invoiceType == 3 or receivableQueryVo.invoiceType == 4)">
             AND ipi.jy_premium != 0
         </if>
         <if test="receivableQueryVo.licenseNo != null and receivableQueryVo.licenseNo != ''">
@@ -661,7 +665,7 @@
         MAX(ipiis.actual_received_amount) AS actual_received_amount,
         MAX(ipiis.receive_payment_date) AS receive_payment_date,
         MAX(ipiis.create_by) AS create_by,
-        MAX(ipiis.create_time) AS create_time
+        MAX(ipiis.create_time) AS create_time, ipiis.settlement_payment_difference , ipiis.settlement_payment_reason, ipii.receivable_supervise_premium
         FROM ins_ply_income_invoice_settlement ipiis
         LEFT JOIN ins_ply_income_invoice ipii ON ipii.id = ipiis.invoice_id AND ipii.is_delete = 0
         LEFT JOIN ins_ply_income_invoice_link ipil ON ipil.invoice_id = ipiis.invoice_id AND ipil.is_delete = 0
@@ -1574,16 +1578,13 @@
             <if test="invoiceRecordQueryVo.invoiceParty != null and invoiceRecordQueryVo.invoiceParty != ''">
                 AND ipii.invoice_party = #{invoiceRecordQueryVo.invoiceParty}
             </if>
+            <if test="invoiceRecordQueryVo.settlementStatus != null and invoiceRecordQueryVo.settlementStatus != ''">
+                AND ipii.status = #{invoiceRecordQueryVo.settlementStatus}
+            </if>
             <if test="invoiceRecordQueryVo.companyNameSimple != null and invoiceRecordQueryVo.companyNameSimple != ''">
                 AND eic.id = #{invoiceRecordQueryVo.companyNameSimple}
             </if>
         </where>
-        <if test="invoiceRecordQueryVo.settlementStatus != null and invoiceRecordQueryVo.settlementStatus != ''">
-            HAVING CASE
-            WHEN ipii.receivable_supervise_premium = SUM(ipiis.actual_received_amount) THEN '1'
-            ELSE '0'
-            END = #{invoiceRecordQueryVo.settlementStatus}
-        </if>
         GROUP BY
         ipii.id,
         ipii.receivable_supervise_premium,