巴林闲侠 3 years ago
parent
commit
e4b92be1bd
  1. 90
      api/app/lib/controllers/alarm/video.js
  2. 2
      api/app/lib/schedule/alarms_handle_statistics.js
  3. 218
      web/client/src/components/setup.jsx
  4. 24
      web/client/src/sections/control/actions/control.js
  5. 914
      web/client/src/sections/control/containers/control.jsx
  6. 4
      web/client/src/utils/webapi.js

90
api/app/lib/controllers/alarm/video.js

@ -284,47 +284,75 @@ async function confirm(ctx) {
} }
} }
let structsAche = {
dataList: [],
expireTime: null//10分钟更新一次结构物列表
}
async function getStructsAche(ctx) {
const { utils: { getAxyStructs } } = ctx.app.fs
try {
if (!structsAche.dataList.length || moment() > moment(structsAche.expireTime)) {
let structList = await getAxyStructs();
structsAche.dataList = structList;
structsAche.expireTime = moment().add(10, 'minute').format('YYYY-MM-DD HH:mm:ss');
}
return structsAche;
} catch (err) {
console.log(`获取结构物列表失败, error: ${err}`);
}
}
async function alarmAdded(ctx) { async function alarmAdded(ctx) {
try { try {
const { models } = ctx.fs.dc; const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs const { clickHouse } = ctx.app.fs
const { utils: { anxinStrucIdRange, sendAppearToWeb } } = ctx.app.fs const { utils: { sendAppearToWeb } } = ctx.app.fs
let anxinStruc = await anxinStrucIdRange({ ctx })
const { serial_no, channel_no, create_time, description, status_id } = ctx.request.body; let structsAche = await getStructsAche(ctx);
if (structsAche) {
let anxinStruc = structsAche.dataList;//结构物列表
const { serial_no, channel_no, create_time, description, status_id } = ctx.request.body;
let belongToStruct = await clickHouse.anxinyun.query( let belongToStruct = await clickHouse.anxinyun.query(
`SELECT name, structure FROM t_video_ipc WHERE serial_no='${serial_no}' and channel_no='${channel_no}'`).toPromise() `SELECT name, structure FROM t_video_ipc WHERE serial_no='${serial_no}' and channel_no=${parseInt(channel_no)}`).toPromise()
let structId = belongToStruct.length ? belongToStruct[0].structure : null let structId = belongToStruct.length ? belongToStruct[0].structure : null
if (structId) { if (structId) {
let exist = anxinStruc.find(s => s.strucId == structId); let exist = anxinStruc.find(s => s.strucId == structId);
let projects = exist.pomsProject.filter(d => !d.del).map(p => p.id); if (exist) {
let datas = projects.map(d => {//需要 项目,告警源,异常类型,时间 let projects = exist.pomsProject.filter(d => !d.del).map(p => p.id);
return { let datas = projects.map(d => {//需要 项目,告警源,异常类型,时间
projectCorrelationId: d, return {
alarmInfo: { messageMode: 'AlarmGeneration', sourceName: belongToStruct[0].name, status_id, content: description },//AlarmGeneration代表告警首次产生 projectCorrelationId: d,
time: create_time, alarmInfo: { messageMode: 'AlarmGeneration', sourceName: belongToStruct[0].name, status_id, content: description },//AlarmGeneration代表告警首次产生
type: description time: create_time,
} type: description
}) }
let rslt = await models.AlarmAppearRecord.bulkCreate(datas, { returning: true }); })
let dynamics = rslt.map(r => { let rslt = await models.AlarmAppearRecord.bulkCreate(datas, { returning: true });
return { let dynamics = rslt.map(r => {
time: r.time, return {
alarmAppearId: r.id, time: r.time,
projectCorrelationId: r.projectCorrelationId, alarmAppearId: r.id,
type: 1//发现 projectCorrelationId: r.projectCorrelationId,
} type: 1//发现
}) }
await models.LatestDynamicList.bulkCreate(dynamics); })
await models.LatestDynamicList.bulkCreate(dynamics);
//消息推送到前端 //消息推送到前端
if (datas.length) { if (datas.length) {
await sendAppearToWeb(datas, 'video'); await sendAppearToWeb(datas, 'video');
}
}
}
ctx.status = 200;
} else {
ctx.status = 400;
ctx.body = {
message: `获取结构物列表失败`
} }
} }
ctx.status = 200;
} catch (error) { } catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`); ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400; ctx.status = 400;

2
api/app/lib/schedule/alarms_handle_statistics.js

@ -7,7 +7,7 @@ module.exports = function (app, opts) {
const { database: anxinyun } = clickHouse.anxinyun.opts.config const { database: anxinyun } = clickHouse.anxinyun.opts.config
const alarmHandleStatistics = app.fs.scheduleInit( const alarmHandleStatistics = app.fs.scheduleInit(
{ {
interval: '0 48 1 ? * MON',//0 48 1 ? * MON 每周一凌晨1点48开始执行 interval: '0 18 1 ? * 1',//每周一1点18触发
// immediate: true, // immediate: true,
proRun: true, proRun: true,
}, },

218
web/client/src/components/setup.jsx

@ -1,122 +1,124 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { import {
Modal, Modal,
CheckboxGroup, CheckboxGroup,
Checkbox, Checkbox,
} from "@douyinfe/semi-ui"; } from "@douyinfe/semi-ui";
function Setup(props) { function Setup (props) {
const { const {
close, close,
tableType, tableType,
tableList tableList,
} = props; layout, //
} = props;
const [check, setCheck] = useState([]); const [check, setCheck] = useState([]);
const checkboxcss = { width: "25%", height: 16, margin: "0 0 20px 0" };
useEffect(() => { const checkboxcss = { width: "25%", height: 16, margin: "0 0 20px 0" };
//
const checkItem = localStorage.getItem(tableType); useEffect(() => {
setCheck(checkItem?JSON.parse(checkItem) : []) //
ischeck(); const checkItem = localStorage.getItem(tableType);
}, []); setCheck(checkItem ? JSON.parse(checkItem) : [])
function ischeck(value) { ischeck();
if (check.length >= 8) { }, []);
if (check.includes(value)) { function ischeck (value) {
return false; if (check.length >= 8) {
} else { if (check.includes(value)) {
return true; return false;
} else {
return true;
}
} }
} }
}
return ( return (
<Modal <Modal
title={ title={
<div> <div>
表格属性设置 表格属性设置
<span <span
style={{ style={{
width: 50, width: 50,
lineHeight: "19px", lineHeight: "19px",
display: "inline-block", display: "inline-block",
color: "white", color: "white",
textAlign: "center", textAlign: "center",
marginLeft: 6, marginLeft: 6,
background: background:
check.length == 8 check.length == 8
? "rgba(40, 123, 255, 1)" ? "rgba(40, 123, 255, 1)"
: "rgba(176, 176, 176, 1)", : "rgba(176, 176, 176, 1)",
}} }}
> >
{check.length}/8 {check.length}/8
</span> </span>
</div> </div>
} }
visible={true} visible={true}
style={{ width: 600 }} style={{ width: 600 }}
onOk={() => { onOk={() => {
localStorage.setItem(tableType, JSON.stringify(check)); localStorage.setItem(tableType, JSON.stringify(check));
close(); close();
}} }}
onCancel={() => { onCancel={() => {
close(); close();
}} }}
>
<CheckboxGroup
style={{ width: "100%", fontSize: 14 }}
key="primary1"
direction="horizontal"
defaultValue={check}
aria-label="表格属性设置"
onChange={(check) => {
setCheck(check);
ischeck();
}}
> >
{tableList.map((item,index)=>{ <CheckboxGroup
return( style={{ width: "100%", fontSize: 14 }}
<div key="primary1"
key={index} direction="horizontal"
style={{ defaultValue={check}
width: 550, aria-label="表格属性设置"
border: "1px solid #EAEAEA", onChange={(check) => {
padding: "0px 5px", setCheck(check);
borderRadius: 4, ischeck();
marginBottom: "20px",
}} }}
> >
<div {tableList.map((item, index) => {
style={{ return (
borderBottom: "1px solid #EAEAEA", <div
marginLeft: "10px", key={index}
padding: "8px 0px", style={{
}} width: 550,
> border: "1px solid #EAEAEA",
{item.title} padding: "0px 5px",
</div> borderRadius: 4,
<div style={{ padding: "15px 12px", width: 530 }}> marginBottom: "20px",
{item.list?.map((itm) => { }}
return ( >
<Checkbox <div
key={itm.value} style={{
value={itm.value} borderBottom: "1px solid #EAEAEA",
style={checkboxcss} marginLeft: "10px",
disabled={ischeck(itm.value)} padding: "8px 0px",
> }}
{itm.name} >
</Checkbox> {item.title}
); </div>
})} <div style={{ padding: "15px 12px", width: 530, display: layout == 'long' ? 'flex' : "", flexDirection: layout == 'long' ? 'column' : "" }}>
</div> {item.list?.map((itm) => {
</div> return (
)})} <Checkbox
</CheckboxGroup> key={itm.value}
</Modal> value={itm.value}
); style={layout == 'long' ? {} : checkboxcss}
disabled={ischeck(itm.value) || ['workbench', 'dynamic', 'handle', 'DeviceAccess','discovery'].includes(itm.value)}
>
{itm.name}
</Checkbox>
);
})}
</div>
</div>
)
})}
</CheckboxGroup>
</Modal>
);
} }
export default Setup; export default Setup;

24
web/client/src/sections/control/actions/control.js

@ -105,4 +105,28 @@ export function getAppAlarmsAggDay (query) { //查询BI分析数据-应用
msg: { option: '查询BI分析应用数据' }, msg: { option: '查询BI分析应用数据' },
reducer: { name: '' } reducer: { name: '' }
}); });
}
export function getAlarmsHandleStatistics (query) { //查询BI分析数据-问题处理效率分析
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
query,
actionType: 'GET_ALARMS_HANDLE_STATISTICS',
url: `${ApiTable.getAlarmsHandleStatistics}`,
msg: { option: '查询BI问题处理效率分析' },
reducer: { name: '' }
});
}
export function getLatestDynamic (query) { //查询最新动态
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
query,
actionType: 'GET_LATEST_DYNAMIC',
url: `${ApiTable.getLatestDynamic}`,
msg: { option: '查询最新动态' },
reducer: { name: '' }
});
} }

914
web/client/src/sections/control/containers/control.jsx

File diff suppressed because it is too large

4
web/client/src/utils/webapi.js

@ -65,6 +65,10 @@ export const ApiTable = {
getDataAlarmsAggDay: 'data/alarms/agg/day', //查询BI分析数据-数据 getDataAlarmsAggDay: 'data/alarms/agg/day', //查询BI分析数据-数据
getVideoAlarmsAggDay: 'video/alarms/agg/day', //查询BI分析数据-视频异常 getVideoAlarmsAggDay: 'video/alarms/agg/day', //查询BI分析数据-视频异常
getAppAlarmsAggDay: 'app/alarms/agg/day', //查询BI分析数据-应用 getAppAlarmsAggDay: 'app/alarms/agg/day', //查询BI分析数据-应用
getAlarmsHandleStatistics: '/alarms/handle/statistics', //查询BI分析数据-问题处理效率分析
getLatestDynamic: '/latest/dynamic', // 查询最新动态
}; };
export const RouteTable = { export const RouteTable = {
apiRoot: "/api/root", apiRoot: "/api/root",

Loading…
Cancel
Save