123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- import ModuleTitle from '@/components/ManagementPage/moduleTitle';
- import TabsContent from '@/components/TabsContent';
- import ThresholdDetail from '@/components/ThresholdDetail';
- import { UnityAction } from '@/utils/utils';
- import { Collapse, Empty, Spin, Table, Tabs } from 'antd';
- import { useEffect, useMemo, useState } from 'react';
- import styles from './VideoAnalysis.less';
- const { TabPane } = Tabs;
- const { Panel } = Collapse;
- const TYPE = {
- video: 1,
- fill: 2,
- water: 3,
- };
- function VideoAnalysis(props) {
- const { videoNum, data, videoData = {}, loading } = props;
- const [tab, setTab] = useState('1');
- const allCount = Object.values(videoData).reduce(
- (total, item) => total + (item?.length || 0),
- 0,
- );
- const [prevKey, setPrevKey] = useState();
- const [selectedName, setSelectedName] = useState('');
- const errorData = useMemo(() => {
- const list1 =
- videoData.dumu_list?.map((item) => {
- return { ...item, type_name: '视频报警', type: TYPE.video };
- }) || [];
- const list2 =
- videoData.environment_list
- ?.filter((item) => item.status)
- .map((item) => {
- return { ...item, type_name: '环境检测', type: TYPE.fill };
- }) || [];
- // const list3 =
- // videoData.fluid_level_list
- // ?.filter((item) => item.status)
- // .map((item) => {
- // return { ...item, type_name: '液位监测', type: TYPE.water };
- // }) || [];
- return [...list1, ...list2];
- }, [videoData]);
- useEffect(() => {
- UnityAction.on('SynCam', selectedItem);
- UnityAction.on('SynDev', selectedItem);
- return () => {
- UnityAction.off('SynDev', selectedItem);
- UnityAction.off('SynCam', selectedItem);
- };
- }, [videoData]);
- //滚动到相应位置
- const selectedItem = (e) => {
- setSelectedName(e);
- const dom = document.querySelector(`div[data-name="${e}"]`);
- if (dom) {
- let v = document.getElementById('videoContent');
- v.scrollTop = dom.offsetTop;
- }
- };
- const onTabChange = (tab) => {
- setTab(tab);
- setSelectedName('');
- UnityAction.sendMsg('SensorAnalysisType', tab);
- };
- return (
- <Spin spinning={loading}>
- <div style={{ height: 'calc(100vh - 5.6rem)', overflow: 'auto' }}>
- <TabsContent
- small
- bold={false}
- spacing={2.5}
- center={false}
- defaultActiveKey="1"
- items={[
- {
- label: `异常(${videoNum})`,
- key: '1',
- children: (
- <AnalysisContent
- errorData={errorData}
- selectedName={selectedName}
- setSelectedName={setSelectedName}
- />
- ),
- },
- {
- label: `全部(${allCount})`,
- key: '2',
- children: (
- <AllContent
- videoData={videoData}
- selectedName={selectedName}
- setSelectedName={setSelectedName}
- />
- ),
- },
- ]}
- onChange={onTabChange}
- />
- </div>
- </Spin>
- );
- }
- function AnalysisContent({ errorData, selectedName, setSelectedName }) {
- const [prevKey, setPrevKey] = useState();
- const handleImgClick = (item) => {
- localStorage.setItem('preview', item.path);
- UnityAction.sendMsg('SensorPic');
- };
- const handleCollapse = (item) => {
- const key = item.type == TYPE.video ? item.device_name : item.device_code;
- const name = item.type == TYPE.video ? 'SynCam' : 'SynDev';
- // 清除unity发送过来的选中设备
- setSelectedName('');
- if (item.key === prevKey) return;
- setPrevKey(item.key);
- UnityAction.sendMsg(name, key);
- };
- const renderContent = (key, item) => {
- let content = '';
- switch (key) {
- case 1:
- content = (
- <>
- <div className={styles.label}>画面报警:</div>
- <div className={styles.content}>
- {item.event_type}
- <img
- className={styles.img}
- src={item.path}
- onClick={() => handleImgClick(item)}
- />
- </div>
- </>
- );
- break;
- case 2:
- content = (
- <>
- <div className={styles.contentFlex}>
- <div>参数:{item.patrol_name}</div>
- <div className={styles.threshold}>
- <span>阈值范围:</span>
- <div style={{ width: '1.8rem' }}>
- <ThresholdDetail
- current={item.value || 0}
- data={{
- JsonNumThreshold: item?.json_num_threshold,
- Type: 2,
- }}
- />
- </div>
- </div>
- <div>
- 状态:
- {item?.status <= 0 ? (
- <span className={styles.textNormal}>正常</span>
- ) : item.status == 1 ? (
- <span className={styles.textAbnormal}>异常</span>
- ) : (
- <span className={styles.textWarning}>警告</span>
- )}
- </div>
- </div>
- </>
- );
- break;
- case 3:
- content = (
- <>
- <div className={styles.contentFlex}>
- <div>原液位:{item.origin_value}</div>
- <div> 差值:{item.value} </div>
- <div className={styles.threshold}>
- <span>阈值范围:</span>
- <div style={{ width: '1.8rem' }}>
- <ThresholdDetail
- current={item.value || 0}
- data={{
- JsonNumThreshold: item?.json_num_threshold,
- Type: 2,
- }}
- />
- </div>
- </div>
- <div>
- 状态:
- {item?.status <= 0 ? (
- <span className={styles.textNormal}>正常</span>
- ) : item.status == 1 ? (
- <span className={styles.textAbnormal}>异常</span>
- ) : (
- <span className={styles.textWarning}>警告</span>
- )}
- </div>
- </div>
- </>
- );
- break;
- }
- return content;
- };
- const getClassName = (item) => {
- const device =
- item.type == TYPE.video ? item.device_name : item.device_code;
- if (selectedName && selectedName == device) {
- return styles.tableSelect;
- } else if (prevKey == item.key) {
- return styles.tableSelect;
- }
- return styles.table;
- };
- return (
- <div
- className={styles.page}
- style={{ height: 'calc(100vh - 6.3rem)', overflow: 'auto' }}
- >
- {errorData?.length > 0 ? (
- errorData.map((item) => (
- <div
- data-name={item.device_name}
- key={item.key}
- onClick={() => handleCollapse(item)}
- >
- <Collapse
- activeKey={item.key}
- className={getClassName(item)}
- expandIcon={() => (
- <div className={styles.typeText}>{item.type_name}</div>
- )}
- >
- <Panel header={item.device_name} key={item.key}>
- <div className={styles.box}>
- <div className={styles.item}>
- {renderContent(item.type, item)}
- </div>
- </div>
- </Panel>
- </Collapse>
- </div>
- ))
- ) : (
- <Empty />
- )}
- </div>
- );
- }
- function AllContent({ videoData = {}, selectedName, setSelectedName }) {
- const {
- environment_list = [],
- // fluid_level_list = [],
- dumu_list = [],
- } = videoData;
- // const [selectedRowKeys, setSelectedRowKeys] = useState([]);
- const [selectKey, setSelectKey] = useState([]);
- const columns1 = [
- {
- title: '设备名称',
- render: (record) => (
- <div>
- {record.device_name}({record.device_code})
- </div>
- ),
- },
- {
- title: '参数',
- dataIndex: 'patrol_name',
- key: 'patrol_name',
- },
- {
- title: '设定值范围',
- render: (record) => (
- <ThresholdDetail
- current={record.value || 0}
- data={{
- JsonNumThreshold: record?.json_num_threshold,
- Type: record.type || 2,
- }}
- />
- ),
- },
- {
- title: '状态',
- dataIndex: 'status',
- render: (status) => {
- switch (status) {
- case -1:
- case 0:
- return (
- <div>
- <i
- className={styles.iconStatus}
- style={{ background: '#12CEB3' }}
- ></i>
- 正常
- </div>
- );
- case 1:
- return (
- <div>
- <i
- className={styles.iconStatus}
- style={{ background: '#FE5850' }}
- ></i>
- 异常
- </div>
- );
- case 2:
- return (
- <div>
- <i
- className={styles.iconStatus}
- style={{ background: '#FFE26D' }}
- ></i>
- 警告
- </div>
- );
- }
- },
- },
- ];
- const columns2 = [
- {
- title: '设备名称',
- render: (record) => (
- <div>
- {record.device_name}({record.device_code})
- </div>
- ),
- },
- {
- title: '液位数',
- dataIndex: 'origin_value',
- key: 'origin_value',
- },
- {
- title: '差值',
- dataIndex: 'value',
- key: 'value',
- },
- {
- title: '设定值范围',
- render: (record) => (
- <ThresholdDetail
- current={record.value || 0}
- data={{
- JsonNumThreshold: record?.json_num_threshold,
- Type: record.type || 2,
- }}
- // onClick={() => onClickThreshold(record)}
- />
- ),
- },
- {
- title: '状态',
- dataIndex: 'status',
- render: (status) => {
- switch (status) {
- case -1:
- case 0:
- return (
- <div>
- <i
- className={styles.iconStatus}
- style={{ background: '#12CEB3' }}
- ></i>
- 正常
- </div>
- );
- case 1:
- return (
- <div>
- <i
- className={styles.iconStatus}
- style={{ background: '#FE5850' }}
- ></i>
- 异常
- </div>
- );
- case 2:
- return (
- <div>
- <i
- className={styles.iconStatus}
- style={{ background: '#FFE26D' }}
- ></i>
- 警告
- </div>
- );
- }
- },
- },
- ];
- const columns3 = [
- {
- title: '名称',
- render: (record) => (
- <div>
- {record.device_name}({record.device_code})
- </div>
- ),
- },
- {
- title: '描述',
- dataIndex: 'event_type',
- key: 'event_type',
- },
- {
- title: '图片',
- render: (item) => (
- <img
- className={styles.img}
- src={item.path}
- onClick={() => handleImgClick(item)}
- />
- ),
- },
- ];
- const onSelectRow = (item, type) => {
- const key = type == TYPE.video ? item.device_name : item.device_code;
- const name = type == TYPE.video ? 'SynCam' : 'SynDev';
- setSelectedName('');
- if (selectKey === item.key) return;
- setSelectKey(item.key);
- UnityAction.sendMsg(name, key);
- };
- const handleImgClick = (item) => {
- localStorage.setItem('preview', item.path);
- UnityAction.sendMsg('SensorPic');
- };
- const setRowClassName = (item) => {
- const device =
- item.type == TYPE.video ? item.device_name : item.device_code;
- if (selectedName && selectedName == device) {
- return styles.tableSelect;
- } else if (selectKey == item.key) {
- return styles.tableSelect;
- }
- return '';
- };
- return (
- <div
- className={styles.page}
- style={{
- height: 'calc(100vh - 6.3rem)',
- overflow: 'auto',
- // backgroundColor: '#FFFFFF',
- }}
- >
- <div className={styles.box}>
- <ModuleTitle title="环境检测" />
- <Table
- dataSource={environment_list}
- columns={columns1}
- rowClassName={setRowClassName}
- onRow={(record, index) => ({
- onClick: () => onSelectRow(record, TYPE.fill),
- })}
- pagination={false}
- scroll={{ y: 400 }}
- />
- </div>
- {/* <div className={`card-box ${styles.box}`}>
- <ModuleTitle title="液位检测" />
- <Table
- dataSource={fluid_level_list}
- columns={columns2}
- rowClassName={setRowClassName}
- onRow={(record, index) => ({
- onClick: () => onSelectRow(record, TYPE.water),
- })}
- pagination={false}
- scroll={{ y: 400 }}
- />
- </div> */}
- <div className={styles.box}>
- <ModuleTitle title="视频识别" />
- <Table
- dataSource={dumu_list}
- columns={columns3}
- rowClassName={setRowClassName}
- onRow={(record, index) => ({
- onClick: () => onSelectRow(record, TYPE.video),
- })}
- rowKey="id"
- pagination={false}
- scroll={{ y: 400 }}
- />
- </div>
- </div>
- );
- }
- export default VideoAnalysis;
|