shaogen1995 14 小時之前
父節點
當前提交
76df2edc9f

+ 115 - 7
project/package-lock.json

@@ -37,6 +37,7 @@
         "redux": "^4.2.0",
         "redux-devtools-extension": "^2.13.9",
         "redux-thunk": "^2.4.1",
+        "relation-graph-react": "^2.2.11",
         "sass": "^1.55.0",
         "swiper": "^11.2.10",
         "typescript": "^4.8.4",
@@ -5905,6 +5906,15 @@
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
+    "node_modules/base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/batch": {
       "version": "0.6.1",
       "resolved": "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz",
@@ -6666,6 +6676,15 @@
         "postcss": "^8.4"
       }
     },
+    "node_modules/css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "license": "MIT",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/css-loader": {
       "version": "6.7.1",
       "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-6.7.1.tgz",
@@ -9868,6 +9887,19 @@
         "webpack": "^5.20.0"
       }
     },
+    "node_modules/html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "license": "MIT",
+      "dependencies": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/htmlparser2": {
       "version": "6.1.0",
       "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz",
@@ -16227,6 +16259,16 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/relation-graph-react": {
+      "version": "2.2.11",
+      "resolved": "https://registry.npmmirror.com/relation-graph-react/-/relation-graph-react-2.2.11.tgz",
+      "integrity": "sha512-eFukFIpYXBnlUDf6KHERX79idqO5nuaZPMQDnN4dJfzBYmAVZaEdmV4Jdw5ddFXIc9OiNJ7qGve+G+11/EQBFg==",
+      "license": "MIT",
+      "dependencies": {
+        "html2canvas": "^1.4.1",
+        "screenfull": "^5.1.0"
+      }
+    },
     "node_modules/renderkid": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz",
@@ -17561,6 +17603,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "license": "MIT",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
@@ -17903,11 +17954,12 @@
       }
     },
     "node_modules/use-sync-external-store": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
-      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+      "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
+      "license": "MIT",
       "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
       }
     },
     "node_modules/util-deprecate": {
@@ -17939,6 +17991,15 @@
         "node": ">= 0.4.0"
       }
     },
+    "node_modules/utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "license": "MIT",
+      "dependencies": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "node_modules/uuid": {
       "version": "8.3.2",
       "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
@@ -23289,6 +23350,11 @@
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
+    "base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
+    },
     "batch": {
       "version": "0.6.1",
       "resolved": "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz",
@@ -23887,6 +23953,14 @@
         "postcss-selector-parser": "^6.0.9"
       }
     },
+    "css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "requires": {
+        "utrie": "^1.0.2"
+      }
+    },
     "css-loader": {
       "version": "6.7.1",
       "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-6.7.1.tgz",
@@ -26320,6 +26394,15 @@
         "tapable": "^2.0.0"
       }
     },
+    "html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "requires": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      }
+    },
     "htmlparser2": {
       "version": "6.1.0",
       "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz",
@@ -31020,6 +31103,15 @@
       "resolved": "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz",
       "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog=="
     },
+    "relation-graph-react": {
+      "version": "2.2.11",
+      "resolved": "https://registry.npmmirror.com/relation-graph-react/-/relation-graph-react-2.2.11.tgz",
+      "integrity": "sha512-eFukFIpYXBnlUDf6KHERX79idqO5nuaZPMQDnN4dJfzBYmAVZaEdmV4Jdw5ddFXIc9OiNJ7qGve+G+11/EQBFg==",
+      "requires": {
+        "html2canvas": "^1.4.1",
+        "screenfull": "^5.1.0"
+      }
+    },
     "renderkid": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz",
@@ -32056,6 +32148,14 @@
         "minimatch": "^3.0.4"
       }
     },
+    "text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "requires": {
+        "utrie": "^1.0.2"
+      }
+    },
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
@@ -32321,9 +32421,9 @@
       }
     },
     "use-sync-external-store": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
-      "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+      "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
       "requires": {}
     },
     "util-deprecate": {
@@ -32352,6 +32452,14 @@
       "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz",
       "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
     },
+    "utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "requires": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "uuid": {
       "version": "8.3.2",
       "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",

+ 1 - 0
project/package.json

@@ -32,6 +32,7 @@
     "redux": "^4.2.0",
     "redux-devtools-extension": "^2.13.9",
     "redux-thunk": "^2.4.1",
+    "relation-graph-react": "^2.2.11",
     "sass": "^1.55.0",
     "swiper": "^11.2.10",
     "typescript": "^4.8.4",

+ 35 - 10
project/public/three/data.js

@@ -8,61 +8,86 @@ const cardNames = [
     id: 1,
     name: '文物的名称1',
     img: '1.png',
-    obj: { 构件: '构件1', 位置: '位置1', 装饰: '装饰1', 材质: '材质1' }
+    obj: { 构件: '构件1', 位置: '位置1', 装饰: '装饰1', 材质: '材质1' },
+    type: '分类二',
+    lines: [
+      { to: 2, text: '1-2' },
+      { to: 3, text: '1-3' },
+      { to: 4, text: '1-4' }
+    ]
   },
   {
     id: 2,
     name: '文物的名称2',
     img: '2.png',
-    obj: { 构件: '构件2', 位置: '位置2', 装饰: '装饰2', 材质: '材质2' }
+    obj: { 构件: '构件2', 位置: '位置2', 装饰: '装饰2', 材质: '材质2' },
+    type: '分类二',
+    lines: [
+      { to: 5, text: '2-5' },
+      { to: 6, text: '2-6' },
+      { to: 7, text: '2-7' }
+    ]
   },
   {
     id: 3,
     name: '文物的名称3',
     img: '3.png',
-    obj: { 构件: '构件3', 位置: '位置3', 装饰: '装饰3', 材质: '材质3' }
+    obj: { 构件: '构件3', 位置: '位置3', 装饰: '装饰3', 材质: '材质3' },
+    type: '分类二'
   },
   {
     id: 4,
     name: '文物的名称4',
     img: '4.png',
-    obj: { 构件: '构件4', 位置: '位置4', 装饰: '装饰4', 材质: '材质4' }
+    obj: { 构件: '构件4', 位置: '位置4', 装饰: '装饰4', 材质: '材质4' },
+    type: '分类二',
+    lines: [
+      { to: 8, text: '4-8' },
+      { to: 9, text: '4-9' },
+      { to: 10, text: '4-10' }
+    ]
   },
   {
     id: 5,
     name: '文物的名称5',
     img: '5.png',
-    obj: { 构件: '构件5', 位置: '位置5', 装饰: '装饰5', 材质: '材质5' }
+    obj: { 构件: '构件5', 位置: '位置5', 装饰: '装饰5', 材质: '材质5' },
+    type: '分类一'
   },
   {
     id: 6,
     name: '文物的名称6',
     img: '6.png',
-    obj: { 构件: '构件6', 位置: '位置6', 装饰: '装饰6', 材质: '材质6' }
+    obj: { 构件: '构件6', 位置: '位置6', 装饰: '装饰6', 材质: '材质6' },
+    type: '分类一'
   },
   {
     id: 7,
     name: '文物的名称7',
     img: '7.png',
-    obj: { 构件: '构件7', 位置: '位置7', 装饰: '装饰7', 材质: '材质7' }
+    obj: { 构件: '构件7', 位置: '位置7', 装饰: '装饰7', 材质: '材质7' },
+    type: '分类一'
   },
   {
     id: 8,
     name: '文物的名称8',
     img: '8.png',
-    obj: { 构件: '构件8', 位置: '位置8', 装饰: '装饰8', 材质: '材质8' }
+    obj: { 构件: '构件8', 位置: '位置8', 装饰: '装饰8', 材质: '材质8' },
+    type: '分类一'
   },
   {
     id: 9,
     name: '文物的名称9',
     img: '9.png',
-    obj: { 构件: '构件9', 位置: '位置9', 装饰: '装饰9', 材质: '材质9' }
+    obj: { 构件: '构件9', 位置: '位置9', 装饰: '装饰9', 材质: '材质9' },
+    type: '分类一'
   },
   {
     id: 10,
     name: '文物的名称10',
     img: '10.png',
-    obj: { 构件: '构件10', 位置: '位置10', 装饰: '装饰10', 材质: '材质10' }
+    obj: { 构件: '构件10', 位置: '位置10', 装饰: '装饰10', 材质: '材质10' },
+    type: '分类一'
   }
 ]
 

+ 1 - 1
project/src/assets/styles/base.css

@@ -118,7 +118,7 @@ textarea {
 }
 .mySorrl::-webkit-scrollbar {
   /*滚动条整体样式*/
-  width: 5px;
+  width: 0.6vw;
   /*高宽分别对应横竖滚动条的尺寸*/
   height: 1px;
 }

+ 17 - 29
project/src/assets/styles/base.less

@@ -13,7 +13,7 @@ video {
   height: 100%;
 }
 
-iframe{
+iframe {
   width: 100%;
   height: 100%;
   border: none;
@@ -33,8 +33,16 @@ html {
 
 body {
   position: relative;
-  font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB',
-    'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
+  font:
+    1em/1.4 'Microsoft Yahei',
+    'PingFang SC',
+    'Avenir',
+    'Segoe UI',
+    'Hiragino Sans GB',
+    'STHeiti',
+    'Microsoft Sans Serif',
+    'WenQuanYi Micro Hei',
+    sans-serif;
   font-size: var(--fontNum);
   height: 100%;
   color: black;
@@ -49,7 +57,6 @@ body {
   background-color: rgba(0, 0, 0, 0.9) !important;
 }
 .ant-image-preview-img-wrapper {
-
   .previewImage {
     width: 100%;
     height: 100%;
@@ -69,7 +76,6 @@ body {
         max-width: 100%;
         max-height: 100%;
         object-fit: contain;
-
       }
     }
     .ImgFromTxt {
@@ -84,10 +90,6 @@ body {
   }
 }
 
-
-
-
-
 #root {
   overflow: hidden;
   margin: auto;
@@ -148,7 +150,7 @@ textarea {
 // 滚动条
 .mySorrl::-webkit-scrollbar {
   /*滚动条整体样式*/
-  width: 5px;
+  width: 0.6vw;
   /*高宽分别对应横竖滚动条的尺寸*/
   height: 1px;
 }
@@ -188,12 +190,14 @@ textarea {
 
 // 默认字体
 .sizeNo {
-  font-family: 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti',
+  font-family:
+    'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti',
     'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif !important;
 }
 
 .adm-auto-center-content {
-  font-family: 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti',
+  font-family:
+    'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti',
     'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif !important;
   font-size: 16px;
   letter-spacing: 3px;
@@ -214,7 +218,6 @@ textarea {
   color: #f1e39e;
 }
 
-
 @keyframes yunShan {
   0% {
     opacity: 1;
@@ -229,7 +232,6 @@ textarea {
   }
 }
 
-
 // 热点页面打开透明的变化
 #HotOpCss {
   animation: HotOpCss 0.5s linear forwards;
@@ -258,7 +260,6 @@ textarea {
 // antd mo 查看图片
 
 @media screen and (orientation: portrait) {
-
   /* 竖屏 */
   .adm-image-viewer-image-wrapper img {
     transform: rotate(90deg) !important;
@@ -292,7 +293,6 @@ textarea {
     }
   }
 
-
   .ant-image-preview-img-wrapper {
     .previewImage {
       position: relative;
@@ -312,8 +312,6 @@ textarea {
     }
   }
 
-
-
   #root .ant-tooltip {
     transform: rotate(0) !important;
     width: 410px !important;
@@ -325,11 +323,7 @@ textarea {
     }
   }
 
-
-
-
   #root .ant-tooltip .tooltip_MT {
-
     .top {
       position: relative;
       width: 100%;
@@ -368,10 +362,8 @@ textarea {
       height: calc(100% - 30px) !important;
     }
   }
-
 }
 
-
 // 热点图标闪动
 .HotIconBase {
   animation: yunShan 2s infinite linear;
@@ -470,10 +462,8 @@ textarea {
     .ant-tooltip-arrow {
       top: 2px !important;
     }
-
   }
 
-
   .ant-tooltip-inner {
     // background: url(../img/tooltipBg.png) no-repeat;
     // background-size: 100% 100%;
@@ -593,7 +583,6 @@ textarea {
     transform: translateX(0);
   }
 
-
   25% {
     transform: translateX(-20px);
   }
@@ -606,7 +595,6 @@ textarea {
     transform: translateX(20px);
   }
 
-
   100% {
     transform: translateX(0);
   }
@@ -800,4 +788,4 @@ textarea {
     /* 10帧:-(10-1)×200 = -1800px */
     transform: translate(-5845px, 0);
   }
-}
+}

二進制
project/src/assets/three/Reset.png


二進制
project/src/assets/three/listBj.png


二進制
project/src/assets/three/type.png


二進制
project/src/assets/three/typeAc.png


+ 43 - 0
project/src/pages/A5view/PageSon/A5atlas/data.ts

@@ -0,0 +1,43 @@
+import { MessageFu } from '@/utils/message'
+import { urlCanRes } from '@/utils/urlCan'
+
+const nodes: any[] = []
+
+const lines: any[] = []
+
+cardNames.forEach(v => {
+  nodes.push({
+    id: v.id + '',
+    text: v.name,
+    data: { name: v.name, img: v.img, lines: v.lines, id: v.id }
+  })
+
+  if (v.lines) {
+    v.lines.forEach((c: any) => {
+      lines.push({
+        from: v.id + '',
+        to: c.to + '',
+        text: c.text,
+        dashType: 2
+      })
+    })
+  }
+})
+
+export const atlData = () => {
+  let objRes: any = {}
+
+  const id = urlCanRes()
+  if (typeof id === 'number') {
+    const obj = cardNames.find(v => v.id === id)
+    if (obj) {
+      objRes = {
+        rootId: id + '',
+        nodes: nodes,
+        lines: lines
+      }
+    } else MessageFu.warning('id错误')
+  } else MessageFu.warning('id错误')
+
+  return objRes
+}

+ 131 - 0
project/src/pages/A5view/PageSon/A5atlas/index.module.scss

@@ -1,4 +1,135 @@
 .A5atlas {
+  position: relative;
+  width: 100%;
+  height: 100%;
+
   :global {
+    .A5Aback {
+      position: absolute;
+      z-index: 5;
+      left: 1.5vw;
+      top: 50%;
+      transform: translateY(-50%);
+      width: 4vw;
+      height: auto;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: auto;
+      }
+      & > div {
+        position: absolute;
+        left: 0;
+        bottom: -22px;
+        width: 100%;
+        text-align: center;
+        color: var(--themeColor2);
+        letter-spacing: 2px;
+        font-size: 18px;
+      }
+    }
+
+    .A5Aloding {
+      left: auto;
+      right: 1.5vw;
+    }
+
+    .A5Amain {
+      width: 100%;
+      height: 100%;
+
+      .relation-graph {
+        background-image: url('../../../../assets/three/background.jpg');
+        background-size: 100% 100%;
+      }
+
+      // 样式重置
+      .relation-graph .rel-map {
+        background-color: transparent;
+      }
+
+      .rel-node-peel {
+        width: 250px;
+        height: 295px;
+      }
+
+      .rel-node-type-node {
+        background-color: transparent !important;
+        display: inline-block;
+        width: 100%;
+        height: 100%;
+        box-shadow: none;
+
+        .A5Arow {
+          display: inline-block;
+          position: relative;
+          width: 200px;
+          height: 238px;
+          background-image: url('../../../../assets/three/bj.png');
+          background-size: 100% 100%;
+          transition: all 0.3s;
+
+          img {
+            pointer-events: none;
+          }
+
+          & > div {
+            position: absolute;
+            top: 9%;
+            left: 5%;
+            width: 90%;
+            height: 72%;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            align-items: center;
+            & > div {
+              color: var(--themeColor2);
+              margin-bottom: 20px;
+              font-size: 18px;
+            }
+            & > img {
+              max-width: 70%;
+              max-height: 50%;
+            }
+          }
+        }
+        // .A5ArowAc {
+        //   transition: all 0.3s;
+        //   transform: scale(1.2);
+        // }
+      }
+
+      .rel-node-peel-checked {
+        .rel-node-checked {
+          box-shadow: none;
+          // transform: scale(1.2);
+          transition: all 0.3s;
+        }
+        /* 当父元素 .rel-node-checked 直接包含一个同时具有 A5ArowAc 和 checked 类的子元素时,匹配该父元素 */
+        .rel-node-checked:has(> .A5ArowAc) {
+          transform: scale(1.2);
+        }
+      }
+      .rel-node {
+        transition: all 0.3s;
+      }
+
+      .c-rg-line-text {
+        font-size: 20px;
+        fill: #fff3c5 !important;
+      }
+
+      .rel-toolbar {
+        display: none;
+        // background-color: rgba(0, 0, 0, 0.6);
+        // .c-current-zoom {
+        //   color: #fff;
+        // }
+      }
+    }
+    .rel-link-peel {
+      pointer-events: none !important;
+    }
   }
 }

+ 101 - 6
project/src/pages/A5view/PageSon/A5atlas/index.tsx

@@ -1,20 +1,115 @@
-import React from 'react'
+import React, { useCallback, useEffect, useRef, useState } from 'react'
 import styles from './index.module.scss'
 import { infoPageIDGet } from '@/utils/locStore'
 import history from '@/utils/history'
+
+import RelationGraph from 'relation-graph-react'
+import { atlData } from './data'
+import { baseOssUrl } from '@/utils/http'
+import { urlCanRes } from '@/utils/urlCan'
+import classNames from 'classnames'
+
 function A5atlas() {
+  // 通过id高亮线条
+  const liangXianFu = useCallback((id: string) => {
+    if (graphRef.current) {
+      setAcId(id)
+      const allLinks: any[] = graphRef.current.getInstance().getLinks()
+      allLinks.forEach(link => {
+        link.relations.forEach((c: any) => {
+          if (c.from === id || c.to === id) {
+            c.opacity = 1
+            c.lineWidth = 3
+          } else {
+            c.opacity = 0.3
+            c.lineWidth = 1
+          }
+        })
+      })
+
+      const arr = graphRef.current.getInstance().getNodes()
+
+      arr.forEach((v1: any) => {
+        // v1.width = 200
+        // v1.height = 238
+        v1.opacity = 0.3
+      })
+
+      const nowObj = graphRef.current.getInstance().getNodeById(id)
+      // console.log('--------', nowObj)
+      // nowObj.width = 250
+      // nowObj.height = 295
+      nowObj.opacity = 1
+      nowObj.targetNodes.forEach((v2: any) => {
+        v2.opacity = 1
+      })
+    }
+  }, [])
+
+  const graphRef = useRef<any>(null)
+
+  const showGraph = useCallback(() => {
+    if (graphRef.current) {
+      graphRef.current.setJsonData(atlData())
+      const id = urlCanRes()
+      if (id) {
+        setTimeout(() => {
+          liangXianFu(id + '')
+        }, 200)
+      }
+    }
+  }, [liangXianFu])
+
+  useEffect(() => {
+    showGraph()
+  }, [showGraph])
+
+  const [acId, setAcId] = useState('0')
+
   return (
     <div className={styles.A5atlas}>
-      <h1 style={{ color: '#fff' }}>图谱页面</h1>
-      <h1
-        style={{ color: '#fff' }}
+      {/* 返回按钮 */}
+      <div
+        className='A5Aback'
         onClick={() => {
           const key = infoPageIDGet()
           history.replace(`/view/${key}`)
         }}
       >
-        返回
-      </h1>
+        <img src={require('@/assets/three/back.png')} alt='' />
+        <div>返回</div>
+      </div>
+
+      {/* 手动重置按钮 */}
+      <div className='A5Aback A5Aloding' onClick={showGraph}>
+        <img src={require('@/assets/three/Reset.png')} alt='' />
+        <div>重置</div>
+      </div>
+
+      <div className={classNames('A5Amain')}>
+        <RelationGraph
+          ref={graphRef}
+          options={{
+            disableDragCanvas: false,
+            defaultLineShape: 3,
+            allowSwitchLineShape: true,
+            allowSwitchJunctionPoint: true,
+            moveToCenterWhenRefresh: true, // 刷新时居中,可选
+            useAnimationWhenRefresh: true // 刷新时使用动画,可选
+          }}
+          nodeSlot={({ node }: any) => (
+            <div
+              className={classNames('A5Arow', acId === node.data.id + '' ? 'A5ArowAc' : '')}
+              onClick={() => liangXianFu(node.data.id + '')}
+            >
+              <div>
+                <div>{node.data.name}</div>
+                <img src={`${baseOssUrl}modelSS/img/${node.data.img}`} alt='' />
+              </div>
+            </div>
+          )}
+        ></RelationGraph>
+      </div>
     </div>
   )
 }

+ 142 - 1
project/src/pages/A5view/PageSon/A5list/index.module.scss

@@ -1,5 +1,146 @@
 .A5list {
-  color: #fff;
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 4% 6% 6% 8%;
   :global {
+    .A5Lback {
+      position: absolute;
+      left: 1.5vw;
+      top: 50%;
+      transform: translateY(-50%);
+      width: 4vw;
+      height: auto;
+      cursor: pointer;
+      img {
+        width: 100%;
+        height: auto;
+      }
+      & > div {
+        position: absolute;
+        left: 0;
+        bottom: -22px;
+        width: 100%;
+        text-align: center;
+        color: var(--themeColor2);
+        letter-spacing: 2px;
+        font-size: 18px;
+      }
+    }
+
+    .A5Ltype {
+      position: absolute;
+      left: 6.5vw;
+      bottom: 1.5vh;
+      display: flex;
+      .A5Lbtn {
+        position: relative;
+        width: auto;
+        height: auto;
+        margin-right: 1vw;
+        cursor: pointer;
+        & > img {
+          pointer-events: none;
+          height: 4vw;
+          width: auto;
+        }
+        & > div {
+          width: 100%;
+          height: 100%;
+          position: absolute;
+          top: 0;
+          left: 0;
+          z-index: 2;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          letter-spacing: 2px;
+          font-size: 24px;
+          color: var(--themeColor);
+        }
+      }
+      .A5LbtnAc {
+        pointer-events: none;
+        & > div {
+          color: var(--themeColor2);
+        }
+      }
+    }
+
+    // 中间主体
+    .A5Lmain {
+      width: 100%;
+      height: 100%;
+      overflow-y: auto;
+      display: flex;
+      flex-wrap: wrap;
+      align-content: flex-start;
+      .A5Lrow {
+        cursor: pointer;
+        width: 24%;
+        min-height: 260px;
+        height: auto;
+        margin-right: 1%;
+        margin-bottom: 2%;
+        position: relative;
+        // background-color: #5d4530;
+        & > img {
+          width: 100%;
+          height: auto;
+        }
+        & > div {
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 100%;
+          height: 100%;
+          z-index: 2;
+          .A5Lrow1 {
+            height: 82%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            padding: 10%;
+            .adm-image-tip {
+              background-color: transparent;
+              svg {
+                width: 100px;
+                height: 100px;
+              }
+            }
+            .adm-image,
+            .adm-image-tip {
+              width: 100%;
+              height: 100%;
+              img {
+                object-fit: contain !important;
+              }
+            }
+            .imgLoding {
+              width: 100%;
+              height: 100%;
+              color: var(--themeColor2);
+              letter-spacing: 3px;
+              font-size: 18px;
+              display: flex;
+              justify-content: center;
+              align-items: center;
+            }
+          }
+          .A5Lrow2 {
+            height: 18%;
+            display: flex;
+            align-items: center;
+            padding: 0 2% 0 4%;
+            letter-spacing: 2px;
+            color: var(--themeColor2);
+            font-size: 18px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+        }
+      }
+    }
   }
 }

+ 67 - 2
project/src/pages/A5view/PageSon/A5list/index.tsx

@@ -1,7 +1,11 @@
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useMemo, useState } from 'react'
 import styles from './index.module.scss'
 import A5win from '../A5win'
 import { infoPageIDSet } from '@/utils/locStore'
+import history from '@/utils/history'
+import classNames from 'classnames'
+import { baseOssUrl } from '@/utils/http'
+import { Image } from 'antd-mobile'
 
 function A5list() {
   const [winId, setWinId] = useState(0)
@@ -10,9 +14,70 @@ function A5list() {
     infoPageIDSet('list')
   }, [])
 
+  const [type, setType] = useState('全部')
+
+  const [typeArr, setTypeArr] = useState<string[]>([])
+
+  useEffect(() => {
+    const arr: string[] = ['全部']
+
+    cardNames.forEach(v => {
+      if (!arr.includes(v.type)) arr.push(v.type)
+    })
+
+    setTypeArr(arr)
+  }, [])
+
+  const list = useMemo(() => {
+    let arr = [...cardNames]
+
+    if (type !== '全部') arr = cardNames.filter(v => v.type === type)
+
+    return arr
+  }, [type])
+
   return (
     <div className={styles.A5list}>
-      <h1 onClick={() => setWinId(1)}>打开弹窗</h1>
+      {/* 返回按钮 */}
+      <div className='A5Lback' onClick={() => history.replace('/view/three')}>
+        <img src={require('@/assets/three/back.png')} alt='' />
+        <div>返回</div>
+      </div>
+
+      {/* 底部分类 */}
+      <div className='A5Ltype'>
+        {typeArr.map((item, index) => (
+          <div
+            key={index}
+            onClick={() => setType(item)}
+            className={classNames('A5Lbtn', type === item ? 'A5LbtnAc' : '')}
+          >
+            <img src={require(`@/assets/three/type${type === item ? 'Ac' : ''}.png`)} alt='' />
+            <div>{item}</div>
+          </div>
+        ))}
+      </div>
+
+      {/* 中级主体 */}
+      <div className='A5Lmain mySorrl'>
+        {list.map(item => (
+          <div className='A5Lrow' key={item.id} onClick={() => setWinId(item.id)}>
+            <img src={require('@/assets/three/listBj.png')} alt='' />
+            <div>
+              <div className='A5Lrow1'>
+                <Image
+                  lazy
+                  src={`${baseOssUrl}modelSS/img/${item.id}.png`}
+                  placeholder={<div className='imgLoding'>加载中...</div>}
+                />
+              </div>
+              <div className='A5Lrow2' title={item.name}>
+                {item.name}
+              </div>
+            </div>
+          </div>
+        ))}
+      </div>
 
       {/* 弹窗页面 */}
       <A5win id={winId} closeFu={() => setWinId(0)} />

+ 47 - 5
project/yarn.lock

@@ -3537,6 +3537,11 @@ balanced-match@^1.0.0:
   resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz"
   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
 
+base64-arraybuffer@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz"
+  integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
+
 batch@0.6.1:
   version "0.6.1"
   resolved "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz"
@@ -4119,6 +4124,13 @@ css-has-pseudo@^3.0.4:
   dependencies:
     postcss-selector-parser "^6.0.9"
 
+css-line-break@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz"
+  integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
+  dependencies:
+    utrie "^1.0.2"
+
 css-loader@^6.5.1:
   version "6.7.1"
   resolved "https://registry.npmmirror.com/css-loader/-/css-loader-6.7.1.tgz"
@@ -6015,6 +6027,14 @@ html-webpack-plugin@^5.5.0:
     pretty-error "^4.0.0"
     tapable "^2.0.0"
 
+html2canvas@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz"
+  integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
+  dependencies:
+    css-line-break "^2.1.0"
+    text-segmentation "^1.0.3"
+
 htmlparser2@^6.1.0:
   version "6.1.0"
   resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz"
@@ -9212,7 +9232,7 @@ react-sortablejs@^6.1.4:
     classnames "2.3.1"
     tiny-invariant "1.2.0"
 
-react@*, "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16", "react@>= 16.3", "react@>= 16.3.0", "react@>= 16.8.0", react@>=15, react@>=16.0.0, react@>=16.11.0, react@>=16.8.0, react@>=16.9.0, react@>=17.0.0:
+react@*, "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", react@^18.0.0, react@^18.2.0, "react@>= 16", "react@>= 16.3", "react@>= 16.3.0", "react@>= 16.8.0", react@>=15, react@>=16.0.0, react@>=16.11.0, react@>=16.8.0, react@>=16.9.0, react@>=17.0.0:
   version "18.2.0"
   resolved "https://registry.npmmirror.com/react/-/react-18.2.0.tgz"
   integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
@@ -9364,6 +9384,14 @@ relateurl@^0.2.7:
   resolved "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz"
   integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==
 
+relation-graph-react@^2.2.11:
+  version "2.2.11"
+  resolved "https://registry.npmmirror.com/relation-graph-react/-/relation-graph-react-2.2.11.tgz"
+  integrity sha512-eFukFIpYXBnlUDf6KHERX79idqO5nuaZPMQDnN4dJfzBYmAVZaEdmV4Jdw5ddFXIc9OiNJ7qGve+G+11/EQBFg==
+  dependencies:
+    html2canvas "^1.4.1"
+    screenfull "^5.1.0"
+
 renderkid@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz"
@@ -9614,7 +9642,7 @@ schema-utils@2.7.0:
     ajv "^6.12.2"
     ajv-keywords "^3.4.1"
 
-screenfull@^5.0.0:
+screenfull@^5.0.0, screenfull@^5.1.0:
   version "5.2.0"
   resolved "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz"
   integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
@@ -10254,6 +10282,13 @@ test-exclude@^6.0.0:
     glob "^7.1.4"
     minimatch "^3.0.4"
 
+text-segmentation@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz"
+  integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
+  dependencies:
+    utrie "^1.0.2"
+
 text-table@^0.2.0:
   version "0.2.0"
   resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz"
@@ -10515,9 +10550,9 @@ url-parse@^1.5.3:
     requires-port "^1.0.0"
 
 use-sync-external-store@^1.0.0, use-sync-external-store@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
-  integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+  version "1.6.0"
+  resolved "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz"
+  integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==
 
 util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
   version "1.0.2"
@@ -10544,6 +10579,13 @@ utils-merge@1.0.1:
   resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz"
   integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
 
+utrie@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz"
+  integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
+  dependencies:
+    base64-arraybuffer "^1.0.2"
+
 uuid@^8.3.2:
   version "8.3.2"
   resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz"