Detail.js 26 KB

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