diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index d4f0c4b..fc6b9e0 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -102,7 +102,8 @@ "--clickHousePepEmis pepca8", "--clickHouseProjectManage peppm8", "--clickHouseVcmp video_access_dev", - "--clickHouseDataAlarm alarm", + "--clickHouseDataAlarm default", + // "--clickHouseDataAlarmLocal default", "--clickHouseIot iota", "--clickHouseCamworkflow camworkflow", "--confirmAlarmAnxinUserId 1", diff --git a/api/app/lib/controllers/project/bind.js b/api/app/lib/controllers/project/bind.js index 3cfa989..d2f81dd 100644 --- a/api/app/lib/controllers/project/bind.js +++ b/api/app/lib/controllers/project/bind.js @@ -7,8 +7,7 @@ async function bindAnxin2pep (ctx) { const models = ctx.fs.dc.models; const { clickHouse } = ctx.app.fs const { userId, pepUserId } = ctx.fs.api - const { bindId, name, pepProjectId, anxinProjectId = [], appId = [], mappingClass } = ctx.request.body - + const { bindId, name, pepProjectId, anxinProjectId = [], appId = [], mappingClass,maintenancePeriod} = ctx.request.body if (name && pepProjectId) { throw '项企项目与自定义项目名称仅可选择一项' } @@ -20,6 +19,8 @@ async function bindAnxin2pep (ctx) { name, pepProjectId, anxinProjectId, updateTime: now, mappingClass, del: false, + maintenanceEnd:maintenancePeriod&&maintenancePeriod.length?maintenancePeriod[1]:'', + maintenanceStart:maintenancePeriod&&maintenancePeriod.length?maintenancePeriod[0]:'' } // 仅限已有 pepProjectId 的项目 diff --git a/api/app/lib/models/project_correlation.js b/api/app/lib/models/project_correlation.js index 66526cb..467b1ed 100644 --- a/api/app/lib/models/project_correlation.js +++ b/api/app/lib/models/project_correlation.js @@ -87,6 +87,24 @@ module.exports = dc => { field: "mapping_class", autoIncrement: false }, + maintenanceStart: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: '维保开始时间', + primaryKey: false, + field: "maintenance_start", + autoIncrement: false + }, + maintenanceEnd: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: '维保结束时间', + primaryKey: false, + field: "maintenance_end", + autoIncrement: false + }, }, { tableName: "project_correlation", comment: "", diff --git a/api/app/lib/schedule/alarms_push.js b/api/app/lib/schedule/alarms_push.js index a95936c..0421161 100644 --- a/api/app/lib/schedule/alarms_push.js +++ b/api/app/lib/schedule/alarms_push.js @@ -407,8 +407,7 @@ module.exports = function (app, opts) { ON anxinStation.id = anxinIpcStation.station ORDER BY cameraAlarm.createTime DESC ` - ).toPromise() : [] - + ).toPromise() : [] let returnD = [] let positionD = {} // 每个设备一个告警 @@ -526,7 +525,7 @@ module.exports = function (app, opts) { dataAlarmSubType_.push(-1) dataAlarmOption.push(`AlarmGroupUnit IN (${dataAlarmSubType_.join(',')})`) } - + //安心云 dataAlarms = !c.alarmSubType || dataAlarmSubType_.length ? await clickHouse.dataAlarm.query(` @@ -541,7 +540,25 @@ module.exports = function (app, opts) { ${dataAlarmOption.length ? ' AND ' + dataAlarmOption.join(' AND ') : ''} ORDER BY StartTime DESC `).toPromise() : [] + //本地化 + const dataAlarmsLocal=!c.alarmSubType || dataAlarmSubType_.length ? + await clickHouse.dataAlarm.query(` + SELECT * FROM alarms + LEFT JOIN sensors + AS anxinStation + ON toString(anxinStation.SensorId)= alarms.SourceId + AND alarms.SourceTypeId = 2 + WHERE + ${`State NOT IN (3, 4) AND `} + StructureId IN (${searchStrucIds.join(',')}) + ${dataAlarmOption.length ? ' AND ' + dataAlarmOption.join(' AND ') : ''} + ORDER BY StartTime DESC + `).toPromise() : [] + //合并本地化和安心云的告警 + dataAlarms=[...dataAlarms,...dataAlarmsLocal] + console.log('合并的告警列表(安心云+本地)',dataAlarms,dataAlarmsLocal) } + let dataAlarmTitle2 = [{ n: '项目', @@ -901,7 +918,7 @@ module.exports = function (app, opts) { pLog(`查得数据告警 ${dataAlarms.length} 条`); // pLog(dataAlarms); - + console.log('dataAlarms111',dataAlarms) if (dataAlarms.length) { const alarmIds = dataAlarms .map(ar => "'" + ar.AlarmId + "'") @@ -917,6 +934,7 @@ module.exports = function (app, opts) { let deviceIds = new Set() for (let d of dataAlarms) { + console.log('xxxxx1111',d) d = { ...d, stationId: d.id } /** 按监测因素筛选 且为测点告警 */ @@ -1051,7 +1069,6 @@ module.exports = function (app, opts) { // 注1 END } else if (d.AlarmGroup == 3) { - /** 按监测因项 factor-item 的名称筛选*/ if (pomsStrucFactorId) { // 兼容之前的设置 有这个信息才进行判断 @@ -1088,6 +1105,7 @@ module.exports = function (app, opts) { deviceStatistic.add(d.SourceId) } + console.log('xxxxx1112',c) if (c.tactics == 'abnormal_rate') { pLog(`异常设备数量 - ${deviceStatistic.size}`) pLog(`异常视频告警数量 - ${videoAlarms.length}`) @@ -1105,6 +1123,7 @@ module.exports = function (app, opts) { } // 注1 if (apMergeDeVeAnxinProjectId_.length || isDev) { + console.log('xascascasca',isDev) for (let a of videoAlarms) { let existStruc = a.struc.find(asc => apMergeDeVeAlarms[asc.id] || isDev) if (existStruc) { @@ -1135,13 +1154,23 @@ module.exports = function (app, opts) { ` let dataAlarmG1Data = dataAlarms.filter(a => a.AlarmGroup == 1) + console.log('dataAlarmG1Datasssss',dataAlarms) + console.log('dataAlarmG1Datasssss',dataAlarmG1Data.length) if (dataAlarmG1Data.length) { + //安心云项目是structureId数组 let dataAlarmG1StructureId = new Set() + //本地化项目structureId数组 + let dataAlarmStructureId = new Set() dataAlarmG1Data.map(c => { - dataAlarmG1StructureId.add(c.StructureId) + if(c.project){ + dataAlarmStructureId.add(c.StructureId) + }else{ + dataAlarmG1StructureId.add(c.StructureId) + } }) - //查询结构物的监测因素 - const factorData = await clickHouse.anxinyun.query( + console.log('xxx1qqqq',dataAlarmG1StructureId) + //查询结构物的监测因素(安心云) + let factorData = await clickHouse.anxinyun.query( ` SELECT t_structure_factor.structure AS structureId, @@ -1155,14 +1184,23 @@ module.exports = function (app, opts) { t_structure_factor.structure IN (${[...dataAlarmG1StructureId]}) ` ).toPromise() || [] - + //查询结构物的监测因素(本地化项目) + let factorDataLocal = await clickHouse.dataAlarm.query( + ` SELECT + StructId AS structureId,SafetyFactorTypeName AS name,SafetyFactorTypeId AS id + FROM + sensors + WHERE sensors.StructId in (${[...dataAlarmStructureId]})` + ).toPromise() || [] + console.log('factorDataLocal',factorDataLocal) + //合并(安心云+本地化项目) + factorData=[...factorDataLocal,...factorData] let factorId = factorData.map(f => f.id) - - //查询结构物对应的测点 - const equipment = await clickHouse.anxinyun.query( - ` + let factorIdLocal=factorIdLocal.map(f => f.id) + //查询结构物对应的测点(安心云) + let equipment = await clickHouse.dataAlarm.query( + ` SELECT - t_sensor.id AS id, t_sensor.name AS name, t_sensor.structure AS structureId, t_sensor.factor AS factorId, @@ -1177,8 +1215,21 @@ module.exports = function (app, opts) { t_sensor.factor IN (${factorId.join(',')}) ` ).toPromise() || [] - - + //查询结构物对应的测点(本地化) + let equipmentLocal = await clickHouse.anxinyun.query( + ` SELECT + SensorLocationDescription AS name, + StructId AS structureId, + SafetyFactorTypeId AS factorId, + SensorId AS iotaDeviceId + FROM sensors + WHERE sensors.StructId IN (${[...dataAlarmStructureId]},) + AND sensors.SafetyFactorTypeId IN (${factorIdLocal.join(',')}) + ` + ).toPromise() || [] + console.log('equipmentLocal',equipmentLocal) + //合并本地化数据+安心云数据 + equipment=[...equipment,...equipmentLocal] const alarmDataRes = await clickHouse.dataAlarm.query( ` SELECT @@ -1194,7 +1245,7 @@ module.exports = function (app, opts) { FROM alarms WHERE - alarms.StructureId In (${[...dataAlarmG1StructureId]}) + alarms.StructureId In (${[...dataAlarmG1StructureId,...dataAlarmStructureId]}) AND alarms.AlarmGroup = 1 AND @@ -1203,7 +1254,7 @@ module.exports = function (app, opts) { // , // alarms.subStations AS subStations ).toPromise() || [] - + console.log('alarmDataRes111',alarmDataRes) let alarmDatas = [] for (let alarms of alarmDataRes) { if (alarms.subStations && alarms.subStations.length) { @@ -1614,6 +1665,7 @@ module.exports = function (app, opts) { `).toPromise() : [] let receiverId = [] + console.log('接收邮件的人',receiverRes) let emails = receiverRes.reduce((arr, r) => { if (r.email) { arr.push(r.email) @@ -1625,6 +1677,7 @@ module.exports = function (app, opts) { if (isDev) { // !开发测试用的数据 emails = ['1650192445@qq.com'] + // emails=['zhao.bin@free-sun.com.cn'] // emails = ['wen.lele@free-sun.com.cn'] } diff --git a/api/config.js b/api/config.js index 327a8cd..d13eb6c 100644 --- a/api/config.js +++ b/api/config.js @@ -49,6 +49,7 @@ args.option('clickHousePepEmis', 'clickHouse 项企数据库名称'); args.option('clickHouseProjectManage', 'clickHouse 项目管理数据库名称'); args.option('clickHouseVcmp', 'clickHouse 视频平台数据库名称'); args.option('clickHouseDataAlarm', 'clickHouse 视频平台数据告警库名称'); +// args.option('clickHouseDataAlarmLocal', 'clickHouse 本地化告警相关数据'); args.option('clickHouseIot', 'clickHouse IOT平台设备信息库名称'); args.option('clickHouseCamworkflow', 'clickHouse 工作流数据库名称'); @@ -122,6 +123,7 @@ const CLICKHOUST_VCMP = process.env.CLICKHOUST_VCMP || flags.clickHouseVcmp const CLICKHOUST_DATA_ALARM = process.env.CLICKHOUST_DATA_ALARM || flags.clickHouseDataAlarm const CLICKHOUST_IOT = process.env.CLICKHOUST_IOT || flags.clickHouseIot const CLICKHOUST_CAM_WORKFLOW = process.env.CLICKHOUST_CAM_WORKFLOW || flags.clickHouseCamworkflow +// const CLICKHOUST_DATA_ALARM_LOCAL=process.env.CLICKHOUST_DATA_ALARM_LOCAL|| flags.clickHouseDataAlarmLocal const CONFIRM_ALARM_ANXIN_USER_ID = process.env.CONFIRM_ALARM_ANXIN_USER_ID || flags.confirmAlarmAnxinUserId @@ -159,7 +161,8 @@ const requireParams = { // CLICKHOUST_CAM_WORKFLOW, CONFIRM_ALARM_ANXIN_USER_ID, VCMP_APP_ID, VCMP_APP_SECRET, - API_CRAW_URL + API_CRAW_URL, + // CLICKHOUST_DATA_ALARM_LOCAL } Object.keys(requireParams).forEach(key => { @@ -324,6 +327,10 @@ const product = { name: 'camWorkflow', db: CLICKHOUST_CAM_WORKFLOW }, + // { + // name: 'alarmLocal', + // db: CLICKHOUST_DATA_ALARM_LOCAL + // } ] }, es: { diff --git a/script/3.4/schema/1.update_project_correlation.sql b/script/3.4/schema/1.update_project_correlation.sql new file mode 100644 index 0000000..4c45ab8 --- /dev/null +++ b/script/3.4/schema/1.update_project_correlation.sql @@ -0,0 +1,16 @@ +alter table public.project_correlation + add "maintenanceETime" timestamp with time zone; + +comment on column public.project_correlation."maintenanceETime" is '维保结束时间' + +alter table public.project_correlation + add "maintenanceSTime" timestamp with time zone; + +comment on column public.project_correlation."maintenanceSTime" is '维保开始时间'; + + +alter table public.project_correlation + rename column "maintenanceETime" to maintenance_end; + +alter table public.project_correlation + rename column "maintenanceSTime" to maintenance_start; diff --git a/web/client/src/sections/install/components/systemModal.jsx b/web/client/src/sections/install/components/systemModal.jsx index 011109c..8464651 100644 --- a/web/client/src/sections/install/components/systemModal.jsx +++ b/web/client/src/sections/install/components/systemModal.jsx @@ -21,7 +21,8 @@ function adminModal (props) { anxinDelete,//修改时安心云项目有删除,显示提示信息 appArr,//修改时添加应用 bindId, - mapping //修改时的映射类型 + mapping, //修改时的映射类型 + maintenancePeriod //维保时间段 } = props; const { install } = actions; const form = useRef();//表单 @@ -257,6 +258,17 @@ function adminModal (props) { }) } + + + + diff --git a/web/client/src/sections/install/containers/system.jsx b/web/client/src/sections/install/containers/system.jsx index e493cd7..b0caa78 100644 --- a/web/client/src/sections/install/containers/system.jsx +++ b/web/client/src/sections/install/containers/system.jsx @@ -29,7 +29,7 @@ const Example = (props) => { const page = useRef(query.page);//哪一页 const [mapping, setMapping] = useState() //修改时的映射类型 const [keyword, setKeyword] = useState() //搜索关键字 - + const [maintenancePeriod,setMaintenancePeriod]=useState([])//维保时间区间 @@ -150,7 +150,7 @@ const Example = (props) => { title: '安心云项目名称', dataIndex: "anxinProject", key: 'anxinProject', - width: 500, + width: 400, render: (_, row) => { let anxinerror = false let anxinerrorArr = [] @@ -258,6 +258,22 @@ const Example = (props) => { return row.pepUserName || '无' } }, + { + title: '维保开始时间', + dataIndex: "maintenanceStart", + key: 'maintenanceStart', + render: (_, row) => { + return row.maintenanceStart?moment(row.maintenanceStart).format('YYYY-MM-DD') : '无' + } + }, + { + title: '维保结束时间', + dataIndex: "maintenanceEnd", + key: 'maintenanceEnd', + render: (_, row) => { + return row.maintenanceEnd?moment(row.maintenanceEnd).format('YYYY-MM-DD') : '无' + } + }, { title: "管理", width: "150px", @@ -301,6 +317,7 @@ const Example = (props) => { setBindId(row.id) setMapping(row?.mappingClass) setSystemEdit(true) + setMaintenancePeriod([row?.maintenanceStart,row?.maintenanceEnd]) }} > 修改 @@ -396,6 +413,7 @@ const Example = (props) => { setAnxincloudArr() setBindId() setMapping('') + setMaintenancePeriod([]) }} > 添加映射关系 @@ -491,6 +509,7 @@ const Example = (props) => { mapping={mapping} appArr={appArr} bindId={bindId} + maintenancePeriod={maintenancePeriod} cancel={() => { setSystemModal(false); }}