From b8cfdd7c8bba56a6d8bdf1171ece29bc6282b780 Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Fri, 8 Mar 2024 16:28:39 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E6=8E=A5=E5=8F=A3=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migration/3.0.0/dml/V3.0.0_11_1__data.sql | 2 +- .../definition/ApiTestCaseController.java | 2 +- .../scenario/ApiScenarioController.java | 2 +- .../api/mapper/ExtApiDebugMapper.java | 9 ++ .../api/mapper/ExtApiDebugMapper.xml | 34 ++++++ .../api/mapper/ExtApiDefinitionMapper.java | 10 ++ .../api/mapper/ExtApiDefinitionMapper.xml | 34 ++++++ .../api/mapper/ExtApiScenarioMapper.java | 12 ++ .../api/mapper/ExtApiScenarioMapper.xml | 38 +++++++ .../api/mapper/ExtApiTestCaseMapper.java | 10 ++ .../api/mapper/ExtApiTestCaseMapper.xml | 34 ++++++ .../api/service/debug/ApiDebugService.java | 54 +++++++-- .../definition/ApiDefinitionService.java | 47 ++++++-- .../definition/ApiTestCaseService.java | 47 +++++--- .../service/scenario/ApiScenarioService.java | 43 +++++-- .../controller/ApiDebugControllerTests.java | 4 + .../ApiDefinitionControllerTests.java | 5 + .../ApiScenarioControllerTests.java | 1 + .../ApiTestCaseControllerTests.java | 5 +- .../controller/EnvironmentController.java | 2 +- .../EnvironmentGroupController.java | 2 +- .../io/metersphere/project/dto/DropNode.java | 9 ++ .../project/dto/MoveNodeSortDTO.java | 23 ++++ .../project/mapper/ExtEnvironmentMapper.java | 17 +++ .../project/mapper/ExtEnvironmentMapper.xml | 71 ++++++++++++ .../service/EnvironmentGroupService.java | 49 +++++--- .../project/service/EnvironmentService.java | 53 ++++++--- .../project/service/MoveNodeService.java | 106 ++++++++++++++++++ .../EnvironmentControllerTests.java | 20 ++++ .../EnvironmentGroupControllerTests.java | 1 + 30 files changed, 665 insertions(+), 81 deletions(-) create mode 100644 backend/services/project-management/src/main/java/io/metersphere/project/dto/DropNode.java create mode 100644 backend/services/project-management/src/main/java/io/metersphere/project/dto/MoveNodeSortDTO.java create mode 100644 backend/services/project-management/src/main/java/io/metersphere/project/service/MoveNodeService.java diff --git a/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql b/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql index bfabbbab04..abfcd8f0ce 100644 --- a/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql +++ b/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql @@ -638,7 +638,7 @@ INSERT INTO message_task_blob(id, template) VALUES (@bug_comment_reply_id, 'mess INSERT INTO project_application (`project_id`, `type`, `type_value`) VALUES ('100001100001', 'VERSION_ENABLE', 'FALSE'); -- 初始化默认项目mock环境 -INSERT INTO environment (`id`, `project_id`, `name`, `create_user`, `create_time`, `update_user`, `update_time`, `mock`,`pos`) VALUES (UUID_SHORT(), '100001100001', 'Mock环境', 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, 5000); +INSERT INTO environment (`id`, `project_id`, `name`, `create_user`, `create_time`, `update_user`, `update_time`, `mock`,`pos`) VALUES (UUID_SHORT(), '100001100001', 'Mock环境', 'admin', unix_timestamp() * 1000, 'admin', unix_timestamp() * 1000, true, 64); INSERT INTO environment_blob (id,config) VALUES ((SELECT id FROM environment where name = 'Mock环境'), 0x504B030414000808080089706858000000000000000000000000030000007A6970CD52CB4EC33010FC179FD3A62D02A1DC1042E2D287A0E282382C8ED358385EE3475155E5DF5937711BA0121CE9293B3B3B3BB3EE9E716C1AD42BB0D03856EC9915EF4138BF968DC0E059713589BF8C7067503BF1ADD166BDC2135809AF4A90C8F34BC66AEFCD2DEA4A6EA8DE3359B24207A532662C7AE4A858C1EED7EB15232A3AAFA11184C42957E479E346DB8B7125FD8C2B0CE59856E40DF2B79113762B6C3E9D4CA6D79734EB7726CE2D968B3BAA0CF87A0E9ED70F41891886A32EA597A88FDB89D17D93F1064BE27D19E8A0430622D4024A61FB44A570DC4A3354434B6D564C7E482DBBC6AC8D73E0E11183E5C7D350DE749A3D133A5E2D29C65EDA0EC1D7275EA0E8DD955212E73EC840AAE92CB2921C86FE9C53C345DEEE52A79287945D518A0A82F2374A428FB56D7C28B1B248AE1DDA930A187906350AF43938412992E314D74AFC0BB7FF23FE4E3D98C5B3CC7FEA969E4ED8F85003A7094A8246858DEC097330C469DB4F504B0708C82FCAE869010000AE030000504B0102140014000808080089706858C82FCAE869010000AE0300000300000000000000000000000000000000007A6970504B05060000000001000100310000009A0100000000); -- set innodb lock wait timeout to default diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java index fbfa3c7039..34ff398b65 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiTestCaseController.java @@ -198,7 +198,7 @@ public class ApiTestCaseController { @Operation(summary = "接口测试-接口管理-接口用例-拖拽排序") @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE) public void editPos(@Validated @RequestBody PosRequest request) { - apiTestCaseService.editPos(request); + apiTestCaseService.moveNode(request); } @PostMapping("/upload/temp/file") diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java index ef29bfe070..4cd4d8fca6 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioController.java @@ -222,7 +222,7 @@ public class ApiScenarioController { @Operation(summary = "接口测试-接口场景管理-场景-拖拽排序") @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_UPDATE) public void editPos(@Validated @RequestBody PosRequest request) { - apiScenarioService.editPos(request); + apiScenarioService.moveNode(request); } @PostMapping("/execute/page") diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.java b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.java index 3fe3563bbc..eaf494d1d0 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.java @@ -2,6 +2,8 @@ package io.metersphere.api.mapper; import io.metersphere.api.dto.debug.ApiDebugSimpleDTO; +import io.metersphere.project.dto.DropNode; +import io.metersphere.project.dto.NodeSortQueryParam; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -21,4 +23,11 @@ public interface ExtApiDebugMapper { Long getLastPos(@Param("userId") String userId, @Param("basePos") Long basePos); + void updatePos(String id, long pos); + + List selectIdByProjectIdOrderByPos(String userId); + + DropNode selectDragInfoById(String id); + + DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam); } \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.xml index fd65c79aec..ecf767e713 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDebugMapper.xml @@ -2,6 +2,11 @@ + + update api_debug + set pos =#{pos} + where id = #{id} + + + + \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.java b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.java index a621ecc31c..c0b817a0d0 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.java @@ -6,6 +6,8 @@ import io.metersphere.api.dto.ApiResourceModuleInfo; import io.metersphere.api.dto.converter.ApiDefinitionImportDetail; import io.metersphere.api.dto.definition.*; import io.metersphere.api.dto.scenario.ScenarioSystemRequest; +import io.metersphere.project.dto.DropNode; +import io.metersphere.project.dto.NodeSortQueryParam; import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.table.TableBatchProcessDTO; import org.apache.ibatis.annotations.Param; @@ -66,4 +68,12 @@ public interface ExtApiDefinitionMapper { List getModuleInfoByIds(@Param("ids") List ids); ApiDefinition selectByProjectNumAndApiNum(@Param("projectNum") String projectNum, @Param("apiNum") String apiNum); + + void updatePos(String id, long pos); + + List selectIdByProjectIdOrderByPos(String projectId); + + DropNode selectDragInfoById(String id); + + DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml index e4345cb522..50ca267c64 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml @@ -226,6 +226,11 @@ where id = #{id} and project_id = #{projectId} + + update api_definition + set pos =#{pos} + where id = #{id} + @@ -560,4 +565,33 @@ AND latest = true limit 1 + + + diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.java b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.java index 40eb6964af..8f495a4260 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.java @@ -5,7 +5,9 @@ import io.metersphere.api.dto.definition.ExecutePageRequest; import io.metersphere.api.dto.definition.ExecuteReportDTO; import io.metersphere.api.dto.scenario.*; import io.metersphere.dto.TestCaseProviderDTO; +import io.metersphere.project.dto.DropNode; import io.metersphere.project.dto.ModuleCountDTO; +import io.metersphere.project.dto.NodeSortQueryParam; import io.metersphere.request.AssociateOtherCaseRequest; import io.metersphere.request.TestCasePageProviderRequest; import io.metersphere.system.dto.sdk.BaseTreeNode; @@ -43,4 +45,14 @@ public interface ExtApiScenarioMapper { Long getLastPosEdit(@Param("projectId") String projectId, @Param("basePos") Long basePos); List getExecuteList(@Param("request") ExecutePageRequest request); + + List selectIdByProjectIdOrderByPos(String projectId); + + DropNode selectDragInfoById(String id); + + DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam); + + void updatePos(String id, long pos); + + Long getPos(String projectId); } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml index e7bfaa7c6d..3769f82666 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml @@ -13,6 +13,11 @@ + + update api_scenario + set pos =#{pos} + where id = #{id} + + + + + diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java index 42b2e2de5b..9b24858ea5 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.java @@ -5,7 +5,9 @@ import io.metersphere.api.domain.ApiTestCase; import io.metersphere.api.dto.definition.*; import io.metersphere.api.dto.scenario.ScenarioSystemRequest; import io.metersphere.dto.TestCaseProviderDTO; +import io.metersphere.project.dto.DropNode; import io.metersphere.project.dto.ModuleCountDTO; +import io.metersphere.project.dto.NodeSortQueryParam; import io.metersphere.request.AssociateOtherCaseRequest; import io.metersphere.request.TestCasePageProviderRequest; import io.metersphere.system.dto.sdk.BaseTreeNode; @@ -64,4 +66,12 @@ public interface ExtApiTestCaseMapper { List getIdsByModules(@Param("request") ScenarioSystemRequest caseRequest); List getApiCaseDefinitionInfo(@Param("ids") List ids); + + void updatePos(String id, long pos); + + List selectIdByProjectIdOrderByPos(String projectId); + + DropNode selectDragInfoById(String id); + + DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam); } \ No newline at end of file diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml index a7a6d9e664..890e7cd2e7 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiTestCaseMapper.xml @@ -23,6 +23,11 @@ #{id} + + update api_test_case + set pos =#{pos} + where id = #{id} + + + + diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java index 0df13d15c2..9e44f70203 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/debug/ApiDebugService.java @@ -21,6 +21,8 @@ import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.domain.FileMetadata; +import io.metersphere.project.dto.MoveNodeSortDTO; +import io.metersphere.project.service.MoveNodeService; import io.metersphere.project.service.ProjectService; import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO; @@ -29,12 +31,18 @@ import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.FileAssociationSourceUtil; import io.metersphere.sdk.util.JSON; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; +import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -49,7 +57,7 @@ import static io.metersphere.api.controller.result.ApiResultCode.API_DEBUG_EXIST */ @Service @Transactional(rollbackFor = Exception.class) -public class ApiDebugService { +public class ApiDebugService extends MoveNodeService { @Resource private ApiDebugMapper apiDebugMapper; @Resource @@ -64,8 +72,8 @@ public class ApiDebugService { private ApiDebugModuleMapper apiDebugModuleMapper; @Resource private ApiCommonService apiCommonService; - - public static final Long ORDER_STEP = 5000L; + @Resource + private SqlSessionFactory sqlSessionFactory; public List list(String protocol, String userId) { return extApiDebugMapper.list(protocol, userId); @@ -112,9 +120,9 @@ public class ApiDebugService { } - private Long getNextOrder(String userId) { + public long getNextOrder(String userId) { Long pos = extApiDebugMapper.getPos(userId); - return (pos == null ? 0 : pos) + ORDER_STEP; + return (pos == null ? 0 : pos) + DEFAULT_NODE_INTERVAL_POS; } private static ApiFileResourceUpdateRequest getApiFileResourceUpdateRequest(String sourceId, String projectId, String operator) { @@ -243,14 +251,38 @@ public class ApiDebugService { return; } request.setProjectId(userId); - ServiceUtils.updatePosField(request, - ApiDebug.class, - apiDebugMapper::selectByPrimaryKey, - extApiDebugMapper::getPrePos, - extApiDebugMapper::getLastPos, - apiDebugMapper::updateByPrimaryKeySelective); + moveNode(request); } + @Override + public void updatePos(String id, long pos) { + extApiDebugMapper.updatePos(id, pos); + } + + @Override + public void refreshPos(String projectId) { + List posIds = extApiDebugMapper.selectIdByProjectIdOrderByPos(projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ExtApiDebugMapper batchUpdateMapper = sqlSession.getMapper(ExtApiDebugMapper.class); + for (int i = 0; i < posIds.size(); i++) { + batchUpdateMapper.updatePos(posIds.get(i), i * DEFAULT_NODE_INTERVAL_POS); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } + + public void moveNode(PosRequest posRequest) { + NodeMoveRequest request = super.getNodeMoveRequest(posRequest); + MoveNodeSortDTO sortDTO = super.getNodeSortDTO( + posRequest.getProjectId(), + request, + extApiDebugMapper::selectDragInfoById, + extApiDebugMapper::selectNodeByPosOperator + ); + this.sort(sortDTO); + } + + /** * 处理关联的文件被更新 * diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionService.java index 72d0e6ae49..abb5635e93 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionService.java @@ -25,9 +25,11 @@ import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.domain.FileMetadata; +import io.metersphere.project.dto.MoveNodeSortDTO; import io.metersphere.project.dto.environment.EnvironmentInfoDTO; import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; import io.metersphere.project.service.EnvironmentService; +import io.metersphere.project.service.MoveNodeService; import io.metersphere.project.service.ProjectService; import io.metersphere.sdk.constants.ApiReportStatus; import io.metersphere.sdk.constants.ApplicationNumScope; @@ -43,6 +45,8 @@ import io.metersphere.system.dto.OperationHistoryDTO; import io.metersphere.system.dto.request.OperationHistoryRequest; import io.metersphere.system.dto.request.OperationHistoryVersionRequest; import io.metersphere.system.dto.sdk.SessionUser; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; +import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.service.OperationHistoryService; @@ -70,9 +74,7 @@ import java.util.stream.Stream; @Service @Transactional(rollbackFor = Exception.class) -public class ApiDefinitionService { - - public static final Long ORDER_STEP = 5000L; +public class ApiDefinitionService extends MoveNodeService { private static final String ALL_API = "api_definition_module.api.all"; @@ -489,9 +491,9 @@ public class ApiDefinitionService { .collect(Collectors.toSet()); } - public Long getNextOrder(String projectId) { + public long getNextOrder(String projectId) { Long pos = extApiDefinitionMapper.getPos(projectId); - return (pos == null ? 0 : pos) + ORDER_STEP; + return (pos == null ? 0 : pos) + DEFAULT_NODE_INTERVAL_POS; } public long getNextNum(String projectId) { @@ -1067,12 +1069,35 @@ public class ApiDefinitionService { if (StringUtils.equals(request.getTargetId(), request.getMoveId())) { return; } - ServiceUtils.updatePosField(request, - ApiDefinition.class, - apiDefinitionMapper::selectByPrimaryKey, - extApiDefinitionMapper::getPrePos, - extApiDefinitionMapper::getLastPos, - apiDefinitionMapper::updateByPrimaryKeySelective); + moveNode(request); + } + + @Override + public void updatePos(String id, long pos) { + extApiDefinitionMapper.updatePos(id, pos); + } + + @Override + public void refreshPos(String projectId) { + List posIds = extApiDefinitionMapper.selectIdByProjectIdOrderByPos(projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ExtApiDefinitionMapper batchUpdateMapper = sqlSession.getMapper(ExtApiDefinitionMapper.class); + for (int i = 0; i < posIds.size(); i++) { + batchUpdateMapper.updatePos(posIds.get(i), i * DEFAULT_NODE_INTERVAL_POS); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } + + public void moveNode(PosRequest posRequest) { + NodeMoveRequest request = super.getNodeMoveRequest(posRequest); + MoveNodeSortDTO sortDTO = super.getNodeSortDTO( + posRequest.getProjectId(), + request, + extApiDefinitionMapper::selectDragInfoById, + extApiDefinitionMapper::selectNodeByPosOperator + ); + this.sort(sortDTO); } private void checkResponseNameCode(Object response) { diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java index 0e4ee60695..dd6fa311cf 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiTestCaseService.java @@ -19,8 +19,10 @@ import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.domain.FileMetadata; import io.metersphere.project.domain.Project; +import io.metersphere.project.dto.MoveNodeSortDTO; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.project.service.EnvironmentService; +import io.metersphere.project.service.MoveNodeService; import io.metersphere.sdk.constants.ApiExecuteRunMode; import io.metersphere.sdk.constants.ApplicationNumScope; import io.metersphere.sdk.constants.DefaultRepositoryDir; @@ -33,6 +35,7 @@ import io.metersphere.sdk.mapper.EnvironmentMapper; import io.metersphere.sdk.util.*; import io.metersphere.system.dto.OperationHistoryDTO; import io.metersphere.system.dto.request.OperationHistoryRequest; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.service.OperationHistoryService; @@ -60,9 +63,7 @@ import java.util.stream.Stream; @Service @Transactional(rollbackFor = Exception.class) -public class ApiTestCaseService { - - public static final Long ORDER_STEP = 5000L; +public class ApiTestCaseService extends MoveNodeService { public static final String PRIORITY = "Priority"; public static final String STATUS = "Status"; @@ -134,9 +135,9 @@ public class ApiTestCaseService { } } - public Long getNextOrder(String projectId) { + public long getNextOrder(String projectId) { Long pos = extApiTestCaseMapper.getPos(projectId); - return (pos == null ? 0 : pos) + ORDER_STEP; + return (pos == null ? 0 : pos) + DEFAULT_NODE_INTERVAL_POS; } private static ApiFileResourceUpdateRequest getApiFileResourceUpdateRequest(String sourceId, String projectId, String operator) { @@ -522,14 +523,6 @@ public class ApiTestCaseService { mapper.updateByExampleSelective(updateCase, example); } - public void editPos(PosRequest request) { - ServiceUtils.updatePosField(request, - ApiTestCase.class, - apiTestCaseMapper::selectByPrimaryKey, - extApiTestCaseMapper::getPrePos, - extApiTestCaseMapper::getLastPos, - apiTestCaseMapper::updateByPrimaryKeySelective); - } public String uploadTempFile(MultipartFile file) { return apiFileResourceService.uploadTempFile(file); @@ -685,4 +678,32 @@ public class ApiTestCaseService { taskRequest.setRunModeConfig(apiRunModeConfig); return taskRequest; } + + @Override + public void updatePos(String id, long pos) { + extApiTestCaseMapper.updatePos(id, pos); + } + + @Override + public void refreshPos(String projectId) { + List posIds = extApiTestCaseMapper.selectIdByProjectIdOrderByPos(projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ExtApiTestCaseMapper batchUpdateMapper = sqlSession.getMapper(ExtApiTestCaseMapper.class); + for (int i = 0; i < posIds.size(); i++) { + batchUpdateMapper.updatePos(posIds.get(i), i * DEFAULT_NODE_INTERVAL_POS); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } + + public void moveNode(PosRequest posRequest) { + NodeMoveRequest request = super.getNodeMoveRequest(posRequest); + MoveNodeSortDTO sortDTO = super.getNodeSortDTO( + posRequest.getProjectId(), + request, + extApiTestCaseMapper::selectDragInfoById, + extApiTestCaseMapper::selectNodeByPosOperator + ); + this.sort(sortDTO); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java index 5e389ff012..d358a12247 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioService.java @@ -31,6 +31,7 @@ import io.metersphere.project.domain.FileAssociation; import io.metersphere.project.domain.FileMetadata; import io.metersphere.project.domain.Project; import io.metersphere.project.domain.ProjectExample; +import io.metersphere.project.dto.MoveNodeSortDTO; import io.metersphere.project.dto.environment.EnvironmentInfoDTO; import io.metersphere.project.dto.environment.http.HttpConfig; import io.metersphere.project.dto.environment.http.HttpConfigModuleMatchRule; @@ -59,6 +60,7 @@ import io.metersphere.system.dto.LogInsertModule; import io.metersphere.system.dto.OperationHistoryDTO; import io.metersphere.system.dto.request.OperationHistoryRequest; import io.metersphere.system.dto.request.ScheduleConfig; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; @@ -82,7 +84,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; -import org.jetbrains.annotations.NotNull; import org.mybatis.spring.SqlSessionUtils; import org.quartz.CronExpression; import org.quartz.CronScheduleBuilder; @@ -102,7 +103,7 @@ import static io.metersphere.api.controller.result.ApiResultCode.API_SCENARIO_EX @Service @Transactional(rollbackFor = Exception.class) -public class ApiScenarioService { +public class ApiScenarioService extends MoveNodeService{ @Resource private ApiScenarioMapper apiScenarioMapper; @@ -883,8 +884,9 @@ public class ApiScenarioService { return NumGenerator.nextNum(projectId, ApplicationNumScope.API_SCENARIO); } - public Long getNextOrder(String projectId) { - return projectService.getNextOrder(extApiScenarioMapper::getLastPos, projectId); + public long getNextOrder(String projectId) { + Long pos = extApiScenarioMapper.getPos(projectId); + return (pos == null ? 0 : pos) + DEFAULT_NODE_INTERVAL_POS; } public void delete(String id, String operator) { @@ -2138,13 +2140,32 @@ public class ApiScenarioService { return steps; } - public void editPos(PosRequest request) { - ServiceUtils.updatePosField(request, - ApiScenario.class, - apiScenarioMapper::selectByPrimaryKey, - extApiScenarioMapper::getPrePos, - extApiScenarioMapper::getLastPosEdit, - apiScenarioMapper::updateByPrimaryKeySelective); + @Override + public void updatePos(String id, long pos) { + extApiScenarioMapper.updatePos(id, pos); + } + + @Override + public void refreshPos(String projectId) { + List posIds = extApiScenarioMapper.selectIdByProjectIdOrderByPos(projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ExtApiTestCaseMapper batchUpdateMapper = sqlSession.getMapper(ExtApiTestCaseMapper.class); + for (int i = 0; i < posIds.size(); i++) { + batchUpdateMapper.updatePos(posIds.get(i), i * DEFAULT_NODE_INTERVAL_POS); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } + + public void moveNode(PosRequest posRequest) { + NodeMoveRequest request = super.getNodeMoveRequest(posRequest); + MoveNodeSortDTO sortDTO = super.getNodeSortDTO( + posRequest.getProjectId(), + request, + extApiScenarioMapper::selectDragInfoById, + extApiScenarioMapper::selectNodeByPosOperator + ); + this.sort(sortDTO); } public List getExecuteList(ExecutePageRequest request) { diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java index 68fc182658..c3adb07de0 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDebugControllerTests.java @@ -29,6 +29,7 @@ import io.metersphere.api.service.ApiCommonService; import io.metersphere.api.service.ApiFileResourceService; import io.metersphere.api.service.BaseFileManagementTestService; import io.metersphere.api.service.BaseResourcePoolTestService; +import io.metersphere.api.service.debug.ApiDebugService; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.api.KeyValueEnableParam; @@ -111,6 +112,8 @@ public class ApiDebugControllerTests extends BaseTest { private CustomFunctionService customFunctionService; @Resource private ApiFileResourceMapper apiFileResourceMapper; + @Resource + private ApiDebugService apiDebugService; private static ApiDebug addApiDebug; private static ApiDebug anotherAddApiDebug; private static String fileMetadataId; @@ -424,6 +427,7 @@ public class ApiDebugControllerTests extends BaseTest { request.setModuleId("def"); requestPost("edit/pos", request).andExpect(status().is5xxServerError()); request.setModuleId("root"); + apiDebugService.refreshPos("admin"); // @@校验权限 requestPostPermissionTest(PermissionConstants.PROJECT_API_DEBUG_UPDATE, "edit/pos", request); } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java index a94f3a5c82..50a1340c78 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java @@ -16,6 +16,7 @@ import io.metersphere.api.model.CheckLogModel; import io.metersphere.api.service.ApiCommonService; import io.metersphere.api.service.ApiFileResourceService; import io.metersphere.api.service.BaseFileManagementTestService; +import io.metersphere.api.service.definition.ApiDefinitionService; import io.metersphere.api.service.definition.ApiTestCaseService; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; @@ -150,6 +151,8 @@ public class ApiDefinitionControllerTests extends BaseTest { private ApiFileResourceMapper apiFileResourceMapper; @Resource private ApiTestCaseService apiTestCaseService; + @Resource + private ApiDefinitionService apiDefinitionService; private static String fileMetadataId; private static String uploadFileId; @@ -1173,6 +1176,8 @@ public class ApiDefinitionControllerTests extends BaseTest { request.setModuleId("module-st-6"); requestPost("edit/pos", request).andExpect(status().is5xxServerError()); + apiDefinitionService.refreshPos(DEFAULT_PROJECT_ID); + } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java index c63bccdc9f..932dbe9843 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioControllerTests.java @@ -2347,6 +2347,7 @@ public class ApiScenarioControllerTests extends BaseTest { posRequest.setMoveMode("BEFORE"); this.requestPostWithOkAndReturn("/edit/pos", posRequest); + apiScenarioService.refreshPos(DEFAULT_PROJECT_ID); } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java index 5225dbcaca..8fb512e05a 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiTestCaseControllerTests.java @@ -14,6 +14,7 @@ import io.metersphere.api.service.ApiCommonService; import io.metersphere.api.service.ApiFileResourceService; import io.metersphere.api.service.BaseFileManagementTestService; import io.metersphere.api.service.definition.ApiReportService; +import io.metersphere.api.service.definition.ApiTestCaseService; import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.project.domain.ProjectVersion; @@ -130,6 +131,8 @@ public class ApiTestCaseControllerTests extends BaseTest { private ApiCommonService apiCommonService; @Resource private ApiFileResourceMapper apiFileResourceMapper; + @Resource + private ApiTestCaseService apiTestCaseService; @Override public String getBasePath() { @@ -647,7 +650,7 @@ public class ApiTestCaseControllerTests extends BaseTest { posRequest.setMoveMode("BEFORE"); this.requestPostWithOkAndReturn(POS_URL, posRequest); - + apiTestCaseService.refreshPos(DEFAULT_PROJECT_ID); } @Test diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java index ec04e3c3ff..ca0d833772 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentController.java @@ -127,7 +127,7 @@ public class EnvironmentController { @Operation(summary = "项目管理-环境-环境目录-修改排序") @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE) public void editPos(@Validated @RequestBody PosRequest request) { - environmentService.editPos(request); + environmentService.moveNode(request); } @GetMapping("/get-options/{projectId}") diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentGroupController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentGroupController.java index 477b9871f5..b017592ff9 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentGroupController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/EnvironmentGroupController.java @@ -83,7 +83,7 @@ public class EnvironmentGroupController { @Operation(summary = "项目管理-环境-环境组-修改排序") @RequiresPermissions(PermissionConstants.PROJECT_ENVIRONMENT_READ_UPDATE) public void editPos(@Validated @RequestBody PosRequest request) { - environmentGroupService.editPos(request); + environmentGroupService.moveNode(request); } } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/DropNode.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/DropNode.java new file mode 100644 index 0000000000..2f453c7714 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/DropNode.java @@ -0,0 +1,9 @@ +package io.metersphere.project.dto; + +import lombok.Data; + +@Data +public class DropNode { + private String id; + private long pos; +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/MoveNodeSortDTO.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/MoveNodeSortDTO.java new file mode 100644 index 0000000000..43b8d0cbe6 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/MoveNodeSortDTO.java @@ -0,0 +1,23 @@ +package io.metersphere.project.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class MoveNodeSortDTO { + @Schema(description = "项目ID") + private String projectId; + + @Schema(description = "要排序的节点") + private DropNode sortNode; + + @Schema(description = "前一个节点") + private DropNode previousNode; + + @Schema(description = "后一个节点") + private DropNode nextNode; + +} + diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.java b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.java index 62a753d110..ff6ad6cb10 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.java @@ -1,5 +1,7 @@ package io.metersphere.project.mapper; +import io.metersphere.project.dto.DropNode; +import io.metersphere.project.dto.NodeSortQueryParam; import io.metersphere.sdk.domain.Environment; import io.metersphere.sdk.domain.EnvironmentGroup; import org.apache.ibatis.annotations.Param; @@ -23,4 +25,19 @@ public interface ExtEnvironmentMapper { Long getGroupPrePos(@Param("projectId") String projectId, @Param("basePos") Long basePos); Long getGroupLastPos(@Param("projectId") String projectId, @Param("basePos") Long basePos); + + DropNode selectDragInfoById(String id); + + DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam); + + List selectIdByProjectIdOrderByPos(String projectId); + long updatePos(@Param("id") String id, @Param("pos") long pos); + + void updateGroupPos(String id, long pos); + + List selectGroupIdByProjectIdOrderByPos(String projectId); + + DropNode selectGroupDragInfoById(String id); + + DropNode selectGroupNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam); } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.xml b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.xml index 472e7b093f..e2bae5adcd 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.xml +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ExtEnvironmentMapper.xml @@ -1,6 +1,18 @@ + + UPDATE + environment + SET pos =#{pos} + WHERE id = #{id} + + + UPDATE + environment_group + SET pos =#{pos} + WHERE id = #{id} + + + + + + + + \ No newline at end of file diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentGroupService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentGroupService.java index d59d085d8c..cdc80dde6e 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentGroupService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentGroupService.java @@ -3,6 +3,7 @@ package io.metersphere.project.service; import io.metersphere.project.domain.Project; import io.metersphere.project.domain.ProjectExample; +import io.metersphere.project.dto.MoveNodeSortDTO; import io.metersphere.project.dto.environment.*; import io.metersphere.project.mapper.ExtEnvironmentMapper; import io.metersphere.project.mapper.ExtProjectMapper; @@ -20,11 +21,12 @@ import io.metersphere.sdk.util.Translator; import io.metersphere.system.domain.UserRoleRelationExample; import io.metersphere.system.dto.sdk.BaseSystemConfigDTO; import io.metersphere.system.dto.sdk.OptionDTO; +import io.metersphere.system.dto.sdk.enums.MoveTypeEnum; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.mapper.UserRoleRelationMapper; import io.metersphere.system.service.SystemParameterService; import io.metersphere.system.uid.IDGenerator; -import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; @@ -42,7 +44,7 @@ import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) -public class EnvironmentGroupService { +public class EnvironmentGroupService extends MoveNodeService{ @Resource private EnvironmentGroupMapper environmentGroupMapper; @@ -62,8 +64,6 @@ public class EnvironmentGroupService { private ExtProjectMapper extProjectMapper; @Resource private EnvironmentService environmentService; - - public static final Long ORDER_STEP = 5000L; private static final String MOCK_EVN_SOCKET = "/mock-server/"; public EnvironmentGroup add(EnvironmentGroupRequest request, String userId) { @@ -87,9 +87,9 @@ public class EnvironmentGroupService { return environmentGroup; } - public Long getNextOrder(String projectId) { + public long getNextOrder(String projectId) { Long pos = extEnvironmentMapper.getGroupPos(projectId); - return (pos == null ? 0 : pos) + ORDER_STEP; + return (pos == null ? 0 : pos) + DEFAULT_NODE_INTERVAL_POS; } private void insertGroupProject(EnvironmentGroupRequest request) { @@ -245,15 +245,6 @@ public class EnvironmentGroupService { return result; } - public void editPos(PosRequest request) { - ServiceUtils.updatePosField(request, - EnvironmentGroup.class, - environmentGroupMapper::selectByPrimaryKey, - extEnvironmentMapper::getGroupPrePos, - extEnvironmentMapper::getGroupLastPos, - environmentGroupMapper::updateByPrimaryKeySelective); - } - public List getEnvironmentGroupRelations(List envGroupIds) { if (CollectionUtils.isEmpty(envGroupIds)) { return Collections.emptyList(); @@ -262,4 +253,32 @@ public class EnvironmentGroupService { example.createCriteria().andEnvironmentGroupIdIn(envGroupIds); return environmentGroupRelationMapper.selectByExample(example); } + + @Override + public void updatePos(String id, long pos) { + extEnvironmentMapper.updateGroupPos(id, pos); + } + + @Override + public void refreshPos(String projectId) { + List groupIds = extEnvironmentMapper.selectGroupIdByProjectIdOrderByPos(projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ExtEnvironmentMapper batchUpdateMapper = sqlSession.getMapper(ExtEnvironmentMapper.class); + for (int i = 0; i < groupIds.size(); i++) { + batchUpdateMapper.updateGroupPos(groupIds.get(i), i * DEFAULT_NODE_INTERVAL_POS); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } + + public void moveNode(PosRequest posRequest) { + NodeMoveRequest request = super.getNodeMoveRequest(posRequest); + MoveNodeSortDTO sortDTO = super.getNodeSortDTO( + posRequest.getProjectId(), + request, + extEnvironmentMapper::selectGroupDragInfoById, + extEnvironmentMapper::selectGroupNodeByPosOperator + ); + this.sort(sortDTO); + } } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java index ede87bf5b6..7ad83a5cce 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/EnvironmentService.java @@ -4,6 +4,7 @@ package io.metersphere.project.service; import io.metersphere.plugin.api.spi.AbstractProtocolPlugin; import io.metersphere.project.domain.Project; import io.metersphere.project.domain.ProjectExample; +import io.metersphere.project.dto.MoveNodeSortDTO; import io.metersphere.project.dto.environment.*; import io.metersphere.project.dto.environment.datasource.DataSource; import io.metersphere.project.mapper.ExtEnvironmentMapper; @@ -21,6 +22,7 @@ import io.metersphere.sdk.util.*; import io.metersphere.system.domain.PluginScript; import io.metersphere.system.dto.sdk.BaseSystemConfigDTO; import io.metersphere.system.dto.sdk.OptionDTO; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; import io.metersphere.system.dto.sdk.request.PosRequest; import io.metersphere.system.dto.table.TableBatchProcessDTO; import io.metersphere.system.log.constants.OperationLogModule; @@ -32,11 +34,14 @@ import io.metersphere.system.service.JdbcDriverPluginService; import io.metersphere.system.service.PluginScriptService; import io.metersphere.system.service.SystemParameterService; import io.metersphere.system.uid.IDGenerator; -import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionUtils; import org.pf4j.Plugin; import org.pf4j.PluginWrapper; import org.springframework.http.HttpHeaders; @@ -55,7 +60,7 @@ import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) -public class EnvironmentService { +public class EnvironmentService extends MoveNodeService { @Resource private EnvironmentMapper environmentMapper; @Resource @@ -80,7 +85,8 @@ public class EnvironmentService { private SystemParameterService systemParameterService; @Resource private EnvironmentGroupRelationMapper environmentGroupRelationMapper; - public static final Long ORDER_STEP = 5000L; + @Resource + private SqlSessionFactory sqlSessionFactory; private static final String USERNAME = "user"; private static final String PASSWORD = "password"; @@ -213,9 +219,9 @@ public class EnvironmentService { } } - public Long getNextOrder(String projectId) { + public long getNextOrder(String projectId) { Long pos = extEnvironmentMapper.getPos(projectId); - return (pos == null ? 0 : pos) + ORDER_STEP; + return (pos == null ? 0 : pos) + DEFAULT_NODE_INTERVAL_POS; } public ResponseEntity exportJson(TableBatchProcessDTO request, String projectId) { @@ -387,15 +393,6 @@ public class EnvironmentService { } } - public void editPos(PosRequest request) { - ServiceUtils.updatePosField(request, - Environment.class, - environmentMapper::selectByPrimaryKey, - extEnvironmentMapper::getPrePos, - extEnvironmentMapper::getLastPos, - environmentMapper::updateByPrimaryKeySelective); - } - public List getPluginScripts(String projectId) { Project project = projectService.checkProjectNotExist(projectId); // 查询组织下有权限的接口插件 @@ -520,4 +517,32 @@ public class EnvironmentService { }); return environmentOptions; } + + @Override + public void updatePos(String id, long pos) { + extEnvironmentMapper.updatePos(id, pos); + } + + @Override + public void refreshPos(String projectId) { + List caseIdList = extEnvironmentMapper.selectIdByProjectIdOrderByPos(projectId); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + ExtEnvironmentMapper batchUpdateMapper = sqlSession.getMapper(ExtEnvironmentMapper.class); + for (int i = 0; i < caseIdList.size(); i++) { + batchUpdateMapper.updatePos(caseIdList.get(i), i * DEFAULT_NODE_INTERVAL_POS); + } + sqlSession.flushStatements(); + SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory); + } + + public void moveNode(PosRequest posRequest) { + NodeMoveRequest request = super.getNodeMoveRequest(posRequest); + MoveNodeSortDTO sortDTO = super.getNodeSortDTO( + posRequest.getProjectId(), + request, + extEnvironmentMapper::selectDragInfoById, + extEnvironmentMapper::selectNodeByPosOperator + ); + this.sort(sortDTO); + } } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/MoveNodeService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/MoveNodeService.java new file mode 100644 index 0000000000..0251de8d65 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/MoveNodeService.java @@ -0,0 +1,106 @@ +package io.metersphere.project.service; + +import io.metersphere.project.dto.DropNode; +import io.metersphere.project.dto.ModuleSortCountResultDTO; +import io.metersphere.project.dto.MoveNodeSortDTO; +import io.metersphere.project.dto.NodeSortQueryParam; +import io.metersphere.project.utils.NodeSortUtils; +import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.util.Translator; +import io.metersphere.system.dto.sdk.enums.MoveTypeEnum; +import io.metersphere.system.dto.sdk.request.NodeMoveRequest; +import io.metersphere.system.dto.sdk.request.PosRequest; +import org.apache.commons.lang3.StringUtils; + +import java.util.function.Function; +public abstract class MoveNodeService { + + public static final long DEFAULT_NODE_INTERVAL_POS = NodeSortUtils.DEFAULT_NODE_INTERVAL_POS; + + public abstract long getNextOrder(String projectId); + + public abstract void updatePos(String id, long pos); + + public abstract void refreshPos(String testPlanId); + + + private static final String MOVE_POS_OPERATOR_LESS = "lessThan"; + private static final String MOVE_POS_OPERATOR_MORE = "moreThan"; + private static final String DRAG_NODE_NOT_EXIST = "drag_node.not.exist"; + + public NodeMoveRequest getNodeMoveRequest(PosRequest posRequest) { + NodeMoveRequest request = new NodeMoveRequest(); + request.setDragNodeId(posRequest.getMoveId()); + request.setDropNodeId(posRequest.getTargetId()); + request.setDropPosition(StringUtils.equals(MoveTypeEnum.AFTER.name(), posRequest.getMoveMode()) ? -1 : 1); + return request; + } + + /** + * 构建节点排序的参数 + * + * @param request 拖拽的前端请求参数 + * @param selectIdNodeFunc 通过id查询节点的函数 + * @param selectPosNodeFunc 通过parentId和pos运算符查询节点的函数 + * @return + */ + public MoveNodeSortDTO getNodeSortDTO(String projectId , NodeMoveRequest request, Function selectIdNodeFunc, Function selectPosNodeFunc) { + if (StringUtils.equals(request.getDragNodeId(), request.getDropNodeId())) { + //两种节点不能一样 + throw new MSException(Translator.get("invalid_parameter") + ": drag node and drop node"); + } + + DropNode dragNode = selectIdNodeFunc.apply(request.getDragNodeId()); + if (dragNode == null) { + throw new MSException(Translator.get(DRAG_NODE_NOT_EXIST) + ":" + request.getDragNodeId()); + } + + DropNode dropNode = selectIdNodeFunc.apply(request.getDropNodeId()); + if (dropNode == null) { + throw new MSException(Translator.get(DRAG_NODE_NOT_EXIST) + ":" + request.getDropNodeId()); + } + + DropNode previousNode; + DropNode nextNode; + + if (request.getDropPosition() == 1) { + //dropPosition=1: 放到dropNode节点后,原dropNode后面的节点之前 + previousNode = dropNode; + NodeSortQueryParam sortParam = new NodeSortQueryParam(); + sortParam.setPos(previousNode.getPos()); + sortParam.setOperator(MOVE_POS_OPERATOR_MORE); + sortParam.setParentId(projectId); + nextNode = selectPosNodeFunc.apply(sortParam); + } else if (request.getDropPosition() == -1) { + //dropPosition=-1: 放到dropNode节点前,原dropNode前面的节点之后 + nextNode = dropNode; + NodeSortQueryParam sortParam = new NodeSortQueryParam(); + sortParam.setPos(nextNode.getPos()); + sortParam.setOperator(MOVE_POS_OPERATOR_LESS); + sortParam.setParentId(projectId); + previousNode = selectPosNodeFunc.apply(sortParam); + } else { + throw new MSException(Translator.get("invalid_parameter") + ": dropPosition"); + } + + return new MoveNodeSortDTO(projectId, dragNode, previousNode, nextNode); + } + + //排序 + public void sort(MoveNodeSortDTO sortDTO) { + + // 获取相邻节点 + DropNode previousNode = sortDTO.getPreviousNode(); + DropNode nextNode = sortDTO.getNextNode(); + + ModuleSortCountResultDTO countResultDTO = NodeSortUtils.countModuleSort( + previousNode == null ? -1 : previousNode.getPos(), + nextNode == null ? -1 : nextNode.getPos()); + + updatePos(sortDTO.getSortNode().getId(), countResultDTO.getPos()); + if (countResultDTO.isRefreshPos()) { + refreshPos(sortDTO.getProjectId()); + } + } + +} diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java index bd4ed6d4ef..8d28c84746 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentControllerTests.java @@ -7,6 +7,8 @@ import io.metersphere.project.api.assertion.body.*; import io.metersphere.project.api.processor.SQLProcessor; import io.metersphere.project.api.processor.ScriptProcessor; import io.metersphere.project.dto.CommonScriptInfo; +import io.metersphere.project.dto.DropNode; +import io.metersphere.project.dto.NodeSortQueryParam; import io.metersphere.project.dto.environment.*; import io.metersphere.project.dto.environment.auth.AuthConfig; import io.metersphere.project.dto.environment.common.CommonParams; @@ -20,6 +22,7 @@ import io.metersphere.project.dto.environment.ssl.KeyStoreConfig; import io.metersphere.project.dto.environment.ssl.KeyStoreEntry; import io.metersphere.project.dto.environment.ssl.KeyStoreFile; import io.metersphere.project.dto.environment.variables.CommonVariables; +import io.metersphere.project.mapper.ExtEnvironmentMapper; import io.metersphere.project.service.EnvironmentService; import io.metersphere.sdk.constants.DefaultRepositoryDir; import io.metersphere.sdk.constants.MsAssertionCondition; @@ -114,6 +117,8 @@ public class EnvironmentControllerTests extends BaseTest { private PluginScriptMapper pluginScriptMapper; @Resource private EnvironmentService environmentService; + @Resource + private ExtEnvironmentMapper extEnvironmentMapper; @Value("${spring.datasource.url}") private String dburl; @Value("${spring.datasource.username}") @@ -996,6 +1001,21 @@ public class EnvironmentControllerTests extends BaseTest { posRequest.setMoveMode("BEFORE"); this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID); + //extEnvironmentMapper + DropNode environmentId1 = extEnvironmentMapper.selectDragInfoById("environmentId1"); + + NodeSortQueryParam sortParam = new NodeSortQueryParam(); + sortParam.setPos(environmentId1.getPos()); + sortParam.setOperator("lessThan"); + sortParam.setParentId(DEFAULT_PROJECT_ID); + + DropNode dropNode = extEnvironmentMapper.selectNodeByPosOperator(sortParam); + extEnvironmentMapper.updatePos(dropNode.getId(), 999); + Assertions.assertNotNull(dropNode); + environments = environmentMapper.selectByExample(example); + posRequest.setMoveMode("AFTER"); + posRequest.setMoveId(environments.getFirst().getId()); + this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID); } diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java index 61abe9f268..80a7669275 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/EnvironmentGroupControllerTests.java @@ -323,6 +323,7 @@ public class EnvironmentGroupControllerTests extends BaseTest { posRequest.setMoveMode("BEFORE"); this.requestPostWithOkAndReturn(POS_URL, posRequest); + environmentGroupService.refreshPos(DEFAULT_PROJECT_ID); }