|
@@ -7,16 +7,18 @@
|
|
|
:style="{ width: '300px', height: '30px' }"
|
|
:style="{ width: '300px', height: '30px' }"
|
|
|
placeholder="请输入搜索内容"
|
|
placeholder="请输入搜索内容"
|
|
|
:prefix-icon="Search"
|
|
:prefix-icon="Search"
|
|
|
- @input="onSearch"
|
|
|
|
|
clearable
|
|
clearable
|
|
|
/></el-form-item>
|
|
/></el-form-item>
|
|
|
<el-tree
|
|
<el-tree
|
|
|
|
|
+ v-loading="loading"
|
|
|
ref="treeRef"
|
|
ref="treeRef"
|
|
|
- :data="filterData"
|
|
|
|
|
|
|
+ :data="nodeData"
|
|
|
show-checkbox
|
|
show-checkbox
|
|
|
node-key="id"
|
|
node-key="id"
|
|
|
:props="defaultProps"
|
|
:props="defaultProps"
|
|
|
- :default-expand-all="true"
|
|
|
|
|
|
|
+ :render-after-expand="false"
|
|
|
|
|
+ :filter-node-method="filterNode"
|
|
|
|
|
+ accordion
|
|
|
@node-click="handleNodeClick"
|
|
@node-click="handleNodeClick"
|
|
|
@check-change="handleCheckChange"
|
|
@check-change="handleCheckChange"
|
|
|
/>
|
|
/>
|
|
@@ -60,11 +62,13 @@
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
import { onMounted, ref, watch } from 'vue';
|
|
import { onMounted, ref, watch } from 'vue';
|
|
|
import { Search } from '@element-plus/icons-vue';
|
|
import { Search } from '@element-plus/icons-vue';
|
|
|
-import type { ElTree } from 'element-plus';
|
|
|
|
|
|
|
+import { ElTree } from 'element-plus';
|
|
|
import { treeSelected, TreeNode, FormattedNode } from '../type';
|
|
import { treeSelected, TreeNode, FormattedNode } from '../type';
|
|
|
import { countLeafNodes, formatTree } from '../hook/index';
|
|
import { countLeafNodes, formatTree } from '../hook/index';
|
|
|
import { queryUserTree } from '../api/index';
|
|
import { queryUserTree } from '../api/index';
|
|
|
import { cloneDeep } from 'lodash-es';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
|
+import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
|
|
|
|
|
+const loading = ref(true);
|
|
|
const queryStr = ref<string>('');
|
|
const queryStr = ref<string>('');
|
|
|
const defaultProps = {
|
|
const defaultProps = {
|
|
|
children: 'children',
|
|
children: 'children',
|
|
@@ -72,45 +76,34 @@ const defaultProps = {
|
|
|
};
|
|
};
|
|
|
const treeData = ref<TreeNode[]>();
|
|
const treeData = ref<TreeNode[]>();
|
|
|
const nodeData = ref<FormattedNode[]>();
|
|
const nodeData = ref<FormattedNode[]>();
|
|
|
-const filterData = ref<FormattedNode[]>();
|
|
|
|
|
-
|
|
|
|
|
-const filterTree = (nodes: FormattedNode[], keyword: string): FormattedNode[] => {
|
|
|
|
|
- const filteredNodes: FormattedNode[] = [];
|
|
|
|
|
- const traverse = (node) => {
|
|
|
|
|
- let includeNode = false;
|
|
|
|
|
- if (node.name.includes(keyword)) {
|
|
|
|
|
- includeNode = true;
|
|
|
|
|
- }
|
|
|
|
|
- if (node.children) {
|
|
|
|
|
- const filteredChildren = node.children
|
|
|
|
|
- .map((child) => traverse(child))
|
|
|
|
|
- .filter((child) => child !== null);
|
|
|
|
|
- if (filteredChildren.length > 0) {
|
|
|
|
|
- includeNode = true;
|
|
|
|
|
- node = { ...node, children: filteredChildren };
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return includeNode ? node : null;
|
|
|
|
|
- };
|
|
|
|
|
- nodes.forEach((node) => {
|
|
|
|
|
- const result = traverse(node);
|
|
|
|
|
- if (result !== null) {
|
|
|
|
|
- filteredNodes.push(result);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- return filteredNodes;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-const onSearch = () => {
|
|
|
|
|
- if (queryStr.value) {
|
|
|
|
|
- filterData.value = filterTree(nodeData.value!, queryStr.value);
|
|
|
|
|
- } else {
|
|
|
|
|
- filterData.value = nodeData.value;
|
|
|
|
|
|
|
+const filterNode = (query: string, nodeData: FormattedNode, node: any) => {
|
|
|
|
|
+ if (!query) return true;
|
|
|
|
|
+ nodeData.filter = nodeData.name!.includes(query);
|
|
|
|
|
+ if (!nodeData.filter && node.level > 1) {
|
|
|
|
|
+ nodeData.filter = node.parent.data.filter;
|
|
|
}
|
|
}
|
|
|
|
|
+ return nodeData.filter!;
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+const treeRef = ref<InstanceType<typeof ElTree>>();
|
|
|
const total = ref<number>(0);
|
|
const total = ref<number>(0);
|
|
|
const selected = ref<number>(0);
|
|
const selected = ref<number>(0);
|
|
|
const selectedPeople = ref<treeSelected[]>([]);
|
|
const selectedPeople = ref<treeSelected[]>([]);
|
|
|
|
|
+const handleTagClose = (id) => {
|
|
|
|
|
+ const index = selectedPeople.value.findIndex((item) => item.id === id);
|
|
|
|
|
+ if (index !== -1) {
|
|
|
|
|
+ selectedPeople.value.splice(index, 1);
|
|
|
|
|
+ selected.value = selectedPeople.value.length;
|
|
|
|
|
+ treeRef.value!.setChecked(id, false, true);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+const emit = defineEmits(['cancel', 'submit']);
|
|
|
|
|
+const handleCancle = () => {
|
|
|
|
|
+ emit('cancel');
|
|
|
|
|
+};
|
|
|
|
|
+const handleSubmit = () => {
|
|
|
|
|
+ emit('submit', selectedPeople.value);
|
|
|
|
|
+};
|
|
|
const handleCheckChange = (node, checked) => {
|
|
const handleCheckChange = (node, checked) => {
|
|
|
if (!node.children || (node.children.length === 0 && node.userId)) {
|
|
if (!node.children || (node.children.length === 0 && node.userId)) {
|
|
|
if (checked) {
|
|
if (checked) {
|
|
@@ -128,25 +121,9 @@ const handleCheckChange = (node, checked) => {
|
|
|
selected.value = selectedPeople.value.length;
|
|
selected.value = selectedPeople.value.length;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
-const treeRef = ref<InstanceType<typeof ElTree>>();
|
|
|
|
|
-const handleTagClose = (id) => {
|
|
|
|
|
- const index = selectedPeople.value.findIndex((item) => item.id === id);
|
|
|
|
|
- if (index !== -1) {
|
|
|
|
|
- selectedPeople.value.splice(index, 1);
|
|
|
|
|
- selected.value = selectedPeople.value.length;
|
|
|
|
|
- treeRef.value!.setChecked(id, false, true);
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-const emit = defineEmits(['cancel', 'submit']);
|
|
|
|
|
-const handleCancle = () => {
|
|
|
|
|
- emit('cancel');
|
|
|
|
|
-};
|
|
|
|
|
-const handleSubmit = () => {
|
|
|
|
|
- emit('submit', selectedPeople.value);
|
|
|
|
|
-};
|
|
|
|
|
-const handleNodeClick = (node) => {
|
|
|
|
|
- const isChecked = treeRef.value!.getCheckedKeys().includes(node.id);
|
|
|
|
|
- treeRef.value!.setChecked(node.id,!isChecked,true);
|
|
|
|
|
|
|
+const handleNodeClick = (node, checked) => {
|
|
|
|
|
+ handleCheckChange(node, checked.checked);
|
|
|
|
|
+ treeRef.value!.setChecked(node.id, !checked.checked, true);
|
|
|
};
|
|
};
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
|
selectedUser: treeSelected[];
|
|
selectedUser: treeSelected[];
|
|
@@ -155,10 +132,10 @@ onMounted(() => {
|
|
|
queryUserTree().then((res) => {
|
|
queryUserTree().then((res) => {
|
|
|
treeData.value = res;
|
|
treeData.value = res;
|
|
|
nodeData.value = formatTree(treeData.value!);
|
|
nodeData.value = formatTree(treeData.value!);
|
|
|
- filterData.value = nodeData.value;
|
|
|
|
|
total.value = countLeafNodes(nodeData.value);
|
|
total.value = countLeafNodes(nodeData.value);
|
|
|
- const selectedIds: string[] = selectedPeople.value.map((item) => item.id as string);
|
|
|
|
|
|
|
+ const selectedIds: TreeKey[] = selectedPeople.value.map((item) => item.id as string);
|
|
|
treeRef.value!.setCheckedKeys(selectedIds);
|
|
treeRef.value!.setCheckedKeys(selectedIds);
|
|
|
|
|
+ loading.value = false;
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
watch(
|
|
watch(
|
|
@@ -169,6 +146,9 @@ watch(
|
|
|
},
|
|
},
|
|
|
{ immediate: true },
|
|
{ immediate: true },
|
|
|
);
|
|
);
|
|
|
|
|
+watch(queryStr, (query) => {
|
|
|
|
|
+ treeRef.value!.filter(query);
|
|
|
|
|
+});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|