Bin.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import React, { useState, useEffect } from 'react';
  2. import { Row, Col, Button, Drawer, Grid } from 'antd';
  3. import { SettingOutlined } from '@ant-design/icons';
  4. import { FormattedMessage } from 'react-intl';
  5. import WorklistTable from './components/WorklistTable';
  6. import BinOperationPanel from './components/BinOperationPanel';
  7. import GenericPagination from '../../components/GenericPagination';
  8. import PatientPortraitFloat from './components/PatientPortraitFloat';
  9. import { useAppDispatch, useAppSelector } from '../../states/store';
  10. import {
  11. fetchBinThunk,
  12. binSelectionSlice,
  13. binPaginationSlice,
  14. binFiltersSlice,
  15. } from '../../states/patient/bin/slices/binSlice';
  16. import { fetchDiskInfoThunk } from '../../states/patient/bin/slices/binDiskInfoSlice';
  17. import { Task } from '@/domain/work';
  18. const { useBreakpoint } = Grid;
  19. const BinPage: React.FC = () => {
  20. const screens = useBreakpoint();
  21. const [drawerVisible, setDrawerVisible] = useState(false);
  22. const [selectedPatientForPortrait, setSelectedPatientForPortrait] =
  23. useState<Task | null>(null);
  24. const dispatch = useAppDispatch();
  25. // 从Redux获取状态
  26. const binData = useAppSelector((state) => state.binEntities.data);
  27. const page = useAppSelector((state) => state.binPagination.page);
  28. const pageSize = useAppSelector((state) => state.binPagination.pageSize);
  29. const filters = useAppSelector((state) => state.binFilters);
  30. const selectedIds = useAppSelector((state) => state.binSelection.selectedIds);
  31. // 初始加载数据
  32. useEffect(() => {
  33. console.log('Bin页面加载,获取回收站数据');
  34. dispatch(fetchBinThunk({ page, pageSize, filters }));
  35. dispatch(fetchDiskInfoThunk());
  36. }, []);
  37. // 监听filters和分页变化,重新获取数据
  38. useEffect(() => {
  39. console.log('回收站过滤条件或分页变化,重新获取数据');
  40. dispatch(fetchBinThunk({ page, pageSize, filters }));
  41. }, [filters, page, pageSize, dispatch]);
  42. // 同步分页到filters
  43. useEffect(() => {
  44. dispatch(
  45. binFiltersSlice.actions.setFilters({
  46. page,
  47. page_size: pageSize,
  48. })
  49. );
  50. }, [dispatch, page, pageSize]);
  51. // 处理行点击事件
  52. const handleRowClick = (record: Task) => {
  53. const studyId = record.StudyID;
  54. const newSelectedIds = [studyId];
  55. // 设置选中患者用于显示照片
  56. setSelectedPatientForPortrait(record);
  57. // 更新 Redux 状态
  58. dispatch(binSelectionSlice.actions.setSelectedIds(newSelectedIds));
  59. };
  60. return (
  61. <div className="h-full">
  62. {/* 患者照片浮动组件 */}
  63. <PatientPortraitFloat
  64. patient={selectedPatientForPortrait}
  65. onClose={() => setSelectedPatientForPortrait(null)}
  66. />
  67. {screens.xs ? (
  68. <>
  69. <div className="flex-1 overflow-auto">
  70. <WorklistTable
  71. columnConfig={[]}
  72. worklistData={binData}
  73. filters={filters}
  74. page={page}
  75. pageSize={pageSize}
  76. selectedIds={selectedIds}
  77. handleRowClick={handleRowClick}
  78. handleRowDoubleClick={() => {}}
  79. />
  80. </div>
  81. <GenericPagination
  82. paginationSelector={(state) => state.binPagination}
  83. entitiesSelector={(state) => state.binEntities}
  84. paginationActions={binPaginationSlice.actions}
  85. className="border-t"
  86. />
  87. <Button
  88. type="primary"
  89. shape="circle"
  90. icon={<SettingOutlined />}
  91. className="fixed bottom-6 right-6 z-50"
  92. onClick={() => setDrawerVisible(true)}
  93. />
  94. <Drawer
  95. title={
  96. <FormattedMessage
  97. id="bin.operationPanel"
  98. defaultMessage="Operation Panel"
  99. />
  100. }
  101. placement="left"
  102. onClose={() => setDrawerVisible(false)}
  103. open={drawerVisible}
  104. width={300}
  105. >
  106. <BinOperationPanel />
  107. </Drawer>
  108. </>
  109. ) : (
  110. <Row className="h-full">
  111. <Col
  112. span={screens.lg ? 18 : screens.md ? 20 : 24}
  113. className="h-full flex flex-col"
  114. >
  115. <div className="flex-1 flex flex-col">
  116. <div className="flex-1 overflow-auto">
  117. <WorklistTable
  118. columnConfig={[]}
  119. worklistData={binData}
  120. filters={filters}
  121. page={page}
  122. pageSize={pageSize}
  123. selectedIds={selectedIds}
  124. handleRowClick={handleRowClick}
  125. handleRowDoubleClick={() => {}}
  126. />
  127. </div>
  128. <GenericPagination
  129. paginationSelector={(state) => state.binPagination}
  130. entitiesSelector={(state) => state.binEntities}
  131. paginationActions={binPaginationSlice.actions}
  132. className="border-t"
  133. />
  134. </div>
  135. </Col>
  136. <Col
  137. span={screens.lg ? 6 : screens.md ? 4 : 0}
  138. className="h-full overflow-auto"
  139. >
  140. <BinOperationPanel />
  141. </Col>
  142. </Row>
  143. )}
  144. </div>
  145. );
  146. };
  147. export default BinPage;