<template>
<a-card :bordered="false" style="height: 100%;" :body-style="{ background: backgroundColor }" >
<a-spin :spinning="loading">
<a-input-search v-if="showSearch" placeholder="按部门名称搜索…" style="margin-bottom: 10px" @search="onSearch" allowClear />
<!--组织机构树-->
<template v-if="treeData.length > 0">
<a-tree
v-if="!treeReloading"
:style="{ background: backgroundColor }"
showLine
:clickRowToExpand="false"
:treeData="treeData"
:selectedKeys="selectedKeys"
:load-data="loadChildrenTreeData"
v-model:expandedKeys="expandedKeys"
@select="onSelect"
></a-tree>
</template>
<a-empty v-else description="暂无数据" />
</a-spin>
</a-card>
</template>
<script lang="ts" setup>
import { inject, nextTick, ref, unref } from 'vue';
import { queryDepartTreeSync } from '../address.api';
import { searchByKeywords } from '/@/views/system/departUser/depart.user.api';
import { Popconfirm } from 'ant-design-vue';
const prefixCls = inject('prefixCls');
// 定义props
const props = defineProps({
// 是否显示搜索框
showSearch: {
type: Boolean,
default: true,
},
// 背景色
backgroundColor: {
type: String,
default: 'inherit',
},
});
const emit = defineEmits(['select', 'rootTreeData']);
const loading = ref<boolean>(false);
// 部门树列表数据
const treeData = ref<any[]>([]);
// 当前展开的项
const expandedKeys = ref<any[]>([]);
// 当前选中的项
const selectedKeys = ref<any[]>([]);
// 树组件重新加载
const treeReloading = ref<boolean>(false);
// 当前选中的部门
const currentDepart = ref<any>(null);
// 搜索关键字
const searchKeyword = ref('');
// 加载顶级部门信息
async function loadRootTreeData() {
try {
loading.value = true;
treeData.value = [];
const result = await queryDepartTreeSync();
if (Array.isArray(result)) {
treeData.value = result;
}
if (expandedKeys.value.length === 0) {
autoExpandParentNode();
}
} finally {
loading.value = false;
}
}
loadRootTreeData();
// 加载子级部门信息
async function loadChildrenTreeData(treeNode) {
try {
const result = await queryDepartTreeSync({
pid: treeNode.dataRef.id,
});
if (result.length == 0) {
treeNode.dataRef.isLeaf = true;
} else {
treeNode.dataRef.children = result;
if (expandedKeys.value.length > 0) {
// 判断获取的子级是否有当前展开的项
let subKeys: any[] = [];
for (let key of expandedKeys.value) {
if (result.findIndex((item) => item.id === key) !== -1) {
subKeys.push(key);
}
}
if (subKeys.length > 0) {
expandedKeys.value = [...expandedKeys.value];
}
}
}
treeData.value = [...treeData.value];
} catch (e) {
console.error(e);
}
return Promise.resolve();
}
// 自动展开父节点,只展开一级
function autoExpandParentNode() {
let item = treeData.value[0];
if (item) {
if (!item.isLeaf) {
expandedKeys.value = [item.key];
}
reloadTree();
}
}
// 重新加载树组件,防止无法默认展开数据
async function reloadTree() {
await nextTick();
treeReloading.value = true;
await nextTick();
treeReloading.value = false;
}
/**
* 设置当前选中的行
*/
function setSelectedKey(key: string, data?: object) {
selectedKeys.value = [key];
if (data) {
currentDepart.value = data;
emit('select', data);
}
}
// 搜索事件
async function onSearch(value: string) {
if (value) {
try {
loading.value = true;
treeData.value = [];
let result = await searchByKeywords({ keyWord: value });
if (Array.isArray(result)) {
treeData.value = result;
}
autoExpandParentNode();
} finally {
loading.value = false;
}
} else {
loadRootTreeData();
}
searchKeyword.value = value;
}
// 树选择事件
function onSelect(selKeys, event) {
if (selKeys.length > 0 && selectedKeys.value[0] !== selKeys[0]) {
setSelectedKey(selKeys[0], event.selectedNodes[0]);
} else {
// 这样可以防止用户取消选择
setSelectedKey(selectedKeys.value[0]);
}
}
defineExpose({
loadRootTreeData,
});
</script>