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


    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}-1if>
        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控件是可以解决的,前端怕改的地方太多引起别的问题,一直没动。不知道大家有没有遇到过,怎么解决的呢?

  • 相关阅读:
    免费翻译软件哪个好用
    java基于微信小程序的超市购物商城系统 小程序 uniapp
    kubernetes配置后端存储 rook-ceph
    四川汇聚荣科技有限公司怎么样?
    Elasticsearch in 查询
    【Linux】shell脚本和bat脚本:
    用DIV+CSS技术设计的凤阳旅游网站(web前端网页制作课作业)HTML+CSS+JavaScript
    [ATC复盘] abc329 20231118
    C++ 静态和运行时断言 assert, static_assert和 throw runtime_error
    如何选择国际通知短信服务商?
  • 原文地址:https://www.cnblogs.com/ComfortableM/p/16915581.html