element UI table横向树结合checkbox进行多选,实现各个节点的[全选,半选,不选]状态附带模拟数据

news2025/3/9 10:42:58

element UI table横向树结合checkbox进行多选,实现各个节点的[全选,半选,不选]状态,包含模拟数据

思路:

步骤一、后端返回tree格式数据,先结合element-ui的table的数据格式要求,将tree转换成table数据,进行行列的合并。
步骤二、拿到数据,递归遍历后将选中数据的id保存,进行回显操作。
步骤三、将每个checkbox进行绑定方法,此方法将作为分叉,如果当前checkbox属于父亲节点,判断当前的选中状态进行勾选,当前节点父亲节点,祖父节点和下级孩子节点进行相应的选中和状态修改,如果当前节点是最底层节点,则只需要选中上级及其上上级的节点和判断上级及上上级的状态和选中状态。重点:根据当前节点id,当前节点父节点id,子节点id,根据选中id存放的数组判树中checkbox的选中状态【半选,全选,不选】
步骤四、勾选后,调用 fatherSelectedState(i) 和 this.sonSelectedState(i) 设置当前节点下父节点,祖父节点,子节点,孙子节点的选中状态,重新刷新table树数据

elemnt 横向树,角色授权,全选半选状态

table所需要的数据格式

{
                    id:"platform-1",
                    name:"基础信息模块1",
                    "menuType": "0",
                    children:[
                        {
                            id:"1-1",
                            name:"用户模块权限1-1",
                            menuType: "1",
                            children:[
                                {
                                    id:"1-1-1",
                                    name:"用户管理1-1-1",
                                    menuType: "2",
                                    children:[
                                        {
                                            id:"1-1-1-1",
                                            name:"组织树管理1-1-1-1",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"1-1-1-1-1",
                                                    name:"新增组织树1-1-1-1-1",
                                                    menuType: "4",
                                                    checkFlag:true,
                                                },
                                                {
                                                    id:"1-1-1-1-2",
                                                    name:"编辑组织树信息1-1-1-1-2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-1-1-1-3",
                                                    name:"删除组织树1-1-1-1-3",
                                                    menuType: "4",
                                                }
                                            ]
                                        },
                                        {
                                            id:"1-1-1-2",
                                            name:"用户管理1-1-1-2",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"1-1-1-2-1",
                                                    name:"新增组织树1-1-1-2-1",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-1-1-2-2",
                                                    name:"编辑组织树信息1-1-1-2-2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-1-1-2-3",
                                                    name:"删除组织树1-1-1-2-3",
                                                    menuType: "4",
                                                }
                                            ]
                                        }
                                    ]
                                },
                                {
                                    id:"1-1-2",
                                    name:"角色权限管理1-1-2",
                                    menuType: "2",
                                    children:[
                                        {
                                            id:"1-1-2-1",
                                            name:"角色权限管理1-1-2-1",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"1-1-2-1-1",
                                                    name:"角色权限管理1-1-2-1-1",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-1-2-1-2",
                                                    name:"角色权限管理1-1-2-1-2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-1-2-1-3",
                                                    name:"角色权限管理1-1-2-1-3",
                                                    menuType: "4",
                                                }
                                            ]
                                        },
                                    ],
                                }
                            ]
                        },
                        {
                            id:"1-2",
                            name:"用户模块权限1-2", 
                            menuType: "1", 
                             children:[
                                {
                                    id:"1-2-1",
                                    name:"用户管理1-2-1",
                                    menuType: "2", 
                                    children:[
                                        {
                                            id:"1-2-1-1",
                                            name:"组织树管理1-2-1-1",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"1-2-1-1-1",
                                                    name:"新增组织树2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-2-1-1-2",
                                                    name:"编辑组织树信息2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-2-1-1-3",
                                                    name:"删除组织树2",
                                                    menuType: "4",
                                                }
                                            ]
                                        },
                                        {
                                            id:"1-2-1-2",
                                            name:"用户管理1-2-1-2",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"1-2-1-2-1",
                                                    name:"新增组织树2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-2-1-2-2",
                                                    name:"编辑组织树信息2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-2-1-2-3",
                                                    name:"删除组织树2",
                                                    menuType: "4",
                                                }
                                            ]
                                        }
                                    ]
                                },
                                {
                                    id:"1-2-2",
                                    name:"角色权限管理1-2-2",
                                    menuType: "2",
                                    children:[
                                        {
                                            id:"1-2-2-1",
                                            name:"角色权限管理",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"1-2-2-1-1",
                                                    name:"角色权限管理",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-2-2-1-2",
                                                    name:"角色权限管理",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"1-2-2-1-3",
                                                    name:"角色权限管理",
                                                    menuType: "4",
                                                }
                                            ]
                                        },
                                    ],
                                }
                            ]
                        }
                    ]
                },
                {
                    id:"platform-2",
                    name:"基础信息模块2",
                    menuType: "0",
                    children:[
                        {
                            id:"2-1",
                            name:"用户模块权限2-1",
                            menuType: "1",
                            children:[
                                {
                                    id:"2-1-1",
                                    name:"用户管理1",
                                    menuType: "2",
                                    children:[
                                        {
                                            id:"2-1-1-1",
                                            name:"组织树管理2AAA",
                                            menuType: "3",
                                            children:[
                                                {
                                                    id:"2-1-1-1-1",
                                                    name:"新增组织树2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"2-1-1-1-2",
                                                    name:"编辑组织树信息2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"2-1-1-1-3",
                                                    name:"删除组织树2",
                                                    menuType: "4",
                                                }
                                            ]
                                        },
                                        {
                                            id:"2-1-1-2A",
                                            name:"用户管理3",
                                            menuType: "4",
                                            children:[]
                                        },
                                        {
                                            id:"2-1-1-2B",
                                            name:"用户管理3",
                                            menuType: "4",
                                            children:[]
                                        },
                                        {
                                            id:"2-1-1-2C",
                                            name:"用户管理3",
                                            menuType: "4",
                                            children:[]
                                        },{
                                            id:"2-1-1-2D",
                                            name:"用户管理3",
                                            menuType: "4",
                                            children:[
                                              
                                            ]
                                        }
                                    ]
                                },
                                {
                                    id:"2-1-2",
                                    name:"角色权限管理2-1-2",
                                    menuType: "2",
                                    children:[
                                        {
                                            id:"2-1-2-1",
                                            menuType: "3",
                                            name:"角色权限管理2",
                                            children:[
                                                {
                                                    id:"2-1-2-1-1",
                                                    name:"角色权限管理2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"2-1-2-1-2",
                                                    name:"角色权限管理2",
                                                    menuType: "4",
                                                },
                                                {
                                                    id:"2-1-2-1-3",
                                                    name:"角色权限管理2aaaa",
                                                    menuType: "4",
                                                }
                                            ]
                                        },
                                    ],
                                }
                            ]
                        }
                    ]
                }

其中“menuType”代表着当前树的各个层级,最多四层,如图所示,功能层是最后两层数据的信息,所需需要将最后两层的属性“children”改为“functionChildren”,并删除children

        processingTreeData(tree){
            //遍历树  获取id数组
            for(let i=0;i<tree.length;i++){
                //功能层和其他的children区分开来,使用functionChidlren来替代children,注意:删除children
                if(tree[i].menuType==="2"){
                    tree[i].functionChildren = tree[i].children
                    delete tree[i].children;
                }
                if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                    this.processingTreeData(tree[i].children);
                }
            }
            return
        },

递归调用,拿到选中数据

开始拿到默认选中的数据,我的当前需求为【倒数第二层不做提交】,所以我要拿到倒数第二层的数据,提交时进行剔除
//拿到默认选中,和倒数第二层数据

 processingTreeDataA(tree){
        //遍历树  获取id数组
        for(let i=0;i<tree.length;i++){
            //根据需求提交的时候去除第一层和倒数第二层的id
            if(tree[i].menuType==="3" || tree[i].menuType==="0"){
                this.treeModelIds.push(tree[i].id)
            }
            //树中根据checkFlag来判断当前是否选中
            if(tree[i].checkFlag===true){
                this.treeSelectIds.push(tree[i].id)
            }
            if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                this.processingTreeDataA(tree[i].children);
            }
        }
        return
    },

功能权限树默认选中

//功能权限默认选中
        treeSekectDefault(){
            this.treeSelectIds.forEach(item=>{
                let node = this.searchTree(this.treeData,item)
                this.fatherSelectedState(node)
                this.sonSelectedState(node)
            })
        },

判断状态的主要方法[根据每个节点,判断当前节点的选中状态]

// 判断一个数组中是否包含另一个数组中的任意值(false不包含,true包含)
        isInclude(data) {
            let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) > -1) {
                    found = true
                    break
                }
            }
            return found
        },
        // 判断一个数组中是否全部在另一个数组中(true不全部包含) 
        isIncludeArr(data) {
            // let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) === -1) {
                return true
                }
            }
            return false
        },
   //根据id找到节点
    searchTree(nodes, searchKey) {
          for (let i = 0; i < nodes.length; i++) {
              if (nodes[i].id === searchKey) {
                  return nodes[i]
              } else {
                  if (nodes[i].children && nodes[i].children.length > 0) {
                      let res = this.searchTree(nodes[i].children, searchKey);
                      if (res) {
                          return res
                      }
                  }else if(nodes[i].functionChildren && nodes[i].functionChildren.length > 0){
                      let res = this.searchTree(nodes[i].functionChildren, searchKey);
                      if (res) {
                          return res
                      }
                  }
              }
          }
          return null
      },
    //找到当前节点的所有父节点  data:要遍历的数据, target:查找目标, result用于装查找结果的数组
        findNodeAndParentsById(tree, id, parents = []) {
            for (const node of tree) {
                if (node.id === id) {
                    return [...parents, node.id];
                }
                if (node.children) {
                    const result = this.findNodeAndParentsById(node.children, id, [...parents,node.id,]);
                    if (result) {
                        return result;
                    }
                }else if(node.functionChildren){
                    const result = this.findNodeAndParentsById(node.functionChildren, id, [...parents,node.id,]);
                    if (result) {
                        return result;
                    }
                }
            }
            return null;
        },
        
        //遍历当前节点下的id
        getAllIds(tree, result) {
            //遍历树  获取id数组
            for(let i=0;i<tree.length;i++){
                result.push(tree[i].id)
                if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                    this.getAllIds(tree[i].children, result);
                }else if(typeof(tree[i].functionChildren)!=="undefined" && tree[i].functionChildren!==null && tree[i].functionChildren.length>0){
                    this.getAllIds(tree[i].functionChildren, result);
                }
            }
            return result;
        },
         //断一个数组中是否包含另一个数组中的任意值(false不包含,true包含)
        isInclude(data) {
            let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) > -1) {
                    found = true
                    break
                }
            }
            return found
        },
        // 判断一个数组中是否全部在另一个数组中(true不全部包含)
        isIncludeArr(data) {
            // let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) === -1) {
                    return false
                }
            }
            return true
        },

重点方法!!![checkbox 的选中方法],一开始checkbox进行修改后,数据改变但是table中的视图并未改变,

解决方法1:当选中时候,处理数据,从新刷新表格和数据,使用table中的:key=“itemKey”,itemKey:Math.random(),来进行刷新表格,但是每次刷新都会回滚到最顶层,解决每次刷新滚动回到顶部问题,使用了refreshTable方法,此方法可以刷新列表后回滚到上一次选中的位置,但是频繁出现闪屏问题,弃用
解决方法2:将el-checkbox中绑定key,惊讶的发现,数据变化了视图跟着变化!!!

果断使用方法二
el-table中el-checkbox绑定数据改变了,视图未发生变化解决方法
![](https://img-blog.csdnimg.cn/219e14289dcb4a0fbeb1cf16e9c0189c.png

checkboxChange(e,i){
           this.$nextTick(()=>{
            if((typeof(i.children)!=="undefined" && i.children.length>0) || (typeof(i.functionChildren)!=="undefined" && i.functionChildren.length>0)){  //如果当前节点为父节点
               this.$nextTick(()=>{
                  if((i.checked===false && i.indeterminate===false) || (i.checked===true && i.indeterminate===true)){  //未选中:如果当前父节点未选中,则选中所有子节点
                    let cruuentNode = this.searchTree(this.treeData,i.id)
                    let fatherId = this.findNodeAndParentsById(this.treeData,i.id,[])
                    let temIdsArr = this.getAllIds([cruuentNode],[]) 
                    for(let i=0;i<fatherId.length;i++){
                        if(this.treeSelectIds.indexOf(fatherId[i])===-1){
                            this.treeSelectIds.push(fatherId[i])
                            let cruuentNodeB = this.searchTree(this.treeData,fatherId[i])
                            cruuentNodeB.checked = true
                        }
                    }
                    for(let i=0;i<temIdsArr.length;i++){
                         if(this.treeSelectIds.indexOf(temIdsArr[i])===-1){
                            this.treeSelectIds.push(temIdsArr[i])
                            let cruuentNodeA = this.searchTree(this.treeData,temIdsArr[i])
                            cruuentNodeA.checked = true
                         }
                    }
                    this.fatherSelectedState(i)
                    this.sonSelectedState(i)
                  }else if(i.checked===true && i.indeterminate===false){ //全选:如果当前是全选状态,点击后子节点全部去除
                    let temIdsArr = this.getAllIds([i],[])   //获取当前节点下的所有节点id              
                    for(let i=0;i<temIdsArr.length;i++){
                        this.treeSelectIds.splice(this.treeSelectIds.indexOf(temIdsArr[i]), 1)  
                    }
                    let fatherId = this.findNodeAndParentsById(this.treeData,i.id,[])  //拿到当前节点的所有父节点的id
                    for(let a=fatherId.length-1;a>=0;a--){ //从叶子节点开始遍历到最顶层
                        let cruuentNode = this.searchTree(this.treeData,fatherId[a]) //获取到父节点的内容
                        let temIdsArr = this.getAllIds([cruuentNode],[])  //获取当前父节点下的所有子节点id
                        let quchuFistId = temIdsArr.filter((element, index) => index > 0) //剔除当前父节点自己本身的节点id
                         if(this.isInclude(quchuFistId)===false && this.treeSelectIds.indexOf(fatherId[a])>-1){  //如果当前节点的子节点的所有id不在treeSelectIds中,并且当前父节点所属子节点有任意值存在,则剔除
                            this.treeSelectIds.splice(this.treeSelectIds.indexOf(fatherId[a]), 1) 
                         }
                    }
                    this.fatherSelectedState(i)
                    this.sonSelectedState(i) 
                  }
               })
            }else {  //如果当前节点不是父节点
                if(e){ //当前节点选中状态
                    //  //根据ID获取所有 父节点,遍历父节点,编辑节点数据,如果treeSelectIds里面存在则不新增,如果不存在则新增
                    this.findNodeAndParentsById(this.treeData,i.id,[]).forEach(element => {
                        let cruuentNode = this.searchTree(this.treeData,element)
                        cruuentNode.checked = true
                        // 如果存在id则不新增
                        if(this.treeSelectIds.indexOf(cruuentNode.id)===-1){
                            this.treeSelectIds.push(element)
                        }
                        // this.searchTree(this.treeData,element)  //               
                    });
                }else{  //当前节点未选中
                    let fatherId = this.findNodeAndParentsById(this.treeData,i.id,[])  //获取所有父亲节点id
                    let findNodeById = this.findNodeAndParentsById(this.treeData,i.id,[]).filter((element, index) => index > 0)  //获取父节点id不包含本节点id
                    for(let i=fatherId.length-1;i>=0;i--){  //从底层节点开始遍历到顶层节点
                        let cruuentNode = this.searchTree(this.treeData,fatherId[i])  //根据父节点id找到该节点,拿到遍历的父节点
                        let temIdsArr = this.getAllIds([cruuentNode],[]) //获取当前选中节点父亲节点下面的所有id
                        let quchuFistId = temIdsArr.filter((element, index) => index > 0) //去除当前节点父节点下的所有id,并删除父节点本身id
                         if(this.isInclude(quchuFistId)===false){  // 判断父节点在treeSelectIds上的选中状态,如果一个都不在treeSelectIds里面,则去除当前节点的id
                            this.treeSelectIds.splice(this.treeSelectIds.indexOf(temIdsArr[0]), 1)
                         }  
                    }
                }
            }
            //获取当前节点下的所有id
                this.fatherSelectedState(i) //设置该节点在父节点的选中状态 
                this.sonSelectedState(i) //设置该节点下所有父节点的所有选中状态
                this.$nextTick(()=>{
                    this.treeToTableData()  //重新编辑table树
                    this.refreshTable() //无感刷新table树结构,滚动记录 
                })
           })
           this.$forceUpdate()
        },
        //设置该节点下所有子节点的所有选中状态
        sonSelectedState(i){
            this.getAllIds([i],[]).forEach(element => {
                let cruuentNode = this.searchTree(this.treeData,element)
                let a = this.getAllIds([cruuentNode],[]).filter((element, index) => index > 0)
                if(this.isIncludeArr(this.getAllIds([cruuentNode],[])) && this.isInclude(this.getAllIds([cruuentNode],[]))){  //全选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(this.getAllIds([cruuentNode],[]))===false && this.isInclude(this.getAllIds([cruuentNode],[]))===true){  //半选
                    cruuentNode.indeterminate = true
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(this.getAllIds([cruuentNode],[]))===false && this.isInclude(this.getAllIds([cruuentNode],[]))===false){  //不选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = false
                }             
            });
        },
        //设置该节点在父节点的选中状态
        fatherSelectedState(i){
            this.findNodeAndParentsById(this.treeData,i.id,[]).forEach(element => {
                let cruuentNode = this.searchTree(this.treeData,element)
                let a = this.getAllIds([cruuentNode],[]).filter((element, index) => index > 0)
                if(this.isIncludeArr(a) && this.isInclude(a)){  //全选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(a)===false && this.isInclude(a)===true){  //半选
                    cruuentNode.indeterminate = true
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(a)===false && this.isInclude(a)===false){  //不选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = false
                }             
            });
        },

将tree树状格式转换成el-table表格可识别格式,并进行单元格合并

  1. 将tree数据转换成二维表格数据
  2. 合并行或列的计算方法
  3. 表格单元格合并-----行
//tree数据处理
        treeToTableData() {
            //将树状结构格式转换成二维数组表格形式
            let ewArr = this.parseTreeToRow(this.treeData);
            let tableData = [];
            ewArr.map((item,index) => {
                if(item.length===2){
                    item.push({
                        label:item[1].label+item.length,
                        isChecked:false,
                    })
                }else if(item.length===1){
                    item.push({label:item[0].label+"1",isChecked:false,})
                    item.push({label:item[0].label+"2",isChecked:false,})
                }
                let obj = {};
                item.map((itemc, indexb) => {
                    // typeof(itemc.functionChildren)!=="undefined"?itemc.functionChildren:null
                    obj["index" + (indexb + 1)] = {
                        id: itemc.id,
                        label: itemc.label,
                        functionChildren:(itemc.functionChildren !== null)?itemc.functionChildren:[],
                        children:(itemc.children !== null)?itemc.children:[],
                        checked:(typeof itemc.checked !== "undefined")?itemc.checked:false,
                        isChecked:itemc.isChecked===false?itemc.isChecked:true,
                        indeterminate:( typeof itemc.indeterminate !== "undefined")?itemc.indeterminate:false
                    };
                    if (typeof itemc.children !== "undefined") {
                        obj.children = { data: itemc.children };
                    }
                });
                tableData.push(obj);
            });
            this.tableData = tableData;
        },
        /**
         * 递归-----将树结构数据格式,转化为,二维数组 表格形式
         * @param node 树的源数据
         * @param data 树转化为二维数组的数据
         * @param row 临时存储数据
         * @returns {*[]}
         */
        parseTreeToRow(node, data = [], row = []) {            
            node.map((item) => {
                let obj = {
                    id: item.id,
                    label:item.name,
                    functionChildren:typeof(item.functionChildren)!=="undefined"?item.functionChildren:null,
                    children:(item.children !== null)?item.children:null,
                    checked:(typeof item.checked !== "undefined")?item.checked:false,
                    indeterminate:(typeof item.indeterminate !== "undefined")?item.indeterminate:false
                };
                if (typeof item.children !== "undefined") {
                    obj.children = item.children.length > 0 ? item.children : [];
                }
                if (item.children && item.children.length != 0) {
                    this.parseTreeToRow(item.children, data, [...row, obj]);
                } else {
                    data.push([...row, obj]);
                }
            });
            return data;
        },
        /**
         * 合并行或列的计算方法
         */
        tableSpanMethod({ row, column, rowIndex, columnIndex }) {
            return {
                rowspan:
                columnIndex < 3
                    ? this.mergeRows(
                        row[column.property],
                        this.tableData,
                        rowIndex,
                        column.property
                    )
                    : 1,
                colspan: 1,
            };
        },
        /**
         * 表格单元格合并-----行
         * @param {Object} value      当前单元格的值
         * @param {Object} data       当前表格所有数据
         * @param {Object} index      当前单元格的值所在 行 索引
         * @param {Object} property   当前列的property
         * @returns {number}          待合并单元格数量
         */
        mergeRows(value, data, index, property) {
            // 判断 当前行的该列数据 与 上一行的该列数据 是否相等
            if (index !== 0 && value.label === data[index - 1][property].label) {
                // 返回 0 使表格被跨 行 的那个单元格不会渲染
                return 0;
            }
            // 判断 当前行的该列数据 与 下一行的该列数据 是否相等  
            let rowSpan = 1;
            for (let i = index + 1; i < data.length; i++) {  
                if (value.label !== data[i][property].label) {
                    break;
                }
                rowSpan++;
            }
            return rowSpan;
        },

完整代码粘贴,附带模拟数据:

<template>
  <div>
    <el-drawer class="el-drawer-role" title="我是标题" :visible.sync="drawer" size="70%" :with-header="false" :before-close="drawerClose">
            <el-tabs style="padding: 20px;"  v-model="activeName" @tab-click="handleClick">
                <el-tab-pane label="应用权限" name="first">
                    <el-table ref="multipleTable" border  :data="appTableData" tooltip-effect="dark" style="width: 100%"
                         @selection-change="handleSelectionChange">
                        <el-table-column type="selection" align="center" width="55"></el-table-column>
                        <el-table-column prop="key" label="应用编码" align="center"  width="120"></el-table-column>
                        <el-table-column prop="name" label="应用名称" align="center"  show-overflow-tooltip></el-table-column>
                    </el-table>
                </el-tab-pane>
                <el-tab-pane label="功能权限" name="second">
                    <el-input
                        v-model="searchContent"
                        placeholder="搜索"
                        clearable
                        size="small"
                        prefix-icon="el-icon-search"
                        style="margin-bottom: 20px"
                    />
                    <el-table style="margin-bottom: 70px;" :key="itemKey" :height="contentHeight"  class="ganteTable" ref="table" :span-method="tableSpanMethod" :data="tableData" border align="center" size="mini" >
                        <el-table-column align="center" prop="index1" label="应用" width="200px">
                            <template slot-scope="scope">
                                {{ scope.row.index1.checked }}
                                <el-checkbox  @change="checkboxChange($event,scope.row.index1)" :key="scope.row.index1.checked+scope.row.index1.indeterminate+''" :indeterminate="scope.row.index1.indeterminate"  :checked="scope.row.index1.checked" :label="scope.row.index1.label"></el-checkbox><br />
                            </template>
                        </el-table-column>
                        <el-table-column align="center" prop="index2" label="模块" width="200px">
                            <template slot-scope="scope">
                                
                                {{ scope.row.index2.checked }}
                                <el-checkbox v-if="scope.row.index2.isChecked" :key="scope.row.index2.checked+scope.row.index2.indeterminate+''" @change="checkboxChange($event,scope.row.index2)" :indeterminate="scope.row.index2.indeterminate"  :checked="scope.row.index2.checked" :label="scope.row.index2.label"></el-checkbox><br />
                            </template>
                        </el-table-column>
                        <el-table-column align="center" prop="index3" label="界面"  width="200px">
                            <template slot-scope="scope">
                                {{ scope.row.index3.checked }}
                                <el-checkbox v-if="scope.row.index3.isChecked"  :key="scope.row.index3.checked+scope.row.index3.indeterminate+''" @change="checkboxChange($event,scope.row.index3)" :indeterminate="scope.row.index3.indeterminate"  :checked="scope.row.index3.checked" :label="scope.row.index3.label"></el-checkbox><br />
                            </template>
                        </el-table-column>
                        <el-table-column prop="children" label="功能" >
                            <template slot-scope="scope">
                                <span  v-for="item in scope.row.index3.functionChildren" :key="item.id">
                                    <div style="margin: 7px;" v-if="item.menuType==='3'">
                                        {{ item.name }}<br />
                                        <span style="margin: 7px;margin-left:10px;" v-for="item2 in item.children" :key="item2.id">
                                            <el-checkbox :checked="item2.checked" :indeterminate="item2.indeterminate" :key="item2.checked+item2.indeterminate+''" @change="checkboxChange($event,item2)">
                                                <span v-if="item2.name.indexOf(searchContent)>-1">
                                                    <span style="color: #f50">{{ searchContent }}</span>
                                                        {{ item2.name.substr(item2.name.indexOf(searchContent) + searchContent.length) }}
                                                </span>
                                                <span v-else>
                                                    {{ item2.name }}
                                                </span>
                                            </el-checkbox>
                                        </span>
                                    </div>
                                    <span v-if="item.menuType==='4'" style="margin: 7px;margin-left:10px;">
                                        <el-checkbox @change="checkboxChange($event,item)" :key="item.checked+item.indeterminate+''" :indeterminate="item.indeterminate" :checked="item.checked" :label="item.name"></el-checkbox>
                                    </span>
                                </span>
                            </template>
                        </el-table-column>
                    </el-table>                  
                </el-tab-pane>
            </el-tabs>
            <div class="demo-drawer__footer" style="position: fixed;bottom: 20px;right: 20px; background: white; ">
                <el-button @click="drawerClose">取 消</el-button>
                <el-button type="primary" @click="submitRole()">确定</el-button>
            </div>
        </el-drawer>
  </div>
</template>
<script>
import { platformGetList,getPlatFormByRoleId,getRolePermissionTreeList,assignRolePermission } from "@/api/userInfo/role"
export default {
    data(){
        return {
            temObj:{}, 
            contentHeight:'0px',
            searchContent:"",
            defaultTreeSelect:[],
            appTableDefaultSelect:[],
            appTableData: [],
            multipleSelection: [],
            checkAll:true,
            tableData:[],
            treeSelectIds:[],
            itemKey:Math.random(),
            drawer:false, //抽屉打开关闭状态
            activeName:"first",  //当前tab激活的状态
            treeModelIds:[], //模块ids不需要传递,和第一层次ID不需要传递
            treeData: [
                // {
                //     id:"platform-1",
                //     name:"基础信息模块1",
                //     "menuType": "0",
                //     children:[
                //         {
                //             id:"1-1",
                //             name:"用户模块权限1-1",
                //             menuType: "1",
                //             children:[
                //                 {
                //                     id:"1-1-1",
                //                     name:"用户管理1-1-1",
                //                     menuType: "2",
                //                     children:[
                //                         {
                //                             id:"1-1-1-1",
                //                             name:"组织树管理1-1-1-1",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"1-1-1-1-1",
                //                                     name:"新增组织树1-1-1-1-1",
                //                                     menuType: "4",
                //                                     checkFlag:true,
                //                                 },
                //                                 {
                //                                     id:"1-1-1-1-2",
                //                                     name:"编辑组织树信息1-1-1-1-2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-1-1-1-3",
                //                                     name:"删除组织树1-1-1-1-3",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         },
                //                         {
                //                             id:"1-1-1-2",
                //                             name:"用户管理1-1-1-2",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"1-1-1-2-1",
                //                                     name:"新增组织树1-1-1-2-1",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-1-1-2-2",
                //                                     name:"编辑组织树信息1-1-1-2-2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-1-1-2-3",
                //                                     name:"删除组织树1-1-1-2-3",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         }
                //                     ]
                //                 },
                //                 {
                //                     id:"1-1-2",
                //                     name:"角色权限管理1-1-2",
                //                     menuType: "2",
                //                     children:[
                //                         {
                //                             id:"1-1-2-1",
                //                             name:"角色权限管理1-1-2-1",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"1-1-2-1-1",
                //                                     name:"角色权限管理1-1-2-1-1",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-1-2-1-2",
                //                                     name:"角色权限管理1-1-2-1-2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-1-2-1-3",
                //                                     name:"角色权限管理1-1-2-1-3",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         },
                //                     ],
                //                 }
                //             ]
                //         },
                //         {
                //             id:"1-2",
                //             name:"用户模块权限1-2", 
                //             menuType: "1", 
                //              children:[
                //                 {
                //                     id:"1-2-1",
                //                     name:"用户管理1-2-1",
                //                     menuType: "2", 
                //                     children:[
                //                         {
                //                             id:"1-2-1-1",
                //                             name:"组织树管理1-2-1-1",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"1-2-1-1-1",
                //                                     name:"新增组织树2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-2-1-1-2",
                //                                     name:"编辑组织树信息2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-2-1-1-3",
                //                                     name:"删除组织树2",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         },
                //                         {
                //                             id:"1-2-1-2",
                //                             name:"用户管理1-2-1-2",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"1-2-1-2-1",
                //                                     name:"新增组织树2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-2-1-2-2",
                //                                     name:"编辑组织树信息2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-2-1-2-3",
                //                                     name:"删除组织树2",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         }
                //                     ]
                //                 },
                //                 {
                //                     id:"1-2-2",
                //                     name:"角色权限管理1-2-2",
                //                     menuType: "2",
                //                     children:[
                //                         {
                //                             id:"1-2-2-1",
                //                             name:"角色权限管理",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"1-2-2-1-1",
                //                                     name:"角色权限管理",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-2-2-1-2",
                //                                     name:"角色权限管理",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"1-2-2-1-3",
                //                                     name:"角色权限管理",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         },
                //                     ],
                //                 }
                //             ]
                //         }
                //     ]
                // },
                // {
                //     id:"platform-2",
                //     name:"基础信息模块2",
                //     menuType: "0",
                //     children:[
                //         {
                //             id:"2-1",
                //             name:"用户模块权限2-1",
                //             menuType: "1",
                //             children:[
                //                 {
                //                     id:"2-1-1",
                //                     name:"用户管理1",
                //                     menuType: "2",
                //                     children:[
                //                         {
                //                             id:"2-1-1-1",
                //                             name:"组织树管理2AAA",
                //                             menuType: "3",
                //                             children:[
                //                                 {
                //                                     id:"2-1-1-1-1",
                //                                     name:"新增组织树2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"2-1-1-1-2",
                //                                     name:"编辑组织树信息2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"2-1-1-1-3",
                //                                     name:"删除组织树2",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         },
                //                         {
                //                             id:"2-1-1-2A",
                //                             name:"用户管理3",
                //                             menuType: "4",
                //                             children:[]
                //                         },
                //                         {
                //                             id:"2-1-1-2B",
                //                             name:"用户管理3",
                //                             menuType: "4",
                //                             children:[]
                //                         },
                //                         {
                //                             id:"2-1-1-2C",
                //                             name:"用户管理3",
                //                             menuType: "4",
                //                             children:[]
                //                         },{
                //                             id:"2-1-1-2D",
                //                             name:"用户管理3",
                //                             menuType: "4",
                //                             children:[
                                              
                //                             ]
                //                         }
                //                     ]
                //                 },
                //                 {
                //                     id:"2-1-2",
                //                     name:"角色权限管理2-1-2",
                //                     menuType: "2",
                //                     children:[
                //                         {
                //                             id:"2-1-2-1",
                //                             menuType: "3",
                //                             name:"角色权限管理2",
                //                             children:[
                //                                 {
                //                                     id:"2-1-2-1-1",
                //                                     name:"角色权限管理2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"2-1-2-1-2",
                //                                     name:"角色权限管理2",
                //                                     menuType: "4",
                //                                 },
                //                                 {
                //                                     id:"2-1-2-1-3",
                //                                     name:"角色权限管理2aaaa",
                //                                     menuType: "4",
                //                                 }
                //                             ]
                //                         },
                //                     ],
                //                 }
                //             ]
                //         }
                //     ]
                // }
            ]
        }
    },
    created(){
    },
    mounted(){  
    },
    methods:{
        //获取应用平台权限
        platformGetList(roleId){
            this.multipleSelection = []
            getPlatFormByRoleId({roleId:roleId}).then(res=>{
                this.appTableData = res.data
                this.$nextTick(()=>{
                    console.log("this.appTableData",this.appTableData)
                    // this.defaultSelect()
                    this.appTableData.forEach(item=>{
                        if(item.selFlag){
                            //再遍历数组,将数据放入方法中  
                            this.$refs.multipleTable.toggleRowSelection(item,true)
                        }
                    })
                })
            })
        },
        //最后一层加上functionChildren
        processingTreeData(tree){
            //遍历树  获取id数组
            for(let i=0;i<tree.length;i++){
                //功能层和其他的children区分开来,使用functionChidlren来替代children,注意:删除children
                if(tree[i].menuType==="2"){
                    tree[i].functionChildren = tree[i].children
                    delete tree[i].children;
                }
                if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                    this.processingTreeData(tree[i].children);
                }
            }
            return
        },
        //拿到默认选中,和倒数第二层数据
         processingTreeDataA(tree){
            //遍历树  获取id数组
            for(let i=0;i<tree.length;i++){
                //根据需求提交的时候去除第一层和倒数第二层的id
                if(tree[i].menuType==="3" || tree[i].menuType==="0"){
                    this.treeModelIds.push(tree[i].id)
                }
                //树中根据checkFlag来判断当前是否选中
                if(tree[i].checkFlag===true){
                    this.treeSelectIds.push(tree[i].id)
                }
                if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                    this.processingTreeDataA(tree[i].children);
                }
            }
            return
        },
        //菜单层选中状态
        processingTreeDataB(tree){
            //遍历树  获取id数组
            for(let i=0;i<tree.length;i++){
                //判断菜单那一成是否需要选中
                if(tree[i].menuType==="3"){
                    //遍历菜单层,判断菜单层下的所有按钮权限只要有一个选中,根据这一个选中判断菜单层的选中状态
                    for(let j=0;j<tree[i].children.length;j++){
                        //如果菜单下的按钮权限有一个包含在treeSelectIds中,则当前菜单被选中
                        if(this.treeSelectIds.indexOf(tree[i].children[j].id)!==-1){
                            //按钮id存在,并且treeSelectIds中没有当前id,则push操作
                            if(this.treeSelectIds.indexOf(tree[i].id)===-1){
                                //则当前菜单被选中后结束当前循环,拿到id,根据id的父节点,子节点判定当前菜单的选中状态
                                this.treeSelectIds.push(tree[i].id)
                                break
                            }
                        }
                    }
                }
                if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                    this.processingTreeDataB(tree[i].children);
                }
            }
            return
        },
        //提交
        submitRole(){
            //去除第一层和倒数第二层的id
            let newArr = this.treeSelectIds .filter((x) => !this.treeModelIds.some((item) => x === item));
            let temObj = {}
            temObj.departId = this.temObj.departId
            temObj.roleId = this.temObj.roleId
            temObj.permissionIdList = newArr
            assignRolePermission(temObj).then(res=>{ 
                this.$message({message: '角色权限授权成功', type: 'success'}); 
            })
        },
        //应用列表默认多选
        defaultSelect(){
            // //创建一个空数组用来存放默认数据
            // let list = []
            // //遍历表格的数据,再遍历需要在表格中反显的数据,两者的id一致
            // this.appTableData.forEach((item) => {
            //     this.appTableDefaultSelect.forEach(val => {
            //         if (val=== item.id) {
            //             // 把判断出来的默认表格数据push到创建的数组中
            //             list.push(item)
            //         }
            //     })
            // })
            // if (list) {
            //     //再遍历数组,将数据放入方法中  
            //     list.forEach((row) => {
            //         this.$refs.multipleTable.toggleRowSelection(row,true)
            //     })
            // }
        },
        //多选
        handleSelectionChange(val) {
            this.multipleSelection = []
            val.forEach(item=>{
                this.multipleSelection.push(item.id);
            })
            //如果有选中则请求选中的所属树
            if(this.multipleSelection.length>0){
                this.temObj.platformIdList = this.multipleSelection
                this.treeModelIds = []
                this.treeSelectIds = []
                getRolePermissionTreeList(this.temObj).then(res=>{
                    this.treeData = res.data
                    this.refreshTable()  //刷新tree表
                    this.processingTreeDataA(this.treeData) //拿到树中的已选中的id和第一层id和倒数第二次id
                    this.processingTreeDataB(this.treeData) //判断倒数第三层的选中状态,后端返回第三层没有返回选中状态,
                    this.processingTreeData(this.treeData) //给最后一层加上functionChidren
                    this.treeSekectDefault()  //功能权限树默认选中
                    this.treeToTableData() //将功能权限树转换成表格形式并合并单元格 
                    this.contentHeight = document.getElementsByClassName("el-drawer__body")[0].clientHeight-220+'px'
                })  
            } else {
                this.temObj.platformIdList = []
                this.treeData = []
            }               
        },
        //功能权限默认选中
        treeSekectDefault(){
            this.treeSelectIds.forEach(item=>{
                let node = this.searchTree(this.treeData,item)
                this.fatherSelectedState(node)
                this.sonSelectedState(node)
            })
        },
        // 判断一个数组中是否包含另一个数组中的任意值(false不包含,true包含)
        isInclude(data) {
            let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) > -1) {
                    found = true
                    break
                }
            }
            return found
        },
        // 判断一个数组中是否全部在另一个数组中(true不全部包含) 
        isIncludeArr(data) {
            // let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) === -1) {
                return true
                }
            }
            return false
        },
        //判断当前节点的选中状态,0未选中,1选中,2半选
        checkboxStatus(){
            this.searchTree(this.treeData,i.id)
        },
        //根据id找到节点
        searchTree(nodes, searchKey) {
            for (let i = 0; i < nodes.length; i++) {
                if (nodes[i].id === searchKey) {
                    return nodes[i]
                } else {
                    if (nodes[i].children && nodes[i].children.length > 0) {
                        let res = this.searchTree(nodes[i].children, searchKey);
                        if (res) {
                            return res
                        }
                    }else if(nodes[i].functionChildren && nodes[i].functionChildren.length > 0){
                        let res = this.searchTree(nodes[i].functionChildren, searchKey);
                        if (res) {
                            return res
                        }
                    }
                }
            }
            return null
        },
        //找到当前节点的所有父节点  data:要遍历的数据, target:查找目标, result用于装查找结果的数组
        findNodeAndParentsById(tree, id, parents = []) {
            for (const node of tree) {
                if (node.id === id) {
                    return [...parents, node.id];
                }
                if (node.children) {
                    const result = this.findNodeAndParentsById(node.children, id, [...parents,node.id,]);
                    if (result) {
                        return result;
                    }
                }else if(node.functionChildren){
                    const result = this.findNodeAndParentsById(node.functionChildren, id, [...parents,node.id,]);
                    if (result) {
                        return result;
                    }
                }
            }
            return null;
        },
        //遍历当前节点下的id
        getAllIds(tree, result) {
            //遍历树  获取id数组
            for(let i=0;i<tree.length;i++){
                result.push(tree[i].id)
                if(typeof(tree[i].children)!=="undefined" && tree[i].children!==null && tree[i].children.length>0){
                    this.getAllIds(tree[i].children, result);
                }else if(typeof(tree[i].functionChildren)!=="undefined" && tree[i].functionChildren!==null && tree[i].functionChildren.length>0){
                    this.getAllIds(tree[i].functionChildren, result);
                }
            }
            return result;
        },
        //断一个数组中是否包含另一个数组中的任意值(false不包含,true包含)
        isInclude(data) {
            let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) > -1) {
                    found = true
                    break
                }
            }
            return found
        },
        // 判断一个数组中是否全部在另一个数组中(true不全部包含)
        isIncludeArr(data) {
            // let found = false
            for (let i = 0; i < data.length; i++) {
                if (this.treeSelectIds.indexOf(data[i]) === -1) {
                    return false
                }
            }
            return true
        },
        //选中
        checkboxChange(e,i){
           this.$nextTick(()=>{
            if((typeof(i.children)!=="undefined" && i.children.length>0) || (typeof(i.functionChildren)!=="undefined" && i.functionChildren.length>0)){  //如果当前节点为父节点
               this.$nextTick(()=>{
                  if((i.checked===false && i.indeterminate===false) || (i.checked===true && i.indeterminate===true)){  //未选中:如果当前父节点未选中,则选中所有子节点
                    let cruuentNode = this.searchTree(this.treeData,i.id)
                    let fatherId = this.findNodeAndParentsById(this.treeData,i.id,[])
                    let temIdsArr = this.getAllIds([cruuentNode],[]) 
                    for(let i=0;i<fatherId.length;i++){
                        if(this.treeSelectIds.indexOf(fatherId[i])===-1){
                            this.treeSelectIds.push(fatherId[i])
                            let cruuentNodeB = this.searchTree(this.treeData,fatherId[i])
                            cruuentNodeB.checked = true
                        }
                    }
                    for(let i=0;i<temIdsArr.length;i++){
                         if(this.treeSelectIds.indexOf(temIdsArr[i])===-1){
                            this.treeSelectIds.push(temIdsArr[i])
                            let cruuentNodeA = this.searchTree(this.treeData,temIdsArr[i])
                            cruuentNodeA.checked = true
                         }
                    }
                    this.fatherSelectedState(i)
                    this.sonSelectedState(i)
                  }else if(i.checked===true && i.indeterminate===false){ //全选:如果当前是全选状态,点击后子节点全部去除
                    let temIdsArr = this.getAllIds([i],[])   //获取当前节点下的所有节点id              
                    for(let i=0;i<temIdsArr.length;i++){
                        this.treeSelectIds.splice(this.treeSelectIds.indexOf(temIdsArr[i]), 1)  
                    }
                    let fatherId = this.findNodeAndParentsById(this.treeData,i.id,[])  //拿到当前节点的所有父节点的id
                    for(let a=fatherId.length-1;a>=0;a--){ //从叶子节点开始遍历到最顶层
                        let cruuentNode = this.searchTree(this.treeData,fatherId[a]) //获取到父节点的内容
                        let temIdsArr = this.getAllIds([cruuentNode],[])  //获取当前父节点下的所有子节点id
                        let quchuFistId = temIdsArr.filter((element, index) => index > 0) //剔除当前父节点自己本身的节点id
                         if(this.isInclude(quchuFistId)===false && this.treeSelectIds.indexOf(fatherId[a])>-1){  //如果当前节点的子节点的所有id不在treeSelectIds中,并且当前父节点所属子节点有任意值存在,则剔除
                            this.treeSelectIds.splice(this.treeSelectIds.indexOf(fatherId[a]), 1) 
                         }
                    }
                    this.fatherSelectedState(i)
                    this.sonSelectedState(i) 
                  }
               })
            }else {  //如果当前节点不是父节点
                if(e){ //当前节点选中状态
                    //  //根据ID获取所有 父节点,遍历父节点,编辑节点数据,如果treeSelectIds里面存在则不新增,如果不存在则新增
                    this.findNodeAndParentsById(this.treeData,i.id,[]).forEach(element => {
                        let cruuentNode = this.searchTree(this.treeData,element)
                        cruuentNode.checked = true
                        // 如果存在id则不新增
                        if(this.treeSelectIds.indexOf(cruuentNode.id)===-1){
                            this.treeSelectIds.push(element)
                        }
                        // this.searchTree(this.treeData,element)  //               
                    });
                }else{  //当前节点未选中
                    let fatherId = this.findNodeAndParentsById(this.treeData,i.id,[])  //获取所有父亲节点id
                    let findNodeById = this.findNodeAndParentsById(this.treeData,i.id,[]).filter((element, index) => index > 0)  //获取父节点id不包含本节点id
                    for(let i=fatherId.length-1;i>=0;i--){  //从底层节点开始遍历到顶层节点
                        let cruuentNode = this.searchTree(this.treeData,fatherId[i])  //根据父节点id找到该节点,拿到遍历的父节点
                        let temIdsArr = this.getAllIds([cruuentNode],[]) //获取当前选中节点父亲节点下面的所有id
                        let quchuFistId = temIdsArr.filter((element, index) => index > 0) //去除当前节点父节点下的所有id,并删除父节点本身id
                         if(this.isInclude(quchuFistId)===false){  // 判断父节点在treeSelectIds上的选中状态,如果一个都不在treeSelectIds里面,则去除当前节点的id
                            this.treeSelectIds.splice(this.treeSelectIds.indexOf(temIdsArr[0]), 1)
                         }  
                    }
                }
            }
            //获取当前节点下的所有id
                this.fatherSelectedState(i) //设置该节点在父节点的选中状态 
                this.sonSelectedState(i) //设置该节点下所有父节点的所有选中状态
                this.$nextTick(()=>{
                    this.treeToTableData()  //重新编辑table树
                    this.refreshTable() //无感刷新table树结构,滚动记录 
                })
           })
           this.$forceUpdate()
        },
        /**
         * 刷新table时候,无感刷新,定位到上一次选中的滚动中
        */
        refreshTable() {
            // let beforeScrollTop = this.$refs.table.$el.querySelector('div.el-table__body-wrapper').scrollTop
            // // this.itemKey = Math.random()
            // this.$forceUpdate()
            // this.$nextTick(()=> {
            //     setTimeout(() => {
            //         this.$refs.table.$el.querySelector('div.el-table__body-wrapper').scrollTop = beforeScrollTop
            //     },0)
            // })
        },
        //设置该节点下所有子节点的所有选中状态
        sonSelectedState(i){
            this.getAllIds([i],[]).forEach(element => {
                let cruuentNode = this.searchTree(this.treeData,element)
                let a = this.getAllIds([cruuentNode],[]).filter((element, index) => index > 0)
                if(this.isIncludeArr(this.getAllIds([cruuentNode],[])) && this.isInclude(this.getAllIds([cruuentNode],[]))){  //全选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(this.getAllIds([cruuentNode],[]))===false && this.isInclude(this.getAllIds([cruuentNode],[]))===true){  //半选
                    cruuentNode.indeterminate = true
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(this.getAllIds([cruuentNode],[]))===false && this.isInclude(this.getAllIds([cruuentNode],[]))===false){  //不选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = false
                }             
            });
        },
        //设置该节点在父节点的选中状态
        fatherSelectedState(i){
            this.findNodeAndParentsById(this.treeData,i.id,[]).forEach(element => {
                let cruuentNode = this.searchTree(this.treeData,element)
                let a = this.getAllIds([cruuentNode],[]).filter((element, index) => index > 0)
                if(this.isIncludeArr(a) && this.isInclude(a)){  //全选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(a)===false && this.isInclude(a)===true){  //半选
                    cruuentNode.indeterminate = true
                    cruuentNode.checked = true
                }else if(this.isIncludeArr(a)===false && this.isInclude(a)===false){  //不选
                    cruuentNode.indeterminate = false
                    cruuentNode.checked = false
                }             
            });
        },
        //tab选项卡
        handleClick(tab, event) {
        },
        //分配权限
        assignPermissions(data){
            //获取平台列表
            this.platformGetList(data.roleId)
            this.temObj.departId = data.departId 
            this.temObj.roleId = data.roleId            
            this.drawer = true
        },
        //关闭窗口
        drawerClose(){
            this.activeName = "first"
            this.tableData = []
            this.treeSelectIds = []
            this.treeModelIds = []
            this.refreshTable() 
            this.drawer = false
        },
        //tree数据处理
        treeToTableData() {
            //将树状结构格式转换成二维数组表格形式
            let ewArr = this.parseTreeToRow(this.treeData);
            let tableData = [];
            ewArr.map((item,index) => {
                if(item.length===2){
                    item.push({
                        label:item[1].label+item.length,
                        isChecked:false,
                    })
                }else if(item.length===1){
                    item.push({label:item[0].label+"1",isChecked:false,})
                    item.push({label:item[0].label+"2",isChecked:false,})
                }
                let obj = {};
                item.map((itemc, indexb) => {
                    // typeof(itemc.functionChildren)!=="undefined"?itemc.functionChildren:null
                    obj["index" + (indexb + 1)] = {
                        id: itemc.id,
                        label: itemc.label,
                        functionChildren:(itemc.functionChildren !== null)?itemc.functionChildren:[],
                        children:(itemc.children !== null)?itemc.children:[],
                        checked:(typeof itemc.checked !== "undefined")?itemc.checked:false,
                        isChecked:itemc.isChecked===false?itemc.isChecked:true,
                        indeterminate:( typeof itemc.indeterminate !== "undefined")?itemc.indeterminate:false
                    };
                    if (typeof itemc.children !== "undefined") {
                        obj.children = { data: itemc.children };
                    }
                });
                tableData.push(obj);
            });
            this.tableData = tableData;
        },
        /**
         * 递归-----将树结构数据格式,转化为,二维数组 表格形式
         * @param node 树的源数据
         * @param data 树转化为二维数组的数据
         * @param row 临时存储数据
         * @returns {*[]}
         */
        parseTreeToRow(node, data = [], row = []) {            
            node.map((item) => {
                let obj = {
                    id: item.id,
                    label:item.name,
                    functionChildren:typeof(item.functionChildren)!=="undefined"?item.functionChildren:null,
                    children:(item.children !== null)?item.children:null,
                    checked:(typeof item.checked !== "undefined")?item.checked:false,
                    indeterminate:(typeof item.indeterminate !== "undefined")?item.indeterminate:false
                };
                if (typeof item.children !== "undefined") {
                    obj.children = item.children.length > 0 ? item.children : [];
                }
                if (item.children && item.children.length != 0) {
                    this.parseTreeToRow(item.children, data, [...row, obj]);
                } else {
                    data.push([...row, obj]);
                }
            });
            return data;
        },
        /**
         * 合并行或列的计算方法
         */
        tableSpanMethod({ row, column, rowIndex, columnIndex }) {
            return {
                rowspan:
                columnIndex < 3
                    ? this.mergeRows(
                        row[column.property],
                        this.tableData,
                        rowIndex,
                        column.property
                    )
                    : 1,
                colspan: 1,
            };
        },
        /**
         * 表格单元格合并-----行
         * @param {Object} value      当前单元格的值
         * @param {Object} data       当前表格所有数据
         * @param {Object} index      当前单元格的值所在 行 索引
         * @param {Object} property   当前列的property
         * @returns {number}          待合并单元格数量
         */
        mergeRows(value, data, index, property) {
            // 判断 当前行的该列数据 与 上一行的该列数据 是否相等
            if (index !== 0 && value.label === data[index - 1][property].label) {
                // 返回 0 使表格被跨 行 的那个单元格不会渲染
                return 0;
            }
            // 判断 当前行的该列数据 与 下一行的该列数据 是否相等  
            let rowSpan = 1;
            for (let i = index + 1; i < data.length; i++) {  
                if (value.label !== data[i][property].label) {
                    break;
                }
                rowSpan++;
            }
            return rowSpan;
        },
        //递归遍历树数据
    }
}
</script>

<style scoped>
    .search{
        color: red;
    }
</style>

最终效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第30章_瑞萨MCU零基础入门系列教程之IRDA红外遥控实验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

苹果iPhone 15/Pro新机发布,毫米波5G仍然只限美国版

苹果公司今日发布了 iPhone 15 系列新机&#xff0c;共四款&#xff0c;分别是 iPhone 15、iPhone 15 Plus、iPhone 15 Pro 和 iPhone 15 Pro Max。这些新机型都配备了 USB-C 接口和灵动岛&#xff0c;而 Pro 版还有更多的特色功能&#xff0c;如 A17 Pro 芯片、轻质钛金属框架…

2023.2.1最新版IDEA创建一个SpringBoot项目,简单小示例

介绍 Springboot Spring Boot_百度百科 新建项目 打开IDEA选择 File->New->Project&#xff1b;选择 Spring Initializr Spring initializr 是Spring 官方提供的一个用来初始化一个Spring boot 项目的工具。组名项目名称可自定义 点击 next 选择 Dependencies Web…

芯科蓝牙BG27开发笔记1-新建示例工程

此笔记的必要性 芯科的官方资料很丰富&#xff0c;并且ssv5中能方便索引到所需文档&#xff0c;不过大而全的问题就是找不到合适的切入点&#xff0c;更不会有本地化比较好的中文的系统的教程了。往往看到一个starting guide&#xff0c;会延伸其他starting guide&#xff0c;…

ChatGPT高级数据分析功能

目录 只需要上传数据集就可以自动化分析,我们测试以下,首先我找了一份数据,主要是关于二手车的,格式如下: 接下来调用,GPT中的高级数据分析功能,上传数据,并要求进行分析 第一步:自动对数据字段进行详细的解释: 第二步,对数据进行预处理,比如缺失值,基本的描述…

第29章_瑞萨MCU零基础入门系列教程之改进型环形缓冲区

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

C语言数组和指针笔试题(一)(一定要看)

目录 一维数组例题1例题2例题3例题4例题5例题6例题7例题8例题9例题10例题输出结果 字符数组一例题1例题2例题3例题4例题5例题6例题7 一维数组 int a[] {1,2,3,4}; 1:printf("%d\n",sizeof(a)); 2:printf("%d\n",sizeof(a0)); 3:printf("%d\n",…

TypeScript高级类型

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 映射类型&#xff08;Mapped Types&#xff09; 1. Readonly 2. Partial 3. Pick 4. Record 条件类型&#xf…

【javaSE】 反射与反射的使用

文章目录 &#x1f332;反射的定义&#x1f38d;反射的用途&#x1f334;反射基本信息&#x1f340;反射相关的类&#x1f6a9;Class类(反射机制的起源 )&#x1f388;Class类中的相关方法 &#x1f6a9;反射示例&#x1f388;获得Class对象的三种方式&#x1f388;反射的使用 …

导数应用:曲线的凹凸性、渐进线、弧微分与曲率

目录 曲线的凹凸性 函数的拐点 曲线的渐近线 函数的弧微分与曲率 曲线的凹凸性 曲线的凹凸性是描述曲线在某一点处的曲率属性的几何性质。 具体来说&#xff0c;对于平面上的曲线&#xff0c;其在某一点的切线的斜率是不断变化的。当切线的斜率在某区间内恒为正值时&#…

基于HTML、CSS和JavaScript制作一个中秋节倒计时网页

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 这个项目使用HTML、CSS和…

第一百四十天学习记录:工作相关:Qt5.14.2的安装

最近一段时间被新项目搞得心力憔悴。 加上需要调用一个同事的OpenCV库一直报错&#xff0c;后面发现是Qt版本不兼容的问题。 在尝试了在线安装Qt无果后&#xff0c;重新安装Qt&#xff0c;顺便回顾一下Qt的安装过程。 毕竟上一次安装Qt还是在2019年……之后的这4年工作电脑和家…

TypeScript类型推断

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 类型推断 1. 基础类型推断 #2. 最佳公共类型推断 3. 上下文类型推断 4. 类型断言 #5. 类型推断和泛型 总结 类…

【javaSE】 Lambda表达式与Lambda表达式的使用

文章目录 &#x1f333;Lambda表达式的背景&#x1f6a9;Lambda表达式的语法&#x1f6a9;函数式接口 &#x1f38b;Lambda表达式的基本使用&#x1f384;语法精简 &#x1f332;变量捕获&#x1f6a9;匿名内部类&#x1f6a9;匿名内部类的变量捕获&#x1f6a9;Lambda的变量捕…

【力扣-二叉树-01】在二叉树中分配硬币-力扣 979 题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

多层全连接网络:实现手写数字识别50轮准确率92.1%

多层全连接网络&#xff1a;实现手写数字识别50轮准确率92.1% 1 导入必备库2 torchvision内置了常用数据集和最常见的模型3 数据批量加载4 绘制样例5 创建模型7 设置是否使用GPU8 设置损失函数和优化器9 定义训练函数10 定义测试函数11 开始训练12 绘制损失曲线并保存13 绘制准…

C++ std::future

std::future是用来接收一个线程的执行结果的&#xff0c;并且是一次性的。 共享状态shared state future可以关联一个共享状态&#xff0c;共享状态是用来储存要执行结果的。这个结果是async、promise、packaged_task设置的&#xff0c;且这个结果只能设置一次。 创建future …

【rtp-benchmarks】读取本地文件基于uvgRtp实现多线程发送

input 文件做内存映射 : get_mem D:\XTRANS\soup\uvg-rtp-dev\rtp-benchmarks\util\util.cc 文件中读取chunksize 到 vector 里作为chunks 创建多个线程进行发送 std::vector<std::thread*> threads;

C++数据结构X篇_12_树的基本概念和存储

学习二叉树之前先学习树的概念。 文章目录 1. 树的基本概念1.1 树的定义1.2 树的特点1.3 若干术语 2. 树的表示法2.1 图形表示法2.2 广义表表示法 3. 树的存储3.1 双亲表示法&#xff1a;保存父节点关系3.2 孩子表示法3.3 左孩子右兄弟表示法 1. 树的基本概念 之前所学均为线性…

22 相交链表

相交链表 题解1 快慢双指针改进 (acb bca)题解2 哈希表(偷懒) 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 题目数据 保证 整个链式结构中不存在环。 注意&#xff…