Procházet zdrojové kódy

质检系统-质量管理-资料管理-资料填报:
新增节点、新增自定义节点、复制节点功能调整(测试环境服务器有问题暂时未测试)

LHB před 3 měsíci
rodič
revize
78f16087b1

+ 221 - 13
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1544,6 +1544,7 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
 
     /*==========================================单份复制==========================================*/
     if (("1").equals(vo.getCopyType())) {
+        //选中节点
         WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
 
         /*结果集-节点表*/
@@ -1553,49 +1554,66 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
         /*结果集-施工台账*/
         List<ConstructionLedger> saveLedger = new ArrayList<>();
 
-        /*获取子级节点、表信息*/
+        /*获取子级节点、表信息*/   //递归查询当前节点下的所有子节点 type=1 表示只查询节点
         List<WbsTreeContract> needCopyChildNodes = this.getChildNodes(needCopyNode);
         if (ObjectUtil.isEmpty(needCopyChildNodes) || needCopyChildNodes.size() == 0) {
             /*最下层级节点复制*/
             needCopyChildNodes = new ArrayList<>();
         }
+        //添加当前节点
         needCopyChildNodes.add(needCopyNode);
+        //包含所有节点和节点下的表信息
         List<WbsTreeContract> nodeChildAll = new ArrayList<>(needCopyChildNodes);
+        //根据查询出的所有节点查询节点下绑定的表信息
         List<WbsTreeContract> addChildNodesTables = this.getChildNodesTables(needCopyChildNodes, needCopyNode.getContractId());
         if (addChildNodesTables != null) {
             nodeChildAll.addAll(addChildNodesTables);
         }
 
-        /*获取数据源表(附件复制使用)*/
+        /*获取数据源表(附件复制使用)*/  //获取 表信息
         Set<WbsTreeContract> oldTabs = nodeChildAll.stream().filter(f -> (new Integer(2).equals(f.getType()))).collect(Collectors.toSet());
 
         /*重置内容*/
         Map<String, Map<String, String>> ekvMap = new HashMap<>();
 
+        // 选中节点不为空
         if (StringUtils.isNotEmpty(vo.getNeedCopyPrimaryKeyId())) {
+            //查询选中节点的父级节点
             WbsTreeContract parent = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getParentPrimaryKeyId());
+            //节点和表的id 与 随机id
             Map<Long, Long> oldToNewIdMap = new HashMap<>();
+
+            //旧节点的pkeyId和新节点的pkeyId
+            Map<Long, Long> oldPKeyIdToNewPKeyIdMap = new HashMap<>();
+            //节点和表的id 与 节点/表 实体类
             Map<String, WbsTreeContract> nodeMap = new HashMap<>();
+
             nodeChildAll.forEach(node -> {
+                oldPKeyIdToNewPKeyIdMap.put(node.getPKeyId(),SnowFlakeUtil.getId());
                 oldToNewIdMap.put(node.getId(), SnowFlakeUtil.getId());
                 nodeMap.put(node.getId().toString(), node);
             });
 
             /*获取元素表数据*/
             Map<Long, Map<String, Object>> colMaps = new HashMap<>();
+            //是否需要复制数据
             if (vo.getIsCopyData() == 1) {
+                //表名集合
                 List<String> tabNames = nodeChildAll.stream()
                         .map(WbsTreeContract::getInitTableName)
                         .filter(ObjectUtil::isNotEmpty)
                         .distinct()
                         .collect(Collectors.toList());
+                //表名集合转逗号拼接的字符串
                 String inClausePlaceholders = String.join(",", Collections.nCopies(tabNames.size(), "?"));
                 String sql = "SELECT table_name AS queryType, GROUP_CONCAT(COLUMN_name) AS ancestors " +
                         "FROM information_schema.COLUMNS WHERE table_name IN (" + inClausePlaceholders + ") " +
                         "GROUP BY table_name";
                 Object[] params = tabNames.toArray();
+                //数据库中查询 表与表对应的列名
                 List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, params);
 
+                //表名集合转Map key=表名 value=表对应的数据集合
                 Map<String, List<WbsTreeContract>> tabsGroup = nodeChildAll.stream()
                         .filter(f -> f.getType() == 2 && ObjectUtil.isNotEmpty(f.getInitTableName()))
                         .collect(Collectors.groupingBy(WbsTreeContract::getInitTableName));
@@ -1607,16 +1625,21 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                     if (ObjectUtil.isEmpty(col) || ObjectUtil.isEmpty(tabName)) {
                         continue;
                     }
-
+                    //字段集合 过滤掉不存在指定字段的表
                     List<String> filteredList = Arrays.stream(col.split(","))
                             .filter(value -> !value.equals("id") && !value.equals("p_key_id") && !value.equals("group_id"))
                             .collect(Collectors.toList());
+                    //过滤之后的字段集合
                     String keys = StringUtils.join(filteredList, ",");
+                    //根据表明查询指定数据集合
                     List<WbsTreeContract> tabs = tabsGroup.get(tabName);
                     for (WbsTreeContract tab : tabs) {
+                        //根据字段
                         String dataSql = "SELECT " + keys + " FROM " + tabName + " WHERE p_key_id = " + tab.getPKeyId() + " LIMIT 1;";
                         try {
+                            //查询指定表指定表节点的数据
                             Map<String, Object> resultMap = jdbcTemplate.queryForMap(dataSql);
+                            //删除空值
                             resultMap.values().removeIf(value -> value == null || (value instanceof String && ObjectUtil.isEmpty(value)));
                             colMaps.put(tab.getPKeyId(), resultMap);
                         } catch (EmptyResultDataAccessException e) {
@@ -1626,39 +1649,56 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 }
                 logger.info("以下元素表没有获取到对应实体表数据,已跳过 ===> 表pKeyId:[{}]", StringUtils.join(continuePkeyIds, ","));
             }
-
+            // 节点+表节点
             for (WbsTreeContract nodeOld : nodeChildAll) {
+                //新节点
                 WbsTreeContract newData = new WbsTreeContract();
+                //把旧节点中数据复制到新节点对象
                 BeanUtils.copyProperties(nodeOld, newData);
-
-                newData.setPKeyId(SnowFlakeUtil.getId());
+                //20250414-lhb-新增 新节点重新设置一个随机id TODO
+                newData.setPKeyId(oldPKeyIdToNewPKeyIdMap.containsKey(nodeOld.getPKeyId()) ? oldPKeyIdToNewPKeyIdMap.get(nodeOld.getPKeyId()) : SnowFlakeUtil.getId());
                 if (nodeOld.getNodeType() != null && nodeOld.getNodeType() == 6) {
+                    //新旧节点关联关系
                     peerMap.put(newData.getPKeyId(), nodeOld.getPKeyId());
                     //复制节点命名配置
+                    //查询节点绑定的公共配置 文件提名信息
                     WbsParam wbsParam = wbsParamClient.getWbsParam(Long.parseLong(vo.getNeedCopyPrimaryKeyId()));
                     if(wbsParam!=null){
                         wbsParam.setId(SnowFlakeUtil.getId());
                         wbsParam.setNodeId(newData.getPKeyId());
+                        //给复制的节点绑定的公共配置
                         wbsParamClient.saveWbsParam(wbsParam);
                     }
                 }
-
+                //源节点是否为复制节点 如果是则设置源节点的源节点 如何不是设置源节点id
                 if (StringUtils.isNotEmpty(nodeOld.getOldId())) {
                     newData.setOldId(nodeOld.getOldId());
                 } else {
                     newData.setOldId(nodeOld.getId().toString());
                 }
-
+                //当前节点是否为节点 还是为表节点
                 if (new Integer("1").equals(nodeOld.getType())) {
+                    //新节点的id设置为随机id
                     newData.setId(oldToNewIdMap.containsKey(nodeOld.getId()) ? oldToNewIdMap.get(nodeOld.getId()) : SnowFlakeUtil.getId());
+                    //20250414-lhb-新增
+                    newData.setTreePId(oldToNewIdMap.containsKey(nodeOld.getId()) ? oldToNewIdMap.get(nodeOld.getId()) : SnowFlakeUtil.getId());
+                    //新节点设置规划编号
                     newData.setPartitionCode(StringUtils.isNotEmpty(vo.getPartitionCode()) ? vo.getPartitionCode() : null);
                 }
+                //如果当前节点是选中节点
                 if (vo.getNeedCopyPrimaryKeyId().equals(nodeOld.getPKeyId().toString())) {
+                    //新节点父级id 为 选中节点的父级id
                     newData.setParentId(parent.getId());
+                    //20250414-lhb-新增
+                    newData.setPId(parent.getPKeyId());
+                    //新节点设置
                     newData.setNodeName(vo.getNeedCopyNodeName());
                     newData.setFullName(vo.getNeedCopyNodeName());
                 } else {
+                    //如果不是  判断旧节点的父级id是否在旧节点集合中 如果在 则设置新节点的父级id为旧节点的父级id的映射id  否则就是随机id
                     newData.setParentId(oldToNewIdMap.containsKey(nodeOld.getParentId()) ? oldToNewIdMap.get(nodeOld.getParentId()) : SnowFlakeUtil.getId());
+                    //20250414-lhb-新增
+                    newData.setPId(oldPKeyIdToNewPKeyIdMap.containsKey(nodeOld.getPId()) ? oldPKeyIdToNewPKeyIdMap.get(nodeOld.getPId()) : SnowFlakeUtil.getId());
                 }
                 newData.setCreateTime(new Date());
                 newData.setUpdateTime(new Date());
@@ -1667,7 +1707,7 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 newData.setPdfUrl(null);
                 newData.setCreateUser(AuthUtil.getUserId());
                 newData.setSort(ObjectUtil.isNotEmpty(nodeOld.getSort()) ? nodeOld.getSort() : 0);
-
+                //重构 祖级节点
                 this.restoreParent(newData, oldToNewIdMap);
 
                 saveList.add(newData);
@@ -1728,7 +1768,19 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                             .append(newString)
                             .append(");");
                 }
+
+
+
             }
+
+            //20250414-lhb-新增 添加祖级字段 ancestorsPId
+            List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(needCopyNode.getContractId()));
+            contractWbsTreeByContractId.addAll(saveList);
+            Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
+            saveList.forEach(node -> {
+                String correctAncestors = createAncestorsPId(node,collect);;
+                node.setAncestorsPId(correctAncestors);
+            });
         }
         needCopyNode.setNodeName(vo.getNeedCopyNodeName());
 
@@ -1815,6 +1867,7 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 /*解析位置信息,进行复制数据构造*/
                 if (toCopyNodes.size() == copyBatches.size()) {
                     for (int i = 0; i < toCopyNodes.size(); i++) {
+                        //当前选中节点
                         WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
                         /*获取需要复制的节点的信息*/
                         WbsTreeContract toCopyNode = toCopyNodes.get(i);
@@ -1903,6 +1956,16 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 List<WbsTreeContract> resultAll = new ArrayList<>();
                 resultAll.addAll(addNodeList);
                 resultAll.addAll(addTabList);
+
+                //20250414-lhb-新增
+                List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(contractId));
+                contractWbsTreeByContractId.addAll(resultAll);
+                Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
+                resultAll.forEach(node -> {
+                    String correctAncestors = createAncestorsPId(node,collect);;
+                    node.setAncestorsPId(correctAncestors);
+                });
+
                 List<WbsTreeContract> allData = this.reBuildAncestors(resultAll);
                 List<WbsTreeContract> nodes = allData.stream().filter(f -> f.getType().equals(1)).collect(Collectors.toList());
                 List<WbsTreeContract> tabs = allData.stream().filter(f -> f.getType().equals(2)).collect(Collectors.toList());
@@ -2307,6 +2370,8 @@ private void addCopyTabData(WbsTreeContract needCopyNode, WbsTreeContract toCopy
                         Long tabId = SnowFlakeUtil.getId();
                         objTab.setId(tabId);
                         objTab.setParentId(toCopyNode.getId());
+                        //20250414-lhb-新增
+                        objTab.setPId(toCopyNode.getPKeyId());
                         objTab.setPKeyId(SnowFlakeUtil.getId());
                         //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
                         //objTab.setIsBussShow(1);
@@ -2372,13 +2437,17 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
     //最下层级节点复制
     if (var == 1) {
         //构造节点
+        Long pId = SnowFlakeUtil.getId();
         Long id = SnowFlakeUtil.getId();
         for (WbsTreeContract needNode : needNodes) {
+            //新节点
             WbsTreeContract obj = BeanUtil.copyProperties(needNode, WbsTreeContract.class);
             if (obj != null) {
                 if (isSameNode == 0) {
                     //跨节点复制,更改父级id
                     obj.setParentId(toCopyNode.getId());
+                    //20250414-lhb-新增 添加父级节点id
+                    obj.setPId(toCopyNode.getPKeyId());
                 }
 
                 if (ObjectUtil.isNotEmpty(needNode.getOldId())) {
@@ -2387,7 +2456,7 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                     obj.setOldId(needNode.getId() + "");
                 }
 
-                obj.setPKeyId(SnowFlakeUtil.getId());
+                obj.setPKeyId(pId);
                 obj.setId(id);
                 obj.setNodeName(toCopyNode.getNodeName());
                 obj.setFullName(toCopyNode.getNodeName());
@@ -2412,6 +2481,10 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                 Long oldPKeyId = needTab.getPKeyId();
                 obj.setId(SnowFlakeUtil.getId());
                 obj.setParentId(id);
+
+                //20250414-lhb-新增 添加父级节点id
+                obj.setPId(pId);
+
                 obj.setPKeyId(SnowFlakeUtil.getId());
                 //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
                 //obj.setIsBussShow(1);
@@ -2466,7 +2539,11 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
         needCopyNode.setPartitionCode(toCopyNode.getPartitionCode());
         needCopyNode.setCreateTime(new Date());
 
+        //id字段和随机id
         Map<Long, Long> parentIdToId = new HashMap<>();
+        //20250414-lhb-新增 老对象唯一ID 和新对象唯一id
+        Map<Long, Long> oldPKeyIdToNewPkeyId = new HashMap<>();
+
         Map<Long, List<WbsTreeContract>> tabMap = needTabs.stream().collect(Collectors.groupingBy(WbsTreeContract::getParentId));
 
         //获取节点下所有表的key
@@ -2476,21 +2553,32 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
         Map<String, QueryProcessDataVO> tabColsAllByTabNameMaps = jdbcTemplate.query("SELECT table_name as queryType, GROUP_CONCAT(COLUMN_name) as ancestors from information_schema.COLUMNS where table_name in (" + joined + ") GROUP BY table_name", new BeanPropertyRowMapper<>(QueryProcessDataVO.class)).stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, Function.identity()));
         for (WbsTreeContract node : needNodes) {
             Long oldId = node.getId();
+            //新节点
             WbsTreeContract obj = BeanUtil.copyProperties(node, WbsTreeContract.class);
             if (obj != null) {
                 //构造节点
                 Long newParentId;
+                //父级id
+                Long newPId;
                 if (parentIdToId.size() > 0) {
                     //去数据源节点获取父级id对应的新id,设置成重设后的新的父级id
                     newParentId = parentIdToId.get(node.getParentId());
+                    newPId = oldPKeyIdToNewPkeyId.get(node.getPId());
                 } else {
                     //根节点
                     newParentId = needCopyNode.getId();
+                    newPId = needCopyNode.getPKeyId();
                 }
                 if (ObjectUtils.isEmpty(newParentId)) {
                     newParentId = needCopyNode.getId();
+                    newPId = needCopyNode.getPKeyId();
                 }
-                obj.setPKeyId(SnowFlakeUtil.getId());
+                //20250414-lhb-调整
+                Long pKeyId = SnowFlakeUtil.getId();
+                obj.setPKeyId(pKeyId);
+
+                //20250414-lhb-新增 保存新老id和新id的映射关系
+                oldPKeyIdToNewPkeyId.put(node.getPKeyId(),obj.getPKeyId());
 
                 if (ObjectUtil.isNotEmpty(node.getOldId())) {
                     obj.setOldId(node.getOldId());
@@ -2504,6 +2592,10 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                 //重设Id
                 obj.setId(id);
                 obj.setParentId(newParentId);
+
+                //20250414-lhb-新增 根据旧节点父级id 通过映射关系 查询对应的新节点id
+                obj.setPId(newPId);
+
                 obj.setCreateTime(new Date());
                 //获取当前复制的节点的sort
                 obj.setSort(ObjectUtils.isNotEmpty(node.getSort()) ? node.getSort() : 0);
@@ -2527,6 +2619,10 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                             Long tabId = SnowFlakeUtil.getId();
                             objTab.setId(tabId);
                             objTab.setParentId(id);
+
+                            //20240514-lhb-新增 设置父级id
+                            objTab.setPId(pKeyId);
+
                             objTab.setPKeyId(SnowFlakeUtil.getId());
                             //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
                             //objTab.setIsBussShow(1);
@@ -2574,9 +2670,13 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
         if (isSameNode == 1) {
             //同节点
             needCopyNode.setParentId(needCopyNode.getParentId());
+            //20250414-lhb-新增
+            needCopyNode.setPId(needCopyNode.getPId());
         } else {
             //跨节点
             needCopyNode.setParentId(toCopyNode.getId());
+            //20250414-lhb-新增
+            needCopyNode.setPId(toCopyNode.getPKeyId());
         }
         addNodeList.add(0, needCopyNode);
     }
@@ -2625,8 +2725,13 @@ private List<WbsTreeContract> getChildNodesTables(List<WbsTreeContract> list, St
 
 /**
  * 重塑父节点链
+ * @param newData 新节点
+ * @param oldToNewIdMap
+ *            key: 旧节点的id字段
+ *            value: 旧节点id字段绑定的随机id
  */
 private void restoreParent(WbsTreeContract newData, Map<Long, Long> oldToNewIdMap) {
+    //旧节点的祖级路径
     String ancestors = newData.getAncestors();
     if (StringUtils.isNotEmpty(ancestors)) {
         //重组后的链表
@@ -2646,6 +2751,59 @@ private void restoreParent(WbsTreeContract newData, Map<Long, Long> oldToNewIdMa
     }
 }
 
+    /**
+     * 20250414-lhb-新增
+     * 创建祖级路径
+     *
+     * 该方法用于构建给定节点的祖先路径标识符(PId)字符串
+     * 它通过追溯节点的父节点,直到达到根节点或满足特定条件为止
+     *
+     * @param node WbsTreeContract类型的节点,表示需要构建路径的起始节点
+     * @param nodeMap 一个映射,其键为节点ID,值为WbsTreeContract类型的节点对象,用于快速查找节点
+     * @return 返回一个字符串,表示构建的祖先路径标识符序列,以逗号分隔
+     */
+    private String createAncestorsPId(WbsTreeContract node,Map<Long,WbsTreeContract> nodeMap) {
+        // 初始化路径列表,用于存储祖先节点的ID
+        List<Long> path = new ArrayList<>();
+        // 从给定的节点开始
+        WbsTreeContract current = node;
+        // 初始化访问集合,用于检测循环引用
+        Set<Long> visited = new HashSet<>();
+
+        while (true) {
+            // 检查当前节点是否为根节点或无效节点
+            if (current == null || current.getPId() == null ||
+                    current.getPId() == 0 || current.getPId().equals(current.getPKeyId())) {
+                break;
+            }
+
+            // 检测循环引用
+            if (visited.contains(current.getPId())) {
+                break;
+            }
+            // 将当前节点的ID添加到已访问集合中
+            visited.add(current.getPKeyId());
+
+            // 从映射中获取当前节点的父节点
+            current = nodeMap.get(current.getPId());
+            // 如果父节点存在,则将其ID添加到路径列表的开头
+            if (current != null) {
+                path.add(0, current.getPKeyId());
+            }
+
+            // 安全限制,防止路径过长导致性能问题
+            if (path.size() > 50) {
+                break;
+            }
+        }
+        // 将根节点ID(0)添加到路径的最前面,表示路径的起点
+        path.add(0, 0L);
+        // 将路径列表转换为字符串并返回
+        return String.join(",", path.stream().map(String::valueOf).toArray(String[]::new));
+    }
+
+
+
 /**
  * 生成施工日志记录
  */
@@ -3182,8 +3340,11 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
 
     //构造参数
     if (selectedNodeList.size() > 0) {
-        //重塑关键信息
+        //重塑关键信息 旧id+新id
         Map<Long, Long> OldIdToNewIdMap = new HashMap<>();
+        // 旧pKeyId+新pKeyId
+        Map<Long, Long> OldPKeyIdToNewPKeyIdMap = new HashMap<>();
+
         Map<String, WbsTreePrivate> nodeMap = new HashMap<>();
         Map<String, WbsTreeContract> nodeMapContract = new HashMap<>();
         selectedNodeList.forEach(half -> {
@@ -3192,6 +3353,9 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
 
             WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(half, WbsTreeContract.class);
             nodeMapContract.put(half.getId().toString(), wbsTreeContract);
+
+            //20250414-lhb-新增  绑定旧keyId和新keyId
+            OldPKeyIdToNewPKeyIdMap.put(half.getPKeyId(),SnowFlakeUtil.getId());
         });
 
         //处理数据
@@ -3201,7 +3365,7 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
             BeanUtils.copyProperties(half, newData);
 
             //重塑pKeyId、id和parentId
-            newData.setPKeyId(SnowFlakeUtil.getId());
+            newData.setPKeyId(OldPKeyIdToNewPKeyIdMap.get(half.getPKeyId()));
             if (new Integer("1").equals(half.getType())) {
                 newData.setId(OldIdToNewIdMap.containsKey(half.getId()) ? OldIdToNewIdMap.get(half.getId()) : SnowFlakeUtil.getId());
             }
@@ -3215,11 +3379,13 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                     WbsTreePrivate wbsTreePrivate = nodeMap.get(half.getParentId() + "");
                     if (treeContract.getNodeType().equals(wbsTreePrivate.getNodeType()) && treeContract.getNodeName().equals(wbsTreePrivate.getNodeName())) {
                         newData.setParentId(treeContract.getId());
+                        newData.setPId(treeContract.getPKeyId());
                         var = false;
 
                         //从复制or新增节点开始操作-》选择新增节点,根节点会走到这里
                     } else if (treeContract.getNodeType().equals(wbsTreePrivate.getNodeType()) && ObjectUtil.isNotEmpty(treeContract.getOldId()) && treeContract.getOldId().equals(wbsTreePrivate.getId().toString())) {
                         newData.setParentId(treeContract.getId());
+                        newData.setPId(treeContract.getPKeyId());
                         var = false;
                     }
                 }
@@ -3232,7 +3398,18 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                                     ||
                                     half.getParentId().toString().equals(treeContract.getOldId())
                                     ? treeContract.getId() : SnowFlakeUtil.getId());
+
+
                         }
+                        // TODO  现阶段 odlId为被复制节点的Id字段的值 不能不能拿来做PId的匹配 后面考虑优化
+                        if(!newData.getPId().equals(0L)){
+                            newData.setPId(OldPKeyIdToNewPKeyIdMap.containsKey(half.getPId())
+                                    ? OldPKeyIdToNewPKeyIdMap.get(half.getPId()) : treeContract.getPKeyId().equals(half.getPId())
+                                    ||
+                                    half.getParentId().toString().equals(treeContract.getOldId())
+                                    ? treeContract.getPKeyId() : SnowFlakeUtil.getId());
+                        }
+
                     } else {
                         //非自定义节点
                         //同节点
@@ -3241,6 +3418,12 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                                 ||
                                 half.getParentId().toString().equals(treeContract.getOldId())
                                 ? treeContract.getId() : SnowFlakeUtil.getId());
+                        // TODO  现阶段 odlId为被复制节点的Id字段的值 不能不能拿来做PId的匹配 后面考虑优化
+                        newData.setPId(OldPKeyIdToNewPKeyIdMap.containsKey(half.getPId())
+                                ? OldPKeyIdToNewPKeyIdMap.get(half.getPId()) : treeContract.getPKeyId().equals(half.getPId())
+                                ||
+                                half.getParentId().toString().equals(treeContract.getOldId())
+                                ? treeContract.getPKeyId() : SnowFlakeUtil.getId());
                     }
                 }
 
@@ -3252,16 +3435,24 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                         if (("1").equals(node.getIsPeer())) {
                             //同级
                             newData.setParentId(treeContract.getParentId());
+                            newData.setPId(treeContract.getPId());
 
                         } else if (("2").equals(node.getIsPeer())) {
                             //下一级
                             newData.setParentId(treeContract.getId());
+                            newData.setPId(treeContract.getPKeyId());
 
                         }
                     }
                 } else if (new Integer("2").equals(half.getType())) {
                     //表
                     newData.setParentId(OldIdToNewIdMap.containsKey(half.getParentId()) ? OldIdToNewIdMap.get(half.getParentId()) : treeContract.getId().equals(half.getParentId()) || treeContract.getOldId().equals(half.getParentId().toString()) ? treeContract.getId() : SnowFlakeUtil.getId());
+                    // TODO  现阶段 odlId为被复制节点的Id字段的值 不能不能拿来做PId的匹配 后面考虑优化
+                    newData.setPId(OldPKeyIdToNewPKeyIdMap.containsKey(half.getPId())
+                            ? OldPKeyIdToNewPKeyIdMap.get(half.getPId()) : treeContract.getPKeyId().equals(half.getPId())
+                            ||
+                            half.getParentId().toString().equals(treeContract.getOldId())
+                            ? treeContract.getPKeyId() : SnowFlakeUtil.getId());
                 }
             }
 
@@ -3334,6 +3525,8 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
                 for (WbsTreeContract wbsTreeContract : sortList) { //重新赋值
                     if (wbsTreeContract.getPKeyId().equals(root.getPKeyId())) { //根节点
                         wbsTreeContract.setParentId(treeContract.getId());
+                        //20250414-lhb-新增
+                        wbsTreeContract.setPId(treeContract.getPKeyId());
                         wbsTreeContract.setAncestors(treeContract.getAncestors() + "," + wbsTreeContract.getParentId());
                         ancestorsMap.put(wbsTreeContract.getId(), wbsTreeContract.getAncestors());
                     }
@@ -3361,9 +3554,21 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
         for (WbsTreeContract wbsTreeContract : saveList) {
             if (topLevelNode.getPKeyId().equals(wbsTreeContract.getPKeyId())) {
                 wbsTreeContract.setParentId(treeContract.getId());
+                //20250414-lhb-新增
+                wbsTreeContract.setPId(treeContract.getPKeyId());
             }
         }
     }
+
+    //20250414-lhb-新增 添加ancestorsPId字段
+    List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(treeContract.getContractId()));
+    contractWbsTreeByContractId.addAll(saveList);
+    Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
+    saveList.forEach(node -> {
+        String correctAncestors = createAncestorsPId(node,collect);;
+        node.setAncestorsPId(correctAncestors);
+    });
+
     R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 2, treeContract);
 
     List<WbsTreeContract> nowTabs = saveList.stream().filter(f -> new Integer(2).equals(f.getType())).collect(Collectors.toList());
@@ -4177,7 +4382,10 @@ public R<Object> customAddContractNode(@RequestBody CustomAddContractNodeDTO dto
             obj.setPartitionCode(dto.getPartitionCode());
         }
         obj.setParentId(parentNode.getId());
+        //20250414-lhb-新增
+        obj.setPId(parentNode.getPKeyId());
         obj.setAncestors(parentNode.getAncestors() + "," + parentNode.getId());
+        obj.setAncestorsPId(parentNode.getAncestorsPId() + "," + parentNode.getPKeyId());
         obj.setType(1);
         obj.setStatus(1);
         obj.setIsDeleted(0);