lvy 4 недель назад
Родитель
Сommit
25458e23cd

+ 179 - 67
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -82,6 +82,8 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -806,11 +808,12 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                         Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
                                         ArrayList::new
                                 ));
+
                         /*获取当前合同段节点对应的资料填报QueryInfo本地缓存信息*/
                         List<WbsTreeContractLazyQueryInfoVO> queryInfoList = this.getQueryInfoList(contractId, tableOwner);
                         Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> Func.isNotEmpty(f.getWbsId())&&Func.isNotEmpty(f.getStatus()))
                                 .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
-                        List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
+//                        List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
                         /* ================ 处理数量 ================ */
                         List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.parallelStream().filter(f -> queryInfoMaps.containsKey(f.getPKeyId())).collect(Collectors.toList());
@@ -830,11 +833,12 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                         long startTime = System.currentTimeMillis();
 //                        List<NodeVO> nodeVOList = distinctNodesAll.stream().map(this::convertToNodeVO).collect(Collectors.toList());
 //                        Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
-                        List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream1(distinctNodesAll, lowestNodesMap);
+//                        List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream1(distinctNodesAll, lowestNodesMap);
 //                        NodeVO.calculateStatusToDFS(treeNodeVOList, nodeVOMap);
                         Map<Long, Integer> nodeColorStatusMap = new HashMap<>();
-                        NodeVO.calculateStatusToDFS1(treeNodeVOList, nodeColorStatusMap);
+//                        NodeVO.calculateStatusToDFS1(treeNodeVOList, nodeColorStatusMap);
 //                        buildNodeTreeByStream(distinctNodesAll, lowestNodesMap, nodeColorStatusMap);
+                        buildNodeTreeAndCalculateStatus(distinctNodesAll, lowestNodesMap, nodeColorStatusMap);
                         // 将树形结构展开成列表
 //                        List<NodeVO> nodeVOS = this.flattenTree(treeNodeVOList);
 //                        Map<Long, Integer> nodeColorStatusMap = nodeVOS.stream().collect(Collectors.toMap(NodeVO::getPKeyId, NodeVO::getStatus, (existing, replacement) -> existing));
@@ -955,9 +959,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 
                                 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<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
-                                List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.parallelStream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
+                                List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.parallelStream().filter(f -> queryInfoMaps.containsKey(f.getPKeyId())).collect(Collectors.toList());
                                 List<Long> lowestNodeParentIdsTB = lowestNodesTB.parallelStream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
                                 List<WbsTreeContractLazyVO> resultParentNodesTB = this.getCachedParentCountNodes(sgContractId, lowestNodeParentIdsTB, nodesAll, tableOwner);
                                 Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
@@ -972,13 +976,14 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 
 //                                List<NodeVO> nodeVOList = distinctNodesAll.stream().map(this::convertToNodeVO).collect(Collectors.toList());
 //                                Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
-                                List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream1(distinctNodesAll, lowestNodesMap);
+//                                List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream1(distinctNodesAll, lowestNodesMap);
 //                                NodeVO.calculateStatusToDFS(treeNodeVOList, nodeVOMap);
 //                                List<NodeVO> nodeVOS = this.flattenTree(treeNodeVOList);
 //                                Map<Long, Integer> nodeColorStatusMap = nodeVOS.stream().collect(Collectors.toMap(NodeVO::getPKeyId, NodeVO::getStatus, (existing, replacement) -> existing));
                                 Map<Long, Integer> nodeColorStatusMap = new HashMap<>();
-                                NodeVO.calculateStatusToDFS1(treeNodeVOList, nodeColorStatusMap);
+//                                NodeVO.calculateStatusToDFS1(treeNodeVOList, nodeColorStatusMap);
 //                                buildNodeTreeByStream(distinctNodesAll, lowestNodesMap, nodeColorStatusMap);
+                                buildNodeTreeAndCalculateStatus(distinctNodesAll, lowestNodesMap, nodeColorStatusMap);
                                 if (lazyNodes.size() > 0) {
                                     Map<Long, Integer> countMap = new HashMap<>();
                                     for (WbsTreeContractLazyVO node : resultParentNodesTB) {
@@ -1301,6 +1306,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
     }
 
 
+
     private List<PrivateTreeVO> buildTree(List<WbsTreePrivate> wbsTreePrivatesNodes, String projectId) {
         List<PrivateTreeVO> privateTreeVOS = BeanUtil.copyProperties(wbsTreePrivatesNodes, PrivateTreeVO.class);
         if (!privateTreeVOS.isEmpty()) {
@@ -1349,34 +1355,68 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             long startTime = System.currentTimeMillis();
 
             /*分页查询,每次5000条*/
-            int pageSize = 5000;
+            int pageSize = 10000;
             int pageNumber = 1;
-            int offset;
-
-            nodesAll = new ArrayList<>();
-            List<WbsTreeContractLazyVO> nodesAllPage;
-            do {
-                offset = (pageNumber - 1) * pageSize;
-                nodesAllPage = jdbcTemplate.query(
-                        "SELECT p_key_id,id,parent_id " +
-                                ",sort,create_time,IFNULL(if(LENGTH (trim(full_name)) > 0, full_name, node_name), node_name) AS fullName " +
-                                "FROM m_wbs_tree_contract " +
-                                "WHERE type = 1 " +
-                                "AND status = 1 " +
-                                "AND is_deleted = 0 " +
-                                "AND contract_id = ? " +
-                                "LIMIT ? OFFSET ?",
-                        new Object[]{contractId, pageSize, offset},
-                        new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class)
-                );
-                nodesAll.addAll(nodesAllPage);
-                pageNumber++;
-            } while (nodesAllPage.size() == pageSize);
+//            int offset;
+
+            List<WbsTreeContractLazyVO> nodes = new CopyOnWriteArrayList<>();
+//            List<WbsTreeContractLazyVO> nodesAllPage;
+            Integer count = jdbcTemplate.queryForObject("select count(1) FROM m_wbs_tree_contract where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractId, Integer.class);
+            if (count != null && count > 0) {
+                int pageCount = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+                CountDownLatch countDownLatch = new CountDownLatch(pageCount);
+                for (int i = 1; i <= pageCount; i++) {
+                    int offset = (i - 1) * pageSize;
+                    new Thread(() -> {
+                        try {
+                            List<WbsTreeContractLazyVO> query = jdbcTemplate.query(
+                                    "SELECT p_key_id,id,parent_id " +
+                                            ",sort,create_time,IFNULL(if(LENGTH (trim(full_name)) > 0, full_name, node_name), node_name) AS fullName " +
+                                            "FROM m_wbs_tree_contract " +
+                                            "WHERE type = 1 " +
+                                            "AND status = 1 " +
+                                            "AND is_deleted = 0 " +
+                                            "AND contract_id = ? " +
+                                            "LIMIT ? OFFSET ?",
+                                    new Object[]{contractId, pageSize, offset},
+                                    new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                            nodes.addAll(query);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                        countDownLatch.countDown();
+                    }).start();
+                }
+                try {
+                    countDownLatch.await();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+//            do {
+//                offset = (pageNumber - 1) * pageSize;
+//                nodesAllPage = jdbcTemplate.query(
+//                        "SELECT p_key_id,id,parent_id " +
+//                                ",sort,create_time,IFNULL(if(LENGTH (trim(full_name)) > 0, full_name, node_name), node_name) AS fullName " +
+//                                "FROM m_wbs_tree_contract " +
+//                                "WHERE type = 1 " +
+//                                "AND status = 1 " +
+//                                "AND is_deleted = 0 " +
+//                                "AND contract_id = ? " +
+//                                "LIMIT ? OFFSET ?",
+//                        new Object[]{contractId, pageSize, offset},
+////                        new Object[]{contractId},
+//                        new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class)
+//                );
+//                nodesAll.addAll(nodesAllPage);
+//            nodesAll = nodesAllPage;
+//                pageNumber++;
+//            } while (nodesAllPage.size() == pageSize);
 
             long endTime = System.currentTimeMillis();
             long executionTime = endTime - startTime;
             _logger.info("合同段 " + contractId + " 查询所有wbs节点树 执行时间:" + executionTime + " ms");
-
+            nodesAll = nodes;
             if (nodesAll.size() > 0) {
                 //判断是否有子级,赋值
                 Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAll.stream()
@@ -1394,7 +1434,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                     }
                 }
                 //更新本地缓存
-//                localCacheNodes.put(contractId, nodesAll);
+                localCacheNodes.put(contractId, nodesAll);
             }
         }
         return nodesAll;
@@ -1422,21 +1462,22 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
         long startTime = System.currentTimeMillis();
 
         /*分页查询,每次5000条*/
-        int pageSize = 5000;
-        int pageNumber = 1;
-        int offset;
+//        int pageSize = 5000;
+//        int pageNumber = 1;
+//        int offset;
 
         List<WbsTreeContractLazyQueryInfoVO> queryInfoListPage;
 
-        do {
-            offset = (pageNumber - 1) * pageSize;
+//        do {
+//            offset = (pageNumber - 1) * pageSize;
             queryInfoListPage = jdbcTemplate.query(
-                    "SELECT wbs_id, `status` FROM u_information_query WHERE id in (SELECT id from (SELECT max(id) as id FROM u_information_query WHERE type = 1 AND contract_id = ? AND classify = ? GROUP BY wbs_id LIMIT ? offset ?) as a)",
-                    new Object[]{contractId, tableOwner, pageSize, offset},
+                    "SELECT wbs_id, `status` FROM u_information_query WHERE id in (SELECT id from (SELECT max(id) as id FROM u_information_query WHERE is_deleted = 0 AND type = 1 AND contract_id = ? AND classify = ? GROUP BY wbs_id) as a)",
+                    new Object[]{contractId, tableOwner},
+//                    new Object[]{contractId, tableOwner, pageSize, offset},
                     new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
             queryInfoList.addAll(queryInfoListPage);
-            pageNumber++;
-        } while (queryInfoListPage.size() == pageSize);
+//            pageNumber++;
+//        } while (queryInfoListPage.size() == pageSize);
 
         long endTime = System.currentTimeMillis();
         long executionTime = endTime - startTime;
@@ -1444,7 +1485,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 
         if (queryInfoList.size() > 0) {
             //更新本地缓存
-//            localCacheQueryInfos.put(cacheKey, queryInfoList);
+            localCacheQueryInfos.put(cacheKey, queryInfoList);
         }
         return queryInfoList;
     }
@@ -1471,15 +1512,16 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             /*重新计算,进行递归获取父节点计数统计*/
 //            this.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAll);
             Map<Long, List<WbsTreeContractLazyVO>> map = nodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getId));
-            recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, map);
+//            recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, map);
+            queueGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, map);
             long endTime = System.currentTimeMillis();
             long executionTime = endTime - startTime;
             _logger.info("合同段 " + contractId + " wbs节点树 数量计算 执行时间:" + executionTime + " ms");
 
-//            if (resultParentNodesTB.size() > 0) {
-//                //更新本地缓存
-//                localCacheParentCountNodes.put(cacheKey, resultParentNodesTB);
-//            }
+            if (resultParentNodesTB.size() > 0) {
+                //更新本地缓存
+                localCacheParentCountNodes.put(cacheKey, resultParentNodesTB);
+            }
         }
         return resultParentNodesTB;
     }
@@ -1556,6 +1598,40 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             this.recursiveGetParentNodes(result, collect, nodeMap);
         }
     }
+    public void queueGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, Map<Long, List<WbsTreeContractLazyVO>> nodeMap) {
+        if (lowestNodeParentIds == null || lowestNodeParentIds.isEmpty()) {
+            return;
+        }
+        Queue<Long> nodeIdQueue = new LinkedList<>(lowestNodeParentIds);
+        while (!nodeIdQueue.isEmpty()) {
+            Map<Long, Long> parentIdGroup = nodeIdQueue.stream()
+                .collect(Collectors.groupingByConcurrent(Function.identity(), Collectors.counting()));
+
+            List<WbsTreeContractLazyVO> collectedNodes = parentIdGroup.entrySet().stream()
+                .flatMap(entry -> {
+                    List<WbsTreeContractLazyVO> nodes = nodeMap.get(entry.getKey());
+                    if (nodes == null || nodes.isEmpty()) {
+                        return Stream.empty();
+                    }
+                    if (entry.getValue() > 1L) {
+                        nodes = nodes.stream().limit(1)
+                            .flatMap(node -> Collections.nCopies(entry.getValue().intValue(), node).stream())
+                            .collect(Collectors.toList());
+                    }
+                    return nodes.stream();
+                })
+                .collect(Collectors.toList());
+            List<Long> collect = collectedNodes.stream()
+                .map(WbsTreeContractLazyVO::getParentId).filter(Objects::nonNull)
+                .collect(Collectors.toList());
+            if (!collect.isEmpty()) {
+                result.addAll(collectedNodes);
+                nodeIdQueue = new LinkedList<>(collect);
+            } else {
+                nodeIdQueue.clear();
+            }
+        }
+    }
 
 
     /**
@@ -1612,24 +1688,11 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
         return result;
     }
 
-    /**
-     * 构造树形结构数据 (解决节点颜色问题)
-     *
-     * @param distinctNodesAll 去重后所有节点数据
-     * @return
-     */
-    public List<NodeVO> buildNodeTreeByStream1(List<WbsTreeContractLazyVO> distinctNodesAll,
-                                              Map<Long, WbsTreeContractLazyVO> lowestNodesMap) {
-        List<WbsTreeContractLazyVO> list = distinctNodesAll.stream().filter(f->f.getParentId()!=null).filter(f -> f.getParentId().equals(0L)).collect(Collectors.toList());
-        Map<Long, List<WbsTreeContractLazyVO>> map = distinctNodesAll.stream().filter(f->f.getParentId()!=null).collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
-        Map<Long, NodeVO> nodeVOMap = new HashMap<>();
-        return recursionFnNodeTree(list, map, lowestNodesMap,nodeVOMap);
-    }
 
-    public List<NodeVO> recursionFnNodeTree
+    public Set<Integer> buildNodeTreeAndCalculateStatus
             (List<WbsTreeContractLazyVO> list, Map<Long, List<WbsTreeContractLazyVO>> map,
-             Map<Long, WbsTreeContractLazyVO> lowestNodesMap, Map<Long, NodeVO> nodeVOMap) {
-        List<NodeVO> result = new ArrayList<>();
+             Map<Long, WbsTreeContractLazyVO> lowestNodesMap, Map<Long, Integer> nodeVOMap, Map<Long, Integer> nodeColorStatusMap) {
+        Set<Integer> result = new HashSet<>();
         for (WbsTreeContractLazyVO vo : list) {
             if (vo.getHasChildren().equals(0)) {
                 WbsTreeContractLazyVO lowestNodeVO = lowestNodesMap.getOrDefault(vo.getPKeyId(), null);
@@ -1641,21 +1704,70 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                 //非最底层节点,颜色默认=1黑色
                 vo.setColorStatus(1);
             }
-            //转换为NodeVO
-            NodeVO nodeVO = convertToNodeVO(vo);
-            nodeVOMap.put(nodeVO.getPKeyId(), nodeVO);
+            Integer status = vo.getColorStatus() != null ? vo.getColorStatus() : 1;
+            nodeVOMap.put(vo.getPKeyId(), status);
             List<WbsTreeContractLazyVO> childrenList = map.get(vo.getId());
             if (childrenList != null && !childrenList.isEmpty()) {
                 List<WbsTreeContractLazyVO> collect = childrenList.stream().filter(child -> !nodeVOMap.containsKey(child.getPKeyId()))
                         .collect(Collectors.toList());
                 if (!collect.isEmpty()) {
-                    nodeVO.setChildren(recursionFnNodeTree(collect, map, lowestNodesMap, nodeVOMap));
+                    Set<Integer> nodeVOS = buildNodeTreeAndCalculateStatus(collect, map, lowestNodesMap, nodeVOMap, nodeColorStatusMap);
+                    Integer status1 = calculateNodeStatus(nodeVOS);
+                    if (status1 != null) {
+                        status = status1;
+                    }
+                    nodeColorStatusMap.put(vo.getPKeyId(), status);
                 }
             }
-            result.add(nodeVO);
+            result.add(status);
         }
         return result;
     }
+    // 1 未填报 2已填报 3待审批 4 已审批
+    public Integer calculateNodeStatus(Set<Integer> childStatusList) {
+        //最底层节点直接返回
+        if (childStatusList ==  null || childStatusList.isEmpty()) {
+            return null;
+        }
+        //判断子级
+        //如果子节点都是相同的状态,则父节点状态也为该状态
+        if (childStatusList.size() == 1) {
+            return childStatusList.iterator().next();
+        }
+        //判断是否存在同时只存在1、3的情况
+        if (childStatusList.contains(1) && childStatusList.contains(3) && !childStatusList.contains(2)) {
+            return 2;
+        }
+        //判断是否存在同时只存在3、4的情况
+        if (childStatusList.contains(3) && childStatusList.contains(4) && !childStatusList.contains(1) && !childStatusList.contains(2)) {
+            return 3;
+        }
+        //判断是否存在只有1但不全是1的情况
+        if (childStatusList.contains(1) && !childStatusList.contains(2) && !childStatusList.contains(3) && !childStatusList.contains(4)) {
+            return 2;
+        }
+
+        //判断是否存在只有2但不全是2的情况
+        if (childStatusList.contains(2) && !childStatusList.contains(1) && !childStatusList.contains(3) && !childStatusList.contains(4)) {
+            return 2;
+        }
+
+        //判断是否存在只有3但不全是3的情况
+        if (childStatusList.contains(3) && !childStatusList.contains(1) && !childStatusList.contains(2) && !childStatusList.contains(4)) {
+            return 3;
+        }
+
+        //其他情况,父节点状态默认为2
+        return 2;
+    }
+
+    public void buildNodeTreeAndCalculateStatus(List<WbsTreeContractLazyVO> distinctNodesAll,
+                                                        Map<Long, WbsTreeContractLazyVO> lowestNodesMap,Map<Long, Integer> nodeColorStatusMap) {
+        List<WbsTreeContractLazyVO> list = distinctNodesAll.stream().filter(f->f.getParentId()!=null).filter(f -> f.getParentId().equals(0L)).collect(Collectors.toList());
+        Map<Long, List<WbsTreeContractLazyVO>> map = distinctNodesAll.stream().filter(f->f.getParentId()!=null).collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+        Map<Long, Integer> nodeVOMap = new HashMap<>();
+        buildNodeTreeAndCalculateStatus(list, map, lowestNodesMap,nodeVOMap, nodeColorStatusMap);
+    }
 
     /**
      * 树形层级结构转为普通List