62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import type { ResourceField } from './resources';
|
|
|
|
export type ResourceFormValue = string | number | boolean | string[] | undefined;
|
|
export type ResourceFormMode = 'create' | 'edit';
|
|
|
|
export function isMissingField(value: ResourceFormValue | null): boolean {
|
|
return value === '' || value === null || value === undefined || (Array.isArray(value) && value.length === 0);
|
|
}
|
|
|
|
export function isResourceFieldRequired(
|
|
field: ResourceField,
|
|
mode: ResourceFormMode,
|
|
): boolean {
|
|
return Boolean(field.required && !(mode === 'edit' && field.type === 'password'));
|
|
}
|
|
|
|
export function buildResourcePayload(
|
|
fields: ResourceField[],
|
|
form: Record<string, ResourceFormValue>,
|
|
mode: ResourceFormMode = 'create',
|
|
): Record<string, unknown> {
|
|
const payload: Record<string, unknown> = {};
|
|
for (const field of fields) {
|
|
if (mode === 'edit' && field.type === 'password') continue;
|
|
const value = form[field.key];
|
|
if (isMissingField(value)) {
|
|
if (!field.required) continue;
|
|
payload[field.key] = value;
|
|
continue;
|
|
}
|
|
switch (field.type) {
|
|
case 'number': {
|
|
const number = Number(value);
|
|
if (!Number.isFinite(number))
|
|
throw new Error(`${field.label}必须是数字`);
|
|
payload[field.key] = number;
|
|
break;
|
|
}
|
|
case 'boolean':
|
|
payload[field.key] = value === true || value === 'true';
|
|
break;
|
|
case 'json':
|
|
if (typeof value !== 'string')
|
|
throw new Error(`${field.label}必须是有效 JSON`);
|
|
JSON.parse(value);
|
|
payload[field.key] = value;
|
|
break;
|
|
case 'date':
|
|
case 'datetime': {
|
|
const date = new Date(String(value));
|
|
if (Number.isNaN(date.getTime()))
|
|
throw new Error(`${field.label}必须是有效日期`);
|
|
payload[field.key] = date.toISOString();
|
|
break;
|
|
}
|
|
default:
|
|
payload[field.key] = value;
|
|
}
|
|
}
|
|
return payload;
|
|
}
|