/* eslint-disable */ import { createSlice, PayloadAction, Middleware, createAsyncThunk } from '@reduxjs/toolkit'; import { AprConfig, getAprExposureParams, getAprByThickness, SetAPR } from '../../API/exam/APRActions'; import { workstationIdFromWorkstation, WorkstationType } from '../workstation'; import { ExtendedBodyPosition, setSelectedBodyPosition } from '../exam/bodyPositionListSlice'; import { initializeProductState } from '../productSlice'; interface AprState { aprConfig: AprConfig; bodysize: string; workstation: string; thickness: number; isAECEnabled: boolean; currentExposureMode: string; /** * 是否正在设置中 */ isPending:boolean; } const initialState: AprState = { aprConfig: { AECDensity: 0, AECField: '', AECFilm: 0, Dose: 0, ExposureMode: 0, Focus: 0, TOD: 0, TubeLoad: 0, kV: 0, mA: 0, mAs: 0, ms: 0, }, bodysize: '', workstation: '', thickness: 0, isAECEnabled: false, currentExposureMode: 'mAs', isPending:false }; const aprSlice = createSlice({ name: 'apr', initialState, reducers: { setAprConfig: (state, action: PayloadAction) => { state.aprConfig = action.payload; }, setBodysize: (state, action: PayloadAction) => { state.bodysize = action.payload; }, setWorkstation: (state, action: PayloadAction) => { state.workstation = action.payload; }, setThickness: (state, action: PayloadAction) => { state.thickness = action.payload; }, setIsAECEnabled: (state, action: PayloadAction) => { state.isAECEnabled = action.payload; }, setCurrentExposureMode: (state, action: PayloadAction) => { state.currentExposureMode = action.payload; }, }, extraReducers: (builder) => { builder .addCase(incKV.pending, (state) => { console.log('Increasing kV...'); }) .addCase(incKV.fulfilled, (state, action) => { console.log('kV increased successfully'); state.aprConfig.kV = action.payload; }) .addCase(incKV.rejected, (state, action) => { console.error('Failed to increase kV', action.error); }) .addCase(decKV.pending, (state) => { console.log('Decreasing kV...'); }) .addCase(decKV.fulfilled, (state, action) => { console.log('kV decreased successfully'); state.aprConfig.kV = action.payload; }) .addCase(decKV.rejected, (state, action) => { console.error('Failed to decrease kV', action.error); }) .addCase(incMA.pending, (state) => { console.log('Increasing mA...'); }) .addCase(incMA.fulfilled, (state, action) => { console.log('mA increased successfully'); state.aprConfig.mA = action.payload; }) .addCase(incMA.rejected, (state, action) => { console.error('Failed to increase mA', action.error); }) .addCase(decMA.pending, (state) => { console.log('Decreasing mA...'); }) .addCase(decMA.fulfilled, (state, action) => { console.log('mA decreased successfully'); state.aprConfig.mA = action.payload; }) .addCase(decMA.rejected, (state, action) => { console.error('Failed to decrease mA', action.error); }) .addCase(incMAS.pending, (state) => { console.log('Increasing mAs...'); }) .addCase(incMAS.fulfilled, (state, action) => { console.log('mAs increased successfully'); state.aprConfig.mAs = action.payload; }) .addCase(incMAS.rejected, (state, action) => { console.error('Failed to increase mAs', action.error); }) .addCase(decMAS.pending, (state) => { console.log('Decreasing mAs...'); }) .addCase(decMAS.fulfilled, (state, action) => { console.log('mAs decreased successfully'); state.aprConfig.mAs = action.payload; }) .addCase(decMAS.rejected, (state, action) => { console.error('Failed to decrease mAs', action.error); }) .addCase(incMS.pending, (state) => { console.log('Increasing ms...'); }) .addCase(incMS.fulfilled, (state, action) => { console.log('ms increased successfully'); state.aprConfig.ms = action.payload; }) .addCase(incMS.rejected, (state, action) => { console.error('Failed to increase ms', action.error); }) .addCase(decMS.pending, (state) => { console.log('Decreasing ms...'); }) .addCase(decMS.fulfilled, (state, action) => { console.log('ms decreased successfully'); state.aprConfig.ms = action.payload; }) .addCase(decMS.rejected, (state, action) => { console.error('Failed to decrease ms', action.error); }) .addCase(incDensity.pending, (state) => { console.log('Increasing Density...'); }) .addCase(incDensity.fulfilled, (state, action) => { console.log('Density increased successfully'); state.aprConfig.AECDensity = action.payload; }) .addCase(incDensity.rejected, (state, action) => { console.error('Failed to increase Density', action.error); }) .addCase(decDensity.pending, (state) => { console.log('Decreasing Density...'); }) .addCase(decDensity.fulfilled, (state, action) => { console.log('Density decreased successfully'); state.aprConfig.AECDensity = action.payload; }) .addCase(decDensity.rejected, (state, action) => { console.error('Failed to decrease Density', action.error); }) .addCase(incThickness.pending, (state) => { console.log('Increasing Thickness...'); }) .addCase(incThickness.fulfilled, (state, action) => { console.log('Thickness increased successfully'); state.thickness = action.payload; }) .addCase(incThickness.rejected, (state, action) => { console.error('Failed to increase Thickness', action.error); }) .addCase(decThickness.pending, (state) => { console.log('Decreasing Thickness...'); }) .addCase(decThickness.fulfilled, (state, action) => { console.log('Thickness decreased successfully'); state.thickness = action.payload; }) .addCase(decThickness.rejected, (state, action) => { console.error('Failed to decrease Thickness', action.error); }) .addCase(setExposureModeThunk.pending, (state) => { console.log('Setting exposure mode...'); state.isPending = true; }) .addCase(setExposureModeThunk.fulfilled, (state, action) => { console.log('Exposure mode set successfully:', action.payload); state.currentExposureMode = action.payload; state.isPending = false; }) .addCase(setExposureModeThunk.rejected, (state, action) => { console.error('Failed to set exposure mode', action.error); state.isPending = false; }) .addCase(setSelectedBodyPosition, (state, action: PayloadAction) => { console.log('APR Extra Reducer triggered for setSelectedBodyPosition action'); const selectedBodyPosition = action.payload; if (selectedBodyPosition) { // 初始化厚度值 state.thickness = selectedBodyPosition.work?.Thickness || 0; console.log('Initialized thickness from selected body position:', state.thickness); const reqParam = JSON.stringify({ P0:{ FOCUS: "0", TECHMODE: state.aprConfig.ExposureMode.toString(), AECFIELD: "101", AECFILM: "0", AECDENSITY: "0", KV: state.aprConfig.kV.toString(), MA: state.aprConfig.mA.toString(), MS: state.aprConfig.ms.toString(), MAS: state.aprConfig.mAs.toString(), KV2: "0.0", MA2: "0.0", MS2: "0.0", DOSE: "0.0", FILTER: "null", TUBELOAD: "0.0", WORKSTATION: selectedBodyPosition.work_station_id }}); SetAPR(reqParam) .then(() => { console.log('SetAPR method called successfully'); }) .catch((error) => { console.error('Error calling SetAPR method:', error); }); } }) .addCase(initializeProductState.fulfilled, (state, action) => { console.log('APR监听到产品初始化完成:', action.payload.productName); if (action.payload.productName === 'VETDROS') { state.workstation = WorkstationType.Free; console.log('自动设置 workstation 为 Free (VETDROS 环境)'); } }); }, }); const aprMiddleware: Middleware = (store) => (next) => (action: any) => { const result = next(action); if ( action.type === aprSlice.actions.setBodysize.type || action.type === aprSlice.actions.setWorkstation.type ) { console.log('APR Middleware triggered:', action.type); const state = store.getState(); const id = state.bodyPositionList.selectedBodyPosition?.view_id || 'default_id'; // Dynamically determined based on selectedBodyPosition const workStationId = workstationIdFromWorkstation( state.apr.workstation, state.product.productName ); const patientSize = state.apr.bodysize; console.log( `Fetching APR exposure parameters for ID: ${id}, Workstation ID: ${workStationId}, Patient Size: ${patientSize}` ); // Fetch APR exposure parameters based on the current state if (!!patientSize) { getAprExposureParams(id, workStationId, patientSize) .then((data) => { console.log('Received APR exposure parameters:', data); // Dispatch the action to set the APR config in the store if (data) { store.dispatch(setAprConfig(data)); // After updating the store, send the APR parameters to the device const currentState = store.getState(); const selectedBodyPosition = currentState.bodyPositionList.selectedBodyPosition; if (selectedBodyPosition) { const reqParam = JSON.stringify({ P0: { FOCUS: "0", TECHMODE: data.ExposureMode.toString(), AECFIELD: "101", AECFILM: "0", AECDENSITY: "0", KV: data.kV.toString(), MA: data.mA.toString(), MS: data.ms.toString(), MAS: data.mAs.toString(), KV2: "0.0", MA2: "0.0", MS2: "0.0", DOSE: "0.0", FILTER: "null", TUBELOAD: "0.0", WORKSTATION: selectedBodyPosition.work_station_id } }); SetAPR(reqParam) .then(() => { console.log('[aprMiddleware] SetAPR called successfully after body size/workstation change'); }) .catch((error) => { console.error('[aprMiddleware] Error calling SetAPR after body size/workstation change:', error); }); } else { console.warn('[aprMiddleware] No selected body position found, skipping SetAPR call'); } } }) .catch((error) => { console.error('Error fetching APR exposure parameters:', error); }) .finally(() => { console.log('APR exposure parameters fetch attempt finished.'); }); } } else if (action.type === aprSlice.actions.setThickness.type) { console.log('APR Middleware triggered by thickness change:', action.type); const state = store.getState(); const thickness = state.apr.thickness; console.log(`Fetching APR exposure parameters by thickness: ${thickness}`); // 确保厚度值在有效范围内 (1-50) if (thickness >= 1 && thickness <= 50) { getAprByThickness(thickness) .then((data) => { console.log('Received APR exposure parameters by thickness:', data); if (data) { store.dispatch(setAprConfig(data)); // After updating the store, send the APR parameters to the device const currentState = store.getState(); const selectedBodyPosition = currentState.bodyPositionList.selectedBodyPosition; console.info(`根据厚度得到arp后,下发kv ms mas ma 给设备`); if (selectedBodyPosition) { const reqParam = JSON.stringify({ P0: { FOCUS: "0", TECHMODE:data.ExposureMode.toString(), AECFIELD: "101", AECFILM: "0", AECDENSITY: "0", KV: data.kV.toString(), MA: data.mA.toString(), MS: (data.mAs/data.mA).toString(), MAS: data.mAs.toString(), KV2: "0.0", MA2: "0.0", MS2: "0.0", DOSE: "0.0", FILTER: "null", TUBELOAD: "0.0", WORKSTATION: selectedBodyPosition.work_station_id } }); console.info(`根据厚度得到arp后,下发之前 kv ms mas ma = ${reqParam}`); SetAPR(reqParam) .then(() => { console.log('[aprMiddleware] SetAPR called successfully after thickness change'); }) .catch((error) => { console.error('[aprMiddleware] Error calling SetAPR after thickness change:', error); }); } else { console.warn('[aprMiddleware] No selected body position found, skipping SetAPR call'); } } }) .catch((error) => { console.error('Error fetching APR exposure parameters by thickness:', error); }) .finally(() => { console.log('APR exposure parameters fetch by thickness attempt finished.'); }); } else { console.warn(`Thickness value ${thickness} is out of valid range (1-50), skipping API call`); } } return result; }; export const incKV = createAsyncThunk('apr/incKV', async (amount: number) => { return amount; }); export const decKV = createAsyncThunk('apr/decKV', async (amount: number) => { return amount; }); export const incMA = createAsyncThunk('apr/incMA', async (amount: number) => { return amount; }); export const decMA = createAsyncThunk('apr/decMA', async (amount: number) => { return amount; }); export const incMAS = createAsyncThunk('apr/incMAS', async (amount: number) => { return amount; }); export const decMAS = createAsyncThunk('apr/decMAS', async (amount: number) => { return amount; }); export const incMS = createAsyncThunk('apr/incMS', async (amount: number) => { return amount; }); export const decMS = createAsyncThunk('apr/decMS', async (amount: number) => { return amount; }); export const incDensity = createAsyncThunk('apr/incDensity', async (amount: number) => { return amount; }); export const decDensity = createAsyncThunk('apr/decDensity', async (amount: number) => { return amount; }); export const incThickness = createAsyncThunk('apr/incThickness', async (amount: number) => { return amount; }); export const decThickness = createAsyncThunk('apr/decThickness', async (amount: number) => { return amount; }); export const setExposureModeThunk = createAsyncThunk('apr/setExposureMode', async (mode: string) => { return mode; }); export const { setAprConfig, setBodysize, setWorkstation, setThickness, setIsAECEnabled, setCurrentExposureMode, } = aprSlice.actions; export default aprSlice.reducer; export { aprMiddleware };