資產管理: 部門、IOT、MQTT欄位 | 系統監控: 系統小卡詳細內容 TABLE不分頁、顯示即時資料、NO Data改成0 | 運維管理: 維運、保養修正搜尋功能、廠商資料隱藏搜尋
This commit is contained in:
parent
d19c7fd240
commit
9e5ff1544c
@ -1,3 +1,4 @@
|
|||||||
VITE_API_BASEURL = "https://ibms-cvilux-api.production.mjmtech.com.tw"
|
VITE_API_BASEURL = "https://ibms-cvilux-api.production.mjmtech.com.tw"
|
||||||
VITE_FILE_API_BASEURL = "https://cgems.cvilux-group.com:8088"
|
VITE_FILE_API_BASEURL = "https://cgems.cvilux-group.com:8088"
|
||||||
|
VITE_MQTT_BASEURL = "ws://192.168.0.217:8083/mqtt"
|
||||||
VITE_FORGE_BASEURL = "https://cgems.cvilux-group.com:8088/dist"
|
VITE_FORGE_BASEURL = "https://cgems.cvilux-group.com:8088/dist"
|
@ -1,3 +1,4 @@
|
|||||||
VITE_API_BASEURL = "https://ibms-cvilux-api.production.mjmtech.com.tw"
|
VITE_API_BASEURL = "https://ibms-cvilux-api.production.mjmtech.com.tw"
|
||||||
VITE_FILE_API_BASEURL = "https://cgems.cvilux-group.com:8088"
|
VITE_FILE_API_BASEURL = "https://cgems.cvilux-group.com:8088"
|
||||||
|
VITE_MQTT_BASEURL = "wss://192.168.0.217:8084/mqtt"
|
||||||
VITE_FORGE_BASEURL = "https://cgems.cvilux-group.com:8088/dist"
|
VITE_FORGE_BASEURL = "https://cgems.cvilux-group.com:8088/dist"
|
435
package-lock.json
generated
435
package-lock.json
generated
@ -22,12 +22,14 @@
|
|||||||
"echarts": "^5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"flag-icons": "^7.2.3",
|
"flag-icons": "^7.2.3",
|
||||||
"jquery-ui": "^1.14.1",
|
"jquery-ui": "^1.14.1",
|
||||||
|
"mqtt": "^5.10.3",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-i18n": "^10.0.4",
|
"vue-i18n": "^10.0.4",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
|
"vuedraggable": "^4.1.0",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.4.0",
|
||||||
"yup-phone-lite": "^2.0.1"
|
"yup-phone-lite": "^2.0.1"
|
||||||
},
|
},
|
||||||
@ -102,9 +104,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.23.9",
|
"version": "7.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
|
||||||
"integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
|
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
@ -764,11 +767,26 @@
|
|||||||
"version": "20.10.4",
|
"version": "20.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz",
|
||||||
"integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==",
|
"integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/readable-stream": {
|
||||||
|
"version": "4.0.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz",
|
||||||
|
"integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"safe-buffer": "~5.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/readable-stream/node_modules/safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/svgo": {
|
"node_modules/@types/svgo": {
|
||||||
"version": "2.6.4",
|
"version": "2.6.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/svgo/-/svgo-2.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/svgo/-/svgo-2.6.4.tgz",
|
||||||
@ -778,6 +796,15 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vitejs/plugin-vue": {
|
"node_modules/@vitejs/plugin-vue": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.5.0.tgz",
|
||||||
@ -1087,6 +1114,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.11.2",
|
"version": "8.11.2",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
|
||||||
@ -1370,6 +1409,26 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/big.js": {
|
"node_modules/big.js": {
|
||||||
"version": "5.2.2",
|
"version": "5.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||||
@ -1388,6 +1447,34 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bl": {
|
||||||
|
"version": "6.0.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-6.0.16.tgz",
|
||||||
|
"integrity": "sha512-V/kz+z2Mx5/6qDfRCilmrukUXcXuCoXKg3/3hDvzKKoSUx8CJKudfIoT29XZc3UE9xBvxs5qictiHdprwtteEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/readable-stream": "^4.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"readable-stream": "^4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bl/node_modules/readable-stream": {
|
||||||
|
"version": "4.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
|
||||||
|
"integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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/bluebird": {
|
"node_modules/bluebird": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
@ -1454,12 +1541,34 @@
|
|||||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-from": {
|
"node_modules/buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||||
"dev": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/cache-base": {
|
"node_modules/cache-base": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@ -1684,6 +1793,12 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/commist": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/component-emitter": {
|
"node_modules/component-emitter": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
|
||||||
@ -1704,6 +1819,21 @@
|
|||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^3.0.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/copy-descriptor": {
|
"node_modules/copy-descriptor": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||||
@ -1926,7 +2056,6 @@
|
|||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
},
|
},
|
||||||
@ -2213,12 +2342,19 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/events": {
|
"node_modules/events": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||||
"dev": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.x"
|
"node": ">=0.8.x"
|
||||||
}
|
}
|
||||||
@ -2354,6 +2490,25 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-unique-numbers": {
|
||||||
|
"version": "8.0.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz",
|
||||||
|
"integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.8",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-unique-numbers/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
"node_modules/fastparse": {
|
"node_modules/fastparse": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
|
||||||
@ -2665,6 +2820,12 @@
|
|||||||
"he": "bin/he"
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "3.10.1",
|
"version": "3.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||||
@ -2679,6 +2840,26 @@
|
|||||||
"readable-stream": "^3.1.1"
|
"readable-stream": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ieee754": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/image-size": {
|
"node_modules/image-size": {
|
||||||
"version": "0.5.5",
|
"version": "0.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
||||||
@ -2710,8 +2891,7 @@
|
|||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/is-accessor-descriptor": {
|
"node_modules/is-accessor-descriptor": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@ -2906,6 +3086,16 @@
|
|||||||
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
|
"integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/js-sdsl"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@ -3035,6 +3225,12 @@
|
|||||||
"loose-envify": "cli.js"
|
"loose-envify": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.5",
|
"version": "0.30.5",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
|
||||||
@ -3149,7 +3345,6 @@
|
|||||||
"version": "1.2.8",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
"dev": true,
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
@ -3200,11 +3395,69 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mqtt": {
|
||||||
|
"version": "5.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.10.3.tgz",
|
||||||
|
"integrity": "sha512-hA/6YrUS4fywhBGCjH/XXUuLeueJiPqruVVWjK2A24Ma4KcWfZ/x8x07aoesBV+HXDWBC08tbT4IWfSXNW0Jtw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/readable-stream": "^4.0.5",
|
||||||
|
"@types/ws": "^8.5.9",
|
||||||
|
"commist": "^3.2.0",
|
||||||
|
"concat-stream": "^2.0.0",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"help-me": "^5.0.0",
|
||||||
|
"lru-cache": "^10.0.1",
|
||||||
|
"minimist": "^1.2.8",
|
||||||
|
"mqtt-packet": "^9.0.1",
|
||||||
|
"number-allocator": "^1.0.14",
|
||||||
|
"readable-stream": "^4.4.2",
|
||||||
|
"reinterval": "^1.1.0",
|
||||||
|
"rfdc": "^1.3.0",
|
||||||
|
"split2": "^4.2.0",
|
||||||
|
"worker-timers": "^7.1.4",
|
||||||
|
"ws": "^8.17.1"
|
||||||
|
},
|
||||||
|
"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.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-koZF1V/X2RZUI6uD9wN5OK1JxxcG1ofAR4H3LjCw1FkeKzruZQ26aAA6v2m1lZyWONZIR5wMMJFrZJDRNzbiQw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bl": "^6.0.8",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"process-nextick-args": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mqtt/node_modules/readable-stream": {
|
||||||
|
"version": "4.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
|
||||||
|
"integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/mz": {
|
"node_modules/mz": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
@ -3371,6 +3624,16 @@
|
|||||||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.1",
|
||||||
|
"js-sdsl": "4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@ -3822,6 +4085,21 @@
|
|||||||
"posthtml-render": "^1.0.6"
|
"posthtml-render": "^1.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/process-nextick-args": {
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/property-expr": {
|
"node_modules/property-expr": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||||
@ -3898,7 +4176,6 @@
|
|||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
"string_decoder": "^1.1.1",
|
"string_decoder": "^1.1.1",
|
||||||
@ -3984,6 +4261,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/reinterval": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/repeat-element": {
|
"node_modules/repeat-element": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
|
||||||
@ -4062,6 +4345,12 @@
|
|||||||
"node": ">=0.10.0"
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "3.29.4",
|
"version": "3.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
|
||||||
@ -4105,7 +4394,6 @@
|
|||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -4377,6 +4665,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sortablejs": {
|
||||||
|
"version": "1.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
|
||||||
|
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
@ -4484,6 +4778,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/split2": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/stable": {
|
"node_modules/stable": {
|
||||||
"version": "0.1.8",
|
"version": "0.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
|
||||||
@ -4542,7 +4845,6 @@
|
|||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.2.0"
|
"safe-buffer": "~5.2.0"
|
||||||
}
|
}
|
||||||
@ -5119,11 +5421,16 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/union-value": {
|
"node_modules/union-value": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@ -5338,8 +5645,7 @@
|
|||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
@ -5492,6 +5798,18 @@
|
|||||||
"vue": "^3.0.0"
|
"vue": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vuedraggable": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"sortablejs": "1.14.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/warning": {
|
"node_modules/warning": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
@ -5577,12 +5895,85 @@
|
|||||||
"integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==",
|
"integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/worker-timers": {
|
||||||
|
"version": "7.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz",
|
||||||
|
"integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.24.5",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"worker-timers-broker": "^6.1.8",
|
||||||
|
"worker-timers-worker": "^7.0.71"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers-broker": {
|
||||||
|
"version": "6.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz",
|
||||||
|
"integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.24.5",
|
||||||
|
"fast-unique-numbers": "^8.0.13",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"worker-timers-worker": "^7.0.71"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers-broker/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers-worker": {
|
||||||
|
"version": "7.0.71",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz",
|
||||||
|
"integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.24.5",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers-worker/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
|
"node_modules/worker-timers/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
"node_modules/wrappy": {
|
"node_modules/wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||||
|
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"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/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "2.3.4",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
|
||||||
|
@ -23,12 +23,14 @@
|
|||||||
"echarts": "^5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"flag-icons": "^7.2.3",
|
"flag-icons": "^7.2.3",
|
||||||
"jquery-ui": "^1.14.1",
|
"jquery-ui": "^1.14.1",
|
||||||
|
"mqtt": "^5.10.3",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"tailwind-merge": "^2.2.1",
|
"tailwind-merge": "^2.2.1",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-i18n": "^10.0.4",
|
"vue-i18n": "^10.0.4",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
|
"vuedraggable": "^4.1.0",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.4.0",
|
||||||
"yup-phone-lite": "^2.0.1"
|
"yup-phone-lite": "^2.0.1"
|
||||||
},
|
},
|
||||||
|
@ -18,3 +18,9 @@ export const DELETE_ASSET_FLOOR_API = `/AssetManage/DeleteFloor`;
|
|||||||
|
|
||||||
export const GET_ASSET_IOT_LIST_API = `/AssetManage/GetIOTList`;
|
export const GET_ASSET_IOT_LIST_API = `/AssetManage/GetIOTList`;
|
||||||
export const GET_ASSET_SUB_POINT_API = `/AssetManage/GetSubPoint`;
|
export const GET_ASSET_SUB_POINT_API = `/AssetManage/GetSubPoint`;
|
||||||
|
|
||||||
|
export const GET_ASSET_IOT_SCHEMA_API = `/AssetManage/GetResponseSchema`;
|
||||||
|
|
||||||
|
export const GET_ASSET_DEPARTMENT_API = `/AssetManage/GetDepartment`;
|
||||||
|
export const POST_ASSET_DEPARTMENT_API = `/AssetManage/SaveDepartment`;
|
||||||
|
export const DELETE_ASSET_DEPARTMENT_API = `/AssetManage/DeleteDepartment`;
|
||||||
|
@ -14,6 +14,10 @@ import {
|
|||||||
DELETE_ASSET_ITEM_API,
|
DELETE_ASSET_ITEM_API,
|
||||||
POST_ASSET_SINGLE_API,
|
POST_ASSET_SINGLE_API,
|
||||||
GET_ASSET_SUB_POINT_API,
|
GET_ASSET_SUB_POINT_API,
|
||||||
|
GET_ASSET_IOT_SCHEMA_API,
|
||||||
|
GET_ASSET_DEPARTMENT_API,
|
||||||
|
POST_ASSET_DEPARTMENT_API,
|
||||||
|
DELETE_ASSET_DEPARTMENT_API,
|
||||||
} from "./api";
|
} from "./api";
|
||||||
import instance from "@/util/request";
|
import instance from "@/util/request";
|
||||||
import apihandler from "@/util/apihandler";
|
import apihandler from "@/util/apihandler";
|
||||||
@ -124,16 +128,15 @@ export const postAssetSingle = async (data) => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
value.forEach((element, index) => {
|
value.forEach((element, index) => {
|
||||||
formData.append(`sub_device[${index}].device_number`, element.device_number);
|
formData.append(
|
||||||
|
`sub_device[${index}].device_number`,
|
||||||
|
element.device_number
|
||||||
|
);
|
||||||
formData.append(`sub_device[${index}].points`, element.points);
|
formData.append(`sub_device[${index}].points`, element.points);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (key === "device_number" && value === "") {
|
formData.append(key, value);
|
||||||
formData.append(key, "0");
|
|
||||||
} else {
|
|
||||||
formData.append(key, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,3 +202,42 @@ export const getAssetSubPoint = async (sub_system_tag) => {
|
|||||||
code: res.code,
|
code: res.code,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getIOTSchema = async (sub_system_tag, points) => {
|
||||||
|
const res = await instance.post(GET_ASSET_IOT_SCHEMA_API, {});
|
||||||
|
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDepartmentList = async () => {
|
||||||
|
const res = await instance.post(GET_ASSET_DEPARTMENT_API, {});
|
||||||
|
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const postDepartmentList = async ({ name, id }) => {
|
||||||
|
const res = await instance.post(POST_ASSET_DEPARTMENT_API, {
|
||||||
|
name,
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteDepartmentItem = async (id) => {
|
||||||
|
const res = await instance.post(DELETE_ASSET_DEPARTMENT_API, { id });
|
||||||
|
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
436
src/components/customUI/DraggableTable.vue
Normal file
436
src/components/customUI/DraggableTable.vue
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
<script setup>
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import { computed, defineProps, provide, ref, watch } from "vue";
|
||||||
|
import Pagination from "@/components/customUI/Pagination.vue";
|
||||||
|
import Checkbox from "@/components/customUI/Checkbox.vue";
|
||||||
|
import draggable from "vuedraggable";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
const { t } = useI18n();
|
||||||
|
/*
|
||||||
|
column={
|
||||||
|
title,key,class, width, filter:Boolean, sort:Boolean
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
const props = defineProps({
|
||||||
|
columns: Array,
|
||||||
|
dataSource: Array,
|
||||||
|
rowKey: String,
|
||||||
|
withStyle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
withDraggable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
pagination: { type: Boolean, default: true } || {
|
||||||
|
pageSize: Number,
|
||||||
|
totalPages: Number,
|
||||||
|
totalItems: Number,
|
||||||
|
},
|
||||||
|
loading: Boolean,
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentDataSource = ref([]);
|
||||||
|
const dataSourceStorage = ref([]);
|
||||||
|
const isDraggable = ref(props.withDraggable);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.dataSource,
|
||||||
|
(newValue) => {
|
||||||
|
dataSourceStorage.value = newValue;
|
||||||
|
filterItems.value = Object.fromEntries(
|
||||||
|
props.columns.map((c, i) => [
|
||||||
|
c.key,
|
||||||
|
[...new Set(newValue.map((d) => d[c.key]))].map((name) => ({
|
||||||
|
name,
|
||||||
|
selected: false,
|
||||||
|
})),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateDataSource = (data) => {
|
||||||
|
console.log("update", data);
|
||||||
|
currentDataSource.value = data;
|
||||||
|
};
|
||||||
|
provide("current_table_data", {
|
||||||
|
updateDataSource,
|
||||||
|
});
|
||||||
|
|
||||||
|
const sortRule = ref({});
|
||||||
|
const filterColumn = ref({});
|
||||||
|
const filterItems = ref({});
|
||||||
|
const selectedFilterItem = ref({});
|
||||||
|
|
||||||
|
const toggleFilterModal = (key) => {
|
||||||
|
let newFilter = Object.assign(filterColumn.value);
|
||||||
|
|
||||||
|
for (let oKey in newFilter) {
|
||||||
|
newFilter[oKey] = key === oKey && !newFilter[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
filterColumn.value = newFilter;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.columns,
|
||||||
|
(newValue) => {
|
||||||
|
sortRule.value = Object.fromEntries(newValue.map((c) => [c.key, 0]));
|
||||||
|
filterColumn.value = Object.fromEntries(
|
||||||
|
newValue.map((c, i) => [c.key, false])
|
||||||
|
);
|
||||||
|
selectedFilterItem.value = Object.fromEntries(
|
||||||
|
newValue.map((c, i) => [c.key, []])
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
0:取消
|
||||||
|
1:ascending
|
||||||
|
2:descending
|
||||||
|
*/
|
||||||
|
const toggleSortRule = (key) => {
|
||||||
|
let newSort = Object.assign(sortRule.value);
|
||||||
|
|
||||||
|
for (let oKey in newSort) {
|
||||||
|
newSort[oKey] = key === oKey ? newSort[key] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortRule.value = newSort;
|
||||||
|
};
|
||||||
|
|
||||||
|
const sort = (column) => {
|
||||||
|
toggleSortRule(column);
|
||||||
|
const cantSort = ["object", "boolean"];
|
||||||
|
console.log(props.dataSource?.[0][column]);
|
||||||
|
if (cantSort.includes(typeof props.dataSource?.[0][column])) return;
|
||||||
|
// 小->大
|
||||||
|
const newArray = Object.assign(props.dataSource, []).sort((a, b) => {
|
||||||
|
// if (column === "timestamp") {
|
||||||
|
// return dayjs(a[column]).valueOf() - dayjs(b[column]).valueOf();
|
||||||
|
// }
|
||||||
|
if (typeof a[column] === "number") return a[column] - b[column];
|
||||||
|
else if (typeof a[column] === "string") {
|
||||||
|
console.log(a[column], b[column], a[column].localeCompare(b[column]));
|
||||||
|
return a[column].localeCompare(b[column]);
|
||||||
|
}
|
||||||
|
// return parseInt(a[column]) - parseInt(b[column]);
|
||||||
|
});
|
||||||
|
if (sortRule.value[column] === 0) {
|
||||||
|
sortRule.value[column] = 1;
|
||||||
|
dataSourceStorage.value = newArray;
|
||||||
|
} else if (sortRule.value[column] === 1) {
|
||||||
|
sortRule.value[column] = 2;
|
||||||
|
dataSourceStorage.value = newArray.reverse();
|
||||||
|
} else if (sortRule.value[column] === 2) {
|
||||||
|
sortRule.value[column] = 0;
|
||||||
|
dataSourceStorage.value = props.dataSource;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const form = ref(null);
|
||||||
|
|
||||||
|
const onFilter = (key, reset = false) => {
|
||||||
|
const formData = new FormData(form.value);
|
||||||
|
reset && formData.delete(key);
|
||||||
|
for (let [name, value] of formData) {
|
||||||
|
console.log(name, value);
|
||||||
|
}
|
||||||
|
selectedFilterItem.value[key] = formData.getAll(key);
|
||||||
|
toggleFilterModal(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
selectedFilterItem,
|
||||||
|
(newVal) => {
|
||||||
|
let newData = Object.assign(props.dataSource);
|
||||||
|
for (let key in newVal) {
|
||||||
|
if (newVal[key].length > 0) {
|
||||||
|
newData = newData.filter((d) => newVal[key].includes(d[key]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataSourceStorage.value = newData;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="withStyle ? 'content-box' : 'py-5'">
|
||||||
|
<div class="content-decoration">
|
||||||
|
<button
|
||||||
|
v-if="withDraggable"
|
||||||
|
class="btn btn-sm mb-2"
|
||||||
|
@click.stop.prevent="isDraggable = !isDraggable"
|
||||||
|
>
|
||||||
|
<font-awesome-icon :icon="['fas', 'stream']" />
|
||||||
|
{{ isDraggable ? "開始排序" : "完成排序" }}
|
||||||
|
</button>
|
||||||
|
<slot name="beforeTable"></slot>
|
||||||
|
<form ref="form" class="overflow-x-auto">
|
||||||
|
<table
|
||||||
|
:class="
|
||||||
|
twMerge(
|
||||||
|
withStyle ? 'table' : 'table border',
|
||||||
|
currentDataSource.length === 0 ? 'h-28' : ''
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<!-- head -->
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
v-for="column in columns"
|
||||||
|
:key="column.key"
|
||||||
|
:class="`${column.class ? column.class : ''}`"
|
||||||
|
:style="{
|
||||||
|
width: `${
|
||||||
|
column.width
|
||||||
|
? typeof column.width === 'string'
|
||||||
|
? column.width
|
||||||
|
: column.width + 'px'
|
||||||
|
: 'auto'
|
||||||
|
}`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span class="flex justify-center">
|
||||||
|
{{ column.title }}
|
||||||
|
<div
|
||||||
|
v-if="column.sort"
|
||||||
|
class="flex flex-col justify-center w-3 mx-2 relative"
|
||||||
|
@click="() => sort(column.key)"
|
||||||
|
>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'sort-up']"
|
||||||
|
:class="
|
||||||
|
twMerge(
|
||||||
|
'absolute top-0',
|
||||||
|
sortRule[column.key] === 1 ? 'text-success' : ''
|
||||||
|
)
|
||||||
|
"
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'sort-down']"
|
||||||
|
:class="
|
||||||
|
twMerge(
|
||||||
|
'absolute bottom-1',
|
||||||
|
sortRule[column.key] === 2 ? 'text-success' : ''
|
||||||
|
)
|
||||||
|
"
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="ml-2 relative" v-if="column.filter">
|
||||||
|
<font-awesome-icon
|
||||||
|
:icon="['fas', 'filter']"
|
||||||
|
:class="
|
||||||
|
twMerge(
|
||||||
|
filterColumn[column.key] ||
|
||||||
|
selectedFilterItem[column.key].length > 0
|
||||||
|
? 'text-success'
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@click="() => toggleFilterModal(column.key)"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="absolute top-full -left-1/2 z-50"
|
||||||
|
v-if="filterColumn[column.key]"
|
||||||
|
>
|
||||||
|
<div class="card min-w-max bg-body shadow-xl px-10 py-5">
|
||||||
|
<Checkbox
|
||||||
|
v-for="item in filterItems[column.key]"
|
||||||
|
:title="item.name"
|
||||||
|
:value="item.name"
|
||||||
|
:key="item.name"
|
||||||
|
:name="column.key"
|
||||||
|
:checked="
|
||||||
|
selectedFilterItem[column.key].includes(item.name)
|
||||||
|
"
|
||||||
|
className="justify-start"
|
||||||
|
/>
|
||||||
|
<div class="card-actions mt-4 justify-end">
|
||||||
|
<input
|
||||||
|
type="reset"
|
||||||
|
class="btn btn-sm text-white btn-error"
|
||||||
|
:value="t('button.reset')"
|
||||||
|
@click="() => onFilter(column.key, true)"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-success"
|
||||||
|
@click.stop.prevent="() => onFilter(column.key)"
|
||||||
|
>
|
||||||
|
{{ $t("button.submit") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody v-if="isDraggable">
|
||||||
|
<tr v-if="loading">
|
||||||
|
<td :colspan="columns.length">
|
||||||
|
<Loading />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-else-if="currentDataSource.length == 0">
|
||||||
|
<td :colspan="columns.length">{{ $t("table.no_data") }}</td>
|
||||||
|
</tr>
|
||||||
|
<template v-else :sort="sortRule">
|
||||||
|
<tr
|
||||||
|
v-for="(data, index) in currentDataSource"
|
||||||
|
:key="data.key || data[rowKey]"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-for="column in columns"
|
||||||
|
:key="`${data.key || data[rowKey]}_${column.key}`"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
:class="column.class"
|
||||||
|
:style="{
|
||||||
|
width: `${
|
||||||
|
column.width
|
||||||
|
? typeof column.width === 'string'
|
||||||
|
? column.width
|
||||||
|
: column.width + 'px'
|
||||||
|
: 'auto'
|
||||||
|
}`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="bodyCell"
|
||||||
|
v-bind="{ record: data, column, index }"
|
||||||
|
>
|
||||||
|
{{ data[column.key] }}</slot
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
<draggable
|
||||||
|
tag="tbody"
|
||||||
|
:list="dataSourceStorage"
|
||||||
|
item-key="rowKey"
|
||||||
|
v-else
|
||||||
|
>
|
||||||
|
<template #item="{ element, index }">
|
||||||
|
<tr :key="element[rowKey] || element.key" >
|
||||||
|
<template
|
||||||
|
v-for="column in columns"
|
||||||
|
:key="`${element[rowKey] || element.key}_${column.key}`"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
:class="column.class"
|
||||||
|
:style="{
|
||||||
|
width: `
|
||||||
|
${
|
||||||
|
column.width
|
||||||
|
? typeof column.width === 'string'
|
||||||
|
? column.width
|
||||||
|
: column.width + 'px'
|
||||||
|
: 'auto'
|
||||||
|
}`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="bodyCell"
|
||||||
|
v-bind="{ record: element, column, index }"
|
||||||
|
>
|
||||||
|
{{ element[column.key] }}</slot
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</draggable>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
<slot name="afterTable"></slot>
|
||||||
|
<Pagination
|
||||||
|
:class="twMerge(!isDraggable ? 'hidden' : 'flex')"
|
||||||
|
:pagination="pagination"
|
||||||
|
:dataSource="dataSourceStorage"
|
||||||
|
:sort="sortRule"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="content-decoration2"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
/**資料框**/
|
||||||
|
.content-box {
|
||||||
|
@apply border border-info p-1 relative mb-4 bg-transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-box .table {
|
||||||
|
@apply rounded-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table th {
|
||||||
|
@apply bg-cyan-600 bg-opacity-30 border-r border-b border-white text-lg font-semibold text-white text-center px-2 py-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td {
|
||||||
|
@apply border-r border-b border-white text-lg font-semibold text-white text-center px-2 py-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table tr td:last-child,
|
||||||
|
.table tr:first-child th:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .table tr:last-child td {
|
||||||
|
border-bottom: v-bind("withStyle ? '0px': '1px'");
|
||||||
|
} */
|
||||||
|
|
||||||
|
/**資料框裝飾**/
|
||||||
|
.content-box::before {
|
||||||
|
@apply absolute top-1 left-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background01.svg')] bg-center;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-box::after {
|
||||||
|
@apply absolute bottom-1 right-1 h-5 w-5 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background05.svg')] bg-center;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
.content-box .content-decoration {
|
||||||
|
@apply bg-normal px-8 py-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .content-box .content-decoration::before {
|
||||||
|
@apply absolute -top-3 -right-[10px] h-8 w-8 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background02.svg')] bg-center;
|
||||||
|
content: "";
|
||||||
|
} */
|
||||||
|
|
||||||
|
.content-box .content-decoration2::before {
|
||||||
|
@apply absolute -bottom-1 -left-8 h-14 w-14 bg-no-repeat z-10 bg-[url('../../assets/img/table/content-box-background03.svg')] bg-center;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .content-box .content-decoration2::after {
|
||||||
|
content: "";
|
||||||
|
background: url(../../assets/img/table/content-box-background04.svg) center
|
||||||
|
center;
|
||||||
|
position: absolute;
|
||||||
|
right: -27px;
|
||||||
|
bottom: -7px;
|
||||||
|
height: 65px;
|
||||||
|
width: 50px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
z-index: 2;
|
||||||
|
} */
|
||||||
|
</style>
|
@ -30,6 +30,10 @@ const props = defineProps({
|
|||||||
const currentDataSource = ref([]);
|
const currentDataSource = ref([]);
|
||||||
const dataSourceStorage = ref([]);
|
const dataSourceStorage = ref([]);
|
||||||
|
|
||||||
|
const tableDataSource = computed(() =>
|
||||||
|
props.pagination ? currentDataSource.value : dataSourceStorage.value
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.dataSource,
|
() => props.dataSource,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
@ -271,12 +275,12 @@ watch(
|
|||||||
<Loading />
|
<Loading />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-else-if="currentDataSource.length == 0">
|
<tr v-else-if="tableDataSource.length == 0">
|
||||||
<td :colspan="columns.length">{{ $t("table.no_data") }}</td>
|
<td :colspan="columns.length">{{ $t("table.no_data") }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<template v-else :sort="sortRule">
|
<template v-else :sort="sortRule">
|
||||||
<tr
|
<tr
|
||||||
v-for="(data, index) in currentDataSource"
|
v-for="(data, index) in tableDataSource"
|
||||||
:key="data.key || data[rowKey]"
|
:key="data.key || data[rowKey]"
|
||||||
>
|
>
|
||||||
<template
|
<template
|
||||||
@ -310,6 +314,7 @@ watch(
|
|||||||
</form>
|
</form>
|
||||||
<slot name="afterTable"></slot>
|
<slot name="afterTable"></slot>
|
||||||
<Pagination
|
<Pagination
|
||||||
|
v-if="pagination"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
:dataSource="dataSourceStorage"
|
:dataSource="dataSourceStorage"
|
||||||
:sort="sortRule"
|
:sort="sortRule"
|
||||||
|
@ -24,7 +24,10 @@
|
|||||||
"yesterday_electricity_consumption": "昨天用电量",
|
"yesterday_electricity_consumption": "昨天用电量",
|
||||||
"this_last_week": "本周/上周",
|
"this_last_week": "本周/上周",
|
||||||
"thisweek_electricity_consumption": "本周用电量",
|
"thisweek_electricity_consumption": "本周用电量",
|
||||||
"lastweek_electricity_consumption": "上周用电量"
|
"lastweek_electricity_consumption": "上周用电量",
|
||||||
|
"one_hour": "1小时",
|
||||||
|
"four_hour": "4小时",
|
||||||
|
"eight_hour": "8小时"
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"title": "历史资料",
|
"title": "历史资料",
|
||||||
@ -170,7 +173,7 @@
|
|||||||
"phone": "电话",
|
"phone": "电话",
|
||||||
"email": "email",
|
"email": "email",
|
||||||
"created_at": "建立日期",
|
"created_at": "建立日期",
|
||||||
"maintainance": "保养",
|
"maintenance": "保养",
|
||||||
"repair": "维修",
|
"repair": "维修",
|
||||||
"company_info": "厂商资料",
|
"company_info": "厂商资料",
|
||||||
"repair_item": "维修项目",
|
"repair_item": "维修项目",
|
||||||
@ -244,7 +247,9 @@
|
|||||||
"associated_device": "关联设备",
|
"associated_device": "关联设备",
|
||||||
"choose": "选择",
|
"choose": "选择",
|
||||||
"index": "编号",
|
"index": "编号",
|
||||||
"floor_plan": "平面图"
|
"floor_plan": "平面图",
|
||||||
|
"department": "部门",
|
||||||
|
"department_name": "部门名称"
|
||||||
},
|
},
|
||||||
"accountManagement": {
|
"accountManagement": {
|
||||||
"account_title": "帐号管理",
|
"account_title": "帐号管理",
|
||||||
|
@ -24,7 +24,10 @@
|
|||||||
"yesterday_electricity_consumption": "昨天用電量",
|
"yesterday_electricity_consumption": "昨天用電量",
|
||||||
"this_last_week": "本週/上週",
|
"this_last_week": "本週/上週",
|
||||||
"thisweek_electricity_consumption": "本周用電量",
|
"thisweek_electricity_consumption": "本周用電量",
|
||||||
"lastweek_electricity_consumption": "上週用電量"
|
"lastweek_electricity_consumption": "上週用電量",
|
||||||
|
"one_hour": "1小時",
|
||||||
|
"four_hour": "4小時",
|
||||||
|
"eight_hour": "8小時"
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"title": "歷史資料",
|
"title": "歷史資料",
|
||||||
@ -170,7 +173,7 @@
|
|||||||
"phone": "電話",
|
"phone": "電話",
|
||||||
"email": "email",
|
"email": "email",
|
||||||
"created_at": "建立日期",
|
"created_at": "建立日期",
|
||||||
"maintainance": "保養",
|
"maintenance": "保養",
|
||||||
"repair": "維修",
|
"repair": "維修",
|
||||||
"company_info": "廠商資料",
|
"company_info": "廠商資料",
|
||||||
"repair_item": "維修項目",
|
"repair_item": "維修項目",
|
||||||
@ -244,7 +247,9 @@
|
|||||||
"associated_device": "關聯設備",
|
"associated_device": "關聯設備",
|
||||||
"choose": "選擇",
|
"choose": "選擇",
|
||||||
"index": "編號",
|
"index": "編號",
|
||||||
"floor_plan": "平面圖"
|
"floor_plan": "平面圖",
|
||||||
|
"department": "部門",
|
||||||
|
"department_name": "部門名稱"
|
||||||
},
|
},
|
||||||
"accountManagement": {
|
"accountManagement": {
|
||||||
"account_title": "帳號管理",
|
"account_title": "帳號管理",
|
||||||
|
@ -42,7 +42,10 @@
|
|||||||
"yesterday_electricity_consumption": "Yesterday’s electricity consumption",
|
"yesterday_electricity_consumption": "Yesterday’s electricity consumption",
|
||||||
"this_last_week": "This Week's / Last Week's",
|
"this_last_week": "This Week's / Last Week's",
|
||||||
"thisweek_electricity_consumption": "This week’s electricity consumption",
|
"thisweek_electricity_consumption": "This week’s electricity consumption",
|
||||||
"lastweek_electricity_consumption": "Last week’s electricity consumption"
|
"lastweek_electricity_consumption": "Last week’s electricity consumption",
|
||||||
|
"one_hour": "1 hour",
|
||||||
|
"four_hour": "4 hour",
|
||||||
|
"eight_hour": "8 hour"
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
@ -147,9 +150,9 @@
|
|||||||
"notify_items": "Notification Items",
|
"notify_items": "Notification Items",
|
||||||
"notify_list": "Notification List",
|
"notify_list": "Notification List",
|
||||||
"choose": "Choose",
|
"choose": "Choose",
|
||||||
"day_time":"Week/Time",
|
"day_time": "Week/Time",
|
||||||
"click_time_period":"Please click the time period with your mouse",
|
"click_time_period": "Please click the time period with your mouse",
|
||||||
"clear":"Clear"
|
"clear": "Clear"
|
||||||
},
|
},
|
||||||
"operation": {
|
"operation": {
|
||||||
"title": "Operation And Maintenance Management",
|
"title": "Operation And Maintenance Management",
|
||||||
@ -244,7 +247,9 @@
|
|||||||
"associated_device": "Associated Devices",
|
"associated_device": "Associated Devices",
|
||||||
"choose": "Choose",
|
"choose": "Choose",
|
||||||
"index": "Serial Number",
|
"index": "Serial Number",
|
||||||
"floor_plan": "Floor Plan"
|
"floor_plan": "Floor Plan",
|
||||||
|
"department": "Department",
|
||||||
|
"department_name": "Department Name"
|
||||||
},
|
},
|
||||||
"accountManagement": {
|
"accountManagement": {
|
||||||
"account_title": "Account Management",
|
"account_title": "Account Management",
|
||||||
|
@ -58,7 +58,8 @@ import {
|
|||||||
faEye,
|
faEye,
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
faDownload
|
faDownload,
|
||||||
|
faStream
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
/* add icons to the library */
|
/* add icons to the library */
|
||||||
@ -118,7 +119,8 @@ library.add(
|
|||||||
faEye,
|
faEye,
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
faDownload
|
faDownload,
|
||||||
|
faStream
|
||||||
);
|
);
|
||||||
|
|
||||||
export default library;
|
export default library;
|
||||||
|
@ -39,7 +39,7 @@ instance.interceptors.response.use(
|
|||||||
// Any status codes that falls outside the range of 2xx cause this function to trigger
|
// Any status codes that falls outside the range of 2xx cause this function to trigger
|
||||||
// Do something with response error
|
// Do something with response error
|
||||||
if (error.response && error.response.status === 401) {
|
if (error.response && error.response.status === 401) {
|
||||||
window.location.href = "/logout";
|
window.location.href = "/";
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ const closeModal = () => {
|
|||||||
>
|
>
|
||||||
<template #modalContent>
|
<template #modalContent>
|
||||||
<form ref="form" class="grid grid-cols-5 gap-5">
|
<form ref="form" class="grid grid-cols-5 gap-5">
|
||||||
<div class="grid grid-cols-2 col-span-2">
|
<div class="grid grid-cols-2 col-span-2 items-end">
|
||||||
<AssetTableModalLeft :current_component_key="current_component_key" />
|
<AssetTableModalLeft :current_component_key="current_component_key" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-3">
|
<div class="col-span-3">
|
||||||
|
@ -3,10 +3,12 @@ import { ref, inject, onBeforeMount, onMounted, watch } from "vue";
|
|||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import "yup-phone-lite";
|
import "yup-phone-lite";
|
||||||
import AssetTableModalLeftInfoIoT from "./AssetTableModalLeftInfoIoT.vue";
|
import AssetTableModalLeftInfoIoT from "./AssetTableModalLeftInfoIoT.vue";
|
||||||
|
import AssetTableModalLeftInfoDept from "./AssetTableModalLeftInfoDept.vue";
|
||||||
import AssetTableModalLeftInfoGraph from "./AssetTableModalLeftInfoGraph.vue";
|
import AssetTableModalLeftInfoGraph from "./AssetTableModalLeftInfoGraph.vue";
|
||||||
|
import AssetTableModalLeftInfoMQTT from "./AssetTableModalLeftInfoMQTT.vue";
|
||||||
import { getOperationCompanyList } from "@/apis/operation";
|
import { getOperationCompanyList } from "@/apis/operation";
|
||||||
|
import { getIOTSchema } from "@/apis/asset";
|
||||||
import useSearchParam from "@/hooks/useSearchParam";
|
import useSearchParam from "@/hooks/useSearchParam";
|
||||||
import OperationTableModal from "@/views/operation/components/OperationTableModal.vue";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@ -28,6 +30,15 @@ let schema = {
|
|||||||
.number()
|
.number()
|
||||||
.transform((value) => (Number.isNaN(value) ? null : value))
|
.transform((value) => (Number.isNaN(value) ? null : value))
|
||||||
.nullable(true),
|
.nullable(true),
|
||||||
|
response_schema_id: yup
|
||||||
|
.number()
|
||||||
|
.transform((value) => (Number.isNaN(value) ? null : value))
|
||||||
|
.nullable(true),
|
||||||
|
department_id: yup
|
||||||
|
.number()
|
||||||
|
.transform((value) => (Number.isNaN(value) ? null : value))
|
||||||
|
.nullable(true),
|
||||||
|
topic: yup.string().nullable(true),
|
||||||
asset_number: yup.string().nullable(true),
|
asset_number: yup.string().nullable(true),
|
||||||
sub_device: yup.array().nullable(true),
|
sub_device: yup.array().nullable(true),
|
||||||
oriFile: yup.array().nullable(true),
|
oriFile: yup.array().nullable(true),
|
||||||
@ -41,7 +52,10 @@ onBeforeMount(() => {
|
|||||||
brand: "",
|
brand: "",
|
||||||
device_model: "",
|
device_model: "",
|
||||||
operation_id: 0,
|
operation_id: 0,
|
||||||
|
response_schema_id: 0,
|
||||||
|
department_id: 0,
|
||||||
asset_number: "",
|
asset_number: "",
|
||||||
|
topic: "",
|
||||||
sub_device: [],
|
sub_device: [],
|
||||||
oriFile: [],
|
oriFile: [],
|
||||||
buying_date: "",
|
buying_date: "",
|
||||||
@ -80,28 +94,25 @@ watch(formState, (newValue) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateFileList = (files) => {
|
|
||||||
formState.value = { ...formState.value, oriFile: files };
|
|
||||||
};
|
|
||||||
|
|
||||||
const companyOptions = ref([]);
|
const companyOptions = ref([]);
|
||||||
|
const iotSchemaOptions = ref([]);
|
||||||
const getCompany = async () => {
|
const getCompany = async () => {
|
||||||
const res = await getOperationCompanyList();
|
const res = await getOperationCompanyList();
|
||||||
companyOptions.value = res.data.map((d) => ({ ...d, key: d.id }));
|
companyOptions.value = res.data.map((d) => ({ ...d, key: d.id }));
|
||||||
};
|
};
|
||||||
|
const getIOTSchemaOptions = async () => {
|
||||||
|
const res = await getIOTSchema();
|
||||||
|
iotSchemaOptions.value = res.data.map((d) => ({ ...d, key: d.id }));
|
||||||
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getCompany();
|
getCompany();
|
||||||
|
getIOTSchemaOptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
const openCompanyAddModal = () => {
|
|
||||||
changeParams({ ...searchParams.value, work_type: 3 }); // 開啟company Add modal
|
|
||||||
operation_action_item.showModal();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- information -->
|
<!-- information -->
|
||||||
<Input :value="formState" width="270" name="full_name">
|
<Input :value="formState" width="290" name="full_name">
|
||||||
<template #topLeft>{{ $t("assetManagement.device_name") }}</template>
|
<template #topLeft>{{ $t("assetManagement.device_name") }}</template>
|
||||||
<template #bottomLeft
|
<template #bottomLeft
|
||||||
><span class="text-error text-base">
|
><span class="text-error text-base">
|
||||||
@ -109,15 +120,8 @@ const openCompanyAddModal = () => {
|
|||||||
</span></template
|
</span></template
|
||||||
></Input
|
></Input
|
||||||
>
|
>
|
||||||
<Input :value="formState" width="270" name="operate_text">
|
<AssetTableModalLeftInfoDept />
|
||||||
<template #topLeft>Mac</template>
|
<Input :value="formState" width="290" name="device_number">
|
||||||
<template #bottomLeft
|
|
||||||
><span class="text-error text-base">
|
|
||||||
{{ formErrorMsg.operate_text }}
|
|
||||||
</span></template
|
|
||||||
></Input
|
|
||||||
>
|
|
||||||
<Input :value="formState" width="270" name="device_number">
|
|
||||||
<template #topLeft
|
<template #topLeft
|
||||||
>Tag_Name ({{ $t("assetManagement.fill_text") }})</template
|
>Tag_Name ({{ $t("assetManagement.fill_text") }})</template
|
||||||
>
|
>
|
||||||
@ -127,28 +131,19 @@ const openCompanyAddModal = () => {
|
|||||||
</span></template
|
</span></template
|
||||||
></Input
|
></Input
|
||||||
>
|
>
|
||||||
<!-- <Input :value="formState" width="270" name="floor_guid">
|
<div class="flex items-center w-72">
|
||||||
<template #topLeft>設備位置(樓層 / 區域)</template>
|
<Select
|
||||||
<template #bottomLeft
|
:value="formState"
|
||||||
><span class="text-error text-base">
|
selectClass="border-info focus-within:border-info"
|
||||||
{{ formErrorMsg.floor_guid }}
|
name="response_schema_id"
|
||||||
</span></template
|
Attribute="name"
|
||||||
></Input
|
:options="iotSchemaOptions"
|
||||||
> -->
|
:required="true"
|
||||||
<Input
|
>
|
||||||
:value="formState"
|
<template #topLeft>IoT</template>
|
||||||
width="270"
|
</Select>
|
||||||
name="device_coordinate"
|
</div>
|
||||||
:disabled="true"
|
<Input :value="formState" width="290" name="asset_number">
|
||||||
>
|
|
||||||
<template #topLeft>{{ $t("assetManagement.device_coordinate") }}</template>
|
|
||||||
<template #bottomLeft
|
|
||||||
><span class="text-error text-base">
|
|
||||||
{{ formErrorMsg.device_coordinate }}
|
|
||||||
</span></template
|
|
||||||
></Input
|
|
||||||
>
|
|
||||||
<Input :value="formState" width="270" name="asset_number">
|
|
||||||
<template #topLeft>{{ $t("assetManagement.asset_number") }}</template>
|
<template #topLeft>{{ $t("assetManagement.asset_number") }}</template>
|
||||||
<template #bottomLeft
|
<template #bottomLeft
|
||||||
><span class="text-error text-base">
|
><span class="text-error text-base">
|
||||||
@ -156,7 +151,7 @@ const openCompanyAddModal = () => {
|
|||||||
</span></template
|
</span></template
|
||||||
></Input
|
></Input
|
||||||
>
|
>
|
||||||
<DateGroup :items="buying_date" width="270" :withLine="false">
|
<DateGroup :items="buying_date" width="290" :withLine="false">
|
||||||
<template #topLeft>{{ $t("assetManagement.buying_date") }}</template>
|
<template #topLeft>{{ $t("assetManagement.buying_date") }}</template>
|
||||||
<template #bottomLeft
|
<template #bottomLeft
|
||||||
><span class="text-error text-base">
|
><span class="text-error text-base">
|
||||||
@ -164,7 +159,7 @@ const openCompanyAddModal = () => {
|
|||||||
</span></template
|
</span></template
|
||||||
>
|
>
|
||||||
</DateGroup>
|
</DateGroup>
|
||||||
<Input :value="formState" width="270" name="brand">
|
<Input :value="formState" width="290" name="brand">
|
||||||
<template #topLeft>{{ $t("assetManagement.brand") }}</template>
|
<template #topLeft>{{ $t("assetManagement.brand") }}</template>
|
||||||
<template #bottomLeft
|
<template #bottomLeft
|
||||||
><span class="text-error text-base">
|
><span class="text-error text-base">
|
||||||
@ -172,7 +167,7 @@ const openCompanyAddModal = () => {
|
|||||||
</span></template
|
</span></template
|
||||||
></Input
|
></Input
|
||||||
>
|
>
|
||||||
<Input :value="formState" width="270" name="device_model">
|
<Input :value="formState" width="290" name="device_model">
|
||||||
<template #topLeft>{{ $t("assetManagement.modal") }}</template>
|
<template #topLeft>{{ $t("assetManagement.modal") }}</template>
|
||||||
<template #bottomLeft
|
<template #bottomLeft
|
||||||
><span class="text-error text-base">
|
><span class="text-error text-base">
|
||||||
@ -180,7 +175,7 @@ const openCompanyAddModal = () => {
|
|||||||
</span></template
|
</span></template
|
||||||
></Input
|
></Input
|
||||||
>
|
>
|
||||||
<div class="flex items-center col-span-2">
|
<div class="flex items-center w-72">
|
||||||
<Select
|
<Select
|
||||||
:value="formState"
|
:value="formState"
|
||||||
selectClass="border-info focus-within:border-info"
|
selectClass="border-info focus-within:border-info"
|
||||||
@ -191,27 +186,9 @@ const openCompanyAddModal = () => {
|
|||||||
>
|
>
|
||||||
<template #topLeft>{{ $t("assetManagement.company") }}</template>
|
<template #topLeft>{{ $t("assetManagement.company") }}</template>
|
||||||
</Select>
|
</Select>
|
||||||
<OperationTableModal type="asset" />
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-add ml-2 mt-7"
|
|
||||||
@click="openCompanyAddModal"
|
|
||||||
>
|
|
||||||
<font-awesome-icon :icon="['fas', 'plus']" />
|
|
||||||
{{ $t("button.add") }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<AssetTableModalLeftInfoMQTT />
|
||||||
<AssetTableModalLeftInfoGraph />
|
<AssetTableModalLeftInfoGraph />
|
||||||
<!-- <Upload
|
|
||||||
name="oriFile"
|
|
||||||
:fileList="formState.oriFile"
|
|
||||||
:getFileList="updateFileList"
|
|
||||||
:multiple="true"
|
|
||||||
class="col-span-2"
|
|
||||||
:baseUrl="FILE_BASEURL"
|
|
||||||
>
|
|
||||||
<template #topLeft>{{ $t("assetManagement.oriFile") }}</template>
|
|
||||||
</Upload> -->
|
|
||||||
<AssetTableModalLeftInfoIoT />
|
<AssetTableModalLeftInfoIoT />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -0,0 +1,161 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, inject, onBeforeMount, watch, computed } from "vue";
|
||||||
|
import {
|
||||||
|
getDepartmentList,
|
||||||
|
postDepartmentList,
|
||||||
|
deleteDepartmentItem,
|
||||||
|
} from "@/apis/asset";
|
||||||
|
import useFormErrorMessage from "@/hooks/useFormErrorMessage";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { openToast, cancelToastOpen } = inject("app_toast");
|
||||||
|
const { formState } = inject("asset_table_modal_form");
|
||||||
|
|
||||||
|
const selectedOption = ref("add");
|
||||||
|
|
||||||
|
const DeptFormState = ref({ id: 0, name: "" });
|
||||||
|
const departmentList = ref([]);
|
||||||
|
|
||||||
|
const getDepartment = async () => {
|
||||||
|
const res = await getDepartmentList();
|
||||||
|
departmentList.value = res.data.map((d) => ({ ...d, key: d.id }));
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDepartment();
|
||||||
|
});
|
||||||
|
|
||||||
|
// modal
|
||||||
|
const openModal = () => {
|
||||||
|
if (selectedOption.value === "add") {
|
||||||
|
DeptFormState.value = {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
};
|
||||||
|
} else if (selectedOption.value === "edit") {
|
||||||
|
const dept = departmentList.value.find(
|
||||||
|
(d) => d.id === formState.value.department_id
|
||||||
|
);
|
||||||
|
if (dept) {
|
||||||
|
DeptFormState.value = {
|
||||||
|
id: dept.id,
|
||||||
|
name: dept.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asset_add_dept.showModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
const form = ref(null);
|
||||||
|
|
||||||
|
const deptScheme = yup.object({
|
||||||
|
name: yup.string().required(t("button.required")),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { formErrorMsg, handleSubmit, handleErrorReset, updateScheme } =
|
||||||
|
useFormErrorMessage(deptScheme);
|
||||||
|
const onOk = async () => {
|
||||||
|
const value = await handleSubmit(deptScheme, DeptFormState.value);
|
||||||
|
|
||||||
|
const res = await postDepartmentList(value);
|
||||||
|
if (res.isSuccess) {
|
||||||
|
getDepartment();
|
||||||
|
onCancel();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDelete = async () => {
|
||||||
|
openToast(
|
||||||
|
"warning",
|
||||||
|
t("msg.sure_to_delete"),
|
||||||
|
"#asset_add_table_item",
|
||||||
|
async () => {
|
||||||
|
await cancelToastOpen();
|
||||||
|
const res = await deleteDepartmentItem(formState.value.department_id);
|
||||||
|
if (res.isSuccess) {
|
||||||
|
getDepartment();
|
||||||
|
openToast("success", t("msg.delete_success"), "#asset_add_table_item");
|
||||||
|
} else {
|
||||||
|
openToast("error", res.msg, "#asset_add_table_item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
DeptFormState.value = {
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
};
|
||||||
|
asset_add_dept.close();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div className="join w-72 mb-4">
|
||||||
|
<Select
|
||||||
|
:value="formState"
|
||||||
|
selectClass="border-info focus-within:border-info rounded-r-none"
|
||||||
|
name="department_id"
|
||||||
|
Attribute="name"
|
||||||
|
:options="departmentList"
|
||||||
|
:isBottomLabelExist="false"
|
||||||
|
>
|
||||||
|
<template #topLeft>{{ $t("assetManagement.department") }}</template>
|
||||||
|
</Select>
|
||||||
|
<select
|
||||||
|
v-model="selectedOption"
|
||||||
|
className="select border-info focus-within:border-info join-item mt-11"
|
||||||
|
>
|
||||||
|
<option value="add" selected>{{ $t("button.add") }}</option>
|
||||||
|
<option value="edit">{{ $t("button.edit") }}</option>
|
||||||
|
<option value="delete">{{ $t("button.delete") }}</option>
|
||||||
|
</select>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-success join-item mt-11"
|
||||||
|
@click="selectedOption === 'delete' ? onDelete() : openModal()"
|
||||||
|
:aria-label="$t('button.submit')"
|
||||||
|
>
|
||||||
|
{{ $t("button.submit") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<Modal
|
||||||
|
id="asset_add_dept"
|
||||||
|
:title="t('assetManagement.department')"
|
||||||
|
:onCancel="onCancel"
|
||||||
|
width="400"
|
||||||
|
>
|
||||||
|
<template #modalContent>
|
||||||
|
<form ref="form">
|
||||||
|
<Input :value="DeptFormState" width="270" name="name">
|
||||||
|
<template #topLeft>{{
|
||||||
|
$t("assetManagement.department_name")
|
||||||
|
}}</template>
|
||||||
|
<template #bottomLeft
|
||||||
|
><span class="text-error text-base">
|
||||||
|
{{ formErrorMsg.name }}
|
||||||
|
</span></template
|
||||||
|
></Input
|
||||||
|
>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
<template #modalAction>
|
||||||
|
<button
|
||||||
|
type="reset"
|
||||||
|
class="btn btn-outline-success mr-2"
|
||||||
|
@click.prevent="onCancel"
|
||||||
|
>
|
||||||
|
{{ $t("button.cancel") }}
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="btn btn-outline-success" @click="onOk">
|
||||||
|
{{ $t("button.submit") }}
|
||||||
|
</button>
|
||||||
|
</template></Modal
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
@ -0,0 +1,134 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, inject, watch, computed } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import mqtt from "mqtt";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { openToast, cancelToastOpen } = inject("app_toast");
|
||||||
|
const { formState } = inject(
|
||||||
|
"asset_table_modal_form"
|
||||||
|
);
|
||||||
|
const BASEURL = import.meta.env.VITE_MQTT_BASEURL;
|
||||||
|
// MQTT相關
|
||||||
|
const mqttClient = ref(null); // MQTT客戶端
|
||||||
|
const receivedMessages = ref([]); // 儲存接收到的訊息
|
||||||
|
const countdown = ref(60); // 倒計時初始為 60 秒
|
||||||
|
let timer = null; // 記錄計時器
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
if (!mqttClient.value) {
|
||||||
|
connectMqtt();
|
||||||
|
}
|
||||||
|
mqtt_test.showModal();
|
||||||
|
startCountdown(); // 開始倒計時
|
||||||
|
};
|
||||||
|
|
||||||
|
const connectMqtt = () => {
|
||||||
|
const topic = formState.value.topic || ""; // 取得主題
|
||||||
|
const mqttHost = `${BASEURL}`;
|
||||||
|
const protocol = import.meta.env.MODE === "production" ? "wss" : "ws"; // 根據伺服器配置,需要設置為 "ws" 或 "wss"
|
||||||
|
mqttClient.value = mqtt.connect(mqttHost, {
|
||||||
|
protocol,
|
||||||
|
reconnectPeriod: 1000, // 每秒嘗試重新連線
|
||||||
|
});
|
||||||
|
|
||||||
|
mqttClient.value.on("connect", () => {
|
||||||
|
console.log("MQTT 已連接");
|
||||||
|
if (topic) {
|
||||||
|
mqttClient.value.subscribe(topic, (err) => {
|
||||||
|
if (!err) {
|
||||||
|
console.log(`已訂閱主題: ${topic}`);
|
||||||
|
} else {
|
||||||
|
console.error("訂閱失敗: ", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mqttClient.value.on("message", (topic, message) => {
|
||||||
|
// 儲存接收到的訊息
|
||||||
|
receivedMessages.value.push({ topic, message: message.toString() });
|
||||||
|
clearInterval(timer); // 收到訊息後清除倒計時
|
||||||
|
});
|
||||||
|
|
||||||
|
mqttClient.value.on("error", (err) => {
|
||||||
|
console.error("MQTT 連線錯誤: ", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const startCountdown = () => {
|
||||||
|
if (timer) return; // 防止重複啟動計時器
|
||||||
|
timer = setInterval(() => {
|
||||||
|
if (countdown.value > 0) {
|
||||||
|
countdown.value--;
|
||||||
|
} else {
|
||||||
|
onCancel(); // 1分鐘後如果沒有收到訊息則觸發 onCancel
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
receivedMessages.value = [];
|
||||||
|
mqtt_test.close();
|
||||||
|
|
||||||
|
// 斷開 MQTT 連線
|
||||||
|
if (mqttClient.value) {
|
||||||
|
mqttClient.value.end();
|
||||||
|
mqttClient.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置倒計時
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null; // 清除計時器引用
|
||||||
|
}
|
||||||
|
countdown.value = 60;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex w-72">
|
||||||
|
<Input :value="formState" name="topic" >
|
||||||
|
<template #topLeft>MQTT Topic</template>
|
||||||
|
</Input>
|
||||||
|
<button type="button" class="btn btn-add mt-11 ms-1" @click="openModal">
|
||||||
|
<font-awesome-icon :icon="['fas', 'cog']" />
|
||||||
|
Test
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Modal id="mqtt_test" title="MQTT Topic" :onCancel="onCancel" width="400">
|
||||||
|
<template #modalContent>
|
||||||
|
<!-- 顯示接收到的訊息 -->
|
||||||
|
<div v-if="receivedMessages.length > 0" class="overflow-y-auto h-96">
|
||||||
|
<ul>
|
||||||
|
<li
|
||||||
|
v-for="(message, index) in receivedMessages"
|
||||||
|
:key="index"
|
||||||
|
class="bg-base-200 rounded-md text-wrap shadow shadow-slate-400 p-4 my-2 me-2"
|
||||||
|
>
|
||||||
|
<strong class=" text-base block text-info mb-2">{{ message.topic }} :</strong>
|
||||||
|
<p class=" text-sm break-words">{{ message.message }}</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- 顯示 loading 和倒計時 -->
|
||||||
|
<p v-else class="text-center mt-20">
|
||||||
|
<Loading />
|
||||||
|
<br />
|
||||||
|
<span class="text-base">{{ countdown }} seconds</span>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
<template #modalAction>
|
||||||
|
<button
|
||||||
|
type="reset"
|
||||||
|
class="btn btn-outline-success mr-2"
|
||||||
|
@click.prevent="onCancel"
|
||||||
|
>
|
||||||
|
{{ t("button.cancel") }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
@ -74,10 +74,10 @@ const defaultOption = (map, data = []) => {
|
|||||||
watch(currentFloor, (newValue) => {
|
watch(currentFloor, (newValue) => {
|
||||||
if (newValue?.floor_map_name) {
|
if (newValue?.floor_map_name) {
|
||||||
const coordinates = totalCoordinates.value[newValue.floor_guid] || [];
|
const coordinates = totalCoordinates.value[newValue.floor_guid] || [];
|
||||||
|
if (coordinates.length === 0 || coordinates.every(coord => coord === "")) return;
|
||||||
const parsedCoordinates = coordinates.map((coord) => {
|
const parsedCoordinates = coordinates.map((coord) => {
|
||||||
return JSON.parse(coord);
|
return JSON.parse(coord);
|
||||||
});
|
});
|
||||||
|
|
||||||
asset_floor_chart.value.updateSvg(
|
asset_floor_chart.value.updateSvg(
|
||||||
{
|
{
|
||||||
full_name: newValue?.floor_map_name,
|
full_name: newValue?.floor_map_name,
|
||||||
@ -209,8 +209,8 @@ const onCancel = () => {
|
|||||||
<template>
|
<template>
|
||||||
<!-- 平面圖 -->
|
<!-- 平面圖 -->
|
||||||
|
|
||||||
<div class="flex items-center justify-between mb-5">
|
<div class="flex gap-4 mb-5">
|
||||||
<div className="join">
|
<div className="join w-80 mb-4">
|
||||||
<Select
|
<Select
|
||||||
:value="formState"
|
:value="formState"
|
||||||
selectClass="border-info focus-within:border-info rounded-r-none"
|
selectClass="border-info focus-within:border-info rounded-r-none"
|
||||||
@ -238,6 +238,19 @@ const onCancel = () => {
|
|||||||
{{ $t("button.submit") }}
|
{{ $t("button.submit") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<Input
|
||||||
|
:value="formState"
|
||||||
|
width="270"
|
||||||
|
name="device_coordinate"
|
||||||
|
:disabled="true"
|
||||||
|
>
|
||||||
|
<template #topLeft>{{ $t("assetManagement.device_coordinate") }}</template>
|
||||||
|
<template #bottomLeft
|
||||||
|
><span class="text-error text-base">
|
||||||
|
{{ formErrorMsg.device_coordinate }}
|
||||||
|
</span></template
|
||||||
|
></Input
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<EffectScatter
|
<EffectScatter
|
||||||
|
@ -89,7 +89,7 @@ const getAllOptions = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateDataSource = (data) => {
|
const updateDataSource = (data) => {
|
||||||
dataSource.value = data.map((d) => ({ ...d, key: d.uuid }));
|
dataSource.value = (data || []).map((d) => ({ ...d, key: d.uuid }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
|
@ -19,7 +19,7 @@ const store = useBuildingStore();
|
|||||||
|
|
||||||
const dataSource = ref([]);
|
const dataSource = ref([]);
|
||||||
const updateDataSource = (data) => {
|
const updateDataSource = (data) => {
|
||||||
dataSource.value = data.map((d) => ({
|
dataSource.value = (data || []).map((d) => ({
|
||||||
...d,
|
...d,
|
||||||
key: d.id,
|
key: d.id,
|
||||||
start_time: d?.start_time ? dayjs(d?.start_time).format("YYYY-MM-DD") : "",
|
start_time: d?.start_time ? dayjs(d?.start_time).format("YYYY-MM-DD") : "",
|
||||||
|
@ -81,7 +81,7 @@ watch(
|
|||||||
:items="submitBtns"
|
:items="submitBtns"
|
||||||
:withLine="false"
|
:withLine="false"
|
||||||
:withBtnClass="true"
|
:withBtnClass="true"
|
||||||
class="ml-5 mr-8 xl:mr-10"
|
v-if="selectedWorkType?.work_type !== 3"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button class="btn btn-add" @click.stop.prevent="() => openModal()">
|
<button class="btn btn-add" @click.stop.prevent="() => openModal()">
|
||||||
|
@ -135,7 +135,8 @@ watch(
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OperationSearchType :selected="selectedSearchType" />
|
<OperationSearchType :selected="selectedSearchType"
|
||||||
|
v-if="selectedWorkType?.work_type !== 3" />
|
||||||
<OperationActionButton :selectedWorkType="selectedWorkType" />
|
<OperationActionButton :selectedWorkType="selectedWorkType" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -116,7 +116,7 @@ watch(
|
|||||||
} else if (newSearchParams.search_type === "serial") {
|
} else if (newSearchParams.search_type === "serial") {
|
||||||
changeParams({
|
changeParams({
|
||||||
...searchParams.value,
|
...searchParams.value,
|
||||||
serial_number: newSerialNumber.value,
|
serial_number: newSerialNumber,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -151,7 +151,7 @@ watch(
|
|||||||
name="serial_number"
|
name="serial_number"
|
||||||
:class="twMerge(searchParams?.work_type === '3' ? '' : 'mr-3')"
|
:class="twMerge(searchParams?.work_type === '3' ? '' : 'mr-3')"
|
||||||
:placeholder="searchParams?.work_type === '3' ? $t('operation.enter_text') : $t('operation.enter_serial')"
|
:placeholder="searchParams?.work_type === '3' ? $t('operation.enter_text') : $t('operation.enter_serial')"
|
||||||
:value="serial_number"
|
:value="searchParams"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -530,7 +530,7 @@ watch(
|
|||||||
class="my-2"
|
class="my-2"
|
||||||
name="email"
|
name="email"
|
||||||
>
|
>
|
||||||
<template #topLeft>>{{ $t("operation.email") }}</template>
|
<template #topLeft>{{ $t("operation.email") }}</template>
|
||||||
<template #bottomLeft
|
<template #bottomLeft
|
||||||
><span class="text-error text-base">
|
><span class="text-error text-base">
|
||||||
{{ companyFormErrorMsg.email }}
|
{{ companyFormErrorMsg.email }}
|
||||||
|
@ -206,6 +206,9 @@ const getCurrentInfoModalData = async (e, position, value) => {
|
|||||||
: "",
|
: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const immediateRes = await getSystemRealTime([value.device_number]);
|
||||||
|
realtimeData.value = immediateRes.data;
|
||||||
}
|
}
|
||||||
const mobile = isMobile(e);
|
const mobile = isMobile(e);
|
||||||
selectedDevice.value = {
|
selectedDevice.value = {
|
||||||
|
194
src/views/system/components/SystemInfoModalChart.vue
Normal file
194
src/views/system/components/SystemInfoModalChart.vue
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<script setup>
|
||||||
|
import { inject, onMounted, onUnmounted, ref, nextTick, watch } from "vue";
|
||||||
|
import { getHistoryData } from "@/apis/history";
|
||||||
|
import LineChart from "@/components/chart/LineChart.vue";
|
||||||
|
import { SECOND_CHART_COLOR } from "@/constant";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const { selectedDevice: data } = inject("system_selectedDevice");
|
||||||
|
const pointsList = ref([]);
|
||||||
|
const timeList = ref([
|
||||||
|
{ value: 1, name: t("dashboard.one_hour") },
|
||||||
|
{ value: 4, name: t("dashboard.four_hour") },
|
||||||
|
{ value: 8, name: t("dashboard.eight_hour") },
|
||||||
|
]);
|
||||||
|
const chartData = ref([]);
|
||||||
|
const forge_chart = ref(null);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 預設圖表選項
|
||||||
|
const defaultChartOption = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: [],
|
||||||
|
textStyle: {
|
||||||
|
color: "#ffffff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: "25%",
|
||||||
|
left: "0%",
|
||||||
|
right: "0%",
|
||||||
|
bottom: "0%",
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
splitLine: { show: false },
|
||||||
|
axisLabel: {
|
||||||
|
color: "#ffffff",
|
||||||
|
formatter: (value) => dayjs(value).format("HH:mm"), // 格式化為時間
|
||||||
|
},
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
splitLine: { show: false },
|
||||||
|
axisLabel: { color: "#ffffff" },
|
||||||
|
},
|
||||||
|
series: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const formState = ref({
|
||||||
|
Cumulant: 1,
|
||||||
|
Type: 2,
|
||||||
|
Points: [],
|
||||||
|
Start_date: dayjs().format("YYYY-MM-DD"),
|
||||||
|
Start_time: dayjs().format("HH:00"),
|
||||||
|
End_date: dayjs().format("YYYY-MM-DD"),
|
||||||
|
End_time: dayjs().format("HH:00"),
|
||||||
|
Device_list: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateTimeRange = (hours) => {
|
||||||
|
const now = dayjs();
|
||||||
|
const startTime = now.subtract(hours, "hour");
|
||||||
|
formState.value.Start_date = startTime.format("YYYY-MM-DD");
|
||||||
|
formState.value.Start_time = startTime.format("HH:00");
|
||||||
|
formState.value.End_date = now.format("YYYY-MM-DD");
|
||||||
|
formState.value.End_time = now.format("HH:00");
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSearch = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await getHistoryData(formState.value);
|
||||||
|
if (res.isSuccess) {
|
||||||
|
if (res.data.items.length > 0) {
|
||||||
|
chartData.value = res.data.items
|
||||||
|
.map((d) => ({
|
||||||
|
timestamp: d.timestamp,
|
||||||
|
value: parseFloat(d.value),
|
||||||
|
}))
|
||||||
|
.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
|
||||||
|
|
||||||
|
// 更新圖表
|
||||||
|
await nextTick();
|
||||||
|
if (forge_chart.value?.chart) {
|
||||||
|
forge_chart.value.chart.setOption({
|
||||||
|
xAxis: {
|
||||||
|
data: chartData.value.map((d) => d.timestamp),
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: data?.value?.value.full_name,
|
||||||
|
type: "line",
|
||||||
|
data: chartData.value.map((d) => d.value),
|
||||||
|
showSymbol: false,
|
||||||
|
itemStyle: {
|
||||||
|
color: SECOND_CHART_COLOR[0], // 使用預設顏色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chartData.value = [];
|
||||||
|
if (forge_chart.value?.chart) {
|
||||||
|
forge_chart.value.chart.clear(); // 清空圖表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("API Error:", res.msg);
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
console.log("Initial data:", data?.value?.value);
|
||||||
|
if (data?.value?.value.device_number) {
|
||||||
|
formState.value.Device_list = [data?.value?.value.device_number];
|
||||||
|
}
|
||||||
|
if (data?.value?.value.points) {
|
||||||
|
pointsList.value = data?.value?.value?.points.map((item) => ({
|
||||||
|
name: item.full_name,
|
||||||
|
value: item.points,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
formState.value = {};
|
||||||
|
chartData.value = [];
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => formState.value.Points,
|
||||||
|
(newPoints) => {
|
||||||
|
if (newPoints.includes("Total")) {
|
||||||
|
formState.value.Cumulant = 2;
|
||||||
|
} else {
|
||||||
|
formState.value.Cumulant = 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<Select
|
||||||
|
:value="formState"
|
||||||
|
class=""
|
||||||
|
selectClass="border-info focus-within:border-info"
|
||||||
|
name="Points"
|
||||||
|
Attribute="name"
|
||||||
|
:options="pointsList"
|
||||||
|
></Select>
|
||||||
|
<Select
|
||||||
|
:value="formState"
|
||||||
|
class=""
|
||||||
|
selectClass="border-info focus-within:border-info"
|
||||||
|
name="time"
|
||||||
|
Attribute="name"
|
||||||
|
:options="timeList"
|
||||||
|
:onChange="updateTimeRange"
|
||||||
|
></Select>
|
||||||
|
<button class="btn btn-search" @click.stop.prevent="onSearch">
|
||||||
|
<font-awesome-icon :icon="['fas', 'search']" />
|
||||||
|
{{ $t("button.search") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="min-h-[300px] relative">
|
||||||
|
<span
|
||||||
|
v-if="loading"
|
||||||
|
className="loading loading-spinner loading-lg text-info absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-20"
|
||||||
|
></span>
|
||||||
|
<LineChart
|
||||||
|
v-if="chartData.length > 0"
|
||||||
|
id="forge_chart"
|
||||||
|
class="min-h-[300px] max-h-fit"
|
||||||
|
:option="defaultChartOption"
|
||||||
|
ref="forge_chart"
|
||||||
|
/>
|
||||||
|
<p class="text-center text-xl" v-if="!loading && chartData.length === 0">
|
||||||
|
{{ $t("table.no_data") }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
@ -3,9 +3,9 @@ import { defineProps, inject, ref, watch } from "vue";
|
|||||||
import SystemInfoModalDesktop from "./SystemInfoModalDesktop.vue";
|
import SystemInfoModalDesktop from "./SystemInfoModalDesktop.vue";
|
||||||
import SystemInfoModalCog from "./SystemInfoModalCog.vue";
|
import SystemInfoModalCog from "./SystemInfoModalCog.vue";
|
||||||
import SystemInfoModalImage from "./SystemInfoModalImage.vue";
|
import SystemInfoModalImage from "./SystemInfoModalImage.vue";
|
||||||
|
import SystemInfoModalChart from "./SystemInfoModalChart.vue";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
|
||||||
const { selectedDevice: data, clearSelectedDeviceInfo } = inject("system_selectedDevice")
|
const { selectedDevice: data, clearSelectedDeviceInfo } = inject("system_selectedDevice")
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +13,8 @@ const currentTab = ref("desktop");
|
|||||||
const tabs = {
|
const tabs = {
|
||||||
desktop: SystemInfoModalDesktop,
|
desktop: SystemInfoModalDesktop,
|
||||||
cog: SystemInfoModalCog,
|
cog: SystemInfoModalCog,
|
||||||
image: SystemInfoModalImage
|
image: SystemInfoModalImage,
|
||||||
|
// chart: SystemInfoModalChart,
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeOpenKey = (key) => {
|
const changeOpenKey = (key) => {
|
||||||
@ -44,28 +45,10 @@ const onCancel = () => {
|
|||||||
<font-awesome-icon :icon="['fas', 'cog']" size="lg"
|
<font-awesome-icon :icon="['fas', 'cog']" size="lg"
|
||||||
:class="twMerge(currentTab === 'cog' ? 'text-success' : 'text-[#a5abb1]')" />
|
:class="twMerge(currentTab === 'cog' ? 'text-success' : 'text-[#a5abb1]')" />
|
||||||
</Button>
|
</Button>
|
||||||
<!-- <Button
|
<!-- <Button type="link" class="btn-link btn-text-without-border px-2" @click="() => changeOpenKey('chart')">
|
||||||
type="link"
|
<font-awesome-icon :icon="['fas', 'chart-line']" size="lg"
|
||||||
class="btn-link btn-text-without-border px-2"
|
:class="twMerge(currentTab === 'chart' ? 'text-success' : 'text-[#a5abb1]')" />
|
||||||
@click="() => changeOpenKey('triangle')"
|
</Button> -->
|
||||||
>
|
|
||||||
<font-awesome-icon
|
|
||||||
:icon="['fas', 'exclamation-triangle']"
|
|
||||||
size="lg"
|
|
||||||
class="text-[#a5abb1]"
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
class="btn-link btn-text-without-border px-2"
|
|
||||||
@click="() => changeOpenKey('bars')"
|
|
||||||
>
|
|
||||||
<font-awesome-icon
|
|
||||||
:icon="['fas', 'bars']"
|
|
||||||
size="lg"
|
|
||||||
class="text-[#a5abb1]"
|
|
||||||
/>
|
|
||||||
</Button>-->
|
|
||||||
<Button type="link" class="btn-link btn-text-without-border px-2" @click="onCancel">
|
<Button type="link" class="btn-link btn-text-without-border px-2" @click="onCancel">
|
||||||
<font-awesome-icon :icon="['fas', 'times']" size="lg" class="text-[#a5abb1]" />
|
<font-awesome-icon :icon="['fas', 'times']" size="lg" class="text-[#a5abb1]" />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -11,14 +11,16 @@ const data = computed(() => {
|
|||||||
|
|
||||||
return selectedDevice.value?.value?.points?.map((d) => ({
|
return selectedDevice.value?.value?.points?.map((d) => ({
|
||||||
...d,
|
...d,
|
||||||
value: selectedDeviceRealtime?.value?.find(({ point }) => point === d.points)?.value || "No Data"
|
value: selectedDeviceRealtime?.value?.find(({ point }) => point === d.points)?.value || 0
|
||||||
})) || []
|
})) || []
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(selectedDeviceRealtime, (newValue) => {
|
watch(selectedDeviceRealtime, (newValue,oldValue) => {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
updatedTime.value = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss");
|
updatedTime.value = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
}else{
|
||||||
|
loading.value = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ const columns = [{
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
:dataSource="data || []"
|
:dataSource="data || []"
|
||||||
:withStyle="false"
|
:withStyle="false"
|
||||||
|
:pagination="false"
|
||||||
>
|
>
|
||||||
</Table>
|
</Table>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user