1
0

92 Коммиты f2cbd23df8 ... b318e9130b

Автор SHA1 Сообщение Дата
  Qchen b318e9130b Merge remote-tracking branch 'origin/master' 4 недель назад
  Qchen 328d0a2291 太平改造车型查询接口 4 недель назад
  lixiaolong d80cf2fbea Merge remote-tracking branch 'origin/master' 4 недель назад
  lixiaolong b39918e114 处理方案过滤险种不匹配的问题 4 недель назад
  Qchen 82811a4fbf 太平添加商业险险种保额 4 недель назад
  Liub 76d0d6c213 fix 大地三者附加医保共享保额 4 недель назад
  lixiaolong 08002a93bd Merge remote-tracking branch 'origin/master' 4 недель назад
  lixiaolong e80e62a7a3 处理操作轨迹表记录查询异常的问题 4 недель назад
  Liub 0bcb0b97a3 fix 合伙人添加和查询关系bug 4 недель назад
  Qchen 21b9701409 Merge remote-tracking branch 'origin/master' 4 недель назад
  Qchen 31a8ef86a5 修改 4 недель назад
  lixiaolong cccda809d3 Merge remote-tracking branch 'origin/master' 4 недель назад
  lixiaolong cdfedf31af 处理订单按车牌+状态分组去重;添加公司logo的问题;批量调整费用比例插入操作轨迹表记录 4 недель назад
  785834757 f853a5342e Merge remote-tracking branch 'origin/master' 4 недель назад
  785834757 bcb30c2d7f 影像判断空 4 недель назад
  Liub 99a54e3264 Merge remote-tracking branch 'origin/master' 4 недель назад
  Liub 1fb82f9da8 fix 方案管理基础方案驾意险不做默认 强制限制 4 недель назад
  wanghao f24a1ae326 Merge remote-tracking branch 'origin/master' 4 недель назад
  wanghao c73e1003c7 子订单查询不到,领导id 递归查询 4 недель назад
  jiakai 5775870277 Merge remote-tracking branch 'origin/master' 4 недель назад
  jiakai 8d3d235cd4 Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260901' 4 недель назад
  wanghao 9d6b33905f 主订单查询业务员,需要递归查全部下属业务员及自己 4 недель назад
  Qchen 7714e1a0b3 Merge remote-tracking branch 'origin/master' 4 недель назад
  Qchen d4cefa7c49 太平配置 4 недель назад
  liub f0043987dd Merge remote-tracking branch 'origin/master' 4 недель назад
  liub ca95d436c4 fix 4 недель назад
  lipf 365caed158 Merge branch 'dev_jzg_lipf_v20260901' 4 недель назад
  wanghao e4178058ad 报价业务员权限配置过滤 4 недель назад
  liub 643d0567bf fix 4 недель назад
  liub 0c56887f96 fix 承保规则包含不包含问题处理 4 недель назад
  liub 29d25ebea7 fix 费用管理首次添加费用时 车牌号显示代码的问题 1 месяц назад
  Qchen b4a4bbeeb2 中煤归属不一致问题修改 1 месяц назад
  jiakai 38d978b16c Merge remote-tracking branch 'origin/master' 1 месяц назад
  jiakai dcc788c730 Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260901' 1 месяц назад
  liub e532f0ef0a fix 方案管理 限制驾意险只可存在一个默认或强制 1 месяц назад
  lixiaolong d3c71b09c4 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong 6a9d27e9a8 处理跨域、抽奖增加白名单的问题;处理远程调用增加抽奖次数异常的问题 1 месяц назад
  jiakai a3b3504e53 Merge remote-tracking branch 'origin/master' 1 месяц назад
  jiakai 2ca64f9c37 Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260901' 1 месяц назад
  liub 6d2c849fc8 fix 方案管理 自选方案不限制座位数 1 месяц назад
  lixiaolong 990780e4f4 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong c5ec350421 处理跨域、抽奖增加白名单的问题 1 месяц назад
  liub fd5ecc809a Merge remote-tracking branch 'origin/master' 1 месяц назад
  liub c413ef65d4 fix 承保规则单挑批量复制 1 месяц назад
  lixiaolong dff2bc34a2 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong fa4647ec69 处理跨域、抽奖增加白名单的问题 1 месяц назад
  wanghao d13199ba66 Merge remote-tracking branch 'origin/master' 1 месяц назад
  wanghao b2ca1f578b 递归查询报价业务员 1 месяц назад
  jiakai 9a3e737d19 Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260901' 1 месяц назад
  lipf aaa6620985 Merge branch 'dev_jzg_lipf_v20260901' 1 месяц назад
  xuqiang 0ae6b41799 Merge remote-tracking branch 'origin/master' 1 месяц назад
  xuqiang 501eaf7c56 合伙人添加业务员 1 месяц назад
  lipf 95aeda553b Merge branch 'master' of http://39.101.143.165:8090/785834757/jzg 1 месяц назад
  lipf 5269d4d0dd Merge branch 'dev_jzg_lipf_v20260901' 1 месяц назад
  lixiaolong 0bb3861f00 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong d11aabb430 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  785834757 1f22c8ff51 添加车主 投保人 被保人姓名因子 1 месяц назад
  lixiaolong cee44a4561 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong 2149da81b3 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  lipf 353dbdcdcb Merge branch 'dev_jzg_lipf_v20260901' 1 месяц назад
  lixiaolong d25d51504c 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  lixiaolong 9938ebdc52 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  lixiaolong 18ee582af8 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  lixiaolong 0f35c5da68 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong 5d77277071 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  xuqiang 7a1303cba8 合伙人添加业务员 1 месяц назад
  lixiaolong 3d0e49e61c 处理批量设置比例出口留点比例大于出口比例的问题 1 месяц назад
  lixiaolong 1ad2bcf26f Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong 3b64358153 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  Qchen 0f7d5b6a92 更新推荐人同时更新推荐人关系表 1 месяц назад
  Qchen 08d7b62d30 Merge remote-tracking branch 'origin/master' 1 месяц назад
  Qchen b0ae5ab892 太平添加决策单元代码 1 месяц назад
  lixiaolong ffa4609888 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  jiakai 95eddeb1eb Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260622' 1 месяц назад
  jiakai 794c643ffc Merge remote-tracking branch 'origin/dev_jzg_lipf_v20260831' 1 месяц назад
  lixiaolong d626b570a7 Merge remote-tracking branch 'origin/master' 1 месяц назад
  lixiaolong d2a3d898f0 处理能源类型只有包含不包含 这个调整下 别的去掉的问题;增加不包含操作符处理逻辑 1 месяц назад
  Qchen 6097704f64 Merge remote-tracking branch 'origin/master' 1 месяц назад
  Qchen c2feb0b271 团队新增负责人字段 分销逻辑统一切换字段 1 месяц назад
  lipf 970e80971c Merge remote-tracking branch 'refs/remotes/origin/master' into dev_jzg_lipf_v20260622 1 месяц назад
  jiakai 27bdedc7bc 修改bug: 1 месяц назад
  lipf a6c40d7d63 Merge branch 'dev_jzg_lipf_v20260901' 1 месяц назад
  wanghao 2934b29236 Merge remote-tracking branch 'origin/master' 1 месяц назад
  wanghao 0a143d5b84 登陆账号用户不存在时捕获异常,提示信息不友好的问题修复 1 месяц назад
  lipf 26f3fd308e Merge branch 'dev_jzg_lipf_v20260901' 1 месяц назад
  Qchen b41ac40c81 Merge remote-tracking branch 'origin/master' 1 месяц назад
  Qchen ede3ead68d 其他分销逻辑修改 1 месяц назад
  wanghao ad47d53bac 复制方案,替换事务回滚方式 1 месяц назад
  wanghao 079b0c92c4 新增报价页面的业务员列表 1 месяц назад
  lipf f730ebdcc8 平台协议样式调整对应的后台代码调整 1 месяц назад
  lipf 9976eab653 平台协议样式调整对应的后台代码调整 1 месяц назад
  lipf 33766d19c2 根据私有协议调整后端逻辑 1 месяц назад
66 измененных файлов с 2087 добавлено и 1002 удалено
  1. 3 0
      authentication/src/main/java/com/jzg/config/JzgAuthenticationProvider.java
  2. 1 1
      authentication/src/main/java/com/jzg/config/SecurityConfig.java
  3. 10 0
      commons/src/main/java/com/jzg/commons/constants/dict/InsOrderStatusEnum.java
  4. 39 0
      commons/src/main/java/com/jzg/commons/entity/dto/AgreementRulesAttrCopyParam.java
  5. 4 0
      commons/src/main/java/com/jzg/commons/entity/dto/InsOrdersParamVO.java
  6. 3 1
      commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostAdd.java
  7. 7 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/InvoiceRecordQueryVo.java
  8. 21 1
      commons/src/main/java/com/jzg/commons/entity/finance/vo/ReceivableQueryVo.java
  9. 27 0
      commons/src/main/java/com/jzg/commons/entity/finance/vo/SettlementQueryVo.java
  10. 6 0
      commons/src/main/java/com/jzg/commons/entity/orders/vo/OrderListVo.java
  11. 2 0
      commons/src/main/java/com/jzg/commons/entity/po/SysOrganization.java
  12. 23 0
      commons/src/main/java/com/jzg/commons/entity/scheme/vo/PtlSchemeSaveVo.java
  13. 6 0
      commons/src/main/java/com/jzg/commons/entity/vo/RuleAttrMappingVo.java
  14. 2 2
      commons/src/main/java/com/jzg/commons/service/impl/OperatorTrajectoryServiceImpl.java
  15. 6 0
      gateway/src/main/java/com/jzg/config/CorsConfig.java
  16. 6 0
      gateway/src/main/java/com/jzg/filter/AuthGlobalFilter.java
  17. 11 0
      gateway/src/main/java/com/jzg/filter/DecryptFilter.java
  18. 4 4
      partner/src/main/java/com/jzg/entity/vo/RelationalVo.java
  19. 1 8
      partner/src/main/java/com/jzg/service/Impl/PartnerUserServiceImpl.java
  20. 2 2
      partner/src/main/java/com/jzg/utils/DistributionUtils.java
  21. 33 20
      partner/src/main/resources/mapper/PartnerUserMapper.xml
  22. 7 2
      tenant/costsorrule/src/main/java/com/jzg/costsorrule/constants/OperatorConstant.java
  23. 53 63
      tenant/costsorrule/src/main/java/com/jzg/costsorrule/service/impl/RuleServiceImpl.java
  24. 3 3
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/client/OrgClient.java
  25. 34 8
      tenant/insurance/quotation-dadi/src/main/java/com/jzg/quotation/dadi/crawler/entity/request/DaDiInsurancePlanRequest.java
  26. 15 9
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java
  27. 7 10
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java
  28. 201 99
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  29. 11 8
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsTaskImagesServiceImpl.java
  30. 6 0
      tenant/insurance/quotation-summary/src/main/resources/application-prod.yaml
  31. 57 18
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml
  32. 1 1
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/component/TaiPingCrawlerRequestComponent.java
  33. 9 1
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/TaipingCrawlerConfigureParameters.java
  34. 4 5
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerBrandNameQueryRequest.java
  35. 1 1
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerGetCarDepreRateRequest.java
  36. 236 207
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerPremiumCalculateRequest.java
  37. 6 9
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerSubmitValidateRequest.java
  38. 8 3
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/response/TaiPingCrawlerBrandNameQueryData.java
  39. 8 3
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/response/TaiPingCrawlerPremiumCalculateData.java
  40. 140 20
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/service/impl/TaipingCrawlerRequestImpl.java
  41. 4 4
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/ZmCrawlerConfigureParameters.java
  42. 1 1
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/dto/SaleInfoDTO.java
  43. 108 129
      tenant/organization/src/main/java/com/jzg/organization/component/BuildDescUtils.java
  44. 10 1
      tenant/organization/src/main/java/com/jzg/organization/controller/AgreementRulesController.java
  45. 16 12
      tenant/organization/src/main/java/com/jzg/organization/controller/ReceivableController.java
  46. 3 3
      tenant/organization/src/main/java/com/jzg/organization/controller/SysOrganizationController.java
  47. 1 1
      tenant/organization/src/main/java/com/jzg/organization/controller/UserController.java
  48. 4 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/EsmUserReferrerMapper.java
  49. 11 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserJzgInfoMapper.java
  50. 11 1
      tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementUndwrtRulesService.java
  51. 6 1
      tenant/organization/src/main/java/com/jzg/organization/service/SysOrganizationService.java
  52. 1 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysUserJzgInfoService.java
  53. 1 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysUserService.java
  54. 100 46
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java
  55. 119 4
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementUndwrtRulesServiceImpl.java
  56. 3 4
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java
  57. 111 61
      tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java
  58. 8 3
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SignInServiceImpl.java
  59. 21 3
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysOrganizationServiceImpl.java
  60. 3 1
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgAppServiceImpl.java
  61. 4 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgInfoServiceImpl.java
  62. 237 148
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java
  63. 4 2
      tenant/organization/src/main/resources/application.yml
  64. 102 61
      tenant/organization/src/main/resources/mapper/ReceivableMapper.xml
  65. 92 0
      tenant/organization/src/main/resources/mapper/SysUserJzgInfoMapper.xml
  66. 82 7
      协议承保规则接口对接文档.md

+ 3 - 0
authentication/src/main/java/com/jzg/config/JzgAuthenticationProvider.java

@@ -419,6 +419,9 @@ public class JzgAuthenticationProvider implements AuthenticationProvider {
                     .filter(x -> Objects.equals(x.getSystemCode(), system))
                     .findFirst()
                     .orElse(null);
+            if(sysUserJzgInfo == null){
+                throw new SystemException("该用户信息不存在,请重新输入");
+            }
             // 租户系统才会校验这个, 后台管理系统,没有租户的概念
             if(this.isTenantLogin(system)){
                 if (sysUserJzgInfo.cannotLogin()) {

+ 1 - 1
authentication/src/main/java/com/jzg/config/SecurityConfig.java

@@ -95,7 +95,7 @@ public class SecurityConfig {
                                 "/auth/login","/auth/captchaById","/auth/register","/sendSmsCode","/appLogin","/smsCodeLogin","/auth/publicKeyExchange","/appAuth/smsCodeLogin","/send/sendSmsCode",
                                 "/appAuth/appLogin","/auth/sendSmsCode","/auth/forgotPassword","/appAuth/partnerAppLogin",
                                 "/supplementOrder/getOrderDetail","/dict/get", "/getAllButtons","/order/qrCode/**","/appUser/userInfoGet",
-                                "/appUser/distributorInvite","/appUser/invitationRegister").permitAll()
+                                "/appUser/distributorInvite","/appUser/invitationRegister","/system/sysListAccountLinking","/signIn/updateSignCompleteRuleIn").permitAll()
                         .anyRequest().authenticated()  // 其他接口需认证
                 )
 //                .formLogin((form) -> form

+ 10 - 0
commons/src/main/java/com/jzg/commons/constants/dict/InsOrderStatusEnum.java

@@ -46,5 +46,15 @@ public enum InsOrderStatusEnum implements IBaseEnum {
         return result;
     }
 
+    /**
+     * 根据code获取描述
+     * @param code 状态码
+     * @return desc,找不到返回null
+     */
+    public static String getDescByCode(String code) {
+        InsOrderStatusEnum statusEnum = matchKey(code);
+        return statusEnum != null ? statusEnum.getDesc() : null;
+    }
+
 
 }

+ 39 - 0
commons/src/main/java/com/jzg/commons/entity/dto/AgreementRulesAttrCopyParam.java

@@ -0,0 +1,39 @@
+package com.jzg.commons.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 批量复制规则因子参数
+ *
+ * @author lipf
+ * @date 2026/9/2
+ */
+@Schema(description = "批量复制规则因子dto")
+@Data
+public class AgreementRulesAttrCopyParam {
+
+    @Schema(description = "要复制的规则因子关联记录ID列表(来源于getRuleInfo返回明细的id字段),源规则由所选因子记录所属规则确定")
+    @NotEmpty(message = "请指定要复制的规则因子")
+    private List<String> attrIds;
+
+    @Schema(description = "目标协议规则列表")
+    @NotEmpty(message = "目标协议不能为空")
+    private List<CopyTarget> targets;
+
+    @Schema(description = "复制目标")
+    @Data
+    public static class CopyTarget {
+
+        @Schema(description = "目标承保协议ID")
+        @NotBlank(message = "目标协议ID不能为空")
+        private String agreementId;
+
+        @Schema(description = "目标承保规则ID(可选);为空时若该协议下已有规则则复制到第一条规则,否则新增规则")
+        private String ruleId;
+    }
+}

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

@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.util.Date;
+import java.util.List;
 
 
 @Data
@@ -61,6 +62,9 @@ public class InsOrdersParamVO extends PageRequest {
     @Schema(description = "主订单标识")
     private String parentId;
 
+    @Schema(description = "主订单标识")
+    private List<String> parentIds;
+
     @Schema(description = "投保人")
     private String policyholder;
 

+ 3 - 1
commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostAdd.java

@@ -10,7 +10,6 @@ import lombok.Data;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.Date;
 import java.util.List;
 
 @Data
@@ -88,6 +87,9 @@ public class PtlAgreementCostAdd {
         @Schema(description = "操作符")
         private String operator;
 
+        @Schema(description = "操作数组")
+        private List<String> minArray;
+
         @Schema(description = "协议承保规则字典")
         private List<PtlAgreementUndwrtRulesDictLabal> dictLabal;
 

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

@@ -4,6 +4,7 @@ import com.jzg.commons.core.base.PageRequest;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -88,4 +89,10 @@ public class InvoiceRecordQueryVo extends PageRequest {
      */
     @Schema(description = "签署月份")
     private String signMonth;
+
+    @Schema(description = "开票金额")
+    private BigDecimal receivableSupervisePremium;
+
+    @Schema(description = "开票金额(参数接收)")
+    private String amount;
 }

+ 21 - 1
commons/src/main/java/com/jzg/commons/entity/finance/vo/ReceivableQueryVo.java

@@ -113,6 +113,9 @@ public class ReceivableQueryVo extends PageRequest {
     @Schema(description = "结算状态")
     private String settlementStatus;
 
+//    @Schema(description = "结算人(姓名/手机号)")
+//    private String settlementPerson;
+
     @Schema(description = "开票和结算状态")
     private String invoiceSettlementStatus;
 
@@ -125,6 +128,12 @@ public class ReceivableQueryVo extends PageRequest {
     @Schema(description = "租户代码")
     private String systemCode;
 
+    @Schema(description = "业务员姓名")
+    private String salesmanName;
+
+    @Schema(description = "业务员手机号")
+    private String salemanPhone;
+
     /**
      * 类型:1:手续费 2:跟单费 3:驾意手续费 4:驾意跟单费
      */
@@ -139,15 +148,26 @@ public class ReceivableQueryVo extends PageRequest {
     @Schema(description = "报价开始时间")
     private String reportTimeBegin;
 
+    // 后期调整成 quotationTimeBegin 字段
     @Schema(description = "报价结束时间")
     private String reportTimeEnd;
 
+    @Schema(description = "报价开始时间")
+    private String quotationTimeBegin;
+
+    @Schema(description = "报价结束时间")
+    private String quotationTimeEnd;
+
     @Schema(description = "保险机构")
     private String partnerCompanyId;
 
-    @Schema(description = "修改人")
+    @Schema(description = "应收修改人")
     private String updateBy;
 
+    @Schema(description = "投保人")
+    private String policyholder;
 
+    @Schema(description = "被保人")
+    private String insurName;
 
 }

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

@@ -100,4 +100,31 @@ public class SettlementQueryVo extends PageRequest {
 
     @Schema(description = "发票号")
     private String invoiceNo;
+
+    @Schema(description = "交强险保单号")
+    private String jqPolicyNo;
+    @Schema(description = "商业险保单号")
+    private String syPolicyNo;
+    @Schema(description = "驾意险保单号")
+    private String jyPolicyNo;
+
+    @Schema(description = "车牌号")
+    private String licenseNo;
+
+    @Schema(description = "被保人")
+    private String insurName;
+
+    @Schema(description = "订单号")
+    private String orderNo;
+
+    @Schema(description = "签单时间-起")
+    private String signingTimeBegin;
+
+    @Schema(description = "签单时间-止")
+    private String signingTimeEnd;
+
+    @Schema(description = "签单时间(如退保、批加,下拉点选)")
+    private String orderStatus;
+
+
 }

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

@@ -23,6 +23,9 @@ public class OrderListVo {
     @ExcelProperty("公司名称")
     private String companyName;
 
+    @ExcelProperty("公司LOGO")
+    private String companyLogo;
+
     @ExcelProperty("报价单号")
     private String no;
     /**
@@ -38,6 +41,9 @@ public class OrderListVo {
     //订单状态
     @ExcelProperty("订单状态")
     private String orderStatus;
+    //订单状态
+    @ExcelProperty("订单状态值")
+    private String orderStatusName;
     //车牌号
     @ExcelProperty("车牌号")
     private String licenseNo;

+ 2 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysOrganization.java

@@ -25,6 +25,8 @@ public class SysOrganization extends BaseModel {
 
     private String managerId;
 
+    private String principalId;
+
     private String describeInformation;
 
     private int attribute;

+ 23 - 0
commons/src/main/java/com/jzg/commons/entity/scheme/vo/PtlSchemeSaveVo.java

@@ -262,6 +262,11 @@ public class PtlSchemeSaveVo {
         List<PtlSchemeInsurance> ptlSchemeInsuranceList = new ArrayList<>();
         for (Scheme scheme : schemeList) {
             scheme.schemeInsuranceList.forEach(schemeInsurance -> {
+                if (Objects.isNull(schemeInsurance.getOptionId()) || schemeInsurance.getOptionId().isEmpty()) {
+                    String insuranceName = Objects.isNull(schemeInsurance.getKindName()) || schemeInsurance.getKindName().isEmpty()
+                            ? schemeInsurance.getInsuranceId() : schemeInsurance.getKindName();
+                    throw new ValidateException("方案[" + scheme.getSchemeName() + "]中险种[" + insuranceName + "]未选择保额");
+                }
                 schemeInsurance.getOptionId().forEach(optionId ->{
                     PtlSchemeInsurance ptlSchemeInsurance = new PtlSchemeInsurance();
                     if(Objects.isNull(scheme.getId()) || scheme.getId().isEmpty()) {
@@ -281,6 +286,24 @@ public class PtlSchemeSaveVo {
     public List<PtlSchemeInsuranceDrivingIntention> getPtlSchemeInsuranceDrivingIntentionList(){
         List<PtlSchemeInsuranceDrivingIntention> ptlSchemeInsuranceDrivingIntentionList = new ArrayList<>();
         for (Scheme scheme : schemeList) {
+            // 仅自选方案(schemeType 1基础 2自选)才校验驾意险默认/强制选中,基础方案不校验
+            if ("2".equals(this.schemeType)) {
+                // 校验同一方案内驾意险的选中类型:默认选中(1)/强制选中(2)只能出现一种且各最多一条(可选=3)
+                long defaultSelectedCount = scheme.getDrivingList().stream()
+                        .filter(drivingIntention -> "1".equals(drivingIntention.getSelectedStatus())).count();
+                long forceSelectedCount = scheme.getDrivingList().stream()
+                        .filter(drivingIntention -> "2".equals(drivingIntention.getSelectedStatus())).count();
+                if (defaultSelectedCount > 1) {
+                    throw new ValidateException("方案[" + scheme.getSchemeName() + "]中默认选中的驾意险只能有一条");
+                }
+                if (forceSelectedCount > 1) {
+                    throw new ValidateException("方案[" + scheme.getSchemeName() + "]中强制选中的驾意险只能有一条");
+                }
+                if (defaultSelectedCount > 0 && forceSelectedCount > 0) {
+                    throw new ValidateException("方案[" + scheme.getSchemeName() + "]中默认选中与强制选中的驾意险不能同时存在");
+                }
+            }
+
             scheme.getDrivingList().forEach(drivingIntention -> {
                 PtlSchemeInsuranceDrivingIntention ptlSchemeInsuranceDrivingIntention = new PtlSchemeInsuranceDrivingIntention();
                 ptlSchemeInsuranceDrivingIntention.setId(IdGenerate.nextId());

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

@@ -107,6 +107,8 @@ public class RuleAttrMappingVo {
             ruleAttrMappingVoList.add(new RuleAttrMappingVo("OwnersInfoSex", ownerInfo.getGender().equals("男") ? "1" : "2"));
             //车主 地址
             ruleAttrMappingVoList.add(new RuleAttrMappingVo("CarOwnersAddress", ownerInfo.getAddr()));
+            //车主姓名
+            ruleAttrMappingVoList.add(new RuleAttrMappingVo("CarOwnersName" ,ownerInfo.getName()));
         }
         // 投保人
         InsOrdersCarUserInfo policyHolderInfo = insOrdersCarUserInfos.stream()
@@ -120,6 +122,8 @@ public class RuleAttrMappingVo {
             ruleAttrMappingVoList.add(new RuleAttrMappingVo("PolicyHolderInfoSex", policyHolderInfo.getGender().equals("男") ? "1" : "2"));
             //投保人 地址
             ruleAttrMappingVoList.add(new RuleAttrMappingVo("PolicyHolderInfoAddress", policyHolderInfo.getAddr()));
+            //投保人姓名
+            ruleAttrMappingVoList.add(new RuleAttrMappingVo("PolicyHolderInfoName", policyHolderInfo.getName()));
         }
         //被保人
         InsOrdersCarUserInfo insuredPersonInfo = insOrdersCarUserInfos.stream()
@@ -133,6 +137,8 @@ public class RuleAttrMappingVo {
             ruleAttrMappingVoList.add(new RuleAttrMappingVo("InsuredPersonInfoSex", insuredPersonInfo.getGender().equals("男") ? "1" : "2"));
             //被保人 地址
             ruleAttrMappingVoList.add(new RuleAttrMappingVo("InsuredPersonInfoAddress", insuredPersonInfo.getAddr()));
+            //被保人 姓名
+            ruleAttrMappingVoList.add(new RuleAttrMappingVo("InsuredPersonInfoName", insuredPersonInfo.getName()));
         }
         String OPIConsistent = "0";
         if(StringUtils.isNotBlank(ownerInfo.getCerType().toString())){

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

@@ -67,8 +67,8 @@ public class OperatorTrajectoryServiceImpl implements OperatorTrajectoryService
     public Page<OperatorTrajectory> list(LogParam logParam) {
 
         LambdaQueryWrapper<OperatorTrajectory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
-        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.getOperator()),OperatorTrajectory::getCreateByName,logParam.getOperator());
+        lambdaQueryWrapper.like(StringUtils.isNotEmpty(logParam.getFunction()),OperatorTrajectory::getOperatorType,logParam.getFunction());
         lambdaQueryWrapper.like(StringUtils.isNotEmpty(logParam.getContent()),OperatorTrajectory::getOperationContent,logParam.getContent());
         lambdaQueryWrapper.eq(StringUtils.isNotEmpty(logParam.getPrimaryValue()),OperatorTrajectory::getPrimaryValue,logParam.getPrimaryValue());
         lambdaQueryWrapper.orderByDesc(OperatorTrajectory::getCreateTime);

+ 6 - 0
gateway/src/main/java/com/jzg/config/CorsConfig.java

@@ -43,6 +43,12 @@ public class CorsConfig {
         corsConfiguration.addAllowedOrigin("http://192.168.0.59:9000");
         corsConfiguration.addAllowedOrigin("http://192.168.1.61:9000");
         corsConfiguration.addAllowedOrigin("http://192.168.1.159:9000");
+        corsConfiguration.addAllowedOrigin("http://192.168.1.65:9010");
+        corsConfiguration.addAllowedOrigin("http://localhost:9010");
+        corsConfiguration.addAllowedOrigin("http://192.168.1.65:9020");
+        corsConfiguration.addAllowedOrigin("http://localhost:9020");
+        corsConfiguration.addAllowedOrigin("http://192.168.1.65:8080");
+        corsConfiguration.addAllowedOrigin("https://test.baoxianzhanggui.com");
         // 允许的方法
         corsConfiguration.addAllowedMethod("*");
         // 允许的头信息

+ 6 - 0
gateway/src/main/java/com/jzg/filter/AuthGlobalFilter.java

@@ -10,6 +10,7 @@ import org.springframework.core.Ordered;
 import org.springframework.core.annotation.Order;
 import org.springframework.core.io.buffer.DataBuffer;
 import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
@@ -94,6 +95,11 @@ public class AuthGlobalFilter implements GlobalFilter {
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         String path = exchange.getRequest().getURI().getPath();
 
+        // 跳过 CORS 预检请求
+        if (HttpMethod.OPTIONS.matches(exchange.getRequest().getMethod().name())) {
+            return chain.filter(exchange);
+        }
+
         // 1. 白名单路径直接放行
         if (isWhitelisted(path)) {
             return chain.filter(exchange);

+ 11 - 0
gateway/src/main/java/com/jzg/filter/DecryptFilter.java

@@ -15,6 +15,7 @@ import org.springframework.cloud.gateway.filter.GlobalFilter;
 import org.springframework.core.io.buffer.DataBuffer;
 import org.springframework.core.io.buffer.DataBufferFactory;
 import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.http.HttpMethod;
 import org.springframework.http.server.reactive.ServerHttpRequest;
 import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
 import org.springframework.stereotype.Component;
@@ -25,6 +26,7 @@ import reactor.core.publisher.Mono;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.security.PrivateKey;
+import java.util.List;
 
 
 @Component
@@ -41,8 +43,17 @@ public class DecryptFilter implements GlobalFilter {
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         ServerHttpRequest request = exchange.getRequest();
+        // CORS 预检请求直接放行,避免 NPE
+        if (HttpMethod.OPTIONS.matches(request.getMethod().name())) {
+            return chain.filter(exchange);
+        }
         boolean contains = request.getURI().getPath().contains("/publicKeyExchange");
         if(isEncrypted && !contains) {
+            // 空指针保护
+            List<String> authHeaders = exchange.getRequest().getHeaders().get("authorization");
+            if (authHeaders == null || authHeaders.isEmpty()) {
+                return chain.filter(exchange);
+            }
             String token = exchange.getRequest().getHeaders().get("authorization").get(0);
             String userName = baseController.getUserName(token);
             // 使用 ServerHttpRequestDecorator 包装请求

+ 4 - 4
partner/src/main/java/com/jzg/entity/vo/RelationalVo.java

@@ -23,16 +23,16 @@ public class RelationalVo {
     private String referrerId;
 
 
-    @Schema(description = "推荐人ID")
+    @Schema(description = "推荐人类型")
     private String type;
 
-    @Schema(description = "推荐人ID")
+    @Schema(description = "推荐人姓名")
     private String suggestName;
 
-    @Schema(description = "推荐人ID")
+    @Schema(description = "推荐人部门")
     private String deptName;
 
-    @Schema(description = "推荐人ID")
+    @Schema(description = "推荐人机构")
     private String agencyName;
 
 

+ 1 - 8
partner/src/main/java/com/jzg/service/Impl/PartnerUserServiceImpl.java

@@ -94,15 +94,8 @@ public class PartnerUserServiceImpl extends ServiceImpl<PartnerUserMapper, Partn
     @Override
     public List<RelationalVo> relationalQuery(String id) {
         SysUserJzgInfo sysUserJzgInfo = getSysUserJzgInfo(id);
-        List<RelationalVo> list = new ArrayList<>();
         Integer grade = baseMapper.selectGradeMin(sysUserJzgInfo.getId());
-        List<RelationalVo> partnerUsers = baseMapper.selectByUserId(sysUserJzgInfo.getId(), grade);
-        if (1 < grade) {
-            querySuperiors(list, grade, partnerUsers);
-        }
-        list.addAll(partnerUsers);
-        querySubordinates(partnerUsers, grade, list);
-        return list;
+        return baseMapper.selectByUserId(sysUserJzgInfo.getId(), grade);
     }
 
     public void querySuperiors(List<RelationalVo> list, Integer grade, List<RelationalVo> partnerUsers) {

+ 2 - 2
partner/src/main/java/com/jzg/utils/DistributionUtils.java

@@ -124,8 +124,8 @@ public class DistributionUtils {
         details.setUserName("");
         details.setIssuerId(userId);
         details.setIssuerName("");
-        details.setOrderno(insOrders.getQuoteNo());
-        details.setCompanyId(insOrders.getId());
+        details.setOrderno(insOrders.getId());
+        details.setCompanyId(insOrders.getCompanyId());
         details.setDeptId(partnerUser.getDeptId());
         details.setLicenseno(licenseNo);
         details.setSumpremium(feeOrders.getTotalPremium());

+ 33 - 20
partner/src/main/resources/mapper/PartnerUserMapper.xml

@@ -144,25 +144,39 @@
     </select>
 
     <select id="selectByUserId" resultType="com.jzg.entity.vo.RelationalVo">
-        SELECT
-        p.id,
-        p.NAME AS userName,
-        p.mobile,
-        p.user_id,
-        p.dept_id,
-        (SELECT `name` FROM sys_dept d WHERE d.id = p.dept_id AND d.is_delete = 0) AS deptName,
-        (SELECT username FROM sys_user u WHERE u.id = p.referrer_id AND u.is_delete = 0) AS suggestName,
-        p.grade AS type,
-        p.referrer_id,
-        p.create_time
-        FROM
-        partner_user p
-        LEFT JOIN sys_user_jzg_info u ON u.user_id = p.user_id AND u.is_delete = 0
-        <where>
-            AND p.is_delete = 0
-            AND p.user_id = #{id}
-            AND p.grade = #{grade}
-        </where>
+        WITH RECURSIVE cte_name AS (
+            SELECT
+            p.id,
+            p.NAME AS userName,
+            p.mobile,
+            p.user_id,
+            p.dept_id,
+            (SELECT `name` FROM sys_dept d WHERE d.id = p.dept_id AND d.is_delete = 0) AS deptName,
+            (SELECT name FROM partner_user u WHERE u.user_id = p.referrer_id AND u.is_delete = 0) AS suggestName,
+            p.grade AS type,
+            p.referrer_id,
+            p.create_time
+            FROM
+            partner_user p
+            WHERE p.user_id = #{id} AND grade = #{grade}
+            UNION ALL
+            SELECT
+                pu.id,
+                pu.NAME AS userName,
+                pu.mobile,
+                pu.user_id,
+                pu.dept_id,
+                (SELECT `name` FROM sys_dept d WHERE d.id = pu.dept_id AND d.is_delete = 0)            AS deptName,
+                (SELECT name FROM partner_user u WHERE u.user_id = pu.referrer_id AND u.is_delete = 0) AS suggestName,
+                pu.grade AS type,
+                pu.referrer_id,
+                pu.create_time
+                    FROM
+                    partner_user pu
+                    INNER JOIN cte_name rt ON pu.referrer_id = rt.user_id
+                    WHERE  pu.grade = (rt.type + 1)
+                    )
+        SELECT * FROM cte_name
     </select>
 
     <select id="selectTodayOverview" resultType="com.jzg.entity.vo.TodayOverview">
@@ -893,7 +907,6 @@
         LEFT JOIN sys_user_jzg_info u ON u.id = p.user_id AND u.is_delete = 0
         <where>
             p.is_delete = 0
-            AND u.`status` = 3
             AND p.user_id = #{userId}
             AND p.grade = #{grade}
         </where>

+ 7 - 2
tenant/costsorrule/src/main/java/com/jzg/costsorrule/constants/OperatorConstant.java

@@ -20,7 +20,9 @@ public class OperatorConstant {
         //选择框
         GT("4","大于"),
         //单选框
-        GE("5","大于等于");
+        GE("5","大于等于"),
+        //不等于
+        NE("6","不等于");
 
         private final String code;
         private final String name;
@@ -39,7 +41,10 @@ public class OperatorConstant {
         //选择框
         GT("4","大于"),
         //单选框
-        GE("5","大于等于");
+        GE("5","大于等于"),
+        //不等于
+        NE("6","不等于");
+
 
         private final String code;
         private final String name;

+ 53 - 63
tenant/costsorrule/src/main/java/com/jzg/costsorrule/service/impl/RuleServiceImpl.java

@@ -54,7 +54,8 @@ public class RuleServiceImpl implements RuleService {
                 }
             }
         });
-
+        //处理险种ProductCode-InsruanceProduct 不匹配的情况
+        attrMap.put("insruanceproduct",attrMap.get("productcode"));
 
 
     }
@@ -130,37 +131,40 @@ public class RuleServiceImpl implements RuleService {
         if (min == null || min.isEmpty()) {
             return false;
         }
-        String[] split = min.split(",");
-        for (String sp : split) {
-            if (sp.equals(value)) {
-                return true;
-            }
-        }
-        return false;
+        boolean contains = Arrays.stream(min.split(","))
+                .anyMatch(sp -> sp.trim().equals(value.trim()));
+        // "1"(EQ):在列表中匹配;"6"(NE):不在列表中匹配
+        boolean isEqgate = OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator());
+        return isEqgate ? contains : !contains;
     }
 
     private boolean inputNumberEqual(RuleAttrLinkVo linkVo, String value) {
         double v = Double.parseDouble(value);
+        double min = linkVo.getMin() != null ? Double.parseDouble(linkVo.getMin()) : Double.MIN_VALUE;
+        double max = linkVo.getMax() != null ? Double.parseDouble(linkVo.getMax()) : Double.MAX_VALUE;
         //统一处理数值
         if (OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator())) {
-            if (Double.parseDouble(linkVo.getMin()) <= v &&
-                    Double.parseDouble(linkVo.getMax()) >= v) {
+            if (min <= v && max >= v) {
                 return true;
             }
         } else if (OperatorConstant.InputNumber.LT.getCode().equals(linkVo.getOperator())) {
-            if (Double.parseDouble(linkVo.getMin()) > v) {
+            if (min > v) {
                 return true;
             }
         } else if (OperatorConstant.InputNumber.LE.getCode().equals(linkVo.getOperator())) {
-            if (Double.parseDouble(linkVo.getMin()) >= v) {
+            if (min >= v) {
                 return true;
             }
         } else if (OperatorConstant.InputNumber.GT.getCode().equals(linkVo.getOperator())) {
-            if (Double.parseDouble(linkVo.getMax()) < v) {
+            if (max < v) {
                 return true;
             }
         } else if (OperatorConstant.InputNumber.GE.getCode().equals(linkVo.getOperator())) {
-            if (Double.parseDouble(linkVo.getMax()) <= v) {
+            if (max <= v) {
+                return true;
+            }
+        } else if (OperatorConstant.InputNumber.NE.getCode().equals(linkVo.getOperator())) {// 不包含:不在 [min, max] 区间内
+            if (min > v || max < v) {
                 return true;
             }
         }
@@ -169,68 +173,50 @@ public class RuleServiceImpl implements RuleService {
 
 
     private boolean inputTagEqual(RuleAttrLinkVo linkVo, String value) {
-        //将值进行分割
-
-        AtomicBoolean returnBool = new AtomicBoolean(false);
-
-        List<String> equalsMap = new ArrayList<>();
-        //字符型评分
-        equalsMap.add("CharacterBasedRating");
-        //交强字符型评分
-        equalsMap.add("JqCharacterBasedRating");
-        //商业字符型评分
-        equalsMap.add("SyCharacterBasedRating");
-
-
-
-        //equest 等于判断
-//        if(equalsMap.contains(linkVo.getAttrCode())){
-//            boolean b = value.anyMatch(value::equals);
-//            returnBool.set(b);
-//        }else if((ptlAgreementProductCostsAttrLink.getAttrCode().equals("BrandandModel") || ptlAgreementProductCostsAttrLink.getAttrCode().equals("CarOwnerName"))
-//                && ptlAgreementProductCostsAttrLink.getOperator().equals("2")){
-//            //处理品牌型号  不包含的情况
-//            boolean anyMatch = Arrays.stream(split)
-//                    .anyMatch(value::contains);
-//            returnBool.set(!anyMatch);
-//        }else {
-//            boolean anyMatch = Arrays.stream(split)
-//                    .anyMatch(value::contains);
-//            returnBool.set(anyMatch);
-//        }
-        return returnBool.get();
+        String min = linkVo.getMin();
+        if (min == null || min.isEmpty() || value == null) {
+            return false;
+        }
+        String[] split = min.split(",");
+        List<String> equalsMap = Arrays.asList(
+                "CharacterBasedRating", "JqCharacterBasedRating", "SyCharacterBasedRating");
+        boolean matched;
+        if (equalsMap.contains(linkVo.getAttrCode())) {
+            matched = Arrays.stream(split).anyMatch(value::equals);
+        } else {
+            matched = Arrays.stream(split).anyMatch(value::contains);
+        }
+        boolean isEqgate = OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator());
+        return isEqgate ? matched : !matched;
     }
 
 
     private boolean selectEqual(RuleAttrLinkVo linkVo, String value) {
-        if (linkVo.getMin() != null && linkVo.getMin().contains(value)) {
-            return true;
+        String min = linkVo.getMin();
+        if (min == null || min.isEmpty() || value == null) {
+            return false;
         }
-        return false;
+        boolean contains = min.contains(value);
+        boolean isEqgate = OperatorConstant.InputNumber.EQ.getCode().equals(linkVo.getOperator());
+        return isEqgate ? contains : !contains;
     }
 
     private boolean radioEqual(RuleAttrLinkVo linkVo, String value) {
-        //新能源判断
-//        if ("NewEnergy".equals(linkVo.getAttrCode())) {
-//            // 是否是新能源车
-//            boolean newEnergy = EnergyType.isNewEnergy(value);
-//            if (newEnergy && linkVo.getMin().equals("1")) {
-//                return true;
-//            } else if (!newEnergy && linkVo.getMin().equals("0")) {
-//                return true;
-//            }
-//        } else if (linkVo.getMin().contains(value)) {
-//            return true;
-//        }
-        //判断如果value 是 boolean值 则将min进行转换为bool
-        boolean minValue = Boolean.valueOf(linkVo.getMin());
         if ("NewEnergyMark".equals(linkVo.getAttrCode())) {
+            //判断如果value 是 boolean值 则将min进行转换为bool
+            boolean minValue = Boolean.valueOf(linkVo.getMin());
+            boolean valueBool = Boolean.valueOf(value);
             if (linkVo.getMin().equals("5") || linkVo.getMin().equals("6")) {
                 minValue = linkVo.getMin().equals("5") ? false : true;
+                valueBool = value.equals("5") ? false : true;
+            }
+            if (linkVo.getOperator().equals(OperatorConstant.InputNumber.EQ.getCode())) {
+                return minValue == valueBool;
+            } else if (linkVo.getOperator().equals(OperatorConstant.InputNumber.NE.getCode())) {
+                return !(minValue == valueBool);
             }
         }
-        boolean valueBool = Boolean.valueOf(value);
-        return minValue == valueBool;
+        return linkVo.getOperator().equals(OperatorConstant.InputNumber.EQ.getCode()) ? linkVo.getMin().contains(value) : !linkVo.getMin().contains(value);
     }
 
     public boolean dateTimeEqual(RuleAttrLinkVo linkVo, String value){
@@ -268,6 +254,10 @@ public class RuleServiceImpl implements RuleService {
             if (v.isAfter(max) || v.isEqual(max)) {
                 return true;
             }
+        } else if (OperatorConstant.DateTime.NE.getCode().equals(linkVo.getOperator())) {
+            if (!(v.isAfter(min) && v.isBefore(max))) {
+                return true;
+            }
         }
         return false;
     }

+ 3 - 3
tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/client/OrgClient.java

@@ -278,9 +278,9 @@ public interface OrgClient {
 
     /**
      * 根据人员id 查询是否为团队长
-     * @param id
+     * @param userId
      */
-    @GetMapping("/sysOrganization/queryOrganizationByManagerId")
-    HttpResult<List<SysOrganization>> queryOrganizationByManagerId(@RequestParam("userId")String userId);
+    @GetMapping("/sysOrganization/queryOrganizationByPrincipalId")
+    HttpResult<List<SysOrganization>> queryOrganizationByPrincipalId(@RequestParam("userId")String userId);
 
 }

+ 34 - 8
tenant/insurance/quotation-dadi/src/main/java/com/jzg/quotation/dadi/crawler/entity/request/DaDiInsurancePlanRequest.java

@@ -412,11 +412,18 @@ public class DaDiInsurancePlanRequest extends DaDiBaseRequest {
                     ? daDiNewEnergyVehicleInsurance.toMap()
                     : daDiFuelVehicleInsurance.toMap();
 
+            // 第三者责任险保额:医保外医疗费用责任险“保额为1”表示共享三者保额时使用(未投保三者则为null,不替换)
+            String thirdPartyLimit = quoteVo.getKindInfoVo().stream()
+                    .filter(k -> "B".equals(k.getKindCode()))
+                    .map(KindInfoVo::getAmount)
+                    .findFirst()
+                    .orElse(null);
+
             for (KindInfoVo kindInfoVo : quoteVo.getKindInfoVo()) {
                 String mKindCode = kindInfoVo.getKindCode();
                 DaDiFuelKindInfo target = insuranceMap.get(mKindCode);
                 if (target != null) {
-                    applyNewEnergySpecialProcessing(target, kindInfoVo, actualValue, priceCoefficient, seatCount);
+                    applyNewEnergySpecialProcessing(target, kindInfoVo, actualValue, priceCoefficient, seatCount, thirdPartyLimit);
                     daDiFuelKindInfo.add(target);
                 }
             }
@@ -494,7 +501,8 @@ public class DaDiInsurancePlanRequest extends DaDiBaseRequest {
      * 新能源车险特殊处理:根据平台险种编码,将源KindInfoVo的字段映射到目标DaDiFuelKindInfo
      */
     private void applyNewEnergySpecialProcessing(DaDiFuelKindInfo target, KindInfoVo source,
-                                                 String actualValue, String priceCoefficient, int seatCount) {
+                                                 String actualValue, String priceCoefficient, int seatCount,
+                                                 String thirdPartyLimit) {
         String platformKindCode = source.getKindCode();
 
         switch (platformKindCode) {
@@ -534,21 +542,39 @@ public class DaDiInsurancePlanRequest extends DaDiBaseRequest {
 
             case "SY_FJ_YBW1":
                 // 附加医保外医疗费用责任险(三者)
-                target.setAmount(source.getAmount());
+                // 保额为1时共享第三者责任险保额(未投保三者则不替换,保持原值)
+                if ("1".equals(source.getAmount()) && thirdPartyLimit != null) {
+                    target.setAmount(thirdPartyLimit);
+                } else {
+                    target.setAmount(source.getAmount());
+                }
                 break;
 
             case "SY_FJ_YBW3":
                 // 附加医保外医疗费用责任险(司机)
-                target.setAmount(source.getAmount());
+                // 保额为1时共享第三者责任险保额(未投保三者则不替换,保持原值)
+                if ("1".equals(source.getAmount()) && thirdPartyLimit != null) {
+                    target.setAmount(thirdPartyLimit);
+                } else {
+                    target.setAmount(source.getAmount());
+                }
                 break;
 
             case "SY_FJ_YBW2":
                 // 附加医保外医疗费用责任险(乘客):单人金额 × (座位数-1)
-                int ybw2UnitAmount = Integer.parseInt(source.getAmount());
                 int ybw2Quantity = seatCount - 1;
-                target.setUnitAmount(source.getAmount());
-                target.setQuantity(String.valueOf(ybw2Quantity));
-                target.setAmount(String.valueOf(ybw2UnitAmount * ybw2Quantity));
+                // 保额为1时共享第三者责任险保额:每座=三者保额,unitAmount=三者保额,总额=三者保额×(座位数-1)
+                if (("1".equals(source.getAmount()) || "1".equals(source.getUnitAmount())) && thirdPartyLimit != null) {
+                    int ybw2SharedUnitAmount = Integer.parseInt(thirdPartyLimit);
+                    target.setUnitAmount(thirdPartyLimit);
+                    target.setQuantity(String.valueOf(ybw2Quantity));
+                    target.setAmount(String.valueOf(ybw2SharedUnitAmount * ybw2Quantity));
+                } else {
+                    int ybw2UnitAmount = Integer.parseInt(source.getAmount());
+                    target.setUnitAmount(source.getAmount());
+                    target.setQuantity(String.valueOf(ybw2Quantity));
+                    target.setAmount(String.valueOf(ybw2UnitAmount * ybw2Quantity));
+                }
                 break;
 
             case "TY1":

+ 15 - 9
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java

@@ -345,24 +345,27 @@ public class FactorMatch {
 
     private static boolean checkBoxEqual(PtlAgreementCostRule rule, String value) {
         if (rule.getMin() == null || value == null) return false;
-        return Arrays.stream(rule.getMin().split(",")).anyMatch(o -> o.trim().equals(value.trim()));
+        boolean contains = Arrays.stream(rule.getMin().split(",")).anyMatch(o -> o.trim().equals(value.trim()));
+        return "1".equals(rule.getOperator()) ? contains : !contains;
     }
 
     private static boolean selectEqual(PtlAgreementCostRule rule, String value, PtlAgreementUndwrtRulesAttr meta) {
         if (rule.getMin() == null || value == null) return false;
         if ("LicenseArea".equals(meta.getAttrCode()) || "LicenseNo".equals(meta.getAttrCode())) return inputTextEqual(rule, value);
         if ("VehicleAge".equals(meta.getAttrCode())) return inputNumberEqual(rule, value);
-        return rule.getMin().contains(value);
+        return "1".equals(rule.getOperator()) ? rule.getMin().contains(value) : !rule.getMin().contains(value);
     }
 
     private static boolean radioEqual(PtlAgreementCostRule rule, String value) {
+        String min = rule.getMin();
+        if (min == null || value == null) return false;
         if ("NewEnergyMark".equals(rule.getAttrCode())) {
-            boolean newEnergy = EnergyTypeCode.isNewEnergy(value);
-            if (newEnergy && "1".equals(rule.getMin())) return true;
-            if (!newEnergy && "0".equals(rule.getMin())) return true;
-            return false;
+            // min 为 "1" 表示新能源,否则表示非新能源
+            // operator "1"(等于):新能源状态与规则一致即匹配;operator "6"(不包含):相反
+            boolean matched = EnergyTypeCode.isNewEnergy(value) == "1".equals(min);
+            return "1".equals(rule.getOperator()) ? matched : !matched;
         }
-        return rule.getMin().contains(value);
+        return "1".equals(rule.getOperator()) ? min.contains(value) : !min.contains(value);
     }
 
     private static boolean inputNumberEqual(PtlAgreementCostRule rule, String value) {
@@ -376,6 +379,8 @@ public class FactorMatch {
             case "3": return min >= v;
             case "4": return max < v;
             case "5": return max <= v;
+            // 不包含:不在 [min, max] 区间内
+            case "6": return v < min || v > max;
             default:  return false;
         }
     }
@@ -385,12 +390,12 @@ public class FactorMatch {
         String[] split = rule.getMin().split(",");
         List<String> equalsMap = Arrays.asList("CharacterBasedRating", "JqCharacterBasedRating", "SyCharacterBasedRating");
         if (equalsMap.contains(rule.getAttrCode())) {
-            return Arrays.stream(split).anyMatch(value::equals);
+            return "1".equals(rule.getOperator()) ? Arrays.stream(split).anyMatch(value::equals) : Arrays.stream(split).noneMatch(value::equals);
         }
         boolean contains = Arrays.stream(split).anyMatch(value::contains);
         boolean notOp = ("BrandandModel".equals(rule.getAttrCode()) || "CarOwnerName".equals(rule.getAttrCode())
                 || "CarOwnersAddress".equals(rule.getAttrCode()) || "ApplicantAddress".equals(rule.getAttrCode())
-                || "InsuredAddress".equals(rule.getAttrCode())) && "2".equals(rule.getOperator());
+                || "InsuredAddress".equals(rule.getAttrCode())) && ("6".equals(rule.getOperator()) || "2".equals(rule.getOperator()));
         return notOp ? !contains : contains;
     }
 
@@ -418,6 +423,7 @@ public class FactorMatch {
             case "3": return !v.isAfter(min);
             case "4": return v.isAfter(max);
             case "5": return !v.isBefore(max);
+            case "6": return !v.isAfter(min) || !v.isBefore(max);
             default:  return false;
         }
     }

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

@@ -784,17 +784,14 @@ public class QuoteVerificationAspect {
                 String level = sysDistributionSetting.getDistributionMode();
                 BigDecimal diffAmount = BigDecimal.ZERO;
 
-                // 标识是否需要继续计算下一级
-                boolean continueNextLevel = true;
-
                 switch (level) {
-                    case "1":
+                    case "1" -> {
                         Map<String, Object> level1Result = calculateLevel1Distribution(insFeeOrders, totalPremium, currentUser.getUserId(), sysDistributionSetting);
                         if (Objects.nonNull(level1Result)) {
                             diffAmount = diffAmount.add(new BigDecimal(level1Result.get("diffAmount").toString()));
                         }
-                        break;
-                    case "2":
+                    }
+                    case "2" -> {
                         // 计算一级分销
                         Map<String, Object> firstDistributor = calculateLevel1Distribution(insFeeOrders, totalPremium, currentUser.getUserId(), sysDistributionSetting);
                         if (firstDistributor != null) {
@@ -809,8 +806,8 @@ public class QuoteVerificationAspect {
                             }
                             // 如果一级是团队长,二级分销费用已经在calculateLevel1Distribution中设置为0
                         }
-                        break;
-                    case "3":
+                    }
+                    case "3" -> {
                         // 计算一级分销
                         Map<String, Object> level1 = calculateLevel1Distribution(insFeeOrders, totalPremium, currentUser.getId(), sysDistributionSetting);
                         if (level1 != null) {
@@ -831,7 +828,7 @@ public class QuoteVerificationAspect {
                                 }
                             }
                         }
-                        break;
+                    }
                 }
                 return diffAmount;
             }
@@ -955,7 +952,7 @@ public class QuoteVerificationAspect {
      */
     private boolean isTeamLeader(String userId) {
         try {
-            HttpResult<List<SysOrganization>> organizations = orgClient.queryOrganizationByManagerId(userId);
+            HttpResult<List<SysOrganization>> organizations = orgClient.queryOrganizationByPrincipalId(userId);
             return organizations.getData() != null && !organizations.getData().isEmpty();
         } catch (Exception e) {
             // 异常处理,默认不是团队长

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

@@ -162,6 +162,9 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
     @Autowired
     private ExportBaseServiceImpl exportBaseService;
 
+    @Value("${minio.url}")
+    private String url;
+
     @Value("${minio.bucket-name}")
     private String bucketName;
 
@@ -1130,6 +1133,9 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
             long offset = (current - 1) * size;
             long total = insOrdersMapper.countOrderListDistinct(insOrdersParam);
             List<OrderListVo> records = insOrdersMapper.queryOrderListDistinct(insOrdersParam, offset, size);
+            records.stream().forEach(record -> {
+                record.setCompanyLogo(record.getCompanyLogo() != null ? url + "/" + bucketName + "/" + record.getCompanyLogo() : null);
+            });
             // 大订单:以主订单为主,查询主订单下的从订单并挂载
             if (StringUtils.equals("1", insOrdersParam.getIsLargeOrder()) && CollUtil.isNotEmpty(records)) {
                 List<String> parentIds = records.stream().map(OrderListVo::getOrderNo).collect(Collectors.toList());
@@ -1151,11 +1157,17 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
         if (CollUtil.isNotEmpty(records)) {
             Map<String, String> attrTypeMap = orgClient.queryAllTypeAttrMap();
             List<OrderListVo> list = records.stream().peek(action -> {
+                // 转换状态的值
+                String descByCode = InsOrderStatusEnum.getDescByCode(action.getOrderStatus());
+                action.setOrderStatusName(descByCode);
+
                 String jzgInfoId1 = action.getJzgInfoId();
                 if (StrUtil.isNotEmpty(jzgInfoId1)) {
                     action.setSalesmanType(attrTypeMap.get(jzgInfoId1));
                 }
             }).toList();
+
+
             orderListVoPage.setRecords(list);
         }
         if (StringUtils.equals("1", insOrdersParam.getIsLargeOrder())) {
@@ -1536,15 +1548,29 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
         }
         insOrdersParam.setSystemCode(systemCode);
         Page<OrderListVo> orderListVoPage = queryMainOrderList(insOrdersParam);
+        if (null == orderListVoPage){
+            throw new SystemException("数据为空,导出失败!");
+        }
         List<OrderListVo> orderListVos = orderListVoPage.getRecords();
+        if (CollUtil.isEmpty(orderListVos)){
+            throw new SystemException("数据为空,导出失败!");
+        }
+
+        insOrdersParam.setParentIds(orderListVos.stream().map(OrderListVo::getOrderNo).toList());
+        Page<OrderListVo> orderListVoPageVos = queryList(insOrdersParam);
+        List<OrderListVo> records = orderListVoPageVos.getRecords();
 
-        log.info("导出订单列表,导出[{}]条记录", CollUtil.size(orderListVos));
+        log.info("导出订单列表,导出[{}]条记录", CollUtil.size(records));
         // 动态设置要导出的字段
         String exportDynamicFields = insOrdersParam.getExportDynamicFields();
+        // 把订单状态的枚举值,转换成订单状态的名称
+        if (exportDynamicFields.contains("orderStatus")){
+            exportDynamicFields = exportDynamicFields.replace("orderStatus", "orderStatusName");
+        }
         Set<String> exportFields = new LinkedHashSet<>(Arrays.asList(exportDynamicFields.split(";")));
 
         // 调用动态导出
-        return exportBaseService.upLoadFileDynamic(OrderListVo.class, orderListVos, exportFields, "车险出单-订单管理-动态导出-" + Instant.now());
+        return exportBaseService.upLoadFileDynamic(OrderListVo.class, records, exportFields, "车险出单-订单管理-动态导出-" + Instant.now());
     }
 
 
@@ -2185,63 +2211,99 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
     }
 
     private Map<String, Object> calcDistLevel1(InsFeeOrders o, BigDecimal totalPremium, String userId, SysDistributionSetting setting) {
-        HttpResult<EsmUserReferrer> ref = orgClient.getReferrer(userId);
-        if (ref == null || ref.getData() == null) return null;
-        EsmUserReferrer referrer = ref.getData();
-        HttpResult<SysUserJzgInfo> info = orgClient.getUserInfo(referrer.getReferrerId());
-        if (info == null || info.getData() == null || !"1".equals(info.getData().getIsDistribution())) {
-            o.setFirstDistributionFee(BigDecimal.ZERO);
-            o.setFirstDistributionRatio(BigDecimal.ZERO);
-            return null;
-        }
-        BigDecimal commissionRatio1 = setting.getCommissionRatioLevel1().divide(new BigDecimal(100)).setScale(5, RoundingMode.DOWN);
-        o.setFirstDistributorId(referrer.getReferrerId());
-        BigDecimal fee5 = totalPremium.multiply(commissionRatio1.setScale(5, RoundingMode.DOWN));
-        o.setFirstDistributionFee(totalPremium.multiply(commissionRatio1.setScale(2, RoundingMode.DOWN)));
-        o.setFirstDistributionRatio(commissionRatio1);
-        Map<String, Object> map = new HashMap<>();
-        map.put("id", referrer.getReferrerId());
-        map.put("diffAmount", fee5.subtract(o.getFirstDistributionFee()));
-        return map;
+        HttpResult<EsmUserReferrer> referrerResult = orgClient.getReferrer(userId);
+        if (referrerResult.getData() != null) {
+            EsmUserReferrer referrer = referrerResult.getData();
+            HttpResult<SysUserJzgInfo> referrerInfoResult = orgClient.getUserInfo(referrer.getReferrerId());
+            if (referrerInfoResult.getData() != null && "1".equals(referrerInfoResult.getData().getIsDistribution())) {
+                String distributorId = referrer.getReferrerId();
+
+                BigDecimal commissionRatio1 = setting.getCommissionRatioLevel1().divide(new BigDecimal(100)).setScale(5, RoundingMode.DOWN);
+                o.setFirstDistributorId(distributorId);
+                BigDecimal fee_5 = (totalPremium.multiply(commissionRatio1).setScale(5, RoundingMode.DOWN));
+                o.setFirstDistributionFee(totalPremium.multiply(commissionRatio1).setScale(2, RoundingMode.DOWN));
+                o.setFirstDistributionRatio(commissionRatio1.multiply(new BigDecimal(100)));
+                BigDecimal diffAmount = fee_5.subtract(o.getFirstDistributionFee());
+
+                // 如果一级分销是团队长,清空后续分销费用(二级、三级)
+                if (isTeamLeader(distributorId)) {
+                    o.setSecondDistributionFee(BigDecimal.ZERO);
+                    o.setSecondDistributionRatio(BigDecimal.ZERO);
+                    o.setThirdDistributionFee(BigDecimal.ZERO);
+                    o.setThirdDistributionRatio(BigDecimal.ZERO);
+                    // 清空后续分销人ID
+                    o.setSecondDistributorId(null);
+                    o.setThirdDistributorId(null);
+                }
+
+                Map<String, Object> map = new HashMap<>();
+                map.put("id", distributorId);
+                map.put("diffAmount", diffAmount);
+                return map;
+            } else {
+                o.setFirstDistributionFee(BigDecimal.ZERO);
+                o.setFirstDistributionRatio(BigDecimal.ZERO);
+            }
+        }
+        return null;
     }
 
     private Map<String, Object> calcDistLevel2(InsFeeOrders o, BigDecimal totalPremium, String upperId, SysDistributionSetting setting) {
-        HttpResult<EsmUserReferrer> ref = orgClient.getReferrer(upperId);
-        if (ref == null || ref.getData() == null) return null;
-        EsmUserReferrer referrer = ref.getData();
-        HttpResult<SysUserJzgInfo> info = orgClient.getUserInfo(referrer.getReferrerId());
-        if (info == null || info.getData() == null || !"1".equals(info.getData().getIsDistribution())) {
-            o.setSecondDistributionFee(BigDecimal.ZERO);
-            o.setSecondDistributionRatio(BigDecimal.ZERO);
-            return null;
-        }
-        BigDecimal commissionRatio2 = setting.getCommissionRatioLevel2().divide(new BigDecimal(100)).setScale(5, RoundingMode.DOWN);
-        o.setSecondDistributorId(referrer.getReferrerId());
-        BigDecimal fee5 = totalPremium.multiply(commissionRatio2).setScale(5, RoundingMode.DOWN);
-        o.setSecondDistributionFee(totalPremium.multiply(commissionRatio2).setScale(2, RoundingMode.DOWN));
-        o.setSecondDistributionRatio(commissionRatio2);
-        Map<String, Object> map = new HashMap<>();
-        map.put("id", referrer.getReferrerId());
-        map.put("diffAmount", fee5.subtract(o.getSecondDistributionFee()));
-        return map;
+        HttpResult<EsmUserReferrer> referrerResult = orgClient.getReferrer(upperId);
+        if (referrerResult.getData() != null) {
+            EsmUserReferrer referrer = referrerResult.getData();
+            HttpResult<SysUserJzgInfo> referrerInfoResult = orgClient.getUserInfo(referrer.getReferrerId());
+            if (referrerInfoResult.getData() != null && "1".equals(referrerInfoResult.getData().getIsDistribution())) {
+                String distributorId = referrer.getReferrerId();
+
+                BigDecimal commissionRatio2 = setting.getCommissionRatioLevel2().divide(new BigDecimal(100)).setScale(5, RoundingMode.DOWN);
+                o.setSecondDistributorId(distributorId);
+                BigDecimal fee_5 = (totalPremium.multiply(commissionRatio2).setScale(5, RoundingMode.DOWN));
+                o.setSecondDistributionFee(totalPremium.multiply(commissionRatio2).setScale(2, RoundingMode.DOWN));
+                o.setSecondDistributionRatio(commissionRatio2.multiply(new BigDecimal(100)));
+                BigDecimal diffAmount = fee_5.subtract(o.getSecondDistributionFee());
+
+                // 如果二级分销是团队长,清空后续分销费用(三级)
+                if (isTeamLeader(distributorId)) {
+                    o.setThirdDistributionFee(BigDecimal.ZERO);
+                    o.setThirdDistributionRatio(BigDecimal.ZERO);
+                    o.setThirdDistributorId(null);
+                }
+
+                Map<String, Object> map = new HashMap<>();
+                map.put("id", distributorId);
+                map.put("diffAmount", diffAmount);
+                return map;
+            } else {
+                o.setSecondDistributionFee(BigDecimal.ZERO);
+                o.setSecondDistributionRatio(BigDecimal.ZERO);
+            }
+        }
+        return null;
     }
 
     private BigDecimal calcDistLevel3(InsFeeOrders o, BigDecimal totalPremium, String upperId, SysDistributionSetting setting) {
-        HttpResult<EsmUserReferrer> ref = orgClient.getReferrer(upperId);
-        if (ref == null || ref.getData() == null) return BigDecimal.ZERO;
-        EsmUserReferrer referrer = ref.getData();
-        HttpResult<SysUserJzgInfo> info = orgClient.getUserInfo(referrer.getReferrerId());
-        if (info == null || info.getData() == null || !"1".equals(info.getData().getIsDistribution())) {
-            o.setThirdDistributionFee(BigDecimal.ZERO);
-            o.setThirdDistributionRatio(BigDecimal.ZERO);
-            return BigDecimal.ZERO;
-        }
-        BigDecimal commissionRatio3 = setting.getCommissionRatioLevel3().divide(new BigDecimal(100)).setScale(5, RoundingMode.DOWN);
-        o.setThirdDistributorId(referrer.getReferrerId());
-        BigDecimal fee5 = totalPremium.multiply(commissionRatio3).setScale(5, RoundingMode.DOWN);
-        o.setThirdDistributionFee(totalPremium.multiply(commissionRatio3).setScale(2, RoundingMode.DOWN));
-        o.setThirdDistributionRatio(commissionRatio3);
-        return fee5.subtract(o.getThirdDistributionFee());
+        HttpResult<EsmUserReferrer> referrerResult = orgClient.getReferrer(upperId);
+        if (referrerResult.getData() != null) {
+            EsmUserReferrer referrer = referrerResult.getData();
+            HttpResult<SysUserJzgInfo> referrerInfoResult = orgClient.getUserInfo(referrer.getReferrerId());
+            if (referrerInfoResult.getData() != null && "1".equals(referrerInfoResult.getData().getIsDistribution())) {
+                String distributorId = referrer.getReferrerId();
+                o.setThirdDistributorId(distributorId);
+                BigDecimal commissionRatio3 = setting.getCommissionRatioLevel3().divide(new BigDecimal(100)).setScale(5, RoundingMode.DOWN);
+                BigDecimal fee_5 = (totalPremium.multiply(commissionRatio3).setScale(5, RoundingMode.DOWN));
+                o.setThirdDistributionFee(totalPremium.multiply(commissionRatio3).setScale(2, RoundingMode.DOWN));
+                o.setThirdDistributionRatio(commissionRatio3.multiply(new BigDecimal(100)));
+                BigDecimal diffAmount = fee_5.subtract(o.getThirdDistributionFee());
+
+                // 三级分销如果是团队长,无需清空后续(已经是最后一级)
+                return diffAmount;
+            } else {
+                o.setThirdDistributionFee(BigDecimal.ZERO);
+                o.setThirdDistributionRatio(BigDecimal.ZERO);
+            }
+        }
+        return BigDecimal.ZERO;
     }
 
     // ===== 费用计算辅助方法 =====
@@ -2471,59 +2533,99 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
      * 区别:userId 取自当前登录用户 baseController.getUserId(),而非订单。
      *
      * @param totalPremium 总保费
-     * @param feeOrders    费用订单对象(用于设置分销字段)
+     * @param insFeeOrders    费用订单对象(用于设置分销字段)
      * @param mobile       业务员手机号
      * @return 分销精度差值(scale=5 - scale=2)
      */
-    private BigDecimal calcDistributionFee(BigDecimal totalPremium, InsFeeOrders feeOrders, String mobile) {
-
-        HttpResult<SysUserJzgInfo> userResult = orgClient.getUserInfoByMobile(mobile);
-        if (userResult == null || userResult.getData() == null) {
-            return BigDecimal.ZERO;
-        }
-        String userId = userResult.getData().getUserId();
+    private BigDecimal calcDistributionFee(BigDecimal totalPremium, InsFeeOrders insFeeOrders, String mobile) {
+        // 获取当前租户信息
+        HttpResult<SysUserJzgInfo> sysUserJzgInfoResult = orgClient.getUserInfoByMobile(mobile);
+        SysUserJzgInfo currentUser = sysUserJzgInfoResult.getData();
 
         // 获取租户分销设置
-        HttpResult<SysDistributionSetting> settingResult = orgClient.getSettingBySystemCode();
-        if (settingResult == null || settingResult.getData() == null) {
-            return BigDecimal.ZERO;
-        }
-        SysDistributionSetting sysDistributionSetting = settingResult.getData();
-        // 判断业务员所属机构是否开启分销
-        String deptId = userResult.getData().getDeptId();
-        HttpResult<SysDeptVo> deptResult = orgClient.deptGet(deptId);
-        if (deptResult == null || deptResult.getData() == null || !"1".equals(deptResult.getData().getIsDistribution())) {
-            return BigDecimal.ZERO;
-        }
-        String level = sysDistributionSetting.getDistributionMode();
-        BigDecimal diffAmount = BigDecimal.ZERO;
-        switch (level) {
-            case "1":
-                Map<String, Object> lv1 = calcDistLevel1(feeOrders, totalPremium, userId, sysDistributionSetting);
-                if (lv1 != null) diffAmount = new BigDecimal(lv1.get("diffAmount").toString());
-                break;
-            case "2":
-                Map<String, Object> first = calcDistLevel1(feeOrders, totalPremium, userId, sysDistributionSetting);
-                if (first != null) {
-                    Map<String, Object> second = calcDistLevel2(feeOrders, totalPremium, first.get("id").toString(), sysDistributionSetting);
-                    if (second != null) diffAmount = new BigDecimal(second.get("diffAmount").toString());
-                    diffAmount = diffAmount.add(new BigDecimal(first.get("diffAmount").toString()));
-                }
-                break;
-            case "3":
-                Map<String, Object> l1 = calcDistLevel1(feeOrders, totalPremium, userId, sysDistributionSetting);
-                if (l1 != null) {
-                    Map<String, Object> l2 = calcDistLevel2(feeOrders, totalPremium, l1.get("id").toString(), sysDistributionSetting);
-                    if (l2 != null) {
-                        BigDecimal l3Diff = calcDistLevel3(feeOrders, totalPremium, l2.get("id").toString(), sysDistributionSetting);
-                        diffAmount = diffAmount.add(l3Diff);
-                        diffAmount = diffAmount.add(new BigDecimal(l2.get("diffAmount").toString()));
-                    }
-                    diffAmount = diffAmount.add(new BigDecimal(l1.get("diffAmount").toString()));
+        HttpResult<SysDistributionSetting> setting = orgClient.getSettingBySystemCode();
+        SysDistributionSetting sysDistributionSetting = setting.getData();
+
+        if (sysDistributionSetting != null) {
+            // 判断业务员所属机构是否被排除
+            String deptId = sysUserJzgInfoResult.getData().getDeptId();
+            HttpResult<SysDeptVo> sysDept = orgClient.deptGet(deptId);
+
+            if (sysDept.getData() != null && sysDept.getData().getIsDistribution().equals("1")) {
+                String level = sysDistributionSetting.getDistributionMode();
+                BigDecimal diffAmount = BigDecimal.ZERO;
+
+                switch (level) {
+                    case "1":
+                        Map<String, Object> level1Result = calcDistLevel1(insFeeOrders, totalPremium, currentUser.getUserId(), sysDistributionSetting);
+                        if (Objects.nonNull(level1Result)) {
+                            diffAmount = diffAmount.add(new BigDecimal(level1Result.get("diffAmount").toString()));
+                        }
+                        break;
+
+                    case "2":
+                        // 计算一级分销
+                        Map<String, Object> firstDistributor = calcDistLevel1(insFeeOrders, totalPremium, currentUser.getUserId(), sysDistributionSetting);
+                        if (firstDistributor != null) {
+                            diffAmount = diffAmount.add(new BigDecimal(firstDistributor.get("diffAmount").toString()));
+
+                            // 判断一级分销用户是否为团队长,如果不是则继续计算二级
+                            if (!isTeamLeader(firstDistributor.get("id").toString())) {
+                                Map<String, Object> level2Result = calcDistLevel2(insFeeOrders, totalPremium, firstDistributor.get("id").toString(), sysDistributionSetting);
+                                if (Objects.nonNull(level2Result)) {
+                                    diffAmount = diffAmount.add(new BigDecimal(level2Result.get("diffAmount").toString()));
+                                }
+                            }
+                            // 如果一级是团队长,二级分销费用已经在calculateLevel1Distribution中设置为0
+                        }
+                        break;
+
+                    case "3":
+                        // 计算一级分销
+                        Map<String, Object> level1 = calcDistLevel1(insFeeOrders, totalPremium, currentUser.getId(), sysDistributionSetting);
+                        if (level1 != null) {
+                            diffAmount = diffAmount.add(new BigDecimal(level1.get("diffAmount").toString()));
+
+                            // 判断一级分销用户是否为团队长
+                            if (!isTeamLeader(level1.get("id").toString())) {
+                                // 计算二级分销
+                                Map<String, Object> level2 = calcDistLevel2(insFeeOrders, totalPremium, level1.get("id").toString(), sysDistributionSetting);
+                                if (level2 != null) {
+                                    diffAmount = diffAmount.add(new BigDecimal(level2.get("diffAmount").toString()));
+
+                                    // 判断二级分销用户是否为团队长
+                                    if (!isTeamLeader(level2.get("id").toString())) {
+                                        // 计算三级分销
+                                        BigDecimal level3Diff = calcDistLevel3(insFeeOrders, totalPremium, level2.get("id").toString(), sysDistributionSetting);
+                                        diffAmount = diffAmount.add(level3Diff);
+                                    }
+                                    // 如果二级是团队长,三级分销费用已经在calculateLevel2Distribution中设置为0
+                                }
+                            }
+                            // 如果一级是团队长,二级和三级分销费用已经在calculateLevel1Distribution中设置为0
+                        }
+                        break;
                 }
-                break;
+                return diffAmount;
+            }
+        }
+        return BigDecimal.ZERO;
+    }
+
+    /**
+     * 判断用户是否为团队长
+     */
+    /**
+     * 判断用户是否为团队长
+     */
+    private boolean isTeamLeader(String userId) {
+        try {
+            HttpResult<List<SysOrganization>> organizations = orgClient.queryOrganizationByPrincipalId(userId);
+            return organizations.getData() != null && !organizations.getData().isEmpty();
+        } catch (Exception e) {
+            // 异常处理,默认不是团队长
+            return false;
         }
-        return diffAmount;
     }
 
     /**

+ 11 - 8
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsTaskImagesServiceImpl.java

@@ -19,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 @Service
 public class  InsTaskImagesServiceImpl extends ServiceImpl<InsTaskImagesMapper, InsTaskImages> implements InsTaskImagesService {
@@ -64,14 +65,16 @@ public class  InsTaskImagesServiceImpl extends ServiceImpl<InsTaskImagesMapper,
         int delete = baseMapper.delete(new LambdaUpdateWrapper<InsTaskImages>()
                 .eq(InsTaskImages::getQuoteNo, quoteNo));
         insuranceUploadImageVo.getImageVoList().forEach(imageVo -> {
-            imageVo.getImageBase64List().forEach(base64 ->{
-                InsTaskImages insTaskImages = new InsTaskImages();
-                insTaskImages.setId(IdGenerate.nextId());
-                insTaskImages.setQuoteNo(quoteNo);
-                insTaskImages.setImageType(imageVo.getImageCode());
-                insTaskImages.setImageId(base64.getImageId());
-                images.add(insTaskImages);
-            });
+            if(Objects.nonNull(imageVo.getImageBase64List())) {
+                imageVo.getImageBase64List().forEach(base64 -> {
+                    InsTaskImages insTaskImages = new InsTaskImages();
+                    insTaskImages.setId(IdGenerate.nextId());
+                    insTaskImages.setQuoteNo(quoteNo);
+                    insTaskImages.setImageType(imageVo.getImageCode());
+                    insTaskImages.setImageId(base64.getImageId());
+                    images.add(insTaskImages);
+                });
+            }
         });
         return !baseMapper.insert(images).isEmpty();
     }

+ 6 - 0
tenant/insurance/quotation-summary/src/main/resources/application-prod.yaml

@@ -238,6 +238,12 @@ zijin:
 #    # 对接三方渠道验车链接接口
 #    sendCheckCarLink: http://open.zking.com/api/v1/open/open-aggregate/auth/wanJiaYun/sendCheckCarLink
 
+taiping:
+  crawler:
+    url: https://autopp.tpi.cntaiping.com/api
+    pythonCreateUrl: http://172.24.144.227:8888/create
+    pythonCkUrl: http://172.24.144.227:8888/tpck
+    pythonHzUrl: http://172.24.144.227:8888/tphz
 
 feign:
   client:

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

@@ -859,6 +859,20 @@
 
     <!--查询车险报价订单 modify by lipf 2026年4月28日09:22:46  和田智确认后,将主订单过滤掉-->
     <select id="queryOrderList" resultType="com.jzg.commons.entity.orders.vo.OrderListVo">
+        WITH RECURSIVE leader_tree AS (
+        SELECT ss.id, su.mobile, 1 AS depth
+        FROM sys_user_jzg_info ss
+        LEFT JOIN sys_user su ON su.id = ss.user_id AND su.is_delete = 0
+        WHERE ss.id = #{insOrdersParam.jzgInfoId}
+        AND ss.is_delete = 0
+        UNION ALL
+        SELECT t.id, su.mobile, lt.depth + 1
+        FROM sys_user_jzg_info t
+        INNER JOIN leader_tree lt ON t.leader_id = lt.id
+        LEFT JOIN sys_user su ON su.id = t.user_id AND su.is_delete = 0
+        WHERE t.is_delete = 0
+        AND lt.depth <![CDATA[ < ]]> 10
+        )
         SELECT
         io.id as order_no,
         io.quote_no as no,
@@ -942,9 +956,9 @@
         <where>
             and io.is_delete = 0 and io.parent_id != '0' and sujis.type_attr NOT IN (1,2,3,4)
             <if test="insOrdersParam.jzgInfoId != null and insOrdersParam.jzgInfoId != ''">
-                and io.real_quote_user_id in (select bbb.mobile from sys_user bbb where bbb.id in ( select ss.user_id
-                from sys_user_jzg_info ss where 1 =1 and (ss.leader_id = #{insOrdersParam.jzgInfoId} or ss.id
-                =#{insOrdersParam.jzgInfoId}) and ss.is_delete = 0 ) and bbb.is_delete = 0 )
+                and io.real_quote_user_id in (
+                select lt.mobile from leader_tree lt where lt.mobile is not null
+                )
             </if>
             <if test="insOrdersParam.orderNo != null and insOrdersParam.orderNo != ''">
                 AND io.id = #{insOrdersParam.orderNo}
@@ -952,6 +966,12 @@
             <if test="insOrdersParam.parentId != null and insOrdersParam.parentId != ''">
                 AND io.parent_id = #{insOrdersParam.parentId}
             </if>
+            <if test="insOrdersParam.parentIds != null and insOrdersParam.parentIds.size() > 0">
+                AND io.parent_id IN
+                <foreach collection="insOrdersParam.parentIds" item="pid" open="(" separator="," close=")">
+                    #{pid}
+                </foreach>
+            </if>
             <if test="insOrdersParam.licenseNo != null and insOrdersParam.licenseNo != ''">
                 AND ioci.license_no = #{insOrdersParam.licenseNo}
             </if>
@@ -1265,6 +1285,18 @@
 
     <!-- 主订单列表:仅查询主订单表 ins_orders,parent_id=0,不联表;筛选条件仅支持主表字段 -->
     <select id="queryMainOrderList" resultType="com.jzg.commons.entity.orders.vo.OrderListVo">
+        WITH RECURSIVE leader_tree AS (
+        SELECT id, leader_id, 1 AS depth
+        FROM sys_user_jzg_info
+        WHERE id = #{insOrdersParam.jzgInfoId}
+        AND is_delete = 0
+        UNION ALL
+        SELECT t.id, t.leader_id, lt.depth + 1
+        FROM sys_user_jzg_info t
+        INNER JOIN leader_tree lt ON t.leader_id = lt.id
+        WHERE t.is_delete = 0
+        AND lt.depth <![CDATA[ < ]]> 10
+        )
         SELECT
         io.id as order_no,
         io.quote_no as no,
@@ -1287,9 +1319,13 @@
         <where>
             and io.is_delete = 0 and io.parent_id = '0'
             <if test="insOrdersParam.jzgInfoId != null and insOrdersParam.jzgInfoId != ''">
-                and io.real_quote_user_id in (select bbb.mobile from sys_user bbb where bbb.id in ( select ss.user_id
-                from sys_user_jzg_info ss where 1 =1 and (ss.leader_id = #{insOrdersParam.jzgInfoId} or ss.id
-                =#{insOrdersParam.jzgInfoId}) and ss.is_delete = 0 ) and bbb.is_delete = 0 )
+                and io.real_quote_user_id in (
+                select bbb.mobile
+                from sys_user bbb
+                inner join sys_user_jzg_info ss on bbb.id = ss.user_id and ss.is_delete = 0
+                inner join leader_tree lt on ss.id = lt.id
+                where bbb.is_delete = 0
+                )
             </if>
             <if test="insOrdersParam.orderNo != null and insOrdersParam.orderNo != ''">
                 AND io.id = #{insOrdersParam.orderNo}
@@ -1300,13 +1336,13 @@
             <if test="insOrdersParam.vinNo != null and insOrdersParam.vinNo != ''">
                 AND ioci.vin_no = #{insOrdersParam.vinNo}
             </if>
-            <if test="insOrdersParam.orderStatus!= null and insOrdersParam.orderStatus!= ''">
+            <if test="insOrdersParam.orderStatus != null and insOrdersParam.orderStatus != ''">
                 AND io.order_status = #{insOrdersParam.orderStatus}
             </if>
-            <if test="insOrdersParam.salesman!= null">
+            <if test="insOrdersParam.salesman != null">
                 AND io.real_quote_user_id = #{insOrdersParam.salesman}
             </if>
-            <if test="insOrdersParam.startDate != null and insOrdersParam.startDate != ''and insOrdersParam.endDate != null and insOrdersParam.endDate != ''">
+            <if test="insOrdersParam.startDate != null and insOrdersParam.startDate != '' and insOrdersParam.endDate != null and insOrdersParam.endDate != ''">
                 AND io.create_time BETWEEN #{insOrdersParam.startDate} and #{insOrdersParam.endDate}
             </if>
             <if test="insOrdersParam.companyName != null and insOrdersParam.companyName != ''">
@@ -1324,10 +1360,10 @@
             <if test="insOrdersParam.paymentLink != null and insOrdersParam.paymentLink != ''">
                 AND io.pay_link = #{insOrdersParam.paymentLink}
             </if>
-            <if test="insOrdersParam.startSigningTime != null and insOrdersParam.startSigningTime != ''and insOrdersParam.endSigningTime != null and insOrdersParam.endSigningTime != ''">
+            <if test="insOrdersParam.startSigningTime != null and insOrdersParam.startSigningTime != '' and insOrdersParam.endSigningTime != null and insOrdersParam.endSigningTime != ''">
                 AND io.signing_time BETWEEN #{insOrdersParam.startSigningTime} and #{insOrdersParam.endSigningTime}
             </if>
-            <if test="insOrdersParam.startPayTime != null and insOrdersParam.startPayTime != ''and insOrdersParam.endPayTime != null and insOrdersParam.endPayTime != ''">
+            <if test="insOrdersParam.startPayTime != null and insOrdersParam.startPayTime != '' and insOrdersParam.endPayTime != null and insOrdersParam.endPayTime != ''">
                 AND io.pay_time BETWEEN #{insOrdersParam.startPayTime} and #{insOrdersParam.endPayTime}
             </if>
         </where>
@@ -1336,11 +1372,12 @@
 
     <!-- 手动分页版:按车牌+状态分组去重(每组取最新一条),返回当前页数据;不触发 MP 自动 count -->
     <select id="queryOrderListDistinct" resultType="com.jzg.commons.entity.orders.vo.OrderListVo">
-        SELECT
+        select * from (SELECT
         io.id as order_no,
         io.quote_no as no,
         io.company_id,
         io.company_name,
+        eicLogo.file_name as companyLogo,
         io.product_id as productCode,
         io.product_name as productName,
         io.order_status,
@@ -1371,15 +1408,15 @@
         io.pay_link as paymentLink,
         ioa.status as adjustStatus,
         ioa.id as adjustId,
-        ioa1.after_premium as adjustPremium
+        ioa1.after_premium as adjustPremium,
+        ROW_NUMBER() OVER(PARTITION BY COALESCE(ioci.license_no, io.id), io.order_status ORDER BY io.create_time DESC)
+        AS rn
         FROM (
         SELECT dedup.order_id
         FROM (
         SELECT
         io.id AS order_id,
-        io.create_time,
-        ROW_NUMBER() OVER(PARTITION BY COALESCE(ioci.license_no, io.id), io.order_status ORDER BY io.create_time DESC)
-        AS rn
+        io.create_time
         FROM
         ins_orders io
         LEFT JOIN ins_orders_car_info ioci ON ioci.order_no = io.id and ioci.is_delete = 0
@@ -1547,11 +1584,12 @@
             </if>
         </where>
         ) dedup
-        WHERE dedup.rn = 1
         ORDER BY dedup.create_time DESC
         LIMIT #{offset}, #{size}
         ) p
         JOIN ins_orders io ON io.id = p.order_id
+        LEFT JOIN esm_ins_company eic on io.company_id = eic.id and eic.is_delete = 0
+        LEFT JOIN sys_upload_files eicLogo on eic.logo = eicLogo.id and eicLogo.is_delete = 0
         LEFT JOIN ins_orders_car_info ioci ON ioci.order_no = io.id and ioci.is_delete = 0
         LEFT JOIN
         ins_orders_car_user_info owner_u on owner_u.order_no = io.id and owner_u.policy_person_type = 1 and
@@ -1597,7 +1635,8 @@
         FROM ins_order_adjust t where t.status = 2 and t.is_delete = 0
         ) x WHERE x.rn = 1
         ) ioa1 ON io.id = ioa1.order_no
-        order by io.create_time desc
+        order by io.create_time desc) tt
+        where tt.rn = 1
     </select>
 
     <!-- 手动分页版:统计按车牌+状态分组去重后的总条数 -->

+ 1 - 1
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/component/TaiPingCrawlerRequestComponent.java

@@ -306,7 +306,7 @@ public class TaiPingCrawlerRequestComponent {
                 = requestPostStrDecrypt(RequestUrl.FIND_APPLY_NO, request, new TypeReference<>(){}, httpHeaders,parameters);
         return response.getData()
                 .getGsApplyInfoMainDtos()
-                .stream().filter(x -> x.getApplyNo().equals(response.getData().getApplyNoDefault()))
+                .stream().filter(x -> x.getApplyNo().equals(parameters.getApplyNo()))
                 .findFirst().orElseThrow(() -> new SystemException("决策单元代码不存在"));
     }
 

+ 9 - 1
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/TaipingCrawlerConfigureParameters.java

@@ -39,9 +39,13 @@ public class TaipingCrawlerConfigureParameters implements ConfigureParameters {
      */
     private String salesmanCode;
     /**
-     * 业务归属机构
+     * 业务归属机构code
      */
     private String companyCode;
+    /**
+     *
+     */
+    private String companyName;
     /**
      * 销售信息代码
      */
@@ -66,6 +70,10 @@ public class TaipingCrawlerConfigureParameters implements ConfigureParameters {
      * 中介业务员
      */
     private String interSalesmanCode;
+    /**
+     * 决策单元代码
+     */
+    private String applyNo;
 
     private String policySort;
 

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

@@ -80,8 +80,8 @@ public class TaiPingCrawlerBrandNameQueryRequest {
     @JsonProperty("telKetConfSwitch")
     private String telKetConfSwitch;
 
-    @JsonProperty("salesmanFlag")
-    private boolean salesmanFlag;
+//    @JsonProperty("salesmanFlag")
+//    private boolean salesmanFlag;
 
     @JsonProperty("renewalNo")
     private String renewalNo;
@@ -102,9 +102,8 @@ public class TaiPingCrawlerBrandNameQueryRequest {
         } else {
             this.brandName = carInfoVo.getBrandName();
         }
-//        this.brandName = carInfoVo.getBrandName();
         this.companyCode = parameters.getCompanyCode();
-        this.frameNo = "";
+        this.frameNo = carInfoVo.getVinNo();
         this.orderNo = orderNo;
         this.irBatchNo = VerifyCodeCreate.getBatchNo();
         this.queryType = "2";
@@ -113,7 +112,7 @@ public class TaiPingCrawlerBrandNameQueryRequest {
         this.intermediaryCode = record.getIntermediaryCode();
         this.licenseTypeCode = carInfoVo.getLicenseKindCode();
         this.channelDetailCode = "0202";
-        this.renewalNo = "";
+//        this.renewalNo = "";
         this.telKetConfSwitch = "0";
     }
 

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

@@ -55,7 +55,7 @@ public class TaiPingCrawlerGetCarDepreRateRequest {
         this.seatCount = Integer.parseInt(itemMotorDtoListDTO.getSeatCount());
         this.tonCount = itemMotorDtoListDTO.getTonCount();
         this.carUseType = carInfoVo.getVehicleUseCode();
-        this.purchasePrice = Integer.valueOf(itemMotorDtoListDTO.getPurchasePrice());
+        this.purchasePrice = Double.valueOf(itemMotorDtoListDTO.getPurchasePrice()).intValue();
         this.fgSwitch = "1";
         this.newEnergyClauseFlag = carInfoVo.getEnergyTypeCode();
         this.energyType = carInfoVo.getEnergyTypeCode();

Разница между файлами не показана из-за своего большого размера
+ 236 - 207
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerPremiumCalculateRequest.java


+ 6 - 9
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerSubmitValidateRequest.java

@@ -1312,14 +1312,12 @@ public class TaiPingCrawlerSubmitValidateRequest{
             this.bankBranchName = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getBankBranchName();
             this.applyNo = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getApplyNo();
             this.queryApplyNo = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getQueryApplyNo();
-            this.zlbWindowNo = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getZlbWindowNo();
             this.optBtn = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getOptBtn();
             this.applyName = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getApplyName();
             this.decisionMakingUnit = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getDecisionMakingUnit();
             this.dsMakingTypeDetail = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getDsMakingTypeDetail();
             this.compLevel = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getCompLevel();
             this.serialNo = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getSerialNo();
-            this.outOrderNo = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getOutOrderNo();
             this.bankCustomerManagerCode = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getBankCustomerManagerCode();
             this.bankBranchCode = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getBankBranchCode();
             this.newCarFlag = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getNewCarFlag();
@@ -1328,7 +1326,6 @@ public class TaiPingCrawlerSubmitValidateRequest{
             this.poaSerialNo = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getPoaSerialNo();
             this.isDangerBz = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getIsDangerBz();
             this.tpFeeFlag = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getTpFeeFlag();
-            this.feeServiceLinkage = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getFeeServiceLinkage();
             this.policySort = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getPolicySort();
             this.argueSolution = taiPingCrawlerPremiumCalculateRequest.getPfMainDto().getArgueSolution();
             this.arbitoryName = null;
@@ -2586,10 +2583,10 @@ public class TaiPingCrawlerSubmitValidateRequest{
         private String vehicleCategory;
 
         @JsonProperty("seatCount")
-        private Integer seatCount;
+        private String seatCount;
 
         @JsonProperty("tonCount")
-        private Integer tonCount;
+        private String tonCount;
 
         @JsonProperty("negotiatedActualValue")
         private String negotiatedActualValue;
@@ -2631,7 +2628,7 @@ public class TaiPingCrawlerSubmitValidateRequest{
         private String localVehicleInd;
 
         @JsonProperty("completeKerbMass")
-        private Integer completeKerbMass;
+        private String completeKerbMass;
 
         @JsonProperty("fuelType")
         private String fuelType;
@@ -2829,7 +2826,7 @@ public class TaiPingCrawlerSubmitValidateRequest{
         private String isSpecialCarFlag;
 
         @JsonProperty("cvFlag")
-        private Boolean cvFlag;
+        private String cvFlag;
 
         @JsonProperty("frameNoHeteroType")
         private String frameNoHeteroType;
@@ -3026,7 +3023,7 @@ public class TaiPingCrawlerSubmitValidateRequest{
             this.carBrand = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getCarBrand();
             this.actualValue = new BigDecimal(taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getActualValue());
             this.localVehicleInd = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getLocalVehicleInd();
-            this.completeKerbMass = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getCompleteKerbMass().intValue();
+            this.completeKerbMass = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getCompleteKerbMass();
             this.fuelType = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getFuelType();
             this.factory = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getFactory();
             this.engineModel = taiPingCrawlerPremiumCalculateRequest.getPfItemMotorDto().getEngineModel();
@@ -3368,7 +3365,7 @@ public class TaiPingCrawlerSubmitValidateRequest{
         private String birthDate;
 
         @JsonProperty("appliAge")
-        private Integer appliAge;
+        private String appliAge;
 
         @JsonProperty("appliCompanyAddress")
         private String appliCompanyAddress;

+ 8 - 3
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/response/TaiPingCrawlerBrandNameQueryData.java

@@ -2,6 +2,7 @@ package com.jzg.quotation.taiping.crawler.entity.response;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.jzg.quotation.commons.filter.CarModelsFilter;
+import com.jzg.quotation.taiping.crawler.entity.request.TaiPingCrawlerGetGuCarShipTaxListRequest;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
@@ -41,7 +42,7 @@ public class TaiPingCrawlerBrandNameQueryData implements Serializable {
     private ButtonPathMapDTO buttonPathMap;
 
     @JsonProperty("pfProposalDto")
-    private Object pfProposalDto;
+    private PfProposalDTO pfProposalDto;
 
     @JsonProperty("itemMotorDtoList")
     private List<ItemMotorDtoListDTO> itemMotorDtoList;
@@ -232,7 +233,7 @@ public class TaiPingCrawlerBrandNameQueryData implements Serializable {
         @JsonProperty("estimateValue")
         private Object estimateValue;
         @JsonProperty("purchasePrice")
-        private Double purchasePrice;
+        private String purchasePrice;
         @JsonProperty("actualValue")
         private Object actualValue;
         @JsonProperty("invoiceNo")
@@ -656,8 +657,12 @@ public class TaiPingCrawlerBrandNameQueryData implements Serializable {
         }
         @Override
         public String getPurchasePrice(){
-            return String.valueOf(purchasePrice.intValue());
+            return purchasePrice;
         }
 
     }
+    @Data
+    public static class PfProposalDTO{
+        private TaiPingCrawlerGetGuCarShipTaxListRequest.PfItemMotorDto pfItemMotorDto;
+    }
 }

+ 8 - 3
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/response/TaiPingCrawlerPremiumCalculateData.java

@@ -1,5 +1,6 @@
 package com.jzg.quotation.taiping.crawler.entity.response;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.jzg.quotation.taiping.crawler.entity.request.TaiPingCrawlerPremiumCalculateRequest;
 import lombok.Data;
@@ -105,7 +106,7 @@ public class TaiPingCrawlerPremiumCalculateData {
     @JsonProperty("bzInformationDetailDto")
     private BzInformationDetailDtoDTO bzInformationDetailDto;
     @JsonProperty("fcProductList")
-    private List<?> fcProductList;
+    private List<TaiPingCrawlerPremiumCalculateRequest.FcProductListDto> fcProductList;
     @JsonProperty("clauseList0801")
     private List<ClauseList0801DTO> clauseList0801;
     @JsonProperty("clauseList0802")
@@ -239,6 +240,7 @@ public class TaiPingCrawlerPremiumCalculateData {
 
     @NoArgsConstructor
     @Data
+    @JsonInclude(JsonInclude.Include.ALWAYS)
     public static class PfItemKindDto0801DTO {
         @JsonProperty("addTax")
         private BigDecimal addTax;
@@ -369,7 +371,7 @@ public class TaiPingCrawlerPremiumCalculateData {
         @JsonProperty("serviceTimes")
         private Integer serviceTimes;
         @JsonProperty("shareList")
-        private Object shareList;
+        private List<?> shareList;
         @JsonProperty("shareModel")
         private String shareModel;
         @JsonProperty("shortRate")
@@ -412,6 +414,9 @@ public class TaiPingCrawlerPremiumCalculateData {
         private String valueType;
         @JsonProperty("yearPremium")
         private BigDecimal yearPremium;
+
+        @JsonProperty("clauseCode")
+        private String clauseCode;
     }
 
     @NoArgsConstructor
@@ -1267,7 +1272,7 @@ public class TaiPingCrawlerPremiumCalculateData {
         @JsonProperty("isEndor")
         private String isEndor;
         @JsonProperty("ggClauseParameterVos")
-        private String ggClauseParameterVos;
+        private List<String> ggClauseParameterVos;
         @JsonProperty("clauseVariableArr")
         private String clauseVariableArr;
         @JsonProperty("showDelete")

+ 140 - 20
tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/service/impl/TaipingCrawlerRequestImpl.java

@@ -35,6 +35,7 @@ import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpHeaders;
 
@@ -113,19 +114,30 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
         // 获取销售信息子代码
         TaiPingCrawlerFindSolutionCodeRequest taiPingCrawlerFindSolutionCodeRequest = new TaiPingCrawlerFindSolutionCodeRequest(parameters);
         TaiPingCrawlerFindSolutionCodeData.RecordsDTO taiPingCrawlerFindSolutionCodeData = taiPingCrawlerRequestComponent.findSolutionCode(taiPingCrawlerFindSolutionCodeRequest,httpHeaders,parameters);
-        // 查询决策单元信息
-        TaiPingCrawlerFindApplyNoRequest taiPingCrawlerFindApplyNoRequest = new TaiPingCrawlerFindApplyNoRequest(parameters,record);
-        TaiPingCrawlerFindApplyNoResponse.GsApplyInfoMainDto gsApplyInfoMainDto = taiPingCrawlerRequestComponent.findApplyNo(taiPingCrawlerFindApplyNoRequest,httpHeaders,parameters);
-
         // 创建订单
         TaiPingCrawlerCreateOrderRequest taiPingCrawlerCreateOrderRequest = new TaiPingCrawlerCreateOrderRequest(parameters,record);
         String orderNo = taiPingCrawlerRequestComponent.orderCreate(taiPingCrawlerCreateOrderRequest, httpHeaders,parameters);
+        // 查询决策单元信息
+        TaiPingCrawlerFindApplyNoRequest taiPingCrawlerFindApplyNoRequest = new TaiPingCrawlerFindApplyNoRequest(parameters,record);
+        TaiPingCrawlerFindApplyNoResponse.GsApplyInfoMainDto gsApplyInfoMainDto = taiPingCrawlerRequestComponent.findApplyNo(taiPingCrawlerFindApplyNoRequest,httpHeaders,parameters);
         // 车型查询
         TaiPingCrawlerBrandNameQueryRequest brandNameQueryRequest = new TaiPingCrawlerBrandNameQueryRequest(quoteVo.getCarInfoVo(),orderNo,record,parameters);
         TaiPingCrawlerBaseResponse<TaiPingCrawlerBrandNameQueryData> brandNameQuery = taiPingCrawlerRequestComponent.queryBrand(brandNameQueryRequest, httpHeaders,parameters);
-        List<TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO> itemMotorDtoList = brandNameQuery.getData()
-                .getItemMotorDtoList();
-        TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO itemMotorDtoListDTO = CarModelsFilterUtils.to(itemMotorDtoList, quoteVo.getCarInfoVo());
+        List<TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO> itemMotorDtoList = new ArrayList<>();
+        TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO itemMotorDtoListDTO;
+        if (brandNameQuery.getData() != null && brandNameQuery.getData().getItemMotorDtoList() != null) {
+            itemMotorDtoList = brandNameQuery.getData()
+                    .getItemMotorDtoList();
+            itemMotorDtoListDTO = CarModelsFilterUtils.to(itemMotorDtoList, quoteVo.getCarInfoVo());
+        } else if (brandNameQuery.getData() != null && brandNameQuery.getData().getPfProposalDto().getPfItemMotorDto() != null) {
+            TaiPingCrawlerGetGuCarShipTaxListRequest.PfItemMotorDto pfItemMotorDto = brandNameQuery.getData().getPfProposalDto().getPfItemMotorDto();
+            TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO convertedDto = new TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO();
+            BeanUtils.copyProperties(pfItemMotorDto, convertedDto);
+            itemMotorDtoList.add(convertedDto);
+            itemMotorDtoListDTO = convertedDto;
+        } else {
+            throw new SystemException("查询不到车型信息,请检查厂牌型号是否录入正确");
+        }
         // 计算折旧价 需要新车购置价 商业险起保日期 车辆注册日期 折旧率
         TaiPingCrawlerGetCarDepreRateRequest taiPingCrawlerGetCarDepreRateRequest = new TaiPingCrawlerGetCarDepreRateRequest(itemMotorDtoListDTO,quoteVo.getCarInfoVo());
         double rate = taiPingCrawlerRequestComponent.getCarDepreRate(taiPingCrawlerGetCarDepreRateRequest, httpHeaders,parameters);
@@ -171,7 +183,7 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
             TaiPingCrawlerBaseResponse<TaiPingCrawlerVehicleForPRPQueryResponse> taiPingCrawlerVehicleForPRPQueryResponse = taiPingCrawlerRequestComponent.vehicleForPRPQuery(taiPingCrawlerVehicleForPRPQueryRequest, httpHeaders, parameters);
             if (taiPingCrawlerVehicleForPRPQueryResponse.isSucc() && taiPingCrawlerVehicleForPRPQueryResponse.getData().getItemMotorDtoList().size() > 0) {
                 TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO itemMotorDtoListDTONew = taiPingCrawlerVehicleForPRPQueryResponse.getData().getItemMotorDtoList().get(0);
-                TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO pfItemMotorDtoDTO = new TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO(quoteVo.getCarInfoVo(), itemMotorDtoListDTONew, orderNo, carActualValue);
+                TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO pfItemMotorDtoDTO = new TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO(quoteVo.getCarInfoVo(), itemMotorDtoListDTONew, orderNo, carActualValue,quoteVo);
                 taiPingCrawlerPremiumCalculateRequest.setPfItemMotorDto(pfItemMotorDtoDTO);
                 premiumCalculateResponse = taiPingCrawlerRequestComponent.premiumCalculate(taiPingCrawlerPremiumCalculateRequest, httpHeaders, parameters);
             } else {
@@ -204,6 +216,7 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
                     policyInfo.setStartTime0801(finalStartDateBZ.substring(11));
                     policyInfo.setEndDate0801(finalEndDateBZ.substring(0, 10));
                     policyInfo.setEndTime0801(finalEndDateBZ.substring(11));
+                    policyInfo.setImmEffectStartDate0801(finalStartDateBZ.substring(0, 10));
                     policyInfo.setEffectFlag0801(false);
                     if (taiPingCrawlerPremiumCalculateRequest.getFcProductList().size() > 0) {
                         taiPingCrawlerPremiumCalculateRequest.getFcProductList().get(0).setStartDate(finalStartDateBZ);
@@ -219,6 +232,7 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
                     policyInfo.setStartTime0802(finalStartDateBS.substring(11));
                     policyInfo.setEndDate0802(finalEndDateBS.substring(0, 10));
                     policyInfo.setEndTime0802(finalEndDateBS.substring(11));
+                    policyInfo.setImmEffectStartDate0802(finalStartDateBS.substring(0, 10));
                     policyInfo.setEffectFlag0802(false);
                     if (taiPingCrawlerPremiumCalculateRequest.getFcProductList().size() > 0) {
                         taiPingCrawlerPremiumCalculateRequest.getFcProductList().get(0).setStartDate(finalStartDateBS);
@@ -234,7 +248,7 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
                     TaiPingCrawlerBaseResponse<TaiPingCrawlerVehicleForPRPQueryResponse> taiPingCrawlerVehicleForPRPQueryResponse = taiPingCrawlerRequestComponent.vehicleForPRPQuery(taiPingCrawlerVehicleForPRPQueryRequest, httpHeaders, parameters);
                     if (taiPingCrawlerVehicleForPRPQueryResponse.isSucc()) {
                         TaiPingCrawlerBrandNameQueryData.ItemMotorDtoListDTO itemMotorDtoListDTONew = taiPingCrawlerVehicleForPRPQueryResponse.getData().getItemMotorDtoList().get(0);
-                        TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO pfItemMotorDtoDTO = new TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO(quoteVo.getCarInfoVo(), itemMotorDtoListDTONew, orderNo, carActualValue);
+                        TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO pfItemMotorDtoDTO = new TaiPingCrawlerPremiumCalculateRequest.PfItemMotorDtoDTO(quoteVo.getCarInfoVo(), itemMotorDtoListDTONew, orderNo, carActualValue,quoteVo);
                         taiPingCrawlerPremiumCalculateRequest.setPfItemMotorDto(pfItemMotorDtoDTO);
                         premiumCalculateResponse = taiPingCrawlerRequestComponent.premiumCalculate(taiPingCrawlerPremiumCalculateRequest, httpHeaders, parameters);
                     }
@@ -243,8 +257,12 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
         }
         // 添加特约重新报价
         if (premiumCalculateResponse != null && premiumCalculateResponse.isSucc()) {
-            taiPingCrawlerPremiumCalculateRequest.setClauseList0801(addClauseList0801(premiumCalculateResponse));
-            taiPingCrawlerPremiumCalculateRequest.setClauseList0802(addClauseList0802(premiumCalculateResponse));
+            if (quoteVo.getCiRiskInfoVo() != null) {
+                taiPingCrawlerPremiumCalculateRequest.setClauseList0801(addClauseList0801(premiumCalculateResponse));
+            }
+            if (quoteVo.getBiRiskInfoVo() != null) {
+                taiPingCrawlerPremiumCalculateRequest.setClauseList0802(addClauseList0802(premiumCalculateResponse));
+            }
             if (premiumCalculateResponse.getData().getDemandNoForce() != null) {
                 taiPingCrawlerPremiumCalculateRequest.setDemandNoForce(premiumCalculateResponse.getData().getDemandNoForce());
             }
@@ -405,12 +423,10 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
 
         // 获取订单信息
         TaiPingCrawlerOrder taiPingCrawlerOrder = taiPingCrawlerOrderRepository.findByOrdersNo(underwritingVo.getOrder().getOrdersNo());
-
         // 获取缓存的报价请求
         TaiPingCrawlerPremiumCalculateRequest taiPingCrawlerPremiumCalculateRequest = taiPingCrawlerCacheComponent
                 .getTaiPingCrawlerPremiumCalculateRequest(underwritingVo.getOrder().getOrdersNo());
-
-        // 重新计算保费(核保前必须设置forceLinkCIFlag关联交商)
+        // 重新计算保费
         taiPingCrawlerPremiumCalculateRequest.getPfMainDto().setForceLinkCIFlag(true);
         log.info("[太平核保]保费重算请求: orderNo={}", taiPingCrawlerOrder.getCompanyOrderNo());
         TaiPingCrawlerBaseResponse<TaiPingCrawlerPremiumCalculateData> recalculateResponse =
@@ -420,7 +436,12 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
         }
         log.info("[太平核保]保费重算成功");
         taiPingCrawlerPremiumCalculateRequest.setIncrementServiceMatchFlag(false);
-        taiPingCrawlerPremiumCalculateRequest.getPfMainDto().setForceLinkCIFlag(true);
+        taiPingCrawlerPremiumCalculateRequest.setPfItemKind0801DtoList(bulidPf0801List(recalculateResponse.getData(), taiPingCrawlerPremiumCalculateRequest));
+//        if (recalculateResponse.getData().getPfItemKindDto0802List() == null) {
+//            taiPingCrawlerPremiumCalculateRequest.setPfItemKind0802DtoList(null);
+//            taiPingCrawlerPremiumCalculateRequest.setClauseList0802(null);
+//        }
+//        taiPingCrawlerPremiumCalculateRequest.getPfPolicyInfoDto().setFcPolicyno0(recalculateResponse.getData().getFcProductList().get(0).getFcOrderNo());
         if (recalculateResponse.getData().getDemandNoForce() != null) {
             taiPingCrawlerPremiumCalculateRequest.setDemandNoForce(recalculateResponse.getData().getDemandNoForce());
             taiPingCrawlerPremiumCalculateRequest.getPfPolicyInfoDto().setDemandNoForce(recalculateResponse.getData().getDemandNoForce());
@@ -438,9 +459,17 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
             taiPingCrawlerPremiumCalculateRequest.getPfPolicyInfoDto().setProposalNo0801(recalculateResponse.getData().getProposalNo0801());
             taiPingCrawlerPremiumCalculateRequest.getPfPolicyInfoDto().setProposalNo0802(recalculateResponse.getData().getProposalNo0802());
         }
-        taiPingCrawlerPremiumCalculateRequest.getPfMainDto().setUnderwriteCode(parameters.getUsername());
-        taiPingCrawlerPremiumCalculateRequest.getPfMainDto().setUnderwriteName("自动核保");
-        taiPingCrawlerPremiumCalculateRequest.getPfMainDto().setUnderWriteInd("2");
+        if (recalculateResponse.getData().getFcProductList() != null && recalculateResponse.getData().getFcProductList().size() > 0) {
+            TaiPingCrawlerPremiumCalculateRequest.FcProductListDto fcProductListDTO = recalculateResponse.getData().getFcProductList().get(0);
+            taiPingCrawlerPremiumCalculateRequest.getFcProductList().get(0).setFcOrderNo(fcProductListDTO.getFcOrderNo());
+            taiPingCrawlerPremiumCalculateRequest.getFcProductList().get(0).setPoaserialNo(fcProductListDTO.getPoaserialNo());
+        }
+        if (taiPingCrawlerPremiumCalculateRequest.getPfItemKind0802DtoList() != null && !taiPingCrawlerPremiumCalculateRequest.getPfItemKind0802DtoList().isEmpty()) {
+            taiPingCrawlerPremiumCalculateRequest.getPfItemKind0802DtoList().stream()
+                    .forEach(pfItemKind0802Dto -> {
+                        pfItemKind0802Dto.setDiscount(recalculateResponse.getData().getPfItemKindDto0802List().stream().filter(dto -> dto.getKindCode().equals(pfItemKind0802Dto.getKindCode())).findFirst().map(TaiPingCrawlerPremiumCalculateData.PfItemKindDto0802ListDTO::getDiscount).orElse(100.0).intValue());
+                    });
+        }
 
         // 提交验证 python代码直接用报价入参提交
 //        TaiPingCrawlerSubmitValidateRequest submitValidateRequest = new TaiPingCrawlerSubmitValidateRequest(
@@ -538,6 +567,97 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
         return underwritingResultsVo;
     }
 
+    public static List<TaiPingCrawlerPremiumCalculateRequest.PfItemKind0801DtoListDTO> bulidPf0801List(TaiPingCrawlerPremiumCalculateData data, TaiPingCrawlerPremiumCalculateRequest request){
+        List<TaiPingCrawlerPremiumCalculateRequest.PfItemKind0801DtoListDTO> pfItemKind0801DtoList = request.getPfItemKind0801DtoList();
+        pfItemKind0801DtoList.clear();
+        TaiPingCrawlerPremiumCalculateData.PfItemKindDto0801DTO pfItemKind0801DtoDTO = data.getPfItemKindDto0801();
+        TaiPingCrawlerPremiumCalculateRequest.PfItemKind0801DtoListDTO target = new TaiPingCrawlerPremiumCalculateRequest.PfItemKind0801DtoListDTO();
+        BeanUtils.copyProperties(pfItemKind0801DtoDTO, target);
+        target.setNodeBtGrossPremium(pfItemKind0801DtoDTO.getNodeBtGrossPremium());
+        target.setItemCode(pfItemKind0801DtoDTO.getItemCode());
+        target.setItemDetailCode(pfItemKind0801DtoDTO.getItemDetailCode());
+        target.setItemDetailList(pfItemKind0801DtoDTO.getItemDetailList());
+        target.setModeCode(pfItemKind0801DtoDTO.getModeCode());
+        target.setModeName(pfItemKind0801DtoDTO.getModeName());
+        target.setStartDate(pfItemKind0801DtoDTO.getStartDate());
+        target.setEndDate(pfItemKind0801DtoDTO.getEndDate());
+        target.setUnitValue(pfItemKind0801DtoDTO.getUnitValue());
+        target.setUnitInsured(pfItemKind0801DtoDTO.getUnitInsured());
+        target.setUnitPremium(pfItemKind0801DtoDTO.getUnitPremium());
+        target.setQuantity(pfItemKind0801DtoDTO.getQuantity());
+        target.setUnit(pfItemKind0801DtoDTO.getUnit());
+        target.setSumValue(pfItemKind0801DtoDTO.getSumValue());
+        target.setSumInsured(pfItemKind0801DtoDTO.getSumInsured());
+        target.setRatePeriod(pfItemKind0801DtoDTO.getRatePeriod());
+        target.setRate(pfItemKind0801DtoDTO.getRate());
+        target.setShortRateFlag(pfItemKind0801DtoDTO.getShortRateFlag());
+        target.setShortRateNumerator(pfItemKind0801DtoDTO.getShortRateNumerator());
+        target.setShortRateDenominator(pfItemKind0801DtoDTO.getShortRateDenominator());
+        target.setShortRate(pfItemKind0801DtoDTO.getShortRate());
+        target.setBasePremium(pfItemKind0801DtoDTO.getBasePremium());
+        target.setPureBenchPremium(pfItemKind0801DtoDTO.getPureBenchPremium());
+        target.setBasePureBenchPremium(pfItemKind0801DtoDTO.getBasePureBenchPremium());
+        target.setBenchmarkPremium(pfItemKind0801DtoDTO.getBenchmarkPremium());
+        target.setNoDebtPremium(pfItemKind0801DtoDTO.getNoDebtPremium());
+        target.setLoading(pfItemKind0801DtoDTO.getLoading());
+        target.setGrossPremium(pfItemKind0801DtoDTO.getGrossPremium());
+        target.setDiscount(pfItemKind0801DtoDTO.getDiscount());
+        target.setAdjustRate(pfItemKind0801DtoDTO.getAdjustRate());
+        target.setNetPremium(pfItemKind0801DtoDTO.getNetPremium());
+        target.setDeductibleRate(pfItemKind0801DtoDTO.getDeductibleRate());
+        target.setDeductible(pfItemKind0801DtoDTO.getDeductible());
+        target.setPremiumFormula(pfItemKind0801DtoDTO.getPremiumFormula());
+        target.setYearPremium(pfItemKind0801DtoDTO.getYearPremium());
+        target.setSurrenderInd(pfItemKind0801DtoDTO.getSurrenderInd());
+        target.setFirstLossRate(pfItemKind0801DtoDTO.getFirstLossRate());
+        target.setKindInd(pfItemKind0801DtoDTO.getKindInd());
+        target.setSuitProduct(pfItemKind0801DtoDTO.getSuitProduct());
+        target.setAssistKindFlag(pfItemKind0801DtoDTO.getAssistKindFlag());
+        target.setRemark(pfItemKind0801DtoDTO.getRemark());
+        target.setFlag(pfItemKind0801DtoDTO.getFlag());
+        target.setUwCount(pfItemKind0801DtoDTO.getUwCount());
+        target.setUwPremium(pfItemKind0801DtoDTO.getUwPremium());
+        target.setOriginUWPremium(pfItemKind0801DtoDTO.getOriginUWPremium());
+        target.setOriginGrossPremium(pfItemKind0801DtoDTO.getOriginGrossPremium());
+        target.setRelatedInd(pfItemKind0801DtoDTO.getRelatedInd());
+        target.setEndorAdjustRate(pfItemKind0801DtoDTO.getEndorAdjustRate());
+        target.setPubInsuredInd(pfItemKind0801DtoDTO.getPubInsuredInd());
+        target.setSpecialInd(pfItemKind0801DtoDTO.getSpecialInd());
+        target.setSubProposalNo(pfItemKind0801DtoDTO.getSubProposalNo());
+        target.setProjectCode(pfItemKind0801DtoDTO.getProjectCode());
+        target.setItemDetailNo(pfItemKind0801DtoDTO.getItemDetailNo());
+        target.setMustInsureInd(pfItemKind0801DtoDTO.getMustInsureInd());
+        target.setPremiumType(pfItemKind0801DtoDTO.getPremiumType());
+        target.setValueType(pfItemKind0801DtoDTO.getValueType());
+        target.setFranchise(pfItemKind0801DtoDTO.getFranchise());
+        target.setReSpecialInd(pfItemKind0801DtoDTO.getReSpecialInd());
+        target.setAdditionalRate(pfItemKind0801DtoDTO.getAdditionalRate());
+        target.setAllBrokenRate(pfItemKind0801DtoDTO.getAllBrokenRate());
+        target.setAddTax(pfItemKind0801DtoDTO.getAddTax());
+        target.setAddTaxRate(pfItemKind0801DtoDTO.getAddTaxRate());
+        target.setPriceTaxTotal(pfItemKind0801DtoDTO.getPriceTaxTotal());
+        target.setOrgPriceTaxTotal(pfItemKind0801DtoDTO.getOrgPriceTaxTotal());
+        target.setServiceTimes(pfItemKind0801DtoDTO.getServiceTimes());
+        target.setRelatedFlagFG2020(pfItemKind0801DtoDTO.getRelatedFlagFG2020());
+        target.setScUpdateTime(pfItemKind0801DtoDTO.getScUpdateTime());
+        target.setUseFormula(pfItemKind0801DtoDTO.getUseFormula());
+        target.setClauseCode(pfItemKind0801DtoDTO.getClauseCode());
+        target.setEasyKindName(pfItemKind0801DtoDTO.getEasyKindName());
+        target.setShareModel(pfItemKind0801DtoDTO.getShareModel());
+        target.setCalcMedicalModel(pfItemKind0801DtoDTO.getCalcMedicalModel());
+        target.setIsExist(pfItemKind0801DtoDTO.getIsExist());
+        target.setRiskShareModelSwitch(pfItemKind0801DtoDTO.getRiskShareModelSwitch());
+        target.setDeductibleList(pfItemKind0801DtoDTO.getDeductibleList());
+        target.setShareList(pfItemKind0801DtoDTO.getShareList());
+        target.setEndorPolicyNo(pfItemKind0801DtoDTO.getEndorPolicyNo());
+        target.setKindCode(pfItemKind0801DtoDTO.getKindCode());
+        target.setKindName("机动车交通事故责任强制险");
+        target.setKindcodeKindname("BZ-机动车交通事故责任强制险");
+        target.setRelieveFund(pfItemKind0801DtoDTO.getRelieveFund());
+        pfItemKind0801DtoList.add(target);
+        return pfItemKind0801DtoList;
+    }
+
     @Override
     public PaymentLinkResultsVo getPaymentLink(PaymentLinkVo paymentLinkVo) {
         OrderBase order = paymentLinkVo.getOrder();
@@ -662,9 +782,9 @@ public class TaipingCrawlerRequestImpl implements TaipingCrawlerRequest {
         TaiPingCrawlerOrder taiPingCrawlerOrder = taiPingCrawlerOrderRepository.findByOrdersNo(orderStatusVo.getOrder().getOrdersNo());
         TaiPingCrawlerQueryListRequest taiPingCrawlerQueryListRequest = new TaiPingCrawlerQueryListRequest(taiPingCrawlerOrder.getCompanyOrderNo());
         List<TaiPingCrawlerQueryListData.RecordsDTO> recordsDTO = null;
-        if (parameters.getMethod().equals("简易")) {
+        if (parameters.getMethod().equals("简易") && taiPingCrawlerOrder.getCompanyOrderNo().contains("DNSP")) {
             recordsDTO = taiPingCrawlerRequestComponent.queryListNsp(taiPingCrawlerQueryListRequest, httpHeaders,parameters);
-        } else if (parameters.getMethod().equals("立保通")){
+        } else if (parameters.getMethod().equals("立保通") && taiPingCrawlerOrder.getCompanyOrderNo().contains("DNQT")){
             recordsDTO = taiPingCrawlerRequestComponent.queryListNqt(taiPingCrawlerQueryListRequest, httpHeaders,parameters);
         }
 

+ 4 - 4
tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/ZmCrawlerConfigureParameters.java

@@ -70,10 +70,10 @@ public class ZmCrawlerConfigureParameters implements ConfigureParameters {
 //     */
 //    private String riskCode;
 
-//    /**
-//     * 中介人名称
-//     */
-//    private String agentName;
+    /**
+     * 中介人名称
+     */
+    private String agentName;
 //
 //    /**
 //     *  业务员名称

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

@@ -283,7 +283,7 @@ public class SaleInfoDTO implements Serializable {
 
     public SaleInfoDTO(ZmCrawlerNetpointQueryResponse response, ZmCrawlerConfigureParameters parameters) {
         ZmCrawlerNetpointQueryResponse.BaseInformationBeanDTO baseInformationBeanDTO = response.getBaseInformationBean().get(0);
-        ZmCrawlerNetpointQueryResponse.BaseInformationBeanDTO.AgentBeanDTO agentBeanDTO = baseInformationBeanDTO.getAgentBean().get(0);
+        ZmCrawlerNetpointQueryResponse.BaseInformationBeanDTO.AgentBeanDTO agentBeanDTO = baseInformationBeanDTO.getAgentBean().stream().filter(agent -> agent.getAgentName().equals(parameters.getAgentName())).findFirst().orElse(null);
         ZmCrawlerNetpointQueryResponse.BaseInformationBeanDTO.HandlerBeanDTO handlerBeanDTO = baseInformationBeanDTO.getHandlerBean().get(0);
         ZmCrawlerNetpointQueryResponse.BaseInformationBeanDTO.NetPointBeanDTO netPointBeanDTO = baseInformationBeanDTO.getNetPointBean().get(0);
         ZmCrawlerNetpointQueryResponse.BaseInformationBeanDTO.SaleUserBeanDTO saleUserBeanDTO = Objects.isNull(baseInformationBeanDTO.getSaleUserBean()) ? null : baseInformationBeanDTO.getSaleUserBean().get(0);

+ 108 - 129
tenant/organization/src/main/java/com/jzg/organization/component/BuildDescUtils.java

@@ -14,185 +14,179 @@ public class BuildDescUtils {
     /**
      * 遍历费用属性描述文字
      *
-     * @param linkList
-     * @param undwrtRulesAttrList
+     * @param linkList            属性记录列表
+     * @param undwrtRulesAttrList 属性定义列表
      * @return
      */
     public static String buildDesc(String companyId, List<PtlAgreementUndwrtRulesAttr> linkList, List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList) {
         StringBuilder desc = new StringBuilder();
+        // 仅保留当前主体可用(all 或匹配 companyId)的属性定义
         Map<String, PtlAgreementUndwrtRulesAttr> attrMap = undwrtRulesAttrList.stream()
-                .filter(attr -> "all".equals(attr.getCompanyIds()) || (attr.getCompanyIds() != null && attr.getCompanyIds().equals(companyId)))
+                .filter(attr -> "all".equals(attr.getCompanyIds()) || Objects.equals(attr.getCompanyIds(), companyId))
                 .collect(Collectors.toMap(PtlAgreementUndwrtRulesAttr::getAttrCode, Function.identity()));
         // 这里进行排序,保证生成的承保规则描述是有序的
-        linkList = linkList.stream().sorted(Comparator.comparing(PtlAgreementUndwrtRulesAttr::getAttrCode)).toList();
-        List<PtlAgreementUndwrtRulesAttr> sortedLinks = new ArrayList<>(linkList);
+        List<PtlAgreementUndwrtRulesAttr> sortedLinks = linkList.stream()
+                .sorted(Comparator.comparing(PtlAgreementUndwrtRulesAttr::getAttrCode))
+                .toList();
 
         for (PtlAgreementUndwrtRulesAttr link : sortedLinks) {
-            PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr = attrMap.get(link.getAttrCode());
-            if (ptlAgreementUndwrtRulesAttr == null) {
+            PtlAgreementUndwrtRulesAttr attr = attrMap.get(link.getAttrCode());
+            if (attr == null) {
                 continue;
             }
-
-            String attrType = ptlAgreementUndwrtRulesAttr.getAttrType();
-
+            String attrType = attr.getAttrType();
             if ("inputNumber".equals(attrType)) {
-                desc.append(inputNumberIdentifying(ptlAgreementUndwrtRulesAttr, link)).append(";\t\t");
+                desc.append(inputNumberDesc(attr.getAttrName(), link.getOperator(), link.getMin(), link.getMax())).append(";\t\t");
             } else if ("radio".equals(attrType)) {
-                desc.append(radioIdentifying(ptlAgreementUndwrtRulesAttr, link)).append(";\t\t");
+                desc.append(radioDesc(attr, link.getMin())).append(";\t\t");
             } else if ("checkbox".equals(attrType) || "select".equals(attrType)) {
                 if (link.getMinArray() != null && link.getMinArray().length > 0) {
                     // minArray 转 Set,避免循环内反复创建 List 做 contains 查找
                     Set<String> minCodes = Arrays.stream(link.getMinArray()).collect(Collectors.toSet());
-                    String names = Optional.ofNullable(link.getDictLabal()).orElse(Collections.emptyList()).stream()
-                            .filter(labal -> minCodes.contains(labal.getCode()))
-                            .map(PtlAgreementUndwrtRulesDictLabal::getName)
-                            .collect(Collectors.joining(","));
-                    desc.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("包含").append(names).append(";\t\t");
+                    String names = joinDictNames(link.getDictLabal(), minCodes, ",");
+                    desc.append(containDesc(attr.getAttrName(), link.getOperator(), names)).append(";\t\t");
                 } else {
-                    desc.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("包含").append(link.getMin()).append(";\t\t");
+                    desc.append(containDesc(attr.getAttrName(), link.getOperator(), link.getMin())).append(";\t\t");
                 }
             } else if ("inputTag".equals(attrType)) {
-                if (link.getOperator() != null && "1".equals(link.getOperator())) {
-                    desc.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("包含").append(link.getMin()).append(";\t\t");
-                } else {
-                    desc.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("不包含").append(link.getMin()).append(";\t\t");
-                }
+                desc.append(containDesc(attr.getAttrName(), link.getOperator(), link.getMin())).append(";\t\t");
             }
         }
-        return desc.toString();
-    }
-
-    private static String radioIdentifying(PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr, PtlAgreementUndwrtRulesAttr link) {
-        Optional<PtlAgreementUndwrtRulesDictLabal> dictLabel = Optional.ofNullable(
-                        ptlAgreementUndwrtRulesAttr.getDictLabal())
-                .flatMap(list -> list.stream().filter(x -> x.getCode().equals(link.getMin())).findFirst());
-
-        return dictLabel.map(dl -> ptlAgreementUndwrtRulesAttr.getAttrName() + "为" + dl.getName())
-                .orElse("");
-    }
-
-    private static String inputNumberIdentifying(PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr, PtlAgreementUndwrtRulesAttr link) {
-        String operator = link.getOperator();
-        switch (operator) {
-            case "1":
-                return ptlAgreementUndwrtRulesAttr.getAttrName() + "范围值" + link.getMin() + "到" + link.getMax();
-            case "2":
-                return ptlAgreementUndwrtRulesAttr.getAttrName() + "小于" + link.getMin();
-            case "3":
-                return ptlAgreementUndwrtRulesAttr.getAttrName() + "小于等于" + link.getMin();
-            case "4":
-                return ptlAgreementUndwrtRulesAttr.getAttrName() + "大于" + link.getMax();
-            case "5":
-                return ptlAgreementUndwrtRulesAttr.getAttrName() + "大于等于" + link.getMax();
-            default:
-                return ptlAgreementUndwrtRulesAttr.getAttrName() + "未知操作符";
-        }
+        // buildDesc返回的条件间以相邻双逗号分隔,此处合并为单个分号
+        return StringUtils.mergeAdjacentComma(desc.toString());
     }
 
-
     /**
      * 遍历承保规则属性描述文字
      *
-     * @param linkList
-     * @param undwrtRulesAttrList
+     * @param linkList            规则因子关联记录列表
+     * @param undwrtRulesAttrList 属性定义列表
      * @return
      */
     public static String buildDesc(List<PtlAgreementUndwrtRulesAttrLink> linkList, List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList) {
         StringBuilder desc = new StringBuilder();
+        // 属性定义按 attrCode 建索引,避免循环内逐条 stream 查找
+        Map<String, PtlAgreementUndwrtRulesAttr> attrMap = undwrtRulesAttrList.stream()
+                .collect(Collectors.toMap(PtlAgreementUndwrtRulesAttr::getAttrCode, Function.identity(), (oldItem, newItem) -> newItem));
         // 这里进行排序,保证生成的承保规则描述是有序的
-        linkList = linkList.stream().sorted(Comparator.comparing(PtlAgreementUndwrtRulesAttrLink::getAttrCode)).toList();
-        List<PtlAgreementUndwrtRulesAttrLink> sortedLinks = new ArrayList<>(linkList);
-
-        for (int i = 0; i < sortedLinks.size(); i++) {
-            int finalI = i;
-            PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr = undwrtRulesAttrList.stream()
-                    .filter(x -> x.getAttrCode().equals(sortedLinks.get(finalI).getAttrCode()))
-                    .findAny()
-                    .get();
+        List<PtlAgreementUndwrtRulesAttrLink> sortedLinks = linkList.stream()
+                .sorted(Comparator.comparing(PtlAgreementUndwrtRulesAttrLink::getAttrCode))
+                .toList();
 
-            //数值范围判断
-
-            if ("inputNumber".equals(ptlAgreementUndwrtRulesAttr.getAttrType())) {
-                desc.append(inputNumberIdentifying(ptlAgreementUndwrtRulesAttr, sortedLinks.get(i))).append(",");
-            }
-            if ("radio".equals(ptlAgreementUndwrtRulesAttr.getAttrType())) {
-                desc.append(radioIdentifying(ptlAgreementUndwrtRulesAttr, sortedLinks.get(i))).append(",");
-            }
-            if ("select".equals(ptlAgreementUndwrtRulesAttr.getAttrType())) {
-                desc.append(selectIdentifying(ptlAgreementUndwrtRulesAttr, sortedLinks.get(i)));
-            }
-            if ("checkbox".equals(ptlAgreementUndwrtRulesAttr.getAttrType())) {
-                desc.append(checkBoxIdentifying(ptlAgreementUndwrtRulesAttr, sortedLinks.get(i)));
+        for (PtlAgreementUndwrtRulesAttrLink link : sortedLinks) {
+            PtlAgreementUndwrtRulesAttr attr = attrMap.get(link.getAttrCode());
+            if (attr == null) {
+                continue;
             }
-            if ("inputTag".equals(ptlAgreementUndwrtRulesAttr.getAttrType())) {
-                if (sortedLinks.get(i).getOperator() != null && sortedLinks.get(i).getOperator().equals("1")) {
-                    desc.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("包含").append(sortedLinks.get(i).getMin()).append(",");
-                } else {
-                    desc.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("不包含").append(sortedLinks.get(i).getMin()).append(",");
-                }
+            String attrType = attr.getAttrType();
+            if ("inputNumber".equals(attrType)) {
+                desc.append(inputNumberDesc(attr.getAttrName(), link.getOperator(), link.getMin(), link.getMax())).append(",");
+            } else if ("radio".equals(attrType)) {
+                desc.append(radioDesc(attr, link.getMin())).append(",");
+            } else if ("select".equals(attrType)) {
+                desc.append(selectIdentifying(attr, link));
+            } else if ("checkbox".equals(attrType)) {
+                desc.append(checkBoxIdentifying(attr, link));
+            } else if ("inputTag".equals(attrType)) {
+                desc.append(containDesc(attr.getAttrName(), link.getOperator(), link.getMin())).append(",");
             }
         }
         // 相邻的","或","转换为"或"字
         return StringUtils.convertAdjacentCommaToOr(desc.toString());
     }
 
-    public static String radioIdentifying(PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr, PtlAgreementUndwrtRulesAttrLink ptlAgreementProductCostsAttrLink) {
-        PtlAgreementUndwrtRulesDictLabal ptlAgreementUndwrtRulesDictLabal = ptlAgreementUndwrtRulesAttr.getDictLabal().stream().filter(x -> x.getCode().equals(ptlAgreementProductCostsAttrLink.getMin())).findAny().get();
-        return ptlAgreementUndwrtRulesAttr.getAttrName() + "为" + ptlAgreementUndwrtRulesDictLabal.getName();
-    }
-
     public static String selectIdentifying(PtlAgreementUndwrtRulesAttr undwrtRulesAttr, PtlAgreementUndwrtRulesAttrLink link) {
         StringBuilder returnMsg = new StringBuilder();
-        // 兼容 min 逗号分隔存储,保证 minArray 有值
-        if (link.getMinArray() == null) {
-            String minStr = link.getMin();
-            if (minStr != null && !minStr.isEmpty()) {
-                link.setMinArray(minStr.split(","));
-            }
-        }
-
+        ensureMinArray(link);
         // 优先取 link 上的字典标签列表(JSONArray -> List),为空时回退到属性自带字典
         List<PtlAgreementUndwrtRulesDictLabal> dictLabalList = getDictLabalList(undwrtRulesAttr, link);
-
         // 用字典标签的 code 匹配 minArray 中的每一项
         if (link.getMinArray() != null && link.getMinArray().length > 0) {
             // minArray 转 Set,避免循环内反复创建 List 做 contains 查找
             Set<String> minCodes = Arrays.stream(link.getMinArray()).collect(Collectors.toSet());
-            String names = Optional.ofNullable(dictLabalList).orElse(Collections.emptyList()).stream()
-                    .filter(labal -> minCodes.contains(labal.getCode()))
-                    .map(PtlAgreementUndwrtRulesDictLabal::getName)
-                    .collect(Collectors.joining(","));
-            returnMsg.append(undwrtRulesAttr.getAttrName()).append("包含").append(names).append(",");
-
+            String names = joinDictNames(dictLabalList, minCodes, ",");
+            returnMsg.append(containDesc(undwrtRulesAttr.getAttrName(), link.getOperator(), names)).append(",");
         }
         return returnMsg.toString();
     }
 
     public static String checkBoxIdentifying(PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr, PtlAgreementUndwrtRulesAttrLink linkList) {
-        StringBuilder returnMsg = new StringBuilder();
-        returnMsg.append(ptlAgreementUndwrtRulesAttr.getAttrName()).append("为");
-        // 兼容 min 逗号分隔存储,保证 minArray 有值
-        if (linkList.getMinArray() == null) {
-            String minStr = linkList.getMin();
-            if (minStr != null && !minStr.isEmpty()) {
-                linkList.setMinArray(minStr.split(","));
-            }
-        }
+        StringBuilder returnMsg = new StringBuilder(ptlAgreementUndwrtRulesAttr.getAttrName()).append("为");
+        ensureMinArray(linkList);
         if (linkList.getMinArray() != null) {
             // 优先取 link 上的字典标签列表(JSONArray -> List),为空时回退到属性自带字典
             List<PtlAgreementUndwrtRulesDictLabal> dictLabalList = getDictLabalList(ptlAgreementUndwrtRulesAttr, linkList);
             // code -> 字典标签 映射,避免 O(n²) 循环匹配
             Map<String, PtlAgreementUndwrtRulesDictLabal> dictLabalMap = dictLabalList.stream()
-                    .filter(x -> x.getCode() != null)
+                    .filter(dictLabal -> dictLabal.getCode() != null)
                     .collect(Collectors.toMap(PtlAgreementUndwrtRulesDictLabal::getCode, Function.identity(), (oldItem, newItem) -> newItem));
             for (String code : linkList.getMinArray()) {
-                PtlAgreementUndwrtRulesDictLabal ptlAgreementUndwrtRulesDictLabal = dictLabalMap.get(code);
-                returnMsg.append(ptlAgreementUndwrtRulesDictLabal != null ? ptlAgreementUndwrtRulesDictLabal.getName() : "").append(",");
+                PtlAgreementUndwrtRulesDictLabal dictLabal = dictLabalMap.get(code);
+                returnMsg.append(dictLabal != null ? dictLabal.getName() : "").append(",");
             }
         }
         return returnMsg.toString();
     }
 
+    /**
+     * 拼接"属性名 + 包含/不包含 + 值"
+     */
+    private static String containDesc(String attrName, String operator, String value) {
+        return attrName + ("1".equals(operator) ? "包含" : "不包含") + value;
+    }
+
+    /**
+     * 数值操作符描述拼接(operator: 1区间 2小于 3小于等于 4大于 5大于等于)
+     */
+    private static String inputNumberDesc(String attrName, String operator, String min, String max) {
+        if ("1".equals(operator)) {
+            return attrName + "范围值" + min + "到" + max;
+        } else if ("2".equals(operator)) {
+            return attrName + "小于" + min;
+        } else if ("3".equals(operator)) {
+            return attrName + "小于等于" + min;
+        } else if ("4".equals(operator)) {
+            return attrName + "大于" + max;
+        } else if ("5".equals(operator)) {
+            return attrName + "大于等于" + max;
+        }
+        return "";
+    }
+
+    /**
+     * 单选字典描述拼接:属性名为 + 字典名称
+     */
+    private static String radioDesc(PtlAgreementUndwrtRulesAttr attr, String code) {
+        return Optional.ofNullable(attr.getDictLabal()).orElse(Collections.emptyList()).stream()
+                .filter(dictLabal -> Objects.equals(dictLabal.getCode(), code))
+                .map(PtlAgreementUndwrtRulesDictLabal::getName)
+                .findFirst()
+                .map(name -> attr.getAttrName() + "为" + name)
+                .orElse("");
+    }
+
+    /**
+     * 将字典 code 集合对应的名称按 separator 拼接为字符串
+     */
+    private static String joinDictNames(List<PtlAgreementUndwrtRulesDictLabal> dictLabalList, Set<String> codes, String separator) {
+        return Optional.ofNullable(dictLabalList).orElse(Collections.emptyList()).stream()
+                .filter(dictLabal -> codes.contains(dictLabal.getCode()))
+                .map(PtlAgreementUndwrtRulesDictLabal::getName)
+                .collect(Collectors.joining(separator));
+    }
+
+    /**
+     * 兼容 min 逗号分隔存储:minArray 为空时将 min 按逗号拆分填充
+     */
+    private static void ensureMinArray(PtlAgreementUndwrtRulesAttrLink link) {
+        if (link.getMinArray() == null) {
+            String minStr = link.getMin();
+            if (minStr != null && !minStr.isEmpty()) {
+                link.setMinArray(minStr.split(","));
+            }
+        }
+    }
+
     /**
      * 获取字典标签列表:优先取 link 上的字典标签列表(JSONArray -> List),为空时回退到属性自带字典
      */
@@ -206,19 +200,4 @@ public class BuildDescUtils {
         return Collections.emptyList();
     }
 
-    private static String inputNumberIdentifying(PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr, PtlAgreementUndwrtRulesAttrLink ptlAgreementProductCostsAttrLink) {
-        if ("1".equals(ptlAgreementProductCostsAttrLink.getOperator())) {
-            return ptlAgreementUndwrtRulesAttr.getAttrName() + "范围值" + ptlAgreementProductCostsAttrLink.getMin() + "到" + ptlAgreementProductCostsAttrLink.getMax();
-        } else if ("2".equals(ptlAgreementProductCostsAttrLink.getOperator())) {
-            return ptlAgreementUndwrtRulesAttr.getAttrName() + "小于" + ptlAgreementProductCostsAttrLink.getMin();
-        } else if ("3".equals(ptlAgreementProductCostsAttrLink.getOperator())) {
-            return ptlAgreementUndwrtRulesAttr.getAttrName() + "小于等于" + ptlAgreementProductCostsAttrLink.getMin();
-        } else if ("4".equals(ptlAgreementProductCostsAttrLink.getOperator())) {
-            return ptlAgreementUndwrtRulesAttr.getAttrName() + "大于" + ptlAgreementProductCostsAttrLink.getMax();
-        } else if ("5".equals(ptlAgreementProductCostsAttrLink.getOperator())) {
-            return ptlAgreementUndwrtRulesAttr.getAttrName() + "大于等于" + ptlAgreementProductCostsAttrLink.getMax();
-        }
-        return "";
-    }
-
 }

+ 10 - 1
tenant/organization/src/main/java/com/jzg/organization/controller/AgreementRulesController.java

@@ -1,10 +1,11 @@
 package com.jzg.organization.controller;
 
 import com.jzg.commons.aop.OperatorTrajectory;
+import com.jzg.commons.constants.OperationTypeEnum;
 import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.core.page.HttpResult;
-import com.jzg.commons.constants.OperationTypeEnum;
 import com.jzg.commons.entity.dto.AgreementRulesAddParam;
+import com.jzg.commons.entity.dto.AgreementRulesAttrCopyParam;
 import com.jzg.commons.entity.dto.AgreementRulesEditParam;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRules;
 import com.jzg.commons.entity.vo.AgreementRulesVo;
@@ -88,6 +89,14 @@ public class AgreementRulesController extends BaseController {
         return HttpResult.ok(rulesVos);
     }
 
+    @OperatorTrajectory(moduleName = "报价配置/协议管理/承保规则/批量复制规则因子", type = "C", OperationDict = OperationTypeEnum.COPY, mapperClass = PtlAgreementUndwrtRulesMapper.class, entityClass = AgreementRulesAttrCopyParam.class)
+    @Operation(summary = "批量复制规则因子:将源承保规则下的规则因子复制到目标协议承保规则下,目标协议无规则时新增")
+    @PostMapping("/rulesAttrBatchCopy")
+    public HttpResult rulesAttrBatchCopy(@Validated @RequestBody AgreementRulesAttrCopyParam param) {
+        return agreementRulesService.rulesAttrBatchCopy(param) ?
+                HttpResult.ok("批量复制规则因子成功") : HttpResult.error("批量复制规则因子失败");
+    }
+
     @Operation(summary = "获取承保规则明细")
     @GetMapping("getRuleInfo")
     public HttpResult getRuleInfo(String ruleId){

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

@@ -17,6 +17,7 @@ import com.jzg.commons.entity.orders.po.InsOrderAdjust;
 import com.jzg.commons.entity.po.EsmInsCompany;
 import com.jzg.commons.request.RequestSingleParam;
 import com.jzg.commons.util.AssertionUtils;
+import com.jzg.commons.util.DateTimeUtils;
 import com.jzg.organization.client.EsmInsCompanyClient;
 import com.jzg.organization.service.ReceivableService;
 import com.jzg.quotation.summary.aop.aspect.OrderOperationLog;
@@ -846,28 +847,31 @@ public class ReceivableController {
         Page page = vo.getPage();
         vo.setSettlementStartTime(vo.getStartTime());
         vo.setSettlementEndTime(vo.getEndTime());
-        if(StrUtil.isEmpty(vo.getSettlementEndTime()) && StrUtil.isEmpty(vo.getSettlementStartTime()) && StrUtil.isEmpty(vo.getReceivePaymentDateBegin()) && StrUtil.isEmpty(vo.getReceivePaymentDateEnd()))  {
+        if(StrUtil.isEmpty(vo.getSettlementEndTime()) && StrUtil.isEmpty(vo.getSettlementStartTime())
+                && StrUtil.isEmpty(vo.getReceivePaymentDateBegin()) && StrUtil.isEmpty(vo.getReceivePaymentDateEnd())
+                && StrUtil.isEmpty(vo.getSigningStartTime()) && StrUtil.isEmpty(vo.getSigningEndTime())
+        )  {
             return HttpResult.ok(receivableService.receiverSettlementReport(page,vo));
         }else{
             if(StrUtil.isNotEmpty(vo.getSettlementStartTime())){
-                LocalDateTime localDateTime = LocalDate.parse(vo.getSettlementStartTime()).atStartOfDay();
-                vo.setSettlementStartTime(DateUtil.formatLocalDateTime(localDateTime));
+                vo.setSettlementStartTime(DateTimeUtils.obtainStartTime(vo.getSettlementStartTime()));
             }
             if(StrUtil.isNotEmpty(vo.getSettlementEndTime())){
-                LocalDateTime localDateTime = LocalDate.parse(vo.getSettlementEndTime()).plusDays(1).atStartOfDay();
-                vo.setSettlementEndTime(DateUtil.formatLocalDateTime(localDateTime));
+                vo.setSettlementEndTime(DateTimeUtils.obtainNextDayStartTime(vo.getSettlementEndTime()));
             }
-
-
             if(StrUtil.isNotEmpty(vo.getReceivePaymentDateBegin())){
-                LocalDateTime localDateTime = LocalDate.parse(vo.getReceivePaymentDateBegin()).atStartOfDay();
-                vo.setReceivePaymentDateBegin(DateUtil.formatLocalDateTime(localDateTime));
+                vo.setReceivePaymentDateBegin(DateTimeUtils.obtainStartTime(vo.getReceivePaymentDateBegin()));
             }
             if(StrUtil.isNotEmpty(vo.getReceivePaymentDateEnd())){
-                LocalDateTime localDateTime = LocalDate.parse(vo.getReceivePaymentDateEnd()).plusDays(1).atStartOfDay();
-                vo.setReceivePaymentDateEnd(DateUtil.formatLocalDateTime(localDateTime));
+                vo.setReceivePaymentDateEnd(DateTimeUtils.obtainNextDayStartTime(vo.getReceivePaymentDateEnd()));
+            }
+            // 签单时间和王文琦沟通过了,先添加上,然后, 后期再想办法,看看能不能添加让其生效
+            if(StrUtil.isNotEmpty(vo.getSigningStartTime())){
+                vo.setSigningStartTime(DateTimeUtils.obtainStartTime(vo.getSigningStartTime()));
+            }
+            if(StrUtil.isNotEmpty(vo.getSigningEndTime())){
+                vo.setSigningEndTime(DateTimeUtils.obtainNextDayStartTime(vo.getSigningEndTime()));
             }
-
             vo.setStartTime(null);
             vo.setEndTime(null);
             // 备注一下: 对于结算时间不为空的时候,查询出来的结算状态都是已结算的数据

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

@@ -167,8 +167,8 @@ public class SysOrganizationController {
     }
 
     @Operation(summary = "根据用户id查询团队")
-    @GetMapping("queryOrganizationByManagerId")
-    public HttpResult<List<SysOrganization>> queryOrganizationByManagerId(@RequestParam("userId") String userId){
-        return HttpResult.ok(sysOrganizationService.queryOrganizationByManagerId(userId));
+    @GetMapping("queryOrganizationByPrincipalId")
+    public HttpResult<List<SysOrganization>> queryOrganizationByPrincipalId(@RequestParam("userId") String userId){
+        return HttpResult.ok(sysOrganizationService.queryOrganizationByPrincipalId(userId));
     }
 }

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

@@ -62,7 +62,7 @@ public class UserController extends BaseController {
     @PostMapping(value = "/getBaojiaUserInfoList")
     public HttpResult<Page<SysUserJzgInfoDto>> getBaojiaUserInfoList(@RequestBody SysUserInfoListVo sysUserInfoListVo) {
         Page page = sysUserInfoListVo.getPage();
-        Page<SysUserJzgInfoDto> userInfoList = sysUserService.getUserInfoList(page, sysUserInfoListVo);
+        Page<SysUserJzgInfoDto> userInfoList = sysUserService.getBaojiaUserInfoList(page, sysUserInfoListVo);
         return HttpResult.ok(userInfoList);
     }
 

+ 4 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/EsmUserReferrerMapper.java

@@ -2,8 +2,12 @@ package com.jzg.organization.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jzg.commons.entity.po.EsmUserReferrer;
+import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface EsmUserReferrerMapper extends BaseMapper<EsmUserReferrer> {
+    @Delete("DELETE FROM esm_user_referrer WHERE id = #{id} AND is_delete = 0")
+    int deleteByIdCheck(@Param("id") String id);
 }

+ 11 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserJzgInfoMapper.java

@@ -16,6 +16,8 @@ import java.util.List;
 @Mapper
 public interface SysUserJzgInfoMapper extends BaseMapper<SysUserJzgInfo> {
 
+    SysUserJzgInfo getYWYById(@Param("id") String id);
+
     /**
      * 查询有效的业务员信息
      *
@@ -37,6 +39,15 @@ public interface SysUserJzgInfoMapper extends BaseMapper<SysUserJzgInfo> {
     Page<SysUserJzgInfoDto> queryYwy(Page page, @Param("sysUserInfoListVo") SysUserInfoListVo sysUserInfoListVo,
                                      @Param("systemCode") String systemCode,@Param("leaderId") String leaderId);
 
+    /**
+     * 查询报价业务员
+     *
+     * @author lipf
+     * @date 2026/4/24 11:08
+     */
+    Page<SysUserJzgInfoDto> queryBJYwy(Page page, @Param("sysUserInfoListVo") SysUserInfoListVo sysUserInfoListVo,
+                                     @Param("systemCode") String systemCode,@Param("leaderId") String leaderId);
+
     /**
      * 查询成员
      *

+ 11 - 1
tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementUndwrtRulesService.java

@@ -1,9 +1,10 @@
 package com.jzg.organization.service;
 
+import com.baomidou.mybatisplus.extension.service.IService;
 import com.jzg.commons.entity.dto.AgreementRulesAddParam;
+import com.jzg.commons.entity.dto.AgreementRulesAttrCopyParam;
 import com.jzg.commons.entity.dto.AgreementRulesEditParam;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRules;
-import com.baomidou.mybatisplus.extension.service.IService;
 import com.jzg.commons.entity.vo.AgreementRulesVo;
 
 import java.util.List;
@@ -70,4 +71,13 @@ public interface PtlAgreementUndwrtRulesService extends IService<PtlAgreementUnd
      * @return
      */
     boolean deleteById(String id);
+
+    /**
+     * 批量复制规则因子:将源承保规则下的某条或多条规则因子复制到某个或多个承保协议下的某条承保规则下,
+     * 若目标承保协议下没有规则则新增规则
+     *
+     * @param param 复制参数
+     * @return boolean 是否成功
+     */
+    boolean rulesAttrBatchCopy(AgreementRulesAttrCopyParam param);
 }

+ 6 - 1
tenant/organization/src/main/java/com/jzg/organization/service/SysOrganizationService.java

@@ -31,6 +31,11 @@ public interface SysOrganizationService extends IService<SysOrganization> {
 
     HttpResult addTeamUsers(SysOrganizationUserLinkAdd organizationUserLinkAdd);
 
+    /**
+     * 设置团队管理人
+     */
+    HttpResult<String> setManagerPerson(SysOrganizationSetPerson setPerson);
+
     /**
      * 设置团队负责人
      *
@@ -62,6 +67,6 @@ public interface SysOrganizationService extends IService<SysOrganization> {
      */
     Page<SysOrganizationUserLinkVo> getTeamUserPage(Page page,SysOrganizationUserLinkQueryVo sysOrganizationUserLinkQueryVo);
 
-    List<SysOrganization> queryOrganizationByManagerId(String userId);
+    List<SysOrganization> queryOrganizationByPrincipalId(String userId);
 
 }

+ 1 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysUserJzgInfoService.java

@@ -43,6 +43,7 @@ public interface SysUserJzgInfoService extends IService<SysUserJzgInfo> {
     SysUserJzgInfo getUserByUserId(String userId);
 
     SysUserJzgInfo getUserById(String userId);
+    SysUserJzgInfo getYWYById(String userId);
 
     /**
      * 通过手机号获取晋掌柜用户信息

+ 1 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysUserService.java

@@ -96,6 +96,7 @@ public interface SysUserService extends IService<SysUser> {
      * @date 2026/4/10 10:01
      */
     Page<SysUserJzgInfoDto> getUserInfoList(Page page, SysUserInfoListVo sysUserInfoListVo);
+    Page<SysUserJzgInfoDto> getBaojiaUserInfoList(Page page, SysUserInfoListVo sysUserInfoListVo);
 
     /**
      * 获取成员转移资源信息

+ 100 - 46
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java

@@ -6,11 +6,13 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ReUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jzg.commons.constants.Constants;
+import com.jzg.commons.constants.Crud;
 import com.jzg.commons.constants.ReturnInformation;
 import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.core.base.StateResult;
@@ -22,8 +24,10 @@ import com.jzg.commons.entity.vo.CostsListVo;
 import com.jzg.commons.entity.vo.PtlAgreementCostRuleVo;
 import com.jzg.commons.entity.vo.PtlAgreementCostVo;
 import com.jzg.commons.exception.SystemException;
+import com.jzg.commons.service.OperatorTrajectoryService;
 import com.jzg.commons.util.ListUtils;
 import com.jzg.commons.util.StringUtils;
+import com.jzg.commons.util.comparble.CompatibleUtils;
 import com.jzg.commons.util.idgen.IdGenerate;
 import com.jzg.organization.client.EsmInsCompanyClient;
 import com.jzg.organization.component.BuildDescUtils;
@@ -99,6 +103,8 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     private SysUserJzgInfoService sysUserJzgInfoService;
     @Autowired
     private PtlAreaLicenseService ptlAreaLicenseService;
+    @Autowired
+    private OperatorTrajectoryService operatorTrajectoryService;
 
     /**
      * 报价配置/费用管理/新增费用
@@ -121,11 +127,19 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
         }
         List<String> createdIds = new ArrayList<>();
         for (CostAdd costAdd : costAddList) {
-            for (PtlAgreementCostAdd ptlAgreementCostAdd : costAdd.getPtlAgreementCostAddList()){
-                if (ListUtils.hasDuplicates(ptlAgreementCostAdd.getRuleConditions())){
+            for (PtlAgreementCostAdd ptlAgreementCostAdd : costAdd.getPtlAgreementCostAddList()) {
+                // 规则条件 min 根据 minArray 重组:多选/下拉等多值场景前端以数组提交,落库需以逗号分隔
+                if (CollUtil.isNotEmpty(ptlAgreementCostAdd.getRuleConditions())) {
+                    ptlAgreementCostAdd.getRuleConditions().forEach(item -> {
+                        if (CollUtil.isNotEmpty(item.getMinArray())) {
+                            item.setMin(String.join(",", item.getMinArray()));
+                        }
+                    });
+                }
+                if (ListUtils.hasDuplicates(ptlAgreementCostAdd.getRuleConditions())) {
                     throw new SystemException("添加数据存在相同费用规则,请检查");
                 }
-                if(StrUtil.isEmpty(costAdd.getPtlAgreementId())){
+                if (StrUtil.isEmpty(costAdd.getPtlAgreementId())) {
                     log.info("新增费用的时候,需要指定关联的协议信息。ptlAgreemenCostAdd=[{}]", JSONUtil.toJsonStr(ptlAgreemenCostAdd));
                     return HttpResult.error("新增费用的时候,需要指定关联的协议信息");
                 }
@@ -174,7 +188,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
         // 校验ptlAgreementCostTypeList 数据  exportKeepPointRatio 不能大于 export
         if (!CollectionUtils.isEmpty(ptlAgreementCostEnd.getPtlAgreementCostTypeList())) {
             for (PtlAgreementCostEnd.PtlAgreementCostTypeDto ptlAgreementCostTypeDto : ptlAgreementCostEnd.getPtlAgreementCostTypeList()) {
-                if (null != ptlAgreementCostTypeDto.getExportKeepPointRatio() && null != ptlAgreementCostTypeDto.getExport()){
+                if (null != ptlAgreementCostTypeDto.getExportKeepPointRatio() && null != ptlAgreementCostTypeDto.getExport()) {
                     if (ptlAgreementCostTypeDto.getExportKeepPointRatio().compareTo(ptlAgreementCostTypeDto.getExport()) > 0) {
                         return HttpResult.error("出口留点比例不能大于出口比例");
                     }
@@ -194,16 +208,15 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
         }
         // 处理minArray
         if (!CollectionUtils.isEmpty(ptlAgreementCostEnd.getRuleConditions())) {
-            ptlAgreementCostEnd.getRuleConditions().forEach(item->{
+            ptlAgreementCostEnd.getRuleConditions().forEach(item -> {
                 StringBuilder min = new StringBuilder();
-                if(item.getMinArray() != null && item.getMinArray().size() > 0){
-                    item.getMinArray().forEach(kk->{
+                if (item.getMinArray() != null && item.getMinArray().size() > 0) {
+                    item.getMinArray().forEach(kk -> {
                         min.append(kk).append(",");
                     });
-                    min.substring(0,min.length()-1);
+                    min.substring(0, min.length() - 1);
                     item.setMin(min.toString());
                 }
-
             });
             costRuleService.saveOrUpdateCostRule(BeanUtil.copyToList(ptlAgreementCostEnd.getRuleConditions(), PtlAgreementCostRule.class), ptlAgreementCost.getId());
         }
@@ -211,36 +224,35 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     }
 
 
-    public String buildDescString(String companyId, List<?> list){
-        if (CollectionUtils.isEmpty(list)){
+    public String buildDescString(String companyId, List<?> list) {
+        if (CollectionUtils.isEmpty(list)) {
             return null;
         }
         String desc = BuildDescUtils.buildDesc(companyId, BeanUtil.copyToList(list, PtlAgreementUndwrtRulesAttr.class), agreementUndwrtRulesAttrService.getUndwrtRulesAttrList());
-        // buildDesc返回的条件间以相邻双逗号分隔,此处合并为单个分号
-        return StringUtils.mergeAdjacentComma(desc);
+        return desc;
     }
 
-    public boolean verify(PtlAgreementCostAdd ptlAgreementCostAdd){
+    public boolean verify(PtlAgreementCostAdd ptlAgreementCostAdd) {
         CostAgreementParam costAgreementParam = new CostAgreementParam();
         costAgreementParam.setPtlAgreementId(ptlAgreementCostAdd.getPtlAgreementId());
         costAgreementParam.setCoverRuleId(ptlAgreementCostAdd.getCoverRuleId());
         List<PtlAgreementCostVo> voList = queryByAgreementId(costAgreementParam);
-        if (CollectionUtils.isEmpty(voList)){
+        if (CollectionUtils.isEmpty(voList)) {
             return false;
         }
         // 比较规则是否相同
         Map<String, List<PtlAgreementCostVo>> listMap = voList.stream().filter(v -> Constants.ENABLE == v.getIsEnabled() && Constants.EFFECTIVE == v.getIsValid()).collect(Collectors.groupingBy(PtlAgreementCostVo::getProductId));
         List<PtlAgreementCostVo> ptlAgreementCostVos = listMap.get(ptlAgreementCostAdd.getProductId());
-        if (CollectionUtils.isEmpty(ptlAgreementCostVos)){
+        if (CollectionUtils.isEmpty(ptlAgreementCostVos)) {
             return false;
         }
         List<RuleConditionsVerify> ruleConditionsVerifies = BeanUtil.copyToList(ptlAgreementCostAdd.getRuleConditions(), RuleConditionsVerify.class);
-        if (CollectionUtils.isEmpty(ruleConditionsVerifies)){
+        if (CollectionUtils.isEmpty(ruleConditionsVerifies)) {
             return false;
         }
         for (PtlAgreementCostVo ptlAgreementCostVo : ptlAgreementCostVos) {
             List<RuleConditionsVerify> verifies = BeanUtil.copyToList(ptlAgreementCostVo.getRuleConditions(), RuleConditionsVerify.class);
-            if (ObjectUtil.equals(verifies,ruleConditionsVerifies)){
+            if (ObjectUtil.equals(verifies, ruleConditionsVerifies)) {
                 return true;
             }
         }
@@ -258,7 +270,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     public HttpResult<PtlAgreementCostVo> queryById(Long id) {
         log.info("查询协议的费用信息:协议费用id=[{}]", id);
         PtlAgreementCostVo ptlAgreementCostVo = ptlAgreementCostMapper.queryById(id);
-        if (ObjectUtil.isEmpty(ptlAgreementCostVo)){
+        if (ObjectUtil.isEmpty(ptlAgreementCostVo)) {
             return HttpResult.ok(ptlAgreementCostVo);
         }
         RList<SysDict> rules = redissonClient.getList(DICT_REDIS_KEY + "rule_operator");
@@ -272,10 +284,10 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                 ruleCondition.setMin(value);
             }
             String attrType = ruleCondition.getAttrType();
-            if (StringUtils.isNotEmpty(attrType) && java.util.Arrays.stream(COST_TYPE_DICT_KEY).anyMatch(attrType::equals)){
-                if (StringUtils.isNotEmpty(ruleCondition.getMin()) && ruleCondition.getMin().contains(",")){
+            if (StringUtils.isNotEmpty(attrType) && java.util.Arrays.stream(COST_TYPE_DICT_KEY).anyMatch(attrType::equals)) {
+                if (StringUtils.isNotEmpty(ruleCondition.getMin()) && ruleCondition.getMin().contains(",")) {
                     ruleCondition.setMinArray(Arrays.asList(ruleCondition.getMin().split(",")));
-                }else {
+                } else {
                     ruleCondition.setMinArray(Collections.singletonList(ruleCondition.getMin()));
                     //ruleCondition.setMinArray(Collections.singletonList(ruleCondition.getMin()));
                 }
@@ -297,21 +309,21 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     }
 
 
-    private List<PtlAgreementCostVo> queryByAgreementId(CostAgreementParam costAgreementParam){
+    private List<PtlAgreementCostVo> queryByAgreementId(CostAgreementParam costAgreementParam) {
         return ptlAgreementCostMapper.queryByAgreementId(costAgreementParam);
     }
 
 
     @Override
-    public HttpResult enableDisableByIds(List<String> ids,Boolean isEnabled) {
-        if (CollectionUtils.isEmpty(ids)){
+    public HttpResult enableDisableByIds(List<String> ids, Boolean isEnabled) {
+        if (CollectionUtils.isEmpty(ids)) {
             return HttpResult.error("参数不能为空");
         }
         PtlAgreementCost ptlAgreementCost = new PtlAgreementCost();
         ptlAgreementCost.setIsEnabled(isEnabled ? 0 : 1);
         ptlAgreementCost.setIsValid(isEnabled ? 0 : 1);
-        return baseMapper.update(ptlAgreementCost,new LambdaQueryWrapper<>(PtlAgreementCost.class)
-                .in(PtlAgreementCost::getId,ids)) > 0 ?
+        return baseMapper.update(ptlAgreementCost, new LambdaQueryWrapper<>(PtlAgreementCost.class)
+                .in(PtlAgreementCost::getId, ids)) > 0 ?
                 HttpResult.ok(isEnabled ? "启用成功" : "禁用成功") : HttpResult.error(isEnabled ? "启用失败" : "禁用失败");
     }
 
@@ -319,7 +331,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
     public void updateAuditMethod(List<Long> ids) {
         PtlAgreementCost ptlAgreementCost = new PtlAgreementCost();
         ptlAgreementCost.setAuditMethod(0);
-        baseMapper.update(ptlAgreementCost,new LambdaQueryWrapper<>(PtlAgreementCost.class).in(PtlAgreementCost::getId,ids));
+        baseMapper.update(ptlAgreementCost, new LambdaQueryWrapper<>(PtlAgreementCost.class).in(PtlAgreementCost::getId, ids));
     }
 
     @Override
@@ -360,9 +372,9 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                     }
                 }
             }
-            if(isSuccessful) {
+            if (isSuccessful) {
                 return HttpResult.ok("审核成功", costReviewParam.isAutomatic() ? nextDataID() : null);
-            }else{
+            } else {
                 return HttpResult.ok("驳回成功", costReviewParam.isAutomatic() ? nextDataID() : null);
             }
         } catch (SystemException e) {
@@ -406,7 +418,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
 //            LocalDateTime localDateTime = end.plusDays(1).atStartOfDay();
 //            costParam.setAuditTimeEnd(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
 //        }
-        if(StrUtil.isNotEmpty(costParam.getCompanyId())){
+        if (StrUtil.isNotEmpty(costParam.getCompanyId())) {
             HttpResult<List<String>> res = esmInsCompanyClient.queryOwnAndSubCompandyIds(costParam.getCompanyId());
             costParam.setCompanyIdList(res.getData());
         }
@@ -430,16 +442,16 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
         Page<CostManagementVo> costManagementVoPage = baseMapper.pageList(costParam.getPage(), costParam);
         // 按承保规则属性 sort 正序,重新排列 cost_rules 各段描述
         reorderCostRules(costManagementVoPage.getRecords());
-        costManagementVoPage.getRecords().forEach(item->{
-            if(item.getCostRules() != null && !item.getCostRules().isEmpty()){
-                item.setCostRules(item.getCostRules().substring(0,item.getCostRules().length()-1));
+        costManagementVoPage.getRecords().forEach(item -> {
+            if (item.getCostRules() != null && !item.getCostRules().isEmpty()) {
+                item.setCostRules(item.getCostRules().substring(0, item.getCostRules().length() - 1));
             }
-            if(item.getRuleDescription() != null && !item.getRuleDescription().isEmpty()){
-                item.setRuleDescription(item.getRuleDescription().substring(0,item.getRuleDescription().length()-1));
+            if (item.getRuleDescription() != null && !item.getRuleDescription().isEmpty()) {
+                item.setRuleDescription(item.getRuleDescription().substring(0, item.getRuleDescription().length() - 1));
             }
             // ruleDescription中出现两个相邻的","或","时,转换为"或"字
             item.setRuleDescription(StringUtils.convertAdjacentCommaToOr(item.getRuleDescription()));
-            item.setAuditPersonName(userName2Name.getOrDefault(item.getAuditPerson(),item.getAuditPerson()));
+            item.setAuditPersonName(userName2Name.getOrDefault(item.getAuditPerson(), item.getAuditPerson()));
         });
         return HttpResult.ok(costManagementVoPage);
     }
@@ -511,9 +523,9 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
         List<String> newCostId = new ArrayList<>();
         List<String> costIds = costCopyParam.getCostIds();
         StringBuilder errMsg = new StringBuilder();
-        costIds.forEach(oldCostId-> {
+        costIds.forEach(oldCostId -> {
             PtlAgreementCost ptlAgreementCost = ptlAgreementCostMapper.selectById(oldCostId);
-            if(ptlAgreementCost != null){
+            if (ptlAgreementCost != null) {
                 List<PtlAgreementCostType> ptlAgreementCostTypes = ptlAgreementCostTypeMapper.selectList(new LambdaQueryWrapper<PtlAgreementCostType>()
                         .eq(PtlAgreementCostType::getPtlAgreementCostId, ptlAgreementCost.getId()));
                 List<PtlAgreementCostRule> ptlAgreementCostRules = ptlAgreementCostRuleMapper.selectList(new LambdaQueryWrapper<PtlAgreementCostRule>()
@@ -527,10 +539,10 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                 ptlAgreementCost.setCostDescribe(ptlAgreementCost.getCostDescribe());
                 ptlAgreementCost.setCreateTime(LocalDateTime.now());
                 ptlAgreementCost.setUpdateTime(LocalDateTime.now());
-                if(costCopyParam.getProductId() != null && !costCopyParam.getProductId().isEmpty()){
+                if (costCopyParam.getProductId() != null && !costCopyParam.getProductId().isEmpty()) {
                     ptlAgreementCost.setProductId(costCopyParam.getProductId());
                 }
-                if(costCopyParam.getProductName() != null && !costCopyParam.getProductName().isEmpty()){
+                if (costCopyParam.getProductName() != null && !costCopyParam.getProductName().isEmpty()) {
                     ptlAgreementCost.setProductName(costCopyParam.getProductName());
                 }
 
@@ -560,7 +572,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                         })
                         .collect(Collectors.toList());
 
-                ptlAgreementCostRules.forEach(item->{
+                ptlAgreementCostRules.forEach(item -> {
                     item.setId(IdGenerate.nextId());
                     item.setPtlAgreementCostId(costId);
                 });
@@ -570,13 +582,13 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                 ptlAgreementCostRuleMapper.insert(ptlAgreementCostRules);
                 newCostId.add(ptlAgreementCost.getId());
 
-            }else{
-                errMsg.append("costId为"+oldCostId+"的费用信息已被删除");
+            } else {
+                errMsg.append("costId为" + oldCostId + "的费用信息已被删除");
             }
 
 
         });
-        return HttpResult.ok(errMsg.toString(),newCostId);
+        return HttpResult.ok(errMsg.toString(), newCostId);
     }
 
     @Override
@@ -640,6 +652,7 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
                 ? HttpResult.ok("批量修改成功,共修改 " + finalCostIds.size() + " 条记录")
                 : HttpResult.error("批量修改失败");
     }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public HttpResult<String> batchAdjustCostRatio(PtlAgreementCostBatchAdjustParam param) {
@@ -658,6 +671,9 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
             return HttpResult.error("未找到需要调整的费用类型记录");
         }
 
+        // 备份调整前的数据 用于操作轨迹 beforeJson
+        List<PtlAgreementCostType> beforeCostTypeList = BeanUtil.copyToList(costTypeList, PtlAgreementCostType.class);
+
         boolean isAdd = "ADD".equalsIgnoreCase(param.getOperationType());
 
         // 校验:至少传递一种险种的比例
@@ -687,6 +703,8 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
             }
 
             if (wasAdjusted) {
+                // 出口留点比例 大于 出口比例 设置 出口留点比例 等于 出口比例
+                clampKeepPointRatios(costType);
                 adjustedCount++;
             }
         }
@@ -697,10 +715,46 @@ public class PtlAgreementCostServiceImpl extends ServiceImpl<PtlAgreementCostMap
 
         // 批量更新
         ptlAgreementCostTypeService.updateBatchById(costTypeList);
-
+        // 插入操作轨迹表记录
+        OperatorTrajectory operatorTrajectory = new OperatorTrajectory();
+        operatorTrajectory.setId(IdGenerate.nextId());
+        operatorTrajectory.setModuleName("报价配置/费用管理/批量调整费用比例");
+        operatorTrajectory.setServiceTag(
+                "com.jzg.organization.service.impl.PtlAgreementCostServiceImpl.batchAdjustCostRatio()");
+        operatorTrajectory.setEntityName(
+                "com.jzg.commons.entity.po.PtlAgreementCostType");
+        operatorTrajectory.setPrimaryValue(String.join(",", param.getCostIds()));
+        operatorTrajectory.setOperatorType(Crud.U.getCode());
+        Map<String, Object> beforeWrapper = new HashMap<>();
+        beforeWrapper.put("costTypeList", beforeCostTypeList);
+        operatorTrajectory.setBeforeJson(JSONUtil.toJsonStr(beforeWrapper));
+
+        Map<String, Object> afterWrapper = new HashMap<>();
+        afterWrapper.put("costTypeList", costTypeList);
+        operatorTrajectory.setAfterJson(JSONUtil.toJsonStr(afterWrapper));
+        operatorTrajectory.setOperationContent("批量调整费用比例");
+        operatorTrajectory.setSystemCode(baseController.getSystemCode());
+        String userTokenString = baseController.getUserTokenString();
+        JSONObject userInfo = JSONObject.parseObject(userTokenString);
+        operatorTrajectory.setCreateBy(userInfo.getString("username"));
+        operatorTrajectory.setCreateByName(userInfo.getString("name"));
+        operatorTrajectory.setCreateTime(LocalDateTime.now());
+        operatorTrajectoryService.save(operatorTrajectory);
         return HttpResult.ok("批量调整成功,共调整 " + adjustedCount + " 条记录");
     }
 
+    /**
+     * 出口留点比例 大于 出口比例 设置 出口留点比例 等于 出口比例
+     */
+    private void clampKeepPointRatios(PtlAgreementCostType costType) {
+        // 出口留点 ≤ 出口比例
+        BigDecimal exportKeep = costType.getExportKeepPointRatio();
+        BigDecimal export = costType.getExport();
+        if (exportKeep != null && export != null && exportKeep.compareTo(export) > 0) {
+            costType.setExportKeepPointRatio(export);
+        }
+    }
+
     /**
      * 调整费用类型的各项比例
      */

+ 119 - 4
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementUndwrtRulesServiceImpl.java

@@ -7,10 +7,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.jzg.commons.entity.dto.AgreementRulesAddParam;
-import com.jzg.commons.entity.dto.AgreementRulesEditParam;
-import com.jzg.commons.entity.dto.CostAgreementParam;
-import com.jzg.commons.entity.dto.RulesGroupParam;
+import com.jzg.commons.entity.dto.*;
 import com.jzg.commons.entity.po.*;
 import com.jzg.commons.entity.vo.AgreementRulesVo;
 import com.jzg.commons.entity.vo.CostListVo;
@@ -767,6 +764,124 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
         return newAttrList;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean rulesAttrBatchCopy(AgreementRulesAttrCopyParam param) {
+        log.info("批量复制规则因子:param=[{}]", JSONUtil.toJsonStr(param));
+
+        // 按 attrIds 精确查询要复制的因子记录,源规则由因子记录所属规则反推
+        List<PtlAgreementUndwrtRulesAttrLink> sourceLinks = agreementUndwrtRulesAttrLinkService.list(
+                new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
+                        .in(PtlAgreementUndwrtRulesAttrLink::getId, param.getAttrIds()));
+        if (CollUtil.isEmpty(sourceLinks)) {
+            throw new SystemException("源规则因子不存在");
+        }
+        if (sourceLinks.size() != new HashSet<>(param.getAttrIds()).size()) {
+            throw new SystemException("部分规则因子不存在或已被删除");
+        }
+
+        // 源因子所属规则必须一致(同一规则或同一批量组)
+        List<String> sourceRuleIds = sourceLinks.stream()
+                .map(PtlAgreementUndwrtRulesAttrLink::getRulesId)
+                .distinct()
+                .collect(Collectors.toList());
+        List<PtlAgreementUndwrtRules> sourceRuleList = baseMapper.selectBatchIds(sourceRuleIds);
+        if (CollUtil.isEmpty(sourceRuleList)) {
+            throw new SystemException("源规则因子所属承保规则不存在或已被删除");
+        }
+        PtlAgreementUndwrtRules sourceRules = sourceRuleList.get(0);
+        if (sourceRuleList.size() > 1) {
+            boolean sameGroup = sourceRuleList.stream().allMatch(r ->
+                    StrUtil.isNotBlank(r.getParentId()) && r.getParentId().equals(sourceRules.getParentId()));
+            if (!sameGroup) {
+                throw new SystemException("源规则因子分属不同规则组,无法批量复制");
+            }
+        }
+        List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList = agreementUndwrtRulesAttrService.getUndwrtRulesAttrList();
+
+        // 遍历目标协议:每个目标协议下新增一条规则承接所选因子,
+        // 新增规则与目标协议已有规则共享 parentId(无已有规则则独立展示),前端按组合并成一条展示;源规则保持不变
+        for (AgreementRulesAttrCopyParam.CopyTarget target : param.getTargets()) {
+            String targetAgreementId = target.getAgreementId();
+
+            // 1. 定位锚定规则(用于确定归组):优先指定的规则,否则取该协议下第一条规则(序号最小)
+            PtlAgreementUndwrtRules anchor = null;
+            if (StrUtil.isNotBlank(target.getRuleId())) {
+                anchor = baseMapper.selectById(target.getRuleId());
+                if (anchor == null) {
+                    throw new SystemException("目标承保规则不存在:" + target.getRuleId());
+                }
+                if (!targetAgreementId.equals(anchor.getAgreementId())) {
+                    throw new SystemException("目标承保规则[" + target.getRuleId() + "]不属于协议[" + targetAgreementId + "]");
+                }
+            } else {
+                LambdaQueryWrapper<PtlAgreementUndwrtRules> wrapper = new LambdaQueryWrapper<>();
+                wrapper.eq(PtlAgreementUndwrtRules::getAgreementId, targetAgreementId)
+                        .eq(PtlAgreementUndwrtRules::getIsDelete, 0)
+                        .orderByAsc(PtlAgreementUndwrtRules::getOrderNum)
+                        .last("LIMIT 1");
+                anchor = baseMapper.selectOne(wrapper);
+            }
+
+            // 2. 获取该协议下最大序号,新规则追加在末尾
+            LambdaQueryWrapper<PtlAgreementUndwrtRules> maxWrapper = new LambdaQueryWrapper<>();
+            maxWrapper.eq(PtlAgreementUndwrtRules::getAgreementId, targetAgreementId)
+                    .eq(PtlAgreementUndwrtRules::getIsDelete, 0)
+                    .orderByDesc(PtlAgreementUndwrtRules::getOrderNum)
+                    .last("LIMIT 1");
+            PtlAgreementUndwrtRules maxRules = baseMapper.selectOne(maxWrapper);
+            int orderNum = Objects.nonNull(maxRules) ? maxRules.getOrderNum() + 1 : 1;
+
+            // 3. 新增规则(仅含本次所选因子),基础信息沿用源规则
+            PtlAgreementUndwrtRules targetRules = new PtlAgreementUndwrtRules();
+            targetRules.setId(IdGenerate.nextId());
+            targetRules.setAgreementId(targetAgreementId);
+            targetRules.setStartTime(sourceRules.getStartTime());
+            targetRules.setEndTime(sourceRules.getEndTime());
+            targetRules.setInputDescription(sourceRules.getInputDescription());
+            targetRules.setOrderNum(orderNum);
+            if (anchor != null) {
+                // 与锚定规则同组展示:锚定已有 parentId 则复用;锚定无 parentId 则生成新组ID并将锚定规则归入该组
+                String groupParentId = anchor.getParentId();
+                if (StrUtil.isBlank(groupParentId)) {
+                    groupParentId = IdGenerate.nextId();
+                    LambdaUpdateWrapper<PtlAgreementUndwrtRules> anchorUpdate = new LambdaUpdateWrapper<>();
+                    anchorUpdate.eq(PtlAgreementUndwrtRules::getId, anchor.getId())
+                            .set(PtlAgreementUndwrtRules::getParentId, groupParentId);
+                    baseMapper.update(null, anchorUpdate);
+                }
+                targetRules.setParentId(groupParentId);
+            }
+            baseMapper.insert(targetRules);
+
+            // 4. 复制所选因子到新规则(同一 attrCode 仅复制一次)
+            List<PtlAgreementUndwrtRulesAttrLink> copiedLinks = new ArrayList<>();
+            Set<String> copiedCodes = new HashSet<>();
+            for (PtlAgreementUndwrtRulesAttrLink sourceLink : sourceLinks) {
+                if (!copiedCodes.add(sourceLink.getAttrCode())) {
+                    continue;
+                }
+                PtlAgreementUndwrtRulesAttrLink newLink = new PtlAgreementUndwrtRulesAttrLink();
+                newLink.setRulesId(targetRules.getId());
+                newLink.setAttrId(sourceLink.getAttrId());
+                newLink.setAttrCode(sourceLink.getAttrCode());
+                newLink.setMin(sourceLink.getMin());
+                newLink.setOperator(sourceLink.getOperator());
+                newLink.setMax(sourceLink.getMax());
+                agreementUndwrtRulesAttrLinkMapper.insert(newLink);
+                copiedLinks.add(newLink);
+            }
+
+            // 5. 生成新规则描述
+            String ruleDescription = BuildDescUtils.buildDesc(copiedLinks, undwrtRulesAttrList);
+            LambdaUpdateWrapper<PtlAgreementUndwrtRules> updateWrapper = new LambdaUpdateWrapper<>();
+            updateWrapper.eq(PtlAgreementUndwrtRules::getId, targetRules.getId())
+                    .set(PtlAgreementUndwrtRules::getRuleDescription, ruleDescription);
+            baseMapper.update(null, updateWrapper);
+        }
+        return true;
+    }
+
     @Override
     public List<AgreementRulesVo> queryListByParentId(String parentId) {
         log.info("根据父ID查询协议承保规则列表。 parentId=[{}]", parentId);

+ 3 - 4
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java

@@ -40,7 +40,6 @@ import com.jzg.organization.client.OrgClient;
 import com.jzg.organization.client.PlatformClient;
 import com.jzg.organization.mapper.*;
 import com.jzg.organization.service.*;
-import io.seata.spring.annotation.GlobalTransactional;
 import org.apache.http.util.TextUtils;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
@@ -184,7 +183,7 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
                 }
             }
         }
-        //校验驾意险座位数范围不可重复
+        // 自选驾意险,校验座位数范围不可重复
         if(!ptlSchemeSaveVo.getSchemeType().equals("2")) {
             validateDrivingIntentionSeatRange(ptlSchemeInsuranceDrivingIntentionList);
         }
@@ -995,7 +994,7 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
     @Autowired
     PtlSchemeService ptlSchemeService;
 
-    @GlobalTransactional
+    @Transactional
     @Override
     public Boolean copyScheme(String schemeInfoId, String productCode) {
 
@@ -1051,7 +1050,7 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
         SalespersonInfoVo salespersonInfo = schemeRuleFilterVo.getSalespersonInfo();
         if (CollUtil.isNotEmpty(companyList) && ObjectUtil.isNotEmpty(salespersonInfo) && StrUtil.isNotBlank(salespersonInfo.getId())) {
             // 根据业务员ID获取业务员信息(含部门ID)
-            SysUserJzgInfo sysUserJzgInfo = sysUserJzgInfoService.getUserById(salespersonInfo.getId());
+            SysUserJzgInfo sysUserJzgInfo = sysUserJzgInfoService.getYWYById(salespersonInfo.getId());
             String userDeptId = sysUserJzgInfo.getDeptId(); // 业务员所属部门ID
 
             // ========== 核心逻辑开始 ==========

+ 111 - 61
tenant/organization/src/main/java/com/jzg/organization/service/impl/ReceivableServiceImpl.java

@@ -305,23 +305,32 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      * 3. 将完整数据设置回分页对象并返回
      * </p>
      *
-     * @param receivableQueryVo 列表查询条件,包含订单号、保险公司ID、结算状态、时间范围等筛选条件,以及分页参数
+     * @param vo 列表查询条件,包含订单号、保险公司ID、结算状态、时间范围等筛选条件,以及分页参数
      * @return Page<InsPlyIncome> 返回分页后的应收订单列表,包含完整的订单信息及关联数据
      */
     @Override
-    public Page<InsPlyIncome> getReceivablePage(ReceivableQueryVo receivableQueryVo) {
-        log.info("获取私有协议手续费应收列表。receivableQueryVo=[{}]", JSONUtil.toJsonStr(receivableQueryVo));
-
-//        if(StrUtil.isNotEmpty(receivableQueryVo.getUpdateBy())){
-//            insFeeOrdersClient.getUserNameByMobile();
-//        }
+    public Page<InsPlyIncome> getReceivablePage(ReceivableQueryVo vo) {
+        log.info("获取私有协议手续费应收列表。vo=[{}]", JSONUtil.toJsonStr(vo));
 
+        // 完善支付时间的查询条件
+        if(StrUtil.isNotEmpty(vo.getPayTimeBegin())){
+            vo.setPayTimeBegin(DateTimeUtils.obtainStartTime(vo.getPayTimeBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getPayTimeEnd())){
+            vo.setPayTimeEnd(DateTimeUtils.obtainNextDayStartTime(vo.getPayTimeEnd()));
+        }
+        if(StrUtil.isNotEmpty(vo.getSigningTimeStart())){
+            vo.setSigningTimeStart(DateTimeUtils.obtainStartTime(vo.getSigningTimeStart()));
+        }
+        if(StrUtil.isNotEmpty(vo.getSigningTimeEnd())){
+            vo.setSigningTimeEnd(DateTimeUtils.obtainNextDayStartTime(vo.getSigningTimeEnd()));
+        }
 
-        Page<InsPlyIncome> page = baseMapper.getReceivablePage(receivableQueryVo.getPage(), receivableQueryVo);
+        Page<InsPlyIncome> page = baseMapper.getReceivablePage(vo.getPage(), vo);
         List<InsPlyIncome> records = page.getRecords();
         records = records.stream().filter(action->{
             // add by lipf 2026年7月3日09:55:17 只有私有的非车,才需要走下面的逻辑。 将非车保费为0的记录不显示
-            if(StrUtil.isEmpty(receivableQueryVo.getQueryType()) || !"3".equals(receivableQueryVo.getQueryType())){
+            if(StrUtil.isEmpty(vo.getQueryType()) || !"3".equals(vo.getQueryType())){
                 return true;
             }
             if(StrUtil.isEmpty(action.getJyPremium())){
@@ -330,7 +339,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
             BigDecimal JyPremium = new BigDecimal(action.getJyPremium());
             return BigDecimal.ZERO.compareTo(JyPremium) != 0;
         }).toList();
-        records = this.fillOtherInfo(records,receivableQueryVo.getInvoiceType());
+        records = this.fillOtherInfo(records,vo.getInvoiceType());
         page.setRecords(records);
         return page;
     }
@@ -844,7 +853,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      * 5. 补充收入表中的其他费用应收数据(驾意险相关费用)
      * </p>
      *
-     * @param settlementReportQueryVo 结算报表查询条件对象,包含查询所需的过滤参数(如时间范围、公司ID等)
+     * @param vo 结算报表查询条件对象,包含查询所需的过滤参数(如时间范围、公司ID等)
      * @return List<FollowCompanyFeeVO> 返回跟单公司费用视图对象列表,每个对象包含:
      *         - partnerCompanyId: 合作公司ID
      *         - companyName: 合作公司名称
@@ -857,10 +866,17 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      *         - totalUnSettlementAmount: 未结算总金额
      */
     @Override
-    public List<FollowCompanyFeeVO> followCompanySuperviseSettlementReport(SettlementReportQueryVo settlementReportQueryVo) {
-        log.info("私有协议-跟单结算记录-结算报表: settlementReportQueryVo=[{}]", JSONUtil.toJsonStr(settlementReportQueryVo));
+    public List<FollowCompanyFeeVO> followCompanySuperviseSettlementReport(SettlementReportQueryVo vo) {
+        log.info("私有协议-跟单结算记录-结算报表: vo=[{}]", JSONUtil.toJsonStr(vo));
+
+        if(StrUtil.isNotEmpty(vo.getReceivePaymentDateBegin())){
+            vo.setReceivePaymentDateBegin(DateTimeUtils.obtainStartTime(vo.getReceivePaymentDateBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getReceivePaymentDateEnd())){
+            vo.setReceivePaymentDateEnd(DateTimeUtils.obtainNextDayStartTime(vo.getReceivePaymentDateEnd()));
+        }
         List<FollowCompanyFeeVO> resultList = new ArrayList<>();
-        String invoiceType = settlementReportQueryVo.getInvoiceType();
+        String invoiceType = vo.getInvoiceType();
 
         // 1. 获取保险公司全量Map
         Map<String, EsmInsCompany> companyMap = getAllInsCompanyMap();
@@ -869,17 +885,17 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         }
 
         // 处理公司ID,递归收集子公司ID
-        fillCompanyChildIds(settlementReportQueryVo, companyMap);
+        fillCompanyChildIds(vo, companyMap);
 
         // 2. 查询跟单主数据并聚合
-        List<FollowCompanyFeeVO> originalFollowList = insFeeFollowOrderMapper.selectFollowCompanySettlementReport(settlementReportQueryVo);
+        List<FollowCompanyFeeVO> originalFollowList = insFeeFollowOrderMapper.selectFollowCompanySettlementReport(vo);
         if (CollUtil.isNotEmpty(originalFollowList)) {
             List<FollowCompanyFeeVO> followAggVoList = aggregateFollowData(originalFollowList, companyMap);
             resultList.addAll(followAggVoList);
         }
 
         // 3. 查询补充应收收入数据并合并
-        fillOtherReceivableData(settlementReportQueryVo, resultList, companyMap, invoiceType);
+        fillOtherReceivableData(vo, resultList, companyMap, invoiceType);
 
         if (CollUtil.isEmpty(resultList)) {
             return resultList;
@@ -5119,17 +5135,32 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      * 3. 将完整数据设置回分页对象并返回
      * </p>
      *
-     * @param receivableQueryVo 列表查询条件,包含订单号、保险公司ID、结算状态、时间范围等筛选条件,以及分页参数
+     * @param vo 列表查询条件,包含订单号、保险公司ID、结算状态、时间范围等筛选条件,以及分页参数
      * @return Page<InsPlyIncome> 返回分页后的平台协议应收订单列表,包含完整的订单信息及关联数据
      */
     @Override
-    public Page<InsPlyIncome> getPlatFormReceivableList(ReceivableQueryVo receivableQueryVo) {
-        log.info("获取平台协议列表. receivableQueryVo=[{}]", JSONUtil.toJsonStr(receivableQueryVo));
-        Page<InsPlyIncome> page = baseMapper.getReceivablePage(receivableQueryVo.getPage(), receivableQueryVo);
+    public Page<InsPlyIncome> getPlatFormReceivableList(ReceivableQueryVo vo) {
+        log.info("获取平台协议列表. vo=[{}]", JSONUtil.toJsonStr(vo));
+
+        // 对支付时间进行增强适配, 在日期后面添加上时分秒
+        if(StrUtil.isNotEmpty(vo.getPayTimeBegin())){
+            vo.setPayTimeBegin(DateTimeUtils.obtainStartTime(vo.getPayTimeBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getPayTimeEnd())){
+            vo.setPayTimeEnd(DateTimeUtils.obtainNextDayStartTime(vo.getPayTimeEnd()));
+        }
+        // 对报价时间进行增强适配
+        if(StrUtil.isNotEmpty(vo.getQuotationTimeBegin())){
+            vo.setQuotationTimeBegin(DateTimeUtils.obtainStartTime(vo.getQuotationTimeBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getQuotationTimeEnd())){
+            vo.setQuotationTimeEnd(DateTimeUtils.obtainNextDayStartTime(vo.getQuotationTimeEnd()));
+        }
+        Page<InsPlyIncome> page = baseMapper.getReceivablePage(vo.getPage(), vo);
         List<InsPlyIncome> records = page.getRecords();
         records = this.fillOtherInfo(records,null);
         // 过滤业务来源
-        records = records.stream().filter(income -> StrUtil.isBlank(receivableQueryVo.getTypeAttr()) || receivableQueryVo.getTypeAttr().equals(income.getTypeAttr())).collect(Collectors.toList());
+        records = records.stream().filter(income -> StrUtil.isBlank(vo.getTypeAttr()) || vo.getTypeAttr().equals(income.getTypeAttr())).collect(Collectors.toList());
         page.setRecords(records);
         return page;
     }
@@ -5434,26 +5465,32 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     /**
      * 平台协议结算记录
      *
-     * @param settlementQueryVo 查询条件
+     * @param vo 查询条件
      * @return Page<ExportSuperviseSettlementExcelDto>
      */
     @Override
-    public Page<ExportSuperviseSettlementExcelDto> platformSettlementExcel(Page page, SettlementQueryVo settlementQueryVo) {
-        log.info("查询平台结算记录:settlementQueryVo=[{}]", JSONUtil.toJsonStr(settlementQueryVo));
+    public Page<ExportSuperviseSettlementExcelDto> platformSettlementExcel(Page page, SettlementQueryVo vo) {
+        log.info("查询平台结算记录:vo=[{}]", JSONUtil.toJsonStr(vo));
 
-        if(StrUtil.isEmpty(settlementQueryVo.getSettlementDateStart())
-            && StrUtil.isEmpty(settlementQueryVo.getSettlementDateEnd())
-            && settlementQueryVo.getSettlementTime() != null &&
-                settlementQueryVo.getSettlementTime().length ==2){
-            DateUtil.parse(settlementQueryVo.getSettlementDateStart());
-            settlementQueryVo.setSettlementDateStart(DateUtil.format(LocalDate.parse(settlementQueryVo.getSettlementTime()[0], DateTimeFormatter.ISO_DATE).atStartOfDay(), "yyyy-MM-dd HH:mm:ss"));
-            settlementQueryVo.setSettlementDateEnd(DateUtil.format(LocalDate.parse(settlementQueryVo.getSettlementTime()[1], DateTimeFormatter.ISO_DATE).plusDays(1).atStartOfDay(), "yyyy-MM-dd HH:mm:ss"));
+        if(StrUtil.isEmpty(vo.getSettlementDateStart())
+            && StrUtil.isEmpty(vo.getSettlementDateEnd())
+            && vo.getSettlementTime() != null &&
+                vo.getSettlementTime().length ==2){
+            DateUtil.parse(vo.getSettlementDateStart());
+            vo.setSettlementDateStart(DateUtil.format(LocalDate.parse(vo.getSettlementTime()[0], DateTimeFormatter.ISO_DATE).atStartOfDay(), "yyyy-MM-dd HH:mm:ss"));
+            vo.setSettlementDateEnd(DateUtil.format(LocalDate.parse(vo.getSettlementTime()[1], DateTimeFormatter.ISO_DATE).plusDays(1).atStartOfDay(), "yyyy-MM-dd HH:mm:ss"));
+        }
+        // 完善回款时间 receivePaymentDateBegin
+        if(StrUtil.isNotEmpty(vo.getReceivePaymentDateBegin())){
+            vo.setReceivePaymentDateBegin(DateTimeUtils.obtainStartTime(vo.getReceivePaymentDateBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getReceivePaymentDateEnd())){
+            vo.setReceivePaymentDateEnd(DateTimeUtils.obtainNextDayStartTime(vo.getReceivePaymentDateEnd()));
         }
-
         // 设置空条件
-        setNoneCondition(settlementQueryVo);
-        settlementQueryVo.setSystemCode(baseController.getSystemCode());
-        Page<ExportSuperviseSettlementExcelDto> exportSuperviseSettlementExcelDtos = baseMapper.platformSettlementExcelDtos(page, settlementQueryVo);
+        setNoneCondition(vo);
+        vo.setSystemCode(baseController.getSystemCode());
+        Page<ExportSuperviseSettlementExcelDto> exportSuperviseSettlementExcelDtos = baseMapper.platformSettlementExcelDtos(page, vo);
         // 补充、转换列表的数据
         supplementaryListData(exportSuperviseSettlementExcelDtos);
         return exportSuperviseSettlementExcelDtos;
@@ -5462,16 +5499,24 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
     /**
      * 跟单协议结算记录
      *
-     * @param settlementQueryVo 查询条件
+     * @param vo 查询条件
      * @return Page<ExportSuperviseSettlementExcelDto>
      */
     @Override
-    public Page<ExportSuperviseSettlementExcelDto> followSettlementExcel(Page page, SettlementQueryVo settlementQueryVo) {
-        log.info("查询平台结算记录:settlementQueryVo=[{}]", JSONUtil.toJsonStr(settlementQueryVo));
+    public Page<ExportSuperviseSettlementExcelDto> followSettlementExcel(Page page, SettlementQueryVo vo) {
+        log.info("查询平台结算记录:vo=[{}]", JSONUtil.toJsonStr(vo));
         // 设置空条件
-        setNoneCondition(settlementQueryVo);
-        settlementQueryVo.setSystemCode(baseController.getSystemCode());
-        Page<ExportSuperviseSettlementExcelDto> exportSuperviseSettlementExcelDtos = baseMapper.followSettlementExcelDtos(page, settlementQueryVo);
+        setNoneCondition(vo);
+        if(StrUtil.isNotEmpty(vo.getReceivePaymentDateBegin())){
+            vo.setReceivePaymentDateBegin(DateTimeUtils.obtainStartTime(vo.getReceivePaymentDateBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getReceivePaymentDateEnd())){
+            vo.setReceivePaymentDateEnd(DateTimeUtils.obtainNextDayStartTime(vo.getReceivePaymentDateEnd()));
+        }
+
+
+        vo.setSystemCode(baseController.getSystemCode());
+        Page<ExportSuperviseSettlementExcelDto> exportSuperviseSettlementExcelDtos = baseMapper.followSettlementExcelDtos(page, vo);
         // 补充、转换列表的数据
         supplementaryListData(exportSuperviseSettlementExcelDtos);
         return exportSuperviseSettlementExcelDtos;
@@ -5642,7 +5687,7 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      * </p>
      *
      * @param page 分页对象,包含页码、每页数量等分页参数
-     * @param settlementQueryVo 结算查询条件,包含订单号、保险公司ID、结算状态、时间范围等筛选条件,主要参数:
+     * @param vo 结算查询条件,包含订单号、保险公司ID、结算状态、时间范围等筛选条件,主要参数:
      *                          - invoiceTypes: 开票类型列表,用于区分平台协议和普通协议
      *                          - systemCode: 租户代码(方法内自动设置)
      * @return Page<ExportSuperviseSettlementDetailExcelDto> 返回分页后的手续费结算明细数据,每个对象包含:
@@ -5651,9 +5696,9 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
      *         - 其他结算明细字段
      */
     @Override
-    public Page<ExportSuperviseSettlementDetailExcelDto> superviseSettlementDetailExcel(Page page, SettlementQueryVo settlementQueryVo) {
-        log.info("superviseSettlementDetailExcel:settlementQueryVo=[{}]", JSONUtil.toJsonStr(settlementQueryVo));
-        settlementQueryVo.setSystemCode(baseController.getSystemCode());
+    public Page<ExportSuperviseSettlementDetailExcelDto> superviseSettlementDetailExcel(Page page, SettlementQueryVo vo) {
+        log.info("superviseSettlementDetailExcel:vo=[{}]", JSONUtil.toJsonStr(vo));
+        vo.setSystemCode(baseController.getSystemCode());
         Page<ExportSuperviseSettlementDetailExcelDto> exportSuperviseSettlementDetailExcelDtos = null;
 
         // 1. 一次性获取保险公司全量Map,全局复用
@@ -5663,41 +5708,46 @@ public class ReceivableServiceImpl extends ServiceImpl<ReceivableMapper, InsPlyI
         }
 
         // 查询当前公司下所有的子公司
-        if (StrUtil.isNotBlank(settlementQueryVo.getCompanyId())){
+        if (StrUtil.isNotBlank(vo.getCompanyId())){
             // 将全量数据按照 parentId 进行分组,key 是 parentId,value 是该 parentId 下的所有公司列表
             Map<String, List<EsmInsCompany>> parentGroupMap = companyMap.values().stream()
                     .filter(c -> c.getParentId() != null)
                     .collect(Collectors.groupingBy(EsmInsCompany::getParentId));
-            List<String> allChildIdspOtimized = getAllChildIdsOptimized(settlementQueryVo.getCompanyId(), parentGroupMap);
-            allChildIdspOtimized.add(settlementQueryVo.getCompanyId());
-            settlementQueryVo.setCompanyIdList(allChildIdspOtimized);
+            List<String> allChildIdspOtimized = getAllChildIdsOptimized(vo.getCompanyId(), parentGroupMap);
+            allChildIdspOtimized.add(vo.getCompanyId());
+            vo.setCompanyIdList(allChildIdspOtimized);
         }
-
-        if (settlementQueryVo.getInvoiceTypes().contains("5") && settlementQueryVo.getInvoiceTypes().contains("6")) {
-            exportSuperviseSettlementDetailExcelDtos = baseMapper.getPlatFormSettlementDetailExcelDtos(page, settlementQueryVo);
+        if(StrUtil.isNotEmpty(vo.getSigningTimeBegin())){
+            vo.setSigningTimeBegin(DateTimeUtils.obtainStartTime(vo.getSigningTimeBegin()));
+        }
+        if(StrUtil.isNotEmpty(vo.getSigningTimeEnd())){
+            vo.setSigningTimeEnd(DateTimeUtils.obtainNextDayStartTime(vo.getSigningTimeEnd()));
+        }
+        if (vo.getInvoiceTypes().contains("5") && vo.getInvoiceTypes().contains("6")) {
+            exportSuperviseSettlementDetailExcelDtos = baseMapper.getPlatFormSettlementDetailExcelDtos(page, vo);
         }else{
-            exportSuperviseSettlementDetailExcelDtos = baseMapper.getSuperviseSettlementDetailExcelDtos(page, settlementQueryVo);
+            exportSuperviseSettlementDetailExcelDtos = baseMapper.getSuperviseSettlementDetailExcelDtos(page, vo);
         }
         if (CollUtil.isNotEmpty(exportSuperviseSettlementDetailExcelDtos.getRecords())){
             Map<String, InsPlyIncomeInvoiceSettlement> settlementMap = new HashMap<>();
-            if (!(settlementQueryVo.getInvoiceTypes().contains("5") && settlementQueryVo.getInvoiceTypes().contains("6"))) {
+            if (!(vo.getInvoiceTypes().contains("5") && vo.getInvoiceTypes().contains("6"))) {
                 // 根据invoiceId关联查询ins_ply_income_invoice_settlement表
                 LambdaQueryWrapper<InsPlyIncomeInvoiceSettlement> insPlyIncomeInvoiceSettlementLambdaQueryWrapper = new LambdaQueryWrapper<>();
                 insPlyIncomeInvoiceSettlementLambdaQueryWrapper.in(InsPlyIncomeInvoiceSettlement::getInvoiceId, exportSuperviseSettlementDetailExcelDtos.getRecords().stream().map(ExportSuperviseSettlementDetailExcelDto::getInvoiceId).toList());
                 insPlyIncomeInvoiceSettlementLambdaQueryWrapper.eq(InsPlyIncomeInvoiceSettlement::getIsDelete, 0);
-                if (StrUtil.isNotBlank(settlementQueryVo.getSettlementPerson())) {
+                if (StrUtil.isNotBlank(vo.getSettlementPerson())) {
                     // 结算人
-                    insPlyIncomeInvoiceSettlementLambdaQueryWrapper.eq(InsPlyIncomeInvoiceSettlement::getCreateBy, settlementQueryVo.getSettlementPerson());
+                    insPlyIncomeInvoiceSettlementLambdaQueryWrapper.eq(InsPlyIncomeInvoiceSettlement::getCreateBy, vo.getSettlementPerson());
                 }
-                if (StrUtil.isNotBlank(settlementQueryVo.getSettlementTimeStart()) && StrUtil.isNotBlank(settlementQueryVo.getSettlementTimeEnd())) {
+                if (StrUtil.isNotBlank(vo.getSettlementTimeStart()) && StrUtil.isNotBlank(vo.getSettlementTimeEnd())) {
                     // 结算时间
-                    insPlyIncomeInvoiceSettlementLambdaQueryWrapper.between(StrUtil.isNotBlank(settlementQueryVo.getSettlementTimeStart()) && StrUtil.isNotBlank(settlementQueryVo.getSettlementTimeEnd()),
-                            InsPlyIncomeInvoiceSettlement::getCreateTime, settlementQueryVo.getSettlementTimeStart(), settlementQueryVo.getSettlementTimeEnd());
+                    insPlyIncomeInvoiceSettlementLambdaQueryWrapper.between(StrUtil.isNotBlank(vo.getSettlementTimeStart()) && StrUtil.isNotBlank(vo.getSettlementTimeEnd()),
+                            InsPlyIncomeInvoiceSettlement::getCreateTime, vo.getSettlementTimeStart(), vo.getSettlementTimeEnd());
                 }
                 List<InsPlyIncomeInvoiceSettlement> insPlyIncomeInvoiceSettlements = insPlyIncomeInvoiceSettlementMapper.selectList(insPlyIncomeInvoiceSettlementLambdaQueryWrapper);
                 // 如果结算记录不为空,且结算人、结算时间不为空,则根据结算记录的invoiceId过滤列表
                 if (CollUtil.isNotEmpty(insPlyIncomeInvoiceSettlements)) {
-                    if (StrUtil.isNotBlank(settlementQueryVo.getSettlementPerson()) || (StrUtil.isNotBlank(settlementQueryVo.getSettlementTimeStart()) && StrUtil.isNotBlank(settlementQueryVo.getSettlementTimeEnd()))) {
+                    if (StrUtil.isNotBlank(vo.getSettlementPerson()) || (StrUtil.isNotBlank(vo.getSettlementTimeStart()) && StrUtil.isNotBlank(vo.getSettlementTimeEnd()))) {
                         List<String> invoiceList = insPlyIncomeInvoiceSettlements.stream().map(InsPlyIncomeInvoiceSettlement::getInvoiceId).toList();
                         // filter:lambda 返回 true 的元素留下,false 的剔除
                         exportSuperviseSettlementDetailExcelDtos.setRecords(exportSuperviseSettlementDetailExcelDtos.getRecords().stream().filter(detail -> invoiceList.contains(detail.getInvoiceId())).toList());

+ 8 - 3
tenant/organization/src/main/java/com/jzg/organization/service/impl/SignInServiceImpl.java

@@ -78,14 +78,19 @@ public class SignInServiceImpl implements SignInService {
     @Override
     public HttpResult updateSignCompleteRuleIn(SysUserActivityCompleteInRule dto){
         log.info("修改签到规则同步状态:dto=[{}]", JSONUtil.toJsonStr(dto));
-
+        SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getId,dto.getUserId()));
+        if (sysUser == null) {
+            return HttpResult.error("用户不存在");
+        }
         SysUserActivityCompleteInRule rule = sysUserActivityCompleteInRuleMapper.selectOne(new LambdaQueryWrapper<SysUserActivityCompleteInRule>()
                 .eq(SysUserActivityCompleteInRule::getSystemCode,dto.getSystemCode())
-                .eq(SysUserActivityCompleteInRule::getUserId,dto.getUserId())
+                .eq(SysUserActivityCompleteInRule::getUserId,sysUser.getMobile())
                 .eq(SysUserActivityCompleteInRule::getActivityId,dto.getActivityId())
                 .eq(SysUserActivityCompleteInRule::getLocalActivityTableId,dto.getLocalActivityTableId())
                 .eq(SysUserActivityCompleteInRule::getStatus,YesNoEnum.NO.getCode()));
-
+        if (rule == null) {
+            return HttpResult.error("签到规则不存在");
+        }
         LotteryCounDTO lotteryCounDTO = new LotteryCounDTO();
         lotteryCounDTO.setAppUserId(dto.getLiveUserId());
         lotteryCounDTO.setActivityId(dto.getActivityId());

+ 21 - 3
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysOrganizationServiceImpl.java

@@ -125,6 +125,24 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
         BeanUtils.copyProperties(organizationUserLinkAdd, organizationUserLink);
         return sysOrganizationUserLinkService.save(organizationUserLink) ? HttpResult.ok("添加成功") : HttpResult.error("添加失败");
     }
+    /**
+     * 设置团队负责人
+     *
+     * @param setPerson 要设置的团队负责人
+     * @author lipf
+     * @date 2026/4/28 9:08
+     */
+    @Override
+    public HttpResult<String> setManagerPerson(SysOrganizationSetPerson setPerson) {
+        SysOrganization sysOrganization = sysOrganizationMapper.selectById(setPerson.getId());
+        if (ObjectUtil.isNotEmpty(sysOrganization)){
+            sysOrganization.setManagerId(setPerson.getManagerId());
+            return sysOrganizationMapper.updateById(sysOrganization) > 0 ? HttpResult.ok("设置成功") : HttpResult.error("设置失败");
+        }
+        return HttpResult.error("所选团队、渠道、电销组不存在或以删除,请刷新");
+    }
+
+
 
     /**
      * 设置团队负责人
@@ -137,7 +155,7 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
     public HttpResult<String> setResponsiblePerson(SysOrganizationSetPerson setPerson) {
         SysOrganization sysOrganization = sysOrganizationMapper.selectById(setPerson.getId());
         if (ObjectUtil.isNotEmpty(sysOrganization)){
-            sysOrganization.setManagerId(setPerson.getManagerId());
+            sysOrganization.setPrincipalId(setPerson.getManagerId());
             return sysOrganizationMapper.updateById(sysOrganization) > 0 ? HttpResult.ok("设置成功") : HttpResult.error("设置失败");
         }
         return HttpResult.error("所选团队、渠道、电销组不存在或以删除,请刷新");
@@ -206,9 +224,9 @@ public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMappe
     }
 
     @Override
-    public List<SysOrganization> queryOrganizationByManagerId(String managerId) {
+    public List<SysOrganization> queryOrganizationByPrincipalId(String principalId) {
         LambdaQueryWrapper<SysOrganization> lambdaQueryWrapper = new LambdaQueryWrapper<SysOrganization>()
-                .eq(SysOrganization::getManagerId, managerId)
+                .eq(SysOrganization::getPrincipalId, principalId)
                 .eq(SysOrganization::getIsDelete, 0);
         return sysOrganizationMapper.selectList(lambdaQueryWrapper);
     }

+ 3 - 1
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgAppServiceImpl.java

@@ -101,7 +101,9 @@ public class SysUserJzgAppServiceImpl extends ServiceImpl<SysUserJzgAppMapper, S
         }
         log.info("获取用户信息:systemCode=[{}],userName=[{}]", systemCode, userName);
         UserInfoVo infoVo = sysUserJzgAppMapper.userInfoGet(userName,systemCode);
-        infoVo.setHeadSculpture(MinioUtils.getPresignedObjectUrl("jzg", infoVo.getHeadSculpture()));
+        if(Objects.nonNull(infoVo.getHeadSculpture())) {
+            infoVo.setHeadSculpture(MinioUtils.getPresignedObjectUrl("jzg", infoVo.getHeadSculpture()));
+        }
         // 获取身份信息
         LambdaQueryWrapper<SysUserJzgInfo> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.select(SysUserJzgInfo::getTypeAttr)

+ 4 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgInfoServiceImpl.java

@@ -102,6 +102,10 @@ public class SysUserJzgInfoServiceImpl extends ServiceImpl<SysUserJzgInfoMapper,
         return baseMapper.selectOne(new LambdaQueryWrapper<SysUserJzgInfo>()
                 .eq(SysUserJzgInfo::getId, id));
     }
+    @Override
+    public SysUserJzgInfo getYWYById(String id) {
+        return sysUserJzgInfoMapper.getYWYById(id);
+    }
 
 
     @Override

+ 237 - 148
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java

@@ -110,6 +110,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Autowired
     private EsmUserReferrerService esmUserReferrerService;
 
+    @Autowired
+    private EsmUserReferrerMapper esmUserReferrerMapper;
+
     @Autowired
     private SysUserJzgInfoBankCardRecordService sysUserJzgInfoBankCardRecordService;
     @Qualifier("baseController")
@@ -188,7 +191,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     /**
      * 分页获取业务员列表
      *
-     * @param page 分页参数
+     * @param page              分页参数
      * @param sysUserInfoListVo 查询参数
      * @author lipf
      * @date 2026/4/10 10:01
@@ -196,7 +199,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public Page<SysUserJzgInfoDto> getUserInfoList(Page page, SysUserInfoListVo sysUserInfoListVo) {
         log.info("获取业务员列表:查询参数: sysUserInfoListVo=[{}]", JSONUtil.toJsonStr(sysUserInfoListVo));
-        if(Objects.nonNull(sysUserInfoListVo.getStatus()) && sysUserInfoListVo.getStatus() == 0){
+        if (Objects.nonNull(sysUserInfoListVo.getStatus()) && sysUserInfoListVo.getStatus() == 0) {
             List<Integer> typeStatus = new ArrayList<>();
             sysUserInfoListVo.setStatus(null);
             typeStatus.add(UserState.UserStateEnum.COMPANY_REVIEW_ING.getValue());
@@ -210,9 +213,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
         String loginUserId = baseController.getUserId();
         // 查询业务员
-        if("2".equals(sysUserInfoListVo.getIsMember())){
+        if ("2".equals(sysUserInfoListVo.getIsMember())) {
             String jzgInfoId = null;
-            if("10".equals(sysUserInfoListVo.getFromPage())){
+            if ("10".equals(sysUserInfoListVo.getFromPage())) {
                 long startTime = System.currentTimeMillis();
                 SysUserJzgInfo userInfoJzgInfo = sysUserJzgInfoService.getUserByUserId(loginUserId);
                 log.info("查询耗时:[{}]", System.currentTimeMillis() - startTime);
@@ -223,37 +226,37 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 //            page.setSize(Long.MAX_VALUE);
             userInfoList = sysUserJzgInfoMapper.queryYwy(page, sysUserInfoListVo, systemCode, jzgInfoId
             );
-        }else if("1".equals(sysUserInfoListVo.getIsMember())){
+        } else if ("1".equals(sysUserInfoListVo.getIsMember())) {
             // 查询成员
-            log.info("查询成员信息:sysUserInfoListVo=[{}]",JSONUtil.toJsonStr(sysUserInfoListVo)  );
+            log.info("查询成员信息:sysUserInfoListVo=[{}]", JSONUtil.toJsonStr(sysUserInfoListVo));
             userInfoList = sysUserJzgInfoMapper.queryMember(page, sysUserInfoListVo);
-        }else{
+        } else {
             // 其他场景先使用原来的逻辑
             userInfoList = sysUserJzgInfoMapper.getUserInfoList(page, sysUserInfoListVo);
         }
         List<SysUserJzgInfoDto> records = userInfoList.getRecords();
-        if(CollectionUtil.isNotEmpty(records)){
+        if (CollectionUtil.isNotEmpty(records)) {
             // 填充岗位信息
             Map<String, String> attrTypeMap = sysUserJzgInfoSalesmanService.queryAllTypeAttrMap();
             Map<String, SysOrganizationVO> stringSysOrganizationVOMap = sysOrganizationService.queryUserBindOrganization(baseController.getSystemCode());
-            records = records.stream().peek(action->{
-                if(loginUserId.equals(action.getUserId())){
+            records = records.stream().peek(action -> {
+                if (loginUserId.equals(action.getUserId())) {
                     action.setDefaultSelected(true);
                 }
-                String typeAttr = attrTypeMap.getOrDefault(action.getId(),null);
+                String typeAttr = attrTypeMap.getOrDefault(action.getId(), null);
                 // 在【业务员管理页面】 要求类型中,不展示1,2,3,4 对应的类型
-                if(StrUtil.isNotEmpty(typeAttr)){
-                    Set<String> set = Set.of("1","2","3");
-                    typeAttr = Arrays.stream(typeAttr.split(",")).filter(action1-> !set.contains(action1)).collect(Collectors.joining(","));
+                if (StrUtil.isNotEmpty(typeAttr)) {
+                    Set<String> set = Set.of("1", "2", "3");
+                    typeAttr = Arrays.stream(typeAttr.split(",")).filter(action1 -> !set.contains(action1)).collect(Collectors.joining(","));
                     action.setTypeAttr(typeAttr);
                 }
                 List<SysRole> userRole = sysUserRoleService.getUserRole(action.getUserId());
-                if(CollectionUtil.isNotEmpty(userRole)){
+                if (CollectionUtil.isNotEmpty(userRole)) {
                     String roleNames = userRole.stream().map(SysRole::getName).distinct().collect(Collectors.joining(","));
                     action.setRoleName(roleNames);
                 }
                 SysOrganizationVO sysOrganizationVO = stringSysOrganizationVOMap.get(action.getUserId());
-                if(sysOrganizationVO != null){
+                if (sysOrganizationVO != null) {
                     action.setOrganizationId(sysOrganizationVO.getOrganizationId());
                     action.setOrganizationName(sysOrganizationVO.getName());
                 }
@@ -262,7 +265,80 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             userInfoList.setRecords(records);
         }
         //Page<SysUserJzgInfoDto> userInfoList = sysUserJzgInfoMapper.getUserInfoList(page, sysUserInfoListVo);
-        log.info("获取业务员/成员列表:查询出[{}]个业务员。 查询参数: sysUserInfoListVo=[{}]", CollUtil.size(userInfoList.getRecords()),JSONUtil.toJsonStr(sysUserInfoListVo));
+        log.info("获取业务员/成员列表:查询出[{}]个业务员。 查询参数: sysUserInfoListVo=[{}]", CollUtil.size(userInfoList.getRecords()), JSONUtil.toJsonStr(sysUserInfoListVo));
+        return userInfoList;
+    }
+
+    @Override
+    public Page<SysUserJzgInfoDto> getBaojiaUserInfoList(Page page, SysUserInfoListVo sysUserInfoListVo) {
+        log.info("获取业务员列表:查询参数: sysUserInfoListVo=[{}]", JSONUtil.toJsonStr(sysUserInfoListVo));
+        if (Objects.nonNull(sysUserInfoListVo.getStatus()) && sysUserInfoListVo.getStatus() == 0) {
+            List<Integer> typeStatus = new ArrayList<>();
+            sysUserInfoListVo.setStatus(null);
+            typeStatus.add(UserState.UserStateEnum.COMPANY_REVIEW_ING.getValue());
+            typeStatus.add(UserState.UserStateEnum.RESIGN_ING.getValue());
+            typeStatus.add(UserState.UserStateEnum.NOT_CERT.getValue());
+            sysUserInfoListVo.setTypeStatus(typeStatus);
+        }
+        // 前端 查询成员和查询业务员的接口,都使用的是这个接口,但是他们区分的时候,差异很大,因此这里将查询成员和查询业务员的接口拆分开来
+        Page<SysUserJzgInfoDto> userInfoList;
+        String systemCode = baseController.getUserSystemCode();
+
+        String loginUserId = baseController.getUserId();
+        // 查询业务员
+        if ("2".equals(sysUserInfoListVo.getIsMember())) {
+            String jzgInfoId = null;
+            if ("10".equals(sysUserInfoListVo.getFromPage())) {
+                long startTime = System.currentTimeMillis();
+                SysUserJzgInfo userInfoJzgInfo = sysUserJzgInfoService.getUserByUserId(loginUserId);
+                log.info("查询耗时:[{}]", System.currentTimeMillis() - startTime);
+                jzgInfoId = userInfoJzgInfo.getId();
+            }
+            log.info("查看成员下的业务员信息:成员的序号:jzgInfoId=[{}]", jzgInfoId);
+            // modify by lipf 查询成员下业务员的时候,不进行分页
+//            page.setSize(Long.MAX_VALUE);
+            userInfoList = sysUserJzgInfoMapper.queryBJYwy(page, sysUserInfoListVo, systemCode, jzgInfoId
+            );
+        } else if ("1".equals(sysUserInfoListVo.getIsMember())) {
+            // 查询成员
+            log.info("查询成员信息:sysUserInfoListVo=[{}]", JSONUtil.toJsonStr(sysUserInfoListVo));
+            userInfoList = sysUserJzgInfoMapper.queryMember(page, sysUserInfoListVo);
+        } else {
+            // 其他场景先使用原来的逻辑
+            userInfoList = sysUserJzgInfoMapper.getUserInfoList(page, sysUserInfoListVo);
+        }
+        List<SysUserJzgInfoDto> records = userInfoList.getRecords();
+        if (CollectionUtil.isNotEmpty(records)) {
+            // 填充岗位信息
+            Map<String, String> attrTypeMap = sysUserJzgInfoSalesmanService.queryAllTypeAttrMap();
+            Map<String, SysOrganizationVO> stringSysOrganizationVOMap = sysOrganizationService.queryUserBindOrganization(baseController.getSystemCode());
+            records = records.stream().peek(action -> {
+                if (loginUserId.equals(action.getUserId())) {
+                    action.setDefaultSelected(true);
+                }
+                String typeAttr = attrTypeMap.getOrDefault(action.getId(), null);
+                // 在【业务员管理页面】 要求类型中,不展示1,2,3,4 对应的类型
+                if (StrUtil.isNotEmpty(typeAttr)) {
+                    Set<String> set = Set.of("1", "2", "3");
+                    typeAttr = Arrays.stream(typeAttr.split(",")).filter(action1 -> !set.contains(action1)).collect(Collectors.joining(","));
+                    action.setTypeAttr(typeAttr);
+                }
+                List<SysRole> userRole = sysUserRoleService.getUserRole(action.getUserId());
+                if (CollectionUtil.isNotEmpty(userRole)) {
+                    String roleNames = userRole.stream().map(SysRole::getName).distinct().collect(Collectors.joining(","));
+                    action.setRoleName(roleNames);
+                }
+                SysOrganizationVO sysOrganizationVO = stringSysOrganizationVOMap.get(action.getUserId());
+                if (sysOrganizationVO != null) {
+                    action.setOrganizationId(sysOrganizationVO.getOrganizationId());
+                    action.setOrganizationName(sysOrganizationVO.getName());
+                }
+
+            }).toList();
+            userInfoList.setRecords(records);
+        }
+        //Page<SysUserJzgInfoDto> userInfoList = sysUserJzgInfoMapper.getUserInfoList(page, sysUserInfoListVo);
+        log.info("获取业务员/成员列表:查询出[{}]个业务员。 查询参数: sysUserInfoListVo=[{}]", CollUtil.size(userInfoList.getRecords()), JSONUtil.toJsonStr(sysUserInfoListVo));
         return userInfoList;
     }
 
@@ -323,9 +399,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     public boolean salesmanAuthSuccess(String userInfoId) {
         SysUserJzgInfo userJzgInfo = sysUserJzgInfoService.getById(userInfoId);
         StateResult stateResult;
-        if(Objects.nonNull(userJzgInfo.getStatus()) && userJzgInfo.getStatus() == UserState.UserStateEnum.RESIGN_ING.getValue()){
+        if (Objects.nonNull(userJzgInfo.getStatus()) && userJzgInfo.getStatus() == UserState.UserStateEnum.RESIGN_ING.getValue()) {
             stateResult = userStateListener.resignAuthSuccess(userJzgInfo);
-        }else {
+        } else {
             stateResult = userStateListener.salesmanAuthSuccess(userJzgInfo);
         }
         if (stateResult.isResult()) {
@@ -340,9 +416,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     public boolean salesmanAuthFailed(AuditSalesmanVo auditSalesmanVo) {
         SysUserJzgInfo userJzgInfo = sysUserJzgInfoService.getById(auditSalesmanVo.getUserInfoId());
         StateResult stateResult;
-        if(Objects.nonNull(userJzgInfo.getStatus()) && userJzgInfo.getStatus() == UserState.UserStateEnum.RESIGN_ING.getValue()){
+        if (Objects.nonNull(userJzgInfo.getStatus()) && userJzgInfo.getStatus() == UserState.UserStateEnum.RESIGN_ING.getValue()) {
             stateResult = userStateListener.resignAuthFailed(userJzgInfo);
-        }else {
+        } else {
             stateResult = userStateListener.salesmanAuthFailed(userJzgInfo);
         }
 
@@ -402,7 +478,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                 item.setDefaultValue(true);
             }
         });
-        log.info("获取用户的租户列表: userName=[{}],tenantList=[{}]", userName,JSONUtil.toJsonStr(tenantList));
+        log.info("获取用户的租户列表: userName=[{}],tenantList=[{}]", userName, JSONUtil.toJsonStr(tenantList));
         return tenantList;
     }
 
@@ -486,7 +562,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                 addSalesmanList(sysUserJzgInfo, sysUserVo);
             }
             // 添加业务员到团队,渠道,电销,个代的时候 (需要确保,成员新增的时候,typeAttr为空)
-            if(StrUtil.isNotEmpty(sysUserVo.getTypeAttr())){
+            if (StrUtil.isNotEmpty(sysUserVo.getTypeAttr())) {
                 addSalesmanList(sysUserJzgInfo, sysUserVo);
             }
             sysUserJzgInfoId = sysUserJzgInfo.getId();
@@ -494,7 +570,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             if (sysUserVo.getOrganizationId() != null && !sysUserVo.getOrganizationId().equals("")) {
                 saveOrganization(sysUserVo.getOrganizationId(), sysUserJzgInfo.getUserId());
             }
-            this.updateUserBindFiles(sysUserVo.getFileList(),Long.parseLong(sysUser.getId()));
+            this.updateUserBindFiles(sysUserVo.getFileList(), Long.parseLong(sysUser.getId()));
             //saveFile(sysUserVo.getSfz1(), sysUserVo.getSfz2(), sysUserVo.getQualification(), sysUserVo.getContract(), sysUserVo.getApplicant(), sysUserVo.getSalaryTable(), sysUserVo.getLeaveTable(), sysUserJzgInfo.getUserId());
             //系统中已存在业务员
 //            throw new SystemException("用户信息已存在,无法添加");
@@ -525,7 +601,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             if (sysUserVo.getOrganizationId() != null && !sysUserVo.getOrganizationId().equals("")) {
                 saveOrganization(sysUserVo.getOrganizationId(), sysUserJzgInfo.getUserId());
             }
-            this.updateUserBindFiles(sysUserVo.getFileList(),Long.parseLong(sysUserId));
+            this.updateUserBindFiles(sysUserVo.getFileList(), Long.parseLong(sysUserId));
             //saveFile(sysUserVo.getSfz1(), sysUserVo.getSfz2(), sysUserVo.getQualification(), sysUserVo.getContract(), sysUserVo.getApplicant(), sysUserVo.getSalaryTable(), sysUserVo.getLeaveTable(), sysUserJzgInfo.getId());
         }
 
@@ -535,7 +611,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                     new SysUserJzgInfoBankCard(sysUserId, sysUserVo.getBankCardId(), sysUserVo.getBankName(), sysUserJzgInfo.getSystemCode());
             sysUserJzgInfoBankCardService.save(sysUserJzgInfoBankCard);
             SysUserJzgInfoBankCardRecord sysUserJzgInfoBankCardRecord =
-                    new SysUserJzgInfoBankCardRecord(sysUserJzgInfoBankCard.getId(),"提交新卡");
+                    new SysUserJzgInfoBankCardRecord(sysUserJzgInfoBankCard.getId(), "提交新卡");
             sysUserJzgInfoBankCardRecord.setStatus("0");
             sysUserJzgInfoBankCardRecordService.save(sysUserJzgInfoBankCardRecord);
         }
@@ -612,7 +688,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     @Transactional(rollbackFor = Exception.class)
     public HttpResult<Boolean> deleteUserInfo(IsDeleteVo isDeleteVo) {
-        log.info("删除业务员信息isDeleteVo=[{}]",JSONUtil.toJsonStr(isDeleteVo));
+        log.info("删除业务员信息isDeleteVo=[{}]", JSONUtil.toJsonStr(isDeleteVo));
         for (String id : isDeleteVo.getIds()) {
             SysUserJzgInfo sysUserJzgInfo = sysUserJzgInfoService.getById(id);
             if (sysUserJzgInfo == null) {
@@ -623,6 +699,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         return HttpResult.ok("删除成功");
     }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean deleteDistribution(IsDeleteVo isDeleteVo) {
@@ -644,7 +721,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             }
             // 解除上下级关系
             if (isDeleteVo.getType().equals("2")) {
-                if (!esmUserReferrerList.isEmpty() ) {
+                if (!esmUserReferrerList.isEmpty()) {
                     esmUserReferrerService.removeBatchByIds(esmUserReferrerList); // 解除分销关系
                 }
                 if (!sysUserJzgInfoListDown.isEmpty()) {
@@ -741,8 +818,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     /**
      * 递归查询下三级(每级下级可多个)
-     * @param currentVo 当前节点VO
-     * @param systemCode 系统编码
+     *
+     * @param currentVo      当前节点VO
+     * @param systemCode     系统编码
      * @param remainingLevel 剩余查询层级(最多3级)
      */
     private void queryLowerLevels(DistributionRelationVo currentVo, String systemCode, int remainingLevel) {
@@ -824,7 +902,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             sysUserJzgInfoService.updateBatchById(sysUserJzgInfoList);
         } else {
             List<String> ids = isEnableVo.getIds();
-            if(CollectionUtil.isEmpty(ids)) {
+            if (CollectionUtil.isEmpty(ids)) {
                 log.info("勾选的用户信息为空");
                 res.setData(Boolean.FALSE);
                 res.setMsg("请勾选要操作的数据");
@@ -974,7 +1052,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             throw new SystemException("该业务员不存在");
         }
         BeanUtils.copyProperties(sysUserVo, sysUserJzgInfo);
-        this.updateUserBindFiles(sysUserVo.getFileList(),Long.parseLong(sysUserJzgInfo.getUserId()));
+        this.updateUserBindFiles(sysUserVo.getFileList(), Long.parseLong(sysUserJzgInfo.getUserId()));
         // verifyFile(sysUserVo, sysUserJzgInfo.getId());
         if (sysUserJzgInfo.getStatus() == 5) { // 如果状态为5  说明该业务员重新提交审核  进行业务员审核
             StateResult stateResult = userStateListener.salesmanAuthIng(sysUserJzgInfo);
@@ -986,18 +1064,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         // modify by lipf, 解决身份证信息没有更新的问题
         SysUser originSysUser = sysUserService.getById(sysUserVo.getUserId());
-        if(originSysUser != null){
-            log.info("更新身份证等信息。原信息originSysUser=[{}]",JSONUtil.toJsonStr(originSysUser));
+        if (originSysUser != null) {
+            log.info("更新身份证等信息。原信息originSysUser=[{}]", JSONUtil.toJsonStr(originSysUser));
             originSysUser.setIdentity(sysUserVo.getIdentity());
-            if(StrUtil.isEmpty(sysUserVo.getIdentityTimeStart())){
+            if (StrUtil.isEmpty(sysUserVo.getIdentityTimeStart())) {
                 originSysUser.setIdentityTimeStart(null);
-            }else{
+            } else {
                 originSysUser.setIdentityTimeStart(LocalDate.parse(sysUserVo.getIdentityTimeStart(), DateTimeFormatter.ISO_DATE));
             }
 
-            if(StrUtil.isEmpty(sysUserVo.getIdentityTimeEnd())){
+            if (StrUtil.isEmpty(sysUserVo.getIdentityTimeEnd())) {
                 originSysUser.setIdentityTimeEnd(null);
-            }else{
+            } else {
                 originSysUser.setIdentityTimeEnd(LocalDate.parse(sysUserVo.getIdentityTimeEnd(), DateTimeFormatter.ISO_DATE));
             }
             if (StrUtil.isNotBlank(sysUserVo.getMobile())) {
@@ -1031,8 +1109,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
 
         //修改团队类型
-        sysOrganizationUserLinkService.getOrganizationUser(Long.parseLong(originSysUser.getId()),baseController.getSystemCode());
-        if (sysUserVo.getTypeAttr() != null && !sysUserVo.getTypeAttr().equals("")){
+        sysOrganizationUserLinkService.getOrganizationUser(Long.parseLong(originSysUser.getId()), baseController.getSystemCode());
+        if (sysUserVo.getTypeAttr() != null && !sysUserVo.getTypeAttr().equals("")) {
             List<SysUserJzgInfoSalesman> typeAttrByUserId = sysUserJzgInfoSalesmanService.getTypeAttrByUserId(sysUserJzgInfo.getId());
             // 个代 团队 电销 渠道 只能存在一条
             List<SysUserJzgInfoSalesman> list = typeAttrByUserId.stream().filter(x -> x.getTypeAttr().equals("5") || x.getTypeAttr().equals("6") || x.getTypeAttr().equals("7") || x.getTypeAttr().equals("8")).toList();
@@ -1046,8 +1124,19 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             sysUserJzgInfoSalesmanService.save(salesman);
         }
 
+        // 修改推荐关系 先删除再添加
+        EsmUserReferrer esmUserReferrer = esmUserReferrerService.getOne(new LambdaQueryWrapper<EsmUserReferrer>()
+                .eq(EsmUserReferrer::getId, sysUserVo.getId())
+                .eq(EsmUserReferrer::getIsDelete, 0));
+        if (esmUserReferrer != null) {
+            esmUserReferrerMapper.deleteByIdCheck(esmUserReferrer.getId());
+            SysUserJzgInfo sysUserJzgInfoReferrer = sysUserJzgInfoService.getById(sysUserVo.getReferrerId());
+            EsmUserReferrer referrer = new EsmUserReferrer(sysUserJzgInfo, sysUserJzgInfoReferrer);
+            esmUserReferrerService.save(referrer);
+        }
+
         boolean isPartner = sysUserJzgInfoService.isPartnerPresent(sysUserJzgInfo.getId());
-        if (isPartner){
+        if (isPartner) {
             sysUserJzgInfoService.updatePartnerByUserId(sysUserJzgInfo);
         }
         return HttpResult.ok("修改业务员成功");
@@ -1055,7 +1144,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     /**
      * 获取业务员详细信息接口
-     *      包括相关的附件,合同,身份证图片等
+     * 包括相关的附件,合同,身份证图片等
      *
      * @author lipf
      * @date 2026/4/22 15:37
@@ -1063,7 +1152,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public HttpResult<SysUserJzgInfo> getUserInfoByUserId(String id) {
         SysUserJzgInfo sysUserJzgInfo = sysUserJzgInfoService.getByUserIdOrId(id);
-        log.info("根据id=[{}]查询用户信息sysUserJzgInfo=[{}]",id, JSONUtil.toJsonStr(sysUserJzgInfo));
+        log.info("根据id=[{}]查询用户信息sysUserJzgInfo=[{}]", id, JSONUtil.toJsonStr(sysUserJzgInfo));
         if (sysUserJzgInfo == null) {
             throw new SystemException("该用户不存在");
         }
@@ -1077,10 +1166,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
         sysUserJzgInfo.setMobile(sysUser.getMobile());
         sysUserJzgInfo.setIdentity(sysUser.getIdentity());
-        if(Objects.nonNull(sysUser.getIdentityTimeStart())) {
+        if (Objects.nonNull(sysUser.getIdentityTimeStart())) {
             sysUserJzgInfo.setIdentityTimeStart(sysUser.getIdentityTimeStart().format(formatter));
         }
-        if(Objects.nonNull(sysUser.getIdentityTimeEnd())) {
+        if (Objects.nonNull(sysUser.getIdentityTimeEnd())) {
             sysUserJzgInfo.setIdentityTimeEnd(sysUser.getIdentityTimeEnd().format(formatter));
         }
         SysDept dept = sysDeptService.getById(sysUserJzgInfo.getDeptId());
@@ -1110,7 +1199,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         String systemCode = baseController.getSystemCode();
         Long userId = Long.parseLong(sysUserJzgInfo.getUserId());
-        SysOrganizationUserLink sysOrganizationUserLink = sysOrganizationUserLinkService.getOrganizationUser(userId,systemCode);
+        SysOrganizationUserLink sysOrganizationUserLink = sysOrganizationUserLinkService.getOrganizationUser(userId, systemCode);
 
         if (!Objects.isNull(sysOrganizationUserLink)) {
             String organizationId = sysOrganizationUserLink.getOrganizationId();
@@ -1178,7 +1267,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                         .eq(SysUserJzgInfo::getIsDelete, 0));
         SysUserJzgInfo userByMobile = sysUserJzgInfoService.getUserByMobile(mobile);
         if (!sysUserJzgInfos.isEmpty()) {
-            log.warn("特定租户下身份证[{}]已存在",identity);
+            log.warn("特定租户下身份证[{}]已存在", identity);
             throw new SystemException("该身份证号已存在,请检查");
         }
         if (sysDept == null) {
@@ -1211,24 +1300,24 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @author lipf
      * @date 2026/4/22 15:06
      */
-    public void updateUserBindFiles(List<SysUserJzgInfoFile> fileList, Long userId){
+    public void updateUserBindFiles(List<SysUserJzgInfoFile> fileList, Long userId) {
         log.info("保存员工的身份证图片等信息:userId=[{}], fileList=[{}]", userId, JSONUtil.toJsonStr(fileList));
         List<SysUserJzgInfoFile> existedFiles = sysUserJzgInfoFileService.queryJzgInfoFilesByUserId(userId);
-        if(CollUtil.isNotEmpty(existedFiles)){
+        if (CollUtil.isNotEmpty(existedFiles)) {
             sysUserJzgInfoFileService.removeByIds(existedFiles.stream().map(SysUserJzgInfoFile::getId).toList());
         }
-        if(CollUtil.isNotEmpty(fileList)){
-            fileList = fileList.stream().peek(action->{
+        if (CollUtil.isNotEmpty(fileList)) {
+            fileList = fileList.stream().peek(action -> {
                 String fileId = action.getFileId();
                 SysUploadFiles sysUploadFiles = sysUploadFilesMapper.selectById(fileId);
-                if(sysUploadFiles != null){
+                if (sysUploadFiles != null) {
                     action.setFileUrl(sysUploadFiles.getDownloadUrl());
                     action.setUserId(String.valueOf(userId));
                     //action.setFileType(sysUploadFiles.getFileType());
                     action.setFileName(sysUploadFiles.getFileName());
                     action.setFileUrl(MinioUtils.getPresignedObjectUrl("jzg", sysUploadFiles.getFileName()));
-                }else{
-                    log.error("文件序号为[{}]的文件不存在",fileId);
+                } else {
+                    log.error("文件序号为[{}]的文件不存在", fileId);
                 }
             }).toList();
             sysUserJzgInfoFileService.saveBatch(fileList);
@@ -1353,19 +1442,19 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public SalesmanVo getUserInfoBySystemCodeAndUserId(String userId) {
         SalesmanVo salesmanVo = sysUserJzgInfoMapper.getUserInfoBySystemCodeAndUserId(userId);
-        if(Objects.nonNull(salesmanVo)){
+        if (Objects.nonNull(salesmanVo)) {
             String leaderId = salesmanVo.getLeaderId();
-            if(StrUtil.isEmpty(leaderId)){
+            if (StrUtil.isEmpty(leaderId)) {
                 return salesmanVo;
             }
             SysUserJzgInfo sysUserJzgInfo = sysUserJzgInfoMapper.selectById(leaderId);
-            if(sysUserJzgInfo == null){
+            if (sysUserJzgInfo == null) {
                 return salesmanVo;
             }
             String leaderUserId = sysUserJzgInfo.getUserId();
             salesmanVo.setRealQuoteUserManagerId(leaderUserId);
             SysUser sysUser = sysUserMapper.selectById(leaderUserId);
-            if(sysUser != null){
+            if (sysUser != null) {
                 salesmanVo.setRealQuoteUserManagerUseName(sysUser.getUsername());
             }
         }
@@ -1374,7 +1463,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     @Override
     public void setTenantList(String systemCode, String userId) {
-       redissonClient.getBucket(RedisKeyConstants.APP_SYSTEM_CODE + userId).set(systemCode);
+        redissonClient.getBucket(RedisKeyConstants.APP_SYSTEM_CODE + userId).set(systemCode);
     }
 
     @Override
@@ -1386,6 +1475,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         SysUserJzgInfo sysUserJzgInfo = sysUserJzgInfoService.getUserById(sysUser.getId());
         return sysUserJzgInfo.getLeaderId();
     }
+
     @Override
     public SysUserJzgInfo getUserInfoByMobile(String mobile) {
         SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getMobile, mobile));
@@ -1398,17 +1488,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public HttpResult saveByPartner(SysUserVo sysUserVo) {
         try {
-            if (CollectionUtil.isEmpty(sysUserVo.getGradeList()) && Objects.isNull(sysUserVo.getGrade())){
+            if (CollectionUtil.isEmpty(sysUserVo.getGradeList()) && Objects.isNull(sysUserVo.getGrade())) {
                 return HttpResult.error("请选择合伙人等级");
             }
             addPartnerTransactional(sysUserVo);
             //  保存合伙人用户数据
             HttpResult httpResult = partnerDistributionClient.addPartnerRule(sysUserVo);
-            if (200 == httpResult.getCode()){
+            if (200 == httpResult.getCode()) {
                 return HttpResult.ok("保存成功");
             }
             return HttpResult.error("保存失败");
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
             log.error("保存合伙人数据异常:{}" + e.getMessage());
             return HttpResult.error("保存失败");
@@ -1416,7 +1506,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     }
 
 
-
     @Transactional(rollbackFor = Exception.class)
     public void addPartnerTransactional(SysUserVo sysUserVo) {
         addPartner(sysUserVo);
@@ -1429,7 +1518,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             sysUserVo.setCodeInvitation(true);
             addPartnerTransactional(sysUserVo);
             return partnerDistributionClient.addPartnerRule(sysUserVo);
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
             log.error("保存合伙人数据异常:{}" + e.getMessage());
             throw new RuntimeException("保存合伙人数据异常");
@@ -1440,11 +1529,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     public HttpResult selectByMobile(String mobile) {
         SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<>(SysUser.class)
                 .eq(SysUser::getMobile, mobile));
-        if (Objects.nonNull(sysUser)){
+        if (Objects.nonNull(sysUser)) {
             SysUserVo sysUserVo = new SysUserVo();
             BeanUtils.copyProperties(sysUser, sysUserVo);
             SysUserJzgInfo userByUserId = sysUserJzgInfoService.getUserByUserId(sysUser.getId());
-            if (Objects.nonNull(userByUserId)){
+            if (Objects.nonNull(userByUserId)) {
                 BeanUtils.copyProperties(userByUserId, sysUserVo);
             }
             return HttpResult.ok(sysUserVo);
@@ -1454,7 +1543,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     @Override
     public HttpResult selectByUserNameAndMobile(String grade) {
-        if (StringUtils.isEmpty(grade)){
+        if (StringUtils.isEmpty(grade)) {
             return HttpResult.error("查询条件不能为空");
         }
         return HttpResult.ok(sysUserJzgInfoService.selectByUserNameAndMobile(grade));
@@ -1466,10 +1555,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     }
 
     @Override
-    public boolean partnerReview(List<String> userInfoId, String reviewStatus,String userId) {
-        int row = sysUserJzgInfoService.partnerReview(userInfoId,reviewStatus, userId);
+    public boolean partnerReview(List<String> userInfoId, String reviewStatus, String userId) {
+        int row = sysUserJzgInfoService.partnerReview(userInfoId, reviewStatus, userId);
         boolean b = row > 0;
-        if (b){
+        if (b) {
             CompletableFuture.runAsync(() -> {
                 try {
                     partnerDistributionClient.commissionInitialization(userInfoId);
@@ -1488,66 +1577,66 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
      * @date 2026/4/15 10:59
      */
     @Override
-    public HttpResult partnerAddsSalesperson(String userId,String token) {
+    public HttpResult partnerAddsSalesperson(String userId, String token) {
         log.info("将合伙人添加为业务员。 合伙人的userId=[{}], token=[{}]", userId, token);
-       try {
-           SysUserJzgInfo userByUserId = sysUserJzgInfoMapper.selectByUserIdInfo(userId);
-           if (Objects.isNull(userByUserId)){
-               return HttpResult.error("用户不存在");
-           }
-           boolean isGeneration = sysUserJzgInfoService.isGeneration(userByUserId.getId());
-           if (isGeneration){
-               return HttpResult.error("业务员已存在");
-           }
-           PartnerUserVo partnerUserVo = partnerDistributionClient.searchUserStudios(userByUserId.getId());
-           if (Objects.isNull(partnerUserVo)){
-               return HttpResult.error("当前合伙人身份不允许添加业务员");
-           }
-           SysOrganizationAdd organizationAdd = new SysOrganizationAdd();
-           organizationAdd.setName(userByUserId.getName() + "团队");
-           organizationAdd.setDeptId(userByUserId.getDeptId());
-           organizationAdd.setManagerId(userByUserId.getUserId());
-           organizationAdd.setDescribeInformation("合伙人业务团队");
-           organizationAdd.setAttribute(1);
-           boolean nameExists = sysOrganizationService.nameExists(organizationAdd);
-           if (nameExists){
-               return HttpResult.error("团队、渠道、电销组名称已存在");
-           }
-           SysOrganization sysOrganization = new SysOrganization();
-           BeanUtils.copyProperties(organizationAdd, sysOrganization);
-           sysOrganization.setId(IdGenerate.nextId());
-           sysOrganizationService.save(sysOrganization);
-
-           // 添加业务员
-           SysUserJzgInfoSalesman sysUserJzgInfoSalesman1 = new SysUserJzgInfoSalesman();
-           sysUserJzgInfoSalesman1.setSysUserJzgInfoId(userByUserId.getId());
-           sysUserJzgInfoSalesman1.setTypeAttr("6");
-           sysUserJzgInfoSalesmanService.save(sysUserJzgInfoSalesman1);
-           // 添加团队关联用户
-           saveOrganization(sysOrganization.getId(), userByUserId.getUserId());
-
-           partnerUserVo.setGrade(partnerUserVo.getGrade() + 1);
-           partnerUserVo.setReferrerId(partnerUserVo.getUserId());
-           partnerUserVo.setId(null);
-           partnerUserVo.setStatus(true);
-           HttpResult result = partnerDistributionClient.add(partnerUserVo);
-           if (200 != result.getCode()){
-               throw new SystemException(result.getMsg());
-           }
-           // 关联用户角色
-           saveRole(userByUserId);
+        try {
+            SysUserJzgInfo userByUserId = sysUserJzgInfoMapper.selectByUserIdInfo(userId);
+            if (Objects.isNull(userByUserId)) {
+                return HttpResult.error("用户不存在");
+            }
+            boolean isGeneration = sysUserJzgInfoService.isGeneration(userByUserId.getId());
+            if (isGeneration) {
+                return HttpResult.error("业务员已存在");
+            }
+            PartnerUserVo partnerUserVo = partnerDistributionClient.searchUserStudios(userByUserId.getId());
+            if (Objects.isNull(partnerUserVo)) {
+                return HttpResult.error("当前合伙人身份不允许添加业务员");
+            }
+            SysOrganizationAdd organizationAdd = new SysOrganizationAdd();
+            organizationAdd.setName(userByUserId.getName() + "团队");
+            organizationAdd.setDeptId(userByUserId.getDeptId());
+            organizationAdd.setManagerId(userByUserId.getUserId());
+            organizationAdd.setDescribeInformation("合伙人业务团队");
+            organizationAdd.setAttribute(1);
+            boolean nameExists = sysOrganizationService.nameExists(organizationAdd);
+            if (nameExists) {
+                return HttpResult.error("团队、渠道、电销组名称已存在");
+            }
+            SysOrganization sysOrganization = new SysOrganization();
+            BeanUtils.copyProperties(organizationAdd, sysOrganization);
+            sysOrganization.setId(IdGenerate.nextId());
+            sysOrganizationService.save(sysOrganization);
+
+            // 添加业务员
+            SysUserJzgInfoSalesman sysUserJzgInfoSalesman1 = new SysUserJzgInfoSalesman();
+            sysUserJzgInfoSalesman1.setSysUserJzgInfoId(userByUserId.getId());
+            sysUserJzgInfoSalesman1.setTypeAttr("6");
+            sysUserJzgInfoSalesmanService.save(sysUserJzgInfoSalesman1);
+            // 添加团队关联用户
+            saveOrganization(sysOrganization.getId(), userByUserId.getUserId());
+
+            partnerUserVo.setGrade(partnerUserVo.getGrade() + 1);
+            partnerUserVo.setReferrerId(partnerUserVo.getUserId());
+            partnerUserVo.setId(null);
+            partnerUserVo.setStatus(true);
+            HttpResult result = partnerDistributionClient.add(partnerUserVo);
+            if (200 != result.getCode()) {
+                throw new SystemException(result.getMsg());
+            }
+            // 关联用户角色
+            saveRole(userByUserId);
             // 合伙人添加业务员    app内也要新增一条数据
-           saveUserApp(userByUserId, userByUserId.getSystemCode());
-           return HttpResult.ok("添加业务员成功");
-       }catch (Exception e){
-           log.error("添加业务员异常",e);
-           throw new RuntimeException("添加业务员失败:", e);
-       }
+            saveUserApp(userByUserId, userByUserId.getSystemCode());
+            return HttpResult.ok("添加业务员成功");
+        } catch (Exception e) {
+            log.error("添加业务员异常", e);
+            throw new RuntimeException("添加业务员失败:", e);
+        }
     }
 
     private void saveUserApp(SysUserJzgInfo userByUserId, String systemCode) {
         boolean exists = sysUserJzgAppMapper.exists(new LambdaQueryWrapper<>(SysUserJzgApp.class).eq(SysUserJzgApp::getUserId, userByUserId.getUserId()));
-        if (!exists){
+        if (!exists) {
             SysUserJzgApp sysUserJzgApp = BeanUtil.copyProperties(userByUserId, SysUserJzgApp.class);
             sysUserJzgApp.setId(IdGenerate.nextId());
             sysUserJzgApp.setSystemCode(systemCode);
@@ -1582,13 +1671,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         return baseMapper.selectById(userId);
     }
 
-    public void addPartner(SysUserVo sysUserVo){
+    public void addPartner(SysUserVo sysUserVo) {
         String referrerId = sysUserVo.getReferrerId();
-        if (StringUtils.isEmpty(referrerId)){
+        if (StringUtils.isEmpty(referrerId) && !sysUserVo.getGradeList().contains("1")) {
             throw new SystemException("推荐人不能为空");
         }
         SysUser sysUser = baseMapper.getUserByMobile(sysUserVo.getMobile());
-        if (sysUserVo.isCodeInvitation()){
+        if (sysUserVo.isCodeInvitation()) {
             SysUserJzgInfo userJzgInfo = sysUserJzgInfoMapper.selectByUserIdInfo(sysUserVo.getReferrerId());
             sysUserVo.setReferrerId(userJzgInfo.getId());
             sysUserVo.setDeptId(userJzgInfo.getDeptId());
@@ -1597,7 +1686,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         SysUserJzgInfo sysUserJzgInfo = new SysUserJzgInfo();
         String sysUserId;
-        if (Objects.isNull(sysUser)){
+        if (Objects.isNull(sysUser)) {
             // 如果手机号为新号 重新生成SysUser 设置默认密码
             SysUser sysUser1 = new SysUser(sysUserVo.getMobile(), sysUserVo.getMobile(), sysUserVo.getIdentity(), sysUserVo.getIdentityTimeStart(), sysUserVo.getIdentityTimeEnd(), sysUserVo.getPassword());
             this.save(sysUser1);
@@ -1607,7 +1696,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             sysUserId = sysUser1.getId();
             sysUserJzgInfo.setStatus(UserState.UserStateEnum.ALREADY_EMPLOYEE.getValue());
             sysUserJzgInfoService.save(sysUserJzgInfo);
-            this.updateUserBindFiles(sysUserVo.getFileList(),Long.parseLong(sysUser1.getId()));
+            this.updateUserBindFiles(sysUserVo.getFileList(), Long.parseLong(sysUser1.getId()));
             //saveFile(sysUserVo.getSfz1(), sysUserVo.getSfz2(), sysUserVo.getQualification(), sysUserVo.getContract(), sysUserVo.getApplicant(), sysUserVo.getSalaryTable(), sysUserVo.getLeaveTable(), sysUserJzgInfo.getId());
             //如果表单输入的银行卡号和银行名不为空,则保存银行卡信息
             if (sysUserVo.getBankCardId() != null && sysUserVo.getBankName() != null) {
@@ -1615,14 +1704,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                         new SysUserJzgInfoBankCard(sysUserId, sysUserVo.getBankCardId(), sysUserVo.getBankName(), sysUserJzgInfo.getSystemCode());
                 sysUserJzgInfoBankCardService.save(sysUserJzgInfoBankCard);
                 SysUserJzgInfoBankCardRecord sysUserJzgInfoBankCardRecord =
-                        new SysUserJzgInfoBankCardRecord(sysUserJzgInfoBankCard.getId(),"提交新卡");
+                        new SysUserJzgInfoBankCardRecord(sysUserJzgInfoBankCard.getId(), "提交新卡");
                 sysUserJzgInfoBankCardRecord.setStatus("0");
                 sysUserJzgInfoBankCardRecordService.save(sysUserJzgInfoBankCardRecord);
             }
             sysUserVo.setUserId(sysUserJzgInfo.getId());
-        }else {
+        } else {
             sysUserJzgInfo = sysUserJzgInfoService.getUserByUserId(sysUser.getId());
-            if (Objects.isNull(sysUserJzgInfo)){
+            if (Objects.isNull(sysUserJzgInfo)) {
                 sysUserJzgInfo = new SysUserJzgInfo();
                 BeanUtils.copyProperties(sysUserVo, sysUserJzgInfo);
                 sysUserJzgInfo.setUserId(sysUser.getId());
@@ -1631,11 +1720,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             }
             sysUserVo.setUserId(sysUserJzgInfo.getId());
         }
-        if (sysUserVo.getGrade() > 3){
+        if (sysUserVo.getGrade() != null && sysUserVo.getGrade() > 3) {
             saveUserApp(sysUserJzgInfo, baseController.getSystemCode());
         }
-        partnerAddsSalespersonIdentity(sysUserJzgInfo.getId(),"3");
-        if ((!Objects.isNull(sysUserVo.getGrade()) && 4 == sysUserVo.getGrade())){
+        partnerAddsSalespersonIdentity(sysUserJzgInfo.getId(), "3");
+        if ((!Objects.isNull(sysUserVo.getGrade()) && 4 == sysUserVo.getGrade())) {
             SysOrganizationAdd organizationAdd = new SysOrganizationAdd();
             organizationAdd.setName(sysUserVo.getName() + "团队");
             organizationAdd.setDeptId(sysUserJzgInfo.getDeptId());
@@ -1643,7 +1732,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             organizationAdd.setDescribeInformation("合伙人业务团队");
             organizationAdd.setAttribute(1);
             boolean nameExists = sysOrganizationService.nameExists(organizationAdd);
-            if (nameExists){
+            if (nameExists) {
                 throw new SystemException("团队、渠道、电销组名称已存在");
             }
             SysOrganization sysOrganization = new SysOrganization();
@@ -1651,17 +1740,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             sysOrganization.setId(IdGenerate.nextId());
             sysOrganizationService.save(sysOrganization);
             // 添加业务员
-            partnerAddsSalespersonIdentity(sysUserJzgInfo.getId(),"6");
+            partnerAddsSalespersonIdentity(sysUserJzgInfo.getId(), "6");
             // 添加团队关联用户
-            saveOrganization(sysOrganization.getId(),sysUserJzgInfo.getUserId());
+            saveOrganization(sysOrganization.getId(), sysUserJzgInfo.getUserId());
         }
-        if (!Objects.isNull(sysUserVo.getGrade()) && 4 < sysUserVo.getGrade()){
-            partnerAddsSalespersonIdentity(sysUserJzgInfo.getId(),"6");
+        if (!Objects.isNull(sysUserVo.getGrade()) && 4 < sysUserVo.getGrade()) {
+            partnerAddsSalespersonIdentity(sysUserJzgInfo.getId(), "6");
             SysOrganizationUserLink userLink = sysOrganizationUserLinkService.getOne(new LambdaQueryWrapper<>(SysOrganizationUserLink.class).eq(SysOrganizationUserLink::getUserId, referrerId));
             // 添加团队关联用户
-            saveOrganization(userLink.getOrganizationId(),sysUserJzgInfo.getUserId());
+            saveOrganization(userLink.getOrganizationId(), sysUserJzgInfo.getUserId());
         }
-        if(!Objects.isNull(sysUserVo.getGrade()) && 3 < sysUserVo.getGrade()){
+        if (!Objects.isNull(sysUserVo.getGrade()) && 3 < sysUserVo.getGrade()) {
             // 关联用户角色
             saveRole(sysUserJzgInfo);
         }
@@ -1670,7 +1759,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     private void saveRole(SysUserJzgInfo sysUserJzgInfo) {
         SysRole sysRole = roleMapper.selectOne(new LambdaQueryWrapper<>(SysRole.class).eq(SysRole::getName, "业务员").last("LIMIT 1"));
-        if (!Objects.isNull(sysRole)){
+        if (!Objects.isNull(sysRole)) {
             SysUserRole userRole = new SysUserRole();
             userRole.setUserId(sysUserJzgInfo.getUserId());
             userRole.setRoleId(sysRole.getId());
@@ -1678,10 +1767,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
     }
 
-    public void partnerAddsSalespersonIdentity(String infoId,String type){
-        boolean exists = sysUserJzgInfoSalesmanService.exists(new LambdaQueryWrapper<>(SysUserJzgInfoSalesman.class).eq(SysUserJzgInfoSalesman::getSysUserJzgInfoId,infoId)
+    public void partnerAddsSalespersonIdentity(String infoId, String type) {
+        boolean exists = sysUserJzgInfoSalesmanService.exists(new LambdaQueryWrapper<>(SysUserJzgInfoSalesman.class).eq(SysUserJzgInfoSalesman::getSysUserJzgInfoId, infoId)
                 .eq(SysUserJzgInfoSalesman::getTypeAttr, type));
-        if (!exists){
+        if (!exists) {
             //   添加合伙人身份
             SysUserJzgInfoSalesman sysUserJzgInfoSalesman = new SysUserJzgInfoSalesman(infoId, type);
             sysUserJzgInfoSalesman.setPartnerStatus(1);
@@ -1699,13 +1788,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public SysUser querySysUserByUserName(String userName) {
         return baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-                .eq(SysUser::getUsername,userName));
+                .eq(SysUser::getUsername, userName));
     }
 
     @Override
     public SysUser querySysUserByMobile(String mobile) {
         return baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-                .eq(SysUser::getMobile,mobile));
+                .eq(SysUser::getMobile, mobile));
     }
 
 }

+ 4 - 2
tenant/organization/src/main/resources/application.yml

@@ -99,11 +99,12 @@ tenant:
     - ptl_agreement_dispatch_action
     - ptl_new_car_judge_rules
     - ptl_new_car_judge_rules
+    - sys_user_activity_complete_in_rule
     - t
 
   ignoreLoginNames:
   ignoreFunction:
-
+# 过滤部门数据权限(下面的方法名是Mapper中的方法名)
 data-scope:
   tables:
     - sys_user_jzg_info
@@ -116,7 +117,8 @@ data-scope:
     - getTeamUserPage
     - getOrganizationUser
     - deleteOrganizationUser
-    - getBaojiaUserInfoList
+    - queryBJYwy
+    - getYWYById
 
 
 

+ 102 - 61
tenant/organization/src/main/resources/mapper/ReceivableMapper.xml

@@ -356,12 +356,33 @@
     <select id="getReceivablePage" resultType="com.jzg.commons.entity.finance.po.InsPlyIncome">
         <include refid="query"/>
         and ipi.system_code = #{receivableQueryVo.systemCode}
+        <if test="receivableQueryVo.policyholder != null and receivableQueryVo.policyholder != ''">
+            and  iocui.name = #{receivableQueryVo.policyholder}
+        </if>
+        <if test="receivableQueryVo.insurName != null and receivableQueryVo.insurName != ''">
+            and iocui2.name = #{receivableQueryVo.insurName}
+        </if>
+        <if test="receivableQueryVo.jqPolicyNo != null and receivableQueryVo.jqPolicyNo != '' ">
+            and iop.jq_policy_no  = #{receivableQueryVo.jqPolicyNo}
+        </if>
+        <if test="receivableQueryVo.syPolicyNo != null and receivableQueryVo.syPolicyNo != '' ">
+            and iop.sy_policy_no = #{receivableQueryVo.syPolicyNo}
+        </if>
+        <if test="receivableQueryVo.jyPolicyNo != null and receivableQueryVo.jyPolicyNo != '' ">
+            and iop.jy_policy_no = #{receivableQueryVo.jyPolicyNo}
+        </if>
+        <if test="receivableQueryVo.agreementId != null and receivableQueryVo.agreementId != ''">
+            and ipi.agreement_id = #{receivableQueryVo.agreementId}
+        </if>
         <if test="receivableQueryVo.payTimeBegin != null and receivableQueryVo.payTimeEnd != null">
             and io.pay_time between #{receivableQueryVo.payTimeBegin} and #{receivableQueryVo.payTimeEnd}
         </if>
         <if test="receivableQueryVo.reportTimeBegin != null and receivableQueryVo.reportTimeEnd != null">
             and io.create_time between #{receivableQueryVo.reportTimeBegin} and #{receivableQueryVo.reportTimeEnd}
         </if>
+        <if test="receivableQueryVo.quotationTimeBegin != null and receivableQueryVo.quotationTimeEnd != null">
+            and io.create_time between #{receivableQueryVo.quotationTimeBegin} and #{receivableQueryVo.quotationTimeEnd}
+        </if>
         <if test="receivableQueryVo.updateBy != null and receivableQueryVo.updateBy !='' ">
             and ipi.update_by = #{receivableQueryVo.updateBy}
         </if>
@@ -382,6 +403,9 @@
             left join sys_user su on su.id = suji.user_id and su.is_delete = 0
             where sujis.type_attr =#{receivableQueryVo.typeAttr})
         </if>
+        <if test="receivableQueryVo.salemanPhone != null and receivableQueryVo.salemanPhone != ''">
+            and io.real_quote_user_id = #{receivableQueryVo.salemanPhone}
+        </if>
         <if test="receivableQueryVo.invoiceSettlementStatus != null and receivableQueryVo.invoiceSettlementStatus != ''">
             <!-- 当状态为1时,查询已开票的数据 -->
             <if test="receivableQueryVo.invoiceSettlementStatus != 2">
@@ -770,6 +794,9 @@
         <where>
             ipiis.is_delete = 0
             AND ipiis.system_code = #{settlementQueryVo.systemCode}
+            <if test="settlementQueryVo.receivePaymentDateBegin != null and settlementQueryVo.receivePaymentDateEnd != ''">
+                and  ipiis.receive_payment_date between #{settlementQueryVo.receivePaymentDateBegin} and #{settlementQueryVo.receivePaymentDateEnd}
+            </if>
             <if test="settlementQueryVo.settlementIds != null and settlementQueryVo.settlementIds != ''">
                 AND ipiis.id IN
                 <foreach collection="settlementQueryVo.settlementIds" item="settlementId" open="(" separator="," close=")">
@@ -827,6 +854,7 @@
         SELECT
         ipiis.id AS settlementId,
         GROUP_CONCAT(DISTINCT ipiis.invoice_id SEPARATOR ',') AS invoiceId,
+        GROUP_CONCAT(DISTINCT ipii.invoice_no SEPARATOR ',') AS invoiceNos,
         GROUP_CONCAT(DISTINCT ipii.company_id SEPARATOR ',') AS company_id,
         GROUP_CONCAT(DISTINCT eic.name SEPARATOR ',') AS company_name,
         GROUP_CONCAT(DISTINCT ipii.invoice_type SEPARATOR ',') AS invoice_type,
@@ -847,6 +875,12 @@
         <where>
             ipiis.is_delete = 0
             AND ipiis.system_code = #{settlementQueryVo.systemCode}
+            <if test="settlementQueryVo.invoiceNo != null and settlementQueryVo.invoiceNo != ''">
+                and ipii.invoice_no  = #{settlementQueryVo.invoiceNo}
+            </if>
+            <if test="settlementQueryVo.receivePaymentDateBegin != null and settlementQueryVo.receivePaymentDateEnd != null">
+                and ipiis.receive_payment_date between #{settlementQueryVo.receivePaymentDateBegin} and #{settlementQueryVo.receivePaymentDateEnd}
+            </if>
             <if test="settlementQueryVo.settlementIds != null and settlementQueryVo.settlementIds != ''">
                 AND ipiis.id IN
                 <foreach collection="settlementQueryVo.settlementIds" item="settlementId" open="(" separator="," close=")">
@@ -984,35 +1018,28 @@
 
 
     <select id="getSuperviseSettlementDetailExcelDtos" resultType="com.jzg.commons.entity.finance.dto.ExportSuperviseSettlementDetailExcelDto">
-        select ipi.contact_person, ipi.contact_person_phone,
-        io.company_name as companyName,
-        io.signing_time as signingTime,
-        ipii.id as invoiceId,
-        ipii.status as status,
-        ipi.license_no as licenseNo,
-        io.product_name as productName,
-        ipii.invoice_type as invoiceType,
-        ipii.invoice_party as invoiceParty,
-        ipii.tax_point as taxPoint,
-        (COALESCE(ipi.jq_supervise_costs_premiums,0)  + COALESCE(ipi.sy_supervise_costs_premiums,0)  + COALESCE(ipi.jy_supervise_costs_premiums,0) ) as receivableSuperviseCosts,
-        COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) as superviseCostPremiums4Car,
-        COALESCE(ipi.jy_supervise_costs_premiums, 0) as jy_supervise_costs_premiums,
-        ipi.jq_premium as jqPremium,
-        ipi.jq_supervise_costs_proportion as jqSuperviseCostsProportion,
-        ipi.jq_policy_no as jqPolicyNo,
-        ipi.sy_premium as syPremium,
-        ipi.sy_supervise_costs_proportion as sySuperviseCostsProportion,
-        ipi.sy_policy_no as syPolicyNo,
-        ipi.jy_premium as jyPremium,
-        ipi.jy_supervise_costs_proportion as jySuperviseCostsProportion,
-        ipi.jy_policy_no as jyPolicyNo,
-        ipi.tax_premium as taxPremium,
-        (SELECT U.USERNAME FROM sys_user U WHERE U.mobile = ipii.create_by) as invoicePerson,
-        ipii.invoice_time
+        SELECT ipii.invoice_no , iop.jq_policy_no ,iop.sy_policy_no , iop.jy_policy_no , io.id as order_no, ipi.contact_person, ipi.contact_person_phone, io.company_name AS companyName, io.signing_time AS signingTime, ipii.id AS invoiceId
+        , ipii.status AS status, ipi.license_no AS licenseNo, io.product_name AS productName, ipii.invoice_type AS invoiceType, ipii.invoice_party AS invoiceParty
+        , ipii.tax_point AS taxPoint
+        , COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) + COALESCE(ipi.jy_supervise_costs_premiums, 0) AS receivableSuperviseCosts
+        , COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) AS superviseCostPremiums4Car
+        , COALESCE(ipi.jy_supervise_costs_premiums, 0) AS jy_supervise_costs_premiums, ipi.jq_premium AS jqPremium
+        , ipi.jq_supervise_costs_proportion AS jqSuperviseCostsProportion, ipi.jq_policy_no AS jqPolicyNo, ipi.sy_premium AS syPremium, ipi.sy_supervise_costs_proportion AS sySuperviseCostsProportion, ipi.sy_policy_no AS syPolicyNo
+        , ipi.jy_premium AS jyPremium, ipi.jy_supervise_costs_proportion AS jySuperviseCostsProportion, ipi.jy_policy_no AS jyPolicyNo, ipi.tax_premium AS taxPremium
+        , (  SELECT U.USERNAME FROM sys_user U WHERE U.mobile = ipii.create_by ) AS invoicePerson, ipii.invoice_time
         FROM ins_ply_income_invoice ipii
-        LEFT JOIN ins_ply_income_invoice_link ipil ON ipii.id = ipil.invoice_id AND ipil.is_delete = 0
-        LEFT JOIN ins_ply_income ipi ON ipi.id = ipil.income_id  AND ipi.is_delete = 0
-        LEFT JOIN ins_orders io  ON ipi.order_no = io.id  AND io.is_delete = 0
+        LEFT JOIN ins_ply_income_invoice_link ipil
+        ON ipii.id = ipil.invoice_id
+        AND ipil.is_delete = 0
+        LEFT JOIN ins_ply_income ipi
+        ON ipi.id = ipil.income_id
+        AND ipi.is_delete = 0
+        AND ipi.system_code = 'G111'
+        LEFT JOIN ins_orders io
+        ON ipi.order_no = io.id
+        AND io.is_delete = 0
+        left join ins_orders_policy iop
+        on io.id = iop.order_no and iop.is_delete = 0
         <where>
             ipii.is_delete = 0
             AND ipii.system_code = #{settlementQueryVo.systemCode}
@@ -1037,49 +1064,60 @@
             <if test="settlementQueryVo.agreementType != null and settlementQueryVo.agreementType != ''">
                 AND ipi.agreement_type = #{settlementQueryVo.agreementType}
             </if>
+            <if test="settlementQueryVo.invoiceNo != null and settlementQueryVo.invoiceNo != ''">
+                and ipii.invoice_no  = #{settlementQueryVo.invoiceNo}
+            </if>
+            <if test="settlementQueryVo.jqPolicyNo != null and settlementQueryVo.jqPolicyNo != '' ">
+                and iop.jq_policy_no  = #{settlementQueryVo.jqPolicyNo}
+            </if>
+            <if test="settlementQueryVo.syPolicyNo != null and settlementQueryVo.syPolicyNo != ''">
+                and iop.sy_policy_no  = #{settlementQueryVo.syPolicyNo}
+            </if>
+            <if test="settlementQueryVo.jyPolicyNo != null and settlementQueryVo.jyPolicyNo != ''">
+                and iop.jy_policy_no = #{settlementQueryVo.jyPolicyNo}
+            </if>
         </where>
     </select>
     <select id="getPlatFormSettlementDetailExcelDtos" resultType="com.jzg.commons.entity.finance.dto.ExportSuperviseSettlementDetailExcelDto">
-        select ipi.contact_person, ipi.contact_person_phone,
-        ipiis.id as settlementId,
-        ipiis.invoice_id as invoiceId,
-        io.company_name as companyName,
-        io.signing_time as signingTime,
-        ipii.status as status,
-        ipi.license_no as licenseNo,
-        io.product_name as productName,
-        ipii.invoice_type as invoiceType,
-        ipii.invoice_party as invoiceParty,
-        ipii.tax_point as taxPoint,
-        COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) + COALESCE(ipi.jy_supervise_costs_premiums, 0) + COALESCE(ipi.jq_other_costs_premiums, 0) + COALESCE(ipi.sy_other_costs_premiums, 0) + COALESCE(ipi.jy_other_costs_premiums, 0) AS receivableSuperviseCosts,
-        ipi.jq_premium as jqPremium,
-        ipi.jq_supervise_costs_proportion as jqSuperviseCostsProportion,
-        ipi.jq_other_costs_proportion,
-        ipi.jq_policy_no as jqPolicyNo,
-        ipi.sy_premium as syPremium,
-        ipi.sy_supervise_costs_proportion as sySuperviseCostsProportion,
-        ipi.sy_other_costs_proportion,
-        ipi.sy_policy_no as syPolicyNo,
-        ipi.jy_premium as jyPremium,
-        ipi.jy_supervise_costs_proportion as jySuperviseCostsProportion,
-        ipi.jy_other_costs_proportion,
-        ipi.jy_policy_no as jyPolicyNo,
-        ipi.tax_premium as taxPremium,
-        ipii.create_by as invoicePerson,
-        ipii.create_time as invoiceTime,
-        ipiis.create_by as settlementPerson,
-        ipiis.create_time as settlementTime,
-        (SELECT U.USERNAME FROM sys_user U WHERE U.mobile = ipii.create_by) as invoicePerson,
-        ipii.invoice_time
-        FROM
-        ins_ply_income_invoice ipii
+        SELECT ioci.license_no ,iocui.name as insurName, iop.jq_policy_no , iop.sy_policy_no , iop.jy_policy_no, ipi.contact_person, ipi.contact_person_phone, ipiis.id AS settlementId, ipiis.invoice_id AS invoiceId, io.company_name AS companyName
+        , io.signing_time AS signingTime, ipii.status AS status, ipi.license_no AS licenseNo, io.product_name AS productName, ipii.invoice_type AS invoiceType
+        , ipii.invoice_party AS invoiceParty, ipii.tax_point AS taxPoint
+        , COALESCE(ipi.jq_supervise_costs_premiums, 0) + COALESCE(ipi.sy_supervise_costs_premiums, 0) + COALESCE(ipi.jy_supervise_costs_premiums, 0) + COALESCE(ipi.jq_other_costs_premiums, 0) + COALESCE(ipi.sy_other_costs_premiums, 0) + COALESCE(ipi.jy_other_costs_premiums, 0) AS receivableSuperviseCosts
+        , ipi.jq_premium AS jqPremium, ipi.jq_supervise_costs_proportion AS jqSuperviseCostsProportion, ipi.jq_other_costs_proportion, ipi.jq_policy_no AS jqPolicyNo, ipi.sy_premium AS syPremium
+        , ipi.sy_supervise_costs_proportion AS sySuperviseCostsProportion, ipi.sy_other_costs_proportion, ipi.sy_policy_no AS syPolicyNo, ipi.jy_premium AS jyPremium, ipi.jy_supervise_costs_proportion AS jySuperviseCostsProportion
+        , ipi.jy_other_costs_proportion, ipi.jy_policy_no AS jyPolicyNo, ipi.tax_premium AS taxPremium, ipii.create_by AS invoicePerson, ipii.create_time AS invoiceTime
+        , ipiis.create_by AS settlementPerson, ipiis.create_time AS settlementTime ,
+        (
+        SELECT U.USERNAME FROM sys_user U WHERE U.mobile = ipii.create_by) AS invoicePerson, ipii.invoice_time
+        FROM ins_ply_income_invoice ipii
         LEFT JOIN ins_ply_income_invoice_settlement ipiis ON ipiis.invoice_id = ipii.id AND ipiis.is_delete = 0
         LEFT JOIN ins_ply_income_invoice_link ipil ON ipil.invoice_id = ipiis.invoice_id AND ipil.is_delete = 0
         LEFT JOIN ins_ply_income ipi ON ipi.id = ipil.income_id AND ipi.is_delete = 0
         LEFT JOIN ins_orders io ON ipi.order_no = io.id AND io.is_delete = 0
+        left join ins_orders_car_info ioci on ioci.order_no  = io.id and ioci.is_delete = 0
+        left join ins_orders_car_user_info iocui on iocui.order_no = io.id and iocui.is_delete = 0 and iocui.policy_person_type = 3
+        left join ins_orders_policy iop on io.id = iop.order_no and iop.is_delete = 0
         <where>
             ipii.is_delete = 0
             AND ipii.system_code = #{settlementQueryVo.systemCode}
+            <if test="settlementQueryVo.signingTimeBegin != null and settlementQueryVo.signingTimeEnd != null">
+                and io.signing_time between #{settlementQueryVo.signingTimeBegin} and #{settlementQueryVo.signingTimeEnd}
+            </if>
+            <if test="settlementQueryVo.licenseNo != null and settlementQueryVo.licenseNo != ''">
+                and ioci.license_no  = #{settlementQueryVo.licenseNo}
+            </if>
+            <if test="settlementQueryVo.insurName != null and settlementQueryVo.insurName != ''">
+                and iocui.name = #{settlementQueryVo.insurName}
+            </if>
+            <if test="settlementQueryVo.jqPolicyNo != null and settlementQueryVo.jqPolicyNo != '' ">
+                and iop.jq_policy_no = #{settlementQueryVo.jqPolicyNo}
+            </if>
+            <if test="settlementQueryVo.syPolicyNo != null and settlementQueryVo.syPolicyNo != ''">
+                and iop.sy_policy_no = #{settlementQueryVo.syPolicyNo}
+            </if>
+            <if test="settlementQueryVo.jyPolicyNo != null and settlementQueryVo.jyPolicyNo != ''">
+                and iop.jy_policy_no = #{settlementQueryVo.jyPolicyNo}
+            </if>
             <if test="settlementQueryVo.settlementId != null and settlementQueryVo.settlementId != ''">
                 AND ipiis.id = #{settlementQueryVo.settlementId}
             </if>
@@ -1692,6 +1730,9 @@
         <where>
             ipii.is_delete = 0
             AND ipii.system_code = #{invoiceRecordQueryVo.systemCode}
+            <if test="invoiceRecordQueryVo.amount != null and invoiceRecordQueryVo.amount != ''">
+                and ipii.receivable_supervise_premium = #{invoiceRecordQueryVo.amount}
+            </if>
             <if test="invoiceRecordQueryVo.invoiceType != null and invoiceRecordQueryVo.invoiceType != ''">
                 AND ipii.invoice_type = #{invoiceRecordQueryVo.invoiceType}
             </if>

+ 92 - 0
tenant/organization/src/main/resources/mapper/SysUserJzgInfoMapper.xml

@@ -56,6 +56,19 @@
             </if>
         </where>
     </select>
+    <select id="getYWYById" resultType="com.jzg.commons.entity.po.SysUserJzgInfo">
+        SELECT id, user_id, name, work_number, status, is_enable, system_code, dept_id,
+        open_id, alipay, approval_opinion, logout_time, head_sculpture, leader_id,
+        referrer_id, manager_id, position_id, operator_code, partner_level, type_attr,
+        factor_verify, address, nations, koseki, birthday, marital_status, politics_status,
+        health, postal_code, email, blood_type, education, school, graduation_time,
+        former_employer, entry_time, agent_qualification_code, emergency_contact_tel,
+        emergency_contact_name, remark, sex, is_computer, speciality, salary, salary_level,
+        live_address, province, city, district, is_delete, is_distribution, distribution_time,
+        bank_card_number, bank_name, last_login_time, create_by, create_time, update_by, update_time
+        FROM sys_user_jzg_info
+        where id = #{id}
+    </select>
     <!-- 查询业务员 lipf 2026年4月24日11:22:18  -->
     <select id="queryYwy" resultMap="BaseResultMap">
         select
@@ -125,6 +138,85 @@
         </where>
         order by suji.create_time desc
     </select>
+    <select id="queryBJYwy" resultMap="BaseResultMap">
+
+        WITH RECURSIVE leader_tree AS (
+        SELECT id, leader_id, 1 AS depth,system_code
+        FROM sys_user_jzg_info
+        WHERE leader_id = #{leaderId}
+        AND is_delete = 0
+        UNION ALL
+        SELECT t.id, t.leader_id, lt.depth + 1,t.system_code
+        FROM sys_user_jzg_info t
+        INNER JOIN leader_tree lt ON t.leader_id = lt.id
+        WHERE t.is_delete = 0
+        AND lt.depth <![CDATA[  <  ]]> 10
+        )
+        SELECT
+        suji.id,
+        suji.user_id,
+        suji.work_number,
+        su.username,
+        su.mobile,
+        suji.name,
+        suji.dept_id,
+        sd.name AS dept_name,
+        suji.status,
+        suji.is_enable,
+        lsu.name AS leader_name,
+        (SELECT aa.mobile FROM sys_user aa
+        WHERE aa.id = lsu.user_id AND aa.is_delete = 0) AS leader_id,
+        (SELECT re.name FROM sys_user_jzg_info re WHERE re.id = suji.referrer_id) AS referrer_name,
+        suji.referrer_id,
+        suji.create_time AS createTime,
+        suji.create_by AS createBy
+        FROM
+        sys_user_jzg_info suji
+        INNER JOIN leader_tree lt ON suji.id = lt.id
+        LEFT JOIN sys_user su ON su.id = suji.user_id AND su.is_delete = 0
+        LEFT JOIN sys_user_jzg_info lsu ON lsu.id = suji.leader_id AND lsu.is_delete = 0
+        LEFT JOIN sys_dept sd ON sd.id = suji.dept_id AND sd.is_delete = 0
+        LEFT JOIN sys_dept d ON suji.dept_id = d.id AND d.is_delete = 0
+        <where>
+            suji.is_delete = 0
+            and suji.id  in (
+            select sujis.sys_user_jzg_info_id  from sys_user_jzg_info_salesman sujis  where  sujis.type_attr != 2 AND sujis.type_attr != 3
+            )
+            <if test="sysUserInfoListVo.deptId != null and sysUserInfoListVo.deptId != ''">
+                and d.route LIKE CONCAT('%', #{sysUserInfoListVo.deptId}, '%')
+            </if>
+            <if test="sysUserInfoListVo.typeAttr != null and sysUserInfoListVo.typeAttr != ''">
+                and suji.type_attr = #{sysUserInfoListVo.typeAttr}
+            </if>
+            <if test="sysUserInfoListVo.status != null and sysUserInfoListVo.status != '-1'">
+                and suji.status = #{sysUserInfoListVo.status}
+            </if>
+            <if test="sysUserInfoListVo.typeStatus != null and sysUserInfoListVo.typeStatus.size() > 0">
+                AND suji.status IN
+                <foreach item="status" collection="sysUserInfoListVo.typeStatus"
+                         open="(" separator="," close=")">
+                    #{status}
+                </foreach>
+            </if>
+            <if test="sysUserInfoListVo.isEnable != null and sysUserInfoListVo.isEnable != ''">
+                and suji.is_enable = #{sysUserInfoListVo.isEnable}
+            </if>
+            <if test="sysUserInfoListVo.sysOrganizationId != null and sysUserInfoListVo.sysOrganizationId != ''">
+                and so.id = #{sysUserInfoListVo.sysOrganizationId}
+            </if>
+            <if test="sysUserInfoListVo.leaderId != null and sysUserInfoListVo.leaderId != ''">
+                and (suji.leader_id = #{sysUserInfoListVo.leaderId}
+                or  lsu.name = #{sysUserInfoListVo.leaderId})
+            </if>
+            <if test="sysUserInfoListVo.salesman != null and sysUserInfoListVo.salesman != ''">
+                and (suji.name like concat('%',#{sysUserInfoListVo.salesman},'%')
+                or  su.mobile = #{sysUserInfoListVo.salesman}
+                or  suji.work_number = #{sysUserInfoListVo.salesman}
+                or  su.id = #{sysUserInfoListVo.salesman})
+            </if>
+        </where>
+        order by suji.create_time desc
+    </select>
 
     <!-- 查询成员 lipf 2026年4月24日11:10:15 -->
     <select id="queryMember" resultMap="BaseResultMap">

+ 82 - 7
协议承保规则接口对接文档.md

@@ -320,15 +320,87 @@
 
 ---
 
+## 八、批量复制规则因子【新增】
+
+**接口路径**:`POST /agreementRules/rulesAttrBatchCopy`
+
+### 功能说明
+
+将源承保规则下的某条或多条规则因子批量复制到某个或多个目标承保协议下:每个目标协议下 **新增一条规则**承接所选因子,并与该协议下已有规则共享
+`parentId`(前端按组合并成一条展示);目标协议下没有规则时,新增的规则独立展示。
+
+### 请求参数
+
+| 字段名    | 类型                | 必填 | 描述                                                                                                      |
+|-----------|---------------------|------|-----------------------------------------------------------------------------------------------------------|
+| `attrIds` | Array\<String\>     | 是   | 要复制的规则因子关联记录ID列表(来源于`getRuleInfo`返回明细的`id`字段),源规则由所选因子记录所属规则确定 |
+| `targets` | Array\<CopyTarget\> | 是   | 目标协议规则列表                                                                                          |
+
+### CopyTarget 结构
+
+| 字段名        | 类型   | 必填 | 描述                                                                                                                                |
+|---------------|--------|------|-------------------------------------------------------------------------------------------------------------------------------------|
+| `agreementId` | String | 是   | 目标承保协议ID                                                                                                                      |
+| `ruleId`      | String | 否   | 归组锚定规则ID:复制出的新规则与该规则共享 `parentId`(同组展示);为空时取该协议下第一条规则作为锚定,协议下无规则则新规则独立展示 |
+
+### 请求体示例
+
+```json
+{
+   "attrIds": [
+      "1692100000000000001",
+      "1692100000000000002"
+   ],
+   "targets": [
+      {
+         "agreementId": "123456",
+         "ruleId": "987655"
+      },
+      {
+         "agreementId": "123457"
+      }
+   ]
+}
+```
+
+### 业务逻辑说明
+
+1. **源规则确定**:源规则由 `attrIds` 所选因子记录所属规则反推;所选因子必须属于同一规则或同一批量规则组,否则返回失败
+2. **因子校验**:`attrIds` 中的ID必须全部有效(因子关联记录ID可通过`getRuleInfo`接口获取),存在无效ID时返回失败
+3. **锚定规则定位(用于确定归组)**:
+   - 指定 `ruleId`:校验该规则存在且属于对应协议,作为归组锚定
+   - 未指定 `ruleId`:取该协议下第一条规则(`orderNum` 最小)作为锚定
+   - 协议下无规则:无锚定,新增规则独立展示
+4. **新增规则与归组(每个目标协议均新增一条)**:
+   - 每个目标协议下新增一条规则承接所选因子(仅含本次所选 `attrIds` 因子),基础信息(生效时间、录入描述)沿用源规则,
+     `orderNum` 取该协议下最大序号 + 1
+   - 锚定规则存在时:新规则与锚定规则共享 `parentId`(前端按组合并展示);锚定规则自身无 `parentId` 时,生成新组ID并将锚定规则归入该组
+   - 锚定规则不存在(协议下无规则)时:新规则 `parentId` 为空,独立展示
+   - **源规则保持不变**(不修改源规则的 `parentId`、不复制源规则本身,因此不会出现"目标下多出源规则")
+5. **因子复制**:将所选因子直接插入新规则(新规则为全新记录,不覆盖任何已有因子);同一 `attrCode` 仅复制一条(批量组内不同子规则存在相同因子时去重)
+6. 复制完成后重新生成新规则的规则描述(`ruleDescription`)
+
+### 响应
+
+```json
+{
+   "code": 200,
+   "msg": "批量复制规则因子成功"
+}
+```
+
+---
+
 ## 变更总结
 
-| 接口 | 变更点 | 变更内容 |
-|---|---|---|
-| `POST /rulesAdd` | 请求参数新增 | `rulesGroups`(批量规则分组),支持一次创建多条规则 |
-| `POST /rulesAdd` | 逻辑变更 | 批量模式下所有子规则共享同一 `parentId`,按分组顺序生成 `orderNum` |
-| `GET /rulesList` | 返回值新增 | `parentId`(父规则ID) |
-| `GET /rulesGet` | 返回值新增 | `parentId`(父规则ID) |
-| `GET /rulesListByParentId` | **新增接口** | 根据父ID查询子规则列表 |
+| 接口                       | 变更点       | 变更内容                                                                                                   |
+|----------------------------|--------------|------------------------------------------------------------------------------------------------------------|
+| `POST /rulesAdd`           | 请求参数新增 | `rulesGroups`(批量规则分组),支持一次创建多条规则                                                        |
+| `POST /rulesAdd`           | 逻辑变更     | 批量模式下所有子规则共享同一 `parentId`,按分组顺序生成 `orderNum`                                         |
+| `GET /rulesList`           | 返回值新增   | `parentId`(父规则ID)                                                                                     |
+| `GET /rulesGet`            | 返回值新增   | `parentId`(父规则ID)                                                                                     |
+| `GET /rulesListByParentId` | **新增接口** | 根据父ID查询子规则列表                                                                                     |
+| `POST /rulesAttrBatchCopy` | **新增接口** | 批量复制规则因子到目标协议:每个目标协议下新增一条规则(仅含所选因子)并与已有规则同组展示,源规则保持不变 |
 
 ### 业务逻辑说明
 
@@ -337,6 +409,9 @@
 - 批量模式与单条模式互斥,优先处理 `rulesGroups`
 - 通过 `rulesListByParentId` 接口可按 `parentId` 查询同批次的所有子规则
 - 修改接口仅支持对单条规则进行编辑
+- `rulesAttrBatchCopy` 支持跨协议批量复制规则因子;源规则由所选因子(`attrIds`
+  )反推,所选因子须属于同一规则或同一规则组;每个目标协议下新增一条规则(仅含所选因子)并与该协议已有规则共享 `parentId`
+  (同组合并展示),源规则保持不变
 
 ### 数据库变更说明
 

Некоторые файлы не были показаны из-за большого количества измененных файлов