Browse Source

实现查询任务清单,正常传递多个查询参数,得到正确数量的数据

dengdx 2 weeks ago
parent
commit
7d104cefd1

+ 15 - 4
src/API/patient/workActions.ts

@@ -118,9 +118,12 @@ export interface RegisterWorkResponse {
 export interface TaskListQuery {
 export interface TaskListQuery {
   patient_id?: string;
   patient_id?: string;
   patient_name?: string;
   patient_name?: string;
-  start_date?: string;
-  end_date?: string;
+  start_time?: string;
+  end_time?: string;
   access_number?: string;
   access_number?: string;
+  status?: string;
+  page?: number;
+  page_size?: number;
 }
 }
 // 作为展示数据的基础,本质是个work
 // 作为展示数据的基础,本质是个work
 export interface Task {
 export interface Task {
@@ -183,11 +186,19 @@ const fetchTaskList = async (
   pageSize,
   pageSize,
   filter: TaskListQuery
   filter: TaskListQuery
 ): Promise<{ items: Task[]; total: number }> => {
 ): Promise<{ items: Task[]; total: number }> => {
+  console.log(
+    `Fetching task list with page: ${page}, pageSize: ${pageSize}, filter: ${JSON.stringify(filter)}`
+  );
   const response = await axiosInstance.get('/auth/study', {
   const response = await axiosInstance.get('/auth/study', {
     params: {
     params: {
       page: page,
       page: page,
-      pageSize: pageSize,
-      ...filter,
+      page_size: pageSize,
+      id: filter.patient_id ?? '',
+      name: filter.patient_name ?? '',
+      start_time: filter.start_time,
+      end_time: filter.end_time,
+      acc_no: filter.access_number,
+      status: filter.status,
     },
     },
   });
   });
   const { studies } = response.data.data;
   const { studies } = response.data.data;

+ 41 - 1
src/pages/patient/components/SearchPanel.tsx

@@ -2,11 +2,30 @@ import React from 'react';
 import { Input, Button, DatePicker } from 'antd';
 import { Input, Button, DatePicker } from 'antd';
 import { SearchOutlined } from '@ant-design/icons';
 import { SearchOutlined } from '@ant-design/icons';
 import { useIntl, FormattedMessage } from 'react-intl';
 import { useIntl, FormattedMessage } from 'react-intl';
+import { useDispatch, useSelector } from 'react-redux';
+import dayjs from 'dayjs';
+import {
+  setId,
+  setName,
+  setAccNo,
+  setStartTime,
+  setEndTime,
+  setStatus,
+  setPage,
+  setPageSize,
+} from '../../../states/patient/worklist/slices/searchSlice';
+import { RootState } from '../../../states/store';
 
 
 const { RangePicker } = DatePicker;
 const { RangePicker } = DatePicker;
 
 
 const SearchPanel: React.FC = () => {
 const SearchPanel: React.FC = () => {
   const intl = useIntl();
   const intl = useIntl();
+  const dispatch = useDispatch();
+  const id = useSelector((state: RootState) => state.search.id);
+  const name = useSelector((state: RootState) => state.search.name);
+  const accNo = useSelector((state: RootState) => state.search.acc_no);
+  const startTime = useSelector((state: RootState) => state.search.start_time);
+  const endTime = useSelector((state: RootState) => state.search.end_time);
 
 
   return (
   return (
     <div className="flex flex-col gap-2 w-full">
     <div className="flex flex-col gap-2 w-full">
@@ -17,6 +36,8 @@ const SearchPanel: React.FC = () => {
         })}
         })}
         prefix={<SearchOutlined />}
         prefix={<SearchOutlined />}
         size="small"
         size="small"
+        value={name}
+        onChange={(e) => dispatch(setName(e.target.value))}
       />
       />
       <Input
       <Input
         placeholder={intl.formatMessage({
         placeholder={intl.formatMessage({
@@ -25,6 +46,8 @@ const SearchPanel: React.FC = () => {
         })}
         })}
         prefix={<SearchOutlined />}
         prefix={<SearchOutlined />}
         size="small"
         size="small"
+        value={id}
+        onChange={(e) => dispatch(setId(e.target.value))}
       />
       />
       <Input
       <Input
         placeholder={intl.formatMessage({
         placeholder={intl.formatMessage({
@@ -33,6 +56,8 @@ const SearchPanel: React.FC = () => {
         })}
         })}
         prefix={<SearchOutlined />}
         prefix={<SearchOutlined />}
         size="small"
         size="small"
+        value={accNo}
+        onChange={(e) => dispatch(setAccNo(e.target.value))}
       />
       />
       <RangePicker
       <RangePicker
         className="w-full"
         className="w-full"
@@ -47,8 +72,23 @@ const SearchPanel: React.FC = () => {
           }),
           }),
         ]}
         ]}
         size="small"
         size="small"
+        value={[dayjs(startTime), dayjs(endTime)]}
+        onChange={(dates) => {
+          if (dates && dates[0] && dates[1]) {
+            dispatch(setStartTime(dates[0].toISOString()));
+            dispatch(setEndTime(dates[1].toISOString()));
+          }
+        }}
       />
       />
-      <Button type="primary" icon={<SearchOutlined />}>
+      <Button
+        type="primary"
+        icon={<SearchOutlined />}
+        onClick={() => {
+          dispatch(setStatus('Arrived,InProgress'));
+          dispatch(setPage(1));
+          dispatch(setPageSize(10));
+        }}
+      >
         <FormattedMessage
         <FormattedMessage
           id="searchPanel.search"
           id="searchPanel.search"
           defaultMessage="searchPanel.search"
           defaultMessage="searchPanel.search"

+ 7 - 2
src/pages/patient/components/WorklistTable.tsx

@@ -131,10 +131,15 @@ const WorklistTable: React.FC = () => {
   const worklistData = useSelector(
   const worklistData = useSelector(
     (state: RootState) => state.workEntities.data
     (state: RootState) => state.workEntities.data
   );
   );
+  const filters = useSelector((state: RootState) => state.search);
+  const page = useSelector((state: RootState) => state.workPagination.page);
+  const pageSize = useSelector(
+    (state: RootState) => state.workPagination.pageSize
+  );
 
 
   useEffect(() => {
   useEffect(() => {
-    dispatch(fetchWorkThunk({ page: 1, pageSize: 10, filters: {} }));
-  }, [dispatch]);
+    dispatch(fetchWorkThunk({ page, pageSize, filters }));
+  }, [dispatch, filters, page, pageSize]);
 
 
   return (
   return (
     <Table columns={columns} dataSource={worklistData} rowKey="patient_id" />
     <Table columns={columns} dataSource={worklistData} rowKey="patient_id" />

+ 3 - 1
src/states/list_template/createListSlices.ts

@@ -10,7 +10,8 @@ import {
 export function createEntityListSlices<T, F extends object>(
 export function createEntityListSlices<T, F extends object>(
   namespace: string,
   namespace: string,
   fetchThunk,
   fetchThunk,
-  deleteThunk
+  deleteThunk,
+  extraReducersForFilter?: (builder) => void
 ) {
 ) {
   const entitiesSlice = createSlice({
   const entitiesSlice = createSlice({
     name: `${namespace}/entities`,
     name: `${namespace}/entities`,
@@ -51,6 +52,7 @@ export function createEntityListSlices<T, F extends object>(
         return {} as FiltersState<F>;
         return {} as FiltersState<F>;
       },
       },
     },
     },
+    extraReducers: extraReducersForFilter,
   });
   });
 
 
   const paginationSlice = createSlice({
   const paginationSlice = createSlice({

+ 67 - 0
src/states/patient/worklist/slices/searchSlice.ts

@@ -0,0 +1,67 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+
+interface SearchState {
+  id: string;
+  name: string;
+  acc_no: string;
+  start_time: string;
+  end_time: string;
+  status: string;
+  page: number;
+  page_size: number;
+}
+
+const initialState: SearchState = {
+  id: '',
+  name: '',
+  acc_no: '',
+  start_time: '',
+  end_time: '',
+  status: 'Arrived,InProgress',
+  page: 1,
+  page_size: 10,
+};
+
+const searchSlice = createSlice({
+  name: 'search',
+  initialState,
+  reducers: {
+    setId: (state, action: PayloadAction<string>) => {
+      state.id = action.payload;
+    },
+    setName: (state, action: PayloadAction<string>) => {
+      state.name = action.payload;
+    },
+    setAccNo: (state, action: PayloadAction<string>) => {
+      state.acc_no = action.payload;
+    },
+    setStartTime: (state, action: PayloadAction<string>) => {
+      state.start_time = action.payload;
+    },
+    setEndTime: (state, action: PayloadAction<string>) => {
+      state.end_time = action.payload;
+    },
+    setStatus: (state, action: PayloadAction<string>) => {
+      state.status = action.payload;
+    },
+    setPage: (state, action: PayloadAction<number>) => {
+      state.page = action.payload;
+    },
+    setPageSize: (state, action: PayloadAction<number>) => {
+      state.page_size = action.payload;
+    },
+  },
+});
+
+export const {
+  setId,
+  setName,
+  setAccNo,
+  setStartTime,
+  setEndTime,
+  setStatus,
+  setPage,
+  setPageSize,
+} = searchSlice.actions;
+
+export default searchSlice.reducer;

+ 63 - 2
src/states/patient/worklist/slices/workSlice.ts

@@ -5,6 +5,17 @@ import {
 } from '../../../list_template/thunk.factory';
 } from '../../../list_template/thunk.factory';
 import { work } from '../types/worklist';
 import { work } from '../types/worklist';
 import { WorkFilter } from '../types/workfilter';
 import { WorkFilter } from '../types/workfilter';
+import { PayloadAction } from '@reduxjs/toolkit';
+import {
+  setId,
+  setName,
+  setAccNo,
+  setStartTime,
+  setEndTime,
+  setStatus,
+  setPage,
+  setPageSize,
+} from '../slices/searchSlice';
 
 
 // Define the fetch thunk
 // Define the fetch thunk
 import { fetchTaskList } from '../../../../API/patient/workActions';
 import { fetchTaskList } from '../../../../API/patient/workActions';
@@ -33,7 +44,56 @@ const deleteWorkThunk = createDeleteThunk(
     // });
     // });
   }
   }
 );
 );
-
+const extraReducersForFilter = (builder) => {
+  builder.addCase(
+    setId.type,
+    (state: WorkFilter, action: PayloadAction<string>) => {
+      state.patient_id = action.payload;
+    }
+  );
+  builder.addCase(
+    setName.type,
+    (state: WorkFilter, action: PayloadAction<string>) => {
+      state.patient_name = action.payload;
+    }
+  );
+  builder.addCase(
+    setAccNo.type,
+    (state: WorkFilter, action: PayloadAction<string>) => {
+      state.access_number = action.payload;
+    }
+  );
+  builder.addCase(
+    setStartTime.type,
+    (state: WorkFilter, action: PayloadAction<string>) => {
+      state.start_date = action.payload;
+    }
+  );
+  builder.addCase(
+    setEndTime.type,
+    (state: WorkFilter, action: PayloadAction<string>) => {
+      state.end_date = action.payload;
+    }
+  );
+  builder.addCase(
+    setStatus.type,
+    (state: WorkFilter, action: PayloadAction<string>) => {
+      state.status = action.payload;
+    }
+  );
+  builder.addCase(
+    setPage.type,
+    (state: WorkFilter, action: PayloadAction<number>) => {
+      state.page = action.payload;
+    }
+  );
+  builder.addCase(
+    setPageSize.type,
+    (state: WorkFilter, action: PayloadAction<number>) => {
+      state.page_size = action.payload;
+    }
+  );
+};
 // Create the worklist slices
 // Create the worklist slices
 const {
 const {
   entitiesSlice,
   entitiesSlice,
@@ -44,7 +104,8 @@ const {
 } = createEntityListSlices<work, WorkFilter>(
 } = createEntityListSlices<work, WorkFilter>(
   'worklist',
   'worklist',
   fetchWorkThunk,
   fetchWorkThunk,
-  deleteWorkThunk
+  deleteWorkThunk,
+  extraReducersForFilter
 );
 );
 
 
 export const workEntitiesSlice = entitiesSlice;
 export const workEntitiesSlice = entitiesSlice;

+ 2 - 0
src/states/store.ts

@@ -12,6 +12,7 @@ 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 functionAreaReducer from './view/functionAreaSlice';
 import functionAreaReducer from './view/functionAreaSlice';
+import searchReducer from './patient/worklist/slices/searchSlice';
 import {
 import {
   workEntitiesSlice,
   workEntitiesSlice,
   workFiltersSlice,
   workFiltersSlice,
@@ -40,6 +41,7 @@ const store = configureStore({
     workPagination: workPaginationSlice.reducer,
     workPagination: workPaginationSlice.reducer,
     workSelection: workSelectionSlice.reducer,
     workSelection: workSelectionSlice.reducer,
     workUI: workUISlice.reducer,
     workUI: workUISlice.reducer,
+    search: searchReducer,
   },
   },
 });
 });