diff --git a/api/app/lib/controllers/alarm/video.js b/api/app/lib/controllers/alarm/video.js
index a7084a1..e8ab1b0 100644
--- a/api/app/lib/controllers/alarm/video.js
+++ b/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) {
try {
const { models } = ctx.fs.dc;
const { clickHouse } = ctx.app.fs
- const { utils: { anxinStrucIdRange, sendAppearToWeb } } = ctx.app.fs
- let anxinStruc = await anxinStrucIdRange({ ctx })
+ const { utils: { sendAppearToWeb } } = ctx.app.fs
- 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(
- `SELECT name, structure FROM t_video_ipc WHERE serial_no='${serial_no}' and channel_no='${channel_no}'`).toPromise()
- let structId = belongToStruct.length ? belongToStruct[0].structure : null
+ let belongToStruct = await clickHouse.anxinyun.query(
+ `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
- if (structId) {
- let exist = anxinStruc.find(s => s.strucId == structId);
- let projects = exist.pomsProject.filter(d => !d.del).map(p => p.id);
- let datas = projects.map(d => {//需要 项目,告警源,异常类型,时间
- return {
- projectCorrelationId: d,
- alarmInfo: { messageMode: 'AlarmGeneration', sourceName: belongToStruct[0].name, status_id, content: description },//AlarmGeneration代表告警首次产生
- time: create_time,
- type: description
- }
- })
- let rslt = await models.AlarmAppearRecord.bulkCreate(datas, { returning: true });
- let dynamics = rslt.map(r => {
- return {
- time: r.time,
- alarmAppearId: r.id,
- projectCorrelationId: r.projectCorrelationId,
- type: 1//发现
- }
- })
- await models.LatestDynamicList.bulkCreate(dynamics);
+ if (structId) {
+ let exist = anxinStruc.find(s => s.strucId == structId);
+ if (exist) {
+ let projects = exist.pomsProject.filter(d => !d.del).map(p => p.id);
+ let datas = projects.map(d => {//需要 项目,告警源,异常类型,时间
+ return {
+ projectCorrelationId: d,
+ alarmInfo: { messageMode: 'AlarmGeneration', sourceName: belongToStruct[0].name, status_id, content: description },//AlarmGeneration代表告警首次产生
+ time: create_time,
+ type: description
+ }
+ })
+ let rslt = await models.AlarmAppearRecord.bulkCreate(datas, { returning: true });
+ let dynamics = rslt.map(r => {
+ return {
+ time: r.time,
+ alarmAppearId: r.id,
+ projectCorrelationId: r.projectCorrelationId,
+ type: 1//发现
+ }
+ })
+ await models.LatestDynamicList.bulkCreate(dynamics);
- //消息推送到前端
- if (datas.length) {
- await sendAppearToWeb(datas, 'video');
+ //消息推送到前端
+ if (datas.length) {
+ await sendAppearToWeb(datas, 'video');
+ }
+ }
+ }
+ ctx.status = 200;
+ } else {
+ ctx.status = 400;
+ ctx.body = {
+ message: `获取结构物列表失败`
}
}
- ctx.status = 200;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
diff --git a/api/app/lib/schedule/alarms_handle_statistics.js b/api/app/lib/schedule/alarms_handle_statistics.js
index dcfa55d..91f9ef6 100644
--- a/api/app/lib/schedule/alarms_handle_statistics.js
+++ b/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 alarmHandleStatistics = app.fs.scheduleInit(
{
- interval: '0 48 1 ? * MON',//0 48 1 ? * MON 每周一凌晨1点48开始执行
+ interval: '0 18 1 ? * 1',//每周一1点18触发
// immediate: true,
proRun: true,
},
diff --git a/web/client/src/components/setup.jsx b/web/client/src/components/setup.jsx
index 8465bcf..324e82d 100644
--- a/web/client/src/components/setup.jsx
+++ b/web/client/src/components/setup.jsx
@@ -1,122 +1,124 @@
import React, { useState, useEffect } from "react";
import {
- Modal,
- CheckboxGroup,
- Checkbox,
+ Modal,
+ CheckboxGroup,
+ Checkbox,
} from "@douyinfe/semi-ui";
-function Setup(props) {
- const {
- close,
- tableType,
- tableList
- } = props;
+function Setup (props) {
+ const {
+ close,
+ tableType,
+ tableList,
+ layout, //格式
+ } = props;
- const [check, setCheck] = useState([]);
-
- const checkboxcss = { width: "25%", height: 16, margin: "0 0 20px 0" };
+ const [check, setCheck] = useState([]);
- useEffect(() => {
- //获取是否勾选信息
- const checkItem = localStorage.getItem(tableType);
- setCheck(checkItem?JSON.parse(checkItem) : [])
- ischeck();
- }, []);
- function ischeck(value) {
- if (check.length >= 8) {
- if (check.includes(value)) {
- return false;
- } else {
- return true;
+ const checkboxcss = { width: "25%", height: 16, margin: "0 0 20px 0" };
+
+ useEffect(() => {
+ //获取是否勾选信息
+ const checkItem = localStorage.getItem(tableType);
+ setCheck(checkItem ? JSON.parse(checkItem) : [])
+ ischeck();
+ }, []);
+ function ischeck (value) {
+ if (check.length >= 8) {
+ if (check.includes(value)) {
+ return false;
+ } else {
+ return true;
+ }
}
- }
- }
+ }
- return (
-
- 表格属性设置
-
+ 表格属性设置
+
- {check.length}/8
-
-
- }
- visible={true}
- style={{ width: 600 }}
- onOk={() => {
- localStorage.setItem(tableType, JSON.stringify(check));
- close();
- }}
- onCancel={() => {
- close();
- }}
- >
- {
- setCheck(check);
- ischeck();
- }}
+ color: "white",
+ textAlign: "center",
+ marginLeft: 6,
+ background:
+ check.length == 8
+ ? "rgba(40, 123, 255, 1)"
+ : "rgba(176, 176, 176, 1)",
+ }}
+ >
+ {check.length}/8
+
+
+ }
+ visible={true}
+ style={{ width: 600 }}
+ onOk={() => {
+ localStorage.setItem(tableType, JSON.stringify(check));
+ close();
+ }}
+ onCancel={() => {
+ close();
+ }}
>
- {tableList.map((item,index)=>{
- return(
- {
+ setCheck(check);
+ ischeck();
}}
- >
-
- {item.title}
-
-
- {item.list?.map((itm) => {
- return (
-
- {itm.name}
-
- );
- })}
-
-
- )})}
-
-
- );
+ >
+ {tableList.map((item, index) => {
+ return (
+
+
+ {item.title}
+
+
+ {item.list?.map((itm) => {
+ return (
+
+ {itm.name}
+
+ );
+ })}
+
+
+ )
+ })}
+
+
+ );
}
export default Setup;
diff --git a/web/client/src/sections/control/actions/control.js b/web/client/src/sections/control/actions/control.js
index 310021e..d4f6c51 100644
--- a/web/client/src/sections/control/actions/control.js
+++ b/web/client/src/sections/control/actions/control.js
@@ -105,4 +105,28 @@ export function getAppAlarmsAggDay (query) { //查询BI分析数据-应用
msg: { option: '查询BI分析应用数据' },
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: '' }
+ });
}
\ No newline at end of file
diff --git a/web/client/src/sections/control/containers/control.jsx b/web/client/src/sections/control/containers/control.jsx
index f7ceae9..0aefc4b 100644
--- a/web/client/src/sections/control/containers/control.jsx
+++ b/web/client/src/sections/control/containers/control.jsx
@@ -1,6 +1,6 @@
import React, { useEffect, useState, useRef } from 'react';
import { connect } from 'react-redux';
-import { Timeline, Card, Button, Modal, Form } from '@douyinfe/semi-ui';
+import { Timeline, Card, Button, Modal, Form, Tooltip } from '@douyinfe/semi-ui';
import { push } from 'react-router-redux';
import '../style.less'
import PerfectScrollbar from "perfect-scrollbar";
@@ -41,6 +41,11 @@ const Control = (props) => {
const [dataBI, setDataBI] = useState({}); //查询BI分析数据-数据
const [videoBI, setVideoBI] = useState([]); //查询BI分析数据-视频
const [appBI, setAppBI] = useState([]); //查询BI分析数据-应用
+ const [efficiencyBI, setEfficiencyBI] = useState({}); //查询BI分析数据-问题处置
+ const [query, setQuery] = useState({ limit: 10, page: 0, projectCorrelationId: '', types: '1,2,3,4' }); //最新动态
+ const [querydata, setQueryData] = useState([]); //最新动态数据
+ const [long, setLong] = useState(''); //最新动态设置
+
const exhibition = useRef({ workbench: [], statistical: [] }) //页面结构
const FormApi = useRef()
@@ -49,6 +54,14 @@ const Control = (props) => {
useEffect(() => {
if (socket) {
socket.on('alarmSendSocket', function (msg) {
+ console.info(msg);
+ if (msg.type == "alarmAppear") {//告警出现
+
+ } else if (msg.type == "alarmConfirm") {//告警确认
+
+ } else if (msg.type == "alarmNotice") {//通知
+
+ }
//console.info(msg);
let a = msg;
});
@@ -62,7 +75,7 @@ const Control = (props) => {
consoleToollink()
//初始化表格显示设置
- let data = ['workbench', 'statistical', 'analyse']
+ let data = ['overall', 'workbench', 'statistical', 'analyse', 'dynamic']
data.map(v => {
localStorage.getItem(v) == null
? localStorage.setItem(v, JSON.stringify(show[v]))
@@ -115,11 +128,58 @@ const Control = (props) => {
})
//查询BI分析数据-应用
dispatch(control.getAppAlarmsAggDay({ pepProjectId: pepProjectId })).then(res => {
- // console.log(res.payload.data);
if (res.success) setAppBI(res.payload.data)
})
-
+ dispatch(control.getAlarmsHandleStatistics({ pepProjectId: pepProjectId })).then(res => {
+ if (res.success) setEfficiencyBI(res.payload.data[0])
+ })
}, [pepProjectId])
+
+ useEffect(() => {
+ //查询最新动态
+ console.log(31116541541);
+ if (exhibition?.current?.dynamic?.length > 0) {
+ dispatch(control.getLatestDynamic({ ...query, projectCorrelationId: pepProjectId })).then(res => {
+ console.log(res.payload.data);
+ let data = []
+ if (res.success) {
+ if (exhibition?.current?.dynamic?.find(v => v.key == 'discovery')) {
+ res.payload.data?.appear?.map(v => data.push({
+ seed: 'discovery',
+ project: v.projectName,
+ sources: v.alarmInfo?.sourceName,
+ type: v.type,
+ time: v.time,
+ }))
+ }
+ if (exhibition?.current?.dynamic?.find(v => v.key == 'confirm')) {
+ res.payload.data?.confirm?.map(v => data.push({
+ seed: 'confirm',
+ project: v.projectName,
+ sources: v.alarmInfo?.source,
+ type: v.alarmInfo?.type,
+ time: v.confirmTime,
+ userName: v.userName,
+ // confirmContent:v.confirmContent,
+ }))
+ }
+ data.sort((a, b) => {
+ if (moment(a.time).isBefore(b.time)) {
+ return 1
+ } else {
+ return -1
+ }
+ })
+ console.log(data);
+ setQueryData(data)
+ }
+ })
+ } else {
+ setQueryData([])
+ }
+ }, [pepProjectId, query, exhibition.current])
+
+
useEffect(() => {
const domProject = document.getElementById("news");
@@ -234,16 +294,18 @@ const Control = (props) => {
let Select = {
+ overall: ['workbench', 'statistical', 'analyse', 'dynamic', 'tool'],
workbench: ['project', 'data', 'app', 'device'],
statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'],
analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'],
- dynamic: [],
+ dynamic: ['discovery', 'notice', 'handle', 'confirm'],
}
let show = {
+ overall: ['workbench', 'statistical', 'analyse', 'dynamic', 'tool'],
workbench: ['project', 'data', 'app', 'device'],
- statistical: ['milestone', 'personnel', 'DeviceAccess', 'web', 'problem'],
+ statistical: ['milestone', 'personnel', 'web', 'problem'],
analyse: ['dataInterrupt', 'dataAbnormal', 'policyHit', 'videoException', 'appAbnormal', 'deviceAbnormal', 'problemAnalysis'],
- dynamic: [],
+ dynamic: ['discovery', 'notice', 'handle', 'confirm'],
}
let listAll = [
@@ -265,6 +327,19 @@ const Control = (props) => {
{ name: '应用异常', sort: 5, key: 'appAbnormal', },
{ name: '设备异常', sort: 6, key: 'deviceAbnormal', },
{ name: '问题处置效率分析', sort: 7, key: 'problemAnalysis', },
+
+ { name: '发现:系统主动感知到的异常问题动态', sort: 1, key: 'discovery', },
+ { name: '通知:系统通过邮件、短信、企业微信等方式通知到运维人员的动态', sort: 2, key: 'notice', },
+ { name: '处置:工单信息处理流程的动态', sort: 3, key: 'handle', },
+ { name: '确认:完结状态的信息动态', sort: 4, key: 'confirm', },
+
+ { name: '我的工作台', sort: 1, key: 'workbench', },
+ { name: '项目概览', sort: 2, key: 'statistical', },
+ { name: 'BI分析模块', sort: 3, key: 'analyse', },
+ { name: '最新动态', sort: 4, key: 'dynamic', },
+ { name: '我常用的工具', sort: 5, key: 'tool', },
+
+
]
useEffect(() => {
@@ -284,7 +359,7 @@ const Control = (props) => {
exhibition.current = { ...exhibition.current, [title]: TableDisplay }
setTableSetup([{ list: data }])
}
-
+ console.log(exhibition.current);
return (
<>
@@ -300,7 +375,11 @@ const Control = (props) => {
-

+

{
+ setSetup(true)
+ setTableType('overall')
+ attribute('overall')
+ }} />
{/* 主体 */}
@@ -377,374 +456,322 @@ const Control = (props) => {
}
+
+
{/* 统计概览 */}
-
-
-
-
统计概览
-
STATISTICAL OVERVIEW
-
-
-

{
- setSetup(true)
- setTableType('statistical')
- attribute('statistical')
- }} />
+ {exhibition.current?.overall?.find(v => v.key == 'statistical') ? <>
+
+
+
+
统计概览
+
STATISTICAL OVERVIEW
+
+
+

{
+ setSetup(true)
+ setTableType('statistical')
+ attribute('statistical')
+ }} />
+
-
-
-
- {/* 项目里程碑 */}
- {exhibition.current?.statistical?.find(v => v.key == 'milestone') ?
-
-
- 项目里程碑
-
-
-
-
- 立项时间:
-
-
- 2022-5-12
-
+ {/* 统计概览 */}
+
+
+ {/* 项目里程碑 */}
+ {exhibition.current?.statistical?.find(v => v.key == 'milestone') ?
+
+
+ 项目里程碑
-
-
- 施工时间:
+
+
+
+ 立项时间:
+
+
+ 2022-5-12
+
-
- 2022-5-12至2022-12-12
+
+
+ 施工时间:
+
+
+ 2022-5-12至2022-12-12
+
-
-
-
-
- 内验时间:
+
+
+
+ 内验时间:
+
+
+ 2023-1-18
+
-
- 2023-1-18
+
+
+ 外验时间:
+
+
+ 2023-3-18
+
-
+
- 外验时间:
+ 工程维保时间:
- 2023-3-18
+ 2022-11-11
-
-
-
- 工程维保时间:
-
-
- 2022-11-11
-
-
-
-
-
- 售后维修时间:
-
-
- 2022-11-11至2023-12-14
+
+
+
+ 售后维修时间:
+
+
+ 2022-11-11至2023-12-14
+
+
-

-
-
- : ""}
- {/* 相关成员 */}
- {exhibition.current?.statistical?.find(v => v.key == 'personnel') ?
-
-
- 相关成员
-
-
- {memberList?.map((item, index) => {
- return (
-
-
-
-

-
-
- {item.name}
-
-
- (负责人)
-
-
-
- 行业服务部
-
-
- )
- })}
-
-
- : ""}
- {/* 平台设备接入 */}
- {exhibition.current?.statistical?.find(v => v.key == 'DeviceAccess') ?
-
-
- 平台设备接入
-
- {
- equipmentList.map((item, index) => {
+ : ""}
+ {/* 相关成员 */}
+ {exhibition.current?.statistical?.find(v => v.key == 'personnel') ?
+
+
+ 相关成员
+
+
+ {memberList?.map((item, index) => {
return (
-
-
- 5阶ZK1高清摄球机
-
-
- 视频
-
-
-

- {/*

*/}
+
+
+
+

+
+
+ {item.name}
+
+
+ (负责人)
+
-
- 在线
+
+ 行业服务部
- {/*
- 掉线
-
*/}
)
- })
- }
-
-
- : ""}
- {/* 关联web应用 */}
- {exhibition.current?.statistical?.find(v => v.key == 'web') ?
-
-
- {
- webList.map((item, index) => {
- return (
-
-
+ : ""}
+ {/* 平台设备接入 */}
+ {exhibition.current?.statistical?.find(v => v.key == 'DeviceAccess') ?
+
+
+ 平台设备接入
+
+
+ {
+ equipmentList.map((item, index) => {
+ return (
+
+
+ 5阶ZK1高清摄球机
+
+
+ 视频
+
-
-
- {item.name}
-
-
- )
- })
- }
-
-
- : ""}
- {/* 异常&问题 */}
- {exhibition.current?.statistical?.find(v => v.key == 'problem') ?
-
-
- {
- problemsList?.map((v, index) => {
- return (
-
{
- dispatch(push(v.url))
- }}>
-
- 【{v.SourceName}】{v.groupName}{v.groupName == '视频异常' ? "" : ',诊断为 '}
{v.typeName},请前往确认
+ : ""}
+ {/* 关联web应用 */}
+ {exhibition.current?.statistical?.find(v => v.key == 'web') ?
+
+
+ 关联web应用
+
+
+ {
+ webList.map((item, index) => {
+ return (
+
+
+
+

+
+
+
+
+ {item.name}
+
-
- {moment(v.StartTime).format("YYYY-MM-DD HH:mm:ss")}
+ )
+ })
+ }
+
+
+ : ""}
+ {/* 异常&问题 */}
+ {exhibition.current?.statistical?.find(v => v.key == 'problem') ?
+
+
+ 异常&问题
+
+
+ {
+ problemsList?.map((v, index) => {
+ return (
+
{
+ dispatch(push(v.url))
+ }}>
+
+ 【{v.SourceName}】{v.groupName}{v.groupName == '视频异常' ? "" : ',诊断为 '} {v.typeName},请前往确认
+
+
+ {moment(v.StartTime).format("YYYY-MM-DD HH:mm:ss")}
+
-
- )
- })
- }
+ )
+ })
+ }
+
-
- : ""}
-
-
+ : ""}
+
+
> : ""}
-
- {/* BI分析模块 */}
-
-
-
-
BI分析模块
-
BI ANAL YSIS MODEL
-
-
-

{
- setSetup(true)
- setTableType('analyse')
- attribute('analyse')
- }} />
+
+ {exhibition.current?.overall?.find(v => v.key == 'analyse') ?
+
+ {/* BI分析模块 */}
+
+
+
+
BI分析模块
+
BI ANAL YSIS MODEL
+
+
+

{
+ setSetup(true)
+ setTableType('analyse')
+ attribute('analyse')
+ }} />
+
-
-
- {exhibition.current?.analyse?.map((v, index) => {
- let startValue = ''
- if (v.key !== 'problemAnalysis') {
- switch (v.key) {
- case 'videoException':
- let videos = videoBI?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || []
- if (videos.length) {
- startValue = videos[0]?.day
- } else {
- startValue = videoBI?.slice(-1)[0]?.day
- }
- break;
- case 'appAbnormal':
- let apps = appBI?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || []
- if (apps.length) {
- startValue = apps[0]?.day
- } else {
- startValue = appBI?.slice(-1)[0]?.day
- }
- break;
- default:
- let datas = dataBI[v.key]?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || []
- if (datas.length) {
- startValue = datas[0]?.day
- } else {
- startValue = dataBI[v.key]?.slice(-1)[0]?.day
- }
- break;
+
+ {exhibition.current?.analyse?.map((v, index) => {
+ let startValue = ''
+ if (v.key !== 'problemAnalysis') {
+ switch (v.key) {
+ case 'videoException':
+ let videos = videoBI?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || []
+ if (videos.length) {
+ startValue = videos[0]?.day
+ } else {
+ startValue = videoBI?.slice(-1)[0]?.day
+ }
+ break;
+ case 'appAbnormal':
+ let apps = appBI?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || []
+ if (apps.length) {
+ startValue = apps[0]?.day
+ } else {
+ startValue = appBI?.slice(-1)[0]?.day
+ }
+ break;
+ default:
+ let datas = dataBI[v.key]?.filter(u => moment(moment().day(moment().day() - 30).format('YYYY-MM-DD')).isBefore(u.day)) || []
+ if (datas.length) {
+ startValue = datas[0]?.day
+ } else {
+ startValue = dataBI[v.key]?.slice(-1)[0]?.day
+ }
+ break;
+ }
}
- }
- // console.log(startValue);
- return v.key == 'problemAnalysis' ?
-
-
- :
+ return v.key == 'problemAnalysis' ?
u.day) : v.key == 'appAbnormal' ? appBI?.map(u => u.day) : dataBI[v.key]?.map(u => u.day) || []
+ boundaryGap: true,
+ deduplication: null,
+ data: ['当日处理', '3日内', '7日内', '15日内', '30日内', '超过30日']
},
yAxis: {
+ min: 0,
+ max: 100,
type: 'value',
- name: "条数",
+ axisLabel: {
+ show: true,
+ interval: 0,
+ formatter: '{value}%'
+ }
},
series: [
{
- type: 'line',
+ data: [efficiencyBI?.day1, efficiencyBI?.day3, efficiencyBI?.day7, efficiencyBI?.day15, efficiencyBI?.day30, efficiencyBI?.day30m],
+ type: 'bar',
name: v.name,
smooth: true,
- areaStyle: {
- color: '#0e9cff26',
+ barWidth: '30%',
+ label: {
+ normal: {
+ show: true,
+ position: 'top'
+ }
},
- data: v.key == 'videoException' ? videoBI?.map(u => u.total) : v.key == 'appAbnormal' ? appBI?.map(u => u.total) : dataBI[v.key]?.map(u => u.total) || []
- },
- {
- type: 'line',
- name: '已处理(含自动恢复)',
- smooth: true,
areaStyle: {
- color: '#0e9cff26',
+ color: '#0F7EFB',
},
- data: v.key == 'videoException' ? videoBI?.map(u => u.done) : v.key == 'appAbnormal' ? appBI?.map(u => u.done) : dataBI[v.key]?.map(u => u.done) || []
+ emphasis: {
+ color: '#E8F3FF',
+ }
+ // data: []
},
-
]
}}
notMerge={true}
@@ -755,10 +782,78 @@ const Control = (props) => {
// opts={}
/>
- })}
-
+ :
+ u.day) : v.key == 'appAbnormal' ? appBI?.map(u => u.day) : dataBI[v.key]?.map(u => u.day) || []
+ },
+ yAxis: {
+ type: 'value',
+ name: "条数",
+ },
+ series: [
+ {
+ type: 'line',
+ name: v.name,
+ smooth: true,
+ areaStyle: {
+ color: '#0e9cff26',
+ },
+ data: v.key == 'videoException' ? videoBI?.map(u => u.total) : v.key == 'appAbnormal' ? appBI?.map(u => u.total) : dataBI[v.key]?.map(u => u.total) || []
+ },
+ {
+ type: 'line',
+ name: '已处理(含自动恢复)',
+ smooth: true,
+ areaStyle: {
+ color: '#0e9cff26',
+ },
+ data: v.key == 'videoException' ? videoBI?.map(u => u.done) : v.key == 'appAbnormal' ? appBI?.map(u => u.done) : dataBI[v.key]?.map(u => u.done) || []
+ },
-
+ ]
+ }}
+ notMerge={true}
+ lazyUpdate={true}
+ theme={'ReactEChart' + index}
+ // onChartReady={this.onChartReadyCallback}
+ // onEvents={EventsDict}
+ // opts={}
+ />
+
+ })}
+
+
+
: ""}
{/* 右边 */}
@@ -771,15 +866,39 @@ const Control = (props) => {
RECENT NEWS
-

setSetup(true)} />
+

{
+ setSetup(true)
+ setTableType('dynamic')
+ attribute('dynamic')
+ setLong('long')
+ }} />
- {timelineList.map((item, index) => {
+ {querydata?.map((v, index) => {
+ let title = v.seed == 'discovery' ?
+ v.project + '项目' + v.sources + v.type :
+ v.seed == 'confirm' ?
+ v.userName + '确认并关闭' + v.project + v.sources + v.type + '的问题' : ""
return (
-
- A项目DTU设备状态异常,诊断为离线
+
+
+
+ {title}
+
+
)
})}
@@ -787,80 +906,81 @@ const Control = (props) => {
{/* 我常用的工具 */}
-
-
-
-
-
我常用的工具
-
MY USUAL TOOLS
+ {exhibition.current?.overall?.find(v => v.key == 'tool') ?
+
+
+
+
+
我常用的工具
+
MY USUAL TOOLS
+
-
- {toolShow.length > 0 ?
- toolShow?.map(v =>
-
{
- document.getElementById(v.id + 'name').style.display = 'none'
- }}
- id={v.id + v.name}
- style={{ marginTop: 24, position: 'relative', display: "inline-block", cursor: 'pointer' }}>
-
- ) : ""}
-
+
{
+ setTool(true)
+ }}
+ >
+ 添加
+
+
+
: ""}
@@ -870,10 +990,12 @@ const Control = (props) => {
{
setSetup(false);
attribute(tableType);
setTableType('')
+ setLong('')
}}
/>
) : (
diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js
index 4f51d0f..e040729 100644
--- a/web/client/src/utils/webapi.js
+++ b/web/client/src/utils/webapi.js
@@ -65,6 +65,10 @@ export const ApiTable = {
getDataAlarmsAggDay: 'data/alarms/agg/day', //查询BI分析数据-数据
getVideoAlarmsAggDay: 'video/alarms/agg/day', //查询BI分析数据-视频异常
getAppAlarmsAggDay: 'app/alarms/agg/day', //查询BI分析数据-应用
+ getAlarmsHandleStatistics: '/alarms/handle/statistics', //查询BI分析数据-问题处理效率分析
+ getLatestDynamic: '/latest/dynamic', // 查询最新动态
+
+
};
export const RouteTable = {
apiRoot: "/api/root",