# 双击RIS条目后追加体位功能设计 ## 需求整理 ### 功能需求 - 在工作列表(worklist)中双击RIS条目时,先执行保存到本地的操作 - 保存成功后,自动打开追加体位对话框 - 用户可以在对话框中选择要追加的体位 - 确认后将选中的体位追加到当前检查中 ### 用户场景 1. 用户在工作列表中浏览RIS数据 2. 双击某个RIS条目 3. 系统自动保存该RIS数据到本地 4. 保存成功后弹出追加体位对话框 5. 用户选择需要追加的体位 6. 确认追加,体位添加到检查中 ### 业务规则 - 只有RIS数据(entry_id存在)才触发此流程 - 保存失败时不打开追加对话框 - 追加体位需要基于当前选中的体位信息 - 追加操作失败时给出相应提示 ## 参与者 ### 核心组件 - **WorklistPage** (`src/pages/patient/worklist.tsx`): 工作列表页面,处理双击事件 - **AppendViewModal** (`src/pages/exam/components/AppendViewModal.tsx`): 追加体位对话框组件 - **BodyPositionList** (`src/pages/exam/components/BodyPositionList.tsx`): 体位列表组件(参考追加体位按钮实现) ### 业务逻辑 - **saveRisData** (`src/domain/patient/risSaveLogic.ts`): RIS数据保存逻辑 - **saveRisBatch** (`src/API/patient/risActions.ts`): RIS批量保存API - **appendViewsThunk** (`src/states/exam/appendViewSlice.ts`): 追加体位Redux异步操作 ### Redux状态 - `selectedBodyPosition`: 当前选中的体位信息 - `selectedViews`: 用户选中的待追加视图 - `viewSelection`: 视图选择状态管理 ### 辅助组件 - **BodyPositionFilter**: 身体部位过滤器 - **RegisterAvailableList**: 可选体位列表 - **SelectedProtocolList**: 已选体位列表 ## 业务链路 ``` 用户双击RIS条目 ↓ WorklistPage.handleRowDoubleClick(record) ↓ (判断为RIS数据) 调用 saveRisData(record.entry_id, onSuccessCallback) ↓ (异步保存) saveRisSingle(entryId, []) → API调用 ↓ (保存成功) 显示成功弹框 + 执行onSuccessCallback ↓ 打开 AppendViewModal 追加体位对话框 ↓ 用户选择体位 → 确认追加 ↓ appendViewsThunk() → 追加体位到检查 ↓ (追加成功) 自动调用 worklistToExam() 进入检查页面 ``` ## 数据流 ### 流程图 (Mermaid) ```mermaid sequenceDiagram participant U as 用户 participant W as WorklistPage participant S as saveRisData participant A as AppendViewModal participant T as appendViewsThunk U->>W: 双击RIS条目 W->>S: saveRisData(entryId, callback) S->>S: 调用saveRisSingle(entryId, []) S->>W: 保存成功回调 + study信息 W->>A: 打开模态框 + 传递study信息 A->>U: 显示追加体位界面 U->>A: 选择体位 U->>A: 确认追加 A->>T: appendViewsThunk(study_id, views) T->>A: 追加成功 A->>W: 调用onSuccess回调 W->>W: 创建Task对象 + 调用worklistToExam() W->>U: 进入检查页面 ``` ### 数据传递链路 1. **双击事件**: `record: Task` → `handleRowDoubleClick` → `saveRisData(entryId, onSuccess)` 2. **保存成功回调**: `onSuccess` 函数执行 → 设置 `isAppendModalOpen = true` 3. **模态框初始化**: `selectedBodyPosition` → `setCurrentBodyPart(bodyPartId)` 4. **用户选择**: `selectedViews` 数组收集用户选择的体位 5. **确认追加**: `selectedViews + study_id + currentWork` → `appendViewsThunk` ### 输入数据 - `record` (Task): 双击的RIS条目数据,包含 `entry_id` 用于保存 - `selectedBodyPosition`: 当前检查的体位信息,用于初始化追加模态框 ### 输出数据 - 保存成功的RIS数据本地化 - 新追加的体位列表更新到当前检查 ## 实现方案 ### 方案选择 采用方案1: 修改saveRisData接受成功回调参数,在保存成功后执行回调打开模态框。 ### 代码修改点 1. **risSaveLogic.ts**: 修改 `saveRisData` 函数使用 `saveRisSingle` API,返回保存的study信息 2. **AppendViewModal.tsx**: 添加 `studyId` 和 `currentWork` 参数,支持worklist页面调用 3. **worklist.tsx**: 添加 `AppendViewModal` 组件和相关状态管理,传递study信息 4. **worklist.tsx**: 修改 `handleRowDoubleClick` 使用回调接收study信息并打开模态框 ### 状态管理 在WorklistPage中添加: - `isAppendModalOpen: boolean` 状态控制模态框显示 - `currentStudy: any` 状态存储当前保存的study信息 - 导入 `AppendViewModal` 组件 - 处理模态框关闭逻辑,清空study信息 ### 问题修复 **问题**: 弹出的对话框中点击"追加"按钮提示"未找到当前检查信息" **原因**: AppendViewModal依赖Redux状态 `selectedBodyPosition`,但worklist页面没有设置此状态 **解决方案**: - 修改AppendViewModal支持接收外部传入的 `studyId` 和 `currentWork` 参数 - 在worklist页面保存RIS数据成功后,传递study信息给AppendViewModal - AppendViewModal优先使用传入的参数,其次使用Redux状态