import { cloneDeep, pick } from 'lodash-es';
|
|
import { getDefaultValue, getSearchMultiple, getSearchType, noSearchList } from './config';
|
|
/**
|
* 列表字段中由「列表设计」维护的属性,刷新时保留,其余属性一律以表单字段为准。
|
* 与 ColumnDesign/src/components/Main.vue 里 setListValue 的回填清单保持一致。
|
*/
|
const COLUMN_OWN_KEYS = [
|
'align',
|
'biz_log_enabled',
|
'contentFormat',
|
'fixed',
|
'headerAlign',
|
'label',
|
'labelI18nCode',
|
'noShow',
|
'sortable',
|
'superQueryNoShow',
|
'useContentFormat',
|
'width',
|
];
|
|
/** 按列表字段的 prop 建立表单字段索引,子表字段的 key 为 `子表字段-子字段` */
|
function buildFormFieldMap(fields: any[]) {
|
const map = new Map<string, any>();
|
const loop = (data: any, parent?: any) => {
|
if (!data) return;
|
if (data.__config__ && Array.isArray(data.__config__.children)) loop(data.__config__.children, data);
|
if (Array.isArray(data)) {
|
for (const item of data) loop(item, parent);
|
return;
|
}
|
const config = data.__config__;
|
if (!config?.jnpfKey || config.layout !== 'colFormItem' || !data.__vModel__) return;
|
const isTableChild = parent?.__config__?.jnpfKey === 'table';
|
const id = isTableChild ? `${parent.__vModel__}-${data.__vModel__}` : data.__vModel__;
|
map.set(id, {
|
id,
|
fullName: isTableChild ? `${parent.__config__.label}-${config.label}` : config.label,
|
fullNameI18nCode: isTableChild ? [parent.__config__.labelI18nCode || '', config.labelI18nCode || ''] : [config.labelI18nCode || ''],
|
...data,
|
});
|
};
|
loop(fields);
|
return map;
|
}
|
|
/**
|
* 列表和查询字段是表单字段配置的副本,只在进入「列表设计」时才会重建。
|
* 保存前按最新表单字段刷新;查询字段沿用列表设计的合并规则:类型相同时保留查询设置,
|
* 类型改变时使用新控件默认设置,不支持查询或在当前端不可见的字段从查询列表移除。
|
*/
|
function isFieldVisible(field: any, platform?: 'app' | 'pc') {
|
if (!platform || !Array.isArray(field.__config__?.visibility)) return true;
|
return field.__config__.visibility.includes(platform);
|
}
|
|
function buildSearchOption(field: any) {
|
const jnpfKey = field.__config__.jnpfKey;
|
return {
|
label: field.fullName,
|
labelI18nCode: field.__config__.labelI18nCode || '',
|
prop: field.id,
|
jnpfKey,
|
sourceType: 2,
|
value: getDefaultValue(field),
|
searchType: getSearchType(field),
|
searchMultiple: getSearchMultiple(jnpfKey),
|
isKeyword: false,
|
...cloneDeep(field),
|
};
|
}
|
|
function syncSearchListFieldConfig(columnData: any, fieldMap: Map<string, any>, platform?: 'app' | 'pc') {
|
if (!Array.isArray(columnData.searchList)) return;
|
columnData.searchList = columnData.searchList.flatMap((search: any) => {
|
const field = fieldMap.get(search.prop);
|
if (!field || !isFieldVisible(field, platform) || noSearchList.includes(field.__config__.jnpfKey)) return [];
|
const nextSearch = buildSearchOption(field);
|
nextSearch.label = search.label;
|
nextSearch.labelI18nCode = search.labelI18nCode;
|
nextSearch.isKeyword = search.isKeyword;
|
if (search.jnpfKey === nextSearch.jnpfKey) {
|
nextSearch.searchType = search.searchType;
|
nextSearch.searchMultiple = search.searchMultiple;
|
nextSearch.noShow = search.noShow;
|
nextSearch.sourceType = search.sourceType;
|
nextSearch.value = cloneDeep(search.value);
|
}
|
return [nextSearch];
|
});
|
}
|
|
export function syncColumnListFieldConfig(columnData: any, formData: any, platform?: 'app' | 'pc') {
|
const fields = formData?.fields;
|
if (!columnData || !Array.isArray(fields) || !fields.length) return columnData;
|
const fieldMap = buildFormFieldMap(fields);
|
if (!fieldMap.size) return columnData;
|
if (Array.isArray(columnData.columnList)) {
|
columnData.columnList = columnData.columnList.map((column: any) => {
|
const field = fieldMap.get(column.prop);
|
if (!field) return column;
|
return {
|
labelI18nCode: field.__config__.labelI18nCode || '',
|
label: field.fullName,
|
prop: field.id,
|
fixed: 'none',
|
headerAlign: 'left',
|
align: 'left',
|
jnpfKey: field.__config__.jnpfKey,
|
sortable: false,
|
width: null,
|
useContentFormat: false,
|
biz_log_enabled: false,
|
superQueryNoShow: false,
|
...cloneDeep(field),
|
...pick(column, COLUMN_OWN_KEYS),
|
};
|
});
|
}
|
syncSearchListFieldConfig(columnData, fieldMap, platform);
|
return columnData;
|
}
|
|
/** 运行时兜底:列上的掩码配置可能是旧快照,按当前表单字段取正确的值 */
|
export function buildFormFieldMaskMap(formData: any) {
|
const map = new Map<string, { maskConfig: any; useMask: boolean }>();
|
const fields = formData?.fields;
|
if (!Array.isArray(fields) || !fields.length) return map;
|
for (const [id, field] of buildFormFieldMap(fields)) {
|
map.set(id, { maskConfig: field.maskConfig, useMask: !!field.useMask });
|
}
|
return map;
|
}
|