EnergyCostDetail.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // 能耗详情
  2. import ChartModule from '@/components/ManagementPage/chartModule';
  3. import PageContent from '@/components/PageContent';
  4. import PageTitle from '@/components/PageTitle';
  5. import {
  6. queryAccumulativeEnergy,
  7. queryChartList,
  8. queryEnergyConfig,
  9. queryEnergyWaterChart,
  10. } from '@/services/OperationManagement';
  11. import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
  12. import { useParams, useRequest } from '@umijs/max';
  13. import { Spin } from 'antd';
  14. import dayjs from 'dayjs';
  15. import { useMemo } from 'react';
  16. import styles from './manage.less';
  17. const EnergyCostDetail = () => {
  18. return (
  19. <PageContent closeable={false}>
  20. <PageTitle returnable>能耗数据</PageTitle>
  21. <EnergyDetail />
  22. </PageContent>
  23. );
  24. };
  25. export default EnergyCostDetail;
  26. export const EnergyDetail = () => {
  27. const { projectId } = useParams();
  28. const TIMER = 3600000;
  29. // 全场概况
  30. const { data: allFactoryData, loading: allFacLoading } = useRequest(
  31. queryEnergyConfig,
  32. {
  33. defaultParams: [projectId],
  34. pollingInterval: TIMER,
  35. },
  36. );
  37. // 当日累计能耗、吨水电耗、环比
  38. const { data: energyData, loading: energyLoading } = useRequest(
  39. queryAccumulativeEnergy,
  40. {
  41. defaultParams: [projectId],
  42. pollingInterval: TIMER,
  43. },
  44. );
  45. // 吨水电耗折线图
  46. const { data: chartData, loading: chartLosding } = useRequest(
  47. queryEnergyWaterChart,
  48. {
  49. defaultParams: [
  50. {
  51. project_id: Number(projectId),
  52. start_time: dayjs().startOf('day').format('YYYY-MM-DD 00:00:00'),
  53. end_time: dayjs().format('YYYY-MM-DD 23:59:59'),
  54. },
  55. ],
  56. pollingInterval: TIMER,
  57. formatResult(data) {
  58. const tempData = data.data;
  59. if (!tempData) {
  60. return null;
  61. }
  62. return {
  63. xData: tempData?.map((item) => item.data_time) || [],
  64. dataList: [
  65. {
  66. type: 0,
  67. name: '吨水电耗',
  68. data: tempData?.map((item) => item.value) || [],
  69. },
  70. ],
  71. };
  72. },
  73. },
  74. );
  75. // 电量折线图
  76. const { data: electricChartData, loading: electricLosding } = useRequest(
  77. () =>
  78. queryChartList({
  79. project_id: Number(projectId),
  80. metric_code: 'plant_electricity',
  81. start_time: dayjs().startOf('day').format('YYYY-MM-DD 00:00:00'),
  82. end_time: dayjs().format('YYYY-MM-DD 23:59:59'),
  83. }),
  84. {
  85. pollingInterval: TIMER,
  86. formatResult(data) {
  87. if (!data?.data) return null;
  88. const tempData = data.data;
  89. const reversedData = tempData.reverse();
  90. return {
  91. xData: reversedData?.map((item) => item.data_time) || [],
  92. dataList: [
  93. {
  94. type: 2,
  95. name: '实际',
  96. data: reversedData?.map((item) => item.value) || [],
  97. },
  98. ],
  99. };
  100. },
  101. },
  102. );
  103. // 全场概况 包括两个折线图的y 轴名称
  104. const allFactory = useMemo(() => {
  105. const data = allFactoryData || {
  106. voltage: '-',
  107. transformer: '-',
  108. capacity: '-',
  109. runtime_capacity: '-',
  110. voltage_unit: 'kV',
  111. transformer_unit: '台',
  112. capacity_unit: 'kVA',
  113. runtime_capacity_unit: 'kVA',
  114. energy_unit: 'kWh/t',
  115. energy_water_unit: 'kWh',
  116. };
  117. return [
  118. {
  119. title: '电量等级',
  120. data: data.voltage,
  121. unit: data.voltage_unit,
  122. color: '#eb0ce2',
  123. },
  124. {
  125. title: '变压器台数',
  126. data: data.transformer,
  127. unit: data.transformer_unit,
  128. color: '#eb8c0c',
  129. },
  130. {
  131. title: '装机容器',
  132. data: data.capacity,
  133. unit: data.capacity_unit,
  134. color: '#0cafeb',
  135. },
  136. {
  137. title: '运行容器',
  138. data: data.runtime_capacity,
  139. unit: data.runtime_capacity_unit,
  140. color: '#50bb0a',
  141. },
  142. ];
  143. }, [allFactoryData]);
  144. const powerData = useMemo(() => {
  145. const power = energyData || {
  146. energy_change: '-',
  147. energy_water_change: '-',
  148. today_energy: '-',
  149. today_energy_water: '-',
  150. yesterday_energy: '-',
  151. yesterday_energy_water: '-',
  152. };
  153. return [
  154. {
  155. title: '当日吨水电耗',
  156. data:
  157. typeof power.today_energy_water == 'string'
  158. ? power.today_energy_water
  159. : power.today_energy_water?.toFixed(2),
  160. unit: 'kWh/t',
  161. color: '#eb0ce2',
  162. },
  163. {
  164. title: '昨日吨水电耗',
  165. data:
  166. typeof power.yesterday_energy_water == 'string'
  167. ? power.yesterday_energy_water
  168. : power.yesterday_energy_water?.toFixed(2),
  169. unit: 'kWh/t',
  170. color: '#eb8c0c',
  171. },
  172. {
  173. title: '环比增长',
  174. data:
  175. typeof power.energy_water_change == 'string'
  176. ? power.energy_water_change
  177. : power.energy_water_change?.toFixed(2),
  178. unit: '%',
  179. icon: power.energy_water_change >= 0 ? 1 : 2,
  180. },
  181. {
  182. title: '当日用电',
  183. data: power.today_energy,
  184. unit: 'kWh',
  185. color: '#eb0ce2',
  186. },
  187. {
  188. title: '昨日用电',
  189. data: power.yesterday_energy,
  190. unit: 'kWh',
  191. color: '#eb8c0c',
  192. },
  193. {
  194. title: '环比增长',
  195. data:
  196. typeof power.energy_change == 'string'
  197. ? power.energy_change
  198. : power.energy_change?.toFixed(2),
  199. unit: '%',
  200. icon: power.energy_change >= 0 ? 1 : 2,
  201. },
  202. ];
  203. }, [energyData]);
  204. const loading = useMemo(() => allFacLoading, [allFacLoading]);
  205. return (
  206. <Spin spinning={loading}>
  207. <div className={styles.infoContainer}>
  208. <div>
  209. <SubTitle title="全厂概览" />
  210. <div style={{ display: 'flex' }}>
  211. {allFactory.map((item, index) => (
  212. <DataCard key={`all_${index}`} {...item} type={4} />
  213. ))}
  214. </div>
  215. </div>
  216. <div>
  217. <SubTitle title="用电概况" />
  218. <div style={{ display: 'flex', flexWrap: 'wrap' }}>
  219. {powerData.map((item, index) => (
  220. <DataCard key={`power_${index}`} {...item} type={3} />
  221. ))}
  222. </div>
  223. </div>
  224. <div>
  225. <SubTitle title="吨水电耗" />
  226. <div style={{ height: '3rem' }}>
  227. {chartData && allFactoryData && (
  228. <ChartModule
  229. yName={allFactoryData?.energy_water_unit || 'kWh'}
  230. xData={chartData.xData}
  231. dataList={chartData.dataList}
  232. />
  233. )}
  234. </div>
  235. </div>
  236. <div>
  237. <SubTitle title="电量" />
  238. <div style={{ height: '3rem' }}>
  239. {electricChartData && allFactoryData && (
  240. <ChartModule
  241. yName={allFactoryData?.energy_unit || 'kWh/t'}
  242. xData={electricChartData.xData}
  243. dataList={electricChartData.dataList}
  244. />
  245. )}
  246. </div>
  247. </div>
  248. </div>
  249. </Spin>
  250. );
  251. };
  252. const DataCard = ({ title, data, unit, icon, color, type }) => {
  253. const width = Math.floor(100 / type - 2) + '%';
  254. return (
  255. <div style={{ width }} className={`${styles.itemContent} card-box`}>
  256. <div style={{ fontSize: '0.26rem' }}>{title}</div>
  257. <div style={{ position: 'relative' }}>
  258. <span
  259. style={{ color: !icon ? color : icon === 1 ? 'red' : '#50bb0a' }}
  260. className={styles.data}
  261. >
  262. {data}
  263. </span>
  264. {unit}
  265. {icon === 1 && (
  266. <ArrowUpOutlined
  267. style={{
  268. height: '0.2rem',
  269. color: 'red',
  270. position: 'absolute',
  271. fontSize: '0.34rem',
  272. right: '0.4rem',
  273. }}
  274. />
  275. )}
  276. {icon === 2 && (
  277. <ArrowDownOutlined
  278. style={{
  279. height: '0.2rem',
  280. color: '#50bb0a',
  281. position: 'absolute',
  282. fontSize: '0.36rem',
  283. right: '0.4rem',
  284. }}
  285. />
  286. )}
  287. </div>
  288. </div>
  289. );
  290. };
  291. const SubTitle = ({ title }) => {
  292. return (
  293. <div
  294. style={{
  295. display: 'flex',
  296. justifyContent: 'flex-start',
  297. alignItems: 'center',
  298. marginBottom: '0.2rem',
  299. fontSize: '0.28rem',
  300. fontWeight: '600',
  301. }}
  302. >
  303. <div
  304. style={{
  305. width: '0.15rem',
  306. height: '0.15rem',
  307. background: '#0139f1',
  308. marginRight: '0.1rem',
  309. borderRadius: '0.16rem',
  310. }}
  311. />
  312. {title}
  313. </div>
  314. );
  315. };