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.
450 lines
17 KiB
450 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 }) => {
|
|
|
|
const [route, setRoute] = useState('') //子页面路由
|
|
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(() => {
|
|
setRoute(match.url.substring(match.url.lastIndexOf("/") + 1, match.url.length))
|
|
// console.log(match.url)
|
|
// console.log(tableType);
|
|
|
|
|
|
}, [])
|
|
|
|
|
|
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);
|
|
}, [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', 'AlarmCodeName', 'createTime', 'updateTime', 'confirm', 'confirmTime'],
|
|
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'
|
|
},
|
|
]
|
|
|
|
|
|
|
|
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>
|
|
}
|
|
{<Button theme='borderless' disabled>已派单</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)
|
|
|