高级处理双端保存方案.md 6.6 KB

高级处理双端保存方案

📋 需求说明

在高级处理(SliderAdjustmentPanel)中实现双端保存机制

核心目标

在保存参数时调用后端API保存参数并重建DCM

具体要求

  • 用户通过滑动条调节图像参数时,仅更新前端预览
  • 用户点击"保存参数"按钮或执行特定操作时,触发后端保存
  • 调用 rebuildDcm API 进行异步保存和重建DCM
  • 实现前端预览 + 后端持久化的双端同步机制

🔍 当前实现分析

1. 当前代码流程

文件位置: src/pages/view/components/SliderAdjustmentPanel.tsx

用户滑动参数
   ↓
handleParameterChange (更新Redux状态)
   ↓
debouncedPreview / debouncedWASMPreview (防抖500ms/300ms)
   ↓
更新 viewer URL (触发图像重新渲染)
   ↓
✅ 预览更新完成
   
❌ 没有调用后端保存 API,也不需要

2. 现有的保存机制

目前只有以下1种情况会调用 rebuildDcm:

  1. 手动保存 (handleSave) - 用户点击"保存参数"按钮

3. 相关API

文件位置: src/API/imageActions.ts

/**
 * 重建dcm(保存应用增强参数后的dcm)
 */
export const rebuildDcm = async (
  sopInstanceUid: string,
  params: RebuildDcmRequest
): Promise<RebuildDcmResponse>

interface RebuildDcmRequest {
  contrast: number;    // 增益
  detail: number;      // 细节
  latitude: number;    // 动态范围
  noise: number;       // 噪声模式
  ww_coef: number;     // 对比度
  wl_coef: number;     // 亮度
}

🔄 参数变化触发场景

参数变化可由多种用户操作和系统行为触发,需要区分哪些场景需要保存到后端:

场景1: 初始化加载 ❌ 不保存

触发时机: 组件挂载时自动执行

useEffect(() => {
  // 从后端加载当前图像的参数
  dispatch(loadImageProcessingParams(sopInstanceUid));
}, [dispatch]);

行为:

  • 从后端读取已保存的参数
  • 更新 Redux 状态
  • 设置 isInitialLoad = true 标志
  • 不触发保存(避免循环调用)

场景2: 用户滑动滑块 ❌ 不保存

触发时机: 用户拖动任一参数滑块

handleParameterChange('contrast', 5.0)  // 增益
handleParameterChange('detail', 8.0)    // 细节
handleParameterChange('latitude', 6.0)  // 动态范围
handleParameterChange('noise', 4.0)     // 噪声模式
handleParameterChange('brightness', 1.2) // 对比度
handleParameterChange('sharpness', -0.5) // 亮度

行为:

  • 更新 Redux 状态
  • 设置 isInitialLoad = false
  • 仅触发防抖预览
  • 更新前端预览(仅前端状态,不保存到后端)

场景3: 切换风格 ❌ 不保存

触发时机: 用户在下拉框中选择风格

handleStyleChange('高对比')  // 均衡 | 高对比 | 锐组织 | 骨骼

行为:

  • 应用风格预设参数
  • 更新 Redux 状态
  • 设置 isInitialLoad = false
  • 仅更新前端预览(参数已批量更新,不保存到后端)

场景4: 重置参数 ❌ 不保存

触发时机: 用户点击"重置参数"按钮

handleReset()

行为:

  • 重置为当前风格的默认参数
  • 更新 Redux 状态
  • 设置 isInitialLoad = false
  • 仅更新前端预览(参数已批量更新,不保存到后端)

场景5: 手动保存 ✅ 立即保存

触发时机: 用户点击"保存参数"按钮

handleSave()

行为:

  • 使用当前 Redux 中的参数
  • 立即调用 saveProcessingParams触发 rebuildDcm
  • 不更新预览(仅保存)

场景6: 算法/LUT切换 ⚠️ 前端状态

触发时机: 用户切换算法或LUT

handleAlgorithmChange('算法A')
handleLUTChange('LUT1')

行为:

  • 仅更新前端 Redux 状态
  • 不调用后端API(算法和LUT是前端渲染配置)

🎯 实现方案

目标流程

用户滑动参数
   ↓
handleParameterChange (更新Redux状态)
   ↓
debouncedPreview / debouncedWASMPreview (防抖)
   ↓
更新 viewer URL (触发图像重新渲染)
   ↓
✅ 预览更新完成(仅前端状态)

保存时机

重建DCM仅在以下情况调用:

  1. 手动保存: 用户点击"保存参数"按钮时,保存当前参数到后端并重建DCM

实现步骤

无需修改 debouncedPreviewdebouncedWASMPreview 函数

  • 保持原有逻辑,仅用于前端预览更新
  • 不添加自动保存调用

⚙️ 技术细节

1. 防抖机制

  • 传统模式: 500ms 防抖延迟
  • WASM模式: 300ms 防抖延迟
  • 仅用于平滑预览更新,不涉及API调用

2. 保存参数映射

Redux State → API Request
------------------------------
contrast    → contrast
detail      → detail
latitude    → latitude
noise       → noise
brightness  → ww_coef
sharpness   → wl_coef

3. 保存错误处理策略

try {
  await rebuildDcm(...);  // 保存到后端
  console.log('✅ 参数已保存到后端');
} catch (saveError) {
  console.error('⚠️ 保存参数失败:', saveError);
  // 显示错误提示,但不影响其他操作
}

🔒 注意事项

1. 性能考虑

  • ✅ 前端预览响应迅速,无API调用阻塞
  • ✅ 保存操作异步执行,不影响UI响应
  • ✅ 防抖机制确保预览流畅

2. 用户体验

  • ✅ 滑动参数时即时预览,无延迟
  • ✅ 需要时手动保存,控制数据持久化
  • ✅ 保存状态明确反馈

3. 与现有功能的兼容性

  • ✅ 保留"保存参数"按钮(立即保存)
  • ✅ 风格切换和重置参数仅更新前端预览
  • ✅ 不影响初始加载逻辑

4. 两种模式的处理

  • 传统模式: 前端预览 + 按需保存到后端
  • WASM模式: 本地WASM预览 + 按需保存到后端

📝 测试清单

  • 滑动参数时,仅更新预览,不调用后端API
  • 防抖生效,快速滑动时预览流畅
  • 传统模式下预览正常
  • WASM模式下预览正常
  • 手动保存按钮可用,点击后调用rebuildDcm
  • 保存成功时,控制台显示"参数已保存到后端"
  • 保存失败时,显示错误提示
  • 切换风格仅更新前端预览,不调用后端API
  • 重置参数仅更新前端预览,不调用后端API

🔧 相关文件

  • 组件: src/pages/view/components/SliderAdjustmentPanel.tsx
  • API: src/API/imageActions.ts
  • Redux: src/states/view/sliderAdjustmentPanelSlice.ts
  • 类型: src/types/imageProcessing.ts

📚 相关文档