From 0d837a51dc6dd067dbc7edea80dc27d55572d104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zhaobing=E2=80=99?= Date: Wed, 30 Aug 2023 17:53:26 +0800 Subject: [PATCH 01/16] =?UTF-8?q?feat:=E5=91=8A=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/images/projectGroup/first.png | Bin 0 -> 976 bytes .../assets/images/projectGroup/second.png | Bin 0 -> 1128 bytes .../assets/images/projectGroup/third.png | Bin 0 -> 1114 bytes .../projectGroup/containers/bigscreen.jsx | 154 +++++++++++++++++- .../src/sections/projectGroup/style.less | 95 ++++++++++- 5 files changed, 244 insertions(+), 5 deletions(-) create mode 100644 web/client/assets/images/projectGroup/first.png create mode 100644 web/client/assets/images/projectGroup/second.png create mode 100644 web/client/assets/images/projectGroup/third.png diff --git a/web/client/assets/images/projectGroup/first.png b/web/client/assets/images/projectGroup/first.png new file mode 100644 index 0000000000000000000000000000000000000000..9b8a315a942984c92ca9dfb8d252f7e40ee72c69 GIT binary patch literal 976 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 { + const [alarmData,setAlarmData]=useState()//第三项之后的数据 + const [biggest,setBiggest]=useState()//最大的刻度值 useEffect(() => { let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId console.log(); dispatch(actions.projectGroup.groupStatisticOnline({ groupId })) }, []) + useEffect(()=>{ + const domProject1 = document.getElementById("alarmRank"); + if (domProject1) { + overviewScrollbar = new PerfectScrollbar("#alarmRank", { + suppressScrollX: true, + }); + } + if (overviewScrollbar&&domProject1) { + overviewScrollbar.update(); + + } + }) + useEffect(()=>{ + const maxCombinedValue = mockData.reduce((max, item) => { + const combinedMax = Math.max(item.alarmCount, item.dealAlarmCount); + if (combinedMax > max) { + return combinedMax; + } + return max; + }, -Infinity) + setBiggest(maxCombinedValue) + + },[]) + const mockData=[ + {id: 1,name: '测试结构物测试结构物',alarmCount: 200,dealAlarmCount: 23}, + {id: 2,name: '测试结构物2',alarmCount: 150,dealAlarmCount: 22}, + {id: 3,name: '测试结构物3',alarmCount: 140,dealAlarmCount: 21}, + {id: 4,name: '测试结构物4',alarmCount: 120,dealAlarmCount: 23}, + {id: 5,name: '测试结构物5',alarmCount: 110,dealAlarmCount: 22}, + {id: 6,name: '测试结构物6',alarmCount: 109,dealAlarmCount: 21}, + {id: 7,name: '测试结构物7',alarmCount: 100,dealAlarmCount: 23}, + {id: 8,name: '测试结构物8',alarmCount: 99,dealAlarmCount: 22}, + {id: 9,name: '测试结构物9',alarmCount: 98,dealAlarmCount: 21}, + {id: 10,name: '测试结构物10',alarmCount: 97,dealAlarmCount: 23}, + {id: 11,name: '测试结构物11',alarmCount: 96,dealAlarmCount: 22}, + {id: 12,name: '测试结构物12',alarmCount: 95,dealAlarmCount: 21}, + {id: 13,name: '测试结构物13',alarmCount: 100,dealAlarmCount: 23}, + {id: 14,name: '测试结构物14',alarmCount: 49,dealAlarmCount: 22}, + {id: 15,name: '测试结构物15',alarmCount: 48,dealAlarmCount: 21}, + {id: 16,name: '测试结构物16',alarmCount: 47,dealAlarmCount: 23}, + {id: 17,name: '测试结构物17',alarmCount: 46,dealAlarmCount: 22}, + {id: 18,name: '测试结构物18',alarmCount: 45,dealAlarmCount: 21}, + {id: 19,name: '测试结构物19',alarmCount: 30,dealAlarmCount: 22}, + {id: 20,name: '测试结构物20',alarmCount: 29,dealAlarmCount: 21}, + {id: 21,name: '测试结构物21',alarmCount: 28,dealAlarmCount: 23}, + {id: 22,name: '测试结构物22',alarmCount: 27,dealAlarmCount: 22}, + {id: 23,name: '测试结构物23',alarmCount: 26,dealAlarmCount: 21}, + ] +useEffect(()=>{ + if(mockData.length>3&&mockData.length<21){ + const newArray = mockData.slice(3) + setAlarmData(newArray) + } + if(mockData.length>21){ + //数据大于20的话,取前20 + const newArray = mockData.slice(3,20) + setAlarmData(newArray) + } + +},[]) + + + console.log(groupStatisticOnline); return ( @@ -28,7 +95,7 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
- +
@@ -105,10 +172,89 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
- +
+
+
+
超阈值个数
+
+
+
手动恢复个数
+
+
+
+ {mockData[0]?(
+
+ +
+
{mockData[0]?.name?.length>5?{mockData[0]?.name.substring(0,5)+'...'}:mockData[0]?.name}
+
+
+
+
+
+
+
+
+
):'' + } + {mockData[1]?(
+
+ +
+
{mockData[1]?.name?.length>5?{mockData[1]?.name.substring(0,5)+'...'}:mockData[0]?.name}
+
+
+
+
+
+
+
+
+
):'' + } + {mockData[2]?(
+
+ +
+
{mockData[2]?.name?.length>5?{mockData[2]?.name.substring(0,5)+'...'}:mockData[0]?.name}
+
+
+
+
+
+
+
+
+
):'' + } + {alarmData&&alarmData.length? + alarmData.map((item,index)=> + { + return (
+
+ {index+4} +
+
{item.name?.length>5?{item.name.substring(0,5)+'...'}:item.name}
+
+
+
+
+
+
+
+
+ +
) + } + ) + :'' + } +
+
- +
diff --git a/web/client/src/sections/projectGroup/style.less b/web/client/src/sections/projectGroup/style.less index 4e1cb69..522cf4b 100644 --- a/web/client/src/sections/projectGroup/style.less +++ b/web/client/src/sections/projectGroup/style.less @@ -1,3 +1,96 @@ .project-group { font-family: PangMenZhengDaoBiaoTiTi; -} \ No newline at end of file +} +.alarmDiv{ + width: 8px; + height: 8px; + background-image: linear-gradient(180deg, #fbac3200 1%, #FBAC32 100%); + box-shadow: inset 0 2px 0 0 #FBAC32; +} +.alarm{ + width: 73px; + height: 12px; + font-family: SourceHanSansCN-Regular; + font-weight: 400; + font-size: 12px; + color: #A0A0A0; + letter-spacing: 0; + line-height: 12px; + // margin-left: 2!important; +} +.dealAlarmCountDiv{ + width: 8px; + height: 8px; + background-image: linear-gradient(180deg, #c2d2ff00 1%, #2A62FC 100%); + box-shadow: inset 0 2px 0 0 #2C66F3; +} +.alarmCount{ + width: 73px; + height: 12px; + font-family: SourceHanSansCN-Regular; + font-weight: 400; + font-size: 12px; + color: #A0A0A0; + letter-spacing: 0; + text-align: right; + line-height: 12px; + // margin-left: 2 !important; + +} +//柱状图外层的div +.barChartDiv{ + width: 740px; + height: 12px; + background: #F0F5FF; + border-radius: 2px; + display: flex; +} +.structDiv{ + width: 100px; + height: 14px; + font-family: SourceHanSansCN-Regular; + font-weight: 400; + font-size: 14px; + color: #3E434E; + letter-spacing: 0; + line-height: 14px; + text-align: center; +} +.rankDiv{ + width: 34.48px; + height: 17.67px; + text-align: center; + span{ + + width: 13px; + height: 16px; + font-family: D-DIN-Italic; + font-weight: Italic; + font-size: 16px; + color: #7C8DB6; + letter-spacing: 0; + + } +} +.rankBackDiv{ + // width: 34.48px; + // height: 9px; + // background-image: linear-gradient(270deg, #f957571f 0%, #f32c2c57 93%); + // margin-bottom: 0; +} +.alarms{ + width: 282px; + height: 10px; + background-image: linear-gradient(116deg, #2c66f329 8%, #2C66F3 100%); + box-shadow: inset 2px 0 0 0 #2C66F3; +} +.dealAlarms{ + width: 108px; + height: 10px; + background-image: linear-gradient(270deg, #fbac3229 1%, #FBAC32 100%); + box-shadow: inset -2px 0 0 0 #FBAC32; +} + + + + From b94eba8ed7165e2b3aae6b7c40ba9f8eb5cd39a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zhaobing=E2=80=99?= Date: Wed, 30 Aug 2023 19:09:48 +0800 Subject: [PATCH 02/16] =?UTF-8?q?feat:=E5=91=8A=E8=AD=A6top20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/projectGroup/actions/group.js | 14 +++ .../projectGroup/containers/bigscreen.jsx | 90 +++++++++++-------- .../src/sections/projectGroup/style.less | 13 +++ web/client/src/utils/webapi.js | 1 + 4 files changed, 80 insertions(+), 38 deletions(-) diff --git a/web/client/src/sections/projectGroup/actions/group.js b/web/client/src/sections/projectGroup/actions/group.js index f60a956..aa351e8 100644 --- a/web/client/src/sections/projectGroup/actions/group.js +++ b/web/client/src/sections/projectGroup/actions/group.js @@ -55,4 +55,18 @@ export function groupStatisticOnline (query = {}) { msg: { error: "获取项目分组在线率统计信息失败" }, reducer: { name: "groupStatisticOnline", params: { noClear: true } }, }); +} + + +export function groupStatisticAlarm (query = {}) { + return (dispatch) => basicAction({ + type: "get", + dispatch: dispatch, + query, + actionType: "GET_STATISTICALARM", + url: `${ApiTable.groupStatisticAlarm}`, + msg: { error: "获获取项目分组告警统计信息失败" }, + reducer: { name: "groupStatisticAlarm", + params: { noClear: true } }, + }); } \ No newline at end of file diff --git a/web/client/src/sections/projectGroup/containers/bigscreen.jsx b/web/client/src/sections/projectGroup/containers/bigscreen.jsx index 754bbb3..5374a1b 100644 --- a/web/client/src/sections/projectGroup/containers/bigscreen.jsx +++ b/web/client/src/sections/projectGroup/containers/bigscreen.jsx @@ -15,12 +15,22 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou const [alarmData,setAlarmData]=useState()//第三项之后的数据 const [biggest,setBiggest]=useState()//最大的刻度值 + const [mockData,setMockData]=useState()//所有的告警数据 + const [xData,setXData]=useState([])//横坐标 useEffect(() => { let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId - console.log(); dispatch(actions.projectGroup.groupStatisticOnline({ groupId })) + dispatch(actions.projectGroup.groupStatisticAlarm({groupId})).then(res=>{ + if(res.success){ + setMockData(res.data) + } + }) }, []) - + useEffect(()=>{ + // let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId + + + },[]) useEffect(()=>{ const domProject1 = document.getElementById("alarmRank"); if (domProject1) { @@ -34,47 +44,49 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou } }) useEffect(()=>{ - const maxCombinedValue = mockData.reduce((max, item) => { + const maxCombinedValue = mockData?.reduce((max, item) => { const combinedMax = Math.max(item.alarmCount, item.dealAlarmCount); if (combinedMax > max) { return combinedMax; } return max; }, -Infinity) - setBiggest(maxCombinedValue) - + const bigD= Math.ceil(maxCombinedValue/50)*50 + 50,40,30,20,10,0 + setXData([bigD,(bigD-bigD/5),(bigD-bigD*2/5),(bigD-bigD*3/5),(bigD-bigD*4/5),0,(bigD-bigD*4/5),(bigD-bigD*3/5),(bigD-bigD*2/5),(bigD-bigD/5),bigD]) + setBiggest(bigD) },[]) - const mockData=[ - {id: 1,name: '测试结构物测试结构物',alarmCount: 200,dealAlarmCount: 23}, - {id: 2,name: '测试结构物2',alarmCount: 150,dealAlarmCount: 22}, - {id: 3,name: '测试结构物3',alarmCount: 140,dealAlarmCount: 21}, - {id: 4,name: '测试结构物4',alarmCount: 120,dealAlarmCount: 23}, - {id: 5,name: '测试结构物5',alarmCount: 110,dealAlarmCount: 22}, - {id: 6,name: '测试结构物6',alarmCount: 109,dealAlarmCount: 21}, - {id: 7,name: '测试结构物7',alarmCount: 100,dealAlarmCount: 23}, - {id: 8,name: '测试结构物8',alarmCount: 99,dealAlarmCount: 22}, - {id: 9,name: '测试结构物9',alarmCount: 98,dealAlarmCount: 21}, - {id: 10,name: '测试结构物10',alarmCount: 97,dealAlarmCount: 23}, - {id: 11,name: '测试结构物11',alarmCount: 96,dealAlarmCount: 22}, - {id: 12,name: '测试结构物12',alarmCount: 95,dealAlarmCount: 21}, - {id: 13,name: '测试结构物13',alarmCount: 100,dealAlarmCount: 23}, - {id: 14,name: '测试结构物14',alarmCount: 49,dealAlarmCount: 22}, - {id: 15,name: '测试结构物15',alarmCount: 48,dealAlarmCount: 21}, - {id: 16,name: '测试结构物16',alarmCount: 47,dealAlarmCount: 23}, - {id: 17,name: '测试结构物17',alarmCount: 46,dealAlarmCount: 22}, - {id: 18,name: '测试结构物18',alarmCount: 45,dealAlarmCount: 21}, - {id: 19,name: '测试结构物19',alarmCount: 30,dealAlarmCount: 22}, - {id: 20,name: '测试结构物20',alarmCount: 29,dealAlarmCount: 21}, - {id: 21,name: '测试结构物21',alarmCount: 28,dealAlarmCount: 23}, - {id: 22,name: '测试结构物22',alarmCount: 27,dealAlarmCount: 22}, - {id: 23,name: '测试结构物23',alarmCount: 26,dealAlarmCount: 21}, - ] + // const mockData=[ + // {id: 1,name: '测试结构物测试结构物',alarmCount: 200,dealAlarmCount: 23}, + // {id: 2,name: '测试结构物2',alarmCount: 300,dealAlarmCount: 22}, + // {id: 3,name: '测试结构物3',alarmCount: 140,dealAlarmCount: 21}, + // {id: 4,name: '测试结构物4',alarmCount: 120,dealAlarmCount: 23}, + // {id: 5,name: '测试结构物5',alarmCount: 110,dealAlarmCount: 22}, + // {id: 6,name: '测试结构物6',alarmCount: 109,dealAlarmCount: 21}, + // {id: 7,name: '测试结构物7',alarmCount: 100,dealAlarmCount: 23}, + // {id: 8,name: '测试结构物8',alarmCount: 99,dealAlarmCount: 22}, + // {id: 9,name: '测试结构物9',alarmCount: 98,dealAlarmCount: 21}, + // {id: 10,name: '测试结构物10',alarmCount: 97,dealAlarmCount: 23}, + // {id: 11,name: '测试结构物11',alarmCount: 96,dealAlarmCount: 22}, + // {id: 12,name: '测试结构物12',alarmCount: 95,dealAlarmCount: 21}, + // {id: 13,name: '测试结构物13',alarmCount: 100,dealAlarmCount: 23}, + // {id: 14,name: '测试结构物14',alarmCount: 49,dealAlarmCount: 22}, + // {id: 15,name: '测试结构物15',alarmCount: 48,dealAlarmCount: 21}, + // {id: 16,name: '测试结构物16',alarmCount: 47,dealAlarmCount: 23}, + // {id: 17,name: '测试结构物17',alarmCount: 46,dealAlarmCount: 22}, + // {id: 18,name: '测试结构物18',alarmCount: 45,dealAlarmCount: 21}, + // {id: 19,name: '测试结构物19',alarmCount: 30,dealAlarmCount: 22}, + // {id: 20,name: '测试结构物20',alarmCount: 29,dealAlarmCount: 21}, + // {id: 21,name: '测试结构物21',alarmCount: 28,dealAlarmCount: 23}, + // {id: 22,name: '测试结构物22',alarmCount: 27,dealAlarmCount: 22}, + // {id: 23,name: '测试结构物23',alarmCount: 26,dealAlarmCount: 21}, + // ] useEffect(()=>{ - if(mockData.length>3&&mockData.length<21){ + if(mockData&&mockData.length>3&&mockData.length<21){ const newArray = mockData.slice(3) setAlarmData(newArray) } - if(mockData.length>21){ + if(mockData&&mockData.length>21){ //数据大于20的话,取前20 const newArray = mockData.slice(3,20) setAlarmData(newArray) @@ -174,7 +186,7 @@ useEffect(()=>{
-
+ {mockData&&mockData.length>0 ?(
超阈值个数
@@ -184,7 +196,7 @@ useEffect(()=>{
- {mockData[0]?(
+ {mockData&&mockData[0]?(
@@ -199,7 +211,7 @@ useEffect(()=>{
):'' } - {mockData[1]?(
+ {mockData&&mockData[1]?(
@@ -214,7 +226,7 @@ useEffect(()=>{
):'' } - {mockData[2]?(
+ {mockData&&mockData[2]?(
@@ -253,9 +265,11 @@ useEffect(()=>{ }
- + {xData?.map(item=>{ + return
{item}
+ })}
-
+
):''}
diff --git a/web/client/src/sections/projectGroup/style.less b/web/client/src/sections/projectGroup/style.less index 522cf4b..dbb1989 100644 --- a/web/client/src/sections/projectGroup/style.less +++ b/web/client/src/sections/projectGroup/style.less @@ -90,6 +90,19 @@ background-image: linear-gradient(270deg, #fbac3229 1%, #FBAC32 100%); box-shadow: inset -2px 0 0 0 #FBAC32; } +.scale{ + display: flex; + width: 740px; + height: 18px; + font-family: DIN-Regular; + font-weight: 400; + font-size: 12px; + color: #5A6685; + letter-spacing: 0; + text-align: center; + justify-content: space-between; + margin-left: 134.48px; +} diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 22281a0..3bfba9a 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -40,6 +40,7 @@ export const ApiTable = { projectGroup: 'project/group', groupStatistic: 'project/group/statistic', groupStatisticOnline: 'project/group/statistic/online', + groupStatisticAlarm:'project/group/statistic/alarm', //告警 getProjectPoms: 'project/poms', //获取已绑定项目 From 582352c40d059274156d36205c940e998976b5a4 Mon Sep 17 00:00:00 2001 From: wenlele Date: Thu, 31 Aug 2023 08:59:53 +0800 Subject: [PATCH 03/16] =?UTF-8?q?UI=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/models/structure_off.js | 18 ++ .../components/customProjGroupModal.jsx | 2 +- .../projectGroup/containers/bigscreen.jsx | 176 +++++++++++++++--- 3 files changed, 164 insertions(+), 32 deletions(-) diff --git a/api/app/lib/models/structure_off.js b/api/app/lib/models/structure_off.js index 153f6a5..a923f4d 100644 --- a/api/app/lib/models/structure_off.js +++ b/api/app/lib/models/structure_off.js @@ -34,6 +34,24 @@ module.exports = dc => { field: "offline", autoIncrement: false }, + totnum: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "测点总数", + primaryKey: false, + field: "totnum", + autoIncrement: false + }, + offnum: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "离线个数", + primaryKey: false, + field: "offnum", + autoIncrement: false + }, offtime: { type: DataTypes.STRING, allowNull: false, diff --git a/web/client/src/layout/components/header/components/customProjGroupModal.jsx b/web/client/src/layout/components/header/components/customProjGroupModal.jsx index 41afab4..5b40557 100644 --- a/web/client/src/layout/components/header/components/customProjGroupModal.jsx +++ b/web/client/src/layout/components/header/components/customProjGroupModal.jsx @@ -27,7 +27,7 @@ const CustomProjGroupModal = (props) => { if (editData) { stoData.id = editData.id } - dispatch(actions.projectGroupAC.editProjectGroup(stoData)).then((res) => { + dispatch(actions.projectGroup.editProjectGroup(stoData)).then((res) => { if (res.success) { cancel({ refresh: true }) form.current?.reset() diff --git a/web/client/src/sections/projectGroup/containers/bigscreen.jsx b/web/client/src/sections/projectGroup/containers/bigscreen.jsx index 9eea52a..50f304d 100644 --- a/web/client/src/sections/projectGroup/containers/bigscreen.jsx +++ b/web/client/src/sections/projectGroup/containers/bigscreen.jsx @@ -1,4 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; +import { Skeleton, Button, Pagination, Select, Popconfirm, Table, Tooltip } from '@douyinfe/semi-ui'; import { connect } from 'react-redux'; import Header from '../components/header'; import Body from '../components/body' @@ -6,18 +7,104 @@ import Card from '../components/card' import '../style.less' import ReactECharts from 'echarts-for-react'; import moment from 'moment' +import PerfectScrollbar from "perfect-scrollbar"; - +let interrupt const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, groupStatisticOnline }) => { + const [InterruptRank, setInterruptRank] = useState([]) + const [online, setOnline] = useState([]) + const [value, setValue] = useState([]) + const [time, setTime] = useState([]) + + + useEffect(() => { let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId console.log(); - dispatch(actions.projectGroup.groupStatisticOnline({ groupId })) + statisticOnline(groupId) }, []) - console.log(groupStatisticOnline); + let statisticOnline = (groupId) => { + dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { + console.log(res); + if (res.success) { + let Interrupt = [] + res.payload.data?.forEach(v => { + if (v.offline?.id) { + Interrupt.push({ name: v.name, ...v.offline }) + } + }) + Interrupt = Interrupt?.sort((a, b) => b.offline - a.offline) + setInterruptRank(Interrupt) + setOnline(res.payload.data || []) + setValue(res.payload.data?.map(v => v.id) || []) + // eChartsData(res.payload.data || [], res.payload.data?.map(v => v.id) || []) + } + }) + } + + // const eChartsData = (data, value) => { + // // 调用函数获取时间节点数组 + // let timeNodes = getTimeNodes() + // let dataList = [] + // data?.forEach(v => { + // if (value?.includes(v.id)) { + // v.timeNodes = [] + // timeNodes?.forEach(s => { + // if (v.online?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == s)?.structure) { + // v.timeNodes.push([s,]) + // } else { + // v.timeNodes.push([s,null]) + // } + // }) + // } + // }) + + // } + + + + + function formatDate (date) { + var year = date.getFullYear(); + var month = String(date.getMonth() + 1).padStart(2, '0'); + var day = String(date.getDate()).padStart(2, '0'); + var hour = String(date.getHours()).padStart(2, '0'); + + return year + '-' + month + '-' + day + ' ' + hour; + } + + function getTimeNodes () { + var currentTime = new Date(); // 当前时间 + var timeNodes = []; + + for (var i = 0; i < 24; i++) { + var timeNode = formatDate(currentTime); + timeNodes.push(timeNode); + + currentTime.setHours(currentTime.getHours() - 1); // 减去1小时 + } + + return timeNodes; + } + + + + + function handleRow (record, index) {//斑马条纹 + // 给偶数行设置斑马纹 + if (index % 2 === 0) { + return { + style: { + background: '#F6F9FF', + } + }; + } else { + return {}; + } + } return (
@@ -40,52 +127,58 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
-
- +
+ {/*
*/} + [moment(f.collect_time).format('YYYY-MM-DD HH'), f.rate]) || [] + data: v.online?.map(f => [moment(f.collect_time).format('YYYY-MM-DD HH'), f.rate.toFixed(1)]) || [] })) || [] }} notMerge={true} @@ -599,7 +600,7 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
- {mockData && mockData.length > 0 ? (
@@ -620,10 +621,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{mockData[0]?.name?.length > 5 ? {mockData[0]?.name.substring(0, 5) + '...'} : mockData[0]?.name}
-
0? ((mockData[0].alarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((mockData[0].alarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
-
0? ((mockData[0].dealAlarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((mockData[0].dealAlarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
) : '' @@ -635,10 +636,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{mockData[1]?.name?.length > 5 ? {mockData[1]?.name.substring(0, 5) + '...'} : mockData[0]?.name}
-
0? ((mockData[1].alarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((mockData[1].alarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
-
0? ((mockData[1].dealAlarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((mockData[1].dealAlarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
) : '' @@ -650,10 +651,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{mockData[2]?.name?.length > 5 ? {mockData[2]?.name.substring(0, 5) + '...'} : mockData[0]?.name}
-
0? ((mockData[2].alarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((mockData[2].alarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
-
0? ((mockData[2].dealAlarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((mockData[2].dealAlarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
) : '' @@ -667,10 +668,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{item.name?.length > 5 ? {item.name.substring(0, 5) + '...'} : item.name}
-
0?((item.alarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((item.alarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
-
0? ((item.dealAlarmCount / biggest) * 100 || '%'):0), height: '100%' }}>
+
0 ? ((item.dealAlarmCount / biggest) * 100 || '%') : 0), height: '100%' }}>
From b3cccd6e14ef897cea7bafdf2f29148ee6769294 Mon Sep 17 00:00:00 2001 From: wenlele Date: Fri, 1 Sep 2023 19:46:43 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E4=B8=AD=E6=96=AD=E6=97=B6=E9=95=BF?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projectGroup/containers/bigscreen.jsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/web/client/src/sections/projectGroup/containers/bigscreen.jsx b/web/client/src/sections/projectGroup/containers/bigscreen.jsx index cf98283..781dfc8 100644 --- a/web/client/src/sections/projectGroup/containers/bigscreen.jsx +++ b/web/client/src/sections/projectGroup/containers/bigscreen.jsx @@ -597,11 +597,22 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou {InterruptRank?.map((c, index) => { let title if (c.offline) { - if (c.offline >= 1440) title = Math.floor(c.offline / 1440) + "天" - if ((c.offline % 1440) >= 60) title = title + Math.floor(c.offline % 1440 / 60) + "时" - if (c.offline % 1440 % 60) title = title + c.offline % 1440 % 60 + "分" + if (c.offline >= 1440 && Math.floor(c.offline / 1440)) title = Math.floor(c.offline / 1440) + "天" + if ((c.offline % 1440) >= 60 && Math.floor(c.offline % 1440 / 60)) { + if (title) { + title = title + Math.floor(c.offline % 1440 / 60) + "时" + } else { + title = Math.floor(c.offline % 1440 / 60) + "时" + } + } + if (c.offline % 1440 % 60) { + if (title) { + title = title + c.offline % 1440 % 60 + "分" + } else { + title = c.offline % 1440 % 60 + "分" + } + } } - return
{c.name}
{title}
From 2e443ac589e1f3b6e5cab4ad7302140a9c2dc60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zhaobing=E2=80=99?= Date: Fri, 1 Sep 2023 19:49:29 +0800 Subject: [PATCH 15/16] =?UTF-8?q?feat=EF=BC=9Afix=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projectGroup/containers/bigscreen.jsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/web/client/src/sections/projectGroup/containers/bigscreen.jsx b/web/client/src/sections/projectGroup/containers/bigscreen.jsx index 781dfc8..f5a7481 100644 --- a/web/client/src/sections/projectGroup/containers/bigscreen.jsx +++ b/web/client/src/sections/projectGroup/containers/bigscreen.jsx @@ -519,10 +519,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{mockData[0]?.name?.length > 5 ? {mockData[0]?.name.substring(0, 5) + '...'} : mockData[0]?.name}
-
0 ? ((mockData[0].alarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((mockData[0].dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
-
0 ? ((mockData[0].dealAlarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((mockData[0].alarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
) : '' @@ -534,10 +534,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{mockData[1]?.name?.length > 5 ? {mockData[1]?.name.substring(0, 5) + '...'} : mockData[0]?.name}
-
0 ? ((mockData[1].alarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((mockData[1].dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
-
0 ? ((mockData[1].dealAlarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((mockData[1].alarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
) : '' @@ -549,10 +549,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{mockData[2]?.name?.length > 5 ? {mockData[2]?.name.substring(0, 5) + '...'} : mockData[0]?.name}
-
0 ? ((mockData[2].alarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((mockData[2].dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
-
0 ? ((mockData[2].dealAlarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((mockData[2].alarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
) : '' @@ -566,10 +566,10 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou
{item.name?.length > 5 ? {item.name.substring(0, 5) + '...'} : item.name}
-
0 ? ((item.alarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0?((item.dealAlarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
-
0 ? ((item.dealAlarmCount / biggest) * 100 + '%') : 0), height: '100%' }}>
+
0? ((item.alarmCount / biggest) * 100 + '%'):0), height: '100%' }}>
From 6bdde941afeedf111d5f9974c933d65fcc06032f Mon Sep 17 00:00:00 2001 From: wenlele Date: Mon, 4 Sep 2023 10:07:51 +0800 Subject: [PATCH 16/16] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E7=8E=87=E5=92=8C=E4=B8=AD=E6=96=AD=E6=8E=92=E5=90=8D=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AE=9A=E6=97=B6=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projectGroup/containers/bigscreen.jsx | 162 ++---------------- 1 file changed, 14 insertions(+), 148 deletions(-) diff --git a/web/client/src/sections/projectGroup/containers/bigscreen.jsx b/web/client/src/sections/projectGroup/containers/bigscreen.jsx index 781dfc8..8ab2c4e 100644 --- a/web/client/src/sections/projectGroup/containers/bigscreen.jsx +++ b/web/client/src/sections/projectGroup/containers/bigscreen.jsx @@ -34,6 +34,8 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou useEffect(() => { let groupId = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId statisticOnline(groupId) + //计算当前时间,定时更新 + timeRequest(groupId) dispatch(actions.projectGroup.groupStatisticAlarm({ groupId })).then(res => { if (res.success) { setMockData(res.payload.data) @@ -63,86 +65,7 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou } }, []) - // const mockData=[ - // { - // "name": "西腰墩水库", - // "id": 2957, - // "alarmCount": 6, - // "dealAlarmCount": 0 - // }, - // { - // "name": "智慧排涝-雄溪河绿新桥南侧智能分流井排口", - // "id": 2966, - // "alarmCount": 1, - // "dealAlarmCount": 0 - // }, - // { - // "name": "智慧排涝-雄溪河东侧绿地山庄红色廊厅排口", - // "id": 2967, - // "alarmCount": 3, - // "dealAlarmCount": 0 - // }, - // { - // "name": "鲍家湖水库", - // "id": 2973, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "长春市九台区水旱灾害防御中心小型水库", - // "id": 2975, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "重庆观音峡项目", - // "id": 2977, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "杭州宝坞口隧道监测", - // "id": 2988, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "大湖湾水库", - // "id": 3004, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "上高高情远韵驿站智慧公厕", - // "id": 3007, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "大湖湾水库", - // "id": 3004, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "上高高情远韵驿站智慧公厕", - // "id": 3007, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "大湖湾水库", - // "id": 3004, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // { - // "name": "上高高情远韵驿站智慧公厕", - // "id": 3007, - // "alarmCount": 0, - // "dealAlarmCount": 0 - // }, - // ] + useEffect(() => { const overview = document.getElementById("alarmRank"); if (overview) { @@ -192,31 +115,6 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou } }, [mockData]) - // const mockData=[ - // {id: 1,name: '测试结构物测试结构物',alarmCount: 200,dealAlarmCount: 23}, - // {id: 2,name: '测试结构物2',alarmCount: 300,dealAlarmCount: 22}, - // {id: 3,name: '测试结构物3',alarmCount: 140,dealAlarmCount: 21}, - // {id: 4,name: '测试结构物4',alarmCount: 120,dealAlarmCount: 23}, - // {id: 5,name: '测试结构物5',alarmCount: 110,dealAlarmCount: 22}, - // {id: 6,name: '测试结构物6',alarmCount: 109,dealAlarmCount: 21}, - // {id: 7,name: '测试结构物7',alarmCount: 100,dealAlarmCount: 23}, - // {id: 8,name: '测试结构物8',alarmCount: 99,dealAlarmCount: 22}, - // {id: 9,name: '测试结构物9',alarmCount: 98,dealAlarmCount: 21}, - // {id: 10,name: '测试结构物10',alarmCount: 97,dealAlarmCount: 23}, - // {id: 11,name: '测试结构物11',alarmCount: 96,dealAlarmCount: 22}, - // {id: 12,name: '测试结构物12',alarmCount: 95,dealAlarmCount: 21}, - // {id: 13,name: '测试结构物13',alarmCount: 100,dealAlarmCount: 23}, - // {id: 14,name: '测试结构物14',alarmCount: 49,dealAlarmCount: 22}, - // {id: 15,name: '测试结构物15',alarmCount: 48,dealAlarmCount: 21}, - // {id: 16,name: '测试结构物16',alarmCount: 47,dealAlarmCount: 23}, - // {id: 17,name: '测试结构物17',alarmCount: 46,dealAlarmCount: 22}, - // {id: 18,name: '测试结构物18',alarmCount: 45,dealAlarmCount: 21}, - // {id: 19,name: '测试结构物19',alarmCount: 30,dealAlarmCount: 22}, - // {id: 20,name: '测试结构物20',alarmCount: 29,dealAlarmCount: 21}, - // {id: 21,name: '测试结构物21',alarmCount: 28,dealAlarmCount: 23}, - // {id: 22,name: '测试结构物22',alarmCount: 27,dealAlarmCount: 22}, - // {id: 23,name: '测试结构物23',alarmCount: 26,dealAlarmCount: 21}, - // ] let statisticOnline = (groupId) => { dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => { if (res.success) { @@ -230,53 +128,21 @@ const Bigscreen = ({ dispatch, actions, user, match, history, clientHeight, grou setInterruptRank(Interrupt) setOnline(res.payload.data?.slice(0, 10) || []) setValue(res.payload.data?.map(v => v.id)?.slice(0, 10) || []) - // eChartsData(res.payload.data || [], res.payload.data?.map(v => v.id) || []) } }) } - // const eChartsData = (data, value) => { - // // 调用函数获取时间节点数组 - // let timeNodes = getTimeNodes() - // let dataList = [] - // data?.forEach(v => { - // if (value?.includes(v.id)) { - // v.timeNodes = [] - // timeNodes?.forEach(s => { - // if (v.online?.find(d => moment(d.collect_time).format('YYYY-MM-DD HH') == s)?.structure) { - // v.timeNodes.push([s,]) - // } else { - // v.timeNodes.push([s,null]) - // } - // }) - // } - // }) - // } - - - - - function formatDate (date) { - var year = date.getFullYear(); - var month = String(date.getMonth() + 1).padStart(2, '0'); - var day = String(date.getDate()).padStart(2, '0'); - var hour = String(date.getHours()).padStart(2, '0'); - - return year + '-' + month + '-' + day + ' ' + hour; - } - - function getTimeNodes () { - var currentTime = new Date(); // 当前时间 - var timeNodes = []; - - for (var i = 0; i < 24; i++) { - var timeNode = formatDate(currentTime); - timeNodes.push(timeNode); - - currentTime.setHours(currentTime.getHours() - 1); // 减去1小时 - } - - return timeNodes; + const timeRequest = (groupId) => { + // 获取当前时间 + const currentTime = moment(); + // 获取下一个小时的时间 + const nextHour = moment().add(1, 'hour').startOf('hour'); + // 计算分钟差 + const minuteDifference = nextHour.diff(currentTime, 'minutes'); + setTimeout(function () { + statisticOnline(groupId) + timeRequest(groupId) + }, 1000 * 60 * (minuteDifference + 1 || 61)); }