From f63477656ab3914380c0e36e5e66a1b8662e75cf Mon Sep 17 00:00:00 2001 From: CODE <1650192445@qq.com> Date: Wed, 30 Aug 2023 09:26:38 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/models/alarm_service_type.js | 76 ++++---- .../models/equipment_maintenance_record.js | 164 ++++++++-------- api/app/lib/models/project_correlation.js | 184 +++++++++--------- 3 files changed, 212 insertions(+), 212 deletions(-) diff --git a/api/app/lib/models/alarm_service_type.js b/api/app/lib/models/alarm_service_type.js index 2ec27b8..fbcb030 100644 --- a/api/app/lib/models/alarm_service_type.js +++ b/api/app/lib/models/alarm_service_type.js @@ -2,42 +2,42 @@ 'use strict'; module.exports = dc => { - const DataTypes = dc.ORM; - const sequelize = dc.orm; - const AlarmServiceType = sequelize.define("alarmServiceType", { - id: { - type: DataTypes.INTEGER, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: true, - field: "id", - autoIncrement: true, - unique: "alarm_service_type_id_uindex" - }, - name: { - type: DataTypes.STRING, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: false, - field: "name", - autoIncrement: false - }, - typeNumber: { - type: DataTypes.INTEGER, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: false, - field: "type_number", - autoIncrement: false - } - }, { - tableName: "alarm_service_type", - comment: "", - indexes: [] - }); - dc.models.AlarmServiceType = AlarmServiceType; - return AlarmServiceType; + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const AlarmServiceType = sequelize.define("alarmServiceType", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true, + unique: "alarm_service_type_id_uindex" + }, + name: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "name", + autoIncrement: false + }, + typeNumber: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "type_number", + autoIncrement: false + } + }, { + tableName: "alarm_service_type", + comment: "", + indexes: [] + }); + dc.models.AlarmServiceType = AlarmServiceType; + return AlarmServiceType; }; \ No newline at end of file diff --git a/api/app/lib/models/equipment_maintenance_record.js b/api/app/lib/models/equipment_maintenance_record.js index 61185d9..9ec07ee 100644 --- a/api/app/lib/models/equipment_maintenance_record.js +++ b/api/app/lib/models/equipment_maintenance_record.js @@ -3,86 +3,86 @@ 'use strict'; module.exports = dc => { - const DataTypes = dc.ORM; - const sequelize = dc.orm; - const EquipmentMaintenanceRecord = sequelize.define("equipmentMaintenanceRecord", { - id: { - type: DataTypes.INTEGER, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: true, - field: "id", - autoIncrement: true - }, - equipmentType: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "equipment_type", - autoIncrement: false - }, - equipmentCategory: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "equipment_category", - autoIncrement: false - }, - maintenanceReason: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "maintenance_reason", - autoIncrement: false - }, - solution: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "solution", - autoIncrement: false - }, - reportTime: { - type: DataTypes.DATE, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "report_time", - autoIncrement: false - }, - completedTime: { - type: DataTypes.DATE, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "completed_time", - autoIncrement: false - }, - status: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "status", - autoIncrement: false - } - }, { - tableName: "equipment_maintenance_record", - comment: "", - indexes: [] - }); - dc.models.EquipmentMaintenanceRecord = EquipmentMaintenanceRecord; - return EquipmentMaintenanceRecord; + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const EquipmentMaintenanceRecord = sequelize.define("equipmentMaintenanceRecord", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true + }, + equipmentType: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "equipment_type", + autoIncrement: false + }, + equipmentCategory: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "equipment_category", + autoIncrement: false + }, + maintenanceReason: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "maintenance_reason", + autoIncrement: false + }, + solution: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "solution", + autoIncrement: false + }, + reportTime: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "report_time", + autoIncrement: false + }, + completedTime: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "completed_time", + autoIncrement: false + }, + status: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "status", + autoIncrement: false + } + }, { + tableName: "equipment_maintenance_record", + comment: "", + indexes: [] + }); + dc.models.EquipmentMaintenanceRecord = EquipmentMaintenanceRecord; + return EquipmentMaintenanceRecord; }; \ No newline at end of file diff --git a/api/app/lib/models/project_correlation.js b/api/app/lib/models/project_correlation.js index b1b5990..66526cb 100644 --- a/api/app/lib/models/project_correlation.js +++ b/api/app/lib/models/project_correlation.js @@ -2,96 +2,96 @@ 'use strict'; module.exports = dc => { - const DataTypes = dc.ORM; - const sequelize = dc.orm; - const ProjectCorrelation = sequelize.define("projectCorrelation", { - id: { - type: DataTypes.INTEGER, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: true, - field: "id", - autoIncrement: true, - unique: "project_correlation_id_uindex" - }, - anxinProjectId: { - type: DataTypes.ARRAY(DataTypes.INTEGER), - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: false, - field: "anxin_project_id", - autoIncrement: false - }, - createTime: { - type: DataTypes.DATE, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: false, - field: "create_time", - autoIncrement: false - }, - createUser: { - type: DataTypes.INTEGER, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: false, - field: "create_user", - autoIncrement: false - }, - name: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "name", - autoIncrement: false - }, - pepProjectId: { - type: DataTypes.INTEGER, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "pep_project_id", - autoIncrement: false - }, - del: { - type: DataTypes.BOOLEAN, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "del", - autoIncrement: false - }, - updateTime: { - type: DataTypes.DATE, - allowNull: false, - defaultValue: null, - comment: null, - primaryKey: false, - field: "update_time", - autoIncrement: false - }, - mappingClass: { - type: DataTypes.STRING, - allowNull: true, - defaultValue: null, - comment: null, - primaryKey: false, - field: "mapping_class", - autoIncrement: false - }, - }, { - tableName: "project_correlation", - comment: "", - indexes: [] - }); - dc.models.ProjectCorrelation = ProjectCorrelation; - return ProjectCorrelation; + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const ProjectCorrelation = sequelize.define("projectCorrelation", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true, + unique: "project_correlation_id_uindex" + }, + anxinProjectId: { + type: DataTypes.ARRAY(DataTypes.INTEGER), + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "anxin_project_id", + autoIncrement: false + }, + createTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "create_time", + autoIncrement: false + }, + createUser: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "create_user", + autoIncrement: false + }, + name: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "name", + autoIncrement: false + }, + pepProjectId: { + type: DataTypes.INTEGER, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "pep_project_id", + autoIncrement: false + }, + del: { + type: DataTypes.BOOLEAN, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "del", + autoIncrement: false + }, + updateTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "update_time", + autoIncrement: false + }, + mappingClass: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "mapping_class", + autoIncrement: false + }, + }, { + tableName: "project_correlation", + comment: "", + indexes: [] + }); + dc.models.ProjectCorrelation = ProjectCorrelation; + return ProjectCorrelation; }; \ No newline at end of file From 0736cff456478470c84a7c3c2ace94f9902429c8 Mon Sep 17 00:00:00 2001 From: CODE <1650192445@qq.com> Date: Wed, 30 Aug 2023 10:45:54 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/project/group.js | 16 ++++++++++++++++ api/app/lib/routes/project/index.js | 3 +++ 2 files changed, 19 insertions(+) diff --git a/api/app/lib/controllers/project/group.js b/api/app/lib/controllers/project/group.js index bead78f..7bbc8ae 100644 --- a/api/app/lib/controllers/project/group.js +++ b/api/app/lib/controllers/project/group.js @@ -318,10 +318,26 @@ async function groupStatisticOnline (ctx) { } } +async function groupStatisticAlarm (ctx) { + try { + const { models } = ctx.fs.dc; + + ctx.status = 200; + ctx.body = [] + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + module.exports = { groupList, editGroup, delGroup, groupStatistic, groupStatisticOnline, + groupStatisticAlarm, }; \ No newline at end of file diff --git a/api/app/lib/routes/project/index.js b/api/app/lib/routes/project/index.js index 395f6c2..545d829 100644 --- a/api/app/lib/routes/project/index.js +++ b/api/app/lib/routes/project/index.js @@ -45,4 +45,7 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/project/group/statistic/online'] = { content: '获取项目分组在线率统计信息', visible: true }; router.get('/project/group/statistic/online', projectGroup.groupStatisticOnline); + + app.fs.api.logAttr['GET/project/group/statistic/alarm'] = { content: '获取项目分组告警统计信息', visible: true }; + router.get('/project/group/statistic/alarm', projectGroup.groupStatisticAlarm); }; \ No newline at end of file From 17d92ae3f4c2caa95397caf1f8ec8b051e7f0b65 Mon Sep 17 00:00:00 2001 From: CODE <1650192445@qq.com> Date: Wed, 30 Aug 2023 11:47:34 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/lib/controllers/project/group.js | 80 +++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/api/app/lib/controllers/project/group.js b/api/app/lib/controllers/project/group.js index 7bbc8ae..c9f0fbb 100644 --- a/api/app/lib/controllers/project/group.js +++ b/api/app/lib/controllers/project/group.js @@ -116,7 +116,7 @@ async function groupStatistic (ctx) { } }) - // 获取全部的 poms 项目id 并构建关系 + // 获取全部的 poms 项目id let pomsProjectIds = new Set() for (let group of progectGroupList) { for (let projectId of group.pomsProjectIds) { @@ -322,8 +322,84 @@ async function groupStatisticAlarm (ctx) { try { const { models } = ctx.fs.dc; + const { groupId } = ctx.query + const sequelize = ctx.fs.dc.orm + const { clickHouse } = ctx.app.fs + + const pomsProjectRes = await sequelize.query(` + SELECT project_correlation.anxin_project_id + FROM project_group + JOIN project_correlation + ON project_correlation.id = ANY(project_group.poms_project_ids) + WHERE project_group.id = ${groupId}; + `) + + const anxinProjectIds = new Set() + for (let pomsProject of (pomsProjectRes[0] || [])) { + for (let pid of pomsProject.anxin_project_id) + anxinProjectIds.add(pid) + } + + const strucIdRes = anxinProjectIds.size ? await clickHouse.anxinyun.query( + ` + SELECT * + FROM t_project_structure + WHERE project IN (${[...anxinProjectIds].join(',')}, -1) + ` + ).toPromise() : [] + let strucIds = new Set() + for (let struc of strucIdRes) { + strucIds.add(struc.structure) + } + let strucIdArr = Array.from(strucIds) + + const strucRes = strucIdArr.length ? await clickHouse.anxinyun.query( + ` + SELECT name, id FROM t_structure WHERE id IN (${[...strucIdArr].join(',')}); + ` + ).toPromise() : [] + + // 查一周内超阈值告警的个数 + strucIdArr = [1] + const alarmRes = strucIdArr.length ? await clickHouse.dataAlarm.query( + ` + SELECT StructureId,count(StructureId) AS alarmCount + FROM alarms + WHERE StructureId IN (${[...strucIdArr].join(',')}) + AND AlarmGroupUnit = 8 + AND StartTime >= '${moment().subtract(7, 'days').format('YYYY-MM-DD HH:mm:ss')}' + group by StructureId + ` + ).toPromise() : [] + + const alarmDealRes = strucIdArr.length ? await clickHouse.dataAlarm.query( + ` + SELECT StructureId,count(StructureId) AS alarmCount + FROM alarms + WHERE StructureId IN (${[...strucIdArr].join(',')}) + AND AlarmGroupUnit = 8 + AND State = 4 + AND StartTime >= '${moment().subtract(30, 'days').format('YYYY-MM-DD HH:mm:ss')}' + group by StructureId + ` + ).toPromise() : [] + + for (let struc of strucRes) { + let corAlarm = alarmRes.find((o) => o.StructureId == struc.id) + let corDealAlarm = alarmDealRes.find((o) => o.StructureId == struc.id) + struc.alarmCount = corAlarm ? corAlarm.alarmCount : 0 + struc.dealAlarmCount = corDealAlarm ? corDealAlarm.alarmCount : 0 + } + strucRes.sort((a, b) => b.alarmCount - a.alarmCount) + ctx.status = 200; - ctx.body = [] + ctx.body = strucRes; + // ctx.body = [{ + // id: 1, + // name: '测试结构物1', + // alarmCount: 128, + // dealAlarmCount: 23 + // }]; } catch (error) { ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.status = 400; 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 4/5] =?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 5/5] =?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', //获取已绑定项目