index.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <!--
  2. - Copyright (c) 2018-2025, lengleng All rights reserved.
  3. -
  4. - Redistribution and use in source and binary forms, with or without
  5. - modification, are permitted provided that the following conditions are met:
  6. -
  7. - Redistributions of source code must retain the above copyright notice,
  8. - this list of conditions and the following disclaimer.
  9. - Redistributions in binary form must reproduce the above copyright
  10. - notice, this list of conditions and the following disclaimer in the
  11. - documentation and/or other materials provided with the distribution.
  12. - Neither the name of the pig4cloud.com developer nor the names of its
  13. - contributors may be used to endorse or promote products derived from
  14. - this software without specific prior written permission.
  15. - Author: lengleng (wangiegie@gmail.com)
  16. -->
  17. <template>
  18. <div class="execution">
  19. <div class="filter">
  20. <div class="startTime" style="display: inline-block">
  21. <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;短期、风速日期:</span>
  22. <el-date-picker
  23. value-format="timestamp"
  24. v-model="ycDate"
  25. :clearable="false"
  26. type="date"
  27. placeholder="选择日期">
  28. </el-date-picker>
  29. </div>
  30. <div class="endTime" style="display: inline-block">
  31. <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;超短期日期:</span>
  32. <el-date-picker
  33. value-format="timestamp"
  34. v-model="cdqDate"
  35. :clearable="false"
  36. type="date"
  37. placeholder="选择日期">
  38. </el-date-picker>
  39. </div>
  40. <div class="endTime" style="display: inline-block">
  41. <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;实际功率日期:</span>
  42. <el-date-picker
  43. value-format="timestamp"
  44. v-model="sjDate"
  45. :clearable="false"
  46. type="date"
  47. placeholder="选择日期">
  48. </el-date-picker>
  49. </div>
  50. <div class="endTime" style="display: inline-block">
  51. <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;AGC限电指令日期:</span>
  52. <el-date-picker
  53. value-format="timestamp"
  54. v-model="agcDate"
  55. :clearable="false"
  56. type="date"
  57. placeholder="选择日期">
  58. </el-date-picker>
  59. </div>
  60. <div class="timeQuery" style="display: inline-block">
  61. &#12288;<el-button size="small" :loading="loading" @click="fetchStationData">查询</el-button>
  62. <el-button size="small" :loading="loading" @click="exportDataEvent">导出</el-button>
  63. </div>
  64. </div>
  65. <div class="station-container">
  66. <el-tabs v-model="activeStation" type="card" @tab-click="handleClick">
  67. <el-tab-pane
  68. v-for="(stationData, stationName) in stationMap"
  69. :key="stationName"
  70. :label="stationName"
  71. :name="stationName"
  72. >
  73. </el-tab-pane>
  74. </el-tabs>
  75. <el-table
  76. :data="tableData"
  77. border
  78. style="width: 100%"
  79. :cell-style="{ textAlign: 'center' }"
  80. v-loading="loading"
  81. height="720"
  82. >
  83. <el-table-column header-align="center" prop="time" label="时间" ></el-table-column>
  84. <el-table-column header-align="center" prop="windSpeed" label="风速" ></el-table-column>
  85. <el-table-column header-align="center" prop="shortTerm" label="短期功率预测" ></el-table-column>
  86. <el-table-column header-align="center" prop="ultraShortTerm" label="超短期功率预测" ></el-table-column>
  87. <el-table-column header-align="center" prop="actualPower" label="实际发电" ></el-table-column>
  88. <el-table-column header-align="center" prop="agc" label="AGC指令" ></el-table-column>
  89. </el-table>
  90. </div>
  91. </div>
  92. </template>
  93. <script>
  94. import {mapGetters} from 'vuex'
  95. import * as echarts from 'echarts';
  96. import {
  97. queryCharts
  98. } from '@/api/windtotalpowercontrast'
  99. export default {
  100. name: 'forecastReport',
  101. data() {
  102. return {
  103. activeStation: '', // 当前激活的场站名称
  104. stationMap: {}, // 存储所有场站数据
  105. ycDate: new Date(new Date().toLocaleDateString()).getTime(),
  106. cdqDate: new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000,
  107. sjDate: new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000,
  108. agcDate: new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000,
  109. dynamicColumns: [], // 动态风电场信息,例如: [{ name: '哈斯风电场' }, { name: '千伏苏加风电场' }]
  110. columns: [],
  111. searchForm: {},
  112. tableData: [],
  113. page: {
  114. total: 0, // 总页数
  115. currentPage: 1, // 当前页数
  116. pageSize: 20 // 每页显示多少条
  117. },
  118. total: 0, // 总页数
  119. currentPage: 1, // 当前页数
  120. pageSize: 10, // 每页显示多少条
  121. wsChart:null,
  122. tableLoading: false,
  123. stationCode: '',
  124. stationType:'',
  125. stationList: [],
  126. forecastManufactor: '',
  127. forecastManufactorList: [],
  128. drawData: {datas: [], times: []},
  129. resizeKey: 1,
  130. activeName: 'first',
  131. loading: false,
  132. ultraShortData: [],
  133. shortData: [],
  134. powerStationStatusData: [],
  135. timeStamp: [],
  136. arrays: [],
  137. fromHead: []
  138. }
  139. },
  140. computed: {
  141. ...mapGetters(['permissions']),
  142. },
  143. mounted() {
  144. this.$nextTick(() => {
  145. this.$refs.table.doLayout();
  146. });
  147. },
  148. methods: {
  149. // 获取场站数据
  150. async fetchStationData() {
  151. this.loading = true;
  152. var queryParams = {
  153. ycDate:this.ycDate,
  154. cdqDate:this.cdqDate,
  155. sjDate:this.sjDate,
  156. agcDate:this.agcDate
  157. }
  158. this.$axios.get('/forecastReportController/queryReport',{params: queryParams}).then((res) => {
  159. this.stationMap = res.data.data;
  160. // 设置默认激活第一个场站
  161. const stationNames = Object.keys(this.stationMap);
  162. if (stationNames.length > 0) {
  163. this.activeStation = stationNames[0];
  164. this.tableData = this.stationMap[this.activeStation];
  165. }
  166. })
  167. this.loading = false;
  168. },
  169. queryDataForCharts() {
  170. if (this.startTime==null){
  171. this.$message.warning('请选择开始时间')
  172. return
  173. }
  174. if (this.endTime==null){
  175. this.$message.warning('请选择结束时间')
  176. return
  177. }
  178. const param = new URLSearchParams()
  179. param.append('startTime', this.startTime)
  180. param.append('endTime', this.endTime)
  181. queryCharts(param).then((res) => {
  182. this.drawData = res.data.data
  183. // 保存动态列(风电场名称)
  184. this.dynamicColumns = res.data.data.columns;
  185. // 转换数据为扁平结构
  186. this.tableData = res.data.data.tableData.map((item, rowIndex) => {
  187. const newItem = {
  188. time: item.time,
  189. predictedTotalPower: item.predictedTotalPower,
  190. actualTotalPower: item.actualTotalPower,
  191. };
  192. // 遍历每个风电场,添加预测和实际功率
  193. res.data.data.columns.forEach((site, index) => {
  194. newItem[`site_${index}_pred`] = item[site].predicted;
  195. newItem[`site_${index}_actual`] = item[site].actual;
  196. });
  197. return newItem;
  198. });
  199. // this.tableData = res.data.data.tableData; // 表格数据
  200. this.total = res.data.data.tableData.length
  201. this.dqDraw(this.drawData)
  202. }).catch((error) => {
  203. if (!this.tableLoading) {
  204. this.loading = false
  205. }
  206. console.log(error)
  207. this.$message.error('查询总功率charts出错' + error)
  208. })
  209. },
  210. handleClick(tab, event) {
  211. this.tableData = this.stationMap[tab.name];
  212. console.log(tab.name);
  213. },
  214. exportDataEvent() {
  215. if (this.startTime==null){
  216. this.$message.warning('请选择开始时间')
  217. return
  218. }
  219. if (this.endTime==null){
  220. this.$message.warning('请选择结束时间')
  221. return
  222. }
  223. this.$axios.get("/windtotalpowercontrast/exportDataEvent/" +this.startTime + "/" + this.endTime, {
  224. responseType: 'blob'// 用于解决中文乱码
  225. }).then((response) => {
  226. this.loading = false
  227. }).catch((error) => {
  228. this.loading = false
  229. this.$message.error('导出失败' + error)
  230. })
  231. },
  232. getCapacity(param) {
  233. return new Promise(function (resolve, reject) {
  234. getCapacity(param).then(response => {
  235. resolve(response.data.data)
  236. })
  237. })
  238. },
  239. handlePageChange({currentPage, pageSize}) {
  240. this.currentPage = currentPage;//当前页
  241. this.pageSize = pageSize//每页显示的条数
  242. },
  243. refreshChange() {
  244. // this.getCompositeData()
  245. this.getStationCode()
  246. }
  247. }
  248. }
  249. </script>