<template>
<div class="system-role-dialog-container">
<el-dialog draggable :title="title" v-model="isShowDialog" width="30%">
<el-form :model="menuRoleForm" label-width="100px">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item label="应用名称 :">
<el-select v-model="menuRoleForm.appList">
<el-option v-for="item in menuOptions" :key="item.label" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="菜单权限 :">
<!-- 遍历展示所有菜单 -->
<div v-for="(item, index) in treeMenu.appList" :key="index">
<div v-if="item.appCode">
<el-tree :data="allTreeData[item.appCode]" ref="treeEle" :label="'title'" node-key="id"
:code="item.appCode" :props="treeProps" :current-node-key="currentKey"
:default-checked-keys="selectedNode[item.appCode]" @check="changeCheck"
v-show="menuRoleForm.appList === item.appCode" show-checkbox>
</el-tree>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel" size="default">取 消</el-button>
<el-button type="primary" @click="onSubmit" size="default">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="systemRoleDialog">
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus'
import { tmRoleApi } from '/@/api/user';
const getRoleOwnMenu = tmRoleApi().getRoleOwnMenu
const postRoleMenuList = tmRoleApi().postRoleMenuList
const props = defineProps(['menuList'])
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh'])
// 定义变量内容
const defaultCheckedKeys = ref<number[]>([]); // 默认选中的节点id数组
const isShowDialog = ref(false)
const title = ref()
let menuOptions: any = ref([])
const dataTree = ref() // 获取菜单结构数据
let selectedIds = ref() // 保存选中的id数组
let treeMenu = ref()
const currentKey = ref('')
// 整理根据菜单划分所有列表
const allTreeData = ref<{ [key: string]: any }>({})
const treeProps = ref({
label: 'title'
})
interface menuRoleForm {
appList: string,
menuTree: any,
}
const menuRoleForm = ref<menuRoleForm>({
appList: '',
menuTree: [],// 保存选中节点的id的数组
})
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
selectedNode.value = {}
};
// 储存选中的菜单
const selectedNode = ref<{ [key: string]: any }>({})
console.log(selectedNode, 'selectedNodeselectedNode');
// 取消
const onCancel = () => {
closeDialog();
};
// 打开弹窗
const openDialog = async (row: any) => {
selectedNode.value = {}
defaultCheckedKeys.value = [] //每次进来回显置空
selectedIds.value = row.id
const resValue = await getRoleOwnMenu(row.id) //根据id获取已授权菜单
treeMenu.value = props.menuList //获取全部菜单列表
// 根据应用列表 添加
for (let i = 0; i < props.menuList.appList.length; i++) {
// 根据应用 区分所有应用下的树列表,并生成角色权限树
let item = props.menuList.appList[i]
if (item.appCode) {
selectedNode.value[item.appCode] = []
allTreeData.value[item.appCode] = props.menuList.menuTree.filter((m: any) => m.appCode === item.appCode)
}
}
// 储存已获取的菜单
for (let i = 0; i < resValue.length; i++) {
let item = resValue[i]
if (item.appCode) {
selectedNode.value[item.appCode].push(...filterSelectedNodes(props.menuList, item.menuIdList))
}
}
function filterSelectedNodes(tree: any, idList: any) {
function findObjectById(data: any, targetId: any) {
for (const node of data) {
if (node.id === targetId) {
return node;
}
if (node.children && node.children.length > 0) {
const foundInChildren: any = findObjectById(node.children, targetId);
if (foundInChildren) {
return foundInChildren;
}
}
}
return null;
}
function processArrayB(arrayA: any, arrayB: any) {
const newArrayB = [...arrayB];
arrayB.forEach((id: any) => {
const foundObject = findObjectById(arrayA, id);
if (foundObject && foundObject.children && foundObject.children.length > 0) {
const childrenIds = foundObject.children.map((child: any) => child.id);
if (!childrenIds.every((childId: any) => newArrayB.includes(childId))) {
const index = newArrayB.indexOf(id);
if (index !== -1) {
newArrayB.splice(index, 1);
}
}
}
});
return newArrayB;
}
return processArrayB(tree.menuTree, idList)
}
menuOptions.value.length = 0
// 应用列表
props.menuList.appList.map((item: any) => {
if (item.appCode) {
menuOptions.value.push({
label: item.appName,
value: item.appCode
})
}
})
menuRoleForm.value.appList = menuRoleForm.value.appList ? menuRoleForm.value.appList : 'busiapp'
const appListValue = props.menuList.menuTree.filter((f: any) => f.appCode === menuRoleForm.value.appList)
dataTree.value = appListValue
for (let i = 0; i < resValue.length; i++) {
defaultCheckedKeys.value.push(...resValue[i].menuIdList)
}
title.value = '授权菜单';
isShowDialog.value = true;
};
// 提交
const onSubmit = async () => {
let keys = Object.keys(selectedNode.value)
let arr: any = []
keys.forEach(item => arr.push(...selectedNode.value[item]))
const params = {
id: JSON.stringify(selectedIds.value),
grantMenuIdList: arr,
}
await postRoleMenuList(params)
await emit('refresh'); //刷新列表
await closeDialog();
await ElMessage({
message: '修改成功',
type: 'success',
})
};
// 改变选中
const changeCheck = (val: any, checked: any) => {
selectedNode.value[val.appCode] = [...checked.checkedKeys]
}
// 暴露变量
defineExpose({
openDialog,
});
// 页面加载时
onMounted(() => {
});
</script>
<style scoped lang="scss">
.system-role-dialog-container {
.menu-data-tree {
width: 100%;
border: 1px solid var(--el-border-color);
border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
padding: 5px;
}
}
</style>