wms-antdvue/.svn/pristine/da/da8b93217577e74a52fa4dd20b4951a71a1f6048.svn-base
2024-11-07 16:33:03 +08:00

194 lines
5.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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 = () => {
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);
};
/**
* 树结构选中发生变化
* @param node 节点
* @param event 事件
*/
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 };
};
/**
* 选中树结构
* @param nodes 节点
* @param parentId 上级ID
* @param checkedIds 选中ID集合
* @param 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>