diff --git a/package.json b/package.json index d8c8c3f2..fd5466d5 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "mathjax": "^3.2.2", "min-dash": "^4.2.1", "mitt": "^3.0.1", + "mqtt": "^5.13.3", "nprogress": "^0.2.0", "pinia": "^2.1.7", "pinia-plugin-persistedstate": "^3.2.1", diff --git a/public/favicon.ico b/public/favicon.ico index fe16b5ad..029a1f39 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon1.ico b/public/favicon1.ico new file mode 100644 index 00000000..fe16b5ad Binary files /dev/null and b/public/favicon1.ico differ diff --git a/src/api/system-boot/dictTree.ts b/src/api/system-boot/dictTree.ts index 543d5b0e..fc4a228a 100644 --- a/src/api/system-boot/dictTree.ts +++ b/src/api/system-boot/dictTree.ts @@ -88,8 +88,8 @@ export const updateStatistical = (data: any) => { // 单位绑定 export function codeDicTree(data: any) { return createAxios({ - url: '/system-boot/dicTree/codeDicTree', - method: 'get', + url: '/system-boot/dictTree/queryByCodeList', + method: 'post', params: data }) } diff --git a/src/components/echarts/rmsboxi.vue b/src/components/echarts/rmsboxi.vue index 9ff7e3fe..376f2aaa 100644 --- a/src/components/echarts/rmsboxi.vue +++ b/src/components/echarts/rmsboxi.vue @@ -134,15 +134,29 @@ export default { }, methods: { backbxlb() { - this.waveDatas = [] - if(this.myChartess){this.myChartess.dispose(); this.myChartess=null; } - if(this.myChartess1){this.myChartess1.dispose(); this.myChartess1=null; } - if(this.myChartess2){this.myChartess2.dispose(); this.myChartess2=null; } - if(this.myChartess3){this.myChartess3.dispose(); this.myChartess3=null; } - if(this.myChartess4){this.myChartess4.dispose(); this.myChartess4=null; } - if(this.myChartess5){this.myChartess5.dispose(); this.myChartess5=null; } + this.waveDatas = [] + + // 清理所有可能的 echarts 实例 + const chartNames = ['myChartess', 'myChartess1', 'myChartess2', 'myChartess3', 'myChartess4', 'myChartess5'] + + chartNames.forEach(name => { + if (this[name]) { + this[name].dispose() + this[name] = null + } + }) + + // 断开 echarts 实例连接 + echarts.disconnect(chartNames.map(name => this[name]).filter(Boolean)) + // this.waveDatas = [] + // if(this.myChartess){this.myChartess.dispose(); this.myChartess=null; } + // if(this.myChartess1){this.myChartess1.dispose(); this.myChartess1=null; } + // if(this.myChartess2){this.myChartess2.dispose(); this.myChartess2=null; } + // if(this.myChartess3){this.myChartess3.dispose(); this.myChartess3=null; } + // if(this.myChartess4){this.myChartess4.dispose(); this.myChartess4=null; } + // if(this.myChartess5){this.myChartess5.dispose(); this.myChartess5=null; } - echarts.disconnect([this.myChartess,this.myChartess1,this.myChartess2,this.myChartess3,this.myChartess4,this.myChartess5]) + // echarts.disconnect([this.myChartess,this.myChartess1,this.myChartess2,this.myChartess3,this.myChartess4,this.myChartess5]) // if (this.echartlist.length > 0) { diff --git a/src/components/echarts/shushiboxi.vue b/src/components/echarts/shushiboxi.vue index 48842a18..f6d5631f 100644 --- a/src/components/echarts/shushiboxi.vue +++ b/src/components/echarts/shushiboxi.vue @@ -122,16 +122,20 @@ export default { }, methods: { backbxlb() { - this.waveDatas = [] - if(this.myChartess){this.myChartess.dispose(); this.myChartess=null; } - if(this.myChartess1){this.myChartess1.dispose(); this.myChartess1=null; } - if(this.myChartess2){this.myChartess2.dispose(); this.myChartess2=null; } - if(this.myChartess3){this.myChartess3.dispose(); this.myChartess3=null; } - if(this.myChartess4){this.myChartess4.dispose(); this.myChartess4=null; } - if(this.myChartess5){this.myChartess5.dispose(); this.myChartess5=null; } - - echarts.disconnect([this.myChartess,this.myChartess1,this.myChartess2,this.myChartess3,this.myChartess4,this.myChartess5]) - + this.waveDatas = [] + + // 清理所有可能的 echarts 实例 + const chartNames = ['myChartess', 'myChartess1', 'myChartess2', 'myChartess3', 'myChartess4', 'myChartess5'] + + chartNames.forEach(name => { + if (this[name]) { + this[name].dispose() + this[name] = null + } + }) + + // 断开 echarts 实例连接 + echarts.disconnect(chartNames.map(name => this[name]).filter(Boolean)) // this.echartlist.forEach(item => { // if (item) { diff --git a/src/components/table/defaultAttribute.ts b/src/components/table/defaultAttribute.ts index 67c9ce92..88bdb307 100644 --- a/src/components/table/defaultAttribute.ts +++ b/src/components/table/defaultAttribute.ts @@ -4,7 +4,7 @@ export const defaultAttribute: VxeTableProps = { align: 'center', headerCellClassName: 'table-header-cell', border: true, - // stripe: true, + size: 'small', columnConfig: { resizable: true }, rowConfig: { isCurrent: true, isHover: true }, diff --git a/src/layouts/admin/components/globalPopUp.vue b/src/layouts/admin/components/globalPopUp.vue new file mode 100644 index 00000000..9ac9713b --- /dev/null +++ b/src/layouts/admin/components/globalPopUp.vue @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + {{ Math.floor(row.eventValue * 10000) / 100 }} + + + + + {{ eventType.filter(item => item.id == row.eventReason)[0]?.name || '/' }} + + + + + + + + + diff --git a/src/layouts/admin/components/navMenus.vue b/src/layouts/admin/components/navMenus.vue index 36a05438..144b28ec 100644 --- a/src/layouts/admin/components/navMenus.vue +++ b/src/layouts/admin/components/navMenus.vue @@ -1,29 +1,46 @@ - - - - - - - + + + + + {{ globalPopUpRef?.eventList.length || 0 }} + + + + + + + + + + + + + + @@ -51,6 +68,8 @@ + + @@ -62,6 +81,7 @@ import { ElMessage } from 'element-plus' import Config from './config.vue' import { useAdminInfo } from '@/stores/adminInfo' import router from '@/router' +import globalPopUp from './globalPopUp.vue' import { routePush } from '@/utils/router' import { fullUrl } from '@/utils/common' import html2canvas from 'html2canvas' @@ -80,7 +100,7 @@ const state = reactive({ showLayoutDrawer: false, showAdminInfoPopover: false }) - +const globalPopUpRef = ref() const savePng = () => { html2canvas(document.body, { scale: 1, @@ -122,6 +142,9 @@ const handleCommand = (key: string) => { break } } +const temporaryLandingEvent = () => { + globalPopUpRef.value.open() +} diff --git a/src/styles/element.css b/src/styles/element.css index 28506adc..8bfb875e 100644 --- a/src/styles/element.css +++ b/src/styles/element.css @@ -68,7 +68,7 @@ } .el-dialog__header .el-dialog__headerbtn:hover .el-icon { - color: #409eff; + color: #ccc; } .el-dialog__header .el-dialog__title { @@ -244,3 +244,30 @@ .el-select__input-wrapper { width: 11px; } + +.el-drawer__header { + background: var(--el-color-primary); + padding: 18px; + margin-right: 0px; +} + +.el-drawer__header .el-drawer__close-btn { + top: 5px; +} + +.el-drawer__header .el-drawer__close-btn .el-icon { + color: var(--el-color-white); +} + +.el-drawer__header .el-drawer__close-btn:hover .el-icon { + color: #ccc; +} + +.el-drawer__header .el-drawer__title { + color: var(--el-color-white); + font-size: 18px; +} + +.el-drawer__body { + padding: 10px; +} diff --git a/src/styles/element.min.css b/src/styles/element.min.css index c54b3016..fd735819 100644 --- a/src/styles/element.min.css +++ b/src/styles/element.min.css @@ -1 +1 @@ -.el-input .el-input__inner{height:30px;line-height:calc(var(--el-input-height, 40px) - 4px)}.datetime-picker{height:32px;padding-top:0;padding-bottom:0}.el-divider__text.is-center{transform:translateX(-50%) translateY(-62%)}.el-menu{user-select:none}.el-menu .el-menu-item:hover,.el-menu .el-sub-menu__title:hover{background-color:var(--el-menu-hover-color) !important;color:var(--el-menu-active-color) !important}.el-menu .el-menu-item:hover .icon,.el-menu .el-sub-menu__title:hover .icon{color:var(--el-menu-active-color) !important}.atooltip{margin-top:0px !important;padding:0 !important}.el-dialog{padding:0px !important}.el-dialog .el-dialog__footer{padding:15px;box-shadow:var(--el-box-shadow);width:100%;bottom:0}.el-dialog__body{max-height:60vh;overflow-y:auto;padding:10px}.el-dialog__header{background:var(--el-color-primary);padding:15px;margin-right:0px}.el-dialog__header .el-dialog__headerbtn{top:5px}.el-dialog__header .el-dialog__headerbtn .el-icon{color:var(--el-color-white)}.el-dialog__header .el-dialog__headerbtn:hover .el-icon{color:#409eff}.el-dialog__header .el-dialog__title{color:var(--el-color-white)}.el-table{--el-table-border-color:var(--ba-border-color)}.el-card{border:none}.el-card__header{border-bottom:1px solid var(--el-border-color-extra-light)}.el-textarea__inner{padding:5px 11px}.el-overlay-dialog,.el-tabs__content,.ba-scroll-style{scrollbar-width:none}.el-overlay-dialog::-webkit-scrollbar,.el-tabs__content::-webkit-scrollbar,.ba-scroll-style::-webkit-scrollbar{width:5px;height:5px}.el-overlay-dialog::-webkit-scrollbar-thumb,.el-tabs__content::-webkit-scrollbar-thumb,.ba-scroll-style::-webkit-scrollbar-thumb{background:#eaeaea;border-radius:var(--el-border-radius-base);box-shadow:none;-webkit-box-shadow:none}.el-overlay-dialog:hover::-webkit-scrollbar-thumb:hover,.el-tabs__content:hover::-webkit-scrollbar-thumb:hover,.ba-scroll-style:hover::-webkit-scrollbar-thumb:hover{background:#c8c9cc}.ba-input-item-radio{margin-bottom:10px}.ba-input-item-radio .el-radio-group .el-radio{margin-bottom:8px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{background:var(--el-color-primary);color:var(--el-color-white)}.el-tabs__header{margin-bottom:0}.el-form--inline .el-form-item{margin-bottom:10px}.el-tabs--border-card>.el-tabs__content{padding:10px}.el-page-header__header{line-height:32px}.el-page-header__header .el-page-header__content{font-size:14px;font-weight:700}.el-select{min-width:200px}.el-tabs__content{height:calc(100% - 40px)}.el-tabs__content .el-tab-pane{height:100%}.el-button--primary:focus{color:var(--el-color-white);outline:0}.el-button--primary:hover{color:var(--el-color-white);border-color:var(--el-color-primary-light-3);background-color:var(--el-color-primary-light-3);outline:0}.el-button.is-plain:focus{color:var(--el-button-text-color);border-color:var(--el-button-border-color)}.el-button.is-plain:hover{color:var(--el-color-primary);border-color:var(--el-color-primary)}.el-button.is-link:focus{color:var(--el-button-text-color)}.el-button.is-link:hover{color:var(--el-button-hover-link-text-color)}.el-button--primary.is-link:hover,.el-button--primary.is-plain:hover,.el-button--primary.is-text:hover{color:var(--el-color-primary-light-5);background-color:var(--el-color-primary-light-9) !important}.el-divider--horizontal{margin:15px 0}.el-step__title{cursor:pointer}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner,.el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:var(--el-color-primary);opacity:0.6}.sgmap-ctrl-bottom-left{display:none !important}.el-drawer__header{margin-bottom:0 !important}.el-pagination__sizes .el-select{min-width:128px}.el-card__header{padding:10px}.el-card__header span{font-size:16px;font-weight:600}.el-select__input-wrapper{width:11px} +.el-input .el-input__inner{height:30px;line-height:calc(var(--el-input-height, 40px) - 4px)}.datetime-picker{height:32px;padding-top:0;padding-bottom:0}.el-divider__text.is-center{transform:translateX(-50%) translateY(-62%)}.el-menu{user-select:none}.el-menu .el-menu-item:hover,.el-menu .el-sub-menu__title:hover{background-color:var(--el-menu-hover-color) !important;color:var(--el-menu-active-color) !important}.el-menu .el-menu-item:hover .icon,.el-menu .el-sub-menu__title:hover .icon{color:var(--el-menu-active-color) !important}.atooltip{margin-top:0px !important;padding:0 !important}.el-dialog{padding:0px !important}.el-dialog .el-dialog__footer{padding:15px;box-shadow:var(--el-box-shadow);width:100%;bottom:0}.el-dialog__body{max-height:60vh;overflow-y:auto;padding:10px}.el-dialog__header{background:var(--el-color-primary);padding:15px;margin-right:0px}.el-dialog__header .el-dialog__headerbtn{top:5px}.el-dialog__header .el-dialog__headerbtn .el-icon{color:var(--el-color-white)}.el-dialog__header .el-dialog__headerbtn:hover .el-icon{color:#ccc}.el-dialog__header .el-dialog__title{color:var(--el-color-white)}.el-table{--el-table-border-color:var(--ba-border-color)}.el-card{border:none}.el-card__header{border-bottom:1px solid var(--el-border-color-extra-light)}.el-textarea__inner{padding:5px 11px}.el-overlay-dialog,.el-tabs__content,.ba-scroll-style{scrollbar-width:none}.el-overlay-dialog::-webkit-scrollbar,.el-tabs__content::-webkit-scrollbar,.ba-scroll-style::-webkit-scrollbar{width:5px;height:5px}.el-overlay-dialog::-webkit-scrollbar-thumb,.el-tabs__content::-webkit-scrollbar-thumb,.ba-scroll-style::-webkit-scrollbar-thumb{background:#eaeaea;border-radius:var(--el-border-radius-base);box-shadow:none;-webkit-box-shadow:none}.el-overlay-dialog:hover::-webkit-scrollbar-thumb:hover,.el-tabs__content:hover::-webkit-scrollbar-thumb:hover,.ba-scroll-style:hover::-webkit-scrollbar-thumb:hover{background:#c8c9cc}.ba-input-item-radio{margin-bottom:10px}.ba-input-item-radio .el-radio-group .el-radio{margin-bottom:8px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{background:var(--el-color-primary);color:var(--el-color-white)}.el-tabs__header{margin-bottom:0}.el-form--inline .el-form-item{margin-bottom:10px}.el-tabs--border-card>.el-tabs__content{padding:10px}.el-page-header__header{line-height:32px}.el-page-header__header .el-page-header__content{font-size:14px;font-weight:700}.el-select{min-width:200px}.el-tabs__content{height:calc(100% - 40px)}.el-tabs__content .el-tab-pane{height:100%}.el-button--primary:focus{color:var(--el-color-white);outline:0}.el-button--primary:hover{color:var(--el-color-white);border-color:var(--el-color-primary-light-3);background-color:var(--el-color-primary-light-3);outline:0}.el-button.is-plain:focus{color:var(--el-button-text-color);border-color:var(--el-button-border-color)}.el-button.is-plain:hover{color:var(--el-color-primary);border-color:var(--el-color-primary)}.el-button.is-link:focus{color:var(--el-button-text-color)}.el-button.is-link:hover{color:var(--el-button-hover-link-text-color)}.el-button--primary.is-link:hover,.el-button--primary.is-plain:hover,.el-button--primary.is-text:hover{color:var(--el-color-primary-light-5);background-color:var(--el-color-primary-light-9) !important}.el-divider--horizontal{margin:15px 0}.el-step__title{cursor:pointer}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner,.el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:var(--el-color-primary);opacity:0.6}.sgmap-ctrl-bottom-left{display:none !important}.el-drawer__header{margin-bottom:0 !important}.el-pagination__sizes .el-select{min-width:128px}.el-card__header{padding:10px}.el-card__header span{font-size:16px;font-weight:600}.el-select__input-wrapper{width:11px}.el-drawer__header{background:var(--el-color-primary);padding:18px;margin-right:0px}.el-drawer__header .el-drawer__close-btn{top:5px}.el-drawer__header .el-drawer__close-btn .el-icon{color:var(--el-color-white)}.el-drawer__header .el-drawer__close-btn:hover .el-icon{color:#ccc}.el-drawer__header .el-drawer__title{color:var(--el-color-white);font-size:18px}.el-drawer__body{padding:10px} diff --git a/src/styles/element.scss b/src/styles/element.scss index 8b58b702..69b3f003 100644 --- a/src/styles/element.scss +++ b/src/styles/element.scss @@ -63,7 +63,7 @@ } .el-dialog__headerbtn:hover { .el-icon { - color: #409eff; + color: #ccc; } } @@ -232,4 +232,28 @@ .el-select__input-wrapper { width: 11px; } +.el-drawer__header { + background: var(--el-color-primary); + padding: 18px; + margin-right: 0px; + .el-drawer__close-btn { + top: 5px; + .el-icon { + color: var(--el-color-white); + } + } + .el-drawer__close-btn:hover { + .el-icon { + color: #ccc; + } + } + + .el-drawer__title { + color: var(--el-color-white); + font-size: 18px; + } +} +.el-drawer__body { + padding: 10px; +} diff --git a/src/utils/mqtt.ts b/src/utils/mqtt.ts new file mode 100644 index 00000000..cb88f244 --- /dev/null +++ b/src/utils/mqtt.ts @@ -0,0 +1,251 @@ +import type { MqttClient, OnMessageCallback, IClientOptions, IClientSubscribeOptions } from 'mqtt'; +import mqtt from 'mqtt'; + +interface MQTTOptions { + protocolId?: string; + qos?: 0 | 1 | 2; + clean?: boolean; + connectTimeout?: number; + clientId?: string; + username?: string; + password?: string; + reconnectPeriod?: number; // 重连间隔(ms) + maxReconnectTimes?: number; // 最大重连次数 +} + +class MQTT { + private topic: string; + private client: MqttClient | null = null; + private isConnected: boolean = false; + private reconnectCount: number = 0; + private maxReconnectTimes: number; + private reconnectPeriod: number; + private isManuallyDisconnected: boolean = false; + private defaultOptions: MQTTOptions = { + protocolId: 'MQTT', + qos: 2, + clean: true, + connectTimeout: 30 * 1000, + clientId: `mqttjs_${Math.random().toString(16).substr(2, 8)}`, + username: 't_user', + password: 'njcnpqs', + reconnectPeriod: 1000, // 默认1秒重试一次 + maxReconnectTimes: 3, // 默认最大重连5次 + }; + + constructor(topic: string, options: MQTTOptions = {}) { + this.topic = topic; + this.maxReconnectTimes = options.maxReconnectTimes || this.defaultOptions.maxReconnectTimes!; + this.reconnectPeriod = options.reconnectPeriod || this.defaultOptions.reconnectPeriod!; + + // 合并选项 + this.defaultOptions = { ...this.defaultOptions, ...options }; + } + + /** + * 初始化 MQTT 客户端 + * @returns Promise + */ + async init(): Promise { + if (this.client) { + throw new Error('MQTT 客户端已初始化'); + } + + try { + const response = await fetch('/'); + const mqttUrl = response.headers.get('X-Mqtt-Url') || 'ws://192.168.1.68:8083/mqtt'; + + this.client = mqtt.connect(mqttUrl, this.defaultOptions as IClientOptions); + this.setupEventListeners(); + + // 等待连接成功或超时 + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + if (!this.isConnected) { + reject(new Error('MQTT 连接超时')); + } + }, this.defaultOptions.connectTimeout); + + this.client?.on('connect', () => { + clearTimeout(timeout); + this.isConnected = true; + this.reconnectCount = 0; // 连接成功重置重连计数 + resolve(); + }); + + this.client?.on('error', (error) => { + clearTimeout(timeout); + console.error('MQTT 连接错误:', error); + reject(error); + }); + }); + } catch (error) { + console.error('初始化 MQTT 失败:', error); + throw error; + } + } + + /** + * 设置事件监听器 + */ + private setupEventListeners(): void { + if (!this.client) return; + + this.client.on('close', () => { + console.log('MQTT 连接已关闭'); + this.isConnected = false; + }); + + this.client.on('offline', () => { + console.log('MQTT 客户端离线'); + this.isConnected = false; + }); + + this.client.on('reconnect', () => { + console.log(`MQTT 正在尝试重连 (${this.reconnectCount + 1}/${this.maxReconnectTimes})...`); + + // 检查是否超过最大重连次数 + if (this.reconnectCount >= this.maxReconnectTimes) { + console.log('已达到最大重连次数,停止重连'); + this.client?.end(true); + this.client = null; + return; + } + + this.reconnectCount++; + }); + } + + /** + * 订阅主题 + * @param subscribeOptions 可选的订阅选项 + * @returns Promise + */ + async subscribe(subscribeOptions: IClientSubscribeOptions = {}): Promise { + if (!this.client || !this.isConnected) { + throw new Error('MQTT 客户端未连接'); + } + + return new Promise((resolve, reject) => { + this.client?.subscribe( + this.topic, + { qos: this.defaultOptions.qos, ...subscribeOptions }, + (error) => { + if (error) { + console.error('订阅失败:', error); + reject(error); + } else { + console.log('订阅成功'); + resolve(); + } + } + ); + }); + } + + /** + * 取消订阅 + * @returns Promise + */ + async unsubscribe(): Promise { + if (!this.client || !this.isConnected) { + throw new Error('MQTT 客户端未连接'); + } + + return new Promise((resolve, reject) => { + this.client?.unsubscribe(this.topic, (error) => { + if (error) { + console.error('取消订阅失败:', error); + reject(error); + } else { + console.log('取消订阅成功'); + resolve(); + } + }); + }); + } + + /** + * 设置消息回调 + * @param callback 消息回调函数 + */ + onMessage(callback: OnMessageCallback): void { + if (!this.client) { + throw new Error('MQTT 客户端未初始化'); + } + this.client.on('message', callback); + } + + /** + * 发布消息 + * @param message 要发布的消息 + * @param options 发布选项 + * @returns Promise + */ + async publish( + message: string | Buffer, + options: { qos?: 0 | 1 | 2; retain?: boolean } = {} + ): Promise { + if (!this.client || !this.isConnected) { + throw new Error('MQTT 客户端未连接'); + } + + return new Promise((resolve, reject) => { + this.client?.publish( + this.topic, + message, + { qos: this.defaultOptions.qos, ...options }, + (error) => { + if (error) { + console.error('消息发布失败:', error); + reject(error); + } else { + console.log('消息发布成功'); + resolve(); + } + } + ); + }); + } + + /** + * 断开连接 + * @param force 是否强制断开 + */ + disconnect(force: boolean = false): void { + this.isManuallyDisconnected = true; + + if (this.client) { + this.client.end(force, () => { + console.log('MQTT 连接已断开'); + this.isConnected = false; + this.client = null; + }); + } + } + + /** + * 检查连接状态 + * @returns boolean + */ + isConnectedToBroker(): boolean { + return this.isConnected; + } + + /** + * 获取当前重连次数 + * @returns number + */ + getReconnectCount(): number { + return this.reconnectCount; + } + + /** + * 重置重连计数器 + */ + resetReconnectCount(): void { + this.reconnectCount = 0; + } +} + +export default MQTT; \ No newline at end of file diff --git a/src/utils/webSocketClient.ts b/src/utils/webSocketClient.ts index 6deae6d4..b7dbe0d8 100644 --- a/src/utils/webSocketClient.ts +++ b/src/utils/webSocketClient.ts @@ -45,10 +45,10 @@ export default class SocketService { } const response = await fetch('/') - const mqttUrl = response.headers.get('X-Mqtt-Url') + const WebSocketUrl = response.headers.get('X-WebSocket-Url') setTimeout(() => { // ws://192.168.1.69:10407/mgtt/api/pushMessage/ - const url = (mqttUrl || 'ws://192.168.1.68:10407/api/pushMessage/') + id + const url = (WebSocketUrl || 'ws://192.168.1.68:10407/api/pushMessage/') + id this.ws = new WebSocket(url) this.ws.onopen = () => this.handleOpen() diff --git a/src/views/pqs/business/terminal/TerminalManagement/index.vue b/src/views/pqs/business/terminal/TerminalManagement/index.vue index cc757040..4cc79618 100644 --- a/src/views/pqs/business/terminal/TerminalManagement/index.vue +++ b/src/views/pqs/business/terminal/TerminalManagement/index.vue @@ -89,39 +89,18 @@ - + - 投运 - 检修 - 停运 + 投运 + 检修 + 停运 - 中断 - 正常 + 中断 + 正常 diff --git a/src/views/pqs/business/terminal/deviceter/index.vue b/src/views/pqs/business/terminal/deviceter/index.vue index e98ff05d..f25783cc 100644 --- a/src/views/pqs/business/terminal/deviceter/index.vue +++ b/src/views/pqs/business/terminal/deviceter/index.vue @@ -53,23 +53,15 @@ 修改提交 + + + 当前操作节点: + - - - - 当前操作节点: - + {{ index == 0 ? '' : ' > ' }}{{ item }} - - - + @@ -1609,13 +1601,12 @@ placeholder="请输入电网侧变电站" > --> - - + { } }) const plevel = ref(0) +const nodeDataList=ref() +const nodeEventList=ref() const nodeClick = (e: anyObj, data: any) => { + nodeDataList.value = data + nodeEventList.value = e plevel.value = data.data.plevel treeClickCount.value++ if (treeClickCount.value > 2) return @@ -2355,8 +2350,10 @@ const next = async () => { const black = () => { pageStatus.value = 1 busBarIndex.value = '0' - deviceIndex.value = '0'; - lineIndex.value = '0'; + deviceIndex.value = '0' + lineIndex.value = '0' + nodeClick(nodeEventList.value,nodeDataList.value) + } // 确认提交 const onsubmit = () => { @@ -2880,58 +2877,107 @@ const evaluate = (node: any) => { evaluate(node.parent) } } -const selectChanged = (value: any) => { - if (value === '3d68ceef26a579efe2fe0cdc654911b7') { - setTheDefaultValue(10, 0.38 * 1000, 0.38 * 100) - - //750kv - } else if (value === '4cf2d844c47a15a1c16a65b4bbfd1b0e') { - setTheDefaultValue(7000, 750 * 1000, 750 * 100) - - //6kv - } else if (value === '37b81bf8aa0fd54098716da3fc0ee433') { - setTheDefaultValue(100, 6 * 1000, 6 * 100) - - //10kv - } else if (value === 'e3da890104e3c4ae1f005021411a1fd7') { - setTheDefaultValue(100, 10 * 1000, 10 * 100) - - //20kv - } else if (value === '87065e15765e5899114a6d6b9e4fb3cb') { - setTheDefaultValue(200, 20 * 1000, 20 * 100) - - //35kv - } else if (value === '8529cfa11356a0666afd3f9fa4da09a4') { - setTheDefaultValue(250, 35 * 1000, 35 * 100) - - //66kv - } else if (value === '9ce75596a3368da4adf3374b4fc3b619') { - setTheDefaultValue(500, 66 * 1000, 66 * 100) - - //110kv - } else if (value === 'e96d74b79bd50ad0bc00a405246f1e1f') { - setTheDefaultValue(750, 110 * 1000, 110 * 100) - - //220kv - } else if (value === '1b7b58ed8fcc2992b95334eaa9010c41') { - setTheDefaultValue(2000, 220 * 1000, 220 * 100) - - //330kv - } else if (value === 'c1b37350a67f5e229a1f96ace0ad04dc') { - setTheDefaultValue(3000, 330 * 1000, 330 * 100) - - //500kv - } else if (value === '1fa650685c77db1656c70f9db4a2edc6') { - setTheDefaultValue(4500, 500 * 1000, 500 * 100) - - //1000kv - } else if (value === '674cf02fb3fcfd9f99fd786cfca090df') { - setTheDefaultValue(9000, 1000 * 1000, 1000 * 100) - } else { - setTheDefaultValue(10, 10, 10) +const selectChanged = async (value: any) => { + let num: any = voltageLevelArr.filter(item => item.id == value)[0].value + let capacity = 10 + switch (num) { + case '500': + capacity = 4500 + break + case '330': + capacity = 3000 + break + case '220': + capacity = 2000 + break + case '110': + capacity = 750 + break + case '35': + capacity = 259 + break + case '10': + capacity = 100 + break + case '6': + capacity = 100 + break + case '0.38': + capacity = 10 + break + case '20': + capacity = 200 + break + case '66': + capacity = 500 + break + case '750': + capacity = 7000 + break + case '800': + capacity = 7000 + break + case '1000': + capacity = 9000 + break } - setvoltageDev(voltageLevelArr.filter(item => item.id == value)[0].value) + setTimeout(() => { + setTheDefaultValue(capacity, num * 1000, num < 1 ? num * 1000 : 100) + setvoltageDev(num) + }, 0) + + // // 0.38 + // if (value === '3d68ceef26a579efe2fe0cdc654911b7') { + // setTheDefaultValue(10, 0.38 * 1000, 0.38 * 1000) + + // //750kv + // } else if (value === '4cf2d844c47a15a1c16a65b4bbfd1b0e') { + // setTheDefaultValue(7000, 750 * 1000, 100) + + // //6kv + // } else if (value === '37b81bf8aa0fd54098716da3fc0ee433') { + // setTheDefaultValue(100, 6 * 1000, 100) + + // //10kv + // } else if (value === 'e3da890104e3c4ae1f005021411a1fd7') { + // setTheDefaultValue(100, 10 * 1000, 100) + + // //20kv + // } else if (value === '87065e15765e5899114a6d6b9e4fb3cb') { + // setTheDefaultValue(200, 20 * 1000, 100) + + // //35kv + // } else if (value === '8529cfa11356a0666afd3f9fa4da09a4') { + // setTheDefaultValue(250, 35 * 1000, 100) + + // //66kv + // } else if (value === '9ce75596a3368da4adf3374b4fc3b619') { + // setTheDefaultValue(500, 66 * 1000, 100) + + // //110kv + // } else if (value === 'e96d74b79bd50ad0bc00a405246f1e1f') { + // setTheDefaultValue(750, 110 * 1000, 100) + + // //220kv + // } else if (value === '1b7b58ed8fcc2992b95334eaa9010c41') { + // setTheDefaultValue(2000, 220 * 1000, 100) + + // //330kv + // } else if (value === 'c1b37350a67f5e229a1f96ace0ad04dc') { + // setTheDefaultValue(3000, 330 * 1000, 100) + + // //500kv + // } else if (value === '1fa650685c77db1656c70f9db4a2edc6') { + // setTheDefaultValue(4500, 500 * 1000, 100) + + // //1000kv + // } else if (value === '674cf02fb3fcfd9f99fd786cfca090df') { + // setTheDefaultValue(9000, 1000 * 1000, 100) + // } else { + // setTheDefaultValue(10, 1, 1) + // } + // setvoltageDev(voltageLevelArr.filter(item => item.id == value)[0].value) } const setTheDefaultValue = (capacity: number, pt1: number, pt2: number) => { @@ -3005,10 +3051,10 @@ const area = () => { month = '0' + (month + 1) } let day: any = data.getDate() - if (day >= 10) { - day = day + if (day >= 10) { + day = day } else { - day = '0' + (day ) + day = '0' + day } deviceBODetail.value.thisTimeCheck = year + '-' + month + '-' + day deviceBODetail.value.loginTime = year + '-' + month + '-' + day @@ -3087,9 +3133,12 @@ area() } .title { width: 500px; + overflow: hidden; // display: flex; white-space: nowrap; font-weight: bold; +} +.titleScroll { animation: scroll 10s linear infinite; /* 滚动动画 */ } @keyframes scroll { diff --git a/src/views/pqs/business/terminal/userLedger/components/detail.vue b/src/views/pqs/business/terminal/userLedger/components/detail.vue index a88a060d..2b98b3b5 100644 --- a/src/views/pqs/business/terminal/userLedger/components/detail.vue +++ b/src/views/pqs/business/terminal/userLedger/components/detail.vue @@ -114,7 +114,7 @@ label="装机容量(MW)" > - {{ proviteData.ratePower }} + {{ proviteData?.ratePower }} 新增 删除 - + diff --git a/src/views/pqs/harmonicMonitoring/detailed/overLabelDetails/index.vue b/src/views/pqs/harmonicMonitoring/detailed/overLabelDetails/index.vue index 7323fe4a..d9633208 100644 --- a/src/views/pqs/harmonicMonitoring/detailed/overLabelDetails/index.vue +++ b/src/views/pqs/harmonicMonitoring/detailed/overLabelDetails/index.vue @@ -3,12 +3,12 @@ - + diff --git a/src/views/pqs/harmonicMonitoring/monitoringPoint/online/index.vue b/src/views/pqs/harmonicMonitoring/monitoringPoint/online/index.vue index 1d393237..ea3158b4 100644 --- a/src/views/pqs/harmonicMonitoring/monitoringPoint/online/index.vue +++ b/src/views/pqs/harmonicMonitoring/monitoringPoint/online/index.vue @@ -91,7 +91,6 @@ onMounted(() => { }) const handleNodeClick = (data: any, node: any) => { if (data.level === 6) { - console.log('🚀 ~ handleNodeClick ~ data:', data) monitoringPoint.setValue('lineId', data.id) monitoringPoint.setValue('pid', data.pids) monitoringPoint.setValue('lineName', data.alias) diff --git a/src/views/pqs/harmonicMonitoring/monitoringPoint/online/wentaishujufenxi/index.vue b/src/views/pqs/harmonicMonitoring/monitoringPoint/online/wentaishujufenxi/index.vue index ed4b90d5..56dd0684 100644 --- a/src/views/pqs/harmonicMonitoring/monitoringPoint/online/wentaishujufenxi/index.vue +++ b/src/views/pqs/harmonicMonitoring/monitoringPoint/online/wentaishujufenxi/index.vue @@ -167,14 +167,14 @@ const init = () => { if (formData.condition.length == 0) { return ElMessage.warning('请选择指标类型') } - loading.value = true + formData.lineId = checked.value ? monitoringPoint.state.lineIds : [monitoringPoint.state.lineId] formData.searchBeginTime = datePickerRef.value.timeValue[0] formData.searchEndTime = datePickerRef.value.timeValue[1] - if (formData.lineId.length > 3) { return ElMessage.warning('最多只能选择3个监测点') } + loading.value = true let directionValue = formData.condition.findIndex(item => { if (item === '39') { item = '50' @@ -1695,6 +1695,8 @@ const getEcharts = () => { echarts.connect('group') } const conditionChange = () => { + console.log(123) + //判断一个指标时 if (formData.condition.length == 1) { if ( diff --git a/src/views/pqs/voltageSags/Region/thermodynamicDiagram/index.vue b/src/views/pqs/voltageSags/Region/thermodynamicDiagram/index.vue index dd228dba..5415b426 100644 --- a/src/views/pqs/voltageSags/Region/thermodynamicDiagram/index.vue +++ b/src/views/pqs/voltageSags/Region/thermodynamicDiagram/index.vue @@ -15,12 +15,7 @@ - + @@ -125,11 +120,11 @@ const map = (res: any) => { visualMap: { left: 26, bottom: 40, + show: true, - color: ['#ff0000', '#37b70c'], - min: minNum, + color: ['#A52a2a', '#DAA520'], + min: 0, max: maxNum, - calculable: true, textStyle: { color: '#000', fontSize: 12 @@ -140,13 +135,14 @@ const map = (res: any) => { series: [ { mapType: 'nanshan', + type: 'heatmap', top: 'center', left: 'center', width: '65%', height: '95%', // name: 'AQI', - type: 'heatmap', + coordinateSystem: 'geo', blurSize: 40, data: areaData @@ -159,6 +155,7 @@ const map = (res: any) => { // 柱状图数据处理 const histogram = (res: any) => { + echartMapList.value.visualMap.max = Math.max(...res.map((item: any) => item.count)) || 1 echartList.value = { title: { text: '区域暂降次数' diff --git a/src/views/pqs/voltageSags/monitoringPoint/online/index.vue b/src/views/pqs/voltageSags/monitoringPoint/online/index.vue index fea91444..99107b92 100644 --- a/src/views/pqs/voltageSags/monitoringPoint/online/index.vue +++ b/src/views/pqs/voltageSags/monitoringPoint/online/index.vue @@ -32,7 +32,7 @@ import router from '@/router' import { useMonitoringPoint } from '@/stores/monitoringPoint' defineOptions({ - // name: 'Descentsystem/monitoringpoint' + name: 'Descentsystem/monitoringpoint' }) const isReload = ref(false) const navigationRef = ref() diff --git a/src/views/pqs/voltageSags/monitoringPoint/online/navigation/map.vue b/src/views/pqs/voltageSags/monitoringPoint/online/navigation/map.vue index 0f73f4c4..06e0167c 100644 --- a/src/views/pqs/voltageSags/monitoringPoint/online/navigation/map.vue +++ b/src/views/pqs/voltageSags/monitoringPoint/online/navigation/map.vue @@ -37,9 +37,10 @@ 无暂降 + - + + - - + + 全局 - - + + - + @@ -17,22 +17,23 @@ - + - + - + - + - + @@ -40,32 +41,32 @@ 侧边栏 - + - + - + - + - + 顶栏 - + - + - + { + if (!value || !value[0]) { + callback(new Error('请选择组件主题色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + tableHeaderBackground: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择表格标题栏背景颜色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + tableHeaderColor: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择表格标题栏文字颜色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + tableCurrent: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择表格激活栏颜色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + menuBackground: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择侧边菜单栏背景色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + menuColor: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择侧边菜单文字颜色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + menuActiveBackground: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择侧边菜单激活项背景色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + menuActiveColor: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择侧边菜单激活项文字色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + menuTopBarBackground: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择侧边菜单顶栏背景色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + headerBarBackground: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择顶栏背景色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + headerBarTabColor: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + if (!value || !value[0]) { + callback(new Error('请选择顶栏文字色')) + } else { + callback() + } + }, + trigger: 'change' + } + ], + logoFile: [ + { + required: true, + validator: (rule: any, value: any, callback: any) => { + // 编辑时如果已有图片则不校验 + if (title.value === '修改主题' && logoFile.url) { + callback() + } else if (!value && !logoFile.url) { + callback(new Error('请上传顶栏logo')) + } else { + callback() + } + }, + trigger: 'change' + } + ] +}) const logoFile = reactive({ url: '', raw: '' }) +const formRef = ref() const open = (e: any) => { title.value = e.text @@ -167,50 +333,54 @@ const open = (e: any) => { } // 确定主题 const onSubmit = () => { - configStore.value.faviconFile = configStore.value.logoFile - configStore.value.color = configStore.value.elementUiPrimary[0] - let form = new FormData() - for (let k in configStore.value) { - if ( - k == 'logoFile' || - k == 'faviconFile' || - k == 'name' || - k == 'color' || - k == 'remark' || - k == 'mainAnimation' || - k == 'id' - ) { - form.append(k, configStore.value[k]) - } else if (k == 'logoUrl' || k == 'faviconUrl') { - if (configStore.value.logoFile == null) { - let str = configStore.value[k].match(/base64,([^"]+)/)[1] - let bin = atob(str) - let arr = new Array(bin.length) - for (let i = 0; i < bin.length; i++) { - arr[i] = bin.charCodeAt(i) + formRef.value.validate((valid: boolean) => { + if (valid) { + configStore.value.faviconFile = configStore.value.logoFile + configStore.value.color = configStore.value.elementUiPrimary[0] + let form = new FormData() + for (let k in configStore.value) { + if ( + k == 'logoFile' || + k == 'faviconFile' || + k == 'name' || + k == 'color' || + k == 'remark' || + k == 'mainAnimation' || + k == 'id' + ) { + form.append(k, configStore.value[k]) + } else if (k == 'logoUrl' || k == 'faviconUrl') { + if (configStore.value.logoFile == null) { + let str = configStore.value[k].match(/base64,([^"]+)/)[1] + let bin = atob(str) + let arr = new Array(bin.length) + for (let i = 0; i < bin.length; i++) { + arr[i] = bin.charCodeAt(i) + } + let b = new Uint8Array(arr) + const blob = new Blob([b], { type: 'image/jpeg' }) + form.append('faviconFile', blob) + form.append('logoFile', blob) + } + } else { + form.append(k, JSON.stringify(configStore.value[k])) } - let b = new Uint8Array(arr) - const blob = new Blob([b], { type: 'image/jpeg' }) - form.append('faviconFile', blob) - form.append('logoFile', blob) } - } else { - form.append(k, JSON.stringify(configStore.value[k])) - } - } - if (title.value == '新增主题') { - addTheme(form).then(res => { - ElMessage.success('新增成功') - Cancel() - }) - } - if (title.value == '修改主题') { - updateTheme(form).then(res => { - ElMessage.success('修改成功') - Cancel() - }) - } + if (title.value == '新增主题') { + addTheme(form).then(res => { + ElMessage.success('新增成功') + Cancel() + }) + } + if (title.value == '修改主题') { + updateTheme(form).then(res => { + ElMessage.success('修改成功') + Cancel() + }) + } + } + }) } // 取消 const Cancel = () => {