|
@@ -1,5 +1,8 @@
|
|
|
+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, Tabs } from 'antd';
|
|
|
+import { Collapse, Spin, Table, Tabs } from 'antd';
|
|
|
import { useEffect, useState } from 'react';
|
|
|
import ThresholdBar from './ThresholdBar';
|
|
|
import styles from './VideoAnalysis.less';
|
|
@@ -8,7 +11,12 @@ const { TabPane } = Tabs;
|
|
|
const { Panel } = Collapse;
|
|
|
|
|
|
function VideoAnalysis(props) {
|
|
|
- const { data, loading } = props;
|
|
|
+ const { videoNum, data, videoData, loading } = props;
|
|
|
+ const [tab, setTab] = useState('1');
|
|
|
+ const allCount = Object.values(videoData).reduce(
|
|
|
+ (total, item) => total + item?.length,
|
|
|
+ 0,
|
|
|
+ );
|
|
|
|
|
|
const [prevKey, setPrevKey] = useState();
|
|
|
const [selectedName, setSelectedName] = useState('');
|
|
@@ -37,47 +45,44 @@ function VideoAnalysis(props) {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ const onTabChange = (tab) => {
|
|
|
+ setTab(tab);
|
|
|
+ // UnityAction.sendMsg('ProcessAnalysisType', tab);
|
|
|
+ };
|
|
|
+
|
|
|
return (
|
|
|
<Spin spinning={loading}>
|
|
|
- <div
|
|
|
- id="videoContent"
|
|
|
- className={styles.page}
|
|
|
- style={{ height: 'calc(100vh - 580px)', overflow: 'auto' }}
|
|
|
- >
|
|
|
- {data?.list?.length > 0 ? (
|
|
|
- data?.list?.map((item) => (
|
|
|
- <div data-name={item.device_name}>
|
|
|
- <Collapse
|
|
|
- defaultActiveKey={[item.id]}
|
|
|
- key={item.id}
|
|
|
- className={
|
|
|
- selectedName == item.device_name || prevKey == item.id
|
|
|
- ? styles.tableSelect
|
|
|
- : styles.table
|
|
|
- }
|
|
|
- expandIcon={() => (
|
|
|
- <div className={styles.typeText}>视频报警</div>
|
|
|
- )}
|
|
|
- onChange={(e) => {
|
|
|
- handleCollapse(item.id);
|
|
|
- }}
|
|
|
- >
|
|
|
- <Panel header={item.device_name} key={item.id}>
|
|
|
- <AnalysisContent item={item} />
|
|
|
- </Panel>
|
|
|
- </Collapse>
|
|
|
- </div>
|
|
|
- ))
|
|
|
- ) : (
|
|
|
- <Empty />
|
|
|
- )}
|
|
|
- </div>
|
|
|
+ <TabsContent
|
|
|
+ small={true}
|
|
|
+ center={false}
|
|
|
+ defaultActiveKey="1"
|
|
|
+ items={[
|
|
|
+ {
|
|
|
+ label: `异常(${videoNum})`,
|
|
|
+ key: '1',
|
|
|
+ children: (
|
|
|
+ <AnalysisContent
|
|
|
+ data={data}
|
|
|
+ videoData={videoData}
|
|
|
+ selectedName={selectedName}
|
|
|
+ prevKey={prevKey}
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: `全部(${allCount})`,
|
|
|
+ key: '2',
|
|
|
+ children: <AllContent data={data} videoData={videoData} />,
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ onChange={onTabChange}
|
|
|
+ />
|
|
|
</Spin>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
-function AnalysisContent({ item }) {
|
|
|
- const handleImgClick = () => {
|
|
|
+function AnalysisContent({ data, selectedName, prevKey }) {
|
|
|
+ const handleImgClick = (item) => {
|
|
|
localStorage.setItem('preview', JSON.stringify(item.data));
|
|
|
UnityAction.sendMsg('SensorPic');
|
|
|
};
|
|
@@ -94,7 +99,7 @@ function AnalysisContent({ item }) {
|
|
|
<img
|
|
|
className={styles.img}
|
|
|
src={item.url}
|
|
|
- onClick={handleImgClick}
|
|
|
+ onClick={() => handleImgClick(item)}
|
|
|
/>
|
|
|
</div>
|
|
|
</>
|
|
@@ -138,13 +143,261 @@ function AnalysisContent({ item }) {
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
- <div className={styles.box}>
|
|
|
- <div className={styles.item}>
|
|
|
- {renderContent(3, item)}
|
|
|
- {/* <div className={styles.content}>
|
|
|
- {item.event_type}
|
|
|
- <img className={styles.img} src={item.url} onClick={handleImgClick} />
|
|
|
- </div> */}
|
|
|
+ <div
|
|
|
+ className={styles.page}
|
|
|
+ style={{ height: 'calc(100vh - 630px)', overflow: 'auto' }}
|
|
|
+ >
|
|
|
+ {data?.length > 0 ? (
|
|
|
+ data?.map((item) => (
|
|
|
+ <div data-name={item.device_name}>
|
|
|
+ <Collapse
|
|
|
+ defaultActiveKey={[item.id]}
|
|
|
+ key={item.id}
|
|
|
+ className={
|
|
|
+ selectedName == item.device_name || prevKey == item.id
|
|
|
+ ? styles.tableSelect
|
|
|
+ : styles.table
|
|
|
+ }
|
|
|
+ expandIcon={() => <div className={styles.typeText}>视频报警</div>}
|
|
|
+ onChange={(e) => {
|
|
|
+ handleCollapse(item.id);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Panel header={item.device_name} key={item.id}>
|
|
|
+ <div className={styles.box}>
|
|
|
+ <div className={styles.item}>{renderContent(1, item)}</div>
|
|
|
+ </div>
|
|
|
+ </Panel>
|
|
|
+ </Collapse>
|
|
|
+ </div>
|
|
|
+ ))
|
|
|
+ ) : (
|
|
|
+ <Empty />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function AllContent({ data = [], videoData = {} }) {
|
|
|
+ const { environment_list = [], fluid_level_list = [] } = videoData;
|
|
|
+ const [selectedRowKeys, setSelectedRowKeys] = 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: 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 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: 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.url}
|
|
|
+ onClick={() => handleImgClick(item)}
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+ const onSelectRow = (record, index) => {
|
|
|
+ const selectedList = [...selectedRowKeys];
|
|
|
+ if (selectedList[0] === index) return;
|
|
|
+ selectedList[0] = index;
|
|
|
+ setSelectedRowKeys(selectedList);
|
|
|
+ UnityAction.sendMsg('SynDev', record.DeviceCode);
|
|
|
+ };
|
|
|
+
|
|
|
+ const setRowClassName = (record, index) => {
|
|
|
+ return index === selectedRowKeys[0] ||
|
|
|
+ record.DeviceCode == selectedRowKeys[0]
|
|
|
+ ? styles.tableSelect
|
|
|
+ : '';
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ className={styles.page}
|
|
|
+ style={{ height: 'calc(100vh - 630px)', overflow: 'auto' }}
|
|
|
+ >
|
|
|
+ <div className={`card-box ${styles.box}`}>
|
|
|
+ <ModuleTitle title="环境监测" />
|
|
|
+ <Table
|
|
|
+ dataSource={environment_list}
|
|
|
+ columns={columns1}
|
|
|
+ // rowClassName={setRowClassName}
|
|
|
+ // onRow={(record, index) => ({
|
|
|
+ // onClick: () => onSelectRow(record, index),
|
|
|
+ // })}
|
|
|
+ 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, index),
|
|
|
+ // })}
|
|
|
+ pagination={false}
|
|
|
+ scroll={{ y: 400 }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className={`card-box ${styles.box}`}>
|
|
|
+ <ModuleTitle title="感知监测" />
|
|
|
+ <Table
|
|
|
+ dataSource={data}
|
|
|
+ columns={columns3}
|
|
|
+ // rowClassName={setRowClassName}
|
|
|
+ // onRow={(record, index) => ({
|
|
|
+ // onClick: () => onSelectRow(record, index),
|
|
|
+ // })}
|
|
|
+ pagination={false}
|
|
|
+ scroll={{ y: 400 }}
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|