diff --git a/api/app/lib/controllers/bigScreen/leader.js b/api/app/lib/controllers/bigScreen/leader.js index b9d4909..24c6fce 100644 --- a/api/app/lib/controllers/bigScreen/leader.js +++ b/api/app/lib/controllers/bigScreen/leader.js @@ -3,10 +3,24 @@ const moment = require("moment"); +function getPlanCount(startTime,endTime,frequencyUnit){ + switch(frequencyUnit){ + case '天': + return Math.ceil(moment(startTime).diff(endTime, 'days')) + case '周': + return Math.ceil(moment(startTime).diff(endTime, 'weeks')) + case '月': + return Math.ceil(moment(startTime).diff(endTime, 'months')) + default: + break + } + +} + async function findPatrolRecords(ctx, next) { const sequelize = ctx.fs.dc.orm; try { - let rslt = { planCount: 0, done: 0 } + let rslt = { planCount: 0, done: 0,count:0,bCount:0 } const models = ctx.fs.dc.models const { projectId, startTime, endTime } = ctx.query @@ -34,7 +48,8 @@ async function findPatrolRecords(ctx, next) { }) if (plan && plan.length) { for (let { dataValues: c } of plan) { - let frequency = Number(c.frequency.split('次')[0]) || 0 + let frequencyNum = Number(c.frequency.split('次')[0]) || 0 + let frequencyUnit = c.frequency.split('/')[1] let points = c.points.length || 0 let done = 0 // @@ -74,8 +89,27 @@ async function findPatrolRecords(ctx, next) { patrolPlanId: c.id } }) - rslt.planCount += frequency * points - done + const result = await sequelize.query(` + select p.name, + count(case when prih.state!=6 then 1 end) as count, + count(case when prih.state=6 then 1 end) as bCount + from project p + left join patrol_record pr + on p.id = pr.project_id + left join patrol_record_issue_handle prih + on pr.id = prih.patrol_record_id + and prih.create_time + between '${startTime}' + and '${endTime}' + where p.id in (${projectId}) + group by p.name + + `) + const planCount=getPlanCount(c.startTime,c.endTime,frequencyUnit) + rslt.planCount += frequencyNum * points * planCount- done rslt.done += dones + rslt.bCount+=result[0][0].bCount + rslt.count=result[0][0].count } } diff --git a/api/app/lib/controllers/bigScreen/run.js b/api/app/lib/controllers/bigScreen/run.js new file mode 100644 index 0000000..d5ce01f --- /dev/null +++ b/api/app/lib/controllers/bigScreen/run.js @@ -0,0 +1,162 @@ +async function findPatrolRecords(ctx) { + const models = ctx.fs.dc.models; + const sequelize = ctx.fs.dc.orm; + try { + const { projectId } = ctx.query + let generalInclude = [ + { model: models.PatrolRecordIssueHandle }, + ] + const rslt = await models.PatrolRecord.findAll({ + where: { projectId: { $in: projectId.split(',') }, alarm: true }, + include: generalInclude, + }) + const res = rslt.reduce((acc, record) => { + const pointId = record.pointId + const inspectionTime = record.inspectionTime + const obj = acc.find(r => r.pointId === pointId); + if (!obj) { + acc.push(record) + } else if (obj && inspectionTime > record.inspectionTime) { + record.findIndex(r => r.pointId === pointId) + acc.splice(index, 1) + acc.push(record) + } + return acc; + }, []); + ctx.body = res + ctx.status = 200 + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { message: '运行监控的列表' } + } +} + +async function getProjectPoints(ctx) { + let rslt = null + try { + const { projectId } = ctx.query + const models = ctx.fs.dc.models; + rslt = await models.Point.findAll({ + attributes: ['id', 'name', 'equipmentNo', 'equipmentModel'], + where: { projectId: { $in: projectId.split(',') } } + }) + ctx.status = 200; + ctx.body = rslt; + } catch (err) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); + ctx.status = 400; + ctx.body = { + name: 'FindError', + message: '获取结构物点位列表失败' + } + } +} + + +async function getDeployPoints(ctx) { + let rslt = null; + try { + const { pictureId } = ctx.query; + const models = ctx.fs.dc.models; + const heatmap = await models.ProjectGraph.findOne({ where: { id: { $in: pictureId.split(',') } } }) + if (heatmap) { + rslt = await models.ProjectPointsDeploy.findAll({ + where: { graphId: { $in: pictureId.split(',') } } + }) + ctx.status = 200; + ctx.body = rslt; + } else { + throw new Error('pictureId not found'); + } + } catch (err) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); + ctx.status = 400; + ctx.body = { + name: 'FindError', + message: '获取结构物平面图测点布设失败' + } + } +} + +async function findSingleGraph(ctx, next) { + const models = ctx.fs.dc.models; + let error = { name: 'FindSingleError', message: '查询单一数据失败' }; + let rslt = null; + const { projectId,subType } = ctx.query; + try { + rslt = await ctx.fs.dc.models.Project.findAll({ + where: { id: { $in: projectId.split(',') },subType}, attributes: ['id', 'sub_type',], + include: [{ + model: models.ProjectGraph + } + ] + }); + + error = null; + } catch (err) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); + } + if (error) { + ctx.status = 400; + ctx.body = error; + } else { + ctx.status = 200; + ctx.body = rslt; + } +} + + +async function findProjects(ctx, next) { + let rslt = {} + const { projectId } = ctx.query; + try { + rslt = await ctx.fs.dc.models.Project.findAll({ + where: { id: { $in: projectId.split(',') } } + }) + ctx.status = 200; + ctx.body = rslt; + + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { message: '运行监控的列表' } + } + +} + +async function findNewestRecord(ctx, next) { + const models = ctx.fs.dc.models; + const { pointId } = ctx.query; + const sequelize = ctx.fs.dc.orm; + try{ + const rs=await sequelize.query(` + SELECT p.* + FROM ( + SELECT id,point_id,alarm,points,inspection_time, ROW_NUMBER() OVER (PARTITION BY point_id ORDER BY inspection_time DESC) AS row_num + FROM patrol_record + WHERE point_id in (${pointId}) + ) AS p + WHERE p.row_num = 1; + `) + + ctx.status = 200 + ctx.body = rs[0]; + }catch(error){ + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { message: '查询巡检最新记录失败' } + } +} + + + + +module.exports = { + findPatrolRecords, + getProjectPoints, + getDeployPoints, + findSingleGraph, + findProjects, + findNewestRecord +} \ No newline at end of file diff --git a/api/app/lib/controllers/patrolManage/patrolRecord.js b/api/app/lib/controllers/patrolManage/patrolRecord.js index 8436da0..879b300 100644 --- a/api/app/lib/controllers/patrolManage/patrolRecord.js +++ b/api/app/lib/controllers/patrolManage/patrolRecord.js @@ -448,24 +448,34 @@ function getSubSystemPatrolAbout(opts) { return async function (ctx, next) { try { let rslt = [] + let generalInclude=[] const models = ctx.fs.dc.models; - const { STime, ETime, keywords } = ctx.query - let generalInclude = [{ model: models.PatrolRecordIssueHandle }, { model: models.Project, where: { subType: { $like: `%${keywords}%` } } }] + const { STime, ETime, keywords,IsbigScreen,projectId } = ctx.query + if(IsbigScreen==='true'){ + generalInclude=[{ model: models.PatrolRecordIssueHandle }, { model: models.Project, where: { id: { $in: projectId.split(',') } } }] + }else{ + generalInclude= [{ model: models.PatrolRecordIssueHandle }, { model: models.Project, where: { subType: { $like: `%${keywords}%` } } }] + } rslt = await models.PatrolRecord.findAll({ where: { inspectionTime: { $between: [STime, ETime] } }, include: generalInclude }) - let userInfo = ctx.fs.api.userInfo; - rslt = rslt.filter(f => f) - if (userInfo.username != 'SuperAdmin') { - if (userInfo.structure) { - rslt = rslt.filter(s => userInfo.structure.find(x => x == s.points.project.id)) - } else { - rslt = [] + if(IsbigScreen==='true'){ + ctx.status = 200; + ctx.body = rslt + }else{ + let userInfo = ctx.fs.api.userInfo; + rslt = rslt.filter(f => f) + if (userInfo.username != 'SuperAdmin') { + if (userInfo.structure) { + rslt = rslt.filter(s => userInfo.structure.find(x => x == s.points.project.id)) + } else { + rslt = [] + } } + ctx.status = 200; + ctx.body = rslt } - ctx.status = 200; - ctx.body = rslt } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; diff --git a/api/app/lib/index.js b/api/app/lib/index.js index 6bbfadd..6ea981c 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -53,7 +53,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq require(`./models/${filename}`)(dc) }); - const { Department, User, UserResource, Resource, Project, Point, + const { Department, User, UserResource, Resource, Project,ProjectGraph, Point, PatrolPlan, PatrolRecord, ReportInfo, PatrolPlanUser, CheckItems, CheckItemsGroup, PatrolTemplate, PatrolTemplateCheckItems, PatrolRecordIssueHandle, @@ -117,4 +117,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq Network.belongsTo(Project,{ foreignKey: 'projectId', otherKey: 'id' }) Project.hasMany(Network,{ foreignKey: 'projectId', sourceKey: 'id' }) + + ProjectGraph.belongsTo(Project,{ foreignKey: 'projectId', otherKey: 'id' }) + Project.hasMany(ProjectGraph,{ foreignKey: 'projectId', sourceKey: 'id' }) }; diff --git a/api/app/lib/routes/bigScreen/run.js b/api/app/lib/routes/bigScreen/run.js new file mode 100644 index 0000000..fe8c719 --- /dev/null +++ b/api/app/lib/routes/bigScreen/run.js @@ -0,0 +1,26 @@ +'use strict'; +const run = require('../../controllers/bigScreen/run'); + +module.exports = function (app, router, opts) { + + + app.fs.api.logAttr['GET/bigScreen/patrol/record'] = { content: '', visible: false }; + router.get('/bigScreen/patrol/record',run.findPatrolRecords) + + + app.fs.api.logAttr['GET/bigScreen/picture/deploy/points'] = { content: '获取点位布设信息', visible: false }; + router.get('bigScreen//picture/deploy/points', run.getDeployPoints); + + app.fs.api.logAttr['GET/bigScreen/project/all/points'] = { content: '获取结构物点位列表', visible: false }; + router.get('/bigScreen/project/all/points', run.getProjectPoints); + + app.fs.api.logAttr['GET/bigScreen/project/planarGraph'] = { content: '获取结构物平面图数据', visible: false }; + router.get('/bigScreen/project/planarGraph', run.findSingleGraph); + + app.fs.api.logAttr['GET/bigScreen/projects'] = { content: '获取结构物', visible: false }; + router.get('/bigScreen/projects', run.findProjects) + + app.fs.api.logAttr['GET/bigScreen/newestRecord'] = { content: '获取最新巡检记录', visible: false }; + router.get('/bigScreen/newestRecord', run.findNewestRecord) + +} \ No newline at end of file diff --git a/web-screen/client/src/layout/components/header/index.js b/web-screen/client/src/layout/components/header/index.js index c68bd77..2f6c04a 100644 --- a/web-screen/client/src/layout/components/header/index.js +++ b/web-screen/client/src/layout/components/header/index.js @@ -28,9 +28,8 @@ const Header = props => { const [patrolManageVisible, setPatrolManageVisible] = useState(false) const [deviceManageTabsVisible, setDeviceManageTabsVisible] = useState(false) const [currentSubMenuTab, setCurrentSubMenuTab] = useState('') - const [tab, setTab] = useState('error') + const [tab, setTab] = useState('run') const [weather, setWeather] = useState([]) - console.log('globalTab', globalTab) let headerTitleStyle = { position: 'absolute', left: '3.125rem', diff --git a/web-screen/client/src/layout/reducers/tab.js b/web-screen/client/src/layout/reducers/tab.js index 523f861..a13b333 100644 --- a/web-screen/client/src/layout/reducers/tab.js +++ b/web-screen/client/src/layout/reducers/tab.js @@ -3,7 +3,7 @@ import Immutable from 'immutable'; const initState = { - tab: 'error', + tab: 'run', showCG: true }; diff --git a/web-screen/client/src/sections/bigScreen/actions/index.js b/web-screen/client/src/sections/bigScreen/actions/index.js index ba34062..db346b1 100644 --- a/web-screen/client/src/sections/bigScreen/actions/index.js +++ b/web-screen/client/src/sections/bigScreen/actions/index.js @@ -1,6 +1,7 @@ 'use strict'; import leader from './leader' +import run from './run' export default { - ...leader, + ...leader,...run } \ No newline at end of file diff --git a/web-screen/client/src/sections/bigScreen/actions/run.js b/web-screen/client/src/sections/bigScreen/actions/run.js new file mode 100644 index 0000000..462ba6e --- /dev/null +++ b/web-screen/client/src/sections/bigScreen/actions/run.js @@ -0,0 +1,103 @@ +'use strict'; +import { basicAction } from '@peace/utils' +import { ApiTable } from '$utils' + +export function getSubSystemPatrolAbout(query) { + return dispatch => basicAction({ + type: 'get', + query, + dispatch: dispatch, + actionType: 'GET_SUB_STYSTEM_PATROL_ABOUT', + url: `${ApiTable.getSubSystemPatrolAbout}`, + msg: { error: '获取巡检记录数' }, + reducer: { name: 'subSystemPatrols'} + }); +} + +export function records(query) { + return (dispatch) => basicAction({ + type: 'get', + dispatch, + query, + actionType: 'GET_PATROL_RECORD_LIST', + url: `${ApiTable.getRecord}`, + msg: { error: '获取巡检记录失败', }, + reducer: { name: 'record' } + }); +} +export function getProjectGraph(query) { + return (dispatch) => basicAction({ + type: 'get', + dispatch, + query, + actionType: 'GET_PROJECT_PLANAR_GRAPH', + url: ApiTable.getProjectGraph, + msg: { option: '获取结构物平面图' }, + reducer: { name: 'projectGraph' } + }); +} + + +export function getProjectPoints(query) { + return (dispatch) => basicAction({ + type: 'get', + dispatch, + query, + actionType: 'GET_PROJECT_ALL_POINTS', + url: ApiTable.getProjectPoints, + msg: { option: '获取结构物所有点位' }, + reducer: { name: 'projectAllPoints' } + }); +} + +export function getDeployPoints(query) { + return (dispatch) => basicAction({ + type: 'get', + dispatch, + query, + actionType: 'GET_PROJECT_DEPLOY_POINTS', + url: ApiTable.getDeployPoints, + msg: { option: '获取结构物平面图测点分布' }, + reducer: { name: 'projectDeployPoints' } + }); +} + + + +export function getProjects(query) { + return (dispatch) => basicAction({ + type: 'get', + dispatch, + query, + actionType: 'GET_PROJECTS', + url: ApiTable.getProjects, + msg: { option: '获取结构物' }, + reducer: { name: 'projects' } + }); +} + +export function findNewestRecord(query) { + return (dispatch) => basicAction({ + type: 'get', + dispatch, + query, + actionType: 'FIND_NEWEST_RECORD', + url: ApiTable.findNewestRecord, + msg: { option: '获取点位最新巡检记录' }, + reducer: { name: 'newestRecords' } + }); +} + + + +export default{ + getSubSystemPatrolAbout, + getDeployPoints, + getProjectPoints, + getProjects, + records, + getProjectGraph, + getDeployPoints, + findNewestRecord + +} \ No newline at end of file diff --git a/web-screen/client/src/sections/bigScreen/components/leader/index.js b/web-screen/client/src/sections/bigScreen/components/leader/index.js index 2e384a6..4b0a922 100644 --- a/web-screen/client/src/sections/bigScreen/components/leader/index.js +++ b/web-screen/client/src/sections/bigScreen/components/leader/index.js @@ -13,10 +13,19 @@ const Leader = (props) => { const {actions,dispatch, globalTab, } = props const {bigScreen}=actions const [centerData,setCenterData]=useState({}) - const fontStyle={ + 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=>{ @@ -34,11 +43,11 @@ const Leader = (props) => {
-
设备总数{centerData.deviceCount}
-
发现问题{centerData.questions}
-
{centerData.handleCount}
累计巡检数
-
出具报告数{centerData.records}
-
处理故障数{centerData.reportCount}
+
设备总数{centerData.deviceCount}
+
发现问题{centerData.questions}
+
{centerData.handleCount}
累计巡检数
+
出具报告数{centerData.records}
+
处理故障数{centerData.reportCount}
diff --git a/web-screen/client/src/sections/bigScreen/components/run/left.js b/web-screen/client/src/sections/bigScreen/components/run/left.js index 14b370f..eeda7ba 100644 --- a/web-screen/client/src/sections/bigScreen/components/run/left.js +++ b/web-screen/client/src/sections/bigScreen/components/run/left.js @@ -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 ( + + ) + } + return ( <> -
+
{/* 左一 */} -
+
{ - 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( - + {months[i]} - , - ); + + ) } - 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( - - {`${i}年`} - ) - // } + + {i} + + ) } return (
-
巡检数据统计
+
巡检数据统计
- {/* 巡检数据统计 */} + + +
- ); + ) }} onPanelChange={onPanelChange} /> @@ -95,109 +270,112 @@ const Left = props => { {/* 左二 */}
-
本周巡检统计
+
本周巡检统计
-
+
-
+
本周应检
- 100 + {weekData.done + weekData.planCount} +
-
+
本周已检
- 100 + {weekData.done} +
-
+
-
+
本周待验
- 100 + {weekData.planCount} +
-
+
待处理问题
- 100 + {weekData.count} +
-
+
-
+
已处理问题
- 100 + {weekData.bCount} +
-
待处理问题
+
- 100 + 100 +
{/* 左三 */}
-
已处理问题
+
已处理问题
-
- + -
+ tooltip: { + trigger: 'item', + // formatter: '{a}
{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)', + }, + }, + }, + ], + }}> +
- ) } diff --git a/web-screen/client/src/sections/bigScreen/components/run/right.js b/web-screen/client/src/sections/bigScreen/components/run/right.js index bda5b03..2f9e3f2 100644 --- a/web-screen/client/src/sections/bigScreen/components/run/right.js +++ b/web-screen/client/src/sections/bigScreen/components/run/right.js @@ -1,33 +1,51 @@ import React, { useEffect, useState } from 'react' -import { Spin, Popconfirm, message, Button, Input, Progress } from 'antd'; +import { Spin, Popconfirm, message, Button, Popover, Carousel } from 'antd'; import { connect } from 'react-redux'; -import ProTable from '@ant-design/pro-table'; import moment from 'moment'; import PerfectScrollbar from 'perfect-scrollbar'; -import ReactEcharts from 'echarts-for-react' import '../style.less' -let scrollbar - +let scrollbarRecord +let recordProblem const Right = (props) => { - const { clientHeight, clientWidth,isFullScreen } = props + const { dispatch, actions, clientHeight, clientWidth, isFullScreen } = props + const { bigScreen } = actions const [beginHeight, setBeginHeight] = useState(window.innerHeight); // // const [isFullScreen, setIsFullScreen] = useState(false); //是否全屏 - const [index,setIndex]=useState('1')//默认第一个tab - + const [index, setIndex] = useState('1')//默认第一个tab + const [recordList, setRecordList] = useState([]) + const [points, setPoints] = useState([]) + const [graph, setGraph] = useState([]) + const [deployPoints, setDeployPoints] = useState([]) + const [subType, setSubType] = useState('指挥中心') + const [numObj, setNumObj] = useState({ + commandCenter: 0, pipeGalleryBody: 0, + elevatorSystem: 0, powerSupplyAndDistributionSystem: 0, + lightningProtectionAndGroundingSystem: 0, + GasSilo: 0, waterSupplyWarehouse: 0, + securitySystem: 0, highVoltagePowerWarehouse: 0 + }) + const STATE_TEXT = { 1: '待制定计划', 2: '待审核', 3: '计划驳回', 4: '待维修', 5: '待验收', 6: '验收通过', 7: '验收不通过', } + let h = clientHeight / 1.3; + let w = clientWidth / 1.4; + + const renderOptionText = (currentState) => { + let text = '待制定计划' + return STATE_TEXT[currentState] || text + } + useEffect(() => { - + getData() }, []) - useEffect(()=>{ - scrollbar = new PerfectScrollbar('#redcordContent', { suppressScrollX: true }); + useEffect(() => { + scrollbarRecord = new PerfectScrollbar('#redcordContent', { suppressScrollX: true }); const dom = document.getElementById('redcordContent'); - console.log('dom', dom) if (dom) { - scrollbar.update(); + scrollbarRecord.update(); dom.scrollTop = 0; } - },[window.innerHeight]) + }, [window.innerHeight]) let header = [ @@ -60,71 +78,319 @@ const Right = (props) => { }, ] //巡检记录表头 - let recordHeader=[ - {name:'结构物名称'}, - {name:'上报人'}, - {name:'上报时间'}, - {name:'点位名称'}, - {name:'问题来源'}, - {name:'严重等级'}, - {name:'当前状态'}, + let recordHeader = [ + { name: '结构物名称' }, + { name: '上报人' }, + { name: '上报时间' }, + { name: '点位名称' }, + { name: '问题来源' }, + { name: '严重等级' }, + { name: '当前状态' }, ] - const ck=(index)=>{ + const ck = (index) => { + switch (index) { + case '1': + setSubType('指挥中心') + break; + case '2': + setSubType('管廊本体') + break; + case '3': + setSubType('电梯系统') + break; + case '4': + setSubType('供配电系统') + break; + case '5': + setSubType('防雷与接地系统') + break; + case '6': + setSubType('燃气仓') + break; + case '7': + setSubType('给水仓') + break; + case '8': + setSubType('安防系统') + break; + case '9': + setSubType('高压电力仓') + break; + default: + break + } setIndex(index) } - return <> -
- {/* 右边的抬头 */} -
- {header.map(item => { - switch (item.name) { - case '指挥中心': - return
{ck('1')}}>{item.name+`(${1})`}
- case '管廊本体': - return
{ck('2')}}>{item.name+`(${1})`}
- case '电梯系统': - return
{ck('3')}}>{item.name+`(${1})`}
- case '供配电系统': - return
{ck('4')}}>{item.name+`(${1})`}
- case '防雷与接地系统': - return
{ck('5')}}>{item.name+`(${1})`}
- case '燃气仓': - return
{ck('6')}}>{item.name+`(${1})`}
- case '给水仓': - return
{ck('7')}}>{item.name+`(${1})`}
- case '安防系统': - return
{ck('8')}}>{item.name+`(${1})`}
- case '管廊本体': - return
{ck('9')}}>{item.name+`(${1})`}
- case '高压电力仓': - return
{ck('10')}}>{item.name+`(${1})`}
- default: - break; + useEffect(() => { + const points = deployPoints.map(item => item.pointId).toString() + if (points) { + dispatch(bigScreen.findNewestRecord({ pointId: points })).then(res => { if (res.success) { setPoints(res.payload.data) } }) + } + }, [deployPoints]) + useEffect(() => { + const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject + dispatch(bigScreen.getProjectGraph({ projectId: structArr.toString(), subType })).then(_ => { + if (_.success) { + let graph = _.payload.data + setGraph(graph) + setDeployPoints([]) + if (graph.length) {//有图片 + dispatch(bigScreen.getDeployPoints({ pictureId: graph?.map(item => item.id).toString() || '-11' })).then(res => { + if (res.success) { + setDeployPoints(res.payload.data) + + } + }) } - })} -
- {/* 中间的图片 */} -
- -
- {/* 巡检记录 */} -
- {recordHeader.map(item=>(
{item.name}
))} -
-
-
+ + } + }); + }, [subType]) + + const getData = () => { + const structArr = JSON.parse(sessionStorage.getItem('user')).monitorObject + dispatch(bigScreen.records({ projectId: structArr.toString() })).then(res => { + if (res.success) { + const data = res.payload.data + const data1 = data.map(item => { + const LEVELS_ = ['严重', '中度', '轻微']; + const recordLevels = [] + item?.points?.inspectContent ? Object.keys(item?.points?.inspectContent).map(key => { + recordLevels.push(item?.points?.inspectContent[key]?.level) + }) : '' + if (Array.isArray(item?.points?.inspectContent)) { + item?.points?.inspectContent?.map(x => { + x.checkItems?.map(v => { + recordLevels.push(v?.level) + }) + }) + } + const level = LEVELS_.find(s => recordLevels.find(x => x == s)) + return { + projectName: item?.points?.project?.name, + reporUsertName: item?.points?.user?.name, + reportTime: item?.patrolRecordIssueHandles && item?.patrolRecordIssueHandles.length && item?.patrolRecordIssueHandles[0]?.createTime ? + moment(item?.patrolRecordIssueHandles[0]?.createTime).format('YYYY-MM-DD HH:mm:ss') : '--', + pointName: item?.points?.itemData?.name, + questionFrom: item?.patrolPlanId === -1 ? '主动上报' : '巡检上报', + level: level, + status: !item?.patrolRecordIssueHandles || item?.patrolRecordIssueHandles?.length == 0 ? '待制定计划' : + renderOptionText(item?.patrolRecordIssueHandles[0]?.state), + } + } + + ) + setRecordList(data1) + if (data.length > 4) { + let problemstop = 0 + let problemsId = document.getElementById('redcordContent'); + if (recordProblem) clearInterval(recordProblem) + if (problemsId) { + function problemstart() { + recordProblem = setInterval(() => { + problemstop += 5 + problemsId.scrollTop = problemstop + if (problemsId.scrollTop >= problemsId.scrollHeight / 2) problemstop = 0, problemsId.scrollTop = problemstop + }, 500); + problemsId.onmouseover = () => clearInterval(recordProblem) + } + problemsId.onmouseout = () => problemstart() + setTimeout(problemstart(), 1000); + } + } + } + }) + dispatch(bigScreen.getProjects({ projectId: structArr.toString() })).then(res => { + if (res.success) { + let obj = { + commandCenter: 0, pipeGalleryBody: 0, + elevatorSystem: 0, powerSupplyAndDistributionSystem: 0, + lightningProtectionAndGroundingSystem: 0, + GasSilo: 0, waterSupplyWarehouse: 0, + securitySystem: 0, highVoltagePowerWarehouse: 0 + } + res.payload.data.map(item => { + switch (item.subType) { + case '指挥中心': + obj.commandCenter += 1 + break; + case '管廊本体': + obj.pipeGalleryBody += 1 + break; + case '电梯系统': + obj.elevatorSystem += 1 + break; + case '供配电系统': + obj.powerSupplyAndDistributionSystem += 1 + break; + case '防雷与接地系统': + obj.lightningProtectionAndGroundingSystem += 1 + break; + case '燃气仓': + obj.GasSilo += 1 + break; + case '给水仓': + obj.waterSupplyWarehouse += 1 + break; + case '安防系统': + obj.securitySystem += 1 + break; + case '高压电力仓': + obj.highVoltagePower += 1 + break; + default: + return + + } + }) + setNumObj(obj) + } + }) + // dispatch(getProjectPoints({projectId: structArr.toString()})).then(res=>{ + // if(res.success){ + // setPoints(res.payload.data) + // } + // }) + + + } + + // let targetStyle = { + // position: 'relative', + // width: width, + // // overflow:'hidden', + // height: height, + // background: `url("/_file-server/${image}") no-repeat`, + // backgroundSize: '100% 100%', + // }; + + + + + + + return <> +
+ {/* 右边的抬头 */} +
+ {header.map(item => { + switch (item.name) { + case '指挥中心': + return
{ ck('1') }}>{item.name + `(${numObj.commandCenter})`}
+ case '管廊本体': + return
{ ck('2') }}>{item.name + `(${numObj.pipeGalleryBody})`}
+ case '电梯系统': + return
{ ck('3') }}>{item.name + `(${numObj.elevatorSystem})`}
+ case '供配电系统': + return
{ ck('4') }}>{item.name + `(${numObj.powerSupplyAndDistributionSystem})`}
+ case '防雷与接地系统': + return
{ ck('5') }}>{item.name + `(${numObj.lightningProtectionAndGroundingSystem})`}
+ case '燃气仓': + return
{ ck('6') }}>{item.name + `(${numObj.GasSilo})`}
+ case '给水仓': + return
{ ck('7') }}>{item.name + `(${numObj.waterSupplyWarehouse})`}
+ case '安防系统': + return
{ ck('8') }}>{item.name + `(${numObj.securitySystem})`}
+ case '高压电力仓': + return
{ ck('9') }}>{item.name + `(${numObj.highVoltagePowerWarehouse})`}
+ default: + break; + } + })} +
+ {/* 中间的图片 */} +
+ {/* */} + {graph?.length ? graph.map(item => (item?.projectGraphs.length ? +
+ { + deployPoints.length ? deployPoints.map(item => ( + +
{moment(points.find(i => i.point_id === item.pointId)?.inspectTime).format('YYYY-MM-DD HH:mm:ss') + '巡检发现异常'}
+
进度:{renderOptionText(points.find(i => i.point_id === item.pointId)?.state)}
+ {/*
{}
*/} + {points.find(i => i.point_id === item.pointId)?.points?.inspectContent?.map(q => ( +
{q.deviceName}:{'是否异常:' + q.alarm}
+ ))} +
+ ) + + }>
i.point_id === item.pointId)?.alarm ? 'rgb(233 16 16)' : 'rgb(16, 142, 233)', + }}>
+ )) : "" + } + {deployPoints.length ? +
+
+
{`异常(${points.filter(item => item.alarm).length})`}
+
+
+
{`正常(${points.filter(item => !item.alarm).length})`}
+
+
: '' + } +
+ : '暂无数据')) : '暂无数据' + } + {/* */} +
+ + + {/* {graph?.length?graph.map(item=>(item?.projectGraphs.length?:'暂无数据')):'暂无数据'} */} + {/* */} + + {/* 巡检记录 */} +
+ {recordHeader.map(item => (
{item.name}
))} +
+
+ {recordList.length ? recordList.map(item => ( +
+
{item.projectName}
+
{item.reporUsertName}
+
{item.reportTime}
+
{item.pointName}
+
{item.questionFrom}
+
{item.level}
+
{item.status}
+
+ )) :
暂无数据
} + + + + + {/*
指挥中心
李一一
2023-11-02 09:23:35
@@ -217,8 +483,8 @@ const Right = (props) => {
巡检上报
轻微
待制定计划
-
-
+
*/} +
diff --git a/web-screen/client/src/sections/bigScreen/components/run/style.less b/web-screen/client/src/sections/bigScreen/components/run/style.less index 44dd54c..27ebc8c 100644 --- a/web-screen/client/src/sections/bigScreen/components/run/style.less +++ b/web-screen/client/src/sections/bigScreen/components/run/style.less @@ -2,6 +2,7 @@ width: 26.3125rem; height: 17.8125rem; margin-top: 1.5rem; + position: relative; .pieChartfs{ text-align: center; height: 17.8125rem; @@ -34,6 +35,22 @@ background-repeat: no-repeat; display: flex; justify-content: space-between; + .ant-row{ + .ant-col{ + .ant-select{ + .ant-select-selector{ + background: transparent; + color: #ffffff; + border-color: transparent; + } + .ant-select-arrow{ + color: #ffffff; + + } + } + } + } + } .ant-row { @@ -167,6 +184,7 @@ height: 33.5rem; // padding-top: 0.5rem; margin-left: 2rem; + position: relative; // color: red; // background: url(/assets/bigScreen/bigImg.png) no-repeat; // background-size: 100% 100%; @@ -229,4 +247,23 @@ } .noFullStyle{ height: 11rem; +} +.events { + margin: 0; + padding: 0; + list-style: none; +} +.events .ant-badge-status { + width: 100%; + overflow: hidden; + font-size: .75rem; + white-space: nowrap; + text-overflow: ellipsis; +} +.notes-month { + font-size: 1.75rem; + text-align: center; +} +.notes-month section { + font-size: 1.75rem; } \ No newline at end of file diff --git a/web-screen/client/src/utils/webapi.js b/web-screen/client/src/utils/webapi.js index 490612e..405305f 100644 --- a/web-screen/client/src/utils/webapi.js +++ b/web-screen/client/src/utils/webapi.js @@ -133,12 +133,12 @@ export const ApiTable = { //项目状态配置 editProjectStatus: 'project/status', //工地平面图 - getProjectGraph: 'project/{projectId}/planarGraph', + getProjectGraph: 'bigScreen/project/planarGraph', createGraph: 'planarGraph/add', updateGraph: 'planarGraph/{id}/modify', deleteGraph: 'project/graph/{id}', - getProjectPoints: 'project/{projectId}/all/points', - getDeployPoints: 'picture/{pictureId}/deploy/points', + getProjectPoints: 'project/all/points', + getDeployPoints: 'bigScreen/picture/deploy/points', setDeployPoints: 'set/picture/{pictureId}/deploy/points', //设备管理 @@ -170,14 +170,19 @@ export const ApiTable = { addOrUpdateNetwork:'network', delNetwork:'network/{id}', - + //领导仓 findPatrolRecords:'bigScreen/patrolRecord', - findPatrolRate:'bigScreen/patrolRate', + findPatrolRate:'bigScreen/getDeployPoints', countByProject:'bigScreen/patrolCount', getDevices:'bigScreen/devices/guarantee', getHistoricalFaults:'bigScreen/historicalFaults', getFaultsRank:'bigScreen/faultsRank', getCenterData:'bigScreen/centerData', + //运行管理 + getSubSystemPatrolAbout:'patrolRecord/subSystemPatrolAbout', + getRecord:'bigScreen/patrol/record', + getProjects:'bigScreen/projects', + findNewestRecord:'bigScreen/newestRecord', }; //