index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import PageContent from '@/components/PageContent';
  2. import PageTitle from '@/components/PageTitle';
  3. import TabsContent from '@/components/TabsContent';
  4. import {
  5. getHistoryRecord,
  6. queryProjectConfig,
  7. querySimulationProfit,
  8. } from '@/services/SmartOps';
  9. import { getPatrolPerception } from '@/services/dumu';
  10. import { GetTokenFromUrl, UnityAction } from '@/utils/utils';
  11. import {
  12. connect,
  13. useNavigate,
  14. useParams,
  15. useRequest,
  16. useSearchParams,
  17. } from '@umijs/max';
  18. import { Tabs } from 'antd';
  19. import dayjs from 'dayjs';
  20. import { useEffect, useMemo, useRef, useState } from 'react';
  21. import Analysis from './Analysis';
  22. import DeviceAnalysis from './components/DeviceAnalysis';
  23. import VideoAnalysis from './components/VideoAnalysis';
  24. import WorkAnalysis from './components/WorkAnalysis';
  25. import styles from './index.less';
  26. const { TabPane } = Tabs;
  27. const icon06 = require('@/assets/smartOps/icon06.png');
  28. const icon07 = require('@/assets/smartOps/icon07.png');
  29. let timer = '';
  30. function SmartOps(props) {
  31. const { list, dispatch, loading, loadingDev, autoReport } = props;
  32. const navigate = useNavigate();
  33. const { projectId } = useParams();
  34. const [searchParams, setSearchParams] = useSearchParams();
  35. const time = searchParams.get('time');
  36. const idList = searchParams.get('idList');
  37. const patrolId = searchParams.get('patrolId');
  38. const [tab, setTab] = useState('1');
  39. const [videoNum, setVideoNum] = useState(0);
  40. const signalRef = useRef();
  41. const {
  42. data: reportData,
  43. loading: reportLoading,
  44. run: getReportData,
  45. } = useRequest(
  46. () =>
  47. getHistoryRecord(
  48. convertObject2FormData({ project_id: Number(projectId) }),
  49. ),
  50. {
  51. manual: true,
  52. formatResult: (res) => {
  53. let data = res.data.list[0];
  54. data.Num2Length = data.Num2.split(',').length;
  55. return data;
  56. },
  57. },
  58. );
  59. const [sTime, eTime] = useMemo(() => {
  60. let sTime = null,
  61. eTime = null;
  62. if (time) {
  63. eTime = time;
  64. sTime = dayjs(eTime).subtract(10, 'minute').format('YYYY-MM-DD HH:mm:ss');
  65. } else if (reportData) {
  66. eTime = reportData.CTime;
  67. sTime = dayjs(eTime).subtract(10, 'minute').format('YYYY-MM-DD HH:mm:ss');
  68. }
  69. return [sTime, eTime];
  70. }, [reportData]);
  71. const initDate = () => {
  72. if (idList || reportData?.Num2) {
  73. //工艺分析
  74. dispatch({
  75. type: 'smartOps/queryList',
  76. payload: {
  77. project_id: projectId * 1,
  78. projectId: projectId * 1,
  79. ids: idList || reportData.Num2,
  80. page_size: 999,
  81. isNewRole: [46, 65, 92, 94].includes(projectId * 1),
  82. },
  83. callback: (data) => {
  84. UnityAction.sendMsg('ProcessAnalysis', JSON.stringify(data?.list));
  85. },
  86. });
  87. }
  88. dispatch({
  89. type: 'eqSelfInspection/getPatrolDataById',
  90. payload: {
  91. routeId: patrolId || reportData.PatrolId,
  92. },
  93. callback: (data) => {
  94. // console.log(data);
  95. const message = data?.extendWarningAllData?.map((item) => {
  96. return {
  97. DeviceCode: item.DeviceCode,
  98. grade_alarm: item.Status === 2 || item.Status === 1 ? 1 : 2,
  99. };
  100. });
  101. UnityAction.sendMsg('DevAnalysis', JSON.stringify(message));
  102. },
  103. });
  104. };
  105. const handlerHistoryClick = () => {
  106. navigate(
  107. `/smart-ops/history-record/${projectId}?JWT-TOKEN=${GetTokenFromUrl()}`,
  108. );
  109. };
  110. const handlerRecordClick = () => {
  111. navigate(
  112. `/smart-ops/operation-record/${projectId}?JWT-TOKEN=${GetTokenFromUrl()}`,
  113. );
  114. };
  115. // 工况分析
  116. const {
  117. data: workAnalysisRequest,
  118. run: runWork,
  119. loading: loadingWork,
  120. } = useRequest(
  121. () =>
  122. queryProjectConfig({
  123. project_id: projectId,
  124. s_time: sTime,
  125. e_time: eTime,
  126. }),
  127. {
  128. manual: true,
  129. onSuccess(res) {
  130. if (!res) return;
  131. UnityAction.sendMsg(
  132. 'WorkAnalysis',
  133. JSON.stringify(res.project_categorys),
  134. );
  135. },
  136. },
  137. );
  138. const optimizationNumber = workAnalysisRequest?.optimizationNumber || 0;
  139. //感知分析
  140. const {
  141. data: videoData,
  142. loading: loadingVideo,
  143. run: runVideo,
  144. } = useRequest(
  145. () =>
  146. getPatrolPerception({
  147. project_id: projectId * 1,
  148. patrol_id: patrolId || reportData.PatrolId,
  149. s_time: sTime,
  150. e_time: eTime,
  151. }),
  152. {
  153. manual: true,
  154. onSuccess: (data) => {
  155. const count1 = data.dumu_list?.length || 0;
  156. const count2 =
  157. data.environment_list?.filter((item) => item.status)?.length || 0;
  158. // const count3 =
  159. // data.fluid_level_list?.filter((item) => item.status)?.length || 0;
  160. setVideoNum(count1 + count2);
  161. const Cam =
  162. data.dumu_list?.map((item) => {
  163. item.key = `dumu_${item.id}`;
  164. return item.device_name;
  165. }) || [];
  166. const Dev =
  167. data.environment_list?.map((item, index) => {
  168. item.key = `environment_${index}_${item.device_code}`;
  169. return { DeviceCode: item.device_code, grade_alarm: item.status };
  170. }) || [];
  171. // const Dev2 =
  172. // data.fluid_level_list?.map((item, index) => {
  173. // item.key = `fluid_${index}_${item.device_code}`;
  174. // return { DeviceCode: item.device_code, grade_alarm: item.status };
  175. // }) || [];
  176. const params = { Cam, Dev };
  177. UnityAction.sendMsg('SensorAnalysis', JSON.stringify(params));
  178. },
  179. },
  180. );
  181. const AnalysisNumber = list?.pagenation?.total || 0;
  182. const deviceNumber = autoReport?.extendWarningData?.length || 0;
  183. // 利润
  184. const { data: profitData, run: getProfit } = useRequest(
  185. () =>
  186. querySimulationProfit({
  187. project_id: projectId,
  188. s_time: dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:00:00'),
  189. e_time: dayjs().format('YYYY-MM-DD HH:00:00'),
  190. }),
  191. {
  192. formatResult(data) {
  193. if (!data?.info) return '-';
  194. return Object.values(data.info).reduce(
  195. (total, currentValue) => total + currentValue,
  196. 0,
  197. );
  198. },
  199. manual: true,
  200. },
  201. );
  202. const showTime = useMemo(() => {
  203. if (!eTime) return '';
  204. return dayjs(eTime).format('MM-DD HH:mm');
  205. }, [eTime]);
  206. const onChangeTab = (type) => {
  207. setTab(type);
  208. UnityAction.sendMsg('SmartAnalysisTab', type);
  209. };
  210. useEffect(() => {
  211. if (!eTime) return;
  212. initDate();
  213. runWork();
  214. runVideo();
  215. getProfit();
  216. }, [eTime]);
  217. useEffect(() => {
  218. if (!time) {
  219. getReportData();
  220. console.log('--------10分钟刷新数据--------', eTime);
  221. timer = setInterval(() => {
  222. getReportData();
  223. }, 60000);
  224. }
  225. dispatch({
  226. type: 'smartOps/queryProcessSection',
  227. payload: projectId,
  228. });
  229. // 通知unity当前处于工况分析
  230. UnityAction.sendMsg('SmartAnalysisTab', 1);
  231. const controller = new AbortController();
  232. signalRef.current = controller;
  233. return () => {
  234. signalRef.current.abort();
  235. clearInterval(timer);
  236. };
  237. }, []);
  238. const lengthCalculate = () => {
  239. return (
  240. autoReport?.extendWarningData?.length +
  241. autoReport?.FluidLevelList?.filter((item) => item.status).length +
  242. autoReport?.DrugFlowList?.filter((item) => item.status)?.length +
  243. autoReport?.WaterInCheckList?.filter((item) => item.status)?.length +
  244. autoReport?.WaterQualityCompareList?.length +
  245. autoReport?.PressureCompareList?.length
  246. );
  247. };
  248. return (
  249. <PageContent closeable>
  250. <PageTitle returnable={time}>智慧运营</PageTitle>
  251. <div className={`card-box ${styles.topContent}`}>
  252. <div className={styles.titleContent}>
  253. <span className={styles.time}>{showTime}</span>
  254. {!time && (
  255. <div style={{ display: 'flex' }}>
  256. <div className={styles.iconLeft} onClick={handlerHistoryClick} />
  257. <div className={styles.iconRight} onClick={handlerRecordClick} />
  258. </div>
  259. )}
  260. </div>
  261. <div className={styles.middle}>
  262. <div className={styles.left}>
  263. <div className={styles.in} />
  264. <div className={styles.out} />
  265. </div>
  266. <div className={styles.right}>
  267. <div className={styles.item1}>
  268. 工况分析:
  269. {optimizationNumber > 0
  270. ? `${optimizationNumber}项可优化`
  271. : '暂无优化'}
  272. </div>
  273. <div className={styles.item2}>
  274. 设备分析:
  275. {lengthCalculate() > 0
  276. ? `${lengthCalculate()}项可优化`
  277. : '暂无优化'}
  278. </div>
  279. <div className={styles.item3}>
  280. 工艺分析:
  281. {list?.pagenation?.total > 0
  282. ? `${list?.pagenation?.total}项可优化`
  283. : '暂无优化'}
  284. </div>
  285. <div className={styles.item4}>
  286. 感知分析:{videoNum > 0 ? `${videoNum}项可优化` : '暂无优化'}
  287. </div>
  288. </div>
  289. </div>
  290. <div className={styles.text}>通过智慧分析预计可省{profitData}元</div>
  291. </div>
  292. <div className={styles.tabContent}>
  293. <TabsContent
  294. defaultActiveKey="1"
  295. small
  296. items={[
  297. {
  298. label: `工况分析(${loadingWork ? '-' : optimizationNumber})`,
  299. key: '1',
  300. children: (
  301. <WorkAnalysis
  302. workAnalysisRequest={workAnalysisRequest}
  303. projectId={projectId}
  304. loading={loadingWork}
  305. eTime={eTime}
  306. />
  307. ),
  308. },
  309. {
  310. label: `设备分析(${loadingDev ? '-' : lengthCalculate()})`,
  311. key: '4',
  312. children: <DeviceAnalysis />,
  313. },
  314. {
  315. label: `工艺分析(${loading ? '-' : AnalysisNumber})`,
  316. key: '2',
  317. children: <Analysis />,
  318. },
  319. {
  320. label: `感知分析(${loadingVideo ? '-' : videoNum})`,
  321. key: '3',
  322. children: (
  323. <VideoAnalysis
  324. videoNum={videoNum}
  325. videoData={videoData}
  326. loading={loadingVideo}
  327. />
  328. ),
  329. },
  330. ]}
  331. onChange={onChangeTab}
  332. />
  333. </div>
  334. </PageContent>
  335. );
  336. }
  337. const convertObject2FormData = (params) => {
  338. const formData = new FormData();
  339. Object.entries(params).forEach(([key, value]) => {
  340. if (value !== null && value !== undefined && value !== NaN) {
  341. formData.append(key, value);
  342. }
  343. });
  344. return formData;
  345. };
  346. export default connect(({ smartOps, eqSelfInspection, loading }) => ({
  347. list: smartOps.list,
  348. loading: loading.models.smartOps,
  349. processList: smartOps.processList,
  350. autoReport: eqSelfInspection.autoReport,
  351. loadingDev: loading.effects['eqSelfInspection/getPatrolDataById'],
  352. }))(SmartOps);