模块树相关操作
This commit is contained in:
parent
d31382ec2a
commit
536d16991f
|
@ -9,9 +9,9 @@ public class TestCaseNode implements Serializable {
|
|||
|
||||
private String name;
|
||||
|
||||
private String pId;
|
||||
private Integer pId;
|
||||
|
||||
private Long order;
|
||||
private Integer level;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
|
@ -43,20 +43,20 @@ public class TestCaseNode implements Serializable {
|
|||
this.name = name == null ? null : name.trim();
|
||||
}
|
||||
|
||||
public String getpId() {
|
||||
public Integer getpId() {
|
||||
return pId;
|
||||
}
|
||||
|
||||
public void setpId(String pId) {
|
||||
this.pId = pId == null ? null : pId.trim();
|
||||
public void setpId(Integer pId) {
|
||||
this.pId = pId;
|
||||
}
|
||||
|
||||
public Long getOrder() {
|
||||
return order;
|
||||
public Integer getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setOrder(Long order) {
|
||||
this.order = order;
|
||||
public void setLevel(Integer level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public Long getCreateTime() {
|
||||
|
|
|
@ -314,123 +314,113 @@ public class TestCaseNodeExample {
|
|||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdEqualTo(String value) {
|
||||
public Criteria andPIdEqualTo(Integer value) {
|
||||
addCriterion("p_id =", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdNotEqualTo(String value) {
|
||||
public Criteria andPIdNotEqualTo(Integer value) {
|
||||
addCriterion("p_id <>", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdGreaterThan(String value) {
|
||||
public Criteria andPIdGreaterThan(Integer value) {
|
||||
addCriterion("p_id >", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdGreaterThanOrEqualTo(String value) {
|
||||
public Criteria andPIdGreaterThanOrEqualTo(Integer value) {
|
||||
addCriterion("p_id >=", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdLessThan(String value) {
|
||||
public Criteria andPIdLessThan(Integer value) {
|
||||
addCriterion("p_id <", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdLessThanOrEqualTo(String value) {
|
||||
public Criteria andPIdLessThanOrEqualTo(Integer value) {
|
||||
addCriterion("p_id <=", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdLike(String value) {
|
||||
addCriterion("p_id like", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdNotLike(String value) {
|
||||
addCriterion("p_id not like", value, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdIn(List<String> values) {
|
||||
public Criteria andPIdIn(List<Integer> values) {
|
||||
addCriterion("p_id in", values, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdNotIn(List<String> values) {
|
||||
public Criteria andPIdNotIn(List<Integer> values) {
|
||||
addCriterion("p_id not in", values, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdBetween(String value1, String value2) {
|
||||
public Criteria andPIdBetween(Integer value1, Integer value2) {
|
||||
addCriterion("p_id between", value1, value2, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andPIdNotBetween(String value1, String value2) {
|
||||
public Criteria andPIdNotBetween(Integer value1, Integer value2) {
|
||||
addCriterion("p_id not between", value1, value2, "pId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderIsNull() {
|
||||
addCriterion("order is null");
|
||||
public Criteria andLevelIsNull() {
|
||||
addCriterion("level is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderIsNotNull() {
|
||||
addCriterion("order is not null");
|
||||
public Criteria andLevelIsNotNull() {
|
||||
addCriterion("level is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderEqualTo(Long value) {
|
||||
addCriterion("order =", value, "order");
|
||||
public Criteria andLevelEqualTo(Integer value) {
|
||||
addCriterion("level =", value, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderNotEqualTo(Long value) {
|
||||
addCriterion("order <>", value, "order");
|
||||
public Criteria andLevelNotEqualTo(Integer value) {
|
||||
addCriterion("level <>", value, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderGreaterThan(Long value) {
|
||||
addCriterion("order >", value, "order");
|
||||
public Criteria andLevelGreaterThan(Integer value) {
|
||||
addCriterion("level >", value, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("order >=", value, "order");
|
||||
public Criteria andLevelGreaterThanOrEqualTo(Integer value) {
|
||||
addCriterion("level >=", value, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderLessThan(Long value) {
|
||||
addCriterion("order <", value, "order");
|
||||
public Criteria andLevelLessThan(Integer value) {
|
||||
addCriterion("level <", value, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderLessThanOrEqualTo(Long value) {
|
||||
addCriterion("order <=", value, "order");
|
||||
public Criteria andLevelLessThanOrEqualTo(Integer value) {
|
||||
addCriterion("level <=", value, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderIn(List<Long> values) {
|
||||
addCriterion("order in", values, "order");
|
||||
public Criteria andLevelIn(List<Integer> values) {
|
||||
addCriterion("level in", values, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderNotIn(List<Long> values) {
|
||||
addCriterion("order not in", values, "order");
|
||||
public Criteria andLevelNotIn(List<Integer> values) {
|
||||
addCriterion("level not in", values, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderBetween(Long value1, Long value2) {
|
||||
addCriterion("order between", value1, value2, "order");
|
||||
public Criteria andLevelBetween(Integer value1, Integer value2) {
|
||||
addCriterion("level between", value1, value2, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andOrderNotBetween(Long value1, Long value2) {
|
||||
addCriterion("order not between", value1, value2, "order");
|
||||
public Criteria andLevelNotBetween(Integer value1, Integer value2) {
|
||||
addCriterion("level not between", value1, value2, "level");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<id column="id" jdbcType="INTEGER" property="id" />
|
||||
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="p_id" jdbcType="VARCHAR" property="pId" />
|
||||
<result column="order" jdbcType="BIGINT" property="order" />
|
||||
<result column="p_id" jdbcType="INTEGER" property="pId" />
|
||||
<result column="level" jdbcType="INTEGER" property="level" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
</resultMap>
|
||||
|
@ -69,7 +69,7 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, project_id, name, p_id, order, create_time, update_time
|
||||
id, project_id, name, p_id, level, create_time, update_time
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseNodeExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -102,19 +102,22 @@
|
|||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseNode">
|
||||
insert into test_case_node (id, project_id, name,
|
||||
p_id, order, create_time,
|
||||
update_time)
|
||||
values (#{id,jdbcType=INTEGER}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
||||
#{pId,jdbcType=VARCHAR}, #{order,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT},
|
||||
#{updateTime,jdbcType=BIGINT})
|
||||
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
|
||||
SELECT LAST_INSERT_ID()
|
||||
</selectKey>
|
||||
insert into test_case_node (project_id, name, p_id,
|
||||
level, create_time, update_time
|
||||
)
|
||||
values (#{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{pId,jdbcType=INTEGER},
|
||||
#{level,jdbcType=INTEGER}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}
|
||||
)
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseNode">
|
||||
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
|
||||
SELECT LAST_INSERT_ID()
|
||||
</selectKey>
|
||||
insert into test_case_node
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
id,
|
||||
</if>
|
||||
<if test="projectId != null">
|
||||
project_id,
|
||||
</if>
|
||||
|
@ -124,8 +127,8 @@
|
|||
<if test="pId != null">
|
||||
p_id,
|
||||
</if>
|
||||
<if test="order != null">
|
||||
order,
|
||||
<if test="level != null">
|
||||
level,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
|
@ -135,9 +138,6 @@
|
|||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
#{id,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="projectId != null">
|
||||
#{projectId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
|
@ -145,10 +145,10 @@
|
|||
#{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="pId != null">
|
||||
#{pId,jdbcType=VARCHAR},
|
||||
#{pId,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="order != null">
|
||||
#{order,jdbcType=BIGINT},
|
||||
<if test="level != null">
|
||||
#{level,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
|
@ -177,10 +177,10 @@
|
|||
name = #{record.name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.pId != null">
|
||||
p_id = #{record.pId,jdbcType=VARCHAR},
|
||||
p_id = #{record.pId,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.order != null">
|
||||
order = #{record.order,jdbcType=BIGINT},
|
||||
<if test="record.level != null">
|
||||
level = #{record.level,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
|
@ -198,8 +198,8 @@
|
|||
set id = #{record.id,jdbcType=INTEGER},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
p_id = #{record.pId,jdbcType=VARCHAR},
|
||||
order = #{record.order,jdbcType=BIGINT},
|
||||
p_id = #{record.pId,jdbcType=INTEGER},
|
||||
level = #{record.level,jdbcType=INTEGER},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT}
|
||||
<if test="_parameter != null">
|
||||
|
@ -216,10 +216,10 @@
|
|||
name = #{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="pId != null">
|
||||
p_id = #{pId,jdbcType=VARCHAR},
|
||||
p_id = #{pId,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="order != null">
|
||||
order = #{order,jdbcType=BIGINT},
|
||||
<if test="level != null">
|
||||
level = #{level,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
|
@ -234,8 +234,8 @@
|
|||
update test_case_node
|
||||
set project_id = #{projectId,jdbcType=VARCHAR},
|
||||
name = #{name,jdbcType=VARCHAR},
|
||||
p_id = #{pId,jdbcType=VARCHAR},
|
||||
order = #{order,jdbcType=BIGINT},
|
||||
p_id = #{pId,jdbcType=INTEGER},
|
||||
level = #{level,jdbcType=INTEGER},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT}
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package io.metersphere.controller;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import io.metersphere.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.service.TestCaseNodeService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
@RequestMapping("/case/node")
|
||||
@RestController
|
||||
public class TestCaseNodeController {
|
||||
|
||||
@Resource
|
||||
TestCaseNodeService testCaseNodeService;
|
||||
|
||||
@GetMapping("/list/{projectId}")
|
||||
public List<TestCaseNodeDTO> getNodeByProjectId(@PathVariable String projectId){
|
||||
return testCaseNodeService.getNodeByProjectId(projectId);
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
public int addNode(@RequestBody TestCaseNode node){
|
||||
return testCaseNodeService.addNode(node);
|
||||
}
|
||||
|
||||
@PostMapping("/edit")
|
||||
public int editNode(@RequestBody TestCaseNode node){
|
||||
return testCaseNodeService.editNode(node);
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{nodeId}")
|
||||
public int deleteNode(@PathVariable int nodeId){
|
||||
return testCaseNodeService.deleteNode(nodeId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TestCaseNodeDTO extends TestCaseNode {
|
||||
|
||||
private String label;
|
||||
private List<TestCaseNodeDTO> children;
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<TestCaseNodeDTO> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import io.metersphere.base.domain.TestCaseNodeExample;
|
||||
import io.metersphere.base.mapper.TestCaseNodeMapper;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.dto.TestCaseNodeDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestCaseNodeService {
|
||||
|
||||
@Resource
|
||||
TestCaseNodeMapper testCaseNodeMapper;
|
||||
|
||||
public int addNode(TestCaseNode node) {
|
||||
|
||||
if(node.getLevel() > 5){
|
||||
throw new RuntimeException("模块树最大深度为5层!");
|
||||
}
|
||||
node.setCreateTime(System.currentTimeMillis());
|
||||
node.setUpdateTime(System.currentTimeMillis());
|
||||
testCaseNodeMapper.insertSelective(node);
|
||||
return node.getId();
|
||||
}
|
||||
|
||||
public List<TestCaseNodeDTO> getNodeByProjectId(String projectId) {
|
||||
|
||||
List<TestCaseNodeDTO> nodeTreeList = new ArrayList<>();
|
||||
|
||||
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
|
||||
testCaseNodeExample.createCriteria().andProjectIdEqualTo(projectId);
|
||||
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
|
||||
|
||||
Map<Integer, List<TestCaseNode>> nodeLevelMap = new HashMap<>();
|
||||
|
||||
nodes.forEach(node -> {
|
||||
Integer level = node.getLevel();
|
||||
if( nodeLevelMap.containsKey(level) ){
|
||||
nodeLevelMap.get(level).add(node);
|
||||
} else {
|
||||
List<TestCaseNode> testCaseNodes = new ArrayList<>();
|
||||
testCaseNodes.add(node);
|
||||
nodeLevelMap.put(node.getLevel(), testCaseNodes);
|
||||
}
|
||||
});
|
||||
|
||||
List<TestCaseNode> rootNodes = Optional.ofNullable(nodeLevelMap.get(1)).orElse(new ArrayList<>());
|
||||
rootNodes.forEach(rootNode -> nodeTreeList.add(buildNodeTree(nodeLevelMap, rootNode)));
|
||||
return nodeTreeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归构建节点树
|
||||
* @param nodeLevelMap
|
||||
* @param rootNode
|
||||
* @return
|
||||
*/
|
||||
private TestCaseNodeDTO buildNodeTree(Map<Integer,List<TestCaseNode>> nodeLevelMap, TestCaseNode rootNode) {
|
||||
|
||||
TestCaseNodeDTO nodeTree = new TestCaseNodeDTO();
|
||||
BeanUtils.copyBean(nodeTree, rootNode);
|
||||
nodeTree.setLabel(rootNode.getName());
|
||||
|
||||
List<TestCaseNode> testCaseNodes = nodeLevelMap.get(rootNode.getLevel() + 1);
|
||||
if(testCaseNodes == null){
|
||||
return nodeTree;
|
||||
}
|
||||
|
||||
List<TestCaseNodeDTO> childrens = Optional.ofNullable(nodeTree.getChildren()).orElse(new ArrayList<>());
|
||||
|
||||
testCaseNodes.forEach(node -> {
|
||||
if (node.getpId().equals(rootNode.getId())){
|
||||
childrens.add(buildNodeTree(nodeLevelMap, node));
|
||||
nodeTree.setChildren(childrens);
|
||||
}
|
||||
});
|
||||
|
||||
return nodeTree;
|
||||
}
|
||||
|
||||
public int editNode(TestCaseNode node) {
|
||||
node.setUpdateTime(System.currentTimeMillis());
|
||||
return testCaseNodeMapper.updateByPrimaryKeySelective(node);
|
||||
}
|
||||
|
||||
public int deleteNode(int nodeId) {
|
||||
return testCaseNodeMapper.deleteByPrimaryKey(nodeId);
|
||||
}
|
||||
}
|
|
@ -21,10 +21,11 @@ CREATE TABLE IF NOT EXISTS `test_case_node` (
|
|||
`id` int(13) PRIMARY KEY AUTO_INCREMENT COMMENT 'Test case node ID',
|
||||
`project_id` varchar(50) NOT NULL COMMENT 'Project ID this node belongs to',
|
||||
`name` varchar(64) NOT NULL COMMENT 'Node name',
|
||||
`p_id` varchar(50) NOT NULL COMMENT 'Parent node ID',
|
||||
`order` bigint(13) COMMENT 'Node order',
|
||||
`p_id` int(13) DEFAULT NULL COMMENT 'Parent node ID',
|
||||
`level` int(10) DEFAULT 1 COMMENT 'Node level',
|
||||
`create_time` bigint(13) NOT NULL COMMENT 'Create timestamp',
|
||||
`update_time` bigint(13) NOT NULL COMMENT 'Update timestamp',
|
||||
FOREIGN KEY (`p_id`) references test_case_node(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`project_id`) references project(`id`)
|
||||
)
|
||||
AUTO_INCREMENT = 1
|
||||
|
|
|
@ -46,10 +46,12 @@
|
|||
|
||||
<!--要生成的数据库表 -->
|
||||
|
||||
<table tableName="test_plan"/>
|
||||
<table tableName="test_case_node"/>
|
||||
<table tableName="test_case"/>
|
||||
<table tableName="test_plan_test_case"/>
|
||||
<!--<table tableName="test_plan"/>-->
|
||||
<table tableName="test_case_node">
|
||||
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
|
||||
</table>
|
||||
<!--<table tableName="test_case"/>-->
|
||||
<!--<table tableName="test_plan_test_case"/>-->
|
||||
|
||||
</context>
|
||||
</generatorConfiguration>
|
|
@ -0,0 +1,31 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class TestCaseTest {
|
||||
|
||||
|
||||
@Resource
|
||||
TestCaseNodeService testCaseNodeService;
|
||||
|
||||
@Test
|
||||
public void addNode() {
|
||||
|
||||
TestCaseNode node = new TestCaseNode();
|
||||
node.setName("node01");
|
||||
node.setProjectId("2ade216b-01a6-43d0-b48c-4a3898306096");
|
||||
node.setCreateTime(System.currentTimeMillis());
|
||||
node.setUpdateTime(System.currentTimeMillis());
|
||||
testCaseNodeService.addNode(node);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -52,16 +52,16 @@
|
|||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser && beaseUrl == 'track'"
|
||||
index="6" popper-class="submenu" v-permission="['test_manager', 'test_user']">
|
||||
<template slot="title">{{$t('test_track.test_track')}}</template>
|
||||
<template slot="title">{{$t('test_track.test_case')}}</template>
|
||||
<recent-case-plan/>
|
||||
<el-divider/>
|
||||
<el-menu-item :index="'/' + beaseUrl + '/case/all'">
|
||||
<font-awesome-icon :icon="['fa', 'list-ul']"/>
|
||||
<span style="padding-left: 5px;">{{$t('commons.show_all')}}</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item :index="'/' + beaseUrl + '/case/create'">
|
||||
<el-button type="text">{{$t('test_track.create_case')}}</el-button>
|
||||
<span style="padding-left: 5px;">{{$t('test_track.case_list')}}</span>
|
||||
</el-menu-item>
|
||||
<!--<el-menu-item :index="'/' + beaseUrl + '/case/create'">-->
|
||||
<!--<el-button type="text">{{$t('test_track.create_case')}}</el-button>-->
|
||||
<!--</el-menu-item>-->
|
||||
</el-submenu>
|
||||
|
||||
<el-submenu v-if="isCurrentWorkspaceUser && beaseUrl == 'track'"
|
||||
|
|
|
@ -1,14 +1,29 @@
|
|||
<template>
|
||||
<div class="case_container" v-loading="result.loading">
|
||||
|
||||
|
||||
<!--<div class="main-content">-->
|
||||
|
||||
<div class="case_container" v-loading="loadingRequire.project && loadingRequire.testCase">
|
||||
<el-container>
|
||||
<el-aside width="250px">
|
||||
<node-tree class="node_tree"></node-tree>
|
||||
|
||||
<el-menu :unique-opened="true" mode="horizontal" active-text-color="write"
|
||||
class="project_menu">
|
||||
<el-submenu index="1" popper-class="submenu" v-permission="['test_user', 'test_viewer']">
|
||||
<template slot="title">
|
||||
{{currentProject.name}}
|
||||
</template>
|
||||
<el-scrollbar style="height:500px">
|
||||
<label v-for="(item,index) in projects" :key="index">
|
||||
<el-menu-item @click="changeProject(item)">
|
||||
{{item.name}}
|
||||
<i class="el-icon-check" v-if="item.id === currentProject.id"></i>
|
||||
</el-menu-item>
|
||||
</label>
|
||||
</el-scrollbar>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
<node-tree class="node_tree" :project-id="currentProject.id"
|
||||
@nodeSelectEvent="getCaseByNodeIds"></node-tree>
|
||||
</el-aside>
|
||||
|
||||
|
||||
<el-main>
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
|
@ -82,10 +97,8 @@
|
|||
</div>
|
||||
</el-card>
|
||||
</el-main>
|
||||
|
||||
</el-container>
|
||||
|
||||
<!--</div>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -109,8 +122,11 @@
|
|||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
loading: false,
|
||||
loadingRequire: {project: true, testCase: true},
|
||||
testId: null,
|
||||
projects: [],
|
||||
initProjects: [],
|
||||
currentProject: null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -122,6 +138,7 @@
|
|||
created: function () {
|
||||
this.projectId = this.$route.params.projectId;
|
||||
this.initTableData();
|
||||
this.getProjects();
|
||||
},
|
||||
methods: {
|
||||
initTableData() {
|
||||
|
@ -134,11 +151,30 @@
|
|||
}
|
||||
|
||||
this.result = this.$post(this.buildPagePath(this.queryPath), param, response => {
|
||||
this.loadingRequire.testCase = false;
|
||||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
});
|
||||
},
|
||||
getProjects() {
|
||||
this.$get("/project/listAll", (response) => {
|
||||
if (response.success) {
|
||||
this.projects = response.data;
|
||||
this.initProjects = this.projects.slice(0, 4);
|
||||
this.currentProject = response.data[0];
|
||||
} else {
|
||||
this.$message()({
|
||||
type: 'warning',
|
||||
message: response.message
|
||||
});
|
||||
}
|
||||
this.loadingRequire.project = false;
|
||||
|
||||
this.checkProject();
|
||||
|
||||
});
|
||||
},
|
||||
search() {
|
||||
this.initTableData();
|
||||
},
|
||||
|
@ -184,6 +220,24 @@
|
|||
this.initTableData();
|
||||
});
|
||||
},
|
||||
checkProject() {
|
||||
if(this.currentProject === null) {
|
||||
this.$alert('该工作空间下无项目,请先创建项目', '创建项目', {
|
||||
confirmButtonText: '去创建项目',
|
||||
callback: action => {
|
||||
this.$router.push("/track/project/create");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
changeProject(project) {
|
||||
this.currentProject = project;
|
||||
},
|
||||
getCaseByNodeIds(data) {
|
||||
|
||||
console.log(data);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -220,4 +274,10 @@
|
|||
/*box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);*/
|
||||
margin: 10%;
|
||||
}
|
||||
|
||||
.project_menu {
|
||||
/*border-style:none;*/
|
||||
margin-left: 20px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,48 +2,47 @@
|
|||
|
||||
<div>
|
||||
|
||||
|
||||
<el-input placeholder="搜索模块" v-model="filterText"
|
||||
size="small">
|
||||
<el-button slot="append" icon="el-icon-folder-add" @click="editNode('add')"></el-button>
|
||||
<el-button slot="append" icon="el-icon-folder-add" @click="openEditNodeDialog('add')"></el-button>
|
||||
</el-input>
|
||||
|
||||
<el-tree
|
||||
class="filter-tree node-tree"
|
||||
:data="trees"
|
||||
node-key="id"
|
||||
@node-drag-start="handleDragStart"
|
||||
@node-drag-enter="handleDragEnter"
|
||||
@node-drag-leave="handleDragLeave"
|
||||
@node-drag-over="handleDragOver"
|
||||
@node-drag-end="handleDragEnd"
|
||||
@node-drop="handleDrop"
|
||||
:filter-node-method="filterNode"
|
||||
:expand-on-click-node="false"
|
||||
draggable
|
||||
:allow-drop="allowDrop"
|
||||
:allow-drag="allowDrag"
|
||||
ref="tree">
|
||||
class="filter-tree node-tree"
|
||||
:data="treeNodes"
|
||||
node-key="id"
|
||||
@node-drag-start="handleDragStart"
|
||||
@node-drag-enter="handleDragEnter"
|
||||
@node-drag-leave="handleDragLeave"
|
||||
@node-drag-over="handleDragOver"
|
||||
@node-drag-end="handleDragEnd"
|
||||
@node-drop="handleDrop"
|
||||
:filter-node-method="filterNode"
|
||||
:expand-on-click-node="false"
|
||||
draggable
|
||||
:allow-drop="allowDrop"
|
||||
:allow-drag="allowDrag"
|
||||
ref="tree">
|
||||
|
||||
<span class="custom-tree-node father" slot-scope="{ node, data }" @click="selectNode">
|
||||
<span>{{node.label}}</span>
|
||||
<el-dropdown class="node-dropdown child">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-folder-add"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>
|
||||
<div @click="editNode('edit', data)">重命名</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item >
|
||||
<div @click="editNode('add', data)">添加子模块</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<div @click="test">删除</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<span class="custom-tree-node father" slot-scope="{ node, data }" @click="selectNode(node)">
|
||||
<span>{{node.label}}</span>
|
||||
<el-dropdown class="node-dropdown child">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-folder-add"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>
|
||||
<div @click="openEditNodeDialog('edit', data)">重命名</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item >
|
||||
<div @click="openEditNodeDialog('add', data)">添加子模块</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<div @click="remove(node, data)">删除</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</span>
|
||||
</el-tree>
|
||||
|
||||
<el-dialog title="添加模块" :visible.sync="dialogFormVisible" width="500px">
|
||||
|
@ -60,7 +59,7 @@
|
|||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveNode">确 定</el-button>
|
||||
<el-button type="primary" @click="editNode">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
|
@ -75,51 +74,6 @@
|
|||
data() {
|
||||
return {
|
||||
filterText: '',
|
||||
trees: [{
|
||||
id: 1,
|
||||
label: '一级 1',
|
||||
children: [{
|
||||
id: 4,
|
||||
label: '二级 1-1',
|
||||
children: [{
|
||||
id: 9,
|
||||
label: '三级 1-1-1'
|
||||
}, {
|
||||
id: 10,
|
||||
label: '三级 1-1-2'
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
id: 2,
|
||||
label: '一级 2',
|
||||
children: [{
|
||||
id: 5,
|
||||
label: '二级 2-1'
|
||||
}, {
|
||||
id: 6,
|
||||
label: '二级 2-2'
|
||||
}]
|
||||
}, {
|
||||
id: 3,
|
||||
label: '一级 3',
|
||||
children: [{
|
||||
id: 7,
|
||||
label: '二级 3-1'
|
||||
}, {
|
||||
id: 8,
|
||||
label: '二级 3-2',
|
||||
children: [{
|
||||
id: 11,
|
||||
label: '三级 3-2-1'
|
||||
}, {
|
||||
id: 12,
|
||||
label: '三级 3-2-2'
|
||||
}, {
|
||||
id: 13,
|
||||
label: '三级 3-2-3'
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
|
@ -138,15 +92,25 @@
|
|||
dialogTableVisible: false,
|
||||
dialogFormVisible: false,
|
||||
editType: '',
|
||||
editData: {}
|
||||
editData: {},
|
||||
treeNodes: [],
|
||||
defaultKeys: []
|
||||
};
|
||||
},
|
||||
props: {
|
||||
projectId: null
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
},
|
||||
projectId(val){
|
||||
this.getNodeTree(val);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getNodeTree(this.projectId);
|
||||
},
|
||||
methods: {
|
||||
handleDragStart(node, ev) {
|
||||
console.log('drag start', node);
|
||||
|
@ -176,59 +140,87 @@
|
|||
allowDrag(draggingNode) {
|
||||
return draggingNode.data.label.indexOf('三级 3-2-2') === -1;
|
||||
},
|
||||
|
||||
append(data) {
|
||||
let id = 0;
|
||||
const newChild = { id: id++, label: 'testtest', children: [] };
|
||||
if (!data.children) {
|
||||
this.$set(data, 'children', []);
|
||||
}
|
||||
data.children.push(newChild);
|
||||
},
|
||||
|
||||
remove(node, data) {
|
||||
const parent = node.parent;
|
||||
const children = parent.data.children || parent.data;
|
||||
const index = children.findIndex(d => d.id === data.id);
|
||||
children.splice(index, 1);
|
||||
this.$post("/case/node/delete/" + data.id, null, () => {
|
||||
const parent = node.parent;
|
||||
const children = parent.data.children || parent.data;
|
||||
const index = children.findIndex(d => d.id === data.id);
|
||||
children.splice(index, 1);
|
||||
});
|
||||
},
|
||||
selectNode() {
|
||||
console.log("selet node-----");
|
||||
selectNode(node) {
|
||||
let nodeIds = [];
|
||||
this.getChildNodeId(node, nodeIds);
|
||||
this.$emit("nodeSelectEvent", nodeIds);
|
||||
},
|
||||
getChildNodeId(rootNode, nodeIds) {
|
||||
//递归获取所有子节点ID
|
||||
nodeIds.push(rootNode.data.id)
|
||||
for (let i = 0; i < rootNode.childNodes.length; i++){
|
||||
this.getChildNodeId(rootNode.childNodes[i], nodeIds);
|
||||
}
|
||||
return nodeIds;
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
},
|
||||
saveNode() {
|
||||
|
||||
let type = this.editType;
|
||||
let node = this.editData;
|
||||
if( type === 'add' ){
|
||||
if(node === undefined){
|
||||
console.log("add root node");
|
||||
} else {
|
||||
console.log("add node");
|
||||
}
|
||||
} else if(type === 'edit'){
|
||||
console.log("rename");
|
||||
}
|
||||
|
||||
this.form.name = '';
|
||||
|
||||
editNode() {
|
||||
this.saveNode(this.editType, this.editData);
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
editNode(type, data) {
|
||||
|
||||
openEditNodeDialog(type, data) {
|
||||
this.editType = type;
|
||||
this.editData = data;
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
test() {
|
||||
getNodeTree(projectId) {
|
||||
if(projectId){
|
||||
this.$get("/case/node/list/" + projectId, response => {
|
||||
this.treeNodes = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
saveNode(type, pNode) {
|
||||
let param = {};
|
||||
let url = '';
|
||||
|
||||
console.log("----");
|
||||
alert("ehllo");
|
||||
// this.dialogFormVisible = true;
|
||||
}
|
||||
if(type === 'add'){
|
||||
url = '/case/node/add';
|
||||
param.level = 1;
|
||||
if(pNode){
|
||||
//非根节点
|
||||
param.pId = pNode.id;
|
||||
param.level = pNode.level + 1;
|
||||
}
|
||||
} else if(type === 'edit'){
|
||||
url = '/case/node/edit';
|
||||
param.id = this.editData.id
|
||||
}
|
||||
|
||||
param.name = this.form.name;
|
||||
param.label = this.form.name;
|
||||
param.projectId = this.projectId;
|
||||
|
||||
this.$post(url, param, response => {
|
||||
if(type === 'edit'){
|
||||
this.editData.label = param.label;
|
||||
} if(type === 'add') {
|
||||
param.id = response.data;
|
||||
if(pNode){
|
||||
if(pNode.children){
|
||||
pNode.children.push(param);
|
||||
} else {
|
||||
pNode.children = [param];
|
||||
}
|
||||
} else {
|
||||
this.treeNodes.push(param);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.form.name = '';
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -167,6 +167,7 @@ export default {
|
|||
test_track: {
|
||||
'test_track': 'Test Track',
|
||||
'test_case': 'Test Case',
|
||||
'case_list': 'Test Case List',
|
||||
'create_case': 'Create Case',
|
||||
'test_plan': 'Test Plan',
|
||||
'create_plan': 'Create Plan',
|
||||
|
|
|
@ -167,6 +167,7 @@ export default {
|
|||
test_track: {
|
||||
'test_track': '测试跟踪',
|
||||
'test_case': '测试用例',
|
||||
'case_list': '用例列表',
|
||||
'create_case': '创建用例',
|
||||
'test_plan': '测试计划',
|
||||
'create_plan': '创建计划',
|
||||
|
|
Loading…
Reference in New Issue