From 4e66592cf8ed50c62e93b173f1ec2244181c69f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=89=E6=B5=A9=E8=8C=B9?= Date: Fri, 10 Oct 2025 10:58:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E6=B8=A9=E6=B9=BF=E5=BA=A6=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97=E3=80=81=E6=B8=A9?= =?UTF-8?q?=E6=B9=BF=E5=BA=A6=E5=90=8C=E6=AD=A5=E5=90=8E=E5=8F=B0=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=9F=A5=E8=AF=A2=E6=97=A5=E5=BF=97=E3=80=81?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E8=A7=86=E9=A2=91=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/AlarmRecord.vue | 41 ++- src/components/EzvizVideoPlayerSimple.vue | 378 +++++++++++++++++----- src/pages/environment/index.vue | 138 ++++++-- src/pages/parameter/index.vue | 30 +- src/pages/visual/index.vue | 28 ++ src/static/html/ezviz-iframe.html | 249 +++++++++++++- src/utils/mqttDataManager.js | 11 +- src/utils/sendMqtt.js | 4 +- 8 files changed, 716 insertions(+), 163 deletions(-) diff --git a/src/components/AlarmRecord.vue b/src/components/AlarmRecord.vue index 948be1c..6be29b3 100644 --- a/src/components/AlarmRecord.vue +++ b/src/components/AlarmRecord.vue @@ -24,7 +24,7 @@ 内容 种类 时间 - 级别 + @@ -56,9 +56,9 @@ {{ alarm.type }} {{ alarm.time }} - + @@ -143,7 +143,6 @@ const mqttAlarmService = { // 获取历史报警记录(分页) getHistoryAlarms: async (page = 0, size = 20, isLoadMore = false) => { - console.log(`获取历史报警记录,页码:${page}, 每页:${size}条`); try { if (!isLoadMore) { isLoading.value = true; @@ -158,8 +157,6 @@ const mqttAlarmService = { size: size }); - console.log('📊 获取告警数据响应:', response); - // 处理响应数据 if (response && response.data) { const newAlarms = response.data.map(item => ({ @@ -188,7 +185,6 @@ const mqttAlarmService = { await createQueryEvent('success', newAlarms.length); } } else { - console.warn('⚠️ 响应数据格式异常:', response); if (!isLoadMore) { alarmList.value = []; } @@ -447,23 +443,23 @@ const stopRealtimeAlarm = () => { // 创建查询事件 const createQueryEvent = async (status, dataCount) => { - try { - const currentTime = formatDateTime(new Date().toISOString()) - const queryEvent = { - eventType: "报警记录查询", - eventTime: currentTime, - status: getEventStatus(status), - description: getEventDescription(status, dataCount), - deviceId: "ALARM_QUERY_001" - } + // try { + // const currentTime = formatDateTime(new Date().toISOString()) + // const queryEvent = { + // eventType: "报警记录查询", + // eventTime: currentTime, + // status: getEventStatus(status), + // description: getEventDescription(status, dataCount), + // deviceId: "ALARM_QUERY_001" + // } - console.log('📤 提交报警查询事件:', queryEvent) - const response = await eventApi.create(queryEvent) - console.log('✅ 报警查询事件创建成功:', response) + // console.log('📤 提交报警查询事件:', queryEvent) + // const response = await eventApi.create(queryEvent) + // console.log('✅ 报警查询事件创建成功:', response) - } catch (error) { - console.error('❌ 报警查询事件创建失败:', error) - } + // } catch (error) { + // console.error('❌ 报警查询事件创建失败:', error) + // } }; // 获取事件状态 @@ -488,7 +484,6 @@ const getEventDescription = (status, dataCount) => { // 刷新数据方法 const refreshData = async () => { - console.log('🔄 刷新报警记录数据') try { // 重置分页状态 currentPage.value = 0; diff --git a/src/components/EzvizVideoPlayerSimple.vue b/src/components/EzvizVideoPlayerSimple.vue index d44dba2..df6887c 100644 --- a/src/components/EzvizVideoPlayerSimple.vue +++ b/src/components/EzvizVideoPlayerSimple.vue @@ -29,27 +29,20 @@ - + - - - {{ isPlaying ? '⏸ 暂停' : '▶ 播放' }} - - - 🔄 刷新 - - + - + - - - + + + {{ isPlaying ? '⏸ 暂停' : '▶ 播放' }} + + + 🔄 刷新 + @@ -134,6 +127,7 @@ export default { const url = encodeURIComponent(config.play_url) this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}` console.log('[简单播放器] APP平台 - 使用本地HTML文件') + console.log('[简单播放器] APP平台 - webviewUrl:', this.webviewUrl) // #endif // #ifdef H5 @@ -145,14 +139,21 @@ export default { '&height=100%' + '&autoplay=1' + '&audio=1' + - '&controls=1' - console.log('[简单播放器] H5平台 - 直接使用萤石云iframe') + '&controls=1'; + console.log('[简单播放器] H5平台 - 直接使用萤石云iframe', this.iframeUrl) // #endif setTimeout(() => { if (this.loading) { this.loading = false this.status = '播放器已加载' + console.log('[简单播放器] 加载完成,显示控制按钮') + console.log('[简单播放器] 当前状态:', { + loading: this.loading, + webviewUrl: !!this.webviewUrl, + iframeUrl: !!this.iframeUrl, + platform: this.platform + }) } }, 3000) @@ -193,55 +194,102 @@ export default { }, // 切换播放/暂停 + // 统一的播放状态切换逻辑 togglePlay() { console.log('[简单播放器] 切换播放状态:', this.isPlaying ? '暂停' : '播放') - // 通过重新加载URL来实现播放/暂停 - // 因为iframe播放器不支持直接控制,所以采用重新加载的方式 - if (this.isPlaying) { - // 暂停:清空URL + // 防止重复点击和加载中操作 + if (this.loading) { + console.log('[简单播放器] 播放器加载中,忽略操作') + return + } + + const newPlayState = !this.isPlaying + + // 统一的状态更新逻辑 + if (newPlayState) { + this.startPlayback() + } else { + this.pausePlayback() + } + + // 返回新的播放状态 + return this.isPlaying + }, + + // 统一的开始播放逻辑 + startPlayback() { + console.log('[简单播放器] 开始播放') + + if (!this.config) { + console.error('[简单播放器] 配置信息不存在,无法播放') + return + } + + try { + // 设置播放URL - 两个平台使用相同的逻辑 // #ifdef APP-PLUS - this.webviewUrl = '' - // #endif - // #ifdef H5 - this.iframeUrl = '' + const token = encodeURIComponent(this.config.accessToken) + const url = encodeURIComponent(this.config.play_url) + this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}` + console.log('[简单播放器] APP平台 - 设置webviewUrl') // #endif + // #ifdef H5 + this.iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' + + 'url=' + encodeURIComponent(this.config.play_url) + + '&accessToken=' + encodeURIComponent(this.config.accessToken) + + '&width=100%' + + '&height=100%' + + '&autoplay=1' + + '&audio=1' + + '&controls=1' + console.log('[简单播放器] H5平台 - 设置iframeUrl', this.iframeUrl) + // #endif + + // 统一更新状态 + this.isPlaying = true + this.status = '播放中' + this.error = false + + // 触发状态变化事件 + this.$emit('playStateChange', true) + console.log('[简单播放器] 播放状态已更新为:播放中') + + } catch (error) { + console.error('[简单播放器] 开始播放失败:', error) + this.error = true + this.errorText = '播放失败: ' + error.message + } + }, + + // 统一的暂停播放逻辑 + pausePlayback() { + console.log('[简单播放器] 暂停播放') + + try { + // 清空播放URL - 两个平台使用相同的逻辑 + // #ifdef APP-PLUS + this.webviewUrl = '' + console.log('[简单播放器] APP平台 - 清空webviewUrl') + // #endif + + // #ifdef H5 + this.iframeUrl = '' + console.log('[简单播放器] H5平台 - 清空iframeUrl') + // #endif + + // 统一更新状态 this.isPlaying = false this.status = '已暂停' // 触发状态变化事件 this.$emit('playStateChange', false) - } else { - // 播放:重新设置URL - if (this.config) { - // #ifdef APP-PLUS - const token = encodeURIComponent(this.config.accessToken) - const url = encodeURIComponent(this.config.play_url) - this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}` - // #endif - - // #ifdef H5 - this.iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' + - 'url=' + encodeURIComponent(this.config.play_url) + - '&accessToken=' + encodeURIComponent(this.config.accessToken) + - '&width=100%' + - '&height=100%' + - '&autoplay=1' + - '&audio=1' + - '&controls=1' - // #endif - - this.isPlaying = true - this.status = '播放中' - - // 触发状态变化事件 - this.$emit('playStateChange', true) - } + console.log('[简单播放器] 播放状态已更新为:已暂停') + + } catch (error) { + console.error('[简单播放器] 暂停播放失败:', error) } - - // 返回新的播放状态 - return this.isPlaying }, // 获取当前播放状态 @@ -249,18 +297,89 @@ export default { return this.isPlaying }, - // 刷新播放器 + // 统一的刷新播放器逻辑 refresh() { console.log('[简单播放器] 刷新播放器') - if (this.config) { + if (!this.config) { + console.error('[简单播放器] 配置信息不存在,无法刷新') + uni.showToast({ + title: '配置信息不存在', + icon: 'error', + duration: 2000 + }) + return + } + + try { + // 显示刷新提示 uni.showToast({ title: '正在刷新...', icon: 'loading', duration: 1000 }) - // 先清空再重新加载 + // 重置播放器状态 + this.error = false + this.loading = true + this.loadingText = '重新加载中...' + + // 先暂停播放 + this.pausePlayback() + + // 延迟重新开始播放,确保清空操作完成 + setTimeout(() => { + try { + // 重新开始播放 + this.startPlayback() + + // 显示成功提示 + uni.showToast({ + title: '刷新成功', + icon: 'success', + duration: 1500 + }) + + // 重置加载状态 + setTimeout(() => { + this.loading = false + this.loadingText = '加载中...' + }, 1000) + + } catch (error) { + console.error('[简单播放器] 重新播放失败:', error) + this.loading = false + this.error = true + this.errorText = '刷新失败: ' + error.message + + uni.showToast({ + title: '刷新失败', + icon: 'error', + duration: 2000 + }) + } + }, 500) + + } catch (error) { + console.error('[简单播放器] 刷新播放器失败:', error) + this.loading = false + this.error = true + this.errorText = '刷新失败: ' + error.message + + uni.showToast({ + title: '刷新失败', + icon: 'error', + duration: 2000 + }) + } + }, + + // 停止播放器(页面关闭时调用) + stopPlayer() { + console.log('[简单播放器] 停止播放器') + + try { + // 清空播放URL,停止播放 // #ifdef APP-PLUS this.webviewUrl = '' // #endif @@ -268,33 +387,18 @@ export default { this.iframeUrl = '' // #endif - setTimeout(() => { - // #ifdef APP-PLUS - const token = encodeURIComponent(this.config.accessToken) - const url = encodeURIComponent(this.config.play_url) - this.webviewUrl = `/static/html/ezviz-iframe.html?accessToken=${token}&playUrl=${url}` - // #endif - - // #ifdef H5 - this.iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' + - 'url=' + encodeURIComponent(this.config.play_url) + - '&accessToken=' + encodeURIComponent(this.config.accessToken) + - '&width=100%' + - '&height=100%' + - '&autoplay=1' + - '&audio=1' + - '&controls=1' - // #endif - - this.isPlaying = true - this.status = '播放中' - - uni.showToast({ - title: '刷新成功', - icon: 'success', - duration: 1500 - }) - }, 500) + // 重置状态 + this.isPlaying = false + this.status = '已停止' + this.loading = false + this.error = false + + // 触发状态变化事件 + this.$emit('playStateChange', false) + + console.log('[简单播放器] 播放器已停止') + } catch (error) { + console.error('[简单播放器] 停止播放器失败:', error) } } } @@ -473,5 +577,107 @@ export default { .refresh-btn:active { background: rgba(25, 118, 210, 1); } + +/* 统一的控制按钮样式 - APP平台使用 cover-view */ +.control-buttons-cover { + position: fixed; + top: 50%; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 20rpx; + z-index: 999; +} + +.control-btn-cover { + background: rgba(0, 0, 0, 0.75); + border: 2rpx solid rgba(255, 255, 255, 0.6); + border-radius: 40rpx; + padding: 16rpx 32rpx; + min-width: 140rpx; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; +} + +.play-btn-cover { + background: rgba(46, 125, 50, 0.85); + border-color: rgba(76, 175, 80, 0.9); +} + +.refresh-btn-cover { + background: rgba(25, 118, 210, 0.85); + border-color: rgba(33, 150, 243, 0.9); +} + +.btn-text { + color: white; + font-size: 24rpx; + font-weight: 600; + text-align: center; +} + +/* 统一的控制按钮样式 - H5平台使用 view */ +.control-buttons-unified { + position: fixed; + top: 50%;; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 20rpx; + z-index: 999; +} + +.control-btn-unified { + background: rgba(0, 0, 0, 0.75); + border: 2rpx solid rgba(255, 255, 255, 0.6); + border-radius: 40rpx; + padding: 16rpx 32rpx; + min-width: 140rpx; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.3s ease; + user-select: none; +} + +.control-btn-unified:hover { + transform: scale(1.05); + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3); +} + +.control-btn-unified:active { + transform: scale(0.95); +} + +.play-btn-unified { + background: rgba(46, 125, 50, 0.85); + border-color: rgba(76, 175, 80, 0.9); +} + +.play-btn-unified:hover { + background: rgba(46, 125, 50, 0.95); + border-color: rgba(76, 175, 80, 1); +} + +.refresh-btn-unified { + background: rgba(25, 118, 210, 0.85); + border-color: rgba(33, 150, 243, 0.9); +} + +.refresh-btn-unified:hover { + background: rgba(25, 118, 210, 0.95); + border-color: rgba(33, 150, 243, 1); +} + +.btn-text-unified { + color: white; + font-size: 24rpx; + font-weight: 600; + text-align: center; + pointer-events: none; +} diff --git a/src/pages/environment/index.vue b/src/pages/environment/index.vue index cc2b553..9081772 100644 --- a/src/pages/environment/index.vue +++ b/src/pages/environment/index.vue @@ -337,12 +337,20 @@ export default { onShow() { console.log('📱 环境参数页面显示,触发页面更新'); this.init(); + // 重新启动定时器 + this.startDataFetching(); // // 只有在非首次显示时才重新获取最新空调温度 // if (this.hasCreatedStartupEvent) { // this.init(); // } }, + onHide() { + console.log('📱 环境参数页面隐藏,停止定时器'); + // 页面隐藏时停止定时器 + this.stopDataFetching(); + }, onUnload() { + console.log('📱 环境参数页面卸载,清理所有资源'); // 页面卸载时移除监听器 if (this.dataUpdateHandler) { mqttDataManager.removeListener('dataUpdate', this.dataUpdateHandler) @@ -356,10 +364,8 @@ export default { clearInterval(this.debugInterval) } - // 清理数据获取定时器 - if (this.dataFetchInterval) { - clearInterval(this.dataFetchInterval) - } + // 停止数据获取定时器 + this.stopDataFetching() }, methods: { init() { @@ -368,11 +374,10 @@ export default { // 获取最新温湿度数据 this.getLatestEnvironmentData() // 首次进入系统时创建启动事件 - this.createStartupEventIfNeeded() + // this.createStartupEventIfNeeded() // 获取温湿度区间设置 this.loadWsdSettings() - // 启动定时获取环境数据 - this.startDataFetching() + // 注意:定时器在 onShow 中启动,避免重复启动 }, // 首次进入系统时创建启动事件 async createStartupEventIfNeeded() { @@ -582,12 +587,18 @@ export default { clearInterval(this.dataFetchInterval) } - // 每3秒获取一次最新环境数据 + // 每5秒获取一次最新环境数据 this.dataFetchInterval = setInterval(() => { this.getLatestEnvironmentData() }, 5000) - - console.log('🔄 已启动环境数据定时获取,间隔3秒') + }, + + // 停止定时获取环境数据 + stopDataFetching() { + if (this.dataFetchInterval) { + clearInterval(this.dataFetchInterval) + this.dataFetchInterval = null + } }, // 初始化MQTT监听 @@ -660,8 +671,6 @@ export default { // 检查MQTT空调数据的报警条件 checkAlerts(mqttData) { const currentTime = this.formatDateTime(new Date()) - console.log('====MQTT空调数据报警检查', mqttData) - // 只处理空调AC设备的数据 if (mqttData.deviceType === 'AC') { // 空调故障报警:acFaultStatus为1 @@ -684,8 +693,6 @@ export default { // 检查从接口获取的数据的报警条件 checkAlertsFromApiData(apiData) { const currentTime = this.formatDateTime(new Date()) - console.log('====API数据报警检查', apiData) - const { temperature, humidity, pm25 } = apiData // 1. 温度报警:使用环境控制设置的区间 @@ -761,10 +768,7 @@ export default { // 记录报警到控制台并调用创建告警接口 async logAlert(alert) { - console.log('🚨 报警触发:', JSON.stringify(alert, null, 2)) - // 调用创建告警接口 try { - console.log('📤 正在创建告警记录...') await alertApi.create(alert) } catch (error) { console.error('❌ 告警记录创建失败:', error) @@ -774,9 +778,12 @@ export default { // 降低目标温度 decreaseTemperature() { if (this.targetTemperature > 16) { + const oldTemp = this.targetTemperature this.targetTemperature-- console.log('目标温度降低至:', this.targetTemperature + '°C') this.showTemperatureChangeToast() + // 记录温度调节日志 + this.logTemperatureAdjustment('降低', oldTemp, this.targetTemperature) } else { uni.showToast({ title: '温度不能低于16°C', @@ -807,8 +814,11 @@ export default { if (this.tempValidationMessage === '') { // 如果没有验证错误,更新目标温度 if (!isNaN(value)) { + const oldTemp = this.targetTemperature this.targetTemperature = value this.showTemperatureChangeToast() + // 记录温度调节日志 + this.logTemperatureAdjustment('设置', oldTemp, this.targetTemperature) } this.tempInputValue = '' } else { @@ -859,9 +869,12 @@ export default { // 提高目标温度 increaseTemperature() { if (this.targetTemperature < 50) { + const oldTemp = this.targetTemperature this.targetTemperature++ console.log('目标温度提高至:', this.targetTemperature + '°C') this.showTemperatureChangeToast() + // 记录温度调节日志 + this.logTemperatureAdjustment('提高', oldTemp, this.targetTemperature) } else { uni.showToast({ title: '温度不能高于50°C', @@ -873,9 +886,12 @@ export default { // 降低目标湿度 decreaseHumidity() { if (this.targetHumidity > 30) { + const oldHumidity = this.targetHumidity this.targetHumidity-- console.log('目标湿度降低至:', this.targetHumidity + '%') this.showHumidityChangeToast() + // 记录湿度调节日志 + this.logHumidityAdjustment('降低', oldHumidity, this.targetHumidity) } else { uni.showToast({ title: '湿度不能低于30%', @@ -887,9 +903,12 @@ export default { // 提高目标湿度 increaseHumidity() { if (this.targetHumidity < 80) { + const oldHumidity = this.targetHumidity this.targetHumidity++ console.log('目标湿度提高至:', this.targetHumidity + '%') this.showHumidityChangeToast() + // 记录湿度调节日志 + this.logHumidityAdjustment('提高', oldHumidity, this.targetHumidity) } else { uni.showToast({ title: '湿度不能高于80%', @@ -920,8 +939,11 @@ export default { if (this.humidityValidationMessage === '') { // 如果没有验证错误,更新目标湿度 if (!isNaN(value)) { + const oldHumidity = this.targetHumidity this.targetHumidity = value this.showHumidityChangeToast() + // 记录湿度调节日志 + this.logHumidityAdjustment('设置', oldHumidity, this.targetHumidity) } this.humidityInputValue = '' } else { @@ -1002,14 +1024,14 @@ export default { // 发送温度参数 - 使用BSQWD作为TagName(与接收数据保持一致) const temperatureData = { "TagValue": this.targetTemperature, - "TagName": "JS_COD", // 使用与接收数据一致的TagName + "TagName": "SDWD", // 使用与接收数据一致的TagName "method": "setValue" } // 发送湿度参数 - 根据文档WSD设备湿度使用SD const humidityData = { "TagValue": this.targetHumidity, - "TagName": "JS_SD", // 使用与WSD设备湿度一致的TagName + "TagName": "SDSD", // 使用与WSD设备湿度一致的TagName "method": "setValue" } @@ -1109,16 +1131,83 @@ export default { eventType: `空调${operation}`, eventTime: currentTime, status: "已完成", - description: `用户手动执行空调${operation}操作`, + description: `用户手动执行空调${operation}操作,当前温度:${this.temperature}°C,目标温度:${this.targetTemperature}°C,空调状态:${this.acStatusList[this.acStatus]}`, deviceId: "AC_001" } - console.log(`📝 记录空调${operation}日志:`, logEvent) - // const response = await eventApi.create(logEvent) - console.log(`✅ 空调${operation}日志记录成功:`, response) + const response = await eventApi.create(logEvent) + + // 显示日志记录成功提示 + uni.showToast({ + title: `操作日志已保存`, + icon: 'success', + duration: 1000 + }) } catch (error) { console.error(`❌ 空调${operation}日志记录失败:`, error) // 日志记录失败不影响主要功能,只记录错误 + uni.showToast({ + title: `日志保存失败`, + icon: 'none', + duration: 1000 + }) + } + }, + + // 记录温度调节日志 + async logTemperatureAdjustment(action, oldTemp, newTemp) { + try { + const currentTime = this.formatDateTime(new Date()) + const logEvent = { + eventType: `空调目标温度${action}`, + eventTime: currentTime, + status: "已完成", + description: `用户手动${action}空调目标温度,从${oldTemp}°C调整到${newTemp}°C,当前环境温度:${this.temperature}°C,空调状态:${this.acStatusList[this.acStatus]}`, + deviceId: "AC_001" + } + + const response = await eventApi.create(logEvent) + } catch (error) { + console.error(`❌ 温度${action}日志记录失败:`, error) + // 日志记录失败不影响主要功能,只记录错误 + } + }, + + // 记录湿度调节日志 + async logHumidityAdjustment(action, oldHumidity, newHumidity) { + try { + const currentTime = this.formatDateTime(new Date()) + const logEvent = { + eventType: `空调目标湿度${action}`, + eventTime: currentTime, + status: "已完成", + description: `用户手动${action}空调目标湿度,从${oldHumidity}%调整到${newHumidity}%,当前环境湿度:${this.humidity}%,空调状态:${this.acStatusList[this.acStatus]}`, + deviceId: "AC_001" + } + + const response = await eventApi.create(logEvent) + } catch (error) { + console.error(`❌ 湿度${action}日志记录失败:`, error) + // 日志记录失败不影响主要功能,只记录错误 + } + }, + + // 记录参数设定保存日志 + async logSettingsSave() { + try { + const currentTime = this.formatDateTime(new Date()) + const logEvent = { + eventType: "环境控制范围更新", + eventTime: currentTime, + status: "已完成", + description: `用户修改温湿度控制范围:温度范围${this.tempSettings.min}°C-${this.tempSettings.max}°C,湿度范围${this.humiditySettings.min}%-${this.humiditySettings.max}%,当前环境温度:${this.temperature}°C,当前环境湿度:${this.humidity}%,空调状态:${this.acStatusList[this.acStatus]}`, + deviceId: "WSD_001" + } + + const response = await eventApi.create(logEvent) + } catch (error) { + console.error(`❌ 参数设定保存日志记录失败:`, error) + // 日志记录失败不影响主要功能,只记录错误 } }, @@ -1236,6 +1325,9 @@ export default { // 关闭弹窗 this.closeSettingsModal() + // 记录参数设定保存日志 + await this.logSettingsSave() + // 显示保存成功提示 uni.showToast({ title: '参数设置已保存', diff --git a/src/pages/parameter/index.vue b/src/pages/parameter/index.vue index a7196f3..25f5200 100644 --- a/src/pages/parameter/index.vue +++ b/src/pages/parameter/index.vue @@ -938,23 +938,23 @@ export default { // 创建查询事件 async createQueryEvent(status, dataCount) { - try { - const currentTime = this.formatDateTime(new Date()) - const queryEvent = { - eventType: "参数记录查询", - eventTime: currentTime, - status: this.getEventStatus(status), - description: this.getEventDescription(status, dataCount), - deviceId: "PARAMETER_QUERY_001" - } + // try { + // const currentTime = this.formatDateTime(new Date()) + // const queryEvent = { + // eventType: "参数记录查询", + // eventTime: currentTime, + // status: this.getEventStatus(status), + // description: this.getEventDescription(status, dataCount), + // deviceId: "PARAMETER_QUERY_001" + // } - console.log('📤 提交查询事件:', queryEvent) - const response = await eventApi.create(queryEvent) - console.log('✅ 查询事件创建成功:', response) + // console.log('📤 提交查询事件:', queryEvent) + // const response = await eventApi.create(queryEvent) + // console.log('✅ 查询事件创建成功:', response) - } catch (error) { - console.error('❌ 查询事件创建失败:', error) - } + // } catch (error) { + // console.error('❌ 查询事件创建失败:', error) + // } }, // 获取事件状态 diff --git a/src/pages/visual/index.vue b/src/pages/visual/index.vue index f3ed819..a677763 100644 --- a/src/pages/visual/index.vue +++ b/src/pages/visual/index.vue @@ -98,6 +98,14 @@ export default { // 可以在这里添加重新连接摄像头等逻辑 this.getVideoData() }, + onUnload() { + console.log('📱 视觉监控页面卸载,停止播放器') + this.stopVideoPlayer() + }, + onHide() { + console.log('📱 视觉监控页面隐藏,停止播放器') + this.stopVideoPlayer() + }, methods: { // 切换调试模式 toggleDebug() { @@ -222,6 +230,26 @@ export default { duration: 3000 }) } + }, + + // 停止视频播放器 + stopVideoPlayer() { + try { + // 检查播放器组件是否存在 + if (this.$refs.playerVideoRef) { + // 调用播放器组件的停止方法 + this.$refs.playerVideoRef.stopPlayer() + } else { + console.log('⚠️ 播放器组件不存在,无需停止') + } + + // 重置页面状态 + this.ezstate = false + this.videoLoaded = false + this.isPlaying = false + } catch (error) { + console.error('❌ 停止视频播放器失败:', error) + } } } } diff --git a/src/static/html/ezviz-iframe.html b/src/static/html/ezviz-iframe.html index ebb4851..5a43f23 100644 --- a/src/static/html/ezviz-iframe.html +++ b/src/static/html/ezviz-iframe.html @@ -27,6 +27,69 @@ object-fit: contain; /* 保持视频比例,不变形 */ } + /* 简化的控制按钮样式 */ + .control-buttons { + position: fixed; + bottom: 30px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 16px; + z-index: 999; + pointer-events: auto; + } + + .control-btn { + background: rgba(0, 0, 0, 0.7); + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 25px; + padding: 12px 20px; + min-width: 100px; + min-height: 44px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + user-select: none; + color: white; + font-size: 14px; + font-weight: 500; + text-align: center; + } + + .control-btn:active { + background: rgba(0, 0, 0, 0.8); + } + + .play-btn { + background: rgba(76, 175, 80, 0.8); + border-color: rgba(76, 175, 80, 0.9); + } + + .play-btn:active { + background: rgba(76, 175, 80, 0.9); + } + + .refresh-btn { + background: rgba(33, 150, 243, 0.8); + border-color: rgba(33, 150, 243, 0.9); + } + + .refresh-btn:active { + background: rgba(33, 150, 243, 0.9); + } + + /* 按钮图标样式 */ + .btn-icon { + margin-right: 6px; + font-size: 16px; + display: inline-block; + } + + .btn-text { + font-weight: 500; + } + .loading { position: absolute; top: 50%; @@ -56,11 +119,56 @@ @keyframes spin { to { transform: rotate(360deg); } } + + /* 简化的暂停占位符样式 */ + .pause-placeholder { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 50%; + background: #000000; + display: none; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 5; + } + + .pause-content { + text-align: center; + color: white; + } + + .pause-title { + font-size: 18px; + font-weight: 400; + color: white; + }
正在加载播放器...
+ + +
+
+
监控已暂停
+
+
+ + + diff --git a/src/utils/mqttDataManager.js b/src/utils/mqttDataManager.js index 6b45e27..901f166 100644 --- a/src/utils/mqttDataManager.js +++ b/src/utils/mqttDataManager.js @@ -69,7 +69,6 @@ class MqttDataManager { // 检查数据是否为数组 if (Array.isArray(data)) { // console.log('📋 收到数组数据,长度:', data.length) - // 遍历数组中的每个设备数据 data.forEach((deviceData, index) => { // console.log(`📦 处理设备数据[${index}]:`, deviceData) @@ -97,13 +96,8 @@ class MqttDataManager { const deviceType = deviceData.Device const deviceDataContent = deviceData.Data const timestamp = deviceData.timestamp || Math.floor(Date.now() / 1000) - - // console.log(`🔍 处理设备类型: ${deviceType}`) - // console.log('设备数据:', deviceDataContent) - // console.log('时间戳:', timestamp) - // 处理所有设备类型的数据 - console.log(`✅ 处理设备类型: ${deviceType}`) + // console.log(`✅ 处理设备类型: ${deviceType}`) this.processAllDeviceData(deviceType, deviceDataContent, timestamp) } catch (error) { console.error('❌ 处理设备数据失败:', error) @@ -113,9 +107,6 @@ class MqttDataManager { // 处理所有设备类型的数据 processAllDeviceData(deviceType, data, timestamp) { try { - console.log(`🌡️ ${deviceType}设备数据解析:`) - console.log('设备数据:', data) - // 构建基础解析数据 const parsedData = { deviceType, diff --git a/src/utils/sendMqtt.js b/src/utils/sendMqtt.js index 21aa8e0..99d7e7d 100644 --- a/src/utils/sendMqtt.js +++ b/src/utils/sendMqtt.js @@ -136,13 +136,13 @@ const initEventHandleMqtt = (topicUrl) => { // 获取信息 const mqttData = JSON.parse(message.toString()); - console.log('📋 解析后的数据:', mqttData); + // console.log('📋 解析后的数据:', mqttData); // 如果是数组,打印数组信息 if (Array.isArray(mqttData)) { mqttData.forEach((item, index) => { if (item.Device) { - console.log(`🔍 设备类型[${index}]: ${item.Device}`); + // console.log(`🔍 设备类型[${index}]: ${item.Device}`); } }); }