瀏覽代碼

feat (1.42.0 -> 1.42.1): 优化患者管理界面布局和测试支持

- 在 BasicLayout 中添加内容区域测试标识
- 重构 PatientManagement 组件使用新的 Tabs API,支持 className 属性
- 优化 Bin 页面布局,添加高度控制和测试标识
- 改进 BinOperationPanel 组件样式控制

改动文件:
- src/layouts/BasicLayout.tsx
- src/pages/patient/Bin.tsx
- src/pages/patient/PatientManagement.tsx
- src/pages/patient/components/BinOperationPanel.tsx
dengdx 1 周之前
父節點
當前提交
fd7c96dd19

+ 16 - 0
CHANGELOG.md

@@ -2,6 +2,22 @@
 
 本项目的所有重要变更都将记录在此文件中。
 
+## [1.42.1] - 2026-01-03 11:38
+
+### 新增 (Added)
+
+- 优化患者管理界面布局和测试支持
+  - 在 BasicLayout 中添加内容区域测试标识
+  - 重构 PatientManagement 组件使用新的 Tabs API,支持 className 属性
+  - 优化 Bin 页面布局,添加高度控制和测试标识
+  - 改进 BinOperationPanel 组件样式控制
+
+**改动文件:**
+- src/layouts/BasicLayout.tsx
+- src/pages/patient/Bin.tsx
+- src/pages/patient/PatientManagement.tsx
+- src/pages/patient/components/BinOperationPanel.tsx
+
 ## [1.42.0] - 2026-01-02 18:50
 
 ### 新增 (Added)

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "zsis",
-  "version": "1.42.0",
+  "version": "1.42.1",
   "private": true,
   "description": "医学成像系统",
   "main": "main.js",

+ 1 - 0
src/layouts/BasicLayout.tsx

@@ -202,6 +202,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = () => {
               // border: '1px solid blue'
             }}
             className="h-full"
+            data-testid="content-area"
           >
             {/* {children} */}
             {contentMap[currentKey]}

+ 4 - 4
src/pages/patient/Bin.tsx

@@ -84,7 +84,7 @@ const BinPage: React.FC = () => {
   };
 
   return (
-    <div className="h-full">
+    <div className="h-full" data-testid="bin-page">
       {/* 患者照片浮动组件 */}
       <PatientPortraitFloat
         patient={selectedPatientForPortrait}
@@ -139,8 +139,8 @@ const BinPage: React.FC = () => {
             span={screens.lg ? 18 : screens.md ? 20 : 24}
             className="h-full flex flex-col"
           >
-            <div className="flex-1 flex flex-col">
-              <div className="flex-1 overflow-auto">
+            <div className="flex-1 flex flex-col h-full">
+              <div className="flex-1 overflow-auto h-full">
                 <WorklistTable
                   columnConfig={[]}
                   worklistData={binData}
@@ -164,7 +164,7 @@ const BinPage: React.FC = () => {
             span={screens.lg ? 6 : screens.md ? 4 : 0}
             className="h-full overflow-auto"
           >
-            <BinOperationPanel />
+            <BinOperationPanel  className='h-full'/>
           </Col>
         </Row>
       )}

+ 111 - 78
src/pages/patient/PatientManagement.tsx

@@ -1,7 +1,9 @@
 import React, { Suspense, lazy } from 'react';
 import { Tabs } from 'antd';
 import { FormattedMessage } from 'react-intl';
-
+interface PatientManagementProps {
+  className?: string;
+}
 // 懒加载各子页面
 const WorklistPage = lazy(() => import('./worklist'));
 const OutputListPage = lazy(() => import('./OutputList'));
@@ -10,90 +12,121 @@ const ArchiveListPage = lazy(() => import('./ArchiveList'));
 const BinPage = lazy(() => import('./Bin'));
 const RegisterPage = lazy(() => import('./register'));
 
-const { TabPane } = Tabs;
 
-const PatientManagement: React.FC = () => {
+
+const PatientManagement: React.FC<PatientManagementProps> = ({ className }) => {
+  const items = [
+    {
+      key: 'worklist',
+      label: (
+        <FormattedMessage
+          id="patient.tab.worklist"
+          defaultMessage="Worklist"
+        />
+      ),
+      children: (
+        <Suspense fallback={null}>
+          <WorklistPage />
+        </Suspense>
+      )
+    },
+    {
+      key: 'output',
+      label: (
+        <FormattedMessage id="patient.tab.output" defaultMessage="Output" />
+      ),
+      children: (
+        <Suspense fallback={null}>
+          <OutputListPage />
+        </Suspense>
+      )
+    },
+    {
+      key: 'history',
+      label: (
+        <FormattedMessage
+          id="patient.tab.history"
+          defaultMessage="History"
+        />
+      ),
+      children: (
+        <Suspense fallback={null}>
+          <HistoryListPage />
+        </Suspense>
+      )
+    },
+    {
+      key: 'archive',
+      label: (
+        <FormattedMessage
+          id="patient.tab.archive"
+          defaultMessage="Archive"
+        />
+      ),
+      children: (
+        <Suspense fallback={null}>
+          <ArchiveListPage />
+        </Suspense>
+      )
+    },
+    {
+      key: 'bin',
+      label: <FormattedMessage id="patient.tab.bin" defaultMessage="Bin" />,
+      children: (
+        <Suspense fallback={null}>
+          <BinPage />
+        </Suspense>
+      ),
+      'data-testid': 'bin-tab-pane'
+    },
+    {
+      key: 'register',
+      label: (
+        <FormattedMessage
+          id="patient.tab.register"
+          defaultMessage="Register"
+        />
+      ),
+      children: (
+        <Suspense fallback={null}>
+          <RegisterPage />
+        </Suspense>
+      )
+    }
+  ];
+
   return (
-    <div className="h-full flex flex-col">
+    <>
+     <style>{`
+        .patient-management-tabs .ant-tabs-content-holder {
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+        }
+        
+        .patient-management-tabs .ant-tabs-content {
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+        }
+        
+        .patient-management-tabs .ant-tabs-tabpane {
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+        }
+      `}</style>
+    <div className={`${className ? `${className} h-full flex flex-col` : 'h-full flex flex-col'}`}>
       <Tabs
+        data-testid="patient-management-tabs"
         defaultActiveKey="worklist"
         type="line"
-        className="flex-1 h-full"
         tabBarGutter={32}
         destroyInactiveTabPane
-      >
-        <TabPane
-          tab={
-            <FormattedMessage
-              id="patient.tab.worklist"
-              defaultMessage="Worklist"
-            />
-          }
-          key="worklist"
-        >
-          <Suspense fallback={null}>
-            <WorklistPage />
-          </Suspense>
-        </TabPane>
-        <TabPane
-          tab={
-            <FormattedMessage id="patient.tab.output" defaultMessage="Output" />
-          }
-          key="output"
-        >
-          <Suspense fallback={null}>
-            <OutputListPage />
-          </Suspense>
-        </TabPane>
-        <TabPane
-          tab={
-            <FormattedMessage
-              id="patient.tab.history"
-              defaultMessage="History"
-            />
-          }
-          key="history"
-        >
-          <Suspense fallback={null}>
-            <HistoryListPage />
-          </Suspense>
-        </TabPane>
-        <TabPane
-          tab={
-            <FormattedMessage
-              id="patient.tab.archive"
-              defaultMessage="Archive"
-            />
-          }
-          key="archive"
-        >
-          <Suspense fallback={null}>
-            <ArchiveListPage />
-          </Suspense>
-        </TabPane>
-        <TabPane
-          tab={<FormattedMessage id="patient.tab.bin" defaultMessage="Bin" />}
-          key="bin"
-        >
-          <Suspense fallback={null}>
-            <BinPage />
-          </Suspense>
-        </TabPane>
-        <TabPane
-          tab={
-            <FormattedMessage
-              id="patient.tab.register"
-              defaultMessage="Register"
-            />
-          }
-          key="register"
-        >
-          <Suspense fallback={null}>
-            <RegisterPage />
-          </Suspense>
-        </TabPane>
-      </Tabs>
-    </div>
+        items={items}
+        className="patient-management-tabs flex-1 h-full"
+      />
+    </div></>
   );
 };
 

+ 19 - 15
src/pages/patient/components/BinOperationPanel.tsx

@@ -10,7 +10,11 @@ import {
 } from '../../../states/patient/bin/slices/binSlice';
 import { fetchDiskInfoThunk } from '../../../states/patient/bin/slices/binDiskInfoSlice';
 
-const BinOperationPanel: React.FC = () => {
+interface BinOperationPanelProps {
+  className?: string;
+}
+
+const BinOperationPanel: React.FC<BinOperationPanelProps> = ({ className }) => {
   const dispatch = useAppDispatch();
 
   // 从Redux获取状态
@@ -99,21 +103,21 @@ const BinOperationPanel: React.FC = () => {
   };
 
   return (
-    <div className="w-full overflow-auto h-full">
+    <div className={className ? `${className} w-full overflow-auto h-full` : 'w-full overflow-auto h-full'}>
       <SearchPanel />
-      <div className="mt-4">
-        <BinActionPanel
-          totalCapacity={diskInfo?.total || 0}
-          freeSpace={diskInfo?.free || 0}
-          binCapacity={diskInfo?.recycle_bin || 0}
-          totalCapacityStr={diskInfo?.total_str || ''}
-          freeSpaceStr={diskInfo?.free_str || ''}
-          binCapacityStr={diskInfo?.recycle_bin_str || ''}
-          onDelete={handleDelete}
-          onRestore={handleRestore}
-          onEmpty={handleEmpty}
-        />
-      </div>
+
+      <BinActionPanel
+        totalCapacity={diskInfo?.total || 0}
+        freeSpace={diskInfo?.free || 0}
+        binCapacity={diskInfo?.recycle_bin || 0}
+        totalCapacityStr={diskInfo?.total_str || ''}
+        freeSpaceStr={diskInfo?.free_str || ''}
+        binCapacityStr={diskInfo?.recycle_bin_str || ''}
+        onDelete={handleDelete}
+        onRestore={handleRestore}
+        onEmpty={handleEmpty}
+      />
+
     </div>
   );
 };