Browse Source

最新动态

dev
wenlele 2 years ago
parent
commit
2ab50e0b68
  1. 12
      web/client/src/components/setup.jsx
  2. 24
      web/client/src/sections/control/actions/control.js
  3. 196
      web/client/src/sections/control/containers/control.jsx
  4. 4
      web/client/src/utils/webapi.js

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

@ -9,7 +9,8 @@ function Setup(props) {
const {
close,
tableType,
tableList
tableList,
layout, //
} = props;
const [check, setCheck] = useState([]);
@ -98,14 +99,14 @@ function Setup(props) {
>
{item.title}
</div>
<div style={{ padding: "15px 12px", width: 530 }}>
<div style={{ padding: "15px 12px", width: 530, display: layout == 'long' ? 'flex' : "", flexDirection: layout == 'long' ? 'column' : "" }}>
{item.list?.map((itm) => {
return (
<Checkbox
key={itm.value}
value={itm.value}
style={checkboxcss}
disabled={ischeck(itm.value)}
style={layout == 'long' ? {} : checkboxcss}
disabled={ischeck(itm.value) || ['workbench', 'dynamic', 'handle', 'DeviceAccess','discovery'].includes(itm.value)}
>
{itm.name}
</Checkbox>
@ -113,7 +114,8 @@ function Setup(props) {
})}
</div>
</div>
)})}
)
})}
</CheckboxGroup>
</Modal>
);

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

@ -106,3 +106,27 @@ export function getAppAlarmsAggDay (query) { //查询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: '' }
});
}

196
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,7 +54,7 @@ const Control = (props) => {
useEffect(() => {
if (socket) {
socket.on('alarmSendSocket', function (msg) {
//console.info(msg);
console.info(msg);
if (msg.type == "alarmAppear") {//
} else if (msg.type == "alarmConfirm") {//
@ -68,7 +73,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]))
@ -121,11 +126,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");
@ -240,16 +292,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 = [
@ -271,6 +325,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(() => {
@ -290,7 +357,7 @@ const Control = (props) => {
exhibition.current = { ...exhibition.current, [title]: TableDisplay }
setTableSetup([{ list: data }])
}
console.log(exhibition.current);
return (
<>
@ -306,7 +373,11 @@ const Control = (props) => {
</div>
</div>
<div style={{ width: 25, height: 25, cursor: "pointer" }}>
<img src="/assets/images/console/icon_all.png" alt="" style={{ width: '100%', height: '100%' }} />
<img src="/assets/images/console/icon_all.png" alt="" style={{ width: '100%', height: '100%' }} onClick={() => {
setSetup(true)
setTableType('overall')
attribute('overall')
}} />
</div>
</div>
{/* 主体 */}
@ -383,7 +454,10 @@ const Control = (props) => {
}
</div>
</div>
{/* 统计概览 */}
{exhibition.current?.overall?.find(v => v.key == 'statistical') ? <>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 25 }}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{ width: 0, height: 20, borderLeft: '3px solid #005ABD', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></div>
@ -398,6 +472,7 @@ const Control = (props) => {
}} />
</div>
</div>
{/* 统计概览 */}
<div id='overview' style={{ position: 'relative' }}>
<div style={{ display: 'inline-flex', marginTop: 16 }}>
{/* 项目里程碑 */}
@ -585,8 +660,10 @@ const Control = (props) => {
</div>
: ""}
</div>
</div></> : ""}
</div>
</div>
{exhibition.current?.overall?.find(v => v.key == 'analyse') ?
<div style={{ background: '#FFFFFF', boxShadow: '0px 0px 12px 2px rgba(220,222,224,0.2)', borderRadius: 2, paddingTop: 20, paddingLeft: 24, marginTop: 22 }}>
{/* BI分析模块 */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
@ -634,54 +711,64 @@ const Control = (props) => {
break;
}
}
// console.log(startValue);
return v.key == 'problemAnalysis' ? <div id={'ReactECharts' + index} style={{ marginTop: 20, padding: 10, width: '50%', display: "inline-block" }}>
<ReactECharts
option={{
title: {
text: v.name,
text: v.name + ' (每周更新) ',
subtext: "上次更新: " + moment(efficiencyBI?.time).format('YYYY-MM-DD HH:mm:ss'),
textStyle: {
fontSize: 18
},
subtextStyle: {
fontSize: 12,
color: '#FE9812'
}
},
grid: {
show: false,
left: '5%',
// right: '4%',
// bottom: '3%',
// containLabel: true
},
dataZoom: [
{
type: 'slider',
// startValue:
},
{
type: 'inside',
},
],
tooltip: {
trigger: 'axis'
},
legend: {
data: [v.name, '已处理(含自动恢复)'],
right: '10%',
},
xAxis: {
type: 'category',
name: "时间",
boundaryGap: false,
data: []
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,
barWidth: '30%',
label: {
normal: {
show: true,
position: 'top'
}
},
areaStyle: {
color: '#0e9cff26',
color: '#0F7EFB',
},
data: []
emphasis: {
color: '#E8F3FF',
}
// data: []
},
]
}}
@ -764,7 +851,7 @@ const Control = (props) => {
})}
</div>
</div>
</div> : ""}
</div>
{/* 右边 */}
<div style={{ width: 415, marginLeft: 20 }}>
@ -777,15 +864,39 @@ const Control = (props) => {
<div style={{ marginLeft: 6, fontSize: 12, color: '#969799', fontFamily: "DINExp", }}>RECENT NEWS</div>
</div>
<div style={{ marginRight: 25 }}>
<img title='设置' src="/assets/images/problem/setup.png" style={{ width: 18, height: 18, cursor: "pointer" }} onClick={() => setSetup(true)} />
<img title='设置' src="/assets/images/problem/setup.png" style={{ width: 18, height: 18, cursor: "pointer" }} onClick={() => {
setSetup(true)
setTableType('dynamic')
attribute('dynamic')
setLong('long')
}} />
</div>
</div>
<div id='news' style={{ height: 578, position: 'relative', marginTop: 10, }}>
<Timeline mode="center" style={{ marginLeft: '-56px', width: 400 }}>
{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 (
<Timeline.Item key={index + 'time'} position='left' time="2019-07-14 10:35" className={index % 2 == 0 ? 'even' : 'odd'} >
A项目DTU设备状态异常诊断为离线
<Timeline.Item key={index + 'time'} position='left' time={moment(v.time).format("YYYY-MM-DD HH:mm:ss")} className={index % 2 == 0 ? 'even' : 'odd'} >
<Tooltip content={title}>
<div style={{
width: 170,
height: '',
display: '-webkit-box',
overflow: 'hidden',
textOverflow: 'ellipsis',
webkitLineClamp: 2,
webkitBoxOrient: 'vertical',
color: '',
background: '',
}}>
{title}
</div>
</Tooltip>
</Timeline.Item>
)
})}
@ -793,6 +904,7 @@ const Control = (props) => {
</div>
</div>
{/* 我常用的工具 */}
{exhibition.current?.overall?.find(v => v.key == 'tool') ?
<div style={{ marginTop: 20, background: '#FFFFFF', boxShadow: '0px 0px 12px 2px rgba(220,222,224,0.2)', borderRadius: 2, padding: 20 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', alignItems: 'center' }}>
@ -866,7 +978,7 @@ const Control = (props) => {
添加
</Button>
</div>
</div> : ""}
</div>
</div>
</div>
@ -876,10 +988,12 @@ const Control = (props) => {
<Setup
tableType={tableType}
tableList={tableSetup}
layout={long}
close={() => {
setSetup(false);
attribute(tableType);
setTableType('')
setLong('')
}}
/>
) : (

4
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",

Loading…
Cancel
Save