refactor(接口测试): 优化执行历史清理和显示

This commit is contained in:
wxg0103 2024-04-16 20:52:12 +08:00 committed by Craftsman
parent 2ceefff085
commit 854e4b2412
18 changed files with 164 additions and 106 deletions

View File

@ -33,6 +33,12 @@ public class ExecuteReportDTO implements Serializable {
@Schema(description = "是否删除") @Schema(description = "是否删除")
private boolean deleted; private boolean deleted;
@Schema(description = "执行历史是否被清理")
private boolean historyDeleted = false;
@Schema(description = "是否集成")
private boolean integrated;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -4,6 +4,7 @@ import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.dto.definition.ApiReportBatchRequest; import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest; import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.definition.ApiReportStepDTO; import io.metersphere.api.dto.definition.ApiReportStepDTO;
import io.metersphere.api.dto.definition.ExecuteReportDTO;
import io.metersphere.api.dto.report.ReportDTO; import io.metersphere.api.dto.report.ReportDTO;
import io.metersphere.system.dto.sdk.ApiReportMessageDTO; import io.metersphere.system.dto.sdk.ApiReportMessageDTO;
import io.metersphere.system.dto.taskcenter.TaskCenterDTO; import io.metersphere.system.dto.taskcenter.TaskCenterDTO;
@ -41,4 +42,6 @@ public interface ExtApiReportMapper {
void updateApiCaseStatus(@Param("ids") List<String> ids); void updateApiCaseStatus(@Param("ids") List<String> ids);
List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> ids); List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> ids);
List<ExecuteReportDTO> getHistoryDeleted(@Param("ids") List<String> ids);
} }

View File

@ -194,8 +194,8 @@
LEFT JOIN api_test_case c ON a.api_test_case_id = c.id LEFT JOIN api_test_case c ON a.api_test_case_id = c.id
LEFT JOIN test_resource_pool t ON ar.pool_id = t.id LEFT JOIN test_resource_pool t ON ar.pool_id = t.id
left join project on ar.project_id = project.id left join project on ar.project_id = project.id
where ar.deleted = false where
and ar.test_plan_id = 'NONE' ar.test_plan_id = 'NONE'
and ar.start_time BETWEEN #{startTime} AND #{endTime} and ar.start_time BETWEEN #{startTime} AND #{endTime}
) as api_report ) as api_report
where where
@ -265,5 +265,14 @@
</if> </if>
</select> </select>
<select id="getHistoryDeleted" resultType="io.metersphere.api.dto.definition.ExecuteReportDTO">
select ar.* from api_report ar INNER JOIN api_report_step ars on ar.id = ars.report_id
<if test="ids != null and ids.size() > 0">
where ar.id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</select>
</mapper> </mapper>

View File

@ -4,6 +4,7 @@ import io.metersphere.api.domain.ApiScenarioBlob;
import io.metersphere.api.domain.ApiScenarioReport; import io.metersphere.api.domain.ApiScenarioReport;
import io.metersphere.api.dto.definition.ApiReportBatchRequest; import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest; import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.definition.ExecuteReportDTO;
import io.metersphere.api.dto.report.ReportDTO; import io.metersphere.api.dto.report.ReportDTO;
import io.metersphere.api.dto.scenario.ApiScenarioReportStepDTO; import io.metersphere.api.dto.scenario.ApiScenarioReportStepDTO;
import io.metersphere.system.dto.sdk.ApiReportMessageDTO; import io.metersphere.system.dto.sdk.ApiReportMessageDTO;
@ -54,4 +55,7 @@ public interface ExtApiScenarioReportMapper {
List<ApiScenarioReportStepDTO> selectStepDeatilByReportId(String id); List<ApiScenarioReportStepDTO> selectStepDeatilByReportId(String id);
List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> ids); List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> ids);
List<ExecuteReportDTO> getHistoryDeleted(@Param("ids") List<String> ids);
} }

View File

@ -173,8 +173,7 @@
left JOIN api_scenario s on a.api_scenario_id = s.id left JOIN api_scenario s on a.api_scenario_id = s.id
left JOIN test_resource_pool t on asr.pool_id = t.id left JOIN test_resource_pool t on asr.pool_id = t.id
left join project on asr.project_id = project.id left join project on asr.project_id = project.id
where asr.deleted = false where asr.test_plan_id = 'NONE'
and asr.test_plan_id = 'NONE'
and asr.start_time BETWEEN #{startTime} AND #{endTime} ) api_scenario_report and asr.start_time BETWEEN #{startTime} AND #{endTime} ) api_scenario_report
where where
api_scenario_report.project_id IN api_scenario_report.project_id IN
@ -245,6 +244,16 @@
</foreach> </foreach>
</if> </if>
</select> </select>
<select id="getHistoryDeleted" resultType="io.metersphere.api.dto.definition.ExecuteReportDTO">
select asr.* from
api_scenario_report asr inner join api_scenario_report_step ars on asr.id = ars.report_id
<if test="ids != null and ids.size() > 0">
where asr.id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</select>
<sql id="filters"> <sql id="filters">
<if test="${filter} != null and ${filter}.size() > 0"> <if test="${filter} != null and ${filter}.size() > 0">

View File

@ -246,7 +246,8 @@
api_report.create_user, api_report.create_user,
api_report.trigger_mode, api_report.trigger_mode,
api_report.test_plan_id, api_report.test_plan_id,
api_report.deleted api_report.deleted,
api_report.integrated
from api_report from api_report
left join api_test_case_record atc on atc.api_report_id = api_report.id left join api_test_case_record atc on atc.api_report_id = api_report.id
where where

View File

@ -2,6 +2,7 @@ package io.metersphere.api.service;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod; import com.github.pagehelper.page.PageMethod;
import io.metersphere.api.dto.definition.ExecuteReportDTO;
import io.metersphere.api.dto.report.ReportDTO; import io.metersphere.api.dto.report.ReportDTO;
import io.metersphere.api.mapper.ExtApiReportMapper; import io.metersphere.api.mapper.ExtApiReportMapper;
import io.metersphere.api.mapper.ExtApiScenarioReportMapper; import io.metersphere.api.mapper.ExtApiScenarioReportMapper;
@ -36,14 +37,13 @@ import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.TaskRunnerClient; import io.metersphere.system.utils.TaskRunnerClient;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.function.Function;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -131,17 +131,25 @@ public class ApiTaskCenterService {
List<TaskCenterDTO> list = new ArrayList<>(); List<TaskCenterDTO> list = new ArrayList<>();
List<String> projectIds = projectList.stream().map(OptionDTO::getId).toList(); List<String> projectIds = projectList.stream().map(OptionDTO::getId).toList();
if (request != null && !projectIds.isEmpty()) { if (request != null && !projectIds.isEmpty()) {
Map<String, ExecuteReportDTO> historyDeletedMap = new HashMap<>();
if (request.getModuleType().equals(TaskCenterResourceType.API_CASE.toString())) { if (request.getModuleType().equals(TaskCenterResourceType.API_CASE.toString())) {
list = extApiReportMapper.taskCenterlist(request, projectIds, DateUtils.getDailyStartTime(), DateUtils.getDailyEndTime()); list = extApiReportMapper.taskCenterlist(request, projectIds, DateUtils.getDailyStartTime(), DateUtils.getDailyEndTime());
//执行历史列表
List<String> reportIds = list.stream().map(TaskCenterDTO::getId).toList();
List<ExecuteReportDTO> historyDeletedList = extApiReportMapper.getHistoryDeleted(reportIds);
historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
} else if (request.getModuleType().equals(TaskCenterResourceType.API_SCENARIO.toString())) { } else if (request.getModuleType().equals(TaskCenterResourceType.API_SCENARIO.toString())) {
list = extApiScenarioReportMapper.taskCenterlist(request, projectIds, DateUtils.getDailyStartTime(), DateUtils.getDailyEndTime()); list = extApiScenarioReportMapper.taskCenterlist(request, projectIds, DateUtils.getDailyStartTime(), DateUtils.getDailyEndTime());
List<String> reportIds = list.stream().map(TaskCenterDTO::getId).toList();
List<ExecuteReportDTO> historyDeletedList = extApiScenarioReportMapper.getHistoryDeleted(reportIds);
historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
} }
processTaskCenter(list, projectList, projectIds); processTaskCenter(list, projectList, projectIds, historyDeletedMap);
} }
return list; return list;
} }
private void processTaskCenter(List<TaskCenterDTO> list, List<OptionDTO> projectList, List<String> projectIds) { private void processTaskCenter(List<TaskCenterDTO> list, List<OptionDTO> projectList, List<String> projectIds, Map<String, ExecuteReportDTO> historyDeletedMap) {
if (!list.isEmpty()) { if (!list.isEmpty()) {
// 取所有的userid // 取所有的userid
Set<String> userSet = list.stream() Set<String> userSet = list.stream()
@ -158,6 +166,7 @@ public class ApiTaskCenterService {
item.setOperationName(userMap.getOrDefault(item.getOperationName(), StringUtils.EMPTY)); item.setOperationName(userMap.getOrDefault(item.getOperationName(), StringUtils.EMPTY));
item.setProjectName(projectMap.getOrDefault(item.getProjectId(), StringUtils.EMPTY)); item.setProjectName(projectMap.getOrDefault(item.getProjectId(), StringUtils.EMPTY));
item.setOrganizationName(orgMap.getOrDefault(item.getProjectId(), StringUtils.EMPTY)); item.setOrganizationName(orgMap.getOrDefault(item.getProjectId(), StringUtils.EMPTY));
item.setHistoryDeleted(MapUtils.isNotEmpty(historyDeletedMap) && !historyDeletedMap.containsKey(item.getId()));
}); });
} }
} }

View File

@ -5,7 +5,6 @@ import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.report.ApiReportListDTO; import io.metersphere.api.dto.report.ApiReportListDTO;
import io.metersphere.api.mapper.*; import io.metersphere.api.mapper.*;
import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.sdk.constants.ApiExecuteResourceType;
import io.metersphere.sdk.constants.ApiReportStatus; import io.metersphere.sdk.constants.ApiReportStatus;
import io.metersphere.sdk.domain.Environment; import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentGroup; import io.metersphere.sdk.domain.EnvironmentGroup;
@ -23,7 +22,6 @@ import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.service.UserLoginService; import io.metersphere.system.service.UserLoginService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
@ -215,41 +213,14 @@ public class ApiReportService {
apiReportDTO.setEnvironmentName(environmentName); apiReportDTO.setEnvironmentName(environmentName);
apiReportDTO.setCreatUserName(userMapper.selectByPrimaryKey(apiReportDTO.getCreateUser()).getName()); apiReportDTO.setCreatUserName(userMapper.selectByPrimaryKey(apiReportDTO.getCreateUser()).getName());
//需要查询出所有的步骤 //需要查询出所有的步骤
if (BooleanUtils.isTrue(apiReport.getIntegrated())) { List<ApiReportStepDTO> apiReportSteps = extApiReportMapper.selectStepsByReportId(id);
List<ApiReportStepDTO> apiReportSteps = extApiReportMapper.selectStepsByReportId(id); if (CollectionUtils.isEmpty(apiReportSteps)) {
if (CollectionUtils.isEmpty(apiReportSteps)) {
throw new MSException(Translator.get("api_case_report_not_exist"));
}
apiReportSteps.sort(Comparator.comparingLong(ApiReportStepDTO::getSort));
apiReportDTO.setChildren(apiReportSteps);
apiReportDTO.setTotal((long) apiReportSteps.size());
apiReportDTO.setPendingCount(apiReportSteps.stream().filter(step -> StringUtils.equals(ApiReportStatus.PENDING.name(), step.getStatus()) || StringUtils.isBlank(step.getStatus())).count());
return apiReportDTO;
}
ApiTestCaseRecordExample example = new ApiTestCaseRecordExample();
example.createCriteria().andApiReportIdEqualTo(id);
List<ApiTestCaseRecord> apiTestCaseRecords = apiTestCaseRecordMapper.selectByExample(example);
if (CollectionUtils.isEmpty(apiTestCaseRecords)) {
throw new MSException(Translator.get("api_case_report_not_exist")); throw new MSException(Translator.get("api_case_report_not_exist"));
} }
ApiReportDetailExample apiReportDetailExample = new ApiReportDetailExample(); apiReportSteps.sort(Comparator.comparingLong(ApiReportStepDTO::getSort));
apiReportDetailExample.createCriteria().andReportIdEqualTo(id).andStepIdEqualTo(apiTestCaseRecords.getFirst().getApiTestCaseId()); apiReportDTO.setChildren(apiReportSteps);
List<ApiReportDetail> apiReportDetails = apiReportDetailMapper.selectByExampleWithBLOBs(apiReportDetailExample); apiReportDTO.setTotal((long) apiReportSteps.size());
if (CollectionUtils.isNotEmpty(apiReportDetails)) { apiReportDTO.setPendingCount(apiReportSteps.stream().filter(step -> StringUtils.equals(ApiReportStatus.PENDING.name(), step.getStatus()) || StringUtils.isBlank(step.getStatus())).count());
ApiReportStepDTO apiReportStepDTO = new ApiReportStepDTO();
BeanUtils.copyBean(apiReportStepDTO, apiReportDetails.getFirst());
apiReportStepDTO.setStepId(apiTestCaseRecords.getFirst().getApiTestCaseId());
apiReportStepDTO.setReportId(id);
apiReportStepDTO.setSort(1L);
apiReportStepDTO.setName(apiReport.getName());
apiReportStepDTO.setStepType(ApiExecuteResourceType.API_CASE.name());
List<ApiReportStepDTO> apiReportSteps = new ArrayList<>();
apiReportSteps.add(apiReportStepDTO);
apiReportDTO.setChildren(apiReportSteps);
} else {
apiReportDTO.setTotal(1L);
apiReportDTO.setPendingCount(1L);
}
return apiReportDTO; return apiReportDTO;
} }

View File

@ -366,6 +366,7 @@ public class ApiTestCaseBatchRunService {
public List<ApiTestCaseRecord> initApiReport(ApiRunModeConfigDTO runModeConfig, List<ApiTestCase> apiTestCases, String userId) { public List<ApiTestCaseRecord> initApiReport(ApiRunModeConfigDTO runModeConfig, List<ApiTestCase> apiTestCases, String userId) {
List<ApiReport> apiReports = new ArrayList<>(); List<ApiReport> apiReports = new ArrayList<>();
List<ApiTestCaseRecord> apiTestCaseRecords = new ArrayList<>(); List<ApiTestCaseRecord> apiTestCaseRecords = new ArrayList<>();
List<ApiReportStep> apiReportSteps = new ArrayList<>();
for (ApiTestCase apiTestCase : apiTestCases) { for (ApiTestCase apiTestCase : apiTestCases) {
// 初始化报告 // 初始化报告
ApiReport apiReport = getApiReport(runModeConfig, apiTestCase, userId); ApiReport apiReport = getApiReport(runModeConfig, apiTestCase, userId);
@ -373,8 +374,10 @@ public class ApiTestCaseBatchRunService {
// 创建报告和用例的关联关系 // 创建报告和用例的关联关系
ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(apiTestCase, apiReport); ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(apiTestCase, apiReport);
apiTestCaseRecords.add(apiTestCaseRecord); apiTestCaseRecords.add(apiTestCaseRecord);
apiReportSteps.add(getApiReportStep(apiTestCase, apiReport.getId(), 1));
} }
apiReportService.insertApiReport(apiReports, apiTestCaseRecords); apiReportService.insertApiReport(apiReports, apiTestCaseRecords);
apiReportService.insertApiReportStep(apiReportSteps);
return apiTestCaseRecords; return apiTestCaseRecords;
} }

View File

@ -102,6 +102,8 @@ public class ApiTestCaseService extends MoveNodeService {
private EnvironmentService environmentService; private EnvironmentService environmentService;
@Resource @Resource
private ApiTestCaseNoticeService apiTestCaseNoticeService; private ApiTestCaseNoticeService apiTestCaseNoticeService;
@Resource
private ExtApiReportMapper extApiReportMapper;
private static final String CASE_TABLE = "api_test_case"; private static final String CASE_TABLE = "api_test_case";
private static final int MAX_TAG_SIZE = 10; private static final int MAX_TAG_SIZE = 10;
@ -557,10 +559,16 @@ public class ApiTestCaseService extends MoveNodeService {
.collect(Collectors.toSet()); .collect(Collectors.toSet());
Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet)); Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
//执行历史列表
List<String> reportIds = executeList.stream().map(ExecuteReportDTO::getId).toList();
List<ExecuteReportDTO> historyDeletedList = extApiReportMapper.getHistoryDeleted(reportIds);
Map<String, ExecuteReportDTO> historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
executeList.forEach(apiReport -> { executeList.forEach(apiReport -> {
apiReport.setOperationUser(userMap.get(apiReport.getCreateUser())); apiReport.setOperationUser(userMap.get(apiReport.getCreateUser()));
Date date = new Date(apiReport.getStartTime()); Date date = new Date(apiReport.getStartTime());
apiReport.setNum(sdf.format(date)); apiReport.setNum(sdf.format(date));
apiReport.setHistoryDeleted(MapUtils.isNotEmpty(historyDeletedMap) && !historyDeletedMap.containsKey(apiReport.getId()));
}); });
return executeList; return executeList;
} }
@ -754,9 +762,21 @@ public class ApiTestCaseService extends MoveNodeService {
ApiTestCaseRecord apiTestCaseRecord = getApiTestCaseRecord(apiTestCase, apiReport); ApiTestCaseRecord apiTestCaseRecord = getApiTestCaseRecord(apiTestCase, apiReport);
apiReportService.insertApiReport(List.of(apiReport), List.of(apiTestCaseRecord)); apiReportService.insertApiReport(List.of(apiReport), List.of(apiTestCaseRecord));
//初始化步骤
apiReportService.insertApiReportStep(List.of(getApiReportStep(apiTestCase, reportId, 1L)));
return apiTestCaseRecord; return apiTestCaseRecord;
} }
private ApiReportStep getApiReportStep(ApiTestCase apiTestCase, String reportId, long sort) {
ApiReportStep apiReportStep = new ApiReportStep();
apiReportStep.setReportId(reportId);
apiReportStep.setStepId(apiTestCase.getId());
apiReportStep.setSort(sort);
apiReportStep.setName(apiTestCase.getName());
apiReportStep.setStepType(ApiExecuteResourceType.API_CASE.name());
return apiReportStep;
}
public ApiTestCaseRecord getApiTestCaseRecord(ApiTestCase apiTestCase, ApiReport apiReport) { public ApiTestCaseRecord getApiTestCaseRecord(ApiTestCase apiTestCase, ApiReport apiReport) {
ApiTestCaseRecord apiTestCaseRecord = new ApiTestCaseRecord(); ApiTestCaseRecord apiTestCaseRecord = new ApiTestCaseRecord();
apiTestCaseRecord.setApiTestCaseId(apiTestCase.getId()); apiTestCaseRecord.setApiTestCaseId(apiTestCase.getId());

View File

@ -192,6 +192,8 @@ public class ApiScenarioService extends MoveNodeService {
private ApiScenarioReportMapper apiScenarioReportMapper; private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource @Resource
private ApiScenarioNoticeService apiScenarioNoticeService; private ApiScenarioNoticeService apiScenarioNoticeService;
@Resource
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
public static final String PRIORITY = "Priority"; public static final String PRIORITY = "Priority";
public static final String STATUS = "Status"; public static final String STATUS = "Status";
@ -2823,12 +2825,18 @@ public class ApiScenarioService extends MoveNodeService {
Set<String> userSet = executeList.stream() Set<String> userSet = executeList.stream()
.flatMap(apiReport -> Stream.of(apiReport.getCreateUser())) .flatMap(apiReport -> Stream.of(apiReport.getCreateUser()))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
//执行历史列表
List<String> reportIds = executeList.stream().map(ExecuteReportDTO::getId).toList();
List<ExecuteReportDTO> historyDeletedList = extApiScenarioReportMapper.getHistoryDeleted(reportIds);
Map<String, ExecuteReportDTO> historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet)); Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
executeList.forEach(apiReport -> { executeList.forEach(apiReport -> {
apiReport.setOperationUser(userMap.get(apiReport.getCreateUser())); apiReport.setOperationUser(userMap.get(apiReport.getCreateUser()));
Date date = new Date(apiReport.getStartTime()); Date date = new Date(apiReport.getStartTime());
apiReport.setNum(sdf.format(date)); apiReport.setNum(sdf.format(date));
apiReport.setHistoryDeleted(MapUtils.isNotEmpty(historyDeletedMap) && !historyDeletedMap.containsKey(apiReport.getId()));
}); });
return executeList; return executeList;
} }

View File

@ -352,54 +352,6 @@ public class ApiReportControllerTests extends BaseTest {
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError()); .andExpect(status().is5xxServerError());
reports = new ArrayList<>();
apiReport = new ApiReport();
apiReport.setId("test-report-id-no-step");
apiReport.setProjectId(DEFAULT_PROJECT_ID);
apiReport.setName("test-report-name");
apiReport.setStartTime(System.currentTimeMillis());
apiReport.setCreateUser("admin");
apiReport.setUpdateUser("admin");
apiReport.setUpdateTime(System.currentTimeMillis());
apiReport.setPoolId(testResourcePools.getFirst().getId());
apiReport.setEnvironmentId(environments.getFirst().getId());
apiReport.setRunMode("api-run-mode");
apiReport.setStatus(ApiReportStatus.SUCCESS.name());
apiReport.setTriggerMode("api-trigger-mode");
apiReport.setIntegrated(false);
reports.add(apiReport);
record = new ApiTestCaseRecord();
record.setApiTestCaseId("api-resource-id");
record.setApiReportId(apiReport.getId());
apiReportService.insertApiReport(reports, List.of(record));
mockMvc.perform(getRequestBuilder(GET + "test-report-id-no-step"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful());
reports = new ArrayList<>();
apiReport = new ApiReport();
apiReport.setId("test-report-id-no-step-no-record");
apiReport.setProjectId(DEFAULT_PROJECT_ID);
apiReport.setName("test-report-name");
apiReport.setStartTime(System.currentTimeMillis());
apiReport.setCreateUser("admin");
apiReport.setUpdateUser("admin");
apiReport.setUpdateTime(System.currentTimeMillis());
apiReport.setPoolId(testResourcePools.getFirst().getId());
apiReport.setEnvironmentId(environments.getFirst().getId());
apiReport.setRunMode("api-run-mode");
apiReport.setStatus(ApiReportStatus.SUCCESS.name());
apiReport.setTriggerMode("api-trigger-mode");
apiReport.setIntegrated(false);
reports.add(apiReport);
apiReportService.insertApiReport(reports, new ArrayList<>());
mockMvc.perform(getRequestBuilder(GET + "test-report-id-no-step-no-record"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
// @@校验权限 // @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_READ, GET + "api-report-id0"); requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_READ, GET + "api-report-id0");

View File

@ -58,5 +58,8 @@ public class TaskCenterDTO implements Serializable {
@Schema(description = "是否为集合报告") @Schema(description = "是否为集合报告")
private boolean integrated; private boolean integrated;
@Schema(description = "执行历史是否被清理")
private boolean historyDeleted = false;
} }

View File

@ -83,11 +83,30 @@
<ExecutionStatus :status="record.status" :module-type="ReportEnum.API_REPORT" /> <ExecutionStatus :status="record.status" :module-type="ReportEnum.API_REPORT" />
</template> </template>
<template #operation="{ record, rowIndex }"> <template #operation="{ record, rowIndex }">
<a-tooltip :disabled="!record.deleted" :content="t('case.detail.report.delete')" position="top"> <div v-if="record.historyDeleted">
<MsButton :disabled="record.deleted" class="!mr-0" @click="showResult(record, rowIndex)" <a-tooltip :content="t('project.executionHistory.cleared')" position="top">
<MsButton
:disabled="
record.historyDeleted ||
hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ+EXECUTE', 'PROJECT_API_REPORT:READ'])
"
class="!mr-0"
@click="showResult(record, rowIndex)"
>{{ t('apiScenario.executeHistory.execution.operation') }}
</MsButton>
</a-tooltip>
</div>
<div v-else>
<MsButton
:disabled="
record.historyDeleted ||
hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ+EXECUTE', 'PROJECT_API_REPORT:READ'])
"
class="!mr-0"
@click="showResult(record, rowIndex)"
>{{ t('apiScenario.executeHistory.execution.operation') }} >{{ t('apiScenario.executeHistory.execution.operation') }}
</MsButton> </MsButton>
</a-tooltip> </div>
</template> </template>
</ms-base-table> </ms-base-table>
</div> </div>
@ -107,6 +126,7 @@
import { getApiCaseExecuteHistory } from '@/api/modules/api-test/management'; import { getApiCaseExecuteHistory } from '@/api/modules/api-test/management';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { hasAnyPermission } from '@/utils/permission';
import { ApiCaseExecuteHistoryItem } from '@/models/apiTest/management'; import { ApiCaseExecuteHistoryItem } from '@/models/apiTest/management';
import { ReportEnum, ReportStatus, TriggerModeLabel } from '@/enums/reportEnum'; import { ReportEnum, ReportStatus, TriggerModeLabel } from '@/enums/reportEnum';

View File

@ -75,9 +75,30 @@
<executeStatus :status="record.status" /> <executeStatus :status="record.status" />
</template> </template>
<template #operation="{ record }"> <template #operation="{ record }">
<MsButton class="!mr-0" @click="showResult(record)" <div v-if="record.historyDeleted">
>{{ t('apiScenario.executeHistory.execution.operation') }} <a-tooltip :content="t('project.executionHistory.cleared')" position="top">
</MsButton> <MsButton
:disabled="
record.historyDeleted ||
hasAnyPermission(['PROJECT_API_SCENARIO:READ+EXECUTE', 'PROJECT_API_REPORT:READ'])
"
class="!mr-0"
@click="showResult(record)"
>{{ t('apiScenario.executeHistory.execution.operation') }}
</MsButton>
</a-tooltip>
</div>
<div v-else>
<MsButton
:disabled="
record.historyDeleted ||
hasAnyPermission(['PROJECT_API_SCENARIO:READ+EXECUTE', 'PROJECT_API_REPORT:READ'])
"
class="!mr-0"
@click="showResult(record)"
>{{ t('apiScenario.executeHistory.execution.operation') }}
</MsButton>
</div>
</template> </template>
</ms-base-table> </ms-base-table>
<!-- 场景报告抽屉 --> <!-- 场景报告抽屉 -->
@ -98,6 +119,7 @@
import { getExecuteHistory } from '@/api/modules/api-test/scenario'; import { getExecuteHistory } from '@/api/modules/api-test/scenario';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { hasAnyPermission } from '@/utils/permission';
import { ExecuteHistoryItem } from '@/models/apiTest/scenario'; import { ExecuteHistoryItem } from '@/models/apiTest/scenario';
import { ExecuteStatusFilters } from '@/enums/apiEnum'; import { ExecuteStatusFilters } from '@/enums/apiEnum';

View File

@ -133,12 +133,27 @@
<span>{{ dayjs(record.operationTime).format('YYYY-MM-DD HH:mm:ss') }}</span> <span>{{ dayjs(record.operationTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
</template> </template>
<template #operation="{ record, rowIndex }"> <template #operation="{ record, rowIndex }">
<MsButton <div v-if="record.historyDeleted">
class="!mr-0" <a-tooltip :content="t('project.executionHistory.cleared')">
:disabled="!hasAnyPermission(permissionsMap[props.group][props.moduleType].report)" <MsButton
@click="viewReport(record.id, rowIndex)" class="!mr-0"
>{{ t('project.taskCenter.viewReport') }} :disabled="
</MsButton> record.historyDeleted || !hasAnyPermission(permissionsMap[props.group][props.moduleType].report)
"
@click="viewReport(record.id, rowIndex)"
>{{ t('project.taskCenter.viewReport') }}
</MsButton>
</a-tooltip>
</div>
<div v-else>
<MsButton
class="!mr-0"
:disabled="record.historyDeleted || !hasAnyPermission(permissionsMap[props.group][props.moduleType].report)"
@click="viewReport(record.id, rowIndex)"
>{{ t('project.taskCenter.viewReport') }}
</MsButton>
</div>
<a-divider v-if="['RUNNING', 'RERUNNING'].includes(record.status)" direction="vertical" /> <a-divider v-if="['RUNNING', 'RERUNNING'].includes(record.status)" direction="vertical" />
<MsButton <MsButton
v-if=" v-if="
@ -177,6 +192,7 @@
import caseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue'; import caseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import ReportDetailDrawer from '@/views/api-test/report/component/reportDetailDrawer.vue'; import ReportDetailDrawer from '@/views/api-test/report/component/reportDetailDrawer.vue';
import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue'; import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue';
import TemplateItem from '@/views/setting/organization/template/components/templateItem.vue';
import { import {
batchStopRealOrdApi, batchStopRealOrdApi,

View File

@ -61,4 +61,5 @@ export default {
'project.taskCenter.disableSuccess': 'Disable successfully', 'project.taskCenter.disableSuccess': 'Disable successfully',
'project.taskCenter.filterPlaceholderText': 'Please select a project', 'project.taskCenter.filterPlaceholderText': 'Please select a project',
'project.taskCenter.filterOrgPlaceholderText': 'Please select an organization', 'project.taskCenter.filterOrgPlaceholderText': 'Please select an organization',
'project.executionHistory.cleared': 'Execution history has been cleared',
}; };

View File

@ -59,4 +59,5 @@ export default {
'project.taskCenter.disableSuccess': '关闭成功', 'project.taskCenter.disableSuccess': '关闭成功',
'project.taskCenter.filterProPlaceholderText': '请选择所属项目', 'project.taskCenter.filterProPlaceholderText': '请选择所属项目',
'project.taskCenter.filterOrgPlaceholderText': '请选择所属组织', 'project.taskCenter.filterOrgPlaceholderText': '请选择所属组织',
'project.executionHistory.cleared': '执行历史被清理',
}; };