Merge branch 'tree-sort'

This commit is contained in:
shiziyuan9527 2020-10-29 18:30:46 +08:00
commit 08183e425e
7 changed files with 211 additions and 66 deletions

View File

@ -19,5 +19,7 @@ public class TestCaseNode implements Serializable {
private Long updateTime;
private Double pos;
private static final long serialVersionUID = 1L;
}

View File

@ -245,72 +245,72 @@ public class TestCaseNodeExample {
}
public Criteria andNameIsNull() {
addCriterion("name is null");
addCriterion("`name` is null");
return (Criteria) this;
}
public Criteria andNameIsNotNull() {
addCriterion("name is not null");
addCriterion("`name` is not null");
return (Criteria) this;
}
public Criteria andNameEqualTo(String value) {
addCriterion("name =", value, "name");
addCriterion("`name` =", value, "name");
return (Criteria) this;
}
public Criteria andNameNotEqualTo(String value) {
addCriterion("name <>", value, "name");
addCriterion("`name` <>", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThan(String value) {
addCriterion("name >", value, "name");
addCriterion("`name` >", value, "name");
return (Criteria) this;
}
public Criteria andNameGreaterThanOrEqualTo(String value) {
addCriterion("name >=", value, "name");
addCriterion("`name` >=", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThan(String value) {
addCriterion("name <", value, "name");
addCriterion("`name` <", value, "name");
return (Criteria) this;
}
public Criteria andNameLessThanOrEqualTo(String value) {
addCriterion("name <=", value, "name");
addCriterion("`name` <=", value, "name");
return (Criteria) this;
}
public Criteria andNameLike(String value) {
addCriterion("name like", value, "name");
addCriterion("`name` like", value, "name");
return (Criteria) this;
}
public Criteria andNameNotLike(String value) {
addCriterion("name not like", value, "name");
addCriterion("`name` not like", value, "name");
return (Criteria) this;
}
public Criteria andNameIn(List<String> values) {
addCriterion("name in", values, "name");
addCriterion("`name` in", values, "name");
return (Criteria) this;
}
public Criteria andNameNotIn(List<String> values) {
addCriterion("name not in", values, "name");
addCriterion("`name` not in", values, "name");
return (Criteria) this;
}
public Criteria andNameBetween(String value1, String value2) {
addCriterion("name between", value1, value2, "name");
addCriterion("`name` between", value1, value2, "name");
return (Criteria) this;
}
public Criteria andNameNotBetween(String value1, String value2) {
addCriterion("name not between", value1, value2, "name");
addCriterion("`name` not between", value1, value2, "name");
return (Criteria) this;
}
@ -385,62 +385,62 @@ public class TestCaseNodeExample {
}
public Criteria andLevelIsNull() {
addCriterion("level is null");
addCriterion("`level` is null");
return (Criteria) this;
}
public Criteria andLevelIsNotNull() {
addCriterion("level is not null");
addCriterion("`level` is not null");
return (Criteria) this;
}
public Criteria andLevelEqualTo(Integer value) {
addCriterion("level =", value, "level");
addCriterion("`level` =", value, "level");
return (Criteria) this;
}
public Criteria andLevelNotEqualTo(Integer value) {
addCriterion("level <>", value, "level");
addCriterion("`level` <>", value, "level");
return (Criteria) this;
}
public Criteria andLevelGreaterThan(Integer value) {
addCriterion("level >", value, "level");
addCriterion("`level` >", value, "level");
return (Criteria) this;
}
public Criteria andLevelGreaterThanOrEqualTo(Integer value) {
addCriterion("level >=", value, "level");
addCriterion("`level` >=", value, "level");
return (Criteria) this;
}
public Criteria andLevelLessThan(Integer value) {
addCriterion("level <", value, "level");
addCriterion("`level` <", value, "level");
return (Criteria) this;
}
public Criteria andLevelLessThanOrEqualTo(Integer value) {
addCriterion("level <=", value, "level");
addCriterion("`level` <=", value, "level");
return (Criteria) this;
}
public Criteria andLevelIn(List<Integer> values) {
addCriterion("level in", values, "level");
addCriterion("`level` in", values, "level");
return (Criteria) this;
}
public Criteria andLevelNotIn(List<Integer> values) {
addCriterion("level not in", values, "level");
addCriterion("`level` not in", values, "level");
return (Criteria) this;
}
public Criteria andLevelBetween(Integer value1, Integer value2) {
addCriterion("level between", value1, value2, "level");
addCriterion("`level` between", value1, value2, "level");
return (Criteria) this;
}
public Criteria andLevelNotBetween(Integer value1, Integer value2) {
addCriterion("level not between", value1, value2, "level");
addCriterion("`level` not between", value1, value2, "level");
return (Criteria) this;
}
@ -563,6 +563,66 @@ public class TestCaseNodeExample {
addCriterion("update_time not between", value1, value2, "updateTime");
return (Criteria) this;
}
public Criteria andPosIsNull() {
addCriterion("pos is null");
return (Criteria) this;
}
public Criteria andPosIsNotNull() {
addCriterion("pos is not null");
return (Criteria) this;
}
public Criteria andPosEqualTo(Double value) {
addCriterion("pos =", value, "pos");
return (Criteria) this;
}
public Criteria andPosNotEqualTo(Double value) {
addCriterion("pos <>", value, "pos");
return (Criteria) this;
}
public Criteria andPosGreaterThan(Double value) {
addCriterion("pos >", value, "pos");
return (Criteria) this;
}
public Criteria andPosGreaterThanOrEqualTo(Double value) {
addCriterion("pos >=", value, "pos");
return (Criteria) this;
}
public Criteria andPosLessThan(Double value) {
addCriterion("pos <", value, "pos");
return (Criteria) this;
}
public Criteria andPosLessThanOrEqualTo(Double value) {
addCriterion("pos <=", value, "pos");
return (Criteria) this;
}
public Criteria andPosIn(List<Double> values) {
addCriterion("pos in", values, "pos");
return (Criteria) this;
}
public Criteria andPosNotIn(List<Double> values) {
addCriterion("pos not in", values, "pos");
return (Criteria) this;
}
public Criteria andPosBetween(Double value1, Double value2) {
addCriterion("pos between", value1, value2, "pos");
return (Criteria) this;
}
public Criteria andPosNotBetween(Double value1, Double value2) {
addCriterion("pos not between", value1, value2, "pos");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -2,9 +2,8 @@ package io.metersphere.base.mapper;
import io.metersphere.base.domain.TestCaseNode;
import io.metersphere.base.domain.TestCaseNodeExample;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface TestCaseNodeMapper {
long countByExample(TestCaseNodeExample example);
@ -15,9 +14,6 @@ public interface TestCaseNodeMapper {
int insert(TestCaseNode record);
int insertBatch(@Param("records") List<TestCaseNode> records);
int insertSelective(TestCaseNode record);
List<TestCaseNode> selectByExample(TestCaseNodeExample example);

View File

@ -9,6 +9,7 @@
<result column="level" jdbcType="INTEGER" property="level" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="pos" jdbcType="DOUBLE" property="pos" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -69,7 +70,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, project_id, name, parent_id, level, create_time, update_time
id, project_id, `name`, parent_id, `level`, create_time, update_time, pos
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestCaseNodeExample" resultMap="BaseResultMap">
select
@ -101,28 +102,14 @@
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insertBatch" parameterType="io.metersphere.base.domain.TestCaseNode">
insert into test_case_node (id, project_id, name,
parent_id, level, create_time,
update_time)
values
<foreach collection="records" item="emp" separator=",">
(#{emp.id,jdbcType=VARCHAR}, #{emp.projectId,jdbcType=VARCHAR}, #{emp.name,jdbcType=VARCHAR},
#{emp.parentId,jdbcType=VARCHAR}, #{emp.level,jdbcType=INTEGER}, #{emp.createTime,jdbcType=BIGINT},
#{emp.updateTime,jdbcType=BIGINT})
</foreach>
</insert>
<insert id="insert" parameterType="io.metersphere.base.domain.TestCaseNode">
insert into test_case_node (id, project_id, name,
parent_id, level, create_time,
update_time)
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{parentId,jdbcType=VARCHAR}, #{level,jdbcType=INTEGER}, #{createTime,jdbcType=BIGINT},
#{updateTime,jdbcType=BIGINT})
insert into test_case_node (id, project_id, `name`,
parent_id, `level`, create_time,
update_time, pos)
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{parentId,jdbcType=VARCHAR}, #{level,jdbcType=INTEGER}, #{createTime,jdbcType=BIGINT},
#{updateTime,jdbcType=BIGINT}, #{pos,jdbcType=DOUBLE})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseNode">
insert into test_case_node
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -133,13 +120,13 @@
project_id,
</if>
<if test="name != null">
name,
`name`,
</if>
<if test="parentId != null">
parent_id,
</if>
<if test="level != null">
level,
`level`,
</if>
<if test="createTime != null">
create_time,
@ -147,6 +134,9 @@
<if test="updateTime != null">
update_time,
</if>
<if test="pos != null">
pos,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -170,6 +160,9 @@
<if test="updateTime != null">
#{updateTime,jdbcType=BIGINT},
</if>
<if test="pos != null">
#{pos,jdbcType=DOUBLE},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.TestCaseNodeExample" resultType="java.lang.Long">
@ -188,13 +181,13 @@
project_id = #{record.projectId,jdbcType=VARCHAR},
</if>
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
`name` = #{record.name,jdbcType=VARCHAR},
</if>
<if test="record.parentId != null">
parent_id = #{record.parentId,jdbcType=VARCHAR},
</if>
<if test="record.level != null">
level = #{record.level,jdbcType=INTEGER},
`level` = #{record.level,jdbcType=INTEGER},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
@ -202,6 +195,9 @@
<if test="record.updateTime != null">
update_time = #{record.updateTime,jdbcType=BIGINT},
</if>
<if test="record.pos != null">
pos = #{record.pos,jdbcType=DOUBLE},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -211,11 +207,12 @@
update test_case_node
set id = #{record.id,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR},
`name` = #{record.name,jdbcType=VARCHAR},
parent_id = #{record.parentId,jdbcType=VARCHAR},
level = #{record.level,jdbcType=INTEGER},
`level` = #{record.level,jdbcType=INTEGER},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT}
update_time = #{record.updateTime,jdbcType=BIGINT},
pos = #{record.pos,jdbcType=DOUBLE}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -227,13 +224,13 @@
project_id = #{projectId,jdbcType=VARCHAR},
</if>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
`name` = #{name,jdbcType=VARCHAR},
</if>
<if test="parentId != null">
parent_id = #{parentId,jdbcType=VARCHAR},
</if>
<if test="level != null">
level = #{level,jdbcType=INTEGER},
`level` = #{level,jdbcType=INTEGER},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
@ -241,17 +238,21 @@
<if test="updateTime != null">
update_time = #{updateTime,jdbcType=BIGINT},
</if>
<if test="pos != null">
pos = #{pos,jdbcType=DOUBLE},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.TestCaseNode">
update test_case_node
set project_id = #{projectId,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR},
`name` = #{name,jdbcType=VARCHAR},
parent_id = #{parentId,jdbcType=VARCHAR},
level = #{level,jdbcType=INTEGER},
`level` = #{level,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT}
update_time = #{updateTime,jdbcType=BIGINT},
pos = #{pos,jdbcType=DOUBLE}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -77,4 +77,9 @@ public class TestCaseNodeController {
public void dragNode(@RequestBody DragNodeRequest node) {
testCaseNodeService.dragNode(node);
}
@PostMapping("/pos")
public void treeSort(@RequestBody List<String> ids) {
testCaseNodeService.sort(ids);
}
}

View File

@ -58,6 +58,8 @@ public class TestCaseNodeService {
node.setCreateTime(System.currentTimeMillis());
node.setUpdateTime(System.currentTimeMillis());
node.setId(UUID.randomUUID().toString());
double pos = getNextLevelPos(node.getProjectId(), node.getLevel());
node.setPos(pos);
testCaseNodeMapper.insertSelective(node);
return node.getId();
}
@ -93,7 +95,7 @@ public class TestCaseNodeService {
public List<TestCaseNodeDTO> getNodeTreeByProjectId(String projectId) {
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
testCaseNodeExample.createCriteria().andProjectIdEqualTo(projectId);
testCaseNodeExample.setOrderByClause("create_time asc");
testCaseNodeExample.setOrderByClause("pos asc");
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
return getNodeTrees(nodes);
}
@ -486,6 +488,8 @@ public class TestCaseNodeService {
testCaseNode.setUpdateTime(System.currentTimeMillis());
testCaseNode.setLevel(level);
testCaseNode.setId(UUID.randomUUID().toString());
double pos = getNextLevelPos(projectId, level);
testCaseNode.setPos(pos);
testCaseNodeMapper.insert(testCaseNode);
return testCaseNode.getId();
}
@ -574,4 +578,60 @@ public class TestCaseNodeService {
return projectMapper.selectByPrimaryKey(projectId);
}
private TestCaseNode getCaseNode(String id) {
return testCaseNodeMapper.selectByPrimaryKey(id);
}
/**
* 测试用例同级模块排序
* @param ids
*/
public void sort(List<String> ids) {
// 获取同级相邻节点
String before = ids.get(0);
String id = ids.get(1);
String after = ids.get(2);
TestCaseNode beforeCase = null;
TestCaseNode afterCase = null;
TestCaseNode caseNode = getCaseNode(id);
if (StringUtils.isNotBlank(before)) {
beforeCase = getCaseNode(before);
beforeCase = beforeCase.getLevel().equals(caseNode.getLevel()) ? beforeCase : null;
}
if (StringUtils.isNotBlank(after)) {
afterCase = getCaseNode(after);
afterCase = afterCase.getLevel().equals(caseNode.getLevel()) ? afterCase : null;
}
double pos;
if (beforeCase == null) {
pos = afterCase != null ? afterCase.getPos() / 2.0 : 65536;
} else {
pos = afterCase != null ? (beforeCase.getPos() + afterCase.getPos()) / 2.0 : beforeCase.getPos() + 65536;
}
// todo pos 低于阈值时触发更新方法重新计算此目录的所有同级目录的 pos
caseNode.setPos(pos);
testCaseNodeMapper.updateByPrimaryKeySelective(caseNode);
}
public double getNextLevelPos(String projectId, int level) {
TestCaseNodeExample example = new TestCaseNodeExample();
example.createCriteria().andProjectIdEqualTo(projectId).andLevelEqualTo(level);
example.setOrderByClause("pos desc");
List<TestCaseNode> list = testCaseNodeMapper.selectByExample(example);
if (!CollectionUtils.isEmpty(list)) {
return list.get(0).getPos() + 65536;
} else {
return 65536;
}
}
}

View File

@ -73,7 +73,8 @@ export default {
children: "children",
label: "label"
},
disabled: false
disabled: false,
list: []
};
},
props: {
@ -108,8 +109,12 @@ export default {
methods: {
handleDragEnd(draggingNode, dropNode, dropType, ev) {
let param = this.buildParam(draggingNode, dropNode, dropType);
this.list = [];
this.getNodeTree(this.treeNodes,draggingNode.data.id, this.list);
this.$post("/case/node/drag", param, () => {
draggingNode.data.level = param.level;
this.$post("/case/node/pos", this.list);
this.refreshTable();
}, (error) => {
this.refreshNode();
@ -148,6 +153,22 @@ export default {
param.nodeIds = nodeIds;
return param;
},
getNodeTree(nodes, id, list) {
if (!nodes) {
return;
}
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].id === id) {
i - 1 >= 0 ? list[0] = nodes[i-1].id : list[0] = "";
list[1] = nodes[i].id;
i + 1 < nodes.length ? list[2] = nodes[i+1].id : list[2] = "";
return;
}
if (nodes[i].children) {
this.getNodeTree(nodes[i].children, id, list);
}
}
},
refreshTable() {
this.$emit('refreshTable');
},