feat(测试跟踪): 测试跟踪模块后显示该模块下的用例数,接口定义模块显示模块下的接口数,接口自动化模块显示模块下的场景数
This commit is contained in:
parent
9afb9c9300
commit
57dd5d03b8
|
@ -2,10 +2,7 @@ package io.metersphere.api.service;
|
|||
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||
import io.metersphere.api.dto.definition.ApiModuleDTO;
|
||||
import io.metersphere.api.dto.definition.DragModuleRequest;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiDefinitionMapper;
|
||||
import io.metersphere.base.mapper.ApiModuleMapper;
|
||||
|
@ -21,6 +18,8 @@ import io.metersphere.log.vo.OperatingLogDetails;
|
|||
import io.metersphere.log.vo.api.ModuleReference;
|
||||
import io.metersphere.service.NodeTreeService;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.track.service.TestPlanApiCaseService;
|
||||
import io.metersphere.track.service.TestPlanProjectService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -81,9 +80,43 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
|
|||
apiModuleMapper.insert(record);
|
||||
}
|
||||
List<ApiModuleDTO> apiModules = extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol);
|
||||
ApiDefinitionRequest request = new ApiDefinitionRequest();
|
||||
request.setProjectId(projectId);
|
||||
request.setProtocol(protocol);
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("Prepare");
|
||||
list.add("Underway");
|
||||
list.add("Completed");
|
||||
Map<String, List<String>> filters = new LinkedHashMap<>();
|
||||
filters.put("status", list);
|
||||
request.setFilters(filters);
|
||||
apiModules.forEach(node -> {
|
||||
List<String> moduleIds = new ArrayList<>();
|
||||
moduleIds = this.nodeList(apiModules, node.getId(), moduleIds);
|
||||
moduleIds.add(node.getId());
|
||||
request.setModuleIds(moduleIds);
|
||||
int num = this.getCaseNum(request);
|
||||
node.setCaseNum(num);
|
||||
});
|
||||
return getNodeTrees(apiModules);
|
||||
}
|
||||
|
||||
private int getCaseNum(ApiDefinitionRequest request) {
|
||||
return extApiDefinitionMapper.list(request).size();
|
||||
}
|
||||
|
||||
public static List<String> nodeList(List<ApiModuleDTO> apiNodes, String pid, List<String> list) {
|
||||
for (ApiModuleDTO node : apiNodes) {
|
||||
//遍历出父id等于参数的id,add进子节点集合
|
||||
if (StringUtils.equals(node.getParentId(), pid)) {
|
||||
list.add(node.getId());
|
||||
//递归遍历下一级
|
||||
nodeList(apiNodes, node.getId(), list);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public String addNode(ApiModule node) {
|
||||
validateNode(node);
|
||||
return addNodeWithoutValidate(node);
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.api.dto.automation.DragApiScenarioModuleRequest;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioModuleMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioModuleMapper;
|
||||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
|
@ -20,6 +21,8 @@ import io.metersphere.log.vo.OperatingLogDetails;
|
|||
import io.metersphere.log.vo.api.ModuleReference;
|
||||
import io.metersphere.service.NodeTreeService;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.track.service.TestPlanProjectService;
|
||||
import io.metersphere.track.service.TestPlanScenarioCaseService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -52,6 +55,8 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
TestPlanProjectService testPlanProjectService;
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
@Resource
|
||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
|
||||
public ApiScenarioModuleService() {
|
||||
super(ApiScenarioModuleDTO.class);
|
||||
|
@ -75,9 +80,43 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
|||
}
|
||||
|
||||
List<ApiScenarioModuleDTO> nodes = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId);
|
||||
ApiScenarioRequest request = new ApiScenarioRequest();
|
||||
request.setProjectId(projectId);
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add("Prepare");
|
||||
list.add("Underway");
|
||||
list.add("Completed");
|
||||
Map<String, List<String>> filters = new LinkedHashMap<>();
|
||||
filters.put("status", list);
|
||||
request.setFilters(filters);
|
||||
nodes.forEach(node -> {
|
||||
List<String> scenarioNodes = new ArrayList<>();
|
||||
scenarioNodes = this.nodeList(nodes, node.getId(), scenarioNodes);
|
||||
scenarioNodes.add(node.getId());
|
||||
request.setModuleIds(scenarioNodes);
|
||||
int num = this.getCaseNum(request);
|
||||
node.setCaseNum(num);
|
||||
});
|
||||
return getNodeTrees(nodes);
|
||||
}
|
||||
|
||||
private int getCaseNum(ApiScenarioRequest request) {
|
||||
return extApiScenarioMapper.list(request).size();
|
||||
}
|
||||
|
||||
public static List<String> nodeList(List<ApiScenarioModuleDTO> nodes, String pid, List<String> list) {
|
||||
for (ApiScenarioModuleDTO node : nodes) {
|
||||
//遍历出父id等于参数的id,add进子节点集合
|
||||
if (StringUtils.equals(node.getParentId(), pid)) {
|
||||
list.add(node.getId());
|
||||
//递归遍历下一级
|
||||
nodeList(nodes, node.getId(), list);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private double getNextLevelPos(String projectId, int level, String parentId) {
|
||||
List<ApiScenarioModule> list = getPos(projectId, level, parentId, "pos desc");
|
||||
if (!CollectionUtils.isEmpty(list) && list.get(0) != null && list.get(0).getPos() != null) {
|
||||
|
|
|
@ -14,4 +14,6 @@ public interface ExtTestCaseNodeMapper {
|
|||
TestCaseNodeDTO get(String id);
|
||||
|
||||
void updatePos(String id, Double pos);
|
||||
|
||||
List<String> getNodes(@Param("parentId") String parentId);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,14 @@
|
|||
from test_case_node
|
||||
where id = #{id}
|
||||
</select>
|
||||
<select id="getNodes" resultType="java.lang.String">
|
||||
select id
|
||||
from test_case_node
|
||||
where parent_id = #{parentId}
|
||||
</select>
|
||||
<update id="updatePos">
|
||||
update test_case_node set pos = #{pos}
|
||||
update test_case_node
|
||||
set pos = #{pos}
|
||||
where id = #{id}
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,9 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class NodeNumDTO extends TestCaseNode {
|
||||
private Integer caseNum;
|
||||
}
|
|
@ -27,5 +27,7 @@ public class TreeNodeDTO<T> {
|
|||
|
||||
private List<T> children;
|
||||
|
||||
private Integer caseNum;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
|||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.dto.NodeNumDTO;
|
||||
import io.metersphere.exception.ExcelException;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.log.utils.ReflexObjectUtil;
|
||||
|
@ -29,6 +30,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
@ -84,6 +86,12 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
return node.getId();
|
||||
}
|
||||
|
||||
public List<String> getNodes(String nodeId) {
|
||||
return extTestCaseNodeMapper.getNodes(nodeId);
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
private void validateNode(TestCaseNode node) {
|
||||
if (node.getLevel() > TestCaseConstants.MAX_NODE_DEPTH) {
|
||||
throw new RuntimeException(Translator.get("test_case_node_level_tip")
|
||||
|
@ -118,7 +126,8 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo("默认模块");
|
||||
long count = testCaseNodeMapper.countByExample(example);
|
||||
if (count <= 0) {
|
||||
TestCaseNode record = new TestCaseNode();
|
||||
NodeNumDTO record = new NodeNumDTO();
|
||||
//TestCaseNode record = new TestCaseNode();
|
||||
record.setId(UUID.randomUUID().toString());
|
||||
record.setCreateUser(SessionUtils.getUserId());
|
||||
record.setName("默认模块");
|
||||
|
@ -128,11 +137,45 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
record.setUpdateTime(System.currentTimeMillis());
|
||||
record.setProjectId(projectId);
|
||||
testCaseNodeMapper.insert(record);
|
||||
record.setCaseNum(0);
|
||||
}
|
||||
List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId);
|
||||
QueryTestCaseRequest request = new QueryTestCaseRequest();
|
||||
request.setUserId(SessionUtils.getUserId());
|
||||
request.setProjectId(projectId);
|
||||
for (TestCaseNodeDTO node : testCaseNodes) {
|
||||
List<String> nodeIds = new ArrayList<>();
|
||||
nodeIds = this.nodeList(testCaseNodes, node.getId(), nodeIds);
|
||||
nodeIds.add(node.getId());
|
||||
request.setNodeIds(nodeIds);
|
||||
int num = this.getCaseNum(request);
|
||||
node.setCaseNum(num);
|
||||
}
|
||||
return getNodeTrees(testCaseNodes);
|
||||
}
|
||||
|
||||
public static List<String> nodeList(List<TestCaseNodeDTO> testCaseNodes, String pid, List<String> list) {
|
||||
for (TestCaseNodeDTO node : testCaseNodes) {
|
||||
//遍历出父id等于参数的id,add进子节点集合
|
||||
if (StringUtils.equals(node.getParentId(), pid)) {
|
||||
list.add(node.getId());
|
||||
//递归遍历下一级
|
||||
nodeList(testCaseNodes, node.getId(), list);
|
||||
}
|
||||
}
|
||||
/*if(null==list||list.size()==0){
|
||||
list.add(pid);
|
||||
}*/
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
//获取模块下用例数
|
||||
public int getCaseNum(QueryTestCaseRequest request) {
|
||||
List<TestCaseDTO> list = extTestCaseMapper.list(request);
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public int editNode(DragNodeRequest request) {
|
||||
request.setUpdateTime(System.currentTimeMillis());
|
||||
checkTestCaseNodeExist(request);
|
||||
|
|
|
@ -299,6 +299,7 @@ export default {
|
|||
if ( this.$refs.testCaseList) {
|
||||
this.$refs.testCaseList.initTableData();
|
||||
}
|
||||
this.$refs.nodeTree.list();
|
||||
},
|
||||
editTestCase(testCase) {
|
||||
this.type = "edit";
|
||||
|
|
|
@ -22,14 +22,17 @@
|
|||
<span class="custom-tree-node father" @click="handleNodeSelect(node)">
|
||||
|
||||
<span v-if="data.isEdit" @click.stop>
|
||||
<el-input @blur.stop="save(node, data)" @keyup.enter.native.stop="$event.target.blur" v-model="data.name" class="name-input" size="mini" ref="nameInput"/>
|
||||
<el-input @blur.stop="save(node, data)" @keyup.enter.native.stop="$event.target.blur" v-model="data.name"
|
||||
class="name-input" size="mini" ref="nameInput"/>
|
||||
</span>
|
||||
|
||||
<span v-if="!data.isEdit" class="node-icon">
|
||||
<i class="el-icon-folder"/>
|
||||
</span>
|
||||
<span v-if="!data.isEdit" class="node-title" v-text="data.name"/>
|
||||
|
||||
<span v-if="data.caseNum" class="node-title">
|
||||
<span>(0/{{ data.caseNum }})</span>
|
||||
</span>
|
||||
<span v-if="!disabled" class="node-operate child">
|
||||
<el-tooltip
|
||||
v-if="data.id !== 'root' && data.name !=='默认模块'"
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<project-change :project-name="currentProject"/>
|
||||
<el-col :span="14">
|
||||
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router
|
||||
:default-active='$route.path'>
|
||||
:default-active="pathName">
|
||||
<el-menu-item :index="'/track/home'">
|
||||
{{ $t("i18n.home") }}
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/track/case/all'">
|
||||
<el-menu-item :index="'/track/case/all'" v-permission="['test_manager','test_user','test_viewer']">
|
||||
{{ $t("test_track.case.test_case") }}
|
||||
</el-menu-item>
|
||||
<!--
|
||||
|
@ -25,10 +25,12 @@
|
|||
:title="$t('test_track.case.create_case')"/>
|
||||
</el-submenu>
|
||||
-->
|
||||
<el-menu-item :index="'/track/review/all'">
|
||||
<el-menu-item :index="'/track/review/all'" v-permission="['test_manager','test_user','test_viewer']"
|
||||
popper-class="submenu">
|
||||
{{ $t('test_track.review.test_review') }}
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/track/plan/all'">
|
||||
<el-menu-item :index="'/track/plan/all'" v-permission="['test_manager','test_user','test_viewer']"
|
||||
popper-class="submenu">
|
||||
{{ $t('test_track.plan.test_plan') }}
|
||||
</el-menu-item>
|
||||
|
||||
|
@ -40,17 +42,17 @@
|
|||
<ms-show-all :index="'/track/review/all'"/>
|
||||
<el-menu-item :index="testCaseReviewEditPath" class="blank_item"/>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/review/create'" :title="$t('test_track.review.create_review')"/>-->
|
||||
<!-- </el-submenu>
|
||||
<!-- </el-submenu>-->
|
||||
|
||||
<el-submenu v-permission="['test_manager','test_user','test_viewer']" :index="'/track/plan/all'" popper-class="submenu">-->
|
||||
<!-- <template v-slot:title>{{ $t('test_track.plan.test_plan') }}</template>
|
||||
<!-- <el-submenu v-permission="['test_manager','test_user','test_viewer']" :index="'/track/plan/all'" popper-class="submenu">
|
||||
<template v-slot:title>{{ $t('test_track.plan.test_plan') }}</template>
|
||||
<ms-recent-list ref="planRecent" :options="planRecent"/>
|
||||
<el-divider/>
|
||||
<ms-show-all :index="'/track/plan/all'"/>
|
||||
<el-menu-item :index="testPlanViewPath" class="blank_item"></el-menu-item>
|
||||
<ms-create-button v-permission="['test_manager','test_user']" :index="'/track/plan/create'"
|
||||
:title="$t('test_track.plan.create_plan')"/>-->
|
||||
<!-- </el-submenu>-->
|
||||
:title="$t('test_track.plan.create_plan')"/>
|
||||
</el-submenu>-->
|
||||
|
||||
<el-menu-item :index="'/track/issue'">
|
||||
{{ $t("缺陷管理") }}
|
||||
|
@ -113,13 +115,24 @@ export default {
|
|||
},
|
||||
router: function (item) {
|
||||
}
|
||||
}
|
||||
},
|
||||
pathName: '',
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route'(to) {
|
||||
'$route': {
|
||||
immediate: true,
|
||||
handler(to, from) {
|
||||
if (to.params && to.params.reviewId) {
|
||||
this.pathName = '/track/review/all';
|
||||
} else if (to.params && to.params.planId) {
|
||||
this.pathName = '/track/plan/all';
|
||||
} else {
|
||||
this.pathName = to.path;
|
||||
}
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
|
|
Loading…
Reference in New Issue