refactor(接口测试): 优化接口拖拽排序

This commit is contained in:
wxg0103 2024-03-08 16:28:39 +08:00 committed by 刘瑞斌
parent 4332f78df3
commit b8cfdd7c8b
30 changed files with 665 additions and 81 deletions

View File

@ -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

View File

@ -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")

View File

@ -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")

View File

@ -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<String> selectIdByProjectIdOrderByPos(String userId);
DropNode selectDragInfoById(String id);
DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
}

View File

@ -2,6 +2,11 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.api.mapper.ExtApiDebugMapper">
<update id="updatePos">
update api_debug
set pos =#{pos}
where id = #{id}
</update>
<select id="list" resultType="io.metersphere.api.dto.debug.ApiDebugSimpleDTO">
select id, name, method, module_id
@ -33,4 +38,33 @@
</if>
order by `pos` desc limit 1;
</select>
<select id="selectIdByProjectIdOrderByPos" resultType="java.lang.String">
SELECT id
FROM api_debug
WHERE create_user = #{userId}
ORDER BY pos
</select>
<select id="selectDragInfoById" resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_debug
WHERE id = #{id}
</select>
<select id="selectNodeByPosOperator"
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_debug
WHERE create_user = #{parentId}
<if test="operator == 'moreThan'">
AND pos &gt; #{pos}
</if>
<if test="operator == 'lessThan'">
AND pos &lt; #{pos}
</if>
ORDER BY pos
<if test="operator == 'lessThan' or operator == 'latest'">
DESC
</if>
LIMIT 1
</select>
</mapper>

View File

@ -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<ApiResourceModuleInfo> getModuleInfoByIds(@Param("ids") List<String> ids);
ApiDefinition selectByProjectNumAndApiNum(@Param("projectNum") String projectNum, @Param("apiNum") String apiNum);
void updatePos(String id, long pos);
List<String> selectIdByProjectIdOrderByPos(String projectId);
DropNode selectDragInfoById(String id);
DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
}

View File

@ -226,6 +226,11 @@
where id = #{id}
and project_id = #{projectId}
</update>
<update id="updatePos">
update api_definition
set pos =#{pos}
where id = #{id}
</update>
<sql id="queryWhereCondition">
<if test="request.keyword != null and request.keyword != ''">
@ -560,4 +565,33 @@
AND latest = true
limit 1
</select>
<select id="selectIdByProjectIdOrderByPos" resultType="java.lang.String">
SELECT id
FROM api_definition
WHERE project_id = #{projectId}
ORDER BY pos
</select>
<select id="selectDragInfoById" resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_definition
WHERE id = #{id}
</select>
<select id="selectNodeByPosOperator"
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_definition
WHERE project_id = #{parentId}
<if test="operator == 'moreThan'">
AND pos &gt; #{pos}
</if>
<if test="operator == 'lessThan'">
AND pos &lt; #{pos}
</if>
ORDER BY pos
<if test="operator == 'lessThan' or operator == 'latest'">
DESC
</if>
LIMIT 1
</select>
</mapper>

View File

@ -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<ExecuteReportDTO> getExecuteList(@Param("request") ExecutePageRequest request);
List<String> selectIdByProjectIdOrderByPos(String projectId);
DropNode selectDragInfoById(String id);
DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
void updatePos(String id, long pos);
Long getPos(String projectId);
}

View File

@ -13,6 +13,11 @@
<resultMap id="TestCaseProviderDTO" type="io.metersphere.dto.TestCaseProviderDTO">
<result column="tags" jdbcType="VARCHAR" property="tags" typeHandler="io.metersphere.handler.ListTypeHandler" />
</resultMap>
<update id="updatePos">
update api_scenario
set pos =#{pos}
where id = #{id}
</update>
<select id="list" resultMap="ApiScenarioDTO">
select
@ -464,6 +469,39 @@
<property name="filter" value="request.filter"/>
</include>
</select>
<select id="selectIdByProjectIdOrderByPos" resultType="java.lang.String">
select id from api_scenario
where project_id = #{projectId}
order by pos
</select>
<select id="selectDragInfoById" resultType="io.metersphere.project.dto.DropNode">
select id, pos from api_scenario where id = #{id}
</select>
<select id="selectNodeByPosOperator"
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_scenario
WHERE project_id = #{parentId}
<if test="operator == 'moreThan'">
AND pos &gt; #{pos}
</if>
<if test="operator == 'lessThan'">
AND pos &lt; #{pos}
</if>
ORDER BY pos
<if test="operator == 'lessThan' or operator == 'latest'">
DESC
</if>
LIMIT 1
</select>
<select id="getPos" resultType="java.lang.Long">
SELECT pos
FROM api_scenario
WHERE project_id = #{projectId}
ORDER BY pos DESC
LIMIT 1;
</select>
<sql id="report_filters">
<if test="${filter} != null and ${filter}.size() > 0">

View File

@ -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<String> getIdsByModules(@Param("request") ScenarioSystemRequest caseRequest);
List<ApiTestCase> getApiCaseDefinitionInfo(@Param("ids") List<String> ids);
void updatePos(String id, long pos);
List<String> selectIdByProjectIdOrderByPos(String projectId);
DropNode selectDragInfoById(String id);
DropNode selectNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
}

View File

@ -23,6 +23,11 @@
#{id}
</foreach>
</update>
<update id="updatePos">
update api_test_case
set pos =#{pos}
where id = #{id}
</update>
<select id="getPos" resultType="java.lang.Long">
SELECT pos
@ -282,6 +287,35 @@
#{id}
</foreach>
</select>
<select id="selectIdByProjectIdOrderByPos" resultType="java.lang.String">
SELECT id
FROM api_test_case
WHERE project_id = #{projectId}
ORDER BY pos
</select>
<select id="selectDragInfoById" resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_test_case
WHERE id = #{id}
</select>
<select id="selectNodeByPosOperator"
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM api_test_case
WHERE project_id = #{parentId}
<if test="operator == 'moreThan'">
AND pos &gt; #{pos}
</if>
<if test="operator == 'lessThan'">
AND pos &lt; #{pos}
</if>
ORDER BY pos
<if test="operator == 'lessThan' or operator == 'latest'">
DESC
</if>
LIMIT 1
</select>
<sql id="report_filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">

View File

@ -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<ApiDebugSimpleDTO> 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<String> 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);
}
/**
* 处理关联的文件被更新
*

View File

@ -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<String> 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) {

View File

@ -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<String> 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);
}
}

View File

@ -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<String> 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<ExecuteReportDTO> getExecuteList(ExecutePageRequest request) {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -2347,6 +2347,7 @@ public class ApiScenarioControllerTests extends BaseTest {
posRequest.setMoveMode("BEFORE");
this.requestPostWithOkAndReturn("/edit/pos", posRequest);
apiScenarioService.refreshPos(DEFAULT_PROJECT_ID);
}

View File

@ -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

View File

@ -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}")

View File

@ -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);
}
}

View File

@ -0,0 +1,9 @@
package io.metersphere.project.dto;
import lombok.Data;
@Data
public class DropNode {
private String id;
private long pos;
}

View File

@ -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;
}

View File

@ -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<String> selectIdByProjectIdOrderByPos(String projectId);
long updatePos(@Param("id") String id, @Param("pos") long pos);
void updateGroupPos(String id, long pos);
List<String> selectGroupIdByProjectIdOrderByPos(String projectId);
DropNode selectGroupDragInfoById(String id);
DropNode selectGroupNodeByPosOperator(NodeSortQueryParam nodeSortQueryParam);
}

View File

@ -1,6 +1,18 @@
<?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="io.metersphere.project.mapper.ExtEnvironmentMapper">
<update id="updatePos">
UPDATE
environment
SET pos =#{pos}
WHERE id = #{id}
</update>
<update id="updateGroupPos">
UPDATE
environment_group
SET pos =#{pos}
WHERE id = #{id}
</update>
<select id="selectByKeyword" resultType="io.metersphere.sdk.domain.Environment">
SELECT
@ -80,4 +92,63 @@
</if>
order by `pos` desc limit 1;
</select>
<select id="selectDragInfoById" resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM environment
WHERE id = #{0}
</select>
<select id="selectNodeByPosOperator"
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM environment
WHERE project_id = #{parentId}
<if test="operator == 'moreThan'">
AND pos &gt; #{pos}
</if>
<if test="operator == 'lessThan'">
AND pos &lt; #{pos}
</if>
ORDER BY pos
<if test="operator == 'lessThan' or operator == 'latest'">
DESC
</if>
LIMIT 1
</select>
<select id="selectIdByProjectIdOrderByPos" resultType="java.lang.String">
SELECT id
FROM environment
WHERE project_id = #{projectId}
ORDER BY pos
</select>
<select id="selectGroupIdByProjectIdOrderByPos" resultType="java.lang.String">
SELECT id
FROM environment_group
WHERE project_id = #{projectId}
ORDER BY pos
</select>
<select id="selectGroupDragInfoById" resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM environment_group
WHERE id = #{0}
</select>
<select id="selectGroupNodeByPosOperator"
parameterType="io.metersphere.project.dto.NodeSortQueryParam"
resultType="io.metersphere.project.dto.DropNode">
SELECT id, pos
FROM environment_group
WHERE project_id = #{parentId}
<if test="operator == 'moreThan'">
AND pos &gt; #{pos}
</if>
<if test="operator == 'lessThan'">
AND pos &lt; #{pos}
</if>
ORDER BY pos
<if test="operator == 'lessThan' or operator == 'latest'">
DESC
</if>
LIMIT 1
</select>
</mapper>

View File

@ -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<EnvironmentGroupRelation> getEnvironmentGroupRelations(List<String> 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<String> 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);
}
}

View File

@ -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<byte[]> 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<EnvironmentPluginScriptDTO> 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<String> 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);
}
}

View File

@ -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<String, DropNode> selectIdNodeFunc, Function<NodeSortQueryParam, DropNode> 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());
}
}
}

View File

@ -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);
}

View File

@ -323,6 +323,7 @@ public class EnvironmentGroupControllerTests extends BaseTest {
posRequest.setMoveMode("BEFORE");
this.requestPostWithOkAndReturn(POS_URL, posRequest);
environmentGroupService.refreshPos(DEFAULT_PROJECT_ID);
}