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 }; };