'use strict'; const moment = require('moment') const RAW_DATA = 'rawData'; const VBRAW_DATA = 'vbRawData'; const ALARM = 'alarm'; async function getMaintenceRecordRank(ctx) { const sequelize = ctx.fs.dc.orm const Sequelize = ctx.fs.dc.ORM; const { clickHouse } = ctx.app.fs const models = ctx.fs.dc.models const { startTime, endTime } = ctx.query console.log(startTime, endTime, ctx.query, '1212312') try { const res = await sequelize.query(` SELECT emrp.project_id,count(1) FROM equipment_maintenance_record RIGHT JOIN equipment_maintenance_record_project emrp on equipment_maintenance_record.id = emrp.equipment_maintenance_record_id where report_time BETWEEN :startTime AND :endTime GROUP BY emrp.project_id ` , { replacements: { startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'), endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss ') } //, type: sequelize.QueryTypes.SELECT } ) //查询equipment_maintenance_record返回的结果[{project_id: 22, count: 1}] let projectList = [] //存project的id let projectIdList = [] // console.log('resssss', res) if (res.length > 0) { res[0].forEach((item) => { projectList.push({ project_id: item.project_id, count: Number(item.count) }) projectIdList.push(item.project_id) }) } const projectNameList = await models.ProjectCorrelation.findAll({ attributes: ['id', 'name'], where: { id: { $in: projectIdList }, name: { [Sequelize.Op.not]: null//有name的结果 } // del: false } }) || [] //在ProjectCorrelation中查不到名字,去clickHouse中去查 const projectNameList1 = await models.ProjectCorrelation.findAll({ attributes: ['id', 'name', 'pepProjectId'], where: { id: { $in: projectIdList }, name: { [Sequelize.Op.eq]: null//无name的结果 } // del: false } }) //存放需要去查询clickHouse的id let idList = new Set() if (projectNameList1.length) { projectNameList1.forEach((item) => { idList.add(item.pepProjectId) }) } //pepProject名称 const projectManageName = idList.size ? await clickHouse.projectManage.query(` SELECT id,project_name FROM t_pim_project WHERE id IN (${[...idList].join(',')}, -1) `).toPromise() : [] // if (projectList.length) { // projectList.forEach((item) => { // projectManageName // }) // } //存的是{id,projectName} let project = [] if (projectNameList1.length && projectManageName.length) { projectManageName.forEach((item) => { const pepObj = projectNameList1.find((item1) => { return item1.pepProjectId === item.id }) project.push({ id: pepObj.id, projectName: item.project_name }) }) } const resAll = project.concat(projectNameList) let mergedArray = [] if (resAll.length && projectList) { mergedArray = projectList.map(obj1 => { const matchingObj = resAll.find(obj2 => obj2.id === obj1.project_id); return { id: obj1.project_id, pepProjectId: matchingObj.id, projectName: matchingObj.projectName || matchingObj.dataValues.name, count: obj1.count }; }); } // console.log('ididididid', resAll) // console.log('ididididid', project) // console.log('ididididid', projectManageName) // console.log('ididididid', projectNameList) // console.log('ididididid', projectList) ctx.status = 200 ctx.body = mergedArray } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '查询维修记录排名失败' } } } async function getMaintenceTotal(ctx) { const sequelize = ctx.fs.dc.orm const Sequelize = ctx.fs.dc.ORM; const { clickHouse } = ctx.app.fs const models = ctx.fs.dc.models const { startTime, endTime } = ctx.query try { //所有维修记录 const res = await sequelize.query(` SELECT emrp.project_id, count(case when record.status in ('维修中','待维修','维修完成') then record.id end) incomplete, count(case when record.status in ('维修完成') then record.id end) completed FROM equipment_maintenance_record record RIGHT JOIN equipment_maintenance_record_project emrp on record.id = emrp.equipment_maintenance_record_id where report_time BETWEEN :startTime AND :endTime GROUP BY emrp.project_id ` , { replacements: { startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss '), endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss ') } //, type: sequelize.QueryTypes.SELECT } ) //查询equipment_maintenance_record返回的结果[{project_id: 22,status:'' count: 1}] let projectList = [] //存project的id let projectIdList = new Set() // console.log('resssss', res) if (res.length > 0) { res[0].forEach((item) => { projectList.push({ project_id: item.project_id, 'incomplete': Number(item.incomplete), completed: Number(item.completed) }) projectIdList.add(item.project_id) }) } // const result = projectList.reduce((acc, curr) => { // if (curr.status === '待维修' || curr.status === '维修中') { // const existingItem = acc.find(item => item.project_id === curr.project_id && item.status === '异常数'); // if (existingItem) { // existingItem.count += curr.count; // } else { // acc.push({ project_id: curr.project_id, status: '异常数', count: curr.count }); // } // } else if (curr.status === '维修完成') { // const existingItem = acc.find(item => item.project_id === curr.project_id && item.status === '维修数'); // if (existingItem) { // existingItem.count += curr.count; // } else { // acc.push({ project_id: curr.project_id, status: '维修数', count: curr.count }); // } // } // return acc; // }, []) //console.log('resssssresult', result) const projectNameList = await models.ProjectCorrelation.findAll({ attributes: ['id', 'name'], where: { id: { $in: [...projectIdList] }, name: { [Sequelize.Op.not]: null//有name的结果 } // del: false } }) || [] //在ProjectCorrelation中查不到名字,去clickHouse中去查 const projectNameList1 = await models.ProjectCorrelation.findAll({ attributes: ['id', 'name', 'pepProjectId'], where: { id: { $in: [...projectIdList] }, name: { [Sequelize.Op.eq]: null//无name的结果 } // del: false } }) //存放需要去查询clickHouse的id let idList = new Set() if (projectNameList1.length) { projectNameList1.forEach((item) => { idList.add(item.pepProjectId) }) } //pepProject名称 const projectManageName = idList.size ? await clickHouse.projectManage.query(` SELECT id,project_name FROM t_pim_project WHERE id IN (${[...idList].join(',')}, -1) `).toPromise() : [] let project = [] if (projectNameList1.length && projectManageName.length) { projectManageName.forEach((item) => { const pepObj = projectNameList1.find((item1) => { return item1.pepProjectId === item.id }) project.push({ id: pepObj.id, projectName: item.project_name }) }) } //pg的数据和clcikHouse的数据(名字)合并 const resAll = project.concat(projectNameList) let mergedArray = [] if (resAll.length && projectList) { mergedArray = projectList.map(obj1 => { const matchingObj = resAll.find(obj2 => obj2.id === obj1.project_id) return { id: obj1.project_id, incomplete: obj1.incomplete, completed: obj1.completed, pepProjectId: matchingObj.id, projectName: matchingObj.projectName || matchingObj.dataValues.name } }); } // console.log('ididididid', resAll) // console.log('ididididid', project) // console.log('ididididid', projectManageName) // console.log('ididididid', projectNameList) // console.log('ididididid', projectList) ctx.status = 200 ctx.body = mergedArray } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '查询维修记录统计失败' } } } async function getEquipmentCategory(ctx) { const { startTime, endTime } = ctx.query const Sequelize = ctx.fs.dc.ORM const models = ctx.fs.dc.models try { const res = await models.EquipmentMaintenanceRecord.findAll({ attributes: [ 'equipment_category', [Sequelize.fn('COUNT', Sequelize.col('equipment_category')), 'count'] ], where: { reportTime: { $between: [moment(startTime).format('YYYY-MM-DD HH:mm:ss '), moment(endTime).format('YYYY-MM-DD HH:mm:ss ')] } }, group: ['equipment_category'] }) ctx.status = 200 ctx.body = res } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '查询设备类型失败' } } } async function getStatus(ctx) { const { startTime, endTime } = ctx.query const Sequelize = ctx.fs.dc.ORM const models = ctx.fs.dc.models try { const res = await models.EquipmentMaintenanceRecord.findAll({ attributes: [ 'status', [Sequelize.fn('COUNT', Sequelize.col('status')), 'count'] ], where: { reportTime: { $between: [moment(startTime).format('YYYY-MM-DD HH:mm:ss '), moment(endTime).format('YYYY-MM-DD HH:mm:ss ')] } }, group: ['status'] }) ctx.status = 200 ctx.body = res } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '查询设备类型失败' } } } async function getOrganizationsStruc(ctx) { try { const { utils: { anxinStrucIdRange } } = ctx.app.fs const { pepProjectId } = ctx.params if (!pepProjectId) { throw '缺少参数 pepProjectId' } let anxinStruc = await anxinStrucIdRange({ ctx, pepProjectId }) || [] ctx.status = 200 ctx.body = anxinStruc } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '获取项目下的结构物信息失败' } } } async function getThingsDeploy(ctx) { let error = { name: 'FindError', message: '获取设备部署信息失败' }; let rslt = null, errStatus = null; let { thingId } = ctx.params; try { if (!thingId) { throw '缺少参数 thingId' } let iotaResponse = await ctx.app.fs.iotRequest.get(`things/${thingId}/deploys`) rslt = JSON.parse(iotaResponse) error = null; } catch (err) { errStatus = err.status ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); } if (error) { if (errStatus == 404) { ctx.status = 200; ctx.body = { 'instances': null }; } else { ctx.status = errStatus; ctx.body = error; } } else { ctx.status = 200; ctx.body = rslt; } } async function findDeviceMetaDeployed(ctx, next) { let rslt = null; const { iotaThingId } = ctx.params; try { let iotaResponse = await ctx.app.fs.iotRequest.get(`meta/things/${iotaThingId}/devices`) rslt = JSON.parse(iotaResponse) ctx.status = 200; ctx.body = rslt; } catch (err) { ctx.status = 400; ctx.body = { "name": "FindError", "message": "设备部署原型获取失败" } } }; async function findDeviceLastData(ctx, deviceIds) { let rslt = []; const clientRaws = ctx.app.fs.esclient[RAW_DATA]; const clientVbraws = ctx.app.fs.esclient[VBRAW_DATA]; if (deviceIds) { for (let id of deviceIds) { let params = { index: clientRaws.config.index, type: clientRaws.config.type, body: { query: { constant_score: { filter: { bool: { must: [ { term: { "iota_device": id } }, { range: { "collect_time": { lte: moment().toISOString() } } } ] } } } }, sort: [ { "collect_time": { order: "desc" } } ], size: 1 } }; let res = await clientRaws.search(params); if (res.hits.hits.length == 0) { params.index = clientVbraws.config.index; params.type = clientVbraws.config.type; res = await clientVbraws.search(params); } let data = res.hits.hits.map(h => { let source = h._source; let data_ = source.data; if (params.index == clientVbraws.config.index) { let tempData = { "最大幅值": '_' }; if (data_.raw && data_.raw.length) { let maxAmplitude = data_.raw[0]; for (let v of data_.raw) { if (maxAmplitude < v) { maxAmplitude = v; } } tempData['最大幅值'] = maxAmplitude + '(gal)'; } data_ = tempData; } return { collectTime: source.collect_time, iotaDevice: source.iota_device, iotaDeviceName: source.iota_device_name, data: data_ } }); rslt.push({ sensorId: id, data: data }); } } return rslt; } async function findSensorLastData(ctx) { try { const sensorIds = ctx.request.body.sensorIds; let rslt = await findDeviceLastData(ctx, sensorIds); // let rslt = [{ sensorId: "2aa1cad1-a52d-4132-8d84-2475034d5bc8", data: [] }, // { sensorId: "9f1702ff-560d-484e-8572-ef188ef73916", data: [] }, // { // sensorId: "360d9098-f2a5-4e1a-ab2b-0bcd3ddcef87", data: [{ // collectTime: "2021-07-12T05:30:44.000Z", data: { readingNumber: 228 }, // iotaDevice: "360d9098-f2a5-4e1a-ab2b-0bcd3ddcef87", iotaDeviceName: "水表" // }] // }, // { sensorId: "8c3a636b-9b62-4486-bf54-4ac835aee094", data: [] }, // { // sensorId: "9ea4d6cd-f0dc-4604-bb85-112f2591d644", data: [{ // collectTime: "2021-07-17T05:53:35.783Z", data: { DI4: 0, DI7: 0, DI5: 0, DI1: 1, DI6: 0, DI2: 1, DI8: 0, DI3: 1 }, // iotaDevice: "9ea4d6cd-f0dc-4604-bb85-112f2591d644", iotaDeviceName: "控制器" // }] // }, // { sensorId: "e18060b4-3c7f-4fad-8a1a-202b5c0bf00c", data: [] } // ] ctx.status = 200; ctx.body = rslt; } catch (error) { ctx.status = 400; ctx.body = { "name": "FindError", "message": "原始数据查询失败" } } } async function findAlarmsDevices(ctx, next) { let rslt = [] const deviceIds = ctx.request.body const { limit, state } = ctx.query try { if (deviceIds.length) { for (let deviceId of deviceIds) { // es search const client = ctx.app.fs.esclient[ALARM];//准备查询 let params = { index: client.config.index, type: client.config.type, size: limit || 9999, body: { "query": { "bool": { "must": [ { "match": { "source_id": deviceId } }, { "terms": { "state": [] } } ] } }, "sort": [ { "start_time": { "order": "desc" } } ] } } if (state == 'new') { let newState = [AlarmState.Creation, AlarmState.CountUpgrade, AlarmState.LevelUpgrade]; params.body.query.bool.must[1].terms.state = newState; } let alarms = await client.search(params); const timer = ctx.app.fs.timer; function filterAlarmMsg(oriMsg) { let msg = []; for (let s of oriMsg) { msg.push({ alarmContent: s._source.alarm_content, alarmCount: s._source.alarm_count, deviceId: s._source.source_id, startTime: timer.toCSTString(s._source.start_time), endTime: timer.toCSTString(s._source.end_time), }) } return msg; } rslt = rslt.concat(filterAlarmMsg(alarms.hits.hits)); } } ctx.status = 200; ctx.body = rslt; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '告警信息查询失败' } } } async function findDevicesCardStatus(ctx, next) { try { let rlst = [] const { clickHouse } = ctx.app.fs const { deviceIds } = ctx.request.body if (deviceIds && deviceIds.length) { const id = `(${deviceIds.map(id => `'${id}'`).join(',')})` rlst = await clickHouse.dataAlarm.query(` SELECT cs.DeviceId,cs.Status,MAX(cs.Time) FROM alarm.CardStatus cs WHERE cs.DeviceId in ${id} GROUP BY cs.DeviceId,cs.Status`).toPromise() } ctx.status = 200; ctx.body = rlst; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: '物联网卡状态查询失败' } } } module.exports = { getOrganizationsStruc, getThingsDeploy, findSensorLastData, findDeviceMetaDeployed, findAlarmsDevices, findDevicesCardStatus }