Kaynağa Gözat

新增集中侧全量预测统计曲线

xusl 11 ay önce
ebeveyn
işleme
a62ea1ebe3

+ 8 - 0
ipp-ap/src/api/forecastpowerultrashortterm.js

@@ -117,3 +117,11 @@ export function putObj(obj) {
     data: obj
   })
 }
+
+export function getCenterData(obj) {
+  return request({
+    url: '/powerstationstatusdata/getCenterData',
+    method: 'post',
+    data: obj
+  })
+}

+ 36 - 0
ipp-ap/src/api/windforecast.js

@@ -0,0 +1,36 @@
+/*
+ *    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)
+ */
+
+import request from '@/router/axios'
+
+
+export function getCompositeData(obj) {
+  return request({
+    url: '/powerstationstatusdata/getCompositeData',
+    method: 'post',
+    data: obj
+  })
+}
+
+export function getTimeStamp(obj) {
+  return request({
+    url: '/powerstationstatusdata/getTimeStamp',
+    method: 'post',
+    data: obj
+  })
+}
+

+ 21 - 1
ipp-ap/src/router/page/index.js

@@ -23,11 +23,31 @@ export default [
     }
   },
   {
+    path: '/idp/center/windforecast',
+    component: Layout,
+    children: [{
+      path: 'index',
+      name: '风电集中预测',
+      component: () =>
+        import ( /* webpackChunkName: "views" */ '@/views/idp/center/windforecast')
+    }],
+  },
+  {
+    path: '/idp/center/gfforecast',
+    component: Layout,
+    children: [{
+      path: 'index',
+      name: '光伏集中预测',
+      component: () =>
+        import ( /* webpackChunkName: "views" */ '@/views/idp/center/gfforecast')
+    }],
+  },
+  {
     path: '/idp/data/forecastpowerdata',
     component: Layout,
     children: [{
       path: 'index',
-      name: '预测数据查询',
+      name: '预测数据对比',
       component: () =>
         import ( /* webpackChunkName: "views" */ '@/views/idp/data/forecastpowerdata')
     }],

+ 105 - 2
ipp-ap/src/router/views/index.js

@@ -4,6 +4,109 @@ export default [
   {
     hasChildren: true,
     icon: "icon-wenjianguanli",
+    id: "3666",
+    keepAlive: "0",
+    label: "中心侧集中预测",
+    menuType: "0",
+    name: "中心侧集中预测",
+    parentId: "-1",
+    path: "/idp/center",
+    permission: null,
+    sort: 20,
+    spread: false,
+    children: [
+      {
+        children: [],
+        hasChildren: false,
+        icon: "icon-bangzhushouji",
+        id: "3111",
+        keepAlive: null,
+        label: "风电集中预测",
+        menuType: "0",
+        name: "风电集中预测",
+        parentId: "3666",
+        path: "/idp/center/windforecast/index",
+        permission: "",
+        sort: 31,
+        spread: false
+      },
+      {
+        children: [],
+        hasChildren: false,
+        icon: "icon-bangzhushouji",
+        id: "3112",
+        keepAlive: null,
+        label: "光伏集中预测",
+        menuType: "0",
+        name: "光伏集中预测",
+        parentId: "3666",
+        path: "/idp/center/gfforecast/index",
+        permission: "",
+        sort: 32,
+        spread: false
+      },
+    ]
+  },
+  {
+    hasChildren: true,
+    icon: "icon-anniu_weixincaidanlianjie",
+    id: "4241",
+    keepAlive: "0",
+    label: "文件解析",
+    menuType: "0",
+    name: "文件解析",
+    parentId: "-1",
+    path: "/an",
+    permission: null,
+    sort: 7,
+    spread: false,
+    children: [{
+      children: [],
+      hasChildren: false,
+      icon: "",
+      id: "4242",
+      keepAlive: "0",
+      label: "解析通道",
+      menuType: "0",
+      name: "解析通道",
+      parentId: "4241",
+      path: "/an/parsingChannel/index",
+      permission: null,
+      sort: 3,
+      spread: false
+    }, {
+      children: [],
+      hasChildren: false,
+      icon: "",
+      id: "4243",
+      keepAlive: "0",
+      label: "解析配置",
+      menuType: "0",
+      name: "解析配置",
+      parentId: "4241",
+      path: "/an/PFParsing/index",
+      permission: null,
+      sort: 3,
+      spread: false
+    }, {
+      children: [],
+      hasChildren: false,
+      icon: "",
+      id: "4244",
+      keepAlive: "0",
+      label: "文件解析记录",
+      menuType: "0",
+      name: "文件解析记录",
+      parentId: "4241",
+      path: "/idp/control/parsingLog/index",
+      permission: "",
+      sort: 3,
+      spread: false
+    }]
+  },
+  {
+    hasChildren: true,
+    icon: "icon-wenjianguanli",
     id: "4058",
     keepAlive: "0",
     label: "数据查询",
@@ -20,9 +123,9 @@ export default [
       icon: "",
       id: "4080",
       keepAlive: "0",
-      label: "预测数据查询",
+      label: "预测数据对比",
       menuType: "0",
-      name: "预测数据查询",
+      name: "预测数据对比",
       parentId: "4058",
       path: "/idp/data/forecastpowerdata/index",
       permission: "",

+ 0 - 0
ipp-ap/src/views/idp/center/gfforecast/index.vue


+ 258 - 0
ipp-ap/src/views/idp/center/windforecast/index.vue

@@ -0,0 +1,258 @@
+<!--
+  -    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
+          v-model="startTime"
+          :clearable="false"
+          type="datetime"
+          value-format="timestamp"
+          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
+          v-model="endTime"
+          :clearable="false"
+          type="datetime"
+          value-format="timestamp"
+          placeholder="选择日期">
+        </el-date-picker>
+      </div>
+      <div class="timeQuery" style="display: inline-block">
+        &#12288;<el-button size="small" :loading="loading" @click="getCenterData">查询</el-button>
+      </div>
+    </div>
+    <el-tabs type="card" v-model="activeName">
+      <el-tab-pane label="图表" name="first">
+        <div style="width: 100%; height: calc(80vh - 50px)" id="echarts"></div>
+      </el-tab-pane>
+      <el-tab-pane label="表格" name="second">
+        <vxe-table
+          align="center"
+          :loading="loading"
+          ref="xTable"
+          auto-resize
+          border
+          resizable
+          highlight-current-row
+          show-overflow
+          :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
+        >
+          <vxe-table-column
+            v-for="(item, index) in fromHead"
+            :key="index"
+            align="center"
+            :title="item.label"
+            :field="item.field"
+          ></vxe-table-column>
+
+        </vxe-table>
+        <vxe-pager
+          perfect
+          :current-page.sync="currentPage"
+          :page-size.sync="pageSize"
+          :total="total"
+          :page-sizes=[10,50,100]
+          :layouts="['PrevJump', 'PrevPage','JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']"
+          @page-change="handlePageChange"
+        >
+        </vxe-pager>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import {
+
+  getCenterData
+} from '@/api/forecastpowerultrashortterm'
+import {tableOption} from '@/const/crud/forecastpowerultrashortterm'
+import {mapGetters} from 'vuex'
+import * as echarts from 'echarts';
+import cc from '../../../curvecolors'
+
+export default {
+  name: 'centerforecast',
+  data() {
+    return {
+      searchForm: {},
+      tableData: [],
+      total: 0, // 总页数
+      currentPage: 1, // 当前页数
+      pageSize: 10, // 每页显示多少条
+      tableLoading: false,
+      tableOption: tableOption,
+      startTime: new Date(new Date().toLocaleDateString()).getTime(),
+      endTime: new Date(new Date().toLocaleDateString()).getTime() + 60 * 60 * 24 * 1000 - 1,
+      drawData: {datas: [], times: []},
+      resizeKey: 1,
+      activeName: 'first',
+      loading: false,
+      ultraShortData: [],
+      shortData: [],
+      timeStamp: [],
+      arrays: [],
+      fromHead: []
+    }
+  },
+  computed: {
+    ...mapGetters(['permissions']),
+  },
+  mounted() {
+    // this.getForecastManufactor(this.page)
+    // this.draw()
+  },
+  methods: {
+    draw(timeaxis, shortPower, ultraShortPower) {
+      this.arrays = []
+      this.arrays.push({
+        name: '短期',
+        type: 'line',
+        smooth: true,
+        showSymbol:false,
+        symbolSize: 5,
+        data: shortPower,
+        itemStyle: {
+          color: 'red'
+        }
+      });
+      this.arrays.push({
+        name: '超短期',
+        type: 'line',
+        smooth: true,
+        showSymbol:false,
+        symbolSize: 5,
+        data: ultraShortPower,
+        itemStyle: {
+          color: '#FFD700'
+        }
+      });
+      let _this = this
+
+      this.chart = echarts.init(document.getElementById('echarts'))
+      const option = {
+        backgroundColor: 'transparent',
+        title: {
+          top: 20,
+          text: '风电集中预测',
+          textStyle: {
+            fontWeight: 'normal',
+            fontSize: 16,
+            color: '#040606'
+          },
+          left: '1%'
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            animation:false,
+            lineStyle: {
+              color: '#040606'
+            }
+          }
+        },
+        legend: {
+          top: 20,
+          icon: 'rect',
+          itemWidth: 14,
+          itemHeight: 5,
+          itemGap: 13,
+          // data: ['实际功率', '短期数据', '超短期数据'],
+          right: '4%',
+          textStyle: {
+            fontSize: 12
+          }
+        },
+        dataZoom: [
+          {
+            startValue: ''
+          },
+          {
+            type: 'inside'
+          }],
+        grid: {
+          top: 100,
+          left: '2%',
+          right: '2%',
+          bottom: '10%',
+          containLabel: true
+        },
+        xAxis: [{
+          type: 'category',
+          boundaryGap: true,
+          axisLine: {
+            lineStyle: {
+              color: '#040606'
+            }
+          },
+          data: timeaxis
+        }],
+        yAxis: [{
+          type: 'value',
+          name: '(MW)',
+          // max:totalcap,
+          min:0,
+          axisTick: {
+            show: false
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#040606'
+            }
+          },
+          axisLabel: {
+            textStyle: {
+              fontSize: 14
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          }
+        }],
+        series: this.arrays
+      };
+      this.chart.setOption(option, true)
+    },
+    getCenterData() {
+      const param = new URLSearchParams()
+      param.append('startTime', this.startTime)
+      param.append('endTime', this.endTime)
+      getCenterData(param).then(response => {
+          this.fromHead = response.data.data.fromHead
+          this.tableData = response.data.data.tableList
+          this.total = response.data.data.tableList.length
+          this.draw(response.data.data.time, response.data.data.dq, response.data.data.cdq)
+      })
+    },
+    handlePageChange({currentPage, pageSize}) {
+      this.currentPage = currentPage;//当前页
+      this.pageSize = pageSize//每页显示的条数
+    },
+
+    refreshChange() {
+    }
+  }
+}
+</script>

+ 6 - 1
ipp-idp/src/main/java/com/jiayue/ipp/idp/controller/PowerStationStatusDataController.java

@@ -86,5 +86,10 @@ public class PowerStationStatusDataController {
             Integer dqPoint) {
         return R.ok(powerStationStatusDataService.getCompositeData(stationCode, new Date(startTime), new Date(endTime), forecastManufactor, cdqPoint,dqPoint));
     }
-
+    @PostMapping("/getCenterData")
+    public R getCenterData(
+            Long startTime,
+            Long endTime) {
+        return R.ok(powerStationStatusDataService.getCenterData(new Date(startTime), new Date(endTime)));
+    }
 }

+ 1 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/service/PowerStationStatusDataService.java

@@ -31,6 +31,7 @@ public interface PowerStationStatusDataService extends IService<PowerStationStat
     List<ArrayList<String>> timeStamp(Date startTime, Date endTime) throws ParseException;
 
     Map<String, List> getCompositeData(String stationCode, Date startTime, Date endTime, String forecastManufactor, Integer cdqPoint, Integer dqPoint);
+    Map<String, List> getCenterData(Date startTime, Date endTime);
 
     List<PowerStationStatusData> findByTimeBetweenAndStationCode(Date pointStarTime, Date pointEndTime, String stationCode);
 }

+ 96 - 0
ipp-idp/src/main/java/com/jiayue/ipp/idp/service/impl/PowerStationStatusDataServiceImpl.java

@@ -8,6 +8,7 @@ import com.jiayue.ipp.idp.mapper.PowerStationStatusDataMapper;
 import com.jiayue.ipp.idp.service.*;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.ZoneOffset;
@@ -498,4 +499,99 @@ public class PowerStationStatusDataServiceImpl extends ServiceImpl<PowerStationS
         }
         return baseMapper.selectList(wrapper);
     }
+
+
+    /**
+     * 中心侧预测数据统计,查询短期、超短期实时表厂家是SYJY的,每个点位值累加一起展示
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    public Map<String, List> getCenterData(Date startTime, Date endTime) {
+        Long startDateTime = startTime.getTime();
+        Long endDateTime = endTime.getTime();
+
+        // 封装列表头信息
+        List headList = new ArrayList();
+        Map<String,String> timeHeadMap = new HashMap<>();
+        timeHeadMap.put("field", "time");
+        timeHeadMap.put("label", "时间");
+        headList.add(timeHeadMap);
+        Map<String,String> dqHeadMap = new HashMap<>();
+        dqHeadMap.put("field", "dq");
+        dqHeadMap.put("label", "短期(MW)");
+        headList.add(dqHeadMap);
+        Map<String,String> cdqHeadMap = new HashMap<>();
+        cdqHeadMap.put("field", "cdq");
+        cdqHeadMap.put("label", "超短期(MW)");
+        headList.add(cdqHeadMap);
+
+        // 获取短期数据SYJY
+        QueryWrapper<ForecastPowerShortTerm> wrapper = new QueryWrapper<>();
+        wrapper.eq("forecast_manufactor","SYJY");
+        wrapper.between("forecast_time", startTime, endTime);
+        List<ForecastPowerShortTerm> forecastPowerShortTermList = forecastPowerShortTermService.list(wrapper);
+        Map<Long, List<ForecastPowerShortTerm>> shortGroupMap = forecastPowerShortTermList.stream().collect(Collectors.groupingBy(s->s.getForecastTime().getTime()));
+
+        // 获取超短期数据SYJY
+        QueryWrapper<ForecastPowerUltraShortTerm> ultrawrapper = new QueryWrapper<>();
+        ultrawrapper.eq("forecast_manufactor","SYJY");
+        ultrawrapper.between("forecast_time", startTime, endTime);
+        List<ForecastPowerUltraShortTerm> forecastPowerUltraShortTermList = forecastPowerUltraShortTermService.list(ultrawrapper);
+        Map<Long, List<ForecastPowerUltraShortTerm>> ultraGroupMap = forecastPowerUltraShortTermList.stream().collect(Collectors.groupingBy(s->s.getForecastTime().getTime()));
+
+        List<String> timeList = new ArrayList<>();
+        List<String> dqList = new ArrayList();
+        List<String> cdqList = new ArrayList();
+
+        List<Map<String,Object>> tableList = new ArrayList();
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        int i=0;
+        for (Long tempDateTime = startDateTime; tempDateTime < endDateTime; tempDateTime = tempDateTime + 15 * 60 * 1000) {
+            // 封装时间轴list
+            String time = format.format(tempDateTime);
+            timeList.add(time);
+            // 封装列表的数据
+            Map<String,Object> map1 = new HashMap<>();
+            map1.put("time", DateUtil.format(new Date(tempDateTime), "yyyy-MM-dd HH:mm"));
+            // 短期数据求和
+            BigDecimal dqBigDecimal = new BigDecimal(0);
+            if (shortGroupMap.get(tempDateTime)!=null){
+                List<ForecastPowerShortTerm> forecastPowerShortTermList1 = shortGroupMap.get(tempDateTime);
+                for (ForecastPowerShortTerm forecastPowerShortTerm:forecastPowerShortTermList1){
+                    dqBigDecimal = dqBigDecimal.add(forecastPowerShortTerm.getFpValue());
+                }
+                map1.put("dq",dqBigDecimal.toString());
+            }
+            else{
+                map1.put("dq",0);
+            }
+            dqList.add(dqBigDecimal.toString());
+
+            // 超短期数据求和
+            BigDecimal cdqBigDecimal = new BigDecimal(0);
+            if (ultraGroupMap.get(tempDateTime)!=null){
+                List<ForecastPowerUltraShortTerm> forecastPowerUltraShortTermList1 = ultraGroupMap.get(tempDateTime);
+                for (ForecastPowerUltraShortTerm forecastPowerUltraShortTerm:forecastPowerUltraShortTermList1){
+                    cdqBigDecimal = cdqBigDecimal.add(forecastPowerUltraShortTerm.getFpValue());
+                }
+                map1.put("cdq",cdqBigDecimal.toString());
+            }
+            else{
+                map1.put("cdq",0);
+            }
+            cdqList.add(cdqBigDecimal.toString());
+
+            tableList.add(map1);
+        }
+
+        Map<String, List> map = new HashMap<>();
+        map.put("dq", dqList);
+        map.put("cdq", cdqList);
+        map.put("time", timeList);
+        map.put("fromHead", headList);
+        map.put("tableList", tableList);
+
+        return map;
+    }
 }