Browse Source

短期历史对比,中心功率预测导出功能

fanxiaoyu 7 months ago
parent
commit
3ca0aecd56

+ 123 - 18
cpp-admin/src/main/java/com/cpp/web/controller/regulation/DqHistoryContrastController.java

@@ -12,6 +12,7 @@ import com.cpp.web.domain.station.ForecastPowerShortTermRegulation;
 import com.cpp.web.domain.station.PowerStationStatusData;
 import com.cpp.web.domain.station.WeatherStationStatusData;
 import com.cpp.web.dto.DqHistoryContrastDto;
+import com.cpp.web.dto.TableColumn;
 import com.cpp.web.service.station.ElectricFieldService;
 import com.cpp.web.service.station.ForecastPowerShortTermRegulationService;
 import com.cpp.web.service.station.PowerStationStatusDataService;
@@ -19,13 +20,19 @@ import com.cpp.web.service.station.WeatherStationStatusDataService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
 import java.math.BigDecimal;
+import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
@@ -38,6 +45,7 @@ import java.util.*;
  */
 @RestController
 @RequiredArgsConstructor
+@Slf4j
 @RequestMapping("/dqHistoryContrastController")
 public class DqHistoryContrastController {
     @Autowired
@@ -47,6 +55,8 @@ public class DqHistoryContrastController {
     @Autowired
     ForecastPowerShortTermRegulationService forecastPowerShortTermRegulationService;
 
+    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
     @ApiOperation(value = "根据条件查询", notes = "分页查询")
     @GetMapping("/queryTableData")
     public R queryTableData(String stationCode, Long startTime, Long endTime) {
@@ -80,23 +90,23 @@ public class DqHistoryContrastController {
 
 
         for (Long tempTime = startTime; tempTime <= endTime; tempTime = tempTime + momentTime) {
-            xAxisBottomList.add(DateUtils.parseDateToStr("MM-dd HH:mm",new Date(tempTime)));
+            xAxisBottomList.add(DateUtils.parseDateToStr("MM-dd HH:mm", new Date(tempTime)));
             DqHistoryContrastDto dqHistoryContrastDto = new DqHistoryContrastDto();
             dqHistoryContrastDto.setStationName(stationName);
             // 设置时间
-            String time = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm",new Date(tempTime));
+            String time = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm", new Date(tempTime));
             dqHistoryContrastDto.setTime(time);
-            if (sjMap.get(tempTime)!=null){
+            if (sjMap.get(tempTime) != null) {
                 PowerStationStatusData powerStationStatusData = sjMap.get(tempTime);
                 dqHistoryContrastDto.setOpenCapacity(powerStationStatusData.getOpenCapacity().toString());
                 dqHistoryContrastDto.setRealValue(powerStationStatusData.getRealValue().toString());
             }
-            if (dqsbMap.get(tempTime)!=null){
+            if (dqsbMap.get(tempTime) != null) {
                 ForecastPowerShortTermRegulation forecastPowerShortTermRegulation = dqsbMap.get(tempTime);
                 dqHistoryContrastDto.setDqValue(forecastPowerShortTermRegulation.getFpValue().toString());
             }
             // 计算短期与实际功率偏差及偏差比
-            if (StrUtil.isNotBlank(dqHistoryContrastDto.getDqValue()) && StrUtil.isNotBlank(dqHistoryContrastDto.getRealValue())){
+            if (StrUtil.isNotBlank(dqHistoryContrastDto.getDqValue()) && StrUtil.isNotBlank(dqHistoryContrastDto.getRealValue())) {
                 // 偏差(短期-实际功率)
                 BigDecimal dqValue = new BigDecimal(dqHistoryContrastDto.getDqValue());
                 BigDecimal realValue = new BigDecimal(dqHistoryContrastDto.getRealValue());
@@ -104,22 +114,19 @@ public class DqHistoryContrastController {
                 // 先判断实际功率是否为0,为0则偏差比为空
                 BigDecimal ratio = null;
                 String ratioStr = "";
-                if (realValue.compareTo(new BigDecimal("0"))==0){
-                }
-                else{
-                    ratio = dqValue.subtract(realValue).divide(realValue,3,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).stripTrailingZeros();
-                    if (ratio.compareTo(new BigDecimal("0"))>=0){
+                if (realValue.compareTo(new BigDecimal("0")) == 0) {
+                } else {
+                    ratio = dqValue.subtract(realValue).divide(realValue, 3, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).stripTrailingZeros();
+                    if (ratio.compareTo(new BigDecimal("0")) >= 0) {
                         ratioStr = "+" + ratio.toPlainString() + "%";
-                    }
-                    else{
+                    } else {
                         ratioStr = ratio.toPlainString() + "%";
                     }
                 }
                 dqHistoryContrastDto.setDqDeviationRatio(ratioStr);
                 dqpcLineList.add(dqHistoryContrastDto.getDqDeviation());
                 ratioLineList.add(ratio);
-            }
-            else{
+            } else {
                 dqpcLineList.add("");
                 ratioLineList.add("");
                 dqHistoryContrastDto.setDqDeviation("");
@@ -127,12 +134,110 @@ public class DqHistoryContrastController {
             }
             tableList.add(dqHistoryContrastDto);
         }
-        map.put("tableList",tableList);
-        map.put("dqpcLineList",dqpcLineList);
-        map.put("ratioLineList",ratioLineList);
-        map.put("xAxisBottomList",xAxisBottomList);
+        map.put("tableList", tableList);
+        map.put("dqpcLineList", dqpcLineList);
+        map.put("ratioLineList", ratioLineList);
+        map.put("xAxisBottomList", xAxisBottomList);
 
         return R.ok(map);
 
     }
+
+    @GetMapping("/export")
+    public void export(String stationCode, Long startTime, Long endTime, HttpServletResponse response) {
+        BufferedOutputStream bos = null;
+        Map map = new HashMap();
+        try {
+
+            StringBuilder templateContent = new StringBuilder();
+            response.setCharacterEncoding("UTF-8");
+            map = (Map) queryTableData(stationCode, startTime, endTime).getData();
+            List<DqHistoryContrastDto> tableList = (List<DqHistoryContrastDto>) map.get("tableList");
+            List<TableColumn> tableColumns = getTableColumn();
+
+            String header = "";
+            StringBuilder content = new StringBuilder();
+
+            for (TableColumn tableColumn : tableColumns) {
+                header += "\"" + tableColumn.getTitle() + "\",";
+            }
+
+            for (DqHistoryContrastDto dqHistoryContrastDto : tableList) {
+                for (TableColumn tableColumn : tableColumns) {
+                    if ("time".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getTime()+ ",");
+                    }
+                    if ("stationName".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getStationName() + ",");
+                    }
+                    if ("openCapacity".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getOpenCapacity() + ",");
+                    }
+                    if ("realValue".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getRealValue() + ",");
+                    }
+                    if ("dqValue".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getDqValue() + ",");
+                    }
+                    if ("dqDeviation".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getDqDeviation() + ",");
+                    }
+                    if ("dqDeviationRatio".equals(tableColumn.getField())){
+                        content.append(dqHistoryContrastDto.getDqDeviationRatio() + ",");
+                    }
+                }
+                content.append("\r\n");
+            }
+
+            header += "\r\n";
+            templateContent.append(header);
+
+            templateContent.append(content.toString());
+
+            String fileName = "";
+            if (sdf.format(startTime).equals(sdf.format(endTime))) {
+                fileName = sdf.format(startTime) + "短期历史对比" + ".csv";
+            } else {
+                fileName = sdf.format(startTime) + "至" + sdf.format(endTime) + "短期历史对比" + ".csv";
+            }
+
+            response.setContentType("application/x-msdownload;charset=UTF-8");
+            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
+            byte[] templateContentBytes = templateContent.toString().getBytes("UTF-8");
+            bos = new BufferedOutputStream(response.getOutputStream());
+            bos.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
+            bos.write(templateContentBytes);
+            response.flushBuffer();
+
+        } catch (Exception e) {
+            log.error("系统错误:" + e.getMessage(), e);
+            throw new RuntimeException(e);
+        } finally {
+            if (bos != null) {
+                try {
+                    bos.close();
+                } catch (IOException e) {
+                    log.error("系统错误:" + e.getMessage(), e);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * 获取表头
+     *
+     * @return
+     */
+    public List<TableColumn> getTableColumn() {
+        List<TableColumn> tableColumns = new ArrayList<>();
+        tableColumns.add(new TableColumn("time", "时间"));
+        tableColumns.add(new TableColumn("stationName", "场站名称"));
+        tableColumns.add(new TableColumn("openCapacity", "开机容量(MW)"));
+        tableColumns.add(new TableColumn("realValue", "实际功率(MW)"));
+        tableColumns.add(new TableColumn("dqValue", "短期预测功率(MW)"));
+        tableColumns.add(new TableColumn("dqDeviation", "短期预测偏差(MW)"));
+        tableColumns.add(new TableColumn("dqDeviationRatio", "短期预测偏差比(%)"));
+        return tableColumns;
+    }
 }

+ 71 - 4
cpp-admin/src/main/java/com/cpp/web/controller/stationDataQuery/PowerStationStatusDataController.java

@@ -9,22 +9,25 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cpp.common.core.domain.R;
 import com.cpp.system.service.ISysConfigService;
+import com.cpp.web.dto.DqHistoryContrastDto;
+import com.cpp.web.dto.TableColumn;
 import com.cpp.web.service.station.PowerStationStatusDataService;
+import com.cpp.web.service.station.impl.PowerStationStatusDataServiceImpl;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
 import java.net.URLEncoder;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 /**
@@ -35,6 +38,7 @@ import java.util.Map;
  */
 @RestController
 @RequiredArgsConstructor
+@Slf4j
 @RequestMapping("/powerstationstatusdata")
 @Api(value = "powerstationstatusdata", tags = "idp_power_station_status_data管理")
 public class PowerStationStatusDataController {
@@ -42,6 +46,8 @@ public class PowerStationStatusDataController {
     private ISysConfigService configService;
     private final PowerStationStatusDataService powerStationStatusDataService;
 
+    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
     @ApiOperation(value = "通过条件查询", notes = "通过条件查询")
     @GetMapping("/queryDays")
     public R queryDays() {
@@ -69,4 +75,65 @@ public class PowerStationStatusDataController {
                               String stationCode) {
         return R.ok(powerStationStatusDataService.cloudDataQuery(new Date(startTime), new Date(endTime), forecastHowLongAgo, stationCode));
     }
+
+    @GetMapping("/export")
+    public void export(Long startTime, Long endTime, Integer forecastHowLongAgo, String stationCode,HttpServletResponse response){
+        BufferedOutputStream bos = null;
+        Map<String,Object> map = new HashMap();
+        try {
+
+            StringBuilder templateContent = new StringBuilder();
+            response.setCharacterEncoding("UTF-8");
+            map = (Map) cloudDataQuery(startTime, endTime, forecastHowLongAgo,stationCode).getData();
+            List<Map<String,Object>> tableList = (List<Map<String,Object>>) map.get("tableData");
+
+            List<TableColumn> tableColumns = (List<TableColumn>) map.get("tableField");
+
+            String header = "";
+            StringBuilder content = new StringBuilder();
+
+            for (TableColumn tableColumn : tableColumns) {
+                header += "\"" + tableColumn.getTitle() + "\",";
+            }
+            for (Map<String, Object> tableData : tableList) {
+                for (TableColumn tableColumn : tableColumns) {
+                    content.append(tableData.get(tableColumn.getField()) + "," );
+                }
+                content.append("\r\n");
+            }
+
+
+            header += "\r\n";
+            templateContent.append(header);
+
+            templateContent.append(content.toString());
+
+            String fileName = "";
+            if (sdf.format(startTime).equals(sdf.format(endTime))) {
+                fileName = sdf.format(startTime) + "中心功率预测" + ".csv";
+            } else {
+                fileName = sdf.format(startTime) + "至" + sdf.format(endTime) + "中心功率预测" + ".csv";
+            }
+
+            response.setContentType("application/x-msdownload;charset=UTF-8");
+            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
+            byte[] templateContentBytes = templateContent.toString().getBytes("UTF-8");
+            bos = new BufferedOutputStream(response.getOutputStream());
+            bos.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
+            bos.write(templateContentBytes);
+            response.flushBuffer();
+
+        } catch (Exception e) {
+            log.error("系统错误:" + e.getMessage(), e);
+            throw new RuntimeException(e);
+        } finally {
+            if (bos != null) {
+                try {
+                    bos.close();
+                } catch (IOException e) {
+                    log.error("系统错误:" + e.getMessage(), e);
+                }
+            }
+        }
+    }
 }

+ 6 - 5
cpp-admin/src/main/java/com/cpp/web/service/station/impl/PowerStationStatusDataServiceImpl.java

@@ -9,6 +9,7 @@ import com.cpp.system.service.ISysConfigService;
 import com.cpp.web.domain.BaseCppEntity;
 import com.cpp.web.domain.cloud.ForecastPowerShortTermCloud;
 import com.cpp.web.domain.station.*;
+import com.cpp.web.dto.TableColumn;
 import com.cpp.web.mapper.station.PowerStationStatusDataMapper;
 import com.cpp.web.service.cloud.ForecastPowerShortTermCloudService;
 import com.cpp.web.service.cloud.ForecastPowerUltraShortTermCloudService;
@@ -541,23 +542,23 @@ public class PowerStationStatusDataServiceImpl extends ServiceImpl<PowerStationS
 
         ElectricField electricField = electricFieldService.findByStationCode(stationCode);
         String electricFieldType = electricField.getElectricFieldTypeEnum();
-        List<TableFiled> tableFields = new ArrayList<>();
+        List<TableColumn> tableFields = new ArrayList<>();
 
-        tableFields.addAll(Arrays.asList(new TableFiled("时间", "time"), new TableFiled("实际功率", "realPower"), new TableFiled("可用功率", "ablePower"), new TableFiled("理论功率", "theoryPower"), new TableFiled("站端", "fpValue")));
+        tableFields.addAll(Arrays.asList(new TableColumn("time","时间"), new TableColumn("realPower","实际功率"), new TableColumn("ablePower","可用功率"), new TableColumn("theoryPower","理论功率"), new TableColumn("fpValue","站端")));
 
         Map<String, String> forecastModelMap = new HashMap<>();
 
         for (SysDictData sysDictData : DictUtils.getDictCache("forecast_model")) {
             forecastModelMap.put(sysDictData.getDictLabel(), sysDictData.getDictValue());
-            tableFields.add(new TableFiled(sysDictData.getDictLabel(), sysDictData.getDictValue()));
+            tableFields.add(new TableColumn(sysDictData.getDictValue(),sysDictData.getDictLabel()));
         }
 
         Map<Date, List<BaseCppEntity>> enStatusDataMap;
         if (electricFieldType.equals("E1")) {
-            tableFields.add(new TableFiled("总辐射", "globalR"));
+            tableFields.add(new TableColumn("globalR","总辐射"));
             enStatusDataMap = weatherStationStatusDataService.findByBetweenTimeAndStationCode(startTime, endTime, stationCode).stream().collect(Collectors.groupingBy(WeatherStationStatusData::getTime, Collectors.toList()));
         } else {
-            tableFields.add(new TableFiled("轮毂风速", "wsHubHeight"));
+            tableFields.add(new TableColumn("wsHubHeight","轮毂风速"));
             enStatusDataMap = windTowerStatusDataService.findByBetweenTimeAndStationCode(startTime, endTime, stationCode).stream().collect(Collectors.groupingBy(WindTowerStatusData::getTime, Collectors.toList()));
         }
 

+ 29 - 0
cpp-ui/src/views/cloudDataQuery/index.vue

@@ -36,6 +36,8 @@
         <el-form-item>
           <el-button type="primary" style="margin-left: 5px" icon="el-icon-search" @click="dataQuery">查询
           </el-button>
+          <el-button type="primary" style="margin-left: 5px" icon="el-icon-download" @click="exportFile">导出
+          </el-button>
         </el-form-item>
       </el-form>
     </div>
@@ -778,6 +780,33 @@ export default {
         this.loading = false
       })
     },
+    exportFile() {
+      let startTime = Math.round(this.dateTime[0])
+      let endTime = Math.round(this.dateTime[1])
+      if (endTime <= startTime) {
+        this.$message.warning("开始时间不能大于结束时间")
+        return
+      }
+      if (endTime - startTime > 60 * 60 * 24 * 1000 * 15) {
+        this.$message.warning("查询数据不能超过15天!")
+        return
+      }
+      let queryParams = {
+        "stationCode": this.stationCode,
+        "startTime": startTime,
+        "endTime": endTime,
+        "forecastHowLongAgo": this.forecastHowLongAgo
+      }
+
+      this.$axios.get("/powerstationstatusdata/export/", {params: queryParams},{
+        responseType: 'blob'// 用于解决中文乱码
+      }).then((response) => {
+        this.loading = false
+      }).catch((error) => {
+        this.loading = false
+        this.$message.error('导出失败' + error)
+      })
+    },
     async getStationCode() {
       await this.$axios({url: '/electricfield/all', method: 'get'}).then(response => {
         this.stationList = response.data

+ 22 - 7
cpp-ui/src/views/regulation/dqHistoryContrast/index.vue

@@ -300,13 +300,28 @@ export default {
       this.currentPage = currentPage
       this.pageSize = pageSize
     },
-    exportFile(){
-      this.$refs.xTable.exportData({
-        filename: '短期历史对比' + new Date().getTime(),
-        type: 'csv',
-        isHeader: true,
-        isFooter: true,
-        data: this.tableData
+    exportFile() {
+      let startTime = Math.round(this.dateTime[0])
+      let endTime = Math.round(this.dateTime[1]) + 1000 * 60 * 60 * 24 - 1
+
+      if (endTime - startTime > 60 * 60 * 24 * 1000 * 30) {
+        this.$message.warning("最多只能查询30天的数据!")
+        return
+      }
+
+      this.loading = true
+      let queryParams = {
+        "stationCode": this.stationCode,
+        "startTime": startTime,
+        "endTime": endTime,
+      }
+      this.$axios.get("/dqHistoryContrastController/export/", {params: queryParams},{
+        responseType: 'blob'// 用于解决中文乱码
+      }).then((response) => {
+        this.loading = false
+      }).catch((error) => {
+        this.loading = false
+        this.$message.error('导出失败' + error)
       })
     },
     async dataQuery() {