From 3352e9ab822ccbdb37789eb4e8c790f2e28bf2ce Mon Sep 17 00:00:00 2001 From: George Date: Sun, 23 Aug 2026 18:09:21 +0800 Subject: [PATCH] =?UTF-8?q?20260823:H5=E4=BF=AE=E5=A4=8D=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=BD=91=E5=85=B3=E8=AE=BE=E5=A4=87=E8=AE=A1=E7=AE=97=E7=89=A9?= =?UTF-8?q?=E7=90=86=E9=87=8Fbug&=E9=A6=96=E9=A1=B5=E4=B8=80=E6=8A=8A?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=89=80=E6=9C=89=E7=9A=84=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yack-app/apis/modules/deviceLog.js | 9 ++ yack-app/pages/tabBar/home/index.vue | 3 +- .../pagesA/home/device/statistic/history.vue | 143 +++++++++++++++--- 3 files changed, 131 insertions(+), 24 deletions(-) diff --git a/yack-app/apis/modules/deviceLog.js b/yack-app/apis/modules/deviceLog.js index bf46db17..ccdcec6a 100644 --- a/yack-app/apis/modules/deviceLog.js +++ b/yack-app/apis/modules/deviceLog.js @@ -50,6 +50,15 @@ export function getSubDeviceComparativeHistory (data) { }) } +// 查询网关计算物模型历史数据(查询时按公式计算) +export function getDeviceHistoryCalculated (data) { + return http.request({ + url: '/data/center/deviceHistoryCalculated', + method: 'post', + data: data, + }) +} + // 查询设备日志详细 export function getDeviceLog (logId) { return http.request({ diff --git a/yack-app/pages/tabBar/home/index.vue b/yack-app/pages/tabBar/home/index.vue index 8f17acea..90122b0c 100644 --- a/yack-app/pages/tabBar/home/index.vue +++ b/yack-app/pages/tabBar/home/index.vue @@ -365,7 +365,8 @@ // 获取分组列表 getGroups () { getGroupList({ - userId: this.profile.userId + userId: this.profile.userId, + pageSize: 99 // 一次性获取全部 }).then(res => { if (res.code === 200) { this.groupList = [{ diff --git a/yack-app/pagesA/home/device/statistic/history.vue b/yack-app/pagesA/home/device/statistic/history.vue index 3fd3c20a..53f387df 100644 --- a/yack-app/pagesA/home/device/statistic/history.vue +++ b/yack-app/pagesA/home/device/statistic/history.vue @@ -81,7 +81,7 @@ import uniPagination from '@/pagesA/components/uni-pagination/index.vue'; import { getSubGatewayList } from '@/apis/modules/gateway.js'; import { listThingsModel } from '@/apis/modules/device.js'; - import { getHistoryList, getSubDeviceComparativeHistory } from '@/apis/modules/deviceLog.js'; + import { getHistoryList, getSubDeviceComparativeHistory, getDeviceHistoryCalculated } from '@/apis/modules/deviceLog.js'; export default { name: 'deviceHistory', @@ -364,6 +364,8 @@ text: item.modelName, value: item.identifier, type: item.type, + isCalculated: item.isCalculated, // 是否计算物模型 + slaveId: item.slaveId, // 子设备从机号(网关自身物模型为空) } } }).filter(item => item !== undefined); @@ -397,22 +399,10 @@ const { deviceId, serialNumber, deviceType } = this.deviceInfo; if (identifiers.length !== 0) { this.historys = []; + const beginTimeStr = moment(beginTime).format('YYYY-MM-DD HH:mm:ss'); + const endTimeStr = moment(endTime).format('YYYY-MM-DD HH:mm:ss'); if (deviceType === 2) { - // 网关设备:调用多设备对比接口,数据按子设备SN存储 - const params = { - gwDeviceId: deviceId, - identifierList: identifiers, - type: 1, - beginTime: moment(beginTime).format('YYYY-MM-DD HH:mm:ss'), - endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'), - }; - getSubDeviceComparativeHistory(params).then(res => { - if (res.code === 200) { - this.historys = res.data || []; - this.chartData = this.getChartDatas(); - this.getTableDatas(); - } - }) + this.getGatewayHistory(identifiers, deviceId, serialNumber, beginTimeStr, endTimeStr); } else { // 直连设备 const idenList = identifiers.map((item) => { @@ -424,8 +414,8 @@ }); const params = { identifierList: idenList, - beginTime: moment(beginTime).format('YYYY-MM-DD HH:mm:ss'), - endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'), + beginTime: beginTimeStr, + endTime: endTimeStr, deviceId: deviceId, serialNumber: serialNumber, }; @@ -439,14 +429,115 @@ } } }, + // 网关设备历史查询:普通变量走多设备对比接口,计算物模型走计算接口,结果合并 + getGatewayHistory (identifiers, deviceId, serialNumber, beginTimeStr, endTimeStr) { + // 计算物模型:isCalculated=1 且属于网关自身产品(无slaveId) + const calculatedItems = identifiers.filter((id) => { + const iden = this.identifierList.find((chil) => chil.value === id); + return iden && iden.isCalculated === 1 && (iden.slaveId === null || iden.slaveId === undefined || iden.slaveId === ''); + }); + const normalIdentifiers = identifiers.filter((id) => !calculatedItems.includes(id)); + + const tasks = []; + if (normalIdentifiers.length > 0) { + // 普通变量:多设备对比接口(数据按子设备SN存储) + tasks.push(getSubDeviceComparativeHistory({ + gwDeviceId: deviceId, + identifierList: normalIdentifiers, + type: 1, + beginTime: beginTimeStr, + endTime: endTimeStr, + }).then(res => ({ + type: 'compare', + data: res.code === 200 ? (res.data || []) : [] + }))); + } + if (calculatedItems.length > 0) { + // 计算物模型:查询时按公式计算 + const idenList = calculatedItems.map((id) => { + const iden = this.identifierList.find((chil) => chil.value === id); + return { + identifier: iden.value, + type: iden.type + }; + }); + tasks.push(getDeviceHistoryCalculated({ + identifierList: idenList, + beginTime: beginTimeStr, + endTime: endTimeStr, + deviceId: deviceId, + serialNumber: serialNumber, + }).then(res => ({ + type: 'calculated', + data: res.code === 200 ? (res.data || []) : [] + }))); + } + if (tasks.length === 0) { + return; + } + + Promise.all(tasks).then((results) => { + // 统一转换为 [{ time, 列名: 值 }] 格式后按时间合并 + const rowMap = new Map(); + results.forEach((result) => { + if (result.type === 'compare') { + // subDeviceComparativeHistory 格式: [{ "time": "...", "子设备A(从机1)": "25.5" }] + result.data.forEach((row) => { + if (!row.time) { + return; + } + if (!rowMap.has(row.time)) { + rowMap.set(row.time, { time: row.time }); + } + const target = rowMap.get(row.time); + Object.keys(row).forEach((k) => { + if (k !== 'time') { + target[k] = row[k]; + } + }); + }); + } else { + // deviceHistoryCalculated 格式: [{ "2026-08-23 10:00:00": [{ "calcVar": "12.3" }] }] + result.data.forEach((item) => { + const time = Object.keys(item)[0]; + if (!time) { + return; + } + if (!rowMap.has(time)) { + rowMap.set(time, { time }); + } + const target = rowMap.get(time); + Object.values(item)[0].forEach((chil) => { + const id = Object.keys(chil)[0]; + const iden = this.identifierList.find((m) => m.value === id); + // 计算物模型列名使用变量名 + target[iden ? iden.text : id] = Object.values(chil)[0]; + }); + }); + } + }); + // 按时间升序排序 + this.historys = Array.from(rowMap.values()).sort((a, b) => (a.time < b.time ? -1 : 1)); + this.chartData = this.getChartDatas(); + this.getTableDatas(); + }); + }, // 获取折线图数据(适配两种接口响应格式) getChartDatas () { const { deviceType } = this.deviceInfo; if (deviceType === 2) { - // subDeviceComparativeHistory 格式: [{ "time": "2026-08-23 10:00:00", "子设备A": "25.5", "子设备B": "26.0" }] + // 网关:合并后的格式 [{ "time": "...", "子设备A(从机1)": "25.5", "计算变量": "12.3" }] + if (this.historys.length === 0) { + return { categories: [], series: [] }; + } const categories = this.historys.map((item) => item.time); - // 获取除 time 外的所有列名作为系列 - const keys = Object.keys(this.historys[0] || {}).filter(k => k !== 'time'); + // 从所有行收集列名(避免第一行缺少某些列) + const keys = []; + this.historys.forEach((item) => Object.keys(item).forEach((k) => { + if (k !== 'time' && !keys.includes(k)) { + keys.push(k); + } + })); const series = keys.map((key) => { return { name: key, @@ -473,8 +564,14 @@ getTableDatas () { const { deviceType } = this.deviceInfo; if (deviceType === 2) { - // subDeviceComparativeHistory 格式 - const keys = Object.keys(this.historys[0] || {}).filter(k => k !== 'time'); + // 网关:合并后的格式 [{ "time": "...", "子设备A(从机1)": "25.5", "计算变量": "12.3" }] + // 从所有行收集列名(避免第一行缺少某些列) + const keys = []; + this.historys.forEach((item) => Object.keys(item).forEach((k) => { + if (k !== 'time' && !keys.includes(k)) { + keys.push(k); + } + })); this.tableHeaders = keys.map((key) => ({ name: key, value: key,