|
|
@@ -1670,13 +1670,19 @@ export class ImageLoadError extends Error {
|
|
|
* @param imageIds - 图像 ID 数组
|
|
|
* @param imageIndex - 当前图像索引
|
|
|
* @param timeout - 超时时间(毫秒),默认30秒
|
|
|
+ * @param onSetStackStart - setStack 开始回调
|
|
|
+ * @param onSetStackComplete - setStack 完成回调
|
|
|
*/
|
|
|
export async function safeSetStack(
|
|
|
viewport: any,
|
|
|
imageIds: string[],
|
|
|
imageIndex: number,
|
|
|
- timeout: number = 30000
|
|
|
+ timeout: number = 30000,
|
|
|
+ onSetStackStart?: (viewportId: string, imageIds: string[], imageIndex: number) => void,
|
|
|
+ onSetStackComplete?: (viewportId: string, imageIds: string[], imageIndex: number, duration: number, success: boolean) => void
|
|
|
): Promise<void> {
|
|
|
+ const startTime = performance.now();
|
|
|
+ const viewportId = viewport?.element?.id || 'unknown';
|
|
|
const errors: string[] = [];
|
|
|
|
|
|
// 错误事件处理器
|
|
|
@@ -1689,6 +1695,9 @@ export async function safeSetStack(
|
|
|
eventTarget.addEventListener(EVENTS.IMAGE_LOAD_ERROR, handler);
|
|
|
|
|
|
try {
|
|
|
+ // 触发开始回调
|
|
|
+ onSetStackStart?.(viewportId, imageIds, imageIndex);
|
|
|
+
|
|
|
// 创建超时 Promise
|
|
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
|
setTimeout(() => {
|
|
|
@@ -1701,7 +1710,9 @@ export async function safeSetStack(
|
|
|
viewport.setStack(imageIds, imageIndex),
|
|
|
timeoutPromise
|
|
|
]);
|
|
|
-
|
|
|
+ const duration = performance.now() - startTime;
|
|
|
+ // 触发完成回调(成功)
|
|
|
+ onSetStackComplete?.(viewportId, imageIds, imageIndex, duration, true);
|
|
|
// setStack 完成后,检查是否有错误
|
|
|
if (errors.length > 0) {
|
|
|
throw new ImageLoadError(
|
|
|
@@ -1711,6 +1722,11 @@ export async function safeSetStack(
|
|
|
}
|
|
|
|
|
|
console.log(`✅ 图像栈设置成功: ${imageIds.length} 张图像`);
|
|
|
+ } catch (error) {
|
|
|
+ const duration = performance.now() - startTime;
|
|
|
+ // 触发完成回调(失败)
|
|
|
+ onSetStackComplete?.(viewportId, imageIds, imageIndex, duration, false);
|
|
|
+ throw error;
|
|
|
} finally {
|
|
|
// 无论成功失败,都移除监听器(清理资源)
|
|
|
eventTarget.removeEventListener(EVENTS.IMAGE_LOAD_ERROR, handler);
|
|
|
@@ -1722,13 +1738,17 @@ const StackViewer = ({
|
|
|
imageUrls = [],
|
|
|
viewportId,
|
|
|
renderingEngineId,
|
|
|
- selected
|
|
|
+ selected,
|
|
|
+ onSetStackStart,
|
|
|
+ onSetStackComplete
|
|
|
}: {
|
|
|
imageIndex?: number;
|
|
|
imageUrls?: string[];
|
|
|
viewportId: string;
|
|
|
renderingEngineId: string;
|
|
|
selected?: boolean;
|
|
|
+ onSetStackStart?: (viewportId: string, imageIds: string[], imageIndex: number) => void;
|
|
|
+ onSetStackComplete?: (viewportId: string, imageIds: string[], imageIndex: number, duration: number, success: boolean) => void;
|
|
|
}) => {
|
|
|
const elementRef = useRef<HTMLDivElement>(null);
|
|
|
// 用于捕获异步错误并在渲染时抛出,让 Error Boundary 能够捕获
|
|
|
@@ -1952,7 +1972,7 @@ const StackViewer = ({
|
|
|
|
|
|
try {
|
|
|
// 设置图像栈,使用扩展后的imageUrls
|
|
|
- await safeSetStack(viewport, finalImageUrls, imageIndex);
|
|
|
+ await safeSetStack(viewport, finalImageUrls, imageIndex, 30000, onSetStackStart, onSetStackComplete);
|
|
|
|
|
|
// 加载完成 - 隐藏进度条
|
|
|
dispatch(completeLoading(viewportId));
|
|
|
@@ -2211,7 +2231,9 @@ export const StackViewerWithErrorBoundary = ({
|
|
|
renderingEngineId,
|
|
|
selected,
|
|
|
maxRetries = 3,
|
|
|
- onError
|
|
|
+ onError,
|
|
|
+ onSetStackStart,
|
|
|
+ onSetStackComplete
|
|
|
}: {
|
|
|
imageIndex?: number;
|
|
|
imageUrls?: string[];
|
|
|
@@ -2220,6 +2242,8 @@ export const StackViewerWithErrorBoundary = ({
|
|
|
selected?: boolean;
|
|
|
maxRetries?: number;
|
|
|
onError?: (error: Error, errorInfo: any) => void;
|
|
|
+ onSetStackStart?: (viewportId: string, imageIds: string[], imageIndex: number) => void;
|
|
|
+ onSetStackComplete?: (viewportId: string, imageIds: string[], imageIndex: number, duration: number, success: boolean) => void;
|
|
|
}) => {
|
|
|
return (
|
|
|
<ImageViewerErrorBoundary
|
|
|
@@ -2232,6 +2256,8 @@ export const StackViewerWithErrorBoundary = ({
|
|
|
viewportId={viewportId}
|
|
|
renderingEngineId={renderingEngineId}
|
|
|
selected={selected}
|
|
|
+ onSetStackStart={onSetStackStart}
|
|
|
+ onSetStackComplete={onSetStackComplete}
|
|
|
/>
|
|
|
</ImageViewerErrorBoundary>
|
|
|
);
|