You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

482 lines
16 KiB

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 = 0; i < 6; 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 => {
repair.push(item.quests === 0 ? 0 : Number((item.done / item.quests * 100).toFixed(2)));
});
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>
&nbsp; | &nbsp;
<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)