155 lines
4.9 KiB
Plaintext
155 lines
4.9 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>
|