VideoAnalysis.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. import ModuleTitle from '@/components/ManagementPage/moduleTitle';
  2. import TabsContent from '@/components/TabsContent';
  3. import ThresholdDetail from '@/components/ThresholdDetail';
  4. import { UnityAction } from '@/utils/utils';
  5. import { Collapse, Spin, Table, Tabs } from 'antd';
  6. import { useEffect, useState } from 'react';
  7. import ThresholdBar from './ThresholdBar';
  8. import styles from './VideoAnalysis.less';
  9. const { TabPane } = Tabs;
  10. const { Panel } = Collapse;
  11. function VideoAnalysis(props) {
  12. const { videoNum, data, videoData, loading } = props;
  13. const [tab, setTab] = useState('1');
  14. const allCount = Object.values(videoData).reduce(
  15. (total, item) => total + item?.length,
  16. 0,
  17. );
  18. const [prevKey, setPrevKey] = useState();
  19. const [selectedName, setSelectedName] = useState('');
  20. const handleCollapse = (key) => {
  21. if (key === prevKey) return;
  22. setPrevKey(key);
  23. const device = data.list.find((item) => item.id === key)?.device_name;
  24. if (device) {
  25. UnityAction.sendMsg('SynCam', device);
  26. }
  27. };
  28. useEffect(() => {
  29. UnityAction.on('SynCam', selectedItem);
  30. return () => UnityAction.off('SynCam', selectedItem);
  31. }, [data?.list]);
  32. //滚动到相应位置
  33. const selectedItem = (e) => {
  34. setSelectedName(e);
  35. const dom = document.querySelector(`div[data-name="${e}"]`);
  36. if (dom) {
  37. let v = document.getElementById('videoContent');
  38. v.scrollTop = dom.offsetTop;
  39. }
  40. };
  41. const onTabChange = (tab) => {
  42. setTab(tab);
  43. // UnityAction.sendMsg('ProcessAnalysisType', tab);
  44. };
  45. return (
  46. <Spin spinning={loading}>
  47. <TabsContent
  48. small={true}
  49. center={false}
  50. defaultActiveKey="1"
  51. items={[
  52. {
  53. label: `异常(${videoNum})`,
  54. key: '1',
  55. children: (
  56. <AnalysisContent
  57. data={data}
  58. videoData={videoData}
  59. selectedName={selectedName}
  60. prevKey={prevKey}
  61. />
  62. ),
  63. },
  64. {
  65. label: `全部(${allCount})`,
  66. key: '2',
  67. children: <AllContent data={data} videoData={videoData} />,
  68. },
  69. ]}
  70. onChange={onTabChange}
  71. />
  72. </Spin>
  73. );
  74. }
  75. function AnalysisContent({ data, selectedName, prevKey }) {
  76. const handleImgClick = (item) => {
  77. localStorage.setItem('preview', JSON.stringify(item.data));
  78. UnityAction.sendMsg('SensorPic');
  79. };
  80. const renderContent = (key, item) => {
  81. let content = '';
  82. switch (key) {
  83. case 1:
  84. content = (
  85. <>
  86. <div className={styles.label}>画面报警:</div>
  87. <div className={styles.content}>
  88. {item.event_type}
  89. <img
  90. className={styles.img}
  91. src={item.url}
  92. onClick={() => handleImgClick(item)}
  93. />
  94. </div>
  95. </>
  96. );
  97. break;
  98. case 2:
  99. content = (
  100. <>
  101. <div className={styles.contentFlex}>
  102. <div>参数:温度</div>
  103. <div className={styles.threshold}>
  104. <span>阈值范围:</span>
  105. <div style={{ width: '180px' }}>
  106. <ThresholdBar current={0.5} thresholds={[0, 1]} />
  107. </div>
  108. </div>
  109. <div>
  110. 状态:<span className={styles.textAbnormal}>异常</span>
  111. </div>
  112. </div>
  113. </>
  114. );
  115. break;
  116. case 3:
  117. content = (
  118. <>
  119. <div className={styles.contentFlex}>
  120. <div>原液位:12.01</div>
  121. <div> 仪表液位:12.12 </div>
  122. <div>
  123. 状态:<span className={styles.textAbnormal}>异常</span>
  124. </div>
  125. </div>
  126. </>
  127. );
  128. break;
  129. }
  130. return content;
  131. };
  132. return (
  133. <div
  134. className={styles.page}
  135. style={{ height: 'calc(100vh - 630px)', overflow: 'auto' }}
  136. >
  137. {data?.length > 0 ? (
  138. data?.map((item) => (
  139. <div data-name={item.device_name}>
  140. <Collapse
  141. defaultActiveKey={[item.id]}
  142. key={item.id}
  143. className={
  144. selectedName == item.device_name || prevKey == item.id
  145. ? styles.tableSelect
  146. : styles.table
  147. }
  148. expandIcon={() => <div className={styles.typeText}>视频报警</div>}
  149. onChange={(e) => {
  150. handleCollapse(item.id);
  151. }}
  152. >
  153. <Panel header={item.device_name} key={item.id}>
  154. <div className={styles.box}>
  155. <div className={styles.item}>{renderContent(1, item)}</div>
  156. </div>
  157. </Panel>
  158. </Collapse>
  159. </div>
  160. ))
  161. ) : (
  162. <Empty />
  163. )}
  164. </div>
  165. );
  166. }
  167. function AllContent({ data = [], videoData = {} }) {
  168. const { environment_list = [], fluid_level_list = [] } = videoData;
  169. const [selectedRowKeys, setSelectedRowKeys] = useState([]);
  170. const columns1 = [
  171. {
  172. title: '设备名称',
  173. render: (record) => (
  174. <div>
  175. {record.device_name}({record.device_code})
  176. </div>
  177. ),
  178. },
  179. {
  180. title: '参数',
  181. dataIndex: 'patrol_name',
  182. key: 'patrol_name',
  183. },
  184. {
  185. title: '设定值范围',
  186. render: (record) => (
  187. <ThresholdDetail
  188. current={record.value || 0}
  189. data={{ JsonNumThreshold: record?.json_num_threshold, Type: 2 }}
  190. // onClick={() => onClickThreshold(record)}
  191. />
  192. ),
  193. },
  194. {
  195. title: '状态',
  196. dataIndex: 'status',
  197. render: (status) => {
  198. switch (status) {
  199. case -1:
  200. case 0:
  201. return (
  202. <div>
  203. <i
  204. className={styles.iconStatus}
  205. style={{ background: '#12CEB3' }}
  206. ></i>
  207. 正常
  208. </div>
  209. );
  210. case 1:
  211. return (
  212. <div>
  213. <i
  214. className={styles.iconStatus}
  215. style={{ background: '#FE5850' }}
  216. ></i>
  217. 异常
  218. </div>
  219. );
  220. case 2:
  221. return (
  222. <div>
  223. <i
  224. className={styles.iconStatus}
  225. style={{ background: '#FFE26D' }}
  226. ></i>
  227. 警告
  228. </div>
  229. );
  230. }
  231. },
  232. },
  233. ];
  234. const columns2 = [
  235. {
  236. title: '设备名称',
  237. render: (record) => (
  238. <div>
  239. {record.device_name}({record.device_code})
  240. </div>
  241. ),
  242. },
  243. {
  244. title: '液位数',
  245. dataIndex: 'origin_value',
  246. key: 'origin_value',
  247. },
  248. {
  249. title: '差值',
  250. dataIndex: 'value',
  251. key: 'value',
  252. },
  253. {
  254. title: '设定值范围',
  255. render: (record) => (
  256. <ThresholdDetail
  257. current={record.value || 0}
  258. data={{ JsonNumThreshold: record?.json_num_threshold, Type: 2 }}
  259. // onClick={() => onClickThreshold(record)}
  260. />
  261. ),
  262. },
  263. {
  264. title: '状态',
  265. dataIndex: 'status',
  266. render: (status) => {
  267. switch (status) {
  268. case -1:
  269. case 0:
  270. return (
  271. <div>
  272. <i
  273. className={styles.iconStatus}
  274. style={{ background: '#12CEB3' }}
  275. ></i>
  276. 正常
  277. </div>
  278. );
  279. case 1:
  280. return (
  281. <div>
  282. <i
  283. className={styles.iconStatus}
  284. style={{ background: '#FE5850' }}
  285. ></i>
  286. 异常
  287. </div>
  288. );
  289. case 2:
  290. return (
  291. <div>
  292. <i
  293. className={styles.iconStatus}
  294. style={{ background: '#FFE26D' }}
  295. ></i>
  296. 警告
  297. </div>
  298. );
  299. }
  300. },
  301. },
  302. ];
  303. const columns3 = [
  304. {
  305. title: '名称',
  306. render: (record) => (
  307. <div>
  308. {record.device_name}({record.device_code})
  309. </div>
  310. ),
  311. },
  312. {
  313. title: '描述',
  314. dataIndex: 'event_type',
  315. key: 'event_type',
  316. },
  317. {
  318. title: '图片',
  319. render: (item) => (
  320. <img
  321. className={styles.img}
  322. src={item.url}
  323. onClick={() => handleImgClick(item)}
  324. />
  325. ),
  326. },
  327. ];
  328. const onSelectRow = (record, index) => {
  329. const selectedList = [...selectedRowKeys];
  330. if (selectedList[0] === index) return;
  331. selectedList[0] = index;
  332. setSelectedRowKeys(selectedList);
  333. UnityAction.sendMsg('SynDev', record.DeviceCode);
  334. };
  335. const setRowClassName = (record, index) => {
  336. return index === selectedRowKeys[0] ||
  337. record.DeviceCode == selectedRowKeys[0]
  338. ? styles.tableSelect
  339. : '';
  340. };
  341. return (
  342. <div
  343. className={styles.page}
  344. style={{ height: 'calc(100vh - 630px)', overflow: 'auto' }}
  345. >
  346. <div className={`card-box ${styles.box}`}>
  347. <ModuleTitle title="环境监测" />
  348. <Table
  349. dataSource={environment_list}
  350. columns={columns1}
  351. // rowClassName={setRowClassName}
  352. // onRow={(record, index) => ({
  353. // onClick: () => onSelectRow(record, index),
  354. // })}
  355. pagination={false}
  356. scroll={{ y: 400 }}
  357. />
  358. </div>
  359. <div className={`card-box ${styles.box}`}>
  360. <ModuleTitle title="液位检测" />
  361. <Table
  362. dataSource={fluid_level_list}
  363. columns={columns2}
  364. // rowClassName={setRowClassName}
  365. // onRow={(record, index) => ({
  366. // onClick: () => onSelectRow(record, index),
  367. // })}
  368. pagination={false}
  369. scroll={{ y: 400 }}
  370. />
  371. </div>
  372. <div className={`card-box ${styles.box}`}>
  373. <ModuleTitle title="感知监测" />
  374. <Table
  375. dataSource={data}
  376. columns={columns3}
  377. // rowClassName={setRowClassName}
  378. // onRow={(record, index) => ({
  379. // onClick: () => onSelectRow(record, index),
  380. // })}
  381. pagination={false}
  382. scroll={{ y: 400 }}
  383. />
  384. </div>
  385. </div>
  386. );
  387. }
  388. export default VideoAnalysis;