# DcmCell 胶片间图像显示错误 Bug 分析 ## 问题描述 用户在胶片1上拖拽一个图像,切换到胶片2时,这个图像也会显示在胶片2上。 ## 根本原因分析 ### 1. 共享渲染引擎问题 ```typescript // 所有 DcmCell 实例共享同一个渲染引擎 const engineId = 'myRenderingEngineForPrint'; let engine: RenderingEngine | null = cornerstone.getRenderingEngines()?.find(en => en.id === engineId) || null; ``` ### 2. viewport ID 生成不唯一 ```typescript // 当前的 viewport ID 生成方式 const viewportId = useMemo(() => `stackViewport-${imageId}-${uuidv4()}`, []); ``` **问题**: - 在组件初始化时,`imageId` 可能为 `null` 或相同值 - 这导致不同胶片的不同格子可能生成相同的 viewport ID 前缀 - `uuidv4()` 只在组件挂载时生成一次,但由于依赖数组为空 `[]`,无法保证真正的唯一性 ### 3. 渲染引擎状态污染 - 共享的渲染引擎在不同胶片间切换时保持了之前的状态 - 当新的 DcmCell 组件挂载时,可能会复用已有的 viewport 或产生冲突 ## 解决方案 ### 1. 改进 viewport ID 生成策略 ```typescript // 使用胶片ID + 格子索引 + UUID 确保唯一性 const viewportId = useMemo(() => `stackViewport-${currentFilm.id}-${indexOfCell}-${uuidv4()}`, [currentFilm.id, indexOfCell] ); ``` ### 2. 分离渲染引擎或改进清理机制 ```typescript // 方案A: 每个胶片使用独立的渲染引擎 const engineId = `renderingEngine-${currentFilm.id}`; // 方案B: 改进现有引擎的 viewport 清理机制 // 在组件卸载时确保完全清理 viewport ``` ### 3. 加强状态隔离 - 确保每个 DcmCell 的状态完全独立 - 在 imageId 变化时正确清理之前的图像状态 - 避免在不同组件间共享 viewport 实例 ### 4. 优化 useEffect 依赖 ```typescript // 移除 currentImageId 从依赖数组,避免无限循环 useEffect(() => { // ... }, [imageId, stackViewport]); ``` ## 修复步骤 1. 修改 viewport ID 生成逻辑,确保唯一性 2. 改进组件卸载时的清理机制 3. 优化 useEffect 依赖数组 4. 测试胶片间切换的图像隔离性