当 study 的所有体位都已经曝光后,双击 worklist 表格项目时,应该直接进入处理界面(process),而不是进入检查界面(exam)。
src/states/BusinessFlowSlice.ts
状态结构:
interface BusinessFlowState {
currentKey: string; // 当前页面: 'register', 'exam', 'process' 等
lastKey?: string; // 上一个页面
}
setBusinessFlow(key: string)
- 切换业务流程到指定页面src/states/exam/examWorksCacheSlice.ts
addWork(task: Task)
- 添加工作到缓存clearWorks()
- 清空工作缓存src/states/exam/bodyPositionListSlice.ts
setBodyPositions(positions)
- 设置体位数据transformWorksToBodyPositions(works)
- 将 works 转换为体位列表Action | 作用 | 参数 |
---|---|---|
setBusinessFlow |
切换业务流程页面 | key: string ('exam' 或 'process') |
addWork |
添加工作到缓存 | task: Task |
clearWorks |
清空工作缓存 | 无 |
setBodyPositions |
设置体位列表 | positions: BodyPosition[] |
src/domain/patient/worklistToExam.ts
src/domain/patient/worklistToExam.ts
(同文件)src/pages/patient/components/WorklistTable.tsx
onDoubleClick
- 触发 handleRowDoubleClick
回调src/pages/patient/worklist.tsx
handleRowDoubleClick(record: Task)
- 调用 worklistToExam(record)
```
用户双击 worklist 表格行 ↓ WorklistTable.onDoubleClick ↓ worklist.handleRowDoubleClick(record) ↓ worklistToExam(task) ↓ prepareWorksForExam(task) - 获取详细数据 ↓ 检查所有 Views 的 expose_status ├─ 所有体位 === 'Exposed' │ ↓ │ dispatch(clearWorks()) │ dispatch(addWork(updatedTask)) │ transformWorksToBodyPositions([updatedTask]) │ dispatch(setBodyPositions(bodyPositions)) │ dispatch(setBusinessFlow('process')) ← 直接进入处理界面 │ └─ 有未曝光体位
↓
dispatch(clearWorks())
dispatch(addWork(updatedTask))
dispatch(setBusinessFlow('exam')) ← 进入检查界面
## 判断逻辑
### 曝光状态判断
在 `Task` 接口中,每个 task 包含 `Views: dview[]` 数组,每个 `dview` 有 `expose_status` 字段:
```typescript
interface dview {
view_id: string;
expose_status: string; // 'Exposed' 或 'Unexposed'
// ... 其他字段
}
判断条件:
const allExposed = task.Views.every((view) => view.expose_status === 'Exposed');
在 src/states/exam/bodyPositionListSlice.ts
中已有类似的判断逻辑:
const allExposed = bodyPositions.every(
(bp) => bp.dview.expose_status === 'Exposed'
);
const allUnExposed = bodyPositions.every(
(bp) => bp.dview.expose_status === 'Unexposed'
);
文件: src/domain/patient/worklistToExam.ts
const worklistToExam = async (task: Task) => {
const dispatch = store.dispatch;
try {
// 1. 使用公共函数准备数据(获取详细信息)
const [updatedTask] = await prepareWorksForExam(task);
// 2. 判断所有体位是否已曝光
const allExposed = updatedTask.Views.every(
(view) => view.expose_status === 'Exposed'
);
// 3. 清空现有缓存
dispatch(clearWorks());
// 4. 保存更新后的 task 到缓存
dispatch(addWork(updatedTask));
// 5. 根据曝光状态决定跳转目标
if (allExposed) {
// 所有体位已曝光 - 进入处理界面
// 需要先转换为体位列表
const bodyPositions = await transformWorksToBodyPositions([updatedTask]);
dispatch(setBodyPositions(bodyPositions));
dispatch(setBusinessFlow('process'));
} else {
// 有未曝光体位 - 进入检查界面
dispatch(setBusinessFlow('exam'));
}
} catch (error) {
console.error('Error in worklistToExam:', error);
throw error;
}
};
const allExposed = updatedTask.Views.every(
(view) => view.expose_status === 'Exposed'
);
条件分支处理
复用现有逻辑
transformWorksToBodyPositions
转换数据(参考 worklistToProcess
)setBodyPositions
设置体位数据worklistToProcess
逻辑every()
对空数组返回 true,需要特殊处理)// 需要额外检查 Views 是否为空
const allExposed =
updatedTask.Views.length > 0 &&
updatedTask.Views.every((view) => view.expose_status === 'Exposed');
根据代码搜索结果,expose_status
的可能值:
'Exposed'
- 已曝光'Unexposed'
- 未曝光需要确保判断逻辑只认为值为 'Exposed'
的才算已曝光。
如果 fetchTaskDetails
失败或返回异常数据,原有的错误处理机制会捕获并抛出错误。
文件路径 | 作用 | 修改内容 |
---|---|---|
src/domain/patient/worklistToExam.ts |
Worklist 跳转逻辑 | 需要修改: 添加曝光状态判断 |
src/states/BusinessFlowSlice.ts |
业务流程管理 | 无需修改 |
src/states/exam/examWorksCacheSlice.ts |
工作缓存 | 无需修改 |
src/states/exam/bodyPositionListSlice.ts |
体位列表管理 | 无需修改,可参考判断逻辑 |
src/pages/patient/worklist.tsx |
Worklist 页面 | 无需修改 |
src/pages/patient/components/WorklistTable.tsx |
表格组件 | 无需修改 |
src/domain/work.ts |
Task 数据类型定义 | 无需修改 |
src/domain/dview.ts |
dview 数据类型定义 | 无需修改 |
worklistToExam
函数,添加曝光状态判断src/states/exam/bodyPositionListSlice.ts:147-154
src/domain/patient/worklistToExam.ts:69-113
(worklistToProcess)src/states/exam/bodyPositionListSlice.ts
中的 transformWorksToBodyPositions
prepareWorksForExam
返回的数据包含完整的 Views 信息transformWorksToBodyPositions
是异步操作,需要等待完成后再跳转