Detail.js 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. import ModuleTitle from '@/components/ManagementPage/moduleTitle';
  2. import TabsContent from '@/components/TabsContent';
  3. import ThresholdDetail from '@/components/ThresholdDetail';
  4. import ThresholdModal from '@/components/ThresholdDetail/ThresholdModal';
  5. import { changeRecordStatus, getDumuDetail } from '@/services/eqSelfInspection';
  6. import { UnityAction } from '@/utils/utils';
  7. import { connect, useRequest } from '@umijs/max';
  8. import {
  9. Col,
  10. DatePicker,
  11. Form,
  12. Input,
  13. Modal,
  14. Row,
  15. Select,
  16. Spin,
  17. Table,
  18. message,
  19. } from 'antd';
  20. import dayjs from 'dayjs';
  21. import { useEffect, useMemo, useState } from 'react';
  22. import ReactZmage from 'react-zmage';
  23. import styles from './PatrolReportDetail.less';
  24. function Detail(props) {
  25. const { data, userList, projectId, dispatch, loading = false } = props;
  26. const [select, setSelect] = useState();
  27. const [dumuList, setDumuList] = useState([]);
  28. const sendMessageToUnity = (select, data) => {
  29. setSelect(select);
  30. if (window.HightlightEquipment) {
  31. window.HightlightEquipment(data);
  32. }
  33. };
  34. const { run: detailRun } = useRequest(getDumuDetail, {
  35. manual: true,
  36. fetchKey: (id) => id,
  37. onSuccess: (data) => {
  38. var item = dumuList?.find((child) => child.id === data.id);
  39. if (item) {
  40. item.url = base64ToImageUrl(data.event_bg);
  41. }
  42. setDumuList([...dumuList]);
  43. },
  44. });
  45. const result = useMemo(() => {
  46. var resultArr = [];
  47. var tempResult = data?.PatrolResult;
  48. var tempArr = tempResult?.split(';');
  49. const getTextColor = (status) => {
  50. switch (status) {
  51. case '警告':
  52. return {
  53. color: '#FFE26D',
  54. className: styles.warn,
  55. };
  56. case '异常':
  57. return {
  58. color: '#FE5850',
  59. className: styles.error,
  60. };
  61. default:
  62. return {
  63. color: '#12CEB3',
  64. className: '',
  65. };
  66. }
  67. };
  68. if (tempArr?.length > 0) {
  69. tempArr?.forEach((item, index) => {
  70. var tempItem = item;
  71. var itemSplit = tempItem.split(':');
  72. if (itemSplit?.length > 1) {
  73. var label = '';
  74. var value = itemSplit[1];
  75. if (index === 0) label = '设备自检';
  76. else if (index === 1) label = '工艺自检';
  77. else {
  78. label = '安全隐患';
  79. value = data?.secureStatus === 0 ? '正常' : '异常';
  80. }
  81. resultArr.push({
  82. ...getTextColor(value),
  83. label,
  84. value,
  85. });
  86. }
  87. });
  88. }
  89. return resultArr;
  90. }, [data]);
  91. useEffect(() => {
  92. dispatch({
  93. type: 'eqSelfInspection/fetchUserList',
  94. payload: {
  95. projectId,
  96. },
  97. });
  98. }, []);
  99. useEffect(() => {
  100. setDumuList(data?.dumuList);
  101. data?.dumuList?.map((item) => {
  102. detailRun(item.id);
  103. });
  104. }, [data?.dumuList]);
  105. return (
  106. <Spin spinning={loading}>
  107. <div className={styles.card}>
  108. <Row>
  109. <Col span={24} className={styles.cardText}>
  110. 自检时间:{data?.CreatedTime}
  111. </Col>
  112. </Row>
  113. <Row>
  114. <Col span={12} className={styles.cardText}>
  115. 自检路线:{data?.RouteInfo?.Name}
  116. </Col>
  117. <Col span={12} className={styles.cardText}>
  118. 工艺段:{data?.RouteInfo?.GroupID}
  119. </Col>
  120. </Row>
  121. <Row>
  122. {result?.map((item) => {
  123. return (
  124. <Col span={8} className={styles.cardText}>
  125. <div className={styles.statusBox}>
  126. <div className={`${styles.orderIcon} ${item.className}`}>
  127. {item.value}
  128. </div>
  129. {item?.label}
  130. </div>
  131. </Col>
  132. );
  133. })}
  134. </Row>
  135. </div>
  136. <div>
  137. <ModuleTitle title="设备自检" />
  138. {/* 设备自检报告 */}
  139. <ReportCom
  140. sendMessageToUnity={sendMessageToUnity}
  141. select={select}
  142. waringData={data?.extendWarningData}
  143. allData={data?.extendWarningAllData}
  144. key="extend"
  145. type={'extend'}
  146. userList={userList}
  147. title={'设备自检报告'}
  148. ></ReportCom>
  149. {/* 液位异常 */}
  150. <LiquidLevelCom
  151. sendMessageToUnity={sendMessageToUnity}
  152. select={select}
  153. allData={data?.FluidLevelList}
  154. key="liquid"
  155. type={'liquid'}
  156. userList={userList}
  157. title={'液位异常'}
  158. />
  159. {/* 加药流量校验 */}
  160. {/* <FlowCom
  161. sendMessageToUnity={sendMessageToUnity}
  162. select={select}
  163. allData={data?.FluidLevelList}
  164. title={<ModuleTitle title="加药流量校验" />}
  165. /> */}
  166. {/* 工艺自检报告"> */}
  167. <div className={styles.content}>
  168. <div className={styles.tableStatus}>
  169. 异常({data?.FaultAnalysis?.length || 0})
  170. </div>
  171. <ModuleTitle title="工艺自检报告" />
  172. <AalysisTable
  173. onClickItem={sendMessageToUnity}
  174. select={select}
  175. data={data}
  176. />
  177. </div>
  178. {/* 安全隐患自检报告"> */}
  179. <div className={styles.content}>
  180. <ModuleTitle title="安全隐患自检报告" />
  181. {/* 环境异常 */}
  182. <ReportCom
  183. sendMessageToUnity={sendMessageToUnity}
  184. select={select}
  185. waringData={data?.sensorWaringData}
  186. allData={data?.sensor}
  187. data={data?.sensorWaringData}
  188. key="sensor"
  189. type={'sensor'}
  190. userList={userList}
  191. title={'环境异常'}
  192. ></ReportCom>
  193. {/* 液位异常 */}
  194. {/* <LiquidLevelCom
  195. sendMessageToUnity={sendMessageToUnity}
  196. select={select}
  197. allData={data?.FluidLevelList}
  198. key="liquid"
  199. type={'liquid'}
  200. userList={userList}
  201. title={<ModuleTitle title="液位异常" />}
  202. /> */}
  203. {/* 安防检测异常 */}
  204. <ReportDumCom data={dumuList} title={'安防检测异常'} />
  205. {/* 电器检测异常 */}
  206. <ReportCom
  207. sendMessageToUnity={sendMessageToUnity}
  208. select={select}
  209. waringData={[]}
  210. allData={[]}
  211. key="extend"
  212. type={'extend'}
  213. userList={userList}
  214. title={'电气检测异常'}
  215. ></ReportCom>
  216. {/* 密闭空间检测异常 */}
  217. <ReportCom
  218. sendMessageToUnity={sendMessageToUnity}
  219. select={select}
  220. waringData={[]}
  221. allData={[]}
  222. key="extend"
  223. type={'extend'}
  224. userList={userList}
  225. title={'密闭空间检测异常'}
  226. ></ReportCom>
  227. </div>
  228. </div>
  229. {/* </Card> */}
  230. </Spin>
  231. );
  232. }
  233. export function DeviceTable(props) {
  234. const {
  235. onClickItem,
  236. data = {},
  237. items,
  238. onErrorHandle,
  239. select,
  240. userList,
  241. type,
  242. } = props;
  243. const { ProjectId, Id } = data;
  244. const [loading, setLoading] = useState(false);
  245. const [visible, setVisible] = useState(false);
  246. const [errVisible, setErrVisible] = useState(false);
  247. const [currentItem, setCurrentItem] = useState({});
  248. const isSensor = type == 'sensor';
  249. const onClickThreshold = (record) => {
  250. setCurrentItem(record);
  251. setVisible(true);
  252. };
  253. const onClickError = (record) => {
  254. setCurrentItem(record);
  255. setErrVisible(true);
  256. };
  257. const handleError = async (values) => {
  258. setLoading(true);
  259. var res = await changeRecordStatus({
  260. ...values,
  261. Id: currentItem.Id,
  262. DeviceCode: currentItem.DeviceCode,
  263. DeviceName: currentItem.DeviceName,
  264. RecordId: data.Id,
  265. RepairMan: values.RepairMan * 1,
  266. });
  267. setLoading(false);
  268. if (res) {
  269. message.success('操作成功');
  270. setErrVisible(false);
  271. }
  272. };
  273. const columns = [
  274. {
  275. title: '设备名称',
  276. width: '20%',
  277. dataIndex: 'DeviceName',
  278. },
  279. {
  280. title: '巡检项',
  281. width: '20%',
  282. dataIndex: 'TemplateItem.Name',
  283. },
  284. // {
  285. // title: '设备位号',
  286. // width: '16%',
  287. // dataIndex: 'DeviceCode',
  288. // },
  289. {
  290. title: '设定值范围',
  291. width: '30%',
  292. render: (record) => (
  293. <ThresholdDetail
  294. current={record.Value || 0}
  295. data={record || {}}
  296. // onClick={() => onClickThreshold(record)}
  297. />
  298. ),
  299. },
  300. {
  301. title: '状态',
  302. dataIndex: 'Status',
  303. render: (Status) => {
  304. switch (Status) {
  305. case -1:
  306. case 0:
  307. return (
  308. <div>
  309. <i
  310. className={styles.iconStatus}
  311. style={{ background: '#12CEB3' }}
  312. ></i>
  313. 正常
  314. </div>
  315. );
  316. case 1:
  317. return (
  318. <div>
  319. <i
  320. className={styles.iconStatus}
  321. style={{ background: '#FE5850' }}
  322. ></i>
  323. 异常
  324. </div>
  325. );
  326. case 2:
  327. return (
  328. <div>
  329. <i
  330. className={styles.iconStatus}
  331. style={{ background: '#FFE26D' }}
  332. ></i>
  333. 警告
  334. </div>
  335. );
  336. }
  337. },
  338. },
  339. ];
  340. const handleClickItem = (data) => {
  341. if (!isSensor) {
  342. onClickItem(`DeviceTable-${data.Id}`, {
  343. type: data.Status,
  344. deviceCode: data.DeviceCode,
  345. });
  346. } else {
  347. onClickItem(`DeviceTable-${data.Id}`, {
  348. // type: data.Status,
  349. deviceCode: data.DeviceCode,
  350. value: Number(data.Value || 0),
  351. threshold: data.JsonNumThreshold,
  352. });
  353. UnityAction.sendMsg('SinglePowerEnvironFromWeb', JSON.stringify(data));
  354. }
  355. };
  356. useEffect(() => {
  357. console.log('温控', items);
  358. if (isSensor)
  359. UnityAction.sendMsg('PowerEnvironsFromWeb', JSON.stringify(items));
  360. }, [items]);
  361. if (!isSensor) {
  362. columns.push({
  363. title: '操作',
  364. render: (record) =>
  365. record.Status == 1 && (
  366. <a style={{ color: '#FE5850' }} onClick={() => onClickError(record)}>
  367. 异常处理
  368. </a>
  369. ),
  370. });
  371. }
  372. return (
  373. <div>
  374. <Table
  375. columns={columns}
  376. dataSource={items}
  377. rowKey="Id"
  378. locale={{
  379. emptyText: <Empty />,
  380. }}
  381. pagination={false}
  382. />
  383. <ThresholdModal
  384. open={visible}
  385. data={currentItem.JsonNumThreshold}
  386. onClose={() => setVisible(false)}
  387. />
  388. <ErrorHandleModal
  389. open={errVisible}
  390. userList={userList}
  391. onCancel={() => setErrVisible(false)}
  392. onOk={handleError}
  393. />
  394. </div>
  395. );
  396. }
  397. function AalysisTable(props) {
  398. const { onClickItem, data = {}, select } = props;
  399. const { FaultAnalysis } = data;
  400. const columns = [
  401. {
  402. title: '异常名称',
  403. width: '18%',
  404. dataIndex: 'device_name',
  405. },
  406. // {
  407. // title: '位号',
  408. // width: '15%',
  409. // dataIndex: 'device_code',
  410. // },
  411. {
  412. title: '可能原因',
  413. width: '30%',
  414. render: (record) => record.reason,
  415. },
  416. {
  417. title: '解决方案',
  418. width: '52%',
  419. render: (record) => {
  420. if (record.fix_plan instanceof Array) {
  421. return (
  422. <div>
  423. {record.fix_plan.map((item) => (
  424. <div>
  425. {item.content}
  426. <br />
  427. </div>
  428. ))}
  429. </div>
  430. );
  431. } else {
  432. return record.fix_plan;
  433. }
  434. },
  435. },
  436. ];
  437. return (
  438. <div>
  439. <Table
  440. columns={columns}
  441. dataSource={FaultAnalysis}
  442. rowKey="device_code"
  443. locale={{
  444. emptyText: <Empty />,
  445. }}
  446. pagination={false}
  447. />
  448. </div>
  449. );
  450. }
  451. function ErrorHandleModal(props) {
  452. const { visible, onCancel, onOk, userList } = props;
  453. const [form] = Form.useForm();
  454. const status = form.getFieldValue('Status');
  455. const handleOk = () => {
  456. form.validateFields((error, values) => {
  457. if (error) return;
  458. onOk({
  459. ...values,
  460. PlanTime: values?.PlanTime?.format('YYYY-MM-DD HH:mm:ss'),
  461. });
  462. });
  463. };
  464. return (
  465. <Modal
  466. title="异常处理"
  467. open={visible}
  468. onCancel={onCancel}
  469. onOk={handleOk}
  470. destroyOnClose
  471. >
  472. <Form labelCol={{ span: 7 }} wrapperCol={{ span: 16 }}>
  473. <Form.Item label="异常处理备注" name="ExceptionHandling">
  474. <Input.TextArea />
  475. </Form.Item>
  476. <Form.Item
  477. label="审核状态"
  478. name="Status"
  479. rules={[{ required: true, message: '请选择验收状态' }]}
  480. >
  481. <Select style={{ width: '100%' }} placeholder="请选择验收状态">
  482. <Select.Option value={1}>已派遣</Select.Option>
  483. <Select.Option value={2}>已通过</Select.Option>
  484. </Select>
  485. </Form.Item>
  486. <Form.Item
  487. label="维修人"
  488. name="RepairMan"
  489. rules={[{ required: true, message: '请选择维修人' }]}
  490. >
  491. <Select
  492. showSearch
  493. placeholder="请选择维修人"
  494. filterOption={(input, option) =>
  495. option.props.children.indexOf(input) >= 0
  496. }
  497. style={{ width: '100%' }}
  498. >
  499. {userList?.map((item) => (
  500. <Select.Option key={item.ID}>{item.CName}</Select.Option>
  501. ))}
  502. </Select>
  503. </Form.Item>
  504. {status == 1 && (
  505. <>
  506. <Form.Item
  507. label="难度级别"
  508. name="DifficultyLevel"
  509. rules={[{ required: true, message: '请选择难度级别' }]}
  510. >
  511. <Select placeholder="请选择难度级别" style={{ width: '100%' }}>
  512. <Select.Option value={0}>大修</Select.Option>
  513. <Select.Option value={1}>项目维修</Select.Option>
  514. <Select.Option value={2}>小修</Select.Option>
  515. </Select>
  516. </Form.Item>
  517. <Form.Item
  518. label="维修方式"
  519. name="RepairType"
  520. rules={[{ required: true, message: '请选择维修方式' }]}
  521. >
  522. <Select placeholder="请选择维修方式" style={{ width: '100%' }}>
  523. <Select.Option value={0}>自维</Select.Option>
  524. <Select.Option value={1}>外委</Select.Option>
  525. </Select>
  526. </Form.Item>
  527. <Form.Item
  528. label="计划完成日期"
  529. name="PlanTime"
  530. rules={[{ required: true, message: '请选择计划完成日期' }]}
  531. >
  532. <DatePicker inputReadOnly />
  533. </Form.Item>
  534. </>
  535. )}
  536. </Form>
  537. </Modal>
  538. );
  539. }
  540. export function WarningTable(props) {
  541. const {
  542. onClickItem,
  543. data = {},
  544. onErrorHandle,
  545. select,
  546. userList,
  547. type,
  548. items,
  549. } = props;
  550. const { ProjectId, Id } = data;
  551. const [loading, setLoading] = useState(false);
  552. const [visible, setVisible] = useState(false);
  553. const [errVisible, setErrVisible] = useState(false);
  554. const [currentItem, setCurrentItem] = useState({});
  555. const isSensor = type == 'sensor';
  556. const onClickThreshold = (record) => {
  557. setCurrentItem(record);
  558. setVisible(true);
  559. };
  560. const onClickError = (record) => {
  561. setCurrentItem(record);
  562. setErrVisible(true);
  563. };
  564. const handleError = async (values) => {
  565. setLoading(true);
  566. var res = await changeRecordStatus({
  567. ...values,
  568. Id: currentItem.Id,
  569. DeviceCode: currentItem.DeviceCode,
  570. DeviceName: currentItem.DeviceName,
  571. RecordId: data.Id,
  572. RepairMan: values.RepairMan * 1,
  573. });
  574. setLoading(false);
  575. if (res) {
  576. message.success('操作成功');
  577. setErrVisible(false);
  578. }
  579. };
  580. const columns = [
  581. {
  582. title: '设备名称',
  583. width: '20%',
  584. dataIndex: 'DeviceName',
  585. },
  586. {
  587. title: '巡检项',
  588. dataIndex: 'TemplateItem.Name',
  589. },
  590. // {
  591. // title: '设备位号',
  592. // width: '16%',
  593. // dataIndex: 'DeviceCode',
  594. // },
  595. {
  596. title: '设定值范围',
  597. width: '30%',
  598. render: (record) => (
  599. <ThresholdDetail
  600. current={record.Value || 0}
  601. data={record || {}}
  602. // onClick={() => onClickThreshold(record)}
  603. />
  604. ),
  605. },
  606. {
  607. title: '状态',
  608. dataIndex: 'Status',
  609. render: (Status) => {
  610. switch (Status) {
  611. case -1:
  612. case 0:
  613. return (
  614. <div>
  615. <i
  616. className={styles.iconStatus}
  617. style={{ background: '#12CEB3' }}
  618. ></i>
  619. 正常
  620. </div>
  621. );
  622. case 1:
  623. return (
  624. <div>
  625. <i
  626. className={styles.iconStatus}
  627. style={{ background: '#FE5850' }}
  628. ></i>
  629. 异常
  630. </div>
  631. );
  632. case 2:
  633. return (
  634. <div>
  635. <i
  636. className={styles.iconStatus}
  637. style={{ background: '#FFE26D' }}
  638. ></i>
  639. 警告
  640. </div>
  641. );
  642. }
  643. },
  644. },
  645. ];
  646. const handleClickItem = (data) => {
  647. if (!isSensor) {
  648. onClickItem(`DeviceTable-${data.Id}`, {
  649. type: data.Status,
  650. deviceCode: data.DeviceCode,
  651. });
  652. } else {
  653. onClickItem(`DeviceTable-${data.Id}`, {
  654. // type: data.Status,
  655. deviceCode: data.DeviceCode,
  656. value: Number(data.Value || 0),
  657. threshold: data.JsonNumThreshold,
  658. });
  659. UnityAction.sendMsg('SinglePowerEnvironFromWeb', JSON.stringify(data));
  660. }
  661. };
  662. if (!isSensor) {
  663. columns.push({
  664. title: '操作',
  665. render: (record) =>
  666. record.Status == 1 && (
  667. <a style={{ color: '#FE5850' }} onClick={() => onClickError(record)}>
  668. 异常处理
  669. </a>
  670. ),
  671. });
  672. }
  673. useEffect(() => {
  674. if (isSensor)
  675. UnityAction.sendMsg('PowerEnvironsFromWeb', JSON.stringify(items));
  676. }, [items]);
  677. return (
  678. <div>
  679. <Table
  680. columns={columns}
  681. dataSource={items}
  682. rowKey="Id"
  683. locale={{
  684. emptyText: <Empty />,
  685. }}
  686. pagination={false}
  687. />
  688. <ThresholdModal
  689. open={visible}
  690. data={currentItem.JsonNumThreshold}
  691. onClose={() => setVisible(false)}
  692. />
  693. <ErrorHandleModal
  694. open={errVisible}
  695. userList={userList}
  696. onCancel={() => setErrVisible(false)}
  697. onOk={handleError}
  698. />
  699. </div>
  700. );
  701. }
  702. function ReportCom(props) {
  703. const {
  704. sendMessageToUnity,
  705. select,
  706. waringData = [],
  707. allData = [],
  708. userList,
  709. type,
  710. title,
  711. data,
  712. } = props;
  713. const [activeKey, setActiveKey] = useState('1');
  714. const handleTabsChange = (activeKey) => {
  715. setActiveKey(activeKey);
  716. };
  717. return (
  718. <div className={styles.detailCard}>
  719. <div className={styles.tableTop}>
  720. {title}
  721. <TabsContent
  722. defaultActiveKey="1"
  723. onChange={handleTabsChange}
  724. small={true}
  725. items={[
  726. {
  727. key: '1',
  728. label: `异常/警告(${waringData.length || 0})`,
  729. children: <div></div>,
  730. },
  731. {
  732. key: '2',
  733. label: `全部(${allData.length || 0})`,
  734. children: <div></div>,
  735. },
  736. ]}
  737. ></TabsContent>
  738. </div>
  739. {activeKey == '1' && (
  740. <WarningTable
  741. onClickItem={sendMessageToUnity}
  742. select={select}
  743. items={waringData}
  744. key={type}
  745. data={data}
  746. type={type}
  747. userList={userList}
  748. />
  749. )}
  750. {activeKey == '2' && (
  751. <DeviceTable
  752. onClickItem={sendMessageToUnity}
  753. select={select}
  754. items={allData}
  755. data={data}
  756. key={type}
  757. type={type}
  758. userList={userList}
  759. />
  760. )}
  761. </div>
  762. );
  763. }
  764. export function LiquidTable(props) {
  765. const { onClickItem, data = {}, items, select, type } = props;
  766. const { ProjectId, Id } = data;
  767. const [loading, setLoading] = useState(false);
  768. const [currentItem, setCurrentItem] = useState({});
  769. const columns = [
  770. {
  771. title: '设备名称',
  772. width: '25%',
  773. dataIndex: 'device_name',
  774. },
  775. {
  776. title: '液位数',
  777. width: '20%',
  778. dataIndex: 'origin_value',
  779. },
  780. {
  781. title: '差值',
  782. width: '16%',
  783. dataIndex: 'value',
  784. },
  785. {
  786. title: '设定值范围',
  787. width: '30%',
  788. render: (record) => (
  789. <ThresholdDetail
  790. current={record.value || 0}
  791. data={{
  792. JsonNumThreshold: record?.json_num_threshold,
  793. Type: record.type || 2,
  794. }}
  795. />
  796. ),
  797. },
  798. {
  799. title: '状态',
  800. dataIndex: 'status',
  801. render: (status) => {
  802. switch (status) {
  803. case -1:
  804. case 0:
  805. return (
  806. <div>
  807. <i
  808. className={styles.iconStatus}
  809. style={{ background: '#12CEB3' }}
  810. ></i>
  811. 正常
  812. </div>
  813. );
  814. case 1:
  815. return (
  816. <div>
  817. <i
  818. className={styles.iconStatus}
  819. style={{ background: '#FFE26D' }}
  820. ></i>
  821. 异常
  822. </div>
  823. );
  824. case 2:
  825. return (
  826. <div>
  827. <i
  828. className={styles.iconStatus}
  829. style={{ background: '#FFE26D' }}
  830. ></i>
  831. 警告
  832. </div>
  833. );
  834. }
  835. },
  836. },
  837. ];
  838. const handleClickItem = (data) => {
  839. onClickItem(`DeviceTable-${data.device_code}`, {
  840. type: data.status,
  841. deviceCode: data.device_code,
  842. });
  843. };
  844. return (
  845. <Table
  846. columns={columns}
  847. dataSource={items}
  848. rowKey="device_code"
  849. locale={{
  850. emptyText: <Empty />,
  851. }}
  852. pagination={false}
  853. />
  854. );
  855. }
  856. function LiquidLevelCom(props) {
  857. const { sendMessageToUnity, select, allData = [], type, title } = props;
  858. const [activeKey, setActiveKey] = useState('1');
  859. const errorData = useMemo(() => {
  860. const errorData = allData?.filter((item) => item.status);
  861. return errorData;
  862. }, [allData]);
  863. const handleTabsChange = (activeKey) => {
  864. setActiveKey(activeKey);
  865. };
  866. return (
  867. <div className={styles.detailCard}>
  868. <div className={styles.tableTop}>
  869. {title}
  870. <TabsContent
  871. defaultActiveKey="1"
  872. onChange={handleTabsChange}
  873. small={true}
  874. items={[
  875. {
  876. key: '1',
  877. label: `异常/警告(${errorData?.length || 0})`,
  878. children: <div></div>,
  879. },
  880. {
  881. key: '2',
  882. label: `全部(${allData?.length || 0})`,
  883. children: <div></div>,
  884. },
  885. ]}
  886. ></TabsContent>
  887. </div>
  888. {activeKey == '1' && (
  889. <LiquidTable
  890. onClickItem={sendMessageToUnity}
  891. select={select}
  892. items={errorData}
  893. key={type}
  894. type={type}
  895. />
  896. )}
  897. {activeKey == '2' && (
  898. <LiquidTable
  899. onClickItem={sendMessageToUnity}
  900. select={select}
  901. items={allData}
  902. key={type}
  903. type={type}
  904. />
  905. )}
  906. </div>
  907. // <div className={styles.detailCard}>
  908. // <Tabs
  909. // defaultActiveKey="1"
  910. // tabBarExtraContent={<div className={styles.tabBarExtraContent}>{title} </div>}
  911. // onChange={handleTabsChange}
  912. // >
  913. // <Tabs.TabPane tab={`异常/警告(${errorData.length || 0})`} key="1">
  914. // {activeKey == '1' && (
  915. // <LiquidTable
  916. // onClickItem={sendMessageToUnity}
  917. // select={select}
  918. // items={errorData}
  919. // key={type}
  920. // // data={data}
  921. // type={type}
  922. // />
  923. // )}
  924. // </Tabs.TabPane>
  925. // <Tabs.TabPane tab={`全部(${allData.length || 0})`} key="2">
  926. // {activeKey == '2' && (
  927. // <LiquidTable
  928. // onClickItem={sendMessageToUnity}
  929. // select={select}
  930. // items={allData}
  931. // // data={data}
  932. // key={type}
  933. // type={type}
  934. // />
  935. // )}
  936. // </Tabs.TabPane>
  937. // </Tabs>
  938. // </div>
  939. );
  940. }
  941. function FlowTable(props) {
  942. const { onClickItem, data = {}, items } = props;
  943. const columns = [
  944. {
  945. title: '设备名称',
  946. width: '20%',
  947. dataIndex: 'device_name',
  948. },
  949. {
  950. title: '实际流量',
  951. width: '20%',
  952. dataIndex: 'origin_value',
  953. },
  954. {
  955. title: '计量流量',
  956. width: '16%',
  957. dataIndex: 'value',
  958. },
  959. {
  960. title: '差值',
  961. width: '15%',
  962. dataIndex: 'value',
  963. },
  964. {
  965. title: '设定值范围',
  966. width: '30%',
  967. render: (record) => (
  968. <ThresholdDetail
  969. current={record.value || 0}
  970. data={{
  971. JsonNumThreshold: record?.json_num_threshold,
  972. Type: record.type || 2,
  973. }}
  974. />
  975. ),
  976. },
  977. {
  978. title: '状态',
  979. dataIndex: 'status',
  980. render: (status) => {
  981. switch (status) {
  982. case -1:
  983. case 0:
  984. return (
  985. <div>
  986. <i
  987. className={styles.iconStatus}
  988. style={{ background: '#12CEB3' }}
  989. ></i>
  990. 正常
  991. </div>
  992. );
  993. case 1:
  994. return (
  995. <div>
  996. <i
  997. className={styles.iconStatus}
  998. style={{ background: '#FFE26D' }}
  999. ></i>
  1000. 异常
  1001. </div>
  1002. );
  1003. case 2:
  1004. return (
  1005. <div>
  1006. <i
  1007. className={styles.iconStatus}
  1008. style={{ background: '#FFE26D' }}
  1009. ></i>
  1010. 警告
  1011. </div>
  1012. );
  1013. }
  1014. },
  1015. },
  1016. ];
  1017. const handleClickItem = (data) => {
  1018. onClickItem(`DeviceTable-${data.device_code}`, {
  1019. type: data.status,
  1020. deviceCode: data.device_code,
  1021. });
  1022. };
  1023. return (
  1024. <Table
  1025. columns={columns}
  1026. dataSource={items}
  1027. rowKey="device_code"
  1028. locale={{
  1029. emptyText: <Empty />,
  1030. }}
  1031. pagination={false}
  1032. />
  1033. );
  1034. }
  1035. function FlowCom(props) {
  1036. const { sendMessageToUnity, select, allData = [], type, title } = props;
  1037. const [activeKey, setActiveKey] = useState('1');
  1038. const errorData = useMemo(() => {
  1039. const errorData = allData?.filter((item) => item.status);
  1040. return errorData;
  1041. }, [allData]);
  1042. const handleTabsChange = (activeKey) => {
  1043. setActiveKey(activeKey);
  1044. };
  1045. return (
  1046. <div className={styles.detailCard}>
  1047. <div className={styles.tableTop}>
  1048. {title}
  1049. <TabsContent
  1050. defaultActiveKey="1"
  1051. onChange={handleTabsChange}
  1052. small={true}
  1053. items={[
  1054. {
  1055. key: '1',
  1056. label: `异常/警告(${errorData?.length || 0})`,
  1057. children: <div></div>,
  1058. },
  1059. {
  1060. key: '2',
  1061. label: `全部(${allData?.length || 0})`,
  1062. children: <div></div>,
  1063. },
  1064. ]}
  1065. ></TabsContent>
  1066. </div>
  1067. {activeKey == '1' && (
  1068. <FlowTable
  1069. onClickItem={sendMessageToUnity}
  1070. select={select}
  1071. items={errorData}
  1072. key={type}
  1073. type={type}
  1074. />
  1075. )}
  1076. {activeKey == '2' && (
  1077. <FlowTable
  1078. onClickItem={sendMessageToUnity}
  1079. select={select}
  1080. items={allData}
  1081. key={type}
  1082. type={type}
  1083. />
  1084. )}
  1085. </div>
  1086. );
  1087. }
  1088. function ReportDumCom(props) {
  1089. const { data = [], title } = props;
  1090. const columns = [
  1091. {
  1092. title: '报警时间',
  1093. dataIndex: 'event_time',
  1094. render: (time) => dayjs(time).format('YYYY-MM-DD HH:mm:ss'),
  1095. },
  1096. {
  1097. title: '设备名称',
  1098. dataIndex: 'device_name',
  1099. },
  1100. {
  1101. title: '报警类型',
  1102. dataIndex: 'event_type',
  1103. // render: type => alarmType[type],
  1104. },
  1105. {
  1106. title: '报警图片',
  1107. render: (item) => (
  1108. <ReactZmage
  1109. controller={{
  1110. // 关闭按钮
  1111. close: true,
  1112. // 旋转按钮
  1113. rotate: true,
  1114. // 缩放按钮
  1115. zoom: false,
  1116. // 下载按钮
  1117. download: false,
  1118. // 翻页按钮
  1119. flip: false,
  1120. // 多页指示
  1121. pagination: false,
  1122. }}
  1123. backdrop="rgba(255,255,255,0.5)"
  1124. style={{ height: '0.9rem' }}
  1125. src={item.path}
  1126. />
  1127. ),
  1128. },
  1129. ];
  1130. return (
  1131. <div style={{ marginBottom: '0.3rem' }}>
  1132. <div className={styles.tabBarExtraContent}>
  1133. <div className={styles.text} style={{ width: '60%' }}>
  1134. {title}
  1135. </div>
  1136. <div className={styles.abnormal}>
  1137. <div className={styles.text} style={{ float: 'right' }}>
  1138. 异常({data?.length || 0})
  1139. </div>
  1140. </div>
  1141. </div>
  1142. <Table
  1143. bordered
  1144. rowKey="event_time"
  1145. columns={columns}
  1146. dataSource={data}
  1147. locale={{
  1148. emptyText: <Empty />,
  1149. }}
  1150. pagination={false}
  1151. />
  1152. </div>
  1153. );
  1154. }
  1155. function base64ToImageUrl(base64String) {
  1156. const byteCharacters = atob(base64String);
  1157. const byteArrays = [];
  1158. for (let i = 0; i < byteCharacters.length; i++) {
  1159. byteArrays.push(byteCharacters.charCodeAt(i));
  1160. }
  1161. const byteArray = new Uint8Array(byteArrays);
  1162. const blob = new Blob([byteArray], { type: 'image/png' });
  1163. const imageUrl = URL.createObjectURL(blob);
  1164. return imageUrl;
  1165. }
  1166. function Empty() {
  1167. return (
  1168. <div>
  1169. <img
  1170. src={require('@/assets/self-empty.png')}
  1171. style={{ margin: '0.2rem 0', width: '1.6rem' }}
  1172. />
  1173. <p style={{ textAlign: 'center', color: '#555' }}>自检正常</p>
  1174. </div>
  1175. );
  1176. }
  1177. export default connect(({ eqSelfInspection }) => ({
  1178. userList: eqSelfInspection.userList,
  1179. mandateInfo: eqSelfInspection.mandateInfo,
  1180. }))(Detail);