|
|
|
'use strict';
|
|
|
|
const fs = require('fs');
|
|
|
|
const moment = require('moment')
|
|
|
|
const { alarmConfirmLog } = require('./alarmConfirmLog');
|
|
|
|
async function deviceType (ctx) {
|
|
|
|
try {
|
|
|
|
const { models } = ctx.fs.dc;
|
|
|
|
const { clickHouse } = ctx.app.fs
|
|
|
|
const { database: anxinyun } = clickHouse.anxinyun.opts.config
|
|
|
|
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
|
|
|
|
let anxinStruc = await anxinStrucIdRange({
|
|
|
|
ctx,
|
|
|
|
})
|
|
|
|
const anxinStrucIds = anxinStruc.map(a => a.strucId)
|
|
|
|
|
|
|
|
const kindRes = await clickHouse.vcmp.query(`
|
|
|
|
SELECT DISTINCT
|
|
|
|
camera_kind.id AS id,camera_kind.kind AS kind
|
|
|
|
FROM camera_kind
|
|
|
|
INNER JOIN camera
|
|
|
|
ON camera_kind.id = camera.kind_id
|
|
|
|
INNER JOIN camera_status_alarm
|
|
|
|
ON camera.channel_no = camera_status_alarm.channel_no
|
|
|
|
AND camera.serial_no = camera_status_alarm.serial_no
|
|
|
|
INNER 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(',')})`}
|
|
|
|
`).toPromise()
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.body = kindRes
|
|
|
|
} catch (error) {
|
|
|
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
|
|
|
|
ctx.status = 400;
|
|
|
|
ctx.body = {
|
|
|
|
message: typeof error == 'string' ? error : undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function exceptionType(ctx) {
|
|
|
|
try {
|
|
|
|
const { models } = ctx.fs.dc;
|
|
|
|
const { clickHouse } = ctx.app.fs
|
|
|
|
const { database: anxinyun } = clickHouse.anxinyun.opts.config
|
|
|
|
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
|
|
|
|
let anxinStruc = await anxinStrucIdRange({
|
|
|
|
ctx,
|
|
|
|
})
|
|
|
|
const anxinStrucIds = anxinStruc.map(a => a.strucId)
|
|
|
|
|
|
|
|
const statusRes = await clickHouse.vcmp.query(`
|
|
|
|
SELECT DISTINCT
|
|
|
|
camera_status.id AS statusId,camera_status.describe AS describe
|
|
|
|
FROM camera_status
|
|
|
|
INNER JOIN camera_status_alarm
|
|
|
|
ON camera_status.id = camera_status_alarm.status_id
|
|
|
|
INNER 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(',')})`}
|
|
|
|
`).toPromise()
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.body = statusRes
|
|
|
|
} catch (error) {
|
|
|
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
|
|
|
|
ctx.status = 400;
|
|
|
|
ctx.body = {
|
|
|
|
message: typeof error == 'string' ? error : undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function alarmList (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, keywordTarget, keyword, state, kindId, sustainTimeStart, sustainTimeEnd, limit, page, statusId, toExport } = ctx.query
|
|
|
|
|
|
|
|
let anxinStruc = await anxinStrucIdRange({
|
|
|
|
ctx, pepProjectId, keywordTarget, keyword
|
|
|
|
})
|
|
|
|
const anxinStrucIds = anxinStruc.map(a => a.strucId)
|
|
|
|
|
|
|
|
let cameraWhereOption = []
|
|
|
|
if (keywordTarget == 'source' && keyword) {
|
|
|
|
cameraWhereOption.push(`camera.name LIKE '%${keyword}%'`)
|
|
|
|
}
|
|
|
|
if (state) {
|
|
|
|
if (state == 'new') {
|
|
|
|
cameraWhereOption.push(`camera_status_alarm.confirm_time IS null`)
|
|
|
|
} else if (state == 'histroy') {
|
|
|
|
cameraWhereOption.push(`camera_status_alarm.confirm_time IS NOT null`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (kindId) {
|
|
|
|
let sql = `camera.kind_id = ${kindId}`
|
|
|
|
if (kindId == 1314) {
|
|
|
|
sql = `(camera.kind_id = ${kindId} OR camera.kind_id IS null)`
|
|
|
|
}
|
|
|
|
cameraWhereOption.push(sql)
|
|
|
|
}
|
|
|
|
|
|
|
|
let statusAlarmWhereOption = []
|
|
|
|
if (sustainTimeStart && sustainTimeEnd) {
|
|
|
|
let momentStart = moment(sustainTimeStart).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
let momentEnd = moment(sustainTimeEnd).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
statusAlarmWhereOption.push(`
|
|
|
|
(
|
|
|
|
camera_status_alarm.create_time
|
|
|
|
BETWEEN '${momentStart}' AND '${momentEnd}'
|
|
|
|
OR
|
|
|
|
camera_status_alarm.update_time BETWEEN '${momentStart}' AND '${momentEnd}'
|
|
|
|
OR (
|
|
|
|
camera_status_alarm.create_time <= '${momentStart}'
|
|
|
|
AND
|
|
|
|
camera_status_alarm.update_time >= '${momentEnd}'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
`)
|
|
|
|
}
|
|
|
|
if (statusId) {
|
|
|
|
statusAlarmWhereOption.push(`camera_status_alarm.status_id = ${statusId}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
const queryStr = `
|
|
|
|
SELECT
|
|
|
|
cameraAlarm.cameraId AS cameraId,
|
|
|
|
cameraAlarm.cameraName AS cameraName,
|
|
|
|
cameraAlarm.cameraKindId AS cameraKindId,
|
|
|
|
cameraAlarm.venderId AS venderId,
|
|
|
|
cameraAlarm.venderName AS venderName,
|
|
|
|
cameraAlarm.cameraSerialNo AS cameraSerialNo,
|
|
|
|
cameraAlarm.cameraChannelNo AS cameraChannelNo,
|
|
|
|
cameraAlarm.alarmId AS alarmId,
|
|
|
|
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.name AS cameraName,
|
|
|
|
camera.kind_id AS cameraKindId,
|
|
|
|
camera.vender_id AS venderId,
|
|
|
|
camera.yingshi_secret_id AS yingshiSecretId,
|
|
|
|
vender.name AS venderName,
|
|
|
|
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
|
|
|
|
${cameraWhereOption.length ? 'AND ' + cameraWhereOption.join(' AND ') : ''}
|
|
|
|
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(',')})`}
|
|
|
|
)
|
|
|
|
${!toExport && limit ? 'LIMIT ' + limit : ''}
|
|
|
|
${!toExport && 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 "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(',')})
|
|
|
|
${keywordTarget == 'struc' && keyword ? `AND anxinStruc.name LIKE '%${keyword}%'` : ''}
|
|
|
|
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]) {
|
|
|
|
let curD = returnD[positionD[a.cameraId].positionReturnD]
|
|
|
|
if (a.resolveId && !curD.resolve.some(r => r.id == a.resolveId)) {
|
|
|
|
curD.resolve.push({
|
|
|
|
id: a.resolveId,
|
|
|
|
resolve: a.resolve
|
|
|
|
})
|
|
|
|
}
|
|
|
|
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,
|
|
|
|
|
|
|
|
venderId: a.venderId,
|
|
|
|
venderName: a.venderName,
|
|
|
|
cameraKindId: a.cameraKindId,
|
|
|
|
yingshiToken: a.yingshiToken,
|
|
|
|
|
|
|
|
resolve: [],
|
|
|
|
struc: [],
|
|
|
|
station: []
|
|
|
|
}
|
|
|
|
|
|
|
|
// pep 项目
|
|
|
|
d.pomsProject = (
|
|
|
|
anxinStruc.find(as => as.strucId == a.strucId) ||
|
|
|
|
{
|
|
|
|
pomsProject: [
|
|
|
|
|
|
|
|
]
|
|
|
|
}
|
|
|
|
).pomsProject
|
|
|
|
|
|
|
|
if (a.resolveId) {
|
|
|
|
d.resolve.push({
|
|
|
|
id: a.resolveId,
|
|
|
|
resolve: a.resolve
|
|
|
|
})
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (toExport) {//数据导出相关
|
|
|
|
await exportVideoAlarms(ctx, returnD);
|
|
|
|
} else {
|
|
|
|
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 exportVideoAlarms (ctx, alarmList) {
|
|
|
|
let accessType = { yingshi: "萤石云", nvr: "NVR", ipc: "IPC", cascade: "级联" }
|
|
|
|
try {
|
|
|
|
const { clickHouse, utils: { simpleExcelDown, getExportAlarmHeader } } = ctx.app.fs;
|
|
|
|
const kindRes = await clickHouse.vcmp.query(`
|
|
|
|
SELECT * FROM camera_kind
|
|
|
|
`).toPromise()
|
|
|
|
let header = await getExportAlarmHeader('video');
|
|
|
|
let exportData = []
|
|
|
|
for (let item of alarmList) {
|
|
|
|
let projectNames = item.pomsProject.map(p => {
|
|
|
|
return p.name || p.pepProject.projectName
|
|
|
|
})
|
|
|
|
let structNames = item.struc.map(str => str.name);
|
|
|
|
item.projectName = projectNames.join('\r\n') || '无';//项目名称
|
|
|
|
item.structureName = structNames.join('\r\n');//结构物名称
|
|
|
|
item.stations = item.station.length ? item.station.map(st => st.position).join('\r\n') : '无';//位置信息
|
|
|
|
item.cameraKindId = kindRes.find(k => k.value == item.cameraKindId) ? kindRes.find(k => k.value == item.cameraKindId).name : '其他';//设备类型 ??????????
|
|
|
|
|
|
|
|
let time = moment(item.confirmTime || item.updateTime || moment().format("YYYY-MM-DD HH:mm:ss")).diff(moment(item.createTime), 'seconds')
|
|
|
|
item.sustainTime = time < 60 ? '< 1分钟' : time > 3600 ? Math.floor(time / 3600) + '小时' + Math.floor((time - Math.floor(time / 3600) * 3600) / 60) + '分钟' : Math.floor((time - Math.floor(time / 3600) * 3600) / 60) + '分钟';
|
|
|
|
|
|
|
|
item.venderName = item.platform ? '未知' : item.venderName;//设备厂家
|
|
|
|
item.point = item.station.length ? item.station.map(st => st.name).join('\r\n') : '无';//测点
|
|
|
|
item.platform = accessType[item.platform] || '无';//接入方式
|
|
|
|
let resolves = item.resolve.map(rs => rs.resolve);
|
|
|
|
item.resolve = resolves.join('\r\n');//解决方案
|
|
|
|
|
|
|
|
item.updateTime = item.updateTime || '无';
|
|
|
|
item.confirmContent = item.confirmContent || '无';
|
|
|
|
item.confirmTime = item.confirmTime || '无';
|
|
|
|
|
|
|
|
exportData.push(item)
|
|
|
|
}
|
|
|
|
const fileName = `视频异常列表_${moment().format('YYYYMMDDHHmmss')}` + '.xlsx'
|
|
|
|
const filePath = await simpleExcelDown({ data: exportData, header, fileName: fileName })
|
|
|
|
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 confirm (ctx) {
|
|
|
|
try {
|
|
|
|
const { alarmId, content, confirmPost } = ctx.request.body;
|
|
|
|
// TODO: 以视频·应用的秘钥进行鉴权
|
|
|
|
await ctx.app.fs.vcmpRequest.put('status/alarm/confirm', {
|
|
|
|
data: {
|
|
|
|
alarmId, content
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
await alarmConfirmLog(ctx, confirmPost, content);//告警确认日志
|
|
|
|
|
|
|
|
ctx.status = 204;
|
|
|
|
} catch (error) {
|
|
|
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
|
|
|
|
ctx.status = 400;
|
|
|
|
ctx.body = {
|
|
|
|
message: typeof error == 'string' ? error : undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let structsAche = {
|
|
|
|
dataList: [],
|
|
|
|
expireTime: null//10分钟更新一次结构物列表
|
|
|
|
}
|
|
|
|
async function getStructsAche (ctx) {
|
|
|
|
const { utils: { getAxyStructs } } = ctx.app.fs
|
|
|
|
try {
|
|
|
|
if (!structsAche.dataList.length || moment() > moment(structsAche.expireTime)) {
|
|
|
|
let structList = await getAxyStructs();
|
|
|
|
structsAche.dataList = structList;
|
|
|
|
structsAche.expireTime = moment().add(10, 'minute').format('YYYY-MM-DD HH:mm:ss');
|
|
|
|
}
|
|
|
|
return structsAche;
|
|
|
|
} catch (err) {
|
|
|
|
console.log(`获取结构物列表失败, error: ${err}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function alarmAdded (ctx) {
|
|
|
|
try {
|
|
|
|
const { models } = ctx.fs.dc;
|
|
|
|
const { clickHouse } = ctx.app.fs
|
|
|
|
const { utils: { sendAppearToWeb } } = ctx.app.fs
|
|
|
|
|
|
|
|
let structsAche = await getStructsAche(ctx);
|
|
|
|
if (structsAche) {
|
|
|
|
let anxinStruc = structsAche.dataList;//结构物列表
|
|
|
|
const { serial_no, channel_no, create_time, description, status_id } = ctx.request.body;
|
|
|
|
|
|
|
|
let belongToStruct = await clickHouse.anxinyun.query(
|
|
|
|
`SELECT name, structure FROM t_video_ipc WHERE serial_no='${serial_no}' and channel_no=${parseInt(channel_no)}`).toPromise()
|
|
|
|
let structId = belongToStruct.length ? belongToStruct[0].structure : null
|
|
|
|
|
|
|
|
if (structId) {
|
|
|
|
let exist = anxinStruc.find(s => s.strucId == structId);
|
|
|
|
if (exist) {
|
|
|
|
let projects = exist.pomsProject.filter(d => !d.del).map(p => p.id);
|
|
|
|
let datas = projects.map(d => {//需要 项目,告警源,异常类型,时间
|
|
|
|
return {
|
|
|
|
projectCorrelationId: d,
|
|
|
|
alarmInfo: { messageMode: 'AlarmGeneration', sourceName: belongToStruct[0].name, status_id, type: description },//AlarmGeneration代表告警首次产生
|
|
|
|
time: create_time,
|
|
|
|
type: description
|
|
|
|
}
|
|
|
|
})
|
|
|
|
let rslt = await models.AlarmAppearRecord.bulkCreate(datas, { returning: true });
|
|
|
|
let dynamics = rslt.map(r => {
|
|
|
|
return {
|
|
|
|
time: r.time,
|
|
|
|
alarmAppearId: r.id,
|
|
|
|
projectCorrelationId: r.projectCorrelationId,
|
|
|
|
type: 1//发现
|
|
|
|
}
|
|
|
|
})
|
|
|
|
await models.LatestDynamicList.bulkCreate(dynamics);
|
|
|
|
|
|
|
|
//消息推送到前端
|
|
|
|
if (datas.length) {
|
|
|
|
await sendAppearToWeb(datas, 'video');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ctx.status = 200;
|
|
|
|
} else {
|
|
|
|
ctx.status = 400;
|
|
|
|
ctx.body = {
|
|
|
|
message: `获取结构物列表失败`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
|
|
|
|
ctx.status = 400;
|
|
|
|
ctx.body = {
|
|
|
|
message: typeof error == 'string' ? error : undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function vcmpAppAuthToken (ctx) {
|
|
|
|
try {
|
|
|
|
const { models } = ctx.fs.dc;
|
|
|
|
const { utils: { vcmpAuth } } = ctx.app.fs
|
|
|
|
|
|
|
|
const token = await vcmpAuth()
|
|
|
|
|
|
|
|
ctx.status = 200;
|
|
|
|
ctx.body = { token }
|
|
|
|
} catch (error) {
|
|
|
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
|
|
|
|
ctx.status = 400;
|
|
|
|
ctx.body = {
|
|
|
|
message: typeof error == 'string' ? error : undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
deviceType,
|
|
|
|
alarmList,
|
|
|
|
confirm,
|
|
|
|
alarmAdded,
|
|
|
|
vcmpAppAuthToken,
|
|
|
|
exceptionType
|
|
|
|
};
|