wenlele
9 months ago
13 changed files with 913 additions and 4 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,74 @@ |
|||||
|
//领导驾驶舱
|
||||
|
'use strict'; |
||||
|
import React, { useEffect, useState } from 'react' |
||||
|
import { Spin, Popconfirm, message, Button, Input } from 'antd'; |
||||
|
import { connect } from 'react-redux'; |
||||
|
import ProTable from '@ant-design/pro-table'; |
||||
|
import moment from 'moment'; |
||||
|
import '../style.less' |
||||
|
|
||||
|
|
||||
|
import Left from './left'; |
||||
|
import Right from './right'; |
||||
|
|
||||
|
|
||||
|
const Leader = ({ actions, dispatch, globalTab, }) => { |
||||
|
|
||||
|
|
||||
|
const { bigScreen } = actions |
||||
|
const [centerData, setCenterData] = useState({}) |
||||
|
|
||||
|
const centerFontStyle = { |
||||
|
fontSize: '1.2rem', |
||||
|
fontStyle: 'italic', |
||||
|
color: '#E5F1FF', |
||||
|
fontFamily: '思源黑体', |
||||
|
|
||||
|
} |
||||
|
const centerNumFontStyle = { |
||||
|
fontSize: '2rem', |
||||
|
// color:'#6eece9',
|
||||
|
fontStyle: 'italic', |
||||
|
paddingLeft: '0.5rem' |
||||
|
} |
||||
|
useEffect(() => { |
||||
|
const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject |
||||
|
dispatch(bigScreen.getCenterData({ projectId: structArr.toString() })).then(res => { |
||||
|
if (res.success) { |
||||
|
setCenterData(res.payload.data) |
||||
|
} |
||||
|
}) |
||||
|
}, []) |
||||
|
return <> |
||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', position: 'relative' }}> |
||||
|
<Left></Left> |
||||
|
<Right></Right> |
||||
|
</div> |
||||
|
<div style={{ position: 'absolute', top: '-10rem', left: '27rem', }}> |
||||
|
<img src='/assets/bigScreen/center.webp' style={{ display: 'inline-block', width: '64.47rem', height: '62.3125rem' }}></img> |
||||
|
</div> |
||||
|
<div style={{ position: 'absolute', top: '14.6rem', left: '37rem', }}><span style={{ ...centerFontStyle }}>设备总数</span><span style={{ ...centerNumFontStyle, color: '#6eece9', }}>{centerData.deviceCount}</span></div> |
||||
|
<div style={{ position: 'absolute', top: '10.5rem', left: '45rem', }}><span style={{ ...centerFontStyle }}>发现问题</span><span style={{ ...centerNumFontStyle, color: 'rgb(204 193 84)', }}>{centerData.questions}</span></div> |
||||
|
<div style={{ position: 'absolute', top: '12.5rem', left: '56.5rem', }}><div style={{ ...centerNumFontStyle, height: '2.5rem', color: '#6eece9', textAlign: 'center' }}>{centerData.records}</div> <span style={{ ...centerFontStyle }}>累计巡检数</span></div> |
||||
|
<div style={{ position: 'absolute', top: '10.5rem', left: '67.5rem', }}><span style={{ ...centerFontStyle }}>出具报告数</span><span style={{ ...centerNumFontStyle, color: '#6eece9', }}>{centerData.reportCount}</span></div> |
||||
|
<div style={{ position: 'absolute', top: '14.6rem', left: '75rem', }}><span style={{ ...centerFontStyle }}>处理故障数</span><span style={{ ...centerNumFontStyle, color: 'rgb(47 229 9)', }}>{centerData.handleCount}</span></div> |
||||
|
|
||||
|
</> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
function mapStateToProps (state) { |
||||
|
const { auth, global, device } = state; |
||||
|
return { |
||||
|
clientHeight: global.clientHeight, |
||||
|
actions: global.actions, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(Leader) |
||||
|
|
@ -0,0 +1,484 @@ |
|||||
|
import React, { useEffect, useState } from 'react' |
||||
|
import { Spin, Popconfirm, message, Button, Input } from 'antd' |
||||
|
import { connect } from 'react-redux' |
||||
|
import ProTable from '@ant-design/pro-table' |
||||
|
import moment from 'moment' |
||||
|
import ReactEcharts from 'echarts-for-react' |
||||
|
import PerfectScrollbar from 'perfect-scrollbar' |
||||
|
import '../style.less' |
||||
|
import AutoRollComponent from '../AutoRollComponent' |
||||
|
|
||||
|
let scrollbarLeft |
||||
|
let problems |
||||
|
const Left = props => { |
||||
|
const { dispatch, clientHeight, clientWidth, actions } = props |
||||
|
const [startTime, setStartTime] = useState(moment().startOf('week').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
const [endTime, setEndTime] = useState(moment().endOf('week').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
const [plan, setPlan] = useState(0) |
||||
|
const [done, setDone] = useState(0) |
||||
|
const [cRate, setCRate] = useState([]) //完成率
|
||||
|
const [rRate, setRRate] = useState([]) //修复率
|
||||
|
const [months, setMonths] = useState([]) |
||||
|
const [period, setPeriod] = useState('week') |
||||
|
const [rank,setRank]=useState([]) |
||||
|
const [state, setState] = useState(0) |
||||
|
const [rankCopy,setRankCopy]=useState([])//用于排序(巡检次数)
|
||||
|
const { bigScreen } = actions |
||||
|
// const questFontColor = { color: '#8f7a49' } //有问题的颜色
|
||||
|
const normalFontColor = { color: 'yellow' } //正常的颜色
|
||||
|
useEffect(() => { |
||||
|
scrollbarLeft = new PerfectScrollbar('#left1', { suppressScrollX: true }) |
||||
|
const dom = document.getElementById('left1') |
||||
|
if (dom) { |
||||
|
scrollbarLeft.update() |
||||
|
// dom.scrollTop = 0
|
||||
|
} |
||||
|
// getData()
|
||||
|
queryData() |
||||
|
const months = generateMonthNames() |
||||
|
setMonths(months) |
||||
|
}, []) |
||||
|
useEffect(() => { |
||||
|
getData() |
||||
|
}, [startTime]) |
||||
|
|
||||
|
const queryData = async () => { |
||||
|
let repair = [] |
||||
|
const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject |
||||
|
const sTime = moment().subtract(6, 'months').format('YYYY-MM-DD HH:mm:ss') |
||||
|
const eTime = moment().format('YYYY-MM-DD HH:mm:ss') |
||||
|
// let count={}
|
||||
|
let cRate = [] |
||||
|
for (let i = 5; i >= 0; i--) { |
||||
|
const currentTime = moment() |
||||
|
const startOfMonth = currentTime.subtract(i, 'months').startOf('month') |
||||
|
const startTime = startOfMonth.format('YYYY-MM-DD HH:mm:ss') |
||||
|
const endTime = startOfMonth.endOf('month').format('YYYY-MM-DD HH:mm:ss') |
||||
|
await dispatch(bigScreen.findPatrolRecords({ projectId: structArr.toString(), startTime, endTime })).then(res => { |
||||
|
if (res.success) { |
||||
|
const data = res.payload.data |
||||
|
// count[i] = { plan: data.planCount, done: data.done, rate:((data.done/data.planCount+data.done)*100).toFixed(2) }
|
||||
|
cRate.push( |
||||
|
Number(data.planCount + data.done > 0 ? ((data.done / (data.planCount + data.done)) * 100).toFixed(2) : 0) |
||||
|
) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
setCRate(cRate) |
||||
|
dispatch(bigScreen.findPatrolRate({ projectId: structArr.toString(), startTime: sTime, endTime: eTime })).then( |
||||
|
res => { |
||||
|
if (res.success) { |
||||
|
const data = res.payload.data |
||||
|
if (data && data.length) { |
||||
|
const repairObject = {} |
||||
|
for (let i = 5; i >=0; i--) { |
||||
|
const currentDate = moment().subtract(i, 'months') |
||||
|
const month = currentDate.month() + 1 |
||||
|
const year = currentDate.year() |
||||
|
repairObject[`${year}-${month}`] = { done: 0, quests: 0, ratio: 0 } |
||||
|
} |
||||
|
data.forEach(item => { |
||||
|
const createTime = moment(item.patrolRecordIssueHandles[0].createTime) |
||||
|
const month = createTime.month()+1 |
||||
|
const year = createTime.year() |
||||
|
const state = item.patrolRecordIssueHandles[0].state |
||||
|
if (state === 6) { |
||||
|
repairObject[`${year}-${month}`].done++ |
||||
|
} |
||||
|
|
||||
|
repairObject[`${year}-${month}`].quests++ |
||||
|
}) |
||||
|
//计算比例
|
||||
|
Object.values(repairObject).forEach(item => { |
||||
|
console.log('item',item) |
||||
|
repair.push(item.quests === 0 ? 0 : Number((item.done / item.quests * 100).toFixed(2))); |
||||
|
}); |
||||
|
console.log('x1111',repair,cRate) |
||||
|
setRRate(repair) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
dispatch(bigScreen.countByProject({ projectId: structArr.toString()})).then(res=>{ |
||||
|
if(res.success){ |
||||
|
//[{},{},{},{},{},{},{},{}]||
|
||||
|
// [{id:1,issueHandleCount:1,patrolRecordCount:2},
|
||||
|
// {id:1,issueHandleCount:2,patrolRecordCount:3},
|
||||
|
// {id:1,issueHandleCount:3,patrolRecordCount:2},
|
||||
|
// {id:1,issueHandleCount:6,patrolRecordCount:4},
|
||||
|
// {id:1,issueHandleCount:7,patrolRecordCount:5},
|
||||
|
// {id:1,issueHandleCount:10,patrolRecordCount:6},
|
||||
|
// {id:1,issueHandleCount:11,patrolRecordCount:7},
|
||||
|
// {id:1,issueHandleCount:19,patrolRecordCount:9}]
|
||||
|
const data=res.payload.data |
||||
|
if(data.length>4){ |
||||
|
let problemstop = 0 |
||||
|
let problemsId = document.getElementById('left1'); |
||||
|
if (problems) clearInterval(problems) |
||||
|
if (problemsId) { |
||||
|
let problems; |
||||
|
let problemstop = 0; |
||||
|
|
||||
|
function problemstart() { |
||||
|
problems = setInterval(() => { |
||||
|
problemstop += 5; |
||||
|
problemsId.scrollTop = problemstop; |
||||
|
if (problemsId.scrollTop >= (problemsId.scrollHeight - 90) / 2) { |
||||
|
problemstop = 0; |
||||
|
problemsId.scrollTop = problemstop; |
||||
|
} |
||||
|
}, 500); |
||||
|
|
||||
|
problemsId.onmouseover = () => clearInterval(problems); |
||||
|
} |
||||
|
|
||||
|
problemsId.onmouseout = () => problemstart(); |
||||
|
|
||||
|
setTimeout(problemstart, 1000); |
||||
|
} |
||||
|
} |
||||
|
if(data.length>10){ |
||||
|
setRank(data.slice(0,10)) |
||||
|
}else{ |
||||
|
setRank(data) |
||||
|
|
||||
|
} |
||||
|
setRankCopy(data) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
function generateMonthNames() { |
||||
|
const currentTime = moment() |
||||
|
const monthNames = [] |
||||
|
for (let i = 0; i < 6; i++) { |
||||
|
const currentMonth = currentTime.clone().subtract(i, 'months').format('MMMM') |
||||
|
monthNames.unshift(currentMonth) |
||||
|
} |
||||
|
return monthNames |
||||
|
} |
||||
|
|
||||
|
const getData = () => { |
||||
|
const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject |
||||
|
dispatch(bigScreen.findPatrolRecords({ projectId: structArr.toString(), startTime, endTime })).then(res => { |
||||
|
if (res.success) { |
||||
|
const data = res.payload.data |
||||
|
setPlan(data.planCount) |
||||
|
setDone(data.done) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
const selectTime = time => { |
||||
|
if (time === 'week') { |
||||
|
setPeriod('week') |
||||
|
setStartTime(moment().startOf('week').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
setEndTime(moment().endOf('week').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
} else { |
||||
|
setPeriod('month') |
||||
|
setStartTime(moment().startOf('month').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
setEndTime(moment().endOf('month').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const topClick=(e)=>{ |
||||
|
switch (e) { |
||||
|
case 'perBottom': |
||||
|
const rs=rankCopy.sort((a,b)=>b.patrolRecordCount-a.patrolRecordCount) |
||||
|
if(rs.length>10){ |
||||
|
setRank(rs.slice(0,10)) |
||||
|
}else{ |
||||
|
setRank(rs) |
||||
|
} |
||||
|
setState(1) |
||||
|
break; |
||||
|
case 'perTop': |
||||
|
const rs1=rankCopy.sort((a,b)=>a.patrolRecordCount-b.patrolRecordCount) |
||||
|
if(rs1.length>10){ |
||||
|
setRank(rs1.slice(0,10)) |
||||
|
}else{ |
||||
|
setRank(rs1) |
||||
|
} |
||||
|
setState(0) |
||||
|
break; |
||||
|
case 'timeBottom': |
||||
|
const rs2=rankCopy.sort((a,b)=>b.issueHandleCount-a.issueHandleCount) |
||||
|
if(rs2.length>10){ |
||||
|
setRank(rs2.slice(0,10)) |
||||
|
}else{ |
||||
|
setRank(rs2) |
||||
|
} |
||||
|
setState(3) |
||||
|
break; |
||||
|
case 'timeTop': |
||||
|
const rs3=rankCopy.sort((a,b)=>a.issueHandleCount-b.issueHandleCount) |
||||
|
if(rs3.length>10){ |
||||
|
setRank(rs3.slice(0,10)) |
||||
|
}else{ |
||||
|
setRank(rs3) |
||||
|
} |
||||
|
setState(2) |
||||
|
break; |
||||
|
default: |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
{/* 左一 */} |
||||
|
{/**backgroundImage: 'linear-gradient(269deg, #000080ff 0%, #1a0080ff 58%, #3d0080ff 100%)' */} |
||||
|
<div> |
||||
|
<div style={{ position: 'relative' }} className='contanier1'> |
||||
|
<div |
||||
|
style={{ |
||||
|
display: 'flex', |
||||
|
justifyContent: 'space-between', |
||||
|
height: '2.6875rem', |
||||
|
background: 'url(/assets/bigScreen/cardHeader.png)', |
||||
|
backgroundSize: '100% 100%', |
||||
|
backgroundRepeat: 'no-repeat', |
||||
|
}}> |
||||
|
<div className='title'>巡检数据统计</div> |
||||
|
<div className='monthOrWeek'> |
||||
|
<span |
||||
|
style={{ color: period === 'week' ? '#6EECE9' : '#8FCFFF' }} |
||||
|
onClick={() => { |
||||
|
selectTime('week') |
||||
|
}}> |
||||
|
周 |
||||
|
</span> |
||||
|
| |
||||
|
<span |
||||
|
style={{ color: period === 'month' ? '#6EECE9' : '#8FCFFF' }} |
||||
|
onClick={() => { |
||||
|
selectTime('month') |
||||
|
}}> |
||||
|
月 |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
style={{ |
||||
|
width: '26.3125rem', |
||||
|
height: '9.5625rem', |
||||
|
display: 'flex', |
||||
|
justifyContent: 'center', |
||||
|
alignItems: 'center', |
||||
|
}}> |
||||
|
<img src='/assets/bigScreen/doneRate.png'></img> |
||||
|
</div> |
||||
|
<div className='rate' style={{ bottom: '6.5125rem', left: '11.875rem' }}> |
||||
|
{`${plan > 0 ? ((done / done + plan) * 100).toFixed(2) : 0}%`} |
||||
|
</div> |
||||
|
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '.5rem' }}>当前巡检完成率</div> |
||||
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
||||
|
<div |
||||
|
style={{ |
||||
|
background: 'url(/assets/bigScreen/plan.png)', |
||||
|
width: '10.375rem', |
||||
|
height: '3.625rem', |
||||
|
position: 'relative', |
||||
|
marginLeft: '.7rem', |
||||
|
backgroundSize: '100% 100%', |
||||
|
}}> |
||||
|
<div |
||||
|
style={{ |
||||
|
position: 'absolute', |
||||
|
bottom: '1.7rem', |
||||
|
right: '2.35rem', |
||||
|
width: '3.75rem', |
||||
|
height: '.75rem', |
||||
|
textAlign: 'center', |
||||
|
}} |
||||
|
className='plan'> |
||||
|
计划巡检数 |
||||
|
</div> |
||||
|
<div |
||||
|
style={{ |
||||
|
position: 'absolute', |
||||
|
bottom: '.1044rem', |
||||
|
right: '2.35rem', |
||||
|
width: '3.75rem', |
||||
|
height: '1.375rem', |
||||
|
textAlign: 'center', |
||||
|
}} |
||||
|
className='number'> |
||||
|
{plan} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
style={{ |
||||
|
background: 'url(/assets/bigScreen/plan.png)', |
||||
|
width: '10.375rem', |
||||
|
height: '3.625rem', |
||||
|
position: 'relative', |
||||
|
marginLeft: '.7rem', |
||||
|
backgroundSize: '100% 100%', |
||||
|
marginRight: '.625rem', |
||||
|
}}> |
||||
|
<div |
||||
|
style={{ |
||||
|
position: 'absolute', |
||||
|
bottom: '1.7rem', |
||||
|
right: '1.75rem', |
||||
|
width: '4.75rem', |
||||
|
height: '.75rem', |
||||
|
textAlign: 'center', |
||||
|
}} |
||||
|
className='plan'> |
||||
|
已完成巡检数 |
||||
|
</div> |
||||
|
<div |
||||
|
style={{ |
||||
|
position: 'absolute', |
||||
|
bottom: '.1044rem', |
||||
|
right: '1.75rem', |
||||
|
width: '4.75rem', |
||||
|
height: '1.375rem', |
||||
|
textAlign: 'center', |
||||
|
}} |
||||
|
className='number'> |
||||
|
{done} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
{/* 左二 */} |
||||
|
<div className='contanier' style={{ height: '17.8125rem' }}> |
||||
|
<div |
||||
|
style={{ |
||||
|
display: 'flex', |
||||
|
justifyContent: 'space-between', |
||||
|
height: '2.5rem', |
||||
|
background: 'url(/assets/bigScreen/cardHeader.png)', |
||||
|
backgroundSize: '100% 100%', |
||||
|
backgroundRepeat: 'no-repeat', |
||||
|
}}> |
||||
|
<div className='title'>巡检成效评估</div> |
||||
|
{/* <div className='monthOrWeek'>{'更多' + '>>'}</div> */} |
||||
|
</div> |
||||
|
<ReactEcharts |
||||
|
style={{ height: '13.4375rem', width: '25.2662rem' }} |
||||
|
option={{ |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
axisPointer: { |
||||
|
type: 'shadow', |
||||
|
}, |
||||
|
}, |
||||
|
legend: { |
||||
|
right: 0, |
||||
|
textStyle: { color: '#CCE6FF' }, |
||||
|
}, |
||||
|
grid: { |
||||
|
left: '3%', |
||||
|
right: '4%', |
||||
|
bottom: '3%', |
||||
|
containLabel: true, |
||||
|
}, |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
type: 'category', |
||||
|
data: months, |
||||
|
}, |
||||
|
], |
||||
|
yAxis: [ |
||||
|
{ |
||||
|
type: 'value', |
||||
|
name: '单位%', |
||||
|
}, |
||||
|
], |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '巡检完成率', |
||||
|
nameTextStyle: { |
||||
|
color: ' #CCE6FF', |
||||
|
fontSize: 14, |
||||
|
fontFamily: 'SourceHanSansCN-Medium', |
||||
|
}, |
||||
|
type: 'bar', |
||||
|
stack: 'Search Engine', |
||||
|
// emphasis: {
|
||||
|
// focus: 'series'
|
||||
|
// },
|
||||
|
data: cRate, |
||||
|
}, |
||||
|
{ |
||||
|
name: '故障修复率', |
||||
|
type: 'bar', |
||||
|
stack: 'Search Engine', |
||||
|
// emphasis: {
|
||||
|
// focus: 'series'
|
||||
|
// },
|
||||
|
data: rRate, |
||||
|
}, |
||||
|
], |
||||
|
}}></ReactEcharts> |
||||
|
</div> |
||||
|
{/* 左三 */} |
||||
|
<div className='contanier'> |
||||
|
<div |
||||
|
style={{ |
||||
|
display: 'flex', |
||||
|
justifyContent: 'space-between', |
||||
|
height: '2.5rem', |
||||
|
background: 'url(/assets/bigScreen/cardHeader.png)', |
||||
|
backgroundSize: '100% 100%', |
||||
|
backgroundRepeat: 'no-repeat', |
||||
|
}}> |
||||
|
<div className='title'>巡检次数排名</div> |
||||
|
</div> |
||||
|
<div className='header' style={{ width: '24.3125rem' }}> |
||||
|
<div className='threeHeaderFontStyle'>序号</div> |
||||
|
<div className='threeHeaderFontStyle'>结构物</div> |
||||
|
<div className='threeHeaderFontStyle' style={{position:'relative'}}>巡检次数 |
||||
|
<i class="angle_top" id={state==0?'angleSelected':null} onClick={()=>topClick('perTop')}></i> |
||||
|
<i id={state==1?'angleSelected':null} class="angle_bottom" onClick={()=>topClick('perBottom')}></i> |
||||
|
</div> |
||||
|
<div className='threeHeaderFontStyle'style={{position:'relative'}}>问题个数 |
||||
|
<i class="angle_top" id={state==2?'angleSelected':null} onClick={()=>topClick('timeTop')}></i> |
||||
|
<i id={state==3?'angleSelected':null} class="angle_bottom" onClick={()=>topClick('timeBottom')}></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id='left1' style={{ width: '25.8125rem', height: '12rem', position: 'relative' }}> |
||||
|
|
||||
|
{rank.map((item,index)=>( |
||||
|
<div className='thridCardItem' style={{ width: '24.3125rem' }}> |
||||
|
<div className='index1'> |
||||
|
<div>{index+1}</div> |
||||
|
</div> |
||||
|
<div className='name1' title={item.name}>{item.name}</div> |
||||
|
<div className='num1'>{item.patrolRecordCount}</div> |
||||
|
<div className='quests1' style={{ ...normalFontColor }}> |
||||
|
{item.issueHandleCount} |
||||
|
</div> |
||||
|
</div> |
||||
|
))} |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { auth, global } = state |
||||
|
return { |
||||
|
clientHeight: global.clientHeight, |
||||
|
clientWidth: global.clientWidth, |
||||
|
actions: global.actions, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(Left) |
@ -0,0 +1,316 @@ |
|||||
|
import React, { useEffect, useState } from 'react' |
||||
|
import { Spin, Popconfirm, message, Button, Input, Progress } from 'antd' |
||||
|
import { connect } from 'react-redux' |
||||
|
import ProTable from '@ant-design/pro-table' |
||||
|
import moment from 'moment' |
||||
|
import ReactEcharts from 'echarts-for-react' |
||||
|
import '../style.less' |
||||
|
import AutoRollComponent from '../AutoRollComponent' |
||||
|
import PerfectScrollbar from 'perfect-scrollbar' |
||||
|
|
||||
|
let scrollbar |
||||
|
let diviceScrollbar |
||||
|
let rank |
||||
|
let device |
||||
|
const Right = props => { |
||||
|
const { dispatch, clientHeight, clientWidth, actions } = props |
||||
|
const { bigScreen } = actions |
||||
|
const questFontColor = { color: '#8f7a49' } //有问题的颜色
|
||||
|
const normalFontColor = { color: 'rgba(33, 106, 167)' } //正常的颜色
|
||||
|
const [deviceLists, setDeviceLists] = useState([]) |
||||
|
const [underGuarantee, setUnderGuarantee] = useState(0) |
||||
|
const [devicescount, setDevicesCount] = useState(0) |
||||
|
const [period, setPeriod] = useState('threeMonths') |
||||
|
const [startTime, setStartTime] = useState(moment().subtract(3, 'months').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
const [endTime, setEndTime] = useState(moment().format('YYYY-MM-DD HH:mm:ss')) |
||||
|
const [projectName, setProjectName] = useState([]) |
||||
|
const [historyFaults, setHistoryFaults] = useState([]) |
||||
|
const [historyFaultsDone, setHistoryFaultsDone] = useState([]) |
||||
|
const [rankData, setRankData] = useState([]) |
||||
|
|
||||
|
//历史故障切换时间变化
|
||||
|
useEffect(() => { |
||||
|
const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject |
||||
|
dispatch(bigScreen.getHistoricalFaults({ projectId: structArr.toString(), startTime, endTime })).then(res => { |
||||
|
if (res.success) { |
||||
|
const data = res.payload.data |
||||
|
let nameArr = [] |
||||
|
let historyFaults = [] |
||||
|
let historyFaultsDone = [] |
||||
|
data.map(item => { |
||||
|
nameArr.push(item.name) |
||||
|
historyFaults.push(Number(item.count)) |
||||
|
historyFaultsDone.push(Number(item.bcount)) |
||||
|
}) |
||||
|
setProjectName(nameArr) |
||||
|
setHistoryFaults(historyFaults) |
||||
|
setHistoryFaultsDone(historyFaultsDone) |
||||
|
|
||||
|
} |
||||
|
}) |
||||
|
}, [period]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
scrollbar = new PerfectScrollbar('#right3', { suppressScrollX: true }) |
||||
|
const dom = document.getElementById('right3') |
||||
|
if (dom) { |
||||
|
scrollbar.update() |
||||
|
// dom.scrollTop = 0
|
||||
|
} |
||||
|
diviceScrollbar = new PerfectScrollbar('#right1', { suppressScrollX: true }) |
||||
|
const doms = document.getElementById('right1') |
||||
|
if (doms) { |
||||
|
diviceScrollbar.update() |
||||
|
// dom.scrollTop = 0
|
||||
|
} |
||||
|
getData() |
||||
|
}, []) |
||||
|
|
||||
|
const getData = () => { |
||||
|
const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject |
||||
|
dispatch(bigScreen.getDevices({ projectId: structArr.toString() })).then(res => { |
||||
|
if (res.success) { |
||||
|
const data = res.payload.data |
||||
|
setDeviceLists(data.rs) |
||||
|
setUnderGuarantee(data.underGuarantee) |
||||
|
setDevicesCount(data.count) |
||||
|
if(data.length>2){ |
||||
|
let problemstops = 0 |
||||
|
let problemsId = document.getElementById('right1'); |
||||
|
if (device) clearInterval(device) |
||||
|
if (problemsId) { |
||||
|
function problemstart () { |
||||
|
device = setInterval(() => { |
||||
|
problemstops += 5 |
||||
|
problemsId.scrollTop = problemstops |
||||
|
if (problemsId.scrollTop >= problemsId.scrollHeight / 2) problemstops = 0, problemsId.scrollTop = problemstops |
||||
|
}, 500); |
||||
|
problemsId.onmouseover = () => clearInterval(device) |
||||
|
} |
||||
|
problemsId.onmouseout = () => problemstart() |
||||
|
setTimeout(problemstart(), 1000); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
dispatch(bigScreen.getFaultsRank({ projectId: structArr.toString() })).then(res => { |
||||
|
if (res.success) { |
||||
|
//[{},{},{},{},{},{},{},{},{}] ||
|
||||
|
const data = res.payload.data |
||||
|
setRankData(data) |
||||
|
if(data.length>4){ |
||||
|
let problemstop = 0 |
||||
|
let problemsId = document.getElementById('right3'); |
||||
|
if (rank) clearInterval(rank) |
||||
|
if (problemsId) { |
||||
|
function problemstart () { |
||||
|
rank = setInterval(() => { |
||||
|
problemstop += 5 |
||||
|
problemsId.scrollTop = problemstop |
||||
|
if (problemsId.scrollTop >= (problemsId.scrollHeight-90) / 2) problemstop = 0, problemsId.scrollTop = problemstop |
||||
|
}, 500); |
||||
|
problemsId.onmouseover = () => clearInterval(rank) |
||||
|
} |
||||
|
problemsId.onmouseout = () => problemstart() |
||||
|
setTimeout(problemstart(), 1000); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
const selectTime = time => { |
||||
|
if (time === 'threeMonths') { |
||||
|
setPeriod('threeMonths') |
||||
|
setStartTime(moment().subtract(3, 'months').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
} else if (time === 'halfYear') { |
||||
|
setPeriod('halfYear') |
||||
|
setStartTime(moment().subtract(6, 'months').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
} else { |
||||
|
setPeriod('oneYear') |
||||
|
setStartTime(moment().subtract(12, 'months').format('YYYY-MM-DD HH:mm:ss')) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<div> |
||||
|
{/* 右一 */} |
||||
|
<div className='contanier1'> |
||||
|
<div className='cardHeader'> |
||||
|
<div className='title'>设备数据总览</div> |
||||
|
<div className='monthOrWeek'>{'更多' + '>>'}</div> |
||||
|
</div> |
||||
|
<div className='right1bg'> |
||||
|
<img src='/assets/bigScreen/qc.png'></img> |
||||
|
</div> |
||||
|
<div className='content'> |
||||
|
<div> |
||||
|
<div className='qcNum numFontStyle'> |
||||
|
{underGuarantee} <span className='ge'>个</span> |
||||
|
</div> |
||||
|
<div className='qcDescribe describeFontStyle'>质保数</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<div className='centerNum'> |
||||
|
{(((devicescount - underGuarantee) / devicescount) * 100).toFixed(0) || 0}% |
||||
|
</div> |
||||
|
<div className='pDescribe pLocation'>质保期比例</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<div className='deviceNum numFontStyle'> |
||||
|
{devicescount} <span className='ge'>个</span> |
||||
|
</div> |
||||
|
<div className='deviceDescribe describeFontStyle'>设备总数</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id='right1' style={{width:'25.25rem',height:'9.2875rem',position:'relative'}}> |
||||
|
{deviceLists?.map(item => ( |
||||
|
<div className='percent'> |
||||
|
{/* <img src='/assets/bigScreen/arrow.png'></img> */} |
||||
|
<div className='describe'> {item.type}</div> |
||||
|
<Progress |
||||
|
format={percent => (percent === 100 ? '100%' : `${percent}`)} |
||||
|
strokeColor={'#6EECE9'} |
||||
|
trailColor={'#0B4A7A'} |
||||
|
percent={(item.count / devicescount).toFixed(2) * 100} |
||||
|
/> |
||||
|
</div> |
||||
|
))} |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
{/* 右2 */} |
||||
|
<div className='contanier' style={{ height: '17.8125rem' }}> |
||||
|
<div className='cardHeader'> |
||||
|
<div className='title'>历史故障统计</div> |
||||
|
<div className='monthOrWeek'> |
||||
|
<span |
||||
|
style={{ color: period === 'threeMonths' ? '#6EECE9' : '#8FCFFF' }} |
||||
|
onClick={() => { |
||||
|
selectTime('threeMonths') |
||||
|
}}> |
||||
|
三个月 |
||||
|
</span> |
||||
|
| |
||||
|
<span |
||||
|
style={{ color: period === 'halfYear' ? '#6EECE9' : '#8FCFFF' }} |
||||
|
onClick={() => { |
||||
|
selectTime('halfYear') |
||||
|
}}> |
||||
|
{' '} |
||||
|
半年 |
||||
|
</span> |
||||
|
| |
||||
|
<span |
||||
|
style={{ color: period === 'oneYear' ? '#6EECE9' : '#8FCFFF' }} |
||||
|
onClick={() => { |
||||
|
selectTime('oneYear') |
||||
|
}}> |
||||
|
{' '} |
||||
|
一年 |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
{projectName.length ? ( |
||||
|
<ReactEcharts |
||||
|
style={{ height: '13.4375rem', width: '25.2662rem' }} |
||||
|
option={{ |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
axisPointer: { |
||||
|
type: 'shadow', |
||||
|
}, |
||||
|
}, |
||||
|
legend: { |
||||
|
right: 0, |
||||
|
textStyle: { color: '#CCE6FF' }, |
||||
|
}, |
||||
|
grid: { |
||||
|
left: '3%', |
||||
|
right: '4%', |
||||
|
bottom: '3%', |
||||
|
containLabel: true, |
||||
|
}, |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
type: 'category', |
||||
|
data: projectName, |
||||
|
}, |
||||
|
], |
||||
|
yAxis: [ |
||||
|
{ |
||||
|
type: 'value', |
||||
|
name: '单位次', |
||||
|
}, |
||||
|
], |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '故障数', |
||||
|
nameTextStyle: { |
||||
|
color: ' #CCE6FF', |
||||
|
fontSize: 14, |
||||
|
fontFamily: 'SourceHanSansCN-Medium', |
||||
|
}, |
||||
|
type: 'line', |
||||
|
stack: 'Search Engine', |
||||
|
// emphasis: {
|
||||
|
// focus: 'series'
|
||||
|
// },
|
||||
|
data: historyFaults, |
||||
|
}, |
||||
|
{ |
||||
|
name: '已闭环', |
||||
|
type: 'line', |
||||
|
stack: 'Search Engine', |
||||
|
// emphasis: {
|
||||
|
// focus: 'series'
|
||||
|
// },
|
||||
|
data: historyFaultsDone, |
||||
|
}, |
||||
|
], |
||||
|
}}></ReactEcharts> |
||||
|
) : ( |
||||
|
'暂无数据' |
||||
|
)} |
||||
|
</div> |
||||
|
{/*右三 */} |
||||
|
<div className='contanier'> |
||||
|
<div className='cardHeader'> |
||||
|
<div className='title'>设备故障排名</div> |
||||
|
</div> |
||||
|
<div className='header1'> |
||||
|
<div className='threeHeaderFontStyle'>序号</div> |
||||
|
<div className='threeHeaderFontStyle'>设备名称</div> |
||||
|
<div className='threeHeaderFontStyle'>故障发生次数</div> |
||||
|
</div> |
||||
|
<div id='right3' style={{ width: '25.8125rem', height: '12rem', position: 'relative' }}> |
||||
|
{rankData.map((item, index) => ( |
||||
|
<div className='thridCardItem' style={{ width: '24.3125rem' }}> |
||||
|
<div className='index'> |
||||
|
<div>{index + 1}</div> |
||||
|
</div> |
||||
|
<div className='name' title={item.name}>{item.name}</div> |
||||
|
<div className='quests' style={{ ...normalFontColor }}> |
||||
|
{item.count} |
||||
|
</div> |
||||
|
</div> |
||||
|
))} |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function mapStateToProps(state) { |
||||
|
const { auth, global, device } = state |
||||
|
return { |
||||
|
clientHeight: global.clientHeight, |
||||
|
clientWidth: global.clientWidth, |
||||
|
actions: global.actions, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps)(Right) |
Loading…
Reference in new issue