feat(componentList): 增加表单校验规则

refactor
钟良源 4 weeks ago
parent d31d00c0e7
commit 2a21018544

@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Modal, Form, Input, Message } from '@arco-design/web-react'; import { Modal, Form, Input, Message } from '@arco-design/web-react';
import EditableTable from '@/pages/componentDevelopment/componentList/editableTable'; import EditableTable, { validateEditableTableData } from '@/pages/componentDevelopment/componentList/editableTable';
import { updateComponentDesign } from '@/api/componentDevelopProcess'; import { updateComponentDesign } from '@/api/componentDevelopProcess';
const FormItem = Form.Item; const FormItem = Form.Item;
@ -18,10 +18,12 @@ const AddApiModal = ({
const [form] = Form.useForm(); const [form] = Form.useForm();
const [parametersData, setParametersData] = useState([]); const [parametersData, setParametersData] = useState([]);
const [responsesData, setResponsesData] = useState([]); const [responsesData, setResponsesData] = useState([]);
const [showTableValidationErrors, setShowTableValidationErrors] = useState(false);
// 当 visible 或 componentDesignProgress 变化时,设置表单初始值 // 当 visible 或 componentDesignProgress 变化时,设置表单初始值
useEffect(() => { useEffect(() => {
if (visible && componentDesignProgress) { if (visible && componentDesignProgress) {
setShowTableValidationErrors(false);
// 设置表单字段值 // 设置表单字段值
form.setFieldsValue({ form.setFieldsValue({
ident: componentDesignProgress.ident || '', ident: componentDesignProgress.ident || '',
@ -51,6 +53,7 @@ const AddApiModal = ({
} }
} }
else if (visible) { else if (visible) {
setShowTableValidationErrors(false);
// 重置表单和表格数据 // 重置表单和表格数据
form.resetFields(); form.resetFields();
setParametersData([]); setParametersData([]);
@ -62,6 +65,15 @@ const AddApiModal = ({
try { try {
await form.validate(); await form.validate();
const formData = form.getFields(); const formData = form.getFields();
const parametersValidation = validateEditableTableData(parametersData);
const responsesValidation = validateEditableTableData(responsesData);
if (!parametersValidation.valid || !responsesValidation.valid) {
setShowTableValidationErrors(true);
const firstError = parametersValidation.errors[0] || responsesValidation.errors[0];
Message.error(firstError || '请检查参数填写是否正确');
return;
}
// 构造要提交的数据 // 构造要提交的数据
const params = { const params = {
@ -170,6 +182,7 @@ const AddApiModal = ({
onDataUpdate={setParametersData} onDataUpdate={setParametersData}
initialData={componentDesignProgress?.parameters || []} initialData={componentDesignProgress?.parameters || []}
visible={visible} visible={visible}
showValidationErrors={showTableValidationErrors}
/> />
</FormItem> </FormItem>
<FormItem label="输出参数" field="responses"> <FormItem label="输出参数" field="responses">
@ -177,6 +190,7 @@ const AddApiModal = ({
onDataUpdate={setResponsesData} onDataUpdate={setResponsesData}
initialData={componentDesignProgress?.responses || []} initialData={componentDesignProgress?.responses || []}
visible={visible} visible={visible}
showValidationErrors={showTableValidationErrors}
/> />
</FormItem> </FormItem>
</Form> </Form>

@ -22,20 +22,70 @@ const arrayTypeOptions = [
{ label: 'OBJECT', value: 'OBJECT' } { label: 'OBJECT', value: 'OBJECT' }
]; ];
function EditableCell({ value, onChange, columnType, record, dataIndex }) { const isEmptyValue = (value) => value === undefined || value === null || `${value}`.trim() === '';
const getFieldError = (record, dataIndex) => {
if (dataIndex === 'ident' && isEmptyValue(record.ident)) {
return '请输入名称';
}
if (dataIndex === 'type' && isEmptyValue(record.type)) {
return '请选择数据类型';
}
if (dataIndex === 'generic' && record.type === 'ARRAY' && isEmptyValue(record.generic)) {
return '请选择数组类型';
}
return '';
};
export const validateEditableTableData = (tableData = []) => {
const errors = [];
tableData.forEach((item, index) => {
const rowIndex = index + 1;
if (isEmptyValue(item.ident)) {
errors.push(`${rowIndex}行请输入名称`);
}
if (isEmptyValue(item.type)) {
errors.push(`${rowIndex}行请选择数据类型`);
}
if (item.type === 'ARRAY' && isEmptyValue(item.generic)) {
errors.push(`${rowIndex}行请选择数组类型`);
}
});
return {
valid: errors.length === 0,
errors
};
};
function EditableCell({ value, onChange, columnType, record, dataIndex, showError, onBlur }) {
const [error, setError] = useState(''); const [error, setError] = useState('');
const requiredError = getFieldError(record, dataIndex);
const mergedError = error || (showError ? requiredError : '');
// 对于数组类型字段的特殊处理 // 对于数组类型字段的特殊处理
if (dataIndex === 'generic') { if (dataIndex === 'generic') {
// 仅当数据类型为 ARRAY 时才可编辑 // 仅当数据类型为 ARRAY 时才可编辑
if (record.type === 'ARRAY') { if (record.type === 'ARRAY') {
return ( return (
<div>
<Select <Select
value={value} value={value}
onChange={onChange} onChange={onChange}
onBlur={onBlur}
options={arrayTypeOptions} options={arrayTypeOptions}
placeholder="请选择数组类型" placeholder="请选择数组类型"
status={mergedError ? 'error' : undefined}
/> />
{mergedError && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{mergedError}</div>}
</div>
); );
} }
else { else {
@ -64,10 +114,11 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
<Input <Input
value={value} value={value}
onChange={handleIdentChange} onChange={handleIdentChange}
onBlur={onBlur}
placeholder="请输入(仅支持英文字母、数字和下划线)" placeholder="请输入(仅支持英文字母、数字和下划线)"
status={error ? 'error' : undefined} status={mergedError ? 'error' : undefined}
/> />
{error && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{error}</div>} {mergedError && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{mergedError}</div>}
</div> </div>
); );
} }
@ -76,6 +127,7 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
<Input <Input
value={value} value={value}
onChange={onChange} onChange={onChange}
onBlur={onBlur}
placeholder="请输入" placeholder="请输入"
/> />
); );
@ -83,20 +135,39 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
if (columnType === 'select') { if (columnType === 'select') {
return ( return (
<div>
<Select <Select
value={value} value={value}
onChange={onChange} onChange={onChange}
onBlur={onBlur}
options={dataTypeOptions} options={dataTypeOptions}
placeholder="请选择数据类型" placeholder="请选择数据类型"
status={mergedError ? 'error' : undefined}
/> />
{mergedError && <div style={{ color: '#f53f3f', fontSize: 12, marginTop: 4 }}>{mergedError}</div>}
</div>
); );
} }
return <span>{value}</span>; return <span>{value}</span>;
} }
function EditableTable({ onDataUpdate, initialData = [], visible }) { function EditableTable({ onDataUpdate, initialData = [], visible, showValidationErrors = false }) {
const [data, setData] = useState([]); const [data, setData] = useState([]);
const [touchedFields, setTouchedFields] = useState({});
const getFieldKey = (key, dataIndex) => `${key}-${dataIndex}`;
const markFieldTouched = (key, dataIndex) => {
setTouchedFields(prev => ({
...prev,
[getFieldKey(key, dataIndex)]: true
}));
};
const shouldShowFieldError = (record, dataIndex) => {
return showValidationErrors || touchedFields[getFieldKey(record.key, dataIndex)];
};
// 当初始数据变化时,更新表格数据 // 当初始数据变化时,更新表格数据
useEffect(() => { useEffect(() => {
@ -112,6 +183,7 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
useEffect(() => { useEffect(() => {
if (!visible) setData([]); if (!visible) setData([]);
if (!visible) setTouchedFields({});
}, [visible]); }, [visible]);
const handleValueChange = (key, dataIndex, value) => { const handleValueChange = (key, dataIndex, value) => {
@ -144,6 +216,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="input" columnType="input"
record={record} record={record}
dataIndex="ident" dataIndex="ident"
showError={shouldShowFieldError(record, 'ident')}
onBlur={() => markFieldTouched(record.key, 'ident')}
/> />
) )
}, },
@ -157,6 +231,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="select" columnType="select"
record={record} record={record}
dataIndex="type" dataIndex="type"
showError={shouldShowFieldError(record, 'type')}
onBlur={() => markFieldTouched(record.key, 'type')}
/> />
) )
}, },
@ -170,6 +246,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="select" columnType="select"
record={record} record={record}
dataIndex="generic" dataIndex="generic"
showError={shouldShowFieldError(record, 'generic')}
onBlur={() => markFieldTouched(record.key, 'generic')}
/> />
) )
}, },
@ -183,6 +261,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="input" columnType="input"
record={record} record={record}
dataIndex="desc" dataIndex="desc"
showError={false}
onBlur={() => markFieldTouched(record.key, 'desc')}
/> />
) )
}, },

Loading…
Cancel
Save