energyLeft.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. <template>
  2. <div class="container">
  3. <!-- 标题区域 -->
  4. <div class="title">
  5. <div class="title_text">能耗管理</div>
  6. <div class="title_sub">Energy Management</div>
  7. </div>
  8. <!-- 内容区域 -->
  9. <div class="content">
  10. <div class="sub_title">能耗统计</div>
  11. <!-- 用电量总计区域 -->
  12. <div class="energy_box">
  13. <div class="energy_box_left">
  14. <div class="left_top">
  15. <img src="@/assets/images/energy-left-icon.png" />
  16. 用电量总计(kw.h)
  17. </div>
  18. <div class="left_bottom" ref="eleValueDom">{{ eleValue }}</div>
  19. </div>
  20. <div class="energy_box_right">
  21. <!-- <div class="right_top">增速</div>
  22. <div class="right_bottom">
  23. <div ref="eleSpeedDom">{{ eleSpeed }}</div>
  24. <span>%</span>
  25. </div> -->
  26. </div>
  27. </div>
  28. <!-- 用水量总计区域 -->
  29. <div class="energy_box">
  30. <div class="energy_box_left">
  31. <div class="left_top">
  32. <img src="@/assets/images/energy-left-icon2.png" />
  33. 用水量总计(m³)
  34. </div>
  35. <div class="left_bottom" ref="waterValueDom">{{ waterValue }}</div>
  36. </div>
  37. <div class="energy_box_right">
  38. <!-- <div class="right_top">增速</div>
  39. <div class="right_bottom">
  40. <div ref="waterSpeedDom">{{ waterSpeed }}</div>
  41. <span>%</span>
  42. </div> -->
  43. </div>
  44. </div>
  45. <!-- 平均用量区域 -->
  46. <div class="evenly">
  47. <div class="evenly_box">
  48. <img src="@/assets/images/evenly-box-icon.png" />
  49. <div class="box_right">
  50. <div class="right_top">
  51. <div ref="eleValueAvDom">{{ eleValueAv }}</div>
  52. <span>kw.h</span>
  53. </div>
  54. <div>人均用电量</div>
  55. </div>
  56. </div>
  57. <div class="evenly_box">
  58. <img src="@/assets/images/evenly-box-icon2.png" />
  59. <div class="box_right">
  60. <div class="right_top">
  61. <div ref="waterValueAvDom">{{ waterValueAv }}</div>
  62. <span>m³</span>
  63. </div>
  64. <div>人均用水量</div>
  65. </div>
  66. </div>
  67. </div>
  68. <div class="sub_title">区域能耗统计</div>
  69. <!-- 水电切换按钮区域 -->
  70. <div class="change">
  71. <div
  72. class="button"
  73. :class="currentIndex === '水' ? 'active' : ''"
  74. @click="handleClickWater"
  75. >
  76. </div>
  77. <div
  78. class="button"
  79. :class="currentIndex === '电' ? 'active' : ''"
  80. @click="handleClickEle"
  81. >
  82. </div>
  83. </div>
  84. <!-- 区域能耗统计图表 -->
  85. <div class="bar" ref="barChart"></div>
  86. </div>
  87. </div>
  88. </template>
  89. <script setup lang="ts">
  90. import { ref, onMounted } from "vue";
  91. import * as Echarts from "echarts";
  92. import { countUpNum } from "@/utils/countUpNum";
  93. // 引入能耗管理相关的接口
  94. import {
  95. reqGetEnergyAll,
  96. reqGetEnergyevenly,
  97. reqGetEnergyMonth,
  98. } from "@/api/energy/index";
  99. // 用电总量
  100. const eleValue = ref();
  101. const eleValueDom = ref();
  102. // 用电速率
  103. // const eleSpeed = ref(10.06);
  104. // const eleSpeedDom = ref();
  105. // 用水总量
  106. const waterValue = ref();
  107. const waterValueDom = ref();
  108. // 用水速率
  109. // const waterSpeed = ref(10.06);
  110. // const waterSpeedDom = ref();
  111. // 人均用电量
  112. const eleValueAv = ref(0);
  113. const eleValueAvDom = ref();
  114. // 人均用水量
  115. const waterValueAv = ref(0);
  116. const waterValueAvDom = ref();
  117. // 区域能耗统计图表实例
  118. let myBarChart: any;
  119. // 区域能耗统计图表DOM
  120. const barChart = ref(null);
  121. // 图表x轴数据
  122. const Xdata = ref<any>([]);
  123. // 地点数组
  124. const placeList = ref<any>([]);
  125. // 探问楼数据
  126. const chartData = ref<any>([]);
  127. // 探理楼数据
  128. const chartData2 = ref<any>([]);
  129. // 探学楼数据
  130. const chartData3 = ref<any>([]);
  131. // 默认选中按钮
  132. const currentIndex = ref("水");
  133. onMounted(() => {
  134. // 获取能耗统计(总量)信息
  135. getEnergyAll();
  136. // 能耗统计(平均)信息接口地址
  137. getEnergyevenly();
  138. // 获取区域能耗统计数据
  139. getChartData();
  140. });
  141. // 获取能耗统计(总量)信息
  142. const getEnergyAll = async () => {
  143. const res = await reqGetEnergyAll();
  144. // console.log(res);
  145. if ((res as any).code == 200) {
  146. res.data.forEach((ele: any) => {
  147. if (ele.name === "用电量") {
  148. eleValue.value = ele.num;
  149. }
  150. if (ele.name === "用水量") {
  151. waterValue.value = ele.num;
  152. }
  153. });
  154. // 让数字跳动
  155. countUpNum(eleValueDom.value, eleValue.value, 2);
  156. countUpNum(waterValueDom.value, waterValue.value, 2);
  157. }
  158. };
  159. // 能耗统计(平均)信息接口地址
  160. const getEnergyevenly = async () => {
  161. const res = await reqGetEnergyevenly();
  162. // console.log(res);
  163. if ((res as any).code == 200) {
  164. res.data.forEach((ele: any) => {
  165. if (ele.name === "用电量") {
  166. eleValueAv.value = ele.num;
  167. }
  168. if (ele.name === "用水量") {
  169. waterValueAv.value = ele.num;
  170. }
  171. });
  172. // 让数字跳动
  173. countUpNum(eleValueAvDom.value, eleValueAv.value, 2);
  174. countUpNum(waterValueAvDom.value, waterValueAv.value, 2);
  175. }
  176. };
  177. // 获取区域能耗统计数据
  178. const getChartData = async () => {
  179. const res = await reqGetEnergyMonth({
  180. type: currentIndex.value === "水" ? 0 : 1,
  181. });
  182. // console.log(res);
  183. if ((res as any).code == 200) {
  184. res.data.forEach((ele: any) => {
  185. // 获取图表x轴数据
  186. Xdata.value.push(ele.month.slice(-2) + "月");
  187. // 获取图表Y轴数据
  188. ele.data.forEach((item: any) => {
  189. if (item.name === "探问楼") {
  190. chartData.value.push(item.num);
  191. } else if (item.name === "探理楼") {
  192. chartData2.value.push(item.num);
  193. } else if (item.name === "探学楼") {
  194. chartData3.value.push(item.num);
  195. }
  196. });
  197. });
  198. // 获取地点数组
  199. res.data[0].data.forEach((ele: any) => {
  200. placeList.value.push(ele.name);
  201. });
  202. }
  203. // 初始化区域能耗统计图表
  204. initBarChart();
  205. };
  206. // 点击水 按钮回调
  207. const handleClickWater = () => {
  208. if (currentIndex.value !== "水") {
  209. currentIndex.value = "水";
  210. // 清空数据重新请求
  211. placeList.value = [];
  212. Xdata.value = [];
  213. chartData.value = [];
  214. chartData2.value = [];
  215. chartData3.value = [];
  216. myBarChart.dispose();
  217. getChartData();
  218. }
  219. };
  220. // 点击电 按钮回调
  221. const handleClickEle = () => {
  222. if (currentIndex.value !== "电") {
  223. currentIndex.value = "电";
  224. // 清空数据重新请求
  225. placeList.value = [];
  226. Xdata.value = [];
  227. chartData.value = [];
  228. chartData2.value = [];
  229. chartData3.value = [];
  230. myBarChart.dispose();
  231. getChartData();
  232. }
  233. };
  234. // 初始化区域能耗统计
  235. const initBarChart = () => {
  236. myBarChart = Echarts.init(barChart.value);
  237. // 图表配置
  238. const options = {
  239. tooltip: {
  240. trigger: "axis",
  241. axisPointer: {
  242. type: "shadow",
  243. },
  244. },
  245. legend: {
  246. data: placeList.value,
  247. top: 45,
  248. right: 22,
  249. textStyle: {
  250. color: "#fff",
  251. },
  252. },
  253. color: ["#0A87E8", "#BFA23B", "#09B9DB", "#00BAAD"],
  254. grid: {
  255. top: "28%",
  256. left: "3%",
  257. right: "6%",
  258. bottom: "6%",
  259. containLabel: true,
  260. },
  261. xAxis: [
  262. {
  263. type: "category",
  264. axisTick: { show: false },
  265. axisLabel: {
  266. color: "#fff",
  267. },
  268. data: Xdata.value,
  269. },
  270. ],
  271. yAxis: [
  272. {
  273. type: "value",
  274. name: currentIndex.value === "水" ? "m³" : "kw.h",
  275. nameTextStyle: {
  276. fontSize: 14,
  277. color: "#fff",
  278. },
  279. axisLabel: {
  280. color: "#fff",
  281. },
  282. splitLine: {
  283. show: false,
  284. },
  285. },
  286. ],
  287. series: [
  288. {
  289. name: placeList.value[0],
  290. type: "bar",
  291. barGap: 0,
  292. emphasis: {
  293. focus: "series",
  294. },
  295. data: chartData.value,
  296. },
  297. {
  298. name: placeList.value[1],
  299. type: "bar",
  300. emphasis: {
  301. focus: "series",
  302. },
  303. data: chartData2.value,
  304. },
  305. {
  306. name: placeList.value[2],
  307. type: "bar",
  308. emphasis: {
  309. focus: "series",
  310. },
  311. data: chartData3.value,
  312. },
  313. ],
  314. };
  315. myBarChart.setOption(options);
  316. };
  317. </script>
  318. <style lang="scss" scoped>
  319. .container {
  320. width: 435px;
  321. height: 951px;
  322. color: #fff;
  323. background-image: url(@/assets/images/box-bg.png);
  324. .title {
  325. display: flex;
  326. align-items: center;
  327. width: 430px;
  328. height: 47px;
  329. font-family: "庞门正道标题体";
  330. background-image: url(@/assets/images/title-bg.png);
  331. background-size: 100% 100%;
  332. .title_text {
  333. margin-left: 38px;
  334. font-size: 20px;
  335. text-shadow: 0px 0px 9px #158eff;
  336. }
  337. .title_sub {
  338. margin-left: 19px;
  339. font-size: 12px;
  340. color: #215a8e;
  341. }
  342. }
  343. .content {
  344. padding: 20px 19px 0 14px;
  345. height: 904px;
  346. .sub_title {
  347. padding-left: 28px;
  348. height: 35px;
  349. line-height: 18px;
  350. color: #abd6ff;
  351. font-weight: bold;
  352. background-image: url(@/assets/images/title-bg2.png);
  353. background-size: 100% 100%;
  354. }
  355. .energy_box {
  356. display: flex;
  357. justify-content: space-between;
  358. margin-top: 24px;
  359. padding: 0 30px 0 26px;
  360. width: 100%;
  361. height: 88px;
  362. background-image: url(@/assets/images/energy-box-bg.png);
  363. background-size: 100% 100%;
  364. .energy_box_left {
  365. .left_top {
  366. display: flex;
  367. align-items: center;
  368. margin-top: 9px;
  369. font-size: 16px;
  370. img {
  371. margin-right: 4px;
  372. width: 20px;
  373. height: 20px;
  374. }
  375. }
  376. .left_bottom {
  377. margin-top: 2px;
  378. font-size: 38px;
  379. font-weight: bold;
  380. }
  381. }
  382. .energy_box_right {
  383. min-width: 100px;
  384. .right_top {
  385. margin-top: 22px;
  386. font-size: 14px;
  387. }
  388. .right_bottom {
  389. display: flex;
  390. align-items: flex-end;
  391. margin-top: 2px;
  392. color: #ffd15c;
  393. font-size: 24px;
  394. font-weight: bold;
  395. span {
  396. margin-left: 2px;
  397. font-size: 18px;
  398. }
  399. }
  400. }
  401. }
  402. .evenly {
  403. display: flex;
  404. height: 130px;
  405. .evenly_box {
  406. flex: 1;
  407. display: flex;
  408. align-items: center;
  409. img {
  410. margin-right: 8px;
  411. width: 84px;
  412. height: 48px;
  413. }
  414. .box_right {
  415. font-size: 16px;
  416. .right_top {
  417. display: flex;
  418. align-items: center;
  419. font-weight: bold;
  420. font-size: 24px;
  421. span {
  422. margin-top: 5px;
  423. margin-left: 5px;
  424. font-size: 12px;
  425. font-weight: 400;
  426. }
  427. }
  428. }
  429. }
  430. }
  431. .change {
  432. display: flex;
  433. justify-content: flex-end;
  434. align-items: flex-end;
  435. height: 60px;
  436. .button {
  437. display: flex;
  438. justify-content: center;
  439. align-items: center;
  440. margin-left: 18px;
  441. width: 88px;
  442. height: 32px;
  443. font-size: 14px;
  444. border-radius: 4px;
  445. border: 1px solid #bef4f7;
  446. background-image: linear-gradient(
  447. rgba(156, 255, 248, 0.4),
  448. rgba(152, 217, 237, 0.15),
  449. rgba(188, 216, 247, 0.4)
  450. );
  451. cursor: pointer;
  452. }
  453. .active {
  454. background-image: linear-gradient(
  455. rgba(29, 242, 228, 0.8),
  456. rgba(61, 198, 239, 0.4),
  457. rgba(26, 94, 232, 0.8)
  458. );
  459. }
  460. }
  461. .bar {
  462. height: 398px;
  463. }
  464. }
  465. }
  466. </style>