Pārlūkot izejas kodu

优化跨节点移动

cr 2 dienas atpakaļ
vecāks
revīzija
f8cef9241a

+ 7 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormulaDataBlockMapper.java

@@ -1,11 +1,18 @@
 package org.springblade.manager.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
 import org.springblade.manager.entity.FormulaDataBlock;
 
+import java.util.List;
+
 
 /**
  * @author yangyj
  */
 public interface FormulaDataBlockMapper extends BaseMapper<FormulaDataBlock> {
+    // 在FormulaDataBlockMapper中添加
+    List<FormulaDataBlock> selectBySwIdsAndContractId(@Param("swIds") List<Long> swIds,
+                                                      @Param("contractId") Long contractId,
+                                                      @Param("type") Integer type);
 }

+ 16 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormulaDataBlockMapper.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.manager.mapper.FormulaDataBlockMapper">
+
+
+    <!-- 在FormulaDataBlockMapper.xml中添加 -->
+    <select id="selectBySwIdsAndContractId" resultType="org.springblade.manager.entity.FormulaDataBlock">
+        SELECT * FROM m_formula_data_block
+        WHERE sw_id IN
+        <foreach collection="swIds" item="swId" open="(" close=")" separator=",">
+            #{swId}
+        </foreach>
+        AND contract_id = #{contractId}
+        AND type = #{type}
+    </select>
+</mapper>

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java

@@ -189,4 +189,7 @@ public interface WbsTreeContractMapper extends EasyBaseMapper<WbsTreeContract> {
     void updateWbsTreeAncestors(@Param("contract")WbsTreeContract contract);
 
     List<WbsTreeContract> getAncestorsList(@Param("pKeyIds") List<Long> longList);
+
+    List<WbsTreeContract> getChildWbsTreeContractsBatch(@Param("parentKeyIds") List<Long> parentKeyIds);
+
 }

+ 6 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml

@@ -1090,5 +1090,11 @@
         ) and is_deleted=0
         order by node_type
     </select>
+    <select id="getChildWbsTreeContractsBatch" resultType="org.springblade.manager.entity.WbsTreeContract">
+        SELECT p_key_id, ancestors, ancestors_p_id, p_id, parent_id
+        FROM m_wbs_tree_contract
+        WHERE is_deleted = 0
+          AND ancestors_p_id LIKE CONCAT('%', #{parentKeyId}, '%')
+    </select>
 
 </mapper>

+ 234 - 69
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -4960,98 +4960,263 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return  R.data(wbsTreeContractMapper.getSiblingWbsContract(pKeyId));
     }
 
+//    @Override
+//    public R moveNode(MoveNodeDTO dto) {
+//        if(dto.getLeftPkeyIds().isEmpty()){
+//            throw new ServiceException("请选择需要移动的节点");
+//        }
+//        if(dto.getRightPkeyId()==null){
+//            throw new ServiceException("请选择要移动到哪个节点");
+//        }
+//        List<WbsTreeContract> list= wbsTreeContractMapper.getWbsTreeContractsByPKeyIds(dto.getLeftPkeyIds());
+//        WbsTreeContract moveFatherNode = this.getById(list.get(0).getPId());
+//        WbsTreeContract fatherContract = this.getById(dto.getRightPkeyId());
+//        Integer leftNodeType = 0;
+//        Integer rightNodeType =0;
+//        if(list.get(0).getNodeType()!=null){
+//            if(list.get(0).getNodeType()==1){
+//                leftNodeType=1;
+//            } else if (list.get(0).getNodeType()==18) {
+//                leftNodeType=2;
+//            }else {
+//                leftNodeType=list.get(0).getNodeType()+1;
+//            }
+//        }
+//        if(fatherContract.getNodeType()!=null){
+//            if(fatherContract.getNodeType()==1){
+//                rightNodeType=1;
+//            } else if (fatherContract.getNodeType()==18) {
+//                rightNodeType=2;
+//            }else {
+//                rightNodeType=fatherContract.getNodeType()+1;
+//            }
+//        }
+//        if(leftNodeType==rightNodeType){
+//            throw new ServiceException("请勿同级节点相互移动");
+//        }
+//        if(leftNodeType<rightNodeType){
+//            throw new ServiceException("请勿向比自己层级低的节点移动");
+//        }
+//
+//
+//        String sql="SELECT * from m_formula_data_block WHERE sw_id = "+moveFatherNode.getId()+" and contract_id ="+moveFatherNode.getContractId()+" and  type =0";
+//        List<FormulaDataBlock> formulaDataBlocks1 = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(FormulaDataBlock.class));
+//
+//        String sql1="SELECT * from m_formula_data_block WHERE sw_id = "+fatherContract.getId()+" and contract_id ="+fatherContract.getContractId()+" and  type =0";
+//        List<FormulaDataBlock> formulaDataBlocks2 = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(FormulaDataBlock.class));
+//        List<ElementBlock> elementBlocks1=new ArrayList<>();
+//        List<ElementBlock> elementBlocks2=new ArrayList<>();
+//        if(formulaDataBlocks2.size()>0){
+//            if(formulaDataBlocks1.size()>0){
+//                elementBlocks1= JSON.parseArray(formulaDataBlocks1.get(0).getVal(), ElementBlock.class);
+//                elementBlocks2= JSON.parseArray(formulaDataBlocks2.get(0).getVal(), ElementBlock.class);
+//                elementBlocks2.addAll(elementBlocks1);
+//                formulaDataBlocks2.get(0).setVal(JSON.toJSONString(elementBlocks2));
+//                formulaDataBlockMapper.updateById(formulaDataBlocks2.get(0));
+//            }
+//        }else {
+//            if(formulaDataBlocks1.size()>0){
+//                elementBlocks1= JSON.parseArray(formulaDataBlocks1.get(0).getVal(), ElementBlock.class);
+//                FormulaDataBlock insert = new FormulaDataBlock();
+//                insert.setContractId(Long.parseLong(fatherContract.getContractId()));
+//                insert.setType(0);
+//                insert.setSwId(fatherContract.getId());
+//                insert.setVal(JSON.toJSONString(elementBlocks1));
+//                formulaDataBlockMapper.insert(insert);
+//            }
+//        }
+//        for (WbsTreeContract contract : list) {
+//            String oldancestorsPId = contract.getAncestorsPId();
+//            String oldancestors = contract.getAncestors();
+//            contract.setPId(fatherContract.getPKeyId());
+//            contract.setParentId(fatherContract.getId());
+//            contract.setAncestorsPId(fatherContract.getAncestorsPId()+","+contract.getPId());
+//            contract.setAncestors(fatherContract.getAncestors());
+//            //查出当前节点所有子节点。
+//            List<WbsTreeContract> childContracts = wbsTreeContractMapper.getChildWbsTreeContracts(contract.getPKeyId());
+//            if(!childContracts.isEmpty()){
+//                for (WbsTreeContract childContract : childContracts) {
+//                    String ancestorsPId =  childContract.getAncestorsPId();
+//                    ancestorsPId=ancestorsPId.replace(oldancestorsPId,contract.getAncestorsPId());
+//                    childContract.setAncestorsPId(ancestorsPId);
+//                    String ancestors = childContract.getAncestors();
+//                    ancestors=ancestors.replace(oldancestors,contract.getAncestors());
+//                    childContract.setAncestors(ancestors);
+//                    //wbsTreeContractMapper.updateAncestorsPid(ancestorsPId,ancestors,childContract.getPKeyId());
+//                }
+//                this.updateBatchById(childContracts);
+//            }
+//            //this.wbsTreeContractMapper.updateWbsTreeAncestors(contract);
+//        }
+//        this.updateBatchById(list);
+//        String ids = dto.getLeftPkeyIds().stream().map(id -> id + "").collect(Collectors.joining(","));
+//        this.wbsTreeContractStatisticsClient.updateAncestors(ids);
+//        return R.success("操作成功");
+//    }
+
     @Override
     public R moveNode(MoveNodeDTO dto) {
-        if(dto.getLeftPkeyIds().isEmpty()){
+        // 参数验证保持不变
+        if (dto.getLeftPkeyIds().isEmpty()) {
             throw new ServiceException("请选择需要移动的节点");
         }
-        if(dto.getRightPkeyId()==null){
+        if (dto.getRightPkeyId() == null) {
             throw new ServiceException("请选择要移动到哪个节点");
         }
-        List<WbsTreeContract> list= wbsTreeContractMapper.getWbsTreeContractsByPKeyIds(dto.getLeftPkeyIds());
-        WbsTreeContract moveFatherNode = this.getById(list.get(0).getPId());
-        WbsTreeContract fatherContract = this.getById(dto.getRightPkeyId());
-        Integer leftNodeType = 0;
-        Integer rightNodeType =0;
-        if(list.get(0).getNodeType()!=null){
-            if(list.get(0).getNodeType()==1){
-                leftNodeType=1;
-            } else if (list.get(0).getNodeType()==18) {
-                leftNodeType=2;
-            }else {
-                leftNodeType=list.get(0).getNodeType()+1;
-            }
-        }
-        if(fatherContract.getNodeType()!=null){
-            if(fatherContract.getNodeType()==1){
-                rightNodeType=1;
-            } else if (fatherContract.getNodeType()==18) {
-                rightNodeType=2;
-            }else {
-                rightNodeType=fatherContract.getNodeType()+1;
-            }
+
+        // 批量查询所有需要移动的节点
+        List<WbsTreeContract> list = wbsTreeContractMapper.getWbsTreeContractsByPKeyIds(dto.getLeftPkeyIds());
+        if (list.isEmpty()) {
+            throw new ServiceException("未找到需要移动的节点");
         }
-        if(leftNodeType==rightNodeType){
+
+        // 批量查询父节点信息
+        Set<Long> parentIds = list.stream()
+                .map(WbsTreeContract::getPId)
+                .collect(Collectors.toSet());
+        List<WbsTreeContract> parentNodes = this.listByIds(parentIds);
+        Map<Long, WbsTreeContract> parentNodeMap = parentNodes.stream()
+                .collect(Collectors.toMap(WbsTreeContract::getId, Function.identity()));
+
+        WbsTreeContract moveFatherNode = parentNodeMap.get(list.get(0).getPId());
+        WbsTreeContract fatherContract = this.getById(dto.getRightPkeyId());
+
+        // 节点类型校验逻辑保持不变
+        Integer leftNodeType = calculateNodeType(list.get(0).getNodeType());
+        Integer rightNodeType = calculateNodeType(fatherContract.getNodeType());
+
+        if (leftNodeType.equals(rightNodeType)) {
             throw new ServiceException("请勿同级节点相互移动");
         }
-        if(leftNodeType<rightNodeType){
+        if (leftNodeType < rightNodeType) {
             throw new ServiceException("请勿向比自己层级低的节点移动");
         }
 
+        // 批量处理FormulaDataBlock数据
+        processFormulaDataBlocks(moveFatherNode, fatherContract);
 
-        String sql="SELECT * from m_formula_data_block WHERE sw_id = "+moveFatherNode.getId()+" and contract_id ="+moveFatherNode.getContractId()+" and  type =0";
-        List<FormulaDataBlock> formulaDataBlocks1 = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(FormulaDataBlock.class));
+        // 批量更新节点关系
+        batchUpdateNodeRelations(list, fatherContract, parentNodeMap);
 
-        String sql1="SELECT * from m_formula_data_block WHERE sw_id = "+fatherContract.getId()+" and contract_id ="+fatherContract.getContractId()+" and  type =0";
-        List<FormulaDataBlock> formulaDataBlocks2 = jdbcTemplate.query(sql1, new BeanPropertyRowMapper<>(FormulaDataBlock.class));
-        List<ElementBlock> elementBlocks1=new ArrayList<>();
-        List<ElementBlock> elementBlocks2=new ArrayList<>();
-        if(formulaDataBlocks2.size()>0){
-            if(formulaDataBlocks1.size()>0){
-                elementBlocks1= JSON.parseArray(formulaDataBlocks1.get(0).getVal(), ElementBlock.class);
-                elementBlocks2= JSON.parseArray(formulaDataBlocks2.get(0).getVal(), ElementBlock.class);
-                elementBlocks2.addAll(elementBlocks1);
-                formulaDataBlocks2.get(0).setVal(JSON.toJSONString(elementBlocks2));
-                formulaDataBlockMapper.updateById(formulaDataBlocks2.get(0));
-            }
-        }else {
-            if(formulaDataBlocks1.size()>0){
-                elementBlocks1= JSON.parseArray(formulaDataBlocks1.get(0).getVal(), ElementBlock.class);
-                FormulaDataBlock insert = new FormulaDataBlock();
-                insert.setContractId(Long.parseLong(fatherContract.getContractId()));
-                insert.setType(0);
-                insert.setSwId(fatherContract.getId());
-                insert.setVal(JSON.toJSONString(elementBlocks1));
-                formulaDataBlockMapper.insert(insert);
+        String ids = dto.getLeftPkeyIds().stream()
+                .map(String::valueOf)
+                .collect(Collectors.joining(","));
+        this.wbsTreeContractStatisticsClient.updateAncestors(ids);
+
+        return R.success("操作成功");
+    }
+
+    /**
+     * 计算节点类型
+     */
+    private Integer calculateNodeType(Integer nodeType) {
+        if (nodeType == null) {
+            return 0;
+        }
+        if (nodeType == 1) {
+            return 1;
+        } else if (nodeType == 18) {
+            return 2;
+        } else {
+            return nodeType + 1;
+        }
+    }
+
+    /**
+     * 批量处理FormulaDataBlock数据
+     */
+    private void processFormulaDataBlocks(WbsTreeContract moveFatherNode, WbsTreeContract fatherContract) {
+        // 批量查询FormulaDataBlock数据
+        List<Long> swIds = Arrays.asList(moveFatherNode.getId(), fatherContract.getId());
+        List<FormulaDataBlock> allFormulaBlocks = formulaDataBlockMapper.selectBySwIdsAndContractId(
+                swIds, Long.parseLong(moveFatherNode.getContractId()), 0);
+
+        Map<Long, FormulaDataBlock> formulaBlockMap = allFormulaBlocks.stream()
+                .collect(Collectors.toMap(FormulaDataBlock::getSwId, Function.identity()));
+
+        FormulaDataBlock sourceBlock = formulaBlockMap.get(moveFatherNode.getId());
+        FormulaDataBlock targetBlock = formulaBlockMap.get(fatherContract.getId());
+
+        if (sourceBlock != null) {
+            List<ElementBlock> sourceElements = JSON.parseArray(sourceBlock.getVal(), ElementBlock.class);
+
+            if (targetBlock != null) {
+                // 合并元素
+                List<ElementBlock> targetElements = JSON.parseArray(targetBlock.getVal(), ElementBlock.class);
+                targetElements.addAll(sourceElements);
+                targetBlock.setVal(JSON.toJSONString(targetElements));
+                formulaDataBlockMapper.updateById(targetBlock);
+            } else {
+                // 创建新的FormulaDataBlock
+                FormulaDataBlock newBlock = new FormulaDataBlock();
+                newBlock.setContractId(Long.parseLong(fatherContract.getContractId()));
+                newBlock.setType(0);
+                newBlock.setSwId(fatherContract.getId());
+                newBlock.setVal(JSON.toJSONString(sourceElements));
+                formulaDataBlockMapper.insert(newBlock);
             }
         }
+    }
+
+    /**
+     * 批量更新节点关系
+     */
+    private void batchUpdateNodeRelations(List<WbsTreeContract> list, WbsTreeContract fatherContract,
+                                          Map<Long, WbsTreeContract> parentNodeMap) {
+        // 收集所有需要更新的节点ID(包括子节点)
+        Set<Long> allUpdateNodeIds = new HashSet<>();
+        Map<Long, String> oldAncestorsMap = new HashMap<>();
+        Map<Long, String> oldAncestorsPIdMap = new HashMap<>();
+
+        // 预处理:收集所有需要更新的节点和旧路径信息
         for (WbsTreeContract contract : list) {
-            String oldancestorsPId = contract.getAncestorsPId();
-            String oldancestors = contract.getAncestors();
+            allUpdateNodeIds.add(contract.getPKeyId());
+            oldAncestorsMap.put(contract.getPKeyId(), contract.getAncestors());
+            oldAncestorsPIdMap.put(contract.getPKeyId(), contract.getAncestorsPId());
+
+            // 更新当前节点信息
+            WbsTreeContract originalParent = parentNodeMap.get(contract.getPId());
             contract.setPId(fatherContract.getPKeyId());
             contract.setParentId(fatherContract.getId());
-            contract.setAncestorsPId(fatherContract.getAncestorsPId()+","+contract.getPId());
+            contract.setAncestorsPId(fatherContract.getAncestorsPId() + "," + contract.getPId());
             contract.setAncestors(fatherContract.getAncestors());
-            //查出当前节点所有子节点。
-            List<WbsTreeContract> childContracts = wbsTreeContractMapper.getChildWbsTreeContracts(contract.getPKeyId());
-            if(!childContracts.isEmpty()){
-                for (WbsTreeContract childContract : childContracts) {
-                    String ancestorsPId =  childContract.getAncestorsPId();
-                    ancestorsPId=ancestorsPId.replace(oldancestorsPId,contract.getAncestorsPId());
-                    childContract.setAncestorsPId(ancestorsPId);
-                    String ancestors = childContract.getAncestors();
-                    ancestors=ancestors.replace(oldancestors,contract.getAncestors());
-                    childContract.setAncestors(ancestors);
-                    //wbsTreeContractMapper.updateAncestorsPid(ancestorsPId,ancestors,childContract.getPKeyId());
+        }
+
+        // 批量查询所有子节点
+        List<Long> parentKeyIds = list.stream()
+                .map(WbsTreeContract::getPKeyId)
+                .collect(Collectors.toList());
+
+        List<WbsTreeContract> allChildContracts = wbsTreeContractMapper.getChildWbsTreeContractsBatch(parentKeyIds);
+
+        // 批量处理子节点更新
+        List<WbsTreeContract> nodesToUpdate = new ArrayList<>(list);
+        if (!allChildContracts.isEmpty()) {
+            for (WbsTreeContract childContract : allChildContracts) {
+                allUpdateNodeIds.add(childContract.getPKeyId());
+
+                // 找到对应的父节点信息
+                for (WbsTreeContract parentContract : list) {
+                    String oldAncestorsPId = oldAncestorsPIdMap.get(parentContract.getPKeyId());
+                    String newAncestorsPId = parentContract.getAncestorsPId();
+                    String oldAncestors = oldAncestorsMap.get(parentContract.getPKeyId());
+                    String newAncestors = parentContract.getAncestors();
+
+                    if (childContract.getAncestorsPId().contains(oldAncestorsPId)) {
+                        String ancestorsPId = childContract.getAncestorsPId().replace(oldAncestorsPId, newAncestorsPId);
+                        childContract.setAncestorsPId(ancestorsPId);
+
+                        String ancestors = childContract.getAncestors().replace(oldAncestors, newAncestors);
+                        childContract.setAncestors(ancestors);
+                        break;
+                    }
                 }
-                this.updateBatchById(childContracts);
             }
-            //this.wbsTreeContractMapper.updateWbsTreeAncestors(contract);
+            nodesToUpdate.addAll(allChildContracts);
         }
-        this.updateBatchById(list);
-        String ids = dto.getLeftPkeyIds().stream().map(id -> id + "").collect(Collectors.joining(","));
-        this.wbsTreeContractStatisticsClient.updateAncestors(ids);
-        return R.success("操作成功");
+
+        // 批量更新所有节点
+        this.updateBatchById(nodesToUpdate);
     }
 
     /**