|
@@ -33,6 +33,7 @@ import StackViewer, {
|
|
activateHipDorsalCoverageMeasurement,
|
|
activateHipDorsalCoverageMeasurement,
|
|
} from './viewers/stack.image.viewer';
|
|
} from './viewers/stack.image.viewer';
|
|
import { useSelector, useDispatch } from 'react-redux';
|
|
import { useSelector, useDispatch } from 'react-redux';
|
|
|
|
+import { getDcmImageUrl } from '@/API/bodyPosition';
|
|
import store, { RootState } from '@/states/store';
|
|
import store, { RootState } from '@/states/store';
|
|
import { clearAction } from '@/states/view/functionAreaSlice';
|
|
import { clearAction } from '@/states/view/functionAreaSlice';
|
|
import {
|
|
import {
|
|
@@ -159,7 +160,7 @@ interface ViewerContainerProps {
|
|
|
|
|
|
const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
console.log(`[ViewerContainer] 新渲染 imageUrls:`, imageUrls);
|
|
console.log(`[ViewerContainer] 新渲染 imageUrls:`, imageUrls);
|
|
-
|
|
|
|
|
|
+
|
|
// 从 Redux 获取状态
|
|
// 从 Redux 获取状态
|
|
const gridLayout = useSelector(selectGridLayout);
|
|
const gridLayout = useSelector(selectGridLayout);
|
|
const selectedViewerUrls = useSelector(selectSelectedViewers);
|
|
const selectedViewerUrls = useSelector(selectSelectedViewers);
|
|
@@ -171,7 +172,7 @@ const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
(state: RootState) => state.bodyPositionList.selectedBodyPosition
|
|
(state: RootState) => state.bodyPositionList.selectedBodyPosition
|
|
);
|
|
);
|
|
|
|
|
|
-
|
|
|
|
|
|
+
|
|
console.log(`[ViewerContainer] rerendered]`);
|
|
console.log(`[ViewerContainer] rerendered]`);
|
|
|
|
|
|
// 当 imageUrls 改变时,更新 Redux 中的 allViewers
|
|
// 当 imageUrls 改变时,更新 Redux 中的 allViewers
|
|
@@ -215,7 +216,7 @@ const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
selectedViewportIds: string[]
|
|
selectedViewportIds: string[]
|
|
) => {
|
|
) => {
|
|
console.log(`开始${config.logPrefix}测量`);
|
|
console.log(`开始${config.logPrefix}测量`);
|
|
-
|
|
|
|
|
|
+
|
|
const viewportIds = selectedViewportIds.length > 0
|
|
const viewportIds = selectedViewportIds.length > 0
|
|
? selectedViewportIds
|
|
? selectedViewportIds
|
|
: Array.from({ length: getVisibleViewportCount() }, (_, i) => `viewport-${i}`);
|
|
: Array.from({ length: getVisibleViewportCount() }, (_, i) => `viewport-${i}`);
|
|
@@ -253,9 +254,7 @@ const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
- useEffect(() => {
|
|
|
|
- renderGrid();
|
|
|
|
- }, [selectedBodyPosition, gridLayout]);
|
|
|
|
|
|
+
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
if (action) {
|
|
if (action) {
|
|
@@ -263,7 +262,7 @@ const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
`[ViewerContainer] 处理功能操作: ${action}, selectedViewers:`,
|
|
`[ViewerContainer] 处理功能操作: ${action}, selectedViewers:`,
|
|
selectedViewerUrls
|
|
selectedViewerUrls
|
|
);
|
|
);
|
|
-
|
|
|
|
|
|
+
|
|
// 将选中的 imageUrl 转换为 viewportId
|
|
// 将选中的 imageUrl 转换为 viewportId
|
|
const selectedViewportIds = selectedViewerUrls
|
|
const selectedViewportIds = selectedViewerUrls
|
|
.map(getViewportIdByUrl)
|
|
.map(getViewportIdByUrl)
|
|
@@ -563,7 +562,7 @@ const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
);
|
|
);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
- }
|
|
|
|
|
|
+ }
|
|
console.log('Activating Angle Measurement from MeasurementPanel');
|
|
console.log('Activating Angle Measurement from MeasurementPanel');
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -608,16 +607,43 @@ const ViewerContainer: React.FC<ViewerContainerProps> = ({ imageUrls }) => {
|
|
console.log('Rendering layout', gridLayout);
|
|
console.log('Rendering layout', gridLayout);
|
|
switch (gridLayout) {
|
|
switch (gridLayout) {
|
|
case '1x1': {
|
|
case '1x1': {
|
|
- //变成单分格时,自动选中第一个
|
|
|
|
- dispatch(toggleViewerSelection(allViewerUrls[0]));
|
|
|
|
- return (
|
|
|
|
- <div
|
|
|
|
- className="h-full w-full"
|
|
|
|
- style={{ display: 'grid', gridTemplateColumns: '1fr' }}
|
|
|
|
- >
|
|
|
|
- {renderViewers(0, 1)}
|
|
|
|
- </div>
|
|
|
|
- );
|
|
|
|
|
|
+ // 变成单分格时,选中对应 selectedBodyPosition 的 URL
|
|
|
|
+ let urlToSelect = allViewerUrls[0]; // 默认选第一个作为fallback
|
|
|
|
+
|
|
|
|
+ if (selectedBodyPosition?.sop_instance_uid) {
|
|
|
|
+ const correspondingUrl = getDcmImageUrl(selectedBodyPosition.sop_instance_uid);
|
|
|
|
+ const urlIndex = allViewerUrls.indexOf(correspondingUrl);
|
|
|
|
+ if (urlIndex !== -1) {
|
|
|
|
+ urlToSelect = allViewerUrls[urlIndex];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 检查当前选中状态,避免无限循环
|
|
|
|
+ const currentSelected = selectedViewerUrls[0];
|
|
|
|
+ if (currentSelected !== urlToSelect) {
|
|
|
|
+ if (currentSelected) {
|
|
|
|
+ dispatch(toggleViewerSelection(currentSelected)); // 取消选中当前
|
|
|
|
+ }
|
|
|
|
+ dispatch(toggleViewerSelection(urlToSelect)); // 选中新的
|
|
|
|
+ }
|
|
|
|
+ // 找到体位列表中选中体位对应的url
|
|
|
|
+ let viewerIndex = 0;
|
|
|
|
+ if (selectedBodyPosition?.sop_instance_uid) {
|
|
|
|
+ const correspondingUrl = getDcmImageUrl(selectedBodyPosition.sop_instance_uid);
|
|
|
|
+ const urlIndex = imageUrls.indexOf(correspondingUrl);
|
|
|
|
+ if (urlIndex !== -1) {
|
|
|
|
+ viewerIndex = urlIndex;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return (
|
|
|
|
+ <div
|
|
|
|
+ className="h-full w-full"
|
|
|
|
+ style={{ display: 'grid', gridTemplateColumns: '1fr' }}
|
|
|
|
+ >
|
|
|
|
+ {renderViewers(viewerIndex, viewerIndex + 1)}
|
|
|
|
+ </div>
|
|
|
|
+ );
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case '1x2':
|
|
case '1x2':
|