import type { FieldDataType } from '#/api/x/eln/fields';
|
|
export interface ControlConfigFormValues {
|
controlDateFormat?: string;
|
controlDefaultChecked?: boolean;
|
controlDefaultDate?: string;
|
controlDefaultOption?: string;
|
controlDefaultValue?: string;
|
controlOptionsText?: string;
|
controlPlaceholder?: string;
|
}
|
|
export interface DropdownOption {
|
display: string;
|
value: string;
|
}
|
|
const MANAGED_KEYS = new Set(['dateFormat', 'defaultChecked', 'defaultValue', 'options', 'placeholder']);
|
|
export function controlConfigFormValues(config?: Record<string, unknown>): { extras: Record<string, unknown>; values: ControlConfigFormValues } {
|
const source = config || {};
|
const values: ControlConfigFormValues = {
|
controlDateFormat: stringValue(source.dateFormat),
|
controlDefaultChecked: Boolean(source.defaultChecked),
|
controlDefaultDate: stringValue(source.defaultValue),
|
controlDefaultOption: stringValue(source.defaultValue),
|
controlDefaultValue: stringValue(source.defaultValue),
|
controlOptionsText: formatDropdownOptions(source.options),
|
controlPlaceholder: stringValue(source.placeholder),
|
};
|
const extras = Object.fromEntries(Object.entries(source).filter(([key]) => !MANAGED_KEYS.has(key)));
|
return { extras, values };
|
}
|
|
export function buildControlConfig(
|
dataType: FieldDataType,
|
values: ControlConfigFormValues,
|
extras: Record<string, unknown> = {},
|
): Record<string, unknown> | undefined {
|
const config: Record<string, unknown> = { ...extras };
|
if (dataType === 'CHECKBOX') {
|
if (values.controlDefaultChecked) config.defaultChecked = true;
|
return Object.keys(config).length ? config : undefined;
|
}
|
|
if (['DECIMAL', 'SELECT', 'TEXT', 'TEXTAREA'].includes(dataType)) {
|
assignTrimmed(config, 'placeholder', values.controlPlaceholder);
|
}
|
if (dataType === 'SELECT') {
|
const options = parseDropdownOptions(values.controlOptionsText || '');
|
if (options.length) config.options = options;
|
assignTrimmed(config, 'defaultValue', values.controlDefaultOption);
|
} else if (dataType === 'DATE' || dataType === 'DATETIME') {
|
assignTrimmed(config, 'dateFormat', values.controlDateFormat);
|
assignTrimmed(config, 'defaultValue', values.controlDefaultDate);
|
} else {
|
assignTrimmed(config, 'defaultValue', values.controlDefaultValue);
|
}
|
return Object.keys(config).length ? config : undefined;
|
}
|
|
export function dropdownOptionsFromText(value?: string): DropdownOption[] {
|
return parseDropdownOptions(value || '');
|
}
|
|
export function dropdownOptionsForSelect(value?: string): DropdownOption[] {
|
try {
|
return parseDropdownOptions(value || '');
|
} catch {
|
return [];
|
}
|
}
|
|
export function validateDropdownOptions(value?: string): Promise<void> {
|
try {
|
const options = parseDropdownOptions(value || '');
|
if (options.length < 2) throw new Error('请至少填写两个下拉选项');
|
return Promise.resolve();
|
} catch (error) {
|
return Promise.reject(error);
|
}
|
}
|
|
function assignTrimmed(config: Record<string, unknown>, key: string, value?: string) {
|
const trimmed = value?.trim();
|
if (trimmed) config[key] = trimmed;
|
}
|
|
function formatDropdownOptions(value: unknown): string {
|
if (!Array.isArray(value)) return '';
|
return value
|
.filter((option): option is Record<string, unknown> => Boolean(option) && typeof option === 'object')
|
.map((option) => `${stringValue(option.display)}|${stringValue(option.value)}`)
|
.join('\n');
|
}
|
|
function parseDropdownOptions(value: string): DropdownOption[] {
|
const lines = value
|
.split(/\r?\n/)
|
.map((line) => line.trim())
|
.filter(Boolean);
|
const options = lines.map((line) => {
|
const separator = line.indexOf('|');
|
if (separator < 1 || separator === line.length - 1) throw new Error('每个下拉选项均应填写“显示文本|业务值”');
|
const display = line.slice(0, separator).trim();
|
const optionValue = line.slice(separator + 1).trim();
|
if (!display || !optionValue) throw new Error('下拉选项的显示文本和业务值不能为空');
|
return { display, value: optionValue };
|
});
|
if (new Set(options.map((option) => option.value)).size !== options.length) throw new Error('下拉选项的业务值不能重复');
|
return options;
|
}
|
|
function stringValue(value: unknown): string {
|
return typeof value === 'string' ? value : '';
|
}
|