17 Dec 2017

VUE树状图Tree(elementUI+SpringData)

介绍: 前端基于elementUI(el-tree组件),后端基于SpringDataJpa(递归) 的树形图

前端(elementUI)

  1. 展示模板 MySpan.vue
    <template>
        <span style="flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;display:inline-block;width:100%">
         <span style="width:30%">
            <span v-if="!showEdit"></span>
        </span>
        <span  style="width:40%">
        <el-input v-if="showEdit" style="width:300px" placeholder="请输入内容" size="mini" v-model='toAddLable'  >
        </el-input>
        <i v-if="showEdit" class="el-icon-check" @click='add'></i>
        </span>
        <span style="width:30%">
            <el-button style="font-size: 12px;" type="text" @click='append'>新增</el-button>
            <el-button style="font-size: 12px;" type="text" @click='edit'>修改</el-button>
            <el-button style="font-size: 12px;" type="text" @click='remove'>删除</el-button>       
        </span>
        </span>
    </template>
    <script>
     import concrete from '../../../api/jquery-concrete';
     let SystemImpl = concrete.module("com.design.SystemUserMgmt");
     export default {
        name: 'mySpan',
        props: {
            node: Object
        },
        data() {
            return {
                showEdit: false,
                toAddLable: ""         
            }
        },
        mounted: function() {
          // Object.assign(o1, o2, o3);
            this.showEdit = !this.node.label;
        },
        methods: {
            append: function(e) {
                this.$emit("addNode", this.node);
            },        
            add: function(e) {
                let _self=this,deptName=this.node.data.deptName;
                this.node.data.deptName=this.toAddLable;
                let onSuccess=(data) =>{
                    _self.$emit("reloadTree", this.node);
                    this.toAddLable = "";
                    this.showEdit = false;
                    };
                if((this.node.data.deptId+"").endsWith("add")){
                    SystemImpl.addDept(this.node.data).success(onSuccess)
                }else{
                SystemImpl.modifyDept(this.node.data).success(onSuccess)
                }
                this.node.data.deptName=this.deptName;           
            },
            edit: function() {
                this.toAddLable = this.node.label;
                this.showEdit = true;
            },
            remove: function(e) {
                this.$emit("removeNode",this.node);
            },
        },
        watch: {
            'node' (to, from) {        }
        }
    }
    </script>
    
  2. 树形图 MyTree.vue
    <template>
        <div id="app1">
            <el-tree :data="treeData" :props="defaultProps" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false" :render-content="renderContent">
            </el-tree>
        </div>
    </template>
    <script>
     let id = 1000;
     import Vue from 'vue'
     import mySpan from './MySpan.vue'
     Vue.component('my-span', mySpan)//注册为全局组件
     import concrete from '../../../api/jquery-concrete';
     let SystemImpl = concrete.module("com.design.SystemUserMgmt");
     export default {
        name: 'MyTree',
        data() {
            return {
               treeData:[],// 树的数据
                defaultProps: {// 属性对应
                    children: 'children',
                    label: 'deptName',
                    id:'deptId'
                }
            }
        },
        methods: {
            reloadTree() {// 重新加载树
              let _self=this;
              SystemImpl.getDeptTree().success(function(data){
                _self.treeData=[];
                _self.treeData.push(data);
              })
            },
            addNode(node) {// 添加节点
              const newChild = { deptId: (id++)+"add", deptName: '',department:node.data.deptId,departmentName:node.data.deptName , children: [] };
                if (!node.data.children) {
                    node.data.children = [];
                }
                node.data.children.push(newChild);
            },
            editNode(data){
              data.node.data.label=data.label;
            },
           removeNode(node) {//移除节点
             const parent = node.parent;
             const children = parent.data.children || parent.data;
             const index = children.findIndex(d => d.id === node.data.id);
             children.splice(index, 1);
           },
            renderContent(h, { node, data, store }) {
                return h("my-span", {
                    attrs: { node: node },//添加属性
                    on: {  //添加监控事件                  
                        addNode: this.addNode,
                        reloadTree:this.reloadTree
                        removeNode:this.removeNode,
                    },
                });
            }
        },
       mounted(){
          this.reloadTree();
        }
    };
    </script>
    <style></style>
    

后端(springDataJpa)

  1. 实体: DeptUserEntity.java
    @Entity
    @Table(name="dept_user")
    public class DeptUserEntity implements Serializable {
     @Id
     private String deptId = Common.getUUIDStr();
     private String department;
     private String deptName;
      //  get/set ...
      }
    
  2. pojo: TreeNodeInfo.java
    public class TreeNodeInfo extends DeptUserInfo {
     private String deptId;
     private String deptName;
     private String department;
     private String departmentName;
     private List<TreeNodeInfo> children;
     //get/set   
    }
    
  3. repo :
    public class DeptUserRepo extends JpaRepository<DeptUserEntity,String>, JpaSpecificationExecutor<DeptUserEntity> {
      // 设定根部门标识为:deptId =department
     @Query(value = "select * from dept_user where deptId =department;",nativeQuery =true )
     List<DeptUserEntity> findRootDept();
    }
    
  4. 组装树(递归):treeBiz.java
    // 获取部门信息
    public TreeNodeInfo getNodeById(String nodeId, List<TreeNodeInfo> treeNodeList) {
     TreeNodeInfo treeNode = new TreeNodeInfo();
     for (TreeNodeInfo item : treeNodeList) {
         if (item.getDeptId().equals(nodeId)) {
             treeNode = item;
             break;
         }
     }
     return treeNode;
    }
    //  获取子部门
    public List<TreeNodeInfo> getChildrenNodeById(String nodeId, List<TreeNodeInfo> treeNodeList) {
     List<TreeNodeInfo> childrenTreeNode = new ArrayList<TreeNodeInfo>();
     for (TreeNodeInfo item : treeNodeList) {
         if (item.getDepartment().equals(nodeId)) {
             childrenTreeNode.add(item);
         }
     }
     return childrenTreeNode;
    }
    // 组装树
    public TreeNodeInfo getDeptTreeFun(String pid, List<TreeNodeInfo> treeNodeList) {
     TreeNodeInfo rootDept = this.getNodeById(pid, treeNodeList);
     List<TreeNodeInfo> childrenTreeNode = this.getChildrenNodeById(pid, treeNodeList);
     if (childrenTreeNode != null && childrenTreeNode.size() > 0) {
         for (TreeNodeInfo item : childrenTreeNode) {
             if (pid.equals(item.getDeptId())) {
                 continue;
             }
             TreeNodeInfo node = this.getDeptTreeFun(item.getDeptId(), treeNodeList);
             if (rootDept.getChildren() == null) {
                 rootDept.setChildren(new ArrayList<TreeNodeInfo>());
             }
             rootDept.getChildren().add(node);
         }
     }
     return rootDept;
    }
    //获取树(对外使用)
    public Object getDeptTree() {
     // 数据库取出所有部门实体
     List<DeptUserEntity> allList = deptUserRepo.findAll();
     List<TreeNodeInfo> treeNodeList = new ArrayList<TreeNodeInfo>();
     // 实体转为pojo
     for (DeptUserEntity entity : allList) {
         TreeNodeInfo info = new TreeNodeInfo();
         BeanUtils.copyProperties(entity, info);
         treeNodeList.add(info);
     }
     // 获取根部门(应该是一个根部门)
     List<DeptUserEntity> rootEntity = deptUserRepo.findRootDept();
     String pid = rootEntity.get(0).getDeptId();
     return (Object) getDeptTreeFun(pid, treeNodeList);
    }
    

Tags: