diff --git a/api/app/lib/controllers/alarm/data.js b/api/app/lib/controllers/alarm/data.js
index ca1204a..f1d2b82 100644
--- a/api/app/lib/controllers/alarm/data.js
+++ b/api/app/lib/controllers/alarm/data.js
@@ -8,17 +8,23 @@ async function groupList (ctx) {
const { clickHouse } = ctx.app.fs
const { database: dataAlarm } = clickHouse.dataAlarm.opts.config
+ const { showAll } = ctx.query
const groupRes = await clickHouse.anxinyun.query(`
SELECT * FROM t_alarm_group
`).toPromise();
+ let whereOption = []
+ if (!showAll) {
+ whereOption.push(` INNER JOIN ${dataAlarm}.alarms
+ ON t_alarm_group_unit.id = ${dataAlarm}.alarms.AlarmGroupUnit`)
+ }
+
for (let g of groupRes) {
g.unit = await await clickHouse.anxinyun.query(`
SELECT DISTINCT
t_alarm_group_unit.id AS id,t_alarm_group_unit.name AS name,t_alarm_group_unit.group_id AS groupId
FROM t_alarm_group_unit
- INNER JOIN ${dataAlarm}.alarms
- ON t_alarm_group_unit.id = ${dataAlarm}.alarms.AlarmGroupUnit
+ ${whereOption}
WHERE group_id = ${g.id}
`).toPromise();
}
@@ -90,7 +96,7 @@ async function list (ctx) {
whereOption.push(`DeviceStatus.Status = ${0}`)
}
}
-
+
let alarmQueryOptionStr = `
FROM
alarms
@@ -218,7 +224,7 @@ async function list (ctx) {
}
}
-async function getAlarmGroups(ctx) {
+async function getAlarmGroups (ctx) {
try {
const { clickHouse } = ctx.app.fs
const groupRes = await clickHouse.anxinyun.query(`
@@ -239,7 +245,7 @@ async function getAlarmGroups(ctx) {
}
}
}
-async function exportDataAlarms(ctx, alarmList, groupId) {
+async function exportDataAlarms (ctx, alarmList, groupId) {
try {
const { utils: { simpleExcelDown, getExportAlarmHeader } } = ctx.app.fs;
let header = await getExportAlarmHeader(groupId);
@@ -303,7 +309,7 @@ async function exportDataAlarms(ctx, alarmList, groupId) {
}
}
}
-async function detail(ctx) {
+async function detail (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
diff --git a/api/app/lib/controllers/alarm/video.js b/api/app/lib/controllers/alarm/video.js
index ab2cff1..b9a0dbf 100644
--- a/api/app/lib/controllers/alarm/video.js
+++ b/api/app/lib/controllers/alarm/video.js
@@ -8,11 +8,18 @@ async function deviceType (ctx) {
const { clickHouse } = ctx.app.fs
const { database: anxinyun } = clickHouse.anxinyun.opts.config
const { utils: { judgeSuper, anxinStrucIdRange } } = ctx.app.fs
+ const { showAll } = ctx.query
let anxinStruc = await anxinStrucIdRange({
ctx,
})
const anxinStrucIds = anxinStruc.map(a => a.strucId)
-
+ let whereOption = []
+ if (!showAll) {
+ whereOption.push(`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(',')})`}`)
+ }
const kindRes = await clickHouse.vcmp.query(`
SELECT DISTINCT
camera_kind.id AS id,camera_kind.kind AS kind
@@ -22,10 +29,7 @@ async function deviceType (ctx) {
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(',')})`}
+ ${whereOption}
`).toPromise()
ctx.status = 200;
ctx.body = kindRes
@@ -38,7 +42,7 @@ async function deviceType (ctx) {
}
}
-async function exceptionType(ctx) {
+async function exceptionType (ctx) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
diff --git a/api/app/lib/controllers/push/config.js b/api/app/lib/controllers/push/config.js
index 0566837..831be16 100644
--- a/api/app/lib/controllers/push/config.js
+++ b/api/app/lib/controllers/push/config.js
@@ -165,11 +165,11 @@ async function edit (ctx) {
const models = ctx.fs.dc.models;
const { userId, pepUserId } = ctx.fs.api
const { pushId, name, pomsProjectId, alarmType = [], receiverPepUserId = [], timeType = [], disable,
- strucId = [], tactics, tacticsParams } = ctx.request.body
+ strucId = [], tactics, tacticsParams, alarmSubType = {} } = ctx.request.body
let storageData = {
name, pomsProjectId, alarmType, receiverPepUserId, timeType, disable,
- strucId, tactics, tacticsParams
+ strucId, tactics, tacticsParams,alarmSubType
}
let repeatOption = {
diff --git a/api/app/lib/models/alarm_push_config.js b/api/app/lib/models/alarm_push_config.js
index 7ea7a19..07606cf 100644
--- a/api/app/lib/models/alarm_push_config.js
+++ b/api/app/lib/models/alarm_push_config.js
@@ -42,6 +42,15 @@ module.exports = dc => {
field: "alarm_type",
autoIncrement: false
},
+ alarmSubType: {
+ type: DataTypes.JSONB,
+ allowNull: true,
+ defaultValue: null,
+ comment: "监听的告警类型",
+ primaryKey: false,
+ field: "alarm_sub_type",
+ autoIncrement: false
+ },
receiverPepUserId: {
type: DataTypes.ARRAY(DataTypes.INTEGER),
allowNull: true,
diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js
index 57f8736..c8bd06b 100644
--- a/api/app/lib/schedule/alarms_push.js
+++ b/api/app/lib/schedule/alarms_push.js
@@ -135,6 +135,7 @@ module.exports = function (app, opts) {
let dataAlarmOption = []
let dataAlarmGroupOption = []
+ let dataAlarmSubType = []
let dataAlarms = []
let videoAlarmWhereOption = []
@@ -211,15 +212,21 @@ module.exports = function (app, opts) {
// 判断告警数据范围
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')) {
- videoAlarms = searchStrucIds.length ? await clickHouse.vcmp.query(
+ 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,
@@ -263,6 +270,7 @@ module.exports = function (app, opts) {
AND camera.channel_no = camera_status_alarm.channel_no
AND camera.delete = false
AND camera.recycle_time is null
+ ${!c.alarmSubType ? `AND camera.kind_id in (${videoAlarmSubType.join(',')})` : ""}
WHERE
camera_status_alarm.confirm_time IS null
${videoAlarmWhereOption.length ? ` AND ${videoAlarmWhereOption.join(' AND ')}` : ''}
@@ -353,7 +361,10 @@ module.exports = function (app, opts) {
videoAlarms = returnD
}
if (c.alarmType.includes('app_exception')) {
- appAlarms = await models.AppAlarm.findAll({
+ 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: [{
@@ -367,25 +378,30 @@ module.exports = function (app, opts) {
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 (dataAlarmGroupOption.length && searchStrucIds.length) {
dataAlarmGroupOption.push(-1)
dataAlarmOption.push(`AlarmGroup IN (${dataAlarmGroupOption.join(',')})`)
- dataAlarms = await clickHouse.dataAlarm.query(`
+ 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 `}
StructureId IN (${searchStrucIds.join(',')})
${dataAlarmOption.length ? ' AND ' + dataAlarmOption.join(' AND ') : ''}
ORDER BY StartTime DESC
- `).toPromise()
+ `).toPromise() : []
console.log(dataAlarms);
}
diff --git a/script/0.10/schema/1.alter_alarm_push_config.sql b/script/0.10/schema/1.alter_alarm_push_config.sql
new file mode 100644
index 0000000..08ad5b3
--- /dev/null
+++ b/script/0.10/schema/1.alter_alarm_push_config.sql
@@ -0,0 +1,8 @@
+alter table alarm_push_config
+ add alarm_sub_type jsonb
+
+comment on column alarm_push_config.alarm_sub_type is '存对应监听模块(alarm_type)的子类(
+ 数据告警:alarms.AlarmGroupUnit,
+ 视频异常:camera.kind_id,
+ 应用异常:app_alarm.errType
+)';
diff --git a/web/client/src/sections/problem/actions/problem.jsx b/web/client/src/sections/problem/actions/problem.jsx
index 91d4913..495e7a5 100644
--- a/web/client/src/sections/problem/actions/problem.jsx
+++ b/web/client/src/sections/problem/actions/problem.jsx
@@ -64,10 +64,11 @@ export function postApiConfirm (data) { //确认应用接口/元素错误信
});
}
-export function getAlarmDataGroup () { //获取数据告警分类
+export function getAlarmDataGroup (query) { //获取数据告警分类
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
+ query,
actionType: 'GET_ALARM_DATA_GROUP',
url: `${ApiTable.getAlarmDataGroup}`,
msg: { option: '获取数据告警分类' },
@@ -138,10 +139,11 @@ export function getAlarmVideoList (query) { //查询视频告警列表
-export function getAlarmVideoDeviceKind () { //查询视频设备类型
+export function getAlarmVideoDeviceKind (query) { //查询视频设备类型
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
+ query,
actionType: 'GET_ALARM_VIDEO_DEVICE_KIND',
url: `${ApiTable.getAlarmVideoDeviceKind}`,
msg: { option: '查询视频设备类型' },
@@ -150,15 +152,15 @@ export function getAlarmVideoDeviceKind () { //查询视频设备类型
}
export function getAlarmVideoExceptionType () { //查询视频异常类型
- return dispatch => basicAction({
- type: 'get',
- dispatch: dispatch,
- actionType: 'GET_ALARM_VIDEO_EXCEPTION_TYPE',
- url: `${ApiTable.getAlarmVideoExceptionType}`,
- msg: { option: '查询视频异常类型' },
- reducer: { name: '' }
- });
- }
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ actionType: 'GET_ALARM_VIDEO_EXCEPTION_TYPE',
+ url: `${ApiTable.getAlarmVideoExceptionType}`,
+ msg: { option: '查询视频异常类型' },
+ reducer: { name: '' }
+ });
+}
export function putAlarmVideoConfirm (data) { //确认视频告警
return dispatch => basicAction({
diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx
index 0b547ff..78cdbfe 100644
--- a/web/client/src/sections/service/components/pushModal.jsx
+++ b/web/client/src/sections/service/components/pushModal.jsx
@@ -15,9 +15,10 @@ function pushModal (props) {
actions,
pushEdit,//是否是编辑
editObj,
- user
+ user,
+ subTypeData
} = props;
- const { service } = actions;
+ const { service, problem } = actions;
const form = useRef();//表单
const [abnormal, setAbnormal] = useState(false); //异常率推送机制disable
const [usersList, setUsersList] = useState([]); //获取全部未删除用户
@@ -32,20 +33,19 @@ function pushModal (props) {
const [interval2, setInterval2] = useState(undefined); //
const [interval3, setInterval3] = useState(undefined); //
const [deviceProportion, setDeviceProportion] = useState(undefined); //
-
-
+ const [subType, setSubType] = useState([]); //监听模块中的子类
//初始化
useEffect(() => {
+ if (editObj?.alarmType) setSubType(editObj?.alarmType)
getOrganizationUsersList()//获取全部未删除用户
getProjectPomsList()//获取已绑定项目
if (editObj.id) {
getProjectStructureList(editObj.pomsProjectId)
if (editObj.pomsProject?.pepProjectId) {
getProjectStatusList()//获取项目状态列表
- }
- else {
+ } else {
setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }])
timeTypePOMS.current = ['POMS']
}
@@ -58,7 +58,7 @@ function pushModal (props) {
setDeviceProportion(editObj.tacticsParams?.deviceProportion)
}
}
- }, []);
+ }, [])
function getOrganizationUsersList () {//获取全部未删除用户
dispatch(service.getOrganizationUsers()).then((res) => {
if (res.success) {
@@ -101,278 +101,58 @@ function pushModal (props) {
}
})
}
+ function caution (tactics, interval, deviceProportion) {
+ let regu = /^[0-9]*[1-9][0-9]*$/;
+ let title = tactics == 'immediately' ? '即时' : tactics == 'continue' ? '持续时长' : '异常率'
+ if (!regu.test(interval) || (tactics == 'abnormal_rate' && interval > 720) || interval > 1440) {
+ console.log(interval);
+ Notification.error({
+ content: title + (interval ? `推送时间不能大于${tactics == 'abnormal_rate' ? 720 : 1440}分钟` : '推送时间应为正整数'),
+ duration: 2,
+ })
+ return false
+ }
+ if (!deviceProportion || deviceProportion > 100) {
+ Notification.error({
+ content: '异常率推送异常率应为正整数且不超过100%',
+ duration: 2,
+ })
+ return false
+ }
+ return true
+ }
+
function handleOk () {
//点击弹框确定 右边按钮
form.current
.validate()
- .then((values) => {
- if (pushEdit) {
- let obj = JSON.parse(JSON.stringify(values))
- if (obj.timeType[0] == 'POMS') {
- obj.timeType = []
- }
- let regu = /^[0-9]*[1-9][0-9]*$/;
- if (obj.tactics == 'immediately') {
- if (obj.interval1) {
- if (regu.test(obj.interval1)) {
- if (obj.interval1 <= 1440) {
- obj.tacticsParams = {
- interval: obj.interval1
- }
- delete obj.interval1
- delete obj.interval2
- delete obj.interval3
- delete obj.deviceProportion
- dispatch(service.postPush({ pushId: editObj.id, ...obj, msg: '编辑推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户
- if (res.success) {
- close();
- }
- })
- } else {
- Notification.error({
- content: '即时推送时间不能大于1440分钟',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '即时推送时间应为正整数',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '即时推送时间应为正整数',
- duration: 2,
- })
- }
- }
- else if (obj.tactics == 'continue') {
- if (obj.interval2) {
- if (regu.test(obj.interval2)) {
- if (obj.interval2 <= 1440) {
- obj.tacticsParams = {
- interval: obj.interval2
- }
- delete obj.interval1
- delete obj.interval2
- delete obj.interval3
- delete obj.deviceProportion
- dispatch(service.postPush({ pushId: editObj.id, ...obj, msg: '编辑推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户
- if (res.success) {
- close();
- }
- })
- } else {
- Notification.error({
- content: '持续时长推送时间不能大于1440分钟',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '持续时长推送时间应为正整数',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '持续时长推送时间应为正整数',
- duration: 2,
- })
- }
- }
- else {
- if (regu.test(obj.interval3) && regu.test(obj.deviceProportion)) {
- if (obj.interval3 <= 720 && obj.deviceProportion <= 100) {
- obj.tacticsParams = {
- interval: obj.interval3,
- deviceProportion: obj.deviceProportion
- }
- delete obj.interval1
- delete obj.interval2
- delete obj.interval3
- delete obj.deviceProportion
- dispatch(service.postPush({ pushId: editObj.id, ...obj, msg: '编辑推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户
- if (res.success) {
- close();
- }
- })
- } else if (obj.interval3 <= 720 && obj.deviceProportion > 100) {
- Notification.error({
- content: '异常率推送异常率不能超过100%',
- duration: 2,
- })
- } else if (obj.interval3 > 720 && obj.deviceProportion <= 100) {
- Notification.error({
- content: '异常率推送时间不能超过720小时',
- duration: 2,
- })
- } else {
- Notification.error({
- content: '异常率推送时间不能超过720小时',
- duration: 2,
- })
- Notification.error({
- content: '异常率推送异常率不能超过100%',
- duration: 2,
- })
- }
- } else if (regu.test(obj.interval3) && !regu.test(obj.deviceProportion)) {
- Notification.error({
- content: '异常率推送异常率应为正整数',
- duration: 2,
- })
- } else if (!regu.test(obj.interval3) && regu.test(obj.deviceProportion)) {
- Notification.error({
- content: '异常率推送时间应为正整数',
- duration: 2,
- })
- } else {
- Notification.error({
- content: '异常率推送异常率应为正整数',
- duration: 2,
- })
- Notification.error({
- content: '异常率推送时间应为正整数',
- duration: 2,
- })
- }
- }
+ .then((v) => {
+ let data = {
+ name: v.name,
+ pomsProjectId: v.pomsProjectId,
+ strucId: v.strucId || [],
+ tactics: v.tactics,
+ tacticsParams: {
+ interval: v.tactics == 'immediately' ? v.interval1 : (v.tactics == 'continue' ? v.interval2 : v.interval3),
+ deviceProportion: v.deviceProportion
+ },
+ alarmType: v.alarmType,
+ timeType: v.timeType[0] == 'POMS' ? [] : v.timeType,
+ receiverPepUserId: v.receiverPepUserId || [],
+ disable: v.disable,
+ alarmSubType: {}
}
- else {
- let obj = JSON.parse(JSON.stringify(values))
- if (obj.timeType[0] == 'POMS') {
- obj.timeType = []
+ for (let key in v) {
+ if (['app_exception', 'data_exception', 'data_outages', 'device_exception', 'video_exception', 'strategy_hit'].includes(key)) {
+ data.alarmSubType = { ...data.alarmSubType, [key]: v[key] }
}
- let regu = /^[0-9]*[1-9][0-9]*$/;
- if (obj.tactics == 'immediately') {
- if (obj.interval1) {
- if (regu.test(obj.interval1)) {
- if (obj.interval1 <= 1440) {
- obj.tacticsParams = {
- interval: obj.interval1
- }
- delete obj.interval1
- delete obj.interval2
- delete obj.interval3
- delete obj.deviceProportion
- dispatch(service.postPush({ ...obj, msg: '新增推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户
- if (res.success) {
- close();
- }
- })
- } else {
- Notification.error({
- content: '即时推送时间不能大于1440分钟',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '即时推送时间应为正整数',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '即时推送时间应为正整数',
- duration: 2,
- })
- }
- }
- else if (obj.tactics == 'continue') {
- if (obj.interval2) {
- if (regu.test(obj.interval2)) {
- if (obj.interval2 <= 1440) {
- obj.tacticsParams = {
- interval: obj.interval2
- }
- delete obj.interval1
- delete obj.interval2
- delete obj.interval3
- delete obj.deviceProportion
- dispatch(service.postPush({ ...obj, msg: '新增推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户
- if (res.success) {
- close();
- }
- })
- } else {
- Notification.error({
- content: '持续时长推送时间不能大于1440分钟',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '持续时长推送时间应为正整数',
- duration: 2,
- })
- }
- } else {
- Notification.error({
- content: '持续时长推送时间应为正整数',
- duration: 2,
- })
- }
- }
- else {
- if (regu.test(obj.interval3) && regu.test(obj.deviceProportion)) {
- if (obj.interval3 <= 720 && obj.deviceProportion <= 100) {
- obj.tacticsParams = {
- interval: obj.interval3,
- deviceProportion: obj.deviceProportion
- }
- delete obj.interval1
- delete obj.interval2
- delete obj.interval3
- delete obj.deviceProportion
- dispatch(service.postPush({ ...obj, msg: '新增推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户
- if (res.success) {
- close();
- }
- })
- } else if (obj.interval3 <= 720 && obj.deviceProportion > 100) {
- Notification.error({
- content: '异常率推送异常率不能超过100%',
- duration: 2,
- })
- } else if (obj.interval3 > 720 && obj.deviceProportion <= 100) {
- Notification.error({
- content: '异常率推送时间不能超过720小时',
- duration: 2,
- })
- } else {
- Notification.error({
- content: '异常率推送时间不能超过720小时',
- duration: 2,
- })
- Notification.error({
- content: '异常率推送异常率不能超过100%',
- duration: 2,
- })
- }
- } else if (regu.test(obj.interval3) && !regu.test(obj.deviceProportion)) {
- Notification.error({
- content: '异常率推送异常率应为正整数',
- duration: 2,
- })
- } else if (!regu.test(obj.interval3) && regu.test(obj.deviceProportion)) {
- Notification.error({
- content: '异常率推送时间应为正整数',
- duration: 2,
- })
- } else {
- Notification.error({
- content: '异常率推送异常率应为正整数',
- duration: 2,
- })
- Notification.error({
- content: '异常率推送时间应为正整数',
- duration: 2,
- })
+ }
+ if (caution(data.tactics, data.tacticsParams.interval, data.tacticsParams.deviceProportion)) {
+ dispatch(service.postPush({ pushId: editObj.id, ...data, msg: pushEdit ? '编辑推送配置' : "新增推送策略" })).then((res) => {//获取项企(PEP)全部部门及其下用户
+ if (res.success) {
+ close();
}
- }
+ })
}
})
}
@@ -403,8 +183,7 @@ function pushModal (props) {
if (values.tactics == 'abnormal_rate') {
form.current.setValue('alarmType', undefined)
setAbnormal(true)
- }
- else {
+ } else {
setAbnormal(false)
}
}
@@ -423,6 +202,9 @@ function pushModal (props) {
}
}
}
+ if (key == 'alarmType') {
+ setSubType(field['alarmType'])
+ }
}
}}
getFormApi={(formApi) => (form.current = formApi)}
@@ -496,9 +278,10 @@ function pushModal (props) {
direction='horizontal'
initValue={editObj?.tactics || ''}
rules={[{ required: true, message: '请选择推送策略' }]}>
-
+
中台每分钟查询,若有告警源新增,则每
@@ -512,7 +295,7 @@ function pushModal (props) {
分钟通过【信鸽服务】发送一条通知信息。
}
- style={{ width: 198 }}>
+ style={{ width: 217 }}>
即时推送机制
- 数据中断
- 数据异常
- 策略命中
- 视频异常
- 应用异常
- 设备异常
+ {
+ [
+ { name: '数据中断', value: "data_outages" },
+ { name: '数据异常', value: "data_exception" },
+ { name: '策略命中', value: "strategy_hit" },
+ { name: '视频异常', value: "video_exception" },
+ { name: '应用异常', value: "app_exception" },
+ { name: '设备异常', value: "device_exception" },
+ ].map((v, index) =>
+
+ {v.name})
+ }
+ {[
+ { name: '数据中断', value: "data_outages", data: subTypeData['data_outages'][0] },
+ { name: '数据异常', value: "data_exception", data: subTypeData['data_exception'][0] },
+ { name: '策略命中', value: "strategy_hit", data: subTypeData['strategy_hit'][0] },
+ { name: '视频异常', value: "video_exception", data: subTypeData['video_exception'][0]?.map(v => ({ id: v.id, name: v.kind })) },
+ { name: '应用异常', value: "app_exception", data: subTypeData['app_exception'][0] },
+ { name: '设备异常', value: "device_exception", data: [...subTypeData['device_exception'][0], ...subTypeData['device_exception'][1]] },
+ ].filter(v => subType?.includes(v.value))?.map((u, index) => {
+ return v.id)) || []}
+ direction='horizontal'
+ showClear
+ >
+ {
+ u.data?.map((v, index) =>
+ {v.name})
+ }
+
+ })
+ }
接收信息配置
diff --git a/web/client/src/sections/service/containers/emPush.jsx b/web/client/src/sections/service/containers/emPush.jsx
index 2017936..ca73760 100644
--- a/web/client/src/sections/service/containers/emPush.jsx
+++ b/web/client/src/sections/service/containers/emPush.jsx
@@ -9,714 +9,750 @@ import '../style.less'
import { Setup } from "$components";
const EmPush = (props) => {
- const form = useRef();//表单
- const { dispatch, actions, user, loading, socket } = props
- const { service } = actions;
- const [setup, setSetup] = useState(false); //表格设置是否显现
- const [setupp, setSetupp] = useState([]);//实际显示的表格列表
- const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息
- const [limits, setLimits] = useState()//每页实际条数
- const mylimits = useRef(); //每页实际条数
- const [pushModal, setPushModal] = useState(false) //信鸽弹框
- const [pushEdit, setPushEdit] = useState(false) //是否是修改
- const [change, setChange] = useState(false) //是否改变
- const [allTableData, setAllTableData] = useState([]) //获取到的所有表格信息
- const [editObj, setEditObj] = useState({});//管理员弹框修改内容
- const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表
- const page = useRef(query.page);//哪一页
- const EMPUSH = "empush";
- const tableList = [//表格属性
- {
- title: '推送信息',
- list: [
- { name: "关联项目", value: "projectName" },
- { name: "策略名称", value: "name" },
- { name: "创建时间", value: "createTime" },
- { name: "接收人", value: "receiverPepUser" },
- { name: "推送方式", value: "pushType" },
- { name: "监听问题模块", value: "alarmType" },
- { name: "生效项目节点", value: "timeType" },
- { name: "推送机制", value: "tactics" },
- { name: "启用状态", value: "disable" },
- { name: "推送次数", value: "pushCount" },
- ]
- },
- ];
- const alarmTypeObj = {
- data_outages: '数据中断',
- data_exception: '数据异常',
- strategy_hit: '策略命中',
- video_exception: '视频异常',
- app_exception: '应用异常',
- device_exception: '设备异常',
- }
- const tacticsObj = {
- immediately: '即时推送机制',
- continue: '持续时长推送机制',
- abnormal_rate: '异常率推送机制',
- }
+ const form = useRef();//表单
+ const { dispatch, actions, user, loading, socket } = props
+ const { service, problem } = actions;
+ const [setup, setSetup] = useState(false); //表格设置是否显现
+ const [setupp, setSetupp] = useState([]);//实际显示的表格列表
+ const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息
+ const [limits, setLimits] = useState()//每页实际条数
+ const mylimits = useRef(); //每页实际条数
+ const [pushModal, setPushModal] = useState(false) //信鸽弹框
+ const [pushEdit, setPushEdit] = useState(false) //是否是修改
+ const [change, setChange] = useState(false) //是否改变
+ const [allTableData, setAllTableData] = useState([]) //获取到的所有表格信息
+ const [editObj, setEditObj] = useState({});//管理员弹框修改内容
+ const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表
+ const [subTypeData, setSubTypedata] = useState({
+ data_outages: [],
+ data_exception: [],
+ strategy_hit: [],
+ video_exception: [],
+ app_exception: [],
+ device_exception: [],
+ }); //数据类监听模块中的子类
+ const page = useRef(query.page);//哪一页
+ const EMPUSH = "empush";
+ const tableList = [//表格属性
+ {
+ title: '推送信息',
+ list: [
+ { name: "关联项目", value: "projectName" },
+ { name: "策略名称", value: "name" },
+ { name: "创建时间", value: "createTime" },
+ { name: "接收人", value: "receiverPepUser" },
+ { name: "推送方式", value: "pushType" },
+ { name: "监听问题模块", value: "alarmType" },
+ { name: "生效项目节点", value: "timeType" },
+ { name: "推送机制", value: "tactics" },
+ { name: "启用状态", value: "disable" },
+ { name: "推送次数", value: "pushCount" },
+ ]
+ },
+ ];
+ const alarmTypeObj = {
+ data_outages: '数据中断',
+ data_exception: '数据异常',
+ strategy_hit: '策略命中',
+ video_exception: '视频异常',
+ app_exception: '应用异常',
+ device_exception: '设备异常',
+ }
+ const tacticsObj = {
+ immediately: '即时推送机制',
+ continue: '持续时长推送机制',
+ abnormal_rate: '异常率推送机制',
+ }
- function handleRow (record, index) {//斑马条纹
- // 给偶数行设置斑马纹
- if (index % 2 === 0) {
- return {
- style: {
- background: '#FAFCFF',
- }
- };
- } else {
- return {};
- }
- }
- const [tableData, setTableData] = useState([]) //表格数据
+ function handleRow (record, index) {//斑马条纹
+ // 给偶数行设置斑马纹
+ if (index % 2 === 0) {
+ return {
+ style: {
+ background: '#FAFCFF',
+ }
+ };
+ } else {
+ return {};
+ }
+ }
+ const [tableData, setTableData] = useState([]) //表格数据
+
+ useEffect(() => {
+ localStorage.getItem(EMPUSH) == null
+ ? localStorage.setItem(
+ EMPUSH,
+ JSON.stringify(['projectName', 'name', 'createTime', 'receiverPepUser', 'alarmType', 'timeType', 'tactics', 'disable'])
+ )
+ : "";
+ getProjectStatusList()
+ getPushList(query);
- useEffect(() => {
- localStorage.getItem(EMPUSH) == null
- ? localStorage.setItem(
- EMPUSH,
- JSON.stringify(['projectName', 'name', 'createTime', 'receiverPepUser', 'alarmType', 'timeType', 'tactics', 'disable'])
- )
- : "";
- getProjectStatusList()
- getPushList(query);
- }, [])
- useEffect(() => {
- let showTableData = JSON.parse(JSON.stringify(allTableData)).slice(query.page * query.limit, (query.page + 1) * query.limit)
- setTableData(showTableData)
- mylimits.current = showTableData.length
- }, [change]);
+ //数据异常异常类型子类
+ dispatch(problem.getAlarmDataGroup({ showAll: 'true' })).then((res) => {
+ if (res.success) {
+ let data = { ...subTypeData }
+ res.payload.data?.map(v => {
+ if (v.id === 1) {
+ data['data_outages'].push(v.unit)
+ } else if (v.id === 2) {
+ data['data_exception'].push(v.unit)
+ } else if (v.id == 3) {
+ data['strategy_hit'].push(v.unit)
+ } else {
+ data['device_exception'].push(v.unit)
+ }
+ })
+ //视频异常异常类型子类
+ dispatch(problem.getAlarmVideoDeviceKind({ showAll: true })).then((res) => {
+ if (res.success) {
+ data['video_exception'].push(res.payload.data)
+ }
+ })
+ data['app_exception'].push([{ id: 'apiError', name: "接口报错", }, { id: 'element', name: "元素异常", }, { id: 'timeout', name: "加载超时", },])
+ setSubTypedata(data)
+ }
+ })
+ }, [])
- function getPushList (query) {
- let val = form.current.getValues()
- dispatch(service.getPush({ ...val })).then((res) => {//获取已绑定项目
- if (res.success) {
- let mytableData = JSON.parse(JSON.stringify(res.payload.data));
- for (let index = 0; index < mytableData.length; index++) {
- mytableData[index].key = String(mytableData[index].id)
- }
- setAllTableData(mytableData)
- let showTableData = mytableData.slice(query.page * query.limit, (query.page + 1) * query.limit)
- setTableData(showTableData)
- setQuery(query)
- setLimits(res.payload.data.length)
- mylimits.current = showTableData.length
+ useEffect(() => {
+ let showTableData = JSON.parse(JSON.stringify(allTableData)).slice(query.page * query.limit, (query.page + 1) * query.limit)
+ setTableData(showTableData)
+ mylimits.current = showTableData.length
+ }, [change]);
+
+ function getPushList (query) {
+ let val = form.current.getValues()
+ dispatch(service.getPush({ ...val })).then((res) => {//获取已绑定项目
+ if (res.success) {
+ let mytableData = JSON.parse(JSON.stringify(res.payload.data));
+ for (let index = 0; index < mytableData.length; index++) {
+ mytableData[index].key = String(mytableData[index].id)
}
- })
- }
- function getProjectStatusList () {//获取项目状态列表
- dispatch(service.getProjectStatus()).then((res) => {
- if (res.success) {
- setProjectStatus(res.payload?.data)
- attribute(res.payload?.data);
+ setAllTableData(mytableData)
+ let showTableData = mytableData.slice(query.page * query.limit, (query.page + 1) * query.limit)
+ setTableData(showTableData)
+ setQuery(query)
+ setLimits(res.payload.data.length)
+ mylimits.current = showTableData.length
+ }
+ })
+ }
+ function getProjectStatusList () {//获取项目状态列表
+ dispatch(service.getProjectStatus()).then((res) => {
+ if (res.success) {
+ setProjectStatus(res.payload?.data)
+ attribute(res.payload?.data);
+ }
+ })
+ }
+ const columns = [//表格属性
+ {
+ title: "操作",
+ width: "12%",
+ dataIndex: "text",
+ key: 'text',
+ render: (_, row) => {
+ return (
+
+
+ {row?.disable ? (
+
+ ) : (
+
{
+ dispatch(service.putPushPushId({ pushId: row?.id, del: false, disable: true, msg: '更改推送配置状态' })).then(() => {
+ getPushList({ limit: query.limit, page: page.current });
+ })
+ }}
+ >
+
+
+ )}
+
{
+ dispatch(service.putPushPushId({ pushId: row?.id, del: true, disable: false, msg: '删除推送配置' })).then(() => {
+ if (page.current > 0 && mylimits.current < 2) {
+ getPushList({ limit: query.limit, page: page.current - 1 });
+ } else {
+ getPushList({ limit: query.limit, page: page.current });
+ }
+ })
+ }}
+ >
+
+
+
+ );
+ },
+ },
+ ]
+ function expandRowRender (record, index) {
+ return (
+
+ 结构物:
+ {
+ record.structure?.map((item, index) => {
+ return (
+
+ {item.name}
+
+ )
+ })
}
- })
- }
- const columns = [//表格属性
- {
- title: "操作",
- width: "12%",
- dataIndex: "text",
- key: 'text',
+
+ )
+ }
+ //获取表格属性设置
+ function attribute (val) {
+ const arr = localStorage.getItem(EMPUSH)
+ ? JSON.parse(localStorage.getItem(EMPUSH))
+ : [];
+ const column = [
+ {
+ title: '关联项目',
+ dataIndex: "projectName",
+ key: "projectName",
render: (_, row) => {
- return (
-
-
- {row?.disable ? (
-
- )
- }
- },
- {
- title: "推送方式",
- dataIndex: "pushType",
- key: "pushType",
- render: (_, r, index) => {
- return '邮件通知';
- },
+ }
+
+ )
+ }
+ },
+ {
+ title: '策略名称',
+ dataIndex: "name",
+ key: 'name',
+ render: (_, row) => {
+ return row.name
+ }
+ },
+ {
+ title: "创建时间",
+ dataIndex: "createTime",
+ key: "createTime",
+ render: (_, r, index) => {
+ return moment(r.createTime).format('YYYY-MM-DD HH:mm:ss');
},
- {
- title: "监听问题模块",
- dataIndex: "alarmType",
- key: "alarmType",
- render: (_, row) => {
- return (
-
- {
- row.alarmType.map((item, index) => {
- return (
-
-
1 ? 'none' : '' }}>
- {alarmTypeObj[item]}
-
-
0 ? 'none' : '' }}>
-
- )
- })
- }
- {
- row.alarmType.length > 2 ? (
-
- {
- row.alarmType.map((item, index) => {
- return (
-
- {alarmTypeObj[item]},
-
- )
- })
- }
-
- } trigger="click" style={{ lineHeight: 2 }}>
-
- +{row.alarmType.length - 2}
-
-
- ) : ('')
- }
-
- )
- }
+ },
+ {
+ title: '接收人',
+ dataIndex: "receiverPepUser",
+ key: 'receiverPepUser',
+ render: (_, row) => {
+ return (
+
+ {
+ row.receiverPepUser.map((item, index) => {
+ return (
+
+
1 ? 'none' : '', color: '#005ABD' }}>
+ {item.name}
+
+
0 ? 'none' : '' }}>
+
+ )
+ })
+ }
+ {
+ row.receiverPepUser.length > 2 ? (
+
+ {
+ row.receiverPepUser.map((item, index) => {
+ return (
+
+ {item.name},
+
+ )
+ })
+ }
+
+ } trigger="click" style={{ lineHeight: 2 }}>
+
+ +{row.receiverPepUser.length - 2}
+
+
+ ) : ('')
+ }
+
+ )
+ }
+ },
+ {
+ title: "推送方式",
+ dataIndex: "pushType",
+ key: "pushType",
+ render: (_, r, index) => {
+ return '邮件通知';
},
- {
- title: "生效项目节点",
- dataIndex: "timeType",
- key: "timeType",
- render: (_, row, index) => {
- return (
-
- {
- row.timeType.length > 0 ? (
- row.timeType.map((item, index) => {
- return (
-
1 ? 'none' : 'flex', alignItems: 'center'
- }}>
-
-
-
-
- {
- val.map((ite, idx) => {
- return (
-
- {ite.id == item ? ite.construction_status : ''}
-
- )
- })
- }
-
-
- )
+ },
+ {
+ title: "监听问题模块",
+ dataIndex: "alarmType",
+ key: "alarmType",
+ render: (_, row) => {
+ return (
+
+ {
+ row.alarmType.map((item, index) => {
+ return (
+
+
1 ? 'none' : '' }}>
+ {alarmTypeObj[item]}
+
+
0 ? 'none' : '' }}>
+
+ )
+ })
+ }
+ {
+ row.alarmType.length > 2 ? (
+
+ {
+ row.alarmType.map((item, index) => {
+ return (
+
+ {alarmTypeObj[item]},
+
+ )
})
- ) : (
-
-
-
-
-
- POMS
-
+ }
+
+ } trigger="click" style={{ lineHeight: 2 }}>
+
+ +{row.alarmType.length - 2}
+
+
+ ) : ('')
+ }
+
+ )
+ }
+ },
+ {
+ title: "生效项目节点",
+ dataIndex: "timeType",
+ key: "timeType",
+ render: (_, row, index) => {
+ return (
+
+ {
+ row.timeType.length > 0 ? (
+ row.timeType.map((item, index) => {
+ return (
+
1 ? 'none' : 'flex', alignItems: 'center'
+ }}>
+
+
+
+
+ {
+ val.map((ite, idx) => {
+ return (
+
+ {ite.id == item ? ite.construction_status : ''}
+
+ )
+ })
+ }
- )
- }
- {
- row.timeType.length > 2 ? (
-
- {
- row.timeType.map((item, index) => {
- return (
-
- {
- val.map((ite, idx) => {
- return (
-
- {ite.id == item ? ite.construction_status : ''}
-
- )
- })
- },
-
- )
+
+ )
+ })
+ ) : (
+
+
+
+
+
+ POMS
+
+
+ )
+ }
+ {
+ row.timeType.length > 2 ? (
+
+ {
+ row.timeType.map((item, index) => {
+ return (
+
+ {
+ val.map((ite, idx) => {
+ return (
+
+ {ite.id == item ? ite.construction_status : ''}
+
+ )
})
- }
-
- } trigger="click" style={{ lineHeight: 2 }}>
-
- +{row.timeType.length - 2}
-
-
- ) : ('')
- }
-
- )
- },
+ },
+
+ )
+ })
+ }
+
+ } trigger="click" style={{ lineHeight: 2 }}>
+
+ +{row.timeType.length - 2}
+
+
+ ) : ('')
+ }
+
+ )
},
- {
- title: "推送机制",
- dataIndex: "tactics",
- key: "tactics",
- render: (_, r, index) => {
- return tacticsObj[r.tactics]
- },
+ },
+ {
+ title: "推送机制",
+ dataIndex: "tactics",
+ key: "tactics",
+ render: (_, r, index) => {
+ return tacticsObj[r.tactics]
},
- {
- title: "启用状态",
- dataIndex: "disable",
- key: "disable",
- render: (_, row, index) => {
- let enableType = ''
- if (row.disable) {
- enableType = '禁用'
- }
- else {
- if (row.timeType.length > 0) {
- for (let i = 0; i < row.timeType.length; i++) {
- if (row.timeType[i] == row.pomsProject?.pepProject?.constructionStatusId) {
- enableType = '已生效'
- break;
- } else {
- enableType = '未生效'
- }
- }
- }
- else {
- enableType = '已生效'
+ },
+ {
+ title: "启用状态",
+ dataIndex: "disable",
+ key: "disable",
+ render: (_, row, index) => {
+ let enableType = ''
+ if (row.disable) {
+ enableType = '禁用'
+ }
+ else {
+ if (row.timeType.length > 0) {
+ for (let i = 0; i < row.timeType.length; i++) {
+ if (row.timeType[i] == row.pomsProject?.pepProject?.constructionStatusId) {
+ enableType = '已生效'
+ break;
+ } else {
+ enableType = '未生效'
}
- }
- return (
-
- {enableType}
-
- )
- },
+ }
+ }
+ else {
+ enableType = '已生效'
+ }
+ }
+ return (
+
+ {enableType}
+
+ )
},
- {
- title: "推送次数",
- dataIndex: "pushCount",
- key: "pushCount",
- render: (_, r, index) => {
- return (r.pushCount||0) + '次'
- },
+ },
+ {
+ title: "推送次数",
+ dataIndex: "pushCount",
+ key: "pushCount",
+ render: (_, r, index) => {
+ return (r.pushCount || 0) + '次'
},
- ];
- for (let i = 0; i < arr.length; i++) {
- let colum = column.filter((item) => {
- return item.key === arr[i];
- });
- columns.splice(columns.length - 1, 0, colum[0]);
- }
- setSetupp(columns);
- }
- return (
- <>
-
-
-
-
-
- 项目
- 结构物
- 策略名
-
-
}
- field="keyword"
- pure
- showClear
- style={{ width: 260, marginLeft: 12, marginRight: 12 }}
- placeholder="请输入或选择关键词"
- />
-
- 即时推送机制
- 持续时长推送机制
- 异常率推送机制
-
-
- 已生效
- 未生效
- 禁用
-
-
-
{
- getPushList({ limit: query.limit, page: 0 })
- }}
- >
- 查询
-
-
-
setSetup(true)} />
-
-
{
- setEditObj({})
- setPushModal(true);
- setPushEdit(false);
- }}
- >
- 添加推送策略
-
-
-
-
-
EM推送提供对映射关系组的项目、结构物问题的监听和通知服务,支持对设备异常率、问题持续时间、即时响应等策略定义的动态推送。
-
-
-
- s)}
- dataSource={tableData}
- bordered={false}
- hideExpandedColumn={false}
- empty="暂无数据"
- expandedRowRender={expandRowRender}
- pagination={false}
- onRow={handleRow}
- />
-
-
-
-
-
-
- 共{limits}条信息
-
-
{
- setQuery({ limit: pageSize, page: currentPage - 1 });
- page.current = currentPage - 1
- setChange(!change)
- }}
- />
-
-
-
+ },
+ ];
+ for (let i = 0; i < arr.length; i++) {
+ let colum = column.filter((item) => {
+ return item.key === arr[i];
+ });
+ columns.splice(columns.length - 1, 0, colum[0]);
+ }
+ setSetupp(columns);
+ }
+ return (
+ <>
+
+
+
+
+
+ 项目
+ 结构物
+ 策略名
+
+
}
+ field="keyword"
+ pure
+ showClear
+ style={{ width: 260, marginLeft: 12, marginRight: 12 }}
+ placeholder="请输入或选择关键词"
+ />
+
+ 即时推送机制
+ 持续时长推送机制
+ 异常率推送机制
+
+
+ 已生效
+ 未生效
+ 禁用
+
+
+
{
+ getPushList({ limit: query.limit, page: 0 })
+ }}
+ >
+ 查询
+
+
+
setSetup(true)} />
+
+
{
+ setPushModal(true);
+ setPushEdit(false);
+ setEditObj({})
+ }}
+ >
+ 添加推送策略
+
+
- {//推送配置弹框
- pushModal ?
-
{
- setPushModal(false);
+
+
EM推送提供对映射关系组的项目、结构物问题的监听和通知服务,支持对设备异常率、问题持续时间、即时响应等策略定义的动态推送。
+
+
+
+ s)}
+ dataSource={tableData}
+ bordered={false}
+ hideExpandedColumn={false}
+ empty="暂无数据"
+ expandedRowRender={expandRowRender}
+ pagination={false}
+ onRow={handleRow}
+ />
+
+
+
+
+
+
+ 共{limits}条信息
+
+
{
+ setQuery({ limit: pageSize, page: currentPage - 1 });
+ page.current = currentPage - 1
+ setChange(!change)
}}
- close={() => {
- setPushModal(false);
- getPushList(query)
- }} >
- : ''
- }
- {setup ? (
- {
- setSetup(false);
- attribute(projectStatus);
- }}
- />
- ) : (
- ""
- )}
- >
- )
+ />
+
+
+
+
+ {//推送配置弹框
+ pushModal ?
+ {
+ setPushModal(false);
+ }}
+ close={() => {
+ setPushModal(false);
+ getPushList(query)
+ }} >
+ : ''
+ }
+ {setup ? (
+ {
+ setSetup(false);
+ attribute(projectStatus);
+ }}
+ />
+ ) : (
+ ""
+ )}
+ >
+ )
}
function mapStateToProps (state) {
- const { auth, global, getPush } = state;
- return {
- loading: getPush.isRequesting,
- user: auth.user,
- actions: global.actions,
- // members: members.data,
- };
+ const { auth, global, getPush } = state;
+ return {
+ loading: getPush.isRequesting,
+ user: auth.user,
+ actions: global.actions,
+ // members: members.data,
+ };
}
export default connect(mapStateToProps)(EmPush);