From c5ac7a13cda7686abf2a4d73ad3083292e85e118 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 23 Nov 2022 15:38:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=8E=A8=E9=80=81=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 1076 ++++++++++++++------------- 1 file changed, 550 insertions(+), 526 deletions(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index c8bd06b..96205d2 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -19,19 +19,23 @@ module.exports = function (app, opts) { del: false, disable: false }, - order: ['id'], - include: [{ - model: models.ProjectCorrelation, - where: { - del: false, - }, - required: true - }], + order: ['id'], }) + let pomsProjectId = new Set() let pepProjectIds = new Set() for (let { dataValues: c } of configListRes) { - if (c.projectCorrelation.pepProjectId) { - pepProjectIds.add(c.projectCorrelation.pepProjectId) + if (c.pomsProjectId) { + c.pomsProjectId.forEach(pid => pomsProjectId.add(pid)) + } + } + const pomsProjectRes = pomsProjectId.size ? await models.ProjectCorrelation.findAll({ + where: { + id: { $in: [...pomsProjectId] } + } + }) : [] + for (let { dataValues: c } of pomsProjectRes) { + if (c.pepProjectId) { + pepProjectIds.add(c.pepProjectId) } } const pepProjectRes = pepProjectIds.size ? @@ -55,29 +59,44 @@ module.exports = function (app, opts) { for (let { dataValues: c } of configListRes) { if (c.tacticsParams && c.tactics) { + // pomsProjectId 是个数组 [] const { projectCorrelation, strucId, pomsProjectId, } = c const { interval, deviceProportion } = c.tacticsParams if ( curMinOfYear % parseInt(interval) == 0 ) { - const corPepProject = projectCorrelation.pepProjectId ? - pepProjectRes.find(p => p.id == projectCorrelation.pepProjectId) - : null - if ( - !projectCorrelation.pepProjectId - || ( - corPepProject - && c.timeType.some(ct => ct == corPepProject.construction_status_id) - ) - ) { - const { anxinProjectId, pepProjectId } = projectCorrelation - // 查当前 poms 下的结构物 并把不包含的去掉 - // 可能有结构物已解绑 - const strucListRes = strucId.length && anxinProjectId.length ? - await clickHouse.anxinyun.query( - ` + const corPomsProject = pomsProjectRes.filter(poms => pomsProjectId.includes(poms.id)) + let curAnxinProjectId = new Set() + let pepProjectName_ = [] + for (let { dataValues: poms } of corPomsProject) { + if (poms.pepProjectId) { + // 找对应的项企项目 + const corPepProject = + pepProjectRes.find(p => p.id == poms.pepProjectId) + if (corPepProject && c.timeType.some(ct => ct == corPepProject.construction_status_id)) { + pepProjectName_.push(corPepProject.project_name) + } else { + // 不符合当前项目的时间节点 + continue + } + } else { + // 是自定义项目 + poms.name ? pepProjectName_.push(poms.name) : null + } + // 筛选全部的 anxinProjectId pepProjectId + for (let axId of poms.anxinProjectId) { + curAnxinProjectId.add(axId) + } + } + + const anxinProjectId = [...curAnxinProjectId] + // 查当前 poms 下的结构物 并把不包含的去掉 + // 可能有结构物已解绑 + const strucListRes = strucId.length && anxinProjectId.length ? + await clickHouse.anxinyun.query( + ` SELECT DISTINCT id, t_structure.id AS id, @@ -109,125 +128,130 @@ module.exports = function (app, opts) { project_state != -1 AND t_project.id IN (${anxinProjectId.join(',')}) AND t_structure.id IN (${strucId.join(',')}) - ` - ).toPromise() : - [] - let strucThingId = [] - let searchStrucIds = strucListRes.map(s => { - if (s.iotaThingId) { - strucThingId.push(s.iotaThingId) - } - return s.id - }) + ).toPromise() : + [] + let strucThingId = [] + let searchStrucIds = strucListRes.map(s => { + if (s.iotaThingId) { + strucThingId.push(s.iotaThingId) + } + return s.id + }) - // 开发测试用的数据 - // searchStrucIds = searchStrucIds.concat([991, 1052, 700]) + // !开发测试用的数据 + // searchStrucIds = searchStrucIds.concat([991, 1052, 700]) - if (searchStrucIds.length) { - searchStrucIds.unshift(-1) - } - let pepProjectName = pepProjectId ? - pepProjectRes.find(p => p.id == pepProjectId).project_name - : projectCorrelation.name - let emailTitle = `${pepProjectName}-${c.name}-` - let emailSubTitle = '' - - let dataAlarmOption = [] - let dataAlarmGroupOption = [] - let dataAlarmSubType = [] - let dataAlarms = [] - - let videoAlarmWhereOption = [] - let videoAlarms = [] - - let appAlarmWhereOption = { - confirmTime: null, - } - let appAlarms = [] - - let deviceCount = 0 - let alarmDeviceCount = 0 - let cameraCount = 0 - let alarmCameraCount = 0 - // 判断推送策略 - let nowTime = moment().startOf('minute') - let pointTime = - moment() - .subtract( - parseInt(interval), - // + 1440 * 365, - 'minute' - ) - .startOf('minute') - .format('YYYY-MM-DD HH:mm:ss') - - let newAddStartTime = pointTime - let newAddEndTime = nowTime.clone() - if (c.tactics == 'immediately') { - // !查所有未解决告警 所以时间范围大可不必 - // dataAlarmOption.push(`StartTime >= '${pointTime}'`); - // appAlarmWhereOption.createTime = { $gte: pointTime } - // videoAlarmWhereOption.push(`camera_status_alarm.create_time >= '${pointTime}'`) - emailTitle += `即时推送服务` - emailSubTitle += `截止${moment(pointTime).format('YYYY年MM月DD日 HH时mm分')}-${moment(nowTime).format('HH时mm分')}:` - } else if (c.tactics == 'continue' || c.tactics == 'abnormal_rate') { - // 新增的应该是上一个时间节点到上上个节点之间 - dataAlarmOption.push(`StartTime <= '${pointTime}'`); - appAlarmWhereOption.createTime = { $lte: pointTime } - videoAlarmWhereOption.push(`camera_status_alarm.create_time <= '${pointTime}'`) - // 新增的应该是上一个时间节点到上上个节点之间 - newAddStartTime = moment(pointTime).subtract(parseInt(interval)).format('YYYY-MM-DD HH:mm:ss') - newAddEndTime = pointTime - - if (c.tactics == 'continue') { - emailTitle += `持续时长推送服务` - emailSubTitle += `告警持续时长超${interval}分钟的告警源,详情如下:` - } else { - if (c.alarmType.includes('data_outages') || c.alarmType.includes('data_exception')) { - // 查了设备异常率 去安心云查当前项目下的设备数量 - let deviceCountRes = - strucThingId.length ? - await clickHouse.iot.query(` + if (searchStrucIds.length) { + searchStrucIds.unshift(-1) + } else { + // 没有结构物可查 + continue + } + let pepProjectName = + pepProjectName_.length ? + pepProjectName_.join('
') + : '' + + let emailTitle = `${pepProjectName_.length ? + pepProjectName_.join('、') + : ''}-${c.name}-` + let emailSubTitle = '' + + let dataAlarmOption = [] + let dataAlarmGroupOption = [] + let dataAlarmSubType = [] + let dataAlarms = [] + + let videoAlarmWhereOption = [] + let videoAlarms = [] + + let appAlarmWhereOption = { + confirmTime: null, + } + let appAlarms = [] + + let deviceCount = 0 + let alarmDeviceCount = 0 + let cameraCount = 0 + let alarmCameraCount = 0 + // 判断推送策略 + let nowTime = moment().startOf('minute') + let pointTime = + moment() + .subtract( + parseInt(interval), + // + 1440 * 365, + 'minute' + ) + .startOf('minute') + .format('YYYY-MM-DD HH:mm:ss') + + let newAddStartTime = pointTime + let newAddEndTime = nowTime.clone() + if (c.tactics == 'immediately') { + // !查所有未解决告警 所以时间范围大可不必 + // dataAlarmOption.push(`StartTime >= '${pointTime}'`); + // appAlarmWhereOption.createTime = { $gte: pointTime } + // videoAlarmWhereOption.push(`camera_status_alarm.create_time >= '${pointTime}'`) + emailTitle += `即时推送服务` + emailSubTitle += `截止${moment(pointTime).format('YYYY年MM月DD日 HH时mm分')}-${moment(nowTime).format('HH时mm分')}:` + } else if (c.tactics == 'continue' || c.tactics == 'abnormal_rate') { + // 新增的应该是上一个时间节点到上上个节点之间 + dataAlarmOption.push(`StartTime <= '${pointTime}'`); + appAlarmWhereOption.createTime = { $lte: pointTime } + videoAlarmWhereOption.push(`camera_status_alarm.create_time <= '${pointTime}'`) + // 新增的应该是上一个时间节点到上上个节点之间 + newAddStartTime = moment(pointTime).subtract(parseInt(interval)).format('YYYY-MM-DD HH:mm:ss') + newAddEndTime = pointTime + + if (c.tactics == 'continue') { + emailTitle += `持续时长推送服务` + emailSubTitle += `告警持续时长超${interval}分钟的告警源,详情如下:` + } else { + if (c.alarmType.includes('data_outages') || c.alarmType.includes('data_exception')) { + // 查了设备异常率 去安心云查当前项目下的设备数量 + let deviceCountRes = + strucThingId.length ? + await clickHouse.iot.query(` SELECT count(DeviceId) AS count FROM device WHERE ThingId IN (${strucThingId.map(t => `'${t}'`).join(',')}, '-1') `).toPromise() - : [] - deviceCount = deviceCountRes.length ? deviceCountRes[0].count : 0 - } - if (c.alarmType.includes('video_exception')) { - // 查了视频异常 去安心云查 接入的 萤石 设备数量 - cameraCount = searchStrucIds.length ? - (await clickHouse.anxinyun.query(` + : [] + deviceCount = deviceCountRes.length ? deviceCountRes[0].count : 0 + } + if (c.alarmType.includes('video_exception')) { + // 查了视频异常 去安心云查 接入的 萤石 设备数量 + cameraCount = searchStrucIds.length ? + (await clickHouse.anxinyun.query(` SELECT count(*) AS count FROM t_video_ipc WHERE structure IN (${searchStrucIds.join(',')}) `).toPromise())[0].count - : 0 - } - emailTitle += `异常率推送服务` - emailSubTitle += `持续产生时间超过${interval}分钟的异常设备数量${interval}个,异常率达到项目或结构物内设备总数量${parseInt(deviceCount) + parseInt(cameraCount)}个的 --%,详情如下` + : 0 } + emailTitle += `异常率推送服务` + emailSubTitle += `持续产生时间超过${interval}分钟的异常设备数量${interval}个,异常率达到项目或结构物内设备总数量${parseInt(deviceCount) + parseInt(cameraCount)}个的 --%,详情如下` } - emailTitle += '——POMS飞尚运维中台' - - // 判断告警数据范围 - if (c.alarmType.includes('data_outages')) { - dataAlarmGroupOption.push(1) - if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['data_outages']) - } - if (c.alarmType.includes('data_exception')) { - dataAlarmGroupOption.push(2) - if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['data_exception']) + } + emailTitle += '——POMS飞尚运维中台' - } - if (c.alarmType.includes('strategy_hit')) { - dataAlarmGroupOption.push(3) - if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['strategy_hit']) - } - if (c.alarmType.includes('video_exception')) { - let videoAlarmSubType = c.alarmSubType ? c.alarmSubType['data_exception'] : [] - if (videoAlarmSubType.length == 1) videoAlarmSubType.push(-1) - videoAlarms = searchStrucIds.length && videoAlarmSubType.length ? await clickHouse.vcmp.query( - ` + // 判断告警数据范围 + if (c.alarmType.includes('data_outages')) { + dataAlarmGroupOption.push(1) + if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['data_outages']) + } + if (c.alarmType.includes('data_exception')) { + dataAlarmGroupOption.push(2) + if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['data_exception']) + } + if (c.alarmType.includes('strategy_hit')) { + dataAlarmGroupOption.push(3) + if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['strategy_hit']) + } + if (c.alarmType.includes('video_exception')) { + let videoAlarmSubType = c.alarmSubType ? c.alarmSubType['data_exception'] : [] + if (videoAlarmSubType.length == 1) videoAlarmSubType.push(-1) + videoAlarms = searchStrucIds.length && videoAlarmSubType.length ? await clickHouse.vcmp.query( + ` SELECT cameraAlarm.cameraId AS cameraId, cameraAlarm.cameraName AS cameraName, @@ -294,107 +318,107 @@ module.exports = function (app, opts) { ON anxinStation.id = anxinIpcStation.station ORDER BY cameraAlarm.createTime DESC ` - ).toPromise() : [] - - let returnD = [] - let positionD = {} - // 每个设备一个告警 - for (let a of videoAlarms) { - if (positionD[a.cameraId]) { - let curD = returnD[positionD[a.cameraId].positionReturnD] - - if (a.strucId && !curD.struc.some(s => s.id == a.strucId)) { - curD.struc.push({ - id: a.strucId, - projectId: a.projectId, - name: a.strucName - }) - } - if (a.anxinStationId && !curD.station.some(s => s.id == a.anxinStationId)) { - curD.station.push({ - id: a.anxinStationId, - name: a.anxinStationName, - position: a.anxinIpcPosition - }) - } - } else { - let d = { - cameraId: a.cameraId, - cameraName: a.cameraName, - camerOnline: a.cameraOnline, - cameraSerialNo: a.cameraSerialNo, - cameraChannelNo: a.cameraChannelNo, - autoRestore: a.autoRestore, - createTime: a.createTime, - updateTime: a.updateTime, - platform: a.platform, - statusDescribe: a.statusDescribe, - alarmId: a.alarmId, - confirmContent: a.confirmContent, - confirmTime: a.confirmTime, - cameraKind: a.cameraKind, - struc: [], - station: [] - } - - if (a.strucId) { - d.struc.push({ - id: a.strucId, - projectId: a.projectId, - name: a.strucName - }) - } - if (a.anxinStationId) { - d.station.push({ - id: a.anxinStationId, - name: a.anxinStationName, - position: a.anxinIpcPosition - }) - } - returnD.push(d) - positionD[a.cameraId] = { - positionReturnD: returnD.length - 1 - } + ).toPromise() : [] + + let returnD = [] + let positionD = {} + // 每个设备一个告警 + for (let a of videoAlarms) { + if (positionD[a.cameraId]) { + let curD = returnD[positionD[a.cameraId].positionReturnD] + + if (a.strucId && !curD.struc.some(s => s.id == a.strucId)) { + curD.struc.push({ + id: a.strucId, + projectId: a.projectId, + name: a.strucName + }) + } + if (a.anxinStationId && !curD.station.some(s => s.id == a.anxinStationId)) { + curD.station.push({ + id: a.anxinStationId, + name: a.anxinStationName, + position: a.anxinIpcPosition + }) + } + } else { + let d = { + cameraId: a.cameraId, + cameraName: a.cameraName, + camerOnline: a.cameraOnline, + cameraSerialNo: a.cameraSerialNo, + cameraChannelNo: a.cameraChannelNo, + autoRestore: a.autoRestore, + createTime: a.createTime, + updateTime: a.updateTime, + platform: a.platform, + statusDescribe: a.statusDescribe, + alarmId: a.alarmId, + confirmContent: a.confirmContent, + confirmTime: a.confirmTime, + cameraKind: a.cameraKind, + struc: [], + station: [] + } + + if (a.strucId) { + d.struc.push({ + id: a.strucId, + projectId: a.projectId, + name: a.strucName + }) + } + if (a.anxinStationId) { + d.station.push({ + id: a.anxinStationId, + name: a.anxinStationName, + position: a.anxinIpcPosition + }) + } + returnD.push(d) + positionD[a.cameraId] = { + positionReturnD: returnD.length - 1 } } - let p = 1 - videoAlarms = returnD } - if (c.alarmType.includes('app_exception')) { - if (c.alarmSubType) { - appAlarmWhereOption.type = { $in: c.alarmSubType['app_exception'] || [] } - } - appAlarms = c.alarmSubType && c.alarmSubType['app_exception'].length ? await models.AppAlarm.findAll({ - where: appAlarmWhereOption, - order: [['createTime', 'DESC']], + let p = 1 + videoAlarms = returnD + } + if (c.alarmType.includes('app_exception')) { + if (c.alarmSubType) { + appAlarmWhereOption.type = { $in: c.alarmSubType['app_exception'] || [] } + } + appAlarms = c.alarmSubType && c.alarmSubType['app_exception'].length ? await models.AppAlarm.findAll({ + where: appAlarmWhereOption, + order: [['createTime', 'DESC']], + include: [{ + model: models.App, + required: true, include: [{ - model: models.App, + model: models.ProjectApp, + where: { + projectId: { $in: pomsProjectId } + }, required: true, - include: [{ - model: models.ProjectApp, - where: { - projectId: pomsProjectId - }, - required: true, - }] }] - }) : [] - } - if (c.alarmType.includes('device_exception')) { - dataAlarmGroupOption.push(4) - dataAlarmGroupOption.push(5) - if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['device_exception']) - } + }] + }) : [] + } + if (c.alarmType.includes('device_exception')) { + dataAlarmGroupOption.push(4) + dataAlarmGroupOption.push(5) + if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['device_exception']) + } - // 查数据告警 三警合一 - if (dataAlarmGroupOption.length && searchStrucIds.length) { - dataAlarmGroupOption.push(-1) - dataAlarmOption.push(`AlarmGroup IN (${dataAlarmGroupOption.join(',')})`) - if (c.alarmSubType && dataAlarmSubType.length) { - dataAlarmSubType.push(-1) - dataAlarmOption.push(`AlarmGroupUnit IN (${dataAlarmSubType.join(',')})`) - } - dataAlarms = (!c.alarmSubType || dataAlarmSubType.length) ? await clickHouse.dataAlarm.query(` + // 查数据告警 三警合一 + if (dataAlarmGroupOption.length && searchStrucIds.length) { + dataAlarmGroupOption.push(-1) + dataAlarmOption.push(`AlarmGroup IN (${dataAlarmGroupOption.join(',')})`) + if (c.alarmSubType && dataAlarmSubType.length) { + dataAlarmSubType.push(-1) + dataAlarmOption.push(`AlarmGroupUnit IN (${dataAlarmSubType.join(',')})`) + } + dataAlarms = (!c.alarmSubType || dataAlarmSubType.length) ? await clickHouse.dataAlarm.query(` SELECT * FROM alarms WHERE ${`State NOT IN (3, 4) AND `} @@ -402,235 +426,235 @@ module.exports = function (app, opts) { ${dataAlarmOption.length ? ' AND ' + dataAlarmOption.join(' AND ') : ''} ORDER BY StartTime DESC `).toPromise() : [] - console.log(dataAlarms); - } + console.log(dataAlarms); + } - let dataAlarmTitle = [{ - n: '项目', - k: '', - v: pepProjectName - }, { - n: '结构物', - k: '', - f: (d) => { - return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name - } - }, { - n: '告警源名称', - k: 'SourceName' - }, { - n: '告警源类型', - k: '', - f: (d) => { - switch (d.SourceTypeId) { - case 0: - return 'DTU' - case 1: - return '传感器' - case 2: - return '测点' - default: - return '' - } - } - }, { - n: '告警信息', - k: 'AlarmContent' - }, { - n: '告警等级(当前)', - k: '', - f: (d) => { - switch (d.CurrentLevel) { - case 1: - return '一级' - case 2: - return '二级' - case 3: - return '三级' - default: - return '' - } - } - }, { - n: '持续时间', - k: '', - f: (d) => { - return d.StartTime ? - '超过' + moment().diff(moment(d.StartTime), 'minutes') + '分钟' : '' - } - },] - - let videoAlarmTitle = [{ - n: '项目', - k: '', - v: pepProjectName - }, { - n: '结构物', - k: '', - f: (d) => { - return d.struc.map(ds => ds.name).join('、') - } - }, { - n: '告警源名称', - k: 'cameraName' - }, { - n: '告警源类型', - k: 'cameraKind' - }, { - n: '序列号', - k: 'cameraSerialNo' - }, { - n: '通道号', - k: 'cameraChannelNo' - }, { - n: '测点', - k: '', - f: (d) => { - return d.station.map(ds => ds.name).join('、') - } - }, { - n: '位置', - k: '', - f: (d) => { - return d.station.map(ds => ds.position).join('、') - } - }, { - n: '告警信息', - k: 'statusDescribe' - }, { - n: '持续时间', - k: '', - f: (d) => { - return d.createTime ? - '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' - } - },] - - let appAlarmTitle = [{ - n: '项目', - k: '', - v: pepProjectName - }, { - n: '应用名称', - k: '', - f: (d) => { - return d.app ? d.app.name : '' - } - }, { - n: '异常类型', - k: '', - f: (d) => { - if (d.type == 'element') { - return '元素异常' - } else if (d.type == 'apiError') { - return '接口报错' - } else { + let dataAlarmTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '结构物', + k: '', + f: (d) => { + return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name + } + }, { + n: '告警源名称', + k: 'SourceName' + }, { + n: '告警源类型', + k: '', + f: (d) => { + switch (d.SourceTypeId) { + case 0: + return 'DTU' + case 1: + return '传感器' + case 2: + return '测点' + default: return '' - } } - }, { - n: '异常信息', - k: 'alarmContent' - }, { - n: 'URL地址', - k: 'cameraName', - f: (d) => { - return d.app && d.app.url ? `${d.app.url}` : '' + } + }, { + n: '告警信息', + k: 'AlarmContent' + }, { + n: '告警等级(当前)', + k: '', + f: (d) => { + switch (d.CurrentLevel) { + case 1: + return '一级' + case 2: + return '二级' + case 3: + return '三级' + default: + return '' } - }, { - n: '持续时间', - k: '', - f: (d) => { - return d.createTime ? - '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' + } + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.StartTime ? + '超过' + moment().diff(moment(d.StartTime), 'minutes') + '分钟' : '' + } + },] + + let videoAlarmTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '结构物', + k: '', + f: (d) => { + return d.struc.map(ds => ds.name).join('、') + } + }, { + n: '告警源名称', + k: 'cameraName' + }, { + n: '告警源类型', + k: 'cameraKind' + }, { + n: '序列号', + k: 'cameraSerialNo' + }, { + n: '通道号', + k: 'cameraChannelNo' + }, { + n: '测点', + k: '', + f: (d) => { + return d.station.map(ds => ds.name).join('、') + } + }, { + n: '位置', + k: '', + f: (d) => { + return d.station.map(ds => ds.position).join('、') + } + }, { + n: '告警信息', + k: 'statusDescribe' + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.createTime ? + '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' + } + },] + + let appAlarmTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '应用名称', + k: '', + f: (d) => { + return d.app ? d.app.name : '' + } + }, { + n: '异常类型', + k: '', + f: (d) => { + if (d.type == 'element') { + return '元素异常' + } else if (d.type == 'apiError') { + return '接口报错' + } else { + return '' } - },] + } + }, { + n: '异常信息', + k: 'alarmContent' + }, { + n: 'URL地址', + k: 'cameraName', + f: (d) => { + return d.app && d.app.url ? `${d.app.url}` : '' + } + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.createTime ? + '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' + } + },] - let ifEmailSend = false - let tableTitlePostfix = ',详情如下:' + let ifEmailSend = false + let tableTitlePostfix = ',详情如下:' - function packageTableTitle (titleArr) { - let tableTitle = '' - for (let t of titleArr) { - tableTitle += `${t.n}` - } - tableTitle += '' - return tableTitle + function packageTableTitle (titleArr) { + let tableTitle = '' + for (let t of titleArr) { + tableTitle += `${t.n}` } - function packageTableData (data, titleArr) { - let tableData = '' - for (let t of titleArr) { - if (t.v) { - tableData += `${t.v}` - } else if (t.f) { - tableData += `${t.f(data)}` - } else if (t.k) { - tableData += `${data[t.k]}` - } else { - tableData += `` - } + tableTitle += '' + return tableTitle + } + function packageTableData (data, titleArr) { + let tableData = '' + for (let t of titleArr) { + if (t.v) { + tableData += `${t.v}` + } else if (t.f) { + tableData += `${t.f(data)}` + } else if (t.k) { + tableData += `${data[t.k]}` + } else { + tableData += `` } - tableData += '' - return tableData } + tableData += '' + return tableData + } - function packageAlarmData2Table (titlePrefix, alarmData, alarmTitleArr, keyOfStartTime = 'StartTime') { - if (!alarmData.length) { - return '' - } - ifEmailSend = true - let tableTitlePrefix = titlePrefix + '告警源' - let newAddCount = 0 - let alarmHtml = '' - let alarmContent = '' - let alarmHtmlTitle = packageTableTitle(alarmTitleArr) - - for (let a of alarmData) { - alarmContent += packageTableData(a, alarmTitleArr) - if (a[keyOfStartTime] && moment(a[keyOfStartTime]).isBetween(newAddStartTime, newAddEndTime)) { - newAddCount++ - } - } - tableTitlePrefix += - c.tactics == 'abnormal_rate' ? - `${alarmData.length}个` : - `新增${newAddCount}个,未解决累计${alarmData.length}个` + tableTitlePostfix - alarmHtml += `' - alarmHtml += alarmHtmlTitle - alarmHtml += alarmContent - alarmHtml += '
` + tableTitlePrefix + '

' - - return alarmHtml + function packageAlarmData2Table (titlePrefix, alarmData, alarmTitleArr, keyOfStartTime = 'StartTime') { + if (!alarmData.length) { + return '' } - - let dataAlarmG1 = []; - let dataAlarmG2 = []; - let dataAlarmG3 = []; - let dataAlarmG45 = []; - let deviceStatistic = new Set() - for (let d of dataAlarms) { - if (d.AlarmGroup == 1) { - dataAlarmG1.push(d) - } else if (d.AlarmGroup == 2) { - dataAlarmG2.push(d) - } else if (d.AlarmGroup == 3) { - dataAlarmG3.push(d) - } else if (d.AlarmGroup == 4 || d.AlarmGroup == 5) { - dataAlarmG45.push(d) + ifEmailSend = true + let tableTitlePrefix = titlePrefix + '告警源' + let newAddCount = 0 + let alarmHtml = '' + let alarmContent = '' + let alarmHtmlTitle = packageTableTitle(alarmTitleArr) + + for (let a of alarmData) { + alarmContent += packageTableData(a, alarmTitleArr) + if (a[keyOfStartTime] && moment(a[keyOfStartTime]).isBetween(newAddStartTime, newAddEndTime)) { + newAddCount++ } - deviceStatistic.add(d.SourceId) } - if (c.tactics == 'abnormal_rate') { - let rate = ((deviceStatistic.size + videoAlarms.length) / (parseInt(deviceCount) + parseInt(cameraCount))); + tableTitlePrefix += + c.tactics == 'abnormal_rate' ? + `${alarmData.length}个` : + `新增${newAddCount}个,未解决累计${alarmData.length}个` + tableTitlePostfix + alarmHtml += `' + alarmHtml += alarmHtmlTitle + alarmHtml += alarmContent + alarmHtml += '
` + tableTitlePrefix + '

' + + return alarmHtml + } - if (rate < parseFloat(deviceProportion)) { - continue - } + let dataAlarmG1 = []; + let dataAlarmG2 = []; + let dataAlarmG3 = []; + let dataAlarmG45 = []; + let deviceStatistic = new Set() + for (let d of dataAlarms) { + if (d.AlarmGroup == 1) { + dataAlarmG1.push(d) + } else if (d.AlarmGroup == 2) { + dataAlarmG2.push(d) + } else if (d.AlarmGroup == 3) { + dataAlarmG3.push(d) + } else if (d.AlarmGroup == 4 || d.AlarmGroup == 5) { + dataAlarmG45.push(d) + } + deviceStatistic.add(d.SourceId) + } + if (c.tactics == 'abnormal_rate') { + let rate = ((deviceStatistic.size + videoAlarms.length) / (parseInt(deviceCount) + parseInt(cameraCount))); - emailSubTitle = emailSubTitle.replace('--%', rate.toFixed(1) + '%') + if (rate < parseFloat(deviceProportion)) { + continue } - let html = ` + + emailSubTitle = emailSubTitle.replace('--%', rate.toFixed(1) + '%') + } + let html = ` @@ -649,99 +673,99 @@ module.exports = function (app, opts) {
${emailSubTitle}
` - if (c.alarmType.includes('data_outages')) { - html += packageAlarmData2Table( - '数据中断', - dataAlarmG1, - dataAlarmTitle, - ) - } - if (c.alarmType.includes('data_exception')) { - html += packageAlarmData2Table( - '数据异常', - dataAlarmG2, - dataAlarmTitle, - ) - } - if (c.alarmType.includes('strategy_hit')) { - html += packageAlarmData2Table( - '策略命中', - dataAlarmG3, - dataAlarmTitle, - ) - } - if (c.alarmType.includes('video_exception')) { - html += packageAlarmData2Table( - '视频异常', - videoAlarms, - videoAlarmTitle, - 'createTime', - ) - } - if (c.alarmType.includes('app_exception')) { - html += packageAlarmData2Table( - '应用异常', - appAlarms, - appAlarmTitle, - 'createTime', - ) - } - if (c.alarmType.includes('device_exception')) { - html += packageAlarmData2Table( - '设备异常', - dataAlarmG45, - dataAlarmTitle, - ) - } + if (c.alarmType.includes('data_outages')) { + html += packageAlarmData2Table( + '数据中断', + dataAlarmG1, + dataAlarmTitle, + ) + } + if (c.alarmType.includes('data_exception')) { + html += packageAlarmData2Table( + '数据异常', + dataAlarmG2, + dataAlarmTitle, + ) + } + if (c.alarmType.includes('strategy_hit')) { + html += packageAlarmData2Table( + '策略命中', + dataAlarmG3, + dataAlarmTitle, + ) + } + if (c.alarmType.includes('video_exception')) { + html += packageAlarmData2Table( + '视频异常', + videoAlarms, + videoAlarmTitle, + 'createTime', + ) + } + if (c.alarmType.includes('app_exception')) { + html += packageAlarmData2Table( + '应用异常', + appAlarms, + appAlarmTitle, + 'createTime', + ) + } + if (c.alarmType.includes('device_exception')) { + html += packageAlarmData2Table( + '设备异常', + dataAlarmG45, + dataAlarmTitle, + ) + } - if (ifEmailSend) { - // 查接收人的信息 - const receiverRes = - c.receiverPepUserId.length ? - await clickHouse.pepEmis.query(` + if (ifEmailSend) { + // 查接收人的信息 + const receiverRes = + c.receiverPepUserId.length ? + await clickHouse.pepEmis.query(` SELECT id, name, email FROM user WHERE id IN (${c.receiverPepUserId.join(',')},-1) `).toPromise() - : [] - let receiverId = [] - const emails = receiverRes.reduce((arr, r) => { - if (r.email) { - arr.push(r.email) - receiverId.push({ id: r.id, name: r.name }) - } - return arr - }, []) - if (emails.length) { - await pushByEmail({ - email: emails, - title: emailTitle, - text: '', - html: html - }) - - //存日志 存动态 socket到前端 - let dataToSave = { - time: moment().format(), - pushConfigId: c.id, - cfgName: c.name,//策略名称 - tactics: c.tactics, - tacticsParams: c.tacticsParams, - projectCorrelationId: pomsProjectId, - toPepUserIds: receiverId.map(r => r.id) - } - let r = await models.EmailSendLog.create(dataToSave, { returning: true }) + : [] + let receiverId = [] + let emails = receiverRes.reduce((arr, r) => { + if (r.email) { + arr.push(r.email) + receiverId.push({ id: r.id, name: r.name }) + } + return arr + }, []) + // emails = ['1650192445@qq.com'] + if (emails.length) { + await pushByEmail({ + email: emails, + title: emailTitle, + text: '', + html: html + }) + + //存日志 存动态 socket到前端 + let dataToSave = { + time: moment().format(), + pushConfigId: c.id, + cfgName: c.name,//策略名称 + tactics: c.tactics, + tacticsParams: c.tacticsParams, + projectCorrelationId: pomsProjectId, + toPepUserIds: receiverId.map(r => r.id) + } + let r = await models.EmailSendLog.create(dataToSave, { returning: true }) - let dynamic = { - time: r.dataValues.time, - emailSendId: r.dataValues.id, - projectCorrelationId: r.dataValues.projectCorrelationId, - type: 2//通知 - } - await models.LatestDynamicList.create(dynamic); + let dynamic = { + time: r.dataValues.time, + emailSendId: r.dataValues.id, + projectCorrelationId: r.dataValues.projectCorrelationId, + type: 2//通知 + } + await models.LatestDynamicList.create(dynamic); - //消息推送到前端 - await sendNoticeToWeb(receiverId, dataToSave); - } + //消息推送到前端 + await sendNoticeToWeb(receiverId, dataToSave); } } }