|
|
@@ -0,0 +1,132 @@
|
|
|
+// ViewportContainer.jsx
|
|
|
+import React, { useRef, useEffect, useState, useMemo } from 'react';
|
|
|
+import * as cornerstone from '@cornerstonejs/core';
|
|
|
+import {
|
|
|
+ RenderingEngine,
|
|
|
+ Enums
|
|
|
+} from '@cornerstonejs/core';
|
|
|
+import { v4 as uuidv4 } from 'uuid';
|
|
|
+import { getDcmImageUrl } from '@/API/bodyPosition';
|
|
|
+// import { dicomWebImageLoader } from '@cornerstonejs/dicom-web-image-loader';
|
|
|
+
|
|
|
+// // 初始化图像加载器(关键:必须提前注册)
|
|
|
+// const initImageLoader = () => {
|
|
|
+// // 注册 DICOM Web 加载器(根据实际场景选择加载器)
|
|
|
+// cornerstone.registerImageLoader('dicomweb', dicomWebImageLoader);
|
|
|
+// // 配置加载器(Worker 路径需指向实际文件)
|
|
|
+// dicomWebImageLoader.configure({
|
|
|
+// webWorkerPath: '/cornerstone-workers/',
|
|
|
+// maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
|
|
|
+// });
|
|
|
+// };
|
|
|
+
|
|
|
+type ViewportContainerProps = {
|
|
|
+ imageId: string;
|
|
|
+ className?: string; // 可选
|
|
|
+};
|
|
|
+
|
|
|
+const ViewportContainer = ({ imageId, className }: ViewportContainerProps) => {
|
|
|
+ console.log(`ViewportContainer 得到的属性 :${imageId}`)
|
|
|
+ const viewportRef = useRef(null);
|
|
|
+ const [renderingEngine, setRenderingEngine] = useState<any>(null);
|
|
|
+ const [stackViewport, setStackViewport] = useState<any>(null);
|
|
|
+ // ✅ 用 useMemo 保证 id 只生成一次
|
|
|
+ const viewportId = useMemo(() => `stackViewport-${imageId}-${uuidv4()}`, []);
|
|
|
+
|
|
|
+ // 初始化 Cornerstone 渲染引擎
|
|
|
+ useEffect(() => {
|
|
|
+ // initImageLoader();
|
|
|
+
|
|
|
+ // 创建渲染引擎实例
|
|
|
+ const engine = new RenderingEngine('myRenderingEngineForPrint');
|
|
|
+ setRenderingEngine(engine);
|
|
|
+
|
|
|
+ // 配置 Viewport
|
|
|
+ if (viewportRef.current) {
|
|
|
+ const viewportInput:cornerstone.Types.PublicViewportInput = {
|
|
|
+ viewportId: viewportId,
|
|
|
+ type: Enums.ViewportType.STACK, // 序列视图类型
|
|
|
+ element: viewportRef.current,
|
|
|
+ defaultOptions: {
|
|
|
+ background: [0.1, 0.1, 0.1], // 深灰背景
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ // 绑定 Viewport 到引擎
|
|
|
+ engine.enableElement(viewportInput);
|
|
|
+ // 获取 Viewport 实例
|
|
|
+ const viewport = engine.getViewport(viewportId);
|
|
|
+ setStackViewport(viewport);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 组件卸载时清理
|
|
|
+ return () => {
|
|
|
+ renderingEngine?.destroy();
|
|
|
+ };
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // 处理拖放事件(核心逻辑)
|
|
|
+ const handleDrop = async (e) => {
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+
|
|
|
+ // 1. 获取拖拽传递的序列标识
|
|
|
+ const seriesInstanceUID = e.dataTransfer.getData('seriesInstanceUID');
|
|
|
+ if (!seriesInstanceUID || !stackViewport) return;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 2. 获取该序列的所有图像 ID(需替换为实际接口)
|
|
|
+ const imageIds = getDcmImageUrl(seriesInstanceUID);//await fetchImageIds(seriesInstanceUID);
|
|
|
+ console.log(`拖拽后要加载图像 是 ${imageIds}`);
|
|
|
+ // 3. 加载图像并设置到 Viewport
|
|
|
+ await stackViewport.setStack([imageIds],0);
|
|
|
+ // 4. 渲染图像
|
|
|
+ stackViewport.render();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载图像失败:', error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 辅助函数:从服务端获取图像 ID 列表
|
|
|
+ const fetchImageIds = async (seriesInstanceUID) => {
|
|
|
+ // 实际项目中替换为真实接口
|
|
|
+ const response = await fetch(`/api/dicom/series/${seriesInstanceUID}/images`);
|
|
|
+ const data = await response.json();
|
|
|
+ // 图像 ID 格式示例: dicomweb://server/studies/1.2.3/series/4.5/instances/6.7
|
|
|
+ return data.imageIds;
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ className="viewport-container"
|
|
|
+ onDragOver={(e) => {
|
|
|
+ e.preventDefault(); // 允许放置
|
|
|
+ e.dataTransfer.dropEffect = 'copy';
|
|
|
+ }}
|
|
|
+ onDrop={handleDrop}
|
|
|
+ style={{
|
|
|
+ width: '100%',
|
|
|
+ height: '600px',
|
|
|
+ border: '2px dashed #666',
|
|
|
+ borderRadius: '8px',
|
|
|
+ position: 'relative'
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {/* Cornerstone 渲染挂载点 */}
|
|
|
+ <div ref={viewportRef} style={{ width: '100%', height: '100%' }} />
|
|
|
+
|
|
|
+ {/* 拖拽提示文字 */}
|
|
|
+ <div style={{
|
|
|
+ position: 'absolute',
|
|
|
+ top: '50%',
|
|
|
+ left: '50%',
|
|
|
+ transform: 'translate(-50%, -50%)',
|
|
|
+ color: '#999'
|
|
|
+ }}>
|
|
|
+ 拖拽序列到此处显示
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default ViewportContainer;
|