feat: 测试用例关系图初版

This commit is contained in:
chenjianxing 2021-10-14 21:35:48 +08:00 committed by jianxing
parent a24b001f24
commit 4327b776e2
24 changed files with 383 additions and 211 deletions

View File

@ -2,16 +2,14 @@ package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
public class RelationshipEdge implements Serializable {
private String sourceId;
private String targetId;
private String relationshipType;
private String resourceType;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RelationshipEdge extends RelationshipEdgeKey implements Serializable {
private String type;
private String graphId;
@ -20,4 +18,4 @@ public class RelationshipEdge implements Serializable {
private Long createTime;
private static final long serialVersionUID = 1L;
}
}

View File

@ -244,143 +244,73 @@ public class RelationshipEdgeExample {
return (Criteria) this;
}
public Criteria andRelationshipTypeIsNull() {
addCriterion("relationship_type is null");
public Criteria andTypeIsNull() {
addCriterion("`type` is null");
return (Criteria) this;
}
public Criteria andRelationshipTypeIsNotNull() {
addCriterion("relationship_type is not null");
public Criteria andTypeIsNotNull() {
addCriterion("`type` is not null");
return (Criteria) this;
}
public Criteria andRelationshipTypeEqualTo(String value) {
addCriterion("relationship_type =", value, "relationshipType");
public Criteria andTypeEqualTo(String value) {
addCriterion("`type` =", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeNotEqualTo(String value) {
addCriterion("relationship_type <>", value, "relationshipType");
public Criteria andTypeNotEqualTo(String value) {
addCriterion("`type` <>", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeGreaterThan(String value) {
addCriterion("relationship_type >", value, "relationshipType");
public Criteria andTypeGreaterThan(String value) {
addCriterion("`type` >", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeGreaterThanOrEqualTo(String value) {
addCriterion("relationship_type >=", value, "relationshipType");
public Criteria andTypeGreaterThanOrEqualTo(String value) {
addCriterion("`type` >=", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeLessThan(String value) {
addCriterion("relationship_type <", value, "relationshipType");
public Criteria andTypeLessThan(String value) {
addCriterion("`type` <", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeLessThanOrEqualTo(String value) {
addCriterion("relationship_type <=", value, "relationshipType");
public Criteria andTypeLessThanOrEqualTo(String value) {
addCriterion("`type` <=", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeLike(String value) {
addCriterion("relationship_type like", value, "relationshipType");
public Criteria andTypeLike(String value) {
addCriterion("`type` like", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeNotLike(String value) {
addCriterion("relationship_type not like", value, "relationshipType");
public Criteria andTypeNotLike(String value) {
addCriterion("`type` not like", value, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeIn(List<String> values) {
addCriterion("relationship_type in", values, "relationshipType");
public Criteria andTypeIn(List<String> values) {
addCriterion("`type` in", values, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeNotIn(List<String> values) {
addCriterion("relationship_type not in", values, "relationshipType");
public Criteria andTypeNotIn(List<String> values) {
addCriterion("`type` not in", values, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeBetween(String value1, String value2) {
addCriterion("relationship_type between", value1, value2, "relationshipType");
public Criteria andTypeBetween(String value1, String value2) {
addCriterion("`type` between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andRelationshipTypeNotBetween(String value1, String value2) {
addCriterion("relationship_type not between", value1, value2, "relationshipType");
return (Criteria) this;
}
public Criteria andResourceTypeIsNull() {
addCriterion("resource_type is null");
return (Criteria) this;
}
public Criteria andResourceTypeIsNotNull() {
addCriterion("resource_type is not null");
return (Criteria) this;
}
public Criteria andResourceTypeEqualTo(String value) {
addCriterion("resource_type =", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeNotEqualTo(String value) {
addCriterion("resource_type <>", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeGreaterThan(String value) {
addCriterion("resource_type >", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeGreaterThanOrEqualTo(String value) {
addCriterion("resource_type >=", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeLessThan(String value) {
addCriterion("resource_type <", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeLessThanOrEqualTo(String value) {
addCriterion("resource_type <=", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeLike(String value) {
addCriterion("resource_type like", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeNotLike(String value) {
addCriterion("resource_type not like", value, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeIn(List<String> values) {
addCriterion("resource_type in", values, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeNotIn(List<String> values) {
addCriterion("resource_type not in", values, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeBetween(String value1, String value2) {
addCriterion("resource_type between", value1, value2, "resourceType");
return (Criteria) this;
}
public Criteria andResourceTypeNotBetween(String value1, String value2) {
addCriterion("resource_type not between", value1, value2, "resourceType");
public Criteria andTypeNotBetween(String value1, String value2) {
addCriterion("`type` not between", value1, value2, "type");
return (Criteria) this;
}
@ -677,4 +607,4 @@ public class RelationshipEdgeExample {
this(condition, value, secondValue, null);
}
}
}
}

View File

@ -0,0 +1,13 @@
package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
@Data
public class RelationshipEdgeKey implements Serializable {
private String sourceId;
private String targetId;
private static final long serialVersionUID = 1L;
}

View File

@ -2,6 +2,7 @@ package io.metersphere.base.mapper;
import io.metersphere.base.domain.RelationshipEdge;
import io.metersphere.base.domain.RelationshipEdgeExample;
import io.metersphere.base.domain.RelationshipEdgeKey;
import java.util.List;
import org.apache.ibatis.annotations.Param;
@ -10,13 +11,21 @@ public interface RelationshipEdgeMapper {
int deleteByExample(RelationshipEdgeExample example);
int deleteByPrimaryKey(RelationshipEdgeKey key);
int insert(RelationshipEdge record);
int insertSelective(RelationshipEdge record);
List<RelationshipEdge> selectByExample(RelationshipEdgeExample example);
RelationshipEdge selectByPrimaryKey(RelationshipEdgeKey key);
int updateByExampleSelective(@Param("record") RelationshipEdge record, @Param("example") RelationshipEdgeExample example);
int updateByExample(@Param("record") RelationshipEdge record, @Param("example") RelationshipEdgeExample example);
}
int updateByPrimaryKeySelective(RelationshipEdge record);
int updateByPrimaryKey(RelationshipEdge record);
}

View File

@ -2,10 +2,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.RelationshipEdgeMapper">
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.RelationshipEdge">
<result column="source_id" jdbcType="VARCHAR" property="sourceId" />
<result column="target_id" jdbcType="VARCHAR" property="targetId" />
<result column="relationship_type" jdbcType="VARCHAR" property="relationshipType" />
<result column="resource_type" jdbcType="VARCHAR" property="resourceType" />
<id column="source_id" jdbcType="VARCHAR" property="sourceId" />
<id column="target_id" jdbcType="VARCHAR" property="targetId" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="graph_id" jdbcType="VARCHAR" property="graphId" />
<result column="creator" jdbcType="VARCHAR" property="creator" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
@ -69,7 +68,7 @@
</where>
</sql>
<sql id="Base_Column_List">
source_id, target_id, relationship_type, resource_type, graph_id, creator, create_time
source_id, target_id, `type`, graph_id, creator, create_time
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.RelationshipEdgeExample" resultMap="BaseResultMap">
select
@ -85,6 +84,18 @@
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="io.metersphere.base.domain.RelationshipEdgeKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from relationship_edge
where source_id = #{sourceId,jdbcType=VARCHAR}
and target_id = #{targetId,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="io.metersphere.base.domain.RelationshipEdgeKey">
delete from relationship_edge
where source_id = #{sourceId,jdbcType=VARCHAR}
and target_id = #{targetId,jdbcType=VARCHAR}
</delete>
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.RelationshipEdgeExample">
delete from relationship_edge
<if test="_parameter != null">
@ -92,12 +103,12 @@
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.RelationshipEdge">
insert into relationship_edge (source_id, target_id, relationship_type,
resource_type, graph_id, creator,
create_time)
values (#{sourceId,jdbcType=VARCHAR}, #{targetId,jdbcType=VARCHAR}, #{relationshipType,jdbcType=VARCHAR},
#{resourceType,jdbcType=VARCHAR}, #{graphId,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT})
insert into relationship_edge (source_id, target_id, `type`,
graph_id, creator, create_time
)
values (#{sourceId,jdbcType=VARCHAR}, #{targetId,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
#{graphId,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.RelationshipEdge">
insert into relationship_edge
@ -108,11 +119,8 @@
<if test="targetId != null">
target_id,
</if>
<if test="relationshipType != null">
relationship_type,
</if>
<if test="resourceType != null">
resource_type,
<if test="type != null">
`type`,
</if>
<if test="graphId != null">
graph_id,
@ -131,11 +139,8 @@
<if test="targetId != null">
#{targetId,jdbcType=VARCHAR},
</if>
<if test="relationshipType != null">
#{relationshipType,jdbcType=VARCHAR},
</if>
<if test="resourceType != null">
#{resourceType,jdbcType=VARCHAR},
<if test="type != null">
#{type,jdbcType=VARCHAR},
</if>
<if test="graphId != null">
#{graphId,jdbcType=VARCHAR},
@ -163,11 +168,8 @@
<if test="record.targetId != null">
target_id = #{record.targetId,jdbcType=VARCHAR},
</if>
<if test="record.relationshipType != null">
relationship_type = #{record.relationshipType,jdbcType=VARCHAR},
</if>
<if test="record.resourceType != null">
resource_type = #{record.resourceType,jdbcType=VARCHAR},
<if test="record.type != null">
`type` = #{record.type,jdbcType=VARCHAR},
</if>
<if test="record.graphId != null">
graph_id = #{record.graphId,jdbcType=VARCHAR},
@ -187,8 +189,7 @@
update relationship_edge
set source_id = #{record.sourceId,jdbcType=VARCHAR},
target_id = #{record.targetId,jdbcType=VARCHAR},
relationship_type = #{record.relationshipType,jdbcType=VARCHAR},
resource_type = #{record.resourceType,jdbcType=VARCHAR},
`type` = #{record.type,jdbcType=VARCHAR},
graph_id = #{record.graphId,jdbcType=VARCHAR},
creator = #{record.creator,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT}
@ -196,4 +197,32 @@
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
</mapper>
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.RelationshipEdge">
update relationship_edge
<set>
<if test="type != null">
`type` = #{type,jdbcType=VARCHAR},
</if>
<if test="graphId != null">
graph_id = #{graphId,jdbcType=VARCHAR},
</if>
<if test="creator != null">
creator = #{creator,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
</set>
where source_id = #{sourceId,jdbcType=VARCHAR}
and target_id = #{targetId,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.RelationshipEdge">
update relationship_edge
set `type` = #{type,jdbcType=VARCHAR},
graph_id = #{graphId,jdbcType=VARCHAR},
creator = #{creator,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}
where source_id = #{sourceId,jdbcType=VARCHAR}
and target_id = #{targetId,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -3,6 +3,7 @@ package io.metersphere.base.mapper.ext;
import io.metersphere.base.domain.TestCase;
import io.metersphere.base.domain.TestCaseWithBLOBs;
import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.dto.RelationshipGraphData;
import io.metersphere.track.dto.TestCaseDTO;
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
@ -120,4 +121,6 @@ public interface ExtTestCaseMapper {
Long getPreOrder(@Param("projectId")String projectId, @Param("baseOrder") Long baseOrder);
List<TestCase> getTestCase(@Param("request") QueryTestCaseRequest request);
List<RelationshipGraphData.Node> getTestCaseForGraph(@Param("ids") Set<String> ids);
}

View File

@ -559,6 +559,15 @@
ORDER BY test_case.order DESC
</select>
<select id="getTestCaseForGraph" resultType="io.metersphere.dto.RelationshipGraphData$Node">
select id,num,custom_num,`name`
from test_case
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<update id="deleteToGc">
update test_case set original_status=status,
status = 'Trash',

View File

@ -19,7 +19,7 @@ public class RelationshipEdgeController {
relationshipEdgeService.saveBatch(request);
}
@GetMapping("/delete")
@GetMapping("/delete/{sourceId}/{targetId}")
public void delete(@PathVariable("sourceId") String sourceId, @PathVariable("targetId") String targetId) {
relationshipEdgeService.delete(sourceId, targetId);
}

View File

@ -9,5 +9,7 @@ import java.util.List;
@Getter
@Setter
public class RelationshipEdgeRequest extends RelationshipEdge {
private String id;
private List<String> targetIds;
private List<String> sourceIds;
}

View File

@ -0,0 +1,31 @@
package io.metersphere.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class RelationshipGraphData {
private List<Node> data;
private List<Edge> links;
@Getter
@Setter
public static class Node {
private String id;
private Integer index;
private String name;
private Integer x;
private Integer y;
}
@Getter
@Setter
public static class Edge {
private Integer source;
private Integer target;
}
}

View File

@ -6,7 +6,9 @@ import io.metersphere.base.domain.RelationshipEdgeExample;
import io.metersphere.base.mapper.RelationshipEdgeMapper;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.RelationshipEdgeRequest;
import io.metersphere.dto.RelationshipGraphData;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
@ -14,9 +16,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author jianxingChen
@ -31,7 +33,6 @@ public class RelationshipEdgeService {
@Resource
private SqlSessionFactory sqlSessionFactory;
public void delete(String sourceId, String targetId) {
RelationshipEdgeExample example = new RelationshipEdgeExample();
example.createCriteria()
@ -47,57 +48,80 @@ public class RelationshipEdgeService {
return relationshipEdgeMapper.selectByExample(example);
}
public List<RelationshipEdge> getBySourceIdAndRelationType(String sourceId, String relationType) {
public List<RelationshipEdge> getByTargetId(String targetId) {
RelationshipEdgeExample example = new RelationshipEdgeExample();
example.createCriteria()
.andSourceIdEqualTo(sourceId)
.andRelationshipTypeEqualTo(relationType);
.andTargetIdEqualTo(targetId);
return relationshipEdgeMapper.selectByExample(example);
}
public void saveBatch(RelationshipEdgeRequest request) {
if (CollectionUtils.isEmpty(request.getTargetIds())) {
return;
}
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
RelationshipEdgeMapper batchMapper = sqlSession.getMapper(RelationshipEdgeMapper.class);
String graphId = UUID.randomUUID().toString();
// 判断这些顶点是否已经和其他顶点连通
// 连通的话加到同一个图中否则新建一个图 graphId
List<String> graphNodes = new ArrayList<>();
graphNodes.add(request.getSourceId());
graphNodes.addAll(request.getTargetIds());
RelationshipEdgeExample example = new RelationshipEdgeExample();
example.createCriteria()
.andSourceIdIn(graphNodes)
.andRelationshipTypeEqualTo(request.getRelationshipType());
example.or(
example.createCriteria()
.andTargetIdIn(graphNodes)
.andRelationshipTypeEqualTo(request.getRelationshipType())
);
List<RelationshipEdge> relationshipEdges = relationshipEdgeMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(relationshipEdges)) {
graphId = relationshipEdges.get(0).getGraphId();
}
String graphId = getGraphId(request);
// todo 检验是否有环
for (String targetId : request.getTargetIds()) {
RelationshipEdge edge = new RelationshipEdge();
edge.setSourceId(request.getSourceId());
edge.setTargetId(targetId);
edge.setGraphId(graphId);
edge.setRelationshipType(request.getRelationshipType());
edge.setResourceType(request.getResourceType());
edge.setCreator(SessionUtils.getUserId());
edge.setCreateTime(System.currentTimeMillis());
batchMapper.insert(edge);
if (CollectionUtils.isNotEmpty(request.getTargetIds())) {
for (String targetId : request.getTargetIds()) {
RelationshipEdge edge = getNewRelationshipEdge(graphId, request.getId(), targetId, request.getType());
batchMapper.insert(edge);
}
}
if (CollectionUtils.isNotEmpty(request.getSourceIds())) {
for (String sourceId : request.getSourceIds()) {
RelationshipEdge edge = getNewRelationshipEdge(graphId, sourceId, request.getId(), request.getType());
batchMapper.insert(edge);
}
}
sqlSession.flushStatements();
}
private RelationshipEdge getNewRelationshipEdge(String graphId, String sourceId, String targetId, String type) {
RelationshipEdge edge = new RelationshipEdge();
edge.setCreator(SessionUtils.getUserId());
edge.setGraphId(graphId);
edge.setCreateTime(System.currentTimeMillis());
edge.setSourceId(sourceId);
edge.setTargetId(targetId);
edge.setType(type);
return edge;
}
/**
* 获取当前节点所在的图的id
* @param request
* @return
*/
private String getGraphId(RelationshipEdgeRequest request) {
// 判断这些顶点是否已经和其他顶点连通
// 连通的话加到同一个图中否则新建一个图 graphId
String graphId = UUID.randomUUID().toString();
List<String> graphNodes = new ArrayList<>();
graphNodes.add(request.getId());
if (request.getTargetIds() != null) {
graphNodes.addAll(request.getTargetIds());
}
if (request.getSourceIds() != null) {
graphNodes.addAll(request.getSourceIds());
}
RelationshipEdgeExample example = new RelationshipEdgeExample();
example.createCriteria()
.andSourceIdIn(graphNodes);
example.or(
example.createCriteria()
.andTargetIdIn(graphNodes)
);
List<RelationshipEdge> relationshipEdges = relationshipEdgeMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(relationshipEdges)) {
return relationshipEdges.get(0).getGraphId();
}
return graphId;
}
}

View File

@ -20,6 +20,7 @@ import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ResetOrderRequest;
import io.metersphere.dto.LoadTestDTO;
import io.metersphere.dto.RelationshipEdgeDTO;
import io.metersphere.dto.RelationshipGraphData;
import io.metersphere.dto.TestCaseTestDao;
import io.metersphere.excel.domain.ExcelResponse;
import io.metersphere.log.annotation.MsAuditLog;
@ -343,6 +344,4 @@ public class TestCaseController {
public void minderEdit(@RequestBody TestCaseMinderEditRequest request) {
testCaseService.minderEdit(request);
}
}

View File

@ -1948,29 +1948,45 @@ public class TestCaseService {
public List<TestCase> getRelationshipRelateList(QueryTestCaseRequest request) {
setDefaultOrder(request);
List<RelationshipEdge> relationshipEdges = relationshipEdgeService.getBySourceId(request.getId());
List<String> ids = relationshipEdges.stream().map(RelationshipEdge::getTargetId).collect(Collectors.toList());
List<RelationshipEdge> sourceRelationshipEdges = relationshipEdgeService.getBySourceId(request.getId());
List<RelationshipEdge> targetRelationshipEdges = relationshipEdgeService.getByTargetId(request.getId());
List<String> ids = sourceRelationshipEdges.stream().map(RelationshipEdge::getTargetId).collect(Collectors.toList());
ids.addAll(targetRelationshipEdges.stream().map(RelationshipEdge::getTargetId).collect(Collectors.toList()));
ids.add(request.getId());
request.setTestCaseContainIds(ids);
return extTestCaseMapper.getTestCase(request);
// return extTestCaseMapper.getTestCaseByNotInPlan(request);
}
public List<RelationshipEdgeDTO> getRelationshipCase(String id, String relationshipType) {
List<RelationshipEdge> relationshipEdges = relationshipEdgeService.getBySourceIdAndRelationType(id, relationshipType);
List<String> targetIds = relationshipEdges.stream()
.map(RelationshipEdge::getTargetId)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(targetIds)) {
List<RelationshipEdge> relationshipEdges;
List<String> ids;
if (StringUtils.equals(relationshipType, "PRE")) {
relationshipEdges = relationshipEdgeService.getBySourceId(id);
ids = relationshipEdges.stream()
.map(RelationshipEdge::getTargetId)
.collect(Collectors.toList());
} else {
relationshipEdges = relationshipEdgeService.getByTargetId(id);
ids = relationshipEdges.stream()
.map(RelationshipEdge::getSourceId)
.collect(Collectors.toList());
}
if (CollectionUtils.isNotEmpty(ids)) {
TestCaseExample example = new TestCaseExample();
example.createCriteria().andIdIn(targetIds);
example.createCriteria().andIdIn(ids);
List<TestCase> testCaseList = testCaseMapper.selectByExample(example);
Map<String, TestCase> caseMap = testCaseList.stream().collect(Collectors.toMap(TestCase::getId, i -> i));
List<RelationshipEdgeDTO> results = new ArrayList<>();
for (RelationshipEdge relationshipEdge : relationshipEdges) {
RelationshipEdgeDTO relationshipEdgeDTO = new RelationshipEdgeDTO();
BeanUtils.copyBean(relationshipEdgeDTO, relationshipEdge);
TestCase testCase = caseMap.get(relationshipEdge.getTargetId());
TestCase testCase;
if (StringUtils.equals(relationshipType, "PRE")) {
testCase = caseMap.get(relationshipEdge.getTargetId());
} else {
testCase = caseMap.get(relationshipEdge.getSourceId());
}
relationshipEdgeDTO.setTargetName(testCase.getName());
relationshipEdgeDTO.setCreator(testCase.getCreateUser());
relationshipEdgeDTO.setTargetNum(testCase.getNum());

@ -1 +1 @@
Subproject commit 5c3d89b449159ebad7f2c9ad36285d75f98b12c6
Subproject commit 141ffff54df6e30dde805d7dc2c872a352ad525e

View File

@ -41,13 +41,12 @@ DROP PROCEDURE IF EXISTS test_cursor;
create table if not exists relationship_edge (
source_id varchar(50) not null comment '源节点的ID',
target_id varchar(50) not null comment '目标节点的ID',
relationship_type varchar(20) not null comment '关系的类型,前置后置或者依赖',
resource_type varchar(20) not null comment '是表示什么资源',
`type` varchar(20) not null comment '边的分类',
graph_id varchar(50) not null comment '所属关系图的ID',
creator varchar(50) not null comment '创建人',
create_time bigint(13) not null,
PRIMARY KEY (source_id, target_id)
)
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE utf8mb4_general_ci;

View File

@ -1,5 +1,6 @@
<template>
<chart
class="ms-chart"
:init-options="defaultInitOptions"
:options="options"
:theme="theme"

View File

@ -0,0 +1,57 @@
<template>
<div class="ms-header">
<el-row type="flex" class="head-bar">
<el-col :span="12">
<div class="name-edit">
<el-button plain size="mini" icon="el-icon-back" @click="close">{{$t('test_track.return')}}
</el-button>
<span class="title">{{title}}</span>
</div>
</el-col>
<el-col :span="12" class="head-right">
<el-button v-for="button in buttons" :disabled="button.disabled" :key="button.name" plain size="mini" @click="button.exec">
{{ button.name }}
</el-button>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: "DrawerHeader",
components: {},
data() {
return {}
},
props:{
title: String,
buttons: []
},
methods: {
close() {
this.$emit('close');
},
},
}
</script>
<style scoped>
.head-bar {
background: white;
height: 45px;
line-height: 45px;
padding: 0 10px;
border: 1px solid #EBEEF5;
box-shadow: 0 0 2px 0 rgba(31, 31, 31, 0.15), 0 1px 2px 0 rgba(31, 31, 31, 0.15);
}
.head-right {
text-align: right;
}
.title {
margin-left: 10px;
}
</style>

View File

@ -48,10 +48,13 @@ export default {
}
},
saveCaseRelevance(param, vueObj) {
param.sourceId = this.caseId;
param.relationshipType = this.relationshipType;
param.resourceType = 'TEST_CASE';
param.targetIds = param.ids;
if (this.relationshipType === 'PRE') {
param.targetIds = param.ids;
} else {
param.sourceIds = param.ids;
}
param.id = this.caseId;
param.type = 'TEST_CASE';
vueObj.result = this.$post('/relationship/edge/save/batch', param, () => {
vueObj.isSaving = false;

View File

@ -0,0 +1,49 @@
<template>
<div class="dependencies-container">
<el-main>
<i class="el-icon-view" @click="openGraph"></i>
</el-main>
<test-case-relationship-list :title="'前置对象'" relationship-type="PRE" :case-id="caseId" ref="preRelationshipList"/>
<test-case-relationship-list :title="'后置对象'" relationship-type="POST" :case-id="caseId" ref="postRelationshipList"/>
<relationship-graph-drawer :graph-data="graphData" ref="relationshipGraph"/>
</div>
</template>
<script>
import TestCaseRelationshipList from "@/business/components/track/case/components/TestCaseRelationshipList";
import RelationshipGraphDrawer from "@/business/components/xpack/graph/RelationshipGraphDrawer";
import {getRelationshipGraph} from "@/network/testCase";
export default {
name: "TestCaseDependencies",
components: {RelationshipGraphDrawer, TestCaseRelationshipList},
props: [
'caseId'
],
data() {
return {
graphData: {}
}
},
methods: {
open() {
this.$refs.preRelationshipList.getTableData();
this.$refs.postRelationshipList.getTableData();
},
openGraph() {
getRelationshipGraph(this.caseId, 'TEST_CASE', (data) => {
this.graphData = data;
this.$refs.relationshipGraph.open();
});
}
}
}
</script>
<style scoped>
.dependencies-container .el-main:nth-child(3) {
margin-top: 20px;
}
</style>

View File

@ -40,8 +40,7 @@
</el-tab-pane>
<el-tab-pane :label="$t('依赖关系')" name="relationship">
<test-case-relationship-list :title="'前置对象'" relationship-type="PRE" :case-id="caseId" ref="preRelationshipList"/>
<test-case-relationship-list :title="'后置对象'" relationship-type="POST" :case-id="caseId" ref="postRelationshipList"/>
<test-case-dependencies :case-id="caseId" ref="relationship"/>
</el-tab-pane>
<el-tab-pane :label="$t('test_track.case.attachment')" name="attachment">
@ -83,12 +82,12 @@ import TestCaseAttachment from "@/business/components/track/case/components/Test
import TestCaseIssueRelate from "@/business/components/track/case/components/TestCaseIssueRelate";
import FormRichTextItem from "@/business/components/track/case/components/FormRichTextItem";
import TestCaseTestRelate from "@/business/components/track/case/components/TestCaseTestRelate";
import TestCaseRelationshipList from "@/business/components/track/case/components/TestCaseRelationshipList";
import TestCaseDependencies from "@/business/components/track/case/components/TestCaseDependencies";
export default {
name: "TestCaseEditOtherInfo",
components: {
TestCaseRelationshipList,
TestCaseDependencies,
TestCaseTestRelate,
FormRichTextItem, TestCaseIssueRelate, TestCaseAttachment, MsRichText, TestCaseRichText},
props: ['form', 'labelWidth', 'caseId', 'readOnly', 'projectId', 'isTestPlan', 'planId'],
@ -120,8 +119,7 @@ export default {
} else if (this.tabActiveName === 'bug') {
this.$refs.issue.getIssues();
} else if (this.tabActiveName === 'relationship') {
this.$refs.preRelationshipList.getTableData();
this.$refs.postRelationshipList.getTableData();
this.$refs.relationship.open();
} else if (this.tabActiveName === 'attachment') {
this.getFileMetaData();
}

View File

@ -4,7 +4,7 @@
<el-button class="add-btn"
:disabled="readOnly" type="primary" size="mini" @click="openRelevance">{{ $t('添加') }}</el-button>
<ms-table
<ms-table
v-loading="result.loading"
:show-select-all="false"
:data="data"
@ -44,6 +44,7 @@
@refresh="getTableData"
:relationship-type="relationshipType"
ref="testCaseRelevance"/>
</el-main>
</template>
@ -105,7 +106,7 @@ export default {
this.getTableData();
this.$success(this.$t('commons.delete_success'));
});
}
},
}
}
</script>
@ -114,8 +115,4 @@ export default {
.add-btn {
margin-left: 20px;
}
.el-main:nth-child(2) {
margin-top: 20px;
}
</style>

@ -1 +1 @@
Subproject commit 68e291c7626aa1250303104f6c39d9646a1339e5
Subproject commit aa48b0520ab5ff6d269b284d7b96494b53c6bc4f

View File

@ -2,6 +2,7 @@ import ECharts from 'vue-echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/pie'
import 'echarts/lib/chart/graph'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/title'
import 'echarts/lib/component/toolbox';

View File

@ -71,3 +71,7 @@ export function getRelationshipCase(id, relationshipType, callback) {
return baseGet('/test/case/relationship/case/' + id + '/' + relationshipType, callback);
}
export function getRelationshipGraph(id, type, callback) {
return baseGet('/graph/relationship/graph/' + id + '/' + type, callback);
}