一、需求
需要根据tree嵌套结构数据渲染出 多层级带勾选的table,想要的对应结构table
二、思路
手撸原生table的demo,然后根据多层级嵌套的遍历,写成html拼接,
由于有几层的遍历逻辑和 tr只能包裹td元素,html拼接后改成元素生成createElement和子级插入appendChild 方式,自动生成对应解构的table
三、代码
效果图
1.获取 tree数据结构 及将数据内容重构
// 获取 角色权限table-tree
async queryRoleTree() {
const res = await roleApi.roleResourceTree(this.roleId) // id
console.log('queryRoleTree()-res', res)
this.roleStatus = res && res.inAdd && ['1'].includes(String(res.inAdd)) ? true : false
if (res && res.firstFloor && res.firstFloor.length > 0) {
this.roleTableTree = res.firstFloor
if (res.firstFloor[0].children && res.firstFloor[0].children.length > 0) {
this.levelOneTree = res.firstFloor[0].children // tree渲染从 firstFloor[0].children 开始
this.createTableHtml(this.levelOneTree)
const allArr = res.firstFloor
allArr.forEach(em1 => {
em1.children && em1.children.forEach(em2 => {
this.levelOneMap[`${em2.cid}-${em2.pid}`] = em2 // 与 创建的 checkbox--name的值保持一致
em2.children && em2.children.forEach(em3 => {
em3.children && em3.children.forEach(em4 => {
this.levelThreeMap[`${em4.cid}-${em4.pid}`]=em4
})
})
})
});
// console.log('this.levelThreeMap', this.levelThreeMap)
this.levelThreeArr = Object.keys(this.levelThreeMap).map(key => (this.levelThreeMap[key]))
console.log('this.levelThreeArr', this.levelThreeArr)
}
}
},
2.根据tree数据嵌套结构及-想要的table结构,创建对应tree-table的demo
createTableHtml(arr) {
// <div v-for="(td,idx) in roleTableTree" :key="idx">
// <tr>
// <td :rowspan="`${1+td.children.length*2}`" class="bor-r-1">
// <div class="oneLevelCell">{{ td.authName}}</div>
// </td>
// </tr>
// v-if="td2.pid && td.cid && String(td2.pid) === String(td.cid)" v-for="(td2,idx2) in td.children" :key="`${idx2}-${td2.cid}`"
// <tr >
// <td class="bor-r-1 bor-b-1" :rowspan="`${1+1}`">
// <div class="twoLevelCell">{{ td2.authName}}</div>
// </td>
// </tr>
// <tr >
// <div class="flex flex-j-start flex-wrap">
// <div v-for="(td3,idx3) in td2.children" :key="idx3" class="threeLevelCell">{{td3.authName }}</div>
// </div>
// </tr>
// </div>
const theadArr = this.theadArr;
const div = document.getElementById("table_DIV");
div.innerHTML = '';
const table = document.createElement('table');
table.id = "visitInfoTable";
table.className = "visitInfoTable";
const thead = document.createElement("thead");
thead.className = "bor-l-1 bor-t-1";
theadArr.forEach(em => {
const th = document.createElement('th'); // 创建行
th.className ='bor-r-1'
th.innerHTML = `<div class="thCell">${em}</div>`;
thead.appendChild(th);
})
table.appendChild(thead);
const tbody = document.createElement("tbody");
tbody.className = 'bor-l-1 bor-t-1 bor-b-1';
/** 创建-tbody ***/
arr.forEach((em1,idx1) => {
const rowOne = tbody.insertRow(); // 创建行
/** 创建-一级菜单下属的单元格 ***/
const cellOne = rowOne.insertCell(); // 创建单元格
cellOne.className = 'bor-r-1 bor-b-1'
const num = em1.children && em1.children.length > 0 ? (em1.children.length * 2) : 1
cellOne.rowSpan = `${1 + num}`;
// dom原例----- cellOne.innerHTML = `<div class="oneLevelCell"> <input type="checkbox" checked="false" /> <span>${em1.authName}</span></div>`;
const oneLevelCell = this.createCellHtml(em1, 'oneLevelCell', true)
cellOne.appendChild(oneLevelCell);
/** 创建-二级菜单下属的单元格 ***/
em1.children && em1.children.forEach((em2,idx2) => {
const rowTwo = tbody.insertRow();
const cellTwo = rowTwo.insertCell();
cellTwo.className = "bor-r-1 bor-b-1";
cellTwo.rowSpan = `${1 + 1}`;
const twoLevelCell = this.createCellHtml(em2, 'twoLevelCell', false, true)
cellTwo.appendChild(twoLevelCell);
// cellTwo.innerHTML = `<div class="twoLevelCell">${em2.authName}</div>`;
const rowThree = tbody.insertRow();
rowThree.className = 'bor-t-1 bor-r-1';
const twoDome = document.createElement('td');
twoDome.className = "flex flex-j-start flex-wrap pad-t-10 pad-b-10";
em2.children && em2.children.forEach((em3, idx3) => {
/** 创建-三级级菜单下属的单元格 ***/
// const divLevel3 = `<div class="threeLevelCell">${em3.authName}</div>`;
const threeLevelCell = this.createCellHtml(em3, 'threeLevelCell', false, true)
twoDome.appendChild(threeLevelCell);
})
rowThree.appendChild(twoDome);
})
})
table.appendChild(tbody);
// console.log('table', table)
div.appendChild(table);
},
3.单元格内-内容: checkbox+label
/**
* 创建单元格 -及内容 checkbox + label
* em
* 单元格div带的class样式名
* isDisabled---checkbox是否设置 disabled
* isHaveCheckBox ---- 是否创建 checkbox
* */
createCellHtml(em, str = 'oneLevelCell', isHaveCheckBox = true, isDisabled = false) {
const cell = document.createElement("div");
cell.className = str // 'oneLevelCell'
if (isHaveCheckBox) {
const inputOne = document.createElement('input')
inputOne.type = 'checkbox'
inputOne.name = `${em.cid}-${em.pid}`
inputOne.checked = em.active // boolean ; em.active && [1].includes(em.active) ? true : false
inputOne.className = 'checkbox'
inputOne.value = `${em.cid}`
inputOne.disabled = isDisabled
inputOne.addEventListener('change', this.checkboxChange) // 添加 checkbox监听事件
cell.appendChild(inputOne);
}
const spanOne = document.createElement('span')
spanOne.className = 'textOne'
spanOne.innerHTML = `${em.authName}`
cell.appendChild(spanOne);
return cell
},
4.单元格内-checkbox勾选,修改对应tree 数据结构节点的active勾选状态 this.roleTableTree[0].children[findIndex].active = checked
// 监听 checkbox 的勾选状态---根据创建时加的name=`${em.cid}-${em.pid}` 做唯一键判断
checkboxChange(event) {
// console.log('checkboxChange()-event', event)
const { target } = event
// console.log('checkboxChange()-target', target)
const { name, value, checked } = target
console.log('checkboxChange()-name', name, 'checked', checked, 'value', value)
if (this.levelOneTree.length > 0) {
const arr = this.levelOneTree
const findIndex = arr.findIndex(em => {
return String(em.cid) === String(value)
})
if (findIndex !== -1) {
this.roleTableTree[0].children[findIndex].active = checked
const levelOneArr = this.roleTableTree[0].children.map(em => {
em.children = []
return em
})
this.changeRoleModify(levelOneArr)
console.log('levelOneArr', levelOneArr)
}
console.log('checkboxChange()-arr', arr, 'findIndex', findIndex, 'children[findIndex].active', this.roleTableTree[0].children[findIndex].active)
}
},
5. 完整代码
visitInfoTable相关css样式要是放在页面内不生效,就放在 外层项目css相关文件夹内,main.js引入该样式
<template>
<el-card class="main">
<div class="body-wrap" id="table_DIV" v-show="levelOneTree.length > 0"></div>
<div class="body-wrap" v-show="levelOneTree.length === 0">
<table class="visitInfoTable">
<thead class="bor-l-1 bor-t-1 bor-b-1">
<th class="bor-r-1">
<div class="thCell">一级功能</div>
</th>
<th class="bor-r-1">
<div class="thCell">二级功能</div>
</th>
<th class="bor-r-1">
<div class="thCell">三级功能</div>
</th>
</thead>
<!-- <tbody class="tbodyNoValue" colspan="3">
暂无数据
<td colspan="3" class="td"></td>
</tbody> -->
</table>
<table class="visitInfoTable">
<div class="tbodyNoValue bor-b-1 bor-l-1 bor-r-1">
暂无数据
</div>
</table>
</div>
</el-card>
</template>
<script>
//import roleApi from '@/api/baseinfo/roleManagement'
function isEmpty(value) {
return ['', null, void 0, undefined, 'null', 'undefined'].includes(value)
}
export default {
name: 'Auth',
props: {
typeData: null,
projectId: null,
selectName: null,
roleId: null,
textarea: null,
},
data() {
return {
roleStatus: false,
textareaText: '', // 描述,
btnLoading: false,
tableConfig: {
params: {}
},
roleTableTree: [],
levelOneTree: [],
levelOneMap: {},
levelThreeMap: {},
levelThreeArr: [],
theadArr: ['一级功能', '二级功能', '三级功能'],
}
},
computed: {
},
watch: {
roleId: {
immediate: true,
handler(val) {
if (!isEmpty(val)) {
this.queryRoleTree()
}
}
},
textarea: {
immediate: true,
handler(val) {
this.textareaText = this.textarea
}
},
},
mounted() {
// if (this.roleId) {
// this.queryRoleTree()
// }
},
methods: {
// 获取 角色权限table-tree
async queryRoleTree() {
const res = [] // 用本地数据 见下面 mockRes.json
// const res = mockRes.result
// const res = await roleApi.roleResourceTree(this.roleId) // id
console.log('queryRoleTree()-res', res)
this.roleStatus = res && res.inAdd && ['1'].includes(String(res.inAdd)) ? true : false
if (res && res.firstFloor && res.firstFloor.length > 0) {
this.roleTableTree = res.firstFloor
if (res.firstFloor[0].children && res.firstFloor[0].children.length > 0) {
this.levelOneTree = res.firstFloor[0].children // tree渲染从 firstFloor[0].children 开始
this.createTableHtml(this.levelOneTree)
const allArr = res.firstFloor
allArr.forEach(em1 => {
em1.children && em1.children.forEach(em2 => {
this.levelOneMap[`${em2.cid}-${em2.pid}`] = em2 // 与 创建的 checkbox--name的值保持一致
em2.children && em2.children.forEach(em3 => {
em3.children && em3.children.forEach(em4 => {
this.levelThreeMap[`${em4.cid}-${em4.pid}`]=em4
})
})
})
});
// console.log('this.levelThreeMap', this.levelThreeMap)
this.levelThreeArr = Object.keys(this.levelThreeMap).map(key => (this.levelThreeMap[key]))
console.log('this.levelThreeArr', this.levelThreeArr)
}
}
},
// 角色资源编辑
async changeRoleModify(levelOneArr) {
// try {
// const params = { firstFloor: levelOneArr, roleId: this.roleId }
// await roleApi.resourceModify(params)
// if (this.roleId) {
// this.queryRoleTree()
// }
// this.$notify({
// title: '成功',
// message: `${'功能权限编辑'}成功`,
// type: 'success',
// duration: 2000
// })
// } catch (e) {
// console.error(e)
// }
},
// 监听 checkbox 的勾选状态---根据创建时加的name=`${em.cid}-${em.pid}` 做唯一键判断
checkboxChange(event) {
// console.log('checkboxChange()-event', event)
const { target } = event
// console.log('checkboxChange()-target', target)
const { name, value, checked } = target
console.log('checkboxChange()-name', name, 'checked', checked, 'value', value)
if (this.levelOneTree.length > 0) {
const arr = this.levelOneTree
const findIndex = arr.findIndex(em => {
return String(em.cid) === String(value)
})
if (findIndex !== -1) {
this.roleTableTree[0].children[findIndex].active = checked
const levelOneArr = this.roleTableTree[0].children.map(em => {
em.children = []
return em
})
this.changeRoleModify(levelOneArr)
console.log('levelOneArr', levelOneArr)
}
console.log('checkboxChange()-arr', arr, 'findIndex', findIndex, 'children[findIndex].active', this.roleTableTree[0].children[findIndex].active)
}
},
createTableHtml(arr) {
// <div v-for="(td,idx) in roleTableTree" :key="idx">
// <tr>
// <td :rowspan="`${1+td.children.length*2}`" class="bor-r-1">
// <div class="oneLevelCell">{{ td.authName}}</div>
// </td>
// </tr>
// v-if="td2.pid && td.cid && String(td2.pid) === String(td.cid)" v-for="(td2,idx2) in td.children" :key="`${idx2}-${td2.cid}`"
// <tr >
// <td class="bor-r-1 bor-b-1" :rowspan="`${1+1}`">
// <div class="twoLevelCell">{{ td2.authName}}</div>
// </td>
// </tr>
// <tr >
// <div class="flex flex-j-start flex-wrap">
// <div v-for="(td3,idx3) in td2.children" :key="idx3" class="threeLevelCell">{{td3.authName }}</div>
// </div>
// </tr>
// </div>
const theadArr = this.theadArr;
const div = document.getElementById("table_DIV");
div.innerHTML = '';
const table = document.createElement('table');
table.id = "visitInfoTable";
table.className = "visitInfoTable";
const thead = document.createElement("thead");
thead.className = "bor-l-1 bor-t-1";
theadArr.forEach(em => {
const th = document.createElement('th'); // 创建行
th.className ='bor-r-1'
th.innerHTML = `<div class="thCell">${em}</div>`;
thead.appendChild(th);
})
table.appendChild(thead);
const tbody = document.createElement("tbody");
tbody.className = 'bor-l-1 bor-t-1 bor-b-1';
/** 创建-tbody ***/
arr.forEach((em1,idx1) => {
const rowOne = tbody.insertRow(); // 创建行
/** 创建-一级菜单下属的单元格 ***/
const cellOne = rowOne.insertCell(); // 创建单元格
cellOne.className = 'bor-r-1 bor-b-1'
const num = em1.children && em1.children.length > 0 ? (em1.children.length * 2) : 1
cellOne.rowSpan = `${1 + num}`;
// dom原例----- cellOne.innerHTML = `<div class="oneLevelCell"> <input type="checkbox" checked="false" /> <span>${em1.authName}</span></div>`;
const oneLevelCell = this.createCellHtml(em1, 'oneLevelCell', true)
cellOne.appendChild(oneLevelCell);
/** 创建-二级菜单下属的单元格 ***/
em1.children && em1.children.forEach((em2,idx2) => {
const rowTwo = tbody.insertRow();
const cellTwo = rowTwo.insertCell();
cellTwo.className = "bor-r-1 bor-b-1";
cellTwo.rowSpan = `${1 + 1}`;
const twoLevelCell = this.createCellHtml(em2, 'twoLevelCell', false, true)
cellTwo.appendChild(twoLevelCell);
// cellTwo.innerHTML = `<div class="twoLevelCell">${em2.authName}</div>`;
const rowThree = tbody.insertRow();
rowThree.className = 'bor-t-1 bor-r-1';
const twoDome = document.createElement('td');
twoDome.className = "flex flex-j-start flex-wrap pad-t-10 pad-b-10";
em2.children && em2.children.forEach((em3, idx3) => {
/** 创建-三级级菜单下属的单元格 ***/
// const divLevel3 = `<div class="threeLevelCell">${em3.authName}</div>`;
const threeLevelCell = this.createCellHtml(em3, 'threeLevelCell', false, true)
twoDome.appendChild(threeLevelCell);
})
rowThree.appendChild(twoDome);
})
})
table.appendChild(tbody);
// console.log('table', table)
div.appendChild(table);
},
/**
* 创建单元格 -及内容 checkbox + label
* em
* 单元格div带的class样式名
* isDisabled---checkbox是否设置 disabled
* isHaveCheckBox ---- 是否创建 checkbox
* */
createCellHtml(em, str = 'oneLevelCell', isHaveCheckBox = true, isDisabled = false) {
const cell = document.createElement("div");
cell.className = str // 'oneLevelCell'
if (isHaveCheckBox) {
const inputOne = document.createElement('input')
inputOne.type = 'checkbox'
inputOne.name = `${em.cid}-${em.pid}`
inputOne.checked = em.active // boolean ; em.active && [1].includes(em.active) ? true : false
inputOne.className = 'checkbox'
inputOne.value = `${em.cid}`
inputOne.disabled = isDisabled
inputOne.addEventListener('change', this.checkboxChange) // 添加 checkbox监听事件
cell.appendChild(inputOne);
}
const spanOne = document.createElement('span')
spanOne.className = 'textOne'
spanOne.innerHTML = `${em.authName}`
cell.appendChild(spanOne);
return cell
},
}
}
</script>
<style lang='scss' scoped>
.textareaText{
width: 200rem;
}
.title{
margin-bottom: 12rem;
.text{
font-size: 15rem;
font-family: 'PingFangSC';
color: #000;
}
}
.body-top{
min-height: 32rem;
padding: 7rem 18rem;
background: var(--fill-color-8);
border-radius: 5px;
font-size: 13rem;
font-family: 'PingFangSC';
color: #000;
margin-bottom: 20rem;
}
.border-1-999{
border: 1px solid #999;
}
.textOne{
font-size: 14rem;
color: #000;
}
.tbodyNoValue{
width: 100%;
height: 200rem;
padding-top: 100rem;
text-align: center;
font-size: 16rem;
font-family: 'PingFangSC';
flex-shrink: 0;
color: #5B6D83;
display: block;
.td{
width: 100%;
}
}
/**创建 table 及 checkbox */
.visitInfoTable{
width: 100%;
.bor-t-1{
border-top: 1rem solid #DCE5EB;
}
.bor-l-1{
border-left: 1rem solid #DCE5EB;
}
.bor-r-1{
border-right: 1rem solid #DCE5EB;
}
.bor-b-1{
border-bottom: 1rem solid #DCE5EB;
}
thead{
th{
font-size: 13rem;
color: #5B6D83 ;
font-weight: 500;
font-family: 'PingFangSC';
background: var(--fill-linear-color-1) ;
.thCell{
height: 44rem;
line-height: 44rem;
padding-left: 8rem;
padding-right: 8rem;
}
}
}
tr{
font-size: 15rem;
color: #263237 ;
font-weight: 400;
font-family: 'PingFangSC';
td{
padding-left: 20rem;
padding-right: 10rem;
}
}
input[type=checkbox] {
font-size: 12rem;
width: 16rem;
height: 16rem;
vertical-align: middle;
// visibility: hidden;
position: relative;
}
input[type=checkbox]::before{
display: block;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
content: "";
border: 1px solid #999;
background-color: #fff;
width: 100%;
height: 100%;
border-radius: 6rem;
}
input[type=checkbox]:checked::before{
display: block;
content: "\2713";
text-align: center;
font-size: 13rem;
color: #fff;
background-color: #00a651;
border-color: #00a651;
width: 100%;
height: 100%;
border-radius: 6rem;
}
.checkbox{
margin-left: 10rem;
margin-right: 15rem;
}
.oneLevelCell{
min-width: 180rem;
}
.twoLevelCell{
min-width: 180rem;
}
.threeLevelCell{
min-width: 180rem;
}
}
// flex
.flex-box {
display: flex;
display: -webkit-box;
display: -webkit-flex;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-1 {
flex: 1;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-nowrap {
flex-wrap: nowrap;
}
.flex-j-start {
display: flex;
align-items: center;
justify-content: flex-start;
}
.flex-j-end {
display: flex;
align-items: center;
justify-content: flex-end;
}
.flex-j-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-j-around {
display: flex;
align-items: center;
justify-content: space-around;
}
.flex-j-center {
display: flex;
align-items: center;
justify-content: center;
}
</style>
6. mockRes.json
{
"code": "200",
"message": "操作成功",
"result": {
"roleId": "1",
"roleName": "admin",
"desc": "admin添加到这里1",
"inAdd": 0,
"active": false,
"firstFloor": [
{
"cid": 1,
"authName": "小程序",
"key": "000",
"path": "/",
"authType": "1",
"orderNum": 1,
"level": 0,
"pid": null,
"active": true,
"children": [
{
"cid": 2,
"authName": "XXXXXX记录",
"key": "menu_cityload",
"path": "pages/cityload/index",
"authType": "1",
"orderNum": 2,
"level": 1,
"pid": "1",
"active": true,
"children": [
{
"cid": 7,
"authName": "XXXXXX记录列表",
"key": "record_cityload",
"path": "record/cityload/list",
"authType": "2",
"orderNum": 1,
"level": 2,
"pid": "2",
"active": true,
"children": [
{
"cid": 90002213,
"authName": "查询XXXXXX记录列表",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "7",
"active": false,
"children": null
},
{
"cid": 90003319,
"authName": "查询关联设施树",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "7",
"active": false,
"children": null
},
{
"cid": 16173319,
"authName": "查询XXXXXX详情",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "7",
"active": false,
"children": null
}
]
},
{
"cid": 8,
"authName": "XXXXXX记录新增",
"key": "record_cityload_add",
"path": "record/cityload/add",
"authType": "2",
"orderNum": 2,
"level": 2,
"pid": "2",
"active": true,
"children": [
{
"cid": 90002210,
"authName": "新增XXXXXX记录",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "8",
"active": false,
"children": null
}
]
},
{
"cid": 9,
"authName": "XXXXXX记录编辑",
"key": "record_cityload_edit",
"path": "record/cityload/edit",
"authType": "2",
"orderNum": 3,
"level": 2,
"pid": "2",
"active": true,
"children": [
{
"cid": 90002232,
"authName": "列表",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "9",
"active": false,
"children": null
},
{
"cid": 90002243,
"authName": "详情",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "9",
"active": false,
"children": null
},
{
"cid": 90002212,
"authName": "修改XXXXXX记录",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "9",
"active": false,
"children": null
},
{
"cid": 90002214,
"authName": "查询XXXXXX详细信息",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "9",
"active": false,
"children": null
}
]
},
{
"cid": 15,
"authName": "XXXXXX打卡记录",
"key": "record_card_city",
"path": "record/card/city/list",
"authType": "2",
"orderNum": 1,
"level": 2,
"pid": "2",
"active": true,
"children": null
},
{
"cid": 16,
"authName": "XXXXXX巡检打卡",
"key": "card_city_add",
"path": "card/city/add",
"authType": "2",
"orderNum": 3,
"level": 2,
"pid": "2",
"active": true,
"children": [
{
"cid": 90002211,
"authName": "巡检打卡",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "16",
"active": false,
"children": null
}
]
}
]
},
{
"cid": 3,
"authName": "巡查记录",
"key": "menu_patrol",
"path": "pages/patrol/index",
"authType": "1",
"orderNum": 1,
"level": 1,
"pid": "1",
"active": true,
"children": [
{
"cid": 4,
"authName": "地图服务",
"key": "map_patrol",
"path": "map/patrol/info",
"authType": "2",
"orderNum": 1,
"level": 2,
"pid": "3",
"active": true,
"children": [
{
"cid": 39000225,
"authName": "任务详情地图",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "4",
"active": false,
"children": null
}
]
},
{
"cid": 5,
"authName": "巡查记录列表",
"key": "record_patrol",
"path": "record/patrol/list",
"authType": "2",
"orderNum": 2,
"level": 2,
"pid": "3",
"active": true,
"children": [
{
"cid": 90002204,
"authName": "查询一条未完成计划",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
},
{
"cid": 90002206,
"authName": "根据日期查询关联的巡查计划",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
},
{
"cid": 90002207,
"authName": "巡查计划统计当月信息",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
},
{
"cid": 90002208,
"authName": "查询所有的巡查任务",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
},
{
"cid": 90002209,
"authName": "新增巡查记录",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
},
{
"cid": 90002217,
"authName": "巡查记录列表",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
},
{
"cid": 90002219,
"authName": "巡查记录修改",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "5",
"active": false,
"children": null
}
]
},
{
"cid": 6,
"authName": "巡查记录新增",
"key": "record_patrol_add",
"path": "record/patrol/add",
"authType": "2",
"orderNum": 3,
"level": 2,
"pid": "3",
"active": true,
"children": null
},
{
"cid": 10,
"authName": "巡检打卡",
"key": "record_cityload_card",
"path": "record/cityload/card",
"authType": "2",
"orderNum": 4,
"level": 2,
"pid": "3",
"active": true,
"children": null
},
{
"cid": 11,
"authName": "巡查计划自动排班",
"key": "record_patrol_auto",
"path": "record/patrol/auto",
"authType": "2",
"orderNum": 5,
"level": 2,
"pid": "3",
"active": true,
"children": null
},
{
"cid": 12,
"authName": "巡查计划复制排班",
"key": "record_patrol_copy",
"path": "record/patrol/copy",
"authType": "2",
"orderNum": 6,
"level": 2,
"pid": "3",
"active": true,
"children": null
},
{
"cid": 13,
"authName": "新建计划",
"key": "plan_patrol_add",
"path": "plan/patrol/add",
"authType": "2",
"orderNum": 7,
"level": 2,
"pid": "3",
"active": true,
"children": null
},
{
"cid": 14,
"authName": "计划列表",
"key": "plan_patrol_list",
"path": "plan/patrol/list",
"authType": "2",
"orderNum": 8,
"level": 2,
"pid": "3",
"active": true,
"children": null
}
]
},
{
"cid": 17,
"authName": "登录权限",
"key": "app_login",
"path": "app/login",
"authType": "1",
"orderNum": 3,
"level": 1,
"pid": "1",
"active": true,
"children": [
{
"cid": 18,
"authName": "登录授权",
"key": "app_login_info",
"path": "app/login/info",
"authType": "2",
"orderNum": 3,
"level": 1,
"pid": "17",
"active": true,
"children": [
{
"cid": 90002200,
"authName": "修改密码",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "18",
"active": false,
"children": null
},
{
"cid": 90002201,
"authName": "token置换",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "18",
"active": false,
"children": null
},
{
"cid": 90002202,
"authName": "登出",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "18",
"active": false,
"children": null
},
{
"cid": 90002203,
"authName": "获取菜单",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "18",
"active": false,
"children": null
},
{
"cid": 90002215,
"authName": "文件上传",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "18",
"active": false,
"children": null
},
{
"cid": 90002216,
"authName": "文件查看",
"key": null,
"path": null,
"authType": "3",
"orderNum": null,
"level": 3,
"pid": "18",
"active": false,
"children": null
}
]
}
]
}
]
}
]
}
}