فهرست منبع

Merge branch 'master' of http://121.41.40.202:3000/zhuwei/bladex

huangtf 1 سال پیش
والد
کامیت
84c9fab651
15فایلهای تغییر یافته به همراه376 افزوده شده و 111 حذف شده
  1. 3 4
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java
  2. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java
  3. 61 4
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/FB02.java
  4. 0 2
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java
  5. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  6. 10 4
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  7. 9 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/bean/NodeVO.java
  8. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  9. 0 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java
  10. 12 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java
  11. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/LevelInfo.java
  12. 46 9
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/TurnPoint.java
  13. 59 16
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  14. 66 33
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  15. 99 23
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

+ 3 - 4
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java

@@ -67,16 +67,15 @@ public interface InformationQueryClient {
     @PostMapping(API_PREFIX + "/updateInformationQuery")
     void updateInformationQuery(@RequestParam String link, @RequestParam String classify, @RequestParam String nodeId, @RequestParam String contractId);
 
-
-    // 更新redis数据
+    //更新redis数据
     @PostMapping(API_PREFIX + "/AsyncWbsTree")
     void AsyncWbsTree(@RequestParam String primaryKeyId, @RequestParam String parentId, @RequestParam String contractId, @RequestParam String contractIdRelation, @RequestParam String classifyType);
 
-    // 删除更新redis数据
+    //删除更新合同段节点树redis缓存
     @PostMapping(API_PREFIX + "/delAsyncWbsTree")
     void delAsyncWbsTree(@RequestParam String contractId);
 
-    // 根据wbsId获取首件填报信息
+    //根据wbsId获取首件填报信息
     @PostMapping(API_PREFIX + "/getFirstInfoByWbsId")
     InformationQuery getFirstInfoByWbsId(@RequestParam String WbsId);
 

+ 7 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -112,6 +112,8 @@ public class FormData {
     private Boolean finished = false;
     /**是否已经初始化好数据*/
     private Boolean initReady=false;
+    /**0表头表尾,1正文*/
+    private Integer structure=0;
     /**
      * 元素和单元格的映射信息
      */
@@ -267,5 +269,10 @@ public class FormData {
         return false;
     }
 
+    /*是否是测量业务数据*/
+    public boolean isContent(){
+        return this.structure==1;
+    }
+
 
 }

+ 61 - 4
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/FB02.java

@@ -2,11 +2,16 @@ package org.springblade.manager.vo;
 
 import lombok.Data;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.dto.Coords;
+import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
+import org.springblade.manager.entity.WbsTreeContract;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * @author yangyj
@@ -20,8 +25,10 @@ public class FB02 {
     private FormData name;
     private FormData passRate;
     private FormData weight;
+    private Integer  rowSize=20;
     private List<FormData> fds = new ArrayList<>();
     private List<Item> datas = new ArrayList<>();
+    private Map<FormData, BiFunction<List<Item>,Integer,List<Object>>> fm = new HashMap<>();
 
 
     @Data
@@ -70,15 +77,19 @@ public class FB02 {
          for(FormData fd:processFds){
               if(fd.getEName().contains("分项工程名称")){
                   this.subItem=fd;
+                  this.fm.put(fd,(List<Item> l,Integer pn)->l.stream().map(Item::getSubItem).collect(Collectors.toList()));
               }else if(fd.getEName().contains("序号")){
                   this.sn=fd;
+                  this.fm.put(fd,(List<Item> l,Integer pn)->IntStream.range(0, l.size()).boxed().map(i->i+pn*l.size()).collect(Collectors.toList()));
               }else if(fd.getEName().contains("实测项目")){
                   this.name=fd;
+                  this.fm.put(fd,(List<Item> l,Integer pn)->l.stream().map(Item::getName).collect(Collectors.toList()));
               }else if(fd.getEName().contains("实测合格率")){
                   this.passRate=fd;
-
+                  this.fm.put(fd,(List<Item> l,Integer pn)->l.stream().map(Item::getPassRate).collect(Collectors.toList()));
               }else if(fd.getEName().contains("权值")){
                   this.weight=fd;
+                  this.fm.put(fd,(List<Item> l,Integer pn)->l.stream().map(Item::getWeight).collect(Collectors.toList()));
               }
               if(this.subItem!=null&&this.name!=null&&this.passRate!=null&&this.weight!=null&&this.sn!=null){
                   /*匹配完成*/
@@ -93,12 +104,58 @@ public class FB02 {
     }
 
     public void initFdCoords(Map<String,String> tableKeysCoordsMap){
+        boolean f=false;
         for(FormData fd:this.fds){
             String coords =tableKeysCoordsMap.get(fd.getKey());
             if(Func.isNotBlank(coords)){
                 fd.flushCoords(coords);
+                f=true;
             }
         }
+        if(f) {
+            this.rowSize = this.fds.get(0).getCoordsList().size();
+        }
+    }
+
+    public boolean flush( List<WbsTreeContract> wtcList){
+        if(wtcList.size()>0) {
+            Map<Integer, List<Item>> pages = IntStream.range(0, datas.size()).boxed()
+                    .collect(Collectors.groupingBy(
+                            i -> i / rowSize,
+                            LinkedHashMap::new,
+                            Collectors.mapping(datas::get, Collectors.toList())
+                    ));
+            pages.forEach((k, v) -> {
+                this.fds.forEach(fd -> {
+                    putEd(k, v, fd);
+                });
+            });
+
+
+         String template="update xxxxx set content='xxxx',update_time=xxx where id =xxxx";
+
+            return true;
+        }
+       return false;
     }
 
+   /**把数据放到对应元素*/
+    private void putEd(int pn,List<Item> items, FormData fd){
+        BiFunction<List<Item>,Integer,List<Object>> fc = this.fm.get(fd);
+        if(fc!=null) {
+            List<Object> data = fc.apply(items,pn);
+            List<ElementData> list = new ArrayList<>();
+            for (int i = 0; i < data.size(); i++) {
+                Coords c = fd.getCoordsList().get(i);
+                list.add(new ElementData(pn, 0, data.get(i), c.getX(), c.getY()));
+            }
+            fd.getValues().addAll(list);
+        }
+    }
+
+    public String getSql(){
+        return "select 1";
+    }
+
+
 }

+ 0 - 2
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java

@@ -1,6 +1,5 @@
 package org.springblade.business.feignClient;
 
-import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -13,7 +12,6 @@ import org.springblade.business.service.IInformationQueryFileService;
 import org.springblade.business.service.IInformationQueryService;
 import org.springblade.business.vo.QueryProcessDataVO;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;

+ 1 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java

@@ -26,7 +26,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.manager.entity.TabBusstimeInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
-import org.springframework.scheduling.annotation.Async;
 
 import java.util.List;
 import java.util.Map;
@@ -160,4 +159,5 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
 
     //根据wbsTreeContract主键集合获取已经审批的资料
     List<Long> getInfoByNodeIds(List<Long> ids);
+
 }

+ 10 - 4
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -920,10 +920,16 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 
     @Override
     public void delAsyncWbsTree(String contractId) {
-        //模糊匹配所有以contractId开头的所有key值
-        Set<String> keys = RedisTemplate.keys("blade-manager::contract:wbstree:" + contractId + "*");
-        if (keys != null) {
-            RedisTemplate.delete(keys);
+        //模糊匹配所有以contractId开头的所有合同段节点key值
+        Set<String> keysByNodes = RedisTemplate.keys("blade-manager::contract:wbstree:" + contractId + "*");
+        if (keysByNodes != null) {
+            RedisTemplate.delete(keysByNodes);
+        }
+
+        //模糊匹配所有以contractId开头的所有资料填报key值
+        Set<String> keysByInformationQuery = RedisTemplate.keys("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "*");
+        if (keysByInformationQuery != null) {
+            RedisTemplate.delete(keysByInformationQuery);
         }
     }
 

+ 9 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/bean/NodeVO.java

@@ -27,6 +27,7 @@ public class NodeVO {
      * DFS
      *
      * @param nodeList
+     * @param nodeParentGroupToIdMap
      */
     public static void calculateStatusToDFS(List<NodeVO> nodeList, Map<Long, NodeVO> nodeParentGroupToIdMap) {
         NodeVO rootNode = findRootNode(nodeList);
@@ -42,19 +43,20 @@ public class NodeVO {
      * @param nodeParentGroupToIdMap
      */
     public static void calculateStatusToBFS(List<NodeVO> nodeList, Map<Long, NodeVO> nodeParentGroupToIdMap) {
-        //计算根节点的颜色
         NodeVO rootNode = findRootNode(nodeList);
         if (rootNode != null) {
             calculateNodeStatusToBFS(rootNode);
-
-            Queue<NodeVO> queue = new LinkedList<>();
-            queue.addAll(rootNode.getChildren());
-
+            Queue<NodeVO> queue = new LinkedList<>(rootNode.getChildren());
             while (!queue.isEmpty()) {
                 NodeVO node = queue.poll();
                 if (node != null) {
                     calculateNodeStatusToBFS(node);
 
+                    //将子节点逐个加入队列
+                    if (node.getChildren() != null) {
+                        queue.addAll(node.getChildren());
+                    }
+
                     if (node.getParentId() != null) {
                         NodeVO nodeVO = nodeParentGroupToIdMap.get(node.getParentId());
                         if (nodeVO != null) {
@@ -89,6 +91,7 @@ public class NodeVO {
      * DFS 判断节点状态
      *
      * @param node
+     * @param nodeParentGroupToIdMap
      */
     private static void calculateNodeStatusToDFS(NodeVO node, Map<Long, NodeVO> nodeParentGroupToIdMap) {
         //最底层节点直接返回
@@ -107,7 +110,7 @@ public class NodeVO {
         //如果子节点都是相同的状态,则父节点状态也为该状态
         if (childStatusList.stream().distinct().count() == 1) {
             node.setStatus(childStatusList.get(0));
-            // 更新父节点的状态
+            //更新父节点的状态
             if (node.getParentId() != null) {
                 NodeVO parentNode = nodeParentGroupToIdMap.get(node.getParentId());
                 if (parentNode != null) {

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -2201,6 +2201,7 @@ public class ExcelTabController extends BladeController {
 
         //合并pdf加载
         excelTabService.getBussPdfs(nodeId, classify, contractId, projectId);
+
         //更新缓存
         informationQueryClient.delAsyncWbsTree(contractId);
 

+ 0 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java

@@ -1,6 +1,5 @@
 package org.springblade.manager.controller;
 
-import cn.hutool.core.date.StopWatch;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -22,7 +21,6 @@ import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.FormulaBean;
-import org.springblade.manager.dto.TreeNode;
 import org.springblade.manager.dto.WbsParamBean;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.service.*;

+ 12 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java

@@ -1,5 +1,6 @@
 package org.springblade.manager.formula;
 
+import com.alibaba.fastjson.JSON;
 import com.mixsmart.utils.ListUtils;
 import com.mixsmart.utils.StringUtils;
 import org.springblade.common.utils.BaseUtils;
@@ -17,7 +18,7 @@ import static org.springblade.manager.formula.TurnPoint.*;
  * @author yangyj
  */
 public interface ITurnPointCalculator {
-    Long VERSION=202310121730L;
+    Long VERSION=202311130910L;
      String ZD_REG="(?i)zd\\d+";
      /*核心计算*/
     static List<TurnPoint> create(List<Map<String, Object>> data, LinkedHashMap<String, String> configMap,LevelInfo levelInfo) {
@@ -324,14 +325,20 @@ public interface ITurnPointCalculator {
             if (StringUtils.isNotEmpty(tp.getSc())) {
                 if (StringUtils.isNotEmpty(tp.getSj())) {
                     tp.setDx(tp.getSc0L() - tp.getSj0L());
+                    if(tp.isOutOfDx()){
+                        tp.reSetDx();
+                        tp.setSc(tp.getSj0L()+tp.getDx0L());
+                    }
                 }
-                if (StringUtils.isEmpty(tp.getQ())) {
+                /*前视缺失 或 非负前视&实测高程不符&前视在允许范围*/
+                if (StringUtils.isEmpty(tp.getQ())||(tp.getQ0L()>0&&!tp.isRealScMatch()&&tp.isWithinRangeRealQ())) {
                     tp.setQ(info.getSightHeight() - tp.getSc0L());
                 }
             } else if (StringUtils.isNotEmpty(tp.getSj())) {
-                if(StringUtils.isEmpty(tp.getDx())) {
-                    String dx = rangeList(1, 0, info.getDx(), 1, 0, 1).get(0).toString();
-                    tp.setDx(dx);
+                if(StringUtils.isEmpty(tp.getDx())||(StringUtils.isNotEmpty(tp.getDx())&&!info.isRangeOfDx(tp.getDx0L()))) {
+                  /*  String dx = rangeList(1, 0, info.getDx(), 1, 0, 1).get(0).toString();
+                    tp.setDx(dx);*/
+                    tp.reSetDx();
                 }
                 if(StringUtils.isNotEmpty(tp.getQ())){
                     double sc=info.getSightHeight()-tp.getQ0L();

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/LevelInfo.java

@@ -168,12 +168,12 @@ public class LevelInfo implements  Cloneable {
     /**判断高程偏差是否在限定范围*/
     public boolean isRangeOfDx(double x){
         try {
-            double[] dxArr = Arrays.stream(getDx().split(",")).mapToDouble(Double::parseDouble).map(e->e*0.001).toArray();
+            double[] dxArr = Arrays.stream(getDx().split("[,,]")).mapToDouble(Double::parseDouble).map(e->e*0.001).toArray();
             return dxArr[0]<=x&&x<=dxArr[1];
         }catch (Exception e){
             e.printStackTrace();
+            return false;
         }
-        return true;
     }
     /**获取最大允许高差*/
     public double maxHeightDx(){

+ 46 - 9
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/TurnPoint.java

@@ -7,8 +7,11 @@ import org.springframework.beans.BeanUtils;
 
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
+import static com.mixsmart.utils.CustomFunction.rangeList;
 import static java.math.BigDecimal.ROUND_HALF_UP;
 
 /**
@@ -243,8 +246,12 @@ public class TurnPoint {
         if(negative){
             d=  Math.abs(d);
         }
-        return d >= levelInfo.getMin() && d <= levelInfo.getStep() && levelInfo.getSightHeight() - getQ0L() == getSc0L();
+        return d >= levelInfo.getMin() && d <= levelInfo.getStep() &&isRealScMatch() ;
+    }
 
+    public boolean isRealScMatch(){
+        /*由视线高和假定的前视推导的实测高程是否与记录的实测高程相相等*/
+        return StringUtils.isEquals(StringUtils.number2StringZero(levelInfo.getSightHeight() - getQ0L(), levelInfo.getScale()), getSc());
     }
     /**判断转点前后视是否在范围*/
     public boolean isWithinRangeValueZd(String any){
@@ -255,6 +262,17 @@ public class TurnPoint {
            return false;
     }
 
+    /*获取当前真实前视高差*/
+    public double getRealQ(){
+        return this.levelInfo.getSightHeight()-this.getSc0L();
+    }
+
+    /*判断当前真实前视是否在测量范围*/
+    public boolean isWithinRangeRealQ(){
+        double d=getRealQ();
+        return d >= levelInfo.getMin() && d <= levelInfo.getStep();
+    }
+
     public Boolean needClose() {
         return this.levelInfo.getCloseZd().size() > 1&& levelInfo.isNotPersist();
     }
@@ -336,6 +354,7 @@ public class TurnPoint {
         return x;
     }
 
+
     public List<TurnPoint> close() {
         List<TurnPoint> result = this.levelInfo.getCloseZd();
         Collections.reverse(result);
@@ -442,19 +461,28 @@ public class TurnPoint {
         if(this.levelInfo.isDistance()){
             Double x= BaseUtils.milestone(this.name);
             if(x!=null) {
+                /*只要包含里程信息就必须重置等效间距*/
                 double d=x-this.levelInfo.getMilestone();
+                double symbol=d / Math.abs(d);
                 /*高差转点每次等效减小200米间距,如果还是小于当前测点与仪器高的间距则返回剩余间距*/
                 if(this.levelInfo.getMissdistance()>0) {
                     /*负向减少里程,正向则增大里程*/
-                    double reduce = this.levelInfo.getMissdistance() * (d / Math.abs(d));
-                    /*更新当前仪器里程信息*/
-                    this.levelInfo.setMilestone(this.levelInfo.getMilestone() + reduce);
-                    /*重置高差转点减少的等效间距*/
-                    this.levelInfo.setMissdistance(0d);
-                    /*重新计算测点与仪器间距*/
-                    d=x-this.levelInfo.getMilestone();
+                    double reduce = this.levelInfo.getMissdistance() * symbol;
+                    if(Math.abs(reduce)<Math.abs(d)) {
+                        /*只有当高差转点不能抵消等效间距的时候,更新当前仪器里程信息*/
+                        this.levelInfo.setMilestone(this.levelInfo.getMilestone() + reduce);
+                        /*重新计算测点与仪器间距*/
+                        d = x - this.levelInfo.getMilestone();
+                    }else{
+                        /*高差转点等效间隔不能越过测点,仪器里程设置为距离当前测点5-25米的范围*/
+                        this.levelInfo.setMilestone(x-(ThreadLocalRandom.current().nextInt(21)+5)*symbol);
+                    }
+                    /*遇到有桩号的测点必须重置高差转点减少的等效间距*/
+                    this.levelInfo.setMissdistance(0D);
+                }else{
+                    this.levelInfo.setMilestone(x-(ThreadLocalRandom.current().nextInt(21)+5)*symbol);
                 }
-                if(Math.abs(d)>=200){
+                if(Math.abs(d)>200.0001){
                     /*间距超过200则返回实际间距*/
                     return d;
                 }
@@ -463,6 +491,15 @@ public class TurnPoint {
         return 0;
     }
 
+    /*判断偏差是否在允许范围*/
+    public boolean isOutOfDx(){
+        return !this.levelInfo.isRangeOfDx(getDx0L());
+    }
+    /*重置偏差值*/
+    public void reSetDx(){
+        setDx(rangeList(1, 0, this.levelInfo.getDx(), 1, 0, 1).get(0).toString());
+    }
+
     public TurnPoint getPeer() {
         return peer;
     }

+ 59 - 16
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -399,14 +399,34 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                         List<WbsTreeContract> wbsTreeContractList = wbsTreeContractMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().in(WbsTreeContract::getPKeyId, resultNodesPKeyIds));
 
                         //获取当前合同段填报过的资料信息Map
-                        List<InformationQuery> informationQueryList;
-                        if (ObjectUtil.isEmpty(tableOwner)) {
-                            informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(InformationQuery.class));
+                        //获取当前合同段所有填报资料缓存信息
+                        List<WbsTreeContractLazyQueryInfoVO> queryInfoList;
+                        Object dataInformationQuery;
+                        if (cn.hutool.core.util.ObjectUtil.isEmpty(tableOwner)) {
+                            dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_1");
                         } else {
-                            informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(InformationQuery.class));
+                            dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_" + tableOwner);
                         }
-                        Map<Long, Integer> informationQueryMaps = informationQueryList.stream().collect(Collectors.toMap(InformationQuery::getWbsId, InformationQuery::getStatus, (v1, v2) -> v1));
-                        List<Long> pKeyIdList = new ArrayList<>(informationQueryMaps.keySet());
+                        if (dataInformationQuery != null) {
+                            queryInfoList = JSON.parseArray(dataInformationQuery.toString(), WbsTreeContractLazyQueryInfoVO.class);
+                        } else {
+                            if (cn.hutool.core.util.ObjectUtil.isEmpty(tableOwner)) {
+                                queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                if (queryInfoList.size() > 0) {
+                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_1", JSON.toJSON(array).toString());
+                                }
+                            } else {
+                                queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                if (queryInfoList.size() > 0) {
+                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_" + tableOwner, JSON.toJSON(array).toString());
+                                }
+                            }
+                        }
+                        Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> cn.hutool.core.util.ObjectUtil.isNotEmpty(f.getWbsId()))
+                                .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
+                        List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
                         //TODO 处理数量
                         //填报过的所有最底层节点
@@ -418,7 +438,7 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                         //最底层节点颜色构造后Map
                         Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
                                 .peek(vo -> {
-                                    Integer colorStatus = informationQueryMaps.get(vo.getPKeyId());
+                                    Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
                                     if (colorStatus != null) {
                                         //任务状态0=未上报=颜色2蓝色、任务状态1=待审批=颜色3橙色、任务状态2=已审批=颜色4绿色
                                         ///*任务状态3=已废除=颜色1黑色*/(2023年10月16日13:59:00 已废除改为=颜色2蓝色)
@@ -465,7 +485,7 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                                             vo.setPrimaryKeyId(node.getPKeyId());
 
                                             //设置数量
-                                            vo.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(vo.getPrimaryKeyId())) ? countMap.get(vo.getPrimaryKeyId()) : (ObjectUtil.isNotEmpty(informationQueryMaps.get(vo.getPrimaryKeyId())) ? 1L : 0L));
+                                            vo.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(vo.getPrimaryKeyId())) ? countMap.get(vo.getPrimaryKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(vo.getPrimaryKeyId())) ? 1L : 0L));
 
                                             //设置颜色
                                             Integer parentColorStatus = nodeColorStatusMap.get(vo.getPrimaryKeyId());
@@ -483,6 +503,7 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                             return R.data(this.buildWbsTreeByStreamByTreeAll(wbsTreeContractTreeAllVOS));
                         }
                     }
+
                 } else if (contractInfo.getContractType().equals(2) || contractInfo.getContractType().equals(3)) {
                     //TODO 监理、指挥部
                     Map<Long, List<WbsTreeContractTreeAllVO>> resultMaps = new LinkedHashMap<>();
@@ -541,22 +562,43 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                             resultNodesPKeyIds.addAll(nodes.stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList()));
                             List<WbsTreeContract> wbsTreeContractList = wbsTreeContractMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().in(WbsTreeContract::getPKeyId, resultNodesPKeyIds));
 
-                            List<InformationQuery> informationQueryList;
-                            if (ObjectUtil.isEmpty(tableOwner)) {
-                                informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractRelationJlyz.getContractIdSg(), new BeanPropertyRowMapper<>(InformationQuery.class));
+                            //资料信息缓存
+                            List<WbsTreeContractLazyQueryInfoVO> queryInfoList;
+                            Object dataInformationQuery;
+                            if (cn.hutool.core.util.ObjectUtil.isEmpty(tableOwner)) {
+                                dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + contractRelationJlyz.getContractIdSg() + "_1");
                             } else {
-                                informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractRelationJlyz.getContractIdSg() + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(InformationQuery.class));
+                                dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + contractRelationJlyz.getContractIdSg() + "_" + tableOwner);
+                            }
+                            if (dataInformationQuery != null) {
+                                queryInfoList = JSON.parseArray(dataInformationQuery.toString(), WbsTreeContractLazyQueryInfoVO.class);
+                            } else {
+                                if (cn.hutool.core.util.ObjectUtil.isEmpty(tableOwner)) {
+                                    queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractRelationJlyz.getContractIdSg(), new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                    if (queryInfoList.size() > 0) {
+                                        JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                        redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + contractRelationJlyz.getContractIdSg() + "_1", JSON.toJSON(array).toString());
+                                    }
+                                } else {
+                                    queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractRelationJlyz.getContractIdSg() + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                    if (queryInfoList.size() > 0) {
+                                        JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                        redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + contractRelationJlyz.getContractIdSg() + "_" + tableOwner, JSON.toJSON(array).toString());
+                                    }
+                                }
                             }
-                            Map<Long, Integer> informationQueryMaps = informationQueryList.stream().collect(Collectors.toMap(InformationQuery::getWbsId, InformationQuery::getStatus, (v1, v2) -> v1));
-                            List<Long> pKeyIdList = new ArrayList<>(informationQueryMaps.keySet());
+                            Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> cn.hutool.core.util.ObjectUtil.isNotEmpty(f.getWbsId()))
+                                    .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
+                            List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
+                            //数量
                             List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId()) && resultNodesPKeyIds.contains(f.getPKeyId())).collect(Collectors.toList());
                             List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
                             List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
                             wbsTreeContractServiceImpl.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAllTemp);
                             Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
                                     .peek(vo -> {
-                                        Integer colorStatus = informationQueryMaps.get(vo.getPKeyId());
+                                        Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
                                         if (colorStatus != null) {
                                             ///*任务状态3=已废除=颜色1黑色*/(2023年10月16日13:59:00 已废除改为=颜色2蓝色)
                                             vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 2)));
@@ -565,6 +607,7 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                                         }
                                     }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
 
+                            //颜色
                             List<NodeVO> nodeVOList = distinctNodesAll.stream().map(wbsTreeContractServiceImpl::convertToNodeVO).collect(Collectors.toList());
                             Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
                             List<NodeVO> treeNodeVOList = wbsTreeContractServiceImpl.buildNodeTreeByStream(distinctNodesAll, lowestNodesMap);
@@ -590,7 +633,7 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                                                 vo.setType(ObjectUtils.isNotEmpty(node.getNodeType()) ? node.getNodeType() : 0);
                                                 vo.setTitle(ObjectUtil.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getNodeName());
                                                 vo.setPrimaryKeyId(node.getPKeyId());
-                                                vo.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(vo.getPrimaryKeyId())) ? countMap.get(vo.getPrimaryKeyId()) : (ObjectUtil.isNotEmpty(informationQueryMaps.get(vo.getPrimaryKeyId())) ? 1L : 0L));
+                                                vo.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(vo.getPrimaryKeyId())) ? countMap.get(vo.getPrimaryKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(vo.getPrimaryKeyId())) ? 1L : 0L));
 
                                                 Integer parentColorStatus = nodeColorStatusMap.get(vo.getPrimaryKeyId());
                                                 if (parentColorStatus != null) {

+ 66 - 33
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.jfireel.expression.Expression;
 import com.mixsmart.utils.*;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang.math.IntRange;
 import org.apache.poi.ss.usermodel.*;
 import org.jsoup.nodes.Document;
 import org.springblade.common.utils.BaseUtils;
@@ -1520,34 +1521,60 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     /*调整页数并返回当所有页*/
-   public List<WbsTreeContract>  adjustPageSize(int pageSizeNow,WbsTreeContract wtc){
-         List<WbsTreeContract> list =this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getInitTableName,wtc.getInitTableName()).eq(WbsTreeContract::getContractId,wtc.getContractId()).eq(WbsTreeContract::getParentId,wtc.getParentId()).orderByDesc(WbsTreeContract::getCreateTime));
-        int length=list.size();
-         if(pageSizeNow!=length){
-                 int dx = pageSizeNow-length;
-                 if(dx>0) {
-                     /*加页*/
-                     WbsTreeContract origin = list.get(length - 1);
-                     if (origin != null) {
-                         List<WbsTreeContract>  saveList = new ArrayList<>();
-                         for (int i = 0; i < dx; i++) {
-                             WbsTreeContract target = FormulaUtils.copyPage(origin);
-                             saveList.add(target);
-                         }
-                         this.wbsTreeContractService.saveOrUpdateBatch(saveList);
-                         list.addAll(saveList);
-                         String sql="select * from "+origin.getInitTableName()+" where p_key_id ="+origin.getPKeyId();
-                     }
-                 }else{
-                    /*删页*/
-                     int cut = length+dx;
-                     List<Long> removeList = list.stream().skip(cut).map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
-                     List<WbsTreeContract> remain = list.subList(0,cut);
-                     this.wbsTreeContractService.update(Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getIsDeleted,1).in(WbsTreeContract::getPKeyId,removeList));
-                     return remain;
-                 }
-          }
-         return list;
+   public List<WbsTreeContract>  adjustPageSize(int pageSizeNow,WbsTreeContract wtc,List<FormData> processFds){
+       try {
+           List<WbsTreeContract> list =this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getInitTableName,wtc.getInitTableName()).eq(WbsTreeContract::getContractId,wtc.getContractId()).eq(WbsTreeContract::getParentId,wtc.getParentId()).orderByDesc(WbsTreeContract::getCreateTime));
+           int length=list.size();
+           if(pageSizeNow!=length){
+               int dx = pageSizeNow-length;
+               if(dx>0) {
+                   /*加页*/
+                   WbsTreeContract origin = list.get(length - 1);
+                   if (origin != null) {
+                       List<WbsTreeContract>  saveList = new ArrayList<>();
+                       for (int i = 0; i < dx; i++) {
+                           WbsTreeContract target = FormulaUtils.copyPage(origin);
+                           saveList.add(target);
+                       }
+                       this.wbsTreeContractService.saveOrUpdateBatch(saveList);
+                       list.addAll(saveList);
+                       String sql="select * from "+origin.getInitTableName()+" where p_key_id ="+origin.getPKeyId();
+                       @SuppressWarnings("unchecked")
+                       Map<String,String> maps = this.getSqlOne(sql,Map.class);
+                       if(maps!=null){
+                           Set<String> exclude = processFds.stream().filter(FormData::isContent).map(FormData::getKey).collect(Collectors.toSet());
+                           /*移除空值,还有p_key_id、id等固定字段*/
+                           List<String> keys= maps.entrySet().stream().filter(e->Func.isNotEmpty(e.getValue())||exclude.contains(e.getKey())||"p_Key_id".equals(e.getKey())||"id".equals(e.getKey())).map(Map.Entry::getKey).collect(Collectors.toList());
+                           List<String> fields = new ArrayList<>(Arrays.asList("id","p_key_id"));
+                           fields.addAll(keys);
+                           List<String>  values = new ArrayList<>();
+                           keys.forEach(k->{
+                                values.add(maps.get(k));
+                           });
+                           String fieldStr= fields.stream().collect(Collectors.joining(",","(",")"));
+                           String  valueStr=  saveList.stream().map(w->{
+                               List<String> l = new ArrayList<>(values);
+                               l.add(0,w.getPKeyId().toString());
+                               l.add(0,SnowFlakeUtil.getId().toString());
+                               return l.stream().collect(Collectors.joining(",","(",")"));
+                           }).collect(Collectors.joining(","));
+                           String template ="insert into "+origin.getInitTableName()+fieldStr+"  values "+valueStr;
+                           this.jdbcTemplate.execute(template);
+                       }
+                   }
+               }else{
+                   /*删页*/
+                   int cut = length+dx;
+                   List<Long> removeList = list.stream().skip(cut).map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
+                   List<WbsTreeContract> remain = list.subList(0,cut);
+                   this.wbsTreeContractService.update(Wrappers.<WbsTreeContract>lambdaUpdate().set(WbsTreeContract::getIsDeleted,1).in(WbsTreeContract::getPKeyId,removeList));
+                   return remain;
+               }
+           }
+           return list;
+       }catch (Exception e){
+           return Collections.emptyList();
+       }
    }
 
     @Override
@@ -1652,8 +1679,12 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<Map<String,Object>> listMaps=this.jdbcTemplate.queryForList(sql,args);
         if(listMaps.size()>0){
             Map<String,Object> target = listMaps.get(0);
-            if (Map.class.equals(clazz)) {
-                return (T) target;
+            if (Map.class.isAssignableFrom(clazz)) {
+                Map<String, String> result = new HashMap<>();
+                for (Map.Entry<String, Object> entry : target.entrySet()) {
+                    result.put(entry.getKey(), Func.toStr(entry.getValue()));
+                }
+                return clazz.cast(result);
             }
             return BeanUtil.toBean(target,clazz);
         }
@@ -2242,7 +2273,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
     @Override
     public List<FormData> createFormDataByTableName(String tableNames) {
-        return this.getSqlList("select b.id, CONCAT(a.tab_en_name,':',b.e_key) code,a.tab_ch_name tableChName,b.e_name eName ,b.e_allow_deviation eAllowDeviation ,b.e_length eLength,c.dict_value eType " +
+        return this.getSqlList("select b.id, CONCAT(a.tab_en_name,':',b.e_key) code,a.tab_ch_name tableChName,b.e_name eName ,b.e_allow_deviation eAllowDeviation ,b.e_length eLength,b.structure,c.dict_value eType " +
                         "from m_table_info a JOIN m_wbs_form_element b on a.id=b.f_id and b.is_deleted=0  " +
                         "LEFT JOIN (select dict_key, dict_value from blade_dict where code ='data_type' and parent_id > 0 and is_sealed = 0 and is_deleted = 0 )c on b.e_type=c.dict_key" +
                         " where  a.tab_en_name in('"+ tableNames+"')"
@@ -2420,8 +2451,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     Map<String,String> tableKeysCoordsMap= FormulaUtils.getElementCell(wtc.getHtmlUrl());
                     fb02.initFdCoords(tableKeysCoordsMap);
                     /*根据数据长度,增减页数*/
-                    List<WbsTreeContract> pages= this.adjustPageSize(10,wtc);
-
+                    List<WbsTreeContract> wtcList= this.adjustPageSize(fb02.getPageNum(),wtc,processFds);
+                    if(fb02.flush(wtcList)) {
+                        this.jdbcTemplate.execute(fb02.getSql());
+                    }
                  }
                 return R.success("成功");
             }

+ 99 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -58,6 +58,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -78,7 +79,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     @Autowired
     StringRedisTemplate redisTemplate;
 
-    
+
     @Override
     public List<WbsTreeContract> selectQueryCurrentNodeByAncestors(List<String> ids, String contractId) {
         return this.baseMapper.selectQueryCurrentNodeByAncestors(ids, contractId);
@@ -710,6 +711,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                             redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                         }
                     }
+
                     //获取当前层懒加载节点
                     List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id) AS drawingsId,id,parent_id,node_type,type,wbs_type,is_concrete,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                     if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
@@ -726,12 +728,30 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 ArrayList::new
                         ));
 
-                        //获取当前合同段所有填报资料信息
+                        //获取当前合同段所有填报资料缓存信息
                         List<WbsTreeContractLazyQueryInfoVO> queryInfoList;
+                        Object dataInformationQuery;
                         if (ObjectUtil.isEmpty(tableOwner)) {
-                            queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                            dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_1");
+                        } else {
+                            dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_" + tableOwner);
+                        }
+                        if (dataInformationQuery != null) {
+                            queryInfoList = JSON.parseArray(dataInformationQuery.toString(), WbsTreeContractLazyQueryInfoVO.class);
                         } else {
-                            queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                            if (ObjectUtil.isEmpty(tableOwner)) {
+                                queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                if (queryInfoList.size() > 0) {
+                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_1", JSON.toJSON(array).toString());
+                                }
+                            } else {
+                                queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                if (queryInfoList.size() > 0) {
+                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + contractId + "_" + tableOwner, JSON.toJSON(array).toString());
+                                }
+                            }
                         }
                         Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> ObjectUtil.isNotEmpty(f.getWbsId()))
                                 .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
@@ -739,8 +759,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
                         //TODO 处理数量
                         //填报过的所有最底层节点
-                        List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
-                        List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
+                        List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.parallelStream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
+                        List<Long> lowestNodeParentIdsTB = lowestNodesTB.parallelStream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
                         List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
                         this.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAll);
 
@@ -831,19 +851,6 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     for (String sgContractId : contractIds) {
                         ContractInfo sgContractInfo = jdbcTemplate.query("select contract_name from m_contract_info where id = " + sgContractId, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
                         if (sgContractInfo != null) {
-                            /*//获取当前合同段所有缓存节点信息
-                            List<WbsTreeContractLazyVO> nodesAll;
-                            Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + sgContractId);
-                            if (data != null) {
-                                nodesAll = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
-                            } else {
-                                nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
-                                if (nodesAll.size() > 0) {
-                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
-                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + sgContractId, JSON.toJSON(array).toString());
-                                }
-                            }*/
-
                             //获取当前合同段所有缓存节点信息
                             List<WbsTreeContractLazyVO> nodesAll;
                             Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + sgContractId);
@@ -886,12 +893,30 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                         ArrayList::new
                                 ));
 
-                                //获取当前合同段所有填报资料信息
+                                //获取当前合同段所有填报资料缓存信息
                                 List<WbsTreeContractLazyQueryInfoVO> queryInfoList;
+                                Object dataInformationQuery;
                                 if (ObjectUtil.isEmpty(tableOwner)) {
-                                    queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                    dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + sgContractId + "_1");
                                 } else {
-                                    queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + sgContractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                    dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + sgContractId + "_" + tableOwner);
+                                }
+                                if (dataInformationQuery != null) {
+                                    queryInfoList = JSON.parseArray(dataInformationQuery.toString(), WbsTreeContractLazyQueryInfoVO.class);
+                                } else {
+                                    if (ObjectUtil.isEmpty(tableOwner)) {
+                                        queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                        if (queryInfoList.size() > 0) {
+                                            JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                            redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + sgContractId + "_1", JSON.toJSON(array).toString());
+                                        }
+                                    } else {
+                                        queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + sgContractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                        if (queryInfoList.size() > 0) {
+                                            JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
+                                            redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + sgContractId + "_" + tableOwner, JSON.toJSON(array).toString());
+                                        }
+                                    }
                                 }
                                 Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> ObjectUtil.isNotEmpty(f.getWbsId()))
                                         .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
@@ -1374,7 +1399,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
      * @param lowestNodeParentIds 最底层节点ParentIds
      * @param nodesAll            所有节点
      */
-    public void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, List<WbsTreeContractLazyVO> nodesAll) {
+    /*public void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, List<WbsTreeContractLazyVO> nodesAll) {
         if (lowestNodeParentIds.isEmpty()) {
             return;
         }
@@ -1412,6 +1437,57 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
         }
 
+        //结果集
+        List<Long> collect = Stream.concat(parentNodes.stream(), multipleParentNodes.stream())
+                .map(WbsTreeContractLazyVO::getParentId)
+                .collect(Collectors.toList());
+
+        if (!collect.isEmpty()) {
+            result.addAll(parentNodes);
+            result.addAll(multipleParentNodes);
+            this.recursiveGetParentNodes(result, collect, nodesAll);
+        }
+    }*/
+    public void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, List<WbsTreeContractLazyVO> nodesAll) {
+        if (lowestNodeParentIds.isEmpty()) {
+            return;
+        }
+
+        //父级Id与出现的次数Map
+        Map<Long, Long> parentIdGroup = lowestNodeParentIds.parallelStream()
+                .collect(Collectors.groupingByConcurrent(Function.identity(), Collectors.counting()));
+
+        Set<Long> keysWithValueOne = new HashSet<>(); //单次
+        Map<Long, Long> keysWithValueSome = new ConcurrentHashMap<>(); //多次
+
+        parentIdGroup.forEach((key, value) -> {
+            if (value == 1L) {
+                keysWithValueOne.add(key);
+            } else {
+                keysWithValueSome.put(key, value);
+            }
+        });
+
+        //批量查询单次节点
+        List<WbsTreeContractLazyVO> parentNodes = new ArrayList<>();
+        if (!keysWithValueOne.isEmpty()) {
+            parentNodes = nodesAll.parallelStream()
+                    .filter(f -> keysWithValueOne.contains(f.getId()))
+                    .collect(Collectors.toList());
+        }
+
+        //批量查询多次节点
+        List<WbsTreeContractLazyVO> multipleParentNodes = new ArrayList<>();
+        keysWithValueSome.forEach((key, count) -> {
+            List<WbsTreeContractLazyVO> nodes = nodesAll.parallelStream()
+                    .filter(f -> key.equals(f.getId()))
+                    .limit(1)  //限制只取一个
+                    .collect(Collectors.toList());
+            if (!nodes.isEmpty()) {
+                multipleParentNodes.addAll(Collections.nCopies(count.intValue(), nodes.get(0)));
+            }
+        });
+
         //结果集
         List<Long> collect = Stream.concat(parentNodes.stream(), multipleParentNodes.stream())
                 .map(WbsTreeContractLazyVO::getParentId)