Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Captain.B 2020-03-26 17:01:07 +08:00
commit f11437bf19
14 changed files with 466 additions and 225 deletions

View File

@ -9,9 +9,9 @@ public class TestCaseNode implements Serializable {
private String name; private String name;
private String pId; private Integer pId;
private Long order; private Integer level;
private Long createTime; private Long createTime;
@ -43,20 +43,20 @@ public class TestCaseNode implements Serializable {
this.name = name == null ? null : name.trim(); this.name = name == null ? null : name.trim();
} }
public String getpId() { public Integer getpId() {
return pId; return pId;
} }
public void setpId(String pId) { public void setpId(Integer pId) {
this.pId = pId == null ? null : pId.trim(); this.pId = pId;
} }
public Long getOrder() { public Integer getLevel() {
return order; return level;
} }
public void setOrder(Long order) { public void setLevel(Integer level) {
this.order = order; this.level = level;
} }
public Long getCreateTime() { public Long getCreateTime() {

View File

@ -314,123 +314,113 @@ public class TestCaseNodeExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdEqualTo(String value) { public Criteria andPIdEqualTo(Integer value) {
addCriterion("p_id =", value, "pId"); addCriterion("p_id =", value, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdNotEqualTo(String value) { public Criteria andPIdNotEqualTo(Integer value) {
addCriterion("p_id <>", value, "pId"); addCriterion("p_id <>", value, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdGreaterThan(String value) { public Criteria andPIdGreaterThan(Integer value) {
addCriterion("p_id >", value, "pId"); addCriterion("p_id >", value, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdGreaterThanOrEqualTo(String value) { public Criteria andPIdGreaterThanOrEqualTo(Integer value) {
addCriterion("p_id >=", value, "pId"); addCriterion("p_id >=", value, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdLessThan(String value) { public Criteria andPIdLessThan(Integer value) {
addCriterion("p_id <", value, "pId"); addCriterion("p_id <", value, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdLessThanOrEqualTo(String value) { public Criteria andPIdLessThanOrEqualTo(Integer value) {
addCriterion("p_id <=", value, "pId"); addCriterion("p_id <=", value, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdLike(String value) { public Criteria andPIdIn(List<Integer> values) {
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) {
addCriterion("p_id in", values, "pId"); addCriterion("p_id in", values, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdNotIn(List<String> values) { public Criteria andPIdNotIn(List<Integer> values) {
addCriterion("p_id not in", values, "pId"); addCriterion("p_id not in", values, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPIdBetween(String value1, String value2) { public Criteria andPIdBetween(Integer value1, Integer value2) {
addCriterion("p_id between", value1, value2, "pId"); addCriterion("p_id between", value1, value2, "pId");
return (Criteria) this; 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"); addCriterion("p_id not between", value1, value2, "pId");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderIsNull() { public Criteria andLevelIsNull() {
addCriterion("order is null"); addCriterion("level is null");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderIsNotNull() { public Criteria andLevelIsNotNull() {
addCriterion("order is not null"); addCriterion("level is not null");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderEqualTo(Long value) { public Criteria andLevelEqualTo(Integer value) {
addCriterion("order =", value, "order"); addCriterion("level =", value, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderNotEqualTo(Long value) { public Criteria andLevelNotEqualTo(Integer value) {
addCriterion("order <>", value, "order"); addCriterion("level <>", value, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderGreaterThan(Long value) { public Criteria andLevelGreaterThan(Integer value) {
addCriterion("order >", value, "order"); addCriterion("level >", value, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderGreaterThanOrEqualTo(Long value) { public Criteria andLevelGreaterThanOrEqualTo(Integer value) {
addCriterion("order >=", value, "order"); addCriterion("level >=", value, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderLessThan(Long value) { public Criteria andLevelLessThan(Integer value) {
addCriterion("order <", value, "order"); addCriterion("level <", value, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderLessThanOrEqualTo(Long value) { public Criteria andLevelLessThanOrEqualTo(Integer value) {
addCriterion("order <=", value, "order"); addCriterion("level <=", value, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderIn(List<Long> values) { public Criteria andLevelIn(List<Integer> values) {
addCriterion("order in", values, "order"); addCriterion("level in", values, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderNotIn(List<Long> values) { public Criteria andLevelNotIn(List<Integer> values) {
addCriterion("order not in", values, "order"); addCriterion("level not in", values, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderBetween(Long value1, Long value2) { public Criteria andLevelBetween(Integer value1, Integer value2) {
addCriterion("order between", value1, value2, "order"); addCriterion("level between", value1, value2, "level");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andOrderNotBetween(Long value1, Long value2) { public Criteria andLevelNotBetween(Integer value1, Integer value2) {
addCriterion("order not between", value1, value2, "order"); addCriterion("level not between", value1, value2, "level");
return (Criteria) this; return (Criteria) this;
} }

View File

@ -5,8 +5,8 @@
<id column="id" jdbcType="INTEGER" property="id" /> <id column="id" jdbcType="INTEGER" property="id" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" /> <result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="name" jdbcType="VARCHAR" property="name" /> <result column="name" jdbcType="VARCHAR" property="name" />
<result column="p_id" jdbcType="VARCHAR" property="pId" /> <result column="p_id" jdbcType="INTEGER" property="pId" />
<result column="order" jdbcType="BIGINT" property="order" /> <result column="level" jdbcType="INTEGER" property="level" />
<result column="create_time" jdbcType="BIGINT" property="createTime" /> <result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" /> <result column="update_time" jdbcType="BIGINT" property="updateTime" />
</resultMap> </resultMap>
@ -69,7 +69,7 @@
</where> </where>
</sql> </sql>
<sql id="Base_Column_List"> <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> </sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseNodeExample" resultMap="BaseResultMap"> <select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseNodeExample" resultMap="BaseResultMap">
select select
@ -102,19 +102,22 @@
</if> </if>
</delete> </delete>
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseNode"> <insert id="insert" parameterType="io.metersphere.base.domain.TestCaseNode">
insert into test_case_node (id, project_id, name, <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
p_id, order, create_time, SELECT LAST_INSERT_ID()
update_time) </selectKey>
values (#{id,jdbcType=INTEGER}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, insert into test_case_node (project_id, name, p_id,
#{pId,jdbcType=VARCHAR}, #{order,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT}, level, create_time, update_time
#{updateTime,jdbcType=BIGINT}) )
values (#{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{pId,jdbcType=INTEGER},
#{level,jdbcType=INTEGER}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}
)
</insert> </insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseNode"> <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 insert into test_case_node
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="projectId != null"> <if test="projectId != null">
project_id, project_id,
</if> </if>
@ -124,8 +127,8 @@
<if test="pId != null"> <if test="pId != null">
p_id, p_id,
</if> </if>
<if test="order != null"> <if test="level != null">
order, level,
</if> </if>
<if test="createTime != null"> <if test="createTime != null">
create_time, create_time,
@ -135,9 +138,6 @@
</if> </if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="projectId != null"> <if test="projectId != null">
#{projectId,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
</if> </if>
@ -145,10 +145,10 @@
#{name,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
</if> </if>
<if test="pId != null"> <if test="pId != null">
#{pId,jdbcType=VARCHAR}, #{pId,jdbcType=INTEGER},
</if> </if>
<if test="order != null"> <if test="level != null">
#{order,jdbcType=BIGINT}, #{level,jdbcType=INTEGER},
</if> </if>
<if test="createTime != null"> <if test="createTime != null">
#{createTime,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT},
@ -177,10 +177,10 @@
name = #{record.name,jdbcType=VARCHAR}, name = #{record.name,jdbcType=VARCHAR},
</if> </if>
<if test="record.pId != null"> <if test="record.pId != null">
p_id = #{record.pId,jdbcType=VARCHAR}, p_id = #{record.pId,jdbcType=INTEGER},
</if> </if>
<if test="record.order != null"> <if test="record.level != null">
order = #{record.order,jdbcType=BIGINT}, level = #{record.level,jdbcType=INTEGER},
</if> </if>
<if test="record.createTime != null"> <if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT},
@ -198,8 +198,8 @@
set id = #{record.id,jdbcType=INTEGER}, set id = #{record.id,jdbcType=INTEGER},
project_id = #{record.projectId,jdbcType=VARCHAR}, project_id = #{record.projectId,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR}, name = #{record.name,jdbcType=VARCHAR},
p_id = #{record.pId,jdbcType=VARCHAR}, p_id = #{record.pId,jdbcType=INTEGER},
order = #{record.order,jdbcType=BIGINT}, level = #{record.level,jdbcType=INTEGER},
create_time = #{record.createTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT} update_time = #{record.updateTime,jdbcType=BIGINT}
<if test="_parameter != null"> <if test="_parameter != null">
@ -216,10 +216,10 @@
name = #{name,jdbcType=VARCHAR}, name = #{name,jdbcType=VARCHAR},
</if> </if>
<if test="pId != null"> <if test="pId != null">
p_id = #{pId,jdbcType=VARCHAR}, p_id = #{pId,jdbcType=INTEGER},
</if> </if>
<if test="order != null"> <if test="level != null">
order = #{order,jdbcType=BIGINT}, level = #{level,jdbcType=INTEGER},
</if> </if>
<if test="createTime != null"> <if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
@ -234,8 +234,8 @@
update test_case_node update test_case_node
set project_id = #{projectId,jdbcType=VARCHAR}, set project_id = #{projectId,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR}, name = #{name,jdbcType=VARCHAR},
p_id = #{pId,jdbcType=VARCHAR}, p_id = #{pId,jdbcType=INTEGER},
order = #{order,jdbcType=BIGINT}, level = #{level,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT} update_time = #{updateTime,jdbcType=BIGINT}
where id = #{id,jdbcType=INTEGER} where id = #{id,jdbcType=INTEGER}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -21,10 +21,11 @@ CREATE TABLE IF NOT EXISTS `test_case_node` (
`id` int(13) PRIMARY KEY AUTO_INCREMENT COMMENT 'Test case node ID', `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', `project_id` varchar(50) NOT NULL COMMENT 'Project ID this node belongs to',
`name` varchar(64) NOT NULL COMMENT 'Node name', `name` varchar(64) NOT NULL COMMENT 'Node name',
`p_id` varchar(50) NOT NULL COMMENT 'Parent node ID', `p_id` int(13) DEFAULT NULL COMMENT 'Parent node ID',
`order` bigint(13) COMMENT 'Node order', `level` int(10) DEFAULT 1 COMMENT 'Node level',
`create_time` bigint(13) NOT NULL COMMENT 'Create timestamp', `create_time` bigint(13) NOT NULL COMMENT 'Create timestamp',
`update_time` bigint(13) NOT NULL COMMENT 'Update 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`) FOREIGN KEY (`project_id`) references project(`id`)
) )
AUTO_INCREMENT = 1 AUTO_INCREMENT = 1

View File

@ -46,10 +46,12 @@
<!--要生成的数据库表 --> <!--要生成的数据库表 -->
<table tableName="test_plan"/> <!--<table tableName="test_plan"/>-->
<table tableName="test_case_node"/> <table tableName="test_case_node">
<table tableName="test_case"/> <generatedKey column="id" sqlStatement="MySql" identity="true"/>
<table tableName="test_plan_test_case"/> </table>
<!--<table tableName="test_case"/>-->
<!--<table tableName="test_plan_test_case"/>-->
</context> </context>
</generatorConfiguration> </generatorConfiguration>

View File

@ -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);
}
}

View File

@ -52,16 +52,16 @@
<el-submenu v-if="isCurrentWorkspaceUser && beaseUrl == 'track'" <el-submenu v-if="isCurrentWorkspaceUser && beaseUrl == 'track'"
index="6" popper-class="submenu" v-permission="['test_manager', 'test_user']"> 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/> <recent-case-plan/>
<el-divider/> <el-divider/>
<el-menu-item :index="'/' + beaseUrl + '/case/all'"> <el-menu-item :index="'/' + beaseUrl + '/case/all'">
<font-awesome-icon :icon="['fa', 'list-ul']"/> <font-awesome-icon :icon="['fa', 'list-ul']"/>
<span style="padding-left: 5px;">{{$t('commons.show_all')}}</span> <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-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>
<el-submenu v-if="isCurrentWorkspaceUser && beaseUrl == 'track'" <el-submenu v-if="isCurrentWorkspaceUser && beaseUrl == 'track'"

View File

@ -1,14 +1,29 @@
<template> <template>
<div class="case_container" v-loading="result.loading"> <div class="case_container" v-loading="loadingRequire.project && loadingRequire.testCase">
<!--<div class="main-content">-->
<el-container> <el-container>
<el-aside width="250px"> <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-aside>
<el-main> <el-main>
<el-card> <el-card>
<div slot="header"> <div slot="header">
@ -82,10 +97,8 @@
</div> </div>
</el-card> </el-card>
</el-main> </el-main>
</el-container> </el-container>
<!--</div>-->
</div> </div>
</template> </template>
@ -109,8 +122,11 @@
currentPage: 1, currentPage: 1,
pageSize: 5, pageSize: 5,
total: 0, total: 0,
loading: false, loadingRequire: {project: true, testCase: true},
testId: null, testId: null,
projects: [],
initProjects: [],
currentProject: null,
} }
}, },
watch: { watch: {
@ -122,6 +138,7 @@
created: function () { created: function () {
this.projectId = this.$route.params.projectId; this.projectId = this.$route.params.projectId;
this.initTableData(); this.initTableData();
this.getProjects();
}, },
methods: { methods: {
initTableData() { initTableData() {
@ -134,11 +151,30 @@
} }
this.result = this.$post(this.buildPagePath(this.queryPath), param, response => { this.result = this.$post(this.buildPagePath(this.queryPath), param, response => {
this.loadingRequire.testCase = false;
let data = response.data; let data = response.data;
this.total = data.itemCount; this.total = data.itemCount;
this.tableData = data.listObject; 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() { search() {
this.initTableData(); this.initTableData();
}, },
@ -184,6 +220,24 @@
this.initTableData(); 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> </script>
@ -220,4 +274,10 @@
/*box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);*/ /*box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);*/
margin: 10%; margin: 10%;
} }
.project_menu {
/*border-style:none;*/
margin-left: 20px;
height: 50px;
}
</style> </style>

View File

@ -2,48 +2,47 @@
<div> <div>
<el-input placeholder="搜索模块" v-model="filterText" <el-input placeholder="搜索模块" v-model="filterText"
size="small"> 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-input>
<el-tree <el-tree
class="filter-tree node-tree" class="filter-tree node-tree"
:data="trees" :data="treeNodes"
node-key="id" node-key="id"
@node-drag-start="handleDragStart" @node-drag-start="handleDragStart"
@node-drag-enter="handleDragEnter" @node-drag-enter="handleDragEnter"
@node-drag-leave="handleDragLeave" @node-drag-leave="handleDragLeave"
@node-drag-over="handleDragOver" @node-drag-over="handleDragOver"
@node-drag-end="handleDragEnd" @node-drag-end="handleDragEnd"
@node-drop="handleDrop" @node-drop="handleDrop"
:filter-node-method="filterNode" :filter-node-method="filterNode"
:expand-on-click-node="false" :expand-on-click-node="false"
draggable draggable
:allow-drop="allowDrop" :allow-drop="allowDrop"
:allow-drag="allowDrag" :allow-drag="allowDrag"
ref="tree"> ref="tree">
<span class="custom-tree-node father" slot-scope="{ node, data }" @click="selectNode"> <span class="custom-tree-node father" slot-scope="{ node, data }" @click="selectNode(node)">
<span>{{node.label}}</span> <span>{{node.label}}</span>
<el-dropdown class="node-dropdown child"> <el-dropdown class="node-dropdown child">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
<i class="el-icon-folder-add"></i> <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> </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-tree>
<el-dialog title="添加模块" :visible.sync="dialogFormVisible" width="500px"> <el-dialog title="添加模块" :visible.sync="dialogFormVisible" width="500px">
@ -60,7 +59,7 @@
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false"> </el-button> <el-button @click="dialogFormVisible = false"> </el-button>
<el-button type="primary" @click="saveNode"> </el-button> <el-button type="primary" @click="editNode"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -75,51 +74,6 @@
data() { data() {
return { return {
filterText: '', 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: { defaultProps: {
children: 'children', children: 'children',
label: 'label' label: 'label'
@ -138,15 +92,25 @@
dialogTableVisible: false, dialogTableVisible: false,
dialogFormVisible: false, dialogFormVisible: false,
editType: '', editType: '',
editData: {} editData: {},
treeNodes: [],
defaultKeys: []
}; };
}, },
props: {
projectId: null
},
watch: { watch: {
filterText(val) { filterText(val) {
this.$refs.tree.filter(val); this.$refs.tree.filter(val);
},
projectId(val){
this.getNodeTree(val);
} }
}, },
created() {
this.getNodeTree(this.projectId);
},
methods: { methods: {
handleDragStart(node, ev) { handleDragStart(node, ev) {
console.log('drag start', node); console.log('drag start', node);
@ -176,59 +140,87 @@
allowDrag(draggingNode) { allowDrag(draggingNode) {
return draggingNode.data.label.indexOf('三级 3-2-2') === -1; 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) { remove(node, data) {
const parent = node.parent; this.$post("/case/node/delete/" + data.id, null, () => {
const children = parent.data.children || parent.data; const parent = node.parent;
const index = children.findIndex(d => d.id === data.id); const children = parent.data.children || parent.data;
children.splice(index, 1); const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
});
}, },
selectNode() { selectNode(node) {
console.log("selet 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) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
return data.label.indexOf(value) !== -1; return data.label.indexOf(value) !== -1;
}, },
saveNode() { editNode() {
this.saveNode(this.editType, this.editData);
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 = '';
this.dialogFormVisible = false; this.dialogFormVisible = false;
}, },
editNode(type, data) { openEditNodeDialog(type, data) {
this.editType = type; this.editType = type;
this.editData = data; this.editData = data;
this.dialogFormVisible = true; 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("----"); if(type === 'add'){
alert("ehllo"); url = '/case/node/add';
// this.dialogFormVisible = true; 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> </script>

View File

@ -167,6 +167,7 @@ export default {
test_track: { test_track: {
'test_track': 'Test Track', 'test_track': 'Test Track',
'test_case': 'Test Case', 'test_case': 'Test Case',
'case_list': 'Test Case List',
'create_case': 'Create Case', 'create_case': 'Create Case',
'test_plan': 'Test Plan', 'test_plan': 'Test Plan',
'create_plan': 'Create Plan', 'create_plan': 'Create Plan',

View File

@ -167,6 +167,7 @@ export default {
test_track: { test_track: {
'test_track': '测试跟踪', 'test_track': '测试跟踪',
'test_case': '测试用例', 'test_case': '测试用例',
'case_list': '用例列表',
'create_case': '创建用例', 'create_case': '创建用例',
'test_plan': '测试计划', 'test_plan': '测试计划',
'create_plan': '创建计划', 'create_plan': '创建计划',