import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit'; import { setCurrentPatientType } from '../../patientTypeSlice'; import { BodyPart } from '@/API/bodyPart'; import { PatientType } from '@/API/patientType'; import { SelectionState, setSelected, } from '@/states/patient/register/SelectionTypeSlice'; import { setCurrentBodyPart } from '../../bodyPartSlice'; import { fetchProcedures, Procedure } from '@/API/patient/procedureActions'; import { fetchViews } from '@/API/patient/viewActions'; export type { Procedure }; // 体位类型 export interface View { internal_id: string; view_id: string; view_name: string; view_name_local: string; view_other_name: string; view_description: string; view_position: string; application: string; anatomic_region: string; patient_type: string; body_part_id: string; view_icon_name: string; view_big_icon_name: string; view_coach_name: string; modality: string; // config_object: any; tech_template: string; img_proc_template: string; sort: number; is_enabled: boolean; product: string; is_pre_install: boolean; } // 协议类型 // export interface Procedure { // ProcedureID: string; // ProcedureCode: string; // ProcedureName: string; // ProcedureOtherName: string; // ProcedureDescription: string; // PatientType: string; // ProcedureGroupID: string; // ProcedureType: string; // FastSearch: boolean; // Enable: boolean; // Order: number; // UserGroupID: string; // ProcedureCategory: string; // Modality: string; // IsImplanted: boolean; // MagFactor: number; // // ProcedureViews: View[]; // // ProcedureViewRelations: any[]; // ClinicProtocol: boolean; // IsFactoryDefault: boolean; // MinBMI: number; // MaxBMI: number; // AutoDecompression: boolean; // ConfigObjectValue: string; // } interface ViewSelectionState { selectedViews: View[]; // 已选择体位列表 availableViews: View[]; // 待选择体位列表 protocols: Procedure[]; // 协议列表(只会出现在待选择列表) currentBodyPart: BodyPart | null; currentPatientType: PatientType | null; currentSelectionType: SelectionState; } const initialState: ViewSelectionState = { selectedViews: [], availableViews: [ { internal_id: '1', view_id: 'AP', view_name: 'Anteroposterior', view_name_local: '前后位', view_other_name: 'AP View', view_description: '前后体位描述', view_position: 'Standing', application: 'General', anatomic_region: 'Chest', patient_type: 'Adult', body_part_id: 'CHEST', view_icon_name: 'ap_icon.png', view_big_icon_name: 'ap_big_icon.png', view_coach_name: 'ap_coach.png', modality: 'X-Ray', tech_template: 'default', img_proc_template: 'default', sort: 1, is_enabled: true, product: 'Standard', is_pre_install: true, }, { internal_id: '2', view_id: 'LAT', view_name: 'Lateral', view_name_local: '侧位', view_other_name: 'LAT View', view_description: '侧体位描述', view_position: 'Standing', application: 'General', anatomic_region: 'Chest', patient_type: 'Adult', body_part_id: 'CHEST', view_icon_name: 'lat_icon.png', view_big_icon_name: 'lat_big_icon.png', view_coach_name: 'lat_coach.png', modality: 'X-Ray', tech_template: 'default', img_proc_template: 'default', sort: 2, is_enabled: true, product: 'Standard', is_pre_install: true, }, ], protocols: [], currentBodyPart: null, currentPatientType: null, currentSelectionType: { selected: 'protocol' }, }; export interface FilterCondition { selection: string; patientType: string | null; bodyPart: string | null; } export const fetchViewsOrProtocols = createAsyncThunk( 'data/fetchData', async (filter: FilterCondition, { rejectWithValue }) => { try { console.log(`触发查询,查询条件是:${JSON.stringify(filter)}`); if (filter.selection === 'protocol') { const response = await fetchProcedures( filter.patientType, filter.bodyPart, true ); return response.data.procedure_list; } if (filter.selection === 'view') { const response = await fetchViews( filter.patientType, filter.bodyPart, true, null ); return response.data.view_list; } } catch (error) { return rejectWithValue(error.message); } } ); const viewSelectionSlice = createSlice({ name: 'viewSelection', initialState, reducers: { // 添加体位到已选择体位列表 addSelectedView(state, action: PayloadAction) { state.selectedViews.push(action.payload); }, // 添加协议中的所有体位到已选择体位列表 // eslint-disable-next-line addProtocolViews(state, action: PayloadAction) { // 假设协议中包含 ProcedureViews 属性,存储体位数组 // todo 这里涉及到基于协议查询其名下的体位,然后再添加 // if (Array.isArray(action.payload.ProcedureViews)) { // state.selectedViews.push(...action.payload.ProcedureViews); // } }, // 可根据需要添加其它 reducer,例如设置 availableViews、Procedures 等 setAvailableViews(state, action: PayloadAction) { state.availableViews = action.payload; }, setProtocols(state, action: PayloadAction) { state.protocols = action.payload; }, }, extraReducers: (builder) => { builder .addCase(setCurrentPatientType, (state, action) => { const currentPatientType = action.payload; if (currentPatientType) { // console.log(`在view section中感知到 current patient type 变化: ${currentPatientType.patient_type_name}`); // 基于过滤条件查询协议或者体位 state.currentPatientType = currentPatientType; } }) .addCase(setCurrentBodyPart, (state, action) => { const currentBodyPart = action.payload; if (currentBodyPart) { state.currentBodyPart = currentBodyPart; // console.log(`在view section中感知到 currentBodyPart 变化: ${JSON.stringify(currentBodyPart, null, 2)}`); } }) .addCase(setSelected, (state, action) => { console .log // `在view section中感知到 currentSelectionType : ${action.payload}` (); state.currentSelectionType.selected = action.payload; }) // eslint-disable-next-line .addCase(fetchViewsOrProtocols.pending, (state, action) => { console.log(`查询view或者protocals:pending`); }) .addCase(fetchViewsOrProtocols.fulfilled, (state, action) => { // console.log(`查询view或者protocals: fulfilled ${JSON.stringify(action.payload)}`); if (action.meta.arg.selection === 'view') { state.availableViews = action.payload as unknown as View[]; console.log( `查询 Views : fulfilled ${JSON.stringify(state.availableViews)}` ); } else { state.protocols = action.payload as unknown as Procedure[]; console.log( `查询protocals: fulfilled ${JSON.stringify(state.protocols)}` ); } }) // eslint-disable-next-line .addCase(fetchViewsOrProtocols.rejected, (state, action) => { console.log(`查询view或者protocals: rejected`); }); }, }); export const { addSelectedView, addProtocolViews, setAvailableViews, setProtocols, } = viewSelectionSlice.actions; export default viewSelectionSlice.reducer;