feat(系统设置): 任务中心增加测试计划列表
This commit is contained in:
parent
a7356c2d98
commit
4e4266972a
|
@ -45,10 +45,9 @@ public class MessageListener {
|
|||
@KafkaListener(id = MESSAGE_CONSUME_ID, topics = KafkaTopicConstants.API_REPORT_TASK_TOPIC, groupId = MESSAGE_CONSUME_ID)
|
||||
public void messageConsume(ConsumerRecord<?, String> record) {
|
||||
try {
|
||||
LogUtils.info("接收到发送通知信息:{}", record.key());
|
||||
if (ObjectUtils.isNotEmpty(record.value())) {
|
||||
ApiNoticeDTO dto = JSON.parseObject(record.value(), ApiNoticeDTO.class);
|
||||
|
||||
LogUtils.info("接收到发送通知信息:{}", dto.getReportId());
|
||||
// 集合报告不发送通知
|
||||
if (!BooleanUtils.isTrue(dto.getIntegratedReport())) {
|
||||
apiReportSendNoticeService.sendNotice(dto);
|
||||
|
|
|
@ -217,7 +217,6 @@
|
|||
left join project on ar.project_id = project.id
|
||||
where
|
||||
ar.deleted = false
|
||||
and ar.test_plan_id = 'NONE'
|
||||
and ar.start_time BETWEEN #{startTime} AND #{endTime}
|
||||
and ar.exec_status in ('PENDING', 'RUNNING', 'RERUNNING')
|
||||
<if test="ids != null and ids.size() > 0">
|
||||
|
|
|
@ -111,7 +111,6 @@
|
|||
left join project on asr.project_id = project.id
|
||||
where
|
||||
asr.deleted = false
|
||||
and asr.test_plan_id = 'NONE'
|
||||
and asr.start_time BETWEEN #{startTime} AND #{endTime}
|
||||
and asr.exec_status in ('PENDING', 'RUNNING', 'RERUNNING')
|
||||
<if test="ids != null and ids.size() > 0">
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package io.metersphere.plan.controller;
|
||||
|
||||
import io.metersphere.plan.service.TestPlanTaskCenterService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.system.dto.taskcenter.TaskCenterDTO;
|
||||
import io.metersphere.system.dto.taskcenter.request.TaskCenterPageRequest;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import io.metersphere.system.utils.SessionUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/task/center/plan")
|
||||
@Tag(name = "任务中心-实时任务-测试计划")
|
||||
public class TestPlanTaskCenterController {
|
||||
|
||||
@Resource
|
||||
private TestPlanTaskCenterService testPlanTaskCenterService;
|
||||
|
||||
private static final String PROJECT = "project";
|
||||
private static final String ORG = "org";
|
||||
private static final String SYSTEM = "system";
|
||||
|
||||
|
||||
@PostMapping("/project/real-time/page")
|
||||
@Operation(summary = "项目-任务中心-测试计划-实时任务列表")
|
||||
public Pager<List<TaskCenterDTO>> projectList(@Validated @RequestBody TaskCenterPageRequest request) {
|
||||
return testPlanTaskCenterService.getProjectPage(request, SessionUtils.getCurrentProjectId());
|
||||
}
|
||||
|
||||
@PostMapping("/org/real-time/page")
|
||||
@Operation(summary = "组织-任务中心-测试计划-实时任务列表")
|
||||
@RequiresPermissions(PermissionConstants.ORGANIZATION_TASK_CENTER_READ)
|
||||
public Pager<List<TaskCenterDTO>> orgList(@Validated @RequestBody TaskCenterPageRequest request) {
|
||||
return testPlanTaskCenterService.getOrganizationPage(request, SessionUtils.getCurrentOrganizationId());
|
||||
}
|
||||
|
||||
@PostMapping("/system/real-time/page")
|
||||
@Operation(summary = "系统-任务中心-测试计划-实时任务列表")
|
||||
@RequiresPermissions(PermissionConstants.SYSTEM_TASK_CENTER_READ)
|
||||
public Pager<List<TaskCenterDTO>> systemList(@Validated @RequestBody TaskCenterPageRequest request) {
|
||||
return testPlanTaskCenterService.getSystemPage(request);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -5,6 +5,8 @@ import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
|
|||
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
|
||||
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
|
||||
import io.metersphere.system.dto.sdk.ApiReportMessageDTO;
|
||||
import io.metersphere.system.dto.taskcenter.TaskCenterDTO;
|
||||
import io.metersphere.system.dto.taskcenter.request.TaskCenterPageRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -31,9 +33,13 @@ public interface ExtTestPlanReportMapper {
|
|||
|
||||
List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> subList);
|
||||
|
||||
long countReportByTime(@Param("time") long timeMills, @Param("projectId") String projectId);
|
||||
long countReportByTime(@Param("time") long timeMills, @Param("projectId") String projectId);
|
||||
|
||||
List<String> selectReportIdByProjectIdAndTime(@Param("time") long timeMills, @Param("projectId") String projectId);
|
||||
List<String> selectReportIdByProjectIdAndTime(@Param("time") long timeMills, @Param("projectId") String projectId);
|
||||
|
||||
List<String> selectReportIdTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
|
||||
|
||||
List<TaskCenterDTO> taskCenterlist(@Param("request") TaskCenterPageRequest request, @Param("projectIds") List<String> projectIds,
|
||||
@Param("startTime") long startTime, @Param("endTime") long endTime);
|
||||
|
||||
List<String> selectReportIdTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,43 @@
|
|||
#{testPlanId}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="taskCenterlist" resultType="io.metersphere.system.dto.taskcenter.TaskCenterDTO">
|
||||
select
|
||||
distinct tpr.id,
|
||||
tpr.project_id,
|
||||
tpr.integrated,
|
||||
tpr.result_status as status,
|
||||
tpr.exec_status,
|
||||
tpr.start_time AS operationTime,
|
||||
tpr.create_user AS operationName,
|
||||
tpr.trigger_mode,
|
||||
tpr.start_time,
|
||||
project.organization_id,
|
||||
|
||||
tp.num AS resourceNum,
|
||||
tp.name AS resourceName,
|
||||
tp.id AS resourceId
|
||||
FROM
|
||||
test_plan_report tpr
|
||||
INNER JOIN test_plan tp ON tpr.test_plan_id = tp.id
|
||||
left join project on tpr.project_id = project.id
|
||||
where
|
||||
tpr.start_time BETWEEN #{startTime} AND #{endTime}
|
||||
<if test="projectIds != null and projectIds.size() > 0">
|
||||
and
|
||||
tpr.project_id IN
|
||||
<foreach collection="projectIds" item="projectId" separator="," open="(" close=")">
|
||||
#{projectId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.keyword != null and request.keyword != ''">
|
||||
and (tp.num like concat('%', #{request.keyword},'%')
|
||||
|
||||
or tp.name like concat('%', #{request.keyword},'%')
|
||||
)
|
||||
</if>
|
||||
<include refid="filter"/>
|
||||
</select>
|
||||
|
||||
<sql id="queryWhereCondition">
|
||||
<where>
|
||||
|
@ -104,10 +141,24 @@
|
|||
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
|
||||
</when>
|
||||
<!-- 执行结果 -->
|
||||
<when test="key == 'resultStatus'">
|
||||
<when test="key == 'resultStatus' || key == 'status'">
|
||||
and tpr.result_status in
|
||||
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
|
||||
</when>
|
||||
<!-- 项目id -->
|
||||
<when test="key=='projectIds'">
|
||||
and tpr.project_id in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
<!-- 组织id -->
|
||||
<when test="key=='organizationIds'">
|
||||
and project.organization_id in
|
||||
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</if>
|
||||
</foreach>
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import io.metersphere.api.dto.definition.ExecuteReportDTO;
|
||||
import io.metersphere.api.mapper.ExtApiScenarioReportMapper;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanReportMapper;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.Organization;
|
||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||
import io.metersphere.system.dto.taskcenter.TaskCenterDTO;
|
||||
import io.metersphere.system.dto.taskcenter.request.TaskCenterPageRequest;
|
||||
import io.metersphere.system.log.service.OperationLogService;
|
||||
import io.metersphere.system.mapper.BaseProjectMapper;
|
||||
import io.metersphere.system.mapper.ExtOrganizationMapper;
|
||||
import io.metersphere.system.mapper.OrganizationMapper;
|
||||
import io.metersphere.system.service.TestResourcePoolService;
|
||||
import io.metersphere.system.service.UserLoginService;
|
||||
import io.metersphere.system.utils.PageUtils;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanTaskCenterService {
|
||||
|
||||
@Resource
|
||||
ExtTestPlanReportMapper extTestPlanReportMapper;
|
||||
|
||||
@Resource
|
||||
ExtOrganizationMapper extOrganizationMapper;
|
||||
|
||||
@Resource
|
||||
BaseProjectMapper baseProjectMapper;
|
||||
|
||||
@Resource
|
||||
UserLoginService userLoginService;
|
||||
|
||||
@Resource
|
||||
ProjectMapper projectMapper;
|
||||
|
||||
@Resource
|
||||
OrganizationMapper organizationMapper;
|
||||
|
||||
@Resource
|
||||
ExtApiScenarioReportMapper extApiScenarioReportMapper;
|
||||
|
||||
@Resource
|
||||
TestResourcePoolService testResourcePoolService;
|
||||
@Resource
|
||||
OperationLogService operationLogService;
|
||||
@Resource
|
||||
private KafkaTemplate<String, String> kafkaTemplate;
|
||||
private static final String DEFAULT_SORT = "start_time desc";
|
||||
private final static String PROJECT_STOP = "/task/center/api/project/stop";
|
||||
private final static String ORG_STOP = "/task/center/api/org/stop";
|
||||
private final static String SYSTEM_STOP = "/task/center/api/system/stop";
|
||||
|
||||
/**
|
||||
* 任务中心实时任务列表-项目级
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 任务中心实时任务列表
|
||||
*/
|
||||
public Pager<List<TaskCenterDTO>> getProjectPage(TaskCenterPageRequest request, String projectId) {
|
||||
checkProjectExist(projectId);
|
||||
List<OptionDTO> projectList = getProjectOption(projectId);
|
||||
return createTaskCenterPager(request, projectList, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务中心实时任务列表-组织级
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 任务中心实时任务列表
|
||||
*/
|
||||
public Pager<List<TaskCenterDTO>> getOrganizationPage(TaskCenterPageRequest request, String organizationId) {
|
||||
checkOrganizationExist(organizationId);
|
||||
List<OptionDTO> projectList = getOrgProjectList(organizationId);
|
||||
return createTaskCenterPager(request, projectList, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务中心实时任务列表-系统级
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 任务中心实时任务列表
|
||||
*/
|
||||
public Pager<List<TaskCenterDTO>> getSystemPage(TaskCenterPageRequest request) {
|
||||
List<OptionDTO> projectList = getSystemProjectList();
|
||||
return createTaskCenterPager(request, projectList, true);
|
||||
}
|
||||
|
||||
private Pager<List<TaskCenterDTO>> createTaskCenterPager(TaskCenterPageRequest request, List<OptionDTO> projectList, boolean isSystem) {
|
||||
Page<Object> page = PageMethod.startPage(request.getCurrent(), request.getPageSize(),
|
||||
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : DEFAULT_SORT);
|
||||
return PageUtils.setPageInfo(page, getPage(request, projectList, isSystem));
|
||||
}
|
||||
|
||||
public List<TaskCenterDTO> getPage(TaskCenterPageRequest request, List<OptionDTO> projectList, boolean isSystem) {
|
||||
List<TaskCenterDTO> list = new ArrayList<>();
|
||||
List<String> projectIds = projectList.stream().map(OptionDTO::getId).toList();
|
||||
Map<String, ExecuteReportDTO> historyDeletedMap = new HashMap<>();
|
||||
list = extTestPlanReportMapper.taskCenterlist(request, isSystem ? new ArrayList<>() : projectIds, DateUtils.getDailyStartTime(), DateUtils.getDailyEndTime());
|
||||
//执行历史列表
|
||||
/*List<String> reportIds = list.stream().map(TaskCenterDTO::getId).toList();
|
||||
if (CollectionUtils.isNotEmpty(reportIds)) {
|
||||
List<ExecuteReportDTO> historyDeletedList = extTestPlanReportMapper.getHistoryDeleted(reportIds);
|
||||
historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
|
||||
}*/
|
||||
processTaskCenter(list, projectList, projectIds, historyDeletedMap);
|
||||
return list;
|
||||
}
|
||||
|
||||
private void processTaskCenter(List<TaskCenterDTO> list, List<OptionDTO> projectList, List<String> projectIds, Map<String, ExecuteReportDTO> historyDeletedMap) {
|
||||
if (!list.isEmpty()) {
|
||||
// 取所有的userid
|
||||
Set<String> userSet = list.stream()
|
||||
.flatMap(item -> Stream.of(item.getOperationName()))
|
||||
.collect(Collectors.toSet());
|
||||
Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet));
|
||||
// 项目
|
||||
Map<String, String> projectMap = projectList.stream().collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName));
|
||||
// 组织
|
||||
List<OptionDTO> orgListByProjectList = getOrgListByProjectIds(projectIds);
|
||||
Map<String, String> orgMap = orgListByProjectList.stream().collect(Collectors.toMap(OptionDTO::getId, OptionDTO::getName));
|
||||
|
||||
list.forEach(item -> {
|
||||
item.setOperationName(userMap.getOrDefault(item.getOperationName(), StringUtils.EMPTY));
|
||||
item.setProjectName(projectMap.getOrDefault(item.getProjectId(), StringUtils.EMPTY));
|
||||
item.setOrganizationName(orgMap.getOrDefault(item.getProjectId(), StringUtils.EMPTY));
|
||||
item.setHistoryDeleted(MapUtils.isNotEmpty(historyDeletedMap) && !historyDeletedMap.containsKey(item.getId()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private List<OptionDTO> getProjectOption(String id) {
|
||||
return baseProjectMapper.getProjectOptionsById(id);
|
||||
}
|
||||
|
||||
private List<OptionDTO> getOrgProjectList(String orgId) {
|
||||
return baseProjectMapper.getProjectOptionsByOrgId(orgId);
|
||||
}
|
||||
|
||||
private List<OptionDTO> getSystemProjectList() {
|
||||
return baseProjectMapper.getProjectOptions();
|
||||
}
|
||||
|
||||
private List<OptionDTO> getOrgListByProjectIds(List<String> projectIds) {
|
||||
return extOrganizationMapper.getOrgListByProjectIds(projectIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看项目是否存在
|
||||
*
|
||||
* @param projectId 项目ID
|
||||
*/
|
||||
private void checkProjectExist(String projectId) {
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
if (project == null) {
|
||||
throw new MSException(Translator.get("project_not_exist"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看组织是否存在
|
||||
*
|
||||
* @param orgId 组织ID
|
||||
*/
|
||||
private void checkOrganizationExist(String orgId) {
|
||||
Organization organization = organizationMapper.selectByPrimaryKey(orgId);
|
||||
if (organization == null) {
|
||||
throw new MSException(Translator.get("organization_not_exist"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package io.metersphere.plan.controller;
|
||||
|
||||
import io.metersphere.sdk.constants.SessionConstants;
|
||||
import io.metersphere.sdk.constants.TaskCenterResourceType;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.dto.taskcenter.request.TaskCenterPageRequest;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
@AutoConfigureMockMvc
|
||||
public class TestPlanTaskCenterControllerTests extends BaseTest {
|
||||
|
||||
private static final String BASE_PATH = "/task/center/plan/";
|
||||
private final static String REAL_TIME_PROJECT_PAGE = BASE_PATH + "project/real-time/page";
|
||||
private final static String REAL_TIME_ORG_PAGE = BASE_PATH + "org/real-time/page";
|
||||
private final static String REAL_TIME_SYSTEM_PAGE = BASE_PATH + "system/real-time/page";
|
||||
|
||||
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
||||
|
||||
|
||||
@Test
|
||||
@Order(9)
|
||||
@Sql(scripts = {"/dml/init_task_plan.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||
public void getPage() throws Exception {
|
||||
|
||||
doTaskCenterPage("KEYWORD", REAL_TIME_PROJECT_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
doTaskCenterPage("FILTER", REAL_TIME_PROJECT_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
doTaskCenterPage("KEYWORD", REAL_TIME_ORG_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
doTaskCenterPage("FILTER", REAL_TIME_ORG_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
doTaskCenterPage("KEYWORD", REAL_TIME_SYSTEM_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
doTaskCenterPage("FILTER", REAL_TIME_SYSTEM_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
}
|
||||
|
||||
private void doTaskCenterPage(String search, String url, String moduleType) throws Exception {
|
||||
TaskCenterPageRequest request = new TaskCenterPageRequest();
|
||||
request.setModuleType(moduleType);
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setSort(Map.of("startTime", "asc"));
|
||||
// "KEYWORD", "FILTER"
|
||||
switch (search) {
|
||||
case "KEYWORD" -> configureKeywordSearch(request);
|
||||
case "FILTER" -> configureFilterSearch(request);
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(url)
|
||||
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||
.header(SessionConstants.CURRENT_PROJECT, DEFAULT_PROJECT_ID)
|
||||
.header(SessionConstants.CURRENT_ORGANIZATION, DEFAULT_ORGANIZATION_ID)
|
||||
.content(JSON.toJSONString(request))
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
||||
|
||||
// 获取返回值
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
LogUtils.info(resultHolder);
|
||||
// 返回请求正常
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
Pager<?> pageData = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), Pager.class);
|
||||
// 返回值不为空
|
||||
Assertions.assertNotNull(pageData);
|
||||
// 返回值的页码和当前页码相同
|
||||
Assertions.assertEquals(pageData.getCurrent(), request.getCurrent());
|
||||
// 返回的数据量不超过规定要返回的数据量相同
|
||||
Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(pageData.getList())).size() <= request.getPageSize());
|
||||
|
||||
}
|
||||
|
||||
private void doTaskCenterPageError(String url, String moduleType) throws Exception {
|
||||
TaskCenterPageRequest request = new TaskCenterPageRequest();
|
||||
request.setModuleType(moduleType);
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setSort(Map.of("startTime", "asc"));
|
||||
configureKeywordSearch(request);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.post(url)
|
||||
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
||||
.header(SessionConstants.CURRENT_PROJECT, "DEFAULT_PROJECT_ID")
|
||||
.header(SessionConstants.CURRENT_ORGANIZATION, "DEFAULT_ORGANIZATION_ID")
|
||||
.content(JSON.toJSONString(request))
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(ERROR_REQUEST_MATCHER);
|
||||
|
||||
}
|
||||
|
||||
private void configureKeywordSearch(TaskCenterPageRequest request) {
|
||||
request.setKeyword("18");
|
||||
request.setSort(Map.of("triggerMode", "asc"));
|
||||
}
|
||||
|
||||
private void configureFilterSearch(TaskCenterPageRequest request) {
|
||||
Map<String, List<String>> filters = new HashMap<>();
|
||||
request.setSort(Map.of());
|
||||
filters.put("triggerMode", List.of("MANUAL"));
|
||||
request.setFilter(filters);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(10)
|
||||
public void getPageError() throws Exception {
|
||||
doTaskCenterPageError(REAL_TIME_PROJECT_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
doTaskCenterPageError(REAL_TIME_ORG_PAGE, TaskCenterResourceType.TEST_PLAN.toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
replace INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`)
|
||||
VALUES ('test_plan_id_1', 5000, '100001100001', 'NONE', '1', '测试一下计划', 'PREPARED', 'TEST_PLAN', NULL,
|
||||
1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||
|
||||
replace INTO `test_plan_report`(`id`, `test_plan_id`, `name`, `create_user`, `create_time`, `start_time`, `end_time`, `trigger_mode`, `exec_status`, `result_status`, `pass_threshold`, `pass_rate`, `project_id`, `integrated`, `deleted`)
|
||||
VALUES
|
||||
('test-plan-report-id-1', 'test_plan_id_1', '测试一下计划报告1', 'admin', UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, 'MANUAL', 'PENDING', 'SUCCESS', '99.99', 100.00, '100001100001', 0, 0),
|
||||
('test-plan-report-id-2', 'test_plan_id_1', '测试一下计划报告1', 'admin', UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, 'MANUAL', 'PENDING', '-', '99.99', 100.00, '100001100001', 0, 0),
|
||||
('test-plan-report-id-3', 'test_plan_id_1', '测试一下计划报告3', 'admin', UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, 'MANUAL', 'PENDING', '-', '99.99', 100.00, '100001100001',1, 0),
|
||||
('test-plan-report-id-4', 'test_plan_id_1', '测试一下计划报告4', 'admin', UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, UNIX_TIMESTAMP()*1000, 'MANUAL', 'PENDING', '-', '99.99', 100.00, '100001100001', 1, 0);
|
||||
|
||||
|
|
@ -28,8 +28,11 @@ import {
|
|||
stopRealSysApiUrl,
|
||||
systemRealTotal,
|
||||
systemScheduleTotal,
|
||||
taskOrgPlanRealCenterListUrl,
|
||||
taskOrgRealCenterListUrl,
|
||||
taskProPlanRealCenterListUrl,
|
||||
taskProRealCenterListUrl,
|
||||
taskSysPlanRealCenterListUrl,
|
||||
taskSysRealCenterListUrl,
|
||||
updateScheduleOrgTaskUrl,
|
||||
updateScheduleProTaskUrl,
|
||||
|
@ -193,4 +196,17 @@ export function getProjectRealTotal() {
|
|||
return MSR.get({ url: `${projectRealTotal}` });
|
||||
}
|
||||
|
||||
// 实时任务 测试计划
|
||||
export function getRealSysPlanList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<RealTaskCenterApiCaseItem>>({ url: taskSysPlanRealCenterListUrl, data });
|
||||
}
|
||||
|
||||
export function getRealOrgPlanList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<RealTaskCenterApiCaseItem>>({ url: taskOrgPlanRealCenterListUrl, data });
|
||||
}
|
||||
|
||||
export function getRealProPlanList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<RealTaskCenterApiCaseItem>>({ url: taskProPlanRealCenterListUrl, data });
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -76,3 +76,7 @@ export const projectScheduleTotal = '/task/center/project/schedule/total';
|
|||
export const systemRealTotal = '/task/center/system/real/total';
|
||||
export const orgRealTotal = '/task/center/org/real/total';
|
||||
export const projectRealTotal = '/task/center/project/real/total';
|
||||
|
||||
export const taskSysPlanRealCenterListUrl = '/task/center/plan/system/real-time/page';
|
||||
export const taskOrgPlanRealCenterListUrl = '/task/center/plan/org/real-time/page';
|
||||
export const taskProPlanRealCenterListUrl = '/task/center/plan/project/real-time/page';
|
||||
|
|
|
@ -86,6 +86,9 @@ export enum TableKeyEnum {
|
|||
TASK_SCHEDULE_TASK_TEST_PLAN_SYSTEM = 'taskCenterScheduleTestPlanSystem',
|
||||
TASK_SCHEDULE_TASK_TEST_PLAN_ORGANIZATION = 'taskCenterScheduleTestPlanOrganization',
|
||||
TASK_SCHEDULE_TASK_TEST_PLAN_PROJECT = 'taskCenterScheduleTestPlanProject',
|
||||
TASK_PLAN_SYSTEM = 'taskCenterPlanSystem',
|
||||
TASK_PLAN_ORGANIZATION = 'taskCenterPlanOrganization',
|
||||
TASK_PLAN_PROJECT = 'taskCenterPlanProject',
|
||||
}
|
||||
|
||||
// 具有特殊功能的列
|
||||
|
|
|
@ -14,7 +14,20 @@
|
|||
</a-tabs>
|
||||
<a-divider margin="0" class="!mb-[16px]"></a-divider>
|
||||
<!-- 接口用例列表-->
|
||||
<ApiCase v-if="activeTask === 'real'" :name="listName" :module-type="activeTab" :group="props.group" />
|
||||
<ApiCase
|
||||
v-if="
|
||||
activeTask === 'real' && (activeTab === TaskCenterEnum.API_CASE || activeTab === TaskCenterEnum.API_SCENARIO)
|
||||
"
|
||||
:name="listName"
|
||||
:module-type="activeTab"
|
||||
:group="props.group"
|
||||
/>
|
||||
<!-- 测试计划列表-->
|
||||
<TestPlan
|
||||
v-if="activeTask === 'real' && activeTab === TaskCenterEnum.TEST_PLAN"
|
||||
:name="listName"
|
||||
:group="props.group"
|
||||
/>
|
||||
<ScheduledTask v-if="activeTask === 'timing'" :name="listName" :group="props.group" :module-type="activeTab" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,10 +38,10 @@
|
|||
|
||||
import ApiCase from './apiCase.vue';
|
||||
import ScheduledTask from './scheduledTask.vue';
|
||||
import TestPlan from './testPlan.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import type { ResourceTypeMapKey } from '@/enums/taskCenter';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
import type { ExtractedKeys } from './utils';
|
||||
|
@ -51,6 +64,10 @@
|
|||
value: TaskCenterEnum.API_SCENARIO,
|
||||
label: t('project.taskCenter.apiScenario'),
|
||||
},
|
||||
{
|
||||
value: TaskCenterEnum.TEST_PLAN,
|
||||
label: t('project.taskCenter.testPlan'),
|
||||
},
|
||||
// TODO 第一个版本目前不上以下几类
|
||||
// {
|
||||
// value: TaskCenterEnum.UI_TEST,
|
||||
|
@ -60,10 +77,6 @@
|
|||
// value: TaskCenterEnum.LOAD_TEST,
|
||||
// label: t('project.taskCenter.performanceTest'),
|
||||
// },
|
||||
// {
|
||||
// value: TaskCenterEnum.TEST_PLAN,
|
||||
// label: t('project.taskCenter.testPlan'),
|
||||
// },
|
||||
]);
|
||||
|
||||
const timingTabList = ref([
|
||||
|
@ -78,7 +91,7 @@
|
|||
{
|
||||
value: TaskCenterEnum.TEST_PLAN,
|
||||
label: t('project.taskCenter.testPlan'),
|
||||
}
|
||||
},
|
||||
]);
|
||||
|
||||
const activeTask = ref(route.query.tab || 'real');
|
||||
|
@ -110,10 +123,12 @@
|
|||
.box {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
.left {
|
||||
width: 252px;
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--color-text-n8);
|
||||
|
||||
.item {
|
||||
padding: 0 20px;
|
||||
height: 38px;
|
||||
|
@ -121,18 +136,21 @@
|
|||
line-height: 38px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
color: rgb(var(--primary-5));
|
||||
background: rgb(var(--primary-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: calc(100% - 300px);
|
||||
flex-grow: 1; /* 自适应 */
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.no-content {
|
||||
:deep(.arco-tabs-content) {
|
||||
padding-top: 0;
|
||||
|
|
|
@ -0,0 +1,419 @@
|
|||
<template>
|
||||
<div class="px-[16px]">
|
||||
<div class="mb-[16px] flex items-center justify-between">
|
||||
<div class="flex items-center"></div>
|
||||
<div class="items-right flex gap-[8px]">
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('system.organization.searchIndexPlaceholder')"
|
||||
allow-clear
|
||||
class="mx-[8px] w-[240px]"
|
||||
@search="searchList"
|
||||
@press-enter="searchList"
|
||||
@clear="searchList"
|
||||
></a-input-search>
|
||||
</div>
|
||||
</div>
|
||||
<ms-base-table
|
||||
v-bind="propsRes"
|
||||
ref="tableRef"
|
||||
:action-config="tableBatchActions"
|
||||
:selectable="hasOperationPermission"
|
||||
v-on="propsEvent"
|
||||
@batch-action="handleTableBatch"
|
||||
>
|
||||
<template #resourceNum="{ record }">
|
||||
<div
|
||||
v-if="!record.integrated"
|
||||
type="text"
|
||||
class="one-line-text w-full"
|
||||
:class="[hasJumpPermission ? 'text-[rgb(var(--primary-5))]' : '']"
|
||||
@click="showDetail()"
|
||||
>{{ record.resourceNum }}
|
||||
</div>
|
||||
</template>
|
||||
<template #resourceName="{ record }">
|
||||
<div
|
||||
v-if="!record.integrated"
|
||||
class="one-line-text max-w-[300px]"
|
||||
:class="[hasJumpPermission ? 'text-[rgb(var(--primary-5))]' : '']"
|
||||
@click="showDetail()"
|
||||
>{{ record.resourceName }}
|
||||
</div>
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<ExecutionStatus :status="record.status" />
|
||||
</template>
|
||||
<template #execStatus="{ record }">
|
||||
<ExecStatus :status="record.execStatus" />
|
||||
</template>
|
||||
<template #[FilterSlotNameEnum.TEST_PLAN_REPORT_EXEC_STATUS]="{ filterContent }">
|
||||
<ExecStatus :status="filterContent.value" />
|
||||
</template>
|
||||
<template #[FilterSlotNameEnum.TEST_PLAN_STATUS_FILTER]="{ filterContent }">
|
||||
<ExecutionStatus :status="filterContent.value" />
|
||||
</template>
|
||||
<template #projectName="{ record }">
|
||||
<a-tooltip :content="`${record.projectName}`" position="tl">
|
||||
<div class="one-line-text">{{ characterLimit(record.projectName) }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #organizationName="{ record }">
|
||||
<a-tooltip :content="`${record.organizationName}`" position="tl">
|
||||
<div class="one-line-text">{{ characterLimit(record.organizationName) }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #triggerMode="{ record }">
|
||||
<span>{{ t(ExecutionMethodsLabel[record.triggerMode as keyof typeof ExecutionMethodsLabel]) }}</span>
|
||||
</template>
|
||||
<template #operationTime="{ record }">
|
||||
<span>{{ dayjs(record.operationTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<div v-if="record.historyDeleted">
|
||||
<a-tooltip :content="t('project.executionHistory.cleared')">
|
||||
<MsButton
|
||||
class="!mr-0"
|
||||
:disabled="record.historyDeleted || !hasAnyPermission(permissionsMap[props.group].report)"
|
||||
@click="viewReport(record.id)"
|
||||
>{{ t('project.taskCenter.viewReport') }}
|
||||
</MsButton>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div v-else>
|
||||
<MsButton
|
||||
class="!mr-0"
|
||||
:disabled="record.historyDeleted || !hasAnyPermission(permissionsMap[props.group].report)"
|
||||
@click="viewReport(record.id)"
|
||||
>{{ t('project.taskCenter.viewReport') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
|
||||
<a-divider v-if="['RUNNING', 'RERUNNING'].includes(record.execStatus)" direction="vertical" />
|
||||
<MsButton
|
||||
v-if="
|
||||
['RUNNING', 'RERUNNING'].includes(record.execStatus) && hasAnyPermission(permissionsMap[props.group].stop)
|
||||
"
|
||||
class="!mr-0"
|
||||
@click="stop()"
|
||||
>{{ t('project.taskCenter.stop') }}
|
||||
</MsButton>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import ExecStatus from '@/views/test-plan/report/component/execStatus.vue';
|
||||
import ExecutionStatus from '@/views/test-plan/report/component/reportStatus.vue';
|
||||
|
||||
import {
|
||||
getRealOrgPlanList,
|
||||
getRealProPlanList,
|
||||
getRealSysPlanList,
|
||||
} from '@/api/modules/project-management/taskCenter';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import { useTableStore } from '@/store';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { BatchApiParams } from '@/models/common';
|
||||
import { ReportExecStatus } from '@/enums/apiEnum';
|
||||
import { PlanReportStatus } from '@/enums/reportEnum';
|
||||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
import { ExecutionMethodsLabel, TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
import { getOrgColumns, getProjectColumns, Group } from './utils';
|
||||
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
|
||||
const tableStore = useTableStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
group: Group;
|
||||
name: string;
|
||||
}>();
|
||||
const keyword = ref<string>('');
|
||||
|
||||
const permissionsMap: Record<Group, any> = {
|
||||
organization: {
|
||||
stop: ['ORGANIZATION_TASK_CENTER:READ+STOP', 'PROJECT_TEST_PLAN:READ+EXECUTE'],
|
||||
jump: ['PROJECT_TEST_PLAN:READ'],
|
||||
report: ['PROJECT_TEST_PLAN:READ+EXECUTE', 'PROJECT_TEST_PLAN_REPORT:READ'],
|
||||
},
|
||||
system: {
|
||||
stop: ['SYSTEM_TASK_CENTER:READ+STOP', 'PROJECT_TEST_PLAN:READ+EXECUTE'],
|
||||
jump: ['PROJECT_TEST_PLAN:READ'],
|
||||
report: ['PROJECT_TEST_PLAN:READ+EXECUTE', 'PROJECT_TEST_PLAN_REPORT:READ'],
|
||||
},
|
||||
project: {
|
||||
stop: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
|
||||
jump: ['PROJECT_TEST_PLAN:READ'],
|
||||
report: ['PROJECT_TEST_PLAN:READ+EXECUTE', 'PROJECT_TEST_PLAN_REPORT:READ'],
|
||||
},
|
||||
};
|
||||
|
||||
const loadRealMap = ref({
|
||||
system: {
|
||||
list: getRealSysPlanList,
|
||||
},
|
||||
organization: {
|
||||
list: getRealOrgPlanList,
|
||||
},
|
||||
project: {
|
||||
list: getRealProPlanList,
|
||||
},
|
||||
});
|
||||
const hasJumpPermission = computed(() => hasAnyPermission(permissionsMap[props.group].jump));
|
||||
const hasOperationPermission = computed(() => hasAnyPermission(permissionsMap[props.group].stop));
|
||||
|
||||
const statusResultOptions = computed(() => {
|
||||
return Object.keys(PlanReportStatus).map((key) => {
|
||||
return {
|
||||
value: key,
|
||||
label: PlanReportStatus[key].statusText,
|
||||
};
|
||||
});
|
||||
});
|
||||
const ExecStatusList = computed(() => {
|
||||
return Object.values(ReportExecStatus).map((e) => {
|
||||
return {
|
||||
value: e,
|
||||
key: e,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const triggerModeList = [
|
||||
{
|
||||
value: 'SCHEDULE',
|
||||
label: t('project.taskCenter.scheduledTask'),
|
||||
},
|
||||
{
|
||||
value: 'MANUAL',
|
||||
label: t('project.taskCenter.manualExecution'),
|
||||
},
|
||||
{
|
||||
value: 'API',
|
||||
label: t('project.taskCenter.interfaceCall'),
|
||||
},
|
||||
{
|
||||
value: 'BATCH',
|
||||
label: t('project.taskCenter.batchExecution'),
|
||||
},
|
||||
];
|
||||
|
||||
const staticColumns: MsTableColumn = [
|
||||
{
|
||||
title: 'project.taskCenter.resourceID',
|
||||
dataIndex: 'resourceNum',
|
||||
slotName: 'resourceNum',
|
||||
width: 200,
|
||||
sortIndex: 1,
|
||||
fixed: 'left',
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
showDrag: false,
|
||||
columnSelectorDisabled: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.resourceName',
|
||||
slotName: 'resourceName',
|
||||
dataIndex: 'resourceName',
|
||||
width: 300,
|
||||
showDrag: false,
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
columnSelectorDisabled: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.executionResult',
|
||||
dataIndex: 'status',
|
||||
slotName: 'status',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
filterConfig: {
|
||||
options: statusResultOptions.value,
|
||||
filterSlotName: FilterSlotNameEnum.TEST_PLAN_STATUS_FILTER,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.status',
|
||||
dataIndex: 'execStatus',
|
||||
slotName: 'execStatus',
|
||||
filterConfig: {
|
||||
options: ExecStatusList.value,
|
||||
filterSlotName: FilterSlotNameEnum.TEST_PLAN_REPORT_EXEC_STATUS,
|
||||
},
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.executionMode',
|
||||
dataIndex: 'triggerMode',
|
||||
slotName: 'triggerMode',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
filterConfig: {
|
||||
options: triggerModeList,
|
||||
},
|
||||
showInTable: true,
|
||||
width: 150,
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.resourcePool',
|
||||
slotName: 'poolName',
|
||||
dataIndex: 'poolName',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
showTooltip: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.operator',
|
||||
slotName: 'operationName',
|
||||
dataIndex: 'operationName',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
showTooltip: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.operating',
|
||||
dataIndex: 'operationTime',
|
||||
slotName: 'operationTime',
|
||||
width: 180,
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'common.operation',
|
||||
slotName: 'operation',
|
||||
dataIndex: 'operation',
|
||||
fixed: 'right',
|
||||
width: hasOperationPermission.value ? 180 : 100,
|
||||
},
|
||||
];
|
||||
|
||||
const tableKeysMap: Record<string, any> = {
|
||||
system: TableKeyEnum.TASK_PLAN_SYSTEM,
|
||||
organization: TableKeyEnum.TASK_PLAN_ORGANIZATION,
|
||||
project: TableKeyEnum.TASK_PLAN_PROJECT,
|
||||
};
|
||||
|
||||
const groupColumnsMap: Record<string, any> = {
|
||||
system: [getOrgColumns(), getProjectColumns(tableKeysMap[props.group]), ...staticColumns],
|
||||
organization: [getProjectColumns(tableKeysMap[props.group]), ...staticColumns],
|
||||
project: staticColumns,
|
||||
};
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, resetFilterParams } = useTable(
|
||||
loadRealMap.value[props.group].list,
|
||||
{
|
||||
tableKey: tableKeysMap[props.group],
|
||||
scroll: {
|
||||
x: 1400,
|
||||
},
|
||||
showSetting: true,
|
||||
selectable: hasOperationPermission.value,
|
||||
heightUsed: 330,
|
||||
enableDrag: false,
|
||||
showSelectAll: true,
|
||||
}
|
||||
);
|
||||
|
||||
function initData() {
|
||||
setLoadListParams({
|
||||
moduleType: TaskCenterEnum.TEST_PLAN,
|
||||
keyword: keyword.value,
|
||||
filter: {
|
||||
...propsRes.value.filter,
|
||||
},
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
|
||||
const tableBatchActions = {
|
||||
baseAction: [
|
||||
{
|
||||
label: 'project.taskCenter.batchStop',
|
||||
eventTag: 'batchStop',
|
||||
anyPermission: permissionsMap[props.group].stop,
|
||||
},
|
||||
],
|
||||
};
|
||||
const batchParams = ref<BatchApiParams>({
|
||||
selectIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [] as string[],
|
||||
condition: {},
|
||||
});
|
||||
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
batchParams.value = { ...params, selectIds: params?.selectedIds || [], condition: params?.condition || {} };
|
||||
if (event.eventTag === 'batchStop') {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
function viewReport(id: string) {
|
||||
openNewPage(RouteEnum.TEST_PLAN_REPORT_DETAIL, {
|
||||
id,
|
||||
});
|
||||
}
|
||||
|
||||
function showDetail() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
function stop() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
function searchList() {
|
||||
resetSelector();
|
||||
initData();
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
initData();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.group,
|
||||
(val) => {
|
||||
if (val) {
|
||||
resetSelector();
|
||||
resetFilterParams();
|
||||
initData();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
await tableStore.initColumn(tableKeysMap[props.group], groupColumnsMap[props.group], 'drawer', true);
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -121,7 +121,10 @@ export const TaskStatus: Record<ResourceTypeMapKey, Record<string, { icon: strin
|
|||
|
||||
export type Group = 'system' | 'organization' | 'project';
|
||||
|
||||
export type ExtractedKeys = Extract<ResourceTypeMapKey, TaskCenterEnum.API_CASE | TaskCenterEnum.API_SCENARIO>;
|
||||
export type ExtractedKeys = Extract<
|
||||
ResourceTypeMapKey,
|
||||
TaskCenterEnum.API_CASE | TaskCenterEnum.API_SCENARIO | TaskCenterEnum.TEST_PLAN
|
||||
>;
|
||||
|
||||
export const resourceTypeMap: Record<ResourceTypeMapKey, Record<string, any>> = {
|
||||
[TaskCenterEnum.API_CASE]: {
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
</template>
|
||||
<!-- 执行状态筛选 -->
|
||||
<template #resultStatus="{ record }">
|
||||
<ExecutionStatus :module-type="ReportStatusEnum.REPORT_STATUS" :status="record.resultStatus" />
|
||||
<ExecutionStatus :status="record.resultStatus" />
|
||||
</template>
|
||||
<template #execStatus="{ record }">
|
||||
<ExecStatus :status="record.execStatus" />
|
||||
|
@ -114,7 +114,7 @@
|
|||
|
||||
import { BatchApiParams } from '@/models/common';
|
||||
import { ReportExecStatus } from '@/enums/apiEnum';
|
||||
import { PlanReportStatus, ReportStatusEnum, TriggerModeLabel } from '@/enums/reportEnum';
|
||||
import { PlanReportStatus, TriggerModeLabel } from '@/enums/reportEnum';
|
||||
import { TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
};
|
||||
|
||||
function getExecutionResult(): IconType {
|
||||
return iconTypeStatus[props.status] ?? iconTypeStatus[props.status]?.DEFAULT;
|
||||
return iconTypeStatus[props.status] ? iconTypeStatus[props.status] : iconTypeStatus.DEFAULT;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue