Ver Fonte

fix (1.34.5): 修复 Redux 序列化错误 - 移除未使用的 annotation slice

- 注释掉 annotationSlice.ts 中的所有代码,避免 Map 对象序列化问题
- 注释掉 annotation.ts 中的类型定义
- 从 store.ts 中移除 annotation reducer 注册
- 彻底移除未使用的 Redux annotation 状态管理,避免控制台出现 'annotation.annotations' 序列化错误

改动文件:
- src/features/imageAnnotation/state/annotationSlice.ts
- src/features/imageAnnotation/types/annotation.ts
- src/states/store.ts
- CHANGELOG.md (版本更新: 1.34.4 -> 1.34.5)
- package.json (版本更新: 1.34.4 -> 1.34.5)
dengdx há 2 semanas atrás
pai
commit
2f0ae460b6

+ 19 - 0
CHANGELOG.md

@@ -2,6 +2,25 @@
 
 本项目的所有重要变更都将记录在此文件中。
 
+## [1.34.5] - 2025-12-30 14:51
+
+### 修复 (Fixed)
+- **修复 Redux 序列化错误** - 移除未使用的 annotation slice 状态管理,避免控制台出现序列化错误信息
+  - 注释掉 annotationSlice.ts 中的所有代码,避免 Map 对象序列化问题
+  - 注释掉 annotation.ts 中的类型定义
+  - 从 store.ts 中移除 annotation reducer 注册
+  - 彻底移除未使用的 Redux annotation 状态管理,避免控制台出现 `annotation.annotations` 序列化错误
+
+**核心改进:**
+- 代码清理:移除未使用的 Redux slice,减少代码复杂度
+- 错误修复:解决 Redux 序列化检查器报错的问题
+- 系统稳定性:避免因未使用状态导致的潜在序列化问题
+
+**改动文件:**
+- src/features/imageAnnotation/state/annotationSlice.ts
+- src/features/imageAnnotation/types/annotation.ts
+- src/states/store.ts
+
 ## [1.34.4] - 2025-12-30 12:37
 
 ### 修复 (Fixed)

+ 4 - 4
config/dev.ts

@@ -81,16 +81,16 @@ export default {
     devServer: {
       proxy: {
         '/dr': {
-          // target: 'http://192.168.110.13:6001', // 你的后端服务地址
-          target: 'http://192.168.110.245:6001',
+          target: 'http://192.168.110.13:6001', // 你的后端服务地址
+          // target: 'http://192.168.110.245:6001',
           changeOrigin: true, // 允许跨域
           // pathRewrite: {
           //   '^/dr/api': '' // 可选,用于重写路径
           // }
         },
         '/mqtt': {
-          // target: 'ws://192.168.110.13:8083', // MQTT WebSocket 服务地址
-          target: 'ws://192.168.110.245:8083',
+          target: 'ws://192.168.110.13:8083', // MQTT WebSocket 服务地址
+          // target: 'ws://192.168.110.245:8083',
           changeOrigin: true,
           ws: true, // 启用 WebSocket 代理
           // pathRewrite: {

Diff do ficheiro suprimidas por serem muito extensas
+ 94 - 118
package-lock.json


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "zsis",
-  "version": "1.34.4",
+  "version": "1.34.5",
   "private": true,
   "description": "医学成像系统",
   "main": "main.js",

+ 2 - 2
src/features/imageAnnotation/services/AnnotationManager.ts

@@ -8,9 +8,9 @@ import { AnnotationSerializer } from './AnnotationSerializer';
 import { AnnotationValidator } from './AnnotationValidator';
 import { annotationAPI } from '../../../API/annotation';
 import { extractSopInstanceUid } from '../../../utils/dicomUtils';
-import type { AnnotationData, AnnotationEventType } from '../types/annotation';
+
 import { IRenderingEngine, IStackViewport } from '@cornerstonejs/core/dist/esm/types';
-import * as cornerstoneTools from '@cornerstonejs/tools';
+
 import { getIpPort } from '../../../API/config';
 
 export class AnnotationManager {

+ 138 - 135
src/features/imageAnnotation/state/annotationSlice.ts

@@ -1,135 +1,138 @@
-// src/features/imageAnnotation/state/annotationSlice.ts
-// Redux状态管理 - 注释相关状态
-
-import { createSlice, PayloadAction } from '@reduxjs/toolkit';
-import type { AnnotationState } from '../types/annotation';
-import { AnnotationStatus } from '../types/annotation';
-
-const initialState: AnnotationState = {
-  annotations: new Map(),
-  status: AnnotationStatus.IDLE,
-  error: null,
-  lastSaved: null,
-};
-
-const annotationSlice = createSlice({
-  name: 'annotation',
-  initialState,
-  reducers: {
-    // 设置加载状态
-    setLoading: (state) => {
-      state.status = AnnotationStatus.LOADING;
-      state.error = null;
-    },
-
-    // 设置保存状态
-    setSaving: (state) => {
-      state.status = AnnotationStatus.SAVING;
-      state.error = null;
-    },
-
-    // 设置成功状态
-    setSuccess: (state) => {
-      state.status = AnnotationStatus.SUCCESS;
-      state.error = null;
-      state.lastSaved = new Date();
-    },
-
-    // 设置错误状态
-    setError: (state, action: PayloadAction<string>) => {
-      state.status = AnnotationStatus.ERROR;
-      state.error = action.payload;
-    },
-
-    // 重置状态
-    resetStatus: (state) => {
-      state.status = AnnotationStatus.IDLE;
-      state.error = null;
-    },
-
-    // 添加注释
-    addAnnotation: (state, action: PayloadAction<any>) => {
-      state.annotations.set(action.payload.id || action.payload.annotationUID, action.payload);
-    },
-
-    // 更新注释
-    updateAnnotation: (state, action: PayloadAction<any>) => {
-      state.annotations.set(action.payload.id || action.payload.annotationUID, action.payload);
-    },
-
-    // 删除注释
-    removeAnnotation: (state, action: PayloadAction<string>) => {
-      state.annotations.delete(action.payload);
-    },
-
-    // 批量设置注释
-    setAnnotations: (state, action: PayloadAction<any[]>) => {
-      state.annotations.clear();
-      action.payload.forEach(annotation => {
-        state.annotations.set(annotation.id || annotation.annotationUID, annotation);
-      });
-    },
-
-    // 清空注释
-    clearAnnotations: (state) => {
-      state.annotations.clear();
-      state.lastSaved = null;
-    },
-
-    // 设置注释高亮状态
-    setAnnotationHighlighted: (state, action: PayloadAction<{ id: string; highlighted: boolean }>) => {
-      const annotation = state.annotations.get(action.payload.id);
-      if (annotation) {
-        annotation.highlighted = action.payload.highlighted;
-      }
-    },
-
-    // 设置注释选中状态
-    setAnnotationSelected: (state, action: PayloadAction<{ id: string; selected: boolean }>) => {
-      const annotation = state.annotations.get(action.payload.id);
-      if (annotation) {
-        annotation.isSelected = action.payload.selected;
-      }
-    },
-
-    // 批量更新注释状态
-    updateAnnotationsStatus: (state, action: PayloadAction<{ ids: string[]; status: any }>) => {
-      action.payload.ids.forEach(id => {
-        const annotation = state.annotations.get(id);
-        if (annotation) {
-          Object.assign(annotation, action.payload.status);
-        }
-      });
-    },
-  },
-});
-
-export const {
-  setLoading,
-  setSaving,
-  setSuccess,
-  setError,
-  resetStatus,
-  addAnnotation,
-  updateAnnotation,
-  removeAnnotation,
-  setAnnotations,
-  clearAnnotations,
-  setAnnotationHighlighted,
-  setAnnotationSelected,
-  updateAnnotationsStatus,
-} = annotationSlice.actions;
-
-// 选择器
-export const selectAnnotations = (state: { annotation: AnnotationState }) => state.annotation.annotations;
-export const selectAnnotationStatus = (state: { annotation: AnnotationState }) => state.annotation.status;
-export const selectAnnotationError = (state: { annotation: AnnotationState }) => state.annotation.error;
-export const selectAnnotationLastSaved = (state: { annotation: AnnotationState }) => state.annotation.lastSaved;
-export const selectAnnotationById = (id: string) => (state: { annotation: AnnotationState }) =>
-  state.annotation.annotations.get(id);
-export const selectAnnotationsByImage = (imageId: string) => (state: { annotation: AnnotationState }) =>
-  Array.from(state.annotation.annotations.values()).filter(
-    annotation => annotation.sopInstanceUid === imageId || annotation.metadata?.referencedImageId === imageId
-  );
-
-export default annotationSlice.reducer;
+// // src/features/imageAnnotation/state/annotationSlice.ts
+// // Redux状态管理 - 注释相关状态
+
+// import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+// import type { AnnotationState } from '../types/annotation';
+// import { AnnotationStatus } from '../types/annotation';
+
+// const initialState: AnnotationState = {
+//   annotations: Object.create(null),// 使用 as Record<string, any> ,避免控制台出现error
+//   status: AnnotationStatus.IDLE,
+//   error: null,
+//   lastSaved: null,
+// };
+
+// const annotationSlice = createSlice({
+//   name: 'annotation',
+//   initialState,
+//   reducers: {
+//     // 设置加载状态
+//     setLoading: (state) => {
+//       state.status = AnnotationStatus.LOADING;
+//       state.error = null;
+//     },
+
+//     // 设置保存状态
+//     setSaving: (state) => {
+//       state.status = AnnotationStatus.SAVING;
+//       state.error = null;
+//     },
+
+//     // 设置成功状态
+//     setSuccess: (state) => {
+//       state.status = AnnotationStatus.SUCCESS;
+//       state.error = null;
+//       state.lastSaved = new Date().toISOString();
+//     },
+
+//     // 设置错误状态
+//     setError: (state, action: PayloadAction<string>) => {
+//       state.status = AnnotationStatus.ERROR;
+//       state.error = action.payload;
+//     },
+
+//     // 重置状态
+//     resetStatus: (state) => {
+//       state.status = AnnotationStatus.IDLE;
+//       state.error = null;
+//     },
+
+//     // 添加注释
+//     addAnnotation: (state, action: PayloadAction<any>) => {
+//       const key = action.payload.id || action.payload.annotationUID;
+//       state.annotations[key] = action.payload;
+//     },
+
+//     // 更新注释
+//     updateAnnotation: (state, action: PayloadAction<any>) => {
+//       const key = action.payload.id || action.payload.annotationUID;
+//       state.annotations[key] = action.payload;
+//     },
+
+//     // 删除注释
+//     removeAnnotation: (state, action: PayloadAction<string>) => {
+//       delete state.annotations[action.payload];
+//     },
+
+//     // 批量设置注释
+//     setAnnotations: (state, action: PayloadAction<any[]>) => {
+//       state.annotations = {};
+//       action.payload.forEach(annotation => {
+//         const key = annotation.id || annotation.annotationUID;
+//         state.annotations[key] = annotation;
+//       });
+//     },
+
+//     // 清空注释
+//     clearAnnotations: (state) => {
+//       state.annotations = {};
+//       state.lastSaved = null;
+//     },
+
+//     // 设置注释高亮状态
+//     setAnnotationHighlighted: (state, action: PayloadAction<{ id: string; highlighted: boolean }>) => {
+//       const annotation = state.annotations[action.payload.id];
+//       if (annotation) {
+//         annotation.highlighted = action.payload.highlighted;
+//       }
+//     },
+
+//     // 设置注释选中状态
+//     setAnnotationSelected: (state, action: PayloadAction<{ id: string; selected: boolean }>) => {
+//       const annotation = state.annotations[action.payload.id];
+//       if (annotation) {
+//         annotation.isSelected = action.payload.selected;
+//       }
+//     },
+
+//     // 批量更新注释状态
+//     updateAnnotationsStatus: (state, action: PayloadAction<{ ids: string[]; status: any }>) => {
+//       action.payload.ids.forEach(id => {
+//         const annotation = state.annotations[id];
+//         if (annotation) {
+//           Object.assign(annotation, action.payload.status);
+//         }
+//       });
+//     },
+//   },
+// });
+
+// export const {
+//   setLoading,
+//   setSaving,
+//   setSuccess,
+//   setError,
+//   resetStatus,
+//   addAnnotation,
+//   updateAnnotation,
+//   removeAnnotation,
+//   setAnnotations,
+//   clearAnnotations,
+//   setAnnotationHighlighted,
+//   setAnnotationSelected,
+//   updateAnnotationsStatus,
+// } = annotationSlice.actions;
+
+// // 选择器
+// export const selectAnnotations = (state: { annotation: AnnotationState }) => state.annotation.annotations;
+// export const selectAnnotationStatus = (state: { annotation: AnnotationState }) => state.annotation.status;
+// export const selectAnnotationError = (state: { annotation: AnnotationState }) => state.annotation.error;
+// export const selectAnnotationLastSaved = (state: { annotation: AnnotationState }) => state.annotation.lastSaved;
+// export const selectAnnotationById = (id: string) => (state: { annotation: AnnotationState }) =>
+//   state.annotation.annotations[id];
+// export const selectAnnotationsByImage = (imageId: string) => (state: { annotation: AnnotationState }) =>
+//   Object.values(state.annotation.annotations).filter(
+//     annotation => annotation.sopInstanceUid === imageId || annotation.metadata?.referencedImageId === imageId
+//   );
+
+// export default annotationSlice.reducer;

+ 147 - 147
src/features/imageAnnotation/types/annotation.ts

@@ -1,147 +1,147 @@
-// src/features/imageAnnotation/types/annotation.ts
-// 注释相关类型定义
-
-import type { Types as CoreTypes } from '@cornerstonejs/core';
-
-/**
- * 注释数据接口 - 基于Cornerstone Tools的注释结构
- */
-export interface AnnotationData {
-  // 基础信息
-  id: string;
-  toolName: string;              // 工具类型,如 'LengthTool', 'AngleTool', 'LabelTool'
-  sopInstanceUid: string;        // 图像SOP Instance UID
-
-  // 几何数据
-  handles: {
-    points: CoreTypes.Point3[];  // 关键点坐标
-    activeHandleIndex?: number;  // 激活的手柄索引
-    textBox?: CoreTypes.Point2; // 文本框位置
-  };
-
-  // 元数据
-  metadata: {
-    viewPlaneNormal: CoreTypes.Point3;
-    viewUp: CoreTypes.Point3;
-    FrameOfReferenceUID: string;
-    referencedImageId: string;
-  };
-
-  // 计算结果(针对测量工具)
-  cachedStats?: {
-    [targetId: string]: {
-      // 测量结果,如长度、角度等
-      length?: number;
-      angle?: number;
-      area?: number;
-      // 其他统计数据
-    };
-  };
-
-  // 显示属性
-  label?: string;                // 显示标签
-  highlighted?: boolean;         // 是否高亮
-  isSelected?: boolean;          // 是否选中
-
-  // 时间戳
-  createdAt: string;
-  updatedAt: string;
-  userId?: string;
-}
-
-/**
- * 注释API响应接口
- */
-export interface GetAnnotationResponse {
-  code: string;
-  description: string;
-  data: string[]; // JSON字符串格式的注释数据
-}
-
-export interface SaveAnnotationResponse {
-  code: string;
-  description: string;
-  data: {};
-}
-
-/**
- * 注释状态枚举
- */
-export enum AnnotationStatus {
-  LOADING = 'loading',
-  SAVING = 'saving',
-  SUCCESS = 'success',
-  ERROR = 'error',
-  IDLE = 'idle',
-}
-
-/**
- * 注释工具类型枚举
- */
-export enum AnnotationToolType {
-  LENGTH = 'LengthTool',
-  ANGLE = 'AngleTool',
-  LABEL = 'LabelTool',
-  HIP_NHA_ANGLE = 'HipNHAAngleMeasurementTool',
-  ELLIPSE = 'EllipseTool',
-  RECTANGLE = 'RectangleTool',
-  ARROW = 'ArrowTool',
-  PROBE = 'ProbeTool',
-}
-
-/**
- * 注释事件类型
- */
-export enum AnnotationEventType {
-  CREATED = 'ANNOTATION_COMPLETED',
-  MODIFIED = 'ANNOTATION_MODIFIED',
-  REMOVED = 'ANNOTATION_REMOVED',
-  SELECTION_CHANGED = 'ANNOTATION_SELECTION_CHANGE',
-  VISIBILITY_CHANGED = 'ANNOTATION_VISIBILITY_CHANGE',
-}
-
-/**
- * 注释状态管理接口
- */
-export interface AnnotationState {
-  annotations: Map<string, any>;
-  status: AnnotationStatus;
-  error: string | null;
-  lastSaved: Date | null;
-}
-
-/**
- * 注释配置接口
- */
-export interface AnnotationConfig {
-  autoSave: boolean;
-  autoSaveDelay: number; // 毫秒
-  maxRetries: number;
-  enableConflictResolution: boolean;
-}
-
-/**
- * 注释序列化器接口
- */
-export interface AnnotationSerializer {
-  serialize(annotation: any, toolName: string): string;
-  deserialize(data: string): any;
-}
-
-/**
- * 注释验证器接口
- */
-export interface AnnotationValidator {
-  validate(data: any): boolean;
-  validateAnnotationData(data: any): void;
-}
-
-/**
- * 注释API服务接口
- */
-export interface AnnotationAPIService {
-  getAnnotations(imageId: string): Promise<string[]>;
-  saveAnnotations(imageId: string, data: string[]): Promise<void>;
-  updateAnnotations(imageId: string, data: string[]): Promise<void>;
-  deleteAnnotations(imageId: string, annotationIds?: string[]): Promise<void>;
-}
+// // src/features/imageAnnotation/types/annotation.ts
+// // 注释相关类型定义
+
+// import type { Types as CoreTypes } from '@cornerstonejs/core';
+
+// /**
+//  * 注释数据接口 - 基于Cornerstone Tools的注释结构
+//  */
+// export interface AnnotationData {
+//   // 基础信息
+//   id: string;
+//   toolName: string;              // 工具类型,如 'LengthTool', 'AngleTool', 'LabelTool'
+//   sopInstanceUid: string;        // 图像SOP Instance UID
+
+//   // 几何数据
+//   handles: {
+//     points: CoreTypes.Point3[];  // 关键点坐标
+//     activeHandleIndex?: number;  // 激活的手柄索引
+//     textBox?: CoreTypes.Point2; // 文本框位置
+//   };
+
+//   // 元数据
+//   metadata: {
+//     viewPlaneNormal: CoreTypes.Point3;
+//     viewUp: CoreTypes.Point3;
+//     FrameOfReferenceUID: string;
+//     referencedImageId: string;
+//   };
+
+//   // 计算结果(针对测量工具)
+//   cachedStats?: {
+//     [targetId: string]: {
+//       // 测量结果,如长度、角度等
+//       length?: number;
+//       angle?: number;
+//       area?: number;
+//       // 其他统计数据
+//     };
+//   };
+
+//   // 显示属性
+//   label?: string;                // 显示标签
+//   highlighted?: boolean;         // 是否高亮
+//   isSelected?: boolean;          // 是否选中
+
+//   // 时间戳
+//   createdAt: string;
+//   updatedAt: string;
+//   userId?: string;
+// }
+
+// /**
+//  * 注释API响应接口
+//  */
+// export interface GetAnnotationResponse {
+//   code: string;
+//   description: string;
+//   data: string[]; // JSON字符串格式的注释数据
+// }
+
+// export interface SaveAnnotationResponse {
+//   code: string;
+//   description: string;
+//   data: {};
+// }
+
+// /**
+//  * 注释状态枚举
+//  */
+// export enum AnnotationStatus {
+//   LOADING = 'loading',
+//   SAVING = 'saving',
+//   SUCCESS = 'success',
+//   ERROR = 'error',
+//   IDLE = 'idle',
+// }
+
+// /**
+//  * 注释工具类型枚举
+//  */
+// export enum AnnotationToolType {
+//   LENGTH = 'LengthTool',
+//   ANGLE = 'AngleTool',
+//   LABEL = 'LabelTool',
+//   HIP_NHA_ANGLE = 'HipNHAAngleMeasurementTool',
+//   ELLIPSE = 'EllipseTool',
+//   RECTANGLE = 'RectangleTool',
+//   ARROW = 'ArrowTool',
+//   PROBE = 'ProbeTool',
+// }
+
+// /**
+//  * 注释事件类型
+//  */
+// export enum AnnotationEventType {
+//   CREATED = 'ANNOTATION_COMPLETED',
+//   MODIFIED = 'ANNOTATION_MODIFIED',
+//   REMOVED = 'ANNOTATION_REMOVED',
+//   SELECTION_CHANGED = 'ANNOTATION_SELECTION_CHANGE',
+//   VISIBILITY_CHANGED = 'ANNOTATION_VISIBILITY_CHANGE',
+// }
+
+// /**
+//  * 注释状态管理接口
+//  */
+// export interface AnnotationState {
+//   annotations: Record<string, any>;
+//   status: AnnotationStatus;
+//   error: string | null;
+//   lastSaved: string | null;
+// }
+
+// /**
+//  * 注释配置接口
+//  */
+// export interface AnnotationConfig {
+//   autoSave: boolean;
+//   autoSaveDelay: number; // 毫秒
+//   maxRetries: number;
+//   enableConflictResolution: boolean;
+// }
+
+// /**
+//  * 注释序列化器接口
+//  */
+// export interface AnnotationSerializer {
+//   serialize(annotation: any, toolName: string): string;
+//   deserialize(data: string): any;
+// }
+
+// /**
+//  * 注释验证器接口
+//  */
+// export interface AnnotationValidator {
+//   validate(data: any): boolean;
+//   validateAnnotationData(data: any): void;
+// }
+
+// /**
+//  * 注释API服务接口
+//  */
+// export interface AnnotationAPIService {
+//   getAnnotations(imageId: string): Promise<string[]>;
+//   saveAnnotations(imageId: string, data: string[]): Promise<void>;
+//   updateAnnotations(imageId: string, data: string[]): Promise<void>;
+//   deleteAnnotations(imageId: string, annotationIds?: string[]): Promise<void>;
+// }

+ 2 - 2
src/states/store.ts

@@ -93,7 +93,7 @@ import risSyncReducer from './ris/risSyncSlice';
 import processingModeReducer from './system/processingModeSlice';
 import invertContrastReducer from './view/invertContrastSlice';
 import serverConfigReducer from '../features/serverConfig/state/serverConfigSlice';
-import annotationReducer from '../features/imageAnnotation/state/annotationSlice';
+// import annotationReducer from '../features/imageAnnotation/state/annotationSlice';
 import versionUpdateReducer from './versionUpdateSlice';
 
 const store = configureStore({
@@ -178,7 +178,7 @@ const store = configureStore({
     processingMode: processingModeReducer,
     invertContrast: invertContrastReducer,
     serverConfig: serverConfigReducer,
-    annotation: annotationReducer,
+    // annotation: annotationReducer,
     versionUpdate: versionUpdateReducer,
   },
   middleware: (getDefaultMiddleware) =>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff