diff --git a/api/app/lib/controllers/alarm/video.js b/api/app/lib/controllers/alarm/video.js
index 7fd42d8..6501066 100644
--- a/api/app/lib/controllers/alarm/video.js
+++ b/api/app/lib/controllers/alarm/video.js
@@ -138,6 +138,7 @@ async function alarmList (ctx) {
cameraAlarm.cameraId AS cameraId,
cameraAlarm.cameraName AS cameraName,
cameraAlarm.cameraKindId AS cameraKindId,
+ cameraAlarm.statusId AS statusId,
cameraAlarm.venderId AS venderId,
cameraAlarm.venderName AS venderName,
cameraAlarm.cameraSerialNo AS cameraSerialNo,
@@ -257,6 +258,7 @@ async function alarmList (ctx) {
let d = {
cameraId: a.cameraId,
cameraName: a.cameraName,
+ statusId: a.statusId,
camerOnline: a.cameraOnline,
cameraSerialNo: a.cameraSerialNo,
cameraChannelNo: a.cameraChannelNo,
diff --git a/api/app/lib/controllers/control/analysis.js b/api/app/lib/controllers/control/analysis.js
index d2aa9f2..a6a2eaf 100644
--- a/api/app/lib/controllers/control/analysis.js
+++ b/api/app/lib/controllers/control/analysis.js
@@ -757,26 +757,26 @@ async function getStrucSeries (ctx) {
index: strucSeriesClient.config.index,
type: strucSeriesClient.config.type,
body: {
- // "query": {
- // "bool": {
- // "filter": [
- // {
- // "range": {
- // "collect_time": {
- // "gte": `${moment().subtract(32, 'hours').format('YYYY-MM-DDTHH:mm:ss.SSS')}Z`,
- // // "gte": "2023-08-24T08:00:00.000Z",
- // }
- // }
- // },
- // {
- // "terms": {
- // "structure": anxinStrucIds,
- // // "structure": [1, 2, 3]
- // }
- // }
- // ]
- // }
- // },
+ "query": {
+ "bool": {
+ "filter": [
+ {
+ "range": {
+ "collect_time": {
+ "gte": `${moment().subtract(32, 'hours').format('YYYY-MM-DDTHH:mm:ss.SSS')}Z`,
+ // "gte": "2023-08-24T08:00:00.000Z",
+ }
+ }
+ },
+ {
+ "terms": {
+ "structure": anxinStrucIds,
+ // "structure": [1, 2, 3]
+ }
+ }
+ ]
+ }
+ },
"sort": [
{
"collect_time": {
@@ -793,23 +793,32 @@ async function getStrucSeries (ctx) {
}
}
- for (let struc of anxinStruc) {
+ const sensor = anxinStrucIds.length ? await clickHouse.anxinyun.query(
+ `SELECT
+ id,structure,name
+ FROM t_sensor
+ INNER JOIN t_structure
+ ON t_structure.id = t_sensor.structure
+ WHERE
+ t_sensor.structure IN (${anxinStrucIds.join(',')})`
+ ).toPromise() : []
+
+ for (let data of sensor) {
let curSeries =
seriesRes.hits.hits
- .filter((h) => h._source.structure == struc.strucId)
- // .sort((a, b) => {
- // return a._source.collect_time - b._source.collect_time
- // })
+ .filter((h) => h._source.sensor == data.id)
.map(s => {
return {
...s._source,
}
})
- struc.series = curSeries
+ let struc = anxinStruc.find((h) => h.strucId == data.structure)
+ data.series = curSeries
+ data.struc = struc
}
ctx.status = 200;
- ctx.body = anxinStruc;
+ ctx.body = sensor;
} else {
ctx.status = 200;
ctx.body = [];
diff --git a/web/client/src/sections/control/components/alarm-chart.js b/web/client/src/sections/control/components/alarm-chart.js
index 6153b42..d1dfd9d 100644
--- a/web/client/src/sections/control/components/alarm-chart.js
+++ b/web/client/src/sections/control/components/alarm-chart.js
@@ -1,6 +1,6 @@
import React, { useEffect, useState, useRef } from 'react';
import { connect } from 'react-redux';
-import { Timeline, Card, Button, Modal, Form, Tooltip, Select, Radio, RadioGroup } from '@douyinfe/semi-ui';
+import { Timeline, Card, Button, Modal, Form, Tooltip, Select, Radio, RadioGroup, Spin } from '@douyinfe/semi-ui';
import { push } from 'react-router-redux';
import { Setup, OutHidden } from "$components";
import ReactECharts from 'echarts-for-react';
@@ -19,7 +19,6 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
const [pomsList, setPomsList] = useState([]); //项目
const [faultId, setFaultId] = useState(''); //项目id 故障数统计
const [onlineId, setOnlineId] = useState(''); //项目id 数据在线率
- const [successionId, setSuccessionId] = useState(''); //项目id 数据连续率
const [setData, setSetData] = useState(); //设置总数
const [radioStatistics, setRadioStatistics] = useState('day'); //故障数统计(日,周,月)
const [radioRank, setRadioRank] = useState('day'); //故障数排名(日,周,月)
@@ -37,9 +36,16 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
const [online, setOnline] = useState([])
const [value, setValue] = useState([])
- const [seriesStruc, setSeriesStruc] = useState([])
- const [series, setSeries] = useState([])
- const [seriesValue, setSeriesValue] = useState([])
+ const [successionId, setSuccessionId] = useState(''); //项目id 数据连续率
+ const [seriesStruc, setSeriesStruc] = useState([]) //连续率 结构物数据
+ const [series, setSeries] = useState([]) //连续率 数据
+ const [seriesValue, setSeriesValue] = useState([]) //连续率 结构物Id
+ const [sensorValue, setSensorValue] = useState([]) //连续率 测点Id
+ const [sensorList, setSensorList] = useState([]) //连续率 测点数数据
+
+ const [statisticsSpin, setStatisticsSpin] = useState(false) //故障数统计 加载中
+ const [rankSpin, setRankSpin] = useState(false) //故障数排名 加载中
+
@@ -52,43 +58,49 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
useEffect(async () => {
if (projectPoms?.length > 0) {
- let data = await getData('day', pepProjectId, true, true)
- await getRank(data)
- setRadioStatistics('day')
- setRadioRank('day')
- setFaultId('')
- if (pepProjectId) {
- setPomsList(projectPoms?.filter(v => v.pepProjectIsDelete != 1 && ((pepProjectId?.length > 0 ? pepProjectId.split(",")?.map(p => Number(p)) : [pepProjectId]).includes(v.id)))?.map(v => ({ value: v.id, label: v.pepProjectName || v.name })))
- } else {
- setPomsList(projectPoms?.filter(v => v.pepProjectIsDelete != 1)?.map(v => ({ value: v.id, label: v.pepProjectName || v.name })))
+ let data = await getData('day', pepProjectId, true, true)
+ await getRank(data)
+ setRadioStatistics('day')
+ setRadioRank('day')
+ setFaultId('')
+
+ await dispatch(control.getStatisticOnline({ pepProjectId: pepProjectId })).then(res => {
+ if (res.success) {
+ setOnlineId('')
+ let data = res.payload.data
+ setOnlineStruc(data?.map(v => ({ value: v.strucId, label: v.strucName })) || [])
+ setOnline(data?.slice(0, 10) || [])
+ setValue(data?.map(v => v.strucId)?.slice(0, 10) || [])
}
- }
- }, [pepProjectId, projectPoms])
+ })
+ await dispatch(control.getStrucSeries({ pepProjectId: pepProjectId })).then(res => {
+ if (res.success) {
+ setSuccessionId('')
+ setSeriesValue('')
+ let data = res.payload.data?.filter(s => !successionId || s?.struc?.pomsProject?.map(p => p.id)?.includes(successionId))
+ setSeriesStruc(data?.map(v => ({ value: v.id, label: v.name })) || [])
+ setSeries(data?.slice(0, 10) || [])
+ setSensorList(data?.map(v => ({ value: v.id, label: v.name })) || [])
+ setSensorValue(data?.map(v => v.id)?.slice(0, 10) || [])
+ }
+ })
- useEffect(() => {
- setOnlineId('')
- dispatch(control.getStatisticOnline({ pepProjectId: onlineId || pepProjectId })).then(res => {
- if (res.success) {
- let data = res.payload.data?.filter(s => !onlineId || s.pomsProject?.map(p => p.id)?.includes(onlineId))
- setOnlineStruc(data?.map(v => ({ value: v.strucId, label: v.strucName })) || [])
- setOnline(data?.slice(0, 10) || [])
- setValue(data?.map(v => v.strucId)?.slice(0, 10) || [])
+ if (pepProjectId) {
+ setPomsList(projectPoms?.filter(v => v.pepProjectIsDelete != 1 && ((pepProjectId?.length > 0 ? pepProjectId.split(",")?.map(p => Number(p)) : [pepProjectId]).includes(v.id)))?.map(v => ({ value: v.id, label: v.pepProjectName || v.name })))
+ if (!pepProjectId?.length > 0 || pepProjectId.split(",")?.length == 1) {
+ setFaultId(Number(pepProjectId))
+ setOnlineId(Number(pepProjectId))
+ setSuccessionId(Number(pepProjectId))
+ }
+ } else {
+ setPomsList(projectPoms?.filter(v => v.pepProjectIsDelete != 1)?.map(v => ({ value: v.id, label: v.pepProjectName || v.name })))
}
- })
- }, [onlineId, pepProjectId])
- useEffect(() => {
- setSuccessionId('')
- dispatch(control.getStrucSeries({ pepProjectId: successionId || pepProjectId })).then(res => {
- if (res.success) {
- let data = res.payload.data?.filter(s => !successionId || s.pomsProject?.map(p => p.id)?.includes(successionId))
- setSeriesStruc(data?.map(v => ({ value: v.strucId, label: v.strucName })) || [])
- setSeries(data?.slice(0, 10) || [])
- setSeriesValue(data?.map(v => v.strucId)?.slice(0, 10) || [])
- }
- })
- }, [successionId, pepProjectId])
+ }
+ }, [pepProjectId, projectPoms])
+
+
const getRank = async (data) => {
let dataList = []
@@ -137,6 +149,8 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
}
const getData = async (radio, pepProjectId, diff1, diff2) => {
+ if (diff2) setStatisticsSpin(true)
+ if (diff1) setRankSpin(true)
let data = {}
await dispatch(control.getAlarmData({
pepProjectId: pepProjectId,
@@ -206,7 +220,8 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
}
})
}
-
+ setStatisticsSpin(false)
+ setRankSpin(false)
return data
}
@@ -214,7 +229,7 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
const behindHandle = (key) => {
let show = []
switch (key) {
- case '数据中段':
+ case '数据中断':
dispatch(problem.getAlarmDataGroup()).then((res) => {
if (res.success) {
let data = res.payload.data?.find(v => v.desc == '数据中断')?.unit || []
@@ -354,228 +369,246 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
{/* 故障数统计 */}
- {behind ?
- <>
-
-
故障数统计
-
-
-
-
-
behindHandle('数据中段')}>
-
数据中段:
-
-
{dataAlarm?.group1?.untreated || 0} /
-
{dataAlarm?.group1?.sum || 0}
+
+
+
behindHandle('数据中段')}>
+
数据中断:
+
+ {dataAlarm?.group1?.untreated || 0} /
+ {dataAlarm?.group1?.sum || 0}
+
-
-
behindHandle('数据异常')}>
-
数据异常:
-
-
{dataAlarm?.group2?.untreated || 0} /
-
{dataAlarm?.group2?.sum || 0}
+
behindHandle('数据异常')}>
+
数据异常:
+
+ {dataAlarm?.group2?.untreated || 0} /
+ {dataAlarm?.group2?.sum || 0}
+
-
-
behindHandle('策略命中')}>
-
策略命中:
-
-
{dataAlarm?.group3?.untreated || 0} /
-
{dataAlarm?.group3?.sum || 0}
+
behindHandle('策略命中')}>
+
策略命中:
+
+ {dataAlarm?.group3?.untreated || 0} /
+ {dataAlarm?.group3?.sum || 0}
+
-
-
behindHandle('视频异常')}>
-
视频异常:
-
-
{videoAlarm?.untreated || 0} /
-
{videoAlarm?.sum || 0}
+
behindHandle('视频异常')}>
+
视频异常:
+
+ {videoAlarm?.untreated || 0} /
+ {videoAlarm?.sum || 0}
+
-
-
behindHandle('应用异常')}>
-
应用异常:
-
-
{useAlarm?.untreated || 0} /
-
{useAlarm?.sum || 0}
+
behindHandle('应用异常')}>
+
应用异常:
+
+ {useAlarm?.untreated || 0} /
+ {useAlarm?.sum || 0}
+
-
-
behindHandle('设备异常')}>
-
设备异常:
-
-
{(dataAlarm?.group4?.untreated || 0) + (dataAlarm?.group5?.untreated || 0)} /
-
{(dataAlarm?.group4?.sum || 0) + (dataAlarm?.group5?.sum || 0)}
+
behindHandle('设备异常')}>
+
设备异常:
+
+ {(dataAlarm?.group4?.untreated || 0) + (dataAlarm?.group5?.untreated || 0)} /
+ {(dataAlarm?.group4?.sum || 0) + (dataAlarm?.group5?.sum || 0)}
+
+
+
+
-
-
-
-
- {(dataAlarm?.group1?.untreated || 0)
- + (dataAlarm?.group2?.untreated || 0)
- + (dataAlarm?.group3?.untreated || 0)
- + (dataAlarm?.group4?.untreated || 0)
- + (dataAlarm?.group5?.untreated || 0)
- + (videoAlarm?.untreated || 0)
- + (useAlarm?.untreated || 0)
- }
- /
- {(dataAlarm?.group1?.sum || 0)
- + (dataAlarm?.group2?.sum || 0)
- + (dataAlarm?.group3?.sum || 0)
- + (dataAlarm?.group4?.sum || 0)
- + (dataAlarm?.group5?.sum || 0)
- + (videoAlarm?.sum || 0)
- + (useAlarm?.sum || 0)
- }
+ {(dataAlarm?.group1?.untreated || 0)
+ + (dataAlarm?.group2?.untreated || 0)
+ + (dataAlarm?.group3?.untreated || 0)
+ + (dataAlarm?.group4?.untreated || 0)
+ + (dataAlarm?.group5?.untreated || 0)
+ + (videoAlarm?.untreated || 0)
+ + (useAlarm?.untreated || 0)
+ }
+ /
+ {(dataAlarm?.group1?.sum || 0)
+ + (dataAlarm?.group2?.sum || 0)
+ + (dataAlarm?.group3?.sum || 0)
+ + (dataAlarm?.group4?.sum || 0)
+ + (dataAlarm?.group5?.sum || 0)
+ + (videoAlarm?.sum || 0)
+ + (useAlarm?.sum || 0)
+ }
+
-
- >
- :
{
- setBehindShow([])
- setBehind(true)
- }}>
-
v.name) || []
- // },
- // {
- // type: 'inside',
- // },
- // ],
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['未处理', '已处理'],
- right: '10%',
- },
- xAxis: {
- type: 'category',
- // boundaryGap: false,
- data: behindShow?.map(v => v.name) || []
- },
- yAxis: {
- type: 'value',
- name: "单位:条",
- },
- series: [
- {
- type: 'bar',
- name: '未处理',
- smooth: true,
- itemStyle: { color: '#df4141', },
- barWidth: 20,
- data: behindShow?.map(v => v.untreated) || []
+ >
+ : {
+ setBehindShow([])
+ setBehind(true)
+ }}>
+ v.name) || []
+ // },
+ // {
+ // type: 'inside',
+ // },
+ // ],
+ tooltip: {
+ trigger: 'axis'
},
- {
- type: 'bar',
- name: '已处理',
- smooth: true,
- itemStyle: { color: '#0ddf42', },
- barWidth: 20,
- data: behindShow?.map(v => v.processed) || []
+ legend: {
+ data: ['未处理', '已处理'],
+ right: '10%',
},
+ xAxis: {
+ type: 'category',
+ // boundaryGap: false,
+ data: behindShow?.map(v => v.name) || []
+ },
+ yAxis: {
+ type: 'value',
+ name: "单位:条",
+ },
+ series: [
+ {
+ type: 'bar',
+ name: '未处理',
+ smooth: true,
+ itemStyle: { color: '#df4141', },
+ barWidth: 20,
+ data: behindShow?.map(v => v.untreated) || []
+ },
+ {
+ type: 'bar',
+ name: '已处理',
+ smooth: true,
+ itemStyle: { color: '#0ddf42', },
+ barWidth: 20,
+ data: behindShow?.map(v => v.processed) || []
+ },
+
+ ]
+ }}
+ notMerge={true}
+ lazyUpdate={true}
+ // onChartReady={this.onChartReadyCallback}
+ // onEvents={EventsDict}
+ // opts={}
+ />
+
+ }
+
- ]
- }}
- notMerge={true}
- lazyUpdate={true}
- // onChartReady={this.onChartReadyCallback}
- // onEvents={EventsDict}
- // opts={}
- />
-
- }
{/* 故障数排名*/}
- {
- setRadioRank(e.target.value)
- let data = await getData(e.target.value, pepProjectId, true, false)
- await getRank(data)
- }}
- >
- 今日
- 本周
- 本月
-
- v.name) || []
- },
- xAxis: {
- type: 'value',
- },
- series: [
- {
- type: 'bar',
- name: '故障数',
- smooth: true,
- itemStyle: { color: '#0ddf42', },
- barWidth: 20,
- data: rankData?.map(v => v.sum) || []
+
+ {
+ setRadioRank(e.target.value)
+ let data = await getData(e.target.value, pepProjectId, true, false)
+ await getRank(data)
+ }}
+ >
+ 今日
+ 本周
+ 本月
+
+ ' + '
' + params[0]?.seriesName + ":" + " " + " " + params[0]?.value
+ return title
+ }
},
+ legend: {
+ data: ['未处理故障数'],
+ right: '10%',
+ },
+ yAxis: {
+ type: 'category',
+ data: rankData?.map(v => {
+ if (v.name?.length > 4) {
+ return v.name?.slice(0, 4) + '...'
+ } else {
+ return v.name
+ }
+ }) || []
+ },
+ xAxis: {
+ type: 'value',
+ },
+ series: [
+ {
+ type: 'bar',
+ name: '未处理故障数',
+ smooth: true,
+ itemStyle: { color: '#0ddf42', },
+ barWidth: 20,
+ data: rankData?.map(v => v.sum) || []
+ },
+
+ ]
+ }}
+ notMerge={true}
+ lazyUpdate={true}
+ // onChartReady={this.onChartReadyCallback}
+ // onEvents={EventsDict}
+ // opts={}
+ />
+
- ]
- }}
- notMerge={true}
- lazyUpdate={true}
- // onChartReady={this.onChartReadyCallback}
- // onEvents={EventsDict}
- // opts={}
- />
@@ -585,6 +618,10 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
{
setOnlineId(v)
+ let data = statisticOnline?.filter(s => !v || s.pomsProject?.map(p => p.id)?.includes(v))
+ setOnlineStruc(data?.map(v => ({ value: v.strucId, label: v.strucName })) || [])
+ setOnline(data?.slice(0, 10) || [])
+ setValue(data?.map(v => v.strucId)?.slice(0, 10) || [])
}}
optionList={pomsList}
/>
@@ -661,6 +698,18 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
{
setSuccessionId(v)
+ setSeriesValue('')
+ let data = strucSeries?.filter(s => !v || s?.struc?.pomsProject?.map(p => p.id)?.includes(v))
+ let struc = []
+ data?.forEach(f => {
+ if (!struc?.find(h => h.value == f.structure)) {
+ struc.push({ value: f.structure, label: f?.struc?.strucName })
+ }
+ })
+ setSeriesStruc(struc)
+ setSeries(data?.slice(0, 10) || [])
+ setSensorList(data?.slice(0, 10)?.map(v => ({ value: v.id, label: v.name })) || [])
+ setSensorValue(data?.slice(0, 10)?.map(d => d.id) || [])
}}
optionList={pomsList}
/>
@@ -674,8 +723,24 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
optionList={seriesStruc}
onChange={v => {
setSeriesValue(v)
- let data = strucSeries?.filter(s => !onlineId || s.pomsProject?.map(p => p.id)?.includes(onlineId))
- setSeries(data?.filter(s => v.includes(s.strucId)))
+ let data = strucSeries?.filter(s => (!v.length > 0 || v.includes(s.structure)) && (!successionId || s.pomsProject?.map(p => p.id)?.includes(successionId)))
+ setSeries(data?.slice(0, 10) || [])
+ setSensorList(data?.slice(0, 10)?.map(v => ({ value: v.id, label: v.name })) || [])
+ setSensorValue(data?.slice(0, 10)?.map(d => d.id) || [])
+ }}
+ />
+ {
+ setSensorValue(v)
+ let data = strucSeries?.filter(s => (!v.length > 0 || v.includes(s.id)) && (!seriesValue?.length > 0 || seriesValue?.includes(s.structure)) && (!successionId || s.pomsProject?.map(p => p.id)?.includes(successionId)))
+ setSeries(data || [])
}}
/>
@@ -683,7 +748,7 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
' + '
'
+ let title = params[0]?.data[0] + '
' + '
'
params.forEach(v => {
- let find = series?.find(s => s.strucName == v.seriesName)?.series?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == v.data[0]) || {}
- title = title + v.seriesName + ":" + " " + " " + v.data[1] + "%" + "(" + find?.num + "/" + find?.tTotal + ")" + '
'
+ let find = series?.find(s => s.name == v.seriesName) || {}
+ let findOne = find?.series?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == v.data[0]) || {}
+ title = title + find?.name + ":" + " " + " " + v.data[1] * 100 + "%" + "(" + findOne?.tTotal + "/" + (findOne?.num || findOne?.tTotal) + ")" + '
'
})
return title
}
@@ -718,7 +783,7 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
},
series: series?.map(v => ({
type: 'line',
- name: v.strucName,
+ name: v.name,
smooth: true,
areaStyle: {
color: '#0e9cff26',
diff --git a/web/client/src/sections/control/containers/control.jsx b/web/client/src/sections/control/containers/control.jsx
index 11beae0..3cd3f79 100644
--- a/web/client/src/sections/control/containers/control.jsx
+++ b/web/client/src/sections/control/containers/control.jsx
@@ -620,7 +620,7 @@ const Control = ({ dispatch, actions, user, history, loading, socket, pepProject
dynamic: ['discovery', 'notice', 'handle', 'confirm'],
}
let show = {
- overall: ['workbench', 'statistical', 'dataAnalyse'],
+ overall: ['workbench', 'dataAnalyse'],
workbench: ['project', 'data', 'app', 'device'],
statistical: ['milestone', 'personnel', 'web', 'problem'],
analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'],