|
@@ -14,14 +14,12 @@
|
|
|
ref="refCheckboxTree"
|
|
|
:data="authList"
|
|
|
:keys="{label:'Name',children:'Children', value:'MenuId'}"
|
|
|
- :default-expand-all="false"
|
|
|
- show-checkbox
|
|
|
+ show-checkbox
|
|
|
node-key="MenuId"
|
|
|
|
|
|
v-model="defaultCheckedKeys"
|
|
|
:checkable="true"
|
|
|
- :check-strictly="false"
|
|
|
- :value-mode="'onlyLeaf'"
|
|
|
+ :value-mode="'all'"
|
|
|
hover
|
|
|
@change="handleCheckChange"
|
|
|
>
|
|
@@ -40,11 +38,14 @@ const route=useRoute()
|
|
|
|
|
|
// 响应式数据
|
|
|
const authList = ref([]);
|
|
|
+const checkList = ref([]);
|
|
|
const defaultCheckedKeys = ref([]);
|
|
|
const treeLoading = ref(false);
|
|
|
const checkAll = ref(false);
|
|
|
const isIndeterminate = ref(false);
|
|
|
|
|
|
+// checkboxTree组件的ref
|
|
|
+const refCheckboxTree = ref(null);
|
|
|
|
|
|
// 获取业务权限列表
|
|
|
const getBusinessAuthList = async () => {
|
|
@@ -62,13 +63,15 @@ const getBusinessAuthList = async () => {
|
|
|
|
|
|
const { List = [], ChoiceList = [], HalfChoiceList = [] } = res.Data;
|
|
|
authList.value = List;
|
|
|
+ checkList.value = ChoiceList.filter(element => !HalfChoiceList.includes(element)); // 过滤掉半选状态的节点
|
|
|
|
|
|
authList.value.forEach(item => checkTree(item));
|
|
|
|
|
|
- await nextTick();
|
|
|
- authList.value.forEach(item => checkTree(item));
|
|
|
- defaultCheckedKeys.value = ChoiceList;
|
|
|
- handleCheckChange(defaultCheckedKeys.value);
|
|
|
+ nextTick(async () => {
|
|
|
+ authList.value.forEach(item => checkTree(item));
|
|
|
+ defaultCheckedKeys.value = checkList.value;
|
|
|
+ handleCheckChange(defaultCheckedKeys.value);
|
|
|
+ })
|
|
|
} catch (error) {
|
|
|
console.error('获取业务权限列表失败:', error);
|
|
|
treeLoading.value = false;
|
|
@@ -80,9 +83,39 @@ const checkTree = (data) => {
|
|
|
if (data.Children && data.Children.length) {
|
|
|
data.Children = data.Children.map(i => checkTree(i));
|
|
|
}
|
|
|
+ // 叶子节点向上检查MenuId
|
|
|
+ if(!data.Children||data.Children&&data.Children.length===0){
|
|
|
+ checkDataList(data)
|
|
|
+ }
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
+//根据MenuId找到对应节点
|
|
|
+const findTreeNode = (MenuId) => {
|
|
|
+ return refCheckboxTree.value.getItems({value:MenuId})
|
|
|
+};
|
|
|
+
|
|
|
+const checkDataList = (data) => {
|
|
|
+ if(!data) return
|
|
|
+
|
|
|
+ //获取data的MenuId 和 checkList对比
|
|
|
+ //如果MenuId不在checkList里,检查data.ParentId在不在checkList里,若在,则从checkList里去除
|
|
|
+ if(!checkList.value.includes(data.MenuId)&&checkList.value.includes(data.ParentId)){
|
|
|
+ const index = checkList.value.indexOf(data.ParentId)
|
|
|
+ index!==-1&&checkList.value.splice(index,1)
|
|
|
+ console.log('应该去除的节点',data.ParentId)
|
|
|
+ }
|
|
|
+ //向上检查MenuId
|
|
|
+ const parentNode = findTreeNode(data.ParentId)
|
|
|
+
|
|
|
+ if(parentNode){
|
|
|
+ checkDataList(parentNode.data)
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const setIndeterminate = () => {
|
|
|
+ return refCheckboxTree.value.getItems().filter(i => i.indeterminate).map(i => i.data.MenuId);
|
|
|
+};
|
|
|
|
|
|
// 处理按钮点击
|
|
|
const handleBtnClik = async (type) => {
|
|
@@ -92,9 +125,11 @@ const handleBtnClik = async (type) => {
|
|
|
return;
|
|
|
}
|
|
|
try {
|
|
|
+ const ChoiceList = Array.from(new Set([...defaultCheckedKeys.value,...setIndeterminate()])) // 合成一个数组并去重->半选节点也要保存下来,不然会导致半选节点丢失问题
|
|
|
const res = await businessCustomInterence.setAuthList({
|
|
|
EtaBusinessId: Number(route.query.id),
|
|
|
- MenuIds: defaultCheckedKeys.value,
|
|
|
+ MenuIds: ChoiceList,
|
|
|
+ HalfMenuIds: setIndeterminate()
|
|
|
});
|
|
|
if (res.Ret !== 200) return;
|
|
|
MessagePlugin.success('权限设置成功');
|
|
@@ -107,6 +142,26 @@ const handleBtnClik = async (type) => {
|
|
|
router.push('/customer/businessList');
|
|
|
};
|
|
|
|
|
|
+function collectIds(arr) {
|
|
|
+ let ids = [];
|
|
|
+ function traverse(array) {
|
|
|
+ for (let item of array) {
|
|
|
+ if (item && typeof item === 'object') {
|
|
|
+ // 收集当前对象的id
|
|
|
+ if ('MenuId' in item) {
|
|
|
+ ids.push(item.MenuId);
|
|
|
+ }
|
|
|
+ // 如果对象有Children属性,递归遍历Children数组
|
|
|
+ if (Array.isArray(item.Children)) {
|
|
|
+ traverse(item.Children);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ traverse(arr);
|
|
|
+ return ids;
|
|
|
+}
|
|
|
+
|
|
|
// 处理复选框变化
|
|
|
const handleCheckChange = (choiceList) => {
|
|
|
const keys = choiceList || defaultCheckedKeys.value || [];
|
|
@@ -118,12 +173,13 @@ const handleCheckChange = (choiceList) => {
|
|
|
if (ChoiceList.includes(i)) nodeLength++;
|
|
|
if (!ChoiceList.includes(i)) nodeLength--;
|
|
|
});
|
|
|
-
|
|
|
+ console.log(nodeLength === topLevelNodes.length);
|
|
|
+
|
|
|
if (nodeLength === topLevelNodes.length) {
|
|
|
checkAll.value = true;
|
|
|
isIndeterminate.value = false;
|
|
|
} else {
|
|
|
- checkAll.value = false;
|
|
|
+ // checkAll.value = false;
|
|
|
isIndeterminate.value = Boolean(ChoiceList.length);
|
|
|
}
|
|
|
};
|
|
@@ -133,17 +189,10 @@ watch(
|
|
|
() => checkAll.value,
|
|
|
(newVal) => {
|
|
|
if (newVal) {
|
|
|
- const topLevelNodes = authList.value.map(i => i.MenuId);
|
|
|
- // refCheckboxTree.value.setCheckedKeys(topLevelNodes);
|
|
|
- defaultCheckedKeys.value = topLevelNodes;
|
|
|
- } else {
|
|
|
- console.log(isIndeterminate.value);
|
|
|
-
|
|
|
- if (isIndeterminate.value) {
|
|
|
- defaultCheckedKeys.value = []
|
|
|
- isIndeterminate.value = false;
|
|
|
|
|
|
- }
|
|
|
+ defaultCheckedKeys.value = collectIds(authList.value)
|
|
|
+ } else {
|
|
|
+ defaultCheckedKeys.value = []
|
|
|
}
|
|
|
}
|
|
|
);
|
|
@@ -153,9 +202,6 @@ watch(
|
|
|
onMounted(() => {
|
|
|
getBusinessAuthList();
|
|
|
});
|
|
|
-
|
|
|
-// 假设checkboxTree组件的ref
|
|
|
-const refCheckboxTree = ref(null);
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|