From d0b4b582b99915548e5f0e6362c308307020fcf6 Mon Sep 17 00:00:00 2001
From: liwenxuan <1298531568@qq.com>
Date: Fri, 6 Feb 2026 10:38:45 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AD=90=E8=A1=A8=E7=BB=93=E5=90=88=E5=85=B3?=
=?UTF-8?q?=E8=81=94=E8=A1=A8=E5=8D=95=E9=A2=84=E5=A1=AB=E5=85=85=E8=AE=BE?=
=?UTF-8?q?=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/DesignForm/assembly/index.ts | 6 +-
.../DesignForm/formControlPropertiNew.vue | 561 ++++++++++++++++++
2 files changed, 566 insertions(+), 1 deletion(-)
diff --git a/src/components/DesignForm/assembly/index.ts b/src/components/DesignForm/assembly/index.ts
index 098fc2d..36282c1 100644
--- a/src/components/DesignForm/assembly/index.ts
+++ b/src/components/DesignForm/assembly/index.ts
@@ -696,7 +696,11 @@ export default [
tableData: [], // 子表表格列表数据集合
control: {
border: true,
- defaultOne: ''
+ defaultOne: '',
+ preFill: {
+ asf: '',
+ ids: []
+ }
},
config: {
addBtnText: '添加一行'
diff --git a/src/components/DesignForm/formControlPropertiNew.vue b/src/components/DesignForm/formControlPropertiNew.vue
index d7201fa..06b3610 100644
--- a/src/components/DesignForm/formControlPropertiNew.vue
+++ b/src/components/DesignForm/formControlPropertiNew.vue
@@ -14,6 +14,7 @@ import { ValidateTextTypes } from "@/components/DesignForm/validateText";
import { ElMessage } from "element-plus";
import { formatNumber } from "@/api/DesignForm/utils";
import { getOrgTreeList } from "@/api/hr/org/index";
+import AssociatedformsForCreate from "@/widget/associatedforms/associatedformsForCreate.vue";
import { orgInfo } from "@/api/hr/org/type";
@@ -831,6 +832,14 @@ const attrList = computed(() => {
vIf: state.isSearch,
vShow: ["table"],
},
+ {
+ label: "预填充设置",
+ value: config.table,
+ path: "config.table",
+ type: "table_preFill",
+ vIf: state.isSearch,
+ vShow: ["table"],
+ },
{
label: "关联填充",
value: config.orgCentent,
@@ -2930,6 +2939,22 @@ const zdtcszTree = computed(()=>{
return []
}
+})//
+
+const xTree = computed(()=>{
+ if(datapropsformList&&datapropsformList.length==0){
+ datapropsformList = JSON.parse(JSON.stringify(props.formList))
+ }
+
+ if(associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf && associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children && associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children.length>0){
+ let datab = JSON.parse(JSON.stringify(associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children))
+ let currentCompId = controlData.value.name
+ //console.log(currentCompId)
+ const treeC = mergeAndFilterAssociatedForms(datapropsformList, datab);
+ return treeC
+ }else{
+ return []
+ }
})
// 使用 ref 替代 computed,使其可写
@@ -3154,6 +3179,408 @@ const handleDetermineZdtcszDialogFlag = () => {
}
+/**
+ * 合并两个组件树,仅保留type为table内的type为associatedForms的节点
+ * @param {Array} treeA - 组件树a,包含表单结构信息
+ * @param {Array} treeB - 组件树b,包含字段数据信息
+ * @returns {Array} - 合并后仅包含table内的associatedForms节点的组件树c
+ */
+function mergeAndFilterAssociatedForms(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";
+ }
+
+ // 计数器
+ let tableCount = 0;
+ let gridCount = 0;
+ let tabsCount = 0;
+ let divCount = 0;
+ let cardCount = 0;
+
+ // 递归处理a树,仅保留table内的associatedForms节点
+ function processANode(node, parentId = commonParentId, isInTable = false) {
+ // 获取当前节点的name和type
+ const nodeName = node.name;
+ const nodeType = node.type;
+
+ // 如果是table类型
+ if (nodeType === 'table') {
+ tableCount++;
+
+ // 查找b树中对应的节点
+ let bNode = null;
+ if (nodeName && bMap.has(nodeName)) {
+ bNode = bMap.get(nodeName);
+ bMap.delete(nodeName);
+ }
+
+ let cNode;
+ const tableLabel = `子表${node.item?.label || nodeName || tableCount}`;
+
+ if (bNode) {
+ // 复制b节点的所有属性
+ cNode = { ...bNode };
+ // 确保children数组存在
+ if (!cNode.children) {
+ cNode.children = [];
+ }
+ // 使用b节点的parentId
+ cNode.parentId = bNode.parentId || parentId;
+ // 更新label
+ cNode.label = tableLabel;
+ // 更新treeAttrs.show
+ if (cNode.treeAttrs) {
+ cNode.treeAttrs.show = tableLabel;
+ } else {
+ cNode.treeAttrs = { show: tableLabel };
+ }
+ // 保留treeA中的name属性
+ cNode.name = nodeName;
+ } else {
+ // 如果b中不存在,则创建新节点
+ const id = nodeName ? `${commonParentId}:${nodeName}` : null;
+ cNode = {
+ id: id,
+ name: nodeName, // 保留treeA中的name属性
+ label: tableLabel,
+ parentId: parentId,
+ children: [],
+ value: id,
+ treeAttrs: {
+ show: tableLabel
+ },
+ disabled: false, // table类型即使叶子节点也可以选择
+ type: 'table'
+ };
+ }
+
+ // 处理子组件,只在table内寻找associatedForms类型
+ let hasAssociatedForms = false;
+ if (node.list && Array.isArray(node.list)) {
+ const childNodes = [];
+ node.list.forEach(child => {
+ const processedChild = processANode(child, cNode.id, true); // 传递isInTable=true
+ if (processedChild) {
+ childNodes.push(processedChild);
+ hasAssociatedForms = true;
+ }
+ });
+ cNode.children = childNodes;
+ }
+
+ // 如果table没有associatedForms子节点,则不保留table节点
+ if (!hasAssociatedForms) {
+ return null;
+ }
+
+ return cNode;
+ }
+
+ // 如果是associatedForms类型,且正在table内
+ if (nodeType === 'associatedForms' && isInTable) {
+ // 查找b树中对应的节点
+ let bNode = null;
+ if (nodeName && bMap.has(nodeName)) {
+ bNode = bMap.get(nodeName);
+ bMap.delete(nodeName); // 从map中删除,标记为已使用
+ }
+
+ let cNode;
+ if (bNode) {
+ // 复制b节点的所有属性
+ cNode = { ...bNode };
+ // 确保children数组存在
+ if (!cNode.children) {
+ cNode.children = [];
+ }
+ // 使用b节点的parentId
+ cNode.parentId = bNode.parentId || parentId;
+ // 保留treeA中的name属性
+ cNode.name = nodeName;
+
+ // 保留a节点中的配置属性
+ if (node.options && Array.isArray(node.options)) {
+ cNode.options = node.options;
+ }
+
+ if (node.control) {
+ if (!cNode.control) {
+ cNode.control = {};
+ }
+ // 保留control中的相关属性
+ if (node.control.glxxsz) {
+ cNode.control.glxxsz = node.control.glxxsz;
+ }
+ if (node.control.modelValue !== undefined) {
+ cNode.control.modelValue = node.control.modelValue;
+ }
+ }
+
+ if (node.config) {
+ cNode.config = node.config;
+ }
+ } else {
+ // 如果b中不存在,则创建新节点
+ const label = node.item?.label || nodeName || 'associatedForms';
+ const id = nodeName ? `${commonParentId}:${nodeName}` : null;
+ cNode = {
+ id: id,
+ name: nodeName, // 保留treeA中的name属性
+ label: label,
+ parentId: parentId,
+ children: [],
+ value: id,
+ treeAttrs: {
+ show: label
+ },
+ disabled: false, // associatedForms类型,叶子节点disabled为false
+ type: 'associatedForms'
+ };
+
+ // 保留a节点中的配置属性
+ if (node.options && Array.isArray(node.options)) {
+ cNode.options = node.options;
+ }
+
+ if (node.control) {
+ cNode.control = { ...node.control };
+ }
+
+ if (node.config) {
+ cNode.config = { ...node.config };
+ }
+ }
+
+ return cNode;
+ }
+
+ // 其他容器类型,需要处理其子节点
+ const containerTypes = ['card', 'flex', 'div', 'grid', 'tabs'];
+ if (containerTypes.includes(nodeType)) {
+ // 创建一个容器节点占位符
+ let containerId;
+ let containerLabel;
+
+ // 根据容器类型设置不同的id和label
+ switch(nodeType) {
+ case 'grid':
+ gridCount++;
+ containerId = `格栅布局${gridCount}`;
+ containerLabel = containerId;
+ break;
+ case 'tabs':
+ tabsCount++;
+ containerId = `标签页${tabsCount}`;
+ containerLabel = containerId;
+ break;
+ case 'div':
+ divCount++;
+ containerId = `容器${divCount}`;
+ containerLabel = containerId;
+ break;
+ case 'card':
+ cardCount++;
+ containerId = `卡片${cardCount}`;
+ containerLabel = containerId;
+ break;
+ case 'flex':
+ // 对于flex,查找b树中对应的节点
+ let bNode = null;
+ if (nodeName && bMap.has(nodeName)) {
+ bNode = bMap.get(nodeName);
+ bMap.delete(nodeName);
+ }
+
+ if (bNode) {
+ containerId = bNode.id || `${commonParentId}:${nodeName}`;
+ containerLabel = `弹性布局${bNode.label || nodeName}`;
+ } else {
+ containerId = `${commonParentId}:${nodeName}`;
+ containerLabel = `弹性布局${node.item?.label || nodeName}`;
+ }
+ break;
+ default:
+ containerId = `${commonParentId}:${nodeName}`;
+ containerLabel = node.item?.label || nodeName || nodeType;
+ }
+
+ // 创建容器节点
+ const containerNode = {
+ id: containerId,
+ name: nodeName, // 保留treeA中的name属性
+ label: containerLabel,
+ parentId: parentId,
+ children: [],
+ value: containerId,
+ treeAttrs: {
+ show: containerLabel
+ },
+ disabled: null, // 容器节点,非叶子节点
+ type: nodeType
+ };
+
+ // 处理子组件
+ let hasValidChildren = false;
+
+ if (nodeType === 'card' || nodeType === 'flex' || nodeType === 'div') {
+ // 这些类型的子组件在list中
+ if (node.list && Array.isArray(node.list)) {
+ const childNodes = [];
+ node.list.forEach(child => {
+ const processedChild = processANode(child, containerId, false);
+ if (processedChild) {
+ childNodes.push(processedChild);
+ hasValidChildren = true;
+ }
+ });
+ containerNode.children = childNodes;
+ }
+ } else if (nodeType === 'grid' || nodeType === 'tabs') {
+ // 这些类型的子组件在columns.list中
+ if (node.columns && Array.isArray(node.columns)) {
+ // 对于tabs,需要为每个column创建子节点
+ if (nodeType === 'tabs') {
+ const tabNodes = [];
+ node.columns.forEach((column, index) => {
+ // 为每个column创建一个节点
+ const columnId = `${containerId}:${column.label}`;
+ const columnNode = {
+ id: columnId,
+ name: column.label || `Tab${index + 1}`, // 使用column.label作为name
+ label: column.label || `Tab${index + 1}`,
+ parentId: containerId,
+ children: [],
+ value: columnId,
+ treeAttrs: {
+ show: column.label || `Tab${index + 1}`
+ },
+ disabled: null, // 非叶子节点
+ type: 'tab'
+ };
+
+ // 处理column中的子组件
+ let columnHasValidChildren = false;
+ if (column.list && Array.isArray(column.list)) {
+ const childNodes = [];
+ column.list.forEach(child => {
+ const processedChild = processANode(child, columnId, false);
+ if (processedChild) {
+ childNodes.push(processedChild);
+ columnHasValidChildren = true;
+ hasValidChildren = true;
+ }
+ });
+ columnNode.children = childNodes;
+ }
+
+ // 如果column有子节点,添加到tabs节点下
+ if (columnHasValidChildren) {
+ tabNodes.push(columnNode);
+ }
+ });
+ containerNode.children = tabNodes;
+ } else {
+ // 对于grid,直接处理所有columns中的子组件
+ const childNodes = [];
+ node.columns.forEach(column => {
+ if (column.list && Array.isArray(column.list)) {
+ column.list.forEach(child => {
+ const processedChild = processANode(child, containerId, false);
+ if (processedChild) {
+ childNodes.push(processedChild);
+ hasValidChildren = true;
+ }
+ });
+ }
+ });
+ containerNode.children = childNodes;
+ }
+ }
+ }
+
+ // 如果容器没有有效的子节点,则返回null
+ if (!hasValidChildren) {
+ // 对于flex,即使没有子节点也要保留(因为可以选择)
+ if (nodeType === 'flex') {
+ containerNode.disabled = false;
+ return containerNode;
+ }
+ return null;
+ }
+
+ // 设置容器节点的disabled属性
+ // 对于flex,即使有子节点也可以选择,disabled为false
+ if (nodeType === 'flex') {
+ containerNode.disabled = false;
+ } else {
+ // 其他容器类型,有子节点为null,没有子节点为true
+ containerNode.disabled = null;
+ }
+
+ return containerNode;
+ }
+
+ // 其他非相关类型,直接返回null
+ return null;
+ }
+
+ // 处理a树的所有根节点
+ const cTree = [];
+ treeA.forEach(rootNode => {
+ const processedNode = processANode(rootNode);
+ if (processedNode) {
+ cTree.push(processedNode);
+ }
+ });
+
+ // 将b树中剩余的associatedForms元素(在a中不存在的)添加到c树中
+ // 注意:我们不知道这些associatedForms节点是否在table内,所以只添加那些可能在table内的节点
+ // 这里我们简单地从bMap中提取所有associatedForms类型的节点
+ bMap.forEach((bNode, nodeName) => {
+ if (bNode.type === 'associatedForms') {
+ // 保留b节点的原始结构
+ const newNode = { ...bNode };
+
+ // 确保children数组存在
+ if (!newNode.children) {
+ newNode.children = [];
+ }
+
+ // 设置disabled属性为false
+ newNode.disabled = false;
+
+ // 添加name属性
+ newNode.name = nodeName;
+
+ cTree.push(newNode);
+ }
+ });
+
+ return cTree;
+}
+
/**
* 合并两个组件树,仅保留type为radio和select的节点,并过滤掉指定compId的节点,同时保留options属性
* @param {Array} treeA - 组件树a,包含表单结构信息
@@ -5187,6 +5614,80 @@ const requiredTextRadio = (val: any) => {
}
};
+
+
+
+//子表预填充设置 liwenxuan 20260204 start
+const preFillDialogFlag = ref(false)
+function preFillDialogShow(){
+ preFillDialogFlag.value = true
+}
+
+function preFillDialogDetermine(){
+ preFillDialogFlag.value = false
+}
+
+const asfsCurrentTable = computed(()=>{
+ let currentTable = []
+ let count = 0
+ let result = []
+ xTree.value.forEach((element:any) => {
+
+ if(getAfterLastColon(element.value) == controlData.value.name){
+ currentTable.push(element)
+ count++
+ }
+ });
+ if(count>0){
+ result = currentTable[0].children
+ }else{
+ result = []
+ }
+
+ return result
+})
+
+const asfPropsData = computed(()=>{
+ let result = {}
+ asfsCurrentTable.value.forEach((element:any) => {
+ if(element.id==controlData.value.control.preFill.asf){
+ result = element
+ }else{
+ result = {}
+ }
+ });
+ return result
+})
+
+/**
+ * 提取字符串中最后一个英文冒号后的内容,无冒号则返回原字符串
+ * @param {string} str - 输入的字符串
+ * @returns {string} 最后一个冒号后的内容或原字符串
+ */
+function getAfterLastColon(str:string) {
+ //console.log(str)
+ // 首先验证入参类型,确保是字符串(避免非字符串类型导致方法出错)
+ if (typeof str !== 'string') {
+ //console.warn('入参必须是字符串类型,当前已自动转为字符串');
+ str = String(str); // 非字符串类型自动转为字符串
+ }
+
+ // 查找最后一个英文冒号的索引位置
+ const lastColonIndex = str.lastIndexOf(':');
+
+ // 若未找到冒号(索引为 -1),或冒号在字符串最后一位(后面无内容),返回原字符串
+ if (lastColonIndex === -1 || lastColonIndex === str.length - 1) {
+ return str;
+ }
+
+ // 截取最后一个冒号后面的字符(索引+1 开始到字符串结尾)
+ return str.slice(lastColonIndex + 1);
+}
+
+//子表预填充设置 liwenxuan 20260204 end
+
+
+
/**
@ 作者: 秦东
@ 时间: 2024-08-14 13:21:43
@@ -6280,6 +6781,20 @@ const formatTooltip = (val: number) => {
+
+
+
+
+ 预填充设置
+
+
+
@@ -8842,7 +9357,53 @@ const formatTooltip = (val: number) => {
+
+
+
+
+{{ asfsCurrentTable }}
+
+{{ controlData.control.preFill.asf }}
+
+{{ asfPropsData }}
+
+
+
+ 请选择关联表单
+
+
+
+
+
+
+
+
+
+
+