EnergyCostDetail.js 8.5 KB

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