|
|
@ -1,93 +1,268 @@ |
|
|
|
import React, { useEffect, useState } from 'react' |
|
|
|
import { Spin, Popconfirm, message, Button, Input, Calendar, Col, Radio, Row, Select, Typography } from 'antd' |
|
|
|
import { Spin, Popconfirm, message, Button, Input, Calendar, Col, Radio, Row, Select, Typography, Badge, Tag } 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 PerfectScrollbar from 'perfect-scrollbar' |
|
|
|
import './style.less' |
|
|
|
import AutoRollComponent from '../AutoRollComponent' |
|
|
|
|
|
|
|
|
|
|
|
let scrollbar |
|
|
|
let scrollbarCalendar |
|
|
|
|
|
|
|
const Left = props => { |
|
|
|
const { clientHeight, clientWidth,isFullScreen} = props |
|
|
|
const questFontColor = { color: '#8f7a49' }//有问题的颜色
|
|
|
|
const normalFontColor = { color: 'rgba(33, 106, 167)' }//正常的颜色
|
|
|
|
const { dispatch, actions, clientHeight, clientWidth, isFullScreen } = props |
|
|
|
const questFontColor = { color: '#8f7a49' } //有问题的颜色
|
|
|
|
const normalFontColor = { color: 'rgba(33, 106, 167)' } //正常的颜色
|
|
|
|
const { bigScreen } = actions |
|
|
|
const [dataList, setDataList] = useState([]) |
|
|
|
const [data, setData] = useState([]) |
|
|
|
const [weekData, setWeekData] = useState({}) |
|
|
|
const [month, setMonth] = useState(moment().format('YYYY-MM-DD HH:mm:ss')) |
|
|
|
const [pieData, setPieData] = useState() |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
scrollbarCalendar = new PerfectScrollbar('#calendar', { suppressScrollX: true }) |
|
|
|
const dom = document.getElementById('calendar') |
|
|
|
if (dom) { |
|
|
|
scrollbarCalendar.update() |
|
|
|
dom.scrollTop = 0 |
|
|
|
} |
|
|
|
queryData() |
|
|
|
}, []) |
|
|
|
useEffect(() => { |
|
|
|
getData(moment(month).startOf('month').format('YYYY-MM-DD HH:mm:ss'), |
|
|
|
moment(month).endOf('month').format('YYYY-MM-DD HH:mm:ss')) |
|
|
|
}, [month]) |
|
|
|
const queryData = () => { |
|
|
|
const startTime = moment().startOf('week').format('YYYY-MM-DD HH:mm:ss') |
|
|
|
const endTime = moment().endOf('week').format('YYYY-MM-DD HH:mm:ss') |
|
|
|
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 |
|
|
|
setWeekData(data) |
|
|
|
} |
|
|
|
}) |
|
|
|
dispatch(bigScreen.getSubSystemPatrolAbout({ |
|
|
|
projectId: structArr.toString(), IsbigScreen: 'true', |
|
|
|
STime: moment('1970-01-01').format('YYYY-MM-DD') + ' 00:00:00', |
|
|
|
ETime: moment('2099-12-31').format('YYYY-MM-DD') + ' 23:59:59', |
|
|
|
}) |
|
|
|
).then(res => { |
|
|
|
if (res.success) { |
|
|
|
const data = res.payload.data |
|
|
|
const maxInspectionTimeByPointId = {}; |
|
|
|
data.forEach((item) => { |
|
|
|
const { pointId, inspectionTime } = item; |
|
|
|
if (pointId in maxInspectionTimeByPointId) { |
|
|
|
if (inspectionTime > maxInspectionTimeByPointId[pointId]) { |
|
|
|
maxInspectionTimeByPointId[pointId] = inspectionTime; |
|
|
|
} |
|
|
|
} else { |
|
|
|
maxInspectionTimeByPointId[pointId] = inspectionTime; |
|
|
|
} |
|
|
|
}) |
|
|
|
const filteredData = data.filter((item) => { |
|
|
|
const { pointId, inspectionTime } = item; |
|
|
|
return inspectionTime === maxInspectionTimeByPointId[pointId]; |
|
|
|
}) |
|
|
|
const deviceLevelStatistics = {}; |
|
|
|
const levelValues = { 轻微: 0, 中度: 1, 严重: 2 }; |
|
|
|
filteredData.forEach((record) => { |
|
|
|
const points = record.points; |
|
|
|
if (points && points.inspectContent && Array.isArray(points.inspectContent)) { |
|
|
|
points.inspectContent.forEach((content) => { |
|
|
|
const device = content.deviceId; |
|
|
|
content.checkItems.forEach(checkItem => { |
|
|
|
const level = checkItem.level; |
|
|
|
if (!checkItem.isNormal) { |
|
|
|
if (!deviceLevelStatistics[device]) { |
|
|
|
// 如果设备不存在于统计对象中,初始化
|
|
|
|
deviceLevelStatistics[device] = { |
|
|
|
deviceName: content.deviceName, // 可能需要设备名称
|
|
|
|
level: level |
|
|
|
}; |
|
|
|
} else { |
|
|
|
// 如果设备已存在于统计对象中,比较level并更新为最低的level
|
|
|
|
deviceLevelStatistics[device].level = levelValues[level] > levelValues[deviceLevelStatistics[device].level] ? level : deviceLevelStatistics[device].level; |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
}) |
|
|
|
const levelCounts = { 轻微: 0, 中度: 0, 严重: 0 }; |
|
|
|
for (const deviceId in deviceLevelStatistics) { |
|
|
|
if (deviceLevelStatistics.hasOwnProperty(deviceId)) { |
|
|
|
const deviceInfo = deviceLevelStatistics[deviceId]; |
|
|
|
const level = deviceInfo.level; |
|
|
|
// 增加相应等级的设备数量
|
|
|
|
levelCounts[level]++; |
|
|
|
} |
|
|
|
} |
|
|
|
const data1 = Object.entries(levelCounts).map(([name, value]) => ({ name, value })) |
|
|
|
setPieData(data1) |
|
|
|
} |
|
|
|
}) |
|
|
|
// const format = 'YYYY-MM-DD HH:mm:ss'
|
|
|
|
// const times = [moment().subtract(70, 'years').format(format), moment().format(format)]
|
|
|
|
// dispatch(bigScreen.records(`patrolRecord/all/${times[0]}/${times[1]}/null/null`,{ projectId: structArr.toString(), IsbigScreen: 'true'})).then(res=>{
|
|
|
|
// if(res.success){
|
|
|
|
// console.log(res.payload.data)
|
|
|
|
// }
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
const getData = (startOfMonth, endOfMonth) => { |
|
|
|
const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject |
|
|
|
dispatch( |
|
|
|
bigScreen.getSubSystemPatrolAbout({ |
|
|
|
projectId: structArr.toString(), |
|
|
|
IsbigScreen: 'true', |
|
|
|
STime: startOfMonth, |
|
|
|
ETime: endOfMonth, |
|
|
|
}) |
|
|
|
).then(res => { |
|
|
|
if (res.success) { |
|
|
|
const data = res.payload.data |
|
|
|
setData(data) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
// const getListData = (value) => {
|
|
|
|
// let listData = []
|
|
|
|
// const days = value.daysInMonth()
|
|
|
|
// for (let i = 0; i < days; i++) {
|
|
|
|
// listData.push({ type: 'default', content: i + 1 })
|
|
|
|
// }
|
|
|
|
// data.forEach(item => {
|
|
|
|
// const day = moment(item.inspectionTime).date()
|
|
|
|
// if(value.date()===day){
|
|
|
|
// if (item.patrolRecordIssueHandles.length) {
|
|
|
|
// listData[day - 1] = { type: 'warning', content: day }
|
|
|
|
// } else {
|
|
|
|
// listData[day - 1] = { type: 'success', content: day }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// })
|
|
|
|
// return listData || []
|
|
|
|
// }
|
|
|
|
|
|
|
|
// useEffect(()=>{
|
|
|
|
const getListData = (value) => { |
|
|
|
let listData = [] |
|
|
|
const record = data.find(item => moment(item.inspectionTime).date() === value.date()) |
|
|
|
if (record) { |
|
|
|
if (record.patrolRecordIssueHandles.length) { |
|
|
|
listData.push({ color: '#f50', content: value.date() }) |
|
|
|
} else { |
|
|
|
listData.push({ color: '#87d068', content: value.date() }) |
|
|
|
} |
|
|
|
} else { |
|
|
|
|
|
|
|
listData.push({ color: 'transparent', content: value.date() }) |
|
|
|
|
|
|
|
} |
|
|
|
return listData || [] |
|
|
|
} |
|
|
|
|
|
|
|
// })
|
|
|
|
const onPanelChange = (value, mode) => { |
|
|
|
console.log('value1', value); |
|
|
|
}; |
|
|
|
const defaultDate = moment({ year: moment().year(), month: moment().month() }); |
|
|
|
setMonth(moment(value).format('YYYY-MM-DD HH:mm:ss')) |
|
|
|
} |
|
|
|
|
|
|
|
const dateFullCellRender = value => { |
|
|
|
const dataList = getListData(value) |
|
|
|
return ( |
|
|
|
<ul className='events'> |
|
|
|
{dataList.map((item, index) => ( |
|
|
|
<li key={item.index}> |
|
|
|
{/* <span>{item.content}</span> */} |
|
|
|
{/* <Badge status={item.type} count={item.content} color='transparent'/> */} |
|
|
|
<Tag color={item.color}>{item.content}</Tag> |
|
|
|
|
|
|
|
</li> |
|
|
|
))} |
|
|
|
</ul> |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
<> |
|
|
|
<div > |
|
|
|
<div> |
|
|
|
{/* 左一 */} |
|
|
|
<div className='left1Container'> |
|
|
|
<div id='calendar' className='left1Container' style={{ height: '21rem' }}> |
|
|
|
<Calendar |
|
|
|
validRange={[moment(moment()).startOf('month'), moment(moment()).endOf('month')]} |
|
|
|
dateFullCellRender={dateFullCellRender} |
|
|
|
fullscreen={false} |
|
|
|
headerRender={({ value, type, onChange, onTypeChange }) => { |
|
|
|
const start = 0; |
|
|
|
const end = 12; |
|
|
|
const monthOptions = []; |
|
|
|
const current = value.clone(); |
|
|
|
const localeData = value.localeData(); |
|
|
|
const months = []; |
|
|
|
const start = 0 |
|
|
|
const end = 12 |
|
|
|
const monthOptions = [] |
|
|
|
let current = value.clone() |
|
|
|
const localeData = value.localeData() |
|
|
|
const months = [] |
|
|
|
for (let i = 0; i < 12; i++) { |
|
|
|
current.month(i); |
|
|
|
months.push(localeData.monthsShort(current)); |
|
|
|
current = current.month(i) |
|
|
|
months.push(localeData.monthsShort(current)) |
|
|
|
} |
|
|
|
for (let i = start; i < end; i++) { |
|
|
|
monthOptions.push( |
|
|
|
<Select.Option key={i} value={i} className="month-item"> |
|
|
|
<Select.Option key={i} value={i} className='month-item'> |
|
|
|
{months[i]} |
|
|
|
</Select.Option>, |
|
|
|
); |
|
|
|
</Select.Option> |
|
|
|
) |
|
|
|
} |
|
|
|
const year = value.year(); |
|
|
|
const month = value.month(); |
|
|
|
const options = []; |
|
|
|
const year = value.year() |
|
|
|
const month = value.month() |
|
|
|
const options = [] |
|
|
|
for (let i = year - 10; i < year + 10; i += 1) { |
|
|
|
// for (let j = 0; j < 12; j++) {
|
|
|
|
options.push( |
|
|
|
<Select.Option key={i} value={i} className="year-item"> |
|
|
|
{`${i}年`} |
|
|
|
</Select.Option>) |
|
|
|
// }
|
|
|
|
<Select.Option key={i} value={i} className='year-item'> |
|
|
|
{i} |
|
|
|
</Select.Option> |
|
|
|
) |
|
|
|
} |
|
|
|
return ( |
|
|
|
<div className='calendarHeader'> |
|
|
|
<div className='cardHeader'> |
|
|
|
<div className='title' >巡检数据统计</div> |
|
|
|
<div className='title'>巡检数据统计</div> |
|
|
|
</div> |
|
|
|
{/* <Typography.Title level={4}>巡检数据统计</Typography.Title> */} |
|
|
|
<Row gutter={8}> |
|
|
|
<Col> |
|
|
|
<Select |
|
|
|
size="small" |
|
|
|
size='small' |
|
|
|
dropdownMatchSelectWidth={false} |
|
|
|
className="my-year-select" |
|
|
|
value={moment().format('yyy-MM')} |
|
|
|
onChange={(newYear) => { |
|
|
|
console.log('x11112', newYear) |
|
|
|
const now = value.clone().year(newYear); |
|
|
|
onChange(now); |
|
|
|
}} |
|
|
|
> |
|
|
|
className='my-year-select' |
|
|
|
value={year} |
|
|
|
onChange={newYear => { |
|
|
|
const now = value.clone().year(newYear) |
|
|
|
onChange(now) |
|
|
|
}}> |
|
|
|
{options} |
|
|
|
</Select> |
|
|
|
</Col> |
|
|
|
<Col> |
|
|
|
<Select |
|
|
|
size='small' |
|
|
|
dropdownMatchSelectWidth={false} |
|
|
|
value={month} |
|
|
|
onChange={newMonth => { |
|
|
|
const now = value.clone().month(newMonth) |
|
|
|
onChange(now) |
|
|
|
}}> |
|
|
|
{monthOptions} |
|
|
|
</Select> |
|
|
|
</Col> |
|
|
|
</Row> |
|
|
|
</div> |
|
|
|
); |
|
|
|
) |
|
|
|
}} |
|
|
|
onPanelChange={onPanelChange} |
|
|
|
/> |
|
|
@ -95,109 +270,112 @@ const Left = props => { |
|
|
|
{/* 左二 */} |
|
|
|
<div className='left1Container'> |
|
|
|
<div className='cardHeader'> |
|
|
|
<div className='title' >本周巡检统计</div> |
|
|
|
<div className='title'>本周巡检统计</div> |
|
|
|
</div> |
|
|
|
<div className='row'> |
|
|
|
<div > |
|
|
|
<div> |
|
|
|
<div className='smallP'> |
|
|
|
<div style={{background:'url(/assets/bigScreen/ying.png) 0% 0% / 100% 100% no-repeat'}}></div> |
|
|
|
<div style={{ background: 'url(/assets/bigScreen/ying.png) 0% 0% / 100% 100% no-repeat' }}></div> |
|
|
|
<div className='describe1'>本周应检</div> |
|
|
|
</div> |
|
|
|
<span className='numbers'>100</span><span>个</span> |
|
|
|
<span className='numbers'>{weekData.done + weekData.planCount}</span> |
|
|
|
<span>个</span> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<div className='smallP'> |
|
|
|
<div style={{background:'url(/assets/bigScreen/yij.png) 0% 0% / 100% 100% no-repeat',}}></div> |
|
|
|
<div style={{ background: 'url(/assets/bigScreen/yij.png) 0% 0% / 100% 100% no-repeat' }}></div> |
|
|
|
<div className='describe1'>本周已检</div> |
|
|
|
</div> |
|
|
|
<span className='numbers'>100</span><span>个</span> |
|
|
|
<span className='numbers'>{weekData.done}</span> |
|
|
|
<span>个</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className='row'> |
|
|
|
<div > |
|
|
|
<div> |
|
|
|
<div className='smallP'> |
|
|
|
<div style={{background:'url(/assets/bigScreen/daij.png) 0% 0% / 100% 100% no-repeat',}}></div> |
|
|
|
<div style={{ background: 'url(/assets/bigScreen/daij.png) 0% 0% / 100% 100% no-repeat' }}></div> |
|
|
|
<div className='describe1'>本周待验</div> |
|
|
|
</div> |
|
|
|
<span className='numbers'>100</span><span>个</span> |
|
|
|
<span className='numbers'>{weekData.planCount}</span> |
|
|
|
<span>个</span> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<div className='smallP'> |
|
|
|
<div style={{background:'url(/assets/bigScreen/daic.png) 0% 0% / 100% 100% no-repeat',}}></div> |
|
|
|
<div style={{ background: 'url(/assets/bigScreen/daic.png) 0% 0% / 100% 100% no-repeat' }}></div> |
|
|
|
<div className='describe1'>待处理问题</div> |
|
|
|
</div> |
|
|
|
<span className='numbers'>100</span><span>个</span> |
|
|
|
<span className='numbers'>{weekData.count}</span> |
|
|
|
<span>个</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div className='row'> |
|
|
|
<div > |
|
|
|
<div> |
|
|
|
<div className='smallP'> |
|
|
|
<div style={{background:'url(/assets/bigScreen/yic.png) 0% 0% / 100% 100% no-repeat',}}></div> |
|
|
|
<div style={{ background: 'url(/assets/bigScreen/yic.png) 0% 0% / 100% 100% no-repeat' }}></div> |
|
|
|
<div className='describe1'>已处理问题</div> |
|
|
|
</div> |
|
|
|
<span className='numbers'>100</span><span>个</span> |
|
|
|
<span className='numbers'>{weekData.bCount}</span> |
|
|
|
<span>个</span> |
|
|
|
</div> |
|
|
|
<div className='last'> |
|
|
|
<div className='smallP'> |
|
|
|
<div></div> |
|
|
|
<div className='describe1'>待处理问题</div> |
|
|
|
<div className='describe1'></div> |
|
|
|
</div> |
|
|
|
<span className='numbers'>100</span><span>个</span> |
|
|
|
<span className='numbers'>100</span> |
|
|
|
<span>个</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
{/* 左三 */} |
|
|
|
<div className='left1Container'> |
|
|
|
<div className='cardHeader'> |
|
|
|
<div className='title' >已处理问题</div> |
|
|
|
<div className='title'>已处理问题</div> |
|
|
|
</div> |
|
|
|
<div className={'pieChartfs'}> |
|
|
|
<ReactEcharts |
|
|
|
style={{ height: !isFullScreen?'13.4375rem':'18.4375rem', width: '25.2662rem' }} |
|
|
|
option={{ |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis', |
|
|
|
axisPointer: { |
|
|
|
type: 'shadow', |
|
|
|
<div className={'pieChartfs'}> |
|
|
|
<ReactEcharts |
|
|
|
style={{ height: !isFullScreen ? '13.4375rem' : '18.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, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
series: [ |
|
|
|
{ |
|
|
|
name: 'Access From', |
|
|
|
type: 'pie', |
|
|
|
radius: '50%', |
|
|
|
data: [ |
|
|
|
{ value: 1048, name: '严重' }, |
|
|
|
{ value: 735, name: '中等' }, |
|
|
|
{ value: 580, name: '轻微' }, |
|
|
|
], |
|
|
|
emphasis: { |
|
|
|
itemStyle: { |
|
|
|
shadowBlur: 10, |
|
|
|
shadowOffsetX: 0, |
|
|
|
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
], |
|
|
|
}}></ReactEcharts> |
|
|
|
</div> |
|
|
|
tooltip: { |
|
|
|
trigger: 'item', |
|
|
|
// formatter: '{a} <br/>{b} : {c} ({d}%)'
|
|
|
|
}, |
|
|
|
legend: { |
|
|
|
right: 0, |
|
|
|
textStyle: { color: '#CCE6FF' } |
|
|
|
}, |
|
|
|
grid: { |
|
|
|
left: '3%', |
|
|
|
right: '4%', |
|
|
|
bottom: '3%', |
|
|
|
containLabel: true, |
|
|
|
}, |
|
|
|
|
|
|
|
series: [ |
|
|
|
{ |
|
|
|
type: 'pie', |
|
|
|
radius: '50%', |
|
|
|
data: pieData, |
|
|
|
emphasis: { |
|
|
|
itemStyle: { |
|
|
|
shadowBlur: 10, |
|
|
|
shadowOffsetX: 0, |
|
|
|
shadowColor: 'rgba(0, 0, 0, 0.5)', |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
], |
|
|
|
}}></ReactEcharts> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</> |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|