Browse Source

自动填充设置v0.2

lwx_v27
liwenxuan 3 weeks ago
parent
commit
287acfe3fb
  1. 8
      src/components/DesignForm/assembly/index.ts
  2. 645
      src/components/DesignForm/formControlPropertiNew.vue

8
src/components/DesignForm/assembly/index.ts

@ -262,6 +262,10 @@ export default [
control: {
modelValue: '',
glxxsz: [],
zdtcsz: {
tbx: '',
tby: ''
},
optionsValue3Formid:'',
optionsValue3Field:'',
},
@ -312,6 +316,10 @@ export default [
modelValue: '',
appendToBody: true,
glxxsz: [],
zdtcsz: {
tbx: '',
tby: ''
},
optionsValue3Formid:'',
optionsValue3Field:'',
},

645
src/components/DesignForm/formControlPropertiNew.vue

@ -2910,6 +2910,485 @@ function mergeArrays(a, b) {
// liwenxuan 20251212 end
// liwenxuan 20251230 start
/**
* 获取字符串最后一个英文冒号:后的字符
* @param {string} str - 待处理的原始字符串
* @returns {string} 最后一个冒号后的子串无冒号/冒号在末尾时返回空字符串
*/
function getLastColonAfterString(str) {
// 1.
if (typeof str !== 'string') {
console.warn('输入必须为字符串类型');
return '';
}
// 2.
const lastColonIndex = str.lastIndexOf(':');
// 3.
if (lastColonIndex === -1 || lastColonIndex === str.length - 1) {
return '';
}
// 4.
return str.slice(lastColonIndex + 1);
}
// ==
const titleOptions = computed(() => {
let result = []
if(controlData.value.control.zdtcsz.tbx){
zdtcszTree.value.forEach(element => {
if(element.id==controlData.value.control.zdtcsz.tbx){
result = element.options
}
});
}
return result
})
const indexOptions = computed(() => { //
let result = []
if(controlData.value.control.zdtcsz.tby){
zdtcszTree.value.forEach(element => {
if(element.id==controlData.value.control.zdtcsz.tby){
result = element.options
}
});
}
return result
})
//
const zdtcszTableColumns = computed(() => {
return titleOptions.value.map(item => ({
label: item.label,
value: item.value
}))
})
//
const zdtcszTableData = computed(() => {
return indexOptions.value.map(rowItem => {
const rowObj = {
rowKey: rowItem.value,
rowLabel: rowItem.label //
}
//
titleOptions.value.forEach(colItem => {
rowObj[`col_${colItem.value}`] = ''
})
return rowObj
})
})
const zdtcszTree = 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))
let currentCompId = controlData.value.name
const treeC = mergeAndFilterFormTrees(datapropsformList, datab,currentCompId);
//console.log(treeC)
return treeC
}else{
return []
}
})
/**
* 合并两个组件树仅保留type为radio和select的节点并过滤掉指定compId的节点同时保留options属性
* @param {Array} treeA - 组件树a包含表单结构信息
* @param {Array} treeB - 组件树b包含字段数据信息
* @param {String} compId - 需要过滤掉的组件id的后一部分
* @returns {Array} - 合并后仅包含radio和select节点的组件树c
*/
function mergeAndFilterFormTrees(treeA, treeB, compId) {
// bkeynameidvalueb
const bMap = new Map();
// bparentIdparentId
let commonParentId = null;
// idnameformField: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 gridCount = 0;
let tabsCount = 0;
let divCount = 0;
let cardCount = 0;
// aradioselectcompId
function processANode(node, parentId = commonParentId) {
// name
const nodeName = node.name;
const nodeType = node.type;
// compIdname
if (compId && nodeName === compId) {
// bMap使
if (nodeName && bMap.has(nodeName)) {
bMap.delete(nodeName);
}
return null;
}
// radioselect
if (nodeType === 'radio' || nodeType === 'select') {
//
if (compId && nodeName === compId) {
return null;
}
// b
let bNode = null;
if (nodeName && bMap.has(nodeName)) {
bNode = bMap.get(nodeName);
bMap.delete(nodeName); // map使
}
// b
if (bNode && compId) {
const bNodeId = bNode.id || '';
const parts = bNodeId.split(':');
const bNodeName = parts[parts.length - 1];
if (bNodeName === compId) {
return null;
}
}
let cNode;
if (bNode) {
// b
cNode = { ...bNode };
// children
if (!cNode.children) {
cNode.children = [];
}
// 使bparentId
cNode.parentId = bNode.parentId || parentId;
// aoptionsc
if (node.options && Array.isArray(node.options)) {
// coptionsaoptions
// aoptions
cNode.options = node.options;
// acontrol.glxxsz
if (node.control && node.control.glxxsz && Array.isArray(node.control.glxxsz)) {
if (!cNode.control) {
cNode.control = {};
}
cNode.control.glxxsz = node.control.glxxsz;
}
}
} else {
// b
const label = node.item?.label || nodeName || nodeType;
const id = nodeName ? `${commonParentId}:${nodeName}` : null;
cNode = {
id: id,
label: label,
parentId: parentId,
children: [],
value: id,
treeAttrs: {
show: label
},
disabled: false, // radioselectdisabledfalse
type: nodeType
};
// aoptions
if (node.options && Array.isArray(node.options)) {
cNode.options = node.options;
}
// control.glxxsz
if (node.control && node.control.glxxsz && Array.isArray(node.control.glxxsz)) {
if (!cNode.control) {
cNode.control = {};
}
cNode.control.glxxsz = node.control.glxxsz;
}
// config
if (node.config) {
cNode.config = node.config;
}
}
return cNode;
}
// radioselect
//
const containerTypes = ['table', 'card', 'flex', 'div', 'grid', 'tabs'];
if (containerTypes.includes(nodeType)) {
//
if (compId && nodeName === compId) {
//
// bMap
if (nodeName && bMap.has(nodeName)) {
bMap.delete(nodeName);
}
return null;
}
//
let containerId;
let containerLabel;
let originalName = nodeName; // name
// idlabel
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 'table':
case 'flex':
// tableflexb
let bNode = null;
if (nodeName && bMap.has(nodeName)) {
bNode = bMap.get(nodeName);
bMap.delete(nodeName);
}
// b
if (bNode && compId) {
const bNodeId = bNode.id || '';
const parts = bNodeId.split(':');
const bNodeName = parts[parts.length - 1];
if (bNodeName === compId) {
return null;
}
}
if (bNode) {
containerId = bNode.id || `${commonParentId}:${nodeName}`;
containerLabel = nodeType === 'table' ? `子表${bNode.label || nodeName}` :
`弹性布局${bNode.label || nodeName}`;
} else {
containerId = `${commonParentId}:${nodeName}`;
containerLabel = nodeType === 'table' ? `子表${node.item?.label || nodeName}` :
`弹性布局${node.item?.label || nodeName}`;
}
break;
default:
containerId = `${commonParentId}:${nodeName}`;
containerLabel = node.item?.label || nodeName || nodeType;
}
//
const containerNode = {
id: containerId,
label: containerLabel,
parentId: parentId,
children: [],
value: containerId,
treeAttrs: {
show: containerLabel
},
disabled: null, //
type: nodeType
};
//
let hasValidChildren = false;
if (nodeType === 'table' || 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);
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)) {
// tabscolumn
if (nodeType === 'tabs') {
const tabNodes = [];
node.columns.forEach((column, index) => {
// column
const columnId = `${containerId}:${column.label}`;
const columnNode = {
id: columnId,
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);
if (processedChild) {
childNodes.push(processedChild);
columnHasValidChildren = true;
hasValidChildren = true;
}
});
columnNode.children = childNodes;
}
// columntabs
if (columnHasValidChildren) {
tabNodes.push(columnNode);
}
});
containerNode.children = tabNodes;
} else {
// gridcolumns
const childNodes = [];
node.columns.forEach(column => {
if (column.list && Array.isArray(column.list)) {
column.list.forEach(child => {
const processedChild = processANode(child, containerId);
if (processedChild) {
childNodes.push(processedChild);
hasValidChildren = true;
}
});
}
});
containerNode.children = childNodes;
}
}
}
// radioselectnull
if (!hasValidChildren) {
// tableflex使
if (nodeType === 'table' || nodeType === 'flex') {
containerNode.disabled = false;
return containerNode;
}
return null;
}
// disabled
// tableflex使disabledfalse
if (nodeType === 'table' || nodeType === 'flex') {
containerNode.disabled = false;
} else {
// nulltrue
containerNode.disabled = null;
}
return containerNode;
}
// radio/selectnull
return null;
}
// a
const cTree = [];
treeA.forEach(rootNode => {
const processedNode = processANode(rootNode);
if (processedNode) {
cTree.push(processedNode);
}
});
// bradioselectac
bMap.forEach((bNode, nodeName) => {
//
if (compId) {
const bNodeId = bNode.id || '';
const parts = bNodeId.split(':');
const bNodeName = parts[parts.length - 1];
if (bNodeName === compId) {
//
return;
}
}
// radioselect
if (bNode.type === 'radio' || bNode.type === 'select') {
// b
const newNode = { ...bNode };
// children
if (!newNode.children) {
newNode.children = [];
}
// disabledfalse
newNode.disabled = false;
cTree.push(newNode);
}
});
return cTree;
}
// 使
// const filteredTree = mergeAndFilterFormTrees(treeA, treeB, 'radio1763601215033');
// liwenxuan 20251230 end
// liwenxuan 20251209 start
@ -2919,13 +3398,14 @@ 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){
let datab = JSON.parse(JSON.stringify(associatedFormsCurrentFormFieldTreeForGlxxszExceptSelf.value[0].children))
const treeC = mergeFormTrees(datapropsformList, datab);
console.log(treeC)
return treeC
}else{
return null
@ -4014,6 +4494,7 @@ function handleDetermineAssociatedFormsChooseDialog() {
//liwenxuan20240426 start
const ZdtcszDialogFlag = ref(false);
const glxxszDialogFlag = ref(false);
const glxxszDialogFlagCheckBox = ref(false);
const glxxszDialogFlagSwitch = ref(false);
@ -4035,6 +4516,24 @@ function handelGlxxszDialog() {
}
}
function handelZdtcszDialog(){
if (controlData.value.options.length === 0) {
alert("无可配置选项,请先添加。");
} else {
if(controlData.value.control.zdtcsz){
}else{
controlData.value.control.zdtcsz = {
tbx: '',
tby: ''
}
}
ZdtcszDialogFlag.value = true;
}
}
function handelGlxxszDialogCheckbox() {
glxxszDialogFlagCheckBox.value = true;
}
@ -4048,6 +4547,9 @@ function handleDetermineGlxxszDialogSwitch() {
function handleDetermineGlxxszDialogCheckBox() {
glxxszDialogFlagCheckBox.value = false;
}
function handleDetermineZdtcszDialogFlag(){
ZdtcszDialogFlag.value = false;
}
//
watch(
() => controlData.value.control,
@ -6228,26 +6730,39 @@ const formatTooltip = (val: number) => {
</template>
</draggable>
</div>
<!--
-->
<!-- 多选选择框选项拖动功能 liwenxuan 20240815 end -->
<el-form-item class="form_cont">
<el-button @click="addSelectOption">{{
controlData.type === "cascader" ? "编辑" : "新增"
}}</el-button>
<el-button size="small" @click="openDialog" style="margin-right: 12px;">
<el-button size="small" style="margin-right: 12px;" @click="openDialog">
批量导入
</el-button>
<div v-if="showHide(['switch'], true)">
<el-button style="position: relative; top: -1px" @click="handelGlxxszDialogSwitch" >关联选项设置</el-button>
</div>
<div
v-if="
showHide(['radio', 'select'], true) && controlData.config.optionsType == 0
"
>
<el-button style="position: relative; top: -1px" @click="handelGlxxszDialog">关联选项设置</el-button>
</div>
<div v-if="showHide(['checkbox'], true) && controlData.config.optionsType == 0">
<el-button style="position: relative; top: -1px" @click="handelGlxxszDialogCheckbox">关联选项设置</el-button>
<div style="width:100%; position: relative; top: 6px; display: flex;">
<div v-if="showHide(['switch'], true)">
<el-button style="position: relative; top: -1px" @click="handelGlxxszDialogSwitch" >关联选项设置</el-button>
</div>
<div
v-if="
showHide(['radio', 'select'], true) && controlData.config.optionsType == 0
"
>
<el-button style="position: relative; top: -1px" @click="handelGlxxszDialog">关联选项设置</el-button>
</div>
<div v-if="showHide(['checkbox'], true) && controlData.config.optionsType == 0">
<el-button style="position: relative; top: -1px" @click="handelGlxxszDialogCheckbox">关联选项设置</el-button>
</div>
<div
v-if="
showHide(['radio', 'select'], true) && controlData.config.optionsType == 0
"
>
<el-button style="position: relative; top: -1px;right:-12px" @click="handelZdtcszDialog">自动填充设置</el-button>
</div>
</div>
</el-form-item>
@ -7972,9 +8487,109 @@ const formatTooltip = (val: number) => {
<!-- 自动填充设置弹窗 start -->
<el-dialog
v-model="ZdtcszDialogFlag"
class="glxxsztc"
top="150px"
:close-on-click-modal="false"
:title="`自动填充设置--` + controlData.name"
:show-close="false"
style="margin-top: 70px"
width="50%"
>
<!-- 外层容器保持flex布局核心是给文本span加固定最小宽度+禁止换行 -->
<div v-if="ZdtcszDialogFlag" style="width: 100%; display: flex; align-items: center; flex-wrap: nowrap; gap: 10px; padding: 8px 0;">
<!-- 标题行文本加min-width+white-space禁止换行 -->
<span style="font-size: larger; margin-left: 35px; min-width: 60px; white-space: nowrap;">标题行</span>
<!-- 第一个树形选择器限制宽度范围避免挤压文本 -->
<el-tree-select
v-model="controlData.control.zdtcsz.tbx"
:data="zdtcszTree"
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="2"
clearable
filterable
style="flex: 1; min-width: 200px; max-width: 400px;"
/>
<!-- 索引列文本同上加min-width+white-space禁止换行 -->
<span style="font-size: larger; min-width: 60px; white-space: nowrap;">索引列</span>
<!-- 第二个树形选择器同上限制宽度范围 -->
<el-tree-select
v-model="controlData.control.zdtcsz.tby"
:data="zdtcszTree"
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="2"
clearable
filterable
style="flex: 1; min-width: 200px; max-width: 400px; margin-right: 35px;"
/>
</div>
{{zdtcszTableData}}
<div style="width: 100%; padding: 20px; overflow-x: auto;">
<el-table
:data="zdtcszTableData"
border
style="width: 100%;"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
>
<!-- 第一列固定列索引列的数字 -->
<el-table-column
label="严重性\频率"
prop="rowLabel"
width="200"
align="center"
/>
<!-- 动态生成标题行对应的表格列带完整描述 -->
<el-table-column
v-for="col in zdtcszTableColumns"
:key="col.value"
:label="col.label"
:prop="`col_${col.value}`"
min-width="200"
align="center"
>
<template #default="scope">
<el-input
v-model="scope.row[`col_${col.value}`]"
size="small"
placeholder="请输入"
/>
</template>
</el-table-column>
</el-table>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="handleDetermineZdtcszDialogFlag">
确定
</el-button>
</div>
</template>
</el-dialog>
<!-- 自动填充设置弹窗 end -->
<!--
-->
<!-- 用户组织联动选择 start-->
<!-- -->
<el-dialog
v-model="selectOrgConnectUserDialogFlag"
title="选择关联的用户组件"

Loading…
Cancel
Save