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) => {