|
|
@@ -2,6 +2,10 @@ import React from 'react';
|
|
|
import { useAppSelector } from '@/states/store';
|
|
|
import { useDispatch } from 'react-redux';
|
|
|
import { setSelectedImageIndex } from '@/states/print/printSlice';
|
|
|
+import { StackViewerWithErrorBoundary } from '@/pages/view/components/viewers/stack.image.viewer';
|
|
|
+import { getDcmImageUrl } from '@/API/bodyPosition';
|
|
|
+
|
|
|
+const renderingEngineId = 'renderingEngineForPrint';
|
|
|
|
|
|
const Film: React.FC = () => {
|
|
|
const dispatch = useDispatch();
|
|
|
@@ -20,7 +24,7 @@ const Film: React.FC = () => {
|
|
|
// 根据布局获取grid类名
|
|
|
const getGridClass = () => {
|
|
|
const { layout, orientation } = currentFilm;
|
|
|
-
|
|
|
+
|
|
|
if (layout === '1x1') {
|
|
|
return 'grid-cols-1 grid-rows-1';
|
|
|
} else if (layout === '1x2') {
|
|
|
@@ -36,36 +40,74 @@ const Film: React.FC = () => {
|
|
|
}
|
|
|
return 'grid-cols-1 grid-rows-1';
|
|
|
};
|
|
|
+ const getViewportIdByUrl = (url: string): string | null => {
|
|
|
+ return `viewport-${url}`;
|
|
|
+ };
|
|
|
+ const generateCell = (imageId) => {
|
|
|
+ const actualUrl = getDcmImageUrl(imageId)
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ key={imageId}
|
|
|
+ className={`border-2 rounded flex items-center justify-center cursor-pointer hover:border-blue-400 transition-colors ${selectedImageIndex === imageId
|
|
|
+ ? 'border-blue-500 bg-blue-50'
|
|
|
+ : 'border-gray-300 bg-gray-50'
|
|
|
+ }`}
|
|
|
+ onClick={() => handleCellClick(imageId)}
|
|
|
+ style={{
|
|
|
+ minHeight: '100px',
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {imageId ? (
|
|
|
+ <div className="text-center">
|
|
|
+ {/* <div className="text-sm text-gray-600">图像 {imageId}</div> */}
|
|
|
+ <StackViewerWithErrorBoundary
|
|
|
+ key={actualUrl}
|
|
|
+ imageIndex={0}
|
|
|
+ imageUrls={[actualUrl]}
|
|
|
+ viewportId={getViewportIdByUrl(actualUrl) as string}
|
|
|
+ renderingEngineId={renderingEngineId}
|
|
|
+ //selected={selectedViewerUrls.includes(originalUrl)}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div className="text-gray-400 text-sm">空格子</div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const getCells = () => {
|
|
|
+ const { layout } = currentFilm;
|
|
|
+ const cells: any[] = [];
|
|
|
+ if (layout === '1x1') {
|
|
|
+ cells.push(generateCell(null));
|
|
|
+ return cells;
|
|
|
+ } else if (layout === '1x2') {
|
|
|
+ cells.push(generateCell(null));
|
|
|
+ cells.push(generateCell(null));
|
|
|
+ return cells;
|
|
|
+ } else if (layout === '2x1') {
|
|
|
+ cells.push(generateCell(null));
|
|
|
+ cells.push(generateCell(null));
|
|
|
+ return cells;
|
|
|
+ } else if (layout === '2x2') {
|
|
|
+ for (let i = 0; i < 4; i++) {
|
|
|
+ cells.push(generateCell(null));
|
|
|
+ }
|
|
|
+ return cells;
|
|
|
+ }
|
|
|
+ console.warn(`没有得到布局信息`);
|
|
|
+ return generateCell(null);//不知道什么布局,认为只有一个格子
|
|
|
+ }
|
|
|
|
|
|
- const handleCellClick = (index: number) => {
|
|
|
- dispatch(setSelectedImageIndex(index));
|
|
|
+ const handleCellClick = (sop_instance_uid: string) => {
|
|
|
+ dispatch(setSelectedImageIndex(sop_instance_uid));
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
<div className="film h-full w-full p-4">
|
|
|
<div className={`grid gap-2 h-full w-full ${getGridClass()}`}>
|
|
|
- {currentFilm.images.map((imageId, index) => (
|
|
|
- <div
|
|
|
- key={index}
|
|
|
- className={`border-2 rounded flex items-center justify-center cursor-pointer hover:border-blue-400 transition-colors ${
|
|
|
- selectedImageIndex === index
|
|
|
- ? 'border-blue-500 bg-blue-50'
|
|
|
- : 'border-gray-300 bg-gray-50'
|
|
|
- }`}
|
|
|
- onClick={() => handleCellClick(index)}
|
|
|
- style={{
|
|
|
- minHeight: '100px',
|
|
|
- }}
|
|
|
- >
|
|
|
- {imageId ? (
|
|
|
- <div className="text-center">
|
|
|
- <div className="text-sm text-gray-600">图像 {imageId}</div>
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <div className="text-gray-400 text-sm">空格子 {index + 1}</div>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- ))}
|
|
|
+ {getCells()}
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|