feat(测试跟踪): 用例搜索刷新模块树用例数量
--story=1008229 --user=陈建星 功能用例优化 https://www.tapd.cn/55049933/s/1191465
This commit is contained in:
parent
f95d2337ed
commit
384f085872
|
@ -6,6 +6,7 @@ import io.metersphere.controller.request.BaseQueryRequest;
|
|||
import io.metersphere.dto.RelationshipGraphData;
|
||||
import io.metersphere.track.dto.CustomFieldResourceCompatibleDTO;
|
||||
import io.metersphere.track.dto.TestCaseDTO;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.DeleteTestCaseRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
|
||||
|
@ -108,7 +109,7 @@ public interface ExtTestCaseMapper {
|
|||
|
||||
List<String> selectRelateIdsByQuery(@Param("request") BaseQueryRequest query);
|
||||
|
||||
List<Map<String, Object>> moduleCountByCollection(@Param("request") QueryTestCaseRequest request);
|
||||
List<TestCaseNodeDTO> getCountNodes(@Param("request") QueryTestCaseRequest request);
|
||||
|
||||
List<TestCaseWithBLOBs> getCustomFieldsByIds(@Param("ids") List<String> ids);
|
||||
|
||||
|
|
|
@ -298,11 +298,12 @@
|
|||
left join project on test_case.project_id = project.id
|
||||
<include refid="queryWhereConditionWidthProject"/>
|
||||
</select>
|
||||
|
||||
<select id="moduleCountByCollection" resultType="java.util.Map">
|
||||
select node_id AS moduleId,count(id) AS countNum from test_case
|
||||
<select id="getCountNodes" resultType="io.metersphere.track.dto.TestCaseNodeDTO">
|
||||
select tcn.id, count(*) as caseNum
|
||||
from test_case
|
||||
inner join test_case_node tcn on test_case.node_id = tcn.id
|
||||
<include refid="queryWhereCondition"/>
|
||||
GROUP BY node_id
|
||||
group by test_case.node_id;
|
||||
</select>
|
||||
<select id="listByMethod" resultType="io.metersphere.track.dto.TestCaseDTO">
|
||||
select load_test.id, load_test.name, load_test.project_id,'性能测试' as type, project_version.name as version_name
|
||||
|
@ -398,7 +399,7 @@
|
|||
from test_case
|
||||
left join (select id,workspace_id,NAME from project where workspace_id =#{request.workspaceId})
|
||||
project on test_case.project_id = project.id
|
||||
where (test_case.STATUS IS NULL OR test_case.STATUS != 'Trash') and test_case.case_public=true GROUP BY ref_id)
|
||||
where test_case.STATUS != 'Trash' and test_case.case_public = true GROUP BY ref_id)
|
||||
tmp on test_case.update_time = tmp.update_time and test_case.ref_id = tmp.ref_id
|
||||
<where>
|
||||
<if test="request.combine != null">
|
||||
|
@ -409,11 +410,11 @@
|
|||
</include>
|
||||
</if>
|
||||
<if test="request.statusIsNot != null">
|
||||
and (test_case.status is null or test_case.status != #{request.statusIsNot})
|
||||
and test_case.status != #{request.statusIsNot}
|
||||
</if>
|
||||
|
||||
<if test="request.notEqStatus != null">
|
||||
and (test_case.status is null or test_case.status != #{request.notEqStatus})
|
||||
and test_case.status != #{request.notEqStatus}
|
||||
</if>
|
||||
<if test="request.name != null">
|
||||
and (test_case.name like CONCAT('%', #{request.name},'%')
|
||||
|
@ -469,11 +470,11 @@
|
|||
</if>
|
||||
|
||||
<if test="request.statusIsNot != null">
|
||||
and (test_case.status is null or test_case.status != #{request.statusIsNot})
|
||||
and test_case.status != #{request.statusIsNot}
|
||||
</if>
|
||||
|
||||
<if test="request.notEqStatus != null">
|
||||
and (test_case.status is null or test_case.status != #{request.notEqStatus})
|
||||
and test_case.status != #{request.notEqStatus}
|
||||
</if>
|
||||
<if test="request.name != null">
|
||||
and (test_case.name like CONCAT('%', #{request.name},'%')
|
||||
|
@ -570,12 +571,12 @@
|
|||
</choose>
|
||||
</if>
|
||||
<if test="key=='status' and (values == null || values.size() == 0)">
|
||||
and (test_case.status is null or test_case.status != 'Trash')
|
||||
and test_case.status != 'Trash'
|
||||
</if>
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.filters == null || request.filters.size() == 0 || !request.filters.containsKey('status')">
|
||||
and (test_case.status is null or test_case.status != 'Trash')
|
||||
and test_case.status != 'Trash'
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.base.domain.TestCase;
|
||||
import io.metersphere.controller.request.BaseQueryRequest;
|
||||
import io.metersphere.track.dto.*;
|
||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||
|
@ -68,7 +67,9 @@ public interface ExtTestPlanTestCaseMapper {
|
|||
|
||||
Long getLastOrder(@Param("planId") String planId, @Param("baseOrder") Long baseOrder);
|
||||
|
||||
List<TestCase> getTestCaseWithNodeInfo(@Param("planId") String planId);
|
||||
List<TestCaseNodeDTO> getTestPlanCountNodes(@Param("request") QueryTestPlanCaseRequest request);
|
||||
|
||||
List<String> projectIdsByPlanId(@Param("planId") String planId);
|
||||
|
||||
List<CountMapDTO> getExecResultMapByPlanId(@Param("planId") String planId);
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@
|
|||
<include refid="queryVersionCondition">
|
||||
<property name="versionTable" value="test_case"/>
|
||||
</include>
|
||||
and (test_case.status != 'Trash' or test_case.status is null)
|
||||
and test_case.status != 'Trash'
|
||||
<include refid="filter"/>
|
||||
</where>
|
||||
</sql>
|
||||
|
@ -523,7 +523,6 @@
|
|||
<if test="id != null and id != ''">
|
||||
and plan_id=#{id,jdbcType=VARCHAR}
|
||||
</if>
|
||||
|
||||
</update>
|
||||
<delete id="deleteByTestCaseID" parameterType="java.lang.String">
|
||||
delete
|
||||
|
@ -557,12 +556,13 @@
|
|||
</if>
|
||||
order by `order` desc limit 1;
|
||||
</select>
|
||||
|
||||
<select id="getTestCaseWithNodeInfo" resultType="io.metersphere.base.domain.TestCase">
|
||||
select tc.project_id, tc.node_id
|
||||
from test_plan_test_case tptc
|
||||
join test_case tc on tptc.case_id = tc.id
|
||||
where tptc.plan_id = #{planId}
|
||||
<select id="getTestPlanCountNodes" resultType="io.metersphere.track.dto.TestCaseNodeDTO">
|
||||
select tcn.id, count(*) as caseNum, test_case.project_id
|
||||
from test_plan_test_case
|
||||
inner join test_case on test_plan_test_case.case_id = test_case.id
|
||||
inner join test_case_node tcn on test_case.node_id = tcn.id
|
||||
<include refid="queryWhereCondition"/>
|
||||
group by test_case.node_id;
|
||||
</select>
|
||||
<select id="getExecResultMapByPlanId" resultType="io.metersphere.track.dto.CountMapDTO">
|
||||
select status as `key`, count(*) as `value`
|
||||
|
@ -577,6 +577,13 @@
|
|||
where id = #{0}
|
||||
</select>
|
||||
|
||||
<select id="projectIdsByPlanId" resultType="java.lang.String">
|
||||
select distinct tc.project_id
|
||||
from test_plan_test_case tptc
|
||||
join test_case tc on tptc.case_id = tc.id
|
||||
where tptc.plan_id = #{planId}
|
||||
</select>
|
||||
|
||||
<sql id="queryVersionCondition">
|
||||
<if test="request.versionId != null">
|
||||
and ${versionTable}.version_id = #{request.versionId}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.track.dto.CountMapDTO;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.dto.TestReviewCaseDTO;
|
||||
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -30,14 +31,17 @@ public interface ExtTestReviewCaseMapper {
|
|||
|
||||
List<TestReviewCaseDTO> listForMinder(@Param("request") QueryCaseReviewRequest request);
|
||||
|
||||
|
||||
List<String> selectReviewIds();
|
||||
|
||||
List<String> getIdsOrderByUpdateTime(@Param("reviewId") String reviewId);
|
||||
|
||||
Long getPreOrder(@Param("reviewId")String reviewId, @Param("baseOrder") Long baseOrder);
|
||||
Long getPreOrder(@Param("reviewId") String reviewId, @Param("baseOrder") Long baseOrder);
|
||||
|
||||
Long getLastOrder(@Param("reviewId")String reviewId, @Param("baseOrder") Long baseOrder);
|
||||
Long getLastOrder(@Param("reviewId") String reviewId, @Param("baseOrder") Long baseOrder);
|
||||
|
||||
List<CountMapDTO> getStatusMapByReviewId(@Param("reviewId") String reviewId);
|
||||
|
||||
List<String> projectIdsByPlanId(@Param("reviewId") String reviewId);
|
||||
|
||||
List<TestCaseNodeDTO> getTestReviewCountNodes(@Param("request") QueryCaseReviewRequest request);
|
||||
}
|
||||
|
|
|
@ -464,7 +464,19 @@
|
|||
where review_id = #{reviewId} and is_del = 0
|
||||
group by status
|
||||
</select>
|
||||
|
||||
<select id="projectIdsByPlanId" resultType="java.lang.String">
|
||||
select distinct project_id
|
||||
from test_case_review_test_case
|
||||
inner join test_case on test_case_review_test_case.case_id = test_case.id
|
||||
</select>
|
||||
<select id="getTestReviewCountNodes" resultType="io.metersphere.track.dto.TestCaseNodeDTO">
|
||||
select tcn.id, count(*) as caseNum, test_case.project_id
|
||||
from test_case_review_test_case
|
||||
inner join test_case on test_case_review_test_case.case_id = test_case.id
|
||||
inner join test_case_node tcn on test_case.node_id = tcn.id
|
||||
<include refid="queryWhereCondition"/>
|
||||
group by test_case.node_id;
|
||||
</select>
|
||||
<sql id="queryVersionCondition">
|
||||
<if test="request.versionId != null">
|
||||
and ${versionTable}.version_id = #{request.versionId}
|
||||
|
|
|
@ -198,7 +198,7 @@ public class BaseModuleService extends NodeTreeService<ModuleNodeDTO> {
|
|||
if (moduleIdObj != null && countNumObj != null) {
|
||||
String moduleId = String.valueOf(moduleIdObj);
|
||||
try {
|
||||
Integer countNumInteger = new Integer(String.valueOf(countNumObj));
|
||||
Integer countNumInteger = Integer.valueOf(String.valueOf(countNumObj));
|
||||
returnMap.put(moduleId, countNumInteger);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.track.dto.TreeNodeDTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class NodeTreeService<T extends TreeNodeDTO> {
|
||||
|
||||
|
@ -32,6 +36,16 @@ public class NodeTreeService<T extends TreeNodeDTO> {
|
|||
|
||||
|
||||
public List<T> getNodeTrees(List<T> nodes) {
|
||||
return getNodeTrees(nodes, null);
|
||||
}
|
||||
|
||||
public Map<String, Integer> getCountMap(List<T> nodes) {
|
||||
Map<String, Integer> countMap = nodes.stream()
|
||||
.collect(Collectors.toMap(TreeNodeDTO::getId, TreeNodeDTO::getCaseNum));
|
||||
return countMap;
|
||||
}
|
||||
|
||||
public List<T> getNodeTrees(List<T> nodes, Map<String, Integer> countMap) {
|
||||
List<T> nodeTreeList = new ArrayList<>();
|
||||
Map<Integer, List<T>> nodeLevelMap = new HashMap<>();
|
||||
nodes.forEach(node -> {
|
||||
|
@ -45,25 +59,24 @@ public class NodeTreeService<T extends TreeNodeDTO> {
|
|||
}
|
||||
});
|
||||
List<T> rootNodes = Optional.ofNullable(nodeLevelMap.get(1)).orElse(new ArrayList<>());
|
||||
rootNodes.forEach(rootNode -> {
|
||||
nodeTreeList.add(buildNodeTree(nodeLevelMap, rootNode));
|
||||
});
|
||||
rootNodes.forEach(rootNode -> nodeTreeList.add(buildNodeTree(nodeLevelMap, rootNode, countMap)));
|
||||
return nodeTreeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归构建节点树
|
||||
* 并统计设置 CaseNum
|
||||
*
|
||||
* @param nodeLevelMap
|
||||
* @param rootNode
|
||||
* @return
|
||||
*/
|
||||
public T buildNodeTree(Map<Integer, List<T>> nodeLevelMap, T rootNode) {
|
||||
public T buildNodeTree(Map<Integer, List<T>> nodeLevelMap, T rootNode, Map<String, Integer> countMap) {
|
||||
|
||||
T nodeTree = getClassInstance();
|
||||
// T nodeTree = (T) new TreeNodeDTO();
|
||||
BeanUtils.copyBean(nodeTree, rootNode);
|
||||
nodeTree.setLabel(rootNode.getName());
|
||||
setCaseNum(countMap, nodeTree);
|
||||
|
||||
List<T> lowerNodes = nodeLevelMap.get(rootNode.getLevel() + 1);
|
||||
if (lowerNodes == null) {
|
||||
|
@ -74,13 +87,95 @@ public class NodeTreeService<T extends TreeNodeDTO> {
|
|||
|
||||
lowerNodes.forEach(node -> {
|
||||
if (node.getParentId() != null && node.getParentId().equals(rootNode.getId())) {
|
||||
children.add(buildNodeTree(nodeLevelMap, node));
|
||||
children.add(buildNodeTree(nodeLevelMap, node, countMap));
|
||||
if (countMap != null) {
|
||||
Integer childrenCount = children.stream().map(TreeNodeDTO::getCaseNum).reduce(Integer::sum).get();
|
||||
nodeTree.setCaseNum(nodeTree.getCaseNum() + childrenCount);
|
||||
}
|
||||
nodeTree.setChildren(children);
|
||||
}
|
||||
});
|
||||
return nodeTree;
|
||||
}
|
||||
|
||||
public T buildNodeTree(Map<Integer, List<T>> nodeLevelMap, T rootNode) {
|
||||
return buildNodeTree(nodeLevelMap, rootNode, null);
|
||||
}
|
||||
|
||||
private void setCaseNum(Map<String, Integer> countMap, T nodeTree) {
|
||||
if (countMap != null) {
|
||||
if (countMap.get(nodeTree.getId()) != null) {
|
||||
nodeTree.setCaseNum(countMap.get(nodeTree.getId()));
|
||||
} else {
|
||||
nodeTree.setCaseNum(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<T> getNodeTreeWithPruningTree(List<T> countModules,
|
||||
Function<List<String>, List<T>> getProjectModulesFunc) {
|
||||
if (org.springframework.util.CollectionUtils.isEmpty(countModules)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<T> list = new ArrayList<>();
|
||||
|
||||
Set<String> projectIdSet = new HashSet<>();
|
||||
countModules.forEach(x -> projectIdSet.add(x.getProjectId()));
|
||||
List<String> projectIds = new ArrayList<>(projectIdSet);
|
||||
|
||||
ProjectService projectService = CommonBeanFactory.getBean(ProjectService.class);
|
||||
List<Project> projects = projectService.getProjectByIds(new ArrayList<>(projectIds));
|
||||
|
||||
Map<String, List<T>> projectModuleMap = getProjectModulesFunc.apply(projectIds)
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(TreeNodeDTO::getProjectId));
|
||||
|
||||
// 模块与用例数的映射
|
||||
Map<String, Integer> countMap = countModules.stream()
|
||||
.collect(Collectors.toMap(TreeNodeDTO::getId, TreeNodeDTO::getCaseNum));
|
||||
|
||||
projects.forEach((project) -> {
|
||||
if (project != null) {
|
||||
List<T> testCaseNodes = projectModuleMap.get(project.getId());
|
||||
|
||||
testCaseNodes = testCaseNodes.stream().sorted(Comparator.comparingDouble(TreeNodeDTO::getPos))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
testCaseNodes = getNodeTreeWithPruningTreeByCaseCount(testCaseNodes, countMap);
|
||||
|
||||
// 项目设置成根节点
|
||||
T projectNode = getClassInstance();
|
||||
projectNode.setId(project.getId());
|
||||
projectNode.setName(project.getName());
|
||||
projectNode.setLabel(project.getName());
|
||||
projectNode.setChildren(testCaseNodes);
|
||||
projectNode.setCaseNum(testCaseNodes.stream().mapToInt(TreeNodeDTO::getCaseNum).sum());
|
||||
if (!org.springframework.util.CollectionUtils.isEmpty(testCaseNodes)) {
|
||||
list.add(projectNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成模块树并剪枝
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<T> getNodeTreeWithPruningTreeByCaseCount(List<T> testCaseNodes, Map<String, Integer> countMap) {
|
||||
List<T> nodeTrees = getNodeTrees(testCaseNodes, countMap);
|
||||
Iterator<T> iterator = nodeTrees.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
T rootNode = iterator.next();
|
||||
if (pruningTreeByCaseCount(rootNode)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return nodeTrees;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除没有数据的节点
|
||||
*
|
||||
|
@ -116,6 +211,26 @@ public class NodeTreeService<T extends TreeNodeDTO> {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean pruningTreeByCaseCount(T rootNode) {
|
||||
List<T> children = rootNode.getChildren();
|
||||
|
||||
if (rootNode.getCaseNum() == null || rootNode.getCaseNum() < 1) {
|
||||
// 没有用例的模块剪掉
|
||||
return true;
|
||||
}
|
||||
|
||||
if (children != null) {
|
||||
Iterator<T> iterator = children.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
T subNode = iterator.next();
|
||||
if (pruningTreeByCaseCount(subNode)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据目标节点路径,创建相关节点
|
||||
*
|
||||
|
|
|
@ -8,13 +8,16 @@ import io.metersphere.service.CheckPermissionService;
|
|||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.DragNodeRequest;
|
||||
import io.metersphere.track.request.testcase.QueryNodeRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||
import io.metersphere.track.service.TestCaseNodeService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@RequestMapping("/case/node")
|
||||
@RestController
|
||||
|
@ -31,6 +34,12 @@ public class TestCaseNodeController {
|
|||
return testCaseNodeService.getNodeTreeByProjectId(projectId);
|
||||
}
|
||||
|
||||
@PostMapping("/list/{projectId}")
|
||||
public List<TestCaseNodeDTO> getNodeByCondition(@PathVariable String projectId, @RequestBody(required = false) QueryTestCaseRequest request) {
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return testCaseNodeService.getNodeTreeByProjectId(projectId, Optional.ofNullable(request).orElse(new QueryTestCaseRequest()));
|
||||
}
|
||||
|
||||
@PostMapping("/minder/extraNode/count")
|
||||
public Map<String, Integer> getMinderTreeExtraNodeCount(@RequestBody List<String> nodeIds) {
|
||||
return testCaseNodeService.getMinderTreeExtraNodeCount(nodeIds);
|
||||
|
@ -70,8 +79,14 @@ public class TestCaseNodeController {
|
|||
return testCaseNodeService.getNodeByPlanId(planId);
|
||||
}
|
||||
|
||||
@PostMapping("/list/plan/{planId}")
|
||||
public List<TestCaseNodeDTO> getNodeByPlanId(@PathVariable String planId, @RequestBody(required = false) QueryTestPlanCaseRequest request) {
|
||||
checkPermissionService.checkTestPlanOwner(planId);
|
||||
return testCaseNodeService.getNodeByPlanId(planId, Optional.ofNullable(request).orElse(new QueryTestPlanCaseRequest()));
|
||||
}
|
||||
|
||||
@GetMapping("/list/plan/{planId}/{runResult}")
|
||||
public List<TestCaseNodeDTO> getNodeByPlanIdAndRunResult(@PathVariable String planId,@PathVariable String runResult) {
|
||||
public List<TestCaseNodeDTO> getNodeByPlanIdAndRunResult(@PathVariable String planId, @PathVariable String runResult) {
|
||||
checkPermissionService.checkTestPlanOwner(planId);
|
||||
QueryTestPlanCaseRequest request = new QueryTestPlanCaseRequest();
|
||||
request.setPlanId(planId);
|
||||
|
@ -85,6 +100,12 @@ public class TestCaseNodeController {
|
|||
return testCaseNodeService.getNodeByReviewId(reviewId);
|
||||
}
|
||||
|
||||
@PostMapping("/list/review/{reviewId}")
|
||||
public List<TestCaseNodeDTO> getNodeByReviewId(@PathVariable String reviewId, @RequestBody(required = false) QueryCaseReviewRequest request) {
|
||||
checkPermissionService.checkTestReviewOwner(reviewId);
|
||||
return testCaseNodeService.getNodeByReviewId(reviewId, Optional.ofNullable(request).orElse(new QueryCaseReviewRequest()));
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE, type = OperLogConstants.CREATE, title = "#node.name", content = "#msClass.getLogDetails(#node)", msClass = TestCaseNodeService.class)
|
||||
public String addNode(@RequestBody TestCaseNode node) {
|
||||
|
|
|
@ -7,8 +7,8 @@ import io.metersphere.base.domain.*;
|
|||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseNodeMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseReviewTestCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestReviewCaseMapper;
|
||||
import io.metersphere.commons.constants.TestCaseConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
|
@ -22,16 +22,19 @@ import io.metersphere.log.vo.DetailColumn;
|
|||
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.TestCaseDTO;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||
import io.metersphere.track.request.testcase.*;
|
||||
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
|
||||
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
@ -63,11 +66,12 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
@Resource
|
||||
ProjectMapper projectMapper;
|
||||
@Resource
|
||||
TestCaseReviewTestCaseMapper testCaseReviewTestCaseMapper;
|
||||
@Resource
|
||||
ExtTestCaseReviewTestCaseMapper extTestCaseReviewTestCaseMapper;
|
||||
@Resource
|
||||
TestCaseReviewMapper testCaseReviewMapper;
|
||||
@Resource
|
||||
ExtTestReviewCaseMapper extTestReviewCaseMapper;
|
||||
@Lazy
|
||||
@Resource
|
||||
ProjectService projectService;
|
||||
|
||||
public TestCaseNodeService() {
|
||||
super(TestCaseNodeDTO.class);
|
||||
|
@ -138,81 +142,42 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
testCaseNodeMapper.insert(record);
|
||||
record.setCaseNum(0);
|
||||
return record;
|
||||
}else {
|
||||
} else {
|
||||
return list.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getNodeTreeByProjectId(String projectId) {
|
||||
QueryTestCaseRequest request = new QueryTestCaseRequest();
|
||||
return getNodeTreeByProjectId(projectId, request);
|
||||
return getNodeTreeByProjectId(projectId, new QueryTestCaseRequest());
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getNodeTreeByProjectId(String projectId, QueryTestCaseRequest request) {
|
||||
// 判断当前项目下是否有默认模块,没有添加默认模块
|
||||
this.getDefaultNode(projectId);
|
||||
List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId);
|
||||
request.setUserId(SessionUtils.getUserId());
|
||||
request.setProjectId(projectId);
|
||||
|
||||
//优化:将for循环内的SQL抽出来,只差一次
|
||||
List<String> allModuleIdList = new ArrayList<>();
|
||||
for (TestCaseNodeDTO node : testCaseNodes) {
|
||||
List<String> moduleIds = new ArrayList<>();
|
||||
moduleIds = this.nodeList(testCaseNodes, node.getId(), moduleIds);
|
||||
moduleIds.add(node.getId());
|
||||
for (String moduleId : moduleIds) {
|
||||
if(!allModuleIdList.contains(moduleId)){
|
||||
allModuleIdList.add(moduleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
request.setModuleIds(allModuleIdList);
|
||||
List<Map<String,Object>> moduleCountList = extTestCaseMapper.moduleCountByCollection(request);
|
||||
Map<String,Integer> moduleCountMap = this.parseModuleCountList(moduleCountList);
|
||||
testCaseNodes.forEach(node -> {
|
||||
List<String> moduleIds = new ArrayList<>();
|
||||
moduleIds = this.nodeList(testCaseNodes, node.getId(), moduleIds);
|
||||
moduleIds.add(node.getId());
|
||||
int countNum = 0;
|
||||
for (String moduleId : moduleIds) {
|
||||
if(moduleCountMap.containsKey(moduleId)){
|
||||
countNum += moduleCountMap.get(moduleId).intValue();
|
||||
}
|
||||
}
|
||||
node.setCaseNum(countNum);
|
||||
});
|
||||
return getNodeTrees(testCaseNodes);
|
||||
request.setUserId(SessionUtils.getUserId());
|
||||
List<TestCaseNodeDTO> countMNodes = extTestCaseMapper.getCountNodes(request);
|
||||
List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId);
|
||||
return getNodeTrees(testCaseNodes, getCountMap(countMNodes));
|
||||
}
|
||||
|
||||
private Map<String, Integer> parseModuleCountList(List<Map<String, Object>> moduleCountList) {
|
||||
Map<String,Integer> returnMap = new HashMap<>();
|
||||
for (Map<String, Object> map: moduleCountList){
|
||||
Map<String, Integer> returnMap = new HashMap<>();
|
||||
for (Map<String, Object> map : moduleCountList) {
|
||||
Object moduleIdObj = map.get("moduleId");
|
||||
Object countNumObj = map.get("countNum");
|
||||
if(moduleIdObj!= null && countNumObj != null){
|
||||
if (moduleIdObj != null && countNumObj != null) {
|
||||
String moduleId = String.valueOf(moduleIdObj);
|
||||
try {
|
||||
Integer countNumInteger = new Integer(String.valueOf(countNumObj));
|
||||
returnMap.put(moduleId,countNumInteger);
|
||||
}catch (Exception e){
|
||||
Integer countNumInteger = Integer.valueOf(String.valueOf(countNumObj));
|
||||
returnMap.put(moduleId, countNumInteger);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public int editNode(DragNodeRequest request) {
|
||||
request.setUpdateTime(System.currentTimeMillis());
|
||||
checkTestCaseNodeExist(request);
|
||||
|
@ -235,6 +200,7 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
|
||||
/**
|
||||
* 修改用例的 nodePath
|
||||
*
|
||||
* @param editNodeIds
|
||||
* @param projectId
|
||||
*/
|
||||
|
@ -263,9 +229,9 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
}
|
||||
|
||||
private List<String> selectCaseIdByNodeIds(List<String> nodeIds) {
|
||||
if(CollectionUtils.isEmpty(nodeIds)){
|
||||
return new ArrayList<>();
|
||||
}else {
|
||||
if (CollectionUtils.isEmpty(nodeIds)) {
|
||||
return new ArrayList<>();
|
||||
} else {
|
||||
return extTestCaseMapper.selectIdsByNodeIds(nodeIds);
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +244,6 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
* @return List<TestCaseNodeDTO>
|
||||
*/
|
||||
public List<TestCaseNodeDTO> getNodeByQueryRequest(QueryTestPlanCaseRequest request) {
|
||||
|
||||
List<TestCaseNodeDTO> list = new ArrayList<>();
|
||||
List<String> projectIds = testPlanProjectService.getProjectIdsByPlanId(request.getPlanId());
|
||||
projectIds.forEach(id -> {
|
||||
|
@ -300,17 +265,22 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
* 获取当前计划下
|
||||
* 有关联数据的节点
|
||||
*
|
||||
* @param planId plan id
|
||||
* @param planId plan id
|
||||
* @param request 根据查询条件过滤用例数量
|
||||
* @return List<TestCaseNodeDTO>
|
||||
*/
|
||||
public List<TestCaseNodeDTO> getNodeByPlanId(String planId) {
|
||||
List<TestCase> testCases = extTestPlanTestCaseMapper.getTestCaseWithNodeInfo(planId);
|
||||
Map<String, List<String>> projectNodeMap = getProjectNodeMap(testCases);
|
||||
return getNodeTreeWithPruningTree(projectNodeMap);
|
||||
public List<TestCaseNodeDTO> getNodeByPlanId(String planId, QueryTestPlanCaseRequest request) {
|
||||
request.setPlanId(planId);
|
||||
request.setProjectId(null);
|
||||
List<TestCaseNodeDTO> countModules = extTestPlanTestCaseMapper.getTestPlanCountNodes(request);
|
||||
return getNodeTreeWithPruningTree(countModules);
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getPublicNodeByProjectNode(List<TestCaseNodeDTO> projectNodes) {
|
||||
QueryTestCaseRequest request = new QueryTestCaseRequest();
|
||||
public List<TestCaseNodeDTO> getNodeByPlanId(String planId) {
|
||||
return this.getNodeByPlanId(planId, new QueryTestPlanCaseRequest());
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getPublicNodeByProjectNode(List<TestCaseNodeDTO> projectNodes, QueryTestCaseRequest request) {
|
||||
request.setCasePublic(true);
|
||||
for (TestCaseNodeDTO dto : projectNodes) {
|
||||
List<TestCaseNodeDTO> children = this.getNodeTreeByProjectId(dto.getId(), request);
|
||||
|
@ -322,60 +292,37 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getNodeByReviewId(String reviewId) {
|
||||
List<TestCase> testCases = extTestCaseReviewTestCaseMapper.getTestCaseWithNodeInfo(reviewId);
|
||||
Map<String, List<String>> projectNodeMap = getProjectNodeMap(testCases);
|
||||
return getNodeTreeWithPruningTree(projectNodeMap);
|
||||
return this.getNodeByReviewId(reviewId, new QueryCaseReviewRequest());
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getNodeTreeWithPruningTree(Map<String, List<String>> projectNodeMap) {
|
||||
List<TestCaseNodeDTO> list = new ArrayList<>();
|
||||
projectNodeMap.forEach((k, v) -> {
|
||||
Project project = projectMapper.selectByPrimaryKey(k);
|
||||
if (project != null) {
|
||||
String name = project.getName();
|
||||
List<TestCaseNodeDTO> testCaseNodes = getNodeTreeWithPruningTree(k, v);
|
||||
TestCaseNodeDTO testCaseNodeDTO = new TestCaseNodeDTO();
|
||||
testCaseNodeDTO.setId(project.getId());
|
||||
testCaseNodeDTO.setName(name);
|
||||
testCaseNodeDTO.setLabel(name);
|
||||
testCaseNodeDTO.setChildren(testCaseNodes);
|
||||
if (!CollectionUtils.isEmpty(testCaseNodes)) {
|
||||
list.add(testCaseNodeDTO);
|
||||
}
|
||||
}
|
||||
});
|
||||
return list;
|
||||
public List<TestCaseNodeDTO> getNodeByReviewId(String reviewId, QueryCaseReviewRequest request) {
|
||||
request.setReviewId(reviewId);
|
||||
request.setProjectId(null);
|
||||
List<TestCaseNodeDTO> countModules = extTestReviewCaseMapper.getTestReviewCountNodes(request);
|
||||
return getNodeTreeWithPruningTree(countModules);
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getNodeTreeWithPruningTree(List<TestCaseNodeDTO> countModules) {
|
||||
return getNodeTreeWithPruningTree(countModules, extTestCaseNodeMapper::getNodeTreeByProjectIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前项目下的
|
||||
* @param projectId
|
||||
* @param pruningTreeIds
|
||||
* 生成模块树并剪枝
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<TestCaseNodeDTO> getNodeTreeWithPruningTree(String projectId, List<String> pruningTreeIds) {
|
||||
List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId);
|
||||
public List<TestCaseNodeDTO> getNodeTreeWithPruningTree(List<TestCaseNodeDTO> testCaseNodes, List<String> containIds) {
|
||||
List<TestCaseNodeDTO> nodeTrees = getNodeTrees(testCaseNodes);
|
||||
Iterator<TestCaseNodeDTO> iterator = nodeTrees.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
TestCaseNodeDTO rootNode = iterator.next();
|
||||
if (pruningTree(rootNode, pruningTreeIds)) {
|
||||
if (pruningTree(rootNode, containIds)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return nodeTrees;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getProjectNodeMap(List<TestCase> testCases) {
|
||||
Map<String, List<String>> projectNodeMap = new HashMap<>();
|
||||
for (TestCase testCase : testCases) {
|
||||
List<String> nodeIds = Optional.ofNullable(projectNodeMap.get(testCase.getProjectId())).orElse(new ArrayList<>());
|
||||
nodeIds.add(testCase.getNodeId());
|
||||
projectNodeMap.put(testCase.getProjectId(), nodeIds);
|
||||
}
|
||||
return projectNodeMap;
|
||||
}
|
||||
|
||||
private List<TestCaseNodeDTO> getNodeDTO(String projectId, QueryTestPlanCaseRequest request) {
|
||||
List<TestPlanCaseDTO> testPlanTestCases = extTestPlanTestCaseMapper.listByPlanId(request);
|
||||
if (testPlanTestCases.isEmpty()) {
|
||||
|
@ -392,7 +339,8 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
.map(TestCase::getNodeId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return getNodeTreeWithPruningTree(projectId, dataNodeIds);
|
||||
List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId);
|
||||
return getNodeTreeWithPruningTree(testCaseNodes, dataNodeIds);
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getAllNodeByPlanId(QueryNodeRequest request) {
|
||||
|
@ -415,7 +363,6 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
if (testCaseReview == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return getNodeTreeByProjectId(projectId);
|
||||
}
|
||||
|
||||
|
@ -533,8 +480,8 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
private List<TestCaseDTO> QueryTestCaseByNodeIds(List<String> nodeIds) {
|
||||
QueryTestCaseRequest testCaseRequest = new QueryTestCaseRequest();
|
||||
testCaseRequest.setNodeIds(nodeIds);
|
||||
if(testCaseRequest.getFilters()!=null && !testCaseRequest.getFilters().containsKey("status")){
|
||||
testCaseRequest.getFilters().put("status",new ArrayList<>(0));
|
||||
if (testCaseRequest.getFilters() != null && !testCaseRequest.getFilters().containsKey("status")) {
|
||||
testCaseRequest.getFilters().put("status", new ArrayList<>(0));
|
||||
}
|
||||
return extTestCaseMapper.list(testCaseRequest);
|
||||
}
|
||||
|
@ -578,10 +525,6 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
return projectMapper.selectByPrimaryKey(projectId);
|
||||
}
|
||||
|
||||
private TestCaseNode getCaseNode(String id) {
|
||||
return testCaseNodeMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestCaseNodeDTO getNode(String id) {
|
||||
return extTestCaseNodeMapper.get(id);
|
||||
|
@ -729,7 +672,7 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
|
||||
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(testCaseNodes)) {
|
||||
|
||||
for (TestCaseMinderEditRequest.TestCaseNodeMinderEditItem item: testCaseNodes) {
|
||||
for (TestCaseMinderEditRequest.TestCaseNodeMinderEditItem item : testCaseNodes) {
|
||||
if (StringUtils.isBlank(item.getParentId()) || item.getParentId().equals("root")) {
|
||||
item.setParentId(null);
|
||||
}
|
||||
|
@ -759,6 +702,7 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
|
|||
|
||||
/**
|
||||
* 统计某些节点下的临时节点的数量
|
||||
*
|
||||
* @param nodeIds
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -2775,7 +2775,7 @@ public class TestCaseService {
|
|||
|
||||
public List<TestCaseNodeDTO> getPublicCaseNode(QueryTestCaseRequest request) {
|
||||
List<TestCaseNodeDTO> testCaseDTOS = publicProjectNode(request);
|
||||
return testCaseNodeService.getPublicNodeByProjectNode(testCaseDTOS);
|
||||
return testCaseNodeService.getPublicNodeByProjectNode(testCaseDTOS, request);
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> publicProjectNode(QueryTestCaseRequest request) {
|
||||
|
|
|
@ -3,34 +3,28 @@
|
|||
|
||||
<ms-aside-container v-show="isAsideHidden">
|
||||
<test-case-node-tree
|
||||
@nodeSelectEvent="nodeChange"
|
||||
:type="'edit'"
|
||||
:total='total'
|
||||
:show-operator="true"
|
||||
:public-total="publicTotal"
|
||||
@refreshTable="refresh"
|
||||
@setTreeNodes="setTreeNodes"
|
||||
@exportTestCase="exportTestCase"
|
||||
@saveAsEdit="editTestCase"
|
||||
:show-operator="true"
|
||||
@createCase="handleCaseSimpleCreate($event, 'add')"
|
||||
@refreshAll="refreshAll"
|
||||
@enableTrash="enableTrash"
|
||||
@enablePublic="enablePublic"
|
||||
@toPublic="toPublic"
|
||||
:type="'edit'"
|
||||
:total='total'
|
||||
:public-total="publicTotal"
|
||||
ref="nodeTree"
|
||||
@importChangeConfirm="importChangeConfirm"
|
||||
@createCase="handleCaseSimpleCreate($event, 'add')"
|
||||
ref="nodeTree"
|
||||
/>
|
||||
</ms-aside-container>
|
||||
|
||||
<ms-aside-container v-if="showPublicNode">
|
||||
<node-tree class="node-tree"
|
||||
:is-display="'public'"
|
||||
v-loading="result.loading"
|
||||
local-suffix="test_case"
|
||||
default-label="未规划用例"
|
||||
@nodeSelectEvent="publicNodeChange"
|
||||
:tree-nodes="publicTreeNodes"
|
||||
ref="publicNodeTree"/>
|
||||
<test-case-public-node-tree
|
||||
@nodeSelectEvent="publicNodeChange"
|
||||
ref="publicNodeTree"/>
|
||||
</ms-aside-container>
|
||||
|
||||
<ms-main-container>
|
||||
|
@ -57,6 +51,7 @@
|
|||
@refresh="refresh"
|
||||
@refreshAll="refreshAll"
|
||||
@setCondition="setCondition"
|
||||
@search="refreshTreeByCaseFilter"
|
||||
ref="testCaseTrashList">
|
||||
</test-case-list>
|
||||
</ms-tab-button>
|
||||
|
@ -81,6 +76,7 @@
|
|||
@refreshAll="refreshAll"
|
||||
@refreshPublic="refreshPublic"
|
||||
@setCondition="setCondition"
|
||||
@search="refreshTreeByCaseFilter"
|
||||
ref="testCasePublicList">
|
||||
</test-case-list>
|
||||
</el-tab-pane>
|
||||
|
@ -115,6 +111,7 @@
|
|||
@refreshAll="refreshAll"
|
||||
@setCondition="setCondition"
|
||||
@decrease="decrease"
|
||||
@search="refreshTreeByCaseFilter"
|
||||
ref="testCaseList">
|
||||
</test-case-list>
|
||||
<test-case-minder
|
||||
|
@ -218,14 +215,15 @@ import {
|
|||
hasPermission,
|
||||
setCurTabId
|
||||
} from "@/common/js/utils";
|
||||
import TestCaseNodeTree from "../common/TestCaseNodeTree";
|
||||
import TestCaseNodeTree from "../module/TestCaseNodeTree";
|
||||
|
||||
import MsTabButton from "@/business/components/common/components/MsTabButton";
|
||||
import TestCaseMinder from "@/business/components/track/common/minder/TestCaseMinder";
|
||||
import IsChangeConfirm from "@/business/components/common/components/IsChangeConfirm";
|
||||
import {openMinderConfirm, saveMinderConfirm} from "@/business/components/track/common/minder/minderUtils";
|
||||
import {openMinderConfirm} from "@/business/components/track/common/minder/minderUtils";
|
||||
import TestCaseEditShow from "@/business/components/track/case/components/TestCaseEditShow";
|
||||
import {PROJECT_ID} from "@/common/js/constants";
|
||||
import TestCasePublicNodeTree from "@/business/components/track/module/TestCasePublicNodeTree";
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const VersionSelect = requireComponent.keys().length > 0 ? requireComponent("./version/VersionSelect.vue") : {};
|
||||
|
@ -233,6 +231,7 @@ const VersionSelect = requireComponent.keys().length > 0 ? requireComponent("./v
|
|||
export default {
|
||||
name: "TestCase",
|
||||
components: {
|
||||
TestCasePublicNodeTree,
|
||||
IsChangeConfirm,
|
||||
TestCaseMinder,
|
||||
MsTabButton,
|
||||
|
@ -267,8 +266,6 @@ export default {
|
|||
currentTrashVersion: null,
|
||||
versionEnable: false,
|
||||
isAsideHidden: true,
|
||||
showPublicNode: false,
|
||||
publicTreeNodes: [],
|
||||
ignoreTreeNodes:false,
|
||||
};
|
||||
},
|
||||
|
@ -306,8 +303,7 @@ export default {
|
|||
this.init(to);
|
||||
},
|
||||
activeName(newVal, oldVal) {
|
||||
this.isAsideHidden = this.activeName === 'default';
|
||||
this.showPublicNode = this.activeName === 'public';
|
||||
this.isAsideHidden = this.activeName === 'default' || this.activeName === 'trash';
|
||||
if (oldVal !== 'default' && newVal === 'default' && this.$refs.minder) {
|
||||
this.$refs.minder.refresh();
|
||||
}
|
||||
|
@ -323,18 +319,15 @@ export default {
|
|||
if (this.trashEnable) {
|
||||
this.activeName = 'trash';
|
||||
} else {
|
||||
this.activeName = 'default';
|
||||
this.actciveName = 'default';
|
||||
}
|
||||
},
|
||||
publicEnable() {
|
||||
if (this.publicEnable) {
|
||||
this.activeName = 'public';
|
||||
this.result = this.$post('/test/case/public/case/node', {workspaceId: getCurrentWorkspaceId()}, res => {
|
||||
this.publicTreeNodes = res.data;
|
||||
this.publicTreeNodes.forEach(firstLevel => {
|
||||
this.$refs.publicNodeTree.nodeExpand(firstLevel);
|
||||
})
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.$refs.publicNodeTree.list();
|
||||
});
|
||||
} else {
|
||||
this.activeName = 'default';
|
||||
}
|
||||
|
@ -355,7 +348,9 @@ export default {
|
|||
let redirectParam = this.$route.params.dataSelectRange;
|
||||
return redirectParam;
|
||||
},
|
||||
|
||||
showPublicNode() {
|
||||
return this.activeName === 'public';
|
||||
},
|
||||
projectId() {
|
||||
return getCurrentProjectID();
|
||||
},
|
||||
|
@ -592,16 +587,7 @@ export default {
|
|||
this.$router.push('/track/case/all');
|
||||
}
|
||||
},
|
||||
nodeChange(node) {
|
||||
this.condition.trashEnable = false;
|
||||
this.trashEnable = false;
|
||||
this.condition.publicEnable = false;
|
||||
this.publicEnable = false;
|
||||
this.activeName = "default";
|
||||
},
|
||||
publicNodeChange(node, nodeIds, pNodes) {
|
||||
this.activeName = 'public';
|
||||
this.publicEnable = true;
|
||||
if (this.$refs.testCasePublicList) {
|
||||
this.$refs.testCasePublicList.initTableData(nodeIds);
|
||||
}
|
||||
|
@ -681,6 +667,13 @@ export default {
|
|||
}
|
||||
this.refreshAll(data);
|
||||
},
|
||||
refreshTreeByCaseFilter() {
|
||||
if (this.publicEnable) {
|
||||
this.$refs.publicNodeTree.list(this.condition);
|
||||
} else if (!this.trashEnable) {
|
||||
this.$refs.nodeTree.list(this.condition);
|
||||
}
|
||||
},
|
||||
setTable(data) {
|
||||
if (data) {
|
||||
for (let index in this.tabs) {
|
||||
|
@ -709,9 +702,7 @@ export default {
|
|||
if (this.$refs.testCasePublicList) {
|
||||
this.$refs.testCasePublicList.initTableData([]);
|
||||
}
|
||||
this.result = this.$post('/test/case/public/case/node', {workspaceId: getCurrentWorkspaceId()}, res => {
|
||||
this.publicTreeNodes = res.data;
|
||||
})
|
||||
this.$refs.publicNodeTree.list();
|
||||
},
|
||||
setTreeNodes(data) {
|
||||
this.treeNodes = data;
|
||||
|
@ -728,11 +719,9 @@ export default {
|
|||
});
|
||||
},
|
||||
enableTrash(data) {
|
||||
this.initApiTableOpretion = "trashEnable";
|
||||
this.trashEnable = data;
|
||||
},
|
||||
enablePublic(data) {
|
||||
this.initApiTableOpretion = "publicEnable";
|
||||
this.publicEnable = !data;
|
||||
this.$nextTick(() => {
|
||||
this.publicEnable = data;
|
||||
|
@ -744,7 +733,6 @@ export default {
|
|||
} else {
|
||||
this.activeName = "trash"
|
||||
}
|
||||
|
||||
},
|
||||
changeVersion(currentVersion) {
|
||||
this.currentVersion = currentVersion || null;
|
||||
|
|
|
@ -823,6 +823,7 @@ export default {
|
|||
// 添加搜索条件时,当前页设置成第一页
|
||||
this.page.currentPage = 1;
|
||||
this.initTableData();
|
||||
this.$emit('search');
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.page.currentPage + "/" + this.page.pageSize;
|
||||
|
@ -1126,7 +1127,6 @@ export default {
|
|||
this.$warning(this.$t('test_track.case.public_warning'));
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
openRelateDemand() {
|
||||
this.$refs.relateDemand.open();
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
:show-operator="showOperator"
|
||||
:condition="condition"
|
||||
:commands="operators"/>
|
||||
<module-trash-button
|
||||
:condition="condition"
|
||||
:total="total"
|
||||
:exe="enableTrash"/>
|
||||
<module-trash-button
|
||||
:condition="condition"
|
||||
:total="total"
|
||||
:exe="enableTrash"/>
|
||||
<module-public-button
|
||||
:condition="condition"
|
||||
:public-total="publicTotal"
|
||||
|
@ -58,8 +58,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import NodeEdit from "./NodeEdit";
|
||||
import MsNodeTree from "./NodeTree";
|
||||
import NodeEdit from "../common/NodeEdit";
|
||||
import MsNodeTree from "../common/NodeTree";
|
||||
import TestCaseCreate from "@/business/components/track/case/components/TestCaseCreate";
|
||||
import TestCaseImport from "@/business/components/track/case/components/import/TestCaseImport";
|
||||
import TestCaseExport from "@/business/components/track/case/components/TestCaseExport";
|
||||
|
@ -69,7 +69,7 @@ import {buildNodePath} from "@/business/components/api/definition/model/NodeTree
|
|||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import ModuleTrashButton from "@/business/components/api/definition/components/module/ModuleTrashButton";
|
||||
import ModulePublicButton from "@/business/components/api/definition/components/module/ModulePublicButton";
|
||||
import {getTestCaseNodes} from "@/network/testCase";
|
||||
import {getTestCaseNodes, getTestCaseNodesByCaseFilter} from "@/network/testCase";
|
||||
import IsChangeConfirm from "@/business/components/common/components/IsChangeConfirm";
|
||||
|
||||
export default {
|
||||
|
@ -181,9 +181,9 @@ export default {
|
|||
this.$emit('enablePublic', this.condition.publicEnable);
|
||||
this.$emit('toPublic', 'public');
|
||||
},
|
||||
list() {
|
||||
list(caseCondition) {
|
||||
if (this.projectId) {
|
||||
this.result = getTestCaseNodes(this.projectId, data => {
|
||||
this.result = getTestCaseNodesByCaseFilter(this.projectId, caseCondition, data => {
|
||||
this.treeNodes = data;
|
||||
this.treeNodes.forEach(node => {
|
||||
node.name = node.name === '未规划用例' ? this.$t('api_test.unplanned_case') : node.name
|
||||
|
@ -275,15 +275,10 @@ export default {
|
|||
this.$store.commit('setTestCaseSelectNodeIds', nodeIds);
|
||||
this.condition.trashEnable = false;
|
||||
this.condition.publicEnable = false;
|
||||
|
||||
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
||||
this.currentModule = node.data;
|
||||
this.currentNode = node;
|
||||
if (node.data.id === 'root') {
|
||||
this.$emit("nodeSelectEvent", node, [], pNodes);
|
||||
} else {
|
||||
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
||||
}
|
||||
|
||||
this.$emit("nodeSelectEvent", node, node.data.id === 'root' ? [] : nodeIds, pNodes);
|
||||
},
|
||||
openMinderConfirm() {
|
||||
let isTestCaseMinderChanged = this.$store.state.isTestCaseMinderChanged;
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<ms-node-tree class="node-tree"
|
||||
:is-display="'public'"
|
||||
v-loading="result.loading"
|
||||
local-suffix="test_case"
|
||||
default-label="未规划用例"
|
||||
@nodeSelectEvent="publicNodeChange"
|
||||
:tree-nodes="publicTreeNodes"
|
||||
ref="publicNodeTree"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsNodeTree from "@/business/components/track/common/NodeTree";
|
||||
import {getTestCasePublicNodes} from "@/network/testCase";
|
||||
export default {
|
||||
name: "TestCasePublicNodeTree",
|
||||
components: {MsNodeTree},
|
||||
data() {
|
||||
return {
|
||||
publicTreeNodes: [],
|
||||
result: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
publicNodeChange(node, nodeIds, pNodes) {
|
||||
this.$emit("nodeSelectEvent", node, node.data.id === 'root' ? [] : nodeIds, pNodes);
|
||||
},
|
||||
list(caseCondition) {
|
||||
let condition = {
|
||||
...caseCondition
|
||||
};
|
||||
condition.projectId = null;
|
||||
this.result = getTestCasePublicNodes(condition, data => {
|
||||
this.publicTreeNodes = data;
|
||||
if (this.$refs.publicNodeTree) {
|
||||
this.publicTreeNodes.forEach(firstLevel => {
|
||||
this.$refs.publicNodeTree.nodeExpand(firstLevel);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="card-container">
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData" ref="tableHeader"
|
||||
<ms-table-header :condition.sync="condition" @search="search" ref="tableHeader"
|
||||
:show-create="false" :tip="$t('commons.search_by_id_name_tag')">
|
||||
|
||||
<!-- 不显示 “全部用例” 标题,使标题为空 -->
|
||||
|
@ -35,7 +35,8 @@
|
|||
:row-order-group-id="planId"
|
||||
:row-order-func="editTestPlanTestCaseOrder"
|
||||
:enable-order-drag="enableOrderDrag"
|
||||
@refresh="initTableData"
|
||||
@filter="search"
|
||||
@order="initTableData"
|
||||
@handlePageChange="initTableData"
|
||||
@handleRowClick="handleEdit"
|
||||
row-key="id"
|
||||
|
@ -236,7 +237,7 @@
|
|||
</span>
|
||||
</ms-table>
|
||||
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
|
||||
<functional-test-case-edit
|
||||
|
@ -252,7 +253,7 @@
|
|||
:test-cases="tableData"
|
||||
:is-read-only="isReadOnly"
|
||||
:total="total"
|
||||
@refreshTable="search"/>
|
||||
@refreshTable="initTableData"/>
|
||||
|
||||
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
||||
:type-arr="typeArr" :value-arr="valueArr" :dialog-title="$t('test_track.case.batch_edit_case')"/>
|
||||
|
@ -469,7 +470,7 @@ export default {
|
|||
},
|
||||
selectNodeIds() {
|
||||
this.condition.selectAll = false;
|
||||
this.search();
|
||||
this.initTableData();
|
||||
},
|
||||
tableLabel: {
|
||||
handler(newVal) {
|
||||
|
@ -632,7 +633,7 @@ export default {
|
|||
},
|
||||
refresh() {
|
||||
this.$refs.table.clear();
|
||||
this.search();
|
||||
this.initTableData();
|
||||
this.$emit('refreshTree');
|
||||
},
|
||||
refreshTableAndPlan() {
|
||||
|
@ -650,6 +651,7 @@ export default {
|
|||
},
|
||||
search() {
|
||||
this.initTableData();
|
||||
this.$emit('search');
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
class="border-hidden sync-textarea"
|
||||
type="textarea"
|
||||
:disabled="true"
|
||||
v-model="scope.row.result"/>eee
|
||||
v-model="scope.row.result"/>
|
||||
</template>
|
||||
</el-table-column>f
|
||||
<el-table-column :label="$t('test_track.plan_view.actual_result')" min-width="21%">
|
||||
G<template v-slot:default="scope">DD
|
||||
<template v-slot:default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.actualResult"
|
||||
clearable
|
||||
|
|
|
@ -23,15 +23,16 @@
|
|||
<functional-test-case-list
|
||||
class="table-list"
|
||||
v-if="activeDom === 'left'"
|
||||
@openTestCaseRelevanceDialog="openTestCaseRelevanceDialog"
|
||||
@refresh="refresh"
|
||||
@refreshTree="refreshTree"
|
||||
@setCondition="setCondition"
|
||||
:plan-id="planId"
|
||||
:plan-status="planStatus "
|
||||
:clickType="clickType"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:version-enable="versionEnable"
|
||||
@refresh="refresh"
|
||||
@refreshTree="refreshTree"
|
||||
@setCondition="setCondition"
|
||||
@search="refreshTreeByCaseFilter"
|
||||
@openTestCaseRelevanceDialog="openTestCaseRelevanceDialog"
|
||||
ref="testPlanTestCaseList"/>
|
||||
<test-plan-minder
|
||||
:tree-nodes="treeNodes"
|
||||
|
@ -69,6 +70,7 @@ import TestPlanFunctionalRelevance
|
|||
from "@/business/components/track/plan/view/comonents/functional/TestPlanFunctionalRelevance";
|
||||
import IsChangeConfirm from "@/business/components/common/components/IsChangeConfirm";
|
||||
import {openMinderConfirm, saveMinderConfirm} from "@/business/components/track/common/minder/minderUtils";
|
||||
import {getTestPlanCaseNodesByCaseFilter} from "@/network/testCase";
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
|
||||
export default {
|
||||
|
@ -143,6 +145,9 @@ export default {
|
|||
openTestCaseRelevanceDialog() {
|
||||
this.$refs.testCaseRelevance.open();
|
||||
},
|
||||
refreshTreeByCaseFilter() {
|
||||
this.getNodeTreeByPlanId(this.condition);
|
||||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
this.$store.commit('setTestPlanViewSelectNode', node);
|
||||
|
@ -153,16 +158,19 @@ export default {
|
|||
this.$refs.testPlanTestCaseList.pageSize = 10;
|
||||
}
|
||||
},
|
||||
getNodeTreeByPlanId() {
|
||||
getNodeTreeByPlanId(condition) {
|
||||
if (this.planId) {
|
||||
let url = "/case/node/list/plan/" + this.planId;
|
||||
if (this.clickType) {
|
||||
url = url + "/" + this.clickType;
|
||||
this.result = this.$get('/' + this.clickType, response => {
|
||||
this.treeNodes = response.data;
|
||||
this.setCurrentKey();
|
||||
});
|
||||
} else {
|
||||
this.result = getTestPlanCaseNodesByCaseFilter(this.planId, condition, (data) => {
|
||||
this.treeNodes = data;
|
||||
this.setCurrentKey();
|
||||
});
|
||||
}
|
||||
this.result = this.$get(url, response => {
|
||||
this.treeNodes = response.data;
|
||||
this.setCurrentKey();
|
||||
});
|
||||
}
|
||||
},
|
||||
setCurrentKey() {
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
<ms-test-plan-common-component>
|
||||
<template v-slot:aside>
|
||||
<ms-node-tree
|
||||
v-loading="result.loading"
|
||||
class="node-tree"
|
||||
:all-label="$t('commons.all_label.review')"
|
||||
local-suffix="test_case"
|
||||
default-label="未规划用例"
|
||||
v-loading="result.loading"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
:tree-nodes="treeNodes"
|
||||
:default-expand-all="true"
|
||||
:all-label="$t('commons.all_label.review')"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
ref="nodeTree"/>
|
||||
</template>
|
||||
<template v-slot:main>
|
||||
|
@ -24,20 +24,21 @@
|
|||
<test-review-test-case-list
|
||||
class="table-list"
|
||||
v-if="activeDom === 'left'"
|
||||
@openTestReviewRelevanceDialog="openTestReviewRelevanceDialog"
|
||||
@refresh="refresh"
|
||||
@setCondition="setCondition"
|
||||
:review-id="reviewId"
|
||||
:clickType="clickType"
|
||||
:current-version="currentVersion"
|
||||
:version-enable="versionEnable"
|
||||
@refresh="refresh"
|
||||
@setCondition="setCondition"
|
||||
@search="refreshTreeByCaseFilter"
|
||||
@openTestReviewRelevanceDialog="openTestReviewRelevanceDialog"
|
||||
ref="testPlanTestCaseList"/>
|
||||
<test-review-minder
|
||||
v-if="activeDom === 'right'"
|
||||
:tree-nodes="treeNodes"
|
||||
:project-id="projectId"
|
||||
:condition="condition"
|
||||
:review-id="reviewId"
|
||||
v-if="activeDom === 'right'"
|
||||
ref="minder"
|
||||
/>
|
||||
</ms-tab-button>
|
||||
|
@ -66,6 +67,7 @@ import TestReviewMinder from "@/business/components/track/common/minder/TestRevi
|
|||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import IsChangeConfirm from "@/business/components/common/components/IsChangeConfirm";
|
||||
import {openMinderConfirm, saveMinderConfirm} from "@/business/components/track/common/minder/minderUtils";
|
||||
import {getTestReviewCaseNodesByCaseFilter} from "@/network/testCase";
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const VersionSelect = requireComponent.keys().length > 0 ? requireComponent("./version/VersionSelect.vue") : {};
|
||||
|
||||
|
@ -84,8 +86,6 @@ export default {
|
|||
result: {},
|
||||
testReviews: [],
|
||||
currentReview: {},
|
||||
// selectNodeIds: [],
|
||||
// selectParentNodes: [],
|
||||
treeNodes: [],
|
||||
isMenuShow: true,
|
||||
activeDom: 'left',
|
||||
|
@ -133,13 +133,16 @@ export default {
|
|||
this.$store.commit('setTestReviewSelectNode', node);
|
||||
this.$store.commit('setTestReviewSelectNodeIds', nodeIds);
|
||||
},
|
||||
getNodeTreeByReviewId() {
|
||||
getNodeTreeByReviewId(condition) {
|
||||
if (this.reviewId) {
|
||||
this.result = this.$get("/case/node/list/review/" + this.reviewId, response => {
|
||||
this.treeNodes = response.data;
|
||||
this.result = getTestReviewCaseNodesByCaseFilter(this.reviewId, condition, (data) => {
|
||||
this.treeNodes = data;
|
||||
});
|
||||
}
|
||||
},
|
||||
refreshTreeByCaseFilter() {
|
||||
this.getNodeTreeByReviewId(this.condition);
|
||||
},
|
||||
openTestReviewRelevanceDialog() {
|
||||
this.$refs.testReviewRelevance.openTestReviewRelevanceDialog();
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="card-container">
|
||||
<ms-table-header :tester-permission="true" :condition.sync="condition" @search="initTableData"
|
||||
<ms-table-header :tester-permission="true" :condition.sync="condition" @search="search"
|
||||
:show-create="false" :tip="$t('commons.search_by_name_or_id')">
|
||||
<template v-slot:button>
|
||||
<ms-table-button v-permission="['PROJECT_TRACK_REVIEW:READ+REVIEW']" icon="el-icon-video-play"
|
||||
|
@ -33,7 +33,8 @@
|
|||
:enable-order-drag="enableOrderDrag"
|
||||
:row-order-func="editTestReviewTestCaseOrder"
|
||||
:row-order-group-id="reviewId"
|
||||
@refresh="initTableData"
|
||||
@order="initTableData"
|
||||
@filter="search"
|
||||
ref="table"
|
||||
>
|
||||
<span v-for="item in fields" :key="item.key">
|
||||
|
@ -136,7 +137,7 @@
|
|||
|
||||
</ms-table>
|
||||
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
<ms-table-pagination :change="initTableData" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
|
||||
<test-review-test-case-edit
|
||||
|
@ -152,7 +153,7 @@
|
|||
@nextPage="nextPage"
|
||||
@prePage="prePage"
|
||||
@refresh="initTableData"
|
||||
@refreshTable="search"/>
|
||||
@refreshTable="initTableData"/>
|
||||
|
||||
|
||||
<batch-edit ref="batchEdit" @batchEdit="batchEdit"
|
||||
|
@ -308,7 +309,7 @@ export default {
|
|||
this.refreshTableAndReview();
|
||||
},
|
||||
selectNodeIds() {
|
||||
this.search();
|
||||
this.initTableData();
|
||||
},
|
||||
condition() {
|
||||
this.$emit('setCondition', this.condition);
|
||||
|
@ -431,10 +432,10 @@ export default {
|
|||
let param = {};
|
||||
param.id = this.reviewId;
|
||||
param.updateTime = Date.now();
|
||||
// this.$post('/test/case/review/edit', param);
|
||||
},
|
||||
search() {
|
||||
this.initTableData();
|
||||
this.$emit('search');
|
||||
},
|
||||
buildPagePath(path) {
|
||||
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||
|
|
|
@ -84,8 +84,20 @@ export function editTestReviewTestCaseOrder(request, callback) {
|
|||
return basePost('/test/review/case/edit/order', request, callback);
|
||||
}
|
||||
|
||||
export function getTestCaseNodes(projectId, callback) {
|
||||
return baseGet('/case/node/list/' + projectId, callback);
|
||||
export function getTestCaseNodesByCaseFilter(projectId, param, callback) {
|
||||
return basePost('/case/node/list/' + projectId, param, callback);
|
||||
}
|
||||
|
||||
export function getTestPlanCaseNodesByCaseFilter(planId, param, callback) {
|
||||
return basePost('/case/node/list/plan/' + planId, param, callback);
|
||||
}
|
||||
|
||||
export function getTestReviewCaseNodesByCaseFilter(reviewId, param, callback) {
|
||||
return basePost('/case/node/list/review/' + reviewId, param, callback);
|
||||
}
|
||||
|
||||
export function getTestCasePublicNodes(param, callback) {
|
||||
return basePost('/test/case/public/case/node', param, callback);
|
||||
}
|
||||
|
||||
export function getRelationshipCase(id, relationshipType, callback) {
|
||||
|
|
Loading…
Reference in New Issue