index.js 10 KB

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