Merge branch 'zxrapp' into 'master'

Zxrapp

See merge request cxcxt/jeecguniapp!27
This commit is contained in:
张 祥瑞 2025-07-18 17:26:53 +08:00
commit 8f0e1585b2
12 changed files with 2678 additions and 104 deletions

View File

@ -76,6 +76,7 @@
"@dcloudio/uni-mp-weixin": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-xhs": "3.0.0-4030620241128001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4030620241128001",
"@stomp/stompjs": "^7.1.1",
"@tanstack/match-sorter-utils": "^8.19.4",
"@tanstack/query-core": "^5.76.0",
"@tanstack/vue-query": "^5.62.16",
@ -101,6 +102,9 @@
"pinia": "2.0.36",
"pinia-plugin-persistedstate": "3.2.1",
"qs": "6.5.3",
"sockjs": "^0.3.24",
"sockjs-client": "^1.6.1",
"stompjs": "^2.3.3",
"tanstack": "^1.0.0",
"tslib": "^2.8.1",
"uni-parse-pages": "^0.0.1",

View File

@ -31,13 +31,13 @@ importers:
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-baidu':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-jd':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-kuaishou':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-lark':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
@ -49,13 +49,16 @@ importers:
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-weixin':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-xhs':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-quickapp-webview':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@stomp/stompjs':
specifier: ^7.1.1
version: 7.1.1
'@tanstack/match-sorter-utils':
specifier: ^8.19.4
version: 8.19.4
@ -131,6 +134,15 @@ importers:
qs:
specifier: 6.5.3
version: 6.5.3
sockjs:
specifier: ^0.3.24
version: 0.3.24
sockjs-client:
specifier: ^1.6.1
version: 1.6.1
stompjs:
specifier: ^2.3.3
version: 2.3.3
tanstack:
specifier: ^1.0.0
version: 1.0.0
@ -170,7 +182,7 @@ importers:
version: 3.4.14
'@dcloudio/uni-automator':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(jest-environment-node@27.5.1)(jest@27.0.4)(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(jest-environment-node@27.5.1)(jest@27.0.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-cli-shared':
specifier: 3.0.0-4030620241128001
version: 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
@ -225,15 +237,6 @@ importers:
'@unocss/preset-legacy-compat':
specifier: ^0.59.4
version: 0.59.4
'@vue/devtools-api':
specifier: ^7.7.6
version: 7.7.6
'@vue/devtools-kit':
specifier: ^7.7.6
version: 7.7.6
'@vue/devtools-shared':
specifier: ^7.7.6
version: 7.7.6
'@vue/runtime-core':
specifier: ^3.4.21
version: 3.5.13
@ -243,9 +246,6 @@ importers:
autoprefixer:
specifier: ^10.4.20
version: 10.4.20(postcss@8.4.49)
birpc:
specifier: ^2.3.0
version: 2.3.0
commitlint:
specifier: ^18.6.1
version: 18.6.1(@types/node@20.17.9)(typescript@5.7.2)
@ -273,18 +273,12 @@ importers:
eslint-plugin-vue:
specifier: ^9.32.0
version: 9.32.0(eslint@8.57.1)
hookable:
specifier: ^5.5.3
version: 5.5.3
mockjs:
specifier: ^1.1.0
version: 1.1.0
openapi-ts-request:
specifier: ^1.1.2
version: 1.1.2(@types/node@20.17.9)(@vue/compiler-sfc@3.5.13)(chokidar@3.6.0)(typescript@5.7.2)
perfect-debounce:
specifier: ^1.0.0
version: 1.0.0
postcss:
specifier: ^8.4.49
version: 8.4.49
@ -1252,12 +1246,14 @@ packages:
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
libc: [gnu]
'@dcloudio/uts-linux-x64-musl@3.0.0-4030620241128001':
resolution: {integrity: sha512-HbuOIYCe0KTzW42oqACQDmSuLWmiEG9zUE3rGpp5QP3MKpcB4wJ5BAOusCt3V02akyVv4/IGToktN8dc9N7+Eg==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@dcloudio/uts-win32-ia32-msvc@3.0.0-4030620241128001':
resolution: {integrity: sha512-pgITm85ya64iJ19mixTUOiYVAyCJQ+V66L5Ue/cmME6CA2dU9DjTtPEP6DdSnoyq9JWcdbQLyVEQkxxtBSOyGA==}
@ -1984,46 +1980,55 @@ packages:
resolution: {integrity: sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.28.0':
resolution: {integrity: sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.28.0':
resolution: {integrity: sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.28.0':
resolution: {integrity: sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-powerpc64le-gnu@4.28.0':
resolution: {integrity: sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.28.0':
resolution: {integrity: sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-s390x-gnu@4.28.0':
resolution: {integrity: sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.28.0':
resolution: {integrity: sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.28.0':
resolution: {integrity: sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-win32-arm64-msvc@4.28.0':
resolution: {integrity: sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==}
@ -2095,6 +2100,9 @@ packages:
'@sinonjs/fake-timers@8.1.0':
resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==}
'@stomp/stompjs@7.1.1':
resolution: {integrity: sha512-chcDs6YkAnKp1FqzwhGvh3i7v0+/ytzqWdKYw6XzINEKAzke/iD00dNgFPWSZEqktHOK+C1gSzXhLkLbARIaZw==}
'@szmarczak/http-timer@4.0.6':
resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
engines: {node: '>=10'}
@ -2958,6 +2966,10 @@ packages:
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
bufferutil@4.0.9:
resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==}
engines: {node: '>=6.14.2'}
builtin-modules@3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
@ -3865,6 +3877,10 @@ packages:
event-emitter@0.3.5:
resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==}
eventsource@2.0.2:
resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==}
engines: {node: '>=12.0.0'}
execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
@ -3920,6 +3936,10 @@ packages:
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
faye-websocket@0.11.4:
resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
engines: {node: '>=0.8.0'}
fb-watchman@2.0.2:
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
@ -4280,6 +4300,9 @@ packages:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
http-parser-js@0.5.10:
resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==}
http-proxy-agent@4.0.1:
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
engines: {node: '>= 6'}
@ -5231,6 +5254,10 @@ packages:
encoding:
optional: true
node-gyp-build@4.8.4:
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true
node-int64@0.4.0:
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
@ -6076,6 +6103,13 @@ packages:
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
engines: {node: '>=10'}
sockjs-client@1.6.1:
resolution: {integrity: sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==}
engines: {node: '>=12'}
sockjs@0.3.24:
resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@ -6146,6 +6180,9 @@ packages:
std-env@3.8.0:
resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
stompjs@2.3.3:
resolution: {integrity: sha512-5l/Ogz0DTFW7TrpHF0LAETGqM/so8UxNJvYZjJKqcX31EVprSQgnGkO80tZctPC/lFBDUrSFiTG3xd0R27XAIA==}
string-hash@1.1.3:
resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==}
@ -6631,6 +6668,10 @@ packages:
url-parse@1.5.10:
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
utf-8-validate@5.0.10:
resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==}
engines: {node: '>=6.14.2'}
utif@2.0.1:
resolution: {integrity: sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==}
@ -6641,6 +6682,10 @@ packages:
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
v8-to-istanbul@8.1.1:
resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==}
engines: {node: '>=10.12.0'}
@ -6820,6 +6865,18 @@ packages:
webpack-virtual-modules@0.6.2:
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
websocket-driver@0.7.4:
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
engines: {node: '>=0.8.0'}
websocket-extensions@0.1.4:
resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==}
engines: {node: '>=0.8.0'}
websocket@1.0.35:
resolution: {integrity: sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==}
engines: {node: '>=4.0.0'}
whatwg-encoding@1.0.5:
resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==}
@ -6952,6 +7009,11 @@ packages:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
yaeti@0.0.6:
resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==}
engines: {node: '>=0.10.32'}
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
@ -8122,7 +8184,7 @@ snapshots:
- ts-node
- vue
'@dcloudio/uni-automator@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(jest-environment-node@27.5.1)(jest@27.0.4)(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))':
'@dcloudio/uni-automator@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(jest-environment-node@27.5.1)(jest@27.0.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))':
dependencies:
'@dcloudio/uni-cli-shared': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
address: 1.2.2
@ -8130,14 +8192,14 @@ snapshots:
debug: 4.3.7
default-gateway: 6.0.3
fs-extra: 10.1.0
jest: 27.0.4
jest: 27.0.4(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-environment-node: 27.5.1
jsonc-parser: 3.3.1
licia: 1.46.0
merge: 2.1.1
qrcode-reader: 1.0.4
qrcode-terminal: 0.12.0
ws: 8.18.0
ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- '@nuxt/kit'
- '@vueuse/core'
@ -8308,13 +8370,13 @@ snapshots:
- ts-node
- vue
'@dcloudio/uni-mp-baidu@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))':
'@dcloudio/uni-mp-baidu@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))':
dependencies:
'@dcloudio/uni-cli-shared': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-compiler': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-vite': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-vue': 3.0.0-4030620241128001
'@dcloudio/uni-mp-weixin': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-weixin': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-shared': 3.0.0-4030620241128001
'@vue/compiler-core': 3.4.21
'@vue/shared': 3.4.21
@ -8322,7 +8384,7 @@ snapshots:
licia: 1.46.0
qrcode-reader: 1.0.4
qrcode-terminal: 0.12.0
ws: 8.18.0
ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- '@nuxt/kit'
- '@vueuse/core'
@ -8372,13 +8434,13 @@ snapshots:
- ts-node
- vue
'@dcloudio/uni-mp-kuaishou@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))':
'@dcloudio/uni-mp-kuaishou@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))':
dependencies:
'@dcloudio/uni-cli-shared': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-compiler': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-vite': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-vue': 3.0.0-4030620241128001
'@dcloudio/uni-mp-weixin': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-weixin': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-shared': 3.0.0-4030620241128001
'@vue/compiler-core': 3.4.21
'@vue/shared': 3.4.21
@ -8473,7 +8535,7 @@ snapshots:
'@dcloudio/uni-shared': 3.0.0-4030620241128001
'@vue/shared': 3.4.21
'@dcloudio/uni-mp-weixin@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))':
'@dcloudio/uni-mp-weixin@3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(bufferutil@4.0.9)(postcss@8.4.49)(rollup@4.28.0)(utf-8-validate@5.0.10)(vue@3.4.21(typescript@5.7.2))':
dependencies:
'@dcloudio/uni-cli-shared': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
'@dcloudio/uni-mp-vite': 3.0.0-4030620241128001(@vueuse/core@11.3.0(vue@3.4.21(typescript@5.7.2)))(postcss@8.4.49)(rollup@4.28.0)(vue@3.4.21(typescript@5.7.2))
@ -8484,7 +8546,7 @@ snapshots:
licia: 1.46.0
qrcode-reader: 1.0.4
qrcode-terminal: 0.12.0
ws: 8.18.0
ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- '@nuxt/kit'
- '@vueuse/core'
@ -8943,7 +9005,7 @@ snapshots:
jest-util: 27.5.1
slash: 3.0.0
'@jest/core@27.5.1':
'@jest/core@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
dependencies:
'@jest/console': 27.5.1
'@jest/reporters': 27.5.1
@ -8957,13 +9019,13 @@ snapshots:
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 27.5.1
jest-config: 27.5.1
jest-config: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-haste-map: 27.5.1
jest-message-util: 27.5.1
jest-regex-util: 27.5.1
jest-resolve: 27.5.1
jest-resolve-dependencies: 27.5.1
jest-runner: 27.5.1
jest-runner: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-runtime: 27.5.1
jest-snapshot: 27.5.1
jest-util: 27.5.1
@ -9551,6 +9613,8 @@ snapshots:
dependencies:
'@sinonjs/commons': 1.8.6
'@stomp/stompjs@7.1.1': {}
'@szmarczak/http-timer@4.0.6':
dependencies:
defer-to-connect: 2.0.1
@ -10696,6 +10760,11 @@ snapshots:
base64-js: 1.5.1
ieee754: 1.2.1
bufferutil@4.0.9:
dependencies:
node-gyp-build: 4.8.4
optional: true
builtin-modules@3.3.0: {}
builtins@5.1.0:
@ -11733,6 +11802,8 @@ snapshots:
d: 1.0.2
es5-ext: 0.10.64
eventsource@2.0.2: {}
execa@5.1.1:
dependencies:
cross-spawn: 7.0.6
@ -11834,6 +11905,10 @@ snapshots:
dependencies:
reusify: 1.0.4
faye-websocket@0.11.4:
dependencies:
websocket-driver: 0.7.4
fb-watchman@2.0.2:
dependencies:
bser: 2.1.1
@ -12251,6 +12326,8 @@ snapshots:
statuses: 2.0.1
toidentifier: 1.0.1
http-parser-js@0.5.10: {}
http-proxy-agent@4.0.1:
dependencies:
'@tootallnate/once': 1.1.2
@ -12557,16 +12634,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
jest-cli@27.5.1:
jest-cli@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
'@jest/core': 27.5.1
'@jest/core': 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
'@jest/test-result': 27.5.1
'@jest/types': 27.5.1
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
import-local: 3.2.0
jest-config: 27.5.1
jest-config: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-util: 27.5.1
jest-validate: 27.5.1
prompts: 2.4.2
@ -12578,7 +12655,7 @@ snapshots:
- ts-node
- utf-8-validate
jest-config@27.5.1:
jest-config@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
'@babel/core': 7.26.0
'@jest/test-sequencer': 27.5.1
@ -12590,13 +12667,13 @@ snapshots:
glob: 7.2.3
graceful-fs: 4.2.11
jest-circus: 27.5.1
jest-environment-jsdom: 27.5.1
jest-environment-jsdom: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-environment-node: 27.5.1
jest-get-type: 27.5.1
jest-jasmine2: 27.5.1
jest-regex-util: 27.5.1
jest-resolve: 27.5.1
jest-runner: 27.5.1
jest-runner: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-util: 27.5.1
jest-validate: 27.5.1
micromatch: 4.0.8
@ -12629,7 +12706,7 @@ snapshots:
jest-util: 27.5.1
pretty-format: 27.5.1
jest-environment-jsdom@27.5.1:
jest-environment-jsdom@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
'@jest/environment': 27.5.1
'@jest/fake-timers': 27.5.1
@ -12637,7 +12714,7 @@ snapshots:
'@types/node': 20.17.9
jest-mock: 27.5.1
jest-util: 27.5.1
jsdom: 16.7.0
jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- bufferutil
- canvas
@ -12750,7 +12827,7 @@ snapshots:
resolve.exports: 1.1.1
slash: 3.0.0
jest-runner@27.5.1:
jest-runner@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
'@jest/console': 27.5.1
'@jest/environment': 27.5.1
@ -12762,7 +12839,7 @@ snapshots:
emittery: 0.8.1
graceful-fs: 4.2.11
jest-docblock: 27.5.1
jest-environment-jsdom: 27.5.1
jest-environment-jsdom: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
jest-environment-node: 27.5.1
jest-haste-map: 27.5.1
jest-leak-detector: 27.5.1
@ -12872,11 +12949,11 @@ snapshots:
merge-stream: 2.0.0
supports-color: 8.1.1
jest@27.0.4:
jest@27.0.4(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
'@jest/core': 27.5.1
'@jest/core': 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
import-local: 3.2.0
jest-cli: 27.5.1
jest-cli: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- bufferutil
- canvas
@ -12916,7 +12993,7 @@ snapshots:
dependencies:
argparse: 2.0.1
jsdom@16.7.0:
jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
abab: 2.0.6
acorn: 8.14.0
@ -12943,7 +13020,7 @@ snapshots:
whatwg-encoding: 1.0.5
whatwg-mimetype: 2.3.0
whatwg-url: 8.7.0
ws: 7.5.10
ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)
xml-name-validator: 3.0.0
transitivePeerDependencies:
- bufferutil
@ -13343,6 +13420,9 @@ snapshots:
dependencies:
whatwg-url: 5.0.0
node-gyp-build@4.8.4:
optional: true
node-int64@0.4.0: {}
node-readfiles@0.2.0:
@ -14264,6 +14344,22 @@ snapshots:
astral-regex: 2.0.0
is-fullwidth-code-point: 3.0.0
sockjs-client@1.6.1:
dependencies:
debug: 3.2.7
eventsource: 2.0.2
faye-websocket: 0.11.4
inherits: 2.0.4
url-parse: 1.5.10
transitivePeerDependencies:
- supports-color
sockjs@0.3.24:
dependencies:
faye-websocket: 0.11.4
uuid: 8.3.2
websocket-driver: 0.7.4
source-map-js@1.2.1: {}
source-map-support@0.5.21:
@ -14334,6 +14430,12 @@ snapshots:
std-env@3.8.0: {}
stompjs@2.3.3:
optionalDependencies:
websocket: 1.0.35
transitivePeerDependencies:
- supports-color
string-hash@1.1.3: {}
string-length@4.0.2:
@ -14921,6 +15023,11 @@ snapshots:
querystringify: 2.2.0
requires-port: 1.0.0
utf-8-validate@5.0.10:
dependencies:
node-gyp-build: 4.8.4
optional: true
utif@2.0.1:
dependencies:
pako: 1.0.11
@ -14929,6 +15036,8 @@ snapshots:
utils-merge@1.0.1: {}
uuid@8.3.2: {}
v8-to-istanbul@8.1.1:
dependencies:
'@types/istanbul-lib-coverage': 2.0.6
@ -15130,6 +15239,26 @@ snapshots:
webpack-virtual-modules@0.6.2: {}
websocket-driver@0.7.4:
dependencies:
http-parser-js: 0.5.10
safe-buffer: 5.2.1
websocket-extensions: 0.1.4
websocket-extensions@0.1.4: {}
websocket@1.0.35:
dependencies:
bufferutil: 4.0.9
debug: 2.6.9
es5-ext: 0.10.64
typedarray-to-buffer: 3.1.5
utf-8-validate: 5.0.10
yaeti: 0.0.6
transitivePeerDependencies:
- supports-color
optional: true
whatwg-encoding@1.0.5:
dependencies:
iconv-lite: 0.4.24
@ -15228,9 +15357,15 @@ snapshots:
imurmurhash: 0.1.4
signal-exit: 4.1.0
ws@7.5.10: {}
ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10):
optionalDependencies:
bufferutil: 4.0.9
utf-8-validate: 5.0.10
ws@8.18.0: {}
ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10):
optionalDependencies:
bufferutil: 4.0.9
utf-8-validate: 5.0.10
xhr@2.6.0:
dependencies:
@ -15262,6 +15397,9 @@ snapshots:
y18n@5.0.8: {}
yaeti@0.0.6:
optional: true
yallist@3.1.1: {}
yallist@4.0.0: {}

View File

@ -0,0 +1,128 @@
import { http } from '@/utils/http';
// const mqtturl='https://szcx.zyyt.sinopec.com/mqttprod';//
const mqtturl = 'http://10.75.15.246:8899/mqttprod';//使
export function gethomelist(config : object) { //
return http({
url: '/RoomOperation/RoomOperation/gethomelist',
method: 'GET',
data: config
})
}
export function testcontiont(config : object) { //
return http({
url: mqtturl + '/mqttSubclient/mqttSubclient/testgetcontint',
method: 'GET',
data: config
})
}
export function contiontmqtt(config : object) { // mqtt
return http({
url: mqtturl + '/mqtt/mqtttest/getMqttPushClient',
method: 'GET',
data: config
})
}
export function treeRootList(config : object) { //
return http({
url: '/sysdepartwlwcode/sysDepartWlwCode/rootList',
method: 'GET',
data: config
})
}
export function selectfjkzbmforfjid(config : object) { //
return http({
url: '/RoomOperation/RoomOperation/selectfjkzbmforfjid',
method: 'GET',
data: config
})
}
export function createdSwitch(config : object) { //
return http({
url: mqtturl +
"/mqttSubclientCreateSwitch/mqttSubclientCreateSwitch/createdSwitch",
method: 'GET',
data: config
})
}
export function getMqttPushClient(config : object) { //
return http({
url: mqtturl + '/mqtt/mqtttest/getMqttPushClient',
method: 'GET',
data: config
})
}
export function treeChildList(config : object) { //
return http({
url: '/sysdepartwlwcode/sysDepartWlwCode/childList',
method: 'GET',
data: config
})
}
export function listAllRegions(config : object) { //
return http({
url: '/sysdepartwlwcode/sysDepartWlwCode/getWlwTree',
method: 'GET',
data: config
})
}
export function Selecthomelist(config : object) { //
return http({
url: '/RoomOperation/RoomOperation/Selecthomelist',
method: 'GET',
data: config
})
}
export function getsblb(config : object) { //
return http({
url: '/RoomOperation/RoomOperation/getsblb',
method: 'GET',
data: config
})
}
export function subscribeByOneTopic(config : object) { //
return http({
url: mqtturl +'/mqttSubclient/mqttSubclient/subscribeByOneTopic',
method: 'GET',
data: config
})
}
export function pushMqttsubscribeForYKQ(config : object) { //
return http({
url: mqtturl +'/mqttpush/mqtttestpush/pushMqttsubscribeForYKQ',
method: 'GET',
data: config
})
}
export function pushMqttsubscribeforSendInfo(config : object) { //
return http({
url: mqtturl +'/mqttpush/mqtttestpush/pushMqttsubscribeforSendInfo',
method: 'GET',
data: config
})
}
export function pushMqttsubscribe(config : object) { //
return http({
url: mqtturl +'/mqttpush/mqtttestpush/pushMqttsubscribe',
method: 'GET',
data: config
})
}
//-------------------------------------- end-----------------------------------------------------------
//**-------------------------------------------------------------------------------------/

View File

@ -0,0 +1,210 @@
// utils/webSocketService.ts
import { ref, Ref, onUnmounted } from 'vue'
import { Uni } from '@dcloudio/uni-app'
//
type MessageCallback = (message: string) => void
// WebSocket
interface WebSocketService {
connected: Ref<boolean>
connectionStatus: Ref<string>
messages: Ref<any[]>
connectWebSocket: (url: string, destination: string) => void
disconnectWebSocket: () => void
subscribe: (callback: MessageCallback) => () => void
sendMessage: (destination: string, content: string) => void
}
// WebSocket
let webSocketServiceInstance: WebSocketService | null = null
/**
* 创建或获取全局WebSocket服务实例
*/
export default function useWebSocketService(): WebSocketService {
//
if (webSocketServiceInstance) {
return webSocketServiceInstance
}
// WebSocket
const connected = ref(false)
const connectionStatus = ref('未连接')
const messages = ref<any[]>([])
let socketTask: UniApp.SocketTask | null = null
let subscribers: MessageCallback[] = [] //
// STOMP
const buildStompFrame = (command: string, headers: Record<string, string> = {}, body: string = '') => {
let frame = `${command}\n`
for (const [key, value] of Object.entries(headers)) {
frame += `${key}:${value}\n`
}
frame += `\n${body}`
return frame + '\x00'
}
// WebSocket
const connectWebSocket = (url: string, destination: string) => {
if (connected.value) return
connectionStatus.value = '连接中...'
if (socketTask) {
socketTask.close({})
socketTask = null
}
socketTask = uni.connectSocket({
url: url,
protocols: ['v12.stomp', 'v11.stomp'],
success: () => {
console.log('开始连接WebSocket')
},
fail: (err) => {
console.error('连接失败:', err)
connectionStatus.value = '连接失败'
}
})
//
socketTask.onOpen((res) => {
console.log('WebSocket连接已打开', res)
connected.value = true
connectionStatus.value = '连接中...'
// STOMP CONNECT
const connectFrame = buildStompFrame('CONNECT', {
'accept-version': '1.2',
'heart-beat': '10000,10000'
})
socketTask?.send({
data: connectFrame
})
})
//
socketTask.onMessage((res) => {
const data = res.data as string
const [commandLine, ...headerLines] = data.split('\n')
const emptyLineIndex = headerLines.findIndex(line => line === '')
const headers: Record<string, string> = {}
for (let i = 0; i < emptyLineIndex; i++) {
const [key, value] = headerLines[i].split(':')
headers[key] = value
}
const body = headerLines.slice(emptyLineIndex + 1).join('\n').replace(/\x00$/, '')
switch (commandLine) {
case 'CONNECTED':
connectionStatus.value = 'STOMP已连接'
//
const subscribeFrame = buildStompFrame('SUBSCRIBE', {
id: 'sub-0',
destination: destination
})
socketTask?.send({
data: subscribeFrame
})
break
case 'MESSAGE':
//
subscribers.forEach(subscriber => {
subscriber(body)
})
break
case 'ERROR':
console.error('服务器错误:', body)
break
}
})
//
socketTask.onError((err) => {
console.error('WebSocket错误:', err)
connectionStatus.value = '连接错误'
connected.value = false
})
//
socketTask.onClose((closeRes) => {
console.log('WebSocket连接已关闭', closeRes)
connectionStatus.value = '已断开'
connected.value = false
})
}
// WebSocket
const disconnectWebSocket = () => {
if (socketTask) {
// STOMP DISCONNECT
const disconnectFrame = buildStompFrame('DISCONNECT', {
receipt: 'disconnect-receipt'
})
socketTask.send({
data: disconnectFrame,
success: () => {
socketTask?.close({
code: 1000,
reason: '用户手动关闭',
success: () => {
connected.value = false
connectionStatus.value = '已断开'
}
})
}
})
}
}
//
const subscribe = (callback: MessageCallback) => {
subscribers.push(callback)
//
return () => {
subscribers = subscribers.filter(sub => sub !== callback)
}
}
//
const sendMessage = (destination: string, content: string) => {
if (!socketTask || !connected.value) {
console.error('WebSocket未连接')
return
}
// STOMP SEND
const sendFrame = buildStompFrame('SEND', {
destination: destination,
'content-type': 'text/plain'
}, content)
socketTask.send({
data: sendFrame
})
}
//
const service: WebSocketService = {
connected,
connectionStatus,
messages,
connectWebSocket,
disconnectWebSocket,
subscribe,
sendMessage
}
//
webSocketServiceInstance = service
return service
}

View File

@ -0,0 +1,814 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationBarTitleText: '办公室设备列表',
},
}
</route>
<template>
<view class="container">
<!-- 楼层选择器 -->
<wd-row>
<wd-col :span="16">
<wd-col-picker label="选择楼层" prop="type" v-model="typeData" :columns="typeData" @confirm="handleConfirm"
:column-change="columnChange" :display-format="displayFormat" style="width: 99%;" />
</wd-col>
<wd-col :span="8" style="margin-top: 5px;">
<wd-button @click="cleanreset">重置</wd-button>
</wd-col>
</wd-row>
<!-- 设备状态卡片网格 - 两列布局 -->
<!-- 设备状态卡片网格 - 两列布局 -->
<view class="floor-wrapper">
<view v-for="(floor, floorIndex) in filteredFloors" :key="'floor' + floorIndex" class="floor-section">
<view class="room-grid">
<view v-for="(room, roomIndex) in floor.rooms" :key="room.id" class="room-card"
:class="{ 'room-active': room.homezt === 1 }"
@click="jump(`./officehomedevice?id=${room.id}&fjh=${room.fjh}`)">
<text v-if="room.fjh" class="room-number">{{ room.fjh }}</text>
<view class="room-info">
<text class="info-label">所属部门</text>
<text class="info-value">{{ room.ssbmname }}</text>
</view>
</view>
</view>
</view>
</view>
<!--
<view class="connection-section">
<button v-if="!connected" @click="connectWebSocket" class="connect-btn">
连接WebSocket
</button>
<button @click="disconnectWebSocket" class="disconnect-btn">
断开连接
</button>
<text :class="['status', connected ? 'connected' : 'disconnected']">
{{ connectionStatus }}
</text>
</view>
<view class="message-container">
<text class="subtitle">消息记录</text>
<scroll-view scroll-y="true" class="message-list">
<view v-for="(item, index) in messages" :key="index" :class="['message-item', item.type]">
<text class="message-content">{{ item.content }}</text>
</view>
</scroll-view>
</view> -->
</view>
</template>
<script setup>
import {
ref
} from 'vue';
import {
gethomelist,
treeRootList,
contiontmqtt,
selectfjkzbmforfjid,
createdSwitch,
getMqttPushClient,
treeChildList,
listAllRegions,
Selecthomelist
} from '@/api/devicecontrol/officedevice';
// WebSocket
const connected = ref(false);
const message = ref('');
const messages = ref([]);
let socketTask = null;
const filteredFloors = ref([]); //
const treeData = ref([]);
const homelist = ref([]) //
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
//
const selectedKeys = ref([]);
const lastSelectedNode = ref('');
const typeData = ref([])
const data = ref([])
const selectBydata = ref([]) //
const jump = (url) => {
uni.navigateTo({
url: url
});
}
/***-------------------------------开始数据处理------------------------**/
const getmqttdata = async () => {
await getMqttPushClient().then(res => {
console.log("连接mqtt数据服务器----0000000----", res)
})
}
//
const getofficehomelist = async () => {
await gethomelist().then((res) => {
if (res.success) {
homelist.value = res.result.map((item, index) => ({
...item, //
homezt: 0, // homezt0
}));
//
}
}).catch((err) => {
console.log(err);
});
filteredFloors.value = groupByFloor(homelist)
console.log("33333333333333-------", filteredFloors.value)
getAllswitchByids();
}
//
const groupByFloor = (data) => {
console.log("data---", data)
const groups = data.value.reduce((acc, cur) => {
const floorKey = cur.wlwbmcode.slice(-2) //
if (!acc[floorKey]) {
acc[floorKey] = {
level: floorKey,
rooms: []
}
}
acc[floorKey].rooms.push(cur)
return acc
}, {})
return Object.values(groups).sort((a, b) => a.level - b.level)
}
/**
* 操作开关
*
*/
const getAllswitchByids = async () => {
//
for (const item of filteredFloors.value) {
for (const item2 of item.rooms) {
let fjkzbm = await getfjkzbm(item2)
if (fjkzbm) {
await sleep(1000);
let device = await foreachhomedata(fjkzbm);
item2.homezt = device.key2 // 使Vue.set $set
console.log("device----房间号-" + item.homename + "---数据---", device.key2)
} else {
item2.homezt = device.key2 // 使Vue.set
}
}
}
}
const getfjkzbm = async (item) => {
// console.log("5555----------",item.id)
let fjkzbm = {};
//
await selectfjkzbmforfjid({
fjbid: item.id
}).then(res => {
if (res.result.length == 1) {
fjkzbm = res.result[0]
}
})
return fjkzbm
}
const foreachhomedata = async (fjkzbm) => {
let device = {}; // device
const res = await createdSwitch({ // await .then
topic: 's' + fjkzbm.sbkzbm,
qos: 0,
pushMessage: fjkzbm.kgzt
})
if (res) {
device = JSON.parse(res.message)
} else {
console.log("错误房间号--" + fjkzbm + "----")
}
return device
}
const cleanreset = () => {
filteredFloors.value = []
loadtree();
}
//----------------
//
const loadtree = () => {
listAllRegions().then((res) => {
data.value = res.result
typeData.value = [data.value.map(item => {
return {
value: item.id,
label: item.name
}
})]
})
}
function handleConfirm({
value
}) {
// console.log("-----",value)
queryRoomsByDepartments(value);
}
const displayFormat = (selectedItems) => {
if (selectedItems.length > 0) {
return selectedItems[selectedItems.length - 1].label
}
}
const columnChange = ({
selectedItem,
resolve,
finish
}) => {
// console.log("selectedItem---------",selectedItem.value)
const areaData = findChildren(data.value, selectedItem.value)
if (areaData && areaData.length) {
resolve(
areaData.map((item) => {
return {
value: item.id,
label: item.name
}
})
)
} else {
finish()
}
}
const findChildren = (data, code) => {
if (!code) {
return data
}
for (const item of data) {
// console.log("item---",item)
// console.log("item--code-",code)
if (item.id === code) {
return item.children || null
}
if (item.children) {
const childrenResult = findChildren(item.children, code)
if (childrenResult) {
return childrenResult
}
}
}
return null
}
// ID
const queryRoomsByDepartments = async (departmentIds) => {
console.log("departmentIds-----------", departmentIds)
const lastId = departmentIds[departmentIds.length - 1]
console.log("Processing last ID:", lastId)
// //
const res = await Selecthomelist({
id: lastId
})
if (res.success) {
selectBydata.value = res.result;
console.log("selectBydata.value", selectBydata.value)
filteredFloors.value = groupByFloor(selectBydata)
console.log("数据分组-555---", filteredFloors.value[0].rooms)
//
getAllswitchByids()
}
}
//----------------end-----------
//---------------------------end-------------
//
const handlesocketMessage = (jsonString) => {
try {
const messageObj = JSON.parse(jsonString);
// content
if (messageObj.content) {
const device = JSON.parse(messageObj.content);
updatafjzt(messageObj.fjid, device);
}
} catch (e) {
console.error('解析消息出错:', e);
}
}
const updatafjzt = (fjid, device) => {
filteredFloors.value = filteredFloors.value.map(floor => ({
...floor,
rooms: floor.rooms.map(room => room.id === fjid ? {
...room,
homezt: device.key2
} :
room
)
}));
};
//------------------------websocket-----------
// WebSocket使/simple
// const WS_URL = 'http://10.75.15.246:8899/mqttprod/ws/simple';
const WS_URL = 'https://szcx.zyyt.sinopec.com/mqttprod/ws/simple';
//
const connectionStatus = ref('未连接');
// STOMP
const buildStompFrame = (command, headers = {}, body = '') => {
let frame = `${command}\n`;
for (const [key, value] of Object.entries(headers)) {
frame += `${key}:${value}\n`;
}
frame += `\n${body}`;
return frame + '\x00';
};
// WebSocket
const connectWebSocket = () => {
if (connected.value) return;
console.log('正在连接WebSocket...');
connectionStatus.value = '连接中...';
//
if (socketTask) {
socketTask.close({});
socketTask = null;
}
// 2使uni.connectSocket API
socketTask = uni.connectSocket({
url: WS_URL,
protocols: ['v12.stomp', 'v11.stomp'], // STOMP
success: () => {
console.log('开始连接WebSocket');
},
fail: (err) => {
console.error('连接失败:', err);
connectionStatus.value = '连接失败';
messages.value.push({
type: 'error',
content: `连接失败: ${err.errMsg || '未知错误'}`,
timestamp: Date.now()
});
}
});
// 3使uni.onSocketOpensocketTask.onOpen
uni.onSocketOpen((res) => {
console.log('WebSocket连接已打开', res);
connected.value = true;
connectionStatus.value = '已连接';
// STOMP CONNECT
const connectFrame = buildStompFrame('CONNECT', {
'accept-version': '1.2',
'heart-beat': '10000,10000'
});
uni.sendSocketMessage({
data: connectFrame,
success: () => {
messages.value.push({
type: 'system',
content: '已发送STOMP连接请求',
timestamp: Date.now()
});
}
});
});
//
socketTask.onMessage((res) => {
const data = res.data;
console.log('收到原始消息:', data);
// STOMP
const [commandLine, ...headerLines] = data.split('\n');
const emptyLineIndex = headerLines.findIndex(line => line === '');
const headers = {};
for (let i = 0; i < emptyLineIndex; i++) {
const [key, value] = headerLines[i].split(':');
headers[key] = value;
}
const body = headerLines.slice(emptyLineIndex + 1).join('\n').replace(/\x00$/, '');
switch (commandLine) {
case 'CONNECTED':
connectionStatus.value = 'STOMP已连接';
messages.value.push({
type: 'system',
content: `STOMP协议连接成功版本: ${headers.version}`,
timestamp: Date.now()
});
//
const subscribeFrame = buildStompFrame('SUBSCRIBE', {
id: 'sub-0',
destination: '/topic/messages'
});
socketTask.send({
data: subscribeFrame,
success: () => {
messages.value.push({
type: 'system',
content: '已订阅消息主题',
timestamp: Date.now()
});
}
});
break;
case 'MESSAGE':
messages.value.push({
type: 'received',
content: `收到: ${body}`,
timestamp: Date.now()
});
handlesocketMessage(body);
break;
case 'ERROR':
messages.value.push({
type: 'error',
content: `服务器错误: ${body}`,
timestamp: Date.now()
});
break;
default:
messages.value.push({
type: 'system',
content: `未知帧类型: ${commandLine}`,
timestamp: Date.now()
});
}
});
//
//
//
uni.onSocketError((err) => {
console.error('WebSocket错误:', err);
connectionStatus.value = '连接错误';
connected.value = false;
messages.value.push({
type: 'error',
content: `连接错误: ${err.errMsg || '未知错误'}`,
timestamp: Date.now()
});
});
//
uni.onSocketClose((closeRes) => {
console.log('WebSocket连接已关闭', closeRes);
connectionStatus.value = '已断开';
connected.value = false;
messages.value.push({
type: 'system',
content: `WebSocket连接已关闭: ${closeRes.code || ''} ${closeRes.reason || ''}`,
timestamp: Date.now()
});
});
};
//
const sendMessage = () => {
if (!message.value.trim()) {
uni.showToast({
title: '消息不能为空',
icon: 'none'
});
return;
}
// STOMP SEND
const sendFrame = buildStompFrame('SEND', {
destination: '/app/chat',
'content-type': 'text/plain'
}, message.value);
socketTask.send({
data: sendFrame,
success: () => {
messages.value.push({
type: 'sent',
content: `发送: ${message.value}`,
timestamp: Date.now()
});
message.value = '';
},
fail: (err) => {
messages.value.push({
type: 'error',
content: `发送失败: ${err.errMsg}`,
timestamp: Date.now()
});
}
});
};
// WebSocket
const disconnectWebSocket = () => {
if (socketTask) {
// STOMP DISCONNECT
const disconnectFrame = buildStompFrame('DISCONNECT', {
receipt: 'disconnect-receipt'
});
socketTask.send({
data: disconnectFrame,
success: () => {
socketTask.close({
code: 1000,
reason: '用户手动关闭',
success: () => {
console.log('WebSocket已关闭');
connected.value = false;
connectionStatus.value = '已断开';
messages.value.push({
type: 'system',
content: '连接已安全关闭',
timestamp: Date.now()
});
}
});
}
});
}
}
onMounted(() => {
loadtree();
connectWebSocket();
getmqttdata();
// getofficehomelist();
})
onUnload(() => {
disconnectWebSocket();
})
</script>
<style>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.page-container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
max-width: 750rpx;
margin: 0 auto;
}
/* 楼层容器 */
.floor-wrapper {
display: flex;
flex-direction: column;
/* 移除 flex-direction: column使用默认的 row但实际楼层是纵向排列的这里可能需要恢复 column否则楼层会横向排列 */
gap: 30rpx;
width: 100%;
box-sizing: border-box;
padding: 0 20rpx;
/* 可选:给整体加边距,避免贴边 */
}
.floor-section {
width: 100%;
box-sizing: border-box;
/* background-color: #fff; */
border-radius: 16rpx;
overflow: hidden;
/* box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); */
}
/* 移除原有的.room-grid样式替换为以下 */
.room-grid {
display: grid;
/* 每列占50%宽度减去间距的一半避免总宽度超100% */
grid-template-columns: repeat(2, calc(50% - 10rpx));
/* 假设间距20rpx每列减10rpx */
gap: 20rpx;
/* 列之间的间距 */
padding: 20rpx;
width: 100%;
box-sizing: border-box;
/* 确保padding不增加总宽度 */
}
/* 房间卡片样式优化 */
.room-card {
width: 100%;
/* 强制卡片占满列宽50% - 10rpx */
box-sizing: border-box;
background-color: #fff;
border: 1px solid #eee;
border-radius: 12rpx;
padding: 25rpx;
min-height: 140rpx;
display: flex;
flex-direction: column;
justify-content: center;
transition: all 0.3s ease;
}
.room-card.room-active {
background-color: #e6f7ee;
border-color: #b7eb8f;
}
.room-card:active {
transform: scale(0.98);
}
/* 房间号样式 */
.room-number {
font-size: 34rpx;
font-weight: 600;
color: #333;
margin-bottom: 15rpx;
display: block;
}
/* 房间信息样式 */
.room-info {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.info-label {
font-size: 26rpx;
color: #666;
}
.info-value {
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 响应式布局调整 */
@media (max-width: 375px) {
.room-grid {
grid-template-columns: 1fr;
}
}
/* 以下为websocket连接样式 */
.connection-section {
display: flex;
align-items: center;
margin-bottom: 30rpx;
padding: 20rpx;
background-color: white;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.connect-btn,
.disconnect-btn {
width: 300rpx;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10rpx;
font-size: 32rpx;
margin-right: 20rpx;
}
.connect-btn {
background-color: #2ecc71;
color: white;
}
.disconnect-btn {
background-color: #e74c3c;
color: white;
}
.status {
flex: 1;
font-size: 32rpx;
font-weight: 500;
text-align: center;
}
.connected {
color: #27ae60;
}
.disconnected {
color: #e74c3c;
}
.input-section {
display: flex;
margin-bottom: 30rpx;
}
.input {
flex: 1;
height: 90rpx;
padding: 0 20rpx;
border: 1rpx solid #ddd;
border-radius: 10rpx;
background-color: white;
font-size: 32rpx;
}
.send-btn {
width: 160rpx;
height: 90rpx;
margin-left: 20rpx;
background-color: #3498db;
color: white;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
}
.send-btn:disabled {
background-color: #bdc3c7;
}
.message-container {
flex: 1;
background-color: white;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
}
.subtitle {
font-size: 34rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #2c3e50;
}
.message-list {
flex: 1;
padding: 10rpx;
background-color: #f9f9f9;
border-radius: 10rpx;
max-height: 60vh;
}
.message-item {
padding: 20rpx;
border-bottom: 1rpx solid #eee;
display: flex;
flex-direction: column;
margin-bottom: 10rpx;
}
.message-item.sent {
background-color: #e3f2fd;
border-radius: 8rpx;
}
.message-item.received {
background-color: #e8f5e9;
border-radius: 8rpx;
}
.message-item.system {
background-color: #fffde7;
border-radius: 8rpx;
}
.message-item.error {
background-color: #ffebee;
border-radius: 8rpx;
}
.message-content {
font-size: 32rpx;
margin-bottom: 10rpx;
word-break: break-all;
}
.message-time {
font-size: 26rpx;
color: #7f8c8d;
align-self: flex-end;
}
</style>

View File

@ -1,44 +1,590 @@
<template>
<PageLayout :navbarShow="false">
<wd-card type="rectangle">
<template #title>
<view class="title">
<view>2020-02-03服务到期</view>
<view class="title-tip">
<wd-icon name="warning" size="14px" custom-style="vertical-align: bottom" />
您可以去电脑上使用该服务
<view class="page-container">
<!-- 设备状态卡片网格 - 两列布局 -->
<view class="floor-wrapper">
<view v-for="(floor, floorIndex) in filteredFloors" :key="'floor' + floorIndex" class="floor-section">
<view class="room-grid">
<view v-for="(room, roomIndex) in floor.rooms" :key="room.id" class="room-card"
:class="{ 'room-active': room.homezt === 1 }"
@click="jump(`./officehomedevice?id=${room.id}&fjh=${room.fjh}`)">
<text v-if="room.fjh" class="room-number">{{ room.fjh }}</text>
<view class="room-info">
<text class="info-label">所属部门</text>
<text class="info-value">{{ room.ssbmname }}</text>
</view>
</view>
</template>
<view style="height: 40px;" class="content">
<image
src="https://img11.360buyimg.com/imagetools/jfs/t1/143248/37/5695/265818/5f3a8546E98d998a4/745897ca9c9e474b.jpg"
width="40"
height="40"
alt="joy"
style="border-radius: 4px; margin-right: 12px;"
/>
<view>
<view style="color: rgba(0,0,0,0.85); font-size: 16px;">智催评营销</view>
<view style="color: rgba(0,0,0,0.25); font-size: 12px;">高级版-快速吸粉 | 周期一年</view>
</view>
</view>
</view>
<!-- <view class="connection-section">
<button v-if="!connected" @click="connectWebSocket" class="connect-btn">
连接WebSocket
</button>
<template #footer>
<view>
<wd-button size="small" style="margin-right: 8px;">评价</wd-button>
<wd-button size="small" plain>立即使用</wd-button>
<button @click="disconnectWebSocket" class="disconnect-btn">
断开连接
</button>
<text :class="['status', connected ? 'connected' : 'disconnected']">
{{ connectionStatus }}
</text>
</view>
<view class="message-container">
<text class="subtitle">消息记录</text>
<scroll-view scroll-y="true" class="message-list">
<view v-for="(item, index) in messages" :key="index" :class="['message-item', item.type]">
<text class="message-content">{{ item.content }}</text>
</view>
</scroll-view>
</view> -->
</view>
</template>
</wd-card>
</PageLayout>
</template>
<script setup>
import {
ref,
onMounted,
onUnmounted
} from 'vue'
import {
gethomelist,
getMqttPushClient,
selectfjkzbmforfjid,
createdSwitch,
listAllRegions,
Selecthomelist
} from '@/api/devicecontrol/officedevice';
import useWebSocketService from '@/api/devicecontrol/webSocketService'
// 0717
const wsService = useWebSocketService()
const unsubscribe = ref(null)
// WebSocket
const connected = ref(false);
const message = ref('');
const messages = ref([]);
let socketTask = null;
const filteredFloors = ref([]); //
const treeData = ref([]);
const homelist = ref([]) //
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
//
const selectedKeys = ref([]);
const lastSelectedNode = ref('');
const typeData = ref([])
const data = ref([])
const selectBydata = ref([]) //
const jump = (url) => {
uni.navigateTo({
url: url
});
}
/***-------------------------------开始数据处理------------------------**/
const getmqttdata = async () => {
await getMqttPushClient().then(res => {
console.log("连接mqtt数据服务器----0000000----", res)
})
}
//
const getofficehomelist = async () => {
await gethomelist().then((res) => {
if (res.success) {
homelist.value = res.result.map((item, index) => ({
...item,
homezt: 0, // homezt0
}));
}
}).catch((err) => {
console.log(err);
});
filteredFloors.value = groupByFloor(homelist)
getAllswitchByids();
}
//
const groupByFloor = (data) => {
const groups = data.value.reduce((acc, cur) => {
const floorKey = cur.wlwbmcode.slice(-2)
if (!acc[floorKey]) {
acc[floorKey] = {
level: floorKey,
rooms: []
}
}
acc[floorKey].rooms.push(cur)
return acc
}, {})
return Object.values(groups).sort((a, b) => a.level - b.level)
}
/**
* 操作开关
*/
const getAllswitchByids = async () => {
//
for (const item of filteredFloors.value) {
for (const item2 of item.rooms) {
let fjkzbm = await getfjkzbm(item2)
if (fjkzbm) {
await sleep(1000);
let device = await foreachhomedata(fjkzbm);
item2.homezt = device.key2
} else {
item2.homezt = 0
}
}
}
}
const getfjkzbm = async (item) => {
let fjkzbm = {};
//
await selectfjkzbmforfjid({
fjbid: item.id
}).then(res => {
if (res.result.length == 1) {
fjkzbm = res.result[0]
}
})
return fjkzbm
}
const foreachhomedata = async (fjkzbm) => {
let device = {};
try { //
const res = await createdSwitch({
topic: 's' + fjkzbm.sbkzbm,
qos: 0,
pushMessage: fjkzbm.kgzt
})
if (res) {
device = JSON.parse(res.message)
} else {
console.log("错误房间号--" + fjkzbm + "----")
}
} catch (error) { //
console.error(`[${fjkzbm}] 请求失败:`, error)
//
// 500 error.response.status
}
return device
}
//----------------
const loadtree = () => {
listAllRegions().then((res) => {
data.value = res.result
typeData.value = [data.value.map(item => {
return {
value: item.id,
label: item.name
}
})]
})
}
function handleConfirm({
value
}) {
queryRoomsByDepartments(value);
}
const displayFormat = (selectedItems) => {
if (selectedItems.length > 0) {
return selectedItems[selectedItems.length - 1].label
}
}
const columnChange = ({
selectedItem,
resolve,
finish
}) => {
const areaData = findChildren(data.value, selectedItem.value)
if (areaData && areaData.length) {
resolve(
areaData.map((item) => {
return {
value: item.id,
label: item.name
}
})
)
} else {
finish()
}
}
const findChildren = (data, code) => {
if (!code) {
return data
}
for (const item of data) {
if (item.id === code) {
return item.children || null
}
if (item.children) {
const childrenResult = findChildren(item.children, code)
if (childrenResult) {
return childrenResult
}
}
}
return null
}
// ID
const queryRoomsByDepartments = async (departmentIds) => {
const lastId = departmentIds[departmentIds.length - 1]
const res = await Selecthomelist({
id: lastId
})
if (res.success) {
selectBydata.value = res.result;
filteredFloors.value = groupByFloor(selectBydata)
getAllswitchByids()
}
}
//----------------end-----------
//
const handlesocketMessage = (jsonString) => {
console.log("1300-----",jsonString)
try {
const messageObj = JSON.parse(jsonString);
// content
if (messageObj.content) {
const device = JSON.parse(messageObj.content);
updatafjzt(messageObj.fjid, device);
}
} catch (e) {
console.error('解析消息出错:', e);
}
}
const updatafjzt = (fjid, device) => {
filteredFloors.value = filteredFloors.value.map(floor => ({
...floor,
rooms: floor.rooms.map(room => room.id === fjid ? {
...room,
homezt: device.key2
} :
room
)
}));
};
//------------------------websocket-----------
// const WS_URL = 'https://szcx.zyyt.sinopec.com/mqttprod/ws/simple';
// const WS_URL = 'http://10.75.15.246:8899/mqttprod/ws/simple';
const connectionStatus = ref('未连接');
// STOMP
const buildStompFrame = (command, headers = {}, body = '') => {
let frame = `${command}\n`;
for (const [key, value] of Object.entries(headers)) {
frame += `${key}:${value}\n`;
}
frame += `\n${body}`;
return frame + '\x00';
};
// WebSocket
const connectWebSocket = () => {
const WS_URL = 'https://szcx.zyyt.sinopec.com/mqttprod/ws/simple'
// const WS_URL = 'http://10.75.15.246:8899/mqttprod/ws/simple';
wsService.connectWebSocket(WS_URL, '/topic/messages')
}
// WebSocket
const disconnectWebSocket = () => {
wsService.disconnectWebSocket()
}
//
unsubscribe.value = wsService.subscribe((message) => {
handlesocketMessage(message)
messages.value.push({
content: message,
type: 'received',
time: new Date().toLocaleTimeString()
})
})
onMounted(() => {
loadtree();
connectWebSocket();
getmqttdata();
getofficehomelist();
})
onUnmounted(() => {
//
if (unsubscribe.value) {
unsubscribe.value()
}
// 使
})
</script>
<style>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.page-container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
max-width: 750rpx;
margin: 0 auto;
}
/* 楼层容器 */
.floor-wrapper {
display: flex;
flex-direction: column;
/* 移除 flex-direction: column使用默认的 row但实际楼层是纵向排列的这里可能需要恢复 column否则楼层会横向排列 */
gap: 30rpx;
width: 100%;
box-sizing: border-box;
padding: 0 20rpx;
/* 可选:给整体加边距,避免贴边 */
}
.floor-section {
width: 100%;
box-sizing: border-box;
/* background-color: #fff; */
border-radius: 16rpx;
overflow: hidden;
/* box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); */
}
/* 移除原有的.room-grid样式替换为以下 */
.room-grid {
display: grid;
/* 每列占50%宽度减去间距的一半避免总宽度超100% */
grid-template-columns: repeat(2, calc(50% - 10rpx));
/* 假设间距20rpx每列减10rpx */
gap: 20rpx;
/* 列之间的间距 */
padding: 20rpx;
width: 100%;
box-sizing: border-box;
/* 确保padding不增加总宽度 */
}
/* 房间卡片样式优化 */
.room-card {
width: 100%;
/* 强制卡片占满列宽50% - 10rpx */
box-sizing: border-box;
background-color: #fff;
border: 1px solid #eee;
border-radius: 12rpx;
padding: 25rpx;
min-height: 140rpx;
display: flex;
flex-direction: column;
justify-content: center;
transition: all 0.3s ease;
}
.room-card.room-active {
background-color: #e6f7ee;
border-color: #b7eb8f;
}
.room-card:active {
transform: scale(0.98);
}
/* 房间号样式 */
.room-number {
font-size: 34rpx;
font-weight: 600;
color: #333;
margin-bottom: 15rpx;
display: block;
}
/* 房间信息样式 */
.room-info {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.info-label {
font-size: 26rpx;
color: #666;
}
.info-value {
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 响应式布局调整 */
@media (max-width: 375px) {
.room-grid {
grid-template-columns: 1fr;
}
}
/* 以下为websocket连接样式 */
.connection-section {
display: flex;
align-items: center;
margin-bottom: 30rpx;
padding: 20rpx;
background-color: white;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.connect-btn,
.disconnect-btn {
width: 300rpx;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10rpx;
font-size: 32rpx;
margin-right: 20rpx;
}
.connect-btn {
background-color: #2ecc71;
color: white;
}
.disconnect-btn {
background-color: #e74c3c;
color: white;
}
.status {
flex: 1;
font-size: 32rpx;
font-weight: 500;
text-align: center;
}
.connected {
color: #27ae60;
}
.disconnected {
color: #e74c3c;
}
.input-section {
display: flex;
margin-bottom: 30rpx;
}
.input {
flex: 1;
height: 90rpx;
padding: 0 20rpx;
border: 1rpx solid #ddd;
border-radius: 10rpx;
background-color: white;
font-size: 32rpx;
}
.send-btn {
width: 160rpx;
height: 90rpx;
margin-left: 20rpx;
background-color: #3498db;
color: white;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
}
.send-btn:disabled {
background-color: #bdc3c7;
}
.message-container {
flex: 1;
background-color: white;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
}
.subtitle {
font-size: 34rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #2c3e50;
}
.message-list {
flex: 1;
padding: 10rpx;
background-color: #f9f9f9;
border-radius: 10rpx;
max-height: 60vh;
}
.message-item {
padding: 20rpx;
border-bottom: 1rpx solid #eee;
display: flex;
flex-direction: column;
margin-bottom: 10rpx;
}
.message-item.sent {
background-color: #e3f2fd;
border-radius: 8rpx;
}
.message-item.received {
background-color: #e8f5e9;
border-radius: 8rpx;
}
.message-item.system {
background-color: #fffde7;
border-radius: 8rpx;
}
.message-item.error {
background-color: #ffebee;
border-radius: 8rpx;
}
.message-content {
font-size: 32rpx;
margin-bottom: 10rpx;
word-break: break-all;
}
.message-time {
font-size: 26rpx;
color: #7f8c8d;
align-self: flex-end;
}
</style>

View File

@ -1,35 +1,87 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationBarTitleText: '办公室设备列表',
},
}
</route>
<template>
<PageLayout navTitle="设备管理">
<PageLayout navTitle="设备管理" :rightButtons="rightButtons">
<!-- <view style="margin: 0 10px;" >
<uni-segmented-control style="margin-top: 10px;margin-bottom: 10px" :current="current" :values="items"
@clickItem="onClickItem" styleType="button"></uni-segmented-control>
</view> -->
<view class="content">
<view v-if="current === 0">
<Personaldevices></Personaldevices>
</view>
<view v-if="current === 1">
<!-- <view class="content" >
<view v-if="current === 0 ">
<Personaldevices></Personaldevices>
</view>
<view v-if="current === 1 ">
<text v-if="!isleader">您目前没有查看该页面权限</text>
<ALLleader v-if="isleader"></ALLleader>
<ALLleader ></ALLleader>
</view>
</view> -->
</PageLayout>
</template>
<script setup>
import Personaldevices from './Personaldevices'
import ALLleader from './ALLleader'
//
import {
useUserStore
} from '@/store/user'
// import { navigateTo } from '@dcloudio/uni-app'
const current = ref(0)
const items = ref(['个人使用房间设备', '全部房间设备'])
const userStore = useUserStore();
const isleader = ref(false)
//
const rightButtons = ref([{
text: '跳转管理端',
fontSize: '14px',
color: '#007AFF',
// icon
// icon: 'https://example.com/icon.png'
}])
//
onNavigationBarButtonTap(() => {
//
uni.navigateTo({
url: '@/pages-home/device-control/office/ALLleader'
})
})
function onClickItem(e) {
console.log("dianji le ---", current.value)
if (current.value != e.currentIndex) {
current.value = e.currentIndex;
}
}
onLoad(() => {
//
// f6817f48af4fb3af11b9e8bf182f618b
//1455737078531104770
//1455737215009562625
//1455737513371377665
//1358226526012129281
console.log("当前登陆人信息000", userStore.userInfo.roles)
console.log("当前登陆人信息222222222222", userStore.userInfo.roles.split(","))
for (let a = 0; a < userStore.userInfo.roles.split(",").length; a++) {
console.log("userStore.userInfo.roles.split(", ")[a]", userStore.userInfo.roles.split(",")[a])
let rolesid = userStore.userInfo.roles.split(",")[a];
if (rolesid == "1455737078531104770" || rolesid ==
"f6817f48af4fb3af11b9e8bf182f618b" || rolesid ==
"1455737215009562625" || rolesid ==
"1455737513371377665" || rolesid ==
"1358226526012129281") { //
isleader.value = true;
console.log("isleader-------", isleader.value)
} else {
isleader.value = false;
}
}
});
</script>
<style>

View File

@ -0,0 +1,569 @@
<template>
<PageLayout :navbarShow="false">
<view class="container">
<!-- 房间头部 -->
<view class="room-header">
<view>
<text class="room-title">{{ fjh }}</text>
</view>
<view>
<uni-icons type="home" size="40" color="#3498db"></uni-icons>
</view>
</view>
<!-- 照明控制卡片 -->
<view class="device-card" :class="{ 'disabled-card': !kgpd }">
<view class="card-header">
<view class="card-icon light-icon">
<uni-icons type="lightbulb" size="26" color="#fff"></uni-icons>
</view>
<view>
<text class="card-title">照明控制</text>
<text class="card-subtitle">智能灯光系统</text>
</view>
</view>
<view class="control-container" v-if="kgpd">
<view class="switch-container">
<view class="status-indicator" :class="device.key2 === 1 ? 'status-on' : 'status-off'"></view>
<text class="switch-label">{{ device.key2 === 1 ? '已开启' : '已关闭' }}</text>
</view>
<wd-switch v-model="lightStatus" active-color="#2ecc71" @change="onChange" />
<!-- <switch :checked="lightStatus" /> -->
</view>
<view class="power-consumption" v-if="kgpd">
<view class="power-item">
<text class="power-value">0W</text>
<text class="power-label">当前功率</text>
</view>
<view class="power-item">
<text class="power-value">0kWh</text>
<text class="power-label">今日用电</text>
</view>
<view class="power-item">
<text class="power-value">0h</text>
<text class="power-label">本月用时</text>
</view>
</view>
</view>
<!-- 空调控制卡片 -->
<view class="device-card" :class="{ 'disabled-card': !ktpd }">
<view class="card-header">
<view class="card-icon ac-icon">
<uni-icons type="fan" size="26" color="#fff"></uni-icons>
</view>
<view>
<text class="card-title">空调控制</text>
<text class="card-subtitle">智能温控系统</text>
</view>
</view>
<view class="ac-controls" v-if="ktpd">
<button class="ac-btn" :class="{ 'active': acMode === 1 }" @click="conditioning(1)">
<uni-icons type="snow" size="20" color="#3498db"></uni-icons>
<text>制冷 25°C</text>
</button>
<button class="ac-btn" :class="{ 'active': acMode === 2 }" @click="conditioning(2)">
<uni-icons type="fire" size="20" color="#e74c3c"></uni-icons>
<text>制热 27°C</text>
</button>
<button class="ac-btn" :class="{ 'active': acMode === 0 }" @click="conditioning(0)">
<uni-icons type="close" size="20" color="#7f8c8d"></uni-icons>
<text>关闭空调</text>
</button>
</view>
<view class="power-consumption" v-if="ktpd">
<view class="power-item">
<text class="power-value">{{ acMode === 0 ? '--' : '0' }}</text>
<text class="power-label">当前温度</text>
</view>
<view class="power-item">
<text class="power-value">{{ acMode === 0 ? '0.0' : '0.0' }}kW</text>
<text class="power-label">当前功率</text>
</view>
<view class="power-item">
<text class="power-value">0kWh</text>
<text class="power-label">今日用电</text>
</view>
</view>
</view>
</view>
</PageLayout>
</template>
<script setup>
import {
pushMqttsubscribeForYKQ,
subscribeByOneTopic,
pushMqttsubscribeforSendInfo,
pushMqttsubscribe,
getsblb
} from '@/api/devicecontrol/officedevice';
import {
useMessage,
useToast
} from 'wot-design-uni';
// const checked = ref(true);
const homenumber = ref(''); //
const kgpd = ref(false); //
const ktpd = ref(false); //
const kgkzbm = ref(''); //
const ktkzbm = ref(''); //
const kgopen = ref(''); //--
const kgclose = ref(''); //--
const kgzt = ref(''); //
const ktzlopen = ref(0) //
const ktzropen = ref(0) //
const ktclose = ref(0) //
const device = ref({})
const fjh = ref(''); //
const lightStatus = ref(false);//
const toast = useToast();
const gethomesblb = (id) => {
getsblb({
fjbid: id
}).then((res) => {
console.log("房间表返回的信息--11111---", res.result)
if (res.success) {
for (const item of res.result) {
// console.log("--11111-item--", item)
if (item.sblb == '开关') {
kgpd.value = true;
kgkzbm.value = item.sbkzbm;
kgopen.value = item.kgopen; //--
kgclose.value = item.kgclose; //--
kgzt.value = item.kgzt; //
testone();
}
if (item.sblb == '空调') {
ktpd.value = true
ktkzbm.value = item.sbkzbm;
ktzlopen.value = item.ktzlopen; //
ktzropen.value = item.ktzropen; //
ktclose.value = item.ktclose; //
//
subconditioning();
}
}
console.log("kgpd===-", kgpd.value)
console.log("ktpd===-", ktpd.value)
}
})
//
subscribeByOneTopic({
topic: 's' + kgkzbm.value,
qos: 0
}).then(res => {
console.log("res--subscribeByOneTopic---", res)
})
}
//createdSwitch
const subconditioning = () => {
var param = {
topic: 's' + ktkzbm.value,
qos: 0
}
console.log("param----subconditioning--22222空调---", param)
subscribeByOneTopic(param).then(res => {
console.log("res---空调--222233333333-------", res)
})
}
//--1-25°02 27
const conditioning = (sendcode) => {
let sendmassage = '';
if (sendcode == 0) { //
sendmassage = ktclose.value;
}
if (sendcode == 1) { //
sendmassage = ktzlopen.value;
}
if (sendcode == 2) { //
sendmassage = ktzropen.value;
}
var param = {
topic: 'f' + ktkzbm.value,
pushMessageone: sendmassage
};
console.log("参数-空调遥控器--444444-", param)
pushMqttsubscribeForYKQ(param).then(res => {
console.log("res------------", res)
if (res.success) {
toast.success('指令发送成功!')
// this.$message.success("")
} else {
toast.warning('指令发送失败!')
// this.$message.error("")
}
})
}
const testone = async () => {
console.log("this.kgkzbm--2222222---", kgkzbm.value)
await subscribeByOneTopic({
topic: 's' + kgkzbm.value,
qos: 0
}).then(res => {
console.log("res--单个接受-2222--333333--", res)
if (res.success) {
getswitch();
} else {}
})
}
const onChange = async (checked) => {
// console.log(':targetStatus', checked.detail);
//
if (checked) {
console.log('点击了开关---');
if (device.value.key2 == 1) {
console.log("--当前状态-开---")
await closeswitch(); //
testone();
}
else if (device.value.key2 == 0) {
console.log("--当前状态-关----")
await openswitch(); //
testone();
}
}
}
const openswitch = () => {
console.log("this.kgkzbm----", kgkzbm.value)
var param = {
topic: 'f' + kgkzbm.value,
pushMessage: kgopen.value,
switchinfoMessage: kgzt.value
// pushMessage: "{'type':'event','key2':1}"
};
pushMqttsubscribe(param).then(res => {
console.log("res------开------", res)
})
}
const closeswitch = () => {
var param = {
topic: 'f' + kgkzbm.value,
pushMessage: kgclose.value,
switchinfoMessage: kgzt.value
// pushMessage: "{'type':'event','key2':0}"
};
pushMqttsubscribe(param).then(res => {
console.log("res-------关-----", res)
})
}
const getswitch = async () => {
// console.log("this.kgzt-----", kgzt.value)
await pushMqttsubscribeforSendInfo({
topic: 'f' + kgkzbm.value,
pushMessage: kgzt.value
}).then(res => {
// console.log("------", res)
device.value = JSON.parse(res.message);
if(device.value.key2=='0'){
console.log("---获取开关状态-关--", device.value.key2)
lightStatus.value=false;
}
else if(device.value.key2=='1'){
console.log("---获取开关状态--开-", device.value.key2)
lightStatus.value=true;
}else{
lightStatus.value=false;
}
})
// console.log("----2222222--", device.value)
}
onMounted(() => {
// getofficehomelist();
})
onLoad((options) => {
console.log("传进来的参数--00000-", options)
console.log("传进来的参数-房间号-00000-", options.fjh)
fjh.value = options.fjh;
// queryById(options.id)
//
kgpd.value = false;
ktpd.value = false;
if (options.id) {
//
gethomesblb(options.id);
} else {
kgpd.value = false;
ktpd.value = false;
}
})
</script>
<style lang="scss" scoped>
.container {
padding: 15px;
}
.room-header {
display: flex;
justify-content: space-between;
align-items: center;
background: white;
border-radius: 20px;
padding: 20px;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.05);
margin-bottom: 25px;
position: relative;
overflow: hidden;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: linear-gradient(90deg, #3498db, #8e44ad);
}
}
.room-title {
font-size: 24px;
font-weight: 700;
color: #2c3e50;
display: block;
margin-bottom: 5px;
}
.room-id {
background: #f0f4f8;
padding: 6px 12px;
border-radius: 50px;
font-size: 14px;
color: #7f8c8d;
}
.device-card {
background: white;
border-radius: 20px;
padding: 25px;
margin-bottom: 25px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.06);
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.12);
}
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #f0f4f8;
}
.card-icon {
width: 45px;
height: 45px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 15px;
&.light-icon {
background: linear-gradient(135deg, #ffd700 0%, #ff9a00 100%);
}
&.ac-icon {
background: linear-gradient(135deg, #3498db 0%, #1abc9c 100%);
}
}
.card-title {
font-size: 20px;
font-weight: 600;
color: #2c3e50;
display: block;
}
.card-subtitle {
font-size: 14px;
color: #7f8c8d;
margin-top: 3px;
display: block;
}
.control-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.switch-container {
display: flex;
align-items: center;
}
.status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 12px;
&.status-on {
background: #2ecc71;
box-shadow: 0 0 10px rgba(46, 204, 113, 0.5);
}
&.status-off {
background: #e74c3c;
}
}
.switch-label {
font-size: 16px;
color: #34495e;
font-weight: 500;
}
.ac-controls {
display: grid;
grid-template-columns: repeat(3, 1fr); //
gap: 12px; //
margin-top: 10px;
width: 100%; //
}
.ac-btn {
//
// padding: 12px 5px; //
position: null;
font-size: 14px; //
border: none;
// border-radius: 15px;
// padding: 15px 10px;
// font-size: 15px;
font-weight: 500;
background: #f8f9fc;
color: #4a6fa5;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&:hover {
background: #eef2f7;
}
&.active {
background: linear-gradient(135deg, #3498db 0%, #1abc9c 100%);
color: white;
box-shadow: 0 6px 15px rgba(52, 152, 219, 0.3);
}
&:nth-child(1) {
color: #3498db;
}
&:nth-child(2) {
color: #e74c3c;
}
&:nth-child(3) {
color: #7f8c8d;
}
}
.disabled-card {
opacity: 0.6;
position: relative;
overflow: hidden;
&::after {
content: "设备未连接";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.85);
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
color: #e74c3c;
border-radius: 20px;
}
}
.power-consumption {
display: flex;
justify-content: space-around;
background: #f8f9fc;
border-radius: 15px;
padding: 15px;
margin-top: 20px;
}
.power-item {
flex: 1;
text-align: center;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
/* 分隔线 */
.power-item:not(:last-child)::after {
content: "";
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
height: 60%;
width: 1px;
background: #f0f4f8;
}
.power-value {
font-size: 20px;
font-weight: 700;
color: #2c3e50;
}
.power-label {
font-size: 13px;
color: #7f8c8d;
margin-top: 5px;
}
@media (max-width: 480px) {
// .ac-controls { grid-template-columns: 1fr; }
//
.ac-btn {
// padding: 10px 3px; //
// font-size: 13px;
}
.ac-controls {
// grid-template-columns: 1fr;
}
.room-title {
font-size: 20px;
}
.device-card {
padding: 20px;
}
}
</style>

View File

@ -229,8 +229,10 @@
/*获取请假类型*/
const getTypeList = () => {
getCategoryItemsApi('1838487445813645313').then((res) => {
console.log("res-------",res.result)
if (res.success) {
data.value = res.result
console.log("res-------",data.value)
typeData.value = [data.value.map(item => {
return {
value: item.name,

View File

@ -222,13 +222,21 @@
"root": "pages-home",
"pages": [
{
"path": "device-control/office/index",
"path": "device-control/office/ALLleader",
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "办公室设备列表"
}
},
{
"path": "device-control/office/index",
"type": "page"
},
{
"path": "device-control/office/officehomedevice",
"type": "page"
},
{
"path": "device-control/office/Personaldevices",
"type": "page"

View File

@ -27,7 +27,9 @@ interface NavigateToOptions {
"/pages/production/shishishuju/nyxhSssj" |
"/pages/production/shishishuju/trqSssj" |
"/pages/production/shishishuju/ysjSssj" |
"/pages-home/device-control/office/ALLleader" |
"/pages-home/device-control/office/index" |
"/pages-home/device-control/office/officehomedevice" |
"/pages-home/device-control/office/Personaldevices" |
"/pages-message/chat/chat" |
"/pages-message/contacts/contacts" |

101
src/utils/socket.ts Normal file
View File

@ -0,0 +1,101 @@
// utils/socket.js
import { ref, onUnmounted } from 'vue';
export default function useWebSocket() {
const continturl='http://10.75.15.246:8899/mqttprod/ws';
console.log("传进来的url----useWebSocket----11111--",continturl)
//
const isConnected = ref(false);
//
const receivedMessages = ref([]);
// WebSocket
let socket = null;
console.log("连接WebSocket---22222---",continturl)
// WebSocket
const connect = () => {
// 使uni-appWebSocket API
socket = uni.connectSocket({
url: continturl,
success: () => {
console.log('WebSocket连接成功');
},
fail: (err) => {
console.error('WebSocket连接失败:', err);
}
});
console.log("连接WebSocket---333333---",continturl)
//
socket.onOpen(() => {
isConnected.value = true;
console.log('WebSocket已连接');
});
//
socket.onMessage((res) => {
try {
// JSON
const message = JSON.parse(res.data);
receivedMessages.value.push(message);
} catch (e) {
//
receivedMessages.value.push(res.data);
}
});
//
socket.onError((err) => {
console.error('WebSocket错误:', err);
});
};
//
socket.onClose(() => {
isConnected.value = false;
console.log('WebSocket已关闭');
});
//
const sendMessage = (data) => {
if (isConnected.value) {
socket.send({
data: typeof data === 'string' ? data : JSON.stringify(data),
success: () => {
console.log('消息发送成功');
},
fail: (err) => {
console.error('消息发送失败:', err);
}
});
} else {
console.error('WebSocket未连接无法发送消息');
}
};
//
const disconnect = () => {
console.log("关闭连接------",socket)
if (socket) {
socket.close({
success: () => {
console.log('WebSocket关闭成功');
},
fail: (err) => {
console.error('WebSocket关闭失败:', err);
}
});
socket = null;
}
};
//
onUnmounted(() => {
disconnect();
});
return {
isConnected,
receivedMessages,
connect,
sendMessage,
disconnect
};
}