运维服务中台
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.
 
 
 
 
 

851 lines
30 KiB

'use strict';
const moment = require('moment');
async function personnelApp (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
const sequelize = ctx.fs.dc.orm;
const { userId, pepUserId, userInfo, pepUserInfo } = ctx.fs.api
const { pepId } = ctx.query
const excludeField = ['lastInTime', 'inTimes', 'onlineDuration', 'lastInAddress', 'deleted', 'updateTime']
let findOption = {
attributes: {
exclude: excludeField,
// include: [[sequelize.fn('array_length', sequelize.col('role')), 'roleCount']]
},
where: {
deleted: false,
$or: [{
$not: {
role: { $contained: ['SuperAdmin', 'admin'] }
}
},
sequelize.where(sequelize.fn('cardinality', sequelize.col('role')), 0)],
// $not: {
// role: { $contained: ['SuperAdmin', 'admin'] }
// }
},
order: [['updateTime', 'DESC']]
}
const userRes = await models.User.findAndCountAll(findOption)
const adminRes = await models.User.findAll({
where: {
role: { $contains: ['admin'] }
},
attributes: {
exclude: excludeField,
},
order: [['updateTime', 'DESC']]
})
let userIds = new Set()
let pomsProjectIds = new Set()
for (let u of userRes.rows.concat(adminRes)) {
userIds.add(u.pepUserId)
for (let pid of u.correlationProject) {
pomsProjectIds.add(pid)
}
}
// 查用户所属的项企pep的部门、人员信息
let userPepRes = userIds.size ?
await clickHouse.pepEmis.query(`
SELECT DISTINCT
user.id AS id, "user"."name" AS name, department.name AS depName, department.id AS depId
FROM department_user
LEFT JOIN user
ON department_user.user=user.id
LEFT JOIN department
ON department.id=department_user.department
WHERE
user.id IN (${[...userIds].join(',')}, -1)
AND department.delete='0'`
).toPromise() :
[]
// 查用户绑定的当前系统的项目 id
let pomsProjectRes = await models.ProjectCorrelation.findAll({
where: {
id: { $in: [...pomsProjectIds] },
// del: false
}
})
// 获取响应的绑定的 项企项目的 id
let pepPojectIds = new Set()
for (let p of pomsProjectRes) {
if (p.pepProjectId && !isNaN(p.pepProjectId)) {
pepPojectIds.add(p.pepProjectId)
}
}
// 查对应的项企项目信息
let pepProjectRes = pepPojectIds.size ?
await clickHouse.projectManage.query(`
SELECT id, project_name, isdelete FROM t_pim_project WHERE id IN (${[...pepPojectIds].join(',')}, -1)
`).toPromise() :
[]
// 遍历用户并将查到的信息拼合
for (let u of userRes.rows.concat(adminRes)) {
// 用户信息
const corUsers = userPepRes.filter(up => up.id == u.pepUserId)
u.dataValues.name = corUsers.length ? corUsers[0].name : ''
u.dataValues.departments = corUsers.length ? corUsers.map(cu => {
return {
name: cu.depName,
id: cu.depId
}
}) : []
// pep项目信息
u.dataValues.correlationProject = u.dataValues.correlationProject.map(cpid => {
let returnData = {
id: cpid,
}
const corPomsProject = pomsProjectRes.find(ppr => ppr.id == cpid)
if (corPomsProject) {
returnData.name = corPomsProject.name
returnData.del = corPomsProject.del
if (corPomsProject.pepProjectId) {
returnData.pepProjectId = corPomsProject.pepProjectId
const corPepProject = pepProjectRes.find(ppr => ppr.id == corPomsProject.pepProjectId)
if (corPepProject) {
returnData.pepProjectName = corPepProject.project_name
returnData.pepIsdelete = corPepProject.isdelete
}
}
}
return returnData
})
}
let findOptions = {
where: {
del: false
},
order: [['updateTime', 'desc']],
attributes: ['id', 'pepProjectId', 'name', 'anxinProjectId'],
distinct: true,
include: {
model: models.App,
}
}
if (!userInfo.role.includes('SuperAdmin') && !userInfo.role.includes('admin')) {
findOptions.where.id = { $in: userInfo.correlationProject }
}
if (pepId) {
findOptions.where.id = { $in: pepId.split(',') }
}
const proRes = await models.ProjectCorrelation.findAndCountAll(findOptions)
let pepProjectIds = new Set()
let anxinProjectIds = new Set()
for (let p of proRes.rows) {
if (p.pepProjectId) {
pepProjectIds.add(p.pepProjectId)
}
for (let ap of p.anxinProjectId) {
if (ap) {
anxinProjectIds.add(ap)
}
}
}
const pepProjectRess = pepProjectIds.size ?
await clickHouse.projectManage.query(
`
SELECT
t_pim_project.id AS id,
t_pim_project.project_name AS project_name,
t_pim_project.isdelete AS isdelete,
t_pim_project_construction.construction_status_id AS construction_status_id,
t_pim_project_state.construction_status AS construction_status
FROM t_pim_project
LEFT JOIN t_pim_project_construction
ON t_pim_project.id = t_pim_project_construction.project_id
LEFT JOIN t_pim_project_state
ON t_pim_project_construction.construction_status_id = t_pim_project_state.id
WHERE id IN (${[...pepProjectIds].join(',')}, -1)
`
).toPromise() :
[]
for (let p of proRes.rows) {
const corPro = pepProjectRess.find(pp => pp.id == p.pepProjectId) || {}
p.dataValues.pepProjectName = corPro.project_name
p.dataValues.pepProjectIsDelete = corPro.isdelete
delete p.dataValues.anxinProjectId
}
let webApp = []
let appproRes = proRes.rows.filter(v => v.dataValues.pepProjectIsDelete != 1).map(r => {
if (r.dataValues.apps.length > 0) {
r.dataValues.apps.map(vv => {
if (!webApp.map(n => n.name).includes(vv.dataValues.name)) {
webApp.push({ name: vv.dataValues.name, url: vv.dataValues.url })
}
})
}
})
let personnel = userRes.rows.filter(r => r.correlationProject.length > 0)
if (pepId) {
let pepIds = pepId.split(',')
personnel = personnel.filter(r => r.dataValues.correlationProject.map(v => v.id).some(pepId => pepIds.includes(pepId)))
}
ctx.status = 200
ctx.body = {
personnel: personnel.map(v => ({ name: v.dataValues.name, department: v.dataValues.departments.map(r => r.name) })),
webApp: webApp
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
}
}
}
async function problem (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
const { utils: { pomsProjectRange, anxinStrucIdRange } } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
const { pepProjectId, limit = 50, page = 0 } = ctx.query
let anxinStruc = await anxinStrucIdRange({
ctx, pepProjectId
})
let pomsProject = await pomsProjectRange({
ctx, pepProjectId,
})
const pomsProjectIds = pomsProject.map(p => p.id)
let whereOption = []
if (anxinStruc.length) {
const anxinStrucIds = anxinStruc.map(a => a.strucId)
whereOption.push(`alarms.StructureId IN (${anxinStrucIds.join(",")}, -1)`)
const alarmRes = await clickHouse.dataAlarm.query(`
SELECT
AlarmId,State,AlarmGroup,AlarmGroupUnit,SourceName,StartTime,${anxinyun}.t_alarm_group_unit.name AS typeName
FROM alarms
LEFT JOIN ${anxinyun}.t_alarm_group_unit
ON ${anxinyun}.t_alarm_group_unit.id = alarms.AlarmGroupUnit
${whereOption.length ? 'WHERE ' + whereOption.join(' AND ') + ' AND ' + 'alarms.State < 3' : ''}
${limit ? 'LIMIT ' + limit : ''}
${limit && page ? 'OFFSET ' + parseInt(limit) * parseInt(page) : ''}
`).toPromise();
alarmRes.forEach(ar => {
switch (ar.AlarmGroup) {
case 1:
ar.groupName = '数据中断'
ar.url = '/problem/dataAlarm/dataLnterrupt'
break;
case 2:
ar.groupName = '数据异常'
ar.url = '/problem/dataAlarm/dataAbnormal'
break;
case 3:
ar.groupName = '策略命中'
ar.url = '/problem/dataAlarm/strategyHit'
break;
default:
ar.groupName = '设备异常'
ar.url = '/problem/deviceAlarm/deviceAbnormal'
break;
}
})
const video = anxinStrucIds.length ? await clickHouse.vcmp.query(
`
SELECT
cameraAlarm.cameraId AS cameraId,
cameraAlarm.cameraName AS cameraName,
cameraAlarm.alarmId AS alarmId,
cameraAlarm.createTime AS createTime,
cameraAlarm.confirmTime AS confirmTime
FROM
(
SELECT
camera.id AS cameraId,
camera.name AS cameraName,
camera_status_alarm.id AS alarmId,
camera_status_alarm.create_time AS createTime,
camera_status_alarm.platform AS platform,
camera_status_alarm.status_id AS statusId,
camera_status_alarm.serial_no AS cameraSerialNo,
camera_status_alarm.channel_no AS cameraChannelNo,
camera_status_alarm.confirm_time AS confirmTime
FROM camera_status_alarm
INNER JOIN camera
ON camera.serial_no = camera_status_alarm.serial_no
AND camera.channel_no = camera_status_alarm.channel_no
WHERE
camera.delete = '0'
AND camera.recycle_time is null
AND alarmId IN (
SELECT camera_status_alarm.id AS alarmId
FROM camera_status_alarm
RIGHT JOIN ${anxinyun}.t_video_ipc
ON toString(${anxinyun}.t_video_ipc.channel_no) = camera_status_alarm.channel_no
AND ${anxinyun}.t_video_ipc.serial_no = camera_status_alarm.serial_no
${`WHERE ${anxinyun}.t_video_ipc.structure IN (${anxinStrucIds.join(',')}, -1)`}
)
${limit ? 'LIMIT ' + limit : ''}
${limit && page ? 'OFFSET ' + parseInt(limit) * parseInt(page) : ''}
) AS cameraAlarm
LEFT JOIN camera_status
ON cameraAlarm.platform = camera_status.platform
AND cameraAlarm.statusId = camera_status.id
LEFT JOIN camera_status_resolve
ON camera_status_resolve.status_id = camera_status.id
LEFT JOIN ${anxinyun}.t_video_ipc AS anxinIpc
ON toString(anxinIpc.channel_no) = cameraAlarm.cameraChannelNo
AND anxinIpc.serial_no = cameraAlarm.cameraSerialNo
LEFT JOIN ${anxinyun}.t_video_ipc_station AS anxinIpcStation
ON anxinIpcStation.ipc = anxinIpc.id
WHERE
cameraAlarm.confirmTime is null
`
).toPromise() : []
let returnD = []
let positionD = {}
// 每个设备一个告警
for (let a of video) {
if (!positionD[a.cameraId]) {
let d = {
cameraId: a.cameraId,
SourceName: a.cameraName,
StartTime: a.createTime,
alarmId: a.alarmId,
}
returnD.push(d)
positionD[a.cameraId] = {
positionReturnD: returnD.length - 1
}
}
}
returnD.forEach(v => {
v.groupName = '视频异常'
v.url = '/problem/dataAlarm/videoAbnormal'
})
let findOption = {
where: {
'$app->projectCorrelations.id$': {
$in: pomsProjectIds
},
confirmTime: null
},
attributes: ['createTime', 'type'],
include: [{
model: models.App,
where: {
},
attributes: ['id', 'name'],
include: [{
model: models.ProjectCorrelation,
where: {
},
attributes: ['id'],
}]
}]
}
const listRes = await models.AppAlarm.findAndCountAll(findOption)
let app = listRes.rows.map(v => ({ StartTime: v.createTime, SourceName: v.app.name, type: v.type }))
let typeData = { element: '元素异常', apiError: "接口报错", timeout: '加载超时' }
app.forEach(v => {
v.groupName = '应用异常'
v.url = '/problem/useAlarm/useAbnormal',
v.typeName = typeData[v.type]
})
let sum = [...alarmRes, ...returnD, ...app]
sum.sort((a, b) => {
if (moment(a.StartTime).isBefore(b.StartTime)) {
return 1
} else {
return -1
}
})
ctx.status = 200;
ctx.body = sum
} else {
ctx.body = []
}
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 getAlarmData (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
const { pepProjectId, startTime } = ctx.query
let anxinStruc = await anxinStrucIdRange({ ctx, pepProjectId })
let whereOption = []
if (anxinStruc.length) {
const anxinStrucIds = anxinStruc.map(a => a.strucId)
whereOption.push(`alarms.StructureId IN (${anxinStrucIds.join(",")})`)
if (startTime) {
whereOption.push(`alarms.StartTime >= '${moment(startTime).format('YYYY-MM-DD HH:mm:ss')}'`)
}
const alarmRes = await clickHouse.dataAlarm.query(`
SELECT
alarm.alarms.State AS State,
SourceName, StartTime, EndTime,AlarmGroup,AlarmGroupUnit,
alarms.StructureId AS StructureId,
${anxinyun}.t_structure.name AS StructureName
FROM
alarms
LEFT JOIN ${anxinyun}.t_structure
ON ${anxinyun}.t_structure.id = alarms.StructureId
${whereOption.length ? 'WHERE ' + whereOption.join(' AND ') : ''}
`).toPromise();
alarmRes.forEach(ar => {
ar.pomsProject = (
anxinStruc.find(as => as.strucId == ar.StructureId) ||
{
pomsProject: [
// TODO: 开发临时添加
]
}
).pomsProject
})
ctx.status = 200;
ctx.body = alarmRes
} else {
ctx.body = []
}
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 getAlarmVideo (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
const { pepProjectId, startTime } = ctx.query
let anxinStruc = await anxinStrucIdRange({ ctx, pepProjectId })
const anxinStrucIds = anxinStruc.map(a => a.strucId)
let statusAlarmWhereOption = []
if (startTime) {
statusAlarmWhereOption.push(`camera_status_alarm.create_time >= '${moment(startTime).format('YYYY-MM-DD HH:mm:ss')}'`)
}
const queryStr = `
SELECT
cameraAlarm.cameraId AS cameraId,
cameraAlarm.venderId AS venderId,
cameraAlarm.cameraSerialNo AS cameraSerialNo,
cameraAlarm.cameraChannelNo AS cameraChannelNo,
cameraAlarm.alarmId AS alarmId,
cameraAlarm.statusId AS statusId,
cameraAlarm.createTime AS createTime,
cameraAlarm.updateTime AS updateTime,
cameraAlarm.platform AS platform,
cameraAlarm.confirmContent AS confirmContent,
cameraAlarm.confirmTime AS confirmTime,
${'cameraAlarm.autoRestore AS autoRestore,'}
camera_status_resolve.id AS resolveId,
camera_status.describe AS statusDescribe,
camera_status_resolve.resolve AS resolve,
"gbCamera".online AS cameraOnline,
secret_yingshi.token AS yingshiToken,
anxinIpc.t_video_ipc.name AS anxinIpcPosition,
anxinStation.id AS anxinStationId,
anxinStation.name AS anxinStationName,
anxinStruc.name AS strucName,
anxinStruc.id AS strucId
FROM
(
SELECT
camera.id AS cameraId,
camera.gb_id AS gbId,
camera.vender_id AS venderId,
camera.yingshi_secret_id AS yingshiSecretId,
camera_status_alarm.id AS alarmId,
camera_status_alarm.create_time AS createTime,
camera_status_alarm.update_time AS updateTime,
camera_status_alarm.platform AS platform,
camera_status_alarm.status_id AS statusId,
camera_status_alarm.serial_no AS cameraSerialNo,
camera_status_alarm.channel_no AS cameraChannelNo,
camera_status_alarm.confirm AS confirmContent,
${'camera_status_alarm.auto_restore AS autoRestore,'}
camera_status_alarm.confirm_time AS confirmTime
FROM camera_status_alarm
INNER JOIN camera
ON camera.serial_no = camera_status_alarm.serial_no
AND camera.channel_no = camera_status_alarm.channel_no
LEFT JOIN vender
ON vender.id = camera.vender_id
WHERE
camera.delete = '0'
AND camera.recycle_time is null
${statusAlarmWhereOption.length ? 'AND ' + statusAlarmWhereOption.join(' AND ') : ''}
AND alarmId IN (
SELECT camera_status_alarm.id AS alarmId
FROM camera_status_alarm
RIGHT JOIN ${anxinyun}.t_video_ipc
ON toString(${anxinyun}.t_video_ipc.channel_no) = camera_status_alarm.channel_no
AND ${anxinyun}.t_video_ipc.serial_no = camera_status_alarm.serial_no
${`WHERE ${anxinyun}.t_video_ipc.structure IN (${anxinStrucIds.join(',')})`}
)
) AS cameraAlarm
LEFT JOIN camera_status
ON cameraAlarm.platform = camera_status.platform
AND cameraAlarm.statusId = camera_status.id
LEFT JOIN camera_status_resolve
ON camera_status_resolve.status_id = camera_status.id
LEFT JOIN "gbCamera"
ON "gbCamera".id = cameraAlarm.gbId
LEFT JOIN "secret_yingshi"
ON "secret_yingshi".id = cameraAlarm.yingshiSecretId
LEFT JOIN ${anxinyun}.t_video_ipc AS anxinIpc
ON toString(anxinIpc.channel_no) = cameraAlarm.cameraChannelNo
AND anxinIpc.serial_no = cameraAlarm.cameraSerialNo
LEFT JOIN ${anxinyun}.t_structure AS anxinStruc
ON anxinStruc.id = anxinIpc.structure
AND anxinStruc.id IN (${anxinStrucIds.join(',')})
LEFT JOIN ${anxinyun}.t_video_ipc_station AS anxinIpcStation
ON anxinIpcStation.ipc = anxinIpc.id
LEFT JOIN ${anxinyun}.t_sensor AS anxinStation
ON anxinStation.id = anxinIpcStation.station
`
const alarmRes = anxinStrucIds.length ? await clickHouse.vcmp.query(
queryStr
).toPromise() : []
console.log(queryStr);
let returnD = []
let positionD = {}
// 每个设备一个告警
for (let a of alarmRes) {
if (positionD[a.cameraId]) {
} else {
let d = {
createTime: a.createTime,
confirmTime: a.confirmTime,
statusId: a.statusId,
}
returnD.push(d)
positionD[a.cameraId] = {
positionReturnD: returnD.length - 1
}
}
}
ctx.status = 200;
ctx.body = returnD
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function getAlarmUse (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
const { utils: { anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs
const { pepProjectId, startTime } = ctx.query
let pomsProject = await pomsProjectRange({
ctx, pepProjectId,
keywordTarget: 'pepProject',
})
const pomsProjectIds = pomsProject.map(p => p.id)
let findOption = {
distinct: true,
where: {},
include: [{
model: models.App,
where: {},
attributes: {
exclude: ['projectId']
},
include: [{
model: models.ProjectCorrelation,
where: {},
attributes: {
exclude: ['createTime', 'createUser', 'anxinProjectId',]
},
}]
}]
}
if (startTime) {
findOption.where.createTime = { $gt: moment(startTime).format('YYYY-MM-DD HH:mm:ss') }
}
findOption.include[0].include[0].where.id = { $in: pomsProjectIds }
const listRes = await models.AppAlarm.findAll(findOption)
for (let lr of listRes) {
if (lr.app && lr.app.projectCorrelations) {
for (let p of lr.app.projectCorrelations) {
let corProjectCorrelations = pomsProject.find(pr => pr.id == p.id)
if (corProjectCorrelations) {
p.dataValues = corProjectCorrelations
}
}
}
}
ctx.status = 200;
ctx.body = listRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function getStatisticOnline (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
const { pepProjectId } = ctx.query
let anxinStruc = await anxinStrucIdRange({ ctx, pepProjectId })
if (anxinStruc.length) {
const anxinStrucIds = anxinStruc.map(a => a.strucId)
// 查在线率
const strucOnlineClient = ctx.app.fs.esclient.strucOnline
const onlineRes = anxinStrucIds.length ?
await strucOnlineClient.search({
index: strucOnlineClient.config.index,
type: strucOnlineClient.config.type,
body: {
"query": {
"bool": {
"filter": [
{
"range": {
"collect_time": {
"gte": `${moment().subtract(32, 'hours').format('YYYY-MM-DDTHH:mm:ss.SSS')}Z`,
// "gte": "2023-08-24T08:00:00.000Z",
}
}
},
{
"terms": {
"structure": anxinStrucIds,
// "structure": [1, 2, 3]
}
}
]
}
},
"sort": [
{
"collect_time": {
"order": "asc"
}
}
],
"size": 10000
}
})
: {
hits: {
hits: []
}
}
for (let struc of anxinStruc) {
let curOnline =
onlineRes.hits.hits
.filter((h) => h._source.structure == struc.strucId)
// .sort((a, b) => {
// return a._source.collect_time - b._source.collect_time
// })
.map(s => {
return {
...s._source,
rate: s._source.online / s._source.total * 100
}
})
struc.online = curOnline
}
ctx.status = 200;
ctx.body = anxinStruc;
} else {
ctx.status = 200;
ctx.body = [];
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function getStrucSeries (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
const { pepProjectId, strucId } = ctx.query
let anxinStruc = await anxinStrucIdRange({ ctx, pepProjectId })
if (anxinStruc.length) {
const anxinStrucIds = [strucId ? strucId : anxinStruc[0].strucId]
// 查在线率
const strucSeriesClient = ctx.app.fs.esclient.strucSeries
const seriesRes = anxinStrucIds.length ?
await strucSeriesClient.search({
index: strucSeriesClient.config.index,
type: strucSeriesClient.config.type,
body: {
"query": {
"bool": {
"filter": [
{
"range": {
"collect_time": {
"gte": `${moment().subtract(32, 'hours').format('YYYY-MM-DDTHH:mm:ss.SSS')}Z`,
// "gte": "2023-08-24T08:00:00.000Z",
}
}
},
{
"terms": {
"structure": anxinStrucIds,
// "structure": [1, 2, 3]
}
}
]
}
},
"sort": [
{
"collect_time": {
"order": "asc"
}
}
],
"size": 10000
}
})
: {
hits: {
hits: []
}
}
const sensor = anxinStrucIds.length ? await clickHouse.anxinyun.query(
`SELECT
id,structure,name
FROM t_sensor
INNER JOIN t_structure
ON t_structure.id = t_sensor.structure
WHERE
t_sensor.structure IN (${anxinStrucIds.join(',')})`
).toPromise() : []
for (let data of sensor) {
let curSeries =
seriesRes.hits.hits
.filter((h) => h._source.sensor == data.id)
.map(s => {
return {
...s._source,
}
})
let struc = anxinStruc.find((h) => h.strucId == data.structure)
data.series = curSeries
data.struc = struc
}
ctx.status = 200;
ctx.body = {
sensor: sensor || [],
anxinStruc: anxinStruc || []
};
} else {
ctx.status = 200;
ctx.body = {
sensor: [],
anxinStruc: []
};
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
personnelApp,
problem,
getAlarmData,
getAlarmVideo,
getAlarmUse,
getStatisticOnline,
getStrucSeries,
}