|
@@ -4,11 +4,15 @@ import cn.hutool.core.comparator.FuncComparator;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.interfaces.Func;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Constants;
|
|
|
import com.google.common.collect.Maps;
|
|
|
import com.nationrel.modules.rp.constant.RpConstant;
|
|
|
import com.nationrel.modules.rp.dto.PredictionStruTreeImport;
|
|
|
import com.nationrel.modules.rp.entity.PredictionStruTree;
|
|
|
import com.nationrel.modules.rp.mapper.PredictionStruTreeMapper;
|
|
|
+import com.nationrel.modules.rp.req.DelStructureReq;
|
|
|
+import com.nationrel.modules.rp.req.PasteStructureReq;
|
|
|
import com.nationrel.modules.rp.req.SaveStructureReq;
|
|
|
import com.nationrel.modules.rp.resp.PredictionStruTreeResp;
|
|
|
import com.nationrel.modules.rp.service.IPredictionStruTreeService;
|
|
@@ -19,6 +23,7 @@ import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.shiro.SecurityUtils;
|
|
|
import org.jeecg.common.exception.NationrelBootException;
|
|
|
import org.jeecg.common.system.vo.LoginUser;
|
|
|
+import org.jeecg.common.util.WrapperUtil;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
@@ -61,6 +66,7 @@ public class PredictionStruTreeServiceImpl extends ServiceImpl<PredictionStruTre
|
|
|
|
|
|
List<PredictionStruTree> predictionStruTreeList = this.list(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
.eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getIsDelete, RpConstant.NOT_DELETE)
|
|
|
.between(PredictionStruTree::getLeftNo, leftNo, rightNo));
|
|
|
List<PredictionStruTreeResp> list = predictionStruTreeList.stream().map(tree -> {
|
|
|
PredictionStruTreeResp resp = new PredictionStruTreeResp();
|
|
@@ -192,6 +198,126 @@ public class PredictionStruTreeServiceImpl extends ServiceImpl<PredictionStruTre
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void deleteStructure(String predictionId, String struId) {
|
|
|
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
+ String uuid = UuidUtils.getUUID();
|
|
|
+ // 取得当前节点
|
|
|
+ PredictionStruTree predictionStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getStruId, struId));
|
|
|
+ if (ObjectUtils.isNotEmpty(predictionStruTree)) {
|
|
|
+ PredictionStruTree tree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getStruId, struId));
|
|
|
+ int leftNo = predictionStruTree.getLeftNo();
|
|
|
+ int rightNo = predictionStruTree.getRightNo();
|
|
|
+ int version = tree.getVersionNo();
|
|
|
+ tree.setRecycleId(uuid);
|
|
|
+ tree.setIsDelete(RpConstant.IS_DELETE);
|
|
|
+ tree.setUpdateUserBy(sysUser.getUsername());
|
|
|
+ tree.setUpdateTime(new Date());
|
|
|
+ tree.setVersionNo(tree.getVersionNo() + 1);
|
|
|
+ int update = predictionStruTreeMapper.update(tree, new LambdaUpdateWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getVersionNo, version)
|
|
|
+ .eq(PredictionStruTree::getStruId, struId));
|
|
|
+ List<PredictionStruTree> childStruTree = predictionStruTreeMapper.selectList(new LambdaUpdateWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .ge(PredictionStruTree::getLeftNo, leftNo)
|
|
|
+ .le(PredictionStruTree::getLeftNo, rightNo));
|
|
|
+ childStruTree.forEach(child -> {
|
|
|
+ int childVersion = child.getVersionNo();
|
|
|
+ child.setRecycleId(uuid);
|
|
|
+ child.setIsDelete(RpConstant.IS_DELETE);
|
|
|
+ child.setUpdateUserBy(sysUser.getUsername());
|
|
|
+ child.setUpdateTime(new Date());
|
|
|
+ child.setVersionNo(child.getVersionNo() + 1);
|
|
|
+ int childUpdate = predictionStruTreeMapper.update(child, new LambdaUpdateWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getVersionNo, childVersion)
|
|
|
+ .eq(PredictionStruTree::getStruId, child.getStruId()));
|
|
|
+ if (childUpdate == 0) {
|
|
|
+ throw new NationrelBootException("当前节点有变更,刷新后再操作");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (update == 0) {
|
|
|
+ throw new NationrelBootException("当前节点有变更,刷新后再操作");
|
|
|
+ }
|
|
|
+
|
|
|
+ PredictionStruTree parentTreeNode = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getStruId, tree.getParentStruId()));
|
|
|
+ int changeNum = rightNo - leftNo + 1;
|
|
|
+ if ((parentTreeNode.getRightNo() - parentTreeNode.getLeftNo() - 1) == changeNum) {
|
|
|
+ parentTreeNode.setType(RpConstant.TREENODE_TYPE_LEAF);
|
|
|
+ parentTreeNode.setUpdateUserBy(sysUser.getUsername());
|
|
|
+ parentTreeNode.setUpdateTime(new Date());
|
|
|
+ predictionStruTreeMapper.updateById(parentTreeNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void pasteStructure(PasteStructureReq pasteStructureReq) throws Exception {
|
|
|
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
+ PredictionStruTree copyStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, pasteStructureReq.getPredictionId())
|
|
|
+ .eq(PredictionStruTree::getStruId, pasteStructureReq.getSrcStruId()));
|
|
|
+ if (ObjectUtils.isEmpty(copyStruTree)) {
|
|
|
+ throw new NationrelBootException("目标节点不存在");
|
|
|
+ }
|
|
|
+ PredictionStruTree selectStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, pasteStructureReq.getPredictionId())
|
|
|
+ .eq(PredictionStruTree::getStruId, pasteStructureReq.getStruId()));
|
|
|
+ if (ObjectUtils.isEmpty(selectStruTree)) {
|
|
|
+ throw new NationrelBootException("选择节点不存在");
|
|
|
+ }
|
|
|
+ if (pasteStructureReq.getOptType() == 2) {
|
|
|
+ // 判断被剪切的节点是否为父子关系(父节点不能剪切到子节点)
|
|
|
+ Long count = predictionStruTreeMapper.selectCount(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, pasteStructureReq.getPredictionId())
|
|
|
+ .eq(PredictionStruTree::getStruId, selectStruTree.getStruId())
|
|
|
+ .gt(PredictionStruTree::getLeftNo, copyStruTree.getLeftNo())
|
|
|
+ .lt(PredictionStruTree::getLeftNo, copyStruTree.getRightNo()));
|
|
|
+ if (count > 0) {
|
|
|
+ throw new NationrelBootException("父节点不能剪切到子节点");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询指定结构下第一个结构的左序号
|
|
|
+ PredictionStruTree firstStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, pasteStructureReq.getPredictionId())
|
|
|
+ .ne(PredictionStruTree::getIsDelete, RpConstant.IS_DELETE)
|
|
|
+ .eq(PredictionStruTree::getParentStruId, selectStruTree.getStruId())
|
|
|
+ .orderByAsc(PredictionStruTree::getLeftNo)
|
|
|
+ .last("limit 0, 1"));
|
|
|
+
|
|
|
+ PredictionStruTree parentRdfmStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, pasteStructureReq.getPredictionId())
|
|
|
+ .eq(PredictionStruTree::getStruId, pasteStructureReq.getStruId()));
|
|
|
+
|
|
|
+ // 1、批量插入复制节点,各节点标识要重新生成,由于属于新建节点,原来关系如果保留,会产生网的冲突。因此,不拷贝关系;(原则,网关系在节点做删除,复制新建操作时,不保留(除合并))
|
|
|
+ if (pasteStructureReq.getOptType() == 1) {
|
|
|
+ int no = 0;
|
|
|
+ if (ObjectUtils.isNotEmpty(firstStruTree)) {
|
|
|
+ no = firstStruTree.getRightNo();
|
|
|
+ } else {
|
|
|
+ no = selectStruTree.getRightNo();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 拷贝
|
|
|
+ this.copy(sysUser, parentRdfmStruTree, pasteStructureReq.getPredictionId(),
|
|
|
+ pasteStructureReq.getStruId(), copyStruTree,
|
|
|
+ pasteStructureReq.getSrcStruId(), no);
|
|
|
+ } else if (pasteStructureReq.getOptType() == 2) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private PredictionStruTree buildStruTree(String rpId, String struId, String pid, String name) {
|
|
|
PredictionStruTree struTree = new PredictionStruTree();
|
|
|
struTree.setPredictionId(rpId);
|
|
@@ -320,8 +446,153 @@ public class PredictionStruTreeServiceImpl extends ServiceImpl<PredictionStruTre
|
|
|
for (PredictionStruTree struTree: struTreeList) {
|
|
|
struTree.setInsertUserBy(userName);
|
|
|
struTree.setInsertTime(new Date());
|
|
|
+ struTree.setIsDelete(RpConstant.NOT_DELETE);
|
|
|
batchStruTrees.add(struTree);
|
|
|
}
|
|
|
this.saveBatch(batchStruTrees);
|
|
|
}
|
|
|
+
|
|
|
+ private Map<String, String> copy(LoginUser user, PredictionStruTree parentStruTree, String predictionId,
|
|
|
+ String parentStruId, PredictionStruTree copyStruTree, String copyStruId,
|
|
|
+ Integer firstStruLeftNo) throws Exception {
|
|
|
+ // 存放旧struid与newstruid信息
|
|
|
+ Map<String, String> newStruIdMap = null;
|
|
|
+ // 1.1 计算出要批量插入节点的数据,并在目标节点处预留,更改目标节点的类型
|
|
|
+ // a、更改目标节点的类型
|
|
|
+ if (parentStruTree.getRightNo() - parentStruTree.getLeftNo() == 1) {
|
|
|
+ parentStruTree.setType(RpConstant.TREENODE_TYPE_NONLEAF);
|
|
|
+ parentStruTree.setUpdateUserBy(user.getUsername());
|
|
|
+ parentStruTree.setUpdateTime(new Date());
|
|
|
+ predictionStruTreeMapper.updateById(parentStruTree);
|
|
|
+ }
|
|
|
+ int rightNo = parentStruTree.getRightNo();
|
|
|
+ PredictionStruTree sonNodeOfStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getParentStruId, parentStruId)
|
|
|
+ .orderByDesc(PredictionStruTree::getLeftNo)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (ObjectUtils.isNotEmpty(sonNodeOfStruTree)) {
|
|
|
+ rightNo = sonNodeOfStruTree.getRightNo() + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ int nodeCnt = copyStruTree.getRightNo() - copyStruTree.getLeftNo() + 1;
|
|
|
+ predictionStruTreeMapper.updateLeftNoByChangeNum(rightNo, nodeCnt, predictionId);
|
|
|
+ predictionStruTreeMapper.updateRightNoByChangeNum(rightNo, nodeCnt, predictionId);
|
|
|
+ copyStruTree = predictionStruTreeMapper.selectOne(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, predictionId)
|
|
|
+ .eq(PredictionStruTree::getStruId, copyStruId));
|
|
|
+ newStruIdMap = this.copyAllChildTreeReturnNewStruId(parentStruTree, copyStruTree, firstStruLeftNo, user);
|
|
|
+ // 将新生成对应拷贝节点的id取出来,留作刷新后选中节点的标志
|
|
|
+ return newStruIdMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, String> copyAllChildTreeReturnNewStruId(PredictionStruTree parentStruTree, PredictionStruTree copyStruTree,
|
|
|
+ int startLeftNo, LoginUser user) {
|
|
|
+ Map<String, String> newStruIdMap = new HashMap<String, String>();
|
|
|
+ // a.左右序,深度,序号的变化特征
|
|
|
+ int offsetDeep = parentStruTree.getDeep() - copyStruTree.getDeep() + 1;
|
|
|
+
|
|
|
+ // b.取得copyRdfmStruTree节点下所有子节点,并且进行左右序,深度,序号,和标识更换
|
|
|
+ String copyPredictionId = copyStruTree.getPredictionId();
|
|
|
+ int copyLeftNo = copyStruTree.getLeftNo();
|
|
|
+ int copyRightNo = copyStruTree.getRightNo();
|
|
|
+ String parentPredictionId = parentStruTree.getPredictionId();
|
|
|
+
|
|
|
+ List<PredictionStruTree> importingTree = new ArrayList<>();
|
|
|
+ // 导出范围的所有节点id集合
|
|
|
+ Map<String, String> importStruIdMap = new HashMap<String, String>();
|
|
|
+ List<PredictionStruTree> addTrees = predictionStruTreeMapper.selectList(new LambdaQueryWrapper<PredictionStruTree>()
|
|
|
+ .eq(PredictionStruTree::getPredictionId, copyPredictionId)
|
|
|
+ .eq(PredictionStruTree::getIsDelete, RpConstant.NOT_DELETE)
|
|
|
+ .ge(PredictionStruTree::getLeftNo, copyLeftNo)
|
|
|
+ .le(PredictionStruTree::getLeftNo, copyRightNo));
|
|
|
+
|
|
|
+ // 父级节点
|
|
|
+ Map<String, String> parentMapFlag = new HashMap<String, String>();
|
|
|
+ for (PredictionStruTree tree : addTrees) {
|
|
|
+ parentMapFlag.put(tree.getParentStruId(), tree.getStruId());
|
|
|
+ // 将所有节点id保存到集合中,用于后面判断接口是否在导出范围
|
|
|
+ importStruIdMap.put(tree.getStruId(), tree.getStruId());
|
|
|
+ }
|
|
|
+ // 进行左右序,深度,序号,和标识更换
|
|
|
+ Stack<PredictionStruTree> stack = new Stack<PredictionStruTree>();
|
|
|
+ int startLeft = startLeftNo;
|
|
|
+ PredictionStruTree tmpNode = null;
|
|
|
+ String oldId;
|
|
|
+ String newId;
|
|
|
+ for (PredictionStruTree tree : addTrees) {
|
|
|
+
|
|
|
+ if (!stack.isEmpty()) {
|
|
|
+ tmpNode = stack.peek();
|
|
|
+ while (tmpNode.getRightNo() < tree.getLeftNo()) {
|
|
|
+ tmpNode = stack.pop();
|
|
|
+ tmpNode.setRightNo(startLeft++);
|
|
|
+ tmpNode = stack.peek();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断是不是叶子结点
|
|
|
+ if (parentMapFlag.containsKey(tree.getStruId())) {
|
|
|
+ // 不是叶子结点
|
|
|
+ tree.setLeftNo(startLeft++);
|
|
|
+ stack.push(tree);
|
|
|
+ } else {
|
|
|
+ tree.setLeftNo(startLeft++);
|
|
|
+ tree.setRightNo(startLeft++);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ // 判断是不是叶子结点
|
|
|
+ if (parentMapFlag.containsKey(tree.getStruId())) {
|
|
|
+ // 不是叶子结点
|
|
|
+ tree.setLeftNo(startLeft++);
|
|
|
+ stack.push(tree);
|
|
|
+ } else {
|
|
|
+ tree.setLeftNo(startLeft++);
|
|
|
+ tree.setRightNo(startLeft++);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 原结构标识
|
|
|
+ oldId = tree.getStruId();
|
|
|
+ // 新结构标识
|
|
|
+ newId = UuidUtils.getUUID();
|
|
|
+ // 记录新旧标识对应关系
|
|
|
+ newStruIdMap.put(oldId, newId);
|
|
|
+ // 将新接口的起始节点和结束节点存入map中(创建新接口时使用)
|
|
|
+ importStruIdMap.put(oldId, newId);
|
|
|
+ // 将原struid替换为新的struid
|
|
|
+ tree.setStruId(newId);
|
|
|
+ tree.setPredictionId(parentPredictionId);
|
|
|
+ tree.setDeep(tree.getDeep() + offsetDeep);
|
|
|
+// tree.setSeriesNo(reviseSeriesNo(tree.getSeriesNo(), copyRdfmStruTree.getSeriesNo(), seriesNo));
|
|
|
+ importingTree.add(tree);
|
|
|
+ }
|
|
|
+
|
|
|
+ while (!stack.isEmpty()) {
|
|
|
+ tmpNode = stack.pop();
|
|
|
+ tmpNode.setRightNo(startLeft++);
|
|
|
+ }
|
|
|
+
|
|
|
+ // c.更新节点的上级节点标识
|
|
|
+ String rootNodeParentStruId = copyStruTree.getParentStruId();
|
|
|
+ String newRootNodeParentId = parentStruTree.getStruId();
|
|
|
+ List<PredictionStruTree> newTree = new ArrayList<>();
|
|
|
+ for (PredictionStruTree tree : importingTree) {
|
|
|
+ oldId = tree.getParentStruId();
|
|
|
+ tree.setId(null);
|
|
|
+ // update5-导入结构树的结构标识和父级结构标识
|
|
|
+ tree.setParentStruId(newStruIdMap.get(oldId));
|
|
|
+ // up6-导入结构树根节点的父级结构标识
|
|
|
+ if (rootNodeParentStruId.equals(oldId)) {
|
|
|
+ tree.setParentStruId(newRootNodeParentId);
|
|
|
+ }
|
|
|
+ tree.setInsertUserBy(user.getUsername());
|
|
|
+ tree.setInsertTime(new Date());
|
|
|
+ newTree.add(tree);
|
|
|
+ }
|
|
|
+ this.saveBatch(newTree);
|
|
|
+ importingTree.clear();
|
|
|
+ return newStruIdMap;
|
|
|
+ }
|
|
|
}
|