From 2a5952da966b72d013e560c9fb3808e65ea7d196 Mon Sep 17 00:00:00 2001 From: wenlele Date: Fri, 17 Mar 2023 10:30:56 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/.vscode/launch.json | 5 +- api/app/lib/controllers/project/index.js | 40 ++++- api/app/lib/schedule/alarms_push.js | 154 +++++++++++++++++- .../sections/install/containers/system.jsx | 63 ++++--- 4 files changed, 234 insertions(+), 28 deletions(-) diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index b93dda7..a12977d 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -44,6 +44,7 @@ "--clickHouseUrl http://10.8.30.161", // "--clickHouseUrl https://clickhouse01.anxinyun.cn/play", "--clickHousePort 30123", + // "--clickHousePort 8123", // 似乎不能传空 先注释 * 2 // "--clickHouseUser ", // "--clickHousePassword ", @@ -55,12 +56,12 @@ // "--clickHouseDataAlarm default", // "--clickHouseIot iot", // 测试 - "--clickHouseAnxincloud anxinyun88", + "--clickHouseAnxincloud anxinyun", "--clickHousePepEmis pepca8", "--clickHouseProjectManage peppm", "--clickHouseVcmp video_access_dev", "--clickHouseDataAlarm default", - "--clickHouseIot iot", + "--clickHouseIot iota", "--confirmAlarmAnxinUserId 1", "--vcmpAppId 5048b08d-c449-4d7f-b1ec-f741012aefe8", "--vcmpAppSecret 5ba8c0ab-9fbd-4f07-9817-c48017c3cbad", diff --git a/api/app/lib/controllers/project/index.js b/api/app/lib/controllers/project/index.js index 45d0f77..6d7802c 100644 --- a/api/app/lib/controllers/project/index.js +++ b/api/app/lib/controllers/project/index.js @@ -23,11 +23,12 @@ async function pomsProject (ctx) { const models = ctx.fs.dc.models; const { clickHouse } = ctx.app.fs const { userId, pepUserId, userInfo, pepUserInfo } = ctx.fs.api - const { limit, page, global, pepId } = ctx.query + const { limit, page, global, pepId, keyword } = ctx.query let findOption = { where: { - del: false + del: false, + // $or:[] }, order: [['updateTime', 'desc']], distinct: true, @@ -47,6 +48,40 @@ async function pomsProject (ctx) { if (page && limit) { findOption.offset = page * limit } + if (keyword) { + const project = await clickHouse.projectManage.query( + ` + SELECT + t_pim_project.id AS id, + t_pim_project.project_name AS project_name, + t_pim_project.isdelete AS isdelete, + t_pim_project_construction.construction_status_id AS construction_status_id, + t_pim_project_state.construction_status AS construction_status + FROM t_pim_project + LEFT JOIN t_pim_project_construction + ON t_pim_project.id = t_pim_project_construction.project_id + LEFT JOIN t_pim_project_state + ON t_pim_project_construction.construction_status_id = t_pim_project_state.id + WHERE project_name LIKE '%${keyword}%' + ` + ).toPromise() || [] + const anxinProjectRes = await clickHouse.anxinyun.query( + `SELECT id,"name", + project_state AS projectState + FROM t_project + WHERE name LIKE '%${keyword}%'`).toPromise() + || [] + let projectId = project.map(v => v.id) + let anxinProjectId = anxinProjectRes.map(v => v.id) + + findOption.where.$or = [ + { name: { $like: `%${keyword}%` } }, + { pepProjectId: { $in: projectId } }] + if (projectId.length > 0) { + findOption.where.$or.push({ anxinProjectId: { $contains: anxinProjectId } }) + } + + } const proRes = await models.ProjectCorrelation.findAndCountAll(findOption) @@ -85,6 +120,7 @@ async function pomsProject (ctx) { ` ).toPromise() : [] + const pepProjectRes = pepProjectIds.size ? await clickHouse.projectManage.query( ` diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index c1a5e13..da54a83 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -1,7 +1,7 @@ const moment = require('moment') let isDev = false -// isDev = true +// let isDev = true let proDebug = false proDebug = true @@ -19,6 +19,7 @@ module.exports = function (app, opts) { const { apMergeDeVeAnxinProjectId = '' } = opts const { clickHouse } = app.fs const { database: anxinyun } = clickHouse.anxinyun.opts.config + const { database: dataAlarm } = clickHouse.dataAlarm.opts.config const { pushBySms, pushByEmail, sendNoticeToWeb } = app.fs.utils const curMinOfYear = moment().diff(moment().startOf('year'), 'minutes') const configListRes = await models.AlarmPushConfig.findAll({ @@ -68,11 +69,21 @@ module.exports = function (app, opts) { if (!minute && minute != 0) { return minute } + let title = '' let dm = 24 * 60 let d = Math.floor(minute / dm) let h = Math.floor(minute % dm / 60) let m = (minute % dm) % 60 - return `${d}天${h}时${m}分` + if (d) { + title = d + '天' + } + if (h) { + title = title + h + '时' + } + if (h) { + title = title + m + '分' + } + return title } for (let { dataValues: c } of configListRes) { @@ -167,7 +178,8 @@ module.exports = function (app, opts) { // !开发测试用的数据 if (isDev) { - searchStrucIds = searchStrucIds.concat([991, 1052, 700]) + // searchStrucIds = searchStrucIds.concat([991, 1052, 700]) + searchStrucIds = searchStrucIds.concat([27, 4003, 700]) } if (searchStrucIds.length) { @@ -541,6 +553,80 @@ module.exports = function (app, opts) { } },] + let dataLnterruptTitle = [{ + n: '项目', + k: '', + v: pepProjectName + }, { + n: '结构物', + k: '', + f: (d) => { + return (strucMap[d.StructureId] || { name: '' }).name + // return (strucListRes.find(s => s.id == d.StructureId) || { name: '' }).name + } + }, { + n: '监测因素(中断比例)', + k: '', + f: (d) => { + // d.factor.join('') + // console.log(21211231131,d.factor); + let data=[] + d.factor.map(f => data.push(f.name + '(' + f.breakData + '/' + f.sum + ')')) + return data.join('
') + } + }, { + n: '告警源名称', + k: 'SourceName' + }, { + n: '告警源类型', + k: '', + f: (d) => { + switch (d.SourceTypeId) { + case 0: + return 'DTU' + case 1: + return '传感器' + case 2: + return '测点' + default: + return '' + } + } + }, { + n: '告警信息', + k: 'AlarmContent' + }, { + n: '告警等级(当前)', + k: '', + f: (d) => { + switch (d.CurrentLevel) { + case 1: + return '一级' + case 2: + return '二级' + case 3: + return '三级' + default: + return '' + } + } + }, { + n: '持续时间', + k: '', + f: (d) => { + return d.StartTime ? + '超过' + calcMinute2DHM(moment().diff(moment(d.StartTime), 'minutes')) : '' + } + }, + { + n: '中断时间', + k: '', + f: (d) => { + return d.StartTime ? + moment(d.StartTime).format('YYYY-MM-DD HH:mm:ss') : '' + } + },] + let videoAlarmTitle = [{ n: '项目', k: '', @@ -715,7 +801,64 @@ module.exports = function (app, opts) { // } if (d.AlarmGroup == 1) { + if (d.StructureId) { + //查询结构物的监测因素 + const factorData = await clickHouse.anxinyun.query( + ` + SELECT + t_structure_factor.structure AS structureId, + t_factor.name AS name, + t_factor.id AS id + FROM + t_structure_factor + LEFT JOIN t_factor + ON t_factor.id = t_structure_factor.factor + WHERE + t_structure_factor.structure = (${d.StructureId}) + + ` + ).toPromise() || [] + let factorId = factorData.map(f => f.id) + + //查询结构物对应的设备 + const equipment = await clickHouse.anxinyun.query( + ` + SELECT + t_sensor.id AS id, + t_sensor.name AS name, + t_sensor.structure AS structureId, + t_sensor.factor AS factorId, + t_device_sensor.iota_device_id AS iotaDeviceId, + ${dataAlarm}.alarms.State AS state, + ${dataAlarm}.alarms.AlarmGroup AS alarmGroup, + ${dataAlarm}.alarms.SourceId AS sourceId + FROM + t_sensor + LEFT JOIN t_device_sensor + ON t_device_sensor.sensor = t_sensor.id + LEFT JOIN ${dataAlarm}.alarms + ON ${dataAlarm}.alarms.SourceId = t_device_sensor.iota_device_id + WHERE + t_sensor.structure = (${d.StructureId}) + AND + t_sensor.factor IN (${factorId.join(',')}) + ` + ).toPromise() || [] + + d.factor = [] + factorData.map(c => { + let breakData = equipment.filter(m => (m.iotaDeviceId && m.sourceId && m.state < 3 && m.alarmGroup == 1 && m.factorId == c.id)) + d.factor.push({ + name: c.name, + sum: equipment.length, + breakData: breakData.length + }) + }) + + } + dataAlarmG1.push(d) + } else if (d.AlarmGroup == 2) { dataAlarmG2.push(d) /** 注1 @@ -862,7 +1005,7 @@ module.exports = function (app, opts) { html += packageAlarmData2Table({ titlePrefix: '数据中断', alarmData: dataAlarmG1, - alarmTitleArr: dataAlarmTitle, + alarmTitleArr: dataLnterruptTitle, }) } if (c.alarmType.includes('data_exception')) { @@ -990,7 +1133,8 @@ module.exports = function (app, opts) { if (isDev) { // !开发测试用的数据 - emails = ['1650192445@qq.com'] + // emails = ['1650192445@qq.com'] + emails = ['2798774060@qq.com'] } if (emails.length) { diff --git a/web/client/src/sections/install/containers/system.jsx b/web/client/src/sections/install/containers/system.jsx index 2702f5d..e2d8f13 100644 --- a/web/client/src/sections/install/containers/system.jsx +++ b/web/client/src/sections/install/containers/system.jsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { connect } from 'react-redux'; -import { Skeleton, Button, Pagination, Table, Popconfirm, Tooltip } from '@douyinfe/semi-ui'; +import { Skeleton, Button, Pagination, Table, Popconfirm, Tooltip, Input } from '@douyinfe/semi-ui'; import { SkeletonScreen, } from "$components"; import moment from "moment"; import SystemModal from '../components/systemModal' @@ -28,6 +28,7 @@ const Example = (props) => { const [tableKey, setTableKey] = useState([]) //修改时绑定的id const page = useRef(query.page);//哪一页 const [mapping, setMapping] = useState() //修改时的映射类型 + const [keyword, setKeyword] = useState() //搜索关键字 @@ -67,7 +68,7 @@ const Example = (props) => { }, [query]); function getProjectPomsList () { - dispatch(install.getProjectPoms(query)).then((res) => {//获取已绑定项目 + dispatch(install.getProjectPoms({ ...query, keyword })).then((res) => {//获取已绑定项目 if (res.success) { let mytableData = JSON.parse(JSON.stringify(res.payload.data.rows)); let mytableKey = [] @@ -347,34 +348,58 @@ const Example = (props) => {
系统映射
ASSOCIATION & MAPPING
-
+ +
+
+
平台通过映射能力将多个系统的结构化、非结构化、半结构化数据按照平台算法进行分类关联,形成整体项目信息结构,以项企PEP的项目名称进行规范。
+
+
+
+ { + console.log(v); + setKeyword(v) + }} />
-
-
-
平台通过映射能力将多个系统的结构化、非结构化、半结构化数据按照平台算法进行分类关联,形成整体项目信息结构,以项企PEP的项目名称进行规范。
+ + +