|
|
@ -1,7 +1,6 @@ |
|
|
|
'use strict'; |
|
|
|
const moment = require('moment'); |
|
|
|
|
|
|
|
|
|
|
|
async function dataList (ctx) { |
|
|
|
try { |
|
|
|
const { models } = ctx.fs.dc; |
|
|
@ -82,12 +81,12 @@ async function dataList (ctx) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async function userlist (ctx) { |
|
|
|
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'] |
|
|
@ -202,6 +201,80 @@ async function userlist (ctx) { |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
findOption.where.id = pepId |
|
|
|
} |
|
|
|
|
|
|
|
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(',')}) |
|
|
|
` |
|
|
|
).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).indexOf(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) { |
|
|
@ -210,7 +283,8 @@ async function userlist (ctx) { |
|
|
|
|
|
|
|
ctx.status = 200 |
|
|
|
ctx.body = { |
|
|
|
personnel: personnel.map(v => v.dataValues.name) |
|
|
|
personnel: personnel.map(v => v.dataValues.name), |
|
|
|
webApp: webApp |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|
|
@ -221,10 +295,197 @@ async function userlist (ctx) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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(",")})`) |
|
|
|
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 = false |
|
|
|
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(',')})`} |
|
|
|
) |
|
|
|
${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 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
module.exports = { |
|
|
|
dataList, |
|
|
|
userlist |
|
|
|
}; |
|
|
|
personnelApp, |
|
|
|
problem |
|
|
|
} |