Browse Source

Merge branch

dev
巴林闲侠 2 years ago
parent
commit
080045fd1e
  1. 49
      api/app/lib/controllers/alarm/alarmConfirmLog.js
  2. 27
      api/app/lib/controllers/alarm/app.js
  3. 6
      api/app/lib/controllers/alarm/data.js
  4. 29
      api/app/lib/controllers/alarm/video.js
  5. 16
      api/app/lib/controllers/control/data.js
  6. 6
      api/app/lib/index.js
  7. 28
      api/app/lib/models/email_send_log.js
  8. 22
      script/0.0.6/schema/2.alarm_confirm_log.sql
  9. 27
      script/0.0.6/schema/3.email_send_log.sql
  10. 23
      script/0.0.6/schema/4.alarm_appear_record.sql
  11. 28
      script/0.0.6/schema/5.latest_dynamic_list.sql
  12. 22
      script/0.0.6/schema/6.alarm_handle_statistics.sql
  13. 47
      web/client/src/sections/problem/containers/dataAlarm.jsx

49
api/app/lib/controllers/alarm/alarmConfirmLog.js

@ -0,0 +1,49 @@
'use strict';
const moment = require('moment')
async function alarmConfirmLog(ctx, confirmPost, content) {
try {
const { models } = ctx.fs.dc;
//存日志
let logDatas = [];
confirmPost.map(cp => {
let { pepUserId, projectCorrelationIds, alarmInfo } = cp;
projectCorrelationIds.map(id => {
logDatas.push({
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);
//TODO 消息推送到前端
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
alarmConfirmLog
};

27
api/app/lib/controllers/alarm/app.js

@ -1,7 +1,7 @@
'use strict';
const moment = require('moment')
const { alarmConfirmLog } = require('./alarmConfirmLog');
async function inspection(ctx) {
// 巡查
try {
@ -328,7 +328,6 @@ async function confirmApiError(ctx) {
try {
const models = ctx.fs.dc.models;
const { confirm, appAlarmId = [], confirmPost } = ctx.request.body
const { pepUserId, projectCorrelationIds, alarmInfo } = confirmPost
await models.AppAlarm.update({
confirm,
confirmTime: moment().format()
@ -338,29 +337,7 @@ async function confirmApiError(ctx) {
}
})
//存日志
let logDatas = projectCorrelationIds.map(id => {
return {
pepUserId,
projectCorrelationId: id,
alarmInfo,//包含告警id,type,source
confirmTime: moment().format(),
confirmContent: confirm
}
})
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);
await alarmConfirmLog(ctx, confirmPost, confirm);//告警确认日志
ctx.status = 204;
} catch (error) {

6
api/app/lib/controllers/alarm/data.js

@ -1,6 +1,6 @@
'use strict';
const moment = require('moment');
const { alarmConfirmLog } = require('./alarmConfirmLog');
async function groupList (ctx) {
try {
const { models } = ctx.fs.dc;
@ -248,7 +248,6 @@ function confirm (opts) {
const { utils: { kfkSendAsync } } = ctx.app.fs
const { clickHouse } = ctx.app.fs
const { content = '', alarmId, confirmPost } = ctx.request.body;
const { pepUserId, projectCorrelationIds, alarmInfo } = confirmPost;
// 发送告警恢复通知
// Topic: alarm
/*
@ -295,6 +294,9 @@ function confirm (opts) {
await kfkSendAsync(payloads)
}
await alarmConfirmLog(ctx, confirmPost, content);//告警确认日志
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);

29
api/app/lib/controllers/alarm/video.js

@ -1,6 +1,6 @@
'use strict';
const moment = require('moment')
const { alarmConfirmLog } = require('./alarmConfirmLog');
async function deviceType (ctx) {
try {
const { models } = ctx.fs.dc;
@ -129,7 +129,7 @@ async function alarmList (ctx, agg) {
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总书记任期
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(',')})`}
)
@ -268,9 +268,7 @@ async function alarmList (ctx, agg) {
async function confirm (ctx) {
try {
const { models } = ctx.fs.dc;
const { alarmId, content, confirmPost } = ctx.request.body;
const { pepUserId, projectCorrelationIds, alarmInfo } = confirmPost;
// TODO: 以视频·应用的秘钥进行鉴权
await ctx.app.fs.vcmpRequest.put('status/alarm/confirm', {
data: {
@ -278,28 +276,7 @@ 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);
await alarmConfirmLog(ctx, confirmPost, content);//告警确认日志
ctx.status = 204;
} catch (error) {

16
api/app/lib/controllers/control/data.js

@ -203,7 +203,11 @@ async function getLatestDynamic(ctx) {
}, {
model: models.AlarmAppearRecord
}, {
model: models.EmailSendLog
model: models.EmailSendLog,
include: [{
model: models.AlarmPushConfig,
attributes: ['id', 'name'],
}]
}, {
model: models.AlarmConfirmLog
}],
@ -219,7 +223,9 @@ async function getLatestDynamic(ctx) {
pepPojectIds.add(p.projectCorrelation.pepProjectId);
if (p.emailSendLog) {
notedUserIds.add(p.emailSendLog.toPepUserId);//通知 接收人
p.emailSendLog.toPepUserIds.map(u => {
notedUserIds.add(u);//通知 接收人
})
}
if (p.alarmConfirmLog && p.alarmConfirmLog.pepUserId) {
notedUserIds.add(p.alarmConfirmLog.pepUserId);//确认 操作者
@ -240,14 +246,14 @@ async function getLatestDynamic(ctx) {
if (d.alarmAppearId) {
appear.push({
projectName,
...d.alarmAppearRecord
...d.alarmAppearRecord.dataValues
});
}
if (d.emailSendId) {
notice.push({
userName: userPepRes.find(u => u.id == d.emailSendLog.toPepUserId).name,
userName: userPepRes.find(u => d.emailSendLog.toPepUserIds.indexOf(u.id) != -1),
projectName,
...d.emailSendLog
...d.emailSendLog.dataValues
});
}
if (d.alarmConfirmId) {

6
api/app/lib/index.js

@ -58,8 +58,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
});
const {
AppInspection, ProjectApp, ProjectCorrelation, AppAlarm, App, AlarmAppearRecord, AlarmConfirmLog, EmailSendLog, LatestDynamicList,
AlarmPushConfig
AppInspection, ProjectApp, ProjectCorrelation, AppAlarm, App, AlarmAppearRecord, AlarmConfirmLog, EmailSendLog, LatestDynamicList, AlarmPushConfig
} = dc.models;
AppInspection.belongsTo(App, { foreignKey: 'projectAppId', targetKey: 'id' });
@ -90,6 +89,9 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
EmailSendLog.belongsTo(ProjectCorrelation, { foreignKey: 'projectCorrelationId', targetKey: 'id' });
ProjectCorrelation.hasMany(EmailSendLog, { foreignKey: 'projectCorrelationId', sourceKey: 'id' });
EmailSendLog.belongsTo(AlarmPushConfig, { foreignKey: 'pushConfigId', targetKey: 'id' });
AlarmPushConfig.hasMany(EmailSendLog, { foreignKey: 'pushConfigId', sourceKey: 'id' });
LatestDynamicList.belongsTo(AlarmAppearRecord, { foreignKey: 'alarmAppearId', targetKey: 'id' });
AlarmAppearRecord.hasMany(LatestDynamicList, { foreignKey: 'alarmAppearId', sourceKey: 'id' });

28
api/app/lib/models/email_send_log.js

@ -1,4 +1,5 @@
/* eslint-disable*/
'use strict';
module.exports = dc => {
@ -15,15 +16,6 @@ module.exports = dc => {
autoIncrement: true,
unique: "email_send_log_id_uindex"
},
toPepUserId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "to_pep_user_id",
autoIncrement: false
},
time: {
type: DataTypes.DATE,
allowNull: false,
@ -59,6 +51,24 @@ module.exports = dc => {
primaryKey: false,
field: "tactics_params",
autoIncrement: false
},
projectCorrelationId: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "project_correlation_id",
autoIncrement: false
},
toPepUserIds: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: false,
defaultValue: null,
comment: null,
primaryKey: false,
field: "to_pep_user_ids",
autoIncrement: false
}
}, {
tableName: "email_send_log",

22
script/0.0.6/schema/2.alarm_confirm_log.sql

@ -0,0 +1,22 @@
create table alarm_confirm_log
(
id serial not null,
pep_user_id int null,
project_correlation_id int not null,
alarm_info json not null,
confirm_time timestamp not null,
confirm_content varchar not null
);
comment on table alarm_confirm_log is '告警确认日志表';
create unique index alarm_confirm_log_id_uindex
on alarm_confirm_log (id);
alter table alarm_confirm_log
add constraint alarm_confirm_log_pk
primary key (id);

27
script/0.0.6/schema/3.email_send_log.sql

@ -0,0 +1,27 @@
create table if not exists email_send_log
(
id serial not null
constraint email_send_log_pk
primary key,
time timestamp not null,
push_config_id integer not null,
tactics varchar(32),
tactics_params jsonb,
project_correlation_id integer not null,
to_pep_user_ids integer[] not null
);
comment on table email_send_log is 'EM推送日志';
alter table email_send_log owner to postgres;
create unique index if not exists email_send_log_id_uindex
on email_send_log (id);

23
script/0.0.6/schema/4.alarm_appear_record.sql

@ -0,0 +1,23 @@
create table alarm_appear_record
(
id serial not null,
project_correlation_id int not null,
alarm_info json not null,
time timestamp,
type varchar null
);
comment on table alarm_appear_record is '告警出现记录到日志';
create unique index alarm_appear_record_id_uindex
on alarm_appear_record (id);
alter table alarm_appear_record
add constraint alarm_appear_record_pk
primary key (id);

28
script/0.0.6/schema/5.latest_dynamic_list.sql

@ -0,0 +1,28 @@
create table latest_dynamic_list
(
id serial not null,
time timestamp not null,
project_correlation_id int not null,
alarm_appear_id int,
email_send_id int,
alarm_confirm_id int,
type int
);
comment on table latest_dynamic_list is '最新动态表';
comment on column latest_dynamic_list.type is '1:发现,2:通知,3:处置,4:确认';
create unique index latest_dynamic_list_id_uindex
on latest_dynamic_list (id);
alter table latest_dynamic_list
add constraint latest_dynamic_list_pk
primary key (id);

22
script/0.0.6/schema/6.alarm_handle_statistics.sql

@ -0,0 +1,22 @@
create table alarm_handle_statistics
(
id serial not null,
time timestamp not null,
project_correlation_id int,
day1 float,
day3 float,
day7 float,
day15 float,
day30 float,
day30m float
);
create unique index alarm_handle_statistics_id_uindex
on alarm_handle_statistics (id);
alter table alarm_handle_statistics
add constraint alarm_handle_statistics_pk
primary key (id);

47
web/client/src/sections/problem/containers/dataAlarm.jsx

@ -37,8 +37,6 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb
const [videoModal, setVideoModal] = useState(false) //
const [videoData, setVideoData] = useState({}) //
const [videoToken, setVideoToken] = useState() //token
const [alarmToConfirm, setAlarmToConfirm] = useState(null) //
const TextAreaApi = useRef('')
@ -306,15 +304,14 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb
name: '操作', sort: 25, value: 'text', render: (_, r, index) => {
return <div style={{ width: 195 }}>
{r.State < 3 || route && ['videoAbnormal', 'useAbnormal'].includes(route) && !r.confirmTime ?
<Button theme='borderless' style={{ width: 65 }} onClick={() => {
setConfirm(true)
setSelected([r.key])
setAlarmToConfirm(r)
}}>确认</Button>
: r.State == 3 || r.autoRestore || r.confirmAuto ?
<Button theme='borderless' style={{ width: 65 }} onClick={() => {
setConfirm(true)
setSelected([r.key])
}}>确认</Button>
: r.State == 3 || r.autoRestore || r.confirmAuto ?
<Button theme='borderless' style={{ width: 65 }} disabled>自动恢复</Button> :
<Button theme='borderless' style={{ width: 65 }} disabled>已确认</Button>
}
<Button theme='borderless' style={{ width: 65 }} disabled>已确认</Button>
}
{route && ['dataLnterrupt', 'dataAbnormal', 'strategyHit', 'deviceAbnormal'].includes(route) ? <>
<Button theme='borderless' style={{ width: 65 }} disabled>已派单</Button>
{route == 'deviceAbnormal' ? "" : <Button theme='borderless' style={{ width: 65 }} onClick={() => {
@ -384,18 +381,24 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb
// console.log(selected);
const getAlarmConfirmItem = () => {
let source = route == 'useAbnormal' ? alarmToConfirm.appName : alarmToConfirm.SourceName;
let type = route == 'useAbnormal' ? alarmToConfirm.type : route == 'videoAbnormal' ? alarmToConfirm.AlarmContent : alarmToConfirm.AlarmGroupUnit;
return {
pepUserId: user.pomsUserInfo.pepUserId,
projectCorrelationIds: alarmToConfirm?.projectName?.map(p => p.id),
alarmInfo: {
id: alarmToConfirm.key,
source: source,//
type: type,//
const getAlarmConfirmItems = () => {
let confirmItems = [];
selected.map(s => {
let alarmInfo = tableData.find(td => td.key == s);
let source = route == 'useAbnormal' ? alarmInfo.appName : alarmInfo.SourceName;
let type = route == 'useAbnormal' ? alarmInfo.type : route == 'videoAbnormal' ? alarmInfo.AlarmContent : alarmInfo.AlarmGroupUnit;
let item = {
pepUserId: user.pomsUserInfo.pepUserId,
projectCorrelationIds: alarmInfo?.projectName?.map(p => p.id),
alarmInfo: {
id: alarmInfo.key,
source: source,//
type: type,//
}
}
};
confirmItems.push(item);
})
return confirmItems;
}
return (
@ -457,7 +460,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb
width={600}
onCancel={() => setConfirm(false)}
onOk={() => {
let confirmPost = getAlarmConfirmItem();
let confirmPost = getAlarmConfirmItems();
if (route == 'useAbnormal') {
TextAreaApi.current.validate().then((v) => {
dispatch(problem.postApiConfirm({ appAlarmId: selected, confirm: content, confirmPost })).then(res => {

Loading…
Cancel
Save