فهرست منبع

优化规则过滤保司接口、新增批量查询保险公司账号接口、新增批量查报价后的调度动作信息

lixiaolong 4 هفته پیش
والد
کامیت
5dd360e30a

+ 6 - 0
platform/src/main/java/com/jzg/controller/AgreementAttributionController.java

@@ -56,6 +56,12 @@ public class AgreementAttributionController extends BaseController {
         return agreementAttributionService.getAgreementAttribution(id);
     }
 
+    @Operation(summary = "批量查询保险公司账号接口", description = "批量查询保险公司账号接口")
+    @PostMapping(value = "/getAgreementAttributionByIds")
+    public HttpResult<List<PtlAgreementAttribution>> getAgreementAttributionByIds(@RequestBody List<String> ids) {
+        return HttpResult.ok(agreementAttributionService.getAgreementAttributionByIds(ids));
+    }
+
     @Operation(summary = "查询保险公司账号列表接口", description = "查询保险公司账号列表接口")
     @PostMapping(value = "/getAgreementAttributionList")
     public HttpResult getActivityList(@RequestBody PtlAgreementAttributionQueryVo ptlAgreementAttributionQueryVo) {

+ 8 - 0
platform/src/main/java/com/jzg/service/PtlAgreementAttributionService.java

@@ -16,6 +16,14 @@ public interface PtlAgreementAttributionService extends IService<PtlAgreementAtt
 
     HttpResult<PtlAgreementAttribution> getAgreementAttribution(String id);
 
+    /**
+     * 批量查询保险公司账号
+     *
+     * @param ids 账号id集合
+     * @return 账号列表
+     */
+    List<PtlAgreementAttribution> getAgreementAttributionByIds(List<String> ids);
+
     /**
      * 查询保险公司账号列表接口
      *

+ 12 - 0
platform/src/main/java/com/jzg/service/impl/PtlAgreementAttributionImpl.java

@@ -1,5 +1,6 @@
 package com.jzg.service.impl;
 
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -23,8 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * @author quchen
@@ -77,6 +80,15 @@ public class PtlAgreementAttributionImpl extends ServiceImpl<PtlAgreementAttribu
         return HttpResult.ok("",ptlAgreementAttribution);
     }
 
+    @Override
+    public List<PtlAgreementAttribution> getAgreementAttributionByIds(List<String> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<String> distinctIds = ids.stream().filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
+        return listByIds(distinctIds);
+    }
+
 
     @Override
     public Page<PtlAgreementAttribution> getAgreementAttributionList(Page page, PtlAgreementAttributionQueryVo ptlAgreementAttributionQueryVo) {

+ 5 - 0
tenant/organization/src/main/java/com/jzg/organization/client/OrgClient.java

@@ -6,11 +6,16 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
+import java.util.List;
+
 @FeignClient(name="${spring.application.name:jzg-organization}")
 public interface OrgClient {
 
     @PostMapping("/ptlAgreementDispatch/getAgreementDispatch")
     HttpResult getAgreementDispatch(@RequestBody PtlAgreementDispatchQuery ptlAgreementDispatchQuery);
 
+    @PostMapping("/ptlAgreementDispatch/getAgreementDispatchByCompanyIds")
+    HttpResult getAgreementDispatchByCompanyIds(@RequestBody List<String> companyIds);
+
 
 }

+ 4 - 0
tenant/organization/src/main/java/com/jzg/organization/client/PlatformClient.java

@@ -29,6 +29,10 @@ public interface PlatformClient {
     @PostMapping(value = "/manager/attribution/getAgreementAttribution2")
     public HttpResult<PtlAgreementAttribution> getAgreementAttribution2(@RequestParam(value = "id") String id);
 
+    @Operation(summary = "批量查询保险公司账号接口", description = "批量查询保险公司账号接口")
+    @PostMapping(value = "/manager/attribution/getAgreementAttributionByIds")
+    public HttpResult<List<PtlAgreementAttribution>> getAgreementAttributionByIds(@RequestBody List<String> ids);
+
     /**
      * 特别约定列表查询
      */

+ 6 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/PtlAgreementDispatchController.java

@@ -40,6 +40,12 @@ public class PtlAgreementDispatchController {
         return HttpResult.ok(ptlAgreementDispatchService.getAgreementDispatch(ptlAgreementDispatchQuery));
     }
 
+    @PostMapping("getAgreementDispatchByCompanyIds")
+    @Operation(summary= "批量获取协议调度")
+    public HttpResult<PtlAgreementDispatchVo> getAgreementDispatchByCompanyIds(@RequestBody List<String> companyIds){
+        return HttpResult.ok(ptlAgreementDispatchService.getAgreementDispatchByCompanyIds(companyIds));
+    }
+
     /**
      * 添加协议调度
      * @author lipf modify by lipf

+ 3 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/PtlAgreementDispatchAfterActionMapper.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jzg.commons.entity.agreement.dispatch.dto.PtlAgreementDispatchAction;
 import com.jzg.commons.entity.agreement.dispatch.dto.PtlAgreementDispatchAfterAction;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -12,4 +13,6 @@ import java.util.List;
 public interface PtlAgreementDispatchAfterActionMapper extends BaseMapper<PtlAgreementDispatchAfterAction> {
 
     public List<PtlAgreementDispatchAfterAction> getAfterActions(String companyId);
+
+    public List<PtlAgreementDispatchAfterAction> getAfterActionsByCompanyIds(@Param("companyIds") List<String> companyIds);
 }

+ 6 - 0
tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementDispatchService.java

@@ -49,6 +49,12 @@ public interface PtlAgreementDispatchService extends IService<PtlAgreementDispat
      */
     public PtlAgreementDispatchVo getAgreementDispatch(PtlAgreementDispatchQuery ptlAgreementDispatchQuery);
 
+    /**
+     * 批量获取多个保司的协议调度信息(公共字典只查一次,消除逐保司重复的耗时查询)
+     * @param companyIds 保司id集合
+     */
+    public PtlAgreementDispatchVo getAgreementDispatchByCompanyIds(List<String> companyIds);
+
     /**
      * 根据调度id 获取调度动作
      * @param dispatchIds

+ 66 - 13
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementDispatchServiceImpl.java

@@ -116,11 +116,31 @@ public class PtlAgreementDispatchServiceImpl extends ServiceImpl<PtlAgreementDis
 
     @Override
     public PtlAgreementDispatchVo getAgreementDispatch(PtlAgreementDispatchQuery ptlAgreementDispatchQuery) {
-        log.info("获取协议调度. ptlAgreementDispatchQuery=[{}]", JSONUtil.toJsonStr(ptlAgreementDispatchQuery));
+        if (ptlAgreementDispatchQuery == null || StrUtil.isBlank(ptlAgreementDispatchQuery.getCompanyId())) {
+            return new PtlAgreementDispatchVo();
+        }
+        return buildDispatchVos(Collections.singletonList(ptlAgreementDispatchQuery.getCompanyId()));
+    }
+
+    /**
+     * 批量获取多个保司的协议调度信息(公共字典/全表查询只执行一次,避免逐保司重复查询;账号查询批量一次完成,消除嵌套串行 RPC)
+     *
+     * @param companyIds 保司id集合
+     */
+    public PtlAgreementDispatchVo getAgreementDispatchByCompanyIds(List<String> companyIds) {
+        if (CollUtil.isEmpty(companyIds)) {
+            return new PtlAgreementDispatchVo();
+        }
+        return buildDispatchVos(companyIds);
+    }
+
+    private PtlAgreementDispatchVo buildDispatchVos(List<String> companyIds) {
+        log.info("批量获取协议调度. companyIds=[{}]", JSONUtil.toJsonStr(companyIds));
+        PtlAgreementDispatchVo dispatchVos = new PtlAgreementDispatchVo();
+        // 一次查询所有保司的调度(公共字典只查一次)
         List<PtlAgreementDispatch> ptlAgreementDispatches = baseMapper.selectList(new LambdaQueryWrapper<PtlAgreementDispatch>()
-                .eq(PtlAgreementDispatch::getCompanyId, ptlAgreementDispatchQuery.getCompanyId())
+                .in(PtlAgreementDispatch::getCompanyId, companyIds)
                 .orderByAsc(PtlAgreementDispatch::getCreateTime));
-        PtlAgreementDispatchVo dispatchVos = new PtlAgreementDispatchVo();
         List<String> dispatchIds = ptlAgreementDispatches.stream().map(PtlAgreementDispatch::getId).collect(Collectors.toList());
         if (!dispatchIds.isEmpty()) {
             List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList = ptlAgreementUndwrtRulesAttrService.getUndwrtRulesAttrList();
@@ -140,8 +160,9 @@ public class PtlAgreementDispatchServiceImpl extends ServiceImpl<PtlAgreementDis
             }).toList();
             // 获取所有保司的动作
             List<PtlAgreementDispatchAction> ptlAgreementDispatchActions = actionMapper.getActions(dispatchIds);
-            // 获取保司的报价失败之后的动作
-            List<PtlAgreementDispatchAfterAction> afterActions = afterActionMapper.getAfterActions(ptlAgreementDispatchQuery.getCompanyId());
+            // 获取保司的报价失败之后的动作(按 companyId 分组复用)
+            Map<String, List<PtlAgreementDispatchAfterAction>> afterActionsByCompany = afterActionMapper.getAfterActionsByCompanyIds(companyIds).stream()
+                    .collect(Collectors.groupingBy(PtlAgreementDispatchAfterAction::getCompanyId));
             int index = 1;
             // add by lipf, 对协议配置中的字典序号进行转义 2026年5月20日16:43:34
             List<PtlAgreementUndwrtRulesDictLabal> ptlAgreementUndwrtRulesDictLabals = baseMapper.queryAllDictLabal();
@@ -160,6 +181,28 @@ public class PtlAgreementDispatchServiceImpl extends ServiceImpl<PtlAgreementDis
                     ));
             Map<String, PtlAreaLicense> areaLicenseMap = ptlAreaLicenseService.queryAllAreaLicenseMap();
 
+            // ===== 收集所有 change_bs_account 动作的 accountId,批量查询一次(消除串行 RPC) =====
+            List<String> accountIds = new ArrayList<>();
+            for (PtlAgreementDispatchAction action : ptlAgreementDispatchActions) {
+                if ("change_bs_account".equals(action.getActionCode()) && action.getActionJson() != null
+                        && StrUtil.isNotBlank(action.getActionJson().getString("accountId"))) {
+                    accountIds.add(action.getActionJson().getString("accountId"));
+                }
+            }
+            Map<String, PtlAgreementAttribution> attributionById = new HashMap<>();
+            if (!accountIds.isEmpty()) {
+                try {
+                    HttpResult<List<PtlAgreementAttribution>> batchRes = platformClient.getAgreementAttributionByIds(accountIds);
+                    if (batchRes.getCode() == 200 && batchRes.getData() != null) {
+                        for (PtlAgreementAttribution attr : batchRes.getData()) {
+                            attributionById.put(attr.getId(), attr);
+                        }
+                    }
+                } catch (Exception e) {
+                    log.warn("批量查询保司账号异常", e);
+                }
+            }
+
             Map<String,String> operatorMap = new HashMap<>();
             operatorMap.put("1","包含");
             operatorMap.put("2","小于");
@@ -243,11 +286,22 @@ public class PtlAgreementDispatchServiceImpl extends ServiceImpl<PtlAgreementDis
                                 String accountId = action.getActionJson().getString("accountId");
                                 // 你的 Objects.nonNull 判断依然有效且非常规范
                                 if (Objects.nonNull(accountId)) {
-                                    HttpResult<PtlAgreementAttribution> agreementAttribution = platformClient.getAgreementAttribution2(accountId);
-                                    if (agreementAttribution.getCode() == 200) {
-                                        PtlAgreementAttribution data = agreementAttribution.getData();
+                                    PtlAgreementAttribution data = attributionById.get(accountId);
+                                    if (data != null) {
                                         action.getActionJson().put("userName", data.getUsername());
                                         action.getActionJson().put("companyName", data.getInsCompanyName());
+                                    } else {
+                                        // 批量未覆盖时回退单次查询,保证兼容
+                                        try {
+                                            HttpResult<PtlAgreementAttribution> agreementAttribution = platformClient.getAgreementAttribution2(accountId);
+                                            if (agreementAttribution.getCode() == 200 && agreementAttribution.getData() != null) {
+                                                PtlAgreementAttribution d = agreementAttribution.getData();
+                                                action.getActionJson().put("userName", d.getUsername());
+                                                action.getActionJson().put("companyName", d.getInsCompanyName());
+                                            }
+                                        } catch (Exception e) {
+                                            log.warn("查询保司账号[{}]异常", accountId, e);
+                                        }
                                     }
                                 }
                             }
@@ -258,7 +312,7 @@ public class PtlAgreementDispatchServiceImpl extends ServiceImpl<PtlAgreementDis
                 dispatchVos.getDispatchVos().add(vo);
             }
 
-            for(PtlAgreementDispatchAfterAction afterAction : afterActions){
+            for(PtlAgreementDispatchAfterAction afterAction : afterActionsByCompany.values().stream().flatMap(List::stream).collect(Collectors.toList())){
                 SysDict sysDict = afterActionsDicts.stream().filter(x -> x.getValue().equals(afterAction.getActionCode())).findFirst().orElse(null);
                 if(sysDict == null){
                     afterAction.setActionName("未知动作");
@@ -276,14 +330,13 @@ public class PtlAgreementDispatchServiceImpl extends ServiceImpl<PtlAgreementDis
                         // change_bs_account 更换保司账号
                         HttpResult<PtlAgreementAttribution> agreementAttribution = esmInsCompanyClient.getAgreementAttribution(afterAction.getActionJson().get("accountId").toString());
                         if(agreementAttribution.getCode() == 200){
-                            PtlAgreementAttribution data = agreementAttribution.getData();
-                            afterAction.getActionJson().put("userName",data.getUsername());
-                            afterAction.getActionJson().put("companyName",data.getInsCompanyName());
+                            afterAction.getActionJson().put("userName",agreementAttribution.getData().getUsername());
+                            afterAction.getActionJson().put("companyName",agreementAttribution.getData().getInsCompanyName());
                         }
                     }
                 }
             }
-            dispatchVos.setAfterActions(afterActions);
+            dispatchVos.setAfterActions(afterActionsByCompany.values().stream().flatMap(List::stream).collect(Collectors.toList()));
         }
 
 

+ 66 - 44
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlSchemeServiceImpl.java

@@ -438,6 +438,32 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
         //   3. 关联账号必须可用 (useStatus == "0") 且可报价 (quoteStatus == "0")
         // 过滤后如果某保司没有任何有效协议,会被下面的 removeIf 自动排除
         if (CollUtil.isNotEmpty(companyList)) {
+            // 1. 收集所有需要校验的归属账号 id(去重)
+            List<String> attributionIds = companyList.stream()
+                    .flatMap(c -> Optional.ofNullable(c.getAgreements()).orElse(Collections.emptyList()).stream())
+                    .map(PtlAgreement::getAttributionId)
+                    .filter(StrUtil::isNotBlank)
+                    .distinct()
+                    .collect(Collectors.toList());
+
+            // 2. 并行批量查询归属账号,构建 id -> 账号信息 索引(避免逐协议串行 RPC)
+            Map<String, PtlAgreementAttribution> attributionMap;
+            if (CollUtil.isNotEmpty(attributionIds)) {
+                attributionMap = attributionIds.parallelStream().collect(HashMap::new, (map, id) -> {
+                    try {
+                        HttpResult<PtlAgreementAttribution> res = platformClient.getAgreementAttribution2(id);
+                        if (res.getCode() == 200 && res.getData() != null) {
+                            map.put(id, res.getData());
+                        }
+                    } catch (Exception e) {
+                        log.warn("批量查询协议归属账号[{}]异常,默认保留", id, e);
+                    }
+                }, HashMap::putAll);
+            } else {
+                attributionMap = Collections.emptyMap();
+            }
+
+            // 3. 基于索引做协议 + 账号状态过滤(无远程调用)
             for (EsmInsCompany company : companyList) {
                 List<PtlAgreement> agreements = company.getAgreements();
                 if (CollUtil.isEmpty(agreements)) {
@@ -450,21 +476,14 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
                         // 归属账号状态
                         .filter(agreement -> {
                             String attributionId = agreement.getAttributionId();
-                            if (attributionId == null || attributionId.isEmpty()) {
+                            if (StrUtil.isBlank(attributionId)) {
                                 return true; // 没有关联账号,不做账号校验
                             }
-                            try {
-                                com.jzg.commons.core.page.HttpResult<PtlAgreementAttribution> res =
-                                        platformClient.getAgreementAttribution2(attributionId);
-                                if (res.getCode() != 200 || res.getData() == null) {
-                                    return true; // 查不到账号信息,默认保留
-                                }
-                                PtlAgreementAttribution attr = res.getData();
-                                return "0".equals(attr.getUseStatus()) && "0".equals(attr.getQuoteStatus());
-                            } catch (Exception e) {
-                                log.warn("查询协议[{}]的归属账号异常,默认保留", agreement.getId(), e);
-                                return true;
+                            PtlAgreementAttribution attr = attributionMap.get(attributionId);
+                            if (attr == null) {
+                                return true; // 查不到账号信息,默认保留
                             }
+                            return "0".equals(attr.getUseStatus()) && "0".equals(attr.getQuoteStatus());
                         })
                         .collect(Collectors.toList());
                 company.setAgreements(validAgreements);
@@ -498,21 +517,22 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
 
         List<PtlSchemeRulesAttrLink> ptlSchemeRulesAttrLinks = ptlSchemeRulesAttrLinkMapper.selectList(new LambdaQueryWrapper<PtlSchemeRulesAttrLink>().in(PtlSchemeRulesAttrLink::getSchemeId, ptlSchemeIds));
 
-        // 将规则根据schemeId聚合转换成Map
-//        Map<String, List<PtlSchemeRulesAttrLink>> ptlSchemeRulesAttrLinkMap = ptlSchemeRulesAttrLinks.stream()
-//                .collect(Collectors.groupingBy(PtlSchemeRulesAttrLink::getSchemeId));
-
         ValidateSchemeRuleVo validateSchemeRuleVo = new ValidateSchemeRuleVo();
         validateSchemeRuleVo.builderQuoteVo(schemeRuleFilterVo, redissonClient);
         validateSchemeRuleVo.setAttrLinks(ptlSchemeRulesAttrLinks);
         HttpResult<List<String>> esmInsCompanyHttpResult = costsRuleClient.validateSchemeRule(validateSchemeRuleVo);
         List<String> insSchemeIds = esmInsCompanyHttpResult.getData();
+        if (CollUtil.isEmpty(insSchemeIds)) {
+            AssertionUtils.isFail(true, "没有可报价的保险公司");
+        }
+        // 用 HashSet 提升 contains 查找效率(O(1))
+        Set<String> insSchemeIdSet = new HashSet<>(insSchemeIds);
         //开始过滤保险公司
         //1.过滤方案
-        ptlSchemes.removeIf(ptlScheme -> !insSchemeIds.contains(ptlScheme.getId()));
-        List<String> companyIds = ptlSchemes.stream().map(ptlScheme -> ptlScheme.getCompanyId()).collect(Collectors.toList());
+        ptlSchemes.removeIf(ptlScheme -> !insSchemeIdSet.contains(ptlScheme.getId()));
+        Set<String> companyIdSet = ptlSchemes.stream().map(PtlScheme::getCompanyId).collect(Collectors.toSet());
         // 移除不匹配方案的保司,以及空协议的保司
-        companyList.removeIf(company -> !companyIds.contains(company.getId()) || CollUtil.isEmpty(company.getAgreements()));
+        companyList.removeIf(company -> !companyIdSet.contains(company.getId()) || CollUtil.isEmpty(company.getAgreements()));
         List<PtlAgreementInsCompanyVo> resVo = new ArrayList<>();
         companyList.forEach(company -> {
             PtlAgreementInsCompanyVo vo = new PtlAgreementInsCompanyVo();
@@ -524,28 +544,14 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
 
         ValidateDispatchRuleVo dispatchRuleVos = new ValidateDispatchRuleVo();
         dispatchRuleVos.setQuoteVo(validateSchemeRuleVo.getQuoteVo());
-        //2.协议调度规则数据拼接
-        String finalSystemCode = systemCode;
-        companyList.forEach(company -> {
-            PtlAgreementDispatchQuery query = new PtlAgreementDispatchQuery();
-            query.setCompanyId(company.getId());
-            HttpResult agreementDispatch = orgClient.getAgreementDispatch(query);
-            if (agreementDispatch.getCode() == 200) {
-                ObjectMapper mapper = new ObjectMapper();
-                List<PtlAgreementDispatchVo.DispatchVo> vos = new ArrayList<>();
-                Map<String, Object> data = (Map<String, Object>) agreementDispatch.getData();
-
-                Object dispatchVosObj = data.get("dispatchVos");
-                if (dispatchVosObj instanceof List) {
-                    List<Map<String, Object>> dispatchVos = (List<Map<String, Object>>) dispatchVosObj;
-                    for (Map<String, Object> map : dispatchVos) {
-                        PtlAgreementDispatchVo.DispatchVo obj = mapper.convertValue(map, PtlAgreementDispatchVo.DispatchVo.class);
-                        vos.add(obj);
-                    }
-                }
-
-                // 根据section 分组 进行拆分 规则
-                for (PtlAgreementDispatchVo.DispatchVo vo : vos) {
+        //2.协议调度规则数据拼接(一次批量查询所有保司,避免逐保司重复的全表/字典查询与串行 RPC)
+        List<String> allCompanyIds = companyList.stream().map(EsmInsCompany::getId).collect(Collectors.toList());
+        try {
+            HttpResult agreementDispatch = orgClient.getAgreementDispatchByCompanyIds(allCompanyIds);
+            if (agreementDispatch != null && agreementDispatch.getCode() == 200 && agreementDispatch.getData() != null) {
+                PtlAgreementDispatchVo dispatchVoResult = new ObjectMapper().convertValue(agreementDispatch.getData(), PtlAgreementDispatchVo.class);
+                List<ValidateDispatchRuleVo.DispatchAttrVo> dispatchAttrVos = new ArrayList<>();
+                for (PtlAgreementDispatchVo.DispatchVo vo : dispatchVoResult.getDispatchVos()) {
                     List<PtlAgreementDispatchRulesAttrLink> attrLinks = vo.getAttrLinks();
                     Map<String, List<PtlAgreementDispatchRulesAttrLink>> grouped = attrLinks.stream().collect(Collectors.groupingBy(link -> Optional.ofNullable(link.getSection()).orElse("0"), LinkedHashMap::new, Collectors.toList()));
                     ValidateDispatchRuleVo.DispatchAttrVo dispatchAttrVo = new ValidateDispatchRuleVo.DispatchAttrVo();
@@ -553,20 +559,36 @@ public class PtlSchemeServiceImpl extends ServiceImpl<PtlSchemeMapper, PtlScheme
                     dispatchAttrVo.setDispatchName(vo.getDispatchName());
                     dispatchAttrVo.setCompanyId(vo.getCompanyId());
                     dispatchAttrVo.setSectionGroups(grouped);
-                    dispatchRuleVos.getDispatchAttrVos().add(dispatchAttrVo);
+                    dispatchAttrVos.add(dispatchAttrVo);
                 }
+                dispatchRuleVos.getDispatchAttrVos().addAll(dispatchAttrVos);
             }
-        });
+        } catch (Exception e) {
+            log.warn("批量查询协议调度异常", e);
+        }
 //
         // 3. 校验调度数据
         HttpResult httpResult = costsRuleClient.validateDispatchRule(dispatchRuleVos);
         if (httpResult.getCode() == 200) {
             // 返回了调度id  通过调度id 查询动作
             List<PtlAgreementDispatchVo.DispatchVo> agreementDispatchAction = ptlAgreementDispatchService.getAgreementDispatchAction((List<String>) httpResult.getData());
+            // 构建 保司id -> DispatchVo 索引(companyId 可能为逗号分隔的多保司)
+            Map<String, PtlAgreementDispatchVo.DispatchVo> dispatchByCompany = new HashMap<>();
+            for (PtlAgreementDispatchVo.DispatchVo dispatch : agreementDispatchAction) {
+                if (dispatch.getCompanyId() == null) {
+                    continue;
+                }
+                for (String cid : dispatch.getCompanyId().split(",")) {
+                    String trimCid = cid.trim();
+                    if (!trimCid.isEmpty()) {
+                        dispatchByCompany.put(trimCid, dispatch);
+                    }
+                }
+            }
             // 如果动作中存在替换协议则 保司标志置为调度
             resVo.forEach(company -> {
                 company.setIsDispatch(0);
-                PtlAgreementDispatchVo.DispatchVo ptlAgreementDispatchVo = agreementDispatchAction.stream().filter(x -> x.getCompanyId().contains(company.getId())).findFirst().orElse(null);
+                PtlAgreementDispatchVo.DispatchVo ptlAgreementDispatchVo = dispatchByCompany.get(company.getId());
                 if (ptlAgreementDispatchVo != null) {
                     PtlAgreementDispatchAction action1 = ptlAgreementDispatchVo.getActions().stream().filter(action -> action.getActionCode().equals(ActionEnum.SPECIFY_AGREEMENT.getCode())).findFirst().orElse(null);
                     if (action1 != null) {

+ 12 - 0
tenant/organization/src/main/resources/mapper/PtlAgreementDispatchAfterActionMapper.xml

@@ -21,4 +21,16 @@
         </where>
     </select>
 
+    <select id="getAfterActionsByCompanyIds" resultMap="ActionMap">
+        select *
+        from ptl_agreement_dispatch_after_action
+        <where>
+            is_delete = 0
+            and company_id IN
+            <foreach collection="companyIds" item="cid" open="(" separator="," close=")">
+                #{cid}
+            </foreach>
+        </where>
+    </select>
+
 </mapper>