From 63f5090e4aaafce23f7b27544d54e5e4dfe93d85 Mon Sep 17 00:00:00 2001 From: wenlele Date: Fri, 18 Nov 2022 11:40:06 +0800 Subject: [PATCH 01/51] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=20=20=E7=AE=A1=E7=90=86=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E7=9A=84=E7=BC=A9=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/client/src/sections/install/containers/system.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/client/src/sections/install/containers/system.jsx b/web/client/src/sections/install/containers/system.jsx index 26017d2..2702f5d 100644 --- a/web/client/src/sections/install/containers/system.jsx +++ b/web/client/src/sections/install/containers/system.jsx @@ -258,7 +258,7 @@ const Example = (props) => { }, { title: "管理", - width: "20%", + width: "150px", dataIndex: "text", key: 'text', render: (_, row) => { From 80dc0880ba680ac86fc40823a38062e6d06b439c Mon Sep 17 00:00:00 2001 From: wenlele Date: Fri, 18 Nov 2022 15:39:23 +0800 Subject: [PATCH 02/51] =?UTF-8?q?=20=E6=98=A0=E5=B0=84=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=9B=BE=E8=A2=AB=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=9A=84=E9=A1=B9=E7=9B=AE=EF=BC=8C=E5=85=B3=E8=81=94?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E5=92=8C=E6=B7=BB=E5=8A=A0=E4=BA=BA=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/project/bind.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/app/lib/controllers/project/bind.js b/api/app/lib/controllers/project/bind.js index 06d25c2..3cfa989 100644 --- a/api/app/lib/controllers/project/bind.js +++ b/api/app/lib/controllers/project/bind.js @@ -105,6 +105,9 @@ async function bindAnxin2pep (ctx) { // 但是有之前的数据 if (existRes.del) { // 不过之前的删除了 + storageData.createUser = userId + storageData.updateTime = now.format() + storageData.createTime = now.format() await models.ProjectCorrelation.update(storageData, { where: { pepProjectId: pepProjectId From 9d2d96bd75077f0644cd42493bc9f463a3cf341c Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Mon, 21 Nov 2022 08:53:32 +0800 Subject: [PATCH 03/51] =?UTF-8?q?=E5=8D=B3=E6=97=B6=E6=8E=A8=E9=80=81=20ti?= =?UTF-8?q?p?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/client/src/sections/service/components/pushModal.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 823a436..d83ee43 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -500,7 +500,7 @@ function pushModal (props) { value='immediately' extra={ - 发现在 + 中台每分钟查询,若有告警源新增,则每 - 分钟内,有告警源新增,则通过【信鸽服务】发送一条通知信息。 + 分钟通过【信鸽服务】发送一条通知信息。 } style={{ width: 198 }}> From 8a133eed215c136aae66cd5ceb1132c522bd09af Mon Sep 17 00:00:00 2001 From: wenlele Date: Mon, 21 Nov 2022 09:30:37 +0800 Subject: [PATCH 04/51] =?UTF-8?q?=E6=8E=A8=E9=80=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/service/components/pushModal.jsx | 1271 +++++++++-------- 1 file changed, 637 insertions(+), 634 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index d83ee43..0b547ff 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -6,660 +6,663 @@ import './pushModal.less' function pushModal (props) { - const { - close, - cancel, - visible, - dispatch, - pepList, - actions, - pushEdit,//是否是编辑 - editObj, - user - } = props; - const { service } = actions; - const form = useRef();//表单 - const [abnormal, setAbnormal] = useState(false); //异常率推送机制disable - const [usersList, setUsersList] = useState([]); //获取全部未删除用户 - const [structure, setStructure] = useState(true); //结构物disable - const [projectPoms, setProjectPoms] = useState([]); //获取已绑定项目 - const [projectStructure, setProjectStructure] = useState([]); //获取绑定项目下结构物 - const [timeTypeDis, setTimeTypeDis] = useState(true); //通知时效disable - const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表 - const timeTypePOMS = useRef([]);//表单 + const { + close, + cancel, + visible, + dispatch, + pepList, + actions, + pushEdit,//是否是编辑 + editObj, + user + } = props; + const { service } = actions; + const form = useRef();//表单 + const [abnormal, setAbnormal] = useState(false); //异常率推送机制disable + const [usersList, setUsersList] = useState([]); //获取全部未删除用户 + const [structure, setStructure] = useState(true); //结构物disable + const [projectPoms, setProjectPoms] = useState([]); //获取已绑定项目 + const [projectStructure, setProjectStructure] = useState([]); //获取绑定项目下结构物 + const [timeTypeDis, setTimeTypeDis] = useState(true); //通知时效disable + const [projectStatus, setProjectStatus] = useState([]); //获取项目状态列表 + const timeTypePOMS = useRef([]);//表单 - const [interval1, setInterval1] = useState(undefined); // - const [interval2, setInterval2] = useState(undefined); // - const [interval3, setInterval3] = useState(undefined); // - const [deviceProportion, setDeviceProportion] = useState(undefined); // + const [interval1, setInterval1] = useState(undefined); // + const [interval2, setInterval2] = useState(undefined); // + const [interval3, setInterval3] = useState(undefined); // + const [deviceProportion, setDeviceProportion] = useState(undefined); // - //初始化 - useEffect(() => { - getOrganizationUsersList()//获取全部未删除用户 - getProjectPomsList()//获取已绑定项目 - if (editObj.id) { - getProjectStructureList(editObj.pomsProjectId) - if (editObj.pomsProject?.pepProjectId) { - getProjectStatusList()//获取项目状态列表 + //初始化 + useEffect(() => { + getOrganizationUsersList()//获取全部未删除用户 + getProjectPomsList()//获取已绑定项目 + if (editObj.id) { + getProjectStructureList(editObj.pomsProjectId) + if (editObj.pomsProject?.pepProjectId) { + getProjectStatusList()//获取项目状态列表 + } + else { + setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) + timeTypePOMS.current = ['POMS'] + } + if (editObj.tactics == 'immediately') { + setInterval1(editObj.tacticsParams?.interval) + } else if (editObj.tactics == 'continue') { + setInterval2(editObj.tacticsParams?.interval) + } else if (editObj.tactics == 'abnormal_rate') { + setInterval3(editObj.tacticsParams?.interval) + setDeviceProportion(editObj.tacticsParams?.deviceProportion) + } + } + }, []); + function getOrganizationUsersList () {//获取全部未删除用户 + dispatch(service.getOrganizationUsers()).then((res) => { + if (res.success) { + setUsersList(res.payload.data) + } + }) + } + function getProjectPomsList () {//获取已绑定项目 + dispatch(service.getProjectPoms()).then((res) => { + if (res.success) { + setProjectPoms(res.payload?.data?.rows) + } + }) + } + function getProjectStructureList (value) {//获取绑定项目下结构物 + dispatch(service.getProjectStructure({ pomsProjectId: value })).then((res) => { + if (res.success) { + let mylist = [] + for (let i = 0; i < res.payload?.data.length; i++) { + mylist.push(res.payload?.data[i].id) } - else { - setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) - timeTypePOMS.current = ['POMS'] - } - if (editObj.tactics == 'immediately') { - setInterval1(editObj.tacticsParams?.interval) - } else if (editObj.tactics == 'continue') { - setInterval2(editObj.tacticsParams?.interval) - } else if (editObj.tactics == 'abnormal_rate') { - setInterval3(editObj.tacticsParams?.interval) - setDeviceProportion(editObj.tacticsParams?.deviceProportion) - } - } - }, []); - function getOrganizationUsersList () {//获取全部未删除用户 - dispatch(service.getOrganizationUsers()).then((res) => { - if (res.success) { - setUsersList(res.payload.data) - } - }) - } - function getProjectPomsList () {//获取已绑定项目 - dispatch(service.getProjectPoms()).then((res) => { - if (res.success) { - setProjectPoms(res.payload?.data?.rows) + setProjectStructure(res.payload?.data) + form.current.setValue('strucId', mylist) + form.current.validate(['strucId', 'timeType']) + setStructure(false) + setTimeTypeDis(false) + } + }) + } + function getProjectStatusList () {//获取项目状态列表 + dispatch(service.getProjectStatus()).then((res) => { + if (res.success) { + setProjectStatus(res.payload?.data) + let mylist = [] + for (let i = 0; i < res.payload?.data.length; i++) { + mylist.push(res.payload?.data[i].id) } - }) - } - function getProjectStructureList (value) {//获取绑定项目下结构物 - dispatch(service.getProjectStructure({ pomsProjectId: value })).then((res) => { - if (res.success) { - let mylist = [] - for (let i = 0; i < res.payload?.data.length; i++) { - mylist.push(res.payload?.data[i].id) - } - setProjectStructure(res.payload?.data) - form.current.setValue('strucId', mylist) - form.current.validate(['strucId', 'timeType']) - setStructure(false) - setTimeTypeDis(false) - } - }) - } - function getProjectStatusList () {//获取项目状态列表 - dispatch(service.getProjectStatus()).then((res) => { - if (res.success) { - setProjectStatus(res.payload?.data) - let mylist = [] - for (let i = 0; i < res.payload?.data.length; i++) { - mylist.push(res.payload?.data[i].id) - } - form.current.setValue('timeType', mylist) - form.current.validate(['strucId', 'timeType']) - } - }) - } - 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, - }) - } + form.current.setValue('timeType', mylist) + form.current.validate(['strucId', 'timeType']) + } + }) + } + 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: '即时推送时间应为正整数', - duration: 2, - }) + Notification.error({ + content: '即时推送时间不能大于1440分钟', + 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 { + 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: '持续时长推送时间应为正整数', - duration: 2, - }) + Notification.error({ + content: '持续时长推送时间不能大于1440分钟', + 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, - }) + } 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 } - } - } - else { - 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({ ...obj, msg: '新增推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户 - if (res.success) { - close(); - } - }) - } else { - Notification.error({ - content: '即时推送时间不能大于1440分钟', - duration: 2, - }) - } - } else { - Notification.error({ - content: '即时推送时间应为正整数', - duration: 2, - }) - } + 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, + }) + } + } + } + else { + 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({ ...obj, msg: '新增推送配置' })).then((res) => {//获取项企(PEP)全部部门及其下用户 + if (res.success) { + close(); + } + }) } else { - Notification.error({ - content: '即时推送时间应为正整数', - duration: 2, - }) + Notification.error({ + content: '即时推送时间不能大于1440分钟', + 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 { + 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: '持续时长推送时间应为正整数', - duration: 2, - }) + Notification.error({ + content: '持续时长推送时间不能大于1440分钟', + 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, - }) + } 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 } - } - } - }) - } - function handleCancel () { - cancel(); - //点击弹框取消 左边按钮 - } - return ( - <> - -
-
{ - for (var key in field) { - if (key == 'tactics') { - if (values.tactics == 'abnormal_rate') { - form.current.setValue('alarmType', undefined) - setAbnormal(true) - } - else { - setAbnormal(false) - } - } - if (key == 'pomsProjectId') { - getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 - for (let i = 0; i < projectPoms.length; i++) { - if (values.pomsProjectId == projectPoms[i].id) { - if (projectPoms[i].pepProjectId) { - getProjectStatusList()//获取项目状态列表 - } - else { - setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) - form.current.setValue('timeType', ['POMS']) - form.current.validate() - } - } - } - } - } - }} - getFormApi={(formApi) => (form.current = formApi)} - > -
- 项目信息配置 -
-
- -
-
- - { - projectPoms.map((item, index) => { - return ( - - {item.pepProjectName || item.name} - - ) - }) - } - -
-
- - { - projectStructure.map((item, index) => { - return ( - - {item.name} - - ) - }) - } - -
-
- - - 中台每分钟查询,若有告警源新增,则每 - - 分钟通过【信鸽服务】发送一条通知信息。 - - } - style={{ width: 198 }}> - 即时推送机制 - - - 告警源持续产生时间超过 - - 分钟,则通过【信鸽服务】发送一条通知信息。 - - } - style={{ width: 198 }}> - 持续时长推送机制 - - - 异常设备数量达到项目或结构物内设备总数量的 - - %,且持续时长超过 - - 小时,则通过【信鸽服务】发送一条通知信息。 - - } - style={{ width: 260 }}> - 异常率推送机制 - - -
-
- - 数据中断 - 数据异常 - 策略命中 - 视频异常 - 应用异常 - 设备异常 - -
-
- 接收信息配置 -
-
- 0 ? editObj?.timeType : timeTypePOMS.current} - disabled={timeTypeDis} - multiple - maxTagCount={3} - > - { - projectStatus.map((item, index) => { - return ( - - {item.construction_status} - - ) - }) - } - - - { - usersList.map((item, index) => { - return ( - - {item.name} - - ) - }) - } - -
-
- 不在项目节点的通知策略,会自动失效. -
-
- - - 启用 - - - 禁用 - - + 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, + }) + } + } + } + }) + } + function handleCancel () { + cancel(); + //点击弹框取消 左边按钮 + } + return ( + <> + +
+ { + for (var key in field) { + if (key == 'tactics') { + if (values.tactics == 'abnormal_rate') { + form.current.setValue('alarmType', undefined) + setAbnormal(true) + } + else { + setAbnormal(false) + } + } + if (key == 'pomsProjectId') { + getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 + for (let i = 0; i < projectPoms.length; i++) { + if (values.pomsProjectId == projectPoms[i].id) { + if (projectPoms[i].pepProjectId) { + getProjectStatusList()//获取项目状态列表 + } + else { + setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) + form.current.setValue('timeType', ['POMS']) + form.current.validate() + } + } + } + } + } + }} + getFormApi={(formApi) => (form.current = formApi)} + > +
+ 项目信息配置 +
+
+ +
+
+ + { + projectPoms.map((item, index) => { + return ( + + {item.pepProjectName || item.name} + + ) + }) + } + +
+
+ + { + projectStructure.map((item, index) => { + return ( + + {item.name} + + ) + }) + } + +
+
+ +
+ + 中台每分钟查询,若有告警源新增,则每 + + 分钟通过【信鸽服务】发送一条通知信息。 + + } + style={{ width: 198 }}> + 即时推送机制 + + + 告警源持续产生时间超过 + + 分钟,则通过【信鸽服务】发送一条通知信息。 + + } + style={{ width: 198 }}> + 持续时长推送机制 + + + 异常设备数量达到项目或结构物内设备总数量的 + + %,且持续时长超过 + + 小时,则通过【信鸽服务】发送一条通知信息。 + + } + style={{ width: 260 }}> + 异常率推送机制 +
- -
- - - ); + + +
+
+ + 数据中断 + 数据异常 + 策略命中 + 视频异常 + 应用异常 + 设备异常 + +
+
+ 接收信息配置 +
+
+ 0 ? editObj?.timeType : timeTypePOMS.current} + disabled={timeTypeDis} + multiple + maxTagCount={3} + > + { + projectStatus.map((item, index) => { + return ( + + {item.construction_status} + + ) + }) + } + + + { + usersList.map((item, index) => { + return ( + + {item.name} + + ) + }) + } + +
+
+ 不在项目节点的通知策略,会自动失效. +
+
+ + + 启用 + + + 禁用 + + +
+ +
+ + + ); } function mapStateToProps (state) { - const { auth, global, members } = state; - return { - // loading: members.isRequesting, - user: auth.user, - actions: global.actions, - // members: members.data, - }; + const { auth, global, members } = state; + return { + // loading: members.isRequesting, + user: auth.user, + actions: global.actions, + // members: members.data, + }; } export default connect(mapStateToProps)(pushModal); From c84f57cb825a9386fd60f5522f90f683d2a892e0 Mon Sep 17 00:00:00 2001 From: wenlele Date: Tue, 22 Nov 2022 16:48:41 +0800 Subject: [PATCH 05/51] =?UTF-8?q?=E9=80=89=E6=8B=A9=E7=9B=91=E5=90=AC?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=A8=A1=E5=9D=97=E7=BB=86=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/alarm/data.js | 18 +- api/app/lib/controllers/alarm/video.js | 16 +- api/app/lib/controllers/push/config.js | 4 +- api/app/lib/models/alarm_push_config.js | 9 + api/app/lib/schedule/alarms_push.js | 26 +- .../0.10/schema/1.alter_alarm_push_config.sql | 8 + .../src/sections/problem/actions/problem.jsx | 24 +- .../sections/service/components/pushModal.jsx | 379 ++--- .../sections/service/containers/emPush.jsx | 1402 +++++++++-------- 9 files changed, 891 insertions(+), 995 deletions(-) create mode 100644 script/0.10/schema/1.alter_alarm_push_config.sql 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 ? ( - + } +
+
) : ( - { - 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} - +
+
+ +
+
+ POMS +
+
) - }) - } -
- ) - } - //获取表格属性设置 - function attribute (val) { - const arr = localStorage.getItem(EMPUSH) - ? JSON.parse(localStorage.getItem(EMPUSH)) - : []; - const column = [ - { - title: '关联项目', - dataIndex: "projectName", - key: "projectName", - render: (_, row) => { - let anxinerror = false - let anxinerrorArr = '' - if (row.pomsProject.del == true) { - anxinerror = true - anxinerrorArr = row.pomsProject.pepProject?.projectName || row.pomsProject.name - } - return ( -
- { - anxinerror ? ( - -
- -
-
) : ('') - } - { -
- -
7 || row.pomsProject?.name?.length > 7 ? '112px' : '', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', color: row.pomsProject.del ? '#F93920' : '' }}> - {row.pomsProject.pepProject?.projectName || row.pomsProject.name} -
-
-
- } - { - row.pomsProject?.pepProject?.projectName ? ( -
-
- -
-
- { - val.map((ite, idx) => { - return ( -
- {ite.id == row.pomsProject?.pepProject.constructionStatusId ? ite.construction_status : ''} -
- ) - }) - } -
-
- ) : ( -
-
- -
-
- POMS -
-
- ) - } -
- ) - } - }, - { - 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: "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: "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 ( - <> -
-
-
-
-
EM推送
-
Em push
-
-
-
console.log(values)} - getFormApi={(formApi) => (form.current = formApi)} - layout="horizontal" - style={{ position: "relative", width: "100%", flex: 1 }} - > - - 项目 - 结构物 - 策略名 - - } - field="keyword" - pure - showClear - style={{ width: 260, marginLeft: 12, marginRight: 12 }} - placeholder="请输入或选择关键词" - /> - - 即时推送机制 - 持续时长推送机制 - 异常率推送机制 - - - 已生效 - 未生效 - 禁用 - - - -
- setSetup(true)} /> -
- -
-
-
-
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 ( + <> +
+
+
+
+
EM推送
+
Em push
+
+
+
console.log(values)} + getFormApi={(formApi) => (form.current = formApi)} + layout="horizontal" + style={{ position: "relative", width: "100%", flex: 1 }} + > + + 项目 + 结构物 + 策略名 + + } + field="keyword" + pure + showClear + style={{ width: 260, marginLeft: 12, marginRight: 12 }} + placeholder="请输入或选择关键词" + /> + + 即时推送机制 + 持续时长推送机制 + 异常率推送机制 + + + 已生效 + 未生效 + 禁用 + + + +
+ setSetup(true)} /> +
+ +
- {//推送配置弹框 - 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); From 004be069f9bf0cc52b0a4d9aa0a562cb3f15209c Mon Sep 17 00:00:00 2001 From: wenlele Date: Tue, 22 Nov 2022 17:02:09 +0800 Subject: [PATCH 06/51] =?UTF-8?q?=E5=AD=90=E7=B1=BB=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/client/src/sections/service/components/pushModal.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 78cdbfe..1c4ebc8 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -384,7 +384,7 @@ function pushModal (props) { key={u.name + u.index} field={u.value} style={{ width: 695 }} - initValue={(editObj?.id && (editObj?.alarmSubType && editObj?.alarmSubType[u.value]) || u.data.map(v => v.id)) || []} + initValue={(editObj?.id && (editObj?.alarmSubType ? editObj?.alarmSubType[u.value] : u.data.map(v => v.id))) || []} direction='horizontal' showClear > From b1a4d03bb51ef8f96b3032d8ae3b0697312f33f9 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 23 Nov 2022 09:18:04 +0800 Subject: [PATCH 07/51] =?UTF-8?q?=E7=BB=91=E5=AE=9A=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=9A=84=E7=BB=93=E6=9E=84=E7=89=A9=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?id=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/project/index.js | 42 +++++++++++-------- .../0.10/schema/1.alter_alarm_push_config.sql | 8 ++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/api/app/lib/controllers/project/index.js b/api/app/lib/controllers/project/index.js index 2659964..c2807a3 100644 --- a/api/app/lib/controllers/project/index.js +++ b/api/app/lib/controllers/project/index.js @@ -57,7 +57,7 @@ async function pomsProject (ctx) { if (p.pepProjectId) { pepProjectIds.add(p.pepProjectId) } - if(p.createUser){ + if (p.createUser) { createUsers.add(p.createUser) } for (let ap of p.anxinProjectId) { @@ -66,18 +66,18 @@ async function pomsProject (ctx) { } } } - const pomsUser = await models.User.findAll({ - where: { - id: { $in: [...createUsers]} - } - }) - let pepUserIds = new Set() - for (let p of pomsUser) { - if (p.pepUserId) { + const pomsUser = await models.User.findAll({ + where: { + id: { $in: [...createUsers] } + } + }) + let pepUserIds = new Set() + for (let p of pomsUser) { + if (p.pepUserId) { pepUserIds.add(p.pepUserId) - } - } - const pepcaUser = pepUserIds.size ? + } + } + const pepcaUser = pepUserIds.size ? await clickHouse.pepEmis.query( ` SELECT * FROM user @@ -112,7 +112,7 @@ async function pomsProject (ctx) { for (let p of proRes.rows) { const corPro = pepProjectRes.find(pp => pp.id == p.pepProjectId) || {} - const pepUserName = (pepcaUser.find(qq => qq.id == (pomsUser.find(oo => oo.id == p.createUser)||{}).pepUserId)||{}).name ||'' + const pepUserName = (pepcaUser.find(qq => qq.id == (pomsUser.find(oo => oo.id == p.createUser) || {}).pepUserId) || {}).name || '' p.dataValues.pepProjectName = corPro.project_name p.dataValues.pepProjectIsDelete = corPro.isdelete p.dataValues.constructionStatusId = corPro.construction_status_id @@ -210,15 +210,23 @@ async function strucWithPomsProject (ctx) { const { clickHouse } = ctx.app.fs const { pomsProjectId } = ctx.query - const bindRes = await models.ProjectCorrelation.findOne({ + const bindRes = await models.ProjectCorrelation.findAll({ where: { - id: pomsProjectId + id: { $in: pomsProjectId.split(',') } } }) + let anxinProjectIds = new Set() + for (let b of bindRes) { + if (b.anxinProjectId.length) { + for (let aid of b.anxinProjectId) { + anxinProjectIds.add(aid) + } + } + } let undelStruc = [] if (bindRes) { - const undelStrucRes = bindRes.anxinProjectId.length ? + const undelStrucRes = anxinProjectIds.size ? await clickHouse.anxinyun.query( ` SELECT @@ -249,7 +257,7 @@ async function strucWithPomsProject (ctx) { WHERE project_state != -1 AND - t_project.id IN (${bindRes.anxinProjectId.join(',')}) + t_project.id IN (${[...anxinProjectIds].join(',')}, -1) ORDER BY strucId ` ).toPromise() : diff --git a/script/0.10/schema/1.alter_alarm_push_config.sql b/script/0.10/schema/1.alter_alarm_push_config.sql index 08ad5b3..8bf1d54 100644 --- a/script/0.10/schema/1.alter_alarm_push_config.sql +++ b/script/0.10/schema/1.alter_alarm_push_config.sql @@ -6,3 +6,11 @@ comment on column alarm_push_config.alarm_sub_type is '存对应监听模块(ala 视频异常:camera.kind_id, 应用异常:app_alarm.errType )'; + + +ALTER TABLE alarm_push_config ALTER COLUMN poms_project_id TYPE INTEGER [] + USING CASE + WHEN poms_project_id is NULL + then NULL + ELSE array [poms_project_id] + END ::INTEGER []; \ No newline at end of file From 341c8358f67bc725835b1e8f4333645ca1c50247 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 23 Nov 2022 10:06:29 +0800 Subject: [PATCH 08/51] =?UTF-8?q?EM=E6=8E=A8=E9=80=81=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/push/config.js | 60 +++++++++++++++---------- api/app/lib/models/alarm_push_config.js | 2 +- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/api/app/lib/controllers/push/config.js b/api/app/lib/controllers/push/config.js index 831be16..9fb0997 100644 --- a/api/app/lib/controllers/push/config.js +++ b/api/app/lib/controllers/push/config.js @@ -9,22 +9,22 @@ async function list (ctx) { const { utils: { anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs const { keyword, keywordTarget, alarmType, state, tactics, pomsProjectId } = ctx.query - let projectCorrelationWhere = { - del: false, - } - if (state == 'notYet') { - projectCorrelationWhere.pepProjectId = { $ne: null } - } + // let projectCorrelationWhere = { + // del: false, + // } + // if (state == 'notYet') { + // projectCorrelationWhere.pepProjectId = { $ne: null } + // } let findOption = { where: { del: false }, order: [['id', 'desc']], - include: [{ - model: models.ProjectCorrelation, - where: projectCorrelationWhere, - required: true - }] + // includes: [{ + // model: models.ProjectCorrelation, + // where: projectCorrelationWhere, + // required: true + // }] } let anxinStrucsRange = await anxinStrucIdRange({ @@ -48,7 +48,7 @@ async function list (ctx) { ctx, pepProjectId: pomsProjectId, keywordTarget, keyword }) let pomsProjectIds = pomsProjectRes.map(p => p.id) - findOption.where.pomsProjectId = { $in: pomsProjectIds } + findOption.where.pomsProjectId = { $overlap: pomsProjectIds } if (alarmType) { findOption.where.alarmType = { $contains: [alarmType] } @@ -65,6 +65,7 @@ async function list (ctx) { } const listRes = await models.AlarmPushConfig.findAll(findOption) + // const listRes = await models.AlarmPushConfig.findAll({}) let allStrucIds = new Set() let allConfigId = [] let allReceiverIds = new Set() @@ -104,17 +105,28 @@ async function list (ctx) { let returnD = [] for (let { dataValues: p } of listRes) { // 查对应的 poms 绑定的结构物绑定关系 - const corBind = pomsProjectRes.find(ppj => ppj.id == p.pomsProjectId) - if (corBind.pepProjectId) { - if (state == 'notYet') { - if (corBind.pepProject && p.timeType.some(pt => pt == corBind.pepProject.constructionStatusId)) { - continue - } - } else if (state == 'takeEffect') { - if (!corBind.pepProject || !p.timeType.some(pt => pt == corBind.pepProject.constructionStatusId)) { - continue + const corBinds = pomsProjectRes.filter(ppj => p.pomsProjectId.includes(ppj.id)) + + + let filterBinds = [] + for (let corBind of corBinds) { + if (corBind.pepProjectId) { + if (state == 'notYet') { + if (corBind.pepProject && p.timeType.some(pt => pt == corBind.pepProject.constructionStatusId)) { + continue + } + } else if (state == 'takeEffect') { + if (!corBind.pepProject || !p.timeType.some(pt => pt == corBind.pepProject.constructionStatusId)) { + continue + } } + } else if(state == 'notYet'){ + continue } + filterBinds.push(corBind) + } + if (!filterBinds.length) { + continue } // 结构物信息 @@ -129,7 +141,7 @@ async function list (ctx) { returnStruc.push({ id: sid, name: structure.name, - unbind: !anxinStrucSeen || !corBind.anxinProjectId.includes(anxinStrucSeen.projectId) + unbind: !anxinStrucSeen || corBinds.every(corBinds => !corBinds.anxinProjectId.includes(anxinStrucSeen.projectId)) }) } else { // 这个结构物已删 @@ -142,7 +154,7 @@ async function list (ctx) { const corReceiver = userRes.filter(u => p.receiverPepUserId.some(prId => u.id == prId)) returnD.push({ ...p, - pomsProject: corBind, + pomsProject: corBinds, structure: returnStruc, pushCount: corLogCount ? corLogCount.dataValues.count : 0, receiverPepUser: corReceiver @@ -169,7 +181,7 @@ async function edit (ctx) { let storageData = { name, pomsProjectId, alarmType, receiverPepUserId, timeType, disable, - strucId, tactics, tacticsParams,alarmSubType + 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 07606cf..24c9417 100644 --- a/api/app/lib/models/alarm_push_config.js +++ b/api/app/lib/models/alarm_push_config.js @@ -25,7 +25,7 @@ module.exports = dc => { autoIncrement: false }, pomsProjectId: { - type: DataTypes.INTEGER, + type: DataTypes.ARRAY(DataTypes.INTEGER), allowNull: false, defaultValue: null, comment: null, From 55fa5dd09bb9f1b1da2e8e8d75ba0f428aa228c8 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 23 Nov 2022 10:08:59 +0800 Subject: [PATCH 09/51] =?UTF-8?q?EM=E6=8E=A8=E9=80=81=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/push/config.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/api/app/lib/controllers/push/config.js b/api/app/lib/controllers/push/config.js index 9fb0997..9d11e33 100644 --- a/api/app/lib/controllers/push/config.js +++ b/api/app/lib/controllers/push/config.js @@ -8,23 +8,11 @@ async function list (ctx) { const { clickHouse } = ctx.app.fs const { utils: { anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs const { keyword, keywordTarget, alarmType, state, tactics, pomsProjectId } = ctx.query - - // let projectCorrelationWhere = { - // del: false, - // } - // if (state == 'notYet') { - // projectCorrelationWhere.pepProjectId = { $ne: null } - // } let findOption = { where: { del: false }, order: [['id', 'desc']], - // includes: [{ - // model: models.ProjectCorrelation, - // where: projectCorrelationWhere, - // required: true - // }] } let anxinStrucsRange = await anxinStrucIdRange({ @@ -120,7 +108,7 @@ async function list (ctx) { continue } } - } else if(state == 'notYet'){ + } else if (state == 'notYet') { continue } filterBinds.push(corBind) From 4dde555dc5625ba318deab013a0a1dfee3007d86 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 23 Nov 2022 10:38:27 +0800 Subject: [PATCH 10/51] =?UTF-8?q?=E9=9A=8F=E7=BB=93=E6=9E=84=E7=89=A9?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=9B=91=E6=B5=8B=E5=9B=A0=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/project/index.js | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/api/app/lib/controllers/project/index.js b/api/app/lib/controllers/project/index.js index c2807a3..3b47b76 100644 --- a/api/app/lib/controllers/project/index.js +++ b/api/app/lib/controllers/project/index.js @@ -231,7 +231,9 @@ async function strucWithPomsProject (ctx) { ` SELECT t_structure.id AS strucId, - t_structure.name AS strucName + t_structure.name AS strucName, + t_factor.id AS factorId, + t_factor.name AS factorName FROM t_project LEFT JOIN @@ -254,6 +256,10 @@ async function strucWithPomsProject (ctx) { ON t_structure.id = t_project_structure.structure OR t_structure.id = t_structuregroup_structure.structure OR t_structure.id = t_structure_site.structid + LEFT JOIN t_structure_factor + ON t_structure_factor.structure = t_structure.id + LEFT JOIN t_factor + ON t_structure_factor.factor = t_factor.id WHERE project_state != -1 AND @@ -263,11 +269,27 @@ async function strucWithPomsProject (ctx) { ).toPromise() : [] for (let s of undelStrucRes) { - if (!undelStruc.some(us => us.id == s.strucId)) { + let corStrut = undelStruc.find(us => us.id == s.strucId) + if (!corStrut) { + let nextFacor = [] + if (s.factorId) { + nextFacor.push({ + id: s.factorId, + name: s.factorName + }) + } undelStruc.push({ id: s.strucId, name: s.strucName, + factor: nextFacor }) + } else { + if (s.factorId) { + corStrut.factor.push({ + id: s.factorId, + name: s.factorName + }) + } } } } From 6473d6dbaf15050946f80a8c4447588afaae094a Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 23 Nov 2022 11:47:24 +0800 Subject: [PATCH 11/51] =?UTF-8?q?debug=20=E5=91=8A=E8=AD=A6=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=B1=95=E7=A4=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/problem/components/tableData.jsx | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/web/client/src/sections/problem/components/tableData.jsx b/web/client/src/sections/problem/components/tableData.jsx index 5eb1177..4393be6 100644 --- a/web/client/src/sections/problem/components/tableData.jsx +++ b/web/client/src/sections/problem/components/tableData.jsx @@ -379,12 +379,23 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition placeholder={SkeletonScreen()} > {(() => { - // console.log(tableData); + console.log(tableData); + console.log(route == 'useAbnormal' || route == 'videoAbnormal' ? + tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] + : tableData); return
暂无告警数据} + empty={ +
+ 暂无告警数据 +
+ } style={{}} pagination={false} onRow={(record, index) => { @@ -457,7 +468,6 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition pageSizeOpts={[10, 20, 30, 40]} onChange={(currentPage, pageSize) => { setQuery({ limit: pageSize, page: currentPage - 1 }); - }} /> : ""} @@ -472,7 +482,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition } -function mapStateToProps(state) { +function mapStateToProps (state) { const { auth, global, members } = state; // console.log(global); return { From 4fffb881b9575e94f64cc49005114438b8e9ac3c Mon Sep 17 00:00:00 2001 From: wenlele Date: Wed, 23 Nov 2022 13:56:22 +0800 Subject: [PATCH 12/51] =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/problem/components/tableData.jsx | 2 +- .../sections/service/components/pushModal.jsx | 4 +- .../sections/service/containers/emPush.jsx | 38 ++++++++++--------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/web/client/src/sections/problem/components/tableData.jsx b/web/client/src/sections/problem/components/tableData.jsx index 5eb1177..7993c9f 100644 --- a/web/client/src/sections/problem/components/tableData.jsx +++ b/web/client/src/sections/problem/components/tableData.jsx @@ -379,7 +379,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition placeholder={SkeletonScreen()} > {(() => { - // console.log(tableData); + // console.log(route); return
{ + dispatch(service.getProjectStructure({ pomsProjectId:value.join(',') })).then((res) => { if (res.success) { let mylist = [] for (let i = 0; i < res.payload?.data.length; i++) { @@ -188,6 +188,7 @@ function pushModal (props) { } } if (key == 'pomsProjectId') { + getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 for (let i = 0; i < projectPoms.length; i++) { if (values.pomsProjectId == projectPoms[i].id) { @@ -232,6 +233,7 @@ function pushModal (props) { style={{ width: 695 }} rules={[{ required: true, message: "请选择项目" }]} initValue={editObj?.pomsProjectId || ""} + multiple filter > { diff --git a/web/client/src/sections/service/containers/emPush.jsx b/web/client/src/sections/service/containers/emPush.jsx index ca73760..c0d9307 100644 --- a/web/client/src/sections/service/containers/emPush.jsx +++ b/web/client/src/sections/service/containers/emPush.jsx @@ -245,17 +245,27 @@ const EmPush = (props) => { dataIndex: "projectName", key: "projectName", render: (_, row) => { + let projectData = [] + row.pomsProject?.map(v => { + projectData.push({ + projectName: v.pepProject?.projectName, + name: v.name, + anxinerror: v.del, + constructionStatus: v.pepProject?.constructionStatus, + }) + }) let anxinerror = false let anxinerrorArr = '' if (row.pomsProject.del == true) { anxinerror = true anxinerrorArr = row.pomsProject.pepProject?.projectName || row.pomsProject.name } + return ( -
+ projectData.map((u, index) =>
{ - anxinerror ? ( - + u.anxinerror ? ( +
@@ -263,17 +273,17 @@ const EmPush = (props) => { } {
- -
7 || row.pomsProject?.name?.length > 7 ? '112px' : '', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', color: row.pomsProject.del ? '#F93920' : '' }}> - {row.pomsProject.pepProject?.projectName || row.pomsProject.name} + +
7 || u.name?.length > 7 ? '112px' : '', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', color: row.pomsProject.del ? '#F93920' : '' }}> + {u.projectName || u.name}
} { - row.pomsProject?.pepProject?.projectName ? ( + u.projectName ? (
@@ -281,15 +291,7 @@ const EmPush = (props) => {
- { - val.map((ite, idx) => { - return ( -
- {ite.id == row.pomsProject?.pepProject.constructionStatusId ? ite.construction_status : ''} -
- ) - }) - } + {u.constructionStatus}
) : ( @@ -307,7 +309,7 @@ const EmPush = (props) => {
) } -
+ ) ) } }, From 7051655098b45ad6af591b64b4315c13c28668cc Mon Sep 17 00:00:00 2001 From: wenlele Date: Wed, 23 Nov 2022 14:07:19 +0800 Subject: [PATCH 13/51] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/client/src/sections/problem/components/tableData.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/client/src/sections/problem/components/tableData.jsx b/web/client/src/sections/problem/components/tableData.jsx index 4393be6..f6f2fb8 100644 --- a/web/client/src/sections/problem/components/tableData.jsx +++ b/web/client/src/sections/problem/components/tableData.jsx @@ -380,14 +380,14 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition > {(() => { console.log(tableData); - console.log(route == 'useAbnormal' || route == 'videoAbnormal' ? - tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] + console.log((route == 'useAbnormal' || route == 'videoAbnormal') ? + (tableData?.slice(query.page * query.limit, (query.page + 1) * query.limit) || []) : tableData); return
Date: Wed, 23 Nov 2022 15:38:17 +0800 Subject: [PATCH 14/51] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 1076 ++++++++++++++------------- 1 file changed, 550 insertions(+), 526 deletions(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index c8bd06b..96205d2 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -19,19 +19,23 @@ module.exports = function (app, opts) { del: false, disable: false }, - order: ['id'], - include: [{ - model: models.ProjectCorrelation, - where: { - del: false, - }, - required: true - }], + order: ['id'], }) + let pomsProjectId = new Set() let pepProjectIds = new Set() for (let { dataValues: c } of configListRes) { - if (c.projectCorrelation.pepProjectId) { - pepProjectIds.add(c.projectCorrelation.pepProjectId) + if (c.pomsProjectId) { + c.pomsProjectId.forEach(pid => pomsProjectId.add(pid)) + } + } + const pomsProjectRes = pomsProjectId.size ? await models.ProjectCorrelation.findAll({ + where: { + id: { $in: [...pomsProjectId] } + } + }) : [] + for (let { dataValues: c } of pomsProjectRes) { + if (c.pepProjectId) { + pepProjectIds.add(c.pepProjectId) } } const pepProjectRes = pepProjectIds.size ? @@ -55,29 +59,44 @@ module.exports = function (app, opts) { for (let { dataValues: c } of configListRes) { if (c.tacticsParams && c.tactics) { + // pomsProjectId 是个数组 [] const { projectCorrelation, strucId, pomsProjectId, } = c const { interval, deviceProportion } = c.tacticsParams if ( curMinOfYear % parseInt(interval) == 0 ) { - const corPepProject = projectCorrelation.pepProjectId ? - pepProjectRes.find(p => p.id == projectCorrelation.pepProjectId) - : null - if ( - !projectCorrelation.pepProjectId - || ( - corPepProject - && c.timeType.some(ct => ct == corPepProject.construction_status_id) - ) - ) { - const { anxinProjectId, pepProjectId } = projectCorrelation - // 查当前 poms 下的结构物 并把不包含的去掉 - // 可能有结构物已解绑 - const strucListRes = strucId.length && anxinProjectId.length ? - await clickHouse.anxinyun.query( - ` + const corPomsProject = pomsProjectRes.filter(poms => pomsProjectId.includes(poms.id)) + let curAnxinProjectId = new Set() + let pepProjectName_ = [] + for (let { dataValues: poms } of corPomsProject) { + if (poms.pepProjectId) { + // 找对应的项企项目 + const corPepProject = + pepProjectRes.find(p => p.id == poms.pepProjectId) + if (corPepProject && c.timeType.some(ct => ct == corPepProject.construction_status_id)) { + pepProjectName_.push(corPepProject.project_name) + } else { + // 不符合当前项目的时间节点 + continue + } + } else { + // 是自定义项目 + poms.name ? pepProjectName_.push(poms.name) : null + } + // 筛选全部的 anxinProjectId pepProjectId + for (let axId of poms.anxinProjectId) { + curAnxinProjectId.add(axId) + } + } + + const anxinProjectId = [...curAnxinProjectId] + // 查当前 poms 下的结构物 并把不包含的去掉 + // 可能有结构物已解绑 + const strucListRes = strucId.length && anxinProjectId.length ? + await clickHouse.anxinyun.query( + ` SELECT DISTINCT id, t_structure.id AS id, @@ -109,125 +128,130 @@ module.exports = function (app, opts) { project_state != -1 AND t_project.id IN (${anxinProjectId.join(',')}) AND t_structure.id IN (${strucId.join(',')}) - ` - ).toPromise() : - [] - let strucThingId = [] - let searchStrucIds = strucListRes.map(s => { - if (s.iotaThingId) { - strucThingId.push(s.iotaThingId) - } - return s.id - }) + ).toPromise() : + [] + let strucThingId = [] + let searchStrucIds = strucListRes.map(s => { + if (s.iotaThingId) { + strucThingId.push(s.iotaThingId) + } + return s.id + }) - // 开发测试用的数据 - // searchStrucIds = searchStrucIds.concat([991, 1052, 700]) + // !开发测试用的数据 + // searchStrucIds = searchStrucIds.concat([991, 1052, 700]) - if (searchStrucIds.length) { - searchStrucIds.unshift(-1) - } - let pepProjectName = pepProjectId ? - pepProjectRes.find(p => p.id == pepProjectId).project_name - : projectCorrelation.name - let emailTitle = `${pepProjectName}-${c.name}-` - let emailSubTitle = '' - - let dataAlarmOption = [] - let dataAlarmGroupOption = [] - let dataAlarmSubType = [] - let dataAlarms = [] - - let videoAlarmWhereOption = [] - let videoAlarms = [] - - let appAlarmWhereOption = { - confirmTime: null, - } - let appAlarms = [] - - let deviceCount = 0 - let alarmDeviceCount = 0 - let cameraCount = 0 - let alarmCameraCount = 0 - // 判断推送策略 - let nowTime = moment().startOf('minute') - let pointTime = - moment() - .subtract( - parseInt(interval), - // + 1440 * 365, - 'minute' - ) - .startOf('minute') - .format('YYYY-MM-DD HH:mm:ss') - - let newAddStartTime = pointTime - let newAddEndTime = nowTime.clone() - if (c.tactics == 'immediately') { - // !查所有未解决告警 所以时间范围大可不必 - // dataAlarmOption.push(`StartTime >= '${pointTime}'`); - // appAlarmWhereOption.createTime = { $gte: pointTime } - // videoAlarmWhereOption.push(`camera_status_alarm.create_time >= '${pointTime}'`) - emailTitle += `即时推送服务` - emailSubTitle += `截止${moment(pointTime).format('YYYY年MM月DD日 HH时mm分')}-${moment(nowTime).format('HH时mm分')}:` - } else if (c.tactics == 'continue' || c.tactics == 'abnormal_rate') { - // 新增的应该是上一个时间节点到上上个节点之间 - dataAlarmOption.push(`StartTime <= '${pointTime}'`); - appAlarmWhereOption.createTime = { $lte: pointTime } - videoAlarmWhereOption.push(`camera_status_alarm.create_time <= '${pointTime}'`) - // 新增的应该是上一个时间节点到上上个节点之间 - newAddStartTime = moment(pointTime).subtract(parseInt(interval)).format('YYYY-MM-DD HH:mm:ss') - newAddEndTime = pointTime - - if (c.tactics == 'continue') { - emailTitle += `持续时长推送服务` - emailSubTitle += `告警持续时长超${interval}分钟的告警源,详情如下:` - } else { - if (c.alarmType.includes('data_outages') || c.alarmType.includes('data_exception')) { - // 查了设备异常率 去安心云查当前项目下的设备数量 - let deviceCountRes = - strucThingId.length ? - await clickHouse.iot.query(` + if (searchStrucIds.length) { + searchStrucIds.unshift(-1) + } else { + // 没有结构物可查 + continue + } + let pepProjectName = + pepProjectName_.length ? + pepProjectName_.join('
') + : '' + + let emailTitle = `${pepProjectName_.length ? + pepProjectName_.join('、') + : ''}-${c.name}-` + let emailSubTitle = '' + + let dataAlarmOption = [] + let dataAlarmGroupOption = [] + let dataAlarmSubType = [] + let dataAlarms = [] + + let videoAlarmWhereOption = [] + let videoAlarms = [] + + let appAlarmWhereOption = { + confirmTime: null, + } + let appAlarms = [] + + let deviceCount = 0 + let alarmDeviceCount = 0 + let cameraCount = 0 + let alarmCameraCount = 0 + // 判断推送策略 + let nowTime = moment().startOf('minute') + let pointTime = + moment() + .subtract( + parseInt(interval), + // + 1440 * 365, + 'minute' + ) + .startOf('minute') + .format('YYYY-MM-DD HH:mm:ss') + + let newAddStartTime = pointTime + let newAddEndTime = nowTime.clone() + if (c.tactics == 'immediately') { + // !查所有未解决告警 所以时间范围大可不必 + // dataAlarmOption.push(`StartTime >= '${pointTime}'`); + // appAlarmWhereOption.createTime = { $gte: pointTime } + // videoAlarmWhereOption.push(`camera_status_alarm.create_time >= '${pointTime}'`) + emailTitle += `即时推送服务` + emailSubTitle += `截止${moment(pointTime).format('YYYY年MM月DD日 HH时mm分')}-${moment(nowTime).format('HH时mm分')}:` + } else if (c.tactics == 'continue' || c.tactics == 'abnormal_rate') { + // 新增的应该是上一个时间节点到上上个节点之间 + dataAlarmOption.push(`StartTime <= '${pointTime}'`); + appAlarmWhereOption.createTime = { $lte: pointTime } + videoAlarmWhereOption.push(`camera_status_alarm.create_time <= '${pointTime}'`) + // 新增的应该是上一个时间节点到上上个节点之间 + newAddStartTime = moment(pointTime).subtract(parseInt(interval)).format('YYYY-MM-DD HH:mm:ss') + newAddEndTime = pointTime + + if (c.tactics == 'continue') { + emailTitle += `持续时长推送服务` + emailSubTitle += `告警持续时长超${interval}分钟的告警源,详情如下:` + } else { + if (c.alarmType.includes('data_outages') || c.alarmType.includes('data_exception')) { + // 查了设备异常率 去安心云查当前项目下的设备数量 + let deviceCountRes = + strucThingId.length ? + await clickHouse.iot.query(` SELECT count(DeviceId) AS count FROM device WHERE ThingId IN (${strucThingId.map(t => `'${t}'`).join(',')}, '-1') `).toPromise() - : [] - deviceCount = deviceCountRes.length ? deviceCountRes[0].count : 0 - } - if (c.alarmType.includes('video_exception')) { - // 查了视频异常 去安心云查 接入的 萤石 设备数量 - cameraCount = searchStrucIds.length ? - (await clickHouse.anxinyun.query(` + : [] + deviceCount = deviceCountRes.length ? deviceCountRes[0].count : 0 + } + if (c.alarmType.includes('video_exception')) { + // 查了视频异常 去安心云查 接入的 萤石 设备数量 + cameraCount = searchStrucIds.length ? + (await clickHouse.anxinyun.query(` SELECT count(*) AS count FROM t_video_ipc WHERE structure IN (${searchStrucIds.join(',')}) `).toPromise())[0].count - : 0 - } - emailTitle += `异常率推送服务` - emailSubTitle += `持续产生时间超过${interval}分钟的异常设备数量${interval}个,异常率达到项目或结构物内设备总数量${parseInt(deviceCount) + parseInt(cameraCount)}个的 --%,详情如下` + : 0 } + emailTitle += `异常率推送服务` + emailSubTitle += `持续产生时间超过${interval}分钟的异常设备数量${interval}个,异常率达到项目或结构物内设备总数量${parseInt(deviceCount) + parseInt(cameraCount)}个的 --%,详情如下` } - emailTitle += '——POMS飞尚运维中台' - - // 判断告警数据范围 - 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']) + } + emailTitle += '——POMS飞尚运维中台' - } - 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')) { - let videoAlarmSubType = c.alarmSubType ? c.alarmSubType['data_exception'] : [] - if (videoAlarmSubType.length == 1) videoAlarmSubType.push(-1) - videoAlarms = searchStrucIds.length && videoAlarmSubType.length ? await clickHouse.vcmp.query( - ` + // 判断告警数据范围 + 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')) { + 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, cameraAlarm.cameraName AS cameraName, @@ -294,107 +318,107 @@ module.exports = function (app, opts) { ON anxinStation.id = anxinIpcStation.station ORDER BY cameraAlarm.createTime DESC ` - ).toPromise() : [] - - let returnD = [] - let positionD = {} - // 每个设备一个告警 - for (let a of videoAlarms) { - if (positionD[a.cameraId]) { - let curD = returnD[positionD[a.cameraId].positionReturnD] - - 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, - cameraKind: a.cameraKind, - struc: [], - station: [] - } - - 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 - } + ).toPromise() : [] + + let returnD = [] + let positionD = {} + // 每个设备一个告警 + for (let a of videoAlarms) { + if (positionD[a.cameraId]) { + let curD = returnD[positionD[a.cameraId].positionReturnD] + + 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, + cameraKind: a.cameraKind, + struc: [], + station: [] + } + + 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 } } - let p = 1 - videoAlarms = returnD } - if (c.alarmType.includes('app_exception')) { - 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']], + let p = 1 + videoAlarms = returnD + } + if (c.alarmType.includes('app_exception')) { + 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: [{ + model: models.App, + required: true, include: [{ - model: models.App, + model: models.ProjectApp, + where: { + projectId: { $in: pomsProjectId } + }, required: true, - include: [{ - model: models.ProjectApp, - where: { - projectId: pomsProjectId - }, - 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 (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(',')})`) - if (c.alarmSubType && dataAlarmSubType.length) { - dataAlarmSubType.push(-1) - dataAlarmOption.push(`AlarmGroupUnit IN (${dataAlarmSubType.join(',')})`) - } - dataAlarms = (!c.alarmSubType || dataAlarmSubType.length) ? await clickHouse.dataAlarm.query(` + // 查数据告警 三警合一 + if (dataAlarmGroupOption.length && searchStrucIds.length) { + dataAlarmGroupOption.push(-1) + dataAlarmOption.push(`AlarmGroup IN (${dataAlarmGroupOption.join(',')})`) + 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 `} @@ -402,235 +426,235 @@ module.exports = function (app, opts) { ${dataAlarmOption.length ? ' AND ' + dataAlarmOption.join(' AND ') : ''} ORDER BY StartTime DESC `).toPromise() : [] - console.log(dataAlarms); - } + console.log(dataAlarms); + } - let dataAlarmTitle = [{ - n: '项目', - k: '', - v: pepProjectName - }, { - n: '结构物', - k: '', - f: (d) => { - return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name - } - }, { - n: '告警源名称', - k: 'SourceName' - }, { - n: '告警源类型', - k: '', - f: (d) => { - switch (d.SourceTypeId) { - case 0: - return 'DTU' - case 1: - return '传感器' - case 2: - return '测点' - default: - return '' - } - } - }, { - n: '告警信息', - k: 'AlarmContent' - }, { - n: '告警等级(当前)', - k: '', - f: (d) => { - switch (d.CurrentLevel) { - case 1: - return '一级' - case 2: - return '二级' - case 3: - return '三级' - default: - return '' - } - } - }, { - n: '持续时间', - k: '', - f: (d) => { - return d.StartTime ? - '超过' + moment().diff(moment(d.StartTime), 'minutes') + '分钟' : '' - } - },] - - let videoAlarmTitle = [{ - n: '项目', - k: '', - v: pepProjectName - }, { - n: '结构物', - k: '', - f: (d) => { - return d.struc.map(ds => ds.name).join('、') - } - }, { - n: '告警源名称', - k: 'cameraName' - }, { - n: '告警源类型', - k: 'cameraKind' - }, { - n: '序列号', - k: 'cameraSerialNo' - }, { - n: '通道号', - k: 'cameraChannelNo' - }, { - n: '测点', - k: '', - f: (d) => { - return d.station.map(ds => ds.name).join('、') - } - }, { - n: '位置', - k: '', - f: (d) => { - return d.station.map(ds => ds.position).join('、') - } - }, { - n: '告警信息', - k: 'statusDescribe' - }, { - n: '持续时间', - k: '', - f: (d) => { - return d.createTime ? - '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' - } - },] - - let appAlarmTitle = [{ - n: '项目', - k: '', - v: pepProjectName - }, { - n: '应用名称', - k: '', - f: (d) => { - return d.app ? d.app.name : '' - } - }, { - n: '异常类型', - k: '', - f: (d) => { - if (d.type == 'element') { - return '元素异常' - } else if (d.type == 'apiError') { - return '接口报错' - } else { + let dataAlarmTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '结构物', + k: '', + f: (d) => { + return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name + } + }, { + n: '告警源名称', + k: 'SourceName' + }, { + n: '告警源类型', + k: '', + f: (d) => { + switch (d.SourceTypeId) { + case 0: + return 'DTU' + case 1: + return '传感器' + case 2: + return '测点' + default: return '' - } } - }, { - n: '异常信息', - k: 'alarmContent' - }, { - n: 'URL地址', - k: 'cameraName', - f: (d) => { - return d.app && d.app.url ? `${d.app.url}` : '' + } + }, { + n: '告警信息', + k: 'AlarmContent' + }, { + n: '告警等级(当前)', + k: '', + f: (d) => { + switch (d.CurrentLevel) { + case 1: + return '一级' + case 2: + return '二级' + case 3: + return '三级' + default: + return '' } - }, { - n: '持续时间', - k: '', - f: (d) => { - return d.createTime ? - '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' + } + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.StartTime ? + '超过' + moment().diff(moment(d.StartTime), 'minutes') + '分钟' : '' + } + },] + + let videoAlarmTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '结构物', + k: '', + f: (d) => { + return d.struc.map(ds => ds.name).join('、') + } + }, { + n: '告警源名称', + k: 'cameraName' + }, { + n: '告警源类型', + k: 'cameraKind' + }, { + n: '序列号', + k: 'cameraSerialNo' + }, { + n: '通道号', + k: 'cameraChannelNo' + }, { + n: '测点', + k: '', + f: (d) => { + return d.station.map(ds => ds.name).join('、') + } + }, { + n: '位置', + k: '', + f: (d) => { + return d.station.map(ds => ds.position).join('、') + } + }, { + n: '告警信息', + k: 'statusDescribe' + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.createTime ? + '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' + } + },] + + let appAlarmTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '应用名称', + k: '', + f: (d) => { + return d.app ? d.app.name : '' + } + }, { + n: '异常类型', + k: '', + f: (d) => { + if (d.type == 'element') { + return '元素异常' + } else if (d.type == 'apiError') { + return '接口报错' + } else { + return '' } - },] + } + }, { + n: '异常信息', + k: 'alarmContent' + }, { + n: 'URL地址', + k: 'cameraName', + f: (d) => { + return d.app && d.app.url ? `${d.app.url}` : '' + } + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.createTime ? + '超过' + moment().diff(moment(d.createTime), 'minutes') + '分钟' : '' + } + },] - let ifEmailSend = false - let tableTitlePostfix = ',详情如下:' + let ifEmailSend = false + let tableTitlePostfix = ',详情如下:' - function packageTableTitle (titleArr) { - let tableTitle = '' - for (let t of titleArr) { - tableTitle += `` - } - tableTitle += '' - return tableTitle + function packageTableTitle (titleArr) { + let tableTitle = '' + for (let t of titleArr) { + tableTitle += `` } - function packageTableData (data, titleArr) { - let tableData = '' - for (let t of titleArr) { - if (t.v) { - tableData += `` - } else if (t.f) { - tableData += `` - } else if (t.k) { - tableData += `` - } else { - tableData += `` - } + tableTitle += '' + return tableTitle + } + function packageTableData (data, titleArr) { + let tableData = '' + for (let t of titleArr) { + if (t.v) { + tableData += `` + } else if (t.f) { + tableData += `` + } else if (t.k) { + tableData += `` + } else { + tableData += `` } - tableData += '' - return tableData } + tableData += '' + return tableData + } - function packageAlarmData2Table (titlePrefix, alarmData, alarmTitleArr, keyOfStartTime = 'StartTime') { - if (!alarmData.length) { - return '' - } - ifEmailSend = true - let tableTitlePrefix = titlePrefix + '告警源' - let newAddCount = 0 - let alarmHtml = '
${t.n}
${t.n}
${t.v}${t.f(data)}${data[t.k]}
${t.v}${t.f(data)}${data[t.k]}
' - let alarmContent = '' - let alarmHtmlTitle = packageTableTitle(alarmTitleArr) - - for (let a of alarmData) { - alarmContent += packageTableData(a, alarmTitleArr) - if (a[keyOfStartTime] && moment(a[keyOfStartTime]).isBetween(newAddStartTime, newAddEndTime)) { - newAddCount++ - } - } - tableTitlePrefix += - c.tactics == 'abnormal_rate' ? - `${alarmData.length}个` : - `新增${newAddCount}个,未解决累计${alarmData.length}个` + tableTitlePostfix - alarmHtml += `' - alarmHtml += alarmHtmlTitle - alarmHtml += alarmContent - alarmHtml += '
` + tableTitlePrefix + '

' - - return alarmHtml + function packageAlarmData2Table (titlePrefix, alarmData, alarmTitleArr, keyOfStartTime = 'StartTime') { + if (!alarmData.length) { + return '' } - - let dataAlarmG1 = []; - let dataAlarmG2 = []; - let dataAlarmG3 = []; - let dataAlarmG45 = []; - let deviceStatistic = new Set() - for (let d of dataAlarms) { - if (d.AlarmGroup == 1) { - dataAlarmG1.push(d) - } else if (d.AlarmGroup == 2) { - dataAlarmG2.push(d) - } else if (d.AlarmGroup == 3) { - dataAlarmG3.push(d) - } else if (d.AlarmGroup == 4 || d.AlarmGroup == 5) { - dataAlarmG45.push(d) + ifEmailSend = true + let tableTitlePrefix = titlePrefix + '告警源' + let newAddCount = 0 + let alarmHtml = '' + let alarmContent = '' + let alarmHtmlTitle = packageTableTitle(alarmTitleArr) + + for (let a of alarmData) { + alarmContent += packageTableData(a, alarmTitleArr) + if (a[keyOfStartTime] && moment(a[keyOfStartTime]).isBetween(newAddStartTime, newAddEndTime)) { + newAddCount++ } - deviceStatistic.add(d.SourceId) } - if (c.tactics == 'abnormal_rate') { - let rate = ((deviceStatistic.size + videoAlarms.length) / (parseInt(deviceCount) + parseInt(cameraCount))); + tableTitlePrefix += + c.tactics == 'abnormal_rate' ? + `${alarmData.length}个` : + `新增${newAddCount}个,未解决累计${alarmData.length}个` + tableTitlePostfix + alarmHtml += `' + alarmHtml += alarmHtmlTitle + alarmHtml += alarmContent + alarmHtml += '
` + tableTitlePrefix + '

' + + return alarmHtml + } - if (rate < parseFloat(deviceProportion)) { - continue - } + let dataAlarmG1 = []; + let dataAlarmG2 = []; + let dataAlarmG3 = []; + let dataAlarmG45 = []; + let deviceStatistic = new Set() + for (let d of dataAlarms) { + if (d.AlarmGroup == 1) { + dataAlarmG1.push(d) + } else if (d.AlarmGroup == 2) { + dataAlarmG2.push(d) + } else if (d.AlarmGroup == 3) { + dataAlarmG3.push(d) + } else if (d.AlarmGroup == 4 || d.AlarmGroup == 5) { + dataAlarmG45.push(d) + } + deviceStatistic.add(d.SourceId) + } + if (c.tactics == 'abnormal_rate') { + let rate = ((deviceStatistic.size + videoAlarms.length) / (parseInt(deviceCount) + parseInt(cameraCount))); - emailSubTitle = emailSubTitle.replace('--%', rate.toFixed(1) + '%') + if (rate < parseFloat(deviceProportion)) { + continue } - let html = ` + + emailSubTitle = emailSubTitle.replace('--%', rate.toFixed(1) + '%') + } + let html = ` @@ -649,99 +673,99 @@ module.exports = function (app, opts) {
${emailSubTitle}
` - if (c.alarmType.includes('data_outages')) { - html += packageAlarmData2Table( - '数据中断', - dataAlarmG1, - dataAlarmTitle, - ) - } - if (c.alarmType.includes('data_exception')) { - html += packageAlarmData2Table( - '数据异常', - dataAlarmG2, - dataAlarmTitle, - ) - } - if (c.alarmType.includes('strategy_hit')) { - html += packageAlarmData2Table( - '策略命中', - dataAlarmG3, - dataAlarmTitle, - ) - } - if (c.alarmType.includes('video_exception')) { - html += packageAlarmData2Table( - '视频异常', - videoAlarms, - videoAlarmTitle, - 'createTime', - ) - } - if (c.alarmType.includes('app_exception')) { - html += packageAlarmData2Table( - '应用异常', - appAlarms, - appAlarmTitle, - 'createTime', - ) - } - if (c.alarmType.includes('device_exception')) { - html += packageAlarmData2Table( - '设备异常', - dataAlarmG45, - dataAlarmTitle, - ) - } + if (c.alarmType.includes('data_outages')) { + html += packageAlarmData2Table( + '数据中断', + dataAlarmG1, + dataAlarmTitle, + ) + } + if (c.alarmType.includes('data_exception')) { + html += packageAlarmData2Table( + '数据异常', + dataAlarmG2, + dataAlarmTitle, + ) + } + if (c.alarmType.includes('strategy_hit')) { + html += packageAlarmData2Table( + '策略命中', + dataAlarmG3, + dataAlarmTitle, + ) + } + if (c.alarmType.includes('video_exception')) { + html += packageAlarmData2Table( + '视频异常', + videoAlarms, + videoAlarmTitle, + 'createTime', + ) + } + if (c.alarmType.includes('app_exception')) { + html += packageAlarmData2Table( + '应用异常', + appAlarms, + appAlarmTitle, + 'createTime', + ) + } + if (c.alarmType.includes('device_exception')) { + html += packageAlarmData2Table( + '设备异常', + dataAlarmG45, + dataAlarmTitle, + ) + } - if (ifEmailSend) { - // 查接收人的信息 - const receiverRes = - c.receiverPepUserId.length ? - await clickHouse.pepEmis.query(` + if (ifEmailSend) { + // 查接收人的信息 + const receiverRes = + c.receiverPepUserId.length ? + await clickHouse.pepEmis.query(` SELECT id, name, email FROM user WHERE id IN (${c.receiverPepUserId.join(',')},-1) `).toPromise() - : [] - let receiverId = [] - const emails = receiverRes.reduce((arr, r) => { - if (r.email) { - arr.push(r.email) - receiverId.push({ id: r.id, name: r.name }) - } - return arr - }, []) - if (emails.length) { - await pushByEmail({ - email: emails, - title: emailTitle, - text: '', - html: html - }) - - //存日志 存动态 socket到前端 - let dataToSave = { - time: moment().format(), - pushConfigId: c.id, - cfgName: c.name,//策略名称 - tactics: c.tactics, - tacticsParams: c.tacticsParams, - projectCorrelationId: pomsProjectId, - toPepUserIds: receiverId.map(r => r.id) - } - let r = await models.EmailSendLog.create(dataToSave, { returning: true }) + : [] + let receiverId = [] + let emails = receiverRes.reduce((arr, r) => { + if (r.email) { + arr.push(r.email) + receiverId.push({ id: r.id, name: r.name }) + } + return arr + }, []) + // emails = ['1650192445@qq.com'] + if (emails.length) { + await pushByEmail({ + email: emails, + title: emailTitle, + text: '', + html: html + }) + + //存日志 存动态 socket到前端 + let dataToSave = { + time: moment().format(), + pushConfigId: c.id, + cfgName: c.name,//策略名称 + tactics: c.tactics, + tacticsParams: c.tacticsParams, + projectCorrelationId: pomsProjectId, + toPepUserIds: receiverId.map(r => r.id) + } + let r = await models.EmailSendLog.create(dataToSave, { returning: true }) - let dynamic = { - time: r.dataValues.time, - emailSendId: r.dataValues.id, - projectCorrelationId: r.dataValues.projectCorrelationId, - type: 2//通知 - } - await models.LatestDynamicList.create(dynamic); + let dynamic = { + time: r.dataValues.time, + emailSendId: r.dataValues.id, + projectCorrelationId: r.dataValues.projectCorrelationId, + type: 2//通知 + } + await models.LatestDynamicList.create(dynamic); - //消息推送到前端 - await sendNoticeToWeb(receiverId, dataToSave); - } + //消息推送到前端 + await sendNoticeToWeb(receiverId, dataToSave); } } } From f5ba9687f77bb354d93296c04566a4da64c683d9 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Thu, 24 Nov 2022 09:13:54 +0800 Subject: [PATCH 15/51] =?UTF-8?q?EM=E6=8E=A8=E9=80=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=A4=9A=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/control/data.js | 45 +++++++++---- api/app/lib/index.js | 4 +- api/app/lib/models/email_send_log.js | 2 +- api/app/lib/models/latest_dynamic_list.js | 2 +- api/app/lib/schedule/alarms_push.js | 8 +-- script/0.11/schema/1.alter_email_send_log.sql | 6 ++ web/client/index.html | 34 +++++----- .../sections/control/containers/control.jsx | 66 ++++++++----------- 8 files changed, 91 insertions(+), 76 deletions(-) create mode 100644 script/0.11/schema/1.alter_email_send_log.sql diff --git a/api/app/lib/controllers/control/data.js b/api/app/lib/controllers/control/data.js index 4b09bcd..5cdd5ad 100644 --- a/api/app/lib/controllers/control/data.js +++ b/api/app/lib/controllers/control/data.js @@ -2,7 +2,7 @@ const moment = require('moment'); //BI分析-数据 -async function getDataAlarmsAggDay(ctx) { +async function getDataAlarmsAggDay (ctx) { try { const { utils: { anxinStrucIdRange } } = ctx.app.fs const { pepProjectId } = ctx.query @@ -12,10 +12,8 @@ async function getDataAlarmsAggDay(ctx) { ctx, pepProjectId }) let whereOption = [] - // ! 1 开发临时增加 if (anxinStruc.length) { const anxinStrucIds = anxinStruc.map(a => a.strucId) - // ! 开发临时注释 whereOption.push(`alarms.StructureId IN (${anxinStrucIds.join(",")})`) let start = moment().add(-1, 'year').format('YYYY-MM-DD HH:mm:ss');//最近一年 @@ -41,7 +39,7 @@ async function getDataAlarmsAggDay(ctx) { } } -async function queryAlarm(ctx, alarmQueryOptionStr, type) { +async function queryAlarm (ctx, alarmQueryOptionStr, type) { const { clickHouse } = ctx.app.fs try { const alarmRes = await clickHouse.dataAlarm.query(` @@ -76,7 +74,7 @@ async function queryAlarm(ctx, alarmQueryOptionStr, type) { } //BI分析-应用异常 -async function getAppAlarmsAggDay(ctx) { +async function getAppAlarmsAggDay (ctx) { try { const models = ctx.fs.dc.models; const { utils: { pomsProjectRange } } = ctx.app.fs @@ -129,7 +127,7 @@ async function getAppAlarmsAggDay(ctx) { } //BI分析-视频异常 -async function getVideoAlarmsAggDay(ctx) { +async function getVideoAlarmsAggDay (ctx) { try { const { clickHouse, utils: { anxinStrucIdRange } } = ctx.app.fs const { database: anxinyun } = clickHouse.anxinyun.opts.config @@ -246,7 +244,7 @@ async function getVideoAlarmsAggDay(ctx) { } //BI分析-问题处置效率分析 -async function getAlarmsHandleStatistics(ctx) { +async function getAlarmsHandleStatistics (ctx) { try { const { projectCorrelationId } = ctx.query const models = ctx.fs.dc.models; @@ -266,7 +264,7 @@ async function getAlarmsHandleStatistics(ctx) { } } //最新动态 -async function getLatestDynamic(ctx) { +async function getLatestDynamic (ctx) { try { const { models } = ctx.fs.dc; const { limit, page, projectCorrelationId, types } = ctx.query; @@ -303,9 +301,9 @@ async function getLatestDynamic(ctx) { }); //查项目名称 查用户名 - let pepPojectIds = new Set(), notedUserIds = new Set(); + let pepPojectIds = new Set(), notedUserIds = new Set(), emailSendPomsProjectIds = new Set(); for (let p of news) { - if(p.projectCorrelation && p.projectCorrelation.pepProjectId){ + if (p.projectCorrelation && p.projectCorrelation.pepProjectId) { pepPojectIds.add(p.projectCorrelation.pepProjectId); } @@ -313,11 +311,28 @@ async function getLatestDynamic(ctx) { p.emailSendLog.toPepUserIds.map(u => { notedUserIds.add(u);//通知 接收人 }) + p.emailSendLog.projectCorrelationId.forEach(pid => emailSendPomsProjectIds.add(pid)) } if (p.alarmConfirmLog && p.alarmConfirmLog.pepUserId) { notedUserIds.add(p.alarmConfirmLog.pepUserId);//确认 操作者 } } + + // EM 推送的特殊处理 + // 查找对应的 projectCorrelation + const emailLogProjectCorrelationRes = + emailSendPomsProjectIds.size ? + await models.ProjectCorrelation.findAll({ + where: { + id: { $in: [...emailSendPomsProjectIds] } + } + }) : [] + + for (let { dataValues: p } of emailLogProjectCorrelationRes) { + if (p.pepProjectId) { + pepPojectIds.add(p.pepProjectId) + } + } let pepProjects = pepPojectIds.size ? await clickHouse.projectManage.query(` SELECT id, project_name FROM t_pim_project WHERE id IN (${[...pepPojectIds].join(',')},-1) `).toPromise() : []; @@ -339,7 +354,15 @@ async function getLatestDynamic(ctx) { if (d.emailSendId) { notice.push({ userName: userPepRes.filter(u => d.emailSendLog.toPepUserIds.indexOf(u.id) != -1), - projectName, + projectName: d.emailSendLog.projectCorrelationId.map(p => { + let projectName = '' + if (p.pepProjectId) { + projectName = pepProjects.find(pp => pp.id == p.pepProjectId).project_name + } else { + projectName = p.name + } + return projectName + }).join('、'), ...d.emailSendLog.dataValues }); } diff --git a/api/app/lib/index.js b/api/app/lib/index.js index dcc655c..84559e9 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -77,8 +77,8 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq AppAlarm.belongsTo(App, { foreignKey: 'projectAppId', targetKey: 'id' }); App.hasMany(AppAlarm, { foreignKey: 'projectAppId', sourceKey: 'id' }); - AlarmPushConfig.belongsTo(ProjectCorrelation, { foreignKey: 'pomsProjectId', targetKey: 'id' }); - ProjectCorrelation.hasMany(AlarmPushConfig, { foreignKey: 'pomsProjectId', sourceKey: 'id' }); + // AlarmPushConfig.belongsTo(ProjectCorrelation, { foreignKey: 'pomsProjectId', targetKey: 'id' }); + // ProjectCorrelation.hasMany(AlarmPushConfig, { foreignKey: 'pomsProjectId', sourceKey: 'id' }); AlarmAppearRecord.belongsTo(ProjectCorrelation, { foreignKey: 'projectCorrelationId', targetKey: 'id' }); ProjectCorrelation.hasMany(AlarmAppearRecord, { foreignKey: 'projectCorrelationId', sourceKey: 'id' }); diff --git a/api/app/lib/models/email_send_log.js b/api/app/lib/models/email_send_log.js index e1d95b6..da0a97f 100644 --- a/api/app/lib/models/email_send_log.js +++ b/api/app/lib/models/email_send_log.js @@ -53,7 +53,7 @@ module.exports = dc => { autoIncrement: false }, projectCorrelationId: { - type: DataTypes.INTEGER, + type: DataTypes.ARRAY(DataTypes.INTEGER), allowNull: false, defaultValue: null, comment: null, diff --git a/api/app/lib/models/latest_dynamic_list.js b/api/app/lib/models/latest_dynamic_list.js index 5b53051..320191a 100644 --- a/api/app/lib/models/latest_dynamic_list.js +++ b/api/app/lib/models/latest_dynamic_list.js @@ -54,7 +54,7 @@ module.exports = dc => { }, projectCorrelationId: { type: DataTypes.INTEGER, - allowNull: false, + allowNull: true, defaultValue: null, comment: null, primaryKey: false, diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 96205d2..9c3460e 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -60,7 +60,7 @@ module.exports = function (app, opts) { for (let { dataValues: c } of configListRes) { if (c.tacticsParams && c.tactics) { // pomsProjectId 是个数组 [] - const { projectCorrelation, strucId, pomsProjectId, } = c + const { strucId, pomsProjectId, } = c const { interval, deviceProportion } = c.tacticsParams if ( @@ -248,7 +248,7 @@ module.exports = function (app, opts) { if (c.alarmSubType) dataAlarmSubType = dataAlarmSubType.concat(c.alarmSubType['strategy_hit']) } if (c.alarmType.includes('video_exception')) { - let videoAlarmSubType = c.alarmSubType ? c.alarmSubType['data_exception'] : [] + let videoAlarmSubType = c.alarmSubType ? c.alarmSubType['video_exception'] : [] if (videoAlarmSubType.length == 1) videoAlarmSubType.push(-1) videoAlarms = searchStrucIds.length && videoAlarmSubType.length ? await clickHouse.vcmp.query( ` @@ -734,6 +734,7 @@ module.exports = function (app, opts) { } return arr }, []) + // !开发测试用的数据 // emails = ['1650192445@qq.com'] if (emails.length) { await pushByEmail({ @@ -758,12 +759,11 @@ module.exports = function (app, opts) { let dynamic = { time: r.dataValues.time, emailSendId: r.dataValues.id, - projectCorrelationId: r.dataValues.projectCorrelationId, + // projectCorrelationId: r.dataValues.projectCorrelationId, type: 2//通知 } await models.LatestDynamicList.create(dynamic); - //消息推送到前端 await sendNoticeToWeb(receiverId, dataToSave); } diff --git a/script/0.11/schema/1.alter_email_send_log.sql b/script/0.11/schema/1.alter_email_send_log.sql new file mode 100644 index 0000000..b6ea2b4 --- /dev/null +++ b/script/0.11/schema/1.alter_email_send_log.sql @@ -0,0 +1,6 @@ +ALTER TABLE email_send_log ALTER COLUMN project_correlation_id TYPE INTEGER [] + USING CASE + WHEN project_correlation_id is NULL + then NULL + ELSE array [project_correlation_id] + END ::INTEGER []; \ No newline at end of file diff --git a/web/client/index.html b/web/client/index.html index 302a7e4..3ee9392 100644 --- a/web/client/index.html +++ b/web/client/index.html @@ -2,26 +2,26 @@ - - + + - + - - + + - - + + - -
+ +
- - + + - - + - + - + \ No newline at end of file diff --git a/web/client/src/sections/control/containers/control.jsx b/web/client/src/sections/control/containers/control.jsx index c4857d2..acba920 100644 --- a/web/client/src/sections/control/containers/control.jsx +++ b/web/client/src/sections/control/containers/control.jsx @@ -8,7 +8,6 @@ import repairFQA from '../../means/containers/repairFQA'; import { Setup, OutHidden } from "$components"; import ReactECharts from 'echarts-for-react'; import moment from "moment"; -import { log } from 'ezuikit-js'; let newScrollbar; let overviewScrollbar; @@ -43,7 +42,7 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const [videoBI, setVideoBI] = useState([]); //查询BI分析数据-视频 const [appBI, setAppBI] = useState([]); //查询BI分析数据-应用 const [efficiencyBI, setEfficiencyBI] = useState({}); //查询BI分析数据-问题处置 - const [query, setQuery] = useState({ limit: 10, page: 0, projectCorrelationId: '', types: '1' }); //最新动态 + const [query, setQuery] = useState({ limit: 23, page: 0, projectCorrelationId: '', types: '1' }); //最新动态 const [querydata1, setQueryData1] = useState([]); //最新动态数据 const [long, setLong] = useState(''); //最新动态设置 const [pomsList, setPomsList] = useState([]); //项目 @@ -184,7 +183,7 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject newest.sort((a, b) => (moment(a.time).isBefore(b.time) ? 1 : -1)) querydata.current = [...newest, ...querydata.current] setQueryData1([...querydata.current]) - + } }, [socketData]) useEffect(() => { @@ -398,6 +397,7 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject })) } if (exhibition?.current?.dynamic?.find(v => v.key == 'notice')) { + // EM 推送 res.payload.data?.notice?.map(v => data.push({ seed: 'notice', time: v.time, @@ -444,14 +444,26 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const line = document.getElementById("line") const news = document.getElementById("news") if (line && news) { - news.onscroll = () => { + news.onscroll = (e) => { + e.stopPropagation(); if ((line.clientHeight - 578) < news.scrollTop + 10) { setQuery({ ...query, page: query.page + 1 }) if (exhibition?.current?.dynamic?.length > 0) { dispatch(control.getLatestDynamic({ ...query, projectCorrelationId: pepProjectId, page: query.page + 1 })).then(res => { - news.scrollTop = news.scrollTop - 640 + // news.scrollTop = news.scrollTop - 640 let data = querydata.current if (res.success) { + let returnJudge = true + for (let k in res.payload.data) { + if (res.payload.data[k].length) { + returnJudge = false + break + } + } + if (returnJudge) { + return + } + if (exhibition?.current?.dynamic?.find(v => v.key == 'discovery')) { res.payload.data?.appear?.map(v => data.push({ seed: 'discovery', @@ -503,9 +515,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject = document.getElementById("news"); if (domProject) { - // newScrollbar = new PerfectScrollbar("#news", { - // suppressScrollX: true, - // }); if (domProject && newScrollbar) { newScrollbar.update(); } @@ -513,9 +522,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const pomsList = document.getElementById("pomsList"); if (pomsList) { - // pomsListScrollbar = new PerfectScrollbar("#pomsList", { - // suppressScrollX: true, - // }); if (pomsList && pomsListScrollbar) { pomsListScrollbar.update(); } @@ -523,9 +529,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject1 = document.getElementById("overviewCalc"); if (domProject1) { - // overviewScrollbar = new PerfectScrollbar("#overviewCalc", { - // suppressScrollY: true, - // }); if (domProject1 && overviewScrollbar) { overviewScrollbar.update(); } @@ -533,9 +536,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject2 = document.getElementById("member"); if (domProject2) { - // memberScrollbar = new PerfectScrollbar("#member", { - // suppressScrollX: true, - // }); if (domProject2 && memberScrollbar) { memberScrollbar.update(); } @@ -543,9 +543,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject3 = document.getElementById("equipment"); if (domProject3) { - // equipmentScrollbar = new PerfectScrollbar("#equipment", { - // suppressScrollX: true, - // }); if (domProject3 && equipmentScrollbar) { equipmentScrollbar.update(); } @@ -553,9 +550,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject4 = document.getElementById("web"); if (domProject4) { - // webScrollbar = new PerfectScrollbar("#web", { - // suppressScrollX: true, - // }) if (domProject4 && webScrollbar) { webScrollbar.update(); } @@ -563,9 +557,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject5 = document.getElementById("problems"); if (domProject5) { - // problemsScrollbar = new PerfectScrollbar("#problems", { - // suppressScrollX: true, - // }); if (domProject5 && problemsScrollbar) { problemsScrollbar.update(); } @@ -573,17 +564,11 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject const domProject6 = document.getElementById("alarm"); if (domProject6) { - // alarmScrollbar = new PerfectScrollbar("#alarm", { - // suppressScrollY: true, - // }); if (domProject6 && alarmScrollbar) { alarmScrollbar.update(); } } - - // ACTION 示例 - // dispatch(actions.example.getMembers(user.orgId)) }) const consoleToollink = () => { @@ -625,8 +610,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject - - let Select = { overall: ['workbench', 'statistical', 'analyse', 'dynamic', 'tool'], workbench: ['project', 'data', 'app', 'device'], @@ -672,8 +655,6 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject { name: 'BI分析模块', sort: 3, key: 'analyse', }, { name: '最新动态', sort: 4, key: 'dynamic', }, { name: '我常用的工具', sort: 5, key: 'tool', }, - - ] useEffect(() => { @@ -1245,8 +1226,8 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject }} />
-
-
+
+
{querydata.current?.map((v, index) => { let title = '' @@ -1256,8 +1237,13 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject title = v.userName ? (v.userName + '确认并关闭' + v.project + '【' + v.sources + '】' + v.type + '的问题') : v.project + '【' + v.sources + '】' + v.type + '已恢复' } else { - title = '【信鸽-' + v.alarmPushConfig + '】已邮件通知' + - v.userName?.map((u, i) => (i > 0 ? ',' + u : u)) + '【' + v.project + '】【' + + title = + '【信鸽-' + v.alarmPushConfig + '】已邮件通知' + + + v.userName?.map((u, i) => (i > 0 ? ',' + u : u)) + + '【' + v.project + + '】【' + + (v.tactics == 'immediately' ? '发现在' + v.interval + '分钟内,有告警源新增' : (v.tactics == 'continue' ? '告警源持续产生时间超过' + v.interval + '分钟' : '异常设备数量达到项目或结构物内设备总数量的' + From 8de7205d8dc9cc176a471b4a41c4966d88338f06 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Thu, 24 Nov 2022 09:24:00 +0800 Subject: [PATCH 16/51] =?UTF-8?q?EM=E6=8E=A8=E9=80=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=A4=9A=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 9c3460e..44eca5e 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -19,7 +19,7 @@ module.exports = function (app, opts) { del: false, disable: false }, - order: ['id'], + order: ['id'], }) let pomsProjectId = new Set() let pepProjectIds = new Set() @@ -90,7 +90,7 @@ module.exports = function (app, opts) { curAnxinProjectId.add(axId) } } - + const anxinProjectId = [...curAnxinProjectId] // 查当前 poms 下的结构物 并把不包含的去掉 // 可能有结构物已解绑 @@ -151,7 +151,7 @@ module.exports = function (app, opts) { let pepProjectName = pepProjectName_.length ? pepProjectName_.join('
') - : '' + : '' let emailTitle = `${pepProjectName_.length ? pepProjectName_.join('、') @@ -249,9 +249,15 @@ module.exports = function (app, opts) { } if (c.alarmType.includes('video_exception')) { let videoAlarmSubType = c.alarmSubType ? c.alarmSubType['video_exception'] : [] - if (videoAlarmSubType.length == 1) videoAlarmSubType.push(-1) - videoAlarms = searchStrucIds.length && videoAlarmSubType.length ? await clickHouse.vcmp.query( - ` + if (videoAlarmSubType.length == 1) { + videoAlarmSubType.push(-1) + } + videoAlarms = + searchStrucIds.length && ( + !c.alarmSubType || videoAlarmSubType.length > 0 + ) ? + await clickHouse.vcmp.query( + ` SELECT cameraAlarm.cameraId AS cameraId, cameraAlarm.cameraName AS cameraName, @@ -294,7 +300,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(',')})` : ""} + ${c.alarmSubType ? `AND camera.kind_id in (${videoAlarmSubType.join(',')})` : ""} WHERE camera_status_alarm.confirm_time IS null ${videoAlarmWhereOption.length ? ` AND ${videoAlarmWhereOption.join(' AND ')}` : ''} @@ -318,7 +324,7 @@ module.exports = function (app, opts) { ON anxinStation.id = anxinIpcStation.station ORDER BY cameraAlarm.createTime DESC ` - ).toPromise() : [] + ).toPromise() : [] let returnD = [] let positionD = {} From 92a0b27d07ae149fe4953c6c687a4a9c278a76b1 Mon Sep 17 00:00:00 2001 From: wenlele Date: Thu, 24 Nov 2022 09:24:28 +0800 Subject: [PATCH 17/51] =?UTF-8?q?=E5=90=AF=E7=94=A8=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0.11/schema/1.alter_alarm_push_config.sql | 4 ++ .../sections/service/components/pushModal.jsx | 37 ++++++++++++++----- .../sections/service/containers/emPush.jsx | 21 ++++++----- 3 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 script/0.11/schema/1.alter_alarm_push_config.sql diff --git a/script/0.11/schema/1.alter_alarm_push_config.sql b/script/0.11/schema/1.alter_alarm_push_config.sql new file mode 100644 index 0000000..af3ccc1 --- /dev/null +++ b/script/0.11/schema/1.alter_alarm_push_config.sql @@ -0,0 +1,4 @@ +alter table alarm_push_config + add poms_struc_factor_id jsonb; + +comment on column alarm_push_config.poms_project_factor_id is '结构物对应监测项 id'; \ No newline at end of file diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 401ac9b..2325e7c 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -34,6 +34,7 @@ function pushModal (props) { const [interval3, setInterval3] = useState(undefined); // const [deviceProportion, setDeviceProportion] = useState(undefined); // const [subType, setSubType] = useState([]); //监听模块中的子类 + const [factor, setFactor] = useState([]); //结构物对应监测项 //初始化 @@ -43,11 +44,12 @@ function pushModal (props) { getProjectPomsList()//获取已绑定项目 if (editObj.id) { getProjectStructureList(editObj.pomsProjectId) - if (editObj.pomsProject?.pepProjectId) { - getProjectStatusList()//获取项目状态列表 - } else { + let division = editObj?.pomsProject?.map(v => (v.pepProject?.id || 'POMS')) + if (division.length == 1 && division?.includes('POMS')) { setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) timeTypePOMS.current = ['POMS'] + } else { + getProjectStatusList()//获取项目状态列表 } if (editObj.tactics == 'immediately') { setInterval1(editObj.tacticsParams?.interval) @@ -74,13 +76,24 @@ function pushModal (props) { }) } function getProjectStructureList (value) {//获取绑定项目下结构物 - dispatch(service.getProjectStructure({ pomsProjectId:value.join(',') })).then((res) => { + dispatch(service.getProjectStructure({ pomsProjectId: value.join(',') })).then((res) => { if (res.success) { + let data = [] + let ProjectId = [] + res.payload?.data.map(v => { + if (ProjectId.includes(v.id)) { + } else { + ProjectId.push(v.id) + data.push(v) + } + }) + let mylist = [] - for (let i = 0; i < res.payload?.data.length; i++) { - mylist.push(res.payload?.data[i].id) + for (let i = 0; i < data.length; i++) { + mylist.push(data[i].id) } - setProjectStructure(res.payload?.data) + setProjectStructure(data) + // setFactor() form.current.setValue('strucId', mylist) form.current.validate(['strucId', 'timeType']) setStructure(false) @@ -93,8 +106,12 @@ function pushModal (props) { if (res.success) { setProjectStatus(res.payload?.data) let mylist = [] - for (let i = 0; i < res.payload?.data.length; i++) { - mylist.push(res.payload?.data[i].id) + if (editObj?.id) { + mylist = editObj?.timeType.map(Number) || [] + } else { + for (let i = 0; i < res.payload?.data.length; i++) { + mylist.push(res.payload?.data[i].id) + } } form.current.setValue('timeType', mylist) form.current.validate(['strucId', 'timeType']) @@ -188,7 +205,7 @@ function pushModal (props) { } } if (key == 'pomsProjectId') { - + getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 for (let i = 0; i < projectPoms.length; i++) { if (values.pomsProjectId == projectPoms[i].id) { diff --git a/web/client/src/sections/service/containers/emPush.jsx b/web/client/src/sections/service/containers/emPush.jsx index c0d9307..c623f4d 100644 --- a/web/client/src/sections/service/containers/emPush.jsx +++ b/web/client/src/sections/service/containers/emPush.jsx @@ -262,7 +262,7 @@ const EmPush = (props) => { } return ( - projectData.map((u, index) =>
+ projectData.map((u, index) =>
{ u.anxinerror ? ( @@ -522,21 +522,22 @@ const EmPush = (props) => { 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) { + } else { + let construcId = row.pomsProject?.map(v => (v.pepProject?.constructionStatusId || 'POMS')) || [] + if (construcId?.includes('POMS')) { + enableType = '已生效' + } else { + let timeType = row.timeType?.map(Number) || [] + for (let i = 0; i < timeType.length; i++) { + if (construcId?.includes(timeType[i])) { enableType = '已生效' - break; + break } else { enableType = '未生效' } } } - else { - enableType = '已生效' - } + } return (
From ec59bd6c0a86a53f6ee448d32cafbd47f479ede9 Mon Sep 17 00:00:00 2001 From: wenlele Date: Thu, 24 Nov 2022 10:50:42 +0800 Subject: [PATCH 18/51] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/models/alarm_push_config.js | 9 +++++++++ web/client/src/sections/service/components/pushModal.jsx | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/api/app/lib/models/alarm_push_config.js b/api/app/lib/models/alarm_push_config.js index 24c9417..0472461 100644 --- a/api/app/lib/models/alarm_push_config.js +++ b/api/app/lib/models/alarm_push_config.js @@ -51,6 +51,15 @@ module.exports = dc => { field: "alarm_sub_type", autoIncrement: false }, + pomsStrucFactorId: { + type: DataTypes.JSONB, + allowNull: true, + defaultValue: null, + comment: "监听的告警类型", + primaryKey: false, + field: "poms_struc_factor_id", + autoIncrement: false + }, receiverPepUserId: { type: DataTypes.ARRAY(DataTypes.INTEGER), allowNull: true, diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 2325e7c..3512a39 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -403,7 +403,11 @@ function pushModal (props) { key={u.name + u.index} field={u.value} style={{ width: 695 }} - initValue={(editObj?.id && (editObj?.alarmSubType ? editObj?.alarmSubType[u.value] : u.data.map(v => v.id))) || []} + initValue={ + editObj?.id ? + editObj?.alarmSubType ? + editObj?.alarmSubType[u.value] : u.data.map(v => v.id) + : []} direction='horizontal' showClear > From d605bf2115f566ad057d0c6e036cb7e8ab93b10f Mon Sep 17 00:00:00 2001 From: wenlele Date: Thu, 24 Nov 2022 15:28:44 +0800 Subject: [PATCH 19/51] poms_struc_factor_id --- api/app/lib/models/alarm_push_config.js | 4 ++-- script/0.11/schema/1.alter_alarm_push_config.sql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/app/lib/models/alarm_push_config.js b/api/app/lib/models/alarm_push_config.js index 0472461..515e635 100644 --- a/api/app/lib/models/alarm_push_config.js +++ b/api/app/lib/models/alarm_push_config.js @@ -46,7 +46,7 @@ module.exports = dc => { type: DataTypes.JSONB, allowNull: true, defaultValue: null, - comment: "监听的告警类型", + comment: "监听的告警类型的子类id的关联", primaryKey: false, field: "alarm_sub_type", autoIncrement: false @@ -55,7 +55,7 @@ module.exports = dc => { type: DataTypes.JSONB, allowNull: true, defaultValue: null, - comment: "监听的告警类型", + comment: "结构物与监测项id的关联", primaryKey: false, field: "poms_struc_factor_id", autoIncrement: false diff --git a/script/0.11/schema/1.alter_alarm_push_config.sql b/script/0.11/schema/1.alter_alarm_push_config.sql index af3ccc1..b48458e 100644 --- a/script/0.11/schema/1.alter_alarm_push_config.sql +++ b/script/0.11/schema/1.alter_alarm_push_config.sql @@ -1,4 +1,4 @@ alter table alarm_push_config add poms_struc_factor_id jsonb; -comment on column alarm_push_config.poms_project_factor_id is '结构物对应监测项 id'; \ No newline at end of file +comment on column alarm_push_config.poms_struc_factor_id is '结构物对应监测项 id'; \ No newline at end of file From 57f1926a8af7e09477c4792b5a52dd57958a36ef Mon Sep 17 00:00:00 2001 From: wenlele Date: Thu, 24 Nov 2022 17:52:33 +0800 Subject: [PATCH 20/51] =?UTF-8?q?=E8=84=9A=E6=9C=AC=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/0.10/schema/1.alter_alarm_push_config.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/0.10/schema/1.alter_alarm_push_config.sql b/script/0.10/schema/1.alter_alarm_push_config.sql index 8bf1d54..7a59716 100644 --- a/script/0.10/schema/1.alter_alarm_push_config.sql +++ b/script/0.10/schema/1.alter_alarm_push_config.sql @@ -1,5 +1,5 @@ alter table alarm_push_config - add alarm_sub_type jsonb + add alarm_sub_type jsonb; comment on column alarm_push_config.alarm_sub_type is '存对应监听模块(alarm_type)的子类( 数据告警:alarms.AlarmGroupUnit, From 7fe6bd3d83d6d69f709ee6a205e13b7e2d990d11 Mon Sep 17 00:00:00 2001 From: wenlele Date: Thu, 24 Nov 2022 19:00:15 +0800 Subject: [PATCH 21/51] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=97=B6=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/service/components/pushModal.jsx | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 3512a39..464cab6 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -205,20 +205,29 @@ function pushModal (props) { } } if (key == 'pomsProjectId') { - - getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 - for (let i = 0; i < projectPoms.length; i++) { - if (values.pomsProjectId == projectPoms[i].id) { - if (projectPoms[i].pepProjectId) { - getProjectStatusList()//获取项目状态列表 - } - else { - setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) - form.current.setValue('timeType', ['POMS']) - form.current.validate() + if (values.pomsProjectId.length > 0) { + getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 + let pepProjectId = [] + let projectData = values.pomsProjectId?.map(v => { + let data = projectPoms?.filter(u => u.id == v) || [] + if (data.length) { + pepProjectId.push(data[0].pepProjectId || 'POMS') } + }) + if (pepProjectId.length == 1 && pepProjectId.includes('POMS')) { + setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) + form.current.setValue('timeType', ['POMS']) + form.current.validate() + } else { + getProjectStatusList()//获取项目状态列表 } + } else { + setProjectStructure([]) + form.current.setValue('strucId', []) + setProjectStatus([]) + form.current.setValue('timeType', []) } + } if (key == 'alarmType') { setSubType(field['alarmType']) From e01a73e2273cf8d31d488ba260f9d86d1ff50afe Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Mon, 28 Nov 2022 09:28:11 +0800 Subject: [PATCH 22/51] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=8E=A8=E9=80=81=20?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E7=9B=91=E6=B5=8B=E5=9B=A0=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/alarm/data.js | 1 - api/app/lib/schedule/alarms_push.js | 72 +++++++++++++++++++++------ 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/api/app/lib/controllers/alarm/data.js b/api/app/lib/controllers/alarm/data.js index f1d2b82..87ac48f 100644 --- a/api/app/lib/controllers/alarm/data.js +++ b/api/app/lib/controllers/alarm/data.js @@ -149,7 +149,6 @@ async function list (ctx) { `).toPromise(); const confirmedAlarm = alarmRes - // TODO: 开发临时注释 .filter(ar => ar.State && ar.State > 2) .map(ar => "'" + ar.AlarmId + "'") const confirmedAlarmDetailMax = confirmedAlarm.length ? diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 44eca5e..7d75d08 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -60,7 +60,7 @@ module.exports = function (app, opts) { for (let { dataValues: c } of configListRes) { if (c.tacticsParams && c.tactics) { // pomsProjectId 是个数组 [] - const { strucId, pomsProjectId, } = c + const { strucId, pomsProjectId, pomsStrucFactorId } = c const { interval, deviceProportion } = c.tacticsParams if ( @@ -274,6 +274,7 @@ module.exports = function (app, opts) { anxinIpc.t_video_ipc.name AS anxinIpcPosition, anxinStation.id AS anxinStationId, anxinStation.name AS anxinStationName, + anxinStation.factor AS anxinStationFactorId, anxinStruc.name AS strucName, anxinStruc.id AS strucId FROM ( @@ -348,6 +349,20 @@ module.exports = function (app, opts) { }) } } else { + + if (pomsStrucFactorId) { + if (!a.strucId || !a.anxinStationFactorId) { + // 当前告警没有绑定结构物或者摄像头没有绑定测点 + continue + } else if (!pomsStrucFactorId[a.strucId]) { + // 推送配置没配置这个结构物 + continue + } else if (!pomsStrucFactorId[a.strucId].includes(a.anxinStationFactorId)) { + // 不包含这个监测因素 + continue + } + } + let d = { cameraId: a.cameraId, cameraName: a.cameraName, @@ -363,6 +378,7 @@ module.exports = function (app, opts) { confirmContent: a.confirmContent, confirmTime: a.confirmTime, cameraKind: a.cameraKind, + factorId: a.anxinStationFactorId, struc: [], station: [] } @@ -387,28 +403,28 @@ module.exports = function (app, opts) { } } } - let p = 1 videoAlarms = returnD } if (c.alarmType.includes('app_exception')) { 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: [{ - model: models.App, - required: true, + appAlarms = c.alarmSubType && c.alarmSubType['app_exception'].length ? + await models.AppAlarm.findAll({ + where: appAlarmWhereOption, + order: [['createTime', 'DESC']], include: [{ - model: models.ProjectApp, - where: { - projectId: { $in: pomsProjectId } - }, + model: models.App, required: true, + include: [{ + model: models.ProjectApp, + where: { + projectId: { $in: pomsProjectId } + }, + required: true, + }] }] - }] - }) : [] + }) : [] } if (c.alarmType.includes('device_exception')) { dataAlarmGroupOption.push(4) @@ -424,15 +440,20 @@ module.exports = function (app, opts) { dataAlarmSubType.push(-1) dataAlarmOption.push(`AlarmGroupUnit IN (${dataAlarmSubType.join(',')})`) } - dataAlarms = (!c.alarmSubType || dataAlarmSubType.length) ? await clickHouse.dataAlarm.query(` + dataAlarms = + !c.alarmSubType || dataAlarmSubType.length ? + await clickHouse.dataAlarm.query(` SELECT * FROM alarms + LEFT JOIN ${anxinyun}.t_sensor + AS anxinStation + ON toString(anxinStation.id) = alarms.SourceId + AND alarms.SourceTypeId = 2 WHERE ${`State NOT IN (3, 4) AND `} StructureId IN (${searchStrucIds.join(',')}) ${dataAlarmOption.length ? ' AND ' + dataAlarmOption.join(' AND ') : ''} ORDER BY StartTime DESC `).toPromise() : [] - console.log(dataAlarms); } let dataAlarmTitle = [{ @@ -640,6 +661,24 @@ module.exports = function (app, opts) { let dataAlarmG45 = []; let deviceStatistic = new Set() for (let d of dataAlarms) { + + if (pomsStrucFactorId && d.SourceTypeId == 2) { + // 做了监测因素筛选 且当前告警有监测因素 + if (!d.factor || d.factor == 0) { + // 监测因素不对劲 + continue + } else if (!d.StructureId) { + // 当前告警没有绑定结构物 + continue + } else if (!pomsStrucFactorId[d.StructureId]) { + // 推送配置没配置这个结构物 + continue + } else if (!pomsStrucFactorId[d.StructureId].includes(d.factor)) { + // 不包含这个监测因素 + continue + } + } + if (d.AlarmGroup == 1) { dataAlarmG1.push(d) } else if (d.AlarmGroup == 2) { @@ -655,6 +694,7 @@ module.exports = function (app, opts) { let rate = ((deviceStatistic.size + videoAlarms.length) / (parseInt(deviceCount) + parseInt(cameraCount))); if (rate < parseFloat(deviceProportion)) { + // 设备异常率低于设定值 continue } From d54d9ccf27a5ed58ddec7d53e0cde20331350aa6 Mon Sep 17 00:00:00 2001 From: wenlele Date: Mon, 28 Nov 2022 15:47:12 +0800 Subject: [PATCH 23/51] =?UTF-8?q?=E7=9B=91=E6=B5=8B=E9=A1=B9=E7=9A=84?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.vscode/launch.json | 2 +- api/app/lib/controllers/project/index.js | 2 +- api/app/lib/controllers/push/config.js | 4 +- .../sections/service/components/pushModal.jsx | 69 ++++++++++++------- 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 5e3848a..c428d9e 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -57,7 +57,7 @@ // "--clickHouseIot iot", // 测试 - "--clickHouseAnxincloud anxinyun88", + "--clickHouseAnxincloud anxinyun1", "--clickHousePepEmis pepca8", "--clickHouseProjectManage peppm8", "--clickHouseVcmp video_access_dev", diff --git a/api/app/lib/controllers/project/index.js b/api/app/lib/controllers/project/index.js index 3b47b76..b04763b 100644 --- a/api/app/lib/controllers/project/index.js +++ b/api/app/lib/controllers/project/index.js @@ -284,7 +284,7 @@ async function strucWithPomsProject (ctx) { factor: nextFacor }) } else { - if (s.factorId) { + if (s.factorId && !corStrut.factor.some(v => v.id == s.factorId)) { corStrut.factor.push({ id: s.factorId, name: s.factorName diff --git a/api/app/lib/controllers/push/config.js b/api/app/lib/controllers/push/config.js index 9d11e33..43feb26 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, alarmSubType = {} } = ctx.request.body + strucId = [], tactics, tacticsParams, alarmSubType = {}, pomsStrucFactorId = {} } = ctx.request.body let storageData = { name, pomsProjectId, alarmType, receiverPepUserId, timeType, disable, - strucId, tactics, tacticsParams, alarmSubType + strucId, tactics, tacticsParams, alarmSubType, pomsStrucFactorId } let repeatOption = { diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 464cab6..2754a4b 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -1,6 +1,6 @@ import React, { useState, useRef, useEffect } from "react"; import { connect } from "react-redux"; -import { Modal, Form, Notification } from "@douyinfe/semi-ui"; +import { Modal, Form, Notification, Tooltip } from "@douyinfe/semi-ui"; import { IconAlertCircle } from '@douyinfe/semi-icons'; import './pushModal.less' @@ -34,7 +34,7 @@ function pushModal (props) { const [interval3, setInterval3] = useState(undefined); // const [deviceProportion, setDeviceProportion] = useState(undefined); // const [subType, setSubType] = useState([]); //监听模块中的子类 - const [factor, setFactor] = useState([]); //结构物对应监测项 + const [factorShow, setFactorShow] = useState([]); //结构物对应监测项 //初始化 @@ -43,7 +43,7 @@ function pushModal (props) { getOrganizationUsersList()//获取全部未删除用户 getProjectPomsList()//获取已绑定项目 if (editObj.id) { - getProjectStructureList(editObj.pomsProjectId) + getProjectStructureList(editObj.pomsProjectId, editObj) let division = editObj?.pomsProject?.map(v => (v.pepProject?.id || 'POMS')) if (division.length == 1 && division?.includes('POMS')) { setProjectStatus([{ construction_status: 'POMS', id: 'POMS' }]) @@ -75,11 +75,12 @@ function pushModal (props) { } }) } - function getProjectStructureList (value) {//获取绑定项目下结构物 + function getProjectStructureList (value, alter) {//获取绑定项目下结构物 dispatch(service.getProjectStructure({ pomsProjectId: value.join(',') })).then((res) => { if (res.success) { let data = [] let ProjectId = [] + let factorId = [] res.payload?.data.map(v => { if (ProjectId.includes(v.id)) { } else { @@ -87,14 +88,15 @@ function pushModal (props) { data.push(v) } }) - - let mylist = [] - for (let i = 0; i < data.length; i++) { - mylist.push(data[i].id) - } setProjectStructure(data) - // setFactor() - form.current.setValue('strucId', mylist) + let FactorId = [] + for (let key in alter?.pomsStrucFactorId) { + FactorId.push(key) + } + setFactorShow(FactorId?.map(Number)) + if (!editObj.id) { + form.current.setValue('strucId', ProjectId) + } form.current.validate(['strucId', 'timeType']) setStructure(false) setTimeTypeDis(false) @@ -122,7 +124,6 @@ function pushModal (props) { 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, @@ -157,11 +158,14 @@ function pushModal (props) { timeType: v.timeType[0] == 'POMS' ? [] : v.timeType, receiverPepUserId: v.receiverPepUserId || [], disable: v.disable, - alarmSubType: {} + alarmSubType: {}, + pomsStrucFactorId: {} } 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] } + } else if (key.indexOf('factor') == 0) { + data.pomsStrucFactorId = { ...data.pomsStrucFactorId, [key.slice(6)]: v[key] } } } if (caution(data.tactics, data.tacticsParams.interval, data.tacticsParams.deviceProportion)) { @@ -190,10 +194,9 @@ function pushModal (props) { >
{ for (var key in field) { if (key == 'tactics') { @@ -203,8 +206,7 @@ function pushModal (props) { } else { setAbnormal(false) } - } - if (key == 'pomsProjectId') { + } else if (key == 'pomsProjectId') { if (values.pomsProjectId.length > 0) { getProjectStructureList(values.pomsProjectId)//获取绑定项目下结构物 let pepProjectId = [] @@ -228,8 +230,9 @@ function pushModal (props) { form.current.setValue('timeType', []) } - } - if (key == 'alarmType') { + } else if (key == 'strucId') { + setFactorShow(values.strucId) + } else if (key == 'alarmType') { setSubType(field['alarmType']) } } @@ -245,7 +248,7 @@ function pushModal (props) { label='策略名称:' maxLength={15} disabled={pushEdit} - style={{ width: 695 }} + style={{ width: 678 }} initValue={editObj?.name || ""} placeholder="请输入策略名称" showClear @@ -256,7 +259,7 @@ function pushModal (props) { label="请选择项目:" field="pomsProjectId" placeholder="请选择项目" - style={{ width: 695 }} + style={{ width: 678 }} rules={[{ required: true, message: "请选择项目" }]} initValue={editObj?.pomsProjectId || ""} multiple @@ -275,10 +278,13 @@ function pushModal (props) {
请选择结构物 + + + :} field="strucId" placeholder="请选择结构物" - style={{ width: 695 }} + style={{ width: 678 }} rules={[{ required: true, message: "请选择结构物" }]} initValue={editObj?.strucId || []} disabled={structure} @@ -297,6 +303,23 @@ function pushModal (props) { }) } + {projectStructure?.filter(v => (factorShow?.includes(v.id) && v.factor?.length > 0))?.map((u, index) => { + return + { + u.factor?.map((v, index) => + {v.name}) + } + + }) + }
Date: Mon, 28 Nov 2022 15:58:25 +0800 Subject: [PATCH 24/51] =?UTF-8?q?=E7=9B=91=E6=B5=8B=E9=A1=B9=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/service/components/pushModal.jsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 2754a4b..7bb780f 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -89,13 +89,19 @@ function pushModal (props) { } }) setProjectStructure(data) - let FactorId = [] - for (let key in alter?.pomsStrucFactorId) { - FactorId.push(key) - } - setFactorShow(FactorId?.map(Number)) + if (!editObj.id) { form.current.setValue('strucId', ProjectId) + } else { + let FactorId = [] + if (alter?.pomsStrucFactorId) { + for (let key in alter?.pomsStrucFactorId) { + FactorId.push(key) + } + setFactorShow(FactorId?.map(Number)) + } else { + setFactorShow(ProjectId) + } } form.current.validate(['strucId', 'timeType']) setStructure(false) @@ -309,7 +315,7 @@ function pushModal (props) { key={u.name + index} field={'factor' + u.id} style={{ width: 695 }} - initValue={editObj?.id ? editObj?.pomsStrucFactorId[u.id] : []} + initValue={editObj?.pomsStrucFactorId ? editObj?.pomsStrucFactorId[u.id] : []} direction='horizontal' showClear > From 93b20481ae90f83a6fc2aeb72b66faad42ce6379 Mon Sep 17 00:00:00 2001 From: wenlele Date: Mon, 28 Nov 2022 16:57:01 +0800 Subject: [PATCH 25/51] =?UTF-8?q?EM=E6=8E=A8=E9=80=81=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/client/src/sections/service/components/pushModal.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 7bb780f..3026a1e 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -202,7 +202,7 @@ function pushModal (props) { { for (var key in field) { if (key == 'tactics') { @@ -370,7 +370,7 @@ function pushModal (props) { 分钟,则通过【信鸽服务】发送一条通知信息。 } - style={{ width: 198 }}> + style={{ width: 173 }}> 持续时长推送机制 Date: Tue, 29 Nov 2022 10:56:43 +0800 Subject: [PATCH 26/51] =?UTF-8?q?bug=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/sections/service/components/pushModal.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index 3026a1e..b237879 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -35,6 +35,7 @@ function pushModal (props) { const [deviceProportion, setDeviceProportion] = useState(undefined); // const [subType, setSubType] = useState([]); //监听模块中的子类 const [factorShow, setFactorShow] = useState([]); //结构物对应监测项 + const [firstPass, setFirstPass] = useState(true) //初始化 @@ -89,10 +90,7 @@ function pushModal (props) { } }) setProjectStructure(data) - - if (!editObj.id) { - form.current.setValue('strucId', ProjectId) - } else { + if (editObj.id && firstPass) { let FactorId = [] if (alter?.pomsStrucFactorId) { for (let key in alter?.pomsStrucFactorId) { @@ -102,6 +100,9 @@ function pushModal (props) { } else { setFactorShow(ProjectId) } + setFirstPass(false) + } else { + form.current.setValue('strucId', ProjectId) } form.current.validate(['strucId', 'timeType']) setStructure(false) @@ -400,7 +401,6 @@ function pushModal (props) { 异常率推送机制
-
From 1547823f1fd900689f7a077db63d4a1babcf7d9e Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 29 Nov 2022 16:45:28 +0800 Subject: [PATCH 27/51] =?UTF-8?q?POMS=20=E9=A1=B9=E7=9B=AE=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=9B=91=E6=B5=8B=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/project/index.js | 47 ++++++++++++++++++++---- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/api/app/lib/controllers/project/index.js b/api/app/lib/controllers/project/index.js index b04763b..3e6b2ae 100644 --- a/api/app/lib/controllers/project/index.js +++ b/api/app/lib/controllers/project/index.js @@ -233,7 +233,10 @@ async function strucWithPomsProject (ctx) { t_structure.id AS strucId, t_structure.name AS strucName, t_factor.id AS factorId, - t_factor.name AS factorName + t_factor.name AS factorName, + t_factor.proto AS factorProto, + t_factor_proto_item.name AS factorItemName, + t_factor_proto_item.id AS factorItemId FROM t_project LEFT JOIN @@ -260,6 +263,8 @@ async function strucWithPomsProject (ctx) { ON t_structure_factor.structure = t_structure.id LEFT JOIN t_factor ON t_structure_factor.factor = t_factor.id + LEFT JOIN t_factor_proto_item + ON t_factor_proto_item.proto = t_factor.proto WHERE project_state != -1 AND @@ -273,9 +278,18 @@ async function strucWithPomsProject (ctx) { if (!corStrut) { let nextFacor = [] if (s.factorId) { + let nextFactorItem = [] + if (s.factorItemId) { + nextFactorItem.push({ + id: s.factorItemId, + name: s.factorItemName, + }) + } nextFacor.push({ id: s.factorId, - name: s.factorName + name: s.factorName, + proto: s.factorProto, + item: nextFactorItem, }) } undelStruc.push({ @@ -284,11 +298,30 @@ async function strucWithPomsProject (ctx) { factor: nextFacor }) } else { - if (s.factorId && !corStrut.factor.some(v => v.id == s.factorId)) { - corStrut.factor.push({ - id: s.factorId, - name: s.factorName - }) + if (s.factorId) { + let corFactor = corStrut.factor.find(v => v.id == s.factorId) + let nextFactorItem = null + if (s.factorItemId) { + nextFactorItem = { + id: s.factorItemId, + name: s.factorItemName, + } + } + if (corFactor) { + if (!corFactor.item.some(fi => fi.id == s.factorItemId) && nextFactorItem) { + corFactor.item.push(nextFactorItem) + } + } else { + corStrut.factor.push({ + id: s.factorId, + name: s.factorName, + proto: s.factorProto, + item: nextFactorItem ? [{ + id: s.factorItemId, + name: s.factorItemName, + }] : [], + }) + } } } } From 2fec8133c7ef4b11234603c3048ea65a00b44a85 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 29 Nov 2022 18:05:36 +0800 Subject: [PATCH 28/51] =?UTF-8?q?=E7=9B=91=E6=B5=8B=E9=A1=B9=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 111 +++++++++++++++++++--------- 1 file changed, 78 insertions(+), 33 deletions(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 7d75d08..aa4d859 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -1,11 +1,14 @@ const moment = require('moment') +let isDev = false +isDev = true + module.exports = function (app, opts) { const alarmsPush = app.fs.scheduleInit( { interval: '12 */1 * * * *', - // immediate: true, // dev - proRun: true, + immediate: isDev, + proRun: !isDev, }, async () => { try { @@ -140,7 +143,9 @@ module.exports = function (app, opts) { }) // !开发测试用的数据 - // searchStrucIds = searchStrucIds.concat([991, 1052, 700]) + if (isDev) { + searchStrucIds = searchStrucIds.concat([991, 1052, 700]) + } if (searchStrucIds.length) { searchStrucIds.unshift(-1) @@ -350,18 +355,19 @@ module.exports = function (app, opts) { } } else { - if (pomsStrucFactorId) { - if (!a.strucId || !a.anxinStationFactorId) { - // 当前告警没有绑定结构物或者摄像头没有绑定测点 - continue - } else if (!pomsStrucFactorId[a.strucId]) { - // 推送配置没配置这个结构物 - continue - } else if (!pomsStrucFactorId[a.strucId].includes(a.anxinStationFactorId)) { - // 不包含这个监测因素 - continue - } - } + /**按监测因素 factor 筛选告警*/ + // if (pomsStrucFactorId) { + // if (!a.strucId || !a.anxinStationFactorId) { + // // 当前告警没有绑定结构物或者摄像头没有绑定测点 + // continue + // } else if (!pomsStrucFactorId[a.strucId]) { + // // 推送配置没配置这个结构物 + // continue + // } else if (!pomsStrucFactorId[a.strucId].includes(a.anxinStationFactorId)) { + // // 不包含这个监测因素 + // continue + // } + // } let d = { cameraId: a.cameraId, @@ -660,30 +666,65 @@ module.exports = function (app, opts) { let dataAlarmG3 = []; let dataAlarmG45 = []; let deviceStatistic = new Set() + let dataAlarmDetails = [] + if (dataAlarms.length) { + dataAlarmDetails = + await clickHouse.dataAlarm.query(` + SELECT * FROM alarm_details + WHERE AlarmId IN (${dataAlarms.map(da => da.AlarmId).join(',')}, '-1') + AND AlarmState = 0 + `) + } for (let d of dataAlarms) { - if (pomsStrucFactorId && d.SourceTypeId == 2) { - // 做了监测因素筛选 且当前告警有监测因素 - if (!d.factor || d.factor == 0) { - // 监测因素不对劲 - continue - } else if (!d.StructureId) { - // 当前告警没有绑定结构物 - continue - } else if (!pomsStrucFactorId[d.StructureId]) { - // 推送配置没配置这个结构物 - continue - } else if (!pomsStrucFactorId[d.StructureId].includes(d.factor)) { - // 不包含这个监测因素 - continue - } - } + /** 按监测因素筛选 且为测点告警 */ + // if (pomsStrucFactorId && d.SourceTypeId == 2) { + // // 做了监测因素筛选 且当前告警有监测因素 + // if (!d.factor || d.factor == 0) { + // // 监测因素不对劲 + // continue + // } else if (!d.StructureId) { + // // 当前告警没有绑定结构物 + // continue + // } else if (!pomsStrucFactorId[d.StructureId]) { + // // 推送配置没配置这个结构物 + // continue + // } else if (!pomsStrucFactorId[d.StructureId].includes(d.factor)) { + // // 不包含这个监测因素 + // continue + // } + // } if (d.AlarmGroup == 1) { dataAlarmG1.push(d) } else if (d.AlarmGroup == 2) { dataAlarmG2.push(d) } else if (d.AlarmGroup == 3) { + + /** 按监测因项 factor-item 的名称筛选*/ + if (pomsStrucFactorId) { + // 兼容之前的设置 有这个信息才进行判断 + if (!d.StructureId) { + // 当前告警没有绑定结构物 + continue + } else if (!pomsStrucFactorId[d.StructureId]) { + // 推送配置没配置这个结构物 + continue + } else { + let corDetail = dataAlarmDetails.find(da => da.AlarmId == d.AlarmId) + if (corDetail) { + // 判断告警详情信息里有没有监测项关键字 + if (!pomsStrucFactorId[d.StructureId].some(factorItemName => { + return corDetail.Content.includes(factorItemName) + })) { + continue + } + } else { + continue + } + } + } + dataAlarmG3.push(d) } else if (d.AlarmGroup == 4 || d.AlarmGroup == 5) { dataAlarmG45.push(d) @@ -780,8 +821,12 @@ module.exports = function (app, opts) { } return arr }, []) - // !开发测试用的数据 - // emails = ['1650192445@qq.com'] + + if (isDev) { + // !开发测试用的数据 + emails = ['1650192445@qq.com'] + } + if (emails.length) { await pushByEmail({ email: emails, From d8acfd2416798580da2ed2139c51041f8eb8594d Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Tue, 29 Nov 2022 18:05:47 +0800 Subject: [PATCH 29/51] =?UTF-8?q?=E7=9B=91=E6=B5=8B=E9=A1=B9=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index aa4d859..e061f8b 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -1,7 +1,7 @@ const moment = require('moment') let isDev = false -isDev = true +// isDev = true module.exports = function (app, opts) { const alarmsPush = app.fs.scheduleInit( From 034f06438ff06bb360e3a0939032c51040e0257f Mon Sep 17 00:00:00 2001 From: wenlele Date: Wed, 30 Nov 2022 08:56:23 +0800 Subject: [PATCH 30/51] =?UTF-8?q?=E7=9B=91=E6=B5=8B=E9=A1=B9=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/service/components/pushModal.jsx | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/web/client/src/sections/service/components/pushModal.jsx b/web/client/src/sections/service/components/pushModal.jsx index b237879..c492244 100644 --- a/web/client/src/sections/service/components/pushModal.jsx +++ b/web/client/src/sections/service/components/pushModal.jsx @@ -127,7 +127,7 @@ function pushModal (props) { } }) } - function caution (tactics, interval, deviceProportion) { + function caution (tactics, interval, deviceProportion, data) { 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) { @@ -144,6 +144,22 @@ function pushModal (props) { }) return false } + if (data.alarmType?.includes('strategy_hit')) { + let factorItem = [] + for (let key in data.pomsStrucFactorId) { + factorItem = [...factorItem, ...data.pomsStrucFactorId[key]] + + } + if (factorItem.length > 0 && data.alarmSubType['strategy_hit']?.length > 0) { + return true + } else { + Notification.error({ + content: '勾选策略命中监听模块后,策略命中细项与监测项都必须勾选一项', + duration: 3, + }) + } + return false + } return true } @@ -175,7 +191,7 @@ function pushModal (props) { data.pomsStrucFactorId = { ...data.pomsStrucFactorId, [key.slice(6)]: v[key] } } } - if (caution(data.tactics, data.tacticsParams.interval, data.tacticsParams.deviceProportion)) { + if (caution(data.tactics, data.tacticsParams.interval, data.tacticsParams.deviceProportion, data)) { dispatch(service.postPush({ pushId: editObj.id, ...data, msg: pushEdit ? '编辑推送配置' : "新增推送策略" })).then((res) => {//获取项企(PEP)全部部门及其下用户 if (res.success) { close(); @@ -311,6 +327,10 @@ function pushModal (props) { } {projectStructure?.filter(v => (factorShow?.includes(v.id) && v.factor?.length > 0))?.map((u, index) => { + let factorItem = [] + u.factor?.map(v => { + v.item.map(vv => factorItem.push(vv.name)) + }) return { - u.factor?.map((v, index) => - {v.name}) + [...new Set(factorItem)].map((v, index) => + {v}) } }) @@ -339,7 +359,6 @@ function pushModal (props) {
中台每分钟查询,若有告警源新增,则每 From 5505392a4fe755e5e1e02489be9bd01ac587817c Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 30 Nov 2022 10:47:25 +0800 Subject: [PATCH 31/51] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=8E=A8=E9=80=81debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index e061f8b..320042c 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -3,6 +3,9 @@ const moment = require('moment') let isDev = false // isDev = true +let proDebug = false +proDebug = true + module.exports = function (app, opts) { const alarmsPush = app.fs.scheduleInit( { @@ -62,6 +65,9 @@ module.exports = function (app, opts) { for (let { dataValues: c } of configListRes) { if (c.tacticsParams && c.tactics) { + if (proDebug) { + console.log(`当前运行EM配置:id=${c.id} name=${c.name}`); + } // pomsProjectId 是个数组 [] const { strucId, pomsProjectId, pomsStrucFactorId } = c const { interval, deviceProportion } = c.tacticsParams @@ -667,6 +673,10 @@ module.exports = function (app, opts) { let dataAlarmG45 = []; let deviceStatistic = new Set() let dataAlarmDetails = [] + if (proDebug) { + console.log(`查得数据告警 ${dataAlarms.length} 条`); + console.log(dataAlarms); + } if (dataAlarms.length) { dataAlarmDetails = await clickHouse.dataAlarm.query(` @@ -675,6 +685,12 @@ module.exports = function (app, opts) { AND AlarmState = 0 `) } + if (proDebug) { + console.log(`查得数据告警详情数据 ${dataAlarmDetails.length} 条`); + } + if (proDebug) { + console.log(`pomsStrucFactorId:`, pomsStrucFactorId); + } for (let d of dataAlarms) { /** 按监测因素筛选 且为测点告警 */ @@ -712,6 +728,9 @@ module.exports = function (app, opts) { continue } else { let corDetail = dataAlarmDetails.find(da => da.AlarmId == d.AlarmId) + if (proDebug) { + console.log(`相应告警详情(策略命中):`, corDetail); + } if (corDetail) { // 判断告警详情信息里有没有监测项关键字 if (!pomsStrucFactorId[d.StructureId].some(factorItemName => { @@ -724,7 +743,9 @@ module.exports = function (app, opts) { } } } - + if (proDebug) { + console.log(`符合条件的策略命中 + 1`, d); + } dataAlarmG3.push(d) } else if (d.AlarmGroup == 4 || d.AlarmGroup == 5) { dataAlarmG45.push(d) From da7cd8a9bbb77fe20003e2ba2c0e13efc8b89ac8 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 30 Nov 2022 11:19:39 +0800 Subject: [PATCH 32/51] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=8E=A8=E9=80=81debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/auth/index.js | 14 ++++++++++++++ api/app/lib/schedule/alarms_push.js | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/api/app/lib/controllers/auth/index.js b/api/app/lib/controllers/auth/index.js index 555caf8..8055d5c 100644 --- a/api/app/lib/controllers/auth/index.js +++ b/api/app/lib/controllers/auth/index.js @@ -93,6 +93,20 @@ async function login (ctx, next) { } } +async function complement (ctx) { + try { + const { models } = ctx.fs.dc; + + ctx.status = 20; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: error`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + async function logout (ctx) { try { const models = ctx.fs.dc.models; diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 320042c..c98f033 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -683,7 +683,7 @@ module.exports = function (app, opts) { SELECT * FROM alarm_details WHERE AlarmId IN (${dataAlarms.map(da => da.AlarmId).join(',')}, '-1') AND AlarmState = 0 - `) + `).toPromise() } if (proDebug) { console.log(`查得数据告警详情数据 ${dataAlarmDetails.length} 条`); From 7dbce51c9f034028e64d33b845e2f4b05e81aa10 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 30 Nov 2022 11:45:03 +0800 Subject: [PATCH 33/51] =?UTF-8?q?AlarmId=20IN=20uuid=20=E5=BC=95=E5=8F=B7?= =?UTF-8?q?=E5=8C=85=E8=A3=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/auth/index.js | 17 ++++++++++++----- api/app/lib/routes/auth/index.js | 3 +++ api/app/lib/schedule/alarms_push.js | 4 +++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/api/app/lib/controllers/auth/index.js b/api/app/lib/controllers/auth/index.js index 8055d5c..3d7887b 100644 --- a/api/app/lib/controllers/auth/index.js +++ b/api/app/lib/controllers/auth/index.js @@ -70,7 +70,7 @@ async function login (ctx, next) { await ctx.redis.hmset(emisLoginRes.token, { expired: moment().add(1, 'day'), - userInfo:JSON.stringify(emisLoginRes) + userInfo: JSON.stringify(emisLoginRes) }); ctx.status = 200; @@ -93,13 +93,19 @@ async function login (ctx, next) { } } -async function complement (ctx) { +async function loginWithToken (ctx) { try { const { models } = ctx.fs.dc; - - ctx.status = 20; + const { token } = ctx.request.body + + const emisLoginRes = await ctx.app.fs.emisRequest.get('user-info', { + query: { token, code: 'POMS' } + }) + + ctx.status = 200; + ctx.body = {} } catch (error) { - ctx.fs.logger.error(`path: ${ctx.path}, error: error`); + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; ctx.body = { message: typeof error == 'string' ? error : undefined @@ -130,4 +136,5 @@ async function logout (ctx) { module.exports = { login, logout, + loginWithToken, }; \ No newline at end of file diff --git a/api/app/lib/routes/auth/index.js b/api/app/lib/routes/auth/index.js index c4df619..db2b20c 100644 --- a/api/app/lib/routes/auth/index.js +++ b/api/app/lib/routes/auth/index.js @@ -6,6 +6,9 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['POST/login'] = { content: '登录', visible: true }; router.post('/login', auth.login); + app.fs.api.logAttr['POST/login/with_token'] = { content: '使用项企token登录', visible: true }; + router.post('/login/with_token', auth.loginWithToken); + app.fs.api.logAttr['PUT/logout'] = { content: '登出', visible: false }; router.put('/logout', auth.logout); }; \ No newline at end of file diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index c98f033..3074b5a 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -678,10 +678,12 @@ module.exports = function (app, opts) { console.log(dataAlarms); } if (dataAlarms.length) { + const alarmIds = dataAlarms + .map(ar => "'" + ar.AlarmId + "'") dataAlarmDetails = await clickHouse.dataAlarm.query(` SELECT * FROM alarm_details - WHERE AlarmId IN (${dataAlarms.map(da => da.AlarmId).join(',')}, '-1') + WHERE AlarmId IN (${alarmIds.join(',')}, '-1') AND AlarmState = 0 `).toPromise() } From eca00e0ba6d7ab5efb00e9ee160d39857d7279d2 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 30 Nov 2022 13:41:26 +0800 Subject: [PATCH 34/51] =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E9=A1=B9=E4=BC=81token=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/auth/index.js | 36 +++++++++------------------ api/app/lib/routes/auth/index.js | 3 --- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/api/app/lib/controllers/auth/index.js b/api/app/lib/controllers/auth/index.js index 3d7887b..3ce02bb 100644 --- a/api/app/lib/controllers/auth/index.js +++ b/api/app/lib/controllers/auth/index.js @@ -10,9 +10,18 @@ async function login (ctx, next) { const models = ctx.fs.dc.models; const params = ctx.request.body; - const emisLoginRes = await ctx.app.fs.emisRequest.post('login', { - data: params - }) + let emisLoginRes = null + if (params.username && params.password) { + emisLoginRes = await ctx.app.fs.emisRequest.post('login', { + data: { ...params, code: 'POMS' } + }) + } else if (params.token) { + emisLoginRes = await ctx.app.fs.emisRequest.get('user-info', { + query: { + token: params.token, code: 'POMS' + } + }) + } if (!emisLoginRes) { throw "无此用户,请使用正确的登录信息" @@ -93,26 +102,6 @@ async function login (ctx, next) { } } -async function loginWithToken (ctx) { - try { - const { models } = ctx.fs.dc; - const { token } = ctx.request.body - - const emisLoginRes = await ctx.app.fs.emisRequest.get('user-info', { - query: { token, code: 'POMS' } - }) - - ctx.status = 200; - ctx.body = {} - } catch (error) { - ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); - ctx.status = 400; - ctx.body = { - message: typeof error == 'string' ? error : undefined - } - } -} - async function logout (ctx) { try { const models = ctx.fs.dc.models; @@ -136,5 +125,4 @@ async function logout (ctx) { module.exports = { login, logout, - loginWithToken, }; \ No newline at end of file diff --git a/api/app/lib/routes/auth/index.js b/api/app/lib/routes/auth/index.js index db2b20c..c4df619 100644 --- a/api/app/lib/routes/auth/index.js +++ b/api/app/lib/routes/auth/index.js @@ -6,9 +6,6 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['POST/login'] = { content: '登录', visible: true }; router.post('/login', auth.login); - app.fs.api.logAttr['POST/login/with_token'] = { content: '使用项企token登录', visible: true }; - router.post('/login/with_token', auth.loginWithToken); - app.fs.api.logAttr['PUT/logout'] = { content: '登出', visible: false }; router.put('/logout', auth.logout); }; \ No newline at end of file From 1721be2540b57700a387f65d116ef79b2bdde229 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Wed, 30 Nov 2022 13:52:47 +0800 Subject: [PATCH 35/51] latest_dynamic_list project_correlation_id drop not null; --- .../{1.alter_email_send_log.sql => 2.alter_email_send_log.sql} | 0 script/0.11/schema/3.alert_latest_dynamic_list.sql | 1 + 2 files changed, 1 insertion(+) rename script/0.11/schema/{1.alter_email_send_log.sql => 2.alter_email_send_log.sql} (100%) create mode 100644 script/0.11/schema/3.alert_latest_dynamic_list.sql diff --git a/script/0.11/schema/1.alter_email_send_log.sql b/script/0.11/schema/2.alter_email_send_log.sql similarity index 100% rename from script/0.11/schema/1.alter_email_send_log.sql rename to script/0.11/schema/2.alter_email_send_log.sql diff --git a/script/0.11/schema/3.alert_latest_dynamic_list.sql b/script/0.11/schema/3.alert_latest_dynamic_list.sql new file mode 100644 index 0000000..13bb8f4 --- /dev/null +++ b/script/0.11/schema/3.alert_latest_dynamic_list.sql @@ -0,0 +1 @@ +alter table latest_dynamic_list alter column project_correlation_id drop not null; \ No newline at end of file From 4f45beeac912b26d0fdf39ef49f4938eb7146582 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Mon, 12 Dec 2022 14:31:13 +0800 Subject: [PATCH 36/51] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E5=AE=9A=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.vscode/launch.json | 11 +- api/app/lib/schedule/alarms_push.js | 233 ++++++++++++++++++++-------- api/config.js | 5 + 3 files changed, 174 insertions(+), 75 deletions(-) diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index c428d9e..636e38a 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -16,13 +16,14 @@ "-p 4600", "-f http://localhost:4600", // 研发 - "-g postgres://postgres:123@10.8.30.32:5432/orational_service", + // "-g postgres://postgres:123@10.8.30.32:5432/orational_service", // 测试 - // "-g postgres://FashionAdmin:123456@10.8.30.156:5432/POMS", + "-g postgres://FashionAdmin:123456@10.8.30.156:5432/POMS", "-k 10.8.30.72:29092,10.8.30.73:29092,10.8.30.74:29092", "--iotaProxy http://10.8.30.157:17007", "--redisHost 10.8.30.112", "--redisPort 6379", + "--apMergeDeVeAnxinProjectId 1,2,3", "--axyApiUrl http://127.0.0.1:4100", // "--apiEmisUrl http://10.8.30.112:14000", // 测试 @@ -43,11 +44,9 @@ "--clickHouseUrl http://10.8.30.161", // "--clickHouseUrl https://clickhouse01.anxinyun.cn/play", "--clickHousePort 30123", - // 似乎不能传空 先注释 * 2 // "--clickHouseUser ", // "--clickHousePassword ", - // 研发 // "--clickHouseAnxincloud anxinyun", // "--clickHousePepEmis pepca", @@ -55,15 +54,13 @@ // "--clickHouseVcmp video_accrss1", // "--clickHouseDataAlarm default", // "--clickHouseIot iot", - // 测试 "--clickHouseAnxincloud anxinyun1", "--clickHousePepEmis pepca8", - "--clickHouseProjectManage peppm8", + "--clickHouseProjectManage peppm", "--clickHouseVcmp video_access_dev", "--clickHouseDataAlarm default", "--clickHouseIot iot", - "--confirmAlarmAnxinUserId 1", "--vcmpAppId 5048b08d-c449-4d7f-b1ec-f741012aefe8", "--vcmpAppSecret 5ba8c0ab-9fbd-4f07-9817-c48017c3cbad", diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 3074b5a..f25e973 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -4,7 +4,7 @@ let isDev = false // isDev = true let proDebug = false -proDebug = true +// proDebug = true module.exports = function (app, opts) { const alarmsPush = app.fs.scheduleInit( @@ -16,6 +16,7 @@ module.exports = function (app, opts) { async () => { try { const { models, ORM: sequelize } = app.fs.dc + const { apMergeDeVeAnxinProjectId = '' } = opts const { clickHouse } = app.fs const { database: anxinyun } = clickHouse.anxinyun.opts.config const { pushBySms, pushByEmail, sendNoticeToWeb } = app.fs.utils @@ -73,7 +74,7 @@ module.exports = function (app, opts) { const { interval, deviceProportion } = c.tacticsParams if ( - curMinOfYear % parseInt(interval) == 0 + curMinOfYear % parseInt(interval) == 0 || isDev ) { const corPomsProject = pomsProjectRes.filter(poms => pomsProjectId.includes(poms.id)) @@ -110,7 +111,8 @@ module.exports = function (app, opts) { DISTINCT id, t_structure.id AS id, t_structure.name AS name, - t_structure.iota_thing_id AS iotaThingId + t_structure.iota_thing_id AS iotaThingId, + t_project.id AS projectId FROM t_project LEFT JOIN @@ -141,10 +143,14 @@ module.exports = function (app, opts) { ).toPromise() : [] let strucThingId = [] + let strucMap = {} let searchStrucIds = strucListRes.map(s => { if (s.iotaThingId) { strucThingId.push(s.iotaThingId) } + strucMap[s.id] = { + ...s + } return s.id }) @@ -476,7 +482,8 @@ module.exports = function (app, opts) { n: '结构物', k: '', f: (d) => { - return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name + return (strucMap[d.StructureId] || { name: '' }).name + // return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name } }, { n: '告警源名称', @@ -549,13 +556,13 @@ module.exports = function (app, opts) { n: '测点', k: '', f: (d) => { - return d.station.map(ds => ds.name).join('、') + return d.station ? d.station.map(ds => ds.name).join('、') : '' } }, { n: '位置', k: '', f: (d) => { - return d.station.map(ds => ds.position).join('、') + return d.station ? d.station.map(ds => ds.position).join('、') : '' } }, { n: '告警信息', @@ -621,15 +628,15 @@ module.exports = function (app, opts) { tableTitle += '' return tableTitle } - function packageTableData (data, titleArr) { + function packageTableData ({ data, titleArr }) { let tableData = '' for (let t of titleArr) { if (t.v) { - tableData += `${t.v}` + tableData += `${t.v || ''}` } else if (t.f) { - tableData += `${t.f(data)}` + tableData += `${t.f(data) || ''}` } else if (t.k) { - tableData += `${data[t.k]}` + tableData += `${data[t.k] || ''}` } else { tableData += `` } @@ -638,33 +645,13 @@ module.exports = function (app, opts) { return tableData } - function packageAlarmData2Table (titlePrefix, alarmData, alarmTitleArr, keyOfStartTime = 'StartTime') { - if (!alarmData.length) { - return '' - } - ifEmailSend = true - let tableTitlePrefix = titlePrefix + '告警源' - let newAddCount = 0 - let alarmHtml = '' - let alarmContent = '' - let alarmHtmlTitle = packageTableTitle(alarmTitleArr) - - for (let a of alarmData) { - alarmContent += packageTableData(a, alarmTitleArr) - if (a[keyOfStartTime] && moment(a[keyOfStartTime]).isBetween(newAddStartTime, newAddEndTime)) { - newAddCount++ - } - } - tableTitlePrefix += - c.tactics == 'abnormal_rate' ? - `${alarmData.length}个` : - `新增${newAddCount}个,未解决累计${alarmData.length}个` + tableTitlePostfix - alarmHtml += `' - alarmHtml += alarmHtmlTitle - alarmHtml += alarmContent - alarmHtml += '
` + tableTitlePrefix + '

' - - return alarmHtml + let apMergeDeVeAnxinProjectId_ = apMergeDeVeAnxinProjectId ? + apMergeDeVeAnxinProjectId.split(',') : []; + let apMergeDeVeAlarms = { + // 结构物id :{ + // data_exception 数据异常告警:[], + // video_exception 视频异常告警:[] + // } } let dataAlarmG1 = []; @@ -693,6 +680,7 @@ module.exports = function (app, opts) { if (proDebug) { console.log(`pomsStrucFactorId:`, pomsStrucFactorId); } + for (let d of dataAlarms) { /** 按监测因素筛选 且为测点告警 */ @@ -717,6 +705,30 @@ module.exports = function (app, opts) { dataAlarmG1.push(d) } else if (d.AlarmGroup == 2) { dataAlarmG2.push(d) + /** 注1 + * 根据指定的安心云结构物把数据异常和视频告警合并在一起的代码 + * 还要指定是扬尘设备 + * 以测点关联 + */ + if ( + isDev || + ( + apMergeDeVeAnxinProjectId_.length && + d.SourceName && d.SourceName.includes('扬尘') && + apMergeDeVeAnxinProjectId_.some(pid => pid == (strucMap[d.StructureId] || {}).projectId) + ) + ) { + if (apMergeDeVeAlarms[d.StructureId]) { + apMergeDeVeAlarms[d.StructureId].data_exception.push(d) + } else { + apMergeDeVeAlarms[d.StructureId] = { + data_exception: [d], + video_exception: [] + } + } + } + // 注1 END + } else if (d.AlarmGroup == 3) { /** 按监测因项 factor-item 的名称筛选*/ @@ -764,6 +776,17 @@ module.exports = function (app, opts) { emailSubTitle = emailSubTitle.replace('--%', rate.toFixed(1) + '%') } + // 注1 + if (apMergeDeVeAnxinProjectId_.length || isDev) { + for (let a of videoAlarms) { + let existStruc = a.struc.find(asc => apMergeDeVeAlarms[asc.id] || isDev) + if (existStruc) { + apMergeDeVeAlarms[existStruc.id].video_exception.push(a) + } + } + } + + // 注1 END let html = ` @@ -783,49 +806,123 @@ module.exports = function (app, opts) {
${emailSubTitle}
` + + function packageAlarmData2Table ({ + titlePrefix, alarmData, alarmTitleArr, keyOfStartTime = 'StartTime' + }) { + if (!alarmData.length) { + return '' + } + ifEmailSend = true + let tableTitlePrefix = titlePrefix + '告警源' + let newAddCount = 0 + let alarmHtml = '' + let alarmContent = '' + let alarmHtmlTitle = packageTableTitle(alarmTitleArr) + + for (let [index, a] of alarmData.entries()) { + alarmContent += packageTableData({ data: a, titleArr: alarmTitleArr }) + + if (a[keyOfStartTime] && moment(a[keyOfStartTime]).isBetween(newAddStartTime, newAddEndTime)) { + newAddCount++ + } + } + tableTitlePrefix += + titlePrefix != '数据异常&视频异常' ? + c.tactics == 'abnormal_rate' ? + `${alarmData.length}个` : + `新增${newAddCount}个,未解决累计${alarmData.length}个` + tableTitlePostfix + : '' + alarmHtml += `' + alarmHtml += alarmHtmlTitle + alarmHtml += alarmContent + alarmHtml += '
` + tableTitlePrefix + '

' + + return alarmHtml + } if (c.alarmType.includes('data_outages')) { - html += packageAlarmData2Table( - '数据中断', - dataAlarmG1, - dataAlarmTitle, - ) + html += packageAlarmData2Table({ + titlePrefix: '数据中断', + alarmData: dataAlarmG1, + alarmTitleArr: dataAlarmTitle, + }) } if (c.alarmType.includes('data_exception')) { - html += packageAlarmData2Table( - '数据异常', - dataAlarmG2, - dataAlarmTitle, - ) + html += packageAlarmData2Table({ + titlePrefix: '数据异常', + alarmData: dataAlarmG2, + alarmTitleArr: dataAlarmTitle, + }) } if (c.alarmType.includes('strategy_hit')) { - html += packageAlarmData2Table( - '策略命中', - dataAlarmG3, - dataAlarmTitle, - ) + html += packageAlarmData2Table({ + titlePrefix: '策略命中', + alarmData: dataAlarmG3, + alarmTitleArr: dataAlarmTitle, + }) } if (c.alarmType.includes('video_exception')) { - html += packageAlarmData2Table( - '视频异常', - videoAlarms, - videoAlarmTitle, - 'createTime', - ) + html += packageAlarmData2Table({ + titlePrefix: '视频异常', + alarmData: videoAlarms, + alarmTitleArr: videoAlarmTitle, + keyOfStartTime: 'createTime', + }) } if (c.alarmType.includes('app_exception')) { - html += packageAlarmData2Table( - '应用异常', - appAlarms, - appAlarmTitle, - 'createTime', - ) + html += packageAlarmData2Table({ + titlePrefix: '应用异常', + alarmData: appAlarms, + alarmTitleArr: appAlarmTitle, + keyOfStartTime: 'createTime', + }) } if (c.alarmType.includes('device_exception')) { - html += packageAlarmData2Table( - '设备异常', - dataAlarmG45, - dataAlarmTitle, + html += packageAlarmData2Table({ + titlePrefix: '设备异常', + alarmData: dataAlarmG45, + alarmTitleArr: dataAlarmTitle, + }) + } + + if (Object.keys(apMergeDeVeAlarms).length) { + let alarmTitle = dataAlarmTitle.concat( + videoAlarmTitle.slice(2).map(v => { + return { + ...v, + n: + v.n == '持续时间' ? + '摄像头告警' + v.n : + '摄像头' + v.n + } + }) ) + let alarmData = [] + for (let aKey in apMergeDeVeAlarms) { + let curStrucAlarm = apMergeDeVeAlarms[aKey] + for (let de of curStrucAlarm.data_exception) { + let corVideoException = curStrucAlarm.video_exception.filter(v => { + // ! de.id 是告警的关联查出来的测点的id + return v.station.some(vs => vs.id == de.id) + }) + if (!corVideoException.length) { + // 构造一个长度 以便在for循环里把 data_exception 放进去 + corVideoException.push({}) + } + for (let ve of corVideoException) { + alarmData.push({ + ...de, + ...ve + }) + } + } + } + + html += packageAlarmData2Table({ + titlePrefix: '数据异常&视频异常', + alarmData: alarmData, + alarmTitleArr: alarmTitle, + }) } if (ifEmailSend) { diff --git a/api/config.js b/api/config.js index 507837c..9ee0158 100644 --- a/api/config.js +++ b/api/config.js @@ -19,6 +19,8 @@ args.option('redisHost', 'redisHost'); args.option('redisPort', 'redisPort'); args.option('redisPswd', 'redisPassword'); +args.option('apMergeDeVeAnxinProjectId', '告警推送自定义の合并数据异常(De)视频异常(Ve)的指定的结构物id'); + args.option('axyApiUrl', '安心云 api'); args.option('apiEmisUrl', '企业管理 api'); args.option('apiVcmpUrl', '视频平台 api'); @@ -67,6 +69,8 @@ const IOTA_REDIS_SERVER_HOST = process.env.IOTA_REDIS_SERVER_HOST || flags.redis const IOTA_REDIS_SERVER_PORT = process.env.IOTA_REDIS_SERVER_PORT || flags.redisPort || "6379";//redis 端口 const IOTA_REDIS_SERVER_PWD = process.env.IOTA_REDIS_SERVER_PWD || flags.redisPswd || "";//redis 密码 +const AP_MERGE_DEVE_ANXINPROJECT_ID = process.env.AP_MERGE_DEVE_ANXINPROJECT_ID || flags.apMergeDeVeAnxinProjectId || ""; + // 安心云api const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.axyApiUrl; // 企业管理 api @@ -155,6 +159,7 @@ const product = { { p: '/alarm/application/api', o: 'POST' }, { p: '/alarm/video/added_log', o: 'POST' } ], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 + apMergeDeVeAnxinProjectId: AP_MERGE_DEVE_ANXINPROJECT_ID, anxinCloud: { confirmAlarmAnxinUserId: CONFIRM_ALARM_ANXIN_USER_ID }, From 8b776c32a120f806af1d16df6daf5de899b33eb0 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Mon, 12 Dec 2022 14:38:39 +0800 Subject: [PATCH 37/51] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/Dockerfile | 38 +++++++++++++++++++------------------- jenkinsfile_poms_api | 18 +++++++++--------- jenkinsfile_poms_web | 16 ++++++++-------- web/Dockerfile | 44 ++++++++++++++++++++++---------------------- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index 74ac3c3..10fc786 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,36 +1,36 @@ -# FROM repository.anxinyun.cn/devops/node:12-dev as builder +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder -# COPY . /var/app +COPY . /var/app -# WORKDIR /var/app +WORKDIR /var/app -# EXPOSE 8080 +EXPOSE 8080 -# RUN npm config set registry=http://10.8.30.22:7000 -# RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json -# RUN npm cache clean -f -# RUN rm -rf package-lock.json -# RUN npm install --registry http://10.8.30.22:7000 +RUN npm config set registry=http://10.8.30.22:7000 +RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json +RUN npm cache clean -f +RUN rm -rf package-lock.json +RUN npm install --registry http://10.8.30.22:7000 -# FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12 +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12 -# COPY --from=builder --chown=node /var/app /home/node/app +COPY --from=builder --chown=node /var/app /home/node/app -# WORKDIR /home/node/app +WORKDIR /home/node/app -# CMD ["node", "server.js"] +CMD ["node", "server.js"] # 旧版本构建方式 -FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 +# FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 -COPY . /var/app +# COPY . /var/app -WORKDIR /var/app +# WORKDIR /var/app -EXPOSE 8080 +# EXPOSE 8080 -CMD ["-u", "http://localhost:8088"] +# CMD ["-u", "http://localhost:8088"] -ENTRYPOINT [ "node", "server.js" ] \ No newline at end of file +# ENTRYPOINT [ "node", "server.js" ] \ No newline at end of file diff --git a/jenkinsfile_poms_api b/jenkinsfile_poms_api index c9291bd..cc66de8 100644 --- a/jenkinsfile_poms_api +++ b/jenkinsfile_poms_api @@ -1,19 +1,19 @@ pipeline { agent { - node{ + node{ label 'jnlp-slave' - } + } } stages { - stage('Testing poms ......') { + stage('Testing site......') { steps { - sh 'switch-auth.sh anxinyun' - buildName "#${BUILD_NUMBER} ~/fs-cloud/${JOB_NAME}:${IMAGE_VERSION}" - buildDescription "registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}" - sh 'docker build -t registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION} ./api' - sh 'docker push registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}' + buildName "#${BUILD_NUMBER} ~/iot/${JOB_NAME}:${IMAGE_VERSION}" + buildDescription "harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}" + sh 'nerdctl build -t harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION} ./code/VideoAccess-VCMP/api ' + sh 'nerdctl push harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}' + } } - } + } } \ No newline at end of file diff --git a/jenkinsfile_poms_web b/jenkinsfile_poms_web index 9d43c6e..79e5de5 100644 --- a/jenkinsfile_poms_web +++ b/jenkinsfile_poms_web @@ -2,18 +2,18 @@ pipeline { agent { node{ label 'jnlp-slave' - } + } } stages { - stage('Testing poms ......') { + stage('Testing site......') { steps { - sh 'switch-auth.sh anxinyun' - buildName "#${BUILD_NUMBER} ~/fs-cloud/${JOB_NAME}:${IMAGE_VERSION}" - buildDescription "registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}" - sh 'docker build -t registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION} ./web' - sh 'docker push registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}' + buildName "#${BUILD_NUMBER} ~/iot/${JOB_NAME}:${IMAGE_VERSION}" + buildDescription "harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}" + sh 'nerdctl build -t harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION} ./code/VideoAccess-VCMP/web' + sh 'nerdctl push harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}' + } } - } + } } \ No newline at end of file diff --git a/web/Dockerfile b/web/Dockerfile index 3991885..0ef1cde 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -1,40 +1,40 @@ -# FROM repository.anxinyun.cn/devops/node:12-dev as builder +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder -# COPY . /var/app +COPY . /var/app -# WORKDIR /var/app +WORKDIR /var/app -# EXPOSE 8080 +EXPOSE 8080 -# RUN npm config set registry=http://10.8.30.22:7000 -# RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json -# RUN npm cache clean -f -# RUN npm install --registry http://10.8.30.22:7000 -# RUN npm run build -# RUN rm -rf client/src -# RUN rm -rf node_modules -# RUN npm install --production --registry http://10.8.30.22:7000 +RUN npm config set registry=http://10.8.30.22:7000 +RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json +RUN npm cache clean -f +RUN npm install --registry http://10.8.30.22:7000 +RUN npm run build +RUN rm -rf client/src +RUN rm -rf node_modules +RUN npm install --production --registry http://10.8.30.22:7000 -# FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node-16:7.22-06-20 +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node-16:7.22-06-20 -# COPY --from=builder --chown=node /var/app /home/node/app +COPY --from=builder --chown=node /var/app /home/node/app -# WORKDIR /home/node/app +WORKDIR /home/node/app -# CMD ["node", "server.js"] +CMD ["node", "server.js"] # 旧版本构建方式 -FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 +# FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 -COPY . /var/app +# COPY . /var/app -WORKDIR /var/app +# WORKDIR /var/app -EXPOSE 8080 +# EXPOSE 8080 -CMD ["-u", "http://localhost:8088"] +# CMD ["-u", "http://localhost:8088"] -ENTRYPOINT [ "node", "server.js" ] \ No newline at end of file +# ENTRYPOINT [ "node", "server.js" ] \ No newline at end of file From f0fa441552702b83105839f68359f88375bd2214 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Mon, 12 Dec 2022 16:16:34 +0800 Subject: [PATCH 38/51] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jenkinsfile_poms_api | 2 +- jenkinsfile_poms_web | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jenkinsfile_poms_api b/jenkinsfile_poms_api index cc66de8..f6e2ce8 100644 --- a/jenkinsfile_poms_api +++ b/jenkinsfile_poms_api @@ -10,7 +10,7 @@ pipeline { steps { buildName "#${BUILD_NUMBER} ~/iot/${JOB_NAME}:${IMAGE_VERSION}" buildDescription "harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}" - sh 'nerdctl build -t harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION} ./code/VideoAccess-VCMP/api ' + sh 'nerdctl build -t harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION} ./api' sh 'nerdctl push harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}' } diff --git a/jenkinsfile_poms_web b/jenkinsfile_poms_web index 79e5de5..a30d41e 100644 --- a/jenkinsfile_poms_web +++ b/jenkinsfile_poms_web @@ -10,7 +10,7 @@ pipeline { steps { buildName "#${BUILD_NUMBER} ~/iot/${JOB_NAME}:${IMAGE_VERSION}" buildDescription "harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}" - sh 'nerdctl build -t harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION} ./code/VideoAccess-VCMP/web' + sh 'nerdctl build -t harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION} ./web' sh 'nerdctl push harbor.anxinyun.cn/iot/${JOB_NAME}:${IMAGE_VERSION}' } From c68e972af70518aae934c209359c527ed3bd9aba Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Fri, 16 Dec 2022 09:04:10 +0800 Subject: [PATCH 39/51] =?UTF-8?q?=E6=9F=A5=E5=BE=97=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=92=8C=E6=B5=8B=E7=82=B9=E7=9A=84=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/schedule/alarms_push.js | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index f25e973..757202f 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -4,7 +4,7 @@ let isDev = false // isDev = true let proDebug = false -// proDebug = true +proDebug = true module.exports = function (app, opts) { const alarmsPush = app.fs.scheduleInit( @@ -681,7 +681,9 @@ module.exports = function (app, opts) { console.log(`pomsStrucFactorId:`, pomsStrucFactorId); } + let deviceIds = new Set() for (let d of dataAlarms) { + d = { ...d, stationId: d.id } /** 按监测因素筛选 且为测点告警 */ // if (pomsStrucFactorId && d.SourceTypeId == 2) { @@ -718,6 +720,11 @@ module.exports = function (app, opts) { apMergeDeVeAnxinProjectId_.some(pid => pid == (strucMap[d.StructureId] || {}).projectId) ) ) { + // SourceTypeId 0: 'DTU' / 1: '传感器' / 2: '测点' + + if (d.SourceTypeId != 2) { + deviceIds.push(d.SourceId) + } if (apMergeDeVeAlarms[d.StructureId]) { apMergeDeVeAlarms[d.StructureId].data_exception.push(d) } else { @@ -886,6 +893,16 @@ module.exports = function (app, opts) { } if (Object.keys(apMergeDeVeAlarms).length) { + + let deviceSensorRes = [] + if (deviceIds.size) { + const device4Search = [...deviceIds] + .map(id => "'" + id + "'") + deviceSensorRes = await clickHouse.anxinyun.query(` + SELECT iota_device_id, sensor FROM t_device_sensor WHERE iota_device_id IN (${device4Search.join(',')}, '-1') + `).toPromise() + } + let alarmTitle = dataAlarmTitle.concat( videoAlarmTitle.slice(2).map(v => { return { @@ -900,9 +917,21 @@ module.exports = function (app, opts) { let alarmData = [] for (let aKey in apMergeDeVeAlarms) { let curStrucAlarm = apMergeDeVeAlarms[aKey] + if (proDebug) { + console.log(`查得数据异常、视频异常合并の告警:`); + console.log(apMergeDeVeAlarms); + console.log(`相关设备及测点信息:`); + console.log(deviceSensorRes); + } for (let de of curStrucAlarm.data_exception) { + if (!de.id) { + let corSensor = deviceSensorRes.find(ds => ds.iota_device_id == de.SourceId) + if (corSensor) { + de.id = corSensor.sensor + } + } let corVideoException = curStrucAlarm.video_exception.filter(v => { - // ! de.id 是告警的关联查出来的测点的id + // ! de.id 是告警信息关联查出来的测点的id return v.station.some(vs => vs.id == de.id) }) if (!corVideoException.length) { From 6045add003295d1e9a7d8494a787958d296cf4cf Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Fri, 16 Dec 2022 09:33:23 +0800 Subject: [PATCH 40/51] redisHost --- api/.vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 636e38a..e7a1783 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -21,7 +21,7 @@ "-g postgres://FashionAdmin:123456@10.8.30.156:5432/POMS", "-k 10.8.30.72:29092,10.8.30.73:29092,10.8.30.74:29092", "--iotaProxy http://10.8.30.157:17007", - "--redisHost 10.8.30.112", + "--redisHost localhost", "--redisPort 6379", "--apMergeDeVeAnxinProjectId 1,2,3", "--axyApiUrl http://127.0.0.1:4100", @@ -57,7 +57,7 @@ // 测试 "--clickHouseAnxincloud anxinyun1", "--clickHousePepEmis pepca8", - "--clickHouseProjectManage peppm", + "--clickHouseProjectManage peppm8", "--clickHouseVcmp video_access_dev", "--clickHouseDataAlarm default", "--clickHouseIot iot", From 200db1292bc779abb2e08ca84eb60ee614656dc7 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Fri, 16 Dec 2022 10:04:48 +0800 Subject: [PATCH 41/51] deviceIds.add --- api/app/lib/schedule/alarms_push.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 757202f..5a594a0 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -723,7 +723,7 @@ module.exports = function (app, opts) { // SourceTypeId 0: 'DTU' / 1: '传感器' / 2: '测点' if (d.SourceTypeId != 2) { - deviceIds.push(d.SourceId) + deviceIds.add(d.SourceId) } if (apMergeDeVeAlarms[d.StructureId]) { apMergeDeVeAlarms[d.StructureId].data_exception.push(d) From 1e580b0c635216d7ec9f611f484b838c9a285a15 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Fri, 16 Dec 2022 10:48:58 +0800 Subject: [PATCH 42/51] debug --- api/app/lib/schedule/alarms_push.js | 17 +++++++++-------- api/app/lib/utils/alarmHandle.js | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index 5a594a0..b9c955b 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -893,7 +893,10 @@ module.exports = function (app, opts) { } if (Object.keys(apMergeDeVeAlarms).length) { - + if (proDebug) { + console.log(`查得数据异常、视频异常合并の告警:`); + console.log(apMergeDeVeAlarms); + } let deviceSensorRes = [] if (deviceIds.size) { const device4Search = [...deviceIds] @@ -902,7 +905,10 @@ module.exports = function (app, opts) { SELECT iota_device_id, sensor FROM t_device_sensor WHERE iota_device_id IN (${device4Search.join(',')}, '-1') `).toPromise() } - + if (proDebug) { + console.log(`相关设备及测点信息:`); + console.log(deviceSensorRes); + } let alarmTitle = dataAlarmTitle.concat( videoAlarmTitle.slice(2).map(v => { return { @@ -917,12 +923,7 @@ module.exports = function (app, opts) { let alarmData = [] for (let aKey in apMergeDeVeAlarms) { let curStrucAlarm = apMergeDeVeAlarms[aKey] - if (proDebug) { - console.log(`查得数据异常、视频异常合并の告警:`); - console.log(apMergeDeVeAlarms); - console.log(`相关设备及测点信息:`); - console.log(deviceSensorRes); - } + for (let de of curStrucAlarm.data_exception) { if (!de.id) { let corSensor = deviceSensorRes.find(ds => ds.iota_device_id == de.SourceId) diff --git a/api/app/lib/utils/alarmHandle.js b/api/app/lib/utils/alarmHandle.js index cdc0807..a9fdf5a 100644 --- a/api/app/lib/utils/alarmHandle.js +++ b/api/app/lib/utils/alarmHandle.js @@ -110,7 +110,7 @@ module.exports = function (app, opts) { } let pepProjects = pepPojectIds.size ? await clickHouse.projectManage.query(` - SELECT id, project_name FROM t_pim_project WHERE id IN (${[...pepPojectIds]}, -1)` + SELECT id, project_name FROM t_pim_project WHERE id IN (${[...pepPojectIds].join(',')}, -1)` ).toPromise() : []; return { projects, pepProjects }; From a5e2b839742708fcac5e46990c26ff8df0b1bad8 Mon Sep 17 00:00:00 2001 From: "gao.zhiyuan" Date: Fri, 16 Dec 2022 11:27:02 +0800 Subject: [PATCH 43/51] device4Search --- api/app/lib/schedule/alarms_push.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index b9c955b..6c4d851 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -902,7 +902,12 @@ module.exports = function (app, opts) { const device4Search = [...deviceIds] .map(id => "'" + id + "'") deviceSensorRes = await clickHouse.anxinyun.query(` - SELECT iota_device_id, sensor FROM t_device_sensor WHERE iota_device_id IN (${device4Search.join(',')}, '-1') + SELECT + iota_device_id, sensor + FROM t_device_sensor + WHERE iota_device_id + ${device4Search.length > 1 ? `IN (${device4Search.join(',')})` : `= ${device4Search[0]}`} + `).toPromise() } if (proDebug) { From 9bee73999f7de8c6c1a6232e95095f9c3bb71aaf Mon Sep 17 00:00:00 2001 From: chengqi Date: Tue, 20 Dec 2022 09:00:59 +0800 Subject: [PATCH 44/51] =?UTF-8?q?ifream=E5=B5=8C=E5=A5=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.vscode/launch.json | 4 ++-- web/client/src/sections/facility/containers/monitor.jsx | 4 +++- .../src/sections/service/containers/reportManagement.jsx | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 636e38a..e7a1783 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -21,7 +21,7 @@ "-g postgres://FashionAdmin:123456@10.8.30.156:5432/POMS", "-k 10.8.30.72:29092,10.8.30.73:29092,10.8.30.74:29092", "--iotaProxy http://10.8.30.157:17007", - "--redisHost 10.8.30.112", + "--redisHost localhost", "--redisPort 6379", "--apMergeDeVeAnxinProjectId 1,2,3", "--axyApiUrl http://127.0.0.1:4100", @@ -57,7 +57,7 @@ // 测试 "--clickHouseAnxincloud anxinyun1", "--clickHousePepEmis pepca8", - "--clickHouseProjectManage peppm", + "--clickHouseProjectManage peppm8", "--clickHouseVcmp video_access_dev", "--clickHouseDataAlarm default", "--clickHouseIot iot", diff --git a/web/client/src/sections/facility/containers/monitor.jsx b/web/client/src/sections/facility/containers/monitor.jsx index 8abf95c..8173c65 100644 --- a/web/client/src/sections/facility/containers/monitor.jsx +++ b/web/client/src/sections/facility/containers/monitor.jsx @@ -14,7 +14,9 @@ const Server = (props) => { return ( <>
- + {/* */} + {/*