Quellcode durchsuchen

refactor(patient-register): restructure registration logic and implement entry to exam via navigation areas exam button from registration process
close #37

sw vor 1 Monat
Ursprung
Commit
f50f46838a

+ 87 - 0
src/domain/patient/registerLogic.ts

@@ -0,0 +1,87 @@
+import { useSelector } from 'react-redux';
+import { RootState } from '@/states/store';
+import {
+  registerWork,
+  RegisterWorkResponseData,
+  RegisterInfo,
+} from '@/API/patient/workActions';
+import { message } from 'antd';
+import registerformSchema from '@/validation/patient/registerSchema';
+import dayjs from 'dayjs';
+import utc from 'dayjs/plugin/utc';
+import { View } from '@/API/patient/viewActions';
+dayjs.extend(utc);
+
+const useRegisterLogic = () => {
+  const formData = useSelector((state: RootState) => state.form.formData);
+  const selectedViews = useSelector(
+    (state: RootState) => state.viewSelection.selectedViews
+  );
+  const currentPatientType = useSelector(
+    (state: RootState) => state.patientType.current
+  );
+
+  const handleRegister = async (): Promise<{
+    success: boolean;
+    data?: RegisterWorkResponseData;
+    views?: View[];
+  }> => {
+    try {
+      let values = formData;
+      const formatDob = values.patient_dob
+        ? dayjs.utc(values.patient_dob).format('YYYY-MM-DDTHH:mm:ss.SSS[Z]')
+        : '';
+      values = { ...values, patient_dob: formatDob };
+
+      const validateResult = registerformSchema.safeParse(values);
+      if (!validateResult.success) {
+        message.error(`必填项未填写或者不合规则`);
+        return { success: false, views: [] };
+      }
+
+      const registerInfo: RegisterInfo = {
+        ...values,
+        patient_type: currentPatientType?.patient_type_id ?? '',
+        modality: 'DX',
+        study_type: 'Normal',
+        patient_age: `${values.patient_age.number}${values.patient_age.unit}`,
+        views: selectedViews.map((view) => ({
+          view_id: view.view_id,
+          procedure_id: view.procedure_id || '',
+        })),
+        accession_number: values.accession_number,
+        patient_id: values.patient_id,
+        patient_name: values.patient_name,
+        patient_size: values.patient_size,
+        patient_dob: values.patient_dob,
+        patient_sex: values.patient_sex,
+        pregnancy_status: values.pregnancy_status,
+        ref_physician: values.ref_physician,
+        operator_id: values.operator_id,
+        weight: values.weight,
+        thickness: values.thickness,
+        length: values.length,
+        comment: values.comment,
+      };
+
+      const response = await registerWork(registerInfo);
+      if (response.code !== '0x000000') {
+        message.error(`注册失败: ${response.description}`);
+        return { success: false, views: [] };
+      }
+
+      message.info('Work registered successfully');
+      return { success: true, data: response.data, views: selectedViews };
+    } catch (error) {
+      console.error('Error registering work:', error);
+      message.error(
+        'Error registering work, please check the console for details.'
+      );
+      return { success: false, views: [] };
+    }
+  };
+
+  return { handleRegister };
+};
+
+export default useRegisterLogic;

+ 8 - 1
src/pages/patient/components/register.form.tsx

@@ -67,8 +67,14 @@ const pregnancyStatusOptions = [
 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 }) => {
+const BasicInfoForm: React.FC<BasicInfoFormProps> = ({
+  style,
+  form,
+  onValuesChange,
+}) => {
   const patient_age = Form.useWatch('patient_age', form);
   React.useEffect(() => {
     console.log('patient_age 变化了:', patient_age); // 每次 NumberWithUnit onChange 都会触发
@@ -84,6 +90,7 @@ const BasicInfoForm: React.FC<BasicInfoFormProps> = ({ style, form }) => {
       initialValues={{
         patient_dob: dayjs(),
       }}
+      onValuesChange={onValuesChange}
     >
       <Form.Item
         label={

+ 10 - 1
src/pages/patient/register.tsx

@@ -1,6 +1,8 @@
 import React from 'react';
 import { Row, Col, Collapse, Grid, Button, Space, Form, message } from 'antd';
 import { FormattedMessage } from 'react-intl';
+import { useDispatch } from 'react-redux';
+import { setFormData } from '@/states/patient/register/formSlice';
 import BasicInfoForm from './components/register.form';
 import SelectedProtocolList from './components/register.selected.view.list';
 import RegisterAvailableList from './components/register.available.list';
@@ -25,6 +27,7 @@ const { Panel } = Collapse;
 const RegisterPage: React.FC = () => {
   const screens = useBreakpoint();
   const [form] = Form.useForm();
+  const dispatch = useDispatch();
   const { selectedViews, currentPatientType } = useRegisterState();
 
   const handleRegister = async (): Promise<{
@@ -101,7 +104,13 @@ const RegisterPage: React.FC = () => {
             }}
             className="h-full px-4"
           >
-            <BasicInfoForm form={form} style={{ overflow: 'auto' }} />
+            <BasicInfoForm
+              form={form}
+              style={{ overflow: 'auto' }}
+              onValuesChange={(changedValues, allValues) => {
+                dispatch(setFormData(allValues));
+              }}
+            />
           </Col>
           <Col
             xs={24}

+ 9 - 1
src/states/businessFlowMiddlewareLogic.ts

@@ -6,6 +6,7 @@ import { suspendOrCompleteStudy } from '@/API/patient/workActions';
 import { RootState } from './store';
 import { getQuota } from '@/API/security/quotaActions';
 import { showQuotaAlert } from './security/quotaModalSlice';
+import useRegisterLogic from '@/domain/patient/registerLogic';
 
 let continueBusinessFlow = '';
 
@@ -42,7 +43,14 @@ const businessFlowMiddlewareLogic: Middleware =
         store.dispatch(showQuotaAlert());
         return;
       }
-
+      // 进入检查前,如果是从register来的,则判断数据合法性,执行注册等逻辑
+      if (currentKey === 'register') {
+        const { handleRegister } = useRegisterLogic();
+        const { success } = await handleRegister();
+        if (success === false) {
+          return;
+        }
+      }
       prepare();
       return next(action);
     }

+ 26 - 0
src/states/patient/register/formSlice.ts

@@ -0,0 +1,26 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+
+interface FormState {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  formData: Record<string, any>;
+}
+
+const initialState: FormState = {
+  formData: {},
+};
+
+const formSlice = createSlice({
+  name: 'form',
+  initialState,
+  reducers: {
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    setFormData: (state, action: PayloadAction<Record<string, any>>) => {
+      state.formData = action.payload;
+    },
+    getFormData: (state) => state, //其实这里用不到
+  },
+});
+
+export const { setFormData, getFormData } = formSlice.actions;
+export type { FormState };
+export default formSlice.reducer;

+ 2 - 0
src/states/store.ts

@@ -41,6 +41,7 @@ import historyPanelSwitchReducer from './patient/worklist/slices/historyPanelSwi
 import panelSwitchForViewReducer from './panelSwitchSliceForView';
 import quotaModalReducer from './security/quotaModalSlice';
 import quotaReducer from './security/quotaSlice';
+import formReducer from './patient/register/formSlice';
 
 const store = configureStore({
   reducer: {
@@ -75,6 +76,7 @@ const store = configureStore({
     panelSwitchForView: panelSwitchForViewReducer,
     quotaModal: quotaModalReducer,
     quota: quotaReducer,
+    form: formReducer,
   },
   middleware: (getDefaultMiddleware) =>
     getDefaultMiddleware().concat(