Browse Source

控制台bug优化

dev
wenlele 1 year ago
parent
commit
bbf5a3546a
  1. 2
      api/app/lib/controllers/alarm/video.js
  2. 63
      api/app/lib/controllers/control/analysis.js
  3. 559
      web/client/src/sections/control/components/alarm-chart.js
  4. 2
      web/client/src/sections/control/containers/control.jsx

2
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,

63
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 = [];

559
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
<div style={{ display: "flex" }}>
{/* 故障数统计 */}
<div style={{ padding: 16, width: '50%', height: 300 }}>
{behind ?
<>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div style={{ fontSize: 18, fontWeight: 'bold', color: "#0b0b0bbd" }}>故障数统计</div>
<div>
<Select showClear filter placeholder='项目' value={faultId} style={{ width: 160, marginRight: 10 }}
onChange={(v) => {
setFaultId(v)
getData(radioStatistics, v, false, true)
}}
optionList={pomsList}
/>
<RadioGroup type='button' buttonSize='middle' value={radioStatistics} style={{ marginRight: 10 }}
onChange={e => {
setRadioStatistics(e.target.value)
getData(e.target.value, pepProjectId, false, true)
}}
>
<Radio value="day">今日</Radio>
<Radio value="week">本周</Radio>
<Radio value="month">本月</Radio>
</RadioGroup>
<Spin spinning={statisticsSpin} tip="数据加载中...">
{behind ?
<>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div style={{ fontSize: 18, fontWeight: 'bold', color: "#0b0b0bbd" }}>故障数统计</div>
<div>
<Select showClear filter placeholder='项目' value={faultId} style={{ width: 160, marginRight: 10 }}
onChange={(v) => {
setFaultId(v)
getData(radioStatistics, v, false, true)
}}
optionList={pomsList}
/>
<RadioGroup type='button' buttonSize='middle' value={radioStatistics} style={{ marginRight: 10 }}
onChange={e => {
setRadioStatistics(e.target.value)
getData(e.target.value, pepProjectId, false, true)
}}
>
<Radio value="day">今日</Radio>
<Radio value="week">本周</Radio>
<Radio value="month">本月</Radio>
</RadioGroup>
</div>
</div>
</div>
<div style={{ display: 'flex', padding: 16, height: "100%" }}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-evenly", width: 180 }}>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('数据中段')}>
<div>数据中段</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{dataAlarm?.group1?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{dataAlarm?.group1?.sum || 0}</span>
<div style={{ display: 'flex', padding: 16, height: "100%" }}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-evenly", width: 180 }}>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('数据中段')}>
<div>数据中断</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{dataAlarm?.group1?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{dataAlarm?.group1?.sum || 0}</span>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('数据异常')}>
<div>数据异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{dataAlarm?.group2?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{dataAlarm?.group2?.sum || 0}</span>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('数据异常')}>
<div>数据异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{dataAlarm?.group2?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{dataAlarm?.group2?.sum || 0}</span>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('策略命中')}>
<div>策略命中</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{dataAlarm?.group3?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{dataAlarm?.group3?.sum || 0}</span>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('策略命中')}>
<div>策略命中</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{dataAlarm?.group3?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{dataAlarm?.group3?.sum || 0}</span>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('视频异常')}>
<div>视频异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{videoAlarm?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{videoAlarm?.sum || 0}</span>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('视频异常')}>
<div>视频异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{videoAlarm?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{videoAlarm?.sum || 0}</span>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('应用异常')}>
<div>应用异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{useAlarm?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{useAlarm?.sum || 0}</span>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('应用异常')}>
<div>应用异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{useAlarm?.untreated || 0}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{useAlarm?.sum || 0}</span>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('设备异常')}>
<div>设备异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{(dataAlarm?.group4?.untreated || 0) + (dataAlarm?.group5?.untreated || 0)}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{(dataAlarm?.group4?.sum || 0) + (dataAlarm?.group5?.sum || 0)}</span>
<div style={{ display: 'flex', justifyContent: "space-between", cursor: 'pointer' }} onClick={() => behindHandle('设备异常')}>
<div>设备异常</div>
<div style={{ fontWeight: 500 }}>
<sapn style={{ color: "red" }}>{(dataAlarm?.group4?.untreated || 0) + (dataAlarm?.group5?.untreated || 0)}</sapn> /
<span style={{ color: "rgb(48 47 138)" }}>{(dataAlarm?.group4?.sum || 0) + (dataAlarm?.group5?.sum || 0)}</span>
</div>
</div>
</div>
<div style={{ width: 'calc(100% - 180px)', display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: 46, fontWeight: 600 }}>
<div style={{ fontWeight: 500 }}>
</div>
<div style={{ width: 'calc(100% - 180px)', display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: 46, fontWeight: 600 }}>
<div style={{ fontWeight: 500 }}>
{(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)
}
</div>
</div>
</div>
</div>
</>
: <div onClick={() => {
setBehindShow([])
setBehind(true)
}}>
<ReactECharts
option={{
title: {
text: '故障数统计',
},
grid: {
left: '10%',
// right: '4%',
// bottom: '3%',
// containLabel: true
},
// dataZoom: [
// {
// type: 'slider',
// // startValue: behindShow?.map(v => 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) || []
</>
: <div onClick={() => {
setBehindShow([])
setBehind(true)
}}>
<ReactECharts
option={{
title: {
text: '故障数统计',
},
grid: {
left: '10%',
// right: '4%',
// bottom: '3%',
// containLabel: true
},
// dataZoom: [
// {
// type: 'slider',
// // startValue: behindShow?.map(v => 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={}
/>
</div>
}
</Spin>
]
}}
notMerge={true}
lazyUpdate={true}
// onChartReady={this.onChartReadyCallback}
// onEvents={EventsDict}
// opts={}
/>
</div>
}
</div>
{/* 故障数排名*/}
<div style={{ padding: 10, width: '50%', height: 300, position: "relative" }}>
<RadioGroup type='button' buttonSize='middle' value={radioRank} style={{ marginRight: 10, zIndex: 10, position: "absolute", top: 8, left: 112 }}
onChange={async e => {
setRadioRank(e.target.value)
let data = await getData(e.target.value, pepProjectId, true, false)
await getRank(data)
}}
>
<Radio value="day">今日</Radio>
<Radio value="week">本周</Radio>
<Radio value="month">本月</Radio>
</RadioGroup>
<ReactECharts
option={{
title: {
text: '故障数排名',
},
grid: {
left: '10%',
// right: '4%',
// bottom: '3%',
// containLabel: true
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['故障数'],
right: '10%',
},
yAxis: {
type: 'category',
data: rankData?.map(v => v.name) || []
},
xAxis: {
type: 'value',
},
series: [
{
type: 'bar',
name: '故障数',
smooth: true,
itemStyle: { color: '#0ddf42', },
barWidth: 20,
data: rankData?.map(v => v.sum) || []
<Spin spinning={rankSpin} tip="数据加载中...">
<RadioGroup type='button' buttonSize='middle' value={radioRank} style={{ marginRight: 10, zIndex: 10, position: "absolute", top: 8, left: 112 }}
onChange={async e => {
setRadioRank(e.target.value)
let data = await getData(e.target.value, pepProjectId, true, false)
await getRank(data)
}}
>
<Radio value="day">今日</Radio>
<Radio value="week">本周</Radio>
<Radio value="month">本月</Radio>
</RadioGroup>
<ReactECharts
option={{
title: {
text: '故障数排名',
},
grid: {
left: 70,
// right: '4%',
// bottom: '3%',
// containLabel: true
},
tooltip: {
trigger: 'axis',
formatter: function (params) {
// 自定义提示框内容
// console.log(params);
let title = rankData[params[0].dataIndex]?.name + '<br/>' + '<br/>' + params[0]?.seriesName + ":" + "&nbsp" + "&nbsp" + 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={}
/>
</Spin>
]
}}
notMerge={true}
lazyUpdate={true}
// onChartReady={this.onChartReadyCallback}
// onEvents={EventsDict}
// opts={}
/>
</div>
</div>
<div style={{ display: "flex" }}>
@ -585,6 +618,10 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
<Select filter showClear placeholder='项目' value={onlineId} style={{ width: 160, marginRight: 10 }}
onChange={(v) => {
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
<Select filter showClear placeholder='项目' value={successionId} style={{ width: 160, marginRight: 10 }}
onChange={(v) => {
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) || [])
}}
/>
<Select showClear
filter
placeholder='测点'
value={sensorValue}
multiple={true}
maxTagCount={1}
style={{ width: 160, marginRight: 10 }}
optionList={sensorList}
onChange={v => {
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
<ReactECharts
option={{
title: {
text: '数据在线率',
text: '数据连续率',
},
grid: {
left: 27,
@ -694,11 +759,11 @@ const AlarmChart = ({ dispatch, actions, user, history, projectPoms, loading, so
trigger: 'axis',
formatter: function (params) {
// 自定义提示框内容
// console.log(params);
let title = params[0].data[0] + '<br/>' + '<br/>'
let title = params[0]?.data[0] + '<br/>' + '<br/>'
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 + ":" + "&nbsp" + "&nbsp" + v.data[1] + "%" + "(" + find?.num + "/" + find?.tTotal + ")" + '<br/>'
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 + ":" + "&nbsp" + "&nbsp" + v.data[1] * 100 + "%" + "(" + findOne?.tTotal + "/" + (findOne?.num || findOne?.tTotal) + ")" + '<br/>'
})
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',

2
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'],

Loading…
Cancel
Save