diff --git a/src/pages/componentDevelopment/componentList/addApiModal.tsx b/src/pages/componentDevelopment/componentList/addApiModal.tsx
index 35334ce..7247996 100644
--- a/src/pages/componentDevelopment/componentList/addApiModal.tsx
+++ b/src/pages/componentDevelopment/componentList/addApiModal.tsx
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from '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';
const FormItem = Form.Item;
@@ -18,10 +18,12 @@ const AddApiModal = ({
const [form] = Form.useForm();
const [parametersData, setParametersData] = useState([]);
const [responsesData, setResponsesData] = useState([]);
+ const [showTableValidationErrors, setShowTableValidationErrors] = useState(false);
// 当 visible 或 componentDesignProgress 变化时,设置表单初始值
useEffect(() => {
if (visible && componentDesignProgress) {
+ setShowTableValidationErrors(false);
// 设置表单字段值
form.setFieldsValue({
ident: componentDesignProgress.ident || '',
@@ -51,6 +53,7 @@ const AddApiModal = ({
}
}
else if (visible) {
+ setShowTableValidationErrors(false);
// 重置表单和表格数据
form.resetFields();
setParametersData([]);
@@ -62,6 +65,15 @@ const AddApiModal = ({
try {
await form.validate();
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 = {
@@ -170,6 +182,7 @@ const AddApiModal = ({
onDataUpdate={setParametersData}
initialData={componentDesignProgress?.parameters || []}
visible={visible}
+ showValidationErrors={showTableValidationErrors}
/>
@@ -177,6 +190,7 @@ const AddApiModal = ({
onDataUpdate={setResponsesData}
initialData={componentDesignProgress?.responses || []}
visible={visible}
+ showValidationErrors={showTableValidationErrors}
/>
@@ -184,4 +198,4 @@ const AddApiModal = ({
);
};
-export default AddApiModal;
\ No newline at end of file
+export default AddApiModal;
diff --git a/src/pages/componentDevelopment/componentList/editableTable.tsx b/src/pages/componentDevelopment/componentList/editableTable.tsx
index 916b361..ea91a89 100644
--- a/src/pages/componentDevelopment/componentList/editableTable.tsx
+++ b/src/pages/componentDevelopment/componentList/editableTable.tsx
@@ -22,20 +22,70 @@ const arrayTypeOptions = [
{ 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 requiredError = getFieldError(record, dataIndex);
+ const mergedError = error || (showError ? requiredError : '');
// 对于数组类型字段的特殊处理
if (dataIndex === 'generic') {
// 仅当数据类型为 ARRAY 时才可编辑
if (record.type === 'ARRAY') {
return (
-
+
+
+ {mergedError &&
{mergedError}
}
+
);
}
else {
@@ -64,10 +114,11 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
- {error && {error}
}
+ {mergedError && {mergedError}
}
);
}
@@ -76,6 +127,7 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
);
@@ -83,20 +135,39 @@ function EditableCell({ value, onChange, columnType, record, dataIndex }) {
if (columnType === 'select') {
return (
-
+
+
+ {mergedError &&
{mergedError}
}
+
);
}
return {value};
}
-function EditableTable({ onDataUpdate, initialData = [], visible }) {
+function EditableTable({ onDataUpdate, initialData = [], visible, showValidationErrors = false }) {
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(() => {
@@ -112,6 +183,7 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
useEffect(() => {
if (!visible) setData([]);
+ if (!visible) setTouchedFields({});
}, [visible]);
const handleValueChange = (key, dataIndex, value) => {
@@ -144,6 +216,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="input"
record={record}
dataIndex="ident"
+ showError={shouldShowFieldError(record, 'ident')}
+ onBlur={() => markFieldTouched(record.key, 'ident')}
/>
)
},
@@ -157,6 +231,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="select"
record={record}
dataIndex="type"
+ showError={shouldShowFieldError(record, 'type')}
+ onBlur={() => markFieldTouched(record.key, 'type')}
/>
)
},
@@ -170,6 +246,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="select"
record={record}
dataIndex="generic"
+ showError={shouldShowFieldError(record, 'generic')}
+ onBlur={() => markFieldTouched(record.key, 'generic')}
/>
)
},
@@ -183,6 +261,8 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
columnType="input"
record={record}
dataIndex="desc"
+ showError={false}
+ onBlur={() => markFieldTouched(record.key, 'desc')}
/>
)
},
@@ -239,4 +319,4 @@ function EditableTable({ onDataUpdate, initialData = [], visible }) {
);
}
-export default EditableTable;
\ No newline at end of file
+export default EditableTable;