feat():ai告警页面更改
parent
09ee59d002
commit
e767f8648a
|
|
@ -2,6 +2,7 @@ import { FC, useEffect, useRef, useState } from 'react'
|
||||||
// import styles from './index.module.less'
|
// import styles from './index.module.less'
|
||||||
import { message, Spin } from "antd";
|
import { message, Spin } from "antd";
|
||||||
import EZUIKit from 'ezuikit-js';
|
import EZUIKit from 'ezuikit-js';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 海康视频H5插件视频播放
|
* 海康视频H5插件视频播放
|
||||||
|
|
@ -23,10 +24,16 @@ const HFivePlayer = ({ wsUrl, playerID, size }) => {
|
||||||
|
|
||||||
|
|
||||||
const initVideo = () => {
|
const initVideo = () => {
|
||||||
|
const hasReplayRange = wsUrl?.beginTime && wsUrl?.endTime && wsUrl?.indexCode;
|
||||||
|
const beginStr = hasReplayRange ? moment(wsUrl.beginTime).format('YYYYMMDDHHmmss') : '';
|
||||||
|
const endStr = hasReplayRange ? moment(wsUrl.endTime).format('YYYYMMDDHHmmss') : '';
|
||||||
|
const ezUrl = hasReplayRange
|
||||||
|
? `ezopen://open.ys7.com/${wsUrl.indexCode}/1.rec?begin=${beginStr}&end=${endStr}`
|
||||||
|
: `ezopen://open.ys7.com/${wsUrl.indexCode}/1.live`;
|
||||||
playerYsy.current = new EZUIKit.EZUIKitPlayer({
|
playerYsy.current = new EZUIKit.EZUIKitPlayer({
|
||||||
id: 'player' + playerID, // 视频容器ID
|
id: 'player' + playerID, // 视频容器ID
|
||||||
accessToken: wsUrl.src,
|
accessToken: wsUrl.src,
|
||||||
url: `ezopen://open.ys7.com/${wsUrl.indexCode}/1.live`,
|
url: ezUrl,
|
||||||
// plugin: ["talk"], // 加载插件,talk-对讲
|
// plugin: ["talk"], // 加载插件,talk-对讲
|
||||||
width: parentRef.current?.offsetWidth,
|
width: parentRef.current?.offsetWidth,
|
||||||
height: parentRef.current?.offsetHeight,
|
height: parentRef.current?.offsetHeight,
|
||||||
|
|
@ -133,6 +140,13 @@ const HFivePlayer = ({ wsUrl, playerID, size }) => {
|
||||||
if (wsUrl?.src) {
|
if (wsUrl?.src) {
|
||||||
setIsLoading(true) //开始加载
|
setIsLoading(true) //开始加载
|
||||||
let preUrl = wsUrl?.src // 播放地址
|
let preUrl = wsUrl?.src // 播放地址
|
||||||
|
// 支持回放时间范围(海康取流地址若后端支持时间参数则追加)
|
||||||
|
if (wsUrl?.beginTime && wsUrl?.endTime) {
|
||||||
|
const begin = moment(wsUrl.beginTime).subtract(1,'hours').format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
const end = moment(wsUrl.endTime).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
const sep = preUrl.includes('?') ? '&' : '?';
|
||||||
|
preUrl = `${preUrl}${sep}beginTime=${begin}&endTime=${end}`;
|
||||||
|
}
|
||||||
console.log(preUrl);
|
console.log(preUrl);
|
||||||
const param = {
|
const param = {
|
||||||
playURL: preUrl,
|
playURL: preUrl,
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ const Page = ({ mySetTms }) => {
|
||||||
{ key==='位移告警'?<Table_wy data={dataObj.shiftWarn} onCancel={()=>setOpen(false)}/>:null }
|
{ key==='位移告警'?<Table_wy data={dataObj.shiftWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||||
{ key==='渗压告警'?<Table_sy data={dataObj.pressWarn} onCancel={()=>setOpen(false)}/>:null }
|
{ key==='渗压告警'?<Table_sy data={dataObj.pressWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||||
{ key==='渗流告警'?<Table_sl data={dataObj.flowWarn} onCancel={()=>setOpen(false)}/>:null }
|
{ key==='渗流告警'?<Table_sl data={dataObj.flowWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||||
{key === 'AI告警' ? <Table_AI /> : null}
|
{key === 'AI告警' ? <Table_AI tms={tms} /> : null}
|
||||||
{ key==='白蚁告警'?<Table_by data={dataObj.byWarn} onCancel={()=>setOpen(false)}/>:null }
|
{ key==='白蚁告警'?<Table_by data={dataObj.byWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import apiurl from "../../../../service/apiurl";
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
|
|
||||||
const Page = () => {
|
const Page = ({ tms }) => {
|
||||||
|
|
||||||
// const { tableProps, search, refresh } = usePageTable(createCrudService('/gunshiApp/tsg/rescue/goods/page/query').find_noCode,{});
|
// const { tableProps, search, refresh } = usePageTable(createCrudService('/gunshiApp/tsg/rescue/goods/page/query').find_noCode,{});
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ const Page = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ant-card-body" style={{padding:"0 10px",height:'600px',overflowY:'auto'}}>
|
<div className="ant-card-body" style={{padding:"0 10px",height:'600px',overflowY:'auto'}}>
|
||||||
<AiWarn/>
|
<AiWarn tm={tms}/>
|
||||||
{/* <div>时间:{moment().format('YYYY-MM-DD HH:mm:ss')} 至 {moment().format('YYYY-MM-DD HH:mm:ss')}</div> */}
|
{/* <div>时间:{moment().format('YYYY-MM-DD HH:mm:ss')} 至 {moment().format('YYYY-MM-DD HH:mm:ss')}</div> */}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,128 @@
|
||||||
import React, { Fragment, useRef, useMemo,useEffect,useState } from 'react';
|
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
|
||||||
import { Table, Card,Modal,Form,Input,Button,Row,Pagination,message } from 'antd';
|
import { Table, Card, Modal, Form, Input, Button, Row, Pagination, message } from 'antd';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import ToolBar from './toolbar';
|
import ToolBar from './toolbar';
|
||||||
import apiurl from '../../../service/apiurl';
|
import apiurl from '../../../service/apiurl';
|
||||||
import usePageTable from '../../../components/crud/usePageTable3';
|
import usePageTable from '../../../components/crud/usePageTable3';
|
||||||
import { createCrudService } from '../../../components/crud/_';
|
import { createCrudService } from '../../../components/crud/_';
|
||||||
|
import { httpget2,httppost2 } from '../../../utils/request';
|
||||||
|
import HFivePlayer from '../../../components/video1Plary';
|
||||||
import CardShow from "./Card"
|
import CardShow from "./Card"
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
const Page = () => {
|
import moment from 'moment';
|
||||||
const role = useSelector(state => state.auth.role);
|
const Page = (props) => {
|
||||||
|
const tm = props?.tm;
|
||||||
const [searchVal, setSearchVal] = useState(false)
|
const statusObj = {
|
||||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.spjk1.aiWarn.page1).find_noCode);
|
0: "未处理",
|
||||||
const onchange = (page, pageSize) => {
|
1: '已处理'
|
||||||
const obj = {
|
};
|
||||||
pageNumber: page,
|
const levelStatus = {
|
||||||
pageSize: pageSize,
|
1: '低',
|
||||||
}
|
2: '中',
|
||||||
const searchParams = {
|
3: '高'
|
||||||
...obj,
|
|
||||||
// search: {
|
|
||||||
// ...searchVal,
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
search(searchParams)
|
|
||||||
}
|
}
|
||||||
|
const role = useSelector(state => state.auth.role);
|
||||||
|
const columns = [
|
||||||
|
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
|
||||||
|
{ title: '事件源名称', key: 'resName', dataIndex: 'resName', width: 150, ellipsis: true },
|
||||||
|
{
|
||||||
|
title: '事件类型名称', key: 'eventTypeName', dataIndex: 'eventTypeName', width: 150, ellipsis: true
|
||||||
|
},
|
||||||
|
{ title: '事件处理状态', key: 'handleStatus', dataIndex: 'handleStatus', width: 120, render: (v) => <span>{statusObj[v]}</span> },
|
||||||
|
{ title: '事件等级', key: 'eventLevel', dataIndex: 'eventLevel', width: 100, render: (v) => <span>{levelStatus[v]}</span> },
|
||||||
|
{ title: '事件开始时间', key: 'startTime', dataIndex: 'startTime', width: 150, render: (v) => <span>{v ? moment(v).format("YYYY-MM-DD HH:mm:ss") : ''}</span> },
|
||||||
|
{ title: '事件结束时间', key: 'endTime', dataIndex: 'endTime', width: 150, render: (v) => <span>{v ? moment(v).format("YYYY-MM-DD HH:mm:ss") : ''}</span> },
|
||||||
|
// {
|
||||||
|
// title: '操作', key: 'opr', dataIndex: 'opr', width: 100, align: "center",
|
||||||
|
// render:(v,r)=><Button type="link" onClick={()=>replay(r)}>回放</Button>
|
||||||
|
// },
|
||||||
|
|
||||||
|
];
|
||||||
|
const [searchVal, setSearchVal] = useState(false)
|
||||||
|
const [replayOpen, setReplayOpen] = useState(false)
|
||||||
|
const [replayItem, setReplayItem] = useState({})
|
||||||
|
const [videoSrc, setVideoSrc] = useState('')
|
||||||
|
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.spjk1.aiWarn.page1).find_noCode);
|
||||||
|
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||||
|
|
||||||
|
const replay = (r) => {
|
||||||
|
setReplayOpen(true);
|
||||||
|
setReplayItem(r)
|
||||||
|
getVideoSrc(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getVideoSrc = async(data) => {
|
||||||
|
try {
|
||||||
|
// 仅获取播放地址,回放时间由播放器拼接
|
||||||
|
const res = await httpget2(`${apiurl.gsxl.zfzl.videosrc}${data.resIndexCode}`)
|
||||||
|
setVideoSrc(res.data)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 当外部传入 tm([start,end])时,初始化查询条件
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (searchVal) {
|
if (tm && Array.isArray(tm) && tm[0]) {
|
||||||
const params = {
|
setSearchVal({
|
||||||
|
startTime: moment(tm[0]).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [tm])
|
||||||
|
|
||||||
|
// 路由直接进入 AI 告警页(没有 tm)时,初始化一次默认查询
|
||||||
|
useEffect(() => {
|
||||||
|
if (!tm) {
|
||||||
|
setSearchVal({})
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const params = {
|
||||||
search: {
|
search: {
|
||||||
...searchVal,
|
...searchVal,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search(params)
|
// 避免初始化时触发空查询造成二次请求闪烁
|
||||||
|
if (searchVal !== false) {
|
||||||
|
search(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [searchVal])
|
}, [searchVal])
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='content-root clearFloat xybm' style={{paddingRight:"0",paddingBottom:"0"}}>
|
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}>
|
||||||
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%" }}>
|
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%" }}>
|
||||||
<Card className='nonebox'>
|
<Card className='nonebox'>
|
||||||
<ToolBar
|
<ToolBar
|
||||||
setSearchVal={setSearchVal}
|
setSearchVal={setSearchVal}
|
||||||
role={role}
|
role={role}
|
||||||
|
tm={tm}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
<div className="ant-card-body" style={{padding:"20px 0 0 0",display:"flex",flexWrap:"wrap",maxHeight:650,overflowY:"auto"}}>
|
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
|
||||||
{
|
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 500px )" }} />
|
||||||
tableProps.dataSource.length > 0 ?
|
|
||||||
tableProps.dataSource.map((item,i) => {
|
|
||||||
return (
|
|
||||||
<div key={i} >
|
|
||||||
<CardShow
|
|
||||||
record={item}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}) : null
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<div style={{textAlign: "right", marginTop: "25px",marginRight:40}}>
|
|
||||||
<Pagination
|
|
||||||
current={tableProps.pagination.current}
|
|
||||||
total={tableProps.pagination.total}
|
|
||||||
showTotal={tableProps.pagination.showTotal}
|
|
||||||
pageSize={tableProps.pagination.pageSize}
|
|
||||||
showSizeChanger
|
|
||||||
showQuickJumper
|
|
||||||
pageSizeOptions={[4, 8, 12, 16]}
|
|
||||||
onChange={onchange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<Modal
|
||||||
|
open={replayOpen}
|
||||||
|
width={800}
|
||||||
|
title={replayItem?.resName}
|
||||||
|
onCancel={() => setReplayOpen(false)}
|
||||||
|
footer={null}
|
||||||
|
destroyOnClose
|
||||||
|
>
|
||||||
|
<div style={{ width: "100%", height: 500 }}>
|
||||||
|
<HFivePlayer
|
||||||
|
size={1}
|
||||||
|
wsUrl={{
|
||||||
|
src: videoSrc,
|
||||||
|
indexCode: replayItem?.resIndexCode,
|
||||||
|
beginTime: replayItem?.startTime,
|
||||||
|
endTime: replayItem?.endTime,
|
||||||
|
}}
|
||||||
|
playerID={replayItem?.id} />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,26 +5,22 @@ import moment from 'moment';
|
||||||
import { httppost2 } from '../../../utils/request';
|
import { httppost2 } from '../../../utils/request';
|
||||||
import apiurl from '../../../service/apiurl';
|
import apiurl from '../../../service/apiurl';
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
const ToolBar = ({ setSearchVal, onSave, storeData, role, tm }) => {
|
||||||
const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true;
|
const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true;
|
||||||
|
|
||||||
const warnTypes = [
|
const warnTypes = [
|
||||||
{
|
{
|
||||||
label: "人员闯入",
|
label: "低",
|
||||||
value:1
|
value:1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "工程车辆识别",
|
label: "中",
|
||||||
value:2
|
value:2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "漂浮物识别",
|
label: "高",
|
||||||
value:3
|
value:3
|
||||||
},
|
}
|
||||||
{
|
|
||||||
label: "游泳识别",
|
|
||||||
value:4
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [codeList, setCodeList] = useState([])
|
const [codeList, setCodeList] = useState([])
|
||||||
|
|
@ -38,46 +34,30 @@ const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onFinish = (values) => {
|
const onFinish = (values) => {
|
||||||
let dateSo;
|
if (values.startTime) {
|
||||||
if (values.tm) {
|
values.startTime = moment(values.startTime).format('YYYY-MM-DD HH:mm:ss');
|
||||||
dateSo = {
|
|
||||||
start: moment(values.tm[0]).format('YYYY-MM-DD 00:00:00'),
|
|
||||||
end: moment(values.tm[1]).format('YYYY-MM-DD 23:59:59')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete values.tm
|
setSearchVal({...values});
|
||||||
setSearchVal({...values, dateTimeRangeSo:dateSo});
|
|
||||||
}
|
}
|
||||||
|
// 预填开始时间(来自外部 tm)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getStationCode()
|
if (tm && Array.isArray(tm) && tm[0]) {
|
||||||
let time = [moment().subtract(1,"weeks"),moment()]
|
form.setFieldsValue({ startTime: moment(tm[0]) })
|
||||||
let dateSo = {
|
}
|
||||||
start:moment(time[0]).format('YYYY-MM-DD 00:00:00'),
|
}, [tm])
|
||||||
end:moment(time[1]).format('YYYY-MM-DD 23:59:59'),
|
|
||||||
}
|
|
||||||
form.setFieldValue("tm",time)
|
|
||||||
setSearchVal({dateTimeRangeSo:dateSo})
|
|
||||||
}, [])
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||||
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} >
|
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} >
|
||||||
<Form.Item label="告警日期" name="tm">
|
<Form.Item label="事件开始时间" name="startTime">
|
||||||
<RangePicker
|
<DatePicker
|
||||||
allowClear
|
allowClear
|
||||||
style={{ width: "350px" }}
|
style={{ width: "200px" }}
|
||||||
format="YYYY-MM-DD"
|
showTime
|
||||||
|
placeholder='请选择时间'
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="告警点位" name="indexCode">
|
<Form.Item label="事件等级" name="eventLevel">
|
||||||
<NormalSelect
|
|
||||||
allowClear
|
|
||||||
style={{ width: "150px" }}
|
|
||||||
options={codeList}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="告警类型" name="type">
|
|
||||||
<NormalSelect
|
<NormalSelect
|
||||||
allowClear
|
allowClear
|
||||||
style={{ width: "150px" }}
|
style={{ width: "150px" }}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue