<template>
|
<ElDialog
|
v-model="visible"
|
title="菜单权限"
|
width="520px"
|
align-center
|
class="el-dialog-border"
|
@close="handleClose"
|
>
|
<ElScrollbar height="70vh">
|
<ElTree
|
ref="treeRef"
|
:data="processedMenuList"
|
show-checkbox
|
node-key="name"
|
:default-expand-all="isExpandAll"
|
:default-checked-keys="[1, 2, 3]"
|
:props="defaultProps"
|
@check="handleTreeCheck"
|
>
|
<template #default="{ data }">
|
<div style="display: flex; align-items: center">
|
<span v-if="data.isAuth">
|
{{ data.label }}
|
</span>
|
<span v-else>{{ defaultProps.label(data) }}</span>
|
</div>
|
</template>
|
</ElTree>
|
</ElScrollbar>
|
<template #footer>
|
<ElButton @click="outputSelectedData" style="margin-left: 8px">获取选中数据</ElButton>
|
|
<ElButton @click="toggleExpandAll">{{ isExpandAll ? '全部收起' : '全部展开' }}</ElButton>
|
<ElButton @click="toggleSelectAll" style="margin-left: 8px">{{
|
isSelectAll ? '取消全选' : '全部选择'
|
}}</ElButton>
|
<ElButton type="primary" @click="savePermission">保存</ElButton>
|
</template>
|
</ElDialog>
|
</template>
|
|
<script setup>
|
import { useMenuStore } from '@/store/modules/menu'
|
import { formatMenuTitle } from '@/utils/router'
|
const props = defineProps({
|
modelValue: { required: false, default: false },
|
roleData: { required: false, default: void 0 }
|
})
|
const emit = defineEmits(['update:modelValue', 'success'])
|
const { menuList } = storeToRefs(useMenuStore())
|
const treeRef = ref()
|
const isExpandAll = ref(true)
|
const isSelectAll = ref(false)
|
const visible = computed({
|
get: () => props.modelValue,
|
set: (value) => emit('update:modelValue', value)
|
})
|
const processedMenuList = computed(() => {
|
const processNode = (node) => {
|
const processed = { ...node }
|
if (node.meta?.authList?.length) {
|
const authNodes = node.meta.authList.map((auth) => ({
|
id: `${node.id}_${auth.authMark}`,
|
name: `${node.name}_${auth.authMark}`,
|
label: auth.title,
|
authMark: auth.authMark,
|
isAuth: true,
|
checked: auth.checked || false
|
}))
|
processed.children = processed.children ? [...processed.children, ...authNodes] : authNodes
|
}
|
if (processed.children) {
|
processed.children = processed.children.map(processNode)
|
}
|
return processed
|
}
|
return menuList.value.map(processNode)
|
})
|
const defaultProps = {
|
children: 'children',
|
label: (data) => formatMenuTitle(data.meta?.title) || data.label || ''
|
}
|
watch(
|
() => props.modelValue,
|
(newVal) => {
|
if (newVal && props.roleData) {
|
console.log('设置权限:', props.roleData)
|
}
|
}
|
)
|
const handleClose = () => {
|
visible.value = false
|
treeRef.value?.setCheckedKeys([])
|
}
|
const savePermission = () => {
|
ElMessage.success('权限保存成功')
|
emit('success')
|
handleClose()
|
}
|
const toggleExpandAll = () => {
|
const tree = treeRef.value
|
if (!tree) return
|
const nodes = tree.store.nodesMap
|
Object.values(nodes).forEach((node) => {
|
node.expanded = !isExpandAll.value
|
})
|
isExpandAll.value = !isExpandAll.value
|
}
|
const toggleSelectAll = () => {
|
const tree = treeRef.value
|
if (!tree) return
|
if (!isSelectAll.value) {
|
const allKeys = getAllNodeKeys(processedMenuList.value)
|
tree.setCheckedKeys(allKeys)
|
} else {
|
tree.setCheckedKeys([])
|
}
|
isSelectAll.value = !isSelectAll.value
|
}
|
const getAllNodeKeys = (nodes) => {
|
const keys = []
|
const traverse = (nodeList) => {
|
nodeList.forEach((node) => {
|
if (node.name) keys.push(node.name)
|
if (node.children?.length) traverse(node.children)
|
})
|
}
|
traverse(nodes)
|
return keys
|
}
|
const handleTreeCheck = () => {
|
const tree = treeRef.value
|
if (!tree) return
|
const checkedKeys = tree.getCheckedKeys()
|
const allKeys = getAllNodeKeys(processedMenuList.value)
|
isSelectAll.value = checkedKeys.length === allKeys.length && allKeys.length > 0
|
}
|
const outputSelectedData = () => {
|
const tree = treeRef.value
|
if (!tree) return
|
const selectedData = {
|
checkedKeys: tree.getCheckedKeys(),
|
halfCheckedKeys: tree.getHalfCheckedKeys(),
|
checkedNodes: tree.getCheckedNodes(),
|
halfCheckedNodes: tree.getHalfCheckedNodes(),
|
totalChecked: tree.getCheckedKeys().length,
|
totalHalfChecked: tree.getHalfCheckedKeys().length
|
}
|
console.log('=== 选中的权限数据 ===', selectedData)
|
ElMessage.success(`已输出选中数据到控制台,共选中 ${selectedData.totalChecked} 个节点`)
|
}
|
</script>
|