diff --git a/api/app/lib/controllers/monitor/index.js b/api/app/lib/controllers/monitor/index.js index 59e451c..61038e9 100644 --- a/api/app/lib/controllers/monitor/index.js +++ b/api/app/lib/controllers/monitor/index.js @@ -1,5 +1,6 @@ -const moment = require('moment'); +const moment = require('moment') +const fs = require('fs') async function getStructures(ctx) { try { @@ -120,18 +121,19 @@ async function getSensors(ctx) { } //根据设备id和监测因素id查询监测数据 async function getMonitorData(ctx) { + try { const { clickHouse } = ctx.app.fs - const { factorId, sensorId, startTime, endTime } = ctx.query - const projectId=sensorId.split('-')[0] + const { factorId, sensorId, startTime, endTime,toExport } = ctx.query + const projectId = sensorId.split('-')[0] const factorsList = await clickHouse.alarmLocal.query(`SELECT FactorID,Items,ItemNames,ItemUnits FROM factors WHERE FactorID=${factorId} AND Project='${projectId}' `).toPromise() || [] const dataArray = sensorId.split(',') const transformedArray = dataArray.map(item => { - return item.replace('-',':')+'' + return item.replace('-', ':') + '' }) - const id=`(${transformedArray.map(id => `'${id}'`).join(',')})` + const id = `(${transformedArray.map(id => `'${id}'`).join(',')})` const monitorData = await clickHouse.alarmLocal.query(`SELECT distinct SensorId,CollectTime,Values FROM themes WHERE SensorId in ${id} AND CollectTime >= toDate('${startTime}') @@ -146,46 +148,103 @@ async function getMonitorData(ctx) { //因素名词 let factorNames = [] //单位 - let c=[] + let c = [] factorsList.map(item => { factors = item.ItemNames.split(',') factorNames = item.Items.split(',') c = item.ItemUnits.split(',') - factorNames.map((child,index)=> { - items[factorNames[index]] = { name:factors[index] , unit:c[index] } - }) + factorNames.map((child, index) => { + items[factorNames[index]] = { name: factors[index], unit: c[index] } + }) }) } //设备数据+数据 let sensors = [] - let data=[] - if(sensor&&monitorData&&sensor.length && monitorData.length){ + let data = [] + if (sensor && monitorData && sensor.length && monitorData.length) { sensor.forEach((item) => { // 过滤与当前传感器相关的数据 const sensorDataArray = monitorData.filter((d) => d.SensorId == item.ID) // 构建最终的传感器数据结构 const sensorDataItem = { - id: item.ID, - name: item.SensorLocationDescription, - data: sensorDataArray.map((d) => { - // 根据 item 对象进行映射 - const values = {}; - itemKeys = Object.keys(items) - itemKeys.forEach((key, index) => { - values[key] = d.Values[index]; - }); - - return { - time: d.CollectTime, - values: values - }; - }) + id: item.ID, + name: item.SensorLocationDescription, + data: sensorDataArray.map((d) => { + // 根据 item 对象进行映射 + const values = {}; + itemKeys = Object.keys(items) + itemKeys.forEach((key, index) => { + values[key] = d.Values[index]; + }); + + return { + time: d.CollectTime, + values: values + }; + }) }; data.push(sensorDataItem) - }) + }) + } + //导出相关 + + if (toExport) { + let arr=items + let columns = [] + columns.push({ + title: '设备位置', + dataIndex: 'position', + key: 'position', + }); + for (let index in arr) { + columns.push({ + title: arr[index].name + '(' + arr[index].unit + ')', + dataIndex: index, + sorter: (a, b) => b[index] - a[index], + key: index, + }) + }; + columns.push({ + title: '采集时间', + dataIndex: 'acqTime', + sorter: (a, b) => b['realTime'] - a['realTime'], + key: 'acqTime', + }); + //设备 + let data1 = [] + let themeStations = data + for (let i = 0; i < themeStations.length; i++) { + for (let k = 0; k < themeStations[i].data.length; k++) { + let cdataT = {} + let startT = ""; + let endT = ""; + let dataTS = themeStations[i].data[k]; + cdataT.key = `station-${themeStations[i].id}-${k}`; + cdataT.position = themeStations[i].name; + cdataT.acqTime = moment(dataTS.time).format('YYYY-MM-DD HH:mm:ss'); + cdataT.realTime = moment(dataTS.time).valueOf(); + if (startT == "") { + startT = dataTS.time; + endT = dataTS.time; + } else { + if (moment(startT) >= moment(dataTS.time)) + startT = dataTS.time; + if (moment(endT) <= moment(dataTS.time)) + endT = dataTS.time; + } + //动态列的值 + for (let themeItem in arr) { + cdataT[themeItem] = dataTS.values[themeItem]; + } + data1.push(cdataT) + } + } + await exportMaterialEnterList(ctx, data1, columns) } + if(!toExport){ ctx.body = { items, sensors: data } ctx.status = 200 + } } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: error`); @@ -196,11 +255,67 @@ async function getMonitorData(ctx) { } } +async function exportMaterialEnterList(ctx, data, columns) { + try { + let header = [] + columns.forEach(item => { + header.push({ title: item.title, key: item.key }) + }) + const { utils: { simpleExcelDown } } = ctx.app.fs + // let exportData = [] + // let item={} + // console.log(dataList[0].dataValues) + let siteName = '数据监控' + // for (let item of data) { + // for(let child of item){ + // if(child!=key){ + // item[child]= + // } + // } + // // item.outTime = moment(item.outTime).format('YYYY-MM-DD HH:mm:ss'); + // // item.branchId = item.siteProcessBranch && item.siteProcessBranch.name ? item.siteProcessBranch.name : '-' + // // item.subItemId = item.siteProcessSubItem && item.siteProcessSubItem.name ? item.siteProcessSubItem.name : '-' + // // item.type = item.materialItem && item.materialItem.name ? item.materialItem.name : '-' + // // item.name = item.materialItem && item.materialItem.name ? item.materialItem.name : '-' + // // item.model = item.materialItem && item.materialItem.model ? item.materialItem.model : '-' + // // item.unit = item.materialItem && item.materialItem.unit ? item.materialItem.unit : '-' + // // item.providerId = item.materialProvider && item.materialProvider.name ? item.materialProvider.name : '-' + // // item.status = (item.status || item.status == 0) && data[item.status] + // exportData.push(item) + // } + const fileName = `${siteName}` + '.xls' + console.log('x11111111',data,fileName,header) + const filePath = await simpleExcelDown({ data: data, header, fileName: fileName, needIndexCell: false }) + const fileData = fs.readFileSync(filePath) + ctx.status = 200 + ctx.set('Content-Type', 'application/x-xls') + ctx.set('Content-disposition', 'attachment; filename=' + encodeURI(fileName)) + ctx.body = fileData + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) + ctx.status = 400 + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} +async function exportFile(ctx) { + try { + const { data, columns } = ctx.query + await exportMaterialEnterList(ctx, data, columns) + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`) + ctx.status = 400 + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} module.exports = { - getStructures, getFactors, getSensors, getMonitorData + getStructures, getFactors, getSensors, getMonitorData, exportFile } \ No newline at end of file diff --git a/web/client/src/sections/data/containers/dataDetail.jsx b/web/client/src/sections/data/containers/dataDetail.jsx index a64e2fc..165441a 100644 --- a/web/client/src/sections/data/containers/dataDetail.jsx +++ b/web/client/src/sections/data/containers/dataDetail.jsx @@ -260,8 +260,12 @@ const DataDetail = (props) => { 数据} itemKey="2"> - - + 0?sensorId.map(item=>`${project}-${item}`).join(','):[-11]} + factorId={factorId?factorId:-1} + startTime={moment(dateRange[0]).format('YYYY-MM-DD HH:mm:ss')} + endTime={moment(dateRange[1]).format('YYYY-MM-DD HH:mm:ss')} + + dataList={checkData}/> diff --git a/web/client/src/sections/data/containers/dataTableComponent.jsx b/web/client/src/sections/data/containers/dataTableComponent.jsx index 743fce7..3994c4e 100644 --- a/web/client/src/sections/data/containers/dataTableComponent.jsx +++ b/web/client/src/sections/data/containers/dataTableComponent.jsx @@ -1,7 +1,4 @@ -/* - * @Author: zhaobing - * @Date: 2023-11-02 09:32:25 - */ + import React, { useState, useEffect } from 'react'; import { connect } from 'react-redux'; import { Table, Button, Alert, Spin } from '@douyinfe/semi-ui'; @@ -10,14 +7,21 @@ import FileSaver from 'file-saver'; import moment from 'moment'; const DataTableComponent = (props) => { - const {dataList}=props + const {dataList,dispatch,actions,user, sensorId,endTime,startTime,factorId}=props const [currentPage, setCurrentPage] = useState(1); const [exportingFlag, setExportingFlag] = useState(false); const [isRequesting, setIsRequesting] = useState(false); const [arr,setArr]=useState(dataList.items) const [data,setData]=useState([]) + const [exportUrl, setExportUrl] = useState('') // const [list,setList]=useState(dataList.sensors) const [columns,setColumns]=useState([]) + // useEffect(() => { + // if (exportUrl) { + //