123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543 |
- import React, { useEffect, useRef } from 'react';
- import {
- Form,
- Input,
- DatePicker,
- InputNumber,
- Select,
- Radio,
- FormInstance,
- } from 'antd';
- import { useIntl, FormattedMessage } from 'react-intl';
- import { registerFormFields } from '@/validation/patient/registerSchema';
- import NumberWithUnit from '@/components/NumberWithUnit';
- import dayjs, { Dayjs } from 'dayjs';
- import { useSelector } from 'react-redux';
- import { RootState } from '@/states/store';
- const genderOptions = [
- {
- value: 'male',
- label: (
- <FormattedMessage
- id="register.gender.male"
- defaultMessage="register.gender.male"
- />
- ),
- },
- {
- value: 'female',
- label: (
- <FormattedMessage
- id="register.gender.female"
- defaultMessage="register.gender.female"
- />
- ),
- },
- ];
- const pregnancyStatusOptions = [
- {
- value: 'yes',
- label: (
- <FormattedMessage
- id="register.pregnancyStatus.yes"
- defaultMessage="register.pregnancyStatus.yes"
- />
- ),
- },
- {
- value: 'no',
- label: (
- <FormattedMessage
- id="register.pregnancyStatus.no"
- defaultMessage="register.pregnancyStatus.no"
- />
- ),
- },
- {
- value: 'na',
- label: (
- <FormattedMessage
- id="register.pregnancyStatus.na"
- defaultMessage="register.pregnancyStatus.na"
- />
- ),
- },
- ];
- interface BasicInfoFormProps {
- style?: React.CSSProperties;
- form?: FormInstance;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- onValuesChange?: (changedValues: any, allValues: any) => void;
- }
- const BasicInfoForm: React.FC<BasicInfoFormProps> = ({
- style,
- form,
- onValuesChange,
- }) => {
- // 使用 ref 记录更新源,防止循环触发
- const updateSourceRef = useRef<'age' | 'dob' | null>(null);
- const patient_age = Form.useWatch('patient_age', form);
- const patient_dob = Form.useWatch('patient_dob', form);
- const productName = useSelector(
- (state: RootState) => state.product.productName
- );
- const intl = useIntl();
- // 根据年龄计算出生日期
- const calculateDobFromAge = (age: {
- number: number;
- unit: 'D' | 'M' | 'Y';
- }): Dayjs => {
- const now = dayjs();
- switch (age.unit) {
- case 'D':
- return now.subtract(age.number, 'day');
- case 'M':
- return now.subtract(age.number, 'month');
- case 'Y':
- return now.subtract(age.number, 'year');
- default:
- return now;
- }
- };
- // 根据出生日期计算年龄
- const calculateAgeFromDob = (
- dob: Dayjs
- ): { number: number; unit: 'D' | 'M' | 'Y' } => {
- const now = dayjs();
- const years = now.diff(dob, 'year');
- if (years >= 1) {
- return { number: years, unit: 'Y' };
- }
- const months = now.diff(dob, 'month');
- if (months >= 1) {
- return { number: months, unit: 'M' };
- }
- const days = now.diff(dob, 'day');
- return { number: Math.max(0, days), unit: 'D' };
- };
- // 监听年龄变化
- useEffect(() => {
- // 如果是出生日期联动更新的年龄,跳过
- if (updateSourceRef.current === 'dob') {
- updateSourceRef.current = null;
- return;
- }
- // 如果年龄有效,计算出生日期
- if (patient_age && patient_age.number >= 0 && form) {
- updateSourceRef.current = 'age';
- const newDob = calculateDobFromAge(patient_age);
- form.setFieldsValue({ patient_dob: newDob });
- console.log('年龄变化,更新出生日期:', newDob.format('YYYY-MM-DD'));
- }
- }, [patient_age, form]);
- // 监听出生日期变化
- useEffect(() => {
- // 如果是年龄联动更新的出生日期,跳过
- if (updateSourceRef.current === 'age') {
- updateSourceRef.current = null;
- return;
- }
- // 如果出生日期有效,计算年龄
- if (patient_dob && dayjs.isDayjs(patient_dob) && form) {
- updateSourceRef.current = 'dob';
- const newAge = calculateAgeFromDob(patient_dob);
- form.setFieldsValue({ patient_age: newAge });
- console.log('出生日期变化,更新年龄:', newAge);
- }
- }, [patient_dob, form]);
- return (
- <Form
- form={form}
- layout="vertical"
- style={style}
- className="px-2"
- initialValues={{
- patient_dob: dayjs(),
- }}
- onValuesChange={onValuesChange}
- >
- {/** 宠物专用 */}
- {productName === 'VETDROS' && (
- <Form.Item
- label={
- <FormattedMessage
- id="register.owner_name"
- defaultMessage="register.owner_name"
- />
- }
- name="owner_name"
- required={registerFormFields.owner_name.required}
- validateTrigger={registerFormFields.owner_name.trigger}
- rules={registerFormFields.owner_name.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.owner_name.placeholder',
- defaultMessage: 'register.owner_name.placeholder',
- })}
- />
- </Form.Item>
- )}
- <Form.Item
- label={
- <FormattedMessage
- id="register.accessionNumber"
- defaultMessage="register.accessionNumber"
- />
- }
- name="accession_number"
- required={registerFormFields.accession_number.required}
- validateTrigger={registerFormFields.accession_number.trigger}
- rules={registerFormFields.accession_number.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.accessionNumber.placeholder',
- defaultMessage: 'register.accessionNumber.placeholder',
- })}
- />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.patientId"
- defaultMessage="register.patientId"
- />
- }
- name="patient_id"
- required={registerFormFields.patient_id.required}
- validateTrigger={registerFormFields.patient_id.trigger}
- rules={registerFormFields.patient_id.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.patientId.placeholder',
- defaultMessage: 'register.patientId.placeholder',
- })}
- />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.patientName"
- defaultMessage="register.patientName"
- />
- }
- name="patient_name"
- required={registerFormFields.patient_name.required}
- validateTrigger={registerFormFields.patient_name.trigger}
- rules={registerFormFields.patient_name.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.patientName.placeholder',
- defaultMessage: 'register.patientName.placeholder',
- })}
- />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.patientSize"
- defaultMessage="register.patientSize"
- />
- }
- name="patient_size"
- required={registerFormFields.patient_size.required}
- validateTrigger={registerFormFields.patient_size.trigger}
- rules={registerFormFields.patient_size.validation}
- initialValue="Medium"
- >
- <Select
- placeholder={intl.formatMessage({
- id: 'register.patientSize.placeholder',
- defaultMessage: 'register.patientSize.placeholder',
- })}
- defaultValue="Medium"
- >
- <Select.Option value="Large">Large</Select.Option>
- <Select.Option value="Medium">Medium</Select.Option>
- <Select.Option value="Small">Small</Select.Option>
- </Select>
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage id="register.age" defaultMessage="register.age" />
- }
- name="patient_age"
- required={registerFormFields.patient_age.required}
- validateTrigger={registerFormFields.patient_age.trigger}
- rules={registerFormFields.patient_age.validation}
- initialValue={{ number: 0, unit: 'Y' }}
- >
- <NumberWithUnit
- align="baseline"
- defaultUnit="Y"
- defaultNumber={0}
- unitClassName="w-full"
- numberClassName="w-full"
- className="w-full"
- options={[
- { label: '天', value: 'D' },
- { label: '月', value: 'M' },
- { label: '年', value: 'Y' },
- ]}
- />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.dateOfBirth"
- defaultMessage="register.dateOfBirth"
- />
- }
- name="patient_dob"
- required={registerFormFields.patient_dob.required}
- validateTrigger={registerFormFields.patient_dob.trigger}
- rules={registerFormFields.patient_dob.validation}
- >
- <DatePicker format="YYYY-MM-DD" style={{ width: '100%' }} />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.gender"
- defaultMessage="register.gender"
- />
- }
- name="patient_sex"
- required={registerFormFields.patient_sex.required}
- validateTrigger={registerFormFields.patient_sex.trigger}
- rules={registerFormFields.patient_sex.validation}
- >
- <Select options={genderOptions} />
- </Form.Item>
- {/** 宠物专用 */}
- {productName === 'VETDROS' && (
- <Form.Item
- label={
- <FormattedMessage
- id="register.sexNeutered"
- defaultMessage="register.sexNeutered"
- />
- }
- name="sex_neutered"
- required={registerFormFields.sex_neutered.required}
- validateTrigger={registerFormFields.sex_neutered.trigger}
- rules={registerFormFields.sex_neutered.validation}
- >
- <Select
- defaultValue={'UNALTERED'}
- placeholder={intl.formatMessage({
- id: 'register.sexNeutered.placeholder',
- defaultMessage: 'register.sexNeutered.placeholder',
- })}
- >
- <Select.Option value="ALTERED">ALTERED (绝育)</Select.Option>
- <Select.Option value="UNALTERED">UNALTERED (未绝育)</Select.Option>
- </Select>
- </Form.Item>
- )}
- {/** 人类专用 */}
- {productName === 'DROS' && (
- <Form.Item
- label={
- <FormattedMessage
- id="register.pregnancyStatus"
- defaultMessage="register.pregnancyStatus"
- />
- }
- name="pregnancy_status"
- required={registerFormFields.pregnancy_status.required}
- validateTrigger={registerFormFields.pregnancy_status.trigger}
- rules={registerFormFields.pregnancy_status.validation}
- >
- <Radio.Group
- options={pregnancyStatusOptions}
- optionType="button"
- buttonStyle="solid"
- />
- </Form.Item>
- )}
- {/** 宠物专用 */}
- {productName === 'VETDROS' && (
- <Form.Item
- label={
- <FormattedMessage
- id="register.chipNumber"
- defaultMessage="register.chipNumber"
- />
- }
- name="chip_number"
- required={registerFormFields.chip_number.required}
- validateTrigger={registerFormFields.chip_number.trigger}
- rules={registerFormFields.chip_number.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.chipNumber.placeholder',
- defaultMessage: 'register.chipNumber.placeholder',
- })}
- />
- </Form.Item>
- )}
- {/** 宠物专用 */}
- {productName === 'VETDROS' && (
- <Form.Item
- label={
- <FormattedMessage
- id="register.variety"
- defaultMessage="register.variety"
- />
- }
- name="variety"
- required={registerFormFields.variety.required}
- validateTrigger={registerFormFields.variety.trigger}
- rules={registerFormFields.variety.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.variety.placeholder',
- defaultMessage: 'register.variety.placeholder',
- })}
- />
- </Form.Item>
- )}
- {/* <Form.Item
- label={
- <FormattedMessage
- id="register.patientType"
- defaultMessage="register.patientType"
- />
- }
- name="patient_type"
- required={registerFormFields.patient_type.required}
- validateTrigger={registerFormFields.patient_type.trigger}
- rules={registerFormFields.patient_type.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.patientType.placeholder',
- defaultMessage: 'register.patientType.placeholder',
- })}
- />
- </Form.Item> */}
- <Form.Item
- label={
- <FormattedMessage
- id="register.referringPhysician"
- defaultMessage="register.referringPhysician"
- />
- }
- name="ref_physician"
- required={registerFormFields.ref_physician.required}
- validateTrigger={registerFormFields.ref_physician.trigger}
- rules={registerFormFields.ref_physician.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.referringPhysician.placeholder',
- defaultMessage: 'register.referringPhysician.placeholder',
- })}
- />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.operatorId"
- defaultMessage="register.operatorId"
- />
- }
- name="operator_id"
- required={registerFormFields.operator_id.required}
- validateTrigger={registerFormFields.operator_id.trigger}
- rules={registerFormFields.operator_id.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.operatorId.placeholder',
- defaultMessage: 'register.operatorId.placeholder',
- })}
- />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.weight"
- defaultMessage="register.weight"
- />
- }
- name="weight"
- required={registerFormFields.weight.required}
- validateTrigger={registerFormFields.weight.trigger}
- rules={registerFormFields.weight.validation}
- >
- <InputNumber min={0} addonAfter="kg" style={{ width: '100%' }} />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.thickness"
- defaultMessage="register.thickness"
- />
- }
- name="thickness"
- required={registerFormFields.thickness.required}
- validateTrigger={registerFormFields.thickness.trigger}
- rules={registerFormFields.thickness.validation}
- >
- <InputNumber min={0} addonAfter="cm" style={{ width: '100%' }} />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.height"
- defaultMessage="register.height"
- />
- }
- name="length"
- required={registerFormFields.length.required}
- validateTrigger={registerFormFields.length.trigger}
- rules={registerFormFields.length.validation}
- >
- <InputNumber min={0} addonAfter="cm" style={{ width: '100%' }} />
- </Form.Item>
- <Form.Item
- label={
- <FormattedMessage
- id="register.comment"
- defaultMessage="register.comment"
- />
- }
- name="comment"
- required={registerFormFields.comment.required}
- validateTrigger={registerFormFields.comment.trigger}
- rules={registerFormFields.comment.validation}
- >
- <Input
- placeholder={intl.formatMessage({
- id: 'register.comment.placeholder',
- defaultMessage: 'register.comment.placeholder',
- })}
- />
- </Form.Item>
- </Form>
- );
- };
- export default BasicInfoForm;
|