Detail.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. import ModuleTitle from '@/components/ManagementPage/moduleTitle';
  2. import { getDumuDetail } from '@/services/eqSelfInspection';
  3. import { connect, useModel, useParams, useRequest } from '@umijs/max';
  4. import { Affix, Checkbox, Col, Row, Spin, Table } from 'antd';
  5. import { useEffect, useMemo, useState } from 'react';
  6. import styles from './PatrolReportDetail.less';
  7. import DosingFlowCom from './Table/DosingFlowCom';
  8. import Empty from './Table/Empty';
  9. import LiquidLevelCom from './Table/LiquidLevelCom';
  10. import MandateBtn from './Table/MandateBtn';
  11. import PressureGaugeCom from './Table/PressureGaugeCom';
  12. import ReportCom from './Table/ReportCom';
  13. import ReportDumCom from './Table/ReportDumCom';
  14. import WaterInCom from './Table/WaterInCom';
  15. import WaterQualityCom from './Table/WaterQualityCom';
  16. function Detail(props) {
  17. const { data, userList, projectId, dispatch, loading = false } = props;
  18. const { routeId } = useParams();
  19. const { queryMandate } = useModel('useMandate');
  20. const [select, setSelect] = useState();
  21. const [statusCheck, setStatusCheck] = useState([0, 1, 2]);
  22. const sendMessageToUnity = (select, data) => {
  23. setSelect(select);
  24. if (window.HightlightEquipment) {
  25. window.HightlightEquipment(data);
  26. }
  27. };
  28. const result = useMemo(() => {
  29. var resultArr = [];
  30. var tempResult = data?.PatrolResult;
  31. var tempArr = tempResult?.split(';');
  32. const getTextColor = (status) => {
  33. switch (status) {
  34. case '警告':
  35. return {
  36. color: '#FFE26D',
  37. className: styles.warn,
  38. };
  39. case '异常':
  40. return {
  41. color: '#FE5850',
  42. className: styles.error,
  43. };
  44. default:
  45. return {
  46. color: '#12CEB3',
  47. className: '',
  48. };
  49. }
  50. };
  51. if (tempArr?.length > 0) {
  52. tempArr?.forEach((item, index) => {
  53. var tempItem = item;
  54. var itemSplit = tempItem.split(':');
  55. if (itemSplit?.length > 1) {
  56. var label = '';
  57. var value = itemSplit[1];
  58. if (index === 0) label = '设备自检';
  59. else if (index === 1) label = '工艺自检';
  60. else {
  61. label = '安全自检';
  62. value =
  63. data?.secureStatus === 0
  64. ? itemSplit[1] !== '异常'
  65. ? '正常'
  66. : '异常'
  67. : '异常';
  68. }
  69. resultArr.push({
  70. ...getTextColor(value),
  71. label,
  72. value,
  73. });
  74. }
  75. });
  76. }
  77. return resultArr;
  78. }, [data]);
  79. useEffect(() => {
  80. queryMandate({
  81. project_id: projectId,
  82. id: routeId,
  83. });
  84. dispatch({
  85. type: 'eqSelfInspection/fetchUserList',
  86. payload: {
  87. projectId,
  88. },
  89. });
  90. }, []);
  91. return (
  92. <Spin spinning={loading}>
  93. <Affix>
  94. <div className={styles.card}>
  95. <Row>
  96. <Col span={24} className={styles.cardText}>
  97. 自检时间:{data?.CreatedTime}
  98. </Col>
  99. </Row>
  100. <Row>
  101. <Col span={10} className={styles.cardText}>
  102. 自检路线:{data?.RouteInfo?.Name}
  103. </Col>
  104. <Col span={8} className={styles.cardText}>
  105. 工艺段:{data?.RouteInfo?.GroupID}
  106. </Col>
  107. </Row>
  108. <Row>
  109. {result.map((item, index) => (
  110. <Col
  111. span={index == 0 ? 10 : 7}
  112. className={styles.cardText}
  113. key={item.label}
  114. >
  115. {index == 0 && '自检结果:'}
  116. {item.label}-
  117. <span style={{ color: item.color }}>{item.value}</span>
  118. </Col>
  119. ))}
  120. </Row>
  121. </div>
  122. </Affix>
  123. <Checkbox.Group
  124. onChange={(check) => {
  125. // 未勾选则认为全部显示
  126. if (check.length == 0) {
  127. setStatusCheck([0, 1, 2]);
  128. } else {
  129. setStatusCheck(check);
  130. }
  131. }}
  132. style={{
  133. width: '70%',
  134. margin: '0 auto',
  135. display: 'flex',
  136. justifyContent: 'center',
  137. marginBottom: '0.3rem',
  138. }}
  139. >
  140. <Checkbox value={1}>异常数据</Checkbox>
  141. <Checkbox value={2} style={{ margin: '0 0.5rem' }}>
  142. 警告数据
  143. </Checkbox>
  144. <Checkbox value={0}>正常数据</Checkbox>
  145. </Checkbox.Group>
  146. {/* 设备自检报告 */}
  147. <DeviceReport
  148. sendMessageToUnity={sendMessageToUnity}
  149. select={select}
  150. data={data}
  151. userList={userList}
  152. statusCheck={statusCheck}
  153. />
  154. {/* 工艺自检报告 */}
  155. <AalysisTable
  156. onClickItem={sendMessageToUnity}
  157. select={select}
  158. data={data}
  159. statusCheck={statusCheck}
  160. />
  161. {/* 安全自检报告 */}
  162. <SecureReport
  163. sendMessageToUnity={sendMessageToUnity}
  164. select={select}
  165. data={data}
  166. userList={userList}
  167. statusCheck={statusCheck}
  168. />
  169. </Spin>
  170. );
  171. }
  172. function DeviceReport(props) {
  173. const { data } = props;
  174. // 子集是否显示
  175. const [subStatus, setSubStatus] = useState([1, 1, 1, 1, 1, 1]);
  176. const subProps = { ...props, setSubStatus };
  177. // 子集全部隐藏的情况下,父级也隐藏
  178. const show = useMemo(() => {
  179. let total = subStatus.reduce((item, total) => total + item, 0);
  180. return total > 0;
  181. }, [subStatus]);
  182. const changeStatus = (type, status) => {
  183. setSubStatus((subStatus) => {
  184. let newSubStatus = [...subStatus];
  185. newSubStatus[type] = status;
  186. return newSubStatus;
  187. });
  188. };
  189. // if (!show) return null;
  190. return (
  191. <div style={{ display: show ? 'block' : 'none' }}>
  192. <ModuleTitle title="设备自检报告" />
  193. {/* 设备自检报告 */}
  194. <ReportCom
  195. {...subProps}
  196. allData={data?.extendWarningAllData}
  197. key="extend"
  198. type={'extend'}
  199. title={<div id="device">设备自检</div>}
  200. changeStatus={(status) => changeStatus(0, status)}
  201. ></ReportCom>
  202. {/* 液位校验 */}
  203. <LiquidLevelCom
  204. {...subProps}
  205. allData={data?.FluidLevelList}
  206. changeStatus={(status) => changeStatus(1, status)}
  207. />
  208. {/* 加药流量校验 */}
  209. <DosingFlowCom
  210. {...subProps}
  211. allData={data?.DrugFlowList}
  212. changeStatus={(status) => changeStatus(2, status)}
  213. />
  214. <WaterInCom
  215. {...subProps}
  216. allData={data?.WaterInCheckList}
  217. changeStatus={(status) => changeStatus(3, status)}
  218. />
  219. <PressureGaugeCom
  220. {...subProps}
  221. allData={data?.PressureCompareList}
  222. title="压力仪表校验"
  223. changeStatus={(status) => changeStatus(4, status)}
  224. />
  225. <WaterQualityCom
  226. {...subProps}
  227. allData={data?.WaterQualityCompareList}
  228. title="水质仪表校验"
  229. changeStatus={(status) => changeStatus(5, status)}
  230. />
  231. </div>
  232. );
  233. }
  234. function SecureReport(props) {
  235. const { data } = props;
  236. const [dumuList, setDumuList] = useState([]);
  237. // 子集是否显示
  238. const [subStatus, setSubStatus] = useState([1, 1, 1]);
  239. const subProps = { ...props, setSubStatus };
  240. // 子集全部隐藏的情况下,父级也隐藏
  241. const show = useMemo(() => {
  242. let total = subStatus.reduce((item, total) => total + item, 0);
  243. return total > 0;
  244. }, [subStatus]);
  245. const changeStatus = (type, status) => {
  246. setSubStatus((subStatus) => {
  247. let newSubStatus = [...subStatus];
  248. newSubStatus[type] = status;
  249. return newSubStatus;
  250. });
  251. };
  252. const { run: detailRun } = useRequest(getDumuDetail, {
  253. manual: true,
  254. fetchKey: (id) => id,
  255. onSuccess: (data) => {
  256. var item = dumuList?.find((child) => child.id === data.id);
  257. if (item) {
  258. item.url = base64ToImageUrl(data.event_bg);
  259. }
  260. setDumuList([...dumuList]);
  261. },
  262. });
  263. useEffect(() => {
  264. setDumuList(data?.dumuList);
  265. data?.dumuList?.forEach((item) => {
  266. detailRun(item.id);
  267. });
  268. }, [data?.dumuList]);
  269. // if (!show) return null;
  270. return (
  271. <div
  272. id="secure"
  273. className={styles.content}
  274. style={{ display: show ? 'block' : 'none' }}
  275. >
  276. <ModuleTitle title="安全自检报告" />
  277. {/* 环境异常 */}
  278. <ReportCom
  279. {...subProps}
  280. allData={data?.sensor}
  281. data={data?.sensorWaringData}
  282. key="sensor"
  283. type={'sensor'}
  284. title={'环境自检'}
  285. changeStatus={(status) => changeStatus(0, status)}
  286. ></ReportCom>
  287. {/* 安防检测异常 */}
  288. <ReportDumCom
  289. {...subProps}
  290. data={dumuList}
  291. title={'安防自检'}
  292. changeStatus={(status) => changeStatus(1, status)}
  293. />
  294. {/* 密闭空间检测异常 */}
  295. <ReportCom
  296. {...subProps}
  297. key="extend"
  298. type={'extend'}
  299. title={'密闭空间自检'}
  300. changeStatus={(status) => changeStatus(2, status)}
  301. ></ReportCom>
  302. </div>
  303. );
  304. }
  305. function AalysisTable(props) {
  306. const { data = {}, statusCheck } = props;
  307. const { FaultAnalysis } = data;
  308. const errorCount = data?.FaultAnalysis?.length || 0;
  309. const columns = [
  310. {
  311. title: '异常名称',
  312. width: '18%',
  313. dataIndex: 'device_name',
  314. },
  315. // {
  316. // title: '位号',
  317. // width: '15%',
  318. // dataIndex: 'device_code',
  319. // },
  320. {
  321. title: '可能原因',
  322. width: '30%',
  323. render: (record) => record.reason,
  324. },
  325. {
  326. title: '解决方案',
  327. render: (record) => {
  328. if (record.fix_plan instanceof Array) {
  329. return (
  330. <div>
  331. {record.fix_plan.map((item, index) => (
  332. <div style={{ lineHeight: 1.8 }} key={index}>
  333. {item.content}
  334. <MandateBtn relationId={record.id} />
  335. </div>
  336. ))}
  337. </div>
  338. );
  339. } else {
  340. return record.fix_plan;
  341. }
  342. },
  343. },
  344. ];
  345. if (statusCheck.length != 3) {
  346. // 不显示异常数据时,隐藏次模块
  347. if (!statusCheck.includes(1)) return null;
  348. // 过滤异常并且此模块没有异常数据时,不显示此模块
  349. if (statusCheck.includes(1) && errorCount == 0) return null;
  350. }
  351. return (
  352. <div className={styles.content} id="technology">
  353. <div className={styles.tableStatus}>异常({errorCount})</div>
  354. <ModuleTitle title="工艺自检报告" />
  355. <Table
  356. columns={columns}
  357. dataSource={FaultAnalysis}
  358. rowKey="device_code"
  359. locale={{
  360. emptyText: <Empty />,
  361. }}
  362. pagination={false}
  363. />
  364. </div>
  365. );
  366. }
  367. function base64ToImageUrl(base64String) {
  368. const byteCharacters = atob(base64String);
  369. const byteArrays = [];
  370. for (let i = 0; i < byteCharacters.length; i++) {
  371. byteArrays.push(byteCharacters.charCodeAt(i));
  372. }
  373. const byteArray = new Uint8Array(byteArrays);
  374. const blob = new Blob([byteArray], { type: 'image/png' });
  375. const imageUrl = URL.createObjectURL(blob);
  376. return imageUrl;
  377. }
  378. export default connect(({ eqSelfInspection }) => ({
  379. userList: eqSelfInspection.userList,
  380. mandateInfo: eqSelfInspection.mandateInfo,
  381. }))(Detail);