feat(接口测试): 接口测试执行信息记录增加版本的处理

接口测试执行信息记录增加版本的处理
This commit is contained in:
song-tianyang 2022-11-14 15:21:47 +08:00 committed by 建国
parent e9119a7472
commit b4b5676972
36 changed files with 725 additions and 225 deletions

View File

@ -0,0 +1,12 @@
package io.metersphere.api.dto;
import lombok.Data;
@Data
public class ApiCaseBasicInfoDTO {
private String id;
private String apiId;
private String name;
private String projectId;
private String versionId;
}

View File

@ -9,6 +9,7 @@
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="execute_type" jdbcType="VARCHAR" property="executeType" />
<result column="version" jdbcType="VARCHAR" property="version" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -69,7 +70,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, source_id, `result`, trigger_mode, create_time, project_id, execute_type
id, source_id, `result`, trigger_mode, create_time, project_id, execute_type, version
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfoExample" resultMap="BaseResultMap">
select
@ -104,10 +105,10 @@
<insert id="insert" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfo">
insert into api_case_execution_info (id, source_id, `result`,
trigger_mode, create_time, project_id,
execute_type)
execute_type, version)
values (#{id,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR},
#{triggerMode,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{projectId,jdbcType=VARCHAR},
#{executeType,jdbcType=VARCHAR})
#{executeType,jdbcType=VARCHAR}, #{version,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfo">
insert into api_case_execution_info
@ -133,6 +134,9 @@
<if test="executeType != null">
execute_type,
</if>
<if test="version != null">
version,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -156,6 +160,9 @@
<if test="executeType != null">
#{executeType,jdbcType=VARCHAR},
</if>
<if test="version != null">
#{version,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfoExample" resultType="java.lang.Long">
@ -188,6 +195,9 @@
<if test="record.executeType != null">
execute_type = #{record.executeType,jdbcType=VARCHAR},
</if>
<if test="record.version != null">
version = #{record.version,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -201,7 +211,8 @@
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
project_id = #{record.projectId,jdbcType=VARCHAR},
execute_type = #{record.executeType,jdbcType=VARCHAR}
execute_type = #{record.executeType,jdbcType=VARCHAR},
version = #{record.version,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -227,6 +238,9 @@
<if test="executeType != null">
execute_type = #{executeType,jdbcType=VARCHAR},
</if>
<if test="version != null">
version = #{version,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -237,7 +251,8 @@
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
project_id = #{projectId,jdbcType=VARCHAR},
execute_type = #{executeType,jdbcType=VARCHAR}
execute_type = #{executeType,jdbcType=VARCHAR},
version = #{version,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -8,6 +8,7 @@
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="execute_type" jdbcType="VARCHAR" property="executeType" />
<result column="version" jdbcType="VARCHAR" property="version" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -68,7 +69,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, source_id, `result`, create_time, project_id, execute_type
id, source_id, `result`, create_time, project_id, execute_type, version
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.ApiExecutionInfoExample" resultMap="BaseResultMap">
select
@ -102,11 +103,11 @@
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.ApiExecutionInfo">
insert into api_execution_info (id, source_id, `result`,
create_time, project_id, execute_type
)
create_time, project_id, execute_type,
version)
values (#{id,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{projectId,jdbcType=VARCHAR}, #{executeType,jdbcType=VARCHAR}
)
#{createTime,jdbcType=BIGINT}, #{projectId,jdbcType=VARCHAR}, #{executeType,jdbcType=VARCHAR},
#{version,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiExecutionInfo">
insert into api_execution_info
@ -129,6 +130,9 @@
<if test="executeType != null">
execute_type,
</if>
<if test="version != null">
version,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -149,6 +153,9 @@
<if test="executeType != null">
#{executeType,jdbcType=VARCHAR},
</if>
<if test="version != null">
#{version,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.ApiExecutionInfoExample" resultType="java.lang.Long">
@ -178,6 +185,9 @@
<if test="record.executeType != null">
execute_type = #{record.executeType,jdbcType=VARCHAR},
</if>
<if test="record.version != null">
version = #{record.version,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -190,7 +200,8 @@
`result` = #{record.result,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
project_id = #{record.projectId,jdbcType=VARCHAR},
execute_type = #{record.executeType,jdbcType=VARCHAR}
execute_type = #{record.executeType,jdbcType=VARCHAR},
version = #{record.version,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -213,6 +224,9 @@
<if test="executeType != null">
execute_type = #{executeType,jdbcType=VARCHAR},
</if>
<if test="version != null">
version = #{version,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -222,7 +236,8 @@
`result` = #{result,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
project_id = #{projectId,jdbcType=VARCHAR},
execute_type = #{executeType,jdbcType=VARCHAR}
execute_type = #{executeType,jdbcType=VARCHAR},
version = #{version,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -9,6 +9,7 @@
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="execute_type" jdbcType="VARCHAR" property="executeType" />
<result column="version" jdbcType="VARCHAR" property="version" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -69,7 +70,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, source_id, `result`, trigger_mode, create_time, project_id, execute_type
id, source_id, `result`, trigger_mode, create_time, project_id, execute_type, version
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.ScenarioExecutionInfoExample" resultMap="BaseResultMap">
select
@ -104,10 +105,10 @@
<insert id="insert" parameterType="io.metersphere.base.domain.ScenarioExecutionInfo">
insert into scenario_execution_info (id, source_id, `result`,
trigger_mode, create_time, project_id,
execute_type)
execute_type, version)
values (#{id,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR},
#{triggerMode,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{projectId,jdbcType=VARCHAR},
#{executeType,jdbcType=VARCHAR})
#{executeType,jdbcType=VARCHAR}, #{version,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ScenarioExecutionInfo">
insert into scenario_execution_info
@ -133,6 +134,9 @@
<if test="executeType != null">
execute_type,
</if>
<if test="version != null">
version,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -156,6 +160,9 @@
<if test="executeType != null">
#{executeType,jdbcType=VARCHAR},
</if>
<if test="version != null">
#{version,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.ScenarioExecutionInfoExample" resultType="java.lang.Long">
@ -188,6 +195,9 @@
<if test="record.executeType != null">
execute_type = #{record.executeType,jdbcType=VARCHAR},
</if>
<if test="record.version != null">
version = #{record.version,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -201,7 +211,8 @@
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
project_id = #{record.projectId,jdbcType=VARCHAR},
execute_type = #{record.executeType,jdbcType=VARCHAR}
execute_type = #{record.executeType,jdbcType=VARCHAR},
version = #{record.version,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -227,6 +238,9 @@
<if test="executeType != null">
execute_type = #{executeType,jdbcType=VARCHAR},
</if>
<if test="version != null">
version = #{version,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -237,7 +251,8 @@
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
project_id = #{projectId,jdbcType=VARCHAR},
execute_type = #{executeType,jdbcType=VARCHAR}
execute_type = #{executeType,jdbcType=VARCHAR},
version = #{version,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -33,7 +33,7 @@ public interface ExtApiDefinitionMapper {
List<ApiComputeResult> selectByIdsAndStatusIsNotTrash(@Param("ids") List<String> ids, @Param("projectId") String projectId);
// int removeToGc(@Param("ids") List<String> ids);
// int removeToGc(@Param("ids") List<String> ids);
int removeToGcByExample(ApiDefinitionExampleWithOperation example);
@ -106,4 +106,8 @@ public interface ExtApiDefinitionMapper {
List<ApiDefinition> selectApiBaseInfoByProjectIdAndProtocolAndStatus(@Param("projectId") String projectId, @Param("protocol") String protocol, @Param("versionId") String versionId, @Param("status") String status);
void updateNoModuleApiToDefaultModule(@Param("projectId") String projectId, @Param("protocol") String protocol, @Param("status") String status, @Param("versionId") String versionId, @Param("moduleId") String moduleId);
List<String> selectApiIdInExecutionInfoByProjectIdIsNull();
long countSourceIdByProjectIdIsNull();
}

View File

@ -1198,6 +1198,17 @@
AND latest IS TRUE
</if>
</select>
<select id="selectApiIdInExecutionInfoByProjectIdIsNull" resultType="java.lang.String">
SELECT DISTINCT source_id FROM api_execution_info
WHERE project_id IS NULL
</select>
<select id="countSourceIdByProjectIdIsNull" resultType="java.lang.Long">
SELECT COUNT(DISTINCT source_id)
FROM api_execution_info
WHERE project_id IS NULL
</select>
<sql id="Same_Where_Clause">
<where>
<if test="blobs">

View File

@ -107,4 +107,8 @@ public interface ExtApiScenarioMapper {
List<ApiScenarioDTO> relevanceScenarioList(@Param("request") ApiScenarioRequest request);
List<BaseCase> selectBaseCaseByProjectId(@Param("projectId") String projectId);
List<String> selectScenarioIdInExecutionInfoByProjectIdIsNull();
long countSourceIdByProjectIdIsNull();
}

View File

@ -1052,4 +1052,17 @@
</where>
and api_scenario.status!='Trash'
</select>
<select id="selectScenarioIdInExecutionInfoByProjectIdIsNull" resultType="java.lang.String">
SELECT DISTINCT source_id
FROM scenario_execution_info
WHERE project_id IS NULL
</select>
<select id="countSourceIdByProjectIdIsNull" resultType="java.lang.Long">
SELECT COUNT(DISTINCT source_id)
FROM scenario_execution_info
WHERE project_id IS NULL
</select>
</mapper>

View File

@ -1,5 +1,6 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.api.dto.ApiCaseBasicInfoDTO;
import io.metersphere.api.dto.ApiCountChartResult;
import io.metersphere.api.dto.ApiCountRequest;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
@ -99,4 +100,12 @@ public interface ExtApiTestCaseMapper {
List<BaseCase> selectBaseCaseByProjectId(@Param("projectId") String projectId);
int getCaseCountById(String id);
ApiDefinition selectApiBasicInfoByCaseId(String id);
ApiCaseBasicInfoDTO selectApiCaseBasicInfoById(String ids);
List<String> selectSourceIdByProjectIdIsNull();
long countSourceIdByProjectIdIsNull();
}

View File

@ -1243,4 +1243,31 @@
AND api_definition_id = #{apiId}
</where>
</select>
<select id="selectApiBasicInfoByCaseId" resultType="io.metersphere.base.domain.ApiDefinition">
select id, project_id, name, version_id
FROM api_definition
WHERE id IN (
SELECT api_definition_id FROM api_test_case WHERE id = #{0}
)
</select>
<select id="selectApiCaseBasicInfoById" resultType="io.metersphere.api.dto.ApiCaseBasicInfoDTO">
SELECT apiCase.id,apiCase.project_id,api.version_id
FROM api_definition api
INNER JOIN api_test_case apiCase ON api.id = apiCase.api_definition_id
WHERE apiCase.id = #{0}
</select>
<select id="selectSourceIdByProjectIdIsNull" resultType="java.lang.String">
SELECT DISTINCT source_id
FROM api_case_execution_info
WHERE project_id IS NULL
</select>
<select id="countSourceIdByProjectIdIsNull" resultType="java.lang.Long">
SELECT COUNT(DISTINCT source_id)
FROM api_case_execution_info
WHERE project_id IS NULL
</select>
</mapper>

View File

@ -6,7 +6,10 @@ import io.metersphere.base.mapper.ext.ExtApiScenarioReportResultMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioReportStructureMapper;
import io.metersphere.commons.constants.KafkaTopicConstants;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.service.definition.ApiCaseExecutionInfoService;
import io.metersphere.service.definition.ApiExecutionInfoService;
import io.metersphere.service.ext.ExtApiScheduleService;
import io.metersphere.service.scenario.ApiScenarioExecutionInfoService;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
@ -39,11 +42,11 @@ public class ProjectDeletedListener {
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ApiExecutionInfoMapper apiExecutionInfoMapper;
private ApiExecutionInfoService apiExecutionInfoService;
@Resource
private ApiCaseExecutionInfoMapper apiCaseExecutionInfoMapper;
private ApiCaseExecutionInfoService apiCaseExecutionInfoService;
@Resource
private ScenarioExecutionInfoMapper scenarioExecutionInfoMapper;
private ApiScenarioExecutionInfoService apiScenarioExecutionInfoService;
public static final String CONSUME_ID = "project-deleted";
@ -79,17 +82,9 @@ public class ProjectDeletedListener {
}
private void deleteExecutionInfo(String projectId) {
ApiExecutionInfoExample apiExecutionInfoExample = new ApiExecutionInfoExample();
apiExecutionInfoExample.createCriteria().andProjectIdEqualTo(projectId);
apiExecutionInfoMapper.deleteByExample(apiExecutionInfoExample);
ApiCaseExecutionInfoExample apiCaseExecutionInfoExample = new ApiCaseExecutionInfoExample();
apiCaseExecutionInfoExample.createCriteria().andProjectIdEqualTo(projectId);
apiCaseExecutionInfoMapper.deleteByExample(apiCaseExecutionInfoExample);
ScenarioExecutionInfoExample scenarioExecutionInfoExample = new ScenarioExecutionInfoExample();
scenarioExecutionInfoExample.createCriteria().andProjectIdEqualTo(projectId);
scenarioExecutionInfoMapper.deleteByExample(scenarioExecutionInfoExample);
apiExecutionInfoService.deleteByProjectId(projectId);
apiCaseExecutionInfoService.deleteByProjectId(projectId);
apiScenarioExecutionInfoService.deleteByProjectId(projectId);
}
private void delReport(String projectId) {

View File

@ -166,9 +166,9 @@ public class TestResultService {
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
if (apiScenario != null) {
if (StringUtils.equalsAnyIgnoreCase(dto.getRunMode(), ApiRunMode.SCENARIO_PLAN.name(), ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
scenarioExecutionInfoService.insertExecutionInfo(dto.getTestId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name());
scenarioExecutionInfoService.insertExecutionInfo(dto.getTestId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name(), apiScenario.getVersionId());
} else {
scenarioExecutionInfoService.insertExecutionInfo(scenarioReport.getScenarioId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name());
scenarioExecutionInfoService.insertExecutionInfo(scenarioReport.getScenarioId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode(), scenarioReport.getProjectId() == null ? apiScenario.getProjectId() : scenarioReport.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiScenario.getVersionId());
}
environment = apiScenarioReportService.getEnvironment(apiScenario);
userName = apiAutomationService.getUser(apiScenario.getUserId());

View File

@ -3,7 +3,7 @@ package io.metersphere.service.definition;
import io.metersphere.base.domain.ApiCaseExecutionInfo;
import io.metersphere.base.domain.ApiCaseExecutionInfoExample;
import io.metersphere.base.mapper.ApiCaseExecutionInfoMapper;
import org.apache.commons.collections.CollectionUtils;
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -18,9 +18,11 @@ import java.util.UUID;
public class ApiCaseExecutionInfoService {
@Resource
private ApiCaseExecutionInfoMapper apiCaseExecutionInfoMapper;
@Resource
private ExtApiTestCaseMapper extApiTestCaseMapper;
@Lazy
public void insertExecutionInfo(String apiCaseId, String result, String triggerMode, String projectId, String executeType) {
public void insertExecutionInfo(String apiCaseId, String result, String triggerMode, String projectId, String executeType, String version) {
if (StringUtils.isNotEmpty(apiCaseId) && StringUtils.isNotEmpty(result)) {
ApiCaseExecutionInfo executionInfo = new ApiCaseExecutionInfo();
executionInfo.setResult(result);
@ -30,6 +32,7 @@ public class ApiCaseExecutionInfoService {
executionInfo.setTriggerMode(triggerMode);
executionInfo.setProjectId(projectId);
executionInfo.setExecuteType(executeType);
executionInfo.setVersion(version);
apiCaseExecutionInfoMapper.insert(executionInfo);
}
}
@ -49,30 +52,29 @@ public class ApiCaseExecutionInfoService {
return apiCaseExecutionInfoMapper.countByExample(example);
}
public List<ApiCaseExecutionInfo> selectByProjectIdIsNull() {
ApiCaseExecutionInfoExample example = new ApiCaseExecutionInfoExample();
example.createCriteria().andProjectIdIsNull();
return apiCaseExecutionInfoMapper.selectByExample(example);
}
public void updateProjectIdBySourceIdAndProjectIdIsNull(String projectId, String executeType, String apiId) {
if (StringUtils.isNoneEmpty(projectId, executeType, apiId)) {
public void updateProjectIdBySourceIdAndProjectIdIsNull(String projectId, String executeType, String version, String sourceId) {
if (StringUtils.isNoneEmpty(projectId, executeType, sourceId)) {
ApiCaseExecutionInfoExample example = new ApiCaseExecutionInfoExample();
example.createCriteria().andProjectIdIsNull().andSourceIdEqualTo(apiId);
example.createCriteria().andProjectIdIsNull().andSourceIdEqualTo(sourceId);
ApiCaseExecutionInfo updateModel = new ApiCaseExecutionInfo();
updateModel.setProjectId(projectId);
updateModel.setExecuteType(executeType);
updateModel.setVersion(version);
apiCaseExecutionInfoMapper.updateByExampleSelective(updateModel, example);
}
}
public void deleteByIds(List<String> deleteIdList) {
if (CollectionUtils.isNotEmpty(deleteIdList)) {
ApiCaseExecutionInfoExample example = new ApiCaseExecutionInfoExample();
example.createCriteria().andIdIn(deleteIdList);
apiCaseExecutionInfoMapper.deleteByExample(example);
}
public List<String> selectSourceIdByProjectIdIsNull() {
return extApiTestCaseMapper.selectSourceIdByProjectIdIsNull();
}
public void deleteBySourceIdAndProjectIsNull(String sourceId) {
ApiCaseExecutionInfoExample example = new ApiCaseExecutionInfoExample();
example.createCriteria().andProjectIdIsNull().andSourceIdEqualTo(sourceId);
apiCaseExecutionInfoMapper.deleteByExample(example);
}
public long countSourceIdByProjectIdIsNull() {
return extApiTestCaseMapper.countSourceIdByProjectIdIsNull();
}
}

View File

@ -6,6 +6,7 @@ import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
import io.metersphere.base.mapper.plan.TestPlanApiCaseMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.NoticeConstants;
@ -63,6 +64,8 @@ public class ApiDefinitionExecResultService {
private ApiCaseExecutionInfoService apiCaseExecutionInfoService;
@Resource
private TestPlanService testPlanService;
@Resource
private ExtApiTestCaseMapper extApiTestCaseMapper;
/**
* API/CASE 重试结果保留一条
@ -302,7 +305,9 @@ public class ApiDefinitionExecResultService {
if (apiCase != null) {
TestPlan testPlan = testPlanService.get(apiCase.getTestPlanId());
if (testPlan != null) {
apiCaseExecutionInfoService.insertExecutionInfo(apiCase.getId(), status, triggerMode, testPlan.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name());
ApiDefinition apiDefinition = extApiTestCaseMapper.selectApiBasicInfoByCaseId(apiCase.getId());
String version = apiDefinition == null ? "" : apiDefinition.getVersionId();
apiCaseExecutionInfoService.insertExecutionInfo(apiCase.getId(), status, triggerMode, testPlan.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name(), version);
}
apiCase.setStatus(status);

View File

@ -75,6 +75,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.json.JSONObject;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
@ -3017,26 +3018,33 @@ public class ApiDefinitionService {
return extApiTestCaseMapper.selectBaseCaseByProjectId(projectId);
}
@Async
public void setProjectIdInExecutionInfo() {
List<ApiExecutionInfo> apiExecutionInfoList = apiExecutionInfoService.selectByProjectIdIsNull();
if (CollectionUtils.isNotEmpty(apiExecutionInfoList)) {
Map<String, List<ApiExecutionInfo>> groupByApiIdMap = apiExecutionInfoList.stream().collect(Collectors.groupingBy(ApiExecutionInfo::getSourceId));
List<ApiDefinition> apiDefinitionList = this.selectByIds(new ArrayList<>(groupByApiIdMap.keySet()));
if (CollectionUtils.isNotEmpty(apiDefinitionList)) {
Map<String, String> apiIdProjectIdMap = apiDefinitionList.stream().collect(Collectors.toMap(ApiDefinition::getId, ApiDefinition::getProjectId));
List<String> deleteIdList = new ArrayList<>();
for (Map.Entry<String, List<ApiExecutionInfo>> entry : groupByApiIdMap.entrySet()) {
String apiId = entry.getKey();
if (apiIdProjectIdMap.containsKey(apiId)) {
apiExecutionInfoService.updateProjectIdByApiIdAndProjectIdIsNull(apiIdProjectIdMap.get(apiId), ExecutionExecuteTypeEnum.BASIC.name(), apiId);
} else {
deleteIdList.addAll(entry.getValue().stream().map(ApiExecutionInfo::getId).collect(Collectors.toList()));
}
}
if (CollectionUtils.isNotEmpty(deleteIdList)) {
apiExecutionInfoService.deleteByIds(deleteIdList);
long lastCount = 0;
long allSourceIdCount = apiExecutionInfoService.countSourceIdByProjectIdIsNull();
//分批进行查询更新处理
int pageSize = 1000;
while (allSourceIdCount > 0) {
if (allSourceIdCount == lastCount) {
//数据无法再更新时跳出循环
break;
} else {
lastCount = allSourceIdCount;
}
PageHelper.startPage(0, pageSize, false);
List<String> sourceIdAboutProjectIdIsNull = apiExecutionInfoService.selectSourceIdByProjectIdIsNull();
PageHelper.clearPage();
//批量更新
for (String apiId : sourceIdAboutProjectIdIsNull) {
ApiDefinition apiDefinition = this.get(apiId);
if (apiDefinition != null) {
apiExecutionInfoService.updateProjectIdByApiIdAndProjectIdIsNull(apiDefinition.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiDefinition.getVersionId(), apiId);
} else {
apiExecutionInfoService.deleteBySourceIdAndProjectIdIsNull(apiId);
}
}
allSourceIdCount = apiExecutionInfoService.countSourceIdByProjectIdIsNull();
}
}
}

View File

@ -1,17 +1,15 @@
package io.metersphere.service.definition;
import io.metersphere.base.domain.ApiCaseExecutionInfo;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiExecutionInfo;
import io.metersphere.base.domain.ApiExecutionInfoExample;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiCaseExecutionInfoMapper;
import io.metersphere.base.mapper.ApiDefinitionMapper;
import io.metersphere.base.mapper.ApiExecutionInfoMapper;
import io.metersphere.base.mapper.ApiTestCaseMapper;
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
import io.metersphere.base.mapper.ext.ExtApiDefinitionMapper;
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
import io.metersphere.base.mapper.plan.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.commons.enums.ExecutionExecuteTypeEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -36,6 +34,10 @@ public class ApiExecutionInfoService {
private ExtApiTestCaseMapper extApiTestCaseMapper;
@Resource
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
private ApiDefinitionMapper apiDefinitionMapper;
@Resource
private ApiTestCaseMapper apiTestCaseMapper;
@Lazy
public void insertExecutionInfo(ApiDefinitionExecResult result) {
@ -44,24 +46,27 @@ public class ApiExecutionInfoService {
if (resourceID == null) {
resourceID = extApiDefinitionExecResultMapper.selectResourceId(result.getId());
}
boolean isApiDefinition = extApiDefinitionMapper.countById(resourceID) > 0;
if (isApiDefinition) {
this.insertApiExecutionInfo(resourceID, result.getStatus(), result.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name());
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(resourceID);
if (apiDefinition != null) {
this.insertApiExecutionInfo(apiDefinition.getId(), result.getStatus(), result.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiDefinition.getVersionId());
} else {
boolean isApiCase = extApiTestCaseMapper.countById(resourceID) > 0;
if (isApiCase) {
this.insertApiCaseExecutionInfo(resourceID, result.getStatus(), result.getTriggerMode(), result.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name());
ApiDefinition apiBasieInfoByCaseId = extApiTestCaseMapper.selectApiBasicInfoByCaseId(resourceID);
if (apiBasieInfoByCaseId != null) {
this.insertApiCaseExecutionInfo(resourceID, result.getStatus(), result.getTriggerMode(), result.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiBasieInfoByCaseId.getVersionId());
} else {
String apiCaseIdInTestPlan = extTestPlanApiCaseMapper.getApiTestCaseIdById(resourceID);
if (StringUtils.isNotEmpty(apiCaseIdInTestPlan)) {
this.insertApiCaseExecutionInfo(resourceID, result.getStatus(), result.getTriggerMode(), result.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name());
apiBasieInfoByCaseId = extApiTestCaseMapper.selectApiBasicInfoByCaseId(resourceID);
if (apiBasieInfoByCaseId != null) {
this.insertApiCaseExecutionInfo(resourceID, result.getStatus(), result.getTriggerMode(), result.getProjectId(), ExecutionExecuteTypeEnum.TEST_PLAN.name(), apiBasieInfoByCaseId.getVersionId());
}
}
}
}
}
}
private void insertApiCaseExecutionInfo(String resourceID, String status, String triggerMode, String projectId, String executeType) {
private void insertApiCaseExecutionInfo(String resourceID, String status, String triggerMode, String projectId, String executeType, String versionId) {
ApiCaseExecutionInfo info = new ApiCaseExecutionInfo();
info.setId(UUID.randomUUID().toString());
info.setSourceId(resourceID);
@ -73,7 +78,7 @@ public class ApiExecutionInfoService {
apiCaseExecutionInfoMapper.insert(info);
}
private void insertApiExecutionInfo(String resourceID, String status, String projectId, String executeType) {
private void insertApiExecutionInfo(String resourceID, String status, String projectId, String executeType, String versionId) {
ApiExecutionInfo info = new ApiExecutionInfo();
info.setId(UUID.randomUUID().toString());
info.setSourceId(resourceID);
@ -81,6 +86,7 @@ public class ApiExecutionInfoService {
info.setResult(status);
info.setProjectId(projectId);
info.setExecuteType(executeType);
info.setVersion(versionId);
apiExecutionInfoMapper.insert(info);
}
@ -92,29 +98,29 @@ public class ApiExecutionInfoService {
}
}
public List<ApiExecutionInfo> selectByProjectIdIsNull() {
ApiExecutionInfoExample example = new ApiExecutionInfoExample();
example.createCriteria().andProjectIdIsNull();
return apiExecutionInfoMapper.selectByExample(example);
}
public void updateProjectIdByApiIdAndProjectIdIsNull(String projectId, String executeType, String apiId) {
public void updateProjectIdByApiIdAndProjectIdIsNull(String projectId, String executeType, String version, String apiId) {
if (StringUtils.isNoneEmpty(projectId, executeType, apiId)) {
ApiExecutionInfoExample example = new ApiExecutionInfoExample();
example.createCriteria().andProjectIdIsNull().andSourceIdEqualTo(apiId);
ApiExecutionInfo updateModel = new ApiExecutionInfo();
updateModel.setProjectId(projectId);
updateModel.setExecuteType(executeType);
updateModel.setVersion(version);
apiExecutionInfoMapper.updateByExampleSelective(updateModel, example);
}
}
public void deleteByIds(List<String> deleteIdList) {
if (CollectionUtils.isNotEmpty(deleteIdList)) {
ApiExecutionInfoExample example = new ApiExecutionInfoExample();
example.createCriteria().andIdIn(deleteIdList);
apiExecutionInfoMapper.deleteByExample(example);
}
public void deleteBySourceIdAndProjectIdIsNull(String sourceId) {
ApiExecutionInfoExample example = new ApiExecutionInfoExample();
example.createCriteria().andSourceIdEqualTo(sourceId).andProjectIdIsNull();
apiExecutionInfoMapper.deleteByExample(example);
}
public List<String> selectSourceIdByProjectIdIsNull() {
return extApiDefinitionMapper.selectApiIdInExecutionInfoByProjectIdIsNull();
}
public long countSourceIdByProjectIdIsNull() {
return extApiDefinitionMapper.countSourceIdByProjectIdIsNull();
}
}

View File

@ -2,6 +2,7 @@ package io.metersphere.service.definition;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ApiScenarioRequest;
@ -41,7 +42,6 @@ import io.metersphere.xpack.api.service.ApiTestCaseSyncService;
import io.metersphere.xpack.version.service.ProjectVersionService;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.comparators.FixedOrderComparator;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@ -51,6 +51,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.util.FileUtil;
import org.json.JSONObject;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@ -1243,52 +1244,47 @@ public class ApiTestCaseService {
return apiCaseExecutionInfoService.countExecutedTimesByProjectId(projectId, executeType);
}
@Async
public void setProjectIdInExecutionInfo() {
List<ApiCaseExecutionInfo> apiExecutionInfoList = apiCaseExecutionInfoService.selectByProjectIdIsNull();
if (CollectionUtils.isNotEmpty(apiExecutionInfoList)) {
Map<String, List<ApiCaseExecutionInfo>> groupByApiIdMap = apiExecutionInfoList.stream().collect(Collectors.groupingBy(ApiCaseExecutionInfo::getSourceId));
List<ApiTestCase> apiTestCaseList = this.selectCasesBydIds(new ArrayList<>(groupByApiIdMap.keySet()));
Map<String, List<ApiCaseExecutionInfo>> testPlanCaseMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(apiTestCaseList)) {
Map<String, String> apiIdProjectIdMap = apiTestCaseList.stream().collect(Collectors.toMap(ApiTestCase::getId, ApiTestCase::getProjectId));
for (Map.Entry<String, List<ApiCaseExecutionInfo>> entry : groupByApiIdMap.entrySet()) {
String apiCaseId = entry.getKey();
if (apiIdProjectIdMap.containsKey(apiCaseId)) {
apiCaseExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(apiIdProjectIdMap.get(apiCaseId), ExecutionExecuteTypeEnum.BASIC.name(), apiCaseId);
} else {
testPlanCaseMap.put(apiCaseId, entry.getValue());
}
}
long lastCount = 0;
long allSourceIdCount = apiCaseExecutionInfoService.countSourceIdByProjectIdIsNull();
//分批进行查询更新处理
int pageSize = 1000;
while (allSourceIdCount > 0) {
if (allSourceIdCount == lastCount) {
//数据无法再更新时跳出循环
break;
} else {
testPlanCaseMap = groupByApiIdMap;
lastCount = allSourceIdCount;
}
if (MapUtils.isNotEmpty(testPlanCaseMap)) {
//通过apiCase查询不到的可能是testPlanApiCase
List<TestPlanApiCase> testPlanApiCaseList = testPlanApiCaseService.selectByIds(new ArrayList<>(testPlanCaseMap.keySet()));
Map<String, TestPlanApiCase> testPlanApiCaseMap = new HashMap<>();
testPlanApiCaseList.forEach(item -> {
testPlanApiCaseMap.put(item.getId(), item);
});
List<String> deleteIdList = new ArrayList<>();
for (Map.Entry<String, List<ApiCaseExecutionInfo>> entry : testPlanCaseMap.entrySet()) {
String testPlanApiCaseId = entry.getKey();
if (testPlanApiCaseMap.containsKey(testPlanApiCaseId)) {
String projectId = testPlanApiCaseService.selectProjectId(testPlanApiCaseMap.get(testPlanApiCaseId).getTestPlanId());
if (StringUtils.isNotEmpty(projectId)) {
apiCaseExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(projectId, ExecutionExecuteTypeEnum.TEST_PLAN.name(), testPlanApiCaseId);
PageHelper.startPage(0, pageSize, false);
List<String> sourceIdAboutProjectIdIsNull = apiCaseExecutionInfoService.selectSourceIdByProjectIdIsNull();
PageHelper.clearPage();
//批量更新
for (String sourceId : sourceIdAboutProjectIdIsNull) {
ApiCaseBasicInfoDTO apiCaseBasicInfoDTO = this.selectApiCaseBasicInfoById(sourceId);
if (apiCaseBasicInfoDTO != null) {
apiCaseExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(apiCaseBasicInfoDTO.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), apiCaseBasicInfoDTO.getVersionId(), sourceId);
} else {
TestPlanApiCase testPlanApiCase = testPlanApiCaseService.getById(sourceId);
if (testPlanApiCase != null) {
String projectId = testPlanApiCaseService.selectProjectId(sourceId);
apiCaseBasicInfoDTO = this.selectApiCaseBasicInfoById(testPlanApiCase.getApiCaseId());
if (StringUtils.isNotEmpty(projectId) && apiCaseBasicInfoDTO != null) {
apiCaseExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(projectId, ExecutionExecuteTypeEnum.TEST_PLAN.name(), apiCaseBasicInfoDTO.getVersionId(), sourceId);
} else {
deleteIdList.addAll(entry.getValue().stream().map(ApiCaseExecutionInfo::getId).collect(Collectors.toList()));
apiCaseExecutionInfoService.deleteBySourceIdAndProjectIsNull(sourceId);
}
} else {
deleteIdList.addAll(entry.getValue().stream().map(ApiCaseExecutionInfo::getId).collect(Collectors.toList()));
apiCaseExecutionInfoService.deleteBySourceIdAndProjectIsNull(sourceId);
}
}
if (CollectionUtils.isNotEmpty(deleteIdList)) {
apiCaseExecutionInfoService.deleteByIds(deleteIdList);
}
}
allSourceIdCount = apiCaseExecutionInfoService.countSourceIdByProjectIdIsNull();
}
}
private ApiCaseBasicInfoDTO selectApiCaseBasicInfoById(String id) {
return extApiTestCaseMapper.selectApiCaseBasicInfoById(id);
}
}

View File

@ -1,8 +1,12 @@
package io.metersphere.service.scenario;
import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioExample;
import io.metersphere.base.domain.ScenarioExecutionInfo;
import io.metersphere.base.domain.ScenarioExecutionInfoExample;
import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ScenarioExecutionInfoMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
import io.metersphere.commons.utils.JSON;
import io.metersphere.commons.utils.LogUtil;
import org.apache.commons.collections.CollectionUtils;
@ -20,9 +24,13 @@ import java.util.UUID;
public class ApiScenarioExecutionInfoService {
@Resource
private ScenarioExecutionInfoMapper scenarioExecutionInfoMapper;
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
private ExtApiScenarioMapper extApiScenarioMapper;
@Lazy
public void insertExecutionInfo(String scenarioId, String result, String triggerMode, String projectId, String executeType) {
public void insertExecutionInfo(String scenarioId, String result, String triggerMode, String projectId, String executeType, String version) {
if (StringUtils.isNotEmpty(scenarioId) && StringUtils.isNotEmpty(result)) {
ScenarioExecutionInfo executionInfo = new ScenarioExecutionInfo();
executionInfo.setResult(result);
@ -32,15 +40,25 @@ public class ApiScenarioExecutionInfoService {
executionInfo.setTriggerMode(triggerMode);
executionInfo.setProjectId(projectId);
executionInfo.setExecuteType(executeType);
executionInfo.setVersion(version);
scenarioExecutionInfoMapper.insert(executionInfo);
}
}
public void insertExecutionInfoByScenarioList(List<ApiScenario> apiScenarios, String status, String triggerMode, String projectId, String executeType) {
for (ApiScenario apiScenario : apiScenarios) {
this.insertExecutionInfo(apiScenario.getId(), status, triggerMode, projectId, executeType, apiScenario.getVersionId());
}
}
public void insertExecutionInfoByScenarioIds(String scenarioIdJsonString, String status, String triggerMode, String projectId, String executeType) {
try {
List<String> scenarioIdList = JSON.parseArray(scenarioIdJsonString, String.class);
for (String scenarioId : scenarioIdList) {
this.insertExecutionInfo(scenarioId, status, triggerMode, projectId, executeType);
if (CollectionUtils.isNotEmpty(scenarioIdList)) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdIn(scenarioIdList);
List<ApiScenario> apiScenarios = apiScenarioMapper.selectByExample(example);
this.insertExecutionInfoByScenarioList(apiScenarios, status, triggerMode, projectId, executeType);
}
} catch (Exception e) {
LogUtil.error("解析场景ID的JSON" + scenarioIdJsonString + "失败!", e);
@ -55,31 +73,22 @@ public class ApiScenarioExecutionInfoService {
}
}
public List<ScenarioExecutionInfo> selectByProjectIdIsNull() {
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
example.createCriteria().andProjectIdIsNull();
return scenarioExecutionInfoMapper.selectByExample(example);
}
public void updateProjectIdBySourceIdAndProjectIdIsNull(String projectId, String executeType, String apiId) {
public void updateProjectIdBySourceIdAndProjectIdIsNull(String projectId, String executeType, String version, String apiId) {
if (StringUtils.isNoneEmpty(projectId, executeType, apiId)) {
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
example.createCriteria().andProjectIdIsNull().andSourceIdEqualTo(apiId);
ScenarioExecutionInfo updateModel = new ScenarioExecutionInfo();
updateModel.setProjectId(projectId);
updateModel.setExecuteType(executeType);
updateModel.setVersion(version);
scenarioExecutionInfoMapper.updateByExampleSelective(updateModel, example);
}
}
public void deleteByIds(List<String> deleteIdList) {
if (CollectionUtils.isNotEmpty(deleteIdList)) {
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
example.createCriteria().andIdIn(deleteIdList);
scenarioExecutionInfoMapper.deleteByExample(example);
}
public void deleteBySourceIdAndProjectIdIsNull(String sourceId) {
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
example.createCriteria().andSourceIdEqualTo(sourceId).andProjectIdIsNull();
scenarioExecutionInfoMapper.deleteByExample(example);
}
public long countExecuteTimesByProjectID(String projectId, String triggerMode) {
@ -91,4 +100,12 @@ public class ApiScenarioExecutionInfoService {
}
return scenarioExecutionInfoMapper.countByExample(example);
}
public List<String> selectSourceIdByProjectIdIsNull() {
return extApiScenarioMapper.selectScenarioIdInExecutionInfoByProjectIdIsNull();
}
public long countSourceIdByProjectIdIsNull() {
return extApiScenarioMapper.countSourceIdByProjectIdIsNull();
}
}

View File

@ -1,5 +1,6 @@
package io.metersphere.service.scenario;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.automation.*;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
@ -74,6 +75,7 @@ import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONObject;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@ -2226,12 +2228,12 @@ public class ApiScenarioService {
List<ApiScenarioWithBLOBs> apiScenarios = apiScenarioMapper.selectByExampleWithBLOBs(example);
Map<String, List<String>> projectEnvMap = new HashMap<>();
apiScenarios.forEach(item -> {
if (StringUtils.isNotBlank(item.getEnvironmentJson())){
if (StringUtils.isNotBlank(item.getEnvironmentJson())) {
JSONObject jsonObject = JSONUtil.parseObject(item.getEnvironmentJson());
Map<String, Object> projectIdEnvMap = jsonObject.toMap();
if (MapUtils.isNotEmpty(projectIdEnvMap)) {
Set<String> projectIds = projectIdEnvMap.keySet();
projectIds.forEach(t->{
projectIds.forEach(t -> {
List<String> envIds = projectEnvMap.get(t);
if (CollectionUtils.isNotEmpty(envIds)) {
if (!envIds.contains(projectIdEnvMap.get(t).toString())) {
@ -2239,9 +2241,9 @@ public class ApiScenarioService {
}
} else {
Object o = projectIdEnvMap.get(t);
List<String>envIdList = new ArrayList<>();
List<String> envIdList = new ArrayList<>();
envIdList.add(o.toString());
projectEnvMap.put(t,envIdList);
projectEnvMap.put(t, envIdList);
}
});
}
@ -2249,51 +2251,55 @@ public class ApiScenarioService {
});
return projectEnvMap;
}
public void setProjectIdInExecutionInfo() {
List<ScenarioExecutionInfo> apiExecutionInfoList = scenarioExecutionInfoService.selectByProjectIdIsNull();
if (CollectionUtils.isNotEmpty(apiExecutionInfoList)) {
Map<String, List<ScenarioExecutionInfo>> groupByScenarioIdMap = apiExecutionInfoList.stream().collect(Collectors.groupingBy(ScenarioExecutionInfo::getSourceId));
List<ApiScenario> scenarioList = this.selectByIds(new ArrayList<>(groupByScenarioIdMap.keySet()));
Map<String, List<ScenarioExecutionInfo>> testPlanScenarioExecutionMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(scenarioList)) {
Map<String, String> scenarioIdProjectIdMap = scenarioList.stream().collect(Collectors.toMap(ApiScenario::getId, ApiScenario::getProjectId));
for (Map.Entry<String, List<ScenarioExecutionInfo>> entry : groupByScenarioIdMap.entrySet()) {
String apiCaseId = entry.getKey();
if (scenarioIdProjectIdMap.containsKey(apiCaseId)) {
scenarioExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(scenarioIdProjectIdMap.get(apiCaseId), ExecutionExecuteTypeEnum.BASIC.name(), apiCaseId);
} else {
testPlanScenarioExecutionMap.put(apiCaseId, entry.getValue());
}
}
} else {
testPlanScenarioExecutionMap = groupByScenarioIdMap;
}
if (MapUtils.isNotEmpty(testPlanScenarioExecutionMap)) {
//通过apiCase查询不到的可能是testPlanApiCase
List<TestPlanApiScenario> scenarios = testPlanScenarioCaseService.selectByIds(new ArrayList<>(testPlanScenarioExecutionMap.keySet()));
Map<String, TestPlanApiScenario> testPlanScenarioMap = new HashMap<>();
scenarios.forEach(item -> {
testPlanScenarioMap.put(item.getId(), item);
});
List<String> deleteIdList = new ArrayList<>();
for (Map.Entry<String, List<ScenarioExecutionInfo>> entry : testPlanScenarioExecutionMap.entrySet()) {
String testPlanApiCaseId = entry.getKey();
if (testPlanScenarioMap.containsKey(testPlanApiCaseId)) {
String projectId = testPlanScenarioCaseService.selectProjectId(testPlanScenarioMap.get(testPlanApiCaseId).getTestPlanId());
if (StringUtils.isNotEmpty(projectId)) {
scenarioExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(projectId, ExecutionExecuteTypeEnum.TEST_PLAN.name(), testPlanApiCaseId);
@Async
public void setProjectIdInExecutionInfo() {
long lastCount = 0;
long allSourceIdCount = scenarioExecutionInfoService.countSourceIdByProjectIdIsNull();
//分批进行查询更新处理
int pageSize = 1000;
while (allSourceIdCount > 0) {
if (allSourceIdCount == lastCount) {
//数据无法再更新时跳出循环
break;
} else {
lastCount = allSourceIdCount;
}
PageHelper.startPage(0, pageSize, false);
List<String> sourceIdAboutProjectIdIsNull = scenarioExecutionInfoService.selectSourceIdByProjectIdIsNull();
PageHelper.clearPage();
//批量更新
for (String sourceId : sourceIdAboutProjectIdIsNull) {
ApiScenario scenario = this.selectApiScenarioById(sourceId);
if (scenario != null) {
scenarioExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(scenario.getProjectId(), ExecutionExecuteTypeEnum.BASIC.name(), scenario.getVersionId(), sourceId);
} else {
TestPlanApiScenario testPlanApiScenario = testPlanScenarioCaseService.get(sourceId);
if (testPlanApiScenario != null) {
String projectId = testPlanScenarioCaseService.selectProjectId(testPlanApiScenario.getTestPlanId());
scenario = this.selectApiScenarioById(testPlanApiScenario.getApiScenarioId());
if (StringUtils.isNotEmpty(projectId) && scenario != null) {
scenarioExecutionInfoService.updateProjectIdBySourceIdAndProjectIdIsNull(projectId, ExecutionExecuteTypeEnum.TEST_PLAN.name(), scenario.getVersionId(), sourceId);
} else {
deleteIdList.addAll(entry.getValue().stream().map(ScenarioExecutionInfo::getId).collect(Collectors.toList()));
scenarioExecutionInfoService.deleteBySourceIdAndProjectIdIsNull(sourceId);
}
} else {
deleteIdList.addAll(entry.getValue().stream().map(ScenarioExecutionInfo::getId).collect(Collectors.toList()));
scenarioExecutionInfoService.deleteBySourceIdAndProjectIdIsNull(sourceId);
}
}
if (CollectionUtils.isNotEmpty(deleteIdList)) {
scenarioExecutionInfoService.deleteByIds(deleteIdList);
}
}
allSourceIdCount = scenarioExecutionInfoService.countSourceIdByProjectIdIsNull();
}
}
private ApiScenario selectApiScenarioById(String id) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdEqualTo(id);
List<ApiScenario> scenarioList = apiScenarioMapper.selectByExample(example);
if (CollectionUtils.isEmpty(scenarioList)) {
return null;
} else {
return scenarioList.get(0);
}
}
}

View File

@ -1,13 +1,23 @@
ALTER TABLE api_execution_info ADD project_id VARCHAR(50) NULL;
ALTER TABLE api_execution_info ADD execute_type VARCHAR(50) NULL;
ALTER TABLE api_case_execution_info ADD project_id VARCHAR(50) NULL;
ALTER TABLE api_case_execution_info ADD execute_type VARCHAR(50) NULL;
ALTER TABLE scenario_execution_info ADD project_id VARCHAR(50) NULL;
ALTER TABLE scenario_execution_info ADD execute_type VARCHAR(50) NULL;
ALTER TABLE api_execution_info ADD INDEX idx_project_id(project_id);
ALTER TABLE api_execution_info ADD INDEX idx_execute_type(execute_type);
ALTER TABLE api_case_execution_info ADD INDEX idx_project_id(project_id);
ALTER TABLE api_case_execution_info ADD INDEX idx_execute_type(execute_type);
ALTER TABLE scenario_execution_info ADD INDEX idx_project_id(project_id);
ALTER TABLE scenario_execution_info ADD INDEX idx_execute_type(execute_type);
ALTER TABLE api_execution_info ADD project_id VARCHAR ( 50 ) NULL;
ALTER TABLE api_execution_info ADD execute_type VARCHAR ( 50 ) NULL;
ALTER TABLE api_execution_info ADD version VARCHAR ( 255 ) NULL;
ALTER TABLE api_case_execution_info ADD project_id VARCHAR ( 50 ) NULL;
ALTER TABLE api_case_execution_info ADD execute_type VARCHAR ( 50 ) NULL;
ALTER TABLE api_case_execution_info ADD version VARCHAR ( 255 ) NULL;
ALTER TABLE scenario_execution_info ADD project_id VARCHAR ( 50 ) NULL;
ALTER TABLE scenario_execution_info ADD execute_type VARCHAR ( 50 ) NULL;
ALTER TABLE scenario_execution_info ADD version VARCHAR ( 255 ) NULL;
ALTER TABLE api_execution_info ADD INDEX idx_project_id(project_id);
ALTER TABLE api_execution_info ADD INDEX idx_execute_type(execute_type);
ALTER TABLE api_execution_info ADD INDEX idx_version ( version );
ALTER TABLE api_case_execution_info ADD INDEX idx_version ( version );
ALTER TABLE api_case_execution_info ADD INDEX idx_project_id(project_id);
ALTER TABLE api_case_execution_info ADD INDEX idx_execute_type(execute_type);
ALTER TABLE scenario_execution_info ADD INDEX idx_version ( version );
ALTER TABLE scenario_execution_info ADD INDEX idx_project_id(project_id);
ALTER TABLE scenario_execution_info ADD INDEX idx_execute_type(execute_type);

View File

@ -1,5 +1,5 @@
<template>
<div style="background-color:#E5E5E5;overflow: auto">
<div style="background-color:#F5F6F7;overflow: auto">
<ms-container>
<ms-main-container style="padding: 0px">
<div class="api-home-layout">
@ -142,6 +142,7 @@ export default {
.api-home-layout :deep(.main-info-card) {
height: 197px;
width: 100%;
color: #646A73;
background-color: #FFFFFF;
box-sizing: border-box;
border: 1px solid #DEE0E3;
@ -157,6 +158,7 @@ export default {
line-height: 22px;
font-size: 14px;
font-weight: 400;
color: #646A73;
}
.api-home-layout :deep(.addition-info-text) {
@ -184,5 +186,4 @@ export default {
color: #1F2329;
line-height: 22px;
}
</style>

View File

@ -5,7 +5,7 @@
<div v-show="!isHover" class="transition-box">
<div style="margin:16px 0 0 16px">
<span class="addition-info-title"> {{ title }}</span>
<el-tooltip class="item" effect="light" :content="toolTip" placement="top-start">
<el-tooltip class="item" effect="dark" :content="toolTip" placement="top">
<img style="height: 14px;width: 14px;margin-left: 4px" src="/assets/figma/icon_question.svg"/>
</el-tooltip>
<div class="common-amount" @mouseenter="isHover=true">

View File

@ -78,12 +78,14 @@ export default {
font-size: 20px;
font-weight: 500;
line-height: 28px;
color: #1F2329;
}
.main-num {
font-size: 32px;
font-weight: 500;
line-height: 40px;
color: #1F2329;
}
.common-amount-button {

View File

@ -134,7 +134,7 @@ export default {
},
title: {
text: "{mainTitle|" + this.$t("home.dashboard.api.api_total") + "}\n\n{number|" + this.getAmount() + "}\n\n",
subtext: this.$t("home.dashboard.public.this_week") + "+" + this.apiData.createdInWeek + " >",
subtext: this.$t("home.dashboard.public.this_week") + "+" + formatNumber(this.apiData.createdInWeek) + " >",
top: "center",
left: "center",
textStyle: {
@ -157,7 +157,7 @@ export default {
color: "#1F2329",
fontSize: 12,
width: 105,
ellipsis: '... >',
ellipsis: '...',
overflow: "truncate",
},
itemGap: -60,
@ -165,7 +165,7 @@ export default {
series: [
{
type: 'pie',
radius: ['75%', '96%'],
radius: ['70%', '96%'],
avoidLabelOverlap: false,
hoverAnimation: true,
label: {

View File

@ -1,6 +1,6 @@
<template>
<div class="dashboard-card">
<el-card shadow="hover" class="box-card" style="height: 100%">
<el-card shadow="never" class="box-card" style="height: 100%">
<div slot="header" class="clearfix">
<span class="dashboard-title">{{ $t('home.dashboard.api_case.title') }}</span>
</div>

View File

@ -1,6 +1,6 @@
<template>
<div class="dashboard-card">
<el-card shadow="hover" class="box-card" style="height: 100%">
<el-card shadow="never" class="box-card" style="height: 100%">
<div slot="header" class="clearfix">
<span class="dashboard-title">{{ $t('home.dashboard.api.title') }}</span>
</div>

View File

@ -1,6 +1,6 @@
<template>
<div class="dashboard-card">
<el-card shadow="hover" class="box-card" style="height: 100%">
<el-card shadow="never" class="box-card" style="height: 100%">
<div slot="header" class="clearfix">
<span class="dashboard-title">{{ $t('home.dashboard.scenario.title') }}</span>
</div>

View File

@ -1,6 +1,6 @@
<template>
<div class="dashboard-card">
<el-card shadow="hover" class="box-card" style="height: 100%">
<el-card shadow="never" class="box-card" style="height: 100%">
<div slot="header" class="clearfix">
<span class="dashboard-title">{{ $t('home.dashboard.scenario_schedule.title') }}</span>
</div>

View File

@ -0,0 +1,110 @@
<template>
<el-row type="flex" justify="end">
<div class="home-table-page">
<el-pagination
background
:pager-count="5"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="pageSize"
:layout="layout"
:total="total">
</el-pagination>
</div>
</el-row>
</template>
<script>
export default {
name: "MsTablePagination",
props: {
page: Object,
currentPage: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 5
},
layout: {
type: String,
default() {
return 'total, sizes, prev, pager, next, jumper';
}
},
pageSizes: {
type: Array,
default: function () {
return [5, 10, 20, 50]
}
},
total: {
type: Number,
default: 0
},
change: Function
},
methods: {
handleSizeChange: function (size) {
this.$emit('update:pageSize', size)
this.change();
},
handleCurrentChange(current) {
this.$emit('update:currentPage', current)
this.change();
}
}
}
</script>
<style scoped>
.home-table-page {
padding-top: 10px;
}
.home-table-page :deep(.el-pagination.is-background .el-pager li) {
background-color: #FFFFFF;
color: #1F2329;
border: 1px solid #BBBFC4;
width: 28px;
height: 28px;
box-sizing: border-box;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
line-height: 26px;
}
.home-table-page :deep(.el-pagination.is-background .el-pager li:not(.disabled).active) {
background-color: #FFFFFF;
color: #783887;
border: 1px solid #783887;
}
.home-table-page :deep(.el-pagination.is-background .btn-next,) {
background-color: #FFFFFF;
border: 1px solid #BBBFC4;
width: 28px;
height: 28px;
box-sizing: border-box;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
line-height: 26px;
}
.home-table-page :deep(.el-pagination.is-background .btn-prev) {
background-color: #FFFFFF;
border: 1px solid #BBBFC4;
width: 28px;
height: 28px;
box-sizing: border-box;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
line-height: 26px;
}
</style>

View File

@ -79,8 +79,9 @@
</div>
</template>
</el-table>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<home-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
layout="prev, pager, next"
:total="total"/>
</div>
</div>
</div>
@ -91,15 +92,15 @@ import {definitionWeekList} from "@/api/definition";
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
import {API_STATUS} from "@/business/definition/model/JsonData";
import ApiStatus from "@/business/definition/components/list/ApiStatus";
import MsTablePagination from "metersphere-frontend/src/components/pagination/TablePagination";
import BasicStatuslabel from "@/business/home/components/BasicStatusLabel";
import HomeTablePagination from "@/business/home/components/table/HomeTablePagination";
import BasicStatusLabel from "@/business/home/components/BasicStatusLabel";
import BasicStatus from "@/business/home/components/BasicStatusLabel";
export default {
name: "UpdatedApiList",
components: {
BasicStatus,
BasicStatuslabel, ApiStatus, MsTablePagination
BasicStatusLabel, ApiStatus, HomeTablePagination
},
data() {
return {
@ -108,7 +109,7 @@ export default {
loading: false,
tableData: [],
currentPage: 1,
pageSize: 10,
pageSize: 5,
total: 0,
status: API_STATUS,
}

View File

@ -19,5 +19,7 @@ public class ApiCaseExecutionInfo implements Serializable {
private String executeType;
private String version;
private static final long serialVersionUID = 1L;
}

View File

@ -583,6 +583,76 @@ public class ApiCaseExecutionInfoExample {
addCriterion("execute_type not between", value1, value2, "executeType");
return (Criteria) this;
}
public Criteria andVersionIsNull() {
addCriterion("version is null");
return (Criteria) this;
}
public Criteria andVersionIsNotNull() {
addCriterion("version is not null");
return (Criteria) this;
}
public Criteria andVersionEqualTo(String value) {
addCriterion("version =", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotEqualTo(String value) {
addCriterion("version <>", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThan(String value) {
addCriterion("version >", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThanOrEqualTo(String value) {
addCriterion("version >=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThan(String value) {
addCriterion("version <", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThanOrEqualTo(String value) {
addCriterion("version <=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLike(String value) {
addCriterion("version like", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotLike(String value) {
addCriterion("version not like", value, "version");
return (Criteria) this;
}
public Criteria andVersionIn(List<String> values) {
addCriterion("version in", values, "version");
return (Criteria) this;
}
public Criteria andVersionNotIn(List<String> values) {
addCriterion("version not in", values, "version");
return (Criteria) this;
}
public Criteria andVersionBetween(String value1, String value2) {
addCriterion("version between", value1, value2, "version");
return (Criteria) this;
}
public Criteria andVersionNotBetween(String value1, String value2) {
addCriterion("version not between", value1, value2, "version");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -17,5 +17,7 @@ public class ApiExecutionInfo implements Serializable {
private String executeType;
private String version;
private static final long serialVersionUID = 1L;
}

View File

@ -513,6 +513,76 @@ public class ApiExecutionInfoExample {
addCriterion("execute_type not between", value1, value2, "executeType");
return (Criteria) this;
}
public Criteria andVersionIsNull() {
addCriterion("version is null");
return (Criteria) this;
}
public Criteria andVersionIsNotNull() {
addCriterion("version is not null");
return (Criteria) this;
}
public Criteria andVersionEqualTo(String value) {
addCriterion("version =", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotEqualTo(String value) {
addCriterion("version <>", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThan(String value) {
addCriterion("version >", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThanOrEqualTo(String value) {
addCriterion("version >=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThan(String value) {
addCriterion("version <", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThanOrEqualTo(String value) {
addCriterion("version <=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLike(String value) {
addCriterion("version like", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotLike(String value) {
addCriterion("version not like", value, "version");
return (Criteria) this;
}
public Criteria andVersionIn(List<String> values) {
addCriterion("version in", values, "version");
return (Criteria) this;
}
public Criteria andVersionNotIn(List<String> values) {
addCriterion("version not in", values, "version");
return (Criteria) this;
}
public Criteria andVersionBetween(String value1, String value2) {
addCriterion("version between", value1, value2, "version");
return (Criteria) this;
}
public Criteria andVersionNotBetween(String value1, String value2) {
addCriterion("version not between", value1, value2, "version");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -19,5 +19,7 @@ public class ScenarioExecutionInfo implements Serializable {
private String executeType;
private String version;
private static final long serialVersionUID = 1L;
}

View File

@ -583,6 +583,76 @@ public class ScenarioExecutionInfoExample {
addCriterion("execute_type not between", value1, value2, "executeType");
return (Criteria) this;
}
public Criteria andVersionIsNull() {
addCriterion("version is null");
return (Criteria) this;
}
public Criteria andVersionIsNotNull() {
addCriterion("version is not null");
return (Criteria) this;
}
public Criteria andVersionEqualTo(String value) {
addCriterion("version =", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotEqualTo(String value) {
addCriterion("version <>", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThan(String value) {
addCriterion("version >", value, "version");
return (Criteria) this;
}
public Criteria andVersionGreaterThanOrEqualTo(String value) {
addCriterion("version >=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThan(String value) {
addCriterion("version <", value, "version");
return (Criteria) this;
}
public Criteria andVersionLessThanOrEqualTo(String value) {
addCriterion("version <=", value, "version");
return (Criteria) this;
}
public Criteria andVersionLike(String value) {
addCriterion("version like", value, "version");
return (Criteria) this;
}
public Criteria andVersionNotLike(String value) {
addCriterion("version not like", value, "version");
return (Criteria) this;
}
public Criteria andVersionIn(List<String> values) {
addCriterion("version in", values, "version");
return (Criteria) this;
}
public Criteria andVersionNotIn(List<String> values) {
addCriterion("version not in", values, "version");
return (Criteria) this;
}
public Criteria andVersionBetween(String value1, String value2) {
addCriterion("version between", value1, value2, "version");
return (Criteria) this;
}
public Criteria andVersionNotBetween(String value1, String value2) {
addCriterion("version not between", value1, value2, "version");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {