From 7c30901bbcc97e26292f5eda49050a55fe316ec9 Mon Sep 17 00:00:00 2001 From: liwenxuan <1298531568@qq.com> Date: Thu, 11 Dec 2025 15:18:13 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=85=B3=E8=81=94=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=BC=98=E5=8C=96=E4=B8=BA=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DesignForm/formControlPropertiNew.vue | 514 +++++++++++++++++- 1 file changed, 509 insertions(+), 5 deletions(-) diff --git a/src/components/DesignForm/formControlPropertiNew.vue b/src/components/DesignForm/formControlPropertiNew.vue index 07791ae..aa93fea 100644 --- a/src/components/DesignForm/formControlPropertiNew.vue +++ b/src/components/DesignForm/formControlPropertiNew.vue @@ -2828,6 +2828,508 @@ function getAssociatedFormsCurrentFieldTree1() { } }); } + +//关联选项设置优化为树 liwenxuan 20251209 start +let datapropsformList = JSON.parse(JSON.stringify(props.formList)) +const glxxszTree = computed(()=>{ + if(datapropsformList.length==0){ + datapropsformList = JSON.parse(JSON.stringify(props.formList)) + } + + console.log(datapropsformList) + if(associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf && associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children && associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children.length>0){ + + + let datab = JSON.parse(JSON.stringify(associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children)) + + const treeC = mergeFormTrees(datapropsformList, datab); + return treeC + }else{ + return null + } + +}) + + + +/** + * 合并两个组件树,以组件树a的结构为准,填充组件树b的数据 + * @param {Array} treeA - 组件树a,包含表单结构信息 + * @param {Array} treeB - 组件树b,包含字段数据信息 + * @returns {Array} - 合并后的组件树c + */ +function mergeFormTrees(treeA, treeB) { + // 构建b树的映射,key为name(从id中提取),value为b树节点 + const bMap = new Map(); + + // 从b树中提取通用的parentId(假设所有节点有相同的parentId) + let commonParentId = null; + + // 从id中提取name:formField:30540:upload1765154030446 -> upload1765154030446 + treeB.forEach(node => { + const id = node.id; + if (id) { + const parts = id.split(':'); + const name = parts[parts.length - 1]; // 取最后一部分作为name + bMap.set(name, node); + + // 设置通用的parentId + if (node.parentId && !commonParentId) { + commonParentId = node.parentId; + } + } + }); + + // 如果没有找到parentId,使用默认值 + if (!commonParentId) { + commonParentId = "formField:30540"; // 默认值,但最好从b树中获取 + } + + // 计数器 + let gridCount = 0; + let tabsCount = 0; + let divCount = 0; + let cardCount = 0; + + // 递归处理a树 + function processANode(node, parentId = commonParentId) { + // 获取当前节点的name + const nodeName = node.name; + + // 处理flex类型 + if (node.type === 'flex') { + // 查找b树中对应的节点 + let bNode = null; + if (nodeName && bMap.has(nodeName)) { + bNode = bMap.get(nodeName); + bMap.delete(nodeName); // 从map中删除,标记为已使用 + } + + let cNode; + let flexLabel = node.item?.label || nodeName || 'flex'; + + if (bNode) { + // 复制b节点的所有属性 + cNode = { ...bNode }; + // 确保children数组存在 + if (!cNode.children) { + cNode.children = []; + } + // 获取原来的label,如果没有则用name + const originalLabel = cNode.label || flexLabel; + // 在label左边拼接"弹性布局" + cNode.label = `弹性布局${originalLabel}`; + + // 如果treeAttrs.show存在,也更新 + if (cNode.treeAttrs && cNode.treeAttrs.show) { + cNode.treeAttrs.show = `弹性布局${cNode.treeAttrs.show}`; + } else if (cNode.treeAttrs) { + cNode.treeAttrs.show = `弹性布局${originalLabel}`; + } + + // 使用b节点的parentId + cNode.parentId = bNode.parentId || parentId; + } else { + // 如果b中不存在,则创建新节点 + cNode = { + id: nodeName ? `${commonParentId}:${nodeName}` : null, + label: `弹性布局${flexLabel}`, + parentId: parentId, + children: [], + value: nodeName ? `${commonParentId}:${nodeName}` : null, + treeAttrs: { + show: `弹性布局${flexLabel}` + }, + disabled: false, // flex类型即使叶子节点也可以选择,设为false + type: 'flex' + }; + } + + // 处理子组件 + let hasChildren = false; + if (node.list && Array.isArray(node.list)) { + const childNodes = []; + node.list.forEach(child => { + const processedChild = processANode(child, cNode.id); + if (processedChild) { + childNodes.push(processedChild); + hasChildren = true; + } + }); + cNode.children = childNodes; + } + + return cNode; + } + + // 处理table类型 + if (node.type === 'table') { + // 查找b树中对应的节点 + let bNode = null; + if (nodeName && bMap.has(nodeName)) { + bNode = bMap.get(nodeName); + bMap.delete(nodeName); // 从map中删除,标记为已使用 + } + + let cNode; + let tableLabel = node.item?.label || nodeName || 'table'; + + if (bNode) { + // 复制b节点的所有属性 + cNode = { ...bNode }; + // 确保children数组存在 + if (!cNode.children) { + cNode.children = []; + } + // 获取原来的label,如果没有则用name + const originalLabel = cNode.label || tableLabel; + // 在label左边拼接"子表" + cNode.label = `子表${originalLabel}`; + + // 如果treeAttrs.show存在,也更新 + if (cNode.treeAttrs && cNode.treeAttrs.show) { + cNode.treeAttrs.show = `子表${cNode.treeAttrs.show}`; + } else if (cNode.treeAttrs) { + cNode.treeAttrs.show = `子表${originalLabel}`; + } + + // 使用b节点的parentId + cNode.parentId = bNode.parentId || parentId; + } else { + // 如果b中不存在,则创建新节点 + cNode = { + id: nodeName ? `${commonParentId}:${nodeName}` : null, + label: `子表${tableLabel}`, + parentId: parentId, + children: [], + value: nodeName ? `${commonParentId}:${nodeName}` : null, + treeAttrs: { + show: `子表${tableLabel}` + }, + disabled: false, // table类型即使叶子节点也可以选择,设为false + type: 'table' + }; + } + + // 处理子组件 + let hasChildren = false; + if (node.list && Array.isArray(node.list)) { + const childNodes = []; + node.list.forEach(child => { + const processedChild = processANode(child, cNode.id); + if (processedChild) { + childNodes.push(processedChild); + hasChildren = true; + } + }); + cNode.children = childNodes; + } + + return cNode; + } + + // 处理grid类型 + if (node.type === 'grid') { + gridCount++; + const gridId = `格栅布局${gridCount}`; + const gridFullId = `${commonParentId}:${gridId}`; + + // 创建grid节点 + const cNode = { + id: gridFullId, + label: gridId, + parentId: parentId, + children: [], + value: gridFullId, + treeAttrs: { + show: gridId + }, + disabled: null, // 非叶子节点,设置为null + type: 'grid' + }; + + // 处理子组件(在columns.list中) + let hasChildren = false; + if (node.columns && Array.isArray(node.columns)) { + const childNodes = []; + node.columns.forEach(column => { + if (column.list && Array.isArray(column.list)) { + column.list.forEach(child => { + const processedChild = processANode(child, gridFullId); + if (processedChild) { + childNodes.push(processedChild); + hasChildren = true; + } + }); + } + }); + cNode.children = childNodes; + } + + // 如果没有子节点,设置disabled为true(容器类型叶子节点) + if (!hasChildren) { + cNode.disabled = true; + } + + return cNode; + } + + // 处理tabs类型 + if (node.type === 'tabs') { + tabsCount++; + const tabsId = `标签页${tabsCount}`; + const tabsFullId = `${commonParentId}:${tabsId}`; + + // 创建tabs节点 + const cNode = { + id: tabsFullId, + label: tabsId, + parentId: parentId, + children: [], + value: tabsFullId, + treeAttrs: { + show: tabsId + }, + disabled: null, // 非叶子节点,设置为null + type: 'tabs' + }; + + // 处理子组件(每个column作为一级) + let hasChildren = false; + if (node.columns && Array.isArray(node.columns)) { + const columnNodes = []; + node.columns.forEach((column, index) => { + // 为每个column创建一个节点 + const columnId = `${tabsFullId}:${column.label}`; + const columnNode = { + id: columnId, + label: column.label || `Tab${index + 1}`, + parentId: tabsFullId, + children: [], + value: columnId, + treeAttrs: { + show: column.label || `Tab${index + 1}` + }, + disabled: null, // 非叶子节点,设置为null + type: 'tab' + }; + + // 处理column中的子组件 + let columnHasChildren = false; + if (column.list && Array.isArray(column.list)) { + const childNodes = []; + column.list.forEach(child => { + const processedChild = processANode(child, columnId); + if (processedChild) { + childNodes.push(processedChild); + columnHasChildren = true; + hasChildren = true; + } + }); + columnNode.children = childNodes; + } + + // 如果column没有子节点,设置disabled为true(容器类型叶子节点) + if (!columnHasChildren) { + columnNode.disabled = true; + } + + columnNodes.push(columnNode); + }); + cNode.children = columnNodes; + } + + // 如果tabs没有子节点,设置disabled为true(容器类型叶子节点) + if (!hasChildren) { + cNode.disabled = true; + } + + return cNode; + } + + // 处理div类型 + if (node.type === 'div') { + divCount++; + const divId = `容器${divCount}`; + const divFullId = `${commonParentId}:${divId}`; + + // 创建div节点 + const cNode = { + id: divFullId, + label: divId, + parentId: parentId, + children: [], + value: divFullId, + treeAttrs: { + show: divId + }, + disabled: null, // 非叶子节点,设置为null + type: 'div' + }; + + // 处理子组件 + let hasChildren = false; + if (node.list && Array.isArray(node.list)) { + const childNodes = []; + node.list.forEach(child => { + const processedChild = processANode(child, divFullId); + if (processedChild) { + childNodes.push(processedChild); + hasChildren = true; + } + }); + cNode.children = childNodes; + } + + // 如果没有子节点,设置disabled为true(容器类型叶子节点) + if (!hasChildren) { + cNode.disabled = true; + } + + return cNode; + } + + // 处理card类型 + if (node.type === 'card') { + cardCount++; + const cardId = `卡片${cardCount}`; + const cardFullId = `${commonParentId}:${cardId}`; + + // 创建card节点 + const cNode = { + id: cardFullId, + label: cardId, + parentId: parentId, + children: [], + value: cardFullId, + treeAttrs: { + show: cardId + }, + disabled: null, // 非叶子节点,设置为null + type: 'card' + }; + + // 处理子组件 + let hasChildren = false; + if (node.list && Array.isArray(node.list)) { + const childNodes = []; + node.list.forEach(child => { + const processedChild = processANode(child, cardFullId); + if (processedChild) { + childNodes.push(processedChild); + hasChildren = true; + } + }); + cNode.children = childNodes; + } + + // 如果没有子节点,设置disabled为true(容器类型叶子节点) + if (!hasChildren) { + cNode.disabled = true; + } + + return cNode; + } + + // 处理其他类型 + // 查找b树中对应的节点 + let bNode = null; + if (nodeName && bMap.has(nodeName)) { + bNode = bMap.get(nodeName); + bMap.delete(nodeName); // 从map中删除,标记为已使用 + } + + // 创建c树节点 + let cNode; + if (bNode) { + // 复制b节点的所有属性 + cNode = { ...bNode }; + // 确保children数组存在 + if (!cNode.children) { + cNode.children = []; + } + // 使用b节点的parentId + cNode.parentId = bNode.parentId || parentId; + } else { + return null; // b中不存在且不是上述容器类型,则忽略 + } + + // 判断是否为叶子节点 + let hasChildren = false; + + // 对于非容器节点,判断是否有子节点 + // 从b节点中获取children信息 + hasChildren = cNode.children && cNode.children.length > 0; + + // 设置disabled属性 + // 容器类型列表 + const containerTypes = ['card', 'div', 'grid', 'tabs']; + + // 如果是容器类型 + if (containerTypes.includes(node.type)) { + // 如果有子节点,设置为null,否则设置为true + cNode.disabled = hasChildren ? null : true; + } else { + // 如果是非容器类型,叶子节点disabled为false + cNode.disabled = false; + } + + return cNode; + } + + // 处理a树的所有根节点 + const cTree = []; + treeA.forEach(rootNode => { + const processedNode = processANode(rootNode); + if (processedNode) { + cTree.push(processedNode); + } + }); + + // 将b树中剩余的元素(在a中不存在的)添加到c树中 + bMap.forEach(bNode => { + // 保留b节点的原始结构 + const newNode = { ...bNode }; + + // 确保children数组存在 + if (!newNode.children) { + newNode.children = []; + } + + // 判断是否为叶子节点 + const hasChildren = newNode.children && newNode.children.length > 0; + + // 容器类型列表(包括flex和table) + const containerTypes = ['card', 'div', 'grid', 'tabs', 'flex', 'table']; + // 判断节点是否是容器类型 + const isContainer = containerTypes.includes(newNode.type); + + // 设置disabled属性 + if (isContainer) { + // 对于flex和table,即使叶子节点也可以选择,设为false + if (newNode.type === 'flex' || newNode.type === 'table') { + newNode.disabled = false; + } else { + // 其他容器类型:有子节点为null,否则为true + newNode.disabled = hasChildren ? null : true; + } + } else { + // 非容器类型:叶子节点为false + newNode.disabled = false; + } + + cTree.push(newNode); + }); + + return cTree; +} + +// 使用示例 +// const treeC = mergeFormTrees(treeA, treeB); +//关联选项设置优化为树 liwenxuan 20251209 end + + + function removeTreeNode(tree: any, targetId: any) { // 深拷贝原始树结构避免污染原数据 const clonedTree = JSON.parse(JSON.stringify(tree)); @@ -7151,8 +7653,10 @@ const formatTooltip = (val: number) => { @@ -7190,7 +7694,7 @@ const formatTooltip = (val: number) => { @@ -7262,7 +7766,7 @@ const formatTooltip = (val: number) => { controlData.control.glxxszForCheckBox[fieldScope.$index].showFields " style="width: 100%" - :data="associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf[0].children" + :data="glxxszTree" multiple /> @@ -7310,7 +7814,7 @@ const formatTooltip = (val: number) => { @@ -7321,7 +7825,7 @@ const formatTooltip = (val: number) => { From 41073f6837582b9153d8f4e0cb600788d4ace707 Mon Sep 17 00:00:00 2001 From: liwenxuan <1298531568@qq.com> Date: Thu, 11 Dec 2025 15:18:45 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=85=B3=E8=81=94=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=BC=98=E5=8C=96=E4=B8=BA=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DesignForm/formControlPropertiNew.vue | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/components/DesignForm/formControlPropertiNew.vue b/src/components/DesignForm/formControlPropertiNew.vue index aa93fea..7a8cc8f 100644 --- a/src/components/DesignForm/formControlPropertiNew.vue +++ b/src/components/DesignForm/formControlPropertiNew.vue @@ -2836,7 +2836,7 @@ const glxxszTree = computed(()=>{ datapropsformList = JSON.parse(JSON.stringify(props.formList)) } - console.log(datapropsformList) + //console.log(datapropsformList) if(associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf && associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children && associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children.length>0){ @@ -7655,6 +7655,10 @@ const formatTooltip = (val: number) => { style="width: 100%" :data="glxxszTree" multiple + show-checkbox + collapse-tags + collapse-tags-tooltip + :max-collapse-tags="2" clearable filterable /> @@ -7696,6 +7700,12 @@ const formatTooltip = (val: number) => { style="width: 100%" :data="glxxszTree" multiple + show-checkbox + collapse-tags + collapse-tags-tooltip + :max-collapse-tags="2" + clearable + filterable /> @@ -7768,6 +7778,12 @@ const formatTooltip = (val: number) => { style="width: 100%" :data="glxxszTree" multiple + show-checkbox + collapse-tags + collapse-tags-tooltip + :max-collapse-tags="2" + clearable + filterable /> @@ -7816,6 +7832,12 @@ const formatTooltip = (val: number) => { style="width: 60%" :data="glxxszTree" multiple + show-checkbox + collapse-tags + collapse-tags-tooltip + :max-collapse-tags="2" + clearable + filterable />
@@ -7827,6 +7849,12 @@ const formatTooltip = (val: number) => { style="width: 60%" :data="glxxszTree" multiple + show-checkbox + collapse-tags + collapse-tags-tooltip + :max-collapse-tags="2" + clearable + filterable />