Forráskód Böngészése

Merge branch 'master' of http://www.sysuimars.cn:3000/feiniao/feiniao-farm-h5

lxf 1 hete
szülő
commit
25432dd739

+ 349 - 26
package-lock.json

@@ -30,6 +30,7 @@
         "mars3d-space": "^3.8.8",
         "mars3d-tdt": "^3.8.8",
         "mitt": "^3.0.1",
+        "mqtt": "^5.14.0",
         "node-polyfill-webpack-plugin": "^4.1.0",
         "npm": "^9.2.0",
         "nprogress": "^0.2.0",
@@ -1977,13 +1978,9 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.26.0",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
-      "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
-      "license": "MIT",
-      "dependencies": {
-        "regenerator-runtime": "^0.14.0"
-      },
+      "version": "7.28.3",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz",
+      "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==",
       "engines": {
         "node": ">=6.9.0"
       }
@@ -5159,6 +5156,14 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@types/readable-stream": {
+      "version": "4.0.21",
+      "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.21.tgz",
+      "integrity": "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/retry": {
       "version": "0.12.0",
       "resolved": "https://registry.npmmirror.com/@types/retry/-/retry-0.12.0.tgz",
@@ -5204,11 +5209,9 @@
       "license": "MIT"
     },
     "node_modules/@types/ws": {
-      "version": "8.5.13",
-      "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
-      "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==",
-      "dev": true,
-      "license": "MIT",
+      "version": "8.18.1",
+      "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
+      "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
       "dependencies": {
         "@types/node": "*"
       }
@@ -6273,6 +6276,17 @@
       "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
       "license": "Apache-2.0"
     },
+    "node_modules/abort-controller": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+      "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+      "dependencies": {
+        "event-target-shim": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6.5"
+      }
+    },
     "node_modules/accepts": {
       "version": "1.3.8",
       "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz",
@@ -7019,6 +7033,17 @@
         "node": ">=8"
       }
     },
+    "node_modules/broker-factory": {
+      "version": "3.1.9",
+      "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.9.tgz",
+      "integrity": "sha512-MzvndyD6EcbkBtX4NXm/HfdO1+cOR5ONNdMCXEKfHpxGdMtuDz7+o+nJf7HMtyPH1sUVf/lEIP+DMluC5PgaBQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.28.3",
+        "fast-unique-numbers": "^9.0.23",
+        "tslib": "^2.8.1",
+        "worker-factory": "^7.0.45"
+      }
+    },
     "node_modules/brorand": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -7824,6 +7849,11 @@
         "node": ">= 12"
       }
     },
+    "node_modules/commist": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz",
+      "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw=="
+    },
     "node_modules/commondir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz",
@@ -7965,6 +7995,20 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/concat-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
+      "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
+      "engines": [
+        "node >= 6.0"
+      ],
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.0.2",
+        "typedarray": "^0.0.6"
+      }
+    },
     "node_modules/concaveman": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz",
@@ -8648,10 +8692,9 @@
       "license": "MIT"
     },
     "node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+      "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
       "dependencies": {
         "ms": "^2.1.3"
       },
@@ -10015,6 +10058,14 @@
         "node": ">=4.0.0"
       }
     },
+    "node_modules/event-target-shim": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+      "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/eventemitter3": {
       "version": "4.0.7",
       "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
@@ -10324,6 +10375,18 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/fast-unique-numbers": {
+      "version": "9.0.23",
+      "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.23.tgz",
+      "integrity": "sha512-jcRIaHo46nfvyvKRMaFSKXmez4jALQ3Qw49gxM5F4siz8HqkyKPPEexpCOYwBSJI1HovrDr4fEedM8QAJ7oX3w==",
+      "dependencies": {
+        "@babel/runtime": "^7.28.3",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18.2.0"
+      }
+    },
     "node_modules/fast-uri": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
@@ -11056,6 +11119,11 @@
         "he": "bin/he"
       }
     },
+    "node_modules/help-me": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
+      "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="
+    },
     "node_modules/highlight.js": {
       "version": "10.7.3",
       "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
@@ -11445,6 +11513,14 @@
       "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==",
       "license": "MIT"
     },
+    "node_modules/ip-address": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
+      "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/ipaddr.js": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz",
@@ -11881,6 +11957,15 @@
         "node": ">=0.6.0"
       }
     },
+    "node_modules/js-sdsl": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
+      "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/js-sdsl"
+      }
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -12928,6 +13013,159 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/mqtt": {
+      "version": "5.14.0",
+      "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.14.0.tgz",
+      "integrity": "sha512-H7EmeCJhbGblbWjm6APF5sAH3SkdI7lxHw/UkblZp8fjSNl8b2MsLcdAkIaQKxvZYmiORkdAjffvKjqQWPkd6w==",
+      "dependencies": {
+        "@types/readable-stream": "^4.0.21",
+        "@types/ws": "^8.18.1",
+        "commist": "^3.2.0",
+        "concat-stream": "^2.0.0",
+        "debug": "^4.4.1",
+        "help-me": "^5.0.0",
+        "lru-cache": "^10.4.3",
+        "minimist": "^1.2.8",
+        "mqtt-packet": "^9.0.2",
+        "number-allocator": "^1.0.14",
+        "readable-stream": "^4.7.0",
+        "rfdc": "^1.4.1",
+        "socks": "^2.8.6",
+        "split2": "^4.2.0",
+        "worker-timers": "^8.0.23",
+        "ws": "^8.18.3"
+      },
+      "bin": {
+        "mqtt": "build/bin/mqtt.js",
+        "mqtt_pub": "build/bin/pub.js",
+        "mqtt_sub": "build/bin/sub.js"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/mqtt-packet": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.2.tgz",
+      "integrity": "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==",
+      "dependencies": {
+        "bl": "^6.0.8",
+        "debug": "^4.3.4",
+        "process-nextick-args": "^2.0.1"
+      }
+    },
+    "node_modules/mqtt-packet/node_modules/bl": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.2.tgz",
+      "integrity": "sha512-6J3oG82fpJ71WF4l0W6XslkwAPMr+Zcp+AmdxJ0L8LsXNzFeO8GYesV2J9AzGArBjrsb2xR50Ocbn/CL1B44TA==",
+      "dependencies": {
+        "@types/readable-stream": "^4.0.0",
+        "buffer": "^6.0.3",
+        "inherits": "^2.0.4",
+        "readable-stream": "^4.2.0"
+      }
+    },
+    "node_modules/mqtt-packet/node_modules/buffer": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+      "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.2.1"
+      }
+    },
+    "node_modules/mqtt-packet/node_modules/readable-stream": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+      "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+      "dependencies": {
+        "abort-controller": "^3.0.0",
+        "buffer": "^6.0.3",
+        "events": "^3.3.0",
+        "process": "^0.11.10",
+        "string_decoder": "^1.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/mqtt/node_modules/buffer": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+      "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.2.1"
+      }
+    },
+    "node_modules/mqtt/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+    },
+    "node_modules/mqtt/node_modules/readable-stream": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+      "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+      "dependencies": {
+        "abort-controller": "^3.0.0",
+        "buffer": "^6.0.3",
+        "events": "^3.3.0",
+        "process": "^0.11.10",
+        "string_decoder": "^1.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/mqtt/node_modules/ws": {
+      "version": "8.18.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+      "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/mrmime": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-1.0.1.tgz",
@@ -16118,6 +16356,15 @@
         "url": "https://github.com/fb55/nth-check?sponsor=1"
       }
     },
+    "node_modules/number-allocator": {
+      "version": "1.0.14",
+      "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
+      "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
+      "dependencies": {
+        "debug": "^4.3.1",
+        "js-sdsl": "4.3.0"
+      }
+    },
     "node_modules/object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
@@ -17943,12 +18190,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/regenerator-runtime": {
-      "version": "0.14.1",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
-      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
-      "license": "MIT"
-    },
     "node_modules/regenerator-transform": {
       "version": "0.15.0",
       "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz",
@@ -18141,6 +18382,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/rfdc": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+      "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="
+    },
     "node_modules/rgbcolor": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
@@ -18810,6 +19056,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/smart-buffer": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+      "engines": {
+        "node": ">= 6.0.0",
+        "npm": ">= 3.0.0"
+      }
+    },
     "node_modules/sockjs": {
       "version": "0.3.24",
       "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@@ -18822,6 +19077,19 @@
         "websocket-driver": "^0.7.4"
       }
     },
+    "node_modules/socks": {
+      "version": "2.8.7",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz",
+      "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
+      "dependencies": {
+        "ip-address": "^10.0.1",
+        "smart-buffer": "^4.2.0"
+      },
+      "engines": {
+        "node": ">= 10.0.0",
+        "npm": ">= 3.0.0"
+      }
+    },
     "node_modules/sort-asc": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz",
@@ -18952,6 +19220,14 @@
       "integrity": "sha512-4OM2BJgC5UzrhVnnJA4BkHKGtjXNzzUfpQjCO8I05xYPsfS/VuQDwjCGGMi8rYQilHEV4j8NBqTFbls/PZEE7A==",
       "license": "MIT"
     },
+    "node_modules/split2": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+      "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+      "engines": {
+        "node": ">= 10.x"
+      }
+    },
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -19676,10 +19952,9 @@
       "license": "MIT"
     },
     "node_modules/tslib": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
-      "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
-      "license": "0BSD"
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
     },
     "node_modules/tty-browserify": {
       "version": "0.0.1",
@@ -19736,6 +20011,11 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
+    },
     "node_modules/ufo": {
       "version": "1.5.4",
       "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
@@ -21278,6 +21558,49 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/worker-factory": {
+      "version": "7.0.45",
+      "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.45.tgz",
+      "integrity": "sha512-FFPCiSv7MD6ZDEfiik/ErM8IrIAWajaXhezLyCo3v0FjhUWud6GXnG2BiTE91jLywXGAVCT8IF48Hhr+D/omMw==",
+      "dependencies": {
+        "@babel/runtime": "^7.28.3",
+        "fast-unique-numbers": "^9.0.23",
+        "tslib": "^2.8.1"
+      }
+    },
+    "node_modules/worker-timers": {
+      "version": "8.0.24",
+      "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.24.tgz",
+      "integrity": "sha512-Ydu/7TRHlxIRjYSGDge1F92L7y9kzInpwR4CkocRVObPE0eRqC6d+0GFh52Hm+m520RHVKiytOERtCUu5sQDVQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.28.3",
+        "tslib": "^2.8.1",
+        "worker-timers-broker": "^8.0.10",
+        "worker-timers-worker": "^9.0.10"
+      }
+    },
+    "node_modules/worker-timers-broker": {
+      "version": "8.0.10",
+      "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.10.tgz",
+      "integrity": "sha512-xvo/9GiuduENbJNdWnvZtkriIkjBKKVbMyw7GXvrBu3n1JHemzZgxqaCcCBNlpfXnRXXF4ekqvXWLh1gb65b8w==",
+      "dependencies": {
+        "@babel/runtime": "^7.28.3",
+        "broker-factory": "^3.1.9",
+        "fast-unique-numbers": "^9.0.23",
+        "tslib": "^2.8.1",
+        "worker-timers-worker": "^9.0.10"
+      }
+    },
+    "node_modules/worker-timers-worker": {
+      "version": "9.0.10",
+      "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.10.tgz",
+      "integrity": "sha512-cfCmAkuoN+nGGJShta/g7CQVP3h7rvQA642EQg72fOHCWP5S2P83rLxDiaGv811Hd+19Cgdqt/tpRBIZ5kj/dw==",
+      "dependencies": {
+        "@babel/runtime": "^7.28.3",
+        "tslib": "^2.8.1",
+        "worker-factory": "^7.0.45"
+      }
+    },
     "node_modules/wrap-ansi": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",

+ 1 - 0
package.json

@@ -33,6 +33,7 @@
     "mars3d-space": "^3.8.8",
     "mars3d-tdt": "^3.8.8",
     "mitt": "^3.0.1",
+    "mqtt": "^5.14.0",
     "node-polyfill-webpack-plugin": "^4.1.0",
     "npm": "^9.2.0",
     "nprogress": "^0.2.0",

+ 11 - 0
src/api/modules/ali.js

@@ -0,0 +1,11 @@
+const config = require("../config")
+module.exports = {
+    credential: {
+        url:  config.base_dev_url + "ali/mini_credential",
+        type: "post",
+    },
+    uploadImg: {
+        url:  config.base_dev_url + "lz_tree_image/insert",
+        type: "post",
+    },
+}

+ 20 - 0
src/api/modules/bbs.js

@@ -0,0 +1,20 @@
+const config = require("../config")
+
+module.exports = {
+    list: {
+        url: config.base_dev_url + "bbs_chat_session/list",
+        type: "get",
+    },
+    createSession: {
+        url: config.base_dev_url + "bbs_chat_session/createSession",
+        type: "get",
+    },
+    sendMsg: {
+        url: config.base_dev_url + "bbs_chat_session/send",
+        type: "post",
+    },
+    readUpdate: {
+        url: config.base_dev_url + "bbs_chat_session/readUpdate",
+        type: "get",
+    },
+}

+ 681 - 0
src/components/chatWindow.vue

@@ -0,0 +1,681 @@
+<template>
+    <div class="chat-container">
+        <!-- 聊天消息区域 -->
+        <div class="chat-messages" ref="messagesContainer">
+            <div v-for="(msg, index) in messages" :key="index" class="message" :class="msg.sender">
+                <!-- 对方消息 -->
+                <template v-if="msg.sender === 'received'">
+                    <!-- <div class="avatar">{{ msg.receiverName.charAt(0) }}</div> -->
+                    <el-avatar class="avatar" :size="40" :src="msg.receiverIcon || 'https://birdseye-img.sysuimars.com/birdseye-look-mini/Group%201321316260.png'" />
+                    <img src="" alt="">
+                    <div class="bubble">
+                        <!-- 文本消息 -->
+                        <div v-if="msg.messageType === 'text'" class="content">{{ msg.content }}</div>
+
+                        <!-- 图片消息 -->
+                        <div v-if="msg.messageType === 'image'" class="image-message">
+                            <img :src="msg.content + resize" @click="showImagePreview(msg.content)" :onload="handleImageLoad()" alt="图片" />
+                        </div>
+
+                        <!-- 语音消息 -->
+                        <div v-if="msg.messageType === 'audio'" class="audio-message" @click="playAudio(msg.content)">
+                            <span class="audio-icon">🎵</span>
+                            <span class="duration">{{ msg.duration }}"</span>
+                        </div>
+
+                        <!-- <div class="time">{{ msg.time }}</div> -->
+                    </div>
+                </template>
+
+                <!-- 我方消息 -->
+                <template v-else>
+                    <div class="bubble">
+                        <!-- 文本消息 -->
+                        <div v-if="msg.messageType === 'text'" class="content">{{ msg.content }}</div>
+
+                        <!-- 图片消息 -->
+                        <div v-if="msg.messageType === 'image'" class="image-message">
+                            <img :src="msg.content + resize" @click="showImagePreview(msg.content)" :onload="handleImageLoad()" alt="图片" />
+                        </div>
+
+                        <!-- 语音消息 -->
+                        <div v-if="msg.messageType === 'audio'" class="audio-message" @click="playAudio(msg.content)">
+                            <span class="audio-icon">🎵</span>
+                            <span class="duration">{{ msg.duration }}"</span>
+                        </div>
+
+                        <!-- <div class="time">{{ msg.time }}</div> -->
+                    </div>
+                    <!-- <div class="avatar avatar-r">{{ msg.senderName.charAt(0) }}</div> -->
+                    <el-avatar class="avatar avatar-r" :size="40" :src="msg.senderIcon || 'https://birdseye-img.sysuimars.com/birdseye-look-mini/Group%201321316260.png'" />
+                </template>
+            </div>
+        </div>
+
+        <!-- 输入框区域 -->
+        <div class="input-area">
+            <div class="toolbar">
+                <!-- <button @click="toggleEmojiPicker">😊</button> -->
+                <!-- <button @click="startImageUpload">📷</button> -->
+                <!-- <button
+                    @mousedown="startRecording"
+                    @mouseup="stopRecording"
+                    @touchstart="startRecording"
+                    @touchend="stopRecording"
+                >
+                    🎤
+                </button> -->
+                <el-icon class="link" @click="startImageUpload"><Link /></el-icon>
+                <input type="file" ref="fileInput" accept="image/*" style="display: none" @change="handleImageUpload" />
+            </div>
+
+            <input type="text" v-model="inputMessage" placeholder="请输入你想说的话~" @keyup.enter="sendTextMessage" />
+            <div class="send" @click="sendTextMessage">发送</div>
+
+            <!-- 录音指示器 -->
+            <div v-if="isRecording" class="recording-indicator">
+                <div class="pulse"></div>
+                录音中... {{ recordingDuration }}s
+            </div>
+        </div>
+
+        <!-- Emoji 选择器 -->
+        <div v-if="showEmojiPicker" class="emoji-picker">
+            <span v-for="emoji in emojis" :key="emoji" @click="addEmoji(emoji)">{{ emoji }}</span>
+        </div>
+
+        <!-- 图片预览模态框 -->
+        <div v-if="previewImage" class="image-preview" @click="previewImage = null">
+            <img :src="previewImage" alt="预览" />
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, nextTick, watch, onActivated, onDeactivated } from "vue";
+import { base_img_url2 } from "@/api/config";
+import { getFileExt } from "@/utils/util";
+import UploadFile from "@/utils/upliadFile";
+import MqttClient from "@/plugins/MqttClient";
+
+const resize = "?x-oss-process=image/resize,p_120/format,webp/quality,q_100";
+
+const props = defineProps({
+    text:{
+        type:String,
+        defalut:''
+    },
+    img:{
+        type:String,
+        defalut:''
+    },
+    userId:{
+        type:[String,Number],
+        defalut:''
+    }
+})
+
+const defalutMsg = ref([
+    {
+        sender: "sent",
+        senderIcon: "王",
+        messageType: "text",
+        content:
+            "你好,我叫陈晓晓。有100亩荔枝,30亩桂味,70亩妃子笑,位置在广州市番禺区大学城110号,希望您可以来指导。",
+        time: "上午10:32",
+    },
+])
+
+const curUserId = Number(localStorage.getItem('MINI_USER_ID'))
+const senderIcon = ref('')
+const receiverIcon = ref('')
+const receiverIdVal = ref(null)
+
+//聊天会话
+const createSession = (toUserId,callback) =>{
+    VE_API.bbs.createSession({toUserId}).then((res) => {
+        senderIcon.value = res.data.senderIcon
+        receiverIcon.value = res.data.receiverIcon
+        receiverIdVal.value = res.data.receiverId
+        messages.value = res.data.messages.map(item =>{
+            let content = item.content
+            if(item.messageType==='image'){
+                content = JSON.parse(item.content).originUrl
+            }
+            return {
+                ...item,
+                content,
+                sender:item.senderId===curUserId?'sent':'received',
+                senderIcon:res.data.senderIcon,
+                receiverIcon:res.data.receiverIcon
+            }
+        })
+        setTimeout(()=>{
+            scrollToBottom();
+        },300)
+        callback && callback()
+    });
+}
+
+//发送消息接口
+//类型 text ,file,image
+const sendMsg = (messageType = 'text',content = '',image = {}) =>{
+    const params = {
+        senderId:curUserId,
+        receiverId:userId.value,
+        content,
+        image,
+        messageType
+    }
+    VE_API.bbs.sendMsg(params);
+}
+
+const userId = ref(null)
+
+watch(()=>props.userId,(newValue) =>{
+    if(newValue){
+        userId.value = newValue
+        createSession(newValue,()=>{
+            if(props.text){
+                sendMsg('text',props.text)
+                messages.value.push({
+                    sender: "sent",
+                    senderIcon: senderIcon.value,
+                    messageType: "text",
+                    content:props.text,
+                })
+                if(props.img){
+                    const imgArr = JSON.parse(props.img)
+                    if(imgArr.length){
+                        imgArr.forEach(item =>{
+                            sendMsg('image','',{
+                                originUrl:item
+                            })
+                            messages.value.push({
+                                sender: "sent",
+                                senderIcon: senderIcon.value,
+                                messageType: "image",
+                                content:item,
+                            })
+                        })
+                    }
+                }
+            }
+        })
+        initMqtt()
+    }
+})
+
+onDeactivated(()=>{
+    mqttClient.value.client.end(true);
+})
+
+// mqtt 连接
+const mqttClient = ref(null)
+const messagesContainer = ref(null);
+
+// 消息数据
+const messages = ref();
+
+// 输入相关
+const inputMessage = ref("");
+const fileInput = ref(null);
+const showEmojiPicker = ref(false);
+const emojis = ["😀", "😂", "😍", "👍", "👋", "🎉", "❤️", "🙏"];
+
+// 录音相关
+const isRecording = ref(false);
+const recordingDuration = ref(0);
+const audioChunks = ref([]);
+const mediaRecorder = ref(null);
+const audioContext = ref(null);
+
+function handleImageLoad() {
+    scrollToBottom();
+}
+
+// 图片预览
+const previewImage = ref(null);
+
+// 初始化 mqtt
+const initMqtt = () => {
+    const topics = ['chat/message/'+curUserId]; // 订阅的主题数组
+    mqttClient.value = new MqttClient(topics, (topic, message) => {
+        const obj = JSON.parse(message)
+        if(obj.senderId === receiverIdVal.value){
+            if(obj.messageType==="image"){
+                const img = JSON.parse(obj.content)
+                obj.content = img.originUrl
+            }
+            obj.receiverId = curUserId
+            obj.sender = obj.senderId === curUserId ?'sent':'received',
+            obj.senderIcon = senderIcon.value
+            obj.receiverIcon = receiverIcon.value
+            messages.value.push(obj)
+            
+            scrollToBottom();
+        }
+    });
+
+    mqttClient.value.connect();
+};
+
+// 发送消息
+const sendMessage = (message) => {
+    if(message.messageType === 'text'){
+        sendMsg('text',message.content)
+    }else{
+        sendMsg('image','',{
+            originUrl:message.content
+        })
+    }
+    messages.value.push(message);
+    scrollToBottom();
+};
+
+// 发送文本消息
+const sendTextMessage = () => {
+    if (inputMessage.value.trim()) {
+        const message = {
+            sender: "sent",
+            messageType: "text",
+            senderIcon: senderIcon.value,
+            content: inputMessage.value,
+            time: getCurrentTime(),
+        };
+        sendMessage(message);
+        inputMessage.value = "";
+    }
+};
+
+// 发送图片消息
+const sendImageMessage = (imageUrl) => {
+    const message = {
+        sender: "sent",
+        messageType: "image",
+        senderIcon: senderIcon.value,
+        content: imageUrl,
+        time: getCurrentTime(),
+    };
+    sendMessage(message);
+};
+
+// 发送语音消息
+const sendAudioMessage = (audioUrl, duration) => {
+    const message = {
+        sender: "sent",
+        messageType: "audio",
+        senderIcon: senderIcon.value,
+        content: audioUrl,
+        duration: duration,
+        time: getCurrentTime(),
+    };
+    sendMessage(message);
+};
+
+// 图片处理
+const startImageUpload = () => {
+    fileInput.value.click();
+};
+
+const uploadFileObj = new UploadFile();
+
+const handleImageUpload = (event) => {
+    const file = event.target.files[0];
+    if (file) {
+        // 实际项目中应该上传到服务器,这里使用本地URL模拟
+        const miniUserId = localStorage.getItem('MINI_USER_ID')
+        let ext = getFileExt(file.name);
+        let key = `birdseye-look-mini/${miniUserId}/${new Date().getTime()}.${ext}`;
+        let imageUrl = ''
+        uploadFileObj.put(key, file).then((resFilename) => {
+            imageUrl = base_img_url2 + resFilename;
+            sendImageMessage(imageUrl);
+        });
+        // const imageUrl = URL.createObjectURL(file);
+    }
+};
+
+const showImagePreview = (imageUrl) => {
+    previewImage.value = imageUrl;
+};
+
+// 语音处理
+const startRecording = async () => {
+    try {
+        audioChunks.value = [];
+        recordingDuration.value = 0;
+
+        const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+        mediaRecorder.value = new MediaRecorder(stream);
+        audioContext.value = new (window.AudioContext || window.webkitAudioContext)();
+
+        mediaRecorder.value.ondataavailable = (event) => {
+            if (event.data.size > 0) {
+                audioChunks.value.push(event.data);
+            }
+        };
+
+        mediaRecorder.value.onstop = async () => {
+            const audioBlob = new Blob(audioChunks.value, { type: "audio/wav" });
+            const audioUrl = URL.createObjectURL(audioBlob);
+
+            // 计算录音时长
+            const duration = Math.round(recordingDuration.value);
+
+            // 实际项目中应该上传到服务器,这里使用本地URL模拟
+            sendAudioMessage(audioUrl, duration);
+
+            // 释放资源
+            stream.getTracks().forEach((track) => track.stop());
+        };
+
+        mediaRecorder.value.start();
+        isRecording.value = true;
+
+        // 更新录音计时器
+        const timer = setInterval(() => {
+            recordingDuration.value += 0.1;
+            if (!isRecording.value) {
+                clearInterval(timer);
+            }
+        }, 100);
+    } catch (error) {
+        console.error("录音失败:", error);
+        alert("无法访问麦克风,请检查权限设置");
+    }
+};
+
+const stopRecording = () => {
+    if (mediaRecorder.value && isRecording.value) {
+        mediaRecorder.value.stop();
+        isRecording.value = false;
+    }
+};
+
+const playAudio = (audioUrl) => {
+    const audio = new Audio(audioUrl);
+    audio.play();
+};
+
+// Emoji 处理
+const toggleEmojiPicker = () => {
+    showEmojiPicker.value = !showEmojiPicker.value;
+};
+
+const addEmoji = (emoji) => {
+    inputMessage.value += emoji;
+    showEmojiPicker.value = false;
+};
+
+// 辅助函数
+const getCurrentTime = () => {
+    return new Date().toLocaleTimeString("zh-CN", {
+        hour: "2-digit",
+        minute: "2-digit",
+    });
+};
+
+const scrollToBottom = () => {
+    nextTick(() => {
+        setTimeout(()=>{
+            if (messagesContainer.value) {
+                messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
+            }
+        },300)
+    });
+};
+
+// 生命周期钩子
+onMounted(() => {
+    // scrollToBottom();
+});
+
+onActivated(()=>{
+    if(props.userId){
+       scrollToBottom();
+    }
+})
+</script>
+
+<style scoped lang="scss">
+/* 基础样式(保持之前的不变) */
+.chat-container {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    width: 100%;
+    margin: 0 auto;
+    border: 1px solid #e6e6e6;
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
+    position: relative;
+    box-sizing: border-box;
+    .chat-messages {
+        flex: 1;
+        padding: 12px;
+        overflow-y: auto;
+        background-color: #f5f5f5;
+        box-sizing: border-box;
+        .message {
+            display: flex;
+            margin-bottom: 15px;
+        }
+        .received {
+            justify-content: flex-start;
+            .bubble {
+                background-color: white;
+                border-radius: 0 10px 10px 10px;
+                padding: 10px 15px;
+                box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+            }
+        }
+        .sent {
+            justify-content: flex-end;
+            .bubble {
+                background-color: #2199f8;
+                border-radius: 10px 0 10px 10px;
+                padding: 10px 15px;
+                color: #fff;
+                box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+            }
+        }
+        .avatar {
+            width: 40px;
+            height: 40px;
+            border-radius: 50%;
+            background-color: #07c160;
+            color: white;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin-right: 10px;
+            font-weight: bold;
+        }
+
+        .avatar-r {
+            margin: 0 0 0 10px;
+        }
+        .bubble {
+            max-width: 70%;
+        }
+    }
+}
+
+.content {
+    font-size: 16px;
+    line-height: 1.4;
+}
+
+.time {
+    font-size: 12px;
+    color: #fff;
+    margin-top: 5px;
+    text-align: right;
+}
+
+.input-area {
+    display: flex;
+    align-items: center;
+    padding: 15px 10px;
+    border-top: 1px solid #e6e6e6;
+    background-color: white;
+    position: relative;
+    width: 100%;
+    box-sizing: border-box;
+    input {
+        flex: 1;
+        padding: 10px;
+        border: 1px solid #e6e6e6;
+        border-radius: 20px;
+        outline: none;
+    }
+    .send {
+        margin-left: 10px;
+        padding: 8px 20px;
+        background-color: #07c160;
+        color: white;
+        border: none;
+        border-radius: 20px;
+        cursor: pointer;
+    }
+}
+// .input-area button:hover {
+//     background-color: #06ad56;
+// }
+
+/* 新增的多媒体消息样式 */
+.image-message {
+    img {
+        max-width: 200px;
+        max-height: 200px;
+        border-radius: 8px;
+        cursor: pointer;
+    }
+}
+
+.audio-message {
+    display: flex;
+    align-items: center;
+    padding: 10px 15px;
+    background-color: #f0f0f0;
+    border-radius: 20px;
+    cursor: pointer;
+}
+
+.audio-message .audio-icon {
+    margin-right: 8px;
+    font-size: 20px;
+}
+
+.audio-message .duration {
+    font-size: 14px;
+    color: #666;
+}
+
+.message.sent .audio-message {
+    background-color: #d8f1cb;
+}
+
+/* 工具栏样式 */
+.toolbar {
+    display: flex;
+    align-items: center;
+    button {
+        background: none;
+        border: none;
+        font-size: 20px;
+        margin-right: 10px;
+        cursor: pointer;
+        padding: 5px;
+    }
+    .link {
+        font-size: 24px;
+        margin-right: 10px;
+    }
+}
+
+/* 录音指示器 */
+.recording-indicator {
+    position: absolute;
+    top: -40px;
+    left: 0;
+    right: 0;
+    background-color: #ff4d4f;
+    color: white;
+    padding: 8px;
+    text-align: center;
+    border-radius: 4px;
+    font-size: 14px;
+}
+
+.recording-indicator .pulse {
+    display: inline-block;
+    width: 10px;
+    height: 10px;
+    border-radius: 50%;
+    background: white;
+    margin-right: 8px;
+    animation: pulse 1.5s infinite;
+}
+
+@keyframes pulse {
+    0% {
+        transform: scale(0.95);
+        opacity: 1;
+    }
+    50% {
+        transform: scale(1.1);
+        opacity: 0.7;
+    }
+    100% {
+        transform: scale(0.95);
+        opacity: 1;
+    }
+}
+
+/* Emoji 选择器 */
+.emoji-picker {
+    position: absolute;
+    bottom: 60px;
+    right: 10px;
+    background: white;
+    border: 1px solid #e6e6e6;
+    border-radius: 8px;
+    padding: 10px;
+    display: grid;
+    grid-template-columns: repeat(4, 1fr);
+    gap: 8px;
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+    z-index: 100;
+}
+
+.emoji-picker span {
+    font-size: 24px;
+    cursor: pointer;
+    text-align: center;
+}
+
+.emoji-picker span:hover {
+    transform: scale(1.2);
+}
+
+/* 图片预览 */
+.image-preview {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: rgba(0, 0, 0, 0.8);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    z-index: 1000;
+}
+
+.image-preview img {
+    max-width: 90%;
+    max-height: 90%;
+    object-fit: contain;
+}
+</style>

+ 72 - 0
src/plugins/MqttClient.js

@@ -0,0 +1,72 @@
+import mqtt from 'mqtt';
+
+class MqttClient {
+  constructor(topics, onMessageCallback) {
+    // 固定参数
+    this.MQTT_MQTTIP = 'wss://ws.emqx.sysuimars.cn/mqtt';
+    this.MQTT_USERNAME = 'admin';
+    this.MQTT_PASSWORD = 'admin';
+    this.topics = topics; // 订阅的主题数组
+    this.onMessageCallback = onMessageCallback; // 接收数据的回调函数
+    this.client = null;
+  }
+
+  connect() {
+    const options = {
+      connectTimeout: 40000,
+      clientId: `clientid-${this.generateClientId()}`, // 生成唯一的客户端 ID
+      username: this.MQTT_USERNAME,
+      password: this.MQTT_PASSWORD,
+      clean: false
+    };
+
+    // 连接 MQTT
+    this.client = mqtt.connect(this.MQTT_MQTTIP, options);
+
+    // 监听连接成功事件
+    this.client.on('connect', () => {
+      console.log('连接成功');
+      this.subscribeToTopics(); // 订阅主题
+    });
+
+    // 监听消息事件
+    this.client.on('message', (topic, message) => {
+      this.onMessageCallback(topic, message.toString()); // 调用回调函数处理消息
+    });
+
+    // 监听重连事件
+    this.client.on('reconnect', (error) => {
+      console.log('正在重连...', error);
+    });
+
+    // 监听错误事件
+    this.client.on('error', (error) => {
+      console.log('连接失败...', error);
+    });
+  }
+
+  // 订阅主题
+  subscribeToTopics() {
+    if (this.topics && this.topics.length > 0) {
+      this.topics.forEach((topic) => {
+        this.client.subscribe(topic, (err) => {
+          if (!err) {
+            console.log(`订阅成功: ${topic}`);
+          } else {
+            console.log(`订阅失败: ${topic}`, err);
+          }
+        });
+      });
+    } else {
+      console.log('未提供订阅主题');
+    }
+  }
+
+  // 生成唯一的客户端 ID
+  generateClientId() {
+    const S4 = () => (((1 + Math.random()) * 0x10000) | 0).toString(32).substring(1);
+    return `${S4()}${S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`;
+  }
+}
+
+export default MqttClient;

+ 7 - 1
src/router/globalRoutes.js

@@ -51,7 +51,13 @@ export default [
         name: "FarmPhoto",
         component: () => import("@/views/old_mini/home/patrolPhoto.vue"),
     },
-    // 咨询专家
+    // 聊天
+    {
+        path: "/chat_frame",
+        name: "ChatFrame",
+        meta: { keepAlive: true },
+        component: () => import("@/views/old_mini/chat_frame/index.vue"),
+    },// 咨询专家
     {
         path: "/expert_list",
         name: "ExpertList",

+ 68 - 0
src/views/old_mini/chat_frame/index.vue

@@ -0,0 +1,68 @@
+<template>
+    <div class="dialogue">
+        <custom-header :name="nameVal" bgColor="#f2f3f5" isGoBack></custom-header>
+        <chat-window :text="desc" :userId="userIdVal" :img="imgVal"></chat-window>
+    </div>
+</template>
+
+<script setup>
+import customHeader from "@/components/customHeader.vue";
+import { onActivated, onDeactivated, ref } from "vue";
+import chatWindow from "@/components/chatWindow";
+import { useRoute, useRouter } from "vue-router";
+import eventBus from "@/api/eventBus";
+
+const route = useRoute();
+const router = useRouter();
+const desc = ref("");
+const nameVal = ref("韦帮稳 (15913130869)");
+const userIdVal = ref(null);
+const imgVal = ref("");
+onActivated(() => {
+    userIdVal.value = null;
+    eventBus.off("header:goback", headerCallBack);
+    setTimeout(() => {
+        const { text, name, userId, img } = route.query;
+        desc.value = text;
+        nameVal.value = name;
+        userIdVal.value = userId;
+        imgVal.value = img;
+        eventBus.on("header:goback", headerCallBack);
+    }, 100);
+});
+
+function headerCallBack() {
+    if (desc.value) {
+        router.go("-2");
+    } else {
+        router.go("-1");
+    }
+}
+
+onDeactivated(() => {
+    eventBus.off("header:goback", headerCallBack);
+    VE_API.bbs.readUpdate({ targetUserId: userIdVal.value }).then((res) => {
+        if (res.success) {
+            eventBus.emit("isUpdateTotal");
+        }
+    });
+});
+</script>
+
+<style lang="scss" scoped>
+.dialogue {
+    width: 100%;
+    height: calc(100vh - 40px);
+    background: #f2f3f5;
+    box-sizing: border-box;
+    .chat-container {
+        display: flex;
+        flex-direction: column;
+        height: 100%;
+        width: 100%;
+        margin: 0 auto;
+        border: 1px solid #e6e6e6;
+        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
+    }
+}
+</style>

+ 16 - 2
src/views/old_mini/home/components/problemReminder.vue

@@ -15,7 +15,7 @@
                 <div class="options-section">
                     <span class="options-label">您可以选择</span>
                     <div class="options-buttons">
-                        <div class="option-btn">拍照识别</div>
+                        <div class="option-btn" @click="toUpload">拍照识别</div>
                         <div class="option-btn" @click="toPage">咨询专家</div>
                     </div>
                 </div>
@@ -40,11 +40,12 @@
 <script setup>
 import { Popup } from "vant";
 import { ref } from "vue";
+import wx from "weixin-js-sdk";
 import detailDialog from "@/components/detailDialog.vue"
 import { useRouter } from "vue-router";
 const router = useRouter();
 
-const show = ref(true);
+const show = ref(false);
 const noShow = ref(false);
 const noClick = () => {
     show.value = false;
@@ -54,6 +55,19 @@ const yesClick = () => {
     show.value = false;
     detailDialogRef.value.showDialog()
 }
+const dropdownGardenItem = ref({
+    organId:766,
+    periodId:1,
+    wktVal:'wktVal',
+    address:'address',
+    district:'district',
+    name:'荔博园',
+});
+const toUpload = () => {
+    wx.miniProgram.navigateTo({
+        url: `/pages/subPages/carmera/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
+    });
+}
 
 function toPage() {
     router.push("/expert_list")

+ 224 - 35
yarn.lock

@@ -953,12 +953,10 @@
     "@babel/types" "^7.4.4"
     esutils "^2.0.2"
 
-"@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4":
-  version "7.26.0"
-  resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz"
-  integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
-  dependencies:
-    regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.28.3", "@babel/runtime@^7.8.4":
+  version "7.28.3"
+  resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz"
+  integrity sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==
 
 "@babel/template@^7.0.0", "@babel/template@^7.18.6":
   version "7.18.6"
@@ -3056,6 +3054,13 @@
   resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz"
   integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
 
+"@types/readable-stream@^4.0.0", "@types/readable-stream@^4.0.21":
+  version "4.0.21"
+  resolved "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.21.tgz"
+  integrity sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==
+  dependencies:
+    "@types/node" "*"
+
 "@types/retry@0.12.0":
   version "0.12.0"
   resolved "https://registry.npmmirror.com/@types/retry/-/retry-0.12.0.tgz"
@@ -3093,10 +3098,10 @@
   resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz"
   integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
 
-"@types/ws@^8.5.1":
-  version "8.5.13"
-  resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz"
-  integrity sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==
+"@types/ws@^8.18.1", "@types/ws@^8.5.1":
+  version "8.18.1"
+  resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz"
+  integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==
   dependencies:
     "@types/node" "*"
 
@@ -4125,6 +4130,16 @@ bl@^4.0.3, bl@^4.1.0:
     inherits "^2.0.4"
     readable-stream "^3.4.0"
 
+bl@^6.0.8:
+  version "6.1.2"
+  resolved "https://registry.npmjs.org/bl/-/bl-6.1.2.tgz"
+  integrity sha512-6J3oG82fpJ71WF4l0W6XslkwAPMr+Zcp+AmdxJ0L8LsXNzFeO8GYesV2J9AzGArBjrsb2xR50Ocbn/CL1B44TA==
+  dependencies:
+    "@types/readable-stream" "^4.0.0"
+    buffer "^6.0.3"
+    inherits "^2.0.4"
+    readable-stream "^4.2.0"
+
 bluebird@^3.1.1:
   version "3.7.2"
   resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz"
@@ -4210,6 +4225,16 @@ braces@^3.0.3, braces@~3.0.2:
   dependencies:
     fill-range "^7.1.1"
 
+broker-factory@^3.1.9:
+  version "3.1.9"
+  resolved "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.9.tgz"
+  integrity sha512-MzvndyD6EcbkBtX4NXm/HfdO1+cOR5ONNdMCXEKfHpxGdMtuDz7+o+nJf7HMtyPH1sUVf/lEIP+DMluC5PgaBQ==
+  dependencies:
+    "@babel/runtime" "^7.28.3"
+    fast-unique-numbers "^9.0.23"
+    tslib "^2.8.1"
+    worker-factory "^7.0.45"
+
 brorand@^1.0.1, brorand@^1.1.0:
   version "1.1.0"
   resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
@@ -4747,6 +4772,11 @@ commander@2:
   resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
 
+commist@^3.2.0:
+  version "3.2.0"
+  resolved "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz"
+  integrity sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==
+
 common-ancestor-path@^1.0.1:
   version "1.0.1"
 
@@ -4788,6 +4818,16 @@ concat-map@0.0.1:
   resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
   integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
 
+concat-stream@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz"
+  integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==
+  dependencies:
+    buffer-from "^1.0.0"
+    inherits "^2.0.3"
+    readable-stream "^3.0.2"
+    typedarray "^0.0.6"
+
 concaveman@^1.2.1:
   version "1.2.1"
   resolved "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz"
@@ -5165,10 +5205,10 @@ debug@^3.1.1:
   dependencies:
     ms "^2.1.1"
 
-debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0:
-  version "4.4.0"
-  resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
-  integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
+debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1:
+  version "4.4.1"
+  resolved "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz"
+  integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
   dependencies:
     ms "^2.1.3"
 
@@ -5818,20 +5858,19 @@ event-pubsub@4.3.0:
 
 event-target-shim@^5.0.0:
   version "5.0.1"
+  resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
+  integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
 
 eventemitter3@^4.0.0:
   version "4.0.7"
   resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz"
   integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
 
-events@^3.0.0, events@^3.2.0:
+events@^3.0.0, events@^3.2.0, events@^3.3.0:
   version "3.3.0"
   resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
   integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
 
-events@^3.3.0:
-  version "3.3.0"
-
 evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
   version "1.0.3"
   resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz"
@@ -5976,6 +6015,14 @@ fast-levenshtein@^2.0.6:
   resolved "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
   integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
 
+fast-unique-numbers@^9.0.23:
+  version "9.0.23"
+  resolved "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.23.tgz"
+  integrity sha512-jcRIaHo46nfvyvKRMaFSKXmez4jALQ3Qw49gxM5F4siz8HqkyKPPEexpCOYwBSJI1HovrDr4fEedM8QAJ7oX3w==
+  dependencies:
+    "@babel/runtime" "^7.28.3"
+    tslib "^2.8.1"
+
 fast-uri@^3.0.1:
   version "3.0.3"
   resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz"
@@ -6491,6 +6538,11 @@ he@^1.2.0:
   resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
   integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
 
+help-me@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz"
+  integrity sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==
+
 highlight.js@^10.7.1:
   version "10.7.3"
   resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz"
@@ -6683,14 +6735,11 @@ icss-utils@^5.0.0, icss-utils@^5.1.0:
   resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz"
   integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
 
-ieee754@^1.1.12, ieee754@^1.1.13:
+ieee754@^1.1.12, ieee754@^1.1.13, ieee754@^1.2.1:
   version "1.2.1"
   resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
   integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
 
-ieee754@^1.2.1:
-  version "1.2.1"
-
 ignore-walk@^6.0.0:
   version "6.0.0"
   dependencies:
@@ -6767,6 +6816,11 @@ init-package-json@^4.0.1:
     validate-npm-package-license "^3.0.4"
     validate-npm-package-name "^5.0.0"
 
+ip-address@^10.0.1:
+  version "10.0.1"
+  resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz"
+  integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==
+
 ip-regex@^4.1.0:
   version "4.3.0"
 
@@ -7051,6 +7105,11 @@ js-message@1.0.7:
   resolved "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz"
   integrity sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==
 
+js-sdsl@4.3.0:
+  version "4.3.0"
+  resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz"
+  integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==
+
 js-tokens@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
@@ -7447,6 +7506,11 @@ lower-case@^2.0.2:
   dependencies:
     tslib "^2.0.3"
 
+lru-cache@^10.4.3:
+  version "10.4.3"
+  resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"
+  integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
+
 lru-cache@^4.0.1:
   version "4.1.5"
   resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz"
@@ -7719,7 +7783,7 @@ minimatch@^9.0.0:
   dependencies:
     brace-expansion "^2.0.1"
 
-minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
+minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8:
   version "1.2.8"
   resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
   integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@@ -7838,6 +7902,37 @@ module-alias@^2.2.2:
   resolved "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz"
   integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==
 
+mqtt-packet@^9.0.2:
+  version "9.0.2"
+  resolved "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.2.tgz"
+  integrity sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==
+  dependencies:
+    bl "^6.0.8"
+    debug "^4.3.4"
+    process-nextick-args "^2.0.1"
+
+mqtt@^5.14.0:
+  version "5.14.0"
+  resolved "https://registry.npmjs.org/mqtt/-/mqtt-5.14.0.tgz"
+  integrity sha512-H7EmeCJhbGblbWjm6APF5sAH3SkdI7lxHw/UkblZp8fjSNl8b2MsLcdAkIaQKxvZYmiORkdAjffvKjqQWPkd6w==
+  dependencies:
+    "@types/readable-stream" "^4.0.21"
+    "@types/ws" "^8.18.1"
+    commist "^3.2.0"
+    concat-stream "^2.0.0"
+    debug "^4.4.1"
+    help-me "^5.0.0"
+    lru-cache "^10.4.3"
+    minimist "^1.2.8"
+    mqtt-packet "^9.0.2"
+    number-allocator "^1.0.14"
+    readable-stream "^4.7.0"
+    rfdc "^1.4.1"
+    socks "^2.8.6"
+    split2 "^4.2.0"
+    worker-timers "^8.0.23"
+    ws "^8.18.3"
+
 mrmime@^1.0.0:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/mrmime/-/mrmime-1.0.1.tgz"
@@ -8234,6 +8329,14 @@ nth-check@^2.0.1:
   dependencies:
     boolbase "^1.0.0"
 
+number-allocator@^1.0.14:
+  version "1.0.14"
+  resolved "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz"
+  integrity sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==
+  dependencies:
+    debug "^4.3.1"
+    js-sdsl "4.3.0"
+
 object-assign@^4.0.1:
   version "4.1.1"
   resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz"
@@ -9067,7 +9170,7 @@ pretty-error@^4.0.0:
 proc-log@^3.0.0:
   version "3.0.0"
 
-process-nextick-args@~2.0.0:
+process-nextick-args@^2.0.1, process-nextick-args@~2.0.0:
   version "2.0.1"
   resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
   integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
@@ -9360,7 +9463,7 @@ readable-stream@^2.3.8:
     string_decoder "~1.1.1"
     util-deprecate "~1.0.1"
 
-readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
+readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
   version "3.6.0"
   resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
   integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -9377,6 +9480,28 @@ readable-stream@^4.1.0:
     events "^3.3.0"
     process "^0.11.10"
 
+readable-stream@^4.2.0:
+  version "4.7.0"
+  resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz"
+  integrity sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==
+  dependencies:
+    abort-controller "^3.0.0"
+    buffer "^6.0.3"
+    events "^3.3.0"
+    process "^0.11.10"
+    string_decoder "^1.3.0"
+
+readable-stream@^4.7.0:
+  version "4.7.0"
+  resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz"
+  integrity sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==
+  dependencies:
+    abort-controller "^3.0.0"
+    buffer "^6.0.3"
+    events "^3.3.0"
+    process "^0.11.10"
+    string_decoder "^1.3.0"
+
 readdirp@^4.0.1:
   version "4.1.2"
   resolved "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz"
@@ -9406,11 +9531,6 @@ regenerator-runtime@^0.13.7:
   resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
   integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
 
-regenerator-runtime@^0.14.0:
-  version "0.14.1"
-  resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz"
-  integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
-
 regenerator-transform@^0.15.0:
   version "0.15.0"
   resolved "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz"
@@ -9528,6 +9648,11 @@ reusify@^1.0.4:
   resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
   integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
 
+rfdc@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz"
+  integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
+
 rgbcolor@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz"
@@ -9939,6 +10064,8 @@ slice-ansi@^4.0.0:
 
 smart-buffer@^4.2.0:
   version "4.2.0"
+  resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz"
+  integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
 
 sockjs@^0.3.24:
   version "0.3.24"
@@ -9962,6 +10089,14 @@ socks@^2.6.2:
     ip "^2.0.0"
     smart-buffer "^4.2.0"
 
+socks@^2.8.6:
+  version "2.8.7"
+  resolved "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz"
+  integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==
+  dependencies:
+    ip-address "^10.0.1"
+    smart-buffer "^4.2.0"
+
 sort-asc@^0.1.0:
   version "0.1.0"
   resolved "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz"
@@ -10057,6 +10192,11 @@ splaytree@^3.1.0:
   resolved "https://registry.npmjs.org/splaytree/-/splaytree-3.1.2.tgz"
   integrity sha512-4OM2BJgC5UzrhVnnJA4BkHKGtjXNzzUfpQjCO8I05xYPsfS/VuQDwjCGGMi8rYQilHEV4j8NBqTFbls/PZEE7A==
 
+split2@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz"
+  integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==
+
 sprintf-js@~1.0.2:
   version "1.0.3"
   resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
@@ -10138,7 +10278,7 @@ stream-wormhole@^1.0.4:
   resolved "https://registry.npmjs.org/stream-wormhole/-/stream-wormhole-1.1.0.tgz"
   integrity sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==
 
-string_decoder@^1.0.0, string_decoder@^1.1.1:
+string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@^1.3.0:
   version "1.3.0"
   resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
   integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
@@ -10465,10 +10605,10 @@ tr46@~0.0.3:
 treeverse@^3.0.0:
   version "3.0.0"
 
-tslib@^2.0.3, tslib@^2.6.2:
-  version "2.7.0"
-  resolved "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz"
-  integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
+tslib@^2.0.3, tslib@^2.6.2, tslib@^2.8.1:
+  version "2.8.1"
+  resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
+  integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
 
 tslib@2.3.0:
   version "2.3.0"
@@ -10522,6 +10662,11 @@ type-is@~1.6.18:
     media-typer "0.3.0"
     mime-types "~2.1.24"
 
+typedarray@^0.0.6:
+  version "0.0.6"
+  resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
+  integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
+
 ufo@^1.5.4:
   version "1.5.4"
   resolved "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz"
@@ -11133,6 +11278,45 @@ word-wrap@^1.2.3:
   resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz"
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
 
+worker-factory@^7.0.45:
+  version "7.0.45"
+  resolved "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.45.tgz"
+  integrity sha512-FFPCiSv7MD6ZDEfiik/ErM8IrIAWajaXhezLyCo3v0FjhUWud6GXnG2BiTE91jLywXGAVCT8IF48Hhr+D/omMw==
+  dependencies:
+    "@babel/runtime" "^7.28.3"
+    fast-unique-numbers "^9.0.23"
+    tslib "^2.8.1"
+
+worker-timers-broker@^8.0.10:
+  version "8.0.10"
+  resolved "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.10.tgz"
+  integrity sha512-xvo/9GiuduENbJNdWnvZtkriIkjBKKVbMyw7GXvrBu3n1JHemzZgxqaCcCBNlpfXnRXXF4ekqvXWLh1gb65b8w==
+  dependencies:
+    "@babel/runtime" "^7.28.3"
+    broker-factory "^3.1.9"
+    fast-unique-numbers "^9.0.23"
+    tslib "^2.8.1"
+    worker-timers-worker "^9.0.10"
+
+worker-timers-worker@^9.0.10:
+  version "9.0.10"
+  resolved "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.10.tgz"
+  integrity sha512-cfCmAkuoN+nGGJShta/g7CQVP3h7rvQA642EQg72fOHCWP5S2P83rLxDiaGv811Hd+19Cgdqt/tpRBIZ5kj/dw==
+  dependencies:
+    "@babel/runtime" "^7.28.3"
+    tslib "^2.8.1"
+    worker-factory "^7.0.45"
+
+worker-timers@^8.0.23:
+  version "8.0.24"
+  resolved "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.24.tgz"
+  integrity sha512-Ydu/7TRHlxIRjYSGDge1F92L7y9kzInpwR4CkocRVObPE0eRqC6d+0GFh52Hm+m520RHVKiytOERtCUu5sQDVQ==
+  dependencies:
+    "@babel/runtime" "^7.28.3"
+    tslib "^2.8.1"
+    worker-timers-broker "^8.0.10"
+    worker-timers-worker "^9.0.10"
+
 wrap-ansi@^3.0.1:
   version "3.0.1"
   resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz"
@@ -11166,6 +11350,11 @@ ws@^7.3.1:
   resolved "https://registry.npmmirror.com/ws/-/ws-7.5.8.tgz"
   integrity sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==
 
+ws@^8.18.3:
+  version "8.18.3"
+  resolved "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz"
+  integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==
+
 ws@^8.4.2:
   version "8.8.0"
   resolved "https://registry.npmmirror.com/ws/-/ws-8.8.0.tgz"