Browse Source

新增报表导出列表,没有excel导出呢

xusl 1 day ago
parent
commit
5919a26dfc

+ 10 - 0
ipp-ap/src/router/page/index.js

@@ -53,6 +53,16 @@ export default [
     }],
   },
   {
+    path: '/idp/data/forecastReport',
+    component: Layout,
+    children: [{
+      path: 'index',
+      name: '预测报表导出',
+      component: () =>
+        import ( /* webpackChunkName: "views" */ '@/views/idp/data/forecastReport')
+    }],
+  },
+  {
     path: '/idp/data/forecastpowerdata',
     component: Layout,
     children: [{

+ 14 - 0
ipp-ap/src/router/views/index.js

@@ -121,6 +121,20 @@ export default [
       children: [],
       hasChildren: false,
       icon: "",
+      id: "4078",
+      keepAlive: "0",
+      label: "预测报表导出",
+      menuType: "0",
+      name: "预测报表导出",
+      parentId: "4058",
+      path: "/idp/data/forecastReport/index",
+      permission: "",
+      sort: 1,
+      spread: false
+    },{
+      children: [],
+      hasChildren: false,
+      icon: "",
       id: "4079",
       keepAlive: "0",
       label: "风电总功率预测对比",

+ 262 - 0
ipp-ap/src/views/idp/data/forecastReport/index.vue

@@ -0,0 +1,262 @@
+<!--
+  -    Copyright (c) 2018-2025, lengleng All rights reserved.
+  -
+  - Redistribution and use in source and binary forms, with or without
+  - modification, are permitted provided that the following conditions are met:
+  -
+  - Redistributions of source code must retain the above copyright notice,
+  - this list of conditions and the following disclaimer.
+  - Redistributions in binary form must reproduce the above copyright
+  - notice, this list of conditions and the following disclaimer in the
+  - documentation and/or other materials provided with the distribution.
+  - Neither the name of the pig4cloud.com developer nor the names of its
+  - contributors may be used to endorse or promote products derived from
+  - this software without specific prior written permission.
+  - Author: lengleng (wangiegie@gmail.com)
+  -->
+<template>
+  <div class="execution">
+    <div class="filter">
+      <div class="startTime" style="display: inline-block">
+        <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;短期、风速日期:</span>
+        <el-date-picker
+          value-format="timestamp"
+          v-model="ycDate"
+          :clearable="false"
+          type="date"
+          placeholder="选择日期">
+        </el-date-picker>
+      </div>
+      <div class="endTime" style="display: inline-block">
+        <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;超短期日期:</span>
+        <el-date-picker
+          value-format="timestamp"
+          v-model="cdqDate"
+          :clearable="false"
+          type="date"
+          placeholder="选择日期">
+        </el-date-picker>
+      </div>
+      <div class="endTime" style="display: inline-block">
+        <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;实际功率日期:</span>
+        <el-date-picker
+          value-format="timestamp"
+          v-model="sjDate"
+          :clearable="false"
+          type="date"
+          placeholder="选择日期">
+        </el-date-picker>
+      </div>
+      <div class="endTime" style="display: inline-block">
+        <span class="timeText" style="font-weight: bold;font-size: 14px">&#12288;AGC限电指令日期:</span>
+        <el-date-picker
+          value-format="timestamp"
+          v-model="agcDate"
+          :clearable="false"
+          type="date"
+          placeholder="选择日期">
+        </el-date-picker>
+      </div>
+      <div class="timeQuery" style="display: inline-block">
+        &#12288;<el-button size="small" :loading="loading" @click="fetchStationData">查询</el-button>
+        <el-button size="small" :loading="loading" @click="exportDataEvent">导出</el-button>
+      </div>
+    </div>
+
+    <div class="station-container">
+      <el-tabs v-model="activeStation" type="card" @tab-click="handleClick">
+        <el-tab-pane
+          v-for="(stationData, stationName) in stationMap"
+          :key="stationName"
+          :label="stationName"
+          :name="stationName"
+        >
+        </el-tab-pane>
+      </el-tabs>
+      <el-table
+        :data="tableData"
+        border
+        style="width: 100%"
+        :cell-style="{ textAlign: 'center' }"
+        v-loading="loading"
+        height="720"
+      >
+        <el-table-column header-align="center" prop="time" label="时间" ></el-table-column>
+        <el-table-column header-align="center" prop="windSpeed" label="风速" ></el-table-column>
+        <el-table-column header-align="center" prop="shortTerm" label="短期功率预测" ></el-table-column>
+        <el-table-column header-align="center" prop="ultraShortTerm" label="超短期功率预测" ></el-table-column>
+        <el-table-column header-align="center" prop="actualPower" label="实际发电" ></el-table-column>
+        <el-table-column header-align="center" prop="agc" label="AGC指令" ></el-table-column>
+      </el-table>
+    </div>
+
+
+  </div>
+
+
+</template>
+
+<script>
+import {mapGetters} from 'vuex'
+import * as echarts from 'echarts';
+import {
+  queryCharts
+
+} from '@/api/windtotalpowercontrast'
+export default {
+  name: 'forecastReport',
+  data() {
+    return {
+      activeStation: '', // 当前激活的场站名称
+      stationMap: {},   // 存储所有场站数据
+      ycDate: new Date(new Date().toLocaleDateString()).getTime(),
+      cdqDate: new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000,
+      sjDate: new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000,
+      agcDate: new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000,
+      dynamicColumns: [], // 动态风电场信息,例如: [{ name: '哈斯风电场' }, { name: '千伏苏加风电场' }]
+      columns: [],
+      searchForm: {},
+      tableData: [],
+      page: {
+        total: 0, // 总页数
+        currentPage: 1, // 当前页数
+        pageSize: 20 // 每页显示多少条
+      },
+      total: 0, // 总页数
+      currentPage: 1, // 当前页数
+      pageSize: 10, // 每页显示多少条
+      wsChart:null,
+      tableLoading: false,
+      stationCode: '',
+      stationType:'',
+      stationList: [],
+      forecastManufactor: '',
+      forecastManufactorList: [],
+      drawData: {datas: [], times: []},
+      resizeKey: 1,
+      activeName: 'first',
+      loading: false,
+      ultraShortData: [],
+      shortData: [],
+      powerStationStatusData: [],
+      timeStamp: [],
+      arrays: [],
+      fromHead: []
+    }
+  },
+  computed: {
+    ...mapGetters(['permissions']),
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$refs.table.doLayout();
+    });
+  },
+  methods: {
+    // 获取场站数据
+    async fetchStationData() {
+      this.loading = true;
+      var queryParams = {
+        ycDate:this.ycDate,
+        cdqDate:this.cdqDate,
+        sjDate:this.sjDate,
+        agcDate:this.agcDate
+      }
+      this.$axios.get('/forecastReportController/queryReport',{params: queryParams}).then((res) => {
+        this.stationMap = res.data.data;
+        // 设置默认激活第一个场站
+        const stationNames = Object.keys(this.stationMap);
+        if (stationNames.length > 0) {
+          this.activeStation = stationNames[0];
+          this.tableData = this.stationMap[this.activeStation];
+        }
+      })
+      this.loading = false;
+    },
+    queryDataForCharts() {
+      if (this.startTime==null){
+        this.$message.warning('请选择开始时间')
+        return
+      }
+      if (this.endTime==null){
+        this.$message.warning('请选择结束时间')
+        return
+      }
+      const param = new URLSearchParams()
+      param.append('startTime', this.startTime)
+      param.append('endTime', this.endTime)
+
+      queryCharts(param).then((res) => {
+        this.drawData = res.data.data
+        // 保存动态列(风电场名称)
+        this.dynamicColumns = res.data.data.columns;
+        // 转换数据为扁平结构
+        this.tableData = res.data.data.tableData.map((item, rowIndex) => {
+          const newItem = {
+            time: item.time,
+            predictedTotalPower: item.predictedTotalPower,
+            actualTotalPower: item.actualTotalPower,
+          };
+
+          // 遍历每个风电场,添加预测和实际功率
+          res.data.data.columns.forEach((site, index) => {
+            newItem[`site_${index}_pred`] = item[site].predicted;
+            newItem[`site_${index}_actual`] = item[site].actual;
+          });
+          return newItem;
+        });
+
+        // this.tableData = res.data.data.tableData; // 表格数据
+        this.total = res.data.data.tableData.length
+
+        this.dqDraw(this.drawData)
+      }).catch((error) => {
+        if (!this.tableLoading) {
+          this.loading = false
+        }
+        console.log(error)
+        this.$message.error('查询总功率charts出错' + error)
+      })
+
+    },
+    handleClick(tab, event) {
+      this.tableData = this.stationMap[tab.name];
+      console.log(tab.name);
+    },
+    exportDataEvent() {
+      if (this.startTime==null){
+        this.$message.warning('请选择开始时间')
+        return
+      }
+      if (this.endTime==null){
+        this.$message.warning('请选择结束时间')
+        return
+      }
+      this.$axios.get("/windtotalpowercontrast/exportDataEvent/" +this.startTime + "/" + this.endTime, {
+        responseType: 'blob'// 用于解决中文乱码
+      }).then((response) => {
+        this.loading = false
+      }).catch((error) => {
+        this.loading = false
+        this.$message.error('导出失败' + error)
+      })
+    },
+
+    getCapacity(param) {
+      return new Promise(function (resolve, reject) {
+        getCapacity(param).then(response => {
+          resolve(response.data.data)
+        })
+      })
+    },
+    handlePageChange({currentPage, pageSize}) {
+      this.currentPage = currentPage;//当前页
+      this.pageSize = pageSize//每页显示的条数
+    },
+    refreshChange() {
+      // this.getCompositeData()
+      this.getStationCode()
+    }
+  }
+}
+</script>

+ 56 - 0
ipp-common/ipp-common-data/src/main/java/com/jiayue/ipp/common/data/entity/GridApCommandValue.java

@@ -0,0 +1,56 @@
+package com.jiayue.ipp.common.data.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.jiayue.ipp.common.mybatis.base.BaseDataEntity;
+import com.jiayue.ipp.common.mybatis.base.NotLogicBaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.Digits;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * idp_power_station_status_data
+ *
+ * @author whc
+ * @date 2022-03-18 15:49:20
+ */
+@Data
+@TableName("grid_ap_command_value")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "grid_ap_command_value")
+public class GridApCommandValue <T extends Model<?>> extends Model<T> {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 时间
+     */
+    @ApiModelProperty(value = "时间")
+    private Date time;
+
+    /**
+     * 场站id
+     */
+    @ApiModelProperty(value = "场站id")
+    private String stationId;
+
+    /**
+     * 命令值
+     */
+    @ApiModelProperty(value = "命令值")
+    private BigDecimal commandValue;
+}

+ 248 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/controller/ForecastReportController.java

@@ -0,0 +1,248 @@
+package com.jiayue.ipp.idp.controller;
+
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.jiayue.ipp.common.data.entity.*;
+import com.jiayue.ipp.common.data.entity.an.ReportingRateRecords;
+import com.jiayue.ipp.idp.dto.ForecastReportDto;
+import com.jiayue.ipp.idp.service.*;
+import com.jiayue.ipp.idp.util.DateTimeUtil;
+import com.jiayue.ipp.idp.util.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * idp_wind_tower_status_data
+ *
+ * @author whc
+ * @date 2022-03-18 15:50:05
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/forecastReportController")
+@Api(value = "forecastReportController", tags = "forecastReportController管理")
+public class ForecastReportController {
+    private final SysParameterService sysParameterService;
+    private final ElectricFieldService electricFieldService;
+    private final ForecastPowerShortTermService forecastPowerShortTermService;
+    private final NwpService nwpService;
+    private final ForecastPowerUltraShortTermService forecastPowerUltraShortTermService;
+    private final PowerStationStatusDataService powerStationStatusDataService;
+    private final GridApCommandValueService gridApCommandValueService;
+
+
+
+    @ApiOperation(value = "通过条件查询", notes = "通过条件查询")
+    @GetMapping("/queryReport")
+    public R queryReport(Long ycDate,Long cdqDate,Long sjDate,Long agcDate) throws Exception {
+        Date ycStartTime = new Date(ycDate+1000*60*15);
+        Date ycEndTime = new Date(ycDate+1000*60*1440);
+        // 获取场站短期实时
+        QueryWrapper<ForecastPowerShortTerm> queryWrapper = new QueryWrapper<>();
+        queryWrapper.between("forecast_time", ycStartTime, ycEndTime);
+        List<ForecastPowerShortTerm> forecastPowerShortTermList = forecastPowerShortTermService.list(queryWrapper);
+        // 按照场站编号进行分组
+        Map<String, List<ForecastPowerShortTerm>> stListByStationCodeMap = forecastPowerShortTermList.stream().collect(Collectors.groupingBy(r -> r.getStationCode()));
+
+        // 获取nwp实时
+        QueryWrapper<Nwp> nwpWrapper = new QueryWrapper<>();
+        nwpWrapper.between("pre_time", ycStartTime, ycEndTime);
+        List<Nwp> nwpList = nwpService.list(nwpWrapper);
+        // 按照场站编号进行分组
+        Map<String, List<Nwp>> nwpListByStationCodeMap = nwpList.stream().collect(Collectors.groupingBy(r -> r.getStationCode()));
+
+        // 获取场站超短期实时
+        Date cdqStartTime = new Date(cdqDate+1000*60*15);
+        Date cdqEndTime = new Date(cdqDate+1000*60*1440);
+        QueryWrapper<ForecastPowerUltraShortTerm> cdqWrapper = new QueryWrapper<>();
+        cdqWrapper.between("forecast_time", cdqStartTime, cdqEndTime);
+        List<ForecastPowerUltraShortTerm> cdqList = forecastPowerUltraShortTermService.list(cdqWrapper);
+        // 按照场站编号进行分组
+        Map<String, List<ForecastPowerUltraShortTerm>> cdqListByStationCodeMap = cdqList.stream().collect(Collectors.groupingBy(r -> r.getStationCode()));
+
+        // 获取场站实际功率
+        Date sjStartTime = new Date(sjDate+1000*60*15);
+        Date sjEndTime = new Date(sjDate+1000*60*1440);
+        QueryWrapper<PowerStationStatusData> sjWrapper = new QueryWrapper<>();
+        sjWrapper.between("time", sjStartTime, sjEndTime);
+        List<PowerStationStatusData> sjList = powerStationStatusDataService.list(sjWrapper);
+        // 按照场站编号进行分组
+        Map<String, List<PowerStationStatusData>> sjListByStationCodeMap = sjList.stream().collect(Collectors.groupingBy(r -> r.getStationCode()));
+
+        // 获取agc
+        Date agcStartTime = new Date(agcDate+1000*60*15);
+        Date agcEndTime = new Date(agcDate+1000*60*1440);
+        QueryWrapper<GridApCommandValue> agcWrapper = new QueryWrapper<>();
+        agcWrapper.between("time", agcStartTime, agcEndTime);
+        List<GridApCommandValue> agcList = gridApCommandValueService.list(agcWrapper);
+        // 按照场站编号进行分组
+        Map<String, List<GridApCommandValue>> agcListByStationCodeMap = agcList.stream().collect(Collectors.groupingBy(r -> r.getStationId()));
+
+        List<ElectricField> list = electricFieldService.list();
+        list.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
+        Map<String,List<ForecastReportDto>> resultMap = new HashMap<>();
+        Long momentTime = 15 * 60 * 1000L;
+        for (int i=0;i<list.size();i++){
+            ElectricField electricField = list.get(i);
+            // 提取短期map
+            Map<String, ForecastPowerShortTerm> stListByTimeMap = new HashMap<>();
+            if (stListByStationCodeMap.get(electricField.getStationCode())!=null){
+                List<ForecastPowerShortTerm> forecastPowerShortTerms = stListByStationCodeMap.get(electricField.getStationCode());
+                stListByTimeMap = forecastPowerShortTerms.stream()
+                        .filter(forecast -> electricField.getBelongForecastManufactor().equals(forecast.getForecastManufactor()))
+                        .collect(Collectors.toMap(
+                                myObject -> DateUtil.format(myObject.getForecastTime(),"HH:mm"), // keyMapper,将Date转换为long
+                                myObject -> myObject, // valueMapper,保持原对象
+                                (existing, replacement) -> existing // mergeFunction,处理重复key的情况,这里简单地保留现有的value
+                        ));
+            }
+            // 提取nwp风速
+            Map<String, Nwp> nwpListByTimeMap = new HashMap<>();
+            if (nwpListByStationCodeMap.get(electricField.getStationCode())!=null){
+                List<Nwp> forecastPowerShortTerms = nwpListByStationCodeMap.get(electricField.getStationCode());
+                nwpListByTimeMap = forecastPowerShortTerms.stream()
+                        .filter(forecast -> "SYJY".equals(forecast.getForecastManufactor()))
+                        .collect(Collectors.toMap(
+                                myObject -> DateUtil.format(myObject.getPreTime(),"HH:mm"), // keyMapper,将Date转换为long
+                                myObject -> myObject, // valueMapper,保持原对象
+                                (existing, replacement) -> existing // mergeFunction,处理重复key的情况,这里简单地保留现有的value
+                        ));
+            }
+            // 获取nwp轮毂高度
+            int nwpHubHeight = Integer.parseInt(sysParameterService.getSysParameterAndStationCode("NWP_HubHeight", "100", electricField.getStationCode()));
+            // 提取超短期map
+            Map<String, ForecastPowerUltraShortTerm> cdqListByTimeMap = new HashMap<>();
+            if (cdqListByStationCodeMap.get(electricField.getStationCode())!=null){
+                List<ForecastPowerUltraShortTerm> cdqTerms = cdqListByStationCodeMap.get(electricField.getStationCode());
+                cdqListByTimeMap = cdqTerms.stream()
+                        .filter(forecast -> electricField.getBelongForecastManufactor().equals(forecast.getForecastManufactor()))
+                        .collect(Collectors.toMap(
+                                myObject -> DateUtil.format(myObject.getForecastTime(),"HH:mm"), // keyMapper,将Date转换为long
+                                myObject -> myObject, // valueMapper,保持原对象
+                                (existing, replacement) -> existing // mergeFunction,处理重复key的情况,这里简单地保留现有的value
+                        ));
+            }
+            // 提取实际功率
+            Map<String, PowerStationStatusData> sjListByTimeMap = new HashMap<>();
+            if (sjListByStationCodeMap.get(electricField.getStationCode())!=null){
+                List<PowerStationStatusData> sjTerms = sjListByStationCodeMap.get(electricField.getStationCode());
+                sjListByTimeMap = sjTerms.stream()
+                        .filter(forecast -> electricField.getStationCode().equals(forecast.getStationCode()))
+                        .collect(Collectors.toMap(
+                                myObject -> DateUtil.format(new Date(myObject.getTime().toInstant(ZoneOffset.of("+8")).toEpochMilli()),"HH:mm"), // keyMapper,将Date转换为long
+                                myObject -> myObject, // valueMapper,保持原对象
+                                (existing, replacement) -> existing // mergeFunction,处理重复key的情况,这里简单地保留现有的value
+                        ));
+            }
+            // 提取agc
+            Map<String, GridApCommandValue> agcListByTimeMap = new HashMap<>();
+            if (agcListByStationCodeMap.get(electricField.getStationCode())!=null){
+                List<GridApCommandValue> agcTerms = agcListByStationCodeMap.get(electricField.getStationCode());
+                agcListByTimeMap = agcTerms.stream()
+                        .filter(forecast -> electricField.getStationCode().equals(forecast.getStationId()))
+                        .collect(Collectors.toMap(
+                                myObject -> DateUtil.format(myObject.getTime(),"HH:mm"), // keyMapper,将Date转换为long
+                                myObject -> myObject, // valueMapper,保持原对象
+                                (existing, replacement) -> existing // mergeFunction,处理重复key的情况,这里简单地保留现有的value
+                        ));
+            }
+
+            List<ForecastReportDto> forecastReportDtoList = new ArrayList<>();
+            for (Long tempTime = ycStartTime.getTime(); tempTime <= ycEndTime.getTime(); tempTime = tempTime + momentTime) {
+                ForecastReportDto forecastReportDto = new ForecastReportDto();
+                String timeStr = DateUtil.format(new Date(tempTime),"HH:mm");
+                if (timeStr.equals("00:00")){
+                    forecastReportDto.setTime("24:00");
+                }
+                else{
+                    forecastReportDto.setTime(timeStr);
+                }
+                // 短期
+                if (stListByTimeMap.get(timeStr)!=null){
+                    ForecastPowerShortTerm forecastPowerShortTerm = stListByTimeMap.get(timeStr);
+                    forecastReportDto.setShortTerm(forecastPowerShortTerm.getFpValue());
+                }
+                // 超短期
+                if (cdqListByTimeMap.get(timeStr)!=null){
+                    ForecastPowerUltraShortTerm forecastPowerUltraShortTerm = cdqListByTimeMap.get(timeStr);
+                    forecastReportDto.setUltraShortTerm(forecastPowerUltraShortTerm.getFpValue());
+                }
+                // 实际功率
+                if (sjListByTimeMap.get(timeStr)!=null){
+                    PowerStationStatusData powerStationStatusData = sjListByTimeMap.get(timeStr);
+                    forecastReportDto.setActualPower(powerStationStatusData.getRealValue());
+                }
+                // agc
+                if (agcListByTimeMap.get(timeStr)!=null){
+                    GridApCommandValue gridApCommandValue = agcListByTimeMap.get(timeStr);
+                    forecastReportDto.setAgc(gridApCommandValue.getCommandValue());
+                }
+                // nwp轮毂风速
+                if (nwpListByTimeMap.get(timeStr)!=null){
+                    Nwp nwp = nwpListByTimeMap.get(timeStr);
+                    // 获取nwp轮毂风速
+                    if (nwpHubHeight==170){
+                        forecastReportDto.setWindSpeed(nwp.getWs170());
+                    }
+                    else if (nwpHubHeight==150){
+                        forecastReportDto.setWindSpeed(nwp.getWs150());
+                    }
+                    else if (nwpHubHeight==140){
+                        forecastReportDto.setWindSpeed(nwp.getWs140());
+                    }
+                    else if (nwpHubHeight==130){
+                        forecastReportDto.setWindSpeed(nwp.getWs130());
+                    }
+                    else if (nwpHubHeight==120){
+                        forecastReportDto.setWindSpeed(nwp.getWs120());
+                    }
+                    else if (nwpHubHeight==110){
+                        forecastReportDto.setWindSpeed(nwp.getWs110());
+                    }
+                    else if (nwpHubHeight==100){
+                        forecastReportDto.setWindSpeed(nwp.getWs100());
+                    }
+                    else if (nwpHubHeight==90){
+                        forecastReportDto.setWindSpeed(nwp.getWs90());
+                    }
+                    else if (nwpHubHeight==80){
+                        forecastReportDto.setWindSpeed(nwp.getWs80());
+                    }
+                    else if (nwpHubHeight==70){
+                        forecastReportDto.setWindSpeed(nwp.getWs70());
+                    }
+                    else if (nwpHubHeight==50){
+                        forecastReportDto.setWindSpeed(nwp.getWs50());
+                    }
+                    else if (nwpHubHeight==30){
+                        forecastReportDto.setWindSpeed(nwp.getWs30());
+                    }
+                    else if (nwpHubHeight==10){
+                        forecastReportDto.setWindSpeed(nwp.getWs10());
+                    }
+
+                }
+                forecastReportDtoList.add(forecastReportDto);
+            }
+            resultMap.put(list.get(i).getName(),forecastReportDtoList);
+        }
+        return R.ok(resultMap);
+    }
+}

+ 24 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/dto/ForecastReportDto.java

@@ -0,0 +1,24 @@
+package com.jiayue.ipp.idp.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author jy
+ * @since 2025/07/18
+ */
+@Data
+public class ForecastReportDto {
+    private String time;
+    // 风速
+    private BigDecimal windSpeed;
+    // 短期
+    private BigDecimal shortTerm;
+    // 超短期
+    private BigDecimal ultraShortTerm;
+    // 实际功率
+    private BigDecimal actualPower;
+    // AGC指令
+    private BigDecimal agc;
+}

+ 15 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/mapper/GridApCommandValueMapper.java

@@ -0,0 +1,15 @@
+package com.jiayue.ipp.idp.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.ipp.common.data.entity.GridApCommandValue;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * idp_forecast_power_short_term
+ *
+ * @author whc
+ * @date 2022-03-18 15:48:55
+ */
+@Mapper
+public interface GridApCommandValueMapper extends BaseMapper<GridApCommandValue> {
+}

+ 14 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/service/GridApCommandValueService.java

@@ -0,0 +1,14 @@
+package com.jiayue.ipp.idp.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.ipp.common.data.entity.GridApCommandValue;
+
+
+/**
+ * idp_forecast_power_short_term
+ *
+ * @author whc
+ * @date 2022-03-18 15:48:55
+ */
+public interface GridApCommandValueService extends IService<GridApCommandValue> {
+}

+ 21 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/service/impl/GridApCommandValueServiceImpl.java

@@ -0,0 +1,21 @@
+package com.jiayue.ipp.idp.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.ipp.common.data.entity.GridApCommandValue;
+import com.jiayue.ipp.idp.mapper.GridApCommandValueMapper;
+import com.jiayue.ipp.idp.service.GridApCommandValueService;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * idp_forecast_power_short_term
+ *
+ * @author whc
+ * @date 2022-03-18 15:48:55
+ */
+@Service
+public class GridApCommandValueServiceImpl extends ServiceImpl<GridApCommandValueMapper, GridApCommandValue> implements GridApCommandValueService {
+
+
+
+}