本文档记录了APR(自动程序检索)参数在切换体型和工作位后同步到设备的实现。
在之前的实现中,APR参数管理存在不一致的问题:
这导致用户在UI上看到的参数已更新,但设备实际使用的仍是旧参数,可能造成曝光参数错误。
详细的需求分析见:APR参数管理流程需求文档
采用方案1:统一在middleware中处理
在 aprMiddleware
中:
setBodysize
和 setWorkstation
actiongetAprExposureParams
获取新的APR参数setAprConfig
更新Redux store(UI自动响应)SetAPR
下发新参数到设备文件: src/states/exam/aprSlice.ts
修改的代码段: aprMiddleware
中间件
const aprMiddleware: Middleware = (store) => (next) => (action: any) => {
const result = next(action);
if (
action.type === aprSlice.actions.setBodysize.type ||
action.type === aprSlice.actions.setWorkstation.type
) {
// ... 获取参数
if (!!patientSize) {
getAprExposureParams(id, workStationId, patientSize)
.then((data) => {
if (data) {
store.dispatch(setAprConfig(data));
// ❌ 缺少:没有调用 SetAPR 下发到设备
}
})
.catch((error) => {
console.error('Error fetching APR exposure parameters:', error);
});
}
}
return result;
};
const aprMiddleware: Middleware = (store) => (next) => (action: any) => {
const result = next(action);
if (
action.type === aprSlice.actions.setBodysize.type ||
action.type === aprSlice.actions.setWorkstation.type
) {
// ... 获取参数
if (!!patientSize) {
getAprExposureParams(id, workStationId, patientSize)
.then((data) => {
if (data) {
// 1. 更新 Redux store
store.dispatch(setAprConfig(data));
// 2. ✅ 新增:下发到设备
const currentState = store.getState();
const selectedBodyPosition =
currentState.bodyPositionList.selectedBodyPosition;
if (selectedBodyPosition) {
// 构建设备参数
const reqParam = JSON.stringify({
P0: {
FOCUS: '0',
TECHMODE: '0',
AECFIELD: '101',
AECFILM: '0',
AECDENSITY: '0',
KV: data.kV.toString(),
MA: data.mA.toString(),
MS: data.ms.toString(),
MAS: data.mAs.toString(),
KV2: '0.0',
MA2: '0.0',
MS2: '0.0',
DOSE: '0.0',
FILTER: 'null',
TUBELOAD: '0.0',
WORKSTATION: selectedBodyPosition.work_station_id,
},
});
// 调用 SetAPR 下发到设备
SetAPR(reqParam)
.then(() => {
console.log(
'[aprMiddleware] SetAPR called successfully after body size/workstation change'
);
})
.catch((error) => {
console.error(
'[aprMiddleware] Error calling SetAPR after body size/workstation change:',
error
);
});
} else {
console.warn(
'[aprMiddleware] No selected body position found, skipping SetAPR call'
);
}
}
})
.catch((error) => {
console.error('Error fetching APR exposure parameters:', error);
});
}
}
return result;
};
用户切换体型/工作位
↓
dispatch(setBodysize/setWorkstation)
↓
aprMiddleware 拦截
↓
getAprExposureParams(id, workStationId, patientSize)
↓
获取到新的 APR 参数
↓
store.dispatch(setAprConfig(data)) ← 更新 Redux store
↓
UI 自动更新显示新参数
↓
获取 selectedBodyPosition 的 work_station_id
↓
构建 SetAPR 所需参数
↓
SetAPR(reqParam) ← 下发到设备
↓
设备参数更新完成
{
P0: {
FOCUS: "0", // 焦点
TECHMODE: "0", // 技术模式
AECFIELD: "101", // AEC场
AECFILM: "0", // AEC胶片
AECDENSITY: "0", // AEC密度
KV: string, // 千伏值(从新获取的APR参数)
MA: string, // 毫安值(从新获取的APR参数)
MS: string, // 毫秒值(从新获取的APR参数)
MAS: string, // 毫安秒值(从新获取的APR参数)
KV2: "0.0", // 第二次曝光千伏
MA2: "0.0", // 第二次曝光毫安
MS2: "0.0", // 第二次曝光毫秒
DOSE: "0.0", // 剂量
FILTER: "null", // 滤过器
TUBELOAD: "0.0", // 管负荷
WORKSTATION: number // 工作位ID(从selectedBodyPosition获取)
}
}
getAprExposureParams
的 catch 块中捕获并记录错误SetAPR
的 catch 块中捕获并记录错误selectedBodyPosition
不存在,记录警告并跳过 SetAPR 调用添加了以下关键日志点:
[aprMiddleware] SetAPR called successfully...
- SetAPR 成功调用[aprMiddleware] Error calling SetAPR...
- SetAPR 调用失败[aprMiddleware] No selected body position found...
- 缺少体位信息警告场景 | 获取APR | 更新UI | 下发设备 | 状态 |
---|---|---|---|---|
更改体位 | N/A(使用已有) | ✅ | ✅ | 已完整实现 |
更新体型 | ✅ | ✅ | ✅ | 已修复 |
更改工作位 | ✅ | ✅ | ✅ | 已修复 |
场景1:切换体型
[aprMiddleware] SetAPR called successfully...
场景2:切换工作位
[aprMiddleware] SetAPR called successfully...
场景3:无体位选择时切换体型
[aprMiddleware] No selected body position found...
如果用户快速连续切换体型或工作位,可能导致多个 SetAPR 调用:
当前没有显示加载状态:
isPending
状态标识isPending
字段但未使用,后续可以集成如果 SetAPR 调用失败,没有重试机制:
src/states/exam/aprSlice.ts
- APR状态管理和中间件src/API/exam/APRActions.ts
- APR相关API调用src/states/exam/bodyPositionListSlice.ts
- 体位状态管理src/pages/exam/ContentAreaLarge.tsx
- UI组件(体型/工作位选择器)实现日期: 2025-10-08
实现人: Development Team
审核状态: 待测试验证