diff --git a/backend/framework/sdk/src/main/resources/i18n/project.properties b/backend/framework/sdk/src/main/resources/i18n/project.properties index f9828e20c1..01a0da59f1 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project.properties @@ -414,6 +414,8 @@ resource_pool_not_exist=资源池不存在 #file management file_module.not.exist=文件模块不存在 +drag_node.not.exist=拖拽节点不存在 +drop_node.not.exist=目标节点不存在 file_module.parent.not.exist=文件模块父节点不存在 upload.file.error=上传文件失败 file.not.exist=文件不存在 diff --git a/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties index 96ce3a8ad3..d1b77722e4 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_en_US.properties @@ -450,6 +450,8 @@ resource_pool_not_exist=Resource pool does not exist #file management file_module.not.exist=File module does not exist +drag_node.not.exist=Drag node is not exist +drop_node.not.exist=Drop node is not exist file_module.parent.not.exist=File module parent does not exist upload.file.error=Upload file error file.not.exist=File does not exist diff --git a/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties index aafb37150f..beb5eded87 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties @@ -449,6 +449,8 @@ resource_pool_not_exist=资源池不存在 #file management file_module.not.exist=文件模块不存在 +drag_node.not.exist=拖拽节点不存在 +drop_node.not.exist=目标节点不存在 file_module.parent.not.exist=文件模块父节点不存在 upload.file.error=上传文件失败 file.not.exist=文件不存在 diff --git a/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties index 3f753fcb1a..ea54f447c4 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_zh_TW.properties @@ -450,6 +450,8 @@ message.domain.schedule_enable=是否開啟 resource_pool_not_exist=資源池不存在 #file management file_module.not.exist=文件模塊不存在 +drag_node.not.exist=拖拽節點不存在 +drop_node.not.exist=目標節點不存在 file_module.parent.not.exist=文件模塊父節點不存在 upload.file.error=上傳文件失敗 file.not.exist=文件不存在 diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/NodeSortQueryParam.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/NodeSortQueryParam.java new file mode 100644 index 0000000000..6de92d6658 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/NodeSortQueryParam.java @@ -0,0 +1,15 @@ +package io.metersphere.project.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class NodeSortQueryParam { + private String parentId; + private String operator; + private long pos; +} + diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.java b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.java index 32b46bc208..b0569fad9c 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.java @@ -1,6 +1,7 @@ package io.metersphere.project.mapper; -import io.metersphere.project.domain.FileModule; +import io.metersphere.project.dto.NodeSortQueryParam; +import io.metersphere.system.dto.sdk.BaseModule; import io.metersphere.system.dto.sdk.BaseTreeNode; import org.apache.ibatis.annotations.Param; @@ -21,11 +22,9 @@ public interface ExtFileModuleMapper { List selectIdsByProjectId(String projectId); - FileModule getLastModuleByParentId(String id); - - FileModule getNextModuleInParentId(@Param("parentId") String parentId, @Param("pos") long pos); - - FileModule getPreviousModuleInParentId(@Param("parentId") String parentId, @Param("pos") long pos); - String selectNameById(String moduleId); + + BaseModule selectBaseModuleById(String dragNodeId); + + BaseModule selectModuleByParentIdAndPosOperator(NodeSortQueryParam nodeSortQueryParam); } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.xml b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.xml index 83aa02d34f..512611c7c5 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.xml +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtFileModuleMapper.xml @@ -37,33 +37,34 @@ SELECT id FROM file_module WHERE parent_id = #{0} ORDER BY pos ASC - + SELECT id, name, pos, project_Id, parent_id FROM file_module - WHERE parent_id = #{0} - ORDER BY pos DESC + WHERE parent_id = #{parentId} + + AND pos > #{pos} + + + AND pos < #{pos} + + ORDER BY pos + + DESC + LIMIT 1 - - + + \ No newline at end of file diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileModuleService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileModuleService.java index 815e13b042..6183606004 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/FileModuleService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/FileModuleService.java @@ -11,7 +11,6 @@ import io.metersphere.project.request.filemanagement.FileModuleUpdateRequest; import io.metersphere.sdk.constants.ModuleConstants; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.Translator; -import io.metersphere.system.dto.sdk.BaseModule; import io.metersphere.system.dto.sdk.BaseTreeNode; import io.metersphere.system.dto.sdk.request.NodeMoveRequest; import io.metersphere.system.service.CleanupProjectResourceService; @@ -152,77 +151,23 @@ public class FileModuleService extends ModuleTreeService implements CleanupProje } public void moveNode(NodeMoveRequest request, String currentUser) { - BaseModule module; - BaseModule parentModule; - BaseModule previousNode = null; - BaseModule nextNode = null; - FileModule dragNode = fileModuleMapper.selectByPrimaryKey(request.getDragNodeId()); - if (dragNode == null) { - throw new MSException("file_module.not.exist:" + request.getDragNodeId()); - } else { - module = new BaseModule(dragNode.getId(), dragNode.getName(), dragNode.getPos(), dragNode.getProjectId(), dragNode.getParentId()); - } - - if (StringUtils.equals(request.getDragNodeId(), request.getDropNodeId())) { - //两种节点不能一样 - throw new MSException(Translator.get("invalid_parameter")); - } - - FileModule dropNode = fileModuleMapper.selectByPrimaryKey(request.getDropNodeId()); - if (dropNode == null) { - throw new MSException("file_module.not.exist:" + request.getDropNodeId()); - } - - if (request.getDropPosition() == 0) { - //dropPosition=0: 放到dropNode节点内,最后一个节点之后 - parentModule = new BaseModule(dropNode.getId(), dropNode.getName(), dropNode.getPos(), dropNode.getProjectId(), dropNode.getParentId()); - FileModule previousModule = extFileModuleMapper.getLastModuleByParentId(parentModule.getId()); - if (previousModule != null) { - previousNode = new BaseModule(previousModule.getId(), previousModule.getName(), previousModule.getPos(), previousModule.getProjectId(), previousModule.getParentId()); - } - } else { - if (StringUtils.equals(dropNode.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)) { - parentModule = new BaseModule(ModuleConstants.ROOT_NODE_PARENT_ID, ModuleConstants.ROOT_NODE_PARENT_ID, 0, module.getProjectId(), ModuleConstants.ROOT_NODE_PARENT_ID); - } else { - FileModule parent = fileModuleMapper.selectByPrimaryKey(dropNode.getParentId()); - parentModule = new BaseModule(parent.getId(), parent.getName(), parent.getPos(), parent.getProjectId(), parent.getParentId()); - } - - if (request.getDropPosition() == 1) { - //dropPosition=1: 放到dropNode节点后,原dropNode后面的节点之前 - previousNode = new BaseModule(dropNode.getId(), dropNode.getName(), dropNode.getPos(), dropNode.getProjectId(), dropNode.getParentId()); - FileModule nextModule = extFileModuleMapper.getNextModuleInParentId(previousNode.getParentId(), previousNode.getPos()); - if (nextModule != null) { - nextNode = new BaseModule(nextModule.getId(), nextModule.getName(), nextModule.getPos(), nextModule.getProjectId(), nextModule.getParentId()); - } - } else if (request.getDropPosition() == -1) { - //dropPosition=-1: 放到dropNode节点前,原dropNode前面的节点之后 - nextNode = new BaseModule(dropNode.getId(), dropNode.getName(), dropNode.getPos(), dropNode.getProjectId(), dropNode.getParentId()); - FileModule previousModule = extFileModuleMapper.getPreviousModuleInParentId(nextNode.getParentId(), nextNode.getPos()); - if (previousModule != null) { - previousNode = new BaseModule(previousModule.getId(), previousModule.getName(), previousModule.getPos(), previousModule.getProjectId(), previousModule.getParentId()); - } - } else { - throw new MSException(Translator.get("invalid_parameter")); - } - } + NodeSortDTO nodeSortDTO = super.getNodeSortDTO(request, + extFileModuleMapper::selectBaseModuleById, + extFileModuleMapper::selectModuleByParentIdAndPosOperator); FileModuleExample example = new FileModuleExample(); - example.createCriteria().andParentIdEqualTo(parentModule.getId()).andIdEqualTo(module.getId()); - //节点换到了别的节点下,要先更新parent节点. + example.createCriteria().andParentIdEqualTo(nodeSortDTO.getParent().getId()).andIdEqualTo(request.getDragNodeId()); + //节点换到了别的节点下,要先更新parent节点再计算sort if (fileModuleMapper.countByExample(example) == 0) { FileModule fileModule = new FileModule(); - fileModule.setId(module.getId()); - fileModule.setParentId(parentModule.getId()); + fileModule.setId(request.getDragNodeId()); + fileModule.setParentId(nodeSortDTO.getParent().getId()); fileModuleMapper.updateByPrimaryKeySelective(fileModule); } - - NodeSortDTO nodeMoveDTO = new NodeSortDTO(module, parentModule, previousNode, nextNode); - super.sort(nodeMoveDTO); - + super.sort(nodeSortDTO); //记录日志 - fileModuleLogService.saveMoveLog(nodeMoveDTO, currentUser); + fileModuleLogService.saveMoveLog(nodeSortDTO, currentUser); } /** diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/ModuleTreeService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/ModuleTreeService.java index 0da8bcad33..2b4a479368 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/ModuleTreeService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/ModuleTreeService.java @@ -2,9 +2,13 @@ package io.metersphere.project.service; import io.metersphere.project.dto.ModuleCountDTO; import io.metersphere.project.dto.NodeSortDTO; +import io.metersphere.project.dto.NodeSortQueryParam; import io.metersphere.sdk.constants.ModuleConstants; +import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.util.Translator; import io.metersphere.system.dto.sdk.BaseModule; import io.metersphere.system.dto.sdk.BaseTreeNode; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; import jakarta.validation.constraints.NotNull; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -14,6 +18,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; public abstract class ModuleTreeService { @@ -78,6 +83,78 @@ public abstract class ModuleTreeService { return baseTreeNodeList; } + private static final String MOVE_POS_OPERATOR_LESS = "lessThan"; + private static final String MOVE_POS_OPERATOR_MORE = "moreThan"; + private static final String MOVE_POS_OPERATOR_LATEST = "latest"; + + + /** + * 构建节点排序的参数 + * + * @param request 拖拽的前端请求参数 + * @param selectIdNodeFunc 通过id查询节点的函数 + * @param selectPosNodeFunc 通过parentId和pos运算符查询节点的函数 + * @return + */ + public NodeSortDTO getNodeSortDTO(NodeMoveRequest request, Function selectIdNodeFunc, Function selectPosNodeFunc) { + if (StringUtils.equals(request.getDragNodeId(), request.getDropNodeId())) { + //两种节点不能一样 + throw new MSException(Translator.get("invalid_parameter")); + } + + BaseModule dragNode = selectIdNodeFunc.apply(request.getDragNodeId()); + if (dragNode == null) { + throw new MSException("drag_node.not.exist" + ":" + request.getDragNodeId()); + } + + BaseModule dropNode = selectIdNodeFunc.apply(request.getDropNodeId()); + if (dropNode == null) { + throw new MSException("drop_node.not.exist" + ":" + request.getDropNodeId()); + + } + BaseModule parentModule; + BaseModule previousNode = null; + BaseModule nextNode = null; + if (request.getDropPosition() == 0) { + //dropPosition=0: 放到dropNode节点内,最后一个节点之后 + parentModule = new BaseModule(dropNode.getId(), dropNode.getName(), dropNode.getPos(), dropNode.getProjectId(), dropNode.getParentId()); + + NodeSortQueryParam sortParam = new NodeSortQueryParam(); + sortParam.setParentId(dropNode.getId()); + sortParam.setOperator(MOVE_POS_OPERATOR_LATEST); + previousNode = selectPosNodeFunc.apply(sortParam); + } else { + if (StringUtils.equals(dropNode.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)) { + parentModule = new BaseModule(ModuleConstants.ROOT_NODE_PARENT_ID, ModuleConstants.ROOT_NODE_PARENT_ID, 0, dragNode.getProjectId(), ModuleConstants.ROOT_NODE_PARENT_ID); + } else { + parentModule = selectIdNodeFunc.apply(dropNode.getParentId()); + } + if (request.getDropPosition() == 1) { + //dropPosition=1: 放到dropNode节点后,原dropNode后面的节点之前 + previousNode = dropNode; + + NodeSortQueryParam sortParam = new NodeSortQueryParam(); + sortParam.setParentId(parentModule.getId()); + sortParam.setPos(previousNode.getPos()); + sortParam.setOperator(MOVE_POS_OPERATOR_MORE); + nextNode = selectPosNodeFunc.apply(sortParam); + } else if (request.getDropPosition() == -1) { + //dropPosition=-1: 放到dropNode节点前,原dropNode前面的节点之后 + nextNode = dropNode; + + NodeSortQueryParam sortParam = new NodeSortQueryParam(); + sortParam.setParentId(parentModule.getId()); + sortParam.setPos(nextNode.getPos()); + sortParam.setOperator(MOVE_POS_OPERATOR_LESS); + previousNode = selectPosNodeFunc.apply(sortParam); + } else { + throw new MSException(Translator.get("invalid_parameter")); + } + } + + return new NodeSortDTO(dragNode, parentModule, previousNode, nextNode); + } + /** * 模块树排序 */