164 lines
5.0 KiB
Plaintext
164 lines
5.0 KiB
Plaintext
<template>
|
||
<a-modal
|
||
v-model:visible="props.visible"
|
||
title="权限设置"
|
||
width="500px"
|
||
@cancel="dialogClose"
|
||
>
|
||
<div>
|
||
<a-checkbox v-model:checked="expandFlag" @change="handleExpand">展开/折叠</a-checkbox>
|
||
<a-checkbox v-model:checked="checkedFlag" @change="handleSelectAll">全选/不全选</a-checkbox>
|
||
<div>
|
||
<a-tree
|
||
:tree-data="menuTree"
|
||
:fieldNames="{children:'children', title:'name', key:'id' }"
|
||
:height="600"
|
||
v-model:checkedKeys="checkedKeys"
|
||
v-model:expandedKeys="expandedKeys"
|
||
@check="onChangePermissionsTree"
|
||
checkable
|
||
/>
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<span class="dialog-footer">
|
||
<a-button @click="dialogClose">取消</a-button>
|
||
<a-button :loading="subLoading" type="primary" @click="submit">
|
||
确定
|
||
</a-button>
|
||
</span>
|
||
</template>
|
||
</a-modal>
|
||
</template>
|
||
<script lang="ts" setup>
|
||
import {getRoleMenuList,roleMenuSave} from "@/api/system/role";
|
||
import {buildTree} from "@/utils/auth";
|
||
import { message } from 'ant-design-vue';
|
||
import { onMounted, ref} from "vue";
|
||
import {useLockFn} from "@/utils/useLockFn";
|
||
import { isArray} from '@/utils/is';
|
||
|
||
const props = defineProps({
|
||
visible: {
|
||
type: Boolean,
|
||
required: true,
|
||
default: false
|
||
},
|
||
roleId: {
|
||
type: Number,
|
||
required: true,
|
||
default: 0
|
||
}
|
||
});
|
||
const emit = defineEmits(["success", "update:visible"]);
|
||
const checkedFlag = ref(false);
|
||
const expandFlag = ref(false)
|
||
const allMenuIds = ref([])
|
||
const checkedKeys = ref([])
|
||
const expandedKeys = ref([])
|
||
const menuArray = ref<any[]>([]);
|
||
const menuTree = ref<any[]>([]);
|
||
|
||
|
||
const handleExpand = () => {
|
||
if(expandFlag.value) {
|
||
expandedKeys.value = allMenuIds.value
|
||
} else {
|
||
expandedKeys.value = []
|
||
}
|
||
};
|
||
|
||
const handleSelectAll = (check) => {
|
||
if(checkedFlag.value) {
|
||
checkedKeys.value = allMenuIds.value
|
||
} else {
|
||
checkedKeys.value = []
|
||
}
|
||
};
|
||
const handleSubmit = async () => {
|
||
let keys = []
|
||
if (!isArray(checkedKeys.value)) {
|
||
checkedKeys.value.checked.map(item=>{
|
||
keys.push(item)
|
||
})
|
||
checkedKeys.value.halfChecked.map(item=>{
|
||
keys.push(item)
|
||
})
|
||
} else {
|
||
keys =checkedKeys.value
|
||
}
|
||
await roleMenuSave({menuIds:keys,roleId:props.roleId});
|
||
message.success("操作成功");
|
||
emit("update:visible", false);
|
||
emit("success");
|
||
};
|
||
|
||
const { lockFn: submit } = useLockFn(handleSubmit);
|
||
|
||
const dialogClose = () => {
|
||
emit("update:visible", false);
|
||
};
|
||
|
||
const onChangePermissionsTree=(node, event)=> {
|
||
checkedKeys.value = node
|
||
}
|
||
const setFormData = async () => {
|
||
const data = await getRoleMenuList(props.roleId);
|
||
menuTree.value = buildTree(data);
|
||
menuArray.value =data;
|
||
menuArray.value.map(item=>{
|
||
allMenuIds.value.push(item.id)
|
||
})
|
||
const keys = checkTree(menuTree.value,0,[],[])
|
||
checkedKeys.value ={checked:keys.checkedIds,halfChecked:keys.halfCheckedIds}
|
||
};
|
||
|
||
function checkTree(nodes, parentId = null,checkedIds,halfCheckedIds) {
|
||
nodes.forEach(node => {
|
||
let allChildrenChecked = true;
|
||
let someChildrenChecked = false;
|
||
|
||
// 检查子节点
|
||
if (node.children && node.children.length > 0) {
|
||
checkTree(node.children, node.id,checkedIds,halfCheckedIds); // 递归检查子节点
|
||
|
||
// 遍历子节点来确定父节点的状态
|
||
node.children.forEach(child => {
|
||
if (child.checked) {
|
||
someChildrenChecked = true;
|
||
// 如果子节点被选中,可能需要将子节点的ID也加入checkedIds(取决于需求)
|
||
// 但通常我们只关心父节点和叶子节点的checked状态
|
||
halfCheckedIds.push(child.id); // 可选,根据需要添加
|
||
} else {
|
||
allChildrenChecked = false;
|
||
}
|
||
});
|
||
|
||
// 根据子节点的状态更新父节点的状态及数组
|
||
if (allChildrenChecked) {
|
||
// 如果所有子节点都选中,则父节点也被视为选中
|
||
checkedIds.push(node.id);
|
||
} else if (someChildrenChecked) {
|
||
// 如果部分子节点选中,则父节点被视为半选
|
||
halfCheckedIds.push(parentId || node.id); // parentId用于处理递归时的父节点
|
||
}
|
||
// 注意:如果所有子节点都未选中,则父节点不会被添加到任何数组中
|
||
// 但如果业务需求是即使所有子节点都未选中,父节点也需要以某种方式被标记,
|
||
// 你需要在这里添加额外的逻辑。
|
||
} else {
|
||
// 如果是叶子节点,直接根据其checked状态处理
|
||
if (node.checked) {
|
||
checkedIds.push(node.id);
|
||
}
|
||
}
|
||
});
|
||
return {checkedIds,halfCheckedIds}
|
||
}
|
||
|
||
onMounted(() => {
|
||
setFormData();
|
||
});
|
||
</script>
|
||
<style lang="less">
|
||
</style>
|