<template> <div> <base-right-dialog ref="baseRightDialog" :footerShow="true" :appendBody="true" :dialogVisible.sync="drawer" :withHeader="false" title="权限分配" @handleClose="handleDialogClose" @handleConfirmClick="handleConfirmClick" :size="'60%'" > <el-tabs v-model="activeName"> <el-tab-pane label="功能权限" name="first"> <el-table border ref="multipleTable" :data="menuDatas" row-key="id" tooltip-effect="dark" style="width: 100%" :default-expand-all="true" :default-checked-keys="keys" @select-all="selectAll" @select="handleSelectionChange" v-loading="buttonLoading" > <el-table-column type="selection" width="45" :reserve-selection="true" ></el-table-column> <el-table-column prop="name" label="菜单名称" width="200" ></el-table-column> <el-table-column prop="buttonSelection" label="按钮"> <template slot-scope="scope"> <i class="el-icon-star-on" style=" height: 30px; line-height: 30px; font-size: 25px; margin-right: 7px; " v-show=" scope.row.buttons.length != 0 && scope.row.buttons.length == scope.row.buttonList.length " @click="cancellation(scope.row)" ></i> <i class="el-icon-star-on" style=" height: 30px; line-height: 30px; font-size: 25px; margin-right: 7px; color: #808080; " v-show=" scope.row.buttons.length != 0 && scope.row.buttons.length != scope.row.buttonList.length " @click="selectAllButton(scope.row)" ></i> <el-checkbox-group v-model="scope.row.buttonList" size="small"> <el-checkbox v-for="item in scope.row.buttons" :label="item.id" :key="item.id" >{{ item.NameCN }}</el-checkbox > </el-checkbox-group> </template> </el-table-column> </el-table></el-tab-pane > <el-tab-pane label="数据权限" name="second"> <data-permissions ref="dataPermissions"></data-permissions> </el-tab-pane> <el-tab-pane label="首页拖拽权限" name="layOutAuth"> <layOutPermissions ref="layOutPermissions"></layOutPermissions> </el-tab-pane> </el-tabs> </base-right-dialog> </div> </template> <script> import baseRightDialog from "@/components/base/baseRightDialog"; import { PopedomSaveData, GetAllBilldata } from "@/api/apis/jurisdiction"; import dataPermissions from "./dataPermissions.vue"; import layOutPermissions from "./layOutPermissions.vue"; import loginVue from "../../../login.vue"; export default { data() { return { drawer: false, multipleSelection: [], keys: [], isAllSelect: false, selected: false, childNode: false, build: "", activeName: "first", dataPermissions: [], buttonLoading: false, }; }, props: { menuData: { type: Array, default: () => { return []; }, }, }, components: { baseRightDialog, dataPermissions, layOutPermissions, }, beforeUpdate() { this.handleTabClick(); }, computed: { menuDatas: { // return JSON.parse(JSON.stringify(this.menuData)); get: function () { return JSON.parse(JSON.stringify(this.menuData)); }, set: function (item) { return JSON.parse(JSON.stringify(item)); }, }, }, methods: { // tab切换 handleTabClick() { this.$nextTick(() => { this.$refs.multipleTable && this.$refs.multipleTable.doLayout(); }); }, selectAllButton(item) { let data = []; item.buttons.forEach((el) => { data.push(el.id); }); item.buttonList = data; }, cancellation(item) { item.buttonList = []; }, // 全选/取消全选 selectAll() { let data = this.treeToArray(this.menuDatas); this.selected = !this.selected; data.forEach((el, index) => { this.$refs.multipleTable.toggleRowSelection(el, this.selected); }); }, handleSelectionChange(val, row) { this.multipleSelection = val; let data = this.treeToArray([row]); this.childNode = !this.childNode; if (data.length > 1) { data.forEach((el, index) => { this.$refs.multipleTable.toggleRowSelection(el, this.childNode); }); let ids = data[0].id; let arr = this.treeFindPath( this.menuDatas, (data) => data.id == ids, "id" ); arr = arr.splice(0, arr.length - 1); let dataList = []; let allList = this.treeToArray(this.menuDatas); allList.forEach((el, index) => { if (arr.includes(el.id)) { dataList.push(el); } }); dataList.forEach((el, index) => { this.$refs.multipleTable.toggleRowSelection(el, true); }); } else { let ids = data[0].id; let arr = this.treeFindPath( this.menuDatas, (data) => data.id == ids, "id" ); arr = arr.splice(0, arr.length - 1); let dataList = []; let allList = this.treeToArray(this.menuDatas); allList.forEach((el, index) => { if (arr.includes(el.id)) { dataList.push(el); } }); dataList.forEach((el, index) => { this.$refs.multipleTable.toggleRowSelection(el, true); }); } }, // 默认选中 exhibitList(id, echo, build) { let data = this.treeToArray(this.menuDatas); this.build = build; data.forEach((el, index) => { if (id.includes(el.id)) { this.$refs.multipleTable.toggleRowSelection(el, true); } }); this.menuDatas = this.addToButtonList(this.menuDatas, echo); this.buttonLoading = false; }, // 数据扁平 treeToArray(items) { let children = []; items.forEach((item) => { children.push(item); if (item.children) { children = children.concat(this.treeToArray(item.children)); } }); return children; }, handleDialogClose() { let data = this.treeToArray(this.menuDatas); data.forEach((el, index) => { this.$refs.multipleTable.toggleRowSelection(el, false); }); this.changeMenu(this.menuDatas, 0); this.drawer = false; this.$parent.permissionPopup = false; }, async handleConfirmClick() { let data = { objectID: this.build, kindid: 2, menuPopedom: "", buttonPopedom: [], dataPopedom: [], widgetPopedom: "", }; this.$refs.multipleTable.selection.forEach((el, index) => { let dataLength = this.$refs.multipleTable.selection.length; if (index == dataLength - 1) { data.menuPopedom = data.menuPopedom.concat(`${el.id}`); } else { data.menuPopedom = data.menuPopedom.concat(`${el.id},`); } if (el.buttonList.length != 0) { data.buttonPopedom.push({ op_MenuID: el.id, op_OperateKindList: el.buttonList + [], }); } }); let dataPopedom = []; this.$refs.dataPermissions.tableData.forEach((el) => { dataPopedom.push({ dp_billKindID: el.billKindID, dp_popeList: el.buttonList.length > 0 ? el.buttonList + [] : "", }); }); let tempStr = ""; this.$refs.layOutPermissions.tableData.forEach((item) => { item.buttonList.forEach((ele) => { tempStr += ele + ","; }); }); data.widgetPopedom = tempStr.length ? tempStr.slice(0, -1) : "none"; data.dataPopedom = dataPopedom; const res = await PopedomSaveData(data); if (res.success == "true") { this.handleDialogClose(); this.$message({ message: "保存成功", type: "success", }); } }, // 递归,添加选中按钮 addToButtonList(arr, newArr) { newArr.forEach((newItem) => { this.addToButtonListRecursive( arr, newItem.op_MenuID, newItem.op_OperateKindList ); }); return arr; }, addToButtonListRecursive(arr, targetId, operateKindList) { for (let i = 0; i < arr.length; i++) { const item = arr[i]; if (item.id == targetId) { let lists = operateKindList.split(","); lists.forEach((el) => { item.buttonList.push(parseInt(el)); }); return item; } if (item.children && item.children.length > 0) { this.addToButtonListRecursive( item.children, targetId, operateKindList ); } } }, changeMenu(data, num) { let level = num; level = level + 1; data.forEach((el) => { el.buttonList = []; el.type = false; if (el.children != null && el.children && el.children.length) { this.changeMenu(el.children, level); } }); }, toFlatArray(tree, parentId) { return tree.reduce((t, _) => { const child = _[children]; return [ ...t, parentId ? { ..._, parentId } : _, ...(child && child.length ? toFlatArray(child, _[id]) : []), ]; }, []); }, getIds(flatArray) { let ids = [nodeId]; let child = flatArray.find((_) => _[id] === nodeId); while (child && child.parentId) { ids = [child.parentId, ...ids]; child = flatArray.find((_) => _[id] === child.parentId); } return ids; }, treeFindPath(tree, func, field = "", path = []) { if (!tree) return []; for (const data of tree) { field === "" ? path.push(data) : path.push(data[field]); if (func(data)) return path; if (data.children) { const findChildren = this.treeFindPath( data.children, func, field, path ); if (findChildren.length) return findChildren; } path.pop(); } return []; }, }, }; </script> <style scoped lang="scss"> .rightDialog { height: 100%; padding: 0 16px; } ::v-deep .cell { display: flex; } ::v-deep .el-checkbox-group { display: flex; align-items: center; flex-wrap: wrap; } ::v-deep .el-checkbox { margin-right: 15px; } ::v-deep .el-tabs__nav { transform: translateX(22px) !important; } </style>