|
|
|
@ -1,5 +1,5 @@ |
|
|
|
<script lang='ts' setup> |
|
|
|
import { computed, onMounted, onBeforeMount,nextTick,inject } from 'vue' |
|
|
|
import { computed, onMounted, onBeforeMount, onUnmounted, nextTick, inject, ref, watch } from 'vue' |
|
|
|
import { criteriaForPeopleList } from '@/api/hr/org/type' |
|
|
|
import request from '@/utils/request'; |
|
|
|
import { useAttrs } from 'vue' |
|
|
|
@ -15,7 +15,6 @@ const props = withDefaults( |
|
|
|
{} |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const emits = defineEmits<{ |
|
|
|
(e: 'update:modelValue', value: string): void |
|
|
|
}>() |
|
|
|
@ -30,6 +29,9 @@ const { location, updateLocation } = inject('location') |
|
|
|
// 上一次选择的值,用于比较 |
|
|
|
const lastSelectedValue = ref(null) |
|
|
|
|
|
|
|
// 修复:组件挂载状态,用于防止卸载后异步操作更新状态 |
|
|
|
const isMounted = ref(false) |
|
|
|
|
|
|
|
// 处理值变化 |
|
|
|
const handleValueChange = (newValue) => { |
|
|
|
if (!multiSelect.value) { |
|
|
|
@ -60,8 +62,9 @@ const handleValueChange = (newValue) => { |
|
|
|
//实现选择用户选择时,自动填充选择组织 liwenxuan 2025-11-11 start |
|
|
|
|
|
|
|
//监听选择用户的当前值,告知父组件form |
|
|
|
updateLocation(value.value,props.data.name) |
|
|
|
|
|
|
|
if (isMounted.value) { |
|
|
|
updateLocation(value.value, props.data.name) |
|
|
|
} |
|
|
|
|
|
|
|
//实现选择用户选择时,自动填充选择组织 liwenxuan 2025-11-11 end |
|
|
|
} else { |
|
|
|
@ -114,10 +117,28 @@ function parseStringToArray(str: string) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 修复:递归清洗树数据,移除所有非数组的children字段 |
|
|
|
const sanitizeTreeData = (data: any[]): any[] => { |
|
|
|
if (!Array.isArray(data)) return []; |
|
|
|
return data.map(node => { |
|
|
|
const newNode = { ...node }; |
|
|
|
if (newNode.children != null) { |
|
|
|
if (Array.isArray(newNode.children)) { |
|
|
|
// 递归清洗子节点 |
|
|
|
newNode.children = sanitizeTreeData(newNode.children); |
|
|
|
} else { |
|
|
|
// 非数组的children会引发el-tree报错,直接删除 |
|
|
|
delete newNode.children; |
|
|
|
} |
|
|
|
} |
|
|
|
return newNode; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
onBeforeMount(() => { |
|
|
|
setTimeout(()=>{ |
|
|
|
// 修复:组件卸载后不再执行 |
|
|
|
if (!isMounted.value) return; |
|
|
|
if(props.modelValue){ |
|
|
|
const initialValue = parseStringToArray(props.modelValue) |
|
|
|
value.value = initialValue; |
|
|
|
@ -126,14 +147,21 @@ onBeforeMount(() => { |
|
|
|
} |
|
|
|
} |
|
|
|
},1500) |
|
|
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
isMounted.value = true; |
|
|
|
}) |
|
|
|
|
|
|
|
onUnmounted(()=>{ |
|
|
|
//console.log("onUnmounted") |
|
|
|
isMounted.value = false; |
|
|
|
// 清理轮询定时器 |
|
|
|
if (pollingTimer) clearTimeout(pollingTimer); |
|
|
|
}) |
|
|
|
|
|
|
|
// 修复:增加轮询定时器清理 |
|
|
|
let pollingTimer: ReturnType<typeof setTimeout> | null = null; |
|
|
|
|
|
|
|
// 递归处理树节点,将部门节点设置为禁用 |
|
|
|
const processTreeData = (data: any[]) => { |
|
|
|
return data.map(node => { |
|
|
|
@ -165,17 +193,23 @@ const loadFullData = async () => { |
|
|
|
|
|
|
|
const result = await checkorgAndManTree1(); |
|
|
|
|
|
|
|
// 根据multiSelect的值处理数据 |
|
|
|
const processedData = !multiSelect.value ? processTreeData(result) : result; |
|
|
|
// 修复:先清洗非法children,再处理禁用状态 |
|
|
|
const cleanedData = sanitizeTreeData(result); |
|
|
|
const processedData = !multiSelect.value ? processTreeData(cleanedData) : cleanedData; |
|
|
|
|
|
|
|
treeData.value = processedData; |
|
|
|
isDataLoaded.value = true; |
|
|
|
// 修复:仅在组件挂载时更新数据 |
|
|
|
if (isMounted.value) { |
|
|
|
treeData.value = processedData; |
|
|
|
isDataLoaded.value = true; |
|
|
|
} |
|
|
|
return processedData; |
|
|
|
} catch (error) { |
|
|
|
console.error('加载组织数据失败:', error); |
|
|
|
return []; |
|
|
|
} finally { |
|
|
|
loading.value = false; |
|
|
|
if (isMounted.value) { |
|
|
|
loading.value = false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -200,6 +234,11 @@ const resData = computed(() => { |
|
|
|
function checkorgAndManTree1() { |
|
|
|
return new Promise((resolve) => { |
|
|
|
const check = () => { |
|
|
|
// 修复:组件已卸载,不再继续轮询 |
|
|
|
if (!isMounted.value) { |
|
|
|
resolve([]); |
|
|
|
return; |
|
|
|
} |
|
|
|
let result = [] |
|
|
|
let i = 0 |
|
|
|
props.orgAndManTree.forEach((element: any) => { |
|
|
|
@ -216,7 +255,7 @@ function checkorgAndManTree1() { |
|
|
|
}); |
|
|
|
resolve(result) |
|
|
|
} else { |
|
|
|
setTimeout(check, 100) |
|
|
|
pollingTimer = setTimeout(check, 100) |
|
|
|
} |
|
|
|
} |
|
|
|
check() |
|
|
|
|