diff --git a/src/components/DesignForm/public/expand/rangedUserTree.vue b/src/components/DesignForm/public/expand/rangedUserTree.vue index dd16fd8..8b5ffd3 100644 --- a/src/components/DesignForm/public/expand/rangedUserTree.vue +++ b/src/components/DesignForm/public/expand/rangedUserTree.vue @@ -10,6 +10,7 @@ const props = withDefaults( modelValue?: string disabled?: boolean orgAndManTree?: any; + data?: any; }>(), {} ) @@ -19,239 +20,152 @@ const emits = defineEmits<{ (e: 'update:modelValue', value: string): void }>() -const value = ref([]) -watch(value,(newValue)=>{ - if(newValue.length > 0){ - let str = "" - - let userAry = new Array - - newValue.forEach(item =>{ - //console.log(item) - userAry.push(item) - - }) - str = userAry.join(',') - //console.log(str) - emits('update:modelValue', str) - // userlist.value = userAry.join(',') - // - }else{ - let str = "" - //console.log(str) - emits('update:modelValue', str) - } -},{ deep: true }) +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) { +function parseStringToArray(str: string) { try { - // 尝试解析JSON格式字符串 const result = JSON.parse(str); - // 验证解析结果是否为数组 if (Array.isArray(result)) { return result; } else { - //console.error("解析结果不是数组"); return []; } } catch (error) { - //console.error("字符串格式错误,无法解析为数组:", error.message); return []; } } -onBeforeMount(() => { - checkorgAndManTree() - setTimeout(()=>{ - value.value = parseStringToArray(props.modelValue) - },500 ) -}) - - -const keys = computed(()=>{ - if(attrs.queryBy == 'role'){ - return attrs.roleRange - }else{ - return attrs.orgRange - } +onBeforeMount(() => { + setTimeout(() => { + value.value = parseStringToArray(props.modelValue) + }, 500) }) - - -const resData = ref() - -const checkorgAndManTree = (()=>{ - if(props.orgAndManTree&&props.orgAndManTree.children&&props.orgAndManTree.children.length>0){ - //alert(1) - let arr = [] - arr.push(modifyTreeData(props.orgAndManTree,keys.value)) - - resData.value = arr - }else{ - setTimeout(()=>{ - checkorgAndManTree() - },100) +// 加载完整数据的函数 +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(); + } +} -onUnmounted(()=>{ - alert(1) +const resData = computed(() => { + return treeData.value; }) - - -function modifyTreeData(treeData, idList) { - console.log("modifyTreeData 执行了") - // 深拷贝树数据,避免修改原数据 - const newTreeData = JSON.parse(JSON.stringify(treeData)); - - // 确保idList是一个数组 - const idArray = Array.isArray(idList) ? idList : [idList]; - if (idArray.length === 0) return Array.isArray(newTreeData) ? [] : null; - - // 1. 收集所有节点,记录:id→节点映射、id→父节点id映射(检测多父节点) - const nodeMap = new Map(); // id → 节点 - const parentMap = new Map(); // id → 父节点id(确保每个节点只有一个父节点) - const multiParentIds = new Set(); // 记录有多个父节点的id - - function collectNodes(node, parentId) { - if (!node || typeof node !== 'object' || !node.id) return; // 跳过无效节点 - - // 记录节点映射 - if (!nodeMap.has(node.id)) { - nodeMap.set(node.id, node); +function checkorgAndManTree1() { + let result = [] + let i = 0 + props.orgAndManTree.forEach((element: any) => { + if (element.hasOwnProperty('tree') && hasNodesInTree(element.tree)) { + i++ } - - // 记录父节点(检测多父节点) - if (parentMap.has(node.id)) { - // 已存在父节点,且与当前父节点不同 → 多父节点 - if (parentMap.get(node.id) !== parentId) { - multiParentIds.add(node.id); - } - } else { - parentMap.set(node.id, parentId); // 首次记录父节点 - } - - // 递归处理子节点,传入当前节点id作为父节点id - if (node.children && Array.isArray(node.children)) { - node.children.forEach(child => collectNodes(child, node.id)); - } - } + }); - // 处理根节点(可能是单个节点或数组) - if (Array.isArray(newTreeData)) { - newTreeData.forEach(root => collectNodes(root, null)); // 根节点父id为null + 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 { - collectNodes(newTreeData, null); + setTimeout(() => { + checkorgAndManTree1() + }, 100) } - - // 警告多父节点问题(核心重复原因) - if (multiParentIds.size > 0) { - console.warn(`以下节点存在多个父节点,可能导致重复:${Array.from(multiParentIds).join(', ')}`); +} + +/** + * 判断树形结构是否存在节点 + */ +function hasNodesInTree(tree) { + if (!Array.isArray(tree)) { + return false; } - - // 2. 收集需要保留的节点ID:目标节点+直系祖先(基于parentMap追溯,确保唯一路径) - const keepIds = new Set(); - idArray.forEach(targetId => { - let currentId = targetId; - // 从目标节点向上追溯,直到根节点(parentId为null) - while (currentId !== null && nodeMap.has(currentId)) { - keepIds.add(currentId); - currentId = parentMap.get(currentId); // 基于唯一父节点追溯 - } - }); - - // 3. 过滤树结构:仅保留keepIds中的节点,且严格校验子节点的parentId是否匹配当前父节点 - function filterTree(node) { - if (!node || typeof node !== 'object' || !keepIds.has(node.id)) { - return null; - } - - // 复制节点(避免修改原引用) - const filteredNode = { ...node }; - - // 处理子节点:仅保留符合条件的子节点(在keepIds中,且parentId等于当前节点id) - if (filteredNode.children && Array.isArray(filteredNode.children)) { - // 临时存储符合条件的子节点(去重) - const validChildren = new Map(); // 用id去重 - - filteredNode.children.forEach(child => { - // 校验:子节点必须在keepIds中,且其父节点id是当前节点id - if (child && typeof child === 'object' && child.id && - keepIds.has(child.id) && parentMap.get(child.id) === filteredNode.id) { - const filteredChild = filterTree(child); - if (filteredChild) { - validChildren.set(filteredChild.id, filteredChild); // 用id去重 - } - } - }); - - // 转为数组,保持原数据格式(空数组→null) - filteredNode.children = Array.from(validChildren.values()); - if (filteredNode.children.length === 0) { - filteredNode.children = null; - } - } else { - filteredNode.children = null; + + function checkNode(node) { + if (node == null) { + return false; } - - return filteredNode; - } - - // 处理根节点(数组或单个节点) - let filteredTree; - if (Array.isArray(newTreeData)) { - // 根节点必须在keepIds中,且父节点为null - filteredTree = newTreeData - .map(root => { - if (root && keepIds.has(root.id) && parentMap.get(root.id) === null) { - return filterTree(root); - } - return null; - }) - .filter(Boolean); - } else { - filteredTree = (keepIds.has(newTreeData.id) && parentMap.get(newTreeData.id) === null) - ? filterTree(newTreeData) - : null; + return true; } - - // 4. 对目标节点修改label和添加number属性 - function modifyLabels(node) { - if (!node || typeof node !== 'object') return; - - if (idArray.includes(node.id)) { - const newLabel = `${node.label}(${node.value || ''})`; - node.label = newLabel; - node.number = newLabel; + + for (const node of tree) { + if (checkNode(node)) { + return true; } - - if (node.children && Array.isArray(node.children)) { - node.children.forEach(child => modifyLabels(child)); + if (Array.isArray(node?.children) && hasNodesInTree(node.children)) { + return true; } } - - // 执行标签修改 - if (Array.isArray(filteredTree)) { - filteredTree.forEach(root => modifyLabels(root)); - } else { - modifyLabels(filteredTree); - } - - return filteredTree; + + return false; } + diff --git a/src/components/DesignForm/public/form/form.vue b/src/components/DesignForm/public/form/form.vue index 83d9cb9..e939203 100644 --- a/src/components/DesignForm/public/form/form.vue +++ b/src/components/DesignForm/public/form/form.vue @@ -1718,7 +1718,7 @@ watch( // ------------------------数据处理结束------------------------ - +const rangedUserTrees1= ref([]); const treeUrl = '/javasys/lowCode/transfer/getOrgAndManTree' const orgAndManTree = ref() function getOrgAndManTree() { @@ -1731,21 +1731,205 @@ function getTree1() { getOrgAndManTree().then(({ data }) => { orgAndManTree.value = data - }) + }).finally(()=>{ + console.log(rangedUsers) + + // 使用示例 + const configArray = rangedUsers; + const groupedNames = groupExpandUserConfigs(configArray); + console.log(groupedNames); + groupedNames.forEach((element:any) => { + let keys = element.keys + let arr = [] + arr.push(modifyTreeData(orgAndManTree.value,keys)) + element.tree = arr + + rangedUsers.forEach((item:any) => { + let i = 0 + element.groupArray.forEach((el:any) => { + if(item.name==el){ + i++ + } + }); + if(i>0){ + item.tree = element.tree + } + }); + }); + rangedUserTrees1.value = rangedUsers + }) +} + + + + + + +function modifyTreeData(treeData, idList) { + console.log("modifyTreeDataMinimal 执行了"); + + const idArray = Array.isArray(idList) ? idList : [idList]; + if (idArray.length === 0 || !treeData) { + return Array.isArray(treeData) ? [] : null; + } + + const roots = Array.isArray(treeData) ? treeData : [treeData]; + + // 创建节点映射和父节点映射 + const nodeMap = new Map(); + const parentMap = new Map(); + + // 使用迭代而非递归构建映射,避免栈溢出 + const stack = [...roots]; + + while (stack.length > 0) { + const node = stack.pop(); + if (!node?.id) continue; + + nodeMap.set(node.id, node); + + if (node.children) { + for (const child of node.children) { + if (child?.id) { + parentMap.set(child.id, node.id); + stack.push(child); + } + } + } + } + + // 找到需要保留的节点(目标节点及其祖先) + const keepIds = new Set(); + for (const id of idArray) { + let currentId = id; + while (currentId && nodeMap.has(currentId)) { + keepIds.add(currentId); + currentId = parentMap.get(currentId); + } + } + + // 构建结果树 - 修复重复问题 + const result = []; + const processedIds = new Set(); // 跟踪已处理的节点ID,防止重复 + + // 只处理根节点中需要保留的节点 + for (const root of roots) { + if (!root?.id || !keepIds.has(root.id) || processedIds.has(root.id)) { + continue; + } + + processedIds.add(root.id); + result.push(buildNodeTree(root, keepIds, idArray, processedIds)); + } + + // 清理临时数据 + nodeMap.clear(); + parentMap.clear(); + keepIds.clear(); + processedIds.clear(); + + return Array.isArray(treeData) ? result : result[0] || null; +} + +// 辅助函数:递归构建节点树 +function buildNodeTree(node, keepIds, idArray, processedIds) { + const newNode = { + id: node.id, + label: node.label, + value: node.value + }; + + // 修改目标节点的标签 + if (idArray.includes(node.id)) { + newNode.label = `${node.label}(${node.value || ''})`; + newNode.number = newNode.label; + } + + // 处理子节点 + if (node.children && node.children.length > 0) { + const children = []; + for (const child of node.children) { + if (child?.id && keepIds.has(child.id) && !processedIds.has(child.id)) { + processedIds.add(child.id); + children.push(buildNodeTree(child, keepIds, idArray, processedIds)); + } + } + if (children.length > 0) { + newNode.children = children; + } + } + + return newNode; +} + + + + +function groupExpandUserConfigs(configs) { + // 用于存储分组结果的Map + // key是排序后的范围数组字符串,value是包含names和原始keys的对象 + const groupMap = new Map(); + + configs.forEach(config => { + // 根据queryBy确定使用哪个范围数组 + let range, rangeType; + if (config.control.queryBy === 'org') { + range = config.control.orgRange; + rangeType = 'orgRange'; + } else { + range = config.control.roleRange; + rangeType = 'roleRange'; + } + + // 对范围数组进行排序并转换为字符串作为分组key + const sortedRange = [...range].sort().join(','); + + // 如果该分组key不存在,创建新的分组 + if (!groupMap.has(sortedRange)) { + groupMap.set(sortedRange, { + names: [], + keys: range, // 存储原始keys,不排序 + rangeType: rangeType + }); + } + + // 将当前配置的name添加到对应分组 + groupMap.get(sortedRange).names.push(config.name); + }); + + // 将Map转换为要求的输出格式 + const result = []; + for (const groupInfo of groupMap.values()) { + result.push({ + groupArray: groupInfo.names, + keys: groupInfo.keys, + rangeType: groupInfo.rangeType // 可选:添加范围类型信息 + }); + } + + return result; } + + + + const asfs: any[] = []; -const rangedUsers: any[] = []; +const rangedUsers :any= []; + const tables: any[] = []; function getAsfs() { - setTimeout(() => { + /* setTimeout(() => { */ + if(props.formData.list&&props.formData.list.length>0){ + //alert(1) let dataList = ref({}); dataList.value = props.formData.list; if (dataList && Array.isArray(dataList.value) && dataList.value.length > 0) { + for (let i = 0; i < dataList.value.length; i++) { if (dataList.value[i].type == "associatedForms") { asfs.push(dataList.value[i]); @@ -1818,8 +2002,14 @@ function getAsfs() { } } } + checkAndGetTree() } - }, 500); + }else{ + setTimeout(()=>{ + getAsfs() + },100) + } + /* }, 500); */ } // 重置表单方法 @@ -1830,6 +2020,7 @@ const resetFields = () => { function checkAndGetTree(){ + console.log("checkAndGetTree") if(rangedUsers.length>0){ getTree1(); }else{ @@ -1844,14 +2035,15 @@ function checkAndGetTree(){ onMounted(() => { + //alert(1) + getAsfs(); // console.log("数据处理结束--->",props.formData) getInitModel(); nextTick(() => { appendRemoveStyle(true); }); showOrHide("kong"); - getAsfs(); - checkAndGetTree(); + }); onUnmounted(() => { @@ -2301,7 +2493,7 @@ const webPage = computed({ :node-key="nodeKey" :purview="purview" @optionsValue3Get2="optionsValue3Get2" - :org-and-man-tree="orgAndManTree" + :org-and-man-tree="rangedUserTrees1" />