Browse Source

feat (1.75.0 -> 1.75.1): 优化人体部位交互组件,解决跨浏览器兼容性问题并增强交互体验

- 更新 human.svg 文件,优化人体部位图形定义和数据属性
- 重构 HumanBodySvg.tsx 组件,移除不必要的鼠标悬停逻辑
- 改进事件处理机制,支持 image 和 g 元素的统一点击处理
- 将交互事件从 onClick 改为 onMouseDown,提升响应灵敏度
- 优化 CSS 样式,添加调试边框并改进指针事件处理
- 修复代码格式,统一接口定义的缩进风格
- 解决 Firefox 147.0.1 (aarch64)、Chrome 144.0.7559.97 和 Edge 144.0.3719.82 浏览器中的显示和点击问题
- 更新 package-lock.json 版本从 1.74.0 到 1.75.1

改动文件:
- package-lock.json
- src/assets/imgs/VirtualHuman/human.svg
- src/components/HumanBodySvg.tsx
dengdx 8 hours ago
parent
commit
61b1832202
5 changed files with 77 additions and 81 deletions
  1. 27 0
      CHANGELOG.md
  2. 9 10
      package-lock.json
  3. 1 1
      package.json
  4. 0 33
      src/assets/imgs/VirtualHuman/human.svg
  5. 40 37
      src/components/HumanBodySvg.tsx

+ 27 - 0
CHANGELOG.md

@@ -2,6 +2,24 @@
 
 本项目的所有重要变更都将记录在此文件中.
 
+## [1.72.1] - 2026-01-21 14:00
+
+feat (1.72.0 -> 1.72.1): 优化人体部位交互组件,解决跨浏览器兼容性问题并增强交互体验
+
+- 更新 human.svg 文件,优化人体部位图形定义和数据属性
+- 重构 HumanBodySvg.tsx 组件,移除不必要的鼠标悬停逻辑
+- 改进事件处理机制,支持 image 和 g 元素的统一点击处理
+- 将交互事件从 onClick 改为 onMouseDown,提升响应灵敏度
+- 优化 CSS 样式,添加调试边框并改进指针事件处理
+- 修复代码格式,统一接口定义的缩进风格
+- 解决 Firefox 147.0.1 (aarch64)、Chrome 144.0.7559.97 和 Edge 144.0.3719.82 浏览器中的显示和点击问题
+
+改动文件:
+
+- package-lock.json
+- src/assets/imgs/VirtualHuman/human.svg
+- src/components/HumanBodySvg.tsx
+
 ## [1.72.0] - 2026-01-21 13:45
 
 fix (1.71.0 -> 1.72.0): 修复工作流设置表格列配置字段命名不一致问题, 同步master分支01438c6df6、06dbaa443f、54d283aa1c提交代码
@@ -425,3 +443,12 @@ fix (1.66.0 -> 1.66.1): 修复服务器配置连接检测和实时更新功能
 - src/API/system/options.ts
 - src/pages/system/SettingsModal/sections/Preferences/index.tsx
 - src/pages/system/SettingsModal/sections/Preferences/report/index.tsx### 新增 (Added)
+
+</file_content>
+<task_progress>
+- [x] Check Git status
+- [x] Analyze file changes and generate commit message
+- [x] Present commit message for user review
+- [ ] Execute Git commands with user confirmation
+</task_progress>
+</write_to_file>

+ 9 - 10
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "zsis",
-  "version": "1.74.0",
+  "version": "1.75.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "zsis",
-      "version": "1.74.0",
+      "version": "1.75.1",
       "dependencies": {
         "@babel/runtime": "^7.24.4",
         "@cornerstonejs/core": "^3.28.0",
@@ -10330,7 +10330,7 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
+      "devOptional": true,
       "license": "MIT",
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3"
@@ -17224,10 +17224,10 @@
       }
     },
     "node_modules/iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "devOptional": true,
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+      "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+      "license": "MIT",
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3.0.0"
       },
@@ -24999,7 +24999,7 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
+      "devOptional": true,
       "license": "MIT",
       "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3"
@@ -26588,8 +26588,7 @@
     "node_modules/safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "devOptional": true
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
     "node_modules/sanitize-filename": {
       "version": "1.6.3",

+ 1 - 1
package.json

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

File diff suppressed because it is too large
+ 0 - 33
src/assets/imgs/VirtualHuman/human.svg


+ 40 - 37
src/components/HumanBodySvg.tsx

@@ -10,17 +10,17 @@ import HumanSvg from '@/assets/imgs/VirtualHuman/human.svg';
 
 
 interface HumanBodySvgProps {
-  // 容器样式(覆盖默认的 .human-container)
-  containerStyle?: React.CSSProperties;
-  
-  // SVG 样式(覆盖默认的 .human-svg)
-  svgStyle?: React.CSSProperties;
-  
-  // 自定义类名(追加到默认类名)
-  className?: string;
-  
-  // 完全自定义的内联样式
-  style?: React.CSSProperties;
+    // 容器样式(覆盖默认的 .human-container)
+    containerStyle?: React.CSSProperties;
+
+    // SVG 样式(覆盖默认的 .human-svg)
+    svgStyle?: React.CSSProperties;
+
+    // 自定义类名(追加到默认类名)
+    className?: string;
+
+    // 完全自定义的内联样式
+    style?: React.CSSProperties;
 }
 
 
@@ -45,32 +45,27 @@ const HumanBody: React.FC<HumanBodySvgProps> = ({
         (state: RootState) => state.selection.selected
     );
 
-    const bringToFront = (el: SVGElement) => {
-        const parent = el.parentNode;
-        if (!parent) return;
-        parent.appendChild(el);
-    };
-
-    const handleMouseOver = (e: React.MouseEvent<SVGSVGElement>) => {
-        const target = e.target as Element;
-        const partEl = target.closest('[data-part]') as SVGElement | null;
-        if (partEl) {
-            bringToFront(partEl);
-        }
-    };
-
     /**
      * SVG 统一点击入口(事件委托)
      */
     const handleSvgClick = (e: React.MouseEvent<SVGSVGElement>) => {
         const target = e.target as Element;
+        let serverName;
+        // 情况 1:点在 image 上(少数浏览器)
+        if (target.tagName === 'image') {
+            console.log((target as SVGImageElement).dataset.part);
+            serverName= (target as SVGImageElement).dataset.part;
+        }
 
-        // 从当前节点向上找 data-part
-        const partEl = target.closest('[data-part]') as SVGElement | null;
-
-        if (!partEl) return;
+        // 情况 2:点在 g 上
+        if (target.tagName === 'g') {
+            const image = target.querySelector('image[data-part]');
+            if (image) {
+                console.log((image as SVGImageElement).dataset.part);
+                serverName= (image as SVGImageElement).dataset.part;
+            }
+        }
 
-        const serverName = partEl.getAttribute('data-part');
         if (!serverName) return;
 
         console.log('点击身体部位:', serverName);
@@ -137,12 +132,21 @@ const HumanBody: React.FC<HumanBodySvgProps> = ({
           opacity: 0.95;
         }
 
+.human-svg g[data-part] {
+  pointer-events: bounding-box;
+  cursor: pointer;
+  //transition: opacity 0.2s ease, filter 0.2s ease;
+  outline: 1px solid red;
+}
+
         /* 默认状态 */
-        .human-svg [data-part] {
-          cursor: pointer;
-          // opacity: 0.35;
-          transition: opacity 0.2s ease, filter 0.2s ease;
-        }
+        // .human-svg image[data-part] {
+        //   cursor: pointer;
+        //   pointer-events: all;
+        //   // opacity: 0.35;
+        //   transition: opacity 0.2s ease, filter 0.2s ease;
+        //   outline: 1px solid red;
+        // }
 
         /* hover */
         .human-svg [data-part]:hover {
@@ -168,8 +172,7 @@ const HumanBody: React.FC<HumanBodySvgProps> = ({
                 <HumanSvg
                     className="human-svg"
                     style={svgStyle}
-                    onMouseOver={handleMouseOver}
-                    onClick={handleSvgClick}
+                    onMouseDown={handleSvgClick}
                 />
             </div>
         </>

Some files were not shown because too many files changed in this diff