RIS自动同步功能用于定期从RIS系统同步患者和检查数据到本地系统,确保worklist中显示最新的检查任务信息。
自动同步机制
配置管理
数据同步
- Pages层
└── src/pages/patient/worklist.tsx (主页面)
- Components层
├── src/components/RisSyncStatus.tsx (同步状态显示)
└── src/pages/patient/components/ActionPanel.tsx (操作面板)
- Hooks层
└── src/hooks/useRisAutoSync.ts (自动同步Hook)
- Services层
└── src/services/risSync/RisSyncService.ts (同步服务)
- Redux层
└── src/states/patient/ris/risSyncSlice.ts (状态管理)
- API层
├── src/API/patient/risActions.ts (RIS API接口)
└── src/API/patient/workActions.ts (工作列表API)
// RisSyncService类
- startAutoSync(): 启动自动同步
- stopAutoSync(): 停止自动同步
- syncOnce(): 执行单次同步
- updateConfig(): 更新配置
// useRisAutoSync Hook
- 管理同步生命周期
- 处理页面切换逻辑
// risSyncSlice
- setSyncConfig: 设置同步配置
- setSyncStatus: 设置同步状态
- setLastSyncTime: 设置最后同步时间
- setSyncError: 设置同步错误
sequenceDiagram
participant User
participant Worklist
participant Hook as useRisAutoSync
participant Service as RisSyncService
participant API
participant Redux
User->>Worklist: 进入worklist页面
Worklist->>Hook: 初始化自动同步
Hook->>API: getRisConfig()
API-->>Hook: 返回配置
Hook->>Redux: 保存配置
alt 自动同步启用
Hook->>Service: startAutoSync(interval)
loop 每N分钟
Service->>API: syncRis()
API-->>Service: 同步结果
Service->>API: fetchTaskList()
API-->>Service: 任务列表
Service->>Redux: 更新数据
Redux-->>Worklist: 刷新显示
end
end
User->>Worklist: 手动同步
Worklist->>Service: syncOnce()
Service->>API: syncRis()
API-->>Service: 同步结果
Service->>API: fetchTaskList()
API-->>Service: 任务列表
Service->>Redux: 更新数据
User->>Worklist: 离开页面
Worklist->>Hook: 清理
Hook->>Service: stopAutoSync()
graph TD
A[RIS系统] -->|API调用| B[syncRis接口]
B --> C[同步数据到本地]
C --> D[fetchTaskList接口]
D --> E[获取混合数据]
E --> F[Redux Store更新]
F --> G[Worklist组件]
G --> H[UI展示]
I[配置API] --> J[getRisConfig]
J --> K[Redux配置状态]
K --> L[自动同步控制]
L --> B
interface RisSyncState {
// 配置信息
config: {
mwl_enable: boolean; // RIS是否启用
mwl_refresh_enable: boolean; // 自动刷新是否启用
mwl_refresh_interval: number; // 刷新间隔(分钟)
} | null;
// 同步状态
syncStatus: 'idle' | 'syncing' | 'success' | 'error';
lastSyncTime: string | null; // 最后同步时间
nextSyncTime: string | null; // 下次同步时间
syncCount: number; // 同步条目数
// 错误信息
error: {
message: string;
timestamp: string;
} | null;
// 控制状态
isAutoSyncActive: boolean; // 自动同步是否激活
isManuallySyncing: boolean; // 是否正在手动同步
}
interface Task {
// 基础字段
StudyID: string;
PatientID: string;
PatientName: string;
AccessionNumber: string;
// RIS特有字段
entry_id?: string; // RIS条目ID
scheduled?: { // 调度信息
scheduled_ae_title: string;
scheduled_performing_physician_name: string;
scheduled_procedure_step_id: string;
};
protocol_code?: Array<{ // 协议代码
code_value: string;
code_meaning: string;
}>;
// 其他字段...
}
flowchart TD
Start[用户进入worklist页面] --> Check{检查currentKey}
Check -->|是worklist| InitSync[初始化同步]
Check -->|否| NoSync[不启动同步]
InitSync --> GetConfig[获取RIS配置]
GetConfig --> CheckEnable{检查是否启用}
CheckEnable -->|启用| SetupTimer[设置定时器]
CheckEnable -->|禁用| ShowDisabled[显示禁用状态]
SetupTimer --> FirstSync[立即执行首次同步]
FirstSync --> WaitInterval[等待间隔时间]
WaitInterval --> AutoSync[执行自动同步]
AutoSync --> UpdateUI[更新界面]
UpdateUI --> WaitInterval
ShowDisabled --> End[结束]
NoSync --> End
flowchart TD
SyncStart[开始同步] --> SetStatus[设置同步中状态]
SetStatus --> GetTimeRange[获取时间范围]
GetTimeRange --> CallSyncAPI[调用syncRis API]
CallSyncAPI -->|成功| SaveCount[保存同步数量]
CallSyncAPI -->|失败| HandleError[处理错误]
SaveCount --> FetchList[调用fetchTaskList]
FetchList -->|成功| UpdateStore[更新Redux Store]
FetchList -->|失败| HandleError
UpdateStore --> SetSuccess[设置成功状态]
HandleError --> SetError[设置错误状态]
SetSuccess --> UpdateTime[更新同步时间]
SetError --> LogError[记录错误日志]
UpdateTime --> SyncEnd[同步结束]
LogError --> SyncEnd
前置条件:
- RIS配置已启用自动同步
- 同步间隔设置为1分钟
测试步骤:
1. 进入worklist页面
2. 观察是否立即触发首次同步
3. 等待1分钟
4. 验证是否自动触发下次同步
预期结果:
- 首次同步成功执行
- 每分钟自动同步一次
- UI显示最新同步时间
测试步骤:
1. 进入worklist页面
2. 点击手动同步按钮
3. 观察同步状态变化
预期结果:
- 按钮显示加载状态
- 同步完成后刷新列表
- 显示同步成功提示
测试步骤:
1. 在worklist页面启动自动同步
2. 切换到其他页面
3. 等待同步间隔时间
4. 返回worklist页面
预期结果:
- 离开页面时停止同步
- 其他页面不触发同步
- 返回时重新启动同步
问题:定时器未正确清理 解决:
useEffect(() => {
const timer = setInterval(sync, interval);
return () => clearInterval(timer); // 清理定时器
}, []);
问题:手动和自动同步同时触发 解决:使用状态锁防止并发
if (isSyncing) {
message.warning('正在同步中,请稍后再试');
return;
}
问题:切换页面后同步状态重置 解决:将同步状态存储在Redux中持久化
问题:单次失败导致长时间无数据 解决:实现指数退避重试机制
const retryWithBackoff = async (fn, maxRetries = 3) => {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;
await sleep(Math.pow(2, i) * 1000);
}
}
};
创建基础结构 (Day 1)
集成到worklist (Day 2)
完善功能 (Day 3)
测试验证 (Day 4)
// 默认配置
const DEFAULT_CONFIG = {
mwl_enable: true,
mwl_refresh_enable: true,
mwl_refresh_interval: 5, // 默认5分钟
};
// 同步时间范围(当天)
const getSyncTimeRange = () => {
const now = new Date();
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
return {
start_time: startOfDay.toISOString().replace('Z', '+08:00'),
end_time: endOfDay.toISOString().replace('Z', '+08:00'),
};
};
graph LR
A[worklist.tsx] --> B[useRisAutoSync]
B --> C[RisSyncService]
C --> D[risActions API]
C --> E[workActions API]
B --> F[risSyncSlice]
F --> G[Redux Store]
A --> H[RisSyncStatus组件]
H --> F
文档版本:1.0.0 更新日期:2025-01-31 作者:系统架构师