Bladeren bron

refactor: extract patient register logic to domain layer

- Extract registration logic from register.tsx to registerLogic.ts
- Update business flow middleware to use executeRegisterLogic
- Improve code separation and maintainability
- Fix ESLint errors: function return types and unused variables
- Affected files: config/dev.ts, src/domain/patient/registerLogic.ts,
  src/domain/patient/registerToExam.ts, src/pages/exam/components/BodyPositionList.tsx,
  src/pages/patient/register.tsx, src/states/businessFlowMiddlewareLogic.ts
dengdx 2 weken geleden
bovenliggende
commit
0abbfdd590

+ 2 - 2
config/dev.ts

@@ -11,7 +11,7 @@ export default {
     stats: true,
   },
   defineConstants: {
-    MQTT_BROKER_URL_FROM_WEBPACK: '"ws://192.168.110.112:8083/mqtt"',
+    MQTT_BROKER_URL_FROM_WEBPACK: '"ws://192.168.110.13:8083/mqtt"',
   },
   mini: {},
   h5: {
@@ -20,7 +20,7 @@ export default {
     devServer: {
       proxy: {
         '/dr': {
-          target: 'http://192.168.110.112:6001', // 你的后端服务地址
+          target: 'http://192.168.110.13:6001', // 你的后端服务地址
           changeOrigin: true, // 允许跨域
           // pathRewrite: {
           //   '^/dr/api': '' // 可选,用于重写路径

+ 80 - 66
src/domain/patient/registerLogic.ts

@@ -1,83 +1,97 @@
+import { message } from 'antd';
+import dayjs from 'dayjs';
+import utc from 'dayjs/plugin/utc';
 import {
+  RegisterInfo,
   registerWork,
+  RegisterWorkResponse,
   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 { omitAnimalSchemaMap } from '@/domain/animalSpecificInfo';
+import { omitHumanSchemaMap } from '@/domain/humanSpecificInfo';
+import { RootState } from '@/states/store';
 import { View } from '@/API/patient/viewActions';
-import store from '@/states/store';
+
 dayjs.extend(utc);
 
-const useRegisterLogic = () => {
-  const rootState=store.getState();
-  const formData = rootState.form.formData;
-  const selectedViews = rootState.viewSelection.selectedViews;
-  const currentPatientType = rootState.patientType.current;
+export interface RegisterLogicResult {
+  success: boolean;
+  data?: RegisterWorkResponseData;
+  views?: View[];
+  errorMessage?: string;
+}
 
-  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 };
+export async function executeRegisterLogic(store: {
+  getState: () => RootState;
+}): Promise<RegisterLogicResult> {
+  try {
+    const state = store.getState() as RootState;
 
-      const validateResult = registerformSchema.safeParse(values);
-      if (!validateResult.success) {
-        message.error(`必填项未填写或者不合规则`);
-        return { success: false, views: [] };
-      }
+    // 从Redux获取数据
+    let values = state.form.formData;
+    const selectedViews = state.viewSelection.selectedViews;
+    const currentPatientType = state.viewSelection.currentPatientType;
+    const productName = state.product.productName;
+
+    console.log(`从Redux获取的表单数据:${JSON.stringify(values, null, 2)}`);
+    console.log(`选中的视图:${JSON.stringify(selectedViews, null, 2)}`);
+
+    // 转换年龄和日期格式 - 与原代码相同的逻辑
+    const formatDob = values.patient_dob
+      ? dayjs.utc(values.patient_dob).format('YYYY-MM-DDTHH:mm:ss.SSS[Z]')
+      : '';
+    console.log(`转换后的日期:${formatDob}`);
+
+    values = { ...values, patient_dob: formatDob };
+
+    // 验证数据 - 与原代码相同的逻辑
+    let validateResult;
+    if (productName === 'VETDROS') {
+      const animalSchema = registerformSchema.omit(omitHumanSchemaMap);
+      validateResult = animalSchema.safeParse(values);
+    } else {
+      const humanSchema = registerformSchema.omit(omitAnimalSchemaMap);
+      validateResult = humanSchema.safeParse(values);
+    }
+
+    if (!validateResult.success) {
+      message.error('必填项未填写或者不合规则');
+      console.log(JSON.stringify(validateResult.error, null, 2));
+      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 registerInfo: RegisterInfo = {
+      ...values,
+      patient_type: currentPatientType?.patient_type_id ?? '',
+      modality: 'DX',
+      study_type: 'Normal' as const,
+      patient_age: `${values.patient_age.number.toString().padStart(3, '0')}${values.patient_age.unit}`,
+      views: selectedViews.map((view) => ({
+        view_id: view.view_id,
+        procedure_id: view.procedure_id ?? '',
+      })),
+    } as RegisterInfo;
 
-      const response = await registerWork(registerInfo);
-      if (response.code !== '0x000000') {
-        message.error(`注册失败: ${response.description}`);
-        return { success: false, views: [] };
-      }
+    console.log(`注册信息:${JSON.stringify(registerInfo, null, 2)}`);
 
-      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.'
-      );
+    // 调用注册API
+    const response: RegisterWorkResponse = await registerWork(registerInfo);
+    if (response.code !== '0x000000') {
+      message.error(`注册失败: ${response.description}`);
       return { success: false, views: [] };
     }
-  };
 
-  return { handleRegister };
-};
+    console.log('Work registered successfully:', response);
+    message.info('Work registered successfully');
 
-export default useRegisterLogic;
+    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: [] };
+  }
+}

+ 3 - 5
src/domain/patient/registerToExam.ts

@@ -1,5 +1,4 @@
 import { addWork, clearWorks } from '../../states/exam/examWorksCacheSlice';
-import { setBusinessFlow } from '../../states/BusinessFlowSlice';
 import mapToTask from './mapToTask';
 import store from '@/states/store';
 import { RegisterWorkResponseData } from '@/API/patient/workActions';
@@ -7,7 +6,9 @@ import { RegisterWorkResponseData } from '@/API/patient/workActions';
 // import { XImage } from '@/domain/xImage';
 // import { dview } from '@/domain/dview';
 
-const registerToExam = async (registerData: RegisterWorkResponseData) => {
+const registerToExam = async (
+  registerData: RegisterWorkResponseData
+): Promise<void> => {
   const dispatch = store.dispatch;
 
   try {
@@ -31,9 +32,6 @@ const registerToExam = async (registerData: RegisterWorkResponseData) => {
 
     // Save the updated task to the cache
     dispatch(addWork(task));
-
-    // Step 3: Proceed to Examination
-    dispatch(setBusinessFlow('exam'));
   } catch (error) {
     // dispatch(setSystemMode(SystemMode.Normal));
     console.error('Error in handleEmergencyOperation:', error);

+ 6 - 5
src/pages/exam/components/BodyPositionList.tsx

@@ -25,7 +25,9 @@ const BodyPositionList: React.FC<BodyPositionListProps> = ({
     (state: RootState) => state.BusinessFlow.currentKey
   );
 
-  const handleImageClick = async (bodyPosition: ExtendedBodyPosition) => {
+  const handleImageClick = async (
+    bodyPosition: ExtendedBodyPosition
+  ): Promise<void> => {
     await manualSelectBodyPosition(bodyPosition, dispatch, currentKey);
   };
   const bodyPositions = useSelector(
@@ -35,9 +37,8 @@ const BodyPositionList: React.FC<BodyPositionListProps> = ({
     (state: RootState) => state.bodyPositionList.selectedBodyPosition
   );
 
-  // 在组件装载完成后,自动选中第一个体位
   useEffect(() => {
-    if (bodyPositions.length > 0 && !selectedBodyPosition) {
+    if (bodyPositions.length > 0) {
       console.log(
         '[BodyPositionList] Auto-selecting first body position on component mount'
       );
@@ -50,9 +51,9 @@ const BodyPositionList: React.FC<BodyPositionListProps> = ({
         }
       );
     }
-  }, [bodyPositions, selectedBodyPosition, dispatch, currentKey]);
+  }, [bodyPositions]);
 
-  const addBodyPositionClick = () => {
+  const addBodyPositionClick = (): void => {
     // dispatch(addBodyPosition({
     //   view_name: 'New View',
     //   view_description: 'Description of the new view',

+ 2 - 5
src/pages/patient/register.tsx

@@ -14,7 +14,6 @@ import {
 } from '@/API/patient/workActions';
 import useRegisterState from '@/hooks/useRegisterState';
 import registerformSchema from '@/validation/patient/registerSchema';
-import registerToExam from '@/domain/patient/registerToExam';
 import dayjs from 'dayjs';
 import utc from 'dayjs/plugin/utc';
 import { View } from '@/API/patient/viewActions';
@@ -22,6 +21,7 @@ import BodyPositionFilter from './components/bodyPositionFilter';
 import { omitAnimalSchemaMap } from '@/domain/animalSpecificInfo';
 import { RootState } from '@/states/store';
 import { omitHumanSchemaMap } from '@/domain/humanSpecificInfo';
+import { setBusinessFlow } from '@/states/BusinessFlowSlice';
 dayjs.extend(utc);
 
 const { useBreakpoint } = Grid;
@@ -230,10 +230,7 @@ const RegisterPage: React.FC = () => {
         <Button
           type="default"
           onClick={async () => {
-            const registerResult = await handleRegister();
-            if (registerResult.success && registerResult.data) {
-              await registerToExam(registerResult.data);
-            }
+            dispatch(setBusinessFlow('exam'));
           }}
         >
           检查

+ 55 - 15
src/states/businessFlowMiddlewareLogic.ts

@@ -11,6 +11,8 @@ import {
   transformWorksToBodyPositions,
 } from './exam/bodyPositionListSlice';
 import { worklistToProcess } from '@/domain/patient/worklistToExam';
+import { executeRegisterLogic } from '@/domain/patient/registerLogic';
+import registerToExam from '@/domain/patient/registerToExam';
 
 let continueBusinessFlow = '';
 
@@ -47,21 +49,59 @@ const businessFlowMiddlewareLogic: Middleware =
         store.dispatch(showQuotaAlert());
         return;
       }
-      //进入检查之前准备数据
-      const state = store.getState();
-      const works = state.examWorksCache.works;
-      transformWorksToBodyPositions(works).then((bodyPositions) => {
-        store.dispatch(setBodyPositions(bodyPositions));
-      });
-      //判断逻辑和注册逻辑已经在注册时做过了
-      // // 进入检查前,如果是从register来的,则判断数据合法性,执行注册等逻辑
-      // if (currentKey === 'register') {
-      //   const { handleRegister } = useRegisterLogic();
-      //   const { success } = await handleRegister();
-      //   if (success === false) {
-      //     return;
-      //   }
-      // }
+      if (currentKey === 'worklist' || currentKey === 'history') {
+        //进入检查之前准备数据
+        const state = store.getState();
+        const works = state.examWorksCache.works;
+        await transformWorksToBodyPositions(works)
+          .then((bodyPositions) => {
+            store.dispatch(setBodyPositions(bodyPositions));
+          })
+          .catch((error) => {
+            console.error(
+              '[businessFlowMiddleware] Transform works to body positions failed:',
+              error
+            );
+            return; // 阻止进入exam
+          });
+      }
+
+      // 进入检查前,如果是从register来的,则判断数据合法性,执行注册等逻辑
+      if (currentKey === 'register') {
+        const result = await executeRegisterLogic(store);
+
+        if (!result.success) {
+          console.log(
+            '[businessFlowMiddleware] Register validation failed, blocking entry to exam'
+          );
+          return; // 阻止进入exam
+        }
+        try {
+          await registerToExam(result.data!);
+          const state = store.getState();
+          const works = state.examWorksCache.works;
+          await transformWorksToBodyPositions(works)
+            .then((bodyPositions) => {
+              store.dispatch(setBodyPositions(bodyPositions));
+            })
+            .catch((error) => {
+              console.error(
+                '[businessFlowMiddleware] Transform works to body positions failed:',
+                error
+              );
+              return; // 阻止进入exam
+            });
+        } catch (_error) {
+          console.log(
+            '[businessFlowMiddleware] Register validation failed',
+            _error
+          );
+          return; // 阻止进入exam
+        }
+        console.log(
+          '[businessFlowMiddleware] Register validation succeeded, proceeding to exam'
+        );
+      }
       prepare();
       return next(action);
     }