Преглед на файлове

Merge branch 'dev_jzg_lipf_v20260901' into test

lipf преди 3 седмици
родител
ревизия
589a91e1d9
променени са 56 файла, в които са добавени 1458 реда и са изтрити 784 реда
  1. 1 1
      authentication/src/main/java/com/jzg/config/SecurityConfig.java
  2. 39 0
      commons/src/main/java/com/jzg/commons/entity/dto/AgreementRulesAttrCopyParam.java
  3. 3 1
      commons/src/main/java/com/jzg/commons/entity/dto/PtlAgreementCostAdd.java
  4. 3 0
      commons/src/main/java/com/jzg/commons/entity/orders/vo/OrderListVo.java
  5. 2 0
      commons/src/main/java/com/jzg/commons/entity/po/SysOrganization.java
  6. 23 0
      commons/src/main/java/com/jzg/commons/entity/scheme/vo/PtlSchemeSaveVo.java
  7. 6 0
      commons/src/main/java/com/jzg/commons/entity/vo/RuleAttrMappingVo.java
  8. 2 2
      commons/src/main/java/com/jzg/commons/service/impl/OperatorTrajectoryServiceImpl.java
  9. 6 0
      gateway/src/main/java/com/jzg/config/CorsConfig.java
  10. 6 0
      gateway/src/main/java/com/jzg/filter/AuthGlobalFilter.java
  11. 11 0
      gateway/src/main/java/com/jzg/filter/DecryptFilter.java
  12. 4 4
      partner/src/main/java/com/jzg/entity/vo/RelationalVo.java
  13. 1 8
      partner/src/main/java/com/jzg/service/Impl/PartnerUserServiceImpl.java
  14. 2 2
      partner/src/main/java/com/jzg/utils/DistributionUtils.java
  15. 33 20
      partner/src/main/resources/mapper/PartnerUserMapper.xml
  16. 7 2
      tenant/costsorrule/src/main/java/com/jzg/costsorrule/constants/OperatorConstant.java
  17. 53 63
      tenant/costsorrule/src/main/java/com/jzg/costsorrule/service/impl/RuleServiceImpl.java
  18. 3 3
      tenant/insurance/quotation-commons/src/main/java/com/jzg/quotation/commons/client/OrgClient.java
  19. 34 8
      tenant/insurance/quotation-dadi/src/main/java/com/jzg/quotation/dadi/crawler/entity/request/DaDiInsurancePlanRequest.java
  20. 15 9
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/FactorMatch.java
  21. 1 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/aop/aspect/QuoteVerificationAspect.java
  22. 7 1
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsOrdersServiceImpl.java
  23. 11 8
      tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/service/impl/InsTaskImagesServiceImpl.java
  24. 6 0
      tenant/insurance/quotation-summary/src/main/resources/application-prod.yaml
  25. 51 18
      tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml
  26. 1 1
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/component/TaiPingCrawlerRequestComponent.java
  27. 9 1
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/TaipingCrawlerConfigureParameters.java
  28. 4 5
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerBrandNameQueryRequest.java
  29. 1 1
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerGetCarDepreRateRequest.java
  30. 236 207
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerPremiumCalculateRequest.java
  31. 6 9
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/request/TaiPingCrawlerSubmitValidateRequest.java
  32. 8 3
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/response/TaiPingCrawlerBrandNameQueryData.java
  33. 8 3
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/entity/response/TaiPingCrawlerPremiumCalculateData.java
  34. 140 20
      tenant/insurance/quotation-taiping/src/main/java/com/jzg/quotation/taiping/crawler/service/impl/TaipingCrawlerRequestImpl.java
  35. 4 4
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/ZmCrawlerConfigureParameters.java
  36. 1 1
      tenant/insurance/quotation-zhongmei/src/main/java/com/jzg/quotation/zhongmei/crawler/entity/dto/SaleInfoDTO.java
  37. 108 129
      tenant/organization/src/main/java/com/jzg/organization/component/BuildDescUtils.java
  38. 10 1
      tenant/organization/src/main/java/com/jzg/organization/controller/AgreementRulesController.java
  39. 3 3
      tenant/organization/src/main/java/com/jzg/organization/controller/SysOrganizationController.java
  40. 4 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/EsmUserReferrerMapper.java
  41. 2 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserJzgInfoMapper.java
  42. 11 1
      tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementUndwrtRulesService.java
  43. 6 1
      tenant/organization/src/main/java/com/jzg/organization/service/SysOrganizationService.java
  44. 1 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysUserJzgInfoService.java
  45. 100 46
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementCostServiceImpl.java
  46. 119 4
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementUndwrtRulesServiceImpl.java
  47. 2 3
      tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java
  48. 8 3
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SignInServiceImpl.java
  49. 7 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysAmountAuditingServiceImpl.java
  50. 21 3
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysOrganizationServiceImpl.java
  51. 3 1
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgAppServiceImpl.java
  52. 4 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgInfoServiceImpl.java
  53. 181 164
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java
  54. 2 0
      tenant/organization/src/main/resources/application.yml
  55. 36 12
      tenant/organization/src/main/resources/mapper/SysUserJzgInfoMapper.xml
  56. 82 7
      协议承保规则接口对接文档.md

+ 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

+ 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;
+    }
+}

+ 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;
 

+ 3 - 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;
     /**

+ 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;
         }
     }

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

@@ -952,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) {
             // 异常处理,默认不是团队长

+ 7 - 1
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());
@@ -2614,7 +2620,7 @@ public class InsOrdersServiceImpl extends ServiceImpl<InsOrdersMapper, InsOrders
      */
     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) {
             // 异常处理,默认不是团队长

+ 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:

+ 51 - 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}
@@ -1271,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,
@@ -1293,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}
@@ -1306,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 != ''">
@@ -1330,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>
@@ -1342,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,
@@ -1377,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
@@ -1553,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
@@ -1603,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){

+ 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));
     }
 }

+ 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);
 }

+ 2 - 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);
+
     /**
      * 查询有效的业务员信息
      *

+ 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);
 
     /**
      * 通过手机号获取晋掌柜用户信息

+ 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);

+ 2 - 3
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);
         }
@@ -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
 
             // ========== 核心逻辑开始 ==========

+ 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());

+ 7 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysAmountAuditingServiceImpl.java

@@ -522,6 +522,13 @@ public class SysAmountAuditingServiceImpl extends ServiceImpl<SysAmountAuditingM
     public String exportYwyIORecs(YwyIOParam ywyIOParam) {
         log.info("导出业务员收支明细:ywyIOParam=[{}]", JSONUtil.toJsonStr(ywyIOParam));
         List<SysUserAccountChangeLog> changeLogs = sysUserAccountIncomeLogService.queryYwyIORecs(ywyIOParam);
+        for (SysUserAccountChangeLog changeLog : changeLogs) {
+            // 提现驳回的时候,金额设置为0
+            if("4".equals(String.valueOf(changeLog.getOperType()))){
+                changeLog.setRemark("提现驳回" + changeLog.getAmount());
+                changeLog.setAmount(BigDecimal.ZERO);
+            }
+        }
         log.info("导出业务员收支明细:ywyIOParam=[{}].导出[{}]条记录", JSONUtil.toJsonStr(ywyIOParam), CollUtil.size(changeLogs));
         String userName=null;
         if(CollUtil.isNotEmpty(changeLogs)){

+ 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

+ 181 - 164
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,13 +265,14 @@ 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){
+        if (Objects.nonNull(sysUserInfoListVo.getStatus()) && sysUserInfoListVo.getStatus() == 0) {
             List<Integer> typeStatus = new ArrayList<>();
             sysUserInfoListVo.setStatus(null);
             typeStatus.add(UserState.UserStateEnum.COMPANY_REVIEW_ING.getValue());
@@ -282,9 +286,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);
@@ -295,37 +299,37 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 //            page.setSize(Long.MAX_VALUE);
             userInfoList = sysUserJzgInfoMapper.queryBJYwy(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());
                 }
@@ -334,7 +338,7 @@ 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;
     }
 
@@ -395,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()) {
@@ -412,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);
         }
 
@@ -474,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;
     }
 
@@ -558,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();
@@ -566,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("用户信息已存在,无法添加");
@@ -597,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());
         }
 
@@ -607,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);
         }
@@ -684,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) {
@@ -695,6 +699,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         return HttpResult.ok("删除成功");
     }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean deleteDistribution(IsDeleteVo isDeleteVo) {
@@ -716,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()) {
@@ -813,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) {
@@ -896,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("请勾选要操作的数据");
@@ -1046,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);
@@ -1058,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())) {
@@ -1103,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();
@@ -1118,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("修改业务员成功");
@@ -1127,7 +1144,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     /**
      * 获取业务员详细信息接口
-     *      包括相关的附件,合同,身份证图片等
+     * 包括相关的附件,合同,身份证图片等
      *
      * @author lipf
      * @date 2026/4/22 15:37
@@ -1135,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("该用户不存在");
         }
@@ -1149,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());
@@ -1182,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();
@@ -1250,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) {
@@ -1283,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);
@@ -1425,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());
             }
         }
@@ -1446,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
@@ -1458,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));
@@ -1470,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("保存失败");
@@ -1488,7 +1506,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     }
 
 
-
     @Transactional(rollbackFor = Exception.class)
     public void addPartnerTransactional(SysUserVo sysUserVo) {
         addPartner(sysUserVo);
@@ -1501,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("保存合伙人数据异常");
@@ -1512,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);
@@ -1526,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));
@@ -1538,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);
@@ -1560,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);
@@ -1654,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());
@@ -1669,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);
@@ -1679,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) {
@@ -1687,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());
@@ -1703,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());
@@ -1715,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();
@@ -1723,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);
         }
@@ -1742,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());
@@ -1750,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);
@@ -1771,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));
     }
 
 }

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

@@ -99,6 +99,7 @@ tenant:
     - ptl_agreement_dispatch_action
     - ptl_new_car_judge_rules
     - ptl_new_car_judge_rules
+    - sys_user_activity_complete_in_rule
     - t
 
   ignoreLoginNames:
@@ -117,6 +118,7 @@ data-scope:
     - getOrganizationUser
     - deleteOrganizationUser
     - queryBJYwy
+    - getYWYById
 
 
 

+ 36 - 12
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
@@ -126,38 +139,49 @@
         order by suji.create_time desc
     </select>
     <select id="queryBJYwy" resultMap="BaseResultMap">
-        select
+
+        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 ,
+        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) referrer_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
+        FROM
         sys_user_jzg_info suji
-        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
+        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="leaderId != null and leaderId != ''">
-                and suji.leader_id = #{leaderId}
-            </if>
             <if test="sysUserInfoListVo.deptId != null and sysUserInfoListVo.deptId != ''">
                 and d.route LIKE CONCAT('%', #{sysUserInfoListVo.deptId}, '%')
             </if>

+ 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`
+  (同组合并展示),源规则保持不变
 
 ### 数据库变更说明
 

Някои файлове не бяха показани, защото твърде много файлове са промени