|
|
@ -1,4 +1,5 @@ |
|
|
|
import React, { useEffect, useRef, useState } from 'react'; |
|
|
|
import { Skeleton, Button, Pagination, Select, Popconfirm, Table, Tooltip } from '@douyinfe/semi-ui'; |
|
|
|
import { connect } from 'react-redux'; |
|
|
|
import Header from '../components/header'; |
|
|
|
import Body from '../components/body' |
|
|
@ -6,18 +7,104 @@ import Card from '../components/card' |
|
|
|
import '../style.less' |
|
|
|
import ReactECharts from 'echarts-for-react'; |
|
|
|
import moment from 'moment' |
|
|
|
import PerfectScrollbar from "perfect-scrollbar"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let interrupt |
|
|
|
const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, groupStatisticOnline }) => { |
|
|
|
|
|
|
|
const [InterruptRank, setInterruptRank] = useState([]) |
|
|
|
const [online, setOnline] = useState([]) |
|
|
|
const [value, setValue] = useState([]) |
|
|
|
const [time, setTime] = useState([]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId |
|
|
|
console.log(); |
|
|
|
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })) |
|
|
|
statisticOnline(groupId) |
|
|
|
}, []) |
|
|
|
|
|
|
|
console.log(groupStatisticOnline); |
|
|
|
let statisticOnline = (groupId) => { |
|
|
|
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { |
|
|
|
console.log(res); |
|
|
|
if (res.success) { |
|
|
|
let Interrupt = [] |
|
|
|
res.payload.data?.forEach(v => { |
|
|
|
if (v.offline?.id) { |
|
|
|
Interrupt.push({ name: v.name, ...v.offline }) |
|
|
|
} |
|
|
|
}) |
|
|
|
Interrupt = Interrupt?.sort((a, b) => b.offline - a.offline) |
|
|
|
setInterruptRank(Interrupt) |
|
|
|
setOnline(res.payload.data || []) |
|
|
|
setValue(res.payload.data?.map(v => v.id) || []) |
|
|
|
// eChartsData(res.payload.data || [], res.payload.data?.map(v => v.id) || []) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
// const eChartsData = (data, value) => { |
|
|
|
// // 调用函数获取时间节点数组 |
|
|
|
// let timeNodes = getTimeNodes() |
|
|
|
// let dataList = [] |
|
|
|
// data?.forEach(v => { |
|
|
|
// if (value?.includes(v.id)) { |
|
|
|
// v.timeNodes = [] |
|
|
|
// timeNodes?.forEach(s => { |
|
|
|
// if (v.online?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == s)?.structure) { |
|
|
|
// v.timeNodes.push([s,]) |
|
|
|
// } else { |
|
|
|
// v.timeNodes.push([s,null]) |
|
|
|
// } |
|
|
|
// }) |
|
|
|
// } |
|
|
|
// }) |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatDate (date) { |
|
|
|
var year = date.getFullYear(); |
|
|
|
var month = String(date.getMonth() + 1).padStart(2, '0'); |
|
|
|
var day = String(date.getDate()).padStart(2, '0'); |
|
|
|
var hour = String(date.getHours()).padStart(2, '0'); |
|
|
|
|
|
|
|
return year + '-' + month + '-' + day + ' ' + hour; |
|
|
|
} |
|
|
|
|
|
|
|
function getTimeNodes () { |
|
|
|
var currentTime = new Date(); // 当前时间 |
|
|
|
var timeNodes = []; |
|
|
|
|
|
|
|
for (var i = 0; i < 24; i++) { |
|
|
|
var timeNode = formatDate(currentTime); |
|
|
|
timeNodes.push(timeNode); |
|
|
|
|
|
|
|
currentTime.setHours(currentTime.getHours() - 1); // 减去1小时 |
|
|
|
} |
|
|
|
|
|
|
|
return timeNodes; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleRow (record, index) {//斑马条纹 |
|
|
|
// 给偶数行设置斑马纹 |
|
|
|
if (index % 2 === 0) { |
|
|
|
return { |
|
|
|
style: { |
|
|
|
background: '#F6F9FF', |
|
|
|
} |
|
|
|
}; |
|
|
|
} else { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return ( |
|
|
|
<div className='project-group'> |
|
|
@ -40,52 +127,58 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
</Card> |
|
|
|
</div> |
|
|
|
<Card title='数据在线率' style={{ width: "calc(50% - 8px)", height: "100%", }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
|
|
|
|
<div style={{ height: '100%', position: 'relative' }}> |
|
|
|
{/* <div > */} |
|
|
|
<Select |
|
|
|
showClear |
|
|
|
value={value} |
|
|
|
multiple={true} |
|
|
|
maxTagCount={1} |
|
|
|
style={{ width: 300, position: 'absolute', top: 0, right: 0, zIndex: 99 }} |
|
|
|
optionList={groupStatisticOnline?.map(v => ({ value: v.id, label: v.name })) || []} |
|
|
|
onChange={v => { |
|
|
|
setValue(v) |
|
|
|
setOnline(groupStatisticOnline?.filter(s => v.includes(s.id))) |
|
|
|
}} |
|
|
|
/> |
|
|
|
{/* </div> */} |
|
|
|
<ReactECharts |
|
|
|
option={{ |
|
|
|
title: { |
|
|
|
// text: v.name, |
|
|
|
}, |
|
|
|
grid: { |
|
|
|
// width: 300, |
|
|
|
// height: 200 |
|
|
|
left: 25, |
|
|
|
right: 10, |
|
|
|
bottom: 20, |
|
|
|
}, |
|
|
|
// dataZoom: [ |
|
|
|
// { |
|
|
|
// type: 'slider', |
|
|
|
// showDetail: false |
|
|
|
// }, |
|
|
|
// { |
|
|
|
// type: 'inside', |
|
|
|
|
|
|
|
// }, |
|
|
|
// ], |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis' |
|
|
|
}, |
|
|
|
legend: { |
|
|
|
data: groupStatisticOnline?.map(v => v.name) || [], |
|
|
|
right: '10%', |
|
|
|
textStyle: { |
|
|
|
color: '#FFF', |
|
|
|
}, |
|
|
|
trigger: 'axis', |
|
|
|
formatter: function (params) { |
|
|
|
// 自定义提示框内容 |
|
|
|
// console.log(params); |
|
|
|
let title = params[0].data[0] + '<br/>' + '<br/>' |
|
|
|
params.forEach(v => { |
|
|
|
let find = online?.find(s => s.name == v.seriesName)?.online?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == v.data[0]) || {} |
|
|
|
title = title + v.seriesName + ":" + " " + " " + v.data[1] + "%" + "(" + find?.online + "/" + find?.total + ")" + '<br/>' |
|
|
|
}) |
|
|
|
return title |
|
|
|
} |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
type: 'time', |
|
|
|
// name: "时间", |
|
|
|
boundaryGap: false, |
|
|
|
minInterval: 1000 * 60, |
|
|
|
|
|
|
|
minInterval: 1000 * 60 * 60, |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value', |
|
|
|
name: "单位:A", |
|
|
|
name: "单位%", |
|
|
|
areaStyle: { |
|
|
|
color: '#FFF', |
|
|
|
}, |
|
|
|
}, |
|
|
|
series: groupStatisticOnline?.map(v => ({ |
|
|
|
series: online?.map(v => ({ |
|
|
|
type: 'line', |
|
|
|
name: v.name, |
|
|
|
smooth: true, |
|
|
@ -100,6 +193,7 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
style={{ width: "100%", height: "100%" }} |
|
|
|
theme={'ReactEChart'} |
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
|
|
|
@ -112,8 +206,28 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
<Card title='中断排名' style={{ width: "calc(50% - 8px)", height: "100%", }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
|
|
|
|
<div style={{ height: '100%', fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400, fontSize: 14, }}> |
|
|
|
<div style={{ display: "flex", background: '#F6F9FF', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>结构物</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>中断时长</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>中断个数</div> |
|
|
|
</div> |
|
|
|
<div id="interrupt" style={{ position: 'relative', height: clientHeight * 0.55 - 100 }}> |
|
|
|
{InterruptRank?.map((c, index) => { |
|
|
|
let title |
|
|
|
if (c.offline) { |
|
|
|
if (c.offline >= 1440) title = Math.floor(c.offline / 1440) + "天" |
|
|
|
if ((c.offline % 1440) >= 60) title = title + Math.floor(c.offline % 1440 / 60) + "时" |
|
|
|
if (c.offline % 1440 % 60) title = title + c.offline % 1440 % 60 + "分" |
|
|
|
} |
|
|
|
|
|
|
|
return <div style={{ display: "flex", background: index % 2 == 0 ? "#F6F9FF;" : '', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{c.name}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{title}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{c.offnum + '/' + c.totnum}</div> |
|
|
|
</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</div> |
|
|
|