Detail.js 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712
  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. <DosingFlowCom
  161. sendMessageToUnity={sendMessageToUnity}
  162. select={select}
  163. allData={data?.FluidLevelList}
  164. title="加药流量校验"
  165. />
  166. <WaterInCom
  167. sendMessageToUnity={sendMessageToUnity}
  168. select={select}
  169. allData={data?.WaterInCheckList}
  170. title="进出水流量校验"
  171. />
  172. <PressureGaugeCom
  173. sendMessageToUnity={sendMessageToUnity}
  174. select={select}
  175. allData={data?.PressureCompareList}
  176. title="压力仪表校验"
  177. />
  178. <WaterQualityCom
  179. sendMessageToUnity={sendMessageToUnity}
  180. select={select}
  181. allData={data?.WaterQualityCompareList}
  182. title="水质仪表校验"
  183. />
  184. {/* 工艺自检报告"> */}
  185. <div className={styles.content}>
  186. <div className={styles.tableStatus}>
  187. 异常({data?.FaultAnalysis?.length || 0})
  188. </div>
  189. <ModuleTitle title="工艺自检报告" />
  190. <AalysisTable
  191. onClickItem={sendMessageToUnity}
  192. select={select}
  193. data={data}
  194. />
  195. </div>
  196. {/* 安全隐患自检报告"> */}
  197. <div className={styles.content}>
  198. <ModuleTitle title="安全隐患自检报告" />
  199. {/* 环境异常 */}
  200. <ReportCom
  201. sendMessageToUnity={sendMessageToUnity}
  202. select={select}
  203. waringData={data?.sensorWaringData}
  204. allData={data?.sensor}
  205. data={data?.sensorWaringData}
  206. key="sensor"
  207. type={'sensor'}
  208. userList={userList}
  209. title={'环境异常'}
  210. ></ReportCom>
  211. {/* 液位异常 */}
  212. {/* <LiquidLevelCom
  213. sendMessageToUnity={sendMessageToUnity}
  214. select={select}
  215. allData={data?.FluidLevelList}
  216. key="liquid"
  217. type={'liquid'}
  218. userList={userList}
  219. title={<ModuleTitle title="液位异常" />}
  220. /> */}
  221. {/* 安防检测异常 */}
  222. <ReportDumCom data={dumuList} title={'安防检测异常'} />
  223. {/* 电器检测异常 */}
  224. <ReportCom
  225. sendMessageToUnity={sendMessageToUnity}
  226. select={select}
  227. waringData={[]}
  228. allData={[]}
  229. key="extend"
  230. type={'extend'}
  231. userList={userList}
  232. title={'电气检测异常'}
  233. ></ReportCom>
  234. {/* 密闭空间检测异常 */}
  235. <ReportCom
  236. sendMessageToUnity={sendMessageToUnity}
  237. select={select}
  238. waringData={[]}
  239. allData={[]}
  240. key="extend"
  241. type={'extend'}
  242. userList={userList}
  243. title={'密闭空间检测异常'}
  244. ></ReportCom>
  245. </div>
  246. </div>
  247. {/* </Card> */}
  248. </Spin>
  249. );
  250. }
  251. export function DeviceTable(props) {
  252. const {
  253. onClickItem,
  254. data = {},
  255. items,
  256. onErrorHandle,
  257. select,
  258. userList,
  259. type,
  260. } = props;
  261. console.log(items);
  262. const { ProjectId, Id } = data;
  263. const [loading, setLoading] = useState(false);
  264. const [visible, setVisible] = useState(false);
  265. const [errVisible, setErrVisible] = useState(false);
  266. const [currentItem, setCurrentItem] = useState({});
  267. const isSensor = type == 'sensor';
  268. const onClickThreshold = (record) => {
  269. setCurrentItem(record);
  270. setVisible(true);
  271. };
  272. const onClickError = (record) => {
  273. setCurrentItem(record);
  274. setErrVisible(true);
  275. };
  276. const handleError = async (values) => {
  277. setLoading(true);
  278. var res = await changeRecordStatus({
  279. ...values,
  280. Id: currentItem.Id,
  281. DeviceCode: currentItem.DeviceCode,
  282. DeviceName: currentItem.DeviceName,
  283. RecordId: data.Id,
  284. RepairMan: values.RepairMan * 1,
  285. });
  286. setLoading(false);
  287. if (res) {
  288. message.success('操作成功');
  289. setErrVisible(false);
  290. }
  291. };
  292. const columns = [
  293. {
  294. title: '设备名称',
  295. width: '20%',
  296. dataIndex: 'DeviceName',
  297. },
  298. {
  299. title: '巡检项',
  300. key: 'TemplateItem.Name',
  301. dataIndex: 'TemplateItem',
  302. render: (TemplateItem) => <div>{TemplateItem.Name}</div>,
  303. },
  304. // {
  305. // title: '设备位号',
  306. // width: '16%',
  307. // dataIndex: 'DeviceCode',
  308. // },
  309. {
  310. title: '设定值范围',
  311. render: (record) => (
  312. <ThresholdDetail
  313. current={record.Value || 0}
  314. data={record || {}}
  315. // onClick={() => onClickThreshold(record)}
  316. />
  317. ),
  318. },
  319. {
  320. title: '状态',
  321. dataIndex: 'Status',
  322. width: '1.25rem',
  323. render: (Status) => {
  324. switch (Status) {
  325. case -1:
  326. case 0:
  327. return (
  328. <div>
  329. <i
  330. className={styles.iconStatus}
  331. style={{ background: '#12CEB3' }}
  332. ></i>
  333. 正常
  334. </div>
  335. );
  336. case 1:
  337. return (
  338. <div>
  339. <i
  340. className={styles.iconStatus}
  341. style={{ background: '#FE5850' }}
  342. ></i>
  343. 异常
  344. </div>
  345. );
  346. case 2:
  347. return (
  348. <div>
  349. <i
  350. className={styles.iconStatus}
  351. style={{ background: '#FFE26D' }}
  352. ></i>
  353. 警告
  354. </div>
  355. );
  356. }
  357. },
  358. },
  359. ];
  360. const handleClickItem = (data) => {
  361. if (!isSensor) {
  362. onClickItem(`DeviceTable-${data.Id}`, {
  363. type: data.Status,
  364. deviceCode: data.DeviceCode,
  365. });
  366. } else {
  367. onClickItem(`DeviceTable-${data.Id}`, {
  368. // type: data.Status,
  369. deviceCode: data.DeviceCode,
  370. value: Number(data.Value || 0),
  371. threshold: data.JsonNumThreshold,
  372. });
  373. UnityAction.sendMsg('SinglePowerEnvironFromWeb', JSON.stringify(data));
  374. }
  375. };
  376. // useEffect(() => {
  377. // console.log('温控', items);
  378. // if (isSensor)
  379. // UnityAction.sendMsg('PowerEnvironsFromWeb', JSON.stringify(items));
  380. // }, [items]);
  381. // if (!isSensor) {
  382. // columns.push({
  383. // title: '操作',
  384. // render: (record) =>
  385. // record.Status == 1 && (
  386. // <a style={{ color: '#FE5850' }} onClick={() => onClickError(record)}>
  387. // 异常处理
  388. // </a>
  389. // ),
  390. // });
  391. // }
  392. return (
  393. <div>
  394. <Table
  395. columns={columns}
  396. dataSource={items}
  397. rowKey="Id"
  398. locale={{
  399. emptyText: <Empty />,
  400. }}
  401. pagination={false}
  402. />
  403. <ThresholdModal
  404. open={visible}
  405. data={currentItem.JsonNumThreshold}
  406. onClose={() => setVisible(false)}
  407. />
  408. <ErrorHandleModal
  409. open={errVisible}
  410. userList={userList}
  411. onCancel={() => setErrVisible(false)}
  412. onOk={handleError}
  413. />
  414. </div>
  415. );
  416. }
  417. function AalysisTable(props) {
  418. const { onClickItem, data = {}, select } = props;
  419. const { FaultAnalysis } = data;
  420. const columns = [
  421. {
  422. title: '异常名称',
  423. width: '18%',
  424. dataIndex: 'device_name',
  425. },
  426. // {
  427. // title: '位号',
  428. // width: '15%',
  429. // dataIndex: 'device_code',
  430. // },
  431. {
  432. title: '可能原因',
  433. width: '30%',
  434. render: (record) => record.reason,
  435. },
  436. {
  437. title: '解决方案',
  438. width: '52%',
  439. render: (record) => {
  440. if (record.fix_plan instanceof Array) {
  441. return (
  442. <div>
  443. {record.fix_plan.map((item) => (
  444. <div>
  445. {item.content}
  446. <br />
  447. </div>
  448. ))}
  449. </div>
  450. );
  451. } else {
  452. return record.fix_plan;
  453. }
  454. },
  455. },
  456. ];
  457. return (
  458. <div>
  459. <Table
  460. columns={columns}
  461. dataSource={FaultAnalysis}
  462. rowKey="device_code"
  463. locale={{
  464. emptyText: <Empty />,
  465. }}
  466. pagination={false}
  467. />
  468. </div>
  469. );
  470. }
  471. function ErrorHandleModal(props) {
  472. const { visible, onCancel, onOk, userList } = props;
  473. const [form] = Form.useForm();
  474. const status = form.getFieldValue('Status');
  475. const handleOk = () => {
  476. form.validateFields((error, values) => {
  477. if (error) return;
  478. onOk({
  479. ...values,
  480. PlanTime: values?.PlanTime?.format('YYYY-MM-DD HH:mm:ss'),
  481. });
  482. });
  483. };
  484. return (
  485. <Modal
  486. title="异常处理"
  487. open={visible}
  488. onCancel={onCancel}
  489. onOk={handleOk}
  490. destroyOnClose
  491. >
  492. <Form labelCol={{ span: 7 }} wrapperCol={{ span: 16 }}>
  493. <Form.Item label="异常处理备注" name="ExceptionHandling">
  494. <Input.TextArea />
  495. </Form.Item>
  496. <Form.Item
  497. label="审核状态"
  498. name="Status"
  499. rules={[{ required: true, message: '请选择验收状态' }]}
  500. >
  501. <Select style={{ width: '100%' }} placeholder="请选择验收状态">
  502. <Select.Option value={1}>已派遣</Select.Option>
  503. <Select.Option value={2}>已通过</Select.Option>
  504. </Select>
  505. </Form.Item>
  506. <Form.Item
  507. label="维修人"
  508. name="RepairMan"
  509. rules={[{ required: true, message: '请选择维修人' }]}
  510. >
  511. <Select
  512. showSearch
  513. placeholder="请选择维修人"
  514. filterOption={(input, option) =>
  515. option.props.children.indexOf(input) >= 0
  516. }
  517. style={{ width: '100%' }}
  518. >
  519. {userList?.map((item) => (
  520. <Select.Option key={item.ID}>{item.CName}</Select.Option>
  521. ))}
  522. </Select>
  523. </Form.Item>
  524. {status == 1 && (
  525. <>
  526. <Form.Item
  527. label="难度级别"
  528. name="DifficultyLevel"
  529. rules={[{ required: true, message: '请选择难度级别' }]}
  530. >
  531. <Select placeholder="请选择难度级别" style={{ width: '100%' }}>
  532. <Select.Option value={0}>大修</Select.Option>
  533. <Select.Option value={1}>项目维修</Select.Option>
  534. <Select.Option value={2}>小修</Select.Option>
  535. </Select>
  536. </Form.Item>
  537. <Form.Item
  538. label="维修方式"
  539. name="RepairType"
  540. rules={[{ required: true, message: '请选择维修方式' }]}
  541. >
  542. <Select placeholder="请选择维修方式" style={{ width: '100%' }}>
  543. <Select.Option value={0}>自维</Select.Option>
  544. <Select.Option value={1}>外委</Select.Option>
  545. </Select>
  546. </Form.Item>
  547. <Form.Item
  548. label="计划完成日期"
  549. name="PlanTime"
  550. rules={[{ required: true, message: '请选择计划完成日期' }]}
  551. >
  552. <DatePicker inputReadOnly />
  553. </Form.Item>
  554. </>
  555. )}
  556. </Form>
  557. </Modal>
  558. );
  559. }
  560. export function WarningTable(props) {
  561. const {
  562. onClickItem,
  563. data = {},
  564. onErrorHandle,
  565. select,
  566. userList,
  567. type,
  568. items,
  569. } = props;
  570. const { ProjectId, Id } = data;
  571. const [loading, setLoading] = useState(false);
  572. const [visible, setVisible] = useState(false);
  573. const [errVisible, setErrVisible] = useState(false);
  574. const [currentItem, setCurrentItem] = useState({});
  575. const isSensor = type == 'sensor';
  576. const onClickThreshold = (record) => {
  577. setCurrentItem(record);
  578. setVisible(true);
  579. };
  580. const onClickError = (record) => {
  581. setCurrentItem(record);
  582. setErrVisible(true);
  583. };
  584. const handleError = async (values) => {
  585. setLoading(true);
  586. var res = await changeRecordStatus({
  587. ...values,
  588. Id: currentItem.Id,
  589. DeviceCode: currentItem.DeviceCode,
  590. DeviceName: currentItem.DeviceName,
  591. RecordId: data.Id,
  592. RepairMan: values.RepairMan * 1,
  593. });
  594. setLoading(false);
  595. if (res) {
  596. message.success('操作成功');
  597. setErrVisible(false);
  598. }
  599. };
  600. const columns = [
  601. {
  602. title: '设备名称',
  603. width: '20%',
  604. dataIndex: 'DeviceName',
  605. },
  606. {
  607. title: '巡检项',
  608. dataIndex: 'TemplateItem.Name',
  609. },
  610. // {
  611. // title: '设备位号',
  612. // width: '16%',
  613. // dataIndex: 'DeviceCode',
  614. // },
  615. {
  616. title: '设定值范围',
  617. width: '30%',
  618. render: (record) => (
  619. <ThresholdDetail
  620. current={record.Value || 0}
  621. data={record || {}}
  622. // onClick={() => onClickThreshold(record)}
  623. />
  624. ),
  625. },
  626. {
  627. title: '状态',
  628. dataIndex: 'Status',
  629. width: '1.25rem',
  630. render: (Status) => {
  631. switch (Status) {
  632. case -1:
  633. case 0:
  634. return (
  635. <div>
  636. <i
  637. className={styles.iconStatus}
  638. style={{ background: '#12CEB3' }}
  639. ></i>
  640. 正常
  641. </div>
  642. );
  643. case 1:
  644. return (
  645. <div>
  646. <i
  647. className={styles.iconStatus}
  648. style={{ background: '#FE5850' }}
  649. ></i>
  650. 异常
  651. </div>
  652. );
  653. case 2:
  654. return (
  655. <div>
  656. <i
  657. className={styles.iconStatus}
  658. style={{ background: '#FFE26D' }}
  659. ></i>
  660. 警告
  661. </div>
  662. );
  663. }
  664. },
  665. },
  666. ];
  667. const handleClickItem = (data) => {
  668. if (!isSensor) {
  669. onClickItem(`DeviceTable-${data.Id}`, {
  670. type: data.Status,
  671. deviceCode: data.DeviceCode,
  672. });
  673. } else {
  674. onClickItem(`DeviceTable-${data.Id}`, {
  675. // type: data.Status,
  676. deviceCode: data.DeviceCode,
  677. value: Number(data.Value || 0),
  678. threshold: data.JsonNumThreshold,
  679. });
  680. UnityAction.sendMsg('SinglePowerEnvironFromWeb', JSON.stringify(data));
  681. }
  682. };
  683. // if (!isSensor) {
  684. // columns.push({
  685. // title: '操作',
  686. // render: (record) =>
  687. // record.Status == 1 && (
  688. // <a style={{ color: '#FE5850' }} onClick={() => onClickError(record)}>
  689. // 异常处理
  690. // </a>
  691. // ),
  692. // });
  693. // }
  694. // useEffect(() => {
  695. // if (isSensor)
  696. // UnityAction.sendMsg('PowerEnvironsFromWeb', JSON.stringify(items));
  697. // }, [items]);
  698. return (
  699. <div>
  700. <Table
  701. columns={columns}
  702. dataSource={items}
  703. rowKey="Id"
  704. locale={{
  705. emptyText: <Empty />,
  706. }}
  707. pagination={false}
  708. />
  709. <ThresholdModal
  710. open={visible}
  711. data={currentItem.JsonNumThreshold}
  712. onClose={() => setVisible(false)}
  713. />
  714. <ErrorHandleModal
  715. open={errVisible}
  716. userList={userList}
  717. onCancel={() => setErrVisible(false)}
  718. onOk={handleError}
  719. />
  720. </div>
  721. );
  722. }
  723. function ReportCom(props) {
  724. const {
  725. sendMessageToUnity,
  726. select,
  727. waringData = [],
  728. allData = [],
  729. userList,
  730. type,
  731. title,
  732. data,
  733. } = props;
  734. const [activeKey, setActiveKey] = useState('1');
  735. const handleTabsChange = (activeKey) => {
  736. setActiveKey(activeKey);
  737. };
  738. return (
  739. <div className={styles.detailCard}>
  740. <div className={styles.tableTop}>
  741. {title}
  742. <TabsContent
  743. defaultActiveKey="1"
  744. onChange={handleTabsChange}
  745. small={true}
  746. items={[
  747. {
  748. key: '1',
  749. label: `异常/警告(${waringData.length || 0})`,
  750. children: <div></div>,
  751. },
  752. {
  753. key: '2',
  754. label: `全部(${allData.length || 0})`,
  755. children: <div></div>,
  756. },
  757. ]}
  758. ></TabsContent>
  759. </div>
  760. {activeKey == '1' && (
  761. <WarningTable
  762. onClickItem={sendMessageToUnity}
  763. select={select}
  764. items={waringData}
  765. key={type}
  766. data={data}
  767. type={type}
  768. userList={userList}
  769. />
  770. )}
  771. {activeKey == '2' && (
  772. <DeviceTable
  773. onClickItem={sendMessageToUnity}
  774. select={select}
  775. items={allData}
  776. data={data}
  777. key={type}
  778. type={type}
  779. userList={userList}
  780. />
  781. )}
  782. </div>
  783. );
  784. }
  785. export function LiquidTable(props) {
  786. const { onClickItem, data = {}, items, select, type } = props;
  787. const { ProjectId, Id } = data;
  788. const [loading, setLoading] = useState(false);
  789. const [currentItem, setCurrentItem] = useState({});
  790. const columns = [
  791. {
  792. title: '设备名称',
  793. width: '20%',
  794. dataIndex: 'device_name',
  795. },
  796. {
  797. title: '类型',
  798. key: 'template_item_name',
  799. dataIndex: 'template_item_name',
  800. },
  801. {
  802. title: '液位数',
  803. dataIndex: 'origin_value',
  804. },
  805. {
  806. title: '差值',
  807. dataIndex: 'value',
  808. },
  809. {
  810. title: '设定值范围',
  811. width: '25%',
  812. render: (record) => (
  813. <ThresholdDetail
  814. current={record.value || 0}
  815. data={{
  816. JsonNumThreshold: record?.json_num_threshold,
  817. Type: record.type || 2,
  818. }}
  819. />
  820. ),
  821. },
  822. {
  823. title: '状态',
  824. dataIndex: 'status',
  825. width: '1.25rem',
  826. render: (status) => {
  827. switch (status) {
  828. case -1:
  829. case 0:
  830. return (
  831. <div>
  832. <i
  833. className={styles.iconStatus}
  834. style={{ background: '#12CEB3' }}
  835. ></i>
  836. 正常
  837. </div>
  838. );
  839. case 1:
  840. return (
  841. <div>
  842. <i
  843. className={styles.iconStatus}
  844. style={{ background: '#FFE26D' }}
  845. ></i>
  846. 异常
  847. </div>
  848. );
  849. case 2:
  850. return (
  851. <div>
  852. <i
  853. className={styles.iconStatus}
  854. style={{ background: '#FFE26D' }}
  855. ></i>
  856. 警告
  857. </div>
  858. );
  859. }
  860. },
  861. },
  862. ];
  863. const handleClickItem = (data) => {
  864. onClickItem(`DeviceTable-${data.device_code}`, {
  865. type: data.status,
  866. deviceCode: data.device_code,
  867. });
  868. };
  869. return (
  870. <Table
  871. columns={columns}
  872. dataSource={items}
  873. rowKey="device_code"
  874. locale={{
  875. emptyText: <Empty />,
  876. }}
  877. pagination={false}
  878. />
  879. );
  880. }
  881. function LiquidLevelCom(props) {
  882. const { sendMessageToUnity, select, allData = [], type, title } = props;
  883. const [activeKey, setActiveKey] = useState('1');
  884. const errorData = useMemo(() => {
  885. const errorData = allData?.filter((item) => item.status);
  886. return errorData;
  887. }, [allData]);
  888. const handleTabsChange = (activeKey) => {
  889. setActiveKey(activeKey);
  890. };
  891. return (
  892. <div className={styles.detailCard}>
  893. <div className={styles.tableTop}>
  894. {title}
  895. <TabsContent
  896. defaultActiveKey="1"
  897. onChange={handleTabsChange}
  898. small
  899. items={[
  900. {
  901. key: '1',
  902. label: `异常/警告(${errorData?.length || 0})`,
  903. children: <div></div>,
  904. },
  905. {
  906. key: '2',
  907. label: `全部(${allData?.length || 0})`,
  908. children: <div></div>,
  909. },
  910. ]}
  911. ></TabsContent>
  912. </div>
  913. {activeKey == '1' && (
  914. <LiquidTable
  915. onClickItem={sendMessageToUnity}
  916. select={select}
  917. items={errorData}
  918. key={type}
  919. type={type}
  920. />
  921. )}
  922. {activeKey == '2' && (
  923. <LiquidTable
  924. onClickItem={sendMessageToUnity}
  925. select={select}
  926. items={allData}
  927. key={type}
  928. type={type}
  929. />
  930. )}
  931. </div>
  932. );
  933. }
  934. function DosingFlowTable(props) {
  935. const { onClickItem, data = {}, items } = props;
  936. const columns = [
  937. {
  938. title: '设备名称',
  939. width: '20%',
  940. dataIndex: 'device_name',
  941. },
  942. {
  943. title: '类型',
  944. width: '1rem',
  945. key: 'template_item_name',
  946. dataIndex: 'template_item_name',
  947. },
  948. {
  949. title: '实际流量',
  950. dataIndex: 'origin_value',
  951. },
  952. {
  953. title: '计量流量',
  954. dataIndex: 'value',
  955. },
  956. {
  957. title: '差值/比值',
  958. dataIndex: 'value',
  959. },
  960. {
  961. title: '设定值范围',
  962. width: '20%',
  963. render: (record) => (
  964. <ThresholdDetail
  965. current={record.value || 0}
  966. data={{
  967. JsonNumThreshold: record?.json_num_threshold,
  968. Type: record.type || 2,
  969. }}
  970. />
  971. ),
  972. },
  973. {
  974. title: '状态',
  975. dataIndex: 'status',
  976. width: '1.25rem',
  977. render: (status) => {
  978. switch (status) {
  979. case -1:
  980. case 0:
  981. return (
  982. <div>
  983. <i
  984. className={styles.iconStatus}
  985. style={{ background: '#12CEB3' }}
  986. />
  987. 正常
  988. </div>
  989. );
  990. case 1:
  991. return (
  992. <div>
  993. <i
  994. className={styles.iconStatus}
  995. style={{ background: '#FF8600' }}
  996. />
  997. 异常
  998. </div>
  999. );
  1000. case 2:
  1001. return (
  1002. <div>
  1003. <i
  1004. className={styles.iconStatus}
  1005. style={{ background: '#FFE26D' }}
  1006. />
  1007. 警告
  1008. </div>
  1009. );
  1010. default:
  1011. return null;
  1012. }
  1013. },
  1014. },
  1015. ];
  1016. const handleClickItem = (data) => {
  1017. onClickItem(`DeviceTable-${data.device_code}`, {
  1018. type: data.status,
  1019. deviceCode: data.device_code,
  1020. });
  1021. };
  1022. return (
  1023. <Table
  1024. columns={columns}
  1025. dataSource={items}
  1026. rowKey="device_code"
  1027. locale={{
  1028. emptyText: <Empty />,
  1029. }}
  1030. pagination={false}
  1031. />
  1032. );
  1033. }
  1034. function DosingFlowCom(props) {
  1035. const { sendMessageToUnity, select, allData = [], type, title } = props;
  1036. const [activeKey, setActiveKey] = useState('1');
  1037. const errorData = useMemo(() => {
  1038. const errorData = allData?.filter((item) => item.status);
  1039. return errorData;
  1040. }, [allData]);
  1041. const handleTabsChange = (key) => {
  1042. setActiveKey(key);
  1043. };
  1044. return (
  1045. <div className={styles.detailCard}>
  1046. <div className={styles.tableTop}>
  1047. {title}
  1048. <TabsContent
  1049. defaultActiveKey="1"
  1050. onChange={handleTabsChange}
  1051. small
  1052. items={[
  1053. {
  1054. key: '1',
  1055. label: `异常/警告(${errorData?.length || 0})`,
  1056. children: <div></div>,
  1057. },
  1058. {
  1059. key: '2',
  1060. label: `全部(${allData?.length || 0})`,
  1061. children: <div></div>,
  1062. },
  1063. ]}
  1064. ></TabsContent>
  1065. </div>
  1066. {activeKey === '1' && (
  1067. <DosingFlowTable
  1068. onClickItem={sendMessageToUnity}
  1069. select={select}
  1070. items={errorData}
  1071. />
  1072. )}
  1073. {activeKey === '2' && (
  1074. <DosingFlowTable
  1075. onClickItem={sendMessageToUnity}
  1076. select={select}
  1077. items={allData}
  1078. />
  1079. )}
  1080. </div>
  1081. );
  1082. }
  1083. function WaterInTable(props) {
  1084. const { onClickItem, data = {}, items } = props;
  1085. const columns = [
  1086. {
  1087. title: '设备名称',
  1088. width: '20%',
  1089. dataIndex: 'item_alias',
  1090. },
  1091. {
  1092. title: '差值',
  1093. // width: '15%',
  1094. dataIndex: 'current_val',
  1095. },
  1096. {
  1097. title: '时间',
  1098. // width: '15%',
  1099. dataIndex: 'create_time',
  1100. render: (text) => {
  1101. if (text) {
  1102. return dayjs(text).format('HH:mm:ss');
  1103. }
  1104. return '-';
  1105. },
  1106. },
  1107. {
  1108. title: '设定值范围',
  1109. width: '30%',
  1110. render: (record) => (
  1111. <ThresholdDetail
  1112. current={record.current_val || 0}
  1113. data={{
  1114. JsonNumThreshold: {
  1115. exception: [
  1116. { ThresholdValue: record?.thresholds, ThresholdType: 1 },
  1117. ],
  1118. },
  1119. Type: 2,
  1120. }}
  1121. />
  1122. ),
  1123. },
  1124. {
  1125. title: '状态',
  1126. dataIndex: 'status',
  1127. width: '1.25rem',
  1128. render: (status) => {
  1129. switch (status) {
  1130. case -1:
  1131. case 0:
  1132. return (
  1133. <div>
  1134. <i
  1135. className={styles.iconStatus}
  1136. style={{ background: '#12CEB3' }}
  1137. />
  1138. 正常
  1139. </div>
  1140. );
  1141. case 1:
  1142. return (
  1143. <div>
  1144. <i
  1145. className={styles.iconStatus}
  1146. style={{ background: '#FF8600' }}
  1147. />
  1148. 异常
  1149. </div>
  1150. );
  1151. case 2:
  1152. return (
  1153. <div>
  1154. <i
  1155. className={styles.iconStatus}
  1156. style={{ background: '#FFE26D' }}
  1157. />
  1158. 警告
  1159. </div>
  1160. );
  1161. default:
  1162. return (
  1163. <div>
  1164. <i
  1165. className={styles.iconStatus}
  1166. style={{ background: '#FF8600' }}
  1167. />
  1168. 异常
  1169. </div>
  1170. );
  1171. }
  1172. },
  1173. },
  1174. ];
  1175. const handleClickItem = (params) => {
  1176. onClickItem(`DeviceTable-${params.device_code}`, {
  1177. type: params.status,
  1178. deviceCode: params.device_code,
  1179. });
  1180. };
  1181. return (
  1182. <Table
  1183. columns={columns}
  1184. dataSource={items}
  1185. rowKey="device_code"
  1186. locale={{
  1187. emptyText: <Empty />,
  1188. }}
  1189. pagination={false}
  1190. />
  1191. );
  1192. }
  1193. function WaterInCom(props) {
  1194. const { sendMessageToUnity, select, allData = [], title } = props;
  1195. const [activeKey, setActiveKey] = useState('1');
  1196. const errorData = useMemo(() => {
  1197. const tempData = allData?.filter((item) => item.status);
  1198. return tempData;
  1199. }, [allData]);
  1200. const handleTabsChange = (key) => {
  1201. setActiveKey(key);
  1202. };
  1203. return (
  1204. <div className={styles.detailCard}>
  1205. <div className={styles.tableTop}>
  1206. {title}
  1207. <TabsContent
  1208. defaultActiveKey="1"
  1209. onChange={handleTabsChange}
  1210. small
  1211. items={[
  1212. {
  1213. key: '1',
  1214. label: `异常/警告(${errorData?.length || 0})`,
  1215. children: <div></div>,
  1216. },
  1217. {
  1218. key: '2',
  1219. label: `全部(${allData?.length || 0})`,
  1220. children: <div></div>,
  1221. },
  1222. ]}
  1223. ></TabsContent>
  1224. </div>
  1225. {activeKey === '1' && (
  1226. <WaterInTable
  1227. onClickItem={sendMessageToUnity}
  1228. select={select}
  1229. items={errorData}
  1230. />
  1231. )}
  1232. {activeKey === '2' && (
  1233. <WaterInTable
  1234. onClickItem={sendMessageToUnity}
  1235. select={select}
  1236. items={allData}
  1237. />
  1238. )}
  1239. </div>
  1240. );
  1241. }
  1242. function PressureGaugeTable(props) {
  1243. const { onClickItem, data = {}, items } = props;
  1244. const columns = [
  1245. {
  1246. title: '设备名称',
  1247. width: '20%',
  1248. dataIndex: 'item_alias',
  1249. },
  1250. {
  1251. title: '时间范围',
  1252. key: 'dataRange',
  1253. width: '1.5rem',
  1254. render: (record) => {
  1255. if (record.query_start && record.query_end) {
  1256. return (
  1257. <>
  1258. {dayjs(record.query_start).format('HH:mm:ss')}
  1259. <br />
  1260. {dayjs(record.query_end).format('HH:mm:ss')}
  1261. </>
  1262. );
  1263. }
  1264. return '-';
  1265. },
  1266. },
  1267. {
  1268. title: (
  1269. <>
  1270. 仪表
  1271. <br />
  1272. 最小数
  1273. </>
  1274. ),
  1275. width: '1.25rem',
  1276. dataIndex: 'data_min',
  1277. },
  1278. {
  1279. title: (
  1280. <>
  1281. 仪表
  1282. <br />
  1283. 最大数
  1284. </>
  1285. ),
  1286. width: '1.25rem',
  1287. dataIndex: 'data_max',
  1288. },
  1289. {
  1290. title: '可能原因',
  1291. dataIndex: 'content',
  1292. },
  1293. {
  1294. title: '状态',
  1295. dataIndex: 'status',
  1296. width: '1.25rem',
  1297. render: (status) => {
  1298. switch (status) {
  1299. case -1:
  1300. case 0:
  1301. return (
  1302. <div>
  1303. <i
  1304. className={styles.iconStatus}
  1305. style={{ background: '#12CEB3' }}
  1306. />
  1307. 正常
  1308. </div>
  1309. );
  1310. case 1:
  1311. return (
  1312. <div>
  1313. <i
  1314. className={styles.iconStatus}
  1315. style={{ background: '#FF8600' }}
  1316. />
  1317. 异常
  1318. </div>
  1319. );
  1320. case 2:
  1321. return (
  1322. <div>
  1323. <i
  1324. className={styles.iconStatus}
  1325. style={{ background: '#FFE26D' }}
  1326. />
  1327. 警告
  1328. </div>
  1329. );
  1330. default:
  1331. return (
  1332. <div>
  1333. <i
  1334. className={styles.iconStatus}
  1335. style={{ background: '#FF8600' }}
  1336. />
  1337. 异常
  1338. </div>
  1339. );
  1340. }
  1341. },
  1342. },
  1343. ];
  1344. const handleClickItem = (params) => {
  1345. onClickItem(`DeviceTable-${params.device_code}`, {
  1346. type: params.status,
  1347. deviceCode: params.device_code,
  1348. });
  1349. };
  1350. return (
  1351. <Table
  1352. columns={columns}
  1353. dataSource={items}
  1354. rowKey="device_code"
  1355. locale={{
  1356. emptyText: <Empty />,
  1357. }}
  1358. pagination={false}
  1359. />
  1360. );
  1361. }
  1362. function PressureGaugeCom(props) {
  1363. const { sendMessageToUnity, select, allData = [], title } = props;
  1364. const [activeKey, setActiveKey] = useState('2');
  1365. const errorData = useMemo(() => {
  1366. const tempData = allData?.filter((item) => item.status);
  1367. return tempData;
  1368. }, [allData]);
  1369. const handleTabsChange = (key) => {
  1370. setActiveKey(key);
  1371. };
  1372. return (
  1373. <div className={styles.detailCard}>
  1374. <div className={styles.tableTop}>
  1375. {title}
  1376. <TabsContent
  1377. defaultActiveKey="2"
  1378. onChange={handleTabsChange}
  1379. small
  1380. items={[
  1381. {
  1382. key: '2',
  1383. label: `异常/警告(${allData?.length || 0})`,
  1384. children: <div></div>,
  1385. },
  1386. ]}
  1387. ></TabsContent>
  1388. </div>
  1389. {activeKey === '2' && (
  1390. <PressureGaugeTable
  1391. onClickItem={sendMessageToUnity}
  1392. select={select}
  1393. items={allData}
  1394. />
  1395. )}
  1396. </div>
  1397. );
  1398. }
  1399. function WaterQualityTable(props) {
  1400. const { onClickItem, data = {}, items } = props;
  1401. const columns = [
  1402. {
  1403. title: '设备名称',
  1404. width: '20%',
  1405. dataIndex: 'item_alias',
  1406. },
  1407. {
  1408. title: '时间范围',
  1409. key: 'dataRange',
  1410. width: '1.5rem',
  1411. render: (record) => {
  1412. if (record.query_start && record.query_end) {
  1413. return (
  1414. <>
  1415. {dayjs(record.query_start).format('HH:mm:ss')}
  1416. <br />
  1417. {dayjs(record.query_end).format('HH:mm:ss')}
  1418. </>
  1419. );
  1420. }
  1421. return '-';
  1422. },
  1423. },
  1424. {
  1425. title: (
  1426. <>
  1427. 仪表
  1428. <br />
  1429. 最小数
  1430. </>
  1431. ),
  1432. width: '1.25rem',
  1433. dataIndex: 'data_min',
  1434. },
  1435. {
  1436. title: (
  1437. <>
  1438. 仪表
  1439. <br />
  1440. 最大数
  1441. </>
  1442. ),
  1443. width: '1.25rem',
  1444. dataIndex: 'data_max',
  1445. },
  1446. {
  1447. title: '可能原因',
  1448. dataIndex: 'content',
  1449. },
  1450. {
  1451. title: '状态',
  1452. dataIndex: 'status',
  1453. width: '1.25rem',
  1454. render: (status) => {
  1455. switch (status) {
  1456. case -1:
  1457. case 0:
  1458. return (
  1459. <div>
  1460. <i
  1461. className={styles.iconStatus}
  1462. style={{ background: '#12CEB3' }}
  1463. />
  1464. 正常
  1465. </div>
  1466. );
  1467. case 1:
  1468. return (
  1469. <div>
  1470. <i
  1471. className={styles.iconStatus}
  1472. style={{ background: '#FF8600' }}
  1473. />
  1474. 异常
  1475. </div>
  1476. );
  1477. case 2:
  1478. return (
  1479. <div>
  1480. <i
  1481. className={styles.iconStatus}
  1482. style={{ background: '#FFE26D' }}
  1483. />
  1484. 警告
  1485. </div>
  1486. );
  1487. default:
  1488. return (
  1489. <div>
  1490. <i
  1491. className={styles.iconStatus}
  1492. style={{ background: '#FF8600' }}
  1493. />
  1494. 异常
  1495. </div>
  1496. );
  1497. }
  1498. },
  1499. },
  1500. ];
  1501. const handleClickItem = (params) => {
  1502. onClickItem(`DeviceTable-${params.device_code}`, {
  1503. type: params.status,
  1504. deviceCode: params.device_code,
  1505. });
  1506. };
  1507. return (
  1508. <Table
  1509. columns={columns}
  1510. dataSource={items}
  1511. rowKey="device_code"
  1512. locale={{
  1513. emptyText: <Empty />,
  1514. }}
  1515. pagination={false}
  1516. />
  1517. );
  1518. }
  1519. function WaterQualityCom(props) {
  1520. const { sendMessageToUnity, select, allData = [], title } = props;
  1521. const [activeKey, setActiveKey] = useState('2');
  1522. const errorData = useMemo(() => {
  1523. const tempData = allData?.filter((item) => item.status);
  1524. return tempData;
  1525. }, [allData]);
  1526. const handleTabsChange = (key) => {
  1527. setActiveKey(key);
  1528. };
  1529. return (
  1530. <div className={styles.detailCard}>
  1531. <div className={styles.tableTop}>
  1532. {title}
  1533. <TabsContent
  1534. defaultActiveKey="2"
  1535. onChange={handleTabsChange}
  1536. small
  1537. items={[
  1538. {
  1539. key: '2',
  1540. label: `异常/警告(${allData?.length || 0})`,
  1541. children: <div></div>,
  1542. },
  1543. ]}
  1544. ></TabsContent>
  1545. </div>
  1546. {activeKey === '2' && (
  1547. <WaterQualityTable
  1548. onClickItem={sendMessageToUnity}
  1549. select={select}
  1550. items={allData}
  1551. />
  1552. )}
  1553. </div>
  1554. );
  1555. }
  1556. function ReportDumCom(props) {
  1557. const { data = [], title } = props;
  1558. const columns = [
  1559. {
  1560. title: '报警时间',
  1561. dataIndex: 'event_time',
  1562. render: (time) => dayjs(time).format('YYYY-MM-DD HH:mm:ss'),
  1563. },
  1564. {
  1565. title: '设备名称',
  1566. dataIndex: 'device_name',
  1567. },
  1568. {
  1569. title: '报警类型',
  1570. dataIndex: 'event_type',
  1571. // render: type => alarmType[type],
  1572. },
  1573. {
  1574. title: '报警图片',
  1575. render: (item) => (
  1576. <ReactZmage
  1577. controller={{
  1578. // 关闭按钮
  1579. close: true,
  1580. // 旋转按钮
  1581. rotate: true,
  1582. // 缩放按钮
  1583. zoom: false,
  1584. // 下载按钮
  1585. download: false,
  1586. // 翻页按钮
  1587. flip: false,
  1588. // 多页指示
  1589. pagination: false,
  1590. }}
  1591. backdrop="rgba(255,255,255,0.5)"
  1592. style={{ height: '0.9rem' }}
  1593. src={item.path}
  1594. />
  1595. ),
  1596. },
  1597. ];
  1598. return (
  1599. <div style={{ marginBottom: '0.3rem' }}>
  1600. <div className={styles.tabBarExtraContent}>
  1601. <div className={styles.text} style={{ width: '60%' }}>
  1602. {title}
  1603. </div>
  1604. <div className={styles.abnormal}>
  1605. <div className={styles.text} style={{ float: 'right' }}>
  1606. 异常({data?.length || 0})
  1607. </div>
  1608. </div>
  1609. </div>
  1610. <Table
  1611. bordered
  1612. rowKey="event_time"
  1613. columns={columns}
  1614. dataSource={data}
  1615. locale={{
  1616. emptyText: <Empty />,
  1617. }}
  1618. pagination={false}
  1619. />
  1620. </div>
  1621. );
  1622. }
  1623. function base64ToImageUrl(base64String) {
  1624. const byteCharacters = atob(base64String);
  1625. const byteArrays = [];
  1626. for (let i = 0; i < byteCharacters.length; i++) {
  1627. byteArrays.push(byteCharacters.charCodeAt(i));
  1628. }
  1629. const byteArray = new Uint8Array(byteArrays);
  1630. const blob = new Blob([byteArray], { type: 'image/png' });
  1631. const imageUrl = URL.createObjectURL(blob);
  1632. return imageUrl;
  1633. }
  1634. function Empty() {
  1635. return (
  1636. <div>
  1637. <img
  1638. src={require('@/assets/self-empty.png')}
  1639. style={{ margin: '0.2rem 0', width: '1rem' }}
  1640. />
  1641. <p style={{ textAlign: 'center', color: '#555' }}>自检正常</p>
  1642. </div>
  1643. );
  1644. }
  1645. export default connect(({ eqSelfInspection }) => ({
  1646. userList: eqSelfInspection.userList,
  1647. mandateInfo: eqSelfInspection.mandateInfo,
  1648. }))(Detail);