|
|
@ -11,6 +11,7 @@ import PerfectScrollbar from "perfect-scrollbar"; |
|
|
|
|
|
|
|
|
|
|
|
let interrupt |
|
|
|
let overviewScrollbar; |
|
|
|
const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, groupStatisticOnline }) => { |
|
|
|
|
|
|
|
const [InterruptRank, setInterruptRank] = useState([]) |
|
|
@ -18,14 +19,104 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
const [value, setValue] = useState([]) |
|
|
|
const [time, setTime] = useState([]) |
|
|
|
|
|
|
|
const [alarmData, setAlarmData] = useState()//第三项之后的数据 |
|
|
|
const [biggest, setBiggest] = useState()//最大的刻度值 |
|
|
|
const [mockData, setMockData] = useState()//所有的告警数据 |
|
|
|
const [xData, setXData] = useState([])//横坐标 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId |
|
|
|
console.log(); |
|
|
|
statisticOnline(groupId) |
|
|
|
dispatch(actions.projectGroup.groupStatisticAlarm({ groupId })).then(res => { |
|
|
|
if (res.success) { |
|
|
|
setMockData(res.data) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const interruptDom = document.getElementById("interrupt"); |
|
|
|
if (interruptDom) { |
|
|
|
interrupt = new PerfectScrollbar("#interrupt", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const overview = document.getElementById("alarmRank"); |
|
|
|
if (overview) { |
|
|
|
overviewScrollbar = new PerfectScrollbar("#alarmRank", { |
|
|
|
suppressScrollX: true, |
|
|
|
}); |
|
|
|
} |
|
|
|
if (overviewScrollbar && overview) { |
|
|
|
overviewScrollbar.update(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const interruptDom = document.getElementById("interrupt"); |
|
|
|
if (interrupt && interruptDom) { |
|
|
|
interrupt.update(); |
|
|
|
|
|
|
|
} |
|
|
|
}) |
|
|
|
useEffect(() => { |
|
|
|
const maxCombinedValue = mockData?.reduce((max, item) => { |
|
|
|
const combinedMax = Math.max(item.alarmCount, item.dealAlarmCount); |
|
|
|
if (combinedMax > max) { |
|
|
|
return combinedMax; |
|
|
|
} |
|
|
|
return max; |
|
|
|
}, -Infinity) |
|
|
|
const bigD = Math.ceil(maxCombinedValue / 50) * 50 |
|
|
|
50, 40, 30, 20, 10, 0 |
|
|
|
setXData([bigD, (bigD - bigD / 5), (bigD - bigD * 2 / 5), (bigD - bigD * 3 / 5), (bigD - bigD * 4 / 5), 0, (bigD - bigD * 4 / 5), (bigD - bigD * 3 / 5), (bigD - bigD * 2 / 5), (bigD - bigD / 5), bigD]) |
|
|
|
setBiggest(bigD) |
|
|
|
}, []) |
|
|
|
// const mockData=[ |
|
|
|
// {id: 1,name: '测试结构物测试结构物',alarmCount: 200,dealAlarmCount: 23}, |
|
|
|
// {id: 2,name: '测试结构物2',alarmCount: 300,dealAlarmCount: 22}, |
|
|
|
// {id: 3,name: '测试结构物3',alarmCount: 140,dealAlarmCount: 21}, |
|
|
|
// {id: 4,name: '测试结构物4',alarmCount: 120,dealAlarmCount: 23}, |
|
|
|
// {id: 5,name: '测试结构物5',alarmCount: 110,dealAlarmCount: 22}, |
|
|
|
// {id: 6,name: '测试结构物6',alarmCount: 109,dealAlarmCount: 21}, |
|
|
|
// {id: 7,name: '测试结构物7',alarmCount: 100,dealAlarmCount: 23}, |
|
|
|
// {id: 8,name: '测试结构物8',alarmCount: 99,dealAlarmCount: 22}, |
|
|
|
// {id: 9,name: '测试结构物9',alarmCount: 98,dealAlarmCount: 21}, |
|
|
|
// {id: 10,name: '测试结构物10',alarmCount: 97,dealAlarmCount: 23}, |
|
|
|
// {id: 11,name: '测试结构物11',alarmCount: 96,dealAlarmCount: 22}, |
|
|
|
// {id: 12,name: '测试结构物12',alarmCount: 95,dealAlarmCount: 21}, |
|
|
|
// {id: 13,name: '测试结构物13',alarmCount: 100,dealAlarmCount: 23}, |
|
|
|
// {id: 14,name: '测试结构物14',alarmCount: 49,dealAlarmCount: 22}, |
|
|
|
// {id: 15,name: '测试结构物15',alarmCount: 48,dealAlarmCount: 21}, |
|
|
|
// {id: 16,name: '测试结构物16',alarmCount: 47,dealAlarmCount: 23}, |
|
|
|
// {id: 17,name: '测试结构物17',alarmCount: 46,dealAlarmCount: 22}, |
|
|
|
// {id: 18,name: '测试结构物18',alarmCount: 45,dealAlarmCount: 21}, |
|
|
|
// {id: 19,name: '测试结构物19',alarmCount: 30,dealAlarmCount: 22}, |
|
|
|
// {id: 20,name: '测试结构物20',alarmCount: 29,dealAlarmCount: 21}, |
|
|
|
// {id: 21,name: '测试结构物21',alarmCount: 28,dealAlarmCount: 23}, |
|
|
|
// {id: 22,name: '测试结构物22',alarmCount: 27,dealAlarmCount: 22}, |
|
|
|
// {id: 23,name: '测试结构物23',alarmCount: 26,dealAlarmCount: 21}, |
|
|
|
// ] |
|
|
|
useEffect(() => { |
|
|
|
if (mockData && mockData.length > 3 && mockData.length < 21) { |
|
|
|
const newArray = mockData.slice(3) |
|
|
|
setAlarmData(newArray) |
|
|
|
} |
|
|
|
if (mockData && mockData.length > 21) { |
|
|
|
//数据大于20的话,取前20 |
|
|
|
const newArray = mockData.slice(3, 20) |
|
|
|
setAlarmData(newArray) |
|
|
|
} |
|
|
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let statisticOnline = (groupId) => { |
|
|
|
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { |
|
|
|
console.log(res); |
|
|
@ -92,20 +183,6 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleRow (record, index) {//斑马条纹 |
|
|
|
// 给偶数行设置斑马纹 |
|
|
|
if (index % 2 === 0) { |
|
|
|
return { |
|
|
|
style: { |
|
|
|
background: '#F6F9FF', |
|
|
|
} |
|
|
|
}; |
|
|
|
} else { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return ( |
|
|
|
<div className='project-group'> |
|
|
|
<Header match={match} history={history} /> |
|
|
@ -120,9 +197,37 @@ 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 - 170 }}> |
|
|
|
{[{ index: 1, name: 'wweq', time: 20 }, |
|
|
|
{ index: 2, name: 'wweq', time: 20 }, |
|
|
|
{ index: 3, name: 'wweq', time: 20 }, |
|
|
|
{ index: 4, name: 'wweq', time: 20 }, |
|
|
|
{ index: 5, name: 'wweq', time: 20 }, |
|
|
|
{ index: 6, name: 'wweq', time: 20 }, |
|
|
|
{ index: 7, name: 'wweq', time: 20 }, |
|
|
|
{ index: 1, name: 'wweq', time: 20 }, |
|
|
|
{ index: 1, name: 'wweq', time: 20 }, |
|
|
|
{ index: 1, name: 'wweq', time: 20 }].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 == 1 ? "#F6F9FF" : '', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#2C66F3', fontWeight: 400 }}>{c.name}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{title}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#F33B3B', fontWeight: 400 }}>{c.offnum + '/' + c.totnum}</div> |
|
|
|
</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
</div> |
|
|
@ -199,11 +304,92 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
|
|
|
|
</div> |
|
|
|
<div style={{ width: '100%', height: "calc(55% - 24px)", display: 'flex', marginTop: 24 }}> |
|
|
|
<Card title='告警排名TOP20' style={{ width: "calc(50% - 8px)", height: "100%", marginRight: 16, }}> |
|
|
|
<div style={{ height: '100%' }}> |
|
|
|
|
|
|
|
|
|
|
|
</div> |
|
|
|
<Card title='告警排名TOP20' style={{ |
|
|
|
width: "calc(50% - 8px)", height: "100%", marginRight: 16 |
|
|
|
}} > |
|
|
|
{mockData && mockData.length > 0 ? (<div style={{ height: '100%' }}> |
|
|
|
<div style={{ display: "flex", justifyContent: 'flex-end' }}> |
|
|
|
<div style={{ display: "flex", alignItems: 'center' }}> |
|
|
|
<div class='alarmDiv'></div><div class='alarm'>超阈值个数</div> |
|
|
|
</div> |
|
|
|
<div style={{ display: "flex", alignItems: 'center' }}> |
|
|
|
<div class='dealAlarmCountDiv'></div><div class='alarmCount'>手动恢复个数</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div id='alarmRank' style={{ height: clientHeight * 0.55 - 150, position: 'relative' }}> |
|
|
|
{mockData && mockData[0] ? (<div style={{ display: 'flex', marginTop: 15, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<img src='/assets/images/projectGroup/first.png'></img> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{mockData[0]?.name?.length > 5 ? <Tooltip content={mockData[0]?.name}>{mockData[0]?.name.substring(0, 5) + '...'}</Tooltip> : mockData[0]?.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width: (mockData[0].alarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width: (mockData[0].dealAlarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div>) : '' |
|
|
|
} |
|
|
|
{mockData && mockData[1] ? (<div style={{ display: 'flex', marginTop: 5, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<img src='/assets/images/projectGroup/second.png'></img> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{mockData[1]?.name?.length > 5 ? <Tooltip content={mockData[1]?.name}>{mockData[1]?.name.substring(0, 5) + '...'}</Tooltip> : mockData[0]?.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width: (mockData[1].alarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width: (mockData[1].dealAlarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div>) : '' |
|
|
|
} |
|
|
|
{mockData && mockData[2] ? (<div style={{ display: 'flex', marginTop: 5, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<img src='/assets/images/projectGroup/third.png'></img> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{mockData[2]?.name?.length > 5 ? <Tooltip content={mockData[2]?.name}>{mockData[2]?.name.substring(0, 5) + '...'}</Tooltip> : mockData[0]?.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width: (mockData[2].alarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width: (mockData[2].dealAlarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div>) : '' |
|
|
|
} |
|
|
|
{alarmData && alarmData.length ? |
|
|
|
alarmData.map((item, index) => { |
|
|
|
return (<div style={{ display: 'flex', marginTop: 5, alignItems: 'center' }}> |
|
|
|
<div class='rankDiv'> |
|
|
|
<span>{index + 4}</span> |
|
|
|
</div> |
|
|
|
<div class='structDiv'>{item.name?.length > 5 ? <Tooltip content={item.name}>{item.name.substring(0, 5) + '...'}</Tooltip> : item.name}</div> |
|
|
|
<div class='barChartDiv'> |
|
|
|
<div style={{ width: '50%', display: 'flex', justifyContent: 'flex-end' }}> |
|
|
|
<div class='alarms' style={{ width: (item.alarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
<div style={{ width: '50%', display: 'flex', }}> |
|
|
|
<div class='dealAlarms' style={{ width: (item.dealAlarmCount / biggest) * 100 || '%', height: '100%' }}></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div>) |
|
|
|
} |
|
|
|
) |
|
|
|
: '' |
|
|
|
} |
|
|
|
</div> |
|
|
|
<div class="scale"> |
|
|
|
{xData?.map(item => { |
|
|
|
return <div >{item}</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|
</div>) : ''} |
|
|
|
</Card> |
|
|
|
<Card title='中断排名' style={{ width: "calc(50% - 8px)", height: "100%", }}> |
|
|
|
<div style={{ height: '100%', fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400, fontSize: 14, }}> |
|
|
@ -212,7 +398,7 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
<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 }}> |
|
|
|
<div id="interrupt" style={{ position: 'relative', height: clientHeight * 0.55 - 170 }}> |
|
|
|
{InterruptRank?.map((c, index) => { |
|
|
|
let title |
|
|
|
if (c.offline) { |
|
|
@ -221,10 +407,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou |
|
|
|
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> |
|
|
|
return <div style={{ display: "flex", background: index % 2 == 1 ? "#F6F9FF" : '', height: 40, alignItems: 'center' }}> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#2C66F3', fontWeight: 400 }}>{c.name}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{title}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%' }}>{c.offnum + '/' + c.totnum}</div> |
|
|
|
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#F33B3B', fontWeight: 400 }}>{c.offnum + '/' + c.totnum}</div> |
|
|
|
</div> |
|
|
|
})} |
|
|
|
</div> |
|
|
|