SearchPanel.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import React from 'react';
  2. import { Input, Button, DatePicker } from 'antd';
  3. import { SearchOutlined } from '@ant-design/icons';
  4. import { useIntl, FormattedMessage } from 'react-intl';
  5. import { useDispatch, useSelector } from 'react-redux';
  6. import dayjs from 'dayjs';
  7. import {
  8. setId,
  9. setName,
  10. setAccNo,
  11. setStartTime,
  12. setEndTime,
  13. // setStatus,
  14. setPage,
  15. setPageSize,
  16. } from '../../../states/patient/worklist/slices/searchSlice';
  17. import { fetchWorkThunk } from '../../../states/patient/worklist/slices/workSlice';
  18. import { fetchBinThunk } from '../../../states/patient/bin/slices/binSlice';
  19. import { AppDispatch, RootState } from '../../../states/store';
  20. import { WorkFilter } from '@/states/patient/worklist/types/workfilter';
  21. import { BinFilter } from '@/states/patient/bin/types/binFilter';
  22. import TimeRangeSelector from './TimeRangeSelector';
  23. // import { AnyAction } from '@reduxjs/toolkit';
  24. const { RangePicker } = DatePicker;
  25. const SearchPanel: React.FC = () => {
  26. const intl = useIntl();
  27. const dispatch = useDispatch<AppDispatch>();
  28. const id = useSelector((state: RootState) => state.search.id);
  29. const name = useSelector((state: RootState) => state.search.name);
  30. const accNo = useSelector((state: RootState) => state.search.acc_no);
  31. const startTime = useSelector((state: RootState) => state.search.start_time);
  32. const endTime = useSelector((state: RootState) => state.search.end_time);
  33. const currentKey = useSelector(
  34. (state: RootState) => state.BusinessFlow.currentKey
  35. );
  36. return (
  37. <div className="flex flex-col gap-2 w-full">
  38. <Input
  39. placeholder={intl.formatMessage({
  40. id: 'searchPanel.name',
  41. defaultMessage: 'searchPanel.name',
  42. })}
  43. prefix={<SearchOutlined />}
  44. size="small"
  45. value={name}
  46. onChange={(e) => dispatch(setName(e.target.value))}
  47. />
  48. <Input
  49. placeholder={intl.formatMessage({
  50. id: 'searchPanel.patientId',
  51. defaultMessage: 'searchPanel.patientId',
  52. })}
  53. prefix={<SearchOutlined />}
  54. size="small"
  55. value={id}
  56. onChange={(e) => dispatch(setId(e.target.value))}
  57. />
  58. <Input
  59. placeholder={intl.formatMessage({
  60. id: 'searchPanel.registrationId',
  61. defaultMessage: 'searchPanel.registrationId',
  62. })}
  63. prefix={<SearchOutlined />}
  64. size="small"
  65. value={accNo}
  66. onChange={(e) => dispatch(setAccNo(e.target.value))}
  67. />
  68. <TimeRangeSelector />
  69. <RangePicker
  70. className="w-full"
  71. placeholder={[
  72. intl.formatMessage({
  73. id: 'searchPanel.startDate',
  74. defaultMessage: 'searchPanel.startDate',
  75. }),
  76. intl.formatMessage({
  77. id: 'searchPanel.endDate',
  78. defaultMessage: 'searchPanel.endDate',
  79. }),
  80. ]}
  81. size="small"
  82. value={startTime && endTime ? [dayjs(startTime), dayjs(endTime)] : null}
  83. onChange={(dates) => {
  84. if (dates && dates[0] && dates[1]) {
  85. // 使用RFC3339Nano格式
  86. dispatch(
  87. setStartTime(dates[0].format('YYYY-MM-DDTHH:mm:ss.SSS[+08:00]'))
  88. );
  89. dispatch(
  90. setEndTime(dates[1].format('YYYY-MM-DDTHH:mm:ss.SSS[+08:00]'))
  91. );
  92. } else {
  93. dispatch(setStartTime(''));
  94. dispatch(setEndTime(''));
  95. }
  96. }}
  97. />
  98. <Button
  99. type="primary"
  100. icon={<SearchOutlined />}
  101. onClick={() => {
  102. dispatch(setPage(1));
  103. dispatch(setPageSize(10));
  104. // 通用的过滤条件
  105. const commonFilters = {
  106. patient_id: id,
  107. patient_name: name,
  108. access_number: accNo,
  109. start_time: startTime,
  110. end_time: endTime,
  111. };
  112. // 根据 currentKey 调用不同的 thunk
  113. if (currentKey === 'bin') {
  114. // 回收站搜索
  115. dispatch(
  116. fetchBinThunk({
  117. page: 1,
  118. pageSize: 10,
  119. filters: commonFilters as BinFilter,
  120. })
  121. );
  122. } else {
  123. // worklist/history 搜索
  124. const status =
  125. currentKey === 'worklist' ? 'Arrived,InProgress' : 'Completed';
  126. dispatch(
  127. fetchWorkThunk({
  128. page: 1,
  129. pageSize: 10,
  130. filters: {
  131. ...commonFilters,
  132. status: status,
  133. } as WorkFilter,
  134. })
  135. );
  136. }
  137. }}
  138. >
  139. <FormattedMessage
  140. id="searchPanel.search"
  141. defaultMessage="searchPanel.search"
  142. />
  143. </Button>
  144. </div>
  145. );
  146. };
  147. export default SearchPanel;