186 lines
5.7 KiB
JavaScript
186 lines
5.7 KiB
JavaScript
import {
|
|
LAYOUT_TYPES,
|
|
FIELD_TYPES,
|
|
SYSTEM_STATUS_FIELD_TYPES,
|
|
SYSTEM_FIELD_TYPES,
|
|
EXCLUDED_GROUP_TYPES
|
|
} from '../../utils/constants.js';
|
|
import {
|
|
sortFieldOptions,
|
|
shouldSortOptions,
|
|
markLookupCopies,
|
|
} from '../../utils/field-utils.js';
|
|
|
|
/**
|
|
* 从属性列表中添加系统状态字段到字段数组中
|
|
* @param {Object} properties - 所有字段属性对象
|
|
* @param {Array} fields - 要添加字段的数组
|
|
*/
|
|
const addSystemStatusFields = (properties, fields) => {
|
|
const propertyList = Object.values(properties);
|
|
|
|
SYSTEM_STATUS_FIELD_TYPES.forEach(type => {
|
|
const field = propertyList.find(f => f.type === type);
|
|
if (field?.enabled) {
|
|
fields.push(field);
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 处理常规行布局中的字段
|
|
* @param {Array} rowFields - 行中的字段列表
|
|
* @param {Object} properties - 字段属性映射
|
|
* @param {Array} fields - 要添加字段的数组
|
|
* @param {Array} spacers - 要添加间距元素的数组
|
|
*/
|
|
const processRowFields = (rowFields, properties, fields, spacers) => {
|
|
for (const field of rowFields) {
|
|
// 跳过标签和分割线布局
|
|
if ([LAYOUT_TYPES.LABEL, LAYOUT_TYPES.HR].includes(field.type)) continue;
|
|
|
|
// 处理间距元素
|
|
if (field.type === LAYOUT_TYPES.SPACER) {
|
|
spacers.push(field);
|
|
continue;
|
|
}
|
|
|
|
const fieldProperty = properties[field.code];
|
|
// 跳过子表和分组类型的字段,这些单独处理
|
|
if ([FIELD_TYPES.SUBTABLE, FIELD_TYPES.GROUP].includes(fieldProperty.type)) continue;
|
|
|
|
// 创建处理后的字段对象,支持选项排序的字段添加排序选项
|
|
const processedField = shouldSortOptions(fieldProperty.type)
|
|
? { ...fieldProperty, sortedOptions: sortFieldOptions(fieldProperty) }
|
|
: fieldProperty;
|
|
|
|
fields.push(processedField);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 处理子表字段
|
|
* @param {Object} layout - 子表布局对象
|
|
* @param {Object} properties - 字段属性映射
|
|
* @param {Array} fields - 要添加字段的数组
|
|
*/
|
|
const processSubtableFields = (layout, properties, fields) => {
|
|
const tableCode = layout.code;
|
|
const tableField = properties[tableCode];
|
|
|
|
if (tableField.type !== FIELD_TYPES.SUBTABLE) return;
|
|
|
|
const subtableFieldsMap = {};
|
|
|
|
// 处理子表中每个字段
|
|
layout.fields.forEach(({ code: fieldCode }) => {
|
|
const subField = tableField.fields[fieldCode];
|
|
const processedField = shouldSortOptions(subField.type)
|
|
? { ...subField, table: tableCode, sortedOptions: sortFieldOptions(subField) }
|
|
: { ...subField, table: tableCode };
|
|
|
|
subtableFieldsMap[fieldCode] = processedField;
|
|
fields.push(processedField);
|
|
});
|
|
|
|
// 将完整的子表信息也添加到字段列表中
|
|
fields.push({ ...tableField, fields: subtableFieldsMap });
|
|
};
|
|
|
|
/**
|
|
* 处理分组字段
|
|
* @param {Object} layout - 分组布局对象
|
|
* @param {Object} properties - 字段属性映射
|
|
* @param {Array} fields - 要添加字段的数组
|
|
* @param {Array} spacers - 要添加间距元素的数组
|
|
*/
|
|
const processGroupFields = (layout, properties, fields, spacers) => {
|
|
const groupCode = layout.code;
|
|
const groupField = properties[groupCode];
|
|
|
|
if (groupField.type !== FIELD_TYPES.GROUP) return;
|
|
|
|
const groupFieldsMap = {};
|
|
|
|
// 处理分组中的每个字段
|
|
layout.layout.forEach(row => {
|
|
row.fields.forEach(field => {
|
|
// 跳过标签和分割线布局
|
|
if ([LAYOUT_TYPES.LABEL, LAYOUT_TYPES.HR].includes(field.type)) return;
|
|
|
|
// 处理间距元素
|
|
if (field.type === LAYOUT_TYPES.SPACER) {
|
|
spacers.push({ ...field, group: groupCode });
|
|
return;
|
|
}
|
|
|
|
const groupSubField = properties[field.code];
|
|
|
|
// 跳过排除的字段类型
|
|
if (EXCLUDED_GROUP_TYPES.includes(groupSubField.type)) return;
|
|
|
|
const processedField = shouldSortOptions(groupSubField.type)
|
|
? { ...groupSubField, group: groupCode, sortedOptions: sortFieldOptions(groupSubField) }
|
|
: { ...groupSubField, group: groupCode };
|
|
|
|
groupFieldsMap[field.code] = processedField;
|
|
fields.push(processedField);
|
|
});
|
|
});
|
|
|
|
// 将完整的分组信息也添加到字段列表中
|
|
fields.push({ ...groupField, fields: groupFieldsMap });
|
|
};
|
|
|
|
/**
|
|
* 添加缺失的系统字段
|
|
* @param {Object} properties - 字段属性对象
|
|
* @param {Array} fields - 要添加字段的数组
|
|
*/
|
|
const addMissingSystemFields = (properties, fields) => {
|
|
const propertyList = Object.values(properties);
|
|
|
|
SYSTEM_FIELD_TYPES.forEach(type => {
|
|
const field = propertyList.find(f => f.type === type);
|
|
// 只添加还没有的系统字段
|
|
if (field && !fields.some(f => f.type === type)) {
|
|
fields.push(field);
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 从表单属性和布局生成处理后的字段和间距数组
|
|
* @param {Object} properties - 字段属性对象
|
|
* @param {Array} layouts - 布局定义
|
|
* @returns {Object} 包含字段和间距数组的对象
|
|
*/
|
|
export const generateFields = (properties, layouts) => {
|
|
const fields = [];
|
|
const spacers = [];
|
|
|
|
// 首先添加系统状态字段
|
|
addSystemStatusFields(properties, fields);
|
|
|
|
// 处理每个布局项
|
|
layouts.forEach(layout => {
|
|
switch (layout.type) {
|
|
case LAYOUT_TYPES.ROW:
|
|
processRowFields(layout.fields, properties, fields, spacers);
|
|
break;
|
|
case LAYOUT_TYPES.SUBTABLE:
|
|
processSubtableFields(layout, properties, fields);
|
|
break;
|
|
case LAYOUT_TYPES.GROUP:
|
|
processGroupFields(layout, properties, fields, spacers);
|
|
break;
|
|
}
|
|
});
|
|
|
|
markLookupCopies(fields);
|
|
|
|
addMissingSystemFields(properties, fields);
|
|
|
|
return { fields, spacers };
|
|
};
|