运维服务中台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

438 lines
17 KiB

import React, { useEffect, useState } from 'react'
import { connect } from 'react-redux'
import { IconAlertCircle } from '@douyinfe/semi-icons'
import { Button, Form, Modal, Skeleton, Pagination, TextArea, Tooltip } from "@douyinfe/semi-ui";
import Statistics from '../components/statistics'
import TableData from '../components/tableData'
import SideSheets from '../components/sideSheet'
import { Setup, OutHidden } from "$components";
import moment from "moment";
import '../style.less'
import { request } from 'screenfull';
const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
let route = match.url.substring(match.url.lastIndexOf("/") + 1, match.url.length)
const [abnormalLenght, setAbnormalLenght] = useState(0) //异常数量
const [collect, setCollect] = useState([]) //搜索结构
const [setup, setSetup] = useState(false); //表格设置是否显现
const [tableSetup, setTableSetup] = useState([]); //单一表格设置信息
const [exhibition, setExhibition] = useState([]); //表格结构
const [anomaly, setAnomaly] = useState(); //单条异常对应的图片
const [pictures, setPictures] = useState(false); //单条异常对应的图片是否显示
const [confirm, setConfirm] = useState(false); //表格确认弹框
const [ifBulk, setIfBulk] = useState(false); //是否批量确认
const [content, setContent] = useState(false); //确认内容
const [selected, setSelected] = useState([]) //表格被勾选项
const [genre, setGenre] = useState([]) //搜索类型
const [checkPop, setCheckPop] = useState(false) //查看弹框是否显现
const [alarmId, setAlarmId] = useState(false) //查看alarmId
const [query, setQuery] = useState({ limit: 10, page: 0 }) //分页
const tableType = { dataLnterrupt: 'dataLnterrupt', dataAbnormal: 'dataAbnormal', strategyHit: 'strategyHit', videoAbnormal: 'videoAbnormal', useAbnormal: 'useAbnormal', deviceAbnormal: 'deviceAbnormal' }
const statistic = { dataLnterrupt: '数据中断统计', dataAbnormal: '数据异常统计', strategyHit: '策略命中统计', videoAbnormal: '视频异常统计', useAbnormal: '应用异常统计', deviceAbnormal: '设备异常统计' }
useEffect(() => {
if (route) {
//初始化表格显示设置
let data = columns[route]
data.splice(0, 1)
localStorage.getItem(tableType[route]) == null
? localStorage.setItem(
tableType[route],
JSON.stringify(data)
)
: "";
}
attribute(tableType[route], route);
}, [])
//搜索结构
const collectData = {
dataLnterrupt: [ //数据中断(dataLnterrupt)
{ name: '搜索', field: '1' },
{
name: '中断类型', field: 'groupUnitId',
data: genre
},
{
name: '中断状态', field: 'state',
data: [
{ name: '当前', value: 'new' },
{ name: '历史', value: 'histroy' }]
}],
dataAbnormal: [ //数据异常(dataAbnormal)
{ name: '搜索', field: '1' },
{
name: '异常类型', field: 'groupUnitId',
data: genre
},
{
name: '异常状态', field: 'state',
data: [
{ name: '当前', value: 'new' },
{ name: '历史', value: 'histroy' }]
}],
strategyHit: [ // 策略命中(strategyHit)
{ name: '搜索', field: '1' },
{
name: '策略类型', field: 'groupUnitId',
data: genre
},
{
name: '命中状态', field: 'state',
data: [
{ name: '当前', value: 'new' },
{ name: '历史', value: 'histroy' }]
}],
videoAbnormal: [ // 视频异常(videoAbnormal)
{ name: '搜索', field: '1' },
{
name: '设备类型', field: '2',
data: [
{ name: '枪机', value: '11' },
{ name: '球机', value: '22' },
{ name: '其他', value: '33' }]
},
{
name: '异常状态', field: '3',
data: [
{ name: '当前', value: '11' },
{ name: '历史', value: '22' }]
}],
useAbnormal: [ // 应用异常(useAbnormal)
{ name: '搜索', field: 'errType' },
{
name: '异常类型', field: '2',
data: [
{ name: '接口报错', value: 'apiError ' },
{ name: '加载超时', value: 'timeout' },
{ name: '元素异常', value: 'element' }]
},
{
name: '异常状态', field: '3',
data: [
{ name: '当前', value: '11' },
{ name: '历史', value: '22' }]
}],
deviceAbnormal: [ // 设备告警(deviceAbnormal)
{ name: '搜索', field: '1' },
{
name: '设备类型', field: 'groupUnitId',
data: genre
},
{
name: '异常状态', field: 'state',
data: [
{ name: '当前', value: 'new' },
{ name: '历史', value: 'histroy' }]
},
{
name: '异常类型', field: '4',
data: [
{ name: '离线', value: '11' }]
}],
common: {
name: '持续时间',
field: 'time'
}
}
//表格设置信息
const tableList = {
dataLnterrupt: ['index', 'projectName', 'StructureName', 'SourceName', 'AlarmGroupUnit', 'AlarmCodeName', 'createTime', 'AlarmContent', 'CurrentLevel', 'updateTime', 'detailCount', 'confirm', 'confirmTime',],
dataAbnormal: ['index', 'projectName', 'StructureName', 'SourceName', 'type', 'alarmType', 'createTime', 'AlarmContent', 'CurrentLevel', 'updateTime', 'detailCount', 'confirm', 'confirmTime'],
strategyHit: ['index', 'projectName', 'StructureName', 'SourceName', 'Strategy', 'State', 'createTime', 'AlarmContent', 'CurrentLevel', 'updateTime', 'detailCount', 'confirm', 'confirmTime'],
videoAbnormal: ['index', 'projectName', 'StructureName', 'SourceName', '19', '20', '21', '22', 'AlarmContent', '111', 'createTime', 'updateTime', 'confirm', 'confirmTime','56115'],
useAbnormal: ['index', 'projectName', 'appName', 'url', 'type', 'alarmContent', 'createTime', 'updateTime', 'confirm', 'confirmTime'],
deviceAbnormal: ['index', 'projectName', 'StructureName', 'SourceName', '19', 'alarmContent', '21', 'AlarmContent', 'AlarmCodeName', 'createTime', 'updateTime', 'confirm', 'confirmTime'],
}
//表格默认配置信息
const columns = {
dataLnterrupt: ['projectName', 'StructureName', 'SourceName', 'AlarmGroupUnit', 'AlarmContent', 'AlarmCodeName', 'createTime', 'updateTime',],
dataAbnormal: ['projectName', 'StructureName', 'SourceName', 'AlarmContent', 'AlarmCodeName', 'createTime', 'updateTime'],
strategyHit: ['projectName', 'StructureName', 'SourceName', 'Strategy', 'AlarmContent', 'CurrentLevel', 'detailCount', 'updateTime'],
videoAbnormal: ['projectName', 'StructureName', 'SourceName', '21', '20', 'AlarmContent', 'createTime', 'updateTime'],
useAbnormal: ['appName', 'projectName', 'url', 'type', 'alarmContent', 'createTime', 'updateTime'],
deviceAbnormal: ['projectName', 'StructureName', 'SourceName', 'alarmContent', '19', 'AlarmContent', 'createTime', 'updateTime'],
}
//所有表格信息
const columnAll = [
{
name: "序号", value: "index", render: (_, r, index) => {
return index + 1;
},
},
{ name: '问题编号', value: 'serialNumber', render: (_, r, index) => r.serialNumber },
{
name: '项目名称', value: 'projectName', render: (_, r, index) => {
return <>
{r.projectName?.map((v, index) => {
let width
let name = v
switch (r.projectName?.length) {
case 1:
if (v.length > 25) width = 358
break;
case 2:
if (v.length > 12) width = 173
break;
default:
if (v.length > 7) width = 112
break;
}
return (<div key={r.id + r.appName + index} style={{ display: 'inline-block', height: 20 }}>
{index > 0 ? <span style={{ width: 1, height: 12, border: '1px solid #DCDEE0', margin: '3px 8px', display: 'inline-block', }}></span> : ""}
{OutHidden({ width, name })}
</div>)
})}
{r.projectName?.length > 3 ?
<Tooltip
trigger="click"
// style={{ lineHeight: 2 }}
content={
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
{r.projectName?.map(vv => {
return <div key={vv}>
{vv}<span style={{ color: '#FFFFFF' }}></span>
</div>
})}
</div>}>
<span style={{ fontSize: 14, color: '#005ABD', marginLeft: 8, cursor: "pointer", }}>
{'+' + (r.projectName?.length - 3)}
</span>
</Tooltip> : ""}
</>
}
},
{ name: '结构物名称', value: 'StructureName' },
{ name: '告警源', value: 'SourceName' },
{ name: '中断类型', value: 'AlarmGroupUnit' },
{ name: '告警信息', value: 'AlarmContent' },
{ name: '常见原因', value: 'AlarmCodeName' },
{ name: '产生时间', value: 'createTime' },
{ name: '更新时间', value: 'updateTime' },
{ name: '服务器地址', value: '9' },
{
name: '告警等级', value: 'CurrentLevel', render: (_, r, index) => {
let data = { 1: '一级', 2: '二级', 3: '三级' }
return data[r.CurrentLevel]
}
},
{ name: '产生次数', value: 'detailCount' },
{ name: '确认信息', value: 'confirm', render: (_, r, index) => r.confirm },
{ name: '确认/恢复时间', value: 'confirmTime', },
{
name: '异常信息', value: 'alarmContent', render: (_, r, index) => {
return <>{r.alarmContent}
{r.screenshot ? <img src="/assets/images/problem/anomaly.png" style={{ display: 'inline-block', width: 12 }} onClick={() => (setAnomaly(r.screenshot), setPictures(true))} /> : ""}
</>
}
},
{ name: '异常原因', value: 'alarmType' },
{ name: '策略类型', value: 'Strategy' },
{
name: '命中状态', value: 'State', render: (_, r, index) => {
if (r.State == 3 || r.State == 4) {
return '历史'
}
return '当前'
}
},
{ name: '位置信息', value: '19' },
{ name: '设备类型', value: '20' },
{ name: '设备厂家', value: '21' },
{ name: '接入方式', value: '22' },
{ name: '应用名称', value: 'appName' },
{ name: 'URL地址', value: 'url' },
{name: '异常类型', value: 'type'},
{name: '解决方案', value: '111'},
{name: '在离线', value: '56115'},
]
const attribute = (name, route) => {
let arr = localStorage.getItem(name)
? JSON.parse(localStorage.getItem(name))
: [];
// console.log(arr);
if (route) {
let setup = tableList[route].map(v => columnAll.find(vv => v == vv.value))
let data = []
// if (tableType[route] == 'dataAbnormal') {
// data = ['AlarmCodeName']
// data.splice(1, 0, ...arr)
// } else {
data.splice(1, 0, ...arr)
// }
// console.log(data)
// let TableDisplay = []
let TableDisplay = data?.map(v => {
let datas = columnAll?.find(vv => v == vv.value)
if (datas) {
return { title: datas.name, dataIndex: datas.value, rowKey: datas.value, render: datas.render }
}
})
// console.log(TableDisplay);
TableDisplay.push({
title: '操作',
dataIndex: 'text',
rowKey: 'text',
render: (_, r) => {
return <div style={{ width: 190 }}>
{r.confirmTime ? <Button theme='borderless' disabled>已确认</Button> :
<Button theme='borderless' onClick={() => (setConfirm(true), setSelected([r.id]))}>确认</Button>
}
{route ? ['dataLnterrupt', 'dataAbnormal', 'strategyHit'].includes(route) ? <>
<Button theme='borderless' disabled>已派单</Button>
<Button theme='borderless' onClick={() => (setCheckPop(true))}>查看</Button>
</>
: "" : ""
}
</div>
}
})
// console.log(TableDisplay);
// console.log(setup);
setExhibition(TableDisplay)
setTableSetup([{ list: setup }])
}
// for (let i = 0; i < arr.length; i++) {
// let colum = column.filter((item) => {
// return item.key === arr[i];
// });
// columns.splice(i + 2, 0, colum[0]);
// }
// setSetupp(columns);
}
const distinguish = (route) => {
switch (route) {
case value:
break;
default:
break;
}
}
return (
<div style={{ minWidth: 1000 }}>
{/* 滞留提醒 */}
<div>
{abnormalLenght > 0 ? <div style={{ height: 30, fontSize: 12, display: 'flex' }}><IconAlertCircle /><div>当前滞留5个工单即将超时请尽快处理</div></div> : ""}
</div>
<Statistics
route={route}
tableType={tableType}
statistic={statistic}
/>
<TableData
route={route}
collectData={collectData}
setSetup={setSetup}
exhibition={exhibition}
setConfirm={setConfirm}
setIfBulk={setIfBulk}
selected={selected}
setSelected={setSelected}
setGenre={setGenre}
/>
{setup ? (
<Setup
tableType={tableType[route] || []}
tableList={tableSetup}
close={() => {
setSetup(false);
attribute(tableType[route], route);
// setcameraSetup(false);
}}
/>
) : (
""
)}
{pictures ? <Modal
hasCancel={false}
closable={false}
visible={true}
footer=''
width={837}
onCancel={() => setPictures(false)}
>
<img src={`/_file-server/${anomaly}`}
style={{ width: 789, height: 359, }}
/>
</Modal> : ""}
{confirm ? <Modal
title={ifBulk ? '批量确认' : "确认"}
visible={true}
width={600}
onCancel={() => setConfirm(false)}
onOk={() => {
if (route == 'useAbnormal') {
dispatch(problem.postApiConfirm({ appAlarmId: selected, confirm: content })).then(res => {
if (res.success) {
setConfirm(false)
setQuery({ limit: query.limit, page: query.page })
}
})
} else if (route == 'videoAbnormal') {
setConfirm(false)
} else {
dispatch(problem.putAlarmdataConfirm({ alarmId: selected, content: content })).then(res => {
if (res.success) {
setConfirm(false)
setQuery({ limit: query.limit, page: query.page })
}
})
}
}}
>
<div style={{ display: 'flex', paddingLeft: 20 }}>
<span style={{ display: 'inline-block', width: 78 }}>确认信息:</span>
<TextArea maxCount={500} showClear onChange={(e) => setContent(e)} />
</div>
</Modal> : ""}
{checkPop ?
<SideSheets
close={() => {
setCheckPop(false)
}}
/> : ""
}
</div>
)
}
function mapStateToProps (state) {
const { auth, global, members, webSocket } = state
return {
// loading: members.isRequesting,
user: auth.user,
actions: global.actions,
// members: members.data,
// socket: webSocket.socket
}
}
export default connect(mapStateToProps)(DataAlarm)