Browse Source

添加实现:在检查模块,切换体位后,设置apr到界面;并在切换体型、工作位后,得到apr曝光参数。还需要调试

dengdx 2 weeks ago
parent
commit
a52fa6ff4b

+ 15 - 1
src/API/exam/APRActions.ts

@@ -68,4 +68,18 @@ const getAprDetails = async (
   return response.data.data;
   return response.data.data;
 };
 };
 
 
-export { getAprDetails };
+const getAprExposureParams = async (
+  id: string,
+  workStationId: number,
+  patientSize: string
+): Promise<AprConfig> => {
+  const response = await axiosInstance.get(`auth/protocol/apr/${id}/tech`, {
+    params: {
+      work_station_id: workStationId,
+      patient_size: patientSize,
+    },
+  });
+  return response.data.data.ep;
+};
+
+export { getAprDetails, getAprExposureParams };

+ 1 - 0
src/pages/exam/components/BodyPositionList.tsx

@@ -79,6 +79,7 @@ const BodyPositionList: React.FC<BodyPositionListProps> = ({ layout }) => {
         registration_number: work.AccessionNumber,
         registration_number: work.AccessionNumber,
         study_description: work.StudyDescription,
         study_description: work.StudyDescription,
         body_position_image: view.view_icon_name,
         body_position_image: view.view_icon_name,
+        work: work,
       }))
       }))
     );
     );
     dispatch(setBodyPositions(bodyPositions));
     dispatch(setBodyPositions(bodyPositions));

+ 23 - 2
src/states/exam/aprSlice.ts

@@ -1,5 +1,5 @@
-import { createSlice, PayloadAction } from '@reduxjs/toolkit';
-import { AprConfig } from '../../API/exam/APRActions';
+import { createSlice, PayloadAction, Middleware } from '@reduxjs/toolkit';
+import { AprConfig, getAprExposureParams } from '../../API/exam/APRActions';
 
 
 interface AprState {
 interface AprState {
   aprConfig: AprConfig;
   aprConfig: AprConfig;
@@ -51,6 +51,26 @@ const aprSlice = createSlice({
     },
     },
   },
   },
 });
 });
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const aprMiddleware: Middleware = (store) => (next) => (action: any) => {
+  if (
+    action.type === aprSlice.actions.setBodysize.type ||
+    action.type === aprSlice.actions.setWorkstation.type
+  ) {
+    const state = store.getState();
+    const id =
+      state.bodyPositionList.selectedBodyPosition?.view_id || 'default_id'; // Dynamically determined based on selectedBodyPosition
+    const workStationId = parseInt(state.apr.workstation, 10);
+    const patientSize = state.apr.bodysize;
+
+    if (state.apr.bodysize && state.apr.workstation) {
+      getAprExposureParams(id, workStationId, patientSize).then((data) => {
+        store.dispatch(setAprConfig(data));
+      });
+    }
+  }
+  return next(action);
+};
 
 
 export const {
 export const {
   setAprConfig,
   setAprConfig,
@@ -60,3 +80,4 @@ export const {
   setCurrentExposureMode,
   setCurrentExposureMode,
 } = aprSlice.actions;
 } = aprSlice.actions;
 export default aprSlice.reducer;
 export default aprSlice.reducer;
+export { aprMiddleware };

+ 2 - 0
src/states/exam/bodyPositionListSlice.ts

@@ -1,5 +1,6 @@
 import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 import { View as BodyPosition } from '../../API/patient/viewActions';
 import { View as BodyPosition } from '../../API/patient/viewActions';
+import { Work } from './examWorksCacheSlice';
 
 
 export interface ExtendedBodyPosition extends BodyPosition {
 export interface ExtendedBodyPosition extends BodyPosition {
   patient_name: string;
   patient_name: string;
@@ -10,6 +11,7 @@ export interface ExtendedBodyPosition extends BodyPosition {
   collimator_length: number | string;
   collimator_length: number | string;
   collimator_width: number | string;
   collimator_width: number | string;
   sid: string;
   sid: string;
+  work: Work;
 }
 }
 
 
 interface BodyPositionListState {
 interface BodyPositionListState {

+ 25 - 0
src/states/exam/bodyPositionListener.ts

@@ -0,0 +1,25 @@
+import { createListenerMiddleware } from '@reduxjs/toolkit';
+import { setSelectedBodyPosition } from './bodyPositionListSlice';
+import { setBodysize, setWorkstation } from './aprSlice';
+import { RootState } from '../store';
+import { workstationFromWorkstationId } from '../workstation';
+
+const bodyPositionListener = createListenerMiddleware();
+
+bodyPositionListener.startListening({
+  actionCreator: setSelectedBodyPosition,
+  effect: async (action, listenerApi) => {
+    const state = listenerApi.getState() as RootState;
+    const selectedBodyPosition = state.bodyPositionList.selectedBodyPosition;
+
+    if (selectedBodyPosition) {
+      const patientSize = selectedBodyPosition.work.PatientSize;
+      const workstationId = selectedBodyPosition.work_station_id;
+      const workstation = workstationFromWorkstationId(workstationId);
+      listenerApi.dispatch(setBodysize(patientSize));
+      listenerApi.dispatch(setWorkstation(workstation));
+    }
+  },
+});
+
+export default bodyPositionListener.middleware;

+ 1 - 0
src/states/exam/examWorksCacheSlice.ts

@@ -29,3 +29,4 @@ const examWorksCacheSlice = createSlice({
 
 
 export const { addWork, removeWork, clearWorks } = examWorksCacheSlice.actions;
 export const { addWork, removeWork, clearWorks } = examWorksCacheSlice.actions;
 export default examWorksCacheSlice.reducer;
 export default examWorksCacheSlice.reducer;
+export type { Work };

+ 7 - 0
src/states/store.ts

@@ -11,6 +11,8 @@ import examWorksCacheReducer from './exam/examWorksCacheSlice';
 import bodyPositionListReducer from './exam/bodyPositionListSlice';
 import bodyPositionListReducer from './exam/bodyPositionListSlice';
 import bodyPositionDetailReducer from './exam/bodyPositionDetailSlice';
 import bodyPositionDetailReducer from './exam/bodyPositionDetailSlice';
 import aprReducer from './exam/aprSlice';
 import aprReducer from './exam/aprSlice';
+import bodyPositionListenerMiddleware from './exam/bodyPositionListener';
+import { aprMiddleware } from './exam/aprSlice';
 import functionAreaReducer from './view/functionAreaSlice';
 import functionAreaReducer from './view/functionAreaSlice';
 import searchReducer from './patient/worklist/slices/searchSlice';
 import searchReducer from './patient/worklist/slices/searchSlice';
 import {
 import {
@@ -43,6 +45,11 @@ const store = configureStore({
     workUI: workUISlice.reducer,
     workUI: workUISlice.reducer,
     search: searchReducer,
     search: searchReducer,
   },
   },
+  middleware: (getDefaultMiddleware) =>
+    getDefaultMiddleware().concat(
+      bodyPositionListenerMiddleware,
+      aprMiddleware
+    ),
 });
 });
 
 
 export type RootState = ReturnType<typeof store.getState>;
 export type RootState = ReturnType<typeof store.getState>;

+ 14 - 0
src/states/workstation.ts

@@ -11,3 +11,17 @@ export const WorkstationTypeLabels: Record<WorkstationType, string> = {
   [WorkstationType.Table]: 'Table',
   [WorkstationType.Table]: 'Table',
   [WorkstationType.Wall]: 'Wall',
   [WorkstationType.Wall]: 'Wall',
 };
 };
+export function workstationFromWorkstationId(id: number) {
+  switch (id) {
+    case 1:
+      return WorkstationType.Free;
+    case 2:
+      return WorkstationType.Direct;
+    case 3:
+      return WorkstationType.Table;
+    case 4:
+      return WorkstationType.Wall;
+    default:
+      return WorkstationType.Free;
+  }
+}