zhuguifei
2025-07-25 85a15646ffe20ed2bbb2042ec500df8c850a69cc
首次提交
已修改15个文件
已删除3个文件
已重命名12个文件
已添加6个文件
3360 ■■■■■ 文件已修改
App.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/api.js 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
common/constant.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dryuniapp.keystore 补丁 | 查看 | 原始文档 | blame | 历史
manifest.json 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
mqtt/MqttView.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 496 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/analy/analyList.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/category/formulaDetail.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/charts/charts.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/device/control.vue 969 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/index/index.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/login/switchMode.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/me/analy.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/me/control.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/pages/me/video.vue 补丁 | 查看 | 原始文档 | blame | 历史
packageA/static/.DS_Store 补丁 | 查看 | 原始文档 | blame | 历史
packageA/static/image/ganzaoji-x.png 补丁 | 查看 | 原始文档 | blame | 历史
packageA/static/image/pic_gz.jpg 补丁 | 查看 | 原始文档 | blame | 历史
packageA/static/image/pic_gzj.jpg 补丁 | 查看 | 原始文档 | blame | 历史
packageA/static/image/zcy_equipment_run.gif 补丁 | 查看 | 原始文档 | blame | 历史
packageA/static/image/zcy_gzj1.png 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 197 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/device/control.vue 658 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/login/login.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/components/equList.vue 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/components/realWarning.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/device.vue 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/formula.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/general.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/me.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/warning-new.vue 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabBar/warning.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
private.wx8aa7310d86d0b80d.key 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
private.wxe6f8a31c3df63a20.key 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
App.vue
@@ -33,16 +33,16 @@
            //推送仅支持Android ios原生平台
            // #ifdef APP-PLUS
            // æ­¤å¤„为unipush1.0的推送方法
            plus.push.getClientInfoAsync((info) => {
                let cid = info["clientid"];
                console.log('客户端推送标识:', cid)
                this.$store.dispatch('setClientPushId', cid); // ä½¿ç”¨ action æ›´æ–° cid
            // plus.push.getClientInfoAsync((info) => {
            //     let cid = info["clientid"];
            //     console.log('客户端推送标识:', cid)
            //     this.$store.dispatch('setClientPushId', cid); // ä½¿ç”¨ action æ›´æ–° cid
            });
            // });
            // #endif
            uni.onPushMessage((res) => {
                console.log("收到推送消息:", res) //监听推送消息
            })
            // uni.onPushMessage((res) => {
            //     console.log("收到推送消息:", res) //监听推送消息
            // })
            uni.getSystemInfo({
                success: function(e) {
common/api.js
@@ -1,15 +1,18 @@
import {
    fly
} from '@/common/request/fly.js'
const base = "http://192.168.21.3:9999"
// const base = "https://lanpucloud.cn"
//配置请求基地址
fly.config.baseURL = "http://lanpucloud.cn/herb"
fly.config.baseURL = base + ""
const ip = uni.getStorageSync('lan_ip');
if (ip) {
    fly.config.baseURL = "http://" + ip + ":9999"
}
const mqttBaseUrl = "lanpucloud.cn";
const emqxBaseUrl = "http://" + mqttBaseUrl + ":1883/api/v5"
const emqxBaseUrl =  base + ":1883/api/v5";
// æµ‹è¯•
function test(params) {
common/constant.js
@@ -12,8 +12,8 @@
//解析时equ替换成真实设备唯一标识
//下行指令前缀
const SERVICE_DOWN = "service/down/res"
//请求查询设备状态
const SERVICE_RES_EQU_STATU = SERVICE_DOWN + "/equ/statu"
//查询设备状态响应  ï¼ˆ%s-请求客户端id)
const SERVICE_RES_EQU_STATU = SERVICE_DOWN + "/equ/statu/%s"
//接收指令响应
const SERVICE_RES_EQU_CMD = SERVICE_DOWN + "/equ/cmd";
@@ -34,6 +34,11 @@
const SERVICE_ONECE_TENANT_REAL_FAULT = "service/onece" + "/real/fault/%s"
// æœåŠ¡ç«¯é€šçŸ¥æ›´æ–°å¹²ç‡¥æœºè¿žæŽ¥çŠ¶æ€
const SERVICE_BROADCAST_TENANT_UPDATE_EQU_STATU = SERVICE_BROADCAST + "/update/equ/statu/%s"
// æœåŠ¡ç«¯å‘ç§»åŠ¨ç«¯æŽ¨é€å®žæ—¶æ•°æ®
const SERVICE_BROADCAST_TENANT_REAL_DATA = SERVICE_BROADCAST + "/real/data/%s"
@@ -56,6 +61,8 @@
    SERVICE_BROADCAST_TENANT_REAL_FAULT,
    SERVICE_ONECE_TENANT_REAL_FAULT,
    SERVICE_BROADCAST_TENANT_UPDATE_EQU_STATU,
    SERVICE_BROADCAST_TENANT_REAL_DATA,
    
    MQTT_TOPIC_MESSAGE,
dryuniapp.keystore
Binary files differ
manifest.json
@@ -18,9 +18,7 @@
            "delay" : 0
        },
        /* æ¨¡å—配置 */
        "modules" : {
            "Push" : {}
        },
        "modules" : {},
        /* åº”用发布信息 */
        "distribute" : {
            /* android打包配置 */
@@ -55,11 +53,7 @@
                    "unipush" : {
                        "icons" : {
                            "small" : {
                                "ldpi" : "static/logo.png",
                                "mdpi" : "static/logo.png",
                                "hdpi" : "static/logo.png",
                                "xhdpi" : "static/logo.png",
                                "xxhdpi" : "static/logo.png"
                                "hdpi" : "static/logo.png"
                            }
                        }
                    }
@@ -120,12 +114,14 @@
            "minified" : true
        },
        "usingComponents" : true,
        "lazyCodeLoading" : "requiredComponents", // å¯ç”¨æŒ‰éœ€æ³¨å…¥
        "unipush" : {
            "enable" : false
        },
        "optimization" : {
            "subPackages" : true
        }
        },
        "runmode" : "liberate"
    },
    "mp-alipay" : {
        "usingComponents" : true
mqtt/MqttView.vue
@@ -41,10 +41,13 @@
                }
                let opts = {
                    // #ifdef H5
                    url: 'ws://' + this.$api.mqttBaseUrl + ':8083/mqtt',
                    url: 'wss://' + this.$api.mqttBaseUrl + ':8084/mqtt',
                    // #endif
                    // #ifdef MP-WEIXIN
                    url: 'wxs://' + this.$api.mqttBaseUrl + ':8084/mqtt',// å¾®ä¿¡å°ç¨‹åºå¼ºåˆ¶ WSS
                    // #endif
                    // #ifdef APP-PLUS
                    url: 'wx://' + this.$api.mqttBaseUrl + ':8083/mqtt',
                    url: 'wxs://' + this.$api.mqttBaseUrl + ':8084/mqtt',  // Android/iOS ç”¨æ™®é€š WebSocket
                    // #endif
                    clientId: deviceid,
                    username: account.username,
@@ -77,6 +80,29 @@
                    console.error(res)
                })
                 
                //订阅干燥设备连接断开状态更新-租户内所有设备
                this.$mqttTool.subscribe({
                    topic: this.$constant.SERVICE_BROADCAST_TENANT_UPDATE_EQU_STATU.replace('%s', this.tenantId),
                    qos: 0
                }).then(res => {
                    console.error(res)
                })
                //订阅查询干燥设备连接状态-单个设备
                this.$mqttTool.subscribe({
                    topic: this.$constant.SERVICE_RES_EQU_STATU.replace('%s', deviceid),
                    qos: 0
                }).then(res => {
                    console.error(res)
                })
                //订阅干燥设备实时数据
                this.$mqttTool.subscribe({
                    topic: this.$constant.SERVICE_BROADCAST_TENANT_REAL_DATA.replace('%s', this.tenantId),
                    qos: 0
                }).then(res => {
                    console.error(res)
                })
                //订阅发送指令返回结果
                // this.$mqttTool.subscribe({
                //     topic: this.$constant.SERVICE_RES_EQU_CMD,
package-lock.json
@@ -59,14 +59,12 @@
        "node_modules/async-limiter": {
            "version": "1.0.1",
            "resolved": "https://registry.npmmirror.com/async-limiter/-/async-limiter-1.0.1.tgz",
            "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
            "license": "MIT"
            "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
        },
        "node_modules/balanced-match": {
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
            "license": "MIT"
            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
        },
        "node_modules/base64-js": {
            "version": "1.5.1",
@@ -85,39 +83,22 @@
                    "type": "consulting",
                    "url": "https://feross.org/support"
                }
            ],
            "license": "MIT"
            ]
        },
        "node_modules/bl": {
            "version": "4.1.0",
            "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
            "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
            "license": "MIT",
            "dependencies": {
                "buffer": "^5.5.0",
                "inherits": "^2.0.4",
                "readable-stream": "^3.4.0"
            }
        },
        "node_modules/bl/node_modules/readable-stream": {
            "version": "3.6.2",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
            "license": "MIT",
            "dependencies": {
                "inherits": "^2.0.3",
                "string_decoder": "^1.1.1",
                "util-deprecate": "^1.0.1"
            },
            "engines": {
                "node": ">= 6"
            }
        },
        "node_modules/brace-expansion": {
            "version": "1.1.11",
            "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
            "license": "MIT",
            "version": "1.1.12",
            "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz",
            "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
            "dependencies": {
                "balanced-match": "^1.0.0",
                "concat-map": "0.0.1"
@@ -141,7 +122,6 @@
                    "url": "https://feross.org/support"
                }
            ],
            "license": "MIT",
            "dependencies": {
                "base64-js": "^1.3.1",
                "ieee754": "^1.1.13"
@@ -150,17 +130,42 @@
        "node_modules/buffer-from": {
            "version": "1.1.2",
            "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
            "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
            "license": "MIT"
            "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
        },
        "node_modules/callback-stream": {
            "version": "1.1.0",
            "resolved": "https://registry.npmmirror.com/callback-stream/-/callback-stream-1.1.0.tgz",
            "integrity": "sha512-sAZ9kODla+mGACBZ1IpTCAisKoGnv6PykW7fPk1LrM+mMepE18Yz0515yoVcrZy7dQsTUp3uZLQ/9Sx1RnLoHw==",
            "license": "MIT",
            "dependencies": {
                "inherits": "^2.0.1",
                "readable-stream": "> 1.0.0 < 3.0.0"
            }
        },
        "node_modules/callback-stream/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/callback-stream/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/callback-stream/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/commander": {
@@ -176,7 +181,6 @@
            "version": "1.1.0",
            "resolved": "https://registry.npmmirror.com/commist/-/commist-1.1.0.tgz",
            "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==",
            "license": "MIT",
            "dependencies": {
                "leven": "^2.1.0",
                "minimist": "^1.1.0"
@@ -185,8 +189,7 @@
        "node_modules/concat-map": {
            "version": "0.0.1",
            "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
            "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
            "license": "MIT"
            "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
        },
        "node_modules/concat-stream": {
            "version": "1.6.2",
@@ -195,7 +198,6 @@
            "engines": [
                "node >= 0.8"
            ],
            "license": "MIT",
            "dependencies": {
                "buffer-from": "^1.0.0",
                "inherits": "^2.0.3",
@@ -203,17 +205,42 @@
                "typedarray": "^0.0.6"
            }
        },
        "node_modules/concat-stream/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/concat-stream/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/concat-stream/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/core-util-is": {
            "version": "1.0.3",
            "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
            "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
            "license": "MIT"
            "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
        },
        "node_modules/d": {
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/d/-/d-1.0.2.tgz",
            "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
            "license": "ISC",
            "dependencies": {
                "es5-ext": "^0.10.64",
                "type": "^2.7.2"
@@ -235,10 +262,9 @@
            "dev": true
        },
        "node_modules/debug": {
            "version": "4.3.7",
            "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.7.tgz",
            "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
            "license": "MIT",
            "version": "4.4.1",
            "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.1.tgz",
            "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
            "dependencies": {
                "ms": "^2.1.3"
            },
@@ -261,7 +287,6 @@
            "version": "3.7.1",
            "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-3.7.1.tgz",
            "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
            "license": "MIT",
            "dependencies": {
                "end-of-stream": "^1.0.0",
                "inherits": "^2.0.1",
@@ -269,11 +294,37 @@
                "stream-shift": "^1.0.0"
            }
        },
        "node_modules/duplexify/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/duplexify/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/duplexify/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/end-of-stream": {
            "version": "1.4.4",
            "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
            "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
            "license": "MIT",
            "version": "1.4.5",
            "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.5.tgz",
            "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
            "dependencies": {
                "once": "^1.4.0"
            }
@@ -283,7 +334,6 @@
            "resolved": "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.64.tgz",
            "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
            "hasInstallScript": true,
            "license": "ISC",
            "dependencies": {
                "es6-iterator": "^2.0.3",
                "es6-symbol": "^3.1.3",
@@ -298,7 +348,6 @@
            "version": "2.0.3",
            "resolved": "https://registry.npmmirror.com/es6-iterator/-/es6-iterator-2.0.3.tgz",
            "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
            "license": "MIT",
            "dependencies": {
                "d": "1",
                "es5-ext": "^0.10.35",
@@ -309,7 +358,6 @@
            "version": "0.1.5",
            "resolved": "https://registry.npmmirror.com/es6-map/-/es6-map-0.1.5.tgz",
            "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
            "license": "MIT",
            "dependencies": {
                "d": "1",
                "es5-ext": "~0.10.14",
@@ -323,7 +371,6 @@
            "version": "0.1.6",
            "resolved": "https://registry.npmmirror.com/es6-set/-/es6-set-0.1.6.tgz",
            "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
            "license": "ISC",
            "dependencies": {
                "d": "^1.0.1",
                "es5-ext": "^0.10.62",
@@ -340,7 +387,6 @@
            "version": "3.1.4",
            "resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.4.tgz",
            "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
            "license": "ISC",
            "dependencies": {
                "d": "^1.0.2",
                "ext": "^1.7.0"
@@ -365,7 +411,6 @@
            "version": "2.0.1",
            "resolved": "https://registry.npmmirror.com/esniff/-/esniff-2.0.1.tgz",
            "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
            "license": "ISC",
            "dependencies": {
                "d": "^1.0.1",
                "es5-ext": "^0.10.62",
@@ -380,7 +425,6 @@
            "version": "0.3.5",
            "resolved": "https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz",
            "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
            "license": "MIT",
            "dependencies": {
                "d": "1",
                "es5-ext": "~0.10.14"
@@ -390,7 +434,6 @@
            "version": "1.7.0",
            "resolved": "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz",
            "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
            "license": "ISC",
            "dependencies": {
                "type": "^2.7.2"
            }
@@ -398,21 +441,18 @@
        "node_modules/extend": {
            "version": "3.0.2",
            "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
            "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
            "license": "MIT"
            "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
        },
        "node_modules/fs.realpath": {
            "version": "1.0.0",
            "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
            "license": "ISC"
            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
        },
        "node_modules/glob": {
            "version": "7.2.3",
            "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
            "deprecated": "Glob versions prior to v9 are no longer supported",
            "license": "ISC",
            "dependencies": {
                "fs.realpath": "^1.0.0",
                "inflight": "^1.0.4",
@@ -432,7 +472,6 @@
            "version": "3.1.0",
            "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-3.1.0.tgz",
            "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
            "license": "ISC",
            "dependencies": {
                "is-glob": "^3.1.0",
                "path-dirname": "^1.0.0"
@@ -442,7 +481,6 @@
            "version": "6.1.0",
            "resolved": "https://registry.npmmirror.com/glob-stream/-/glob-stream-6.1.0.tgz",
            "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==",
            "license": "MIT",
            "dependencies": {
                "extend": "^3.0.0",
                "glob": "^7.1.1",
@@ -457,6 +495,33 @@
            },
            "engines": {
                "node": ">= 0.10"
            }
        },
        "node_modules/glob-stream/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/glob-stream/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/glob-stream/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/gzip-size": {
@@ -478,7 +543,6 @@
            "version": "1.1.0",
            "resolved": "https://registry.npmmirror.com/help-me/-/help-me-1.1.0.tgz",
            "integrity": "sha512-P/IZ8yOMne3SCTHbVY429NZ67B/2bVQlcYGZh2iPPbdLrEQ/qY5aGChn0YTDmt7Sb4IKRI51fypItav+lNl76w==",
            "license": "MIT",
            "dependencies": {
                "callback-stream": "^1.0.2",
                "glob-stream": "^6.1.0",
@@ -509,15 +573,13 @@
                    "type": "consulting",
                    "url": "https://feross.org/support"
                }
            ],
            "license": "BSD-3-Clause"
            ]
        },
        "node_modules/inflight": {
            "version": "1.0.6",
            "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
            "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
            "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
            "license": "ISC",
            "dependencies": {
                "once": "^1.3.0",
                "wrappy": "1"
@@ -526,14 +588,12 @@
        "node_modules/inherits": {
            "version": "2.0.4",
            "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
            "license": "ISC"
            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
        },
        "node_modules/is-absolute": {
            "version": "1.0.0",
            "resolved": "https://registry.npmmirror.com/is-absolute/-/is-absolute-1.0.0.tgz",
            "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
            "license": "MIT",
            "dependencies": {
                "is-relative": "^1.0.0",
                "is-windows": "^1.0.1"
@@ -546,7 +606,6 @@
            "version": "2.1.1",
            "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
            "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
            "license": "MIT",
            "engines": {
                "node": ">=0.10.0"
            }
@@ -555,7 +614,6 @@
            "version": "3.1.0",
            "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-3.1.0.tgz",
            "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
            "license": "MIT",
            "dependencies": {
                "is-extglob": "^2.1.0"
            },
@@ -567,7 +625,6 @@
            "version": "1.0.0",
            "resolved": "https://registry.npmmirror.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
            "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==",
            "license": "MIT",
            "engines": {
                "node": ">=0.10.0"
            }
@@ -576,7 +633,6 @@
            "version": "1.0.0",
            "resolved": "https://registry.npmmirror.com/is-relative/-/is-relative-1.0.0.tgz",
            "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
            "license": "MIT",
            "dependencies": {
                "is-unc-path": "^1.0.0"
            },
@@ -588,7 +644,6 @@
            "version": "1.0.0",
            "resolved": "https://registry.npmmirror.com/is-unc-path/-/is-unc-path-1.0.0.tgz",
            "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
            "license": "MIT",
            "dependencies": {
                "unc-path-regex": "^0.1.2"
            },
@@ -600,7 +655,6 @@
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
            "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
            "license": "MIT",
            "engines": {
                "node": ">=0.10.0"
            }
@@ -608,20 +662,17 @@
        "node_modules/isarray": {
            "version": "1.0.0",
            "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
            "license": "MIT"
            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
        },
        "node_modules/json-stable-stringify-without-jsonify": {
            "version": "1.0.1",
            "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
            "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
            "license": "MIT"
            "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
        },
        "node_modules/leven": {
            "version": "2.1.0",
            "resolved": "https://registry.npmmirror.com/leven/-/leven-2.1.0.tgz",
            "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
            "license": "MIT",
            "engines": {
                "node": ">=0.10.0"
            }
@@ -635,7 +686,6 @@
            "version": "3.1.2",
            "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
            "license": "ISC",
            "dependencies": {
                "brace-expansion": "^1.1.7"
            },
@@ -647,7 +697,6 @@
            "version": "1.2.8",
            "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
            "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
            "license": "MIT",
            "funding": {
                "url": "https://github.com/sponsors/ljharb"
            }
@@ -656,7 +705,6 @@
            "version": "3.0.0",
            "resolved": "https://registry.npmmirror.com/mqtt/-/mqtt-3.0.0.tgz",
            "integrity": "sha512-0nKV6MAc1ibKZwaZQUTb3iIdT4NVpj541BsYrqrGBcQdQ7Jd0MnZD1/6/nj1UFdGTboK9ZEUXvkCu2nPCugHFA==",
            "license": "MIT",
            "dependencies": {
                "base64-js": "^1.3.0",
                "commist": "^1.0.0",
@@ -687,11 +735,37 @@
            "version": "6.10.0",
            "resolved": "https://registry.npmmirror.com/mqtt-packet/-/mqtt-packet-6.10.0.tgz",
            "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==",
            "license": "MIT",
            "dependencies": {
                "bl": "^4.0.2",
                "debug": "^4.1.1",
                "process-nextick-args": "^2.0.1"
            }
        },
        "node_modules/mqtt/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/mqtt/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/mqtt/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/mrmime": {
@@ -706,20 +780,17 @@
        "node_modules/ms": {
            "version": "2.1.3",
            "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
            "license": "MIT"
            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
        },
        "node_modules/next-tick": {
            "version": "1.1.0",
            "resolved": "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz",
            "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
            "license": "ISC"
            "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
        },
        "node_modules/once": {
            "version": "1.4.0",
            "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
            "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
            "license": "ISC",
            "dependencies": {
                "wrappy": "1"
            }
@@ -737,22 +808,46 @@
            "version": "1.0.1",
            "resolved": "https://registry.npmmirror.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
            "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==",
            "license": "MIT",
            "dependencies": {
                "readable-stream": "^2.0.1"
            }
        },
        "node_modules/ordered-read-streams/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/ordered-read-streams/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/ordered-read-streams/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/path-dirname": {
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/path-dirname/-/path-dirname-1.0.2.tgz",
            "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==",
            "license": "MIT"
            "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q=="
        },
        "node_modules/path-is-absolute": {
            "version": "1.0.1",
            "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
            "license": "MIT",
            "engines": {
                "node": ">=0.10.0"
            }
@@ -766,14 +861,12 @@
        "node_modules/process-nextick-args": {
            "version": "2.0.1",
            "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
            "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
            "license": "MIT"
            "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
        },
        "node_modules/pump": {
            "version": "3.0.2",
            "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.2.tgz",
            "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
            "license": "MIT",
            "version": "3.0.3",
            "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.3.tgz",
            "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
            "dependencies": {
                "end-of-stream": "^1.1.0",
                "once": "^1.3.1"
@@ -783,7 +876,6 @@
            "version": "1.5.1",
            "resolved": "https://registry.npmmirror.com/pumpify/-/pumpify-1.5.1.tgz",
            "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
            "license": "MIT",
            "dependencies": {
                "duplexify": "^3.6.0",
                "inherits": "^2.0.3",
@@ -794,44 +886,52 @@
            "version": "2.0.1",
            "resolved": "https://registry.npmmirror.com/pump/-/pump-2.0.1.tgz",
            "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
            "license": "MIT",
            "dependencies": {
                "end-of-stream": "^1.1.0",
                "once": "^1.3.1"
            }
        },
        "node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "license": "MIT",
            "version": "3.6.2",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
                "inherits": "^2.0.3",
                "string_decoder": "^1.1.1",
                "util-deprecate": "^1.0.1"
            },
            "engines": {
                "node": ">= 6"
            }
        },
        "node_modules/reinterval": {
            "version": "1.1.0",
            "resolved": "https://registry.npmmirror.com/reinterval/-/reinterval-1.1.0.tgz",
            "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
            "license": "MIT"
            "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ=="
        },
        "node_modules/remove-trailing-separator": {
            "version": "1.1.0",
            "resolved": "https://registry.npmmirror.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
            "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
            "license": "ISC"
            "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="
        },
        "node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
            "license": "MIT"
            "version": "5.2.1",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
            "funding": [
                {
                    "type": "github",
                    "url": "https://github.com/sponsors/feross"
                },
                {
                    "type": "patreon",
                    "url": "https://www.patreon.com/feross"
                },
                {
                    "type": "consulting",
                    "url": "https://feross.org/support"
                }
            ]
        },
        "node_modules/sirv": {
            "version": "2.0.4",
@@ -851,45 +951,27 @@
            "version": "3.2.2",
            "resolved": "https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz",
            "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
            "license": "ISC",
            "dependencies": {
                "readable-stream": "^3.0.0"
            }
        },
        "node_modules/split2/node_modules/readable-stream": {
            "version": "3.6.2",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
            "license": "MIT",
            "dependencies": {
                "inherits": "^2.0.3",
                "string_decoder": "^1.1.1",
                "util-deprecate": "^1.0.1"
            },
            "engines": {
                "node": ">= 6"
            }
        },
        "node_modules/stream-shift": {
            "version": "1.0.3",
            "resolved": "https://registry.npmmirror.com/stream-shift/-/stream-shift-1.0.3.tgz",
            "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
            "license": "MIT"
            "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ=="
        },
        "node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "license": "MIT",
            "version": "1.3.0",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
            "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
                "safe-buffer": "~5.2.0"
            }
        },
        "node_modules/through2": {
            "version": "2.0.5",
            "resolved": "https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz",
            "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
            "license": "MIT",
            "dependencies": {
                "readable-stream": "~2.3.6",
                "xtend": "~4.0.1"
@@ -899,17 +981,42 @@
            "version": "3.0.0",
            "resolved": "https://registry.npmmirror.com/through2-filter/-/through2-filter-3.0.0.tgz",
            "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
            "license": "MIT",
            "dependencies": {
                "through2": "~2.0.0",
                "xtend": "~4.0.0"
            }
        },
        "node_modules/through2/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/through2/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/through2/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/to-absolute-glob": {
            "version": "2.0.2",
            "resolved": "https://registry.npmmirror.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
            "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==",
            "license": "MIT",
            "dependencies": {
                "is-absolute": "^1.0.0",
                "is-negated-glob": "^1.0.0"
@@ -930,26 +1037,22 @@
        "node_modules/type": {
            "version": "2.7.3",
            "resolved": "https://registry.npmmirror.com/type/-/type-2.7.3.tgz",
            "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
            "license": "ISC"
            "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
        },
        "node_modules/typedarray": {
            "version": "0.0.6",
            "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz",
            "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
            "license": "MIT"
            "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
        },
        "node_modules/ultron": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/ultron/-/ultron-1.1.1.tgz",
            "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
            "license": "MIT"
            "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
        },
        "node_modules/unc-path-regex": {
            "version": "0.1.2",
            "resolved": "https://registry.npmmirror.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
            "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
            "license": "MIT",
            "engines": {
                "node": ">=0.10.0"
            }
@@ -958,7 +1061,6 @@
            "version": "2.3.1",
            "resolved": "https://registry.npmmirror.com/unique-stream/-/unique-stream-2.3.1.tgz",
            "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
            "license": "MIT",
            "dependencies": {
                "json-stable-stringify-without-jsonify": "^1.0.1",
                "through2-filter": "^3.0.0"
@@ -967,8 +1069,7 @@
        "node_modules/util-deprecate": {
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
            "license": "MIT"
            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
        },
        "node_modules/webpack-bundle-analyzer": {
            "version": "4.10.2",
@@ -996,7 +1097,62 @@
                "node": ">= 10.13.0"
            }
        },
        "node_modules/webpack-bundle-analyzer/node_modules/ws": {
        "node_modules/websocket-stream": {
            "version": "5.5.2",
            "resolved": "https://registry.npmmirror.com/websocket-stream/-/websocket-stream-5.5.2.tgz",
            "integrity": "sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ==",
            "dependencies": {
                "duplexify": "^3.5.1",
                "inherits": "^2.0.1",
                "readable-stream": "^2.3.3",
                "safe-buffer": "^5.1.2",
                "ws": "^3.2.0",
                "xtend": "^4.0.0"
            }
        },
        "node_modules/websocket-stream/node_modules/readable-stream": {
            "version": "2.3.8",
            "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
            "dependencies": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.3",
                "isarray": "~1.0.0",
                "process-nextick-args": "~2.0.0",
                "safe-buffer": "~5.1.1",
                "string_decoder": "~1.1.1",
                "util-deprecate": "~1.0.1"
            }
        },
        "node_modules/websocket-stream/node_modules/safe-buffer": {
            "version": "5.1.2",
            "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "node_modules/websocket-stream/node_modules/string_decoder": {
            "version": "1.1.1",
            "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            "dependencies": {
                "safe-buffer": "~5.1.0"
            }
        },
        "node_modules/websocket-stream/node_modules/ws": {
            "version": "3.3.3",
            "resolved": "https://registry.npmmirror.com/ws/-/ws-3.3.3.tgz",
            "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
            "dependencies": {
                "async-limiter": "~1.0.0",
                "safe-buffer": "~5.1.0",
                "ultron": "~1.1.0"
            }
        },
        "node_modules/wrappy": {
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
        },
        "node_modules/ws": {
            "version": "7.5.10",
            "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz",
            "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
@@ -1017,42 +1173,10 @@
                }
            }
        },
        "node_modules/websocket-stream": {
            "version": "5.5.2",
            "resolved": "https://registry.npmmirror.com/websocket-stream/-/websocket-stream-5.5.2.tgz",
            "integrity": "sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ==",
            "license": "BSD-2-Clause",
            "dependencies": {
                "duplexify": "^3.5.1",
                "inherits": "^2.0.1",
                "readable-stream": "^2.3.3",
                "safe-buffer": "^5.1.2",
                "ws": "^3.2.0",
                "xtend": "^4.0.0"
            }
        },
        "node_modules/wrappy": {
            "version": "1.0.2",
            "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
            "license": "ISC"
        },
        "node_modules/ws": {
            "version": "3.3.3",
            "resolved": "https://registry.npmmirror.com/ws/-/ws-3.3.3.tgz",
            "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
            "license": "MIT",
            "dependencies": {
                "async-limiter": "~1.0.0",
                "safe-buffer": "~5.1.0",
                "ultron": "~1.1.0"
            }
        },
        "node_modules/xtend": {
            "version": "4.0.2",
            "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz",
            "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
            "license": "MIT",
            "engines": {
                "node": ">=0.4"
            }
package.json
packageA/pages/analy/analyList.vue
packageA/pages/category/formulaDetail.vue
packageA/pages/charts/charts.vue
packageA/pages/device/control.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,969 @@
<template>
    <view class="container">
        <cu-custom bgColor="bg-gradual-blue" :isBack="true">
            <block slot="content">{{option.name}}</block>
        </cu-custom>
        <view class="uni-padding-wrap">
            <!-- <view class="page-section swiper">
                <view class="page-section-spacing">
                     <swiper class="swiper" style="height: 450rpx;" circular="true" indicator-dots="true" autoplay="true"
                        interval="3500" duration="600">
                        <swiper-item class="swiper-list" v-for="(item, index) in bannerList" :key="index">
                            <view class="swiper-item uni-bg-red">
                                <image class="swiper-img" :src="item.imageUrl" mode="aspectFit"></image>
                            </view>
                        </swiper-item>
                    </swiper>
                </view>
            </view> -->
            <view class="fault-box">
                <image style="width: 100%;border-radius: 20rpx; " src="../../../packageA/static/image/ganzaoji-x.png"
                    mode="aspectFit">
                </image>
                <view class="fault-inner">
                    <view class="fault-info" v-for="(item,index) in realFaults" :style="{
                      position: 'absolute',
                      top: item.position.top + 'rpx',
                      left: item.position.left + 'rpx',
                      fontSize: '24rpx'
                    }">
                        <view :class="['fault-animal', item.type === 1 ? 'fault-marker' : 'warn-marker']"></view>
                        <view :class="['fault-tag', item.type === 1 ? 'fault-text' : 'warn-text']">{{item.name}}</view>
                    </view>
                </view>
            </view>
        </view>
        <!-- å¯é€šè¿‡è®¾ç½®bar-animate-mode="worm"开启毛毛虫模式-->
        <z-tabs ref="tabs" :current="swiperCurrent" :list="swiperList" @change="tabsChange"></z-tabs>
        <swiper class="custom-swiper" :current="swiperCurrent" @transition="swiperTransition"
            @animationfinish="swiperAnimationfinish">
            <swiper-item :key="0">
                <view class="swiper-item-view">
                    <uni-section title="设备信息" type="line">
                        <text class="text-bold text-black"></text>
                        <view class="h-table">
                            <view class="h-tr h-tr-2 h-thead">
                                <view class="h-td">设备状态</view>
                                <view class="h-td">运行状态</view>
                                <view class="h-td">暂停标志</view>
                                <view class="h-td">温度过低</view>
                            </view>
                            <view class="h-tr h-tr-2">
                                <view class="h-td">
                                    <u-tag v-if="model.connected" size="mini" text="在线" type="success" plain
                                        plainFill></u-tag>
                                    <u-tag v-else size="mini" text="离线" type="error" plain plainFill></u-tag>
                                </view>
                                <view class="h-td">
                                    <template>
                                        <u-tag size="mini" :text="$lget(model,'level')" plain plainFill></u-tag>
                                    </template>
                                </view>
                                <view class="h-td">{{ model.stop ? '是':'否'}}</view>
                                <view class="h-td">{{ model.lowalarm ? '低':'正常'}}</view>
                            </view>
                        </view>
                        <view class="h-table">
                            <view class="h-tr h-tr-2 h-thead">
                                <view class="h-td">热风</view>
                                <view class="h-td">温度</view>
                                <view class="h-td">电能</view>
                                <view class="h-td">蒸汽</view>
                            </view>
                            <view class="h-tr h-tr-2">
                                <view class="h-td">{{model.wind ? '开' : '关'}}</view>
                                <view class="h-td">{{$lget(model,'temp2')}}%</view>
                                <view class="h-td">{{$lget(model,'watt')}}kW·h</view>
                                <view class="h-td">{{$lget(model,'steam')}}m³</view>
                            </view>
                        </view>
                    </uni-section>
                    <uni-section title="药材信息" type="line" class="margin-top-sm">
                        <text class="text-bold text-black"></text>
                        <view class="h-table">
                            <view class="h-tr h-tr-2 h-thead">
                                <view class="h-td">物料</view>
                                <view class="h-td">投料量</view>
                                <view class="h-td">初始重量</view>
                                <view class="h-td">实时重量</view>
                            </view>
                            <view class="h-tr h-tr-2">
                                <view class="h-td">{{$lget(model,'name')}}</view>
                                <view class="h-td">{{$lget(model,'weight1')}}筐
                                </view>
                                <view class="h-td">{{$lget(model,'weight2') }}kg
                                </view>
                                <view class="h-td">{{$lget(model,'weight3')}}kg</view>
                            </view>
                        </view>
                        <view class="h-table">
                            <view class="h-tr h-tr-2 h-thead">
                                <view class="h-td"> </view>
                                <view class="h-td">初始含水率</view>
                                <view class="h-td">当前含水率</view>
                                <view class="h-td">目标含水率</view>
                            </view>
                            <view class="h-tr h-tr-2">
                                <view class="h-td"> </view>
                                <view class="h-td">{{$lget(model,'moisture1')}}%
                                </view>
                                <view class="h-td">{{$lget(model,'moisture2') }}%
                                </view>
                                <view class="h-td">{{$lget(model,'moisture3')}}%</view>
                            </view>
                        </view>
                    </uni-section>
                    <uni-section title="进度信息" type="line" class="margin-top-sm">
                        <text class="text-bold text-black"></text>
                        <view class="h-table">
                            <view class="h-tr h-tr-2 h-thead">
                                <view class="h-td">时间设定值</view>
                                <view class="h-td">时间计数</view>
                                <view class="h-td">总时间</view>
                            </view>
                            <view class="h-tr h-tr-2">
                                <view class="h-td">{{$lget(model,'time1')}}min</view>
                                <view class="h-td">{{$lget(model,'time2')}}</view>
                                <view class="h-td">{{$lget(model,'time3')}}min</view>
                            </view>
                        </view>
                        <view class="h-table">
                            <view class="h-tr h-tr-2 h-thead">
                                <view class="h-td">翻料次数</view>
                                <view class="h-td">阶段预测时间</view>
                                <view class="h-td">预测剩余总时间</view>
                            </view>
                            <view class="h-tr h-tr-2">
                                <view class="h-td">{{$lget(model,'turntime')}}</view>
                                <view class="h-td">{{$lget(model,'ai_time')}}min</view>
                                <view class="h-td">{{$lget(model,'ai_total_time')}}min</view>
                            </view>
                        </view>
                    </uni-section>
                </view>
            </swiper-item>
            <swiper-item :key="1">
                <uni-section title="指令" type="line">
                    <view class="flex justify-center padding-lg bg-white">
                        <view class="margin-right-sm">
                            <u-button :disabled="model.connected" text="开机" type="success"
                                @click="$u.throttle(showModal(1), 500)"></u-button>
                        </view>
                        <view class="margin-left-sm">
                            <u-button :disabled="!model.connected" text="关机" type="error"
                                @click="$u.throttle(showModal(2), 500)"></u-button>
                        </view>
                    </view>
                </uni-section>
                <uni-section title="控制台" type="line" class="margin-top-sm ">
                    <view class="padding-left-sm padding-right-sm padding-bottom-sm">
                        <view class="text-sm text-gray" :class="{'margin-top-sm':index>0}"
                            v-for="(log,index) in logList">{{log}}</view>
                        <!-- <view class="text-sm text-gray  margin-top-sm">12:00:10: å‘送<开机>指令</view> -->
                    </view>
                </uni-section>
            </swiper-item>
        </swiper>
        <u-modal :show="show" @confirm="confirm" :showCancelButton="true" @cancel="show=false" ref="uModal"
            :asyncClose="true">
            <slot>
                <view style="width: 100%;height:100%;">
                    <view style="color:red">
                        è¿œç¨‹æŽ§åˆ¶æ“ä½œå¯èƒ½å­˜åœ¨å®‰å…¨é£Žé™©ï¼Œè¯·è°¨æ…Žæ“ä½œ
                    </view>
                    <u--input style="width: 100%;" placeholder="请输入二级安全密码" border="surround" password
                        clearable></u--input>
                </view>
            </slot>
        </u-modal>
    </view>
</template>
<script>
    import get from 'lodash.get'
    import dayjs from 'dayjs'
    export default {
        data() {
            return {
                //上个页面传递过来的数据
                option: {},
                //操作指令log
                logList: [],
                //当前设备连接状态
                //开关机指令 1-开机 2-关机
                cmd: -1,
                show: false,
                swiperList: ["监测", "控制"],
                swiperCurrent: 0,
                notice: "2023-03-1812:00:001号机台低温报警",
                model: {
                    // è®¾å¤‡è¿žæŽ¥çŠ¶æ€
                    connected: false,
                    realData: {}
                },
                queryParam: {
                    machineid: "",
                    tenantid: null
                },
                bannerList: [{
                    imageUrl: '../../static/image/zcy_gzj1.png'
                }],
                timer: null,
                realFaults: [],
                allFaults: [{
                        id: 1,
                        name: '设备急停(总)',
                        type: 1,
                        position: {
                            top: 70,
                            left: 230
                        },
                        show: false
                    },
                    {
                        id: 2,
                        name: '左前急停',
                        type: 1,
                        position: {
                            top: 100,
                            left: 250
                        },
                        show: false
                    },
                    {
                        id: 3,
                        name: '出料急停',
                        type: 1,
                        position: {
                            top: 130,
                            left: 230
                        },
                        show: false
                    },
                    {
                        id: 4,
                        name: '面板急停',
                        type: 1,
                        position: {
                            top: 160,
                            left: 250
                        },
                        show: false
                    },
                    {
                        id: 5,
                        name: '风箱升超时',
                        type: 1,
                        position: {
                            top: 190,
                            left: 230
                        },
                        show: false
                    },
                    {
                        id: 6,
                        name: '风箱降超时',
                        type: 1,
                        position: {
                            top: 220,
                            left: 250
                        },
                        show: false
                    },
                    {
                        id: 7,
                        name: '风机过流',
                        type: 1,
                        position: {
                            top: 250,
                            left: 230
                        },
                        show: false
                    },
                    {
                        id: 8,
                        name: '滚筒升超时',
                        type: 1,
                        position: {
                            top: 280,
                            left: 250
                        },
                        show: false
                    },
                    {
                        id: 9,
                        name: '滚筒降超时',
                        type: 1,
                        position: {
                            top: 310,
                            left: 230
                        },
                        show: false
                    },
                    {
                        id: 10,
                        name: '滚筒电机过流',
                        type: 1,
                        position: {
                            top: 340,
                            left: 250
                        },
                        show: false
                    },
                    {
                        id: 11,
                        name: '温度失控',
                        type: 1,
                        position: {
                            top: 370,
                            left: 230
                        },
                        show: false
                    },
                    {
                        id: 12,
                        name: '左前门报警',
                        type: 2,
                        position: {
                            top: 100,
                            left: 0
                        },
                        show: false
                    },
                    {
                        id: 13,
                        name: '左后门报警',
                        type: 2,
                        position: {
                            top: 130,
                            left: 20
                        },
                        show: false
                    },
                    {
                        id: 14,
                        name: '右前门报警',
                        type: 2,
                        position: {
                            top: 160,
                            left: 0
                        },
                        show: false
                    },
                    {
                        id: 15,
                        name: '右后门报警',
                        type: 2,
                        position: {
                            top: 190,
                            left: 20
                        },
                        show: false
                    },
                    {
                        id: 16,
                        name: '滚筒不在高位',
                        type: 2,
                        position: {
                            top: 220,
                            left: 0
                        },
                        show: false
                    },
                    {
                        id: 17,
                        name: '风箱不在高位',
                        type: 2,
                        position: {
                            top: 250,
                            left: 20
                        },
                        show: false
                    },
                    {
                        id: 18,
                        name: '风箱不在低位',
                        type: 2,
                        position: {
                            top: 280,
                            left: 0
                        },
                        show: false
                    },
                    {
                        id: 19,
                        name: '加热位传感器报警',
                        type: 2,
                        position: {
                            top: 310,
                            left: 20
                        },
                        show: false
                    },
                    {
                        id: 20,
                        name: '左前风箱高位',
                        type: 2,
                        position: {
                            top: 340,
                            left: 0
                        },
                        show: false
                    },
                    {
                        id: 21,
                        name: '左前风箱低位',
                        type: 2,
                        position: {
                            top: 370,
                            left: 20
                        },
                        show: false
                    },
                    {
                        id: 22,
                        name: '左后风箱高位',
                        type: 2,
                        position: {
                            top: 100,
                            left: 430
                        },
                        show: false
                    },
                    {
                        id: 23,
                        name: '左后风箱低位',
                        type: 2,
                        position: {
                            top: 130,
                            left: 450
                        },
                        show: false
                    },
                    {
                        id: 24,
                        name: '右前风箱高位',
                        type: 2,
                        position: {
                            top: 160,
                            left: 430
                        },
                        show: false
                    },
                    {
                        id: 25,
                        name: '右前风箱低位',
                        type: 2,
                        position: {
                            top: 190,
                            left: 450
                        },
                        show: false
                    },
                    {
                        id: 26,
                        name: '右后风箱高位',
                        type: 2,
                        position: {
                            top: 220,
                            left: 430
                        },
                        show: false
                    },
                    {
                        id: 27,
                        name: '右后风箱低位',
                        type: 2,
                        position: {
                            top: 250,
                            left: 450
                        },
                        show: false
                    },
                    {
                        id: 28,
                        name: '左前滚筒低位',
                        type: 2,
                        position: {
                            top: 280,
                            left: 430
                        },
                        show: false
                    },
                    {
                        id: 29,
                        name: '左后滚筒低位',
                        type: 2,
                        position: {
                            top: 310,
                            left: 450
                        },
                        show: false
                    },
                    {
                        id: 30,
                        name: '右前滚筒低位',
                        type: 2,
                        position: {
                            top: 340,
                            left: 430
                        },
                        show: false
                    },
                    {
                        id: 31,
                        name: '右后滚筒低位',
                        type: 2,
                        position: {
                            top: 370,
                            left: 450
                        },
                        show: false
                    },
                ],
            }
        },
        onShow() {
            console.info("onShow")
        },
        onLoad(option) {
            this.initPageData(option);
        },
        onBackPress() {
        },
        onHide() {
        },
        onUnload() {
        },
        mounted() {
            this.queryEquStatu()
            this.mqttData()
            this.startTimer()
        },
        beforeDestroy() {
            this.stopTimer()
            uni.$off(this.$constant.MQTT_TOPIC_MESSAGE)
        },
        onReady() {
        },
        methods: {
            mqttData() {
                uni.$on(this.$constant.MQTT_TOPIC_MESSAGE, (data) => {
                    try {
                        // 1. æ•°æ®è§£æžå’ŒéªŒè¯
                        const {
                            data: wdata,
                            topic
                        } = this.parseAndValidateMqttData(data);
                        if (!wdata || !topic) return;
                        // 2. å‡†å¤‡ä¸»é¢˜å¸¸é‡
                        const topics = this.prepareMqttTopics();
                        // 3. æ›´æ–°åˆ·æ–°æ—¶é—´
                        this.refreshTime = dayjs().format('HH:mm:ss');
                        // 4. æ ¹æ®ä¸»é¢˜å¤„理数据
                        switch (topic) {
                            case topics.updateEquStatu:
                                this.handleEquStatusUpdate(wdata);
                                break;
                            case topics.realData:
                                if (!this.model.connected) {
                                    return false
                                }
                                this.mergeMqttRealData(wdata);
                                break;
                                //topic å®žæ—¶æŠ¥è­¦
                            case topics.realFaultTopic:
                            case topics.oneceFaultTopic:
                                if (!this.model.connected) {
                                    return false
                                }
                                if (wdata != null && Array.isArray(wdata) && wdata.length != 0) {
                                    const realFaultNames = wdata.filter(item => item.tenantId == this.tenantId &&
                                        item.equCode == this.option.code).map(item => item.faultName);
                                    const realFaults = this.allFaults.filter(item =>
                                        realFaultNames.some(name =>
                                            name.startsWith(item.name)
                                        ))
                                    this.realFaults = realFaults
                                }
                                break
                        }
                    } catch (error) {
                        console.error('MQTT数据处理错误:', error);
                    }
                });
            },
            // è®¾å¤‡æ•°æ®å’Œmtqq实时数据合并
            mergeMqttRealData(mqttData) {
                const {
                    tenantid,
                    machineid
                } = mqttData;
                if (!tenantid || !machineid) return;
                const key = `${tenantid}_${machineid}`;
                if (tenantid == this.option.tenantid && machineid == this.option.code) {
                    this.model = {
                        ...mqttData,
                        connected: this.model.connected
                    };
                }
                console.error(this.model)
            },
            handleEquStatusUpdate(wdata) {
                const isSuccess = wdata?.success ?? false;
                if (isSuccess) {
                    console.log("操作成功");
                } else {
                    console.log("操作失败或未返回 success å­—段");
                }
                this.model.connected = isSuccess;
            },
            startTimer() {
                this.timer = setInterval(() => {
                    this.queryEquStatu()
                }, 3000);
            },
            stopTimer() {
                clearInterval(this.timer);
            },
            /**
             * åˆå§‹åŒ–页面数据
             * @param {Object} option - é¡µé¢å‚æ•°
             */
            initPageData(option) {
                const {
                    loginTenantId,
                    username
                } = this.getUserInfo();
                // åˆå¹¶é¡µé¢å‚数和用户信息
                this.option = {
                    ...option,
                    tenantid: loginTenantId,
                    username
                };
                // åˆå§‹åŒ–查询参数
                this.queryParam = {
                    machineid: option.code,
                    tenantid: loginTenantId
                };
            },
            /**
             * èŽ·å–ç”¨æˆ·ä¿¡æ¯
             * @returns {Object} ç”¨æˆ·ä¿¡æ¯å¯¹è±¡
             */
            getUserInfo() {
                try {
                    const userinfo = uni.getStorageSync('userinfo');
                    return {
                        loginTenantId: userinfo?.loginTenantId,
                        username: userinfo?.username
                    };
                } catch (error) {
                    console.error('获取用户信息失败:', error);
                    return {
                        loginTenantId: null,
                        username: null
                    };
                }
            },
            // è¾…助方法:解析和验证MQTT数据
            parseAndValidateMqttData(data) {
                try {
                    const json = JSON.parse(data);
                    if (!json?.data || !json?.topic) return {
                        data: null,
                        topic: null
                    };
                    return {
                        data: json.data,
                        topic: json.topic
                    };
                } catch (e) {
                    return {
                        data: null,
                        topic: null
                    };
                }
            },
            // è¾…助方法:准备MQTT主题
            prepareMqttTopics() {
                return {
                    updateEquStatu: this.$constant.SERVICE_RES_EQU_STATU
                        .replace('%s', this.deviceId),
                    realData: this.$constant.SERVICE_BROADCAST_TENANT_REAL_DATA
                        .replace('%s', this.tenantId),
                    realFaultTopic: this.$constant.SERVICE_BROADCAST_TENANT_REAL_FAULT
                        .replace('%s', this.tenantId),
                    oneceFaultTopic: this.$constant.SERVICE_ONECE_TENANT_REAL_FAULT.replace('%s', this
                        .deviceId)
                };
            },
            //MQTT
            queryEquStatu() {
                //1.查询设备实时状态
                const message = {
                    clientId: this.option.clientId,
                    timestamp: new Date(),
                    req: this.deviceId
                }
                let opts = {
                    topic: this.$constant.MOBILE_QUERY_EQU_STATU,
                    message: JSON.stringify(message),
                }
                this.$mqttTool.publish(opts).then(res => {
                    console.error(res)
                })
            },
            sendEquCmd() {
                //添加log
                let log = this.getCurrentTime() + '发送' + (this.cmd == 1 ? ":《开机》" : ":《关机》") + '指令';
                this.logList.push(log)
                //1.发送开关机指令 1-开机  2-关机
                const message = {
                    clientId: this.option.clientId,
                    cmd: this.cmd,
                    timestamp: new Date(),
                    req: this.deviceId
                }
                let opts = {
                    topic: this.$constant.MOBILE_REQ_EQU_CMD,
                    message: JSON.stringify(message),
                }
                this.$mqttTool.publish(opts).then(res => {
                    console.error(res)
                })
            },
            showModal(cmd) {
                this.show = true;
                this.cmd = cmd;
            },
            confirm() {
                this.sendEquCmd()
            },
            //tabs通知swiper切换
            tabsChange(index) {
                this.swiperCurrent = index;
            },
            //swiper滑动中
            swiperTransition(e) {
                this.$refs.tabs.setDx(e.detail.dx);
            },
            //swiper滑动结束
            swiperAnimationfinish(e) {
                this.swiperCurrent = e.detail.current;
                this.$refs.tabs.unlockDx();
            },
            getCurrentTime() {
                // èŽ·å–å½“å‰æ—¶é—´
                let now = new Date();
                // æ ¼å¼åŒ–æ—¶é—´
                let year = now.getFullYear();
                let month = (now.getMonth() + 1).toString().padStart(2, '0');
                let day = now.getDate().toString().padStart(2, '0');
                let hours = now.getHours().toString().padStart(2, '0');
                let minutes = now.getMinutes().toString().padStart(2, '0');
                let seconds = now.getSeconds().toString().padStart(2, '0');
                // è¿”回结果
                return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
            },
            goBack() {
                uni.navigateBack({
                    delta: 1
                })
            }
        },
        computed: {
            deviceId() {
                return uni.getStorageSync(this.$constant.DEVICE_ID);
            },
            tenantId() {
                const userinfo = uni.getStorageSync('userinfo');
                const tenantid = userinfo.loginTenantId
                return tenantid + "";
            }
        }
    }
</script>
<style lang="scss" scoped>
    @import "components/table/helang-table";
    .swiper-box {
        flex: 1;
    }
    .swiper-item {
        height: 100%;
    }
    .custom-swiper {
        min-height: 1100rpx;
    }
    .swiper-item-view {}
    .fault-box {
        width: 100%;
        height: 460rpx;
        position: relative;
        .fault-inner {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            padding: 20rpx 0;
            background: transparent;
            overflow: hidden;
            .fault-info {
                position: absolute;
                display: flex;
                align-items: center;
                justify-content: center;
            }
            .fault-tag {
                display: flex;
                align-items: center;
                margin-left: 6rpx;
                height: 28rpx;
                padding: 0 10rpx;
                background: gray;
                border-radius: 5rpx;
                font-size: 22rpx;
                font-weight: bold;
                color: red;
                white-space: nowrap;
                /* ä¸æ¢è¡Œ */
                overflow: hidden;
                /* è¶…出部分隐藏 */
                text-overflow: ellipsis;
                /* è¶…出部分用省略号表示 */
            }
            .fault-marker {
                width: 20rpx;
                height: 20rpx;
                background: red;
                border-radius: 50%;
            }
            .warn-marker {
                width: 24rpx;
                height: 24rpx;
                background: orange;
                border-radius: 50%;
            }
            .fault-text {
                color: red;
            }
            .warn-text {
                color: orange;
            }
            .fault-animal {
                -webkit-animation: scaleout 2s infinite ease-in-out;
                animation: scaleout 2s infinite ease-in-out;
            }
            @-webkit-keyframes scaleout {
                0% {
                    -webkit-transform: scale(1);
                }
                100% {
                    -webkit-transform: scale(1.1);
                    opacity: 0;
                }
            }
            @keyframes scaleout {
                0% {
                    transform: scale(1);
                    -webkit-transform: scale(1);
                }
                100% {
                    transform: scale(1.1);
                    -webkit-transform: scale(1.1);
                    opacity: 0;
                }
            }
        }
    }
</style>
packageA/pages/index/index.vue
packageA/pages/login/switchMode.vue
packageA/pages/me/analy.vue
ÎļþÃû´Ó pages/me/analy.vue ÐÞ¸Ä
@@ -76,7 +76,7 @@
            this.$refs.form.validate().then(res => {
                uni.$u.toast('校验通过')
                uni.navigateTo({
                    url:"/pages/analy/analyList"
                    url:"/packageA/pages/analy/analyList"
                })
             
            }).catch(errors => {
packageA/pages/me/control.vue
packageA/pages/me/video.vue
packageA/static/.DS_Store
Binary files differ
packageA/static/image/ganzaoji-x.png
packageA/static/image/pic_gz.jpg

packageA/static/image/pic_gzj.jpg

packageA/static/image/zcy_equipment_run.gif

packageA/static/image/zcy_gzj1.png

pages.json
@@ -16,105 +16,12 @@
        },
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "uni-app"
            }
        },
        {
            "path": "pages/tabBar/main",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        }, {
            "path": "pages/tabBar/formula",
            "style": {
                "navigationStyle": "custom"
            }
        }, {
            "path": "pages/category/formulaDetail",
            "style": {
                "navigationStyle": "custom"
            }
        }, {
            "path": "pages/tabBar/monitor",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        }, {
            "path": "pages/tabBar/me",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        }, {
            "path": "pages/tabBar/general",
            "style": {
                "navigationStyle": "custom"
            }
        }
        , {
            "path": "pages/charts/charts",
            "style": {
                "navigationBarTitleText": "图表",
                "enablePullDownRefresh": false
            }
        }, {
            "path": "pages/me/analy",
            "style": {
                "navigationStyle": "custom"
            }
        }, {
            "path": "pages/analy/analyList",
            "style": {
                "navigationBarTitleText": "生产记录分析",
                "enablePullDownRefresh": false
            }
        }, {
            "path": "pages/tabBar/demo",
            "style": {
                "navigationBarTitleText": "测试",
                "enablePullDownRefresh": false
            }
        }, {
            "path": "pages/me/control",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        // {
        //     "path": "pages/me/video",
        //     "style": {
        //         "navigationStyle": "custom",
        //         "app-plus": {
        //             "titleNView": false
        //         }
        //     }
        // },
        {
            "path": "pages/tabBar/device",
            "style": {
@@ -134,6 +41,99 @@
            }
        },
        {
            "path": "pages/tabBar/formula",
            "style": {
                "navigationStyle": "custom"
            }
        },
         {
             "path": "pages/tabBar/me",
             "style": {
                 "navigationStyle": "custom",
                 "app-plus": {
                     "titleNView": false
                 }
             }
         }
        /* {
             "path": "pages/tabBar/main",
             "style": {
                 "navigationStyle": "custom",
                 "app-plus": {
                     "titleNView": false
                 }
             }
         },
        {
            "path": "pages/tabBar/monitor",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        }, */
    ],
    "subPackages": [
        {
              "root": "packageA",
              "pages": [
               {
                   "path": "pages/category/formulaDetail",
                   "style": {
                       "navigationStyle": "custom"
                   }
               }, {
                   "path": "pages/charts/charts",
                   "style": {
                       "navigationBarTitleText": "图表",
                       "enablePullDownRefresh": false
                   }
               }, {
                   "path": "pages/me/analy",
                   "style": {
                       "navigationStyle": "custom"
                   }
               }, {
                   "path": "pages/analy/analyList",
                   "style": {
                       "navigationBarTitleText": "生产记录分析",
                       "enablePullDownRefresh": false
                   }
               },
               {
                   "path": "pages/me/control",
                   "style": {
                       "navigationStyle": "custom",
                       "app-plus": {
                           "titleNView": false
                       }
                   }
               },
               // {
               //     "path": "pages/me/video",
               //     "style": {
               //         "navigationStyle": "custom",
               //         "app-plus": {
               //             "titleNView": false
               //         }
               //     }
               // },
               {
            "path": "pages/device/control",
            "style": {
                "navigationStyle": "custom",
@@ -151,8 +151,15 @@
                }
            }
        }
              ]
            }
    ],
    "preloadRule": {
        "packageA/pages/device/control": {
          "network": "all",
          "packages": ["packageA"]
        }
    },
    "globalStyle": {
        "navigationBarTextStyle": "white",
        "navigationBarTitleText": "兰宝智能",
@@ -179,7 +186,7 @@
            "pagePath": "pages/tabBar/warning",
            "iconPath": "static/tabBar/analy.png",
            "selectedIconPath": "static/tabBar/analy_cur.png",
            "text": "报警通知"
            "text": "报警统计"
        }, {
            "pagePath": "pages/tabBar/formula",
            "iconPath": "static/tabBar/order.png",
pages/device/control.vue
ÎļþÒÑɾ³ý
pages/login/login.vue
@@ -44,8 +44,8 @@
                show: false,
                pass: "",
                model: {
                    username: "tongjitang",
                    password: "123456"
                    username: "",
                    password: ""
                },
                rules: {
                    'username': {
@@ -95,13 +95,11 @@
            },
            switchMode() {
                uni.navigateTo({
                    url: "/pages/login/switchMode"
                    url: "/packageA/pages/login/switchMode"
                })
            },
            forget() {
                uni.navigateTo({
                    url: "/pages/tabBar/demo"
                })
            },
            submit() {
                const mode = uni.getStorageSync('mode');
pages/tabBar/components/equList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,224 @@
<template>
    <view class="app">
        <z-paging ref="paging" v-model="dataList" show-refresher-update-time @query="queryList" :hide-empty-view="true">
            <!-- éœ€è¦å›ºå®šåœ¨é¡¶éƒ¨ä¸æ»šåŠ¨çš„view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
            <template #top>
                <view class="card-box dynamic shadow">
                    <view class="title-box margin-bottom-sm">
                        <view style="width: 100vw;" class="left justify-between">
                            <view class="flex align-center">
                                <uni-text class="cuIcon-titles text-blue"></uni-text>
                                <view class="title">总览</view>
                            </view>
                            <view>
                                <text class="text-gray text-sm">{{curDate}}</text>
                            </view>
                        </view>
                    </view>
                    <view class="flex flex-direction padding-xs">
                        <view class="flex">
                            <view class="flex-sub flex flex-direction">
                                <text class="text-df">报警总数</text>
                                <text class="text-bold text-sl margin-top-xs text-red margin-top-sm">{{count}}
                                    <text class="text-gray text-sm margin-left-xs">次</text></text>
                            </view>
                            <view class="flex-twice flex flex-direction justify-between">
                                <view class="flex-sub flex">
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-gray text-xs">报警信息</text>
                                        <text class="text-black">故障次数:</text>
                                        <text class="margin-lr-xs text-red text-bold text-xl">{{faultCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-gray text-xs">机台信息</text>
                                        <text class="text-black">故障机台:</text>
                                        <text class="margin-lr-xs text-red">{{faultEqus}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                </view>
                                <view class="flex-sub flex">
                                    <view class="flex flex-direction flex-sub"  >
                                        <text class="text-white text-xs">报警信息</text>
                                        <text class="text-black">告警次数:</text>
                                        <text class="margin-lr-xs text-orange text-bold text-xl">{{alarmCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-white text-xs">机台信息</text>
                                        <text class="text-black">告警机台:</text>
                                        <text class="margin-lr-xs text-orange">{{alarmEqus}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
            </template>
            <view class="container">
                <view class="equ-box borderTop">
                    <div v-for="i in 9" class="equ-item">
                    </div>
                </view>
            </view>
        </z-paging>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                dataList: [],
                loading: false,
                //实时报警数据更新时间(一般10s)
                refreshTime: '',
                //报警总数
                count: 0,
                //告警总数
                alarmCount: 0,
                //故障总数
                faultCount: 0,
                //故障机台
                faultEqus: "",
                //告警机台
                alarmEqus: "",
                curDate: dayjs().format('YYYY-MM-DD'),
            }
        },
        methods:{
            queryList(pageNo, pageSize) {
                this.loading = true;
                // ç»„件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
                // è¿™é‡Œçš„pageNo和pageSize会自动计算好,直接传给服务器即可
                // æ¨¡æ‹Ÿè¯·æ±‚服务器获取分页数据,请替换成自己的网络请求
                const params = {
                    pageNo: pageNo,
                    pageSize: pageSize,
                }
                //
                this.$api.querySampleList(params).then((res) => {
                    //     // å°†è¯·æ±‚的结果数组传递给z-paging
                    //实时故障
                    if (this.tabCurrent === 0) {
                        this.queryRealFaultData()
                    }else if(this.tabCurrent === 1){
                        this.$refs.hisWarining.init();
                    }
                    this.$refs.paging.complete(res.result.records);
                    this.loading = false
                }).catch(res => {
                    // å¦‚果请求失败写this.$refs.paging.complete(false);
                    // æ³¨æ„ï¼Œæ¯æ¬¡éƒ½éœ€è¦åœ¨catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
                    // åœ¨åº•层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
                    this.$refs.paging.complete(false);
                    this.loading = false
                })
            },
        }
    }
</script>
<style lang="scss" scoped>
    .container {
        margin: 0 20rpx;
        padding: 20rpx;
        box-sizing: border-box;
        background-color: white;
        font-family: Helvetica Neue, Helvetica, sans-serif;
    }
    .card-box {
        margin: 20rpx;
        padding: 20rpx;
        box-sizing: border-box;
        background-color: white;
        border-radius: 20rpx;
        font-family: Helvetica Neue, Helvetica, sans-serif;
    }
    .title-box {
        display: flex;
        flex-direction: row;
        align-items: center;
        .left {
            display: flex;
            align-items: center;
            .title {
                margin: 0 10rpx;
                font-weight: bold;
            }
        }
        .right {
            display: flex;
            align-items: center;
            .title {
                margin: 0 10rpx;
                font-weight: bold;
            }
        }
    }
    .equ-box {
        display: flex;
        flex-wrap: wrap;
        gap: 20rpx 0px;
        justify-content: space-between;
    }
    .equ-item {
        width: calc((100% - 20rpx)/2);
        height: 200rpx;
        border-radius: 20rpx;
        background-color: #ecf5ff;
    }
    .borderTop {
        border-top: 2rpx solid #f2f2f2;
        padding-top: 20rpx;
    }
</style>
pages/tabBar/components/realWarning.vue
@@ -16,7 +16,7 @@
            </view>
            <view class="fault-box">
                <image style="width: 100%;border-radius: 20rpx; " src="../../../static/image/ganzaoji-x.png"
                <image style="width: 100%;border-radius: 20rpx; " src="../../../packageA/static/image/ganzaoji-x.png"
                    mode="aspectFit">
                </image>
@@ -56,7 +56,7 @@
                <view style="height: 180rpx;display: flex;align-items: center;">
                    <view>
                        <image style="width: 80rpx;height: 80rpx;margin:20rpx;border-radius: 20rpx; "
                            src="../../../static/image/pic_gz.jpg"></image>
                            src="../../../packageA/static/image/pic_gz.jpg"></image>
                    </view>
                    <view
                        style="display: flex;flex: 1;flex-direction: column; justify-content: space-between;  ;height: 100%;padding: 20rpx;">
@@ -77,7 +77,7 @@
                </view>
            </view>
            </view>
        </view>
@@ -407,6 +407,7 @@
                        show: false
                    },
                ],
            }
        },
        mounted() {
pages/tabBar/device.vue
@@ -18,14 +18,15 @@
                                <view class="title">总览</view>
                            </view>
                            <view>
                                <text
                                    class="text-gray margin-right-lg">{{curDate}}</text>
                                <text class="text-gray text-sm">{{curDate}}</text>
                            </view>
                        </view>
                    </view>
                    <view class="flex flex-direction padding-xs">
                    <!-- <view class="flex flex-direction padding-xs">
                        <view class="flex">
                            <view class="flex-sub flex flex-direction text-center">
                                <text class="text-df">设备总数</text>
@@ -52,7 +53,65 @@
                        </view>
                    </view> -->
                    <view class="flex flex-direction padding-xs">
                        <view class="flex">
                            <view class="flex-sub flex flex-direction">
                                <text class="text-df">在线设备</text>
                                <text class="text-bold text-sl margin-top-xs text-green margin-top-sm">{{onlineCount}}
                                    <text class="text-gray text-sm margin-left-xs">台</text></text>
                    </view>
                            <view class="flex-twice flex flex-direction justify-between">
                                <view class="flex-sub flex">
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-gray text-xs">设备信息</text>
                                        <text class="text-black">设备总数:</text>
                                        <text class="margin-lr-xs text-gray text-bold text-xl">{{equCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-gray text-xs">报警信息</text>
                                        <text class="text-black">故障机台:</text>
                                        <text class="margin-lr-xs text-red text-bold text-xl">{{faultEquCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                </view>
                                <view class="flex-sub flex">
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-white text-xs">报警信息</text>
                                        <text class="text-black">停用设备:</text>
                                        <text class="margin-lr-xs text-orange text-bold text-xl">0</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-white text-xs">机台信息</text>
                                        <text class="text-black">告警机台:</text>
                                        <text
                                            class="margin-lr-xs text-orange text-bold text-xl">{{alarmEquCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
@@ -64,7 +123,7 @@
            <u-skeleton   rows="20" :loading="loading" :title="false">
                <!-- å¦‚果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
                <view class="card-box dynamic shadow" v-for="(item,index) in dataList" :key="index"
                <view class="card-item-box dynamic shadow" v-for="(item,index) in dataList" :key="index"
                    @click="itemClick(item)">
                    <view class="title-box">
                        <view class="left flex-sub">
@@ -73,47 +132,58 @@
                            <view class="flex title text-green text-sm">
                                <u-tag v-if="item.online" size="mini" text="在线" type="success" plain plainFill></u-tag>
                                <u-tag v-else  size="mini" text="离线" type="warning" plain plainFill></u-tag>
                                <u-tag v-if="item.online" class="margin-left-sm" size="mini" text="在线" type="success" plain plainFill></u-tag>
                                <u-tag  v-else class="margin-left-sm" size="mini" text="停机" type="error" plain plainFill></u-tag>
                                <view style="width: 20rpx;height: 2rpx"></view>
                                <template v-if="$lget(item,'realData.level')!= '--'">
                                    <u-tag size="mini" :text="$lget(item,'realData.level')" plain plainFill></u-tag>
                                </template>
                            </view>
                        </view>
                        <view class="right" style="min-width: 240rpx;">
                            <!-- <u-badge :isDot="true" type="success"></u-badge> -->
                            <!-- <view class="title text-gray text-sm">开机时间:</view> -->
                            <view class="title text-gray text-sm">{{$lget(item,'upTime')}}</view>
                            <view class="title text-gray text-sm">{{$lget(item,'realData.workorder')}}</view>
                        </view>
                    </view>
                    <view class="info-box">
                        <view class="left flex-sub">
                            <view class="title text-sm">烘干药材:</view>
                            <view class="title text-sm text-gray">--</view>
                            <view class="title text-sm">{{$lget(item,'realData.name')}}</view>
                        </view>
                        <view class="right" style="min-width: 240rpx;">
                            <view class="title text-sm">烘干时间:</view>
                            <view class="title text-sm text-gray">--</view>
                            <view class="title text-sm">投料量:</view>
                            <view class="title text-sm text-gray">{{$lget(item,'realData.weight1')}}筐</view>
                        </view>
                    </view>
                    <view class="info-box">
                        <view class="left flex-sub">
                            <view class="title text-sm">已用时间:</view>
                            <view class="title text-sm">{{$lget(item,'realData.time3')}}min</view>
                        </view>
                        <view class="right" style="min-width: 240rpx;">
                            <view class="title text-sm">预测剩余:</view>
                            <view class="title text-sm text-gray">{{$lget(item,'realData.ai_total_time')}}min</view>
                        </view>
                    </view>
                    <view class="info-box">
                        <view class="left flex-sub">
                            <view class="title text-sm text-cut">报警信息:</view>
                            <view class="flex  title text-sm">
                                <template v-if="item.online && !item.fault">
                                    <u-tag size="mini" text="正常" type="success" plain plainFill></u-tag>
                            <template v-if="item.errorData">
                                <view class="title text-sm text-red">故障 {{item.errorData.length}}</view>
                                </template>
                                <template v-else-if="item.fault">
                                    <u-tag size="mini" text="温度传感器报警" type="warning" plain plainFill></u-tag>
                                    <u-tag size="mini" class="margin-left-xs" text="前门未关" type="warning" plain
                                        plainFill></u-tag>
                                    <u-tag size="mini" class="margin-left-xs" text="风箱低位报警" type="error" plain
                                        plainFill></u-tag>
                                </template>
                                <template v-else>
                                </template>
                            </view>
                        </view>
                            <template v-if="item.warnData">
                                <view class="title text-sm text-yellow">告警 {{item.warnData.length}}</view>
                            </template>
                        </view>
                        <view class="right" style="min-width: 240rpx;">
                            <view class="title text-sm">更新时间:</view>
                            <view class="title text-sm text-gray">{{ refreshTime}}</view>
                        </view>
                    </view>
                </view>
@@ -124,6 +194,7 @@
</template>
<script>
    import dayjs from 'dayjs'
    export default {
        data() {
            return {
@@ -131,7 +202,24 @@
                // v-model绑定的这个变量不要在分页请求结束中自己赋值!!!
                dataList: [],
                curDate:uni.$u.timeFormat(new Date(), 'yyyy-mm-dd'),
                isProcessing: false,
                // key->设备租户+code
                dataMap: new Map(),
                // æ›´æ–°æ—¶é—´
                refreshTime: '',
                alarmEquCount: 0,
                faultEquCount: 0,
                timer: null
            }
        },
        mounted() {
            this.startTimer()
            this.mqttData()
        },
        beforeDestroy() {
            this.stopTimer()
            uni.$off(this.$constant.MQTT_TOPIC_MESSAGE)
        },
        onTabItemTap : function(e) {
        getApp().globalData.selectTab = e.index
@@ -139,31 +227,211 @@
        methods: {
            queryList(pageNo, pageSize) {
                this.loading = true;
                // ç»„件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
                // è¿™é‡Œçš„pageNo和pageSize会自动计算好,直接传给服务器即可
                // æ¨¡æ‹Ÿè¯·æ±‚服务器获取分页数据,请替换成自己的网络请求
                const params = {
                    pageNo: pageNo,
                    pageSize: pageSize,
                }
                this.$api.queryEquList(params).then((res) => {
                    //     // å°†è¯·æ±‚的结果数组传递给z-paging
                    this.$refs.paging.complete(res.result.records);
                    this.loading = false
                }).catch(res => {
                    // å¦‚果请求失败写this.$refs.paging.complete(false);
                    // æ³¨æ„ï¼Œæ¯æ¬¡éƒ½éœ€è¦åœ¨catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
                    // åœ¨åº•层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
                    this.$refs.paging.complete(false);
                    this.loading = false
                })
            },
            // è®¾å¤‡æ•°æ®å’Œmtqq实时数据合并
            mergeMqttRealData(mqttData) {
                const {
                    tenantid,
                    machineid
                } = mqttData;
                if (!tenantid || !machineid) return;
                const key = `${tenantid}_${machineid}`;
                const targetItem = this.dataList.find(item =>
                    item.tenantId === tenantid && item.code === machineid
                );
                if (targetItem) {
                    const updatedItem = {
                        ...targetItem,
                        realData: mqttData
                    };
                    this.$set(this.dataList, this.dataList.indexOf(targetItem), updatedItem);
                }
            },
            startTimer() {
                this.timer = setInterval(() => {
                    this.queryRealFaultData();
                }, 3000);
            },
            stopTimer() {
                clearInterval(this.timer);
            },
            queryRealFaultData() {
                //发送数据
                const message = {
                    req: this.deviceId,
                    tenantId: this.tenantId,
                    timeStamp: new Date(),
                }
                let opts = {
                    topic: this.$constant.MOBILE_REQ_EQU_REAL_FAULT,
                    message: JSON.stringify(message),
                }
                this.$mqttTool.publish(opts).then(res => {
                })
            },
            itemClick(item) {
                uni.navigateTo({
                    url: "/pages/device/control?code="+item.code+"&clientId="+item.clientId
                    url: "/packageA/pages/device/control?code=" + item.code + "&name=" + item.name + "&clientId=" +
                        item.clientId
                })
            },
            mqttData() {
                uni.$on(this.$constant.MQTT_TOPIC_MESSAGE, (data) => {
                    try {
                        // 1. æ•°æ®è§£æžå’ŒéªŒè¯
                        const {
                            data: wdata,
                            topic
                        } = this.parseAndValidateMqttData(data);
                        if (!wdata || !topic) return;
                        // 2. å‡†å¤‡ä¸»é¢˜å¸¸é‡
                        const topics = this.prepareMqttTopics();
                        // 3. æ›´æ–°åˆ·æ–°æ—¶é—´
                        this.refreshTime = dayjs().format('HH:mm:ss');
                        // 4. æ ¹æ®ä¸»é¢˜å¤„理数据
                        switch (topic) {
                            case topics.updateEquStatu:
                                this.handleEquipmentStatusUpdate(wdata);
                                break;
                            case topics.realData:
                                this.mergeMqttRealData(wdata);
                                break;
                            case topics.realFaultTopic:
                            case topics.oneceFaultTopic:
                                this.handleFaultData(wdata);
                                break;
            }
                    } catch (error) {
                        console.error('MQTT数据处理错误:', error);
                    }
                });
            },
            // è¾…助方法:解析和验证MQTT数据
            parseAndValidateMqttData(data) {
                try {
                    const json = JSON.parse(data);
                    if (!json?.data || !json?.topic) return {
                        data: null,
                        topic: null
                    };
                    return {
                        data: json.data,
                        topic: json.topic
                    };
                } catch (e) {
                    return {
                        data: null,
                        topic: null
                    };
                }
            },
            // è¾…助方法:准备MQTT主题
            prepareMqttTopics() {
                return {
                    updateEquStatu: this.$constant.SERVICE_BROADCAST_TENANT_UPDATE_EQU_STATU
                        .replace('%s', this.tenantId),
                    realData: this.$constant.SERVICE_BROADCAST_TENANT_REAL_DATA
                        .replace('%s', this.tenantId),
                    realFaultTopic: this.$constant.SERVICE_BROADCAST_TENANT_REAL_FAULT
                        .replace('%s', this.tenantId),
                    oneceFaultTopic: this.$constant.SERVICE_ONECE_TENANT_REAL_FAULT.replace('%s', this
                        .deviceId)
                };
            },
            // è¾…助方法:处理设备状态更新
            handleEquipmentStatusUpdate(wdata) {
                const {
                    connected,
                    tenantId,
                    code
                } = wdata;
                const index = this.dataList.findIndex(item =>
                    (item.tenantId + "") === tenantId && item.code === code
                );
                if (index === -1) return;
                // æ›´æ–°åœ¨çº¿çŠ¶æ€
                this.$set(this.dataList[index], 'online', connected);
                // å¦‚果离线,删除实时数据
                if (!connected && this.dataList[index]?.realData) {
                    this.$delete(this.dataList[index], 'realData');
                }
            },
            // è¾…助方法:处理故障数据
            handleFaultData(wdata) {
                if (!Array.isArray(wdata)) return;
                // æŒ‰è®¾å¤‡åˆ†ç»„故障数据
                const faultMap = wdata.reduce((map, item) => {
                    const key = `${item.tenantId}_${item.equCode}`;
                    map.get(key)?.push(item) || map.set(key, [item]);
                    return map;
                }, new Map());
                // æ›´æ–°æ¯ä¸ªè®¾å¤‡çš„æ•…障信息
                faultMap.forEach((faults, key) => {
                    const [tenantId, equCode] = key.split("_");
                    const targetItem = this.dataList.find(i =>
                        i.tenantId == tenantId && i.code == equCode
                    );
                    if (targetItem) {
                        const updatedItem = {
                            ...targetItem,
                            errorData: faults.filter(f => f.faultType === 1).map(n => n.faultName),
                            warnData: faults.filter(f => f.faultType === 2).map(n => n.faultName),
                        };
                        this.$set(this.dataList, this.dataList.indexOf(targetItem), updatedItem);
                    }
                });
                this.faultEquCount = this.dataList.filter(item => {
                    return (
                        item.errorData &&
                        Array.isArray(item.errorData) &&
                        item.errorData.length > 0
                    );
                }).length || 0;
                this.alarmEquCount = this.dataList.filter(item => {
                    return (
                        item.warnData &&
                        Array.isArray(item.warnData) &&
                        item.warnData.length > 0
                    );
                }).length || 0;
            }
        },
        onReady() {
@@ -176,6 +444,14 @@
            onlineCount() {
                const list = this.dataList.filter(item => item.online)
                return list.length
            },
            tenantId() {
                const userinfo = uni.getStorageSync('userinfo');
                const tenantid = userinfo.loginTenantId
                return tenantid + "";
            },
            deviceId() {
                return uni.getStorageSync(this.$constant.DEVICE_ID);
            }
        }
    }
@@ -195,7 +471,24 @@
        background-color: white;
        border-radius: 20rpx;
        font-family: Helvetica Neue, Helvetica, sans-serif;
    }
    .card-item-box {
        margin: 0rpx 20rpx 10rpx 20rpx;
        padding: 20rpx;
        box-sizing: border-box;
        background-color: white;
        border-radius: 20rpx;
        font-family: Helvetica Neue, Helvetica, sans-serif;
    }
    /* ç¬¬äºŒä¸ªåŠä¹‹åŽçš„ item */
    .card-item-box:not(:first-child) {
        margin: 10rpx 20rpx;
    }
    .margin-left-sm {
        margin-left: 20rpx;
    }
pages/tabBar/formula.vue
@@ -61,7 +61,7 @@
      showItem(item){
        console.info(item)
        uni.navigateTo({
          url:"/pages/category/formulaDetail"
          url:"/packageA/pages/category/formulaDetail"
        })
      },
      getImg() {
pages/tabBar/general.vue
@@ -368,6 +368,9 @@
                    // #ifdef APP-PLUS
                    url: 'wx://' + this.$api.mqttBaseUrl + ':8083/mqtt',
                    // #endif
                    // #ifdef MP-WEIXIN
                    url: 'wss://' + this.$api.mqttBaseUrl + '/mqtt', // å¿…须用 wss,端口通常为443可省略
                    // #endif
                    clientId: this.deviceId,
                    username: account.username,
                    password: account.password
@@ -398,6 +401,8 @@
                }).then(res => {
                    console.error(res)
                })
                //订阅发送指令返回结果
                // this.$mqttTool.subscribe({
                //     topic: this.$constant.SERVICE_RES_EQU_CMD,
@@ -456,7 +461,7 @@
            },
            goCharts(e) {
                uni.navigateTo({
                    url: "/pages/charts/charts"
                    url: "/packageA/pages/charts/charts"
                })
            },
            getOrderList(date1, date2) {
@@ -573,7 +578,6 @@
<style lang="scss" scoped>
    .app {
        width: 100%;
        max-height: 100vh;
        overflow: hidden;
    }
pages/tabBar/me.vue
@@ -227,15 +227,15 @@
            itemClick(mode) {
                if (mode == 'control') {
                    uni.navigateTo({
                        url: "/pages/me/control"
                        url: "/packageA/pages/me/control"
                    })
                } else if (mode == 'video') {
                    uni.navigateTo({
                        url: "/pages/me/video"
                        url: "/packageA/pages/me/video"
                    })
                } else if (mode == 'analy') {
                    uni.navigateTo({
                        url: "/pages/me/analy"
                        url: "/packageA/pages/me/analy"
                    })
                } else if (mode == 'other') {
                    uni.navigateTo({
pages/tabBar/warning-new.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,267 @@
<template>
    <view class="app">
        <z-paging ref="paging" v-model="dataList" show-refresher-update-time @query="queryList" :hide-empty-view="true">
            <!-- éœ€è¦å›ºå®šåœ¨é¡¶éƒ¨ä¸æ»šåŠ¨çš„view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
            <template #top>
                <cu-custom bgColor="bg-gradual-blue" :isBack="false" :isRight="true" @rightclick="">
                    <block slot="content">报警机台</block>
                </cu-custom>
                <view class="card-box dynamic shadow">
                    <view class="title-box margin-bottom-sm">
                        <view style="width: 100vw;" class="left justify-between">
                            <view class="flex align-center">
                                <uni-text class="cuIcon-titles text-blue"></uni-text>
                                <view class="title">总览</view>
                            </view>
                            <view>
                                <text class="text-gray text-sm">{{curDate}}</text>
                            </view>
                        </view>
                    </view>
                    <view class="flex flex-direction padding-xs">
                        <view class="flex">
                            <view class="flex-sub flex flex-direction">
                                <text class="text-df">报警总数</text>
                                <text class="text-bold text-sl margin-top-xs text-red margin-top-sm">{{count}}
                                    <text class="text-gray text-sm margin-left-xs">次</text></text>
                            </view>
                            <view class="flex-twice flex flex-direction justify-between">
                                <view class="flex-sub flex">
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-gray text-xs">报警信息</text>
                                        <text class="text-black">故障次数:</text>
                                        <text class="margin-lr-xs text-red text-bold text-xl">{{faultCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-gray text-xs">机台信息</text>
                                        <text class="text-black">故障机台:</text>
                                        <text class="margin-lr-xs text-red">{{faultEqus}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                </view>
                                <view class="flex-sub flex">
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-white text-xs">报警信息</text>
                                        <text class="text-black">告警次数:</text>
                                        <text class="margin-lr-xs text-orange text-bold text-xl">{{alarmCount}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                    <view class="flex flex-direction flex-sub">
                                        <text class="text-white text-xs">机台信息</text>
                                        <text class="text-black">告警机台:</text>
                                        <text class="margin-lr-xs text-orange">{{alarmEqus}}</text>
                                        <text class="text-gray text-xs"></text>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
            </template>
            <view class="container">
                <view class="flex align-center">
                    <uni-text class="cuIcon-titles text-blue"></uni-text>
                    <view class="title">设备列表</view>
                </view>
                <view class="equ-box">
                    <div v-for="(item,index) in dataList" :key="index" class="equ-item">
                    </div>
                </view>
            </view>
        </z-paging>
    </view>
</template>
<script>
    import dayjs from 'dayjs'
    export default {
        data() {
            return {
                loading: true,
                dataList: [],
                curDate: dayjs().format('YYYY-MM-DD'),
                //实时报警数据更新时间(一般10s)
                refreshTime: '',
                //报警总数
                count: 0,
                //告警总数
                alarmCount: 0,
                //故障总数
                faultCount: 0,
                //故障机台
                faultEqus: "",
                //告警机台
                alarmEqus: "",
            }
        },
        onTabItemTap: function(e) {
            getApp().globalData.selectTab = e.index
        },
        onShow() {
        },
        onReady() {
        },
        methods: {
            queryList(pageNo, pageSize) {
                this.loading = true;
                const params = {
                    pageNo: pageNo,
                    pageSize: pageSize,
                }
             this.$api.queryEquList(params).then((res) => {
                 this.$refs.paging.complete(res.result.records);
                 this.loading = false
             }).catch(res => {
                 this.$refs.paging.complete(false);
                 this.loading = false
             })
            },
            queryRealFaultData() {
                //发送数据
                const message = {
                    req: this.deviceId,
                    tenantId: this.tenantId,
                    timeStamp: new Date(),
                }
                let opts = {
                    topic: this.$constant.MOBILE_REQ_EQU_REAL_FAULT,
                    message: JSON.stringify(message),
                }
                this.$mqttTool.publish(opts).then(res => {
                    //console.error(res)
                })
            },
        },
        onReady() {
        },
        computed: {
            tenantId() {
                const userinfo = uni.getStorageSync('userinfo');
                const tenantid = userinfo.loginTenantId
                return tenantid + "";
            },
            deviceId() {
                return uni.getStorageSync(this.$constant.DEVICE_ID);
            },
        },
    }
</script>
<style lang="scss" scoped>
    .container {
        margin: 0 20rpx;
        padding: 20rpx;
        box-sizing: border-box;
        background-color: white;
        font-family: Helvetica Neue, Helvetica, sans-serif;
        border-radius: 20rpx;
    }
    .card-box {
        margin: 20rpx;
        padding: 20rpx;
        box-sizing: border-box;
        background-color: white;
        border-radius: 20rpx;
        font-family: Helvetica Neue, Helvetica, sans-serif;
    }
    .title-box {
        display: flex;
        flex-direction: row;
        align-items: center;
        .left {
            display: flex;
            align-items: center;
            .title {
                margin: 0 10rpx;
                font-weight: bold;
            }
        }
        .right {
            display: flex;
            align-items: center;
            .title {
                margin: 0 10rpx;
                font-weight: bold;
            }
        }
    }
    .equ-box {
        display: flex;
        flex-wrap: wrap;
        margin-top: 20rpx;
        gap: 20rpx 0px;
        justify-content: space-between;
    }
    .equ-item {
        width: calc((100% - 20rpx)/2);
        height: 200rpx;
        border-radius: 20rpx;
        background-color: #ecf5ff;
    }
    .borderTop {
        border-top: 2rpx solid #f2f2f2;
        padding-top: 20rpx;
    }
</style>
pages/tabBar/warning.vue
@@ -4,7 +4,7 @@
            <!-- éœ€è¦å›ºå®šåœ¨é¡¶éƒ¨ä¸æ»šåŠ¨çš„view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
            <template #top>
                <cu-custom bgColor="bg-gradual-blue" :isBack="false" :isRight="true" @rightclick="rclick">
                    <block slot="content">报警</block>
                    <block slot="content">报警统计</block>
                </cu-custom>
@@ -33,6 +33,7 @@
                        </view>
                    </view>
                    <view class="flex flex-direction padding-xs">
                        <view class="flex">
                            <view class="flex-sub flex flex-direction">
@@ -114,8 +115,8 @@
            </view>
            <!-- å¦‚果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
            <real-warning ref="realWarining" v-if="tabCurrent === 0" @handleData="realHandleData"></real-warning>
            <his-warning ref="hisWarining" v-else @handleData="hisHandleData"></his-warning>
          <!-- <real-warning ref="realWarining" v-if="tabCurrent === 0" @handleData="realHandleData"></real-warning>  -->
            <his-warning ref="hisWarining" v-if="tabCurrent === 0" @handleData="hisHandleData"></his-warning>
        </z-paging>
@@ -139,18 +140,20 @@
                // v-model绑定的这个变量不要在分页请求结束中自己赋值!!!
                dataList: [],
                curDate: dayjs().format('YYYY-MM-DD'),
                tabList: [{
                    name: '实时报警',
                    // badge: {
                    //     count: 6
                    // }
                }, {
                tabList: [
                //     {
                //     name: '实时报警',
                //     // badge: {
                //     //     count: 6
                //     // }
                // },
                {
                    name: '报警统计',
                }],
                equList: [{
                equList: [/* {
                        code: 1,
                        name: '1#干燥机'
                    },
                    }, */
                    {
                        code: 2,
                        name: '2#干燥机'
private.wx8aa7310d86d0b80d.key
ÎļþÒÑɾ³ý
private.wxe6f8a31c3df63a20.key
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA0BFj3BZsxbfJdpVxGZTwHHrmHTZtdJ708RwgJb5qcOWu8m7S
KxOhXiObzMxCVYrsPtfnbvd6QbfdP7XKF2DK2cvzoNcX+6H3WQW9GYZOumV8vMHY
YFQNtJMw5a41+M18baDDRglGy2U0i/dg/WRi0EDbaaf6PlqouPym06iQp5cQx6nQ
pHFyeH1RYOxx6ygqielyjMGCVtwh6yQyAt9R4IYsJpW6VS9Yu8YvP5w4Bc/P+KnN
M7OsV9a5nMew6KJUfXa0eU2HRnWtPYx7W2OTxT0zTdO90Iknetg8LMO9cmgEt9mX
74JCc7TwGf5RBmieQK14wYkZSK9EbGjMAfDmrQIDAQABAoIBAGEA2oePROLhDmHk
xjfhAhilC4dvCpSmTxfhvvMZ1VIRIwEPvZgrrL3Q6CAQ0pRDEmUyD0niwvLEn7fG
LxO7IpdryIeiACJmnoS4cjLmNOodyovN6+ztAv6+6LsL/0mhs3MA0klipcjJxDfE
+0jndlIVCrY1hCtx5NtpnvVqzxXyNqzo/qs07euThUUvclNJsN8+YM2OJwGLpY/z
lAsyYlohqfwVALTdFJoAdrcjN4nDS4xGue4Fj8XaDRAD4cayhG6cMO1acRYW0u+a
2+XaeKGeHQCea/6E/6hJ0KmcT9nWbSLD09xfxvyovxXMe7msvX7k4WJUKLvXcqZh
rVoj2NkCgYEA7X9Ead5qQtFzS805tEtV1dRPJGDpooX6NJl3BzqceJXd6jhnTsSv
OqrK4p5Hrog4EF3MzVB7PtRS156emZ7MWe4qQTQu69+Vy1MxZwxcIN7N3lWlE2A9
aAFqx65UEVlsApfZvP2Q5PBi1yknP8cngih5fd8R9P6rG0/l6OrF0iMCgYEA4Ecs
8y46UdmIiBwYj8mDb8OzrOZ+b7IpPIiltc92kLqC9HsNDMlo5XwilsjCsX+lnMl6
xFwT5hY54BCvouvkdtr4EJcvWARCUpIUmkbU6/hkc4dLMrvlaP8N1JWnT4vWBz4j
OXiKMkreLFMGNZviY121dfCDA4MSs6UL3OAG6O8CgYEAudtp14vmDmpI1x5AtTZr
cs4WLTrmO3iriHQ8sNyOTNPDeaMwPXUwSDIWWehR4mTZsv0k49vCxzVzqyeHqGKc
Oxhl2ucSfSZY3Gg7dhA3HMYfx4mwiIw9IeJSBPgI9BbNru3UyNCKjo8MWqLrAz9A
TNyNzxI9xENz9gi9vFvV+Y8CgYEAiQ+WTcsbgvfQ83VQIVdCRuQvguOdsz8K6l6L
/q8Zw1roOuaUVBMmUtBpBwML0JO0rzuGFkg7NOqyVdd8rrFAfs5UuTbbjQuVSIbT
pnDRIKA9K0ksUIX5rg/o8NjAVeGcW/LCbhXXRuLwIeBfNBXe5WDYS4o/Vr8ch8K+
nC4gqusCgYA0vgMDTpCtFv1oR2Id/saRA1+oClB4xclJfYZiMVAAo0yVvRFoqoBP
QFbVWt6Tdll5fV7LNpre11ckRF8B8nYA8HxYZ1UhHSVgrTwQYsH8Tx2w+ung58UU
lLNHHmxb7Z+0+5ZgMXvpNcwHocpfT5uTUbo2PtvHl1ldZTumjP63Hw==
-----END RSA PRIVATE KEY-----