From 5fa4e98c157eca702e31b407c17eef46f7823f2f Mon Sep 17 00:00:00 2001 From: wuqun Date: Tue, 25 Oct 2022 09:54:36 +0800 Subject: [PATCH] =?UTF-8?q?(*)=E6=8E=A7=E5=88=B6=E5=8F=B0=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=20=E4=BF=AE=E6=94=B9=E5=88=B0control?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/alarm/data.js | 3 +- api/app/lib/controllers/alarm/video.js | 39 +++++++++++-- .../{console/index.js => control/data.js} | 58 +++++++++++++++---- api/app/lib/routes/console/index.js | 23 -------- api/app/lib/routes/control/index.js | 16 +++++ 5 files changed, 97 insertions(+), 42 deletions(-) rename api/app/lib/controllers/{console/index.js => control/data.js} (67%) delete mode 100644 api/app/lib/routes/console/index.js diff --git a/api/app/lib/controllers/alarm/data.js b/api/app/lib/controllers/alarm/data.js index ae135b5..595cd60 100644 --- a/api/app/lib/controllers/alarm/data.js +++ b/api/app/lib/controllers/alarm/data.js @@ -247,7 +247,8 @@ function confirm (opts) { const { models } = ctx.fs.dc; const { utils: { kfkSendAsync } } = ctx.app.fs const { clickHouse } = ctx.app.fs - const { content = '', alarmId } = ctx.request.body + const { content = '', alarmId, confirmPost } = ctx.request.body; + const { pepUserId, projectCorrelationIds, alarmInfo } = confirmPost; // 发送告警恢复通知 // Topic: alarm /* diff --git a/api/app/lib/controllers/alarm/video.js b/api/app/lib/controllers/alarm/video.js index 1263203..007b176 100644 --- a/api/app/lib/controllers/alarm/video.js +++ b/api/app/lib/controllers/alarm/video.js @@ -21,7 +21,7 @@ async function deviceType (ctx) { } } -async function alarmList (ctx) { +async function alarmList(ctx, agg) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs @@ -69,7 +69,7 @@ async function alarmList (ctx) { } const alarmRes = anxinStrucIds.length ? await clickHouse.vcmp.query( ` - SELECT + SELECT cameraAlarm.cameraId AS cameraId, cameraAlarm.cameraName AS cameraName, cameraAlarm.cameraKindId AS cameraKindId, @@ -250,8 +250,12 @@ async function alarmList (ctx) { } } - ctx.status = 200; - ctx.body = returnD + if (agg == 'day') {//控制台 按日聚集 + return returnD + } else { + ctx.status = 200; + ctx.body = returnD + } } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; @@ -264,8 +268,8 @@ async function alarmList (ctx) { async function confirm (ctx) { try { const { models } = ctx.fs.dc; - const { alarmId, content } = ctx.request.body; - + const { alarmId, content, confirmPost } = ctx.request.body; + const { pepUserId, projectCorrelationIds, alarmInfo } = confirmPost; // TODO: 以视频·应用的秘钥进行鉴权 await ctx.app.fs.vcmpRequest.put('status/alarm/confirm', { data: { @@ -273,6 +277,29 @@ async function confirm (ctx) { } }) + //存日志 + let logDatas = projectCorrelationIds.map(id => { + return { + pepUserId, + projectCorrelationId: id, + alarmInfo,//包含告警id,type,source + confirmTime: moment().format(), + confirmContent: content + } + }) + let rslt = await models.AlarmConfirmLog.bulkCreate(logDatas, { returning: true }); + + //存最新动态 + let dynamics = rslt.map(r => { + return { + time: r.confirmTime, + alarmConfirmId: r.id, + projectCorrelationId: r.projectCorrelationId, + type: 4//告警确认 + } + }) + await models.LatestDynamicList.bulkCreate(dynamics); + ctx.status = 204; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); diff --git a/api/app/lib/controllers/console/index.js b/api/app/lib/controllers/control/data.js similarity index 67% rename from api/app/lib/controllers/console/index.js rename to api/app/lib/controllers/control/data.js index b12aabd..d875b5e 100644 --- a/api/app/lib/controllers/console/index.js +++ b/api/app/lib/controllers/control/data.js @@ -1,6 +1,6 @@ 'use strict'; const moment = require('moment'); - +const { alarmList } = require('../alarm/video'); //工作台 async function getWorkbench(ctx) { try { @@ -22,16 +22,40 @@ async function getWorkbench(ctx) { async function getProjectsInfo(ctx) { try { const { models } = ctx.fs.dc; - const { clickHouse } = ctx.app.fs; - const { alarmId, limit, page, projectCorrelationId } = ctx.query; + const { clickHouse, utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs + const { database: anxinyun } = clickHouse.anxinyun.opts.config + const { alarmId, limit, page, projectCorrelationId, pepProjectId, keywordTarget, keyword } = ctx.query; const { userInfo } = ctx.fs.api; - let where = {} - if (!userInfo.role.includes('SuperAdmin') && !userInfo.role.includes('admin')) { - where.projectCorrelationId = { $in: userInfo.correlationProject } - } - if (projectCorrelationId) {//查指定项目,控制台全局切换 - where.projectCorrelationId = projectCorrelationId - } + // let where = {} + // if (!userInfo.role.includes('SuperAdmin') && !userInfo.role.includes('admin')) { + // where.projectCorrelationId = { $in: userInfo.correlationProject } + // } + // if (projectCorrelationId) {//查指定项目,控制台全局切换 + // where.projectCorrelationId = projectCorrelationId + // } + let anxinStruc = await anxinStrucIdRange({ + ctx, pepProjectId, keywordTarget, keyword + }) + const anxinStrucIds = anxinStruc.map(a => a.strucId); + //先查全部的摄像头 + const videoList = anxinStrucIds.length ? await clickHouse.vcmp.query( + `select camera.id, + camera.name, + camera.serial_no from camera where camera.delete=false and camera.recycle_time is null + + 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` + ).toPromise() : [] + + ctx.status = 200; ctx.body = [] } catch (error) { @@ -48,9 +72,19 @@ async function getBiAnalysis(ctx) { try { const { models } = ctx.fs.dc; const { clickHouse } = ctx.app.fs - const { alarmId, limit, page } = ctx.query + const { alarmId, limit, page } = ctx.query; + let videoAlarms = await alarmList(ctx, 'day'); + let aggDayMap = []; + for (let a of videoAlarms) { + let exist = aggDayMap.find(ad => ad.day == moment(a.createTime).format('YYYY-MM-DD')) + if (exist) { + exist.number++ + } else { + aggDayMap.push({ day: moment(a.createTime).format('YYYY-MM-DD'), number: 1 }) + } + } ctx.status = 200; - ctx.body = [] + ctx.body = aggDayMap; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; diff --git a/api/app/lib/routes/console/index.js b/api/app/lib/routes/console/index.js deleted file mode 100644 index a9ccc58..0000000 --- a/api/app/lib/routes/console/index.js +++ /dev/null @@ -1,23 +0,0 @@ - - -'use strict'; - -const console = require('../../controllers/console/index'); - -module.exports = function (app, router, opts) { - //我的工作台 - app.fs.api.logAttr['GET/user/:userId/workbench'] = { content: '查询工作台问题', visible: false }; - router.get('/user/:userId/workbench', console.getWorkbench); - - //项目概览 - app.fs.api.logAttr['GET/user/:userId/projects/info'] = { content: '查询项目概览', visible: false }; - router.get('/user/:userId/projects/info', console.getProjectsInfo); - - //BI分析模块 - app.fs.api.logAttr['GET/user/:userId/bi/analysis'] = { content: '查询BI分析数据', visible: false }; - router.get('/user/:userId/bi/analysis', console.getBiAnalysis); - - //最新动态 - app.fs.api.logAttr['GET/latest/dynamic'] = { content: '查询最新动态', visible: false }; - router.get('/latest/dynamic', console.getLatestDynamic); -}; diff --git a/api/app/lib/routes/control/index.js b/api/app/lib/routes/control/index.js index 70b54c3..548c9d0 100644 --- a/api/app/lib/routes/control/index.js +++ b/api/app/lib/routes/control/index.js @@ -1,6 +1,7 @@ 'use strict'; const toolLink = require('../../controllers/control/toolLink'); +const csData = require('../../controllers/control/data'); module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/console/toollink'] = { content: '获取常用工具', visible: true }; @@ -14,4 +15,19 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/console/count'] = { content: '查询告警数量', visible: true }; router.get('/console/count', toolLink.count); + + + + + //项目概览 + app.fs.api.logAttr['GET/projects/info'] = { content: '查询项目概览', visible: false }; + router.get('/projects/info', csData.getProjectsInfo); + + //BI分析模块 + app.fs.api.logAttr['GET/bi/analysis'] = { content: '查询BI分析数据', visible: false }; + router.get('/bi/analysis', csData.getBiAnalysis); + + //最新动态 + app.fs.api.logAttr['GET/latest/dynamic'] = { content: '查询最新动态', visible: false }; + router.get('/latest/dynamic', csData.getLatestDynamic); }; \ No newline at end of file