|
|
|
|
<script lang='ts' setup>
|
|
|
|
|
import { computed, onMounted, nextTick } from 'vue'
|
|
|
|
|
import { criteriaForPeopleList } from '@/api/hr/org/type'
|
|
|
|
|
import request from '@/utils/request';
|
|
|
|
|
import { useAttrs } from 'vue'
|
|
|
|
|
const attrs = useAttrs()
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
modelValue?: string
|
|
|
|
|
disabled?: boolean
|
|
|
|
|
orgAndManTree?: any;
|
|
|
|
|
data?: any;
|
|
|
|
|
}>(),
|
|
|
|
|
{}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const emits = defineEmits<{
|
|
|
|
|
(e: 'update:modelValue', value: string): void
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const value = ref([])
|
|
|
|
|
const treeData = ref([]) // 存储懒加载的数据
|
|
|
|
|
const isDataLoaded = ref(false) // 标记数据是否已加载
|
|
|
|
|
|
|
|
|
|
watch(value, (newValue) => {
|
|
|
|
|
if (newValue.length > 0) {
|
|
|
|
|
let str = ""
|
|
|
|
|
let userAry = new Array
|
|
|
|
|
|
|
|
|
|
newValue.forEach(item => {
|
|
|
|
|
userAry.push(item)
|
|
|
|
|
})
|
|
|
|
|
str = userAry.join(',')
|
|
|
|
|
emits('update:modelValue', str)
|
|
|
|
|
} else {
|
|
|
|
|
let str = ""
|
|
|
|
|
emits('update:modelValue', str)
|
|
|
|
|
}
|
|
|
|
|
}, { deep: true })
|
|
|
|
|
|
|
|
|
|
function parseStringToArray(str: string) {
|
|
|
|
|
try {
|
|
|
|
|
const result = JSON.parse(str);
|
|
|
|
|
if (Array.isArray(result)) {
|
|
|
|
|
return result;
|
|
|
|
|
} else {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onBeforeMount(() => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
value.value = parseStringToArray(props.modelValue)
|
|
|
|
|
}, 500)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 加载完整数据的函数
|
|
|
|
|
const loadFullData = async () => {
|
|
|
|
|
if (isDataLoaded.value) return treeData.value;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const result = checkorgAndManTree1();
|
|
|
|
|
treeData.value = result;
|
|
|
|
|
isDataLoaded.value = true;
|
|
|
|
|
return result;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('加载组织数据失败:', error);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 点击树选择器时的处理
|
|
|
|
|
const handleTreeSelectClick = async () => {
|
|
|
|
|
if (!isDataLoaded.value) {
|
|
|
|
|
await loadFullData();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下拉框显示状态变化时的处理
|
|
|
|
|
const handleVisibleChange = async (visible: boolean) => {
|
|
|
|
|
if (visible && !isDataLoaded.value) {
|
|
|
|
|
await loadFullData();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resData = computed(() => {
|
|
|
|
|
return treeData.value;
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function checkorgAndManTree1() {
|
|
|
|
|
let result = []
|
|
|
|
|
let i = 0
|
|
|
|
|
props.orgAndManTree.forEach((element: any) => {
|
|
|
|
|
if (element.hasOwnProperty('tree') && hasNodesInTree(element.tree)) {
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (i == props.orgAndManTree.length) {
|
|
|
|
|
props.orgAndManTree.forEach((item: any) => {
|
|
|
|
|
if (props.data.name == item.name) {
|
|
|
|
|
//console.log(item.tree)
|
|
|
|
|
result = item.tree
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return result
|
|
|
|
|
} else {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
checkorgAndManTree1()
|
|
|
|
|
}, 100)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判断树形结构是否存在节点
|
|
|
|
|
*/
|
|
|
|
|
function hasNodesInTree(tree) {
|
|
|
|
|
if (!Array.isArray(tree)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNode(node) {
|
|
|
|
|
if (node == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const node of tree) {
|
|
|
|
|
if (checkNode(node)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (Array.isArray(node?.children) && hasNodesInTree(node.children)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div style="width:100%">
|
|
|
|
|
<el-tree-select
|
|
|
|
|
node-key="number"
|
|
|
|
|
v-model="value"
|
|
|
|
|
:data="resData"
|
|
|
|
|
multiple
|
|
|
|
|
:render-after-expand="false"
|
|
|
|
|
show-checkbox
|
|
|
|
|
clearable
|
|
|
|
|
collapse-tags
|
|
|
|
|
collapse-tags-tooltip
|
|
|
|
|
:max-collapse-tags="4"
|
|
|
|
|
filterable
|
|
|
|
|
@click="handleTreeSelectClick"
|
|
|
|
|
@visible-change="handleVisibleChange"
|
|
|
|
|
:disabled="props.disabled"
|
|
|
|
|
:popper-append-to-body="false"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<style lang='scss' scoped></style>
|