mysql查询结果拼接树结构(树节点的移动)

思路:单表内查询全部数据,在业务层内递归拼接树结构。

前端用的是element的Tree 树形控件:

树结构实体:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TreeSelect implements Serializable { /**
* 所需参数跟前端商讨,参数名跟前端确认一下,我的就是两个前端没统一后面还重加了个
*/ private static final long serialVersionUID = -1370015781272165366L; private Long id; private Long pid; private String label; /**
* 排序,树节点移动需要
*/
private int sno; @ApiModelProperty(value = "是否启用,0禁用,1正常")
private int status; /**
* 子级,下一级节点
*/
private List<TreeSelect> subordinate; }

业务层拼接树:

    @Override
public Object getSysClassifyItemTree(Long versionId) {
//查询出全部数据
List<TreeSelect> sysClassifyItemList = classifyMapper.getAll(versionId); Map<Long, List<TreeSelect>> collect = sysClassifyItemList.stream().collect(Collectors.groupingBy(TreeSelect::getPid));
List<TreeSelect> list = collect.get(0L);
List<TreeSelect> items = new ArrayList<>();
if (null == list) {
//在没有数据的时候,给前端返回一个虚拟节点方便展示,操作
TreeSelect sss = new TreeSelect(0l, "虚拟节点", 0l);
items.add(sss);
return JSON.toJSON(items).toString();
}
for (TreeSelect sysClassifyItem : collect.get(0L)) {
buildTree(sysClassifyItem, collect);
}
//如果这个树需要一个固定的父节点,new一个TreeSelect对象 f,把拼出来的树塞到f的subordinate也就是子级。
return JSON.toJSON(list).toString();
} /**
* 拼接树
*/
private void buildTree(TreeSelect sysClassifyItem, Map<Long, List<TreeSelect>> collect) {
if (null == sysClassifyItem || null == collect.get(sysClassifyItem.getId())) {
return;
}
sysClassifyItem.setSubordinate(collect.get(sysClassifyItem.getId()));
for (TreeSelect classifyItem : collect.get(sysClassifyItem.getId())) {
buildTree(classifyItem, collect);
}
}

下来是树节点的移动,也就是上移下移(提出到上层节点跟插入到子级节点就不放了,单纯的修改而已)

在移动的时候我们需要知道自己的位置和要移动到的位置,也就是目标位置

移动节点实体:

@Data
public class MoveNode implements Serializable {
private static final long serialVersionUID = 8370232720686896563L; private Long parentId;
private Long sno;//排序,节点当前位置
private Long targetSno;//目标位置
private Long id; }

业务层:

@Override
public boolean moveUp(MoveNode moveNode) { //判断节点是上移还是下移
if (moveNode.getMoveSno() > moveNode.getSno()) {
if (structureMapper.moveDownA(moveNode) == -1 || structureMapper.move(moveNode) == -1) {
return false;
}
} else if (moveNode.getMoveSno() < moveNode.getSno()) {
if (structureMapper.moveUpA(moveNode) == -1 || structureMapper.move(moveNode) == -1) {
return false;
}
}
return true;
}

mapper:

<!--上移我们需要以目标位置到自身位置的前一个位置为区间给每个节点的顺序都往后调一位-->
<update id="moveUpA">
UPDATE SYS_TEAM
<set>
WEIGHT = WEIGHT + 1
</set>
<where>
<if test="parentId != null">and UNITID = #{parentId}</if>
<if test="moveSno != null and sno != null">and WEIGHT BETWEEN #{moveSno} and #{sno}-1</if>
</where>
</update> <!--下移就刚好相反,我们需要以自身位置的后一个位置到目标位置为区间给每个节点的顺序都往前调一位-->
<update id="moveDownA">
UPDATE SYS_TEAM
<set>
WEIGHT = WEIGHT - 1
</set>
<where>
<if test="parentId != null">and UNITID = #{parentId}</if>
<if test="moveSno != null and sno != null">and WEIGHT BETWEEN #{sno}+1 and #{moveSno}</if>
</where>
</update> <!--每次移动后将自身位置替换为目标位置-->
<update id="move">
UPDATE SYS_TEAM
<set>
<if test="moveSno != null">WEIGHT = #{moveSno}</if>
</set>
<where>
<if test="parentId != null">and UNITID = #{parentId}</if>
<if test="sno != null">and WEIGHT = #{sno}</if>
<if test="id != null">and ID = #{id}</if>
</where>
</update>

看下图,移动这里有个问题是前端无法拿到准确的位置,因为element的可拖拽树每个节点有after,before两条线,绑定的是这个节点自身的属性,也就是说两个节点之间有两条线,这就导致c节点在移动到A——B之间时可能会放到a2的这条线导致目标位置拿成了A的位置。即我本身是想将c移动到B的上方,结果是变成了A的上方,同理下移的时候A移动到B的下面,不小心就变成了C的下面。我在网上看有其他的tree控件是可以解决的,前端怕改的地方太多引起别的问题,一直没动。不知道大家有没有遇到过,怎么解决的呢?

最新文章

  1. Vue.js介绍样码
  2. web前端程序员真的值这么多钱吗?
  3. Android布局优化之过度绘制
  4. HDU3501 Calculation 2(欧拉函数)
  5. 求出数组前面k个元素或数组中元素大于一半的元素(快速排序与堆排序的灵活运用)
  6. 使用nodejs引用socket.io做聊天室
  7. Java自增原子性问题(测试Volatile、AtomicInteger)
  8. 华夏的理财30天A和华夏财富宝货币哪个收益比较好?
  9. 辛星PHP教程之yii和ci教程已经写完,望与朋友们交流
  10. Delphi ADO数据操作封装类
  11. gulp learning note
  12. C# Ioc ASP.NET MVC Dependency Injection
  13. mongodb学习一
  14. AD服务无法启动
  15. 爬虫之scrapy扩展
  16. Connect To Ubuntu 16.04 / 17.10 / 18.04 Desktop Via Remote Desktop Connection (RDP) With Xrdp
  17. bzoj4428
  18. ip+掩码
  19. Oracle更改redo log的大小
  20. P3924 康娜的线段树(期望)

热门文章

  1. 《Win10——常用快捷键》
  2. Nginx相关模块学习使用实践指南
  3. Kubernetes 基本概念与组件
  4. kvm使用桥接的方法
  5. 阿里云SLB的http强制转https
  6. 通过开启swap分区来解决小内存阿里云服务器的内存瓶颈
  7. switch分支
  8. C#-3 深入理解类
  9. 掌控(control) 方法记录
  10. Windows Socket 接口简介