# PACS节点拉取和显示功能实现规划 ## 1. 参与者清单(从粗到细) ### 1.1 页面层级 - **HistoryList.tsx** - 历史清单页面,包含操作面板切换逻辑 - **SendPanel.tsx** - 发送面板组件(需要改造) ### 1.2 组件层级 - **ActionPanel.tsx** - 操作按钮面板,包含发送按钮 - `handleSend()` 方法 - 触发切换到发送面板 ### 1.3 状态管理层级 - **historyPanelSwitchSlice.ts** - 面板切换状态管理 - `switchToSendPanel` action - 切换到发送面板 - `switchToOperationPanel` action - 切换回操作面板 - **pacsNodeSlice.ts** - PACS节点状态管理(需要创建) - `pacsNodes` state - 存储PACS节点列表 - `loading` state - 加载状态 - `error` state - 错误信息 - `selectedNodeIds` state - 选中的节点ID列表 - `fetchPacsNodesThunk` - 异步获取节点的thunk - `toggleNodeSelection` action - 切换节点选中状态 - `selectAllNodes` action - 全选节点 - `deselectAllNodes` action - 取消全选 ### 1.4 API层级 - **pacsNodeActions.ts** - PACS节点相关API - `getPacsNodeList()` - 获取PACS节点列表(已存在) - 相关类型定义: - `PacsNode` - 节点数据结构 - `PacsNodeListResponse` - API响应结构 ### 1.5 Store配置 - **store.ts** - Redux store配置(需要添加新的reducer) ## 2. Todo List ### 需要创建的文件 - [ ] `src/states/output/pacsNodeSlice.ts` - PACS节点状态管理slice ### 需要修改的文件 - [ ] `src/pages/output/SendPanel.tsx` - 改造为动态加载PACS节点列表 - [ ] `src/states/store.ts` - 注册新的pacsNode reducer ### 需要实现的功能 - [ ] 创建Redux slice管理PACS节点状态 - [ ] 实现异步thunk获取PACS节点 - [ ] 改造SendPanel组件,在挂载时自动拉取数据 - [ ] 实现节点的选中/取消选中功能 - [ ] 显示加载状态和错误处理 - [ ] 实现发送按钮的实际功能(连接发送API) ## 3. 交互流程(泳道图) ``` 用户 ActionPanel historyPanelSwitchSlice SendPanel pacsNodeSlice API │ │ │ │ │ │ │─点击发送按钮─────>│ │ │ │ │ │ │ │ │ │ │ │ │─dispatch(switchToSendPanel)─>│ │ │ │ │ │ │ │ │ │ │ │ │─更新currentPanel─>│ │ │ │ │ │ 为'SendPanel' │ │ │ │ │ │ │ │ │ │ │ │ │─组件挂载────────>│ │ │ │ │ │ useEffect │ │ │ │ │ │ │ │ │ │ │ │ │─dispatch(fetchPacsNodesThunk)─>│ │ │ │ │ │ │ │ │ │ │ │ │─调用getPacsNodeList() │ │ │ │ │ │ │ │ │ │ │<─返回节点列表───│ │ │ │ │ │ │ │ │ │ │<─更新nodes状态───│ │ │ │ │ │ loading=false │ │ │ │ │ │ │ │ │<─────显示节点列表────────────────────────────────────────────────│ │ │ │ │ │ │ │ │ │─选择节点─────────────────────────────────────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │─dispatch(toggleNodeSelection)─────>│ │ │ │ │ │ │ │ │ │ │ │<─更新selectedNodeIds───────────────│ │ │ │ │ │ │ │ │<─────更新UI(复选框选中状态)────────────────────────────────────│ │ │ │ │ │ │ │ │ │─点击发送图像按钮──────────────────────────────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │─调用发送API────────────────────────>│ │ │ │ │ (传入selectedNodeIds) │ │ │ │ │ │ │ │<─────显示发送结果────────────────────────────────────────────────│<─────────────────────────────────────│ │ │ │ │ │ │ ``` ## 4. 数据流 ### 4.1 PACS节点获取流程 ``` 用户操作 → dispatch(switchToSendPanel) → 面板切换 → SendPanel挂载 → dispatch(fetchPacsNodesThunk) → 调用getPacsNodeList() API → 更新Redux state (pacsNodes, loading, error) → 组件重新渲染 → 显示节点列表 ``` ### 4.2 节点选择流程 ``` 用户点击复选框 → dispatch(toggleNodeSelection(nodeId)) → 更新selectedNodeIds数组 → 组件重新渲染 → 更新复选框状态 ``` ### 4.3 发送图像流程 ``` 用户点击发送按钮 → 验证是否选中节点 → 调用发送API(selectedNodeIds, imageData) → 显示发送进度/结果 → 成功后可选返回操作面板 ``` ## 5. 数据结构 ### 5.1 Redux State Structure ```typescript // pacsNodeSlice state interface PacsNodeState { nodes: PacsNode[]; // PACS节点列表 loading: boolean; // 加载状态 error: string | null; // 错误信息 selectedNodeIds: number[]; // 选中的节点ID列表 } // PacsNode (已存在于pacsNodeActions.ts) interface PacsNode { id: number; name: string; type: string; address: string; port: number; aet: string; aec: string; is_enabled: boolean; is_default: boolean; params?: Record; } ``` ### 5.2 API Response Structure (已存在) ```typescript interface PacsNodeListResponse { code: string; description: string; solution: string; data: { '@type': string; scp: PacsNode[]; }; } ``` ## 6. 执行流程(从起点开始) ### 起点:用户点击"发送"按钮 #### 第一步:触发面板切换 1. 用户在 HistoryList 页面点击 ActionPanel 中的"发送"按钮 2. 调用 `handleSend()` 方法 3. dispatch `switchToSendPanel()` action 4. historyPanelSwitchSlice 更新 `currentPanel` 为 'SendPanel' 5. HistoryList 组件根据状态渲染 SendPanel #### 第二步:SendPanel 初始化 1. SendPanel 组件挂载 2. useEffect 触发,dispatch `fetchPacsNodesThunk()` 3. 设置 loading 为 true #### 第三步:获取PACS节点数据 1. thunk 调用 `getPacsNodeList()` API 2. API 返回节点列表数据 3. thunk fulfilled,更新 Redux state: - nodes: 返回的PACS节点数组 - loading: false - error: null #### 第四步:渲染节点列表 1. SendPanel 从 Redux state 读取 nodes 和 loading 2. 显示加载状态(如果 loading 为 true) 3. 遍历 nodes 数组,为每个节点渲染一个 Checkbox 项 4. 根据 selectedNodeIds 设置复选框的选中状态 #### 第五步:用户选择节点 1. 用户点击某个节点的复选框 2. dispatch `toggleNodeSelection(nodeId)` action 3. Redux state 更新 selectedNodeIds 4. 组件重新渲染,更新复选框状态 #### 第六步:发送图像 1. 用户点击"发送图像"按钮 2. 验证是否选中了至少一个节点 3. 调用发送图像的API(传入 selectedNodeIds 和图像数据) 4. 显示发送进度或结果 5. 成功后可选择返回操作面板 ## 7. 错误处理和边界情况 ### 7.1 API错误处理 - 网络请求失败时显示错误信息 - 提供重试按钮 ### 7.2 空数据处理 - 如果没有可用的PACS节点,显示提示信息 ### 7.3 选择验证 - 发送前验证是否至少选中一个节点 - 未选中时显示警告提示 ## 8. 后续优化建议 1. **添加搜索和过滤功能** - 当节点列表很长时方便查找 2. **记住上次选择** - 使用 localStorage 保存用户的常用节点选择 3. **批量操作** - 添加全选/取消全选功能 4. **节点状态指示** - 显示节点是否在线/可用 5. **发送进度** - 显示发送任务的进度条 6. **发送历史** - 记录发送历史便于追溯 ## 实现日期 2025-01-10