运维服务中台
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.
 
 
 
 
 

361 lines
19 KiB

import React, { useState, useEffect, useRef } from "react";
import { connect } from "react-redux";
import { Button, Form, Modal, Skeleton, Pagination, Table } from "@douyinfe/semi-ui";
import { SkeletonScreen, } from "$components";
import moment from "moment";
import { validate } from "schema-utils";
import { emit } from "superagent";
const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition, pepProjectId,
selected, setSelected, setIfBulk, setConfirm, setGenre, query, setQuery, tableData, setTableData }) => {
const { problem } = actions
const [count, setCount] = useState(0) //
const [search, setSearch] = useState({}) //查询
const [checkAll, setCheckAll] = useState(true) //查询
const api = useRef();
let title = { dataLnterrupt: "数据中断详情", dataAbnormal: "数据异常详情", strategyHit: "策略命中详情", videoAbnormal: "视频异常详情", useAbnormal: "应用异常详情", deviceAbnormal: "设备异常详情" }
useEffect(() => {
switch (route) {
case 'useAbnormal':
dispatch(problem.getAlarmLnspectionApi({ ...search, pepProjectId: pepProjectId })).then((res) => {
if (res.success) {
let typeData = { element: "元素异常", apiError: "接口报错 ", timeout: "加载超时" }
let tableDatas = res.payload.data?.rows.map(v => ({
key: v.id,
projectName: v.app?.projectCorrelations?.map(r => (r.name ? { id: r.id, name: r.name, state: 'PMOS' } : {
id: r.id, name: r.pepProject?.projectName, state: r.pepProject?.constructionStatus
}))?.filter(c => c),
appName: v.app?.name,
url: v.app?.url,
createTime: v.createTime ? moment(v.createTime).format("YYYY-MM-DD HH:mm:ss") : "",
updateTime: v.updateTime ? moment(v.updateTime).format("YYYY-MM-DD HH:mm:ss") : "",
confirmTime: v.confirmTime ? moment(v.confirmTime).format("YYYY-MM-DD HH:mm:ss") : "",
alarmContent: v.alarmContent || '无',
screenshot: v.screenshot,
type: v.type ? typeData[v.type] : "",
confirm: v.confirm,
confirmAuto: v.confirmAuto,
}))
setCount(tableDatas?.length || 0);
setTableData(tableDatas)
}
})
break;
case 'videoAbnormal':
let cameraKind = []
dispatch(problem.getAlarmVideoDeviceKind()).then((res) => {
if (res.success) {
cameraKind = res.payload.data.map(v => ({ name: v.kind, value: v.id }))
setGenre(res.payload.data.map(v => ({ name: v.kind, value: v.id })))
}
})
dispatch(problem.getAlarmVideoList({ ...search, pepProjectId: pepProjectId })).then((res) => {
if (res.success) {
let tableDatas = res.payload.data?.map(v => ({
key: v.alarmId,
StructureName: v.struc,
projectName: v.pomsProject?.map(r => (r.name ? { id: r.id, name: r.name, state: 'PMOS' } : {
id: r.id, name: r.pepProject?.projectName, state: r.pepProject?.constructionStatus
}))?.filter(c => c),
createTime: v.createTime ? moment(v.createTime).format("YYYY-MM-DD HH:mm:ss") : "",
updateTime: v.updateTime ? moment(v.updateTime).format("YYYY-MM-DD HH:mm:ss") : "",
confirmTime: v.confirmTime ? moment(v.confirmTime).format("YYYY-MM-DD HH:mm:ss") : "",
SourceName: v.cameraName,
yingshiToken: v.yingshiToken,
AlarmContent: v.statusDescribe,
station: v.station || [],
resolve: v.resolve || [],
cameraChannelNo: v.cameraChannelNo,
cameraSerialNo: v.cameraSerialNo,
cameraKindId: v.cameraKindId ? cameraKind?.find(u => u.value == v.cameraKindId)?.name : "",
venderName: v.venderName,
platform: v.platform,
confirm: v.confirmContent,
camerOnline: v.camerOnline,
autoRestore: v.autoRestore,
}))
setCount(tableDatas?.length || 0);
setTableData(tableDatas)
}
})
break;
default:
dispatch(problem.getAlarmDataGroup()).then((res) => {
if (res.success) {
let routeData = { dataLnterrupt: '数据中断', dataAbnormal: '数据异常', strategyHit: '策略命中', deviceAbnormal: '' }
let data
if (route == 'dataLnterrupt') data = res.payload.data?.filter(v => v.desc == '数据中断')
if (route == 'dataAbnormal') data = res.payload.data?.filter(v => v.desc == '数据异常')
if (route == 'strategyHit') data = res.payload.data?.filter(v => v.desc == '策略命中')
if (route == 'deviceAbnormal') data = res.payload.data?.filter(v => v.desc == '掉线' || v.desc == '不活跃')
let genreData = []
data?.map(v => {
v?.unit?.map(vv => {
genreData.push({ name: vv.name, value: vv.id })
})
})
setGenre(genreData)
if (data && data[0]?.id) {
dispatch(problem.getAlarmDataList({ ...query, ...search, groupId: data.map(v => v.id).join(), pepProjectId: pepProjectId })).then((res) => {
if (res.success) {
setCount(res.payload.data?.count || 0)
let tableDatas = res.payload.data?.rows?.map(v => ({
key: v.AlarmId,
StructureName: v.StructureName,
projectName: v.pomsProject?.map(r => (r.name ? { id: r.id, name: r.name, state: 'PMOS' } : {
id: r.id, name: r.pepProject?.projectName, state: r.pepProject?.constructionStatus
}))?.filter(c => c),
createTime: v.StartTime ? moment(v.StartTime).format("YYYY-MM-DD HH:mm:ss") : "",
updateTime: v.EndTime ? moment(v.EndTime).format("YYYY-MM-DD HH:mm:ss") : "",
confirmTime: v.confirmedTime ? moment(v.confirmedTime).format("YYYY-MM-DD HH:mm:ss") : "",
SourceName: v.SourceName,
AlarmGroupUnit: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "无",
Strategy: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "",
type: route == 'deviceAbnormal' ? v.DeviceStatus == 0 ? "离线" : '' : v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "",
cameraKindId: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "",
AlarmCodeName: v.AlarmCodeName,
CurrentLevel: v.CurrentLevel,
detailCount: v.detailCount,
AlarmContent: v.AlarmContent,
State: v.State,
alarmType: v.alarmType,
confirm: v.confirmedContent,
station: v.StructureLongitude && v.StructureLatitude ? v.StructureLongitude + '. ' + v.StructureLatitude : "",
}))
setTableData(tableDatas)
}
})
}
}
})
break;
}
}, [query, search, pepProjectId])
return (
<>
<div style={{ backgroundColor: '#FFFFFF', margin: "20px 12px 12px", padding: "20px 20px 40px" }}>
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 6 }}>
<span style={{ width: 0, height: 20, margin: "0 8px 0 0", borderLeft: '3px solid #005ABD', borderTop: '3px solid transparent', borderBottom: '3px solid transparent' }}></span>
<span style={{ fontSize: 24, fontFamily: 'YouSheBiaoTiHei', color: '#101531', }}>{title[route]}</span>
<span style={{ marginLeft: 6, fontSize: 12, color: "rgb(150, 151, 153)", fontFamily: 'DINExp' }}>DETAILED INFORMATION</span>
</div>
<div style={{}}>
<div style={{ display: "flex", marginBottom: 16, }}>
<Form
onSubmit={(values) => console.log(values)}
getFormApi={(formApi) => (api.current = formApi)}
layout="horizontal"
style={{ position: "relative", width: "100%", flex: 1 }}
>
{(() => {
let frame = []
collectData[route]?.map((v, index) => {
if (index == 0) {
if (route == 'useAbnormal') {
frame.push(<Form.Input
label={v.name + ':'}
labelPosition="left"
field={v.field}
placeholder="项目或应用关键字"
showClear
style={{ width: 146, marginRight: 16, marginBottom: 16 }} />)
} else {
frame.push(<Form.InputGroup key={v.field} label={v.name + ':'} labelPosition="left" style={{ width: 203, marginRight: 16, marginBottom: 16 }}>
<Form.Select style={{ width: 88 }} field='keywordTarget' initValue='source' rules={[{ required: true, message: '请选择筛选类型' }]} showClear>
{[{ name: "告警源", value: "source" }, { name: "项目", value: "pepProject" }, { name: "结构物", value: "struc" },].map(vv => {
return <Form.Select.Option value={vv.value} key={vv.value}>{vv.name}</Form.Select.Option>
})}
</Form.Select>
<Form.Input field='keyword' maxLength="16" placeholder="关键字搜索" style={{ width: 115 }} />
</Form.InputGroup>)
}
} else {
frame.push(<Form.Select
label={v.name + ':'}
labelPosition="left"
field={v.field}
key={v.field}
maxLength="10"
style={{ width: 116, marginRight: 16, color: "#F9F9F9", }}
placeholder="全部"
filter
showClear
>
{v.data?.map((item) => {
return (
<Form.Select.Option key={item.value} value={item.value}>
{item.name}
</Form.Select.Option>
);
})}
</Form.Select>)
}
})
frame.push(<Form.DatePicker
type="dateTimeRange"
labelPosition="left"
style={{ width: 352 }}
label={collectData.common.name + ':'}
field={collectData.common.field}
key={collectData.common.field}
// onChange={(v) => console.log(v)}
/>)
return frame
})()}
</Form>
<div
style={{
width: 138,
display: "flex",
justifyContent: "space-between",
alignItems: "flex-end",
marginRight: 20,
marginBottom: 16
}}
>
<img title='导出' src="/assets/images/problem/export.png" style={{ width: 20 }} />
<img title='设置' src="/assets/images/problem/setup.png" style={{ width: 20 }} onClick={() => setSetup(true)} />
<Button
theme="solid"
type="primary"
style={{ width: 80, height: 32, borderRadius: 3, }}
onClick={() => {
api.current.validate().then((v) => {
setSearch({
state: v.state,
keywordTarget: v.keywordTarget,
keyword: v.keyword,
kindId: v.kindId,
groupUnitId: v.groupUnitId,
errType: v.errType,
confirmState: v.confirmState,
onlineState: v.onlineState,
sustainTimeStart: v.time && v.time.length > 0 ? moment(v.time[0]).format("YYYY-MM-DD HH:mm:ss") : "",
sustainTimeEnd: v.time && v.time.length > 0 ? moment(v.time[1]).format("YYYY-MM-DD HH:mm:ss") : "",
});
setSelected([])
setQuery({ limit: 10, page: 0 })
});
}}
>
查询
</Button>
</div>
</div>
</div>
<Skeleton
loading={false}
active={true}
placeholder={SkeletonScreen()}
>
<Table
columns={exhibition}
dataSource={route == 'useAbnormal' || route == 'videoAbnormal' ? tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] : tableData}
bordered={false}
empty={<div><img src="/assets/images/problem/shield.png" style={{ width: 20 }} />暂无告警数据</div>}
style={{}}
pagination={false}
onRow={(record, index) => {
if (index % 1 === 0) {
return { style: { background: '#FAFCFF' } }
}
}}
rowSelection={{
selectedRowKeys: selected || [],
getCheckboxProps: record => ({
disabled: record.confirmTime ? true : false,
// name: record.name,
}),
onSelect: (record, selected) => {
// console.log(`select row: ${selected}`, record);
},
// onSelectAll: (selected, selectedRows) => {
// console.log(`select all rows: ${selected}`, selectedRows);
// },
onChange: (selectedRowKeys, selectedRows) => {
// console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
setSelected(selectedRows?.map(v => v.key))
},
}}
/>
</Skeleton>
<div
style={{
display: "flex",
justifyContent: "space-between",
padding: "20px 20px",
}}
>
<div>
<div style={{ display: 'inline-block', lineHeight: '30px', fontSize: 13 }}>勾选<span style={{ fontWeight: 400, color: '#0F7EFB', margin: '0 6px' }}>{selected.length}</span></div>
<Button onClick={() => {
if (checkAll) {
setSelected((route == 'useAbnormal' || route == 'videoAbnormal' ? tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] : tableData)?.map(v => {
if (['videoAbnormal', 'useAbnormal'].includes(route)) {
if (!v.confirmTime) {
return v.key
}
} else {
if (!(v.State > 2)) {
return v.key
}
}
})?.filter(v => v))
} else {
setSelected([])
}
setCheckAll(!checkAll)
}}
style={{ width: 93, height: 24, borderRadius: '1px', border: '1px solid #0F7EFB', color: '#0F7EFB', background: "#FFFFFF", fontWeight: 400, margin: '0 10px' }}>
{checkAll ? '全选' : "取消全选"}
</Button>
<Button type='primary' theme='solid' onClick={() => (setIfBulk(true), setConfirm(true))} style={{ width: 93, height: 24, borderRadius: '1px', border: '1px solid #0F7EFB', color: '#FFFFFF', fontWeight: 400, }}>批量确认</Button>
</div>
{count > 0 ? <div style={{ display: 'flex', }}>
<span style={{ lineHeight: "30px", fontSize: 13 }}>
{count}个问题
</span>
<Pagination
className="22"
total={count}
showSizeChanger
currentPage={(query?.page || 0) + 1}
pageSizeOpts={[10, 20, 30, 40]}
onChange={(currentPage, pageSize) => {
setQuery({ limit: pageSize, page: currentPage - 1 });
}}
/>
</div> : ""}
</div>
</div>
</>
)
}
function mapStateToProps (state) {
const { auth, global, members } = state;
// console.log(global);
return {
user: auth.user,
actions: global.actions,
global: global,
pepProjectId: global.pepProjectId,
// members: members,
};
}
export default connect(mapStateToProps)(TableData);