MemberForm.jsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import React, { useEffect, useState } from 'react';
  2. import { Form, Input, Button, Select, DatePicker, InputNumber, Switch, Upload, message } from 'antd';
  3. import { UploadOutlined } from '@ant-design/icons';
  4. import moment from 'moment';
  5. const { Option } = Select;
  6. const MemberForm = ({ onSubmit, initialValues }) => {
  7. const [form] = Form.useForm();
  8. const [servicePositions, setServicePositions] = useState([
  9. '主日学老师',
  10. '敬拜团成员',
  11. '接待员',
  12. '财务',
  13. '音控',
  14. '祷告组长'
  15. ]);
  16. useEffect(() => {
  17. if (initialValues) {
  18. form.setFieldsValue({
  19. ...initialValues,
  20. birthDate: initialValues.birthDate ? moment(initialValues.birthDate) : null,
  21. baptismDate: initialValues.baptismDate ? moment(initialValues.baptismDate) : null,
  22. });
  23. } else {
  24. form.resetFields();
  25. }
  26. }, [initialValues, form]);
  27. const onFinish = (values) => {
  28. const formattedValues = {
  29. ...values,
  30. birthDate: values.birthDate ? values.birthDate.format('YYYY-MM-DD') : null,
  31. baptismDate: values.baptismDate ? values.baptismDate.format('YYYY-MM-DD') : null,
  32. photo: values.photo && values.photo[0] ? values.photo[0].originFileObj : null,
  33. };
  34. onSubmit(formattedValues);
  35. };
  36. const normFile = (e) => {
  37. if (Array.isArray(e)) {
  38. return e;
  39. }
  40. return e && e.fileList;
  41. };
  42. const beforeUpload = (file) => {
  43. const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  44. if (!isJpgOrPng) {
  45. message.error('只能上传 JPG/PNG 格式的图片!');
  46. }
  47. const isLt2M = file.size / 1024 / 1024 < 2;
  48. if (!isLt2M) {
  49. message.error('图片大小不能超过 2MB!');
  50. }
  51. return isJpgOrPng && isLt2M;
  52. };
  53. const handleServicePositionChange = (value) => {
  54. if (value && !servicePositions.includes(value)) {
  55. setServicePositions([...servicePositions, value]);
  56. }
  57. };
  58. return (
  59. <Form
  60. form={form}
  61. name="memberForm"
  62. onFinish={onFinish}
  63. layout="vertical"
  64. >
  65. <Form.Item
  66. name="name"
  67. label="姓名"
  68. rules={[{ required: true, message: '请输入姓名' }]}
  69. >
  70. <Input />
  71. </Form.Item>
  72. <Form.Item
  73. name="gender"
  74. label="性别"
  75. rules={[{ required: true, message: '请选择性别' }]}
  76. >
  77. <Select>
  78. <Option value="男">男</Option>
  79. <Option value="女">女</Option>
  80. </Select>
  81. </Form.Item>
  82. <Form.Item
  83. name="age"
  84. label="年龄"
  85. rules={[{ required: true, message: '请输入年龄' }]}
  86. >
  87. <InputNumber min={0} max={150} />
  88. </Form.Item>
  89. <Form.Item
  90. name="birthDate"
  91. label="出生日期"
  92. rules={[{ required: true, message: '请选择出生日期' }]}
  93. >
  94. <DatePicker />
  95. </Form.Item>
  96. <Form.Item
  97. name="maritalStatus"
  98. label="婚姻状况"
  99. rules={[{ required: true, message: '请选择婚姻状况' }]}
  100. >
  101. <Select>
  102. <Option value="未婚">未婚</Option>
  103. <Option value="已婚">已婚</Option>
  104. <Option value="离异">离异</Option>
  105. <Option value="丧偶">丧偶</Option>
  106. </Select>
  107. </Form.Item>
  108. <Form.Item
  109. name="isBaptized"
  110. label="是否受洗"
  111. valuePropName="checked"
  112. >
  113. <Switch />
  114. </Form.Item>
  115. <Form.Item
  116. name="baptismDate"
  117. label="受洗日期"
  118. >
  119. <DatePicker />
  120. </Form.Item>
  121. <Form.Item
  122. name="contact"
  123. label="联系方式"
  124. rules={[{ required: true, message: '请输入联系方式' }]}
  125. >
  126. <Input />
  127. </Form.Item>
  128. <Form.Item
  129. name="servicePosition"
  130. label="服侍岗位"
  131. >
  132. <Select
  133. mode="tags"
  134. style={{ width: '100%' }}
  135. placeholder="请选择或输入服侍岗位"
  136. onChange={handleServicePositionChange}
  137. >
  138. {servicePositions.map(position => (
  139. <Option key={position} value={position}>{position}</Option>
  140. ))}
  141. </Select>
  142. </Form.Item>
  143. <Form.Item
  144. name="photo"
  145. label="单寸照片"
  146. valuePropName="fileList"
  147. getValueFromEvent={normFile}
  148. >
  149. <Upload
  150. name="photo"
  151. listType="picture"
  152. beforeUpload={beforeUpload}
  153. maxCount={1}
  154. >
  155. <Button icon={<UploadOutlined />}>上传照片</Button>
  156. </Upload>
  157. </Form.Item>
  158. <Form.Item>
  159. <Button type="primary" htmlType="submit">
  160. 提交
  161. </Button>
  162. </Form.Item>
  163. </Form>
  164. );
  165. };
  166. export default MemberForm;