运维服务中台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

353 lines
12 KiB

const moment = require('moment')
const fs = require('fs')
async function getStructures(ctx) {
try {
const { models } = ctx.fs.dc
const { clickHouse } = ctx.app.fs
const { pomsProjectId } = ctx.query
let bindRes = []
//选择全局就是查询所有项目下的结构物,有选择项目就只查询对应项目的结构物
if (pomsProjectId) {
bindRes = await models.ProjectCorrelation.findAll({ where: { id: { $in: pomsProjectId.split(',') } } })
} else {
bindRes = await models.ProjectCorrelation.findAll()
}
let anxinProjectIds = new Set()
for (let b of bindRes) {
if (b.anxinProjectId.length) {
for (let aid of b.anxinProjectId) {
anxinProjectIds.add(aid)
}
}
}
let undelStrucRes = []
if (bindRes) {
undelStrucRes = anxinProjectIds.size
? await clickHouse.anxinyun
.query(
`
SELECT
t_structure.id AS strucId,
t_structure.name AS strucName
FROM
t_project
LEFT JOIN
t_project_structure
ON t_project_structure.project = t_project.id
LEFT JOIN
t_project_structuregroup
ON t_project_structuregroup.project = t_project.id
LEFT JOIN
t_structuregroup_structure
ON t_structuregroup_structure.structuregroup = t_project_structuregroup.structuregroup
LEFT JOIN
t_project_construction
ON t_project_construction.project = t_project.id
LEFT JOIN
t_structure_site
ON t_structure_site.siteid = t_project_construction.construction
RIGHT JOIN
t_structure
ON t_structure.id = t_project_structure.structure
OR t_structure.id = t_structuregroup_structure.structure
OR t_structure.id = t_structure_site.structid
WHERE
project_state != -1
AND
t_project.id IN (${[...anxinProjectIds].join(',')}, -1)
AND t_structure.external_platform is not null
ORDER BY strucId
`
)
.toPromise()
: []
}
// undelStrucRes.push({ strucId: 4036, strucName: '象山港大桥' })
// undelStrucRes.push({ strucId: 1, strucName: '象山港大' })
ctx.status = 200
ctx.body = undelStrucRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`)
ctx.status = 400
ctx.body = {
message: typeof error == 'string' ? error : undefined,
}
}
}
async function getFactors(ctx) {
try {
const { models } = ctx.fs.dc
const { clickHouse } = ctx.app.fs
const { structId, cacl } = ctx.query
let list = []
if (cacl) {
const factorList = await clickHouse.dataAlarm
.query(`select SafetyFactorTypeId, SafetyFactorTypeName from sensors where PlatformStructureId = ${structId}`)
.toPromise()
const project = await clickHouse.dataAlarm
.query(`select Project from sensors where PlatformStructureId =${structId} limit 1 `)
.toPromise()
let fList = factorList.map(m => m.SafetyFactorTypeId)
list = await clickHouse.dataAlarm
.query(
`select distinct FactorID, Name,Items,ItemNames from factors
where FactorID in (${[...fList, -1].join(',')})
and Project = '${[...project, 0][0].Project}'
`
)
.toPromise()
} else {
list = await clickHouse.dataAlarm
.query(
`select distinct SafetyFactorTypeId, SafetyFactorTypeName from sensors where PlatformStructureId =${structId}`
)
.toPromise()
}
ctx.body = list
ctx.status = 200
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`)
ctx.status = 400
ctx.body = {
message: typeof error == 'string' ? error : undefined,
}
}
}
//查询设备
async function getSensors(ctx) {
try {
const { models } = ctx.fs.dc
const { clickHouse } = ctx.app.fs
const { structId, SafetyFactorTypeId } = ctx.query
const list = await clickHouse.dataAlarm
.query(
`
select distinct SensorId,SensorLocationDescription,Project
from sensors where PlatformStructureId =${structId}
and SafetyFactorTypeId=${SafetyFactorTypeId}`
)
.toPromise()
ctx.body = list
ctx.status = 200
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`)
ctx.status = 400
ctx.body = {
message: typeof error == 'string' ? error : undefined,
}
}
}
//根据设备id和监测因素id查询监测数据
async function getMonitorData(ctx) {
try {
const { clickHouse } = ctx.app.fs
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('-', ':') + ''
})
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}')
AND CollectTime <= toDate('${endTime}')
`
)
.toPromise()) || []
const sensor = await clickHouse.alarmLocal
.query(`SELECT distinct ID, SensorId,SensorLocationDescription FROM sensors WHERE ID in ${id}`)
.toPromise()
//监测项
let items = {}
if (factorsList && factorsList.length > 0) {
//因素解释
let factors = []
//因素名词
let factorNames = []
//单位
let c = []
factorsList.map(item => {
factors = item.ItemNames.split(',')
factorNames = item.Items.split(',')
c = item.ItemUnits.split(',')
factorNames.map((child, index) => {
items[factorNames[index]?factorNames[index]:factors[index]] = { name: factors[index], unit: c[index] }
})
})
}
//设备数据+数据
let sensors = []
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,
}
}),
}
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`)
ctx.status = 400
ctx.body = {
message: typeof error == 'string' ? error : undefined,
}
}
}
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'
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,
exportFile,
}