Files
if.u.clients.web/src/components/PeopleForm.tsx
2025-11-12 14:59:36 +08:00

188 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from 'react';
import { Form, Input, Select, InputNumber, Button, message, Row, Col } from 'antd';
import type { FormInstance } from 'antd';
import './PeopleForm.css';
import KeyValueList from './KeyValueList.tsx'
import { createPeople, type People } from '../apis';
const { TextArea } = Input;
interface PeopleFormProps {
initialData?: any;
// 编辑模式下由父组件控制提交,隐藏内部提交按钮
hideSubmitButton?: boolean;
// 暴露 AntD Form 实例给父组件,用于在外部触发校验与取值
onFormReady?: (form: FormInstance) => void;
}
const PeopleForm: React.FC<PeopleFormProps> = ({ initialData, hideSubmitButton = false, onFormReady }) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
// 当 initialData 变化时,自动填充表单
useEffect(() => {
if (initialData) {
console.log('收到API返回数据自动填充表单:', initialData);
// 处理返回的数据,将其转换为表单需要的格式
const formData: any = {};
if (initialData.name) formData.name = initialData.name;
if (initialData.contact) formData.contact = initialData.contact;
if (initialData.cover) formData.cover = initialData.cover;
if (initialData.gender) formData.gender = initialData.gender;
if (initialData.age) formData.age = initialData.age;
if (initialData.height) formData.height = initialData.height;
if (initialData.marital_status) formData.marital_status = initialData.marital_status;
if (initialData.match_requirement) formData.match_requirement = initialData.match_requirement;
if (initialData.introduction) formData.introduction = initialData.introduction;
// 设置表单字段值
form.setFieldsValue(formData);
// 显示成功消息
// message.success('已自动填充表单,请检查并确认信息');
}
}, [initialData, form]);
// 将表单实例暴露给父组件
useEffect(() => {
onFormReady?.(form);
// 仅在首次挂载时调用一次
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const onFinish = async (values: any) => {
setLoading(true);
try {
const peopleData: People = {
name: values.name,
contact: values.contact || undefined,
gender: values.gender,
age: values.age,
height: values.height || undefined,
marital_status: values.marital_status || undefined,
introduction: values.introduction || {},
match_requirement: values.match_requirement || undefined,
cover: values.cover || undefined,
};
console.log('提交人员数据:', peopleData);
const response = await createPeople(peopleData);
console.log('API响应:', response);
if (response.error_code === 0) {
message.success('人员信息已成功提交到后端!');
form.resetFields();
} else {
message.error(response.error_info || '提交失败,请重试');
}
} catch (error: any) {
console.error('提交失败:', error);
// 根据错误类型显示不同的错误信息
if (error.status === 422) {
message.error('表单数据格式有误,请检查输入内容');
} else if (error.status >= 500) {
message.error('服务器错误,请稍后重试');
} else {
message.error(error.message || '提交失败,请重试');
}
} finally {
setLoading(false);
}
};
return (
<div className="people-form">
<Form
form={form}
layout="vertical"
size="large"
onFinish={onFinish}
>
<Row gutter={[12, 12]}>
<Col xs={24} md={12}>
<Form.Item name="name" label="姓名" rules={[{ required: true, message: '请输入姓名' }]}>
<Input placeholder="如:张三" />
</Form.Item>
</Col>
<Col xs={24} md={12}>
<Form.Item name="contact" label="联系人">
<Input placeholder="如:李四(可留空)" />
</Form.Item>
</Col>
</Row>
<Row gutter={[12, 12]}>
<Col xs={24}>
<Form.Item name="cover" label="人物封面">
<Input placeholder="请输入图片链接(可留空)" />
</Form.Item>
</Col>
</Row>
<Row gutter={[12, 12]}>
<Col xs={24} md={6}>
<Form.Item name="gender" label="性别" rules={[{ required: true, message: '请选择性别' }]}>
<Select
placeholder="请选择性别"
options={[
{ label: '男', value: '男' },
{ label: '女', value: '女' },
{ label: '其他/保密', value: '其他/保密' },
]}
/>
</Form.Item>
</Col>
<Col xs={24} md={6}>
<Form.Item name="age" label="年龄" rules={[{ required: true, message: '请输入年龄' }]}>
<InputNumber min={0} max={120} style={{ width: '100%' }} placeholder="如28" />
</Form.Item>
</Col>
<Col xs={24} md={6}>
<Form.Item name="height" label="身高(cm)">
<InputNumber
min={0}
max={250}
style={{ width: '100%' }}
placeholder="如175可留空"
/>
</Form.Item>
</Col>
<Col xs={24} md={6}>
<Form.Item name="marital_status" label="婚姻状况">
<Input placeholder="可自定义输入,例如:未婚、已婚、离异等" />
</Form.Item>
</Col>
</Row>
<Form.Item name="introduction" label="个人介绍(键值对)">
<KeyValueList />
</Form.Item>
<Form.Item name="match_requirement" label="择偶要求">
<TextArea autoSize={{ minRows: 3, maxRows: 6 }} placeholder="例如:性格开朗、三观一致等" />
</Form.Item>
{!hideSubmitButton && (
<Form.Item>
<Button type="primary" htmlType="submit" loading={loading} block>
{loading ? '提交中...' : '提交'}
</Button>
</Form.Item>
)}
</Form>
</div>
);
};
export default PeopleForm;