Kaynağa Gözat

短期调控记录明细展示

xusl 6 ay önce
ebeveyn
işleme
a20182779f

+ 74 - 2
cpp-admin/src/main/java/com/cpp/web/controller/regulation/DqRegulationController.java

@@ -22,6 +22,7 @@ import com.cpp.web.domain.regulation.TempShortRegulationDetail;
 import com.cpp.web.domain.regulation.TempShortUsual;
 import com.cpp.web.domain.regulation.TempShortUsualDetail;
 import com.cpp.web.domain.station.ElectricField;
+import com.cpp.web.domain.station.ForecastPowerShortTermRegulation;
 import com.cpp.web.domain.station.ForecastPowerShortTermStation;
 import com.cpp.web.domain.station.InverterStatusData;
 import com.cpp.web.dto.TempShortRegulationDto;
@@ -31,6 +32,7 @@ import com.cpp.web.service.regulation.TempShortRegulationService;
 import com.cpp.web.service.regulation.TempShortUsualDetailService;
 import com.cpp.web.service.regulation.TempShortUsualService;
 import com.cpp.web.service.station.ElectricFieldService;
+import com.cpp.web.service.station.ForecastPowerShortTermRegulationService;
 import com.cpp.web.service.station.ForecastPowerShortTermStationService;
 import com.cpp.web.utils.DateTimeUtil;
 import io.swagger.annotations.ApiOperation;
@@ -70,6 +72,8 @@ public class DqRegulationController {
     ISysConfigService configService;
     @Autowired
     ISysUserService iSysUserService;
+    @Autowired
+    ForecastPowerShortTermRegulationService forecastPowerShortTermRegulationService;
 
 
 
@@ -157,6 +161,7 @@ public class DqRegulationController {
                         refDownList.add(xx);
                     }
 
+
                     if (tempShortRegulationDetailList.isEmpty()){
                         // 使用原始值
                         TempShortRegulationDto tempShortRegulationDto = new TempShortRegulationDto();
@@ -368,9 +373,76 @@ public class DqRegulationController {
             }
             tableList.add(map);
         }
+        return R.ok(tableList);
+    }
 
+    /**
+     * 短期调控记录单行记录的明细参数及曲线图
+     *
+     * @return
+     */
+    @ApiOperation(value = "分页查询", notes = "分页查询")
+    @GetMapping("/getDqRegulationDetail")
+    public R getDqRegulationDetail(String stationCode, String tkDate,String forecastDate) {
+        // 获取明细列表
+        QueryWrapper<TempShortRegulationDetail> tempShortRegulationDetailQueryWrapper = new QueryWrapper<>();
+        tempShortRegulationDetailQueryWrapper.eq("station_code", stationCode);
+        tempShortRegulationDetailQueryWrapper.eq("tk_date", DateUtil.parse(tkDate, "yyyy-MM-dd"));
+        tempShortRegulationDetailQueryWrapper.eq("forecast_date", DateUtil.parse(forecastDate, "yyyy-MM-dd"));
+        List<TempShortRegulationDetail> tempShortRegulationDetailList = tempShortRegulationDetailService.list(tempShortRegulationDetailQueryWrapper);
+        // 定义调控参数列表
+        List<TempShortRegulationDto> detailList = new ArrayList<>();
+        // 定义调控曲线数据
+        List<BigDecimal> tkLineList = new ArrayList<>();
+        // 定义原始曲线数据
+        List<BigDecimal> ysLineList = new ArrayList<>();
+        // 定义上报曲线数据
+        List<BigDecimal> sbLineList = new ArrayList<>();
+        if (tempShortRegulationDetailList.size()>0){
+            // 先按预测时间排序
+            tempShortRegulationDetailList.sort(Comparator.comparing(TempShortRegulationDetail::getTime));
+            for (TempShortRegulationDetail tempShortRegulationDetail:tempShortRegulationDetailList){
+                TempShortRegulationDto tempShortRegulationDto = new TempShortRegulationDto();
+                tempShortRegulationDto.setTime(DateUtils.parseDateToStr("HH:mm",tempShortRegulationDetail.getTime()));
+                tempShortRegulationDto.setForecastDate(tempShortRegulationDetail.getForecastDate());
+                tempShortRegulationDto.setTkDate(tempShortRegulationDetail.getTkDate());
+                tempShortRegulationDto.setYsValue(tempShortRegulationDetail.getYsValue());
+                tempShortRegulationDto.setTkValue(tempShortRegulationDetail.getTkValue());
+                tempShortRegulationDto.setSz(tempShortRegulationDetail.getSz());
+                tempShortRegulationDto.setXs(tempShortRegulationDetail.getXs());
+                tempShortRegulationDto.setStationCode(stationCode);
+                detailList.add(tempShortRegulationDto);
+                // 调控曲线数据封装
+                tkLineList.add(tempShortRegulationDetail.getTkValue());
+                // 原始曲线数据封装
+                ysLineList.add(tempShortRegulationDetail.getYsValue());
+            }
+        }
+        Map<String, Object> map = new HashMap<>();
+        // 弹出框明细列表
+        map.put("detailList",detailList);
+        map.put("tkLineList",tkLineList);
+        map.put("ysLineList",ysLineList);
+        // 获取上报曲线数据
+        long time = DateUtil.parse(forecastDate, "yyyy-MM-dd").getTime();
+        Date startForecastTime = DateTimeUtil.getDayStartTime(time);
+        Date endForecastTime = DateTimeUtil.getDayLastTime(time);
+        int howLongAgo = DateTimeUtil.getDaysBetweenTwoDate(DateUtil.parse(tkDate, "yyyy-MM-dd").getTime(),startForecastTime.getTime());
 
-
-        return R.ok(tableList);
+        QueryWrapper<ForecastPowerShortTermRegulation> forecastPowerShortTermRegulationQueryWrapper = new QueryWrapper<>();
+        forecastPowerShortTermRegulationQueryWrapper.eq("station_code", stationCode);
+        forecastPowerShortTermRegulationQueryWrapper.between("time", startForecastTime,endForecastTime);
+        forecastPowerShortTermRegulationQueryWrapper.eq("forecast_how_long_ago",howLongAgo);
+        List<ForecastPowerShortTermRegulation> forecastPowerShortTermRegulationList = forecastPowerShortTermRegulationService.list(forecastPowerShortTermRegulationQueryWrapper);
+        if (forecastPowerShortTermRegulationList.size()>0){
+            forecastPowerShortTermRegulationList.sort(Comparator.comparing(ForecastPowerShortTermRegulation::getTime));
+            for (ForecastPowerShortTermRegulation forecastPowerShortTermRegulation:forecastPowerShortTermRegulationList){
+                sbLineList.add(forecastPowerShortTermRegulation.getFpValue());
+            }
+        }
+        map.put("sbLineList",sbLineList);
+        ElectricField electricField = electricFieldService.findByStationCode(stationCode);
+        map.put("electricField",electricField);
+        return R.ok(map);
     }
 }

+ 317 - 38
cpp-ui/src/views/regulation/dqRegulationRecord/index.vue

@@ -4,14 +4,14 @@
       <el-form ref="queryForm" size="small" :inline="true" popper-class="cpp-popper">
         <el-form-item label="调控日期">
           <el-date-picker
-            :picker-options="expireDateOption"
-            :clearable="false"
-            v-model="dateTime"
-            type="daterange"
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            popper-class="cpp-popper"
+              :picker-options="expireDateOption"
+              :clearable="false"
+              v-model="dateTime"
+              type="daterange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              popper-class="cpp-popper"
           />
         </el-form-item>
         <el-form-item label="场站名称">
@@ -27,23 +27,23 @@
           >
             <div style="padding: 0 20px; line-height: 34px">
               <el-checkbox
-                v-model="isCheckAll"
-                :indeterminate="isIndeterminate"
-                @change="handleCheckAllChange"
+                  v-model="isCheckAll"
+                  :indeterminate="isIndeterminate"
+                  @change="handleCheckAllChange"
               >所有场站
               </el-checkbox
               >
             </div>
             <el-checkbox-group v-model="biddingStage">
               <el-option
-                v-for="item in options"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
               >
                 <el-checkbox
-                  style="pointer-events: none"
-                  :label="item.value"
+                    style="pointer-events: none"
+                    :label="item.value"
                 >
                   {{ item.label }}
                 </el-checkbox>
@@ -59,16 +59,16 @@
     </div>
     <div style="padding-top: 10px">
       <vxe-table
-        ref="xTable"
-        align="center"
-        class="mytable-style"
-        auto-resize
-        border
-        resizable
-        export-config
-        highlight-current-row
-        show-overflow
-        :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)">
+          ref="xTable"
+          align="center"
+          class="mytable-style"
+          auto-resize
+          border
+          resizable
+          export-config
+          highlight-current-row
+          show-overflow
+          :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)">
         <vxe-table-column field="tkDate" title="调控日期"></vxe-table-column>
         <vxe-table-column field="stationCode" title="调控场站" :formatter="stationCodeFormat"></vxe-table-column>
         <vxe-table-column field="forecastDate" title="上报预测日期"></vxe-table-column>
@@ -82,24 +82,93 @@
         </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"
+          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>
     </div>
+
+
+    <!--  策略选择弹窗     -->
+    <div class="dark-el-dialog">
+      <el-dialog :visible.sync="detailOpen" :before-close="closeDialog" :close-on-click-modal="false" width="60%"
+                 style="height: calc(100% - 200px);">
+
+        <div class="flex">
+          <div style="font-size: 15px;font-weight: bold;">{{this.dialogShowForecastDate}}短期调控策略</div>
+          <div style="margin-left: 100px;font-size: 15px;font-weight: bold;">调控日期: {{this.dialogShowTkDate}}</div>
+        </div>
+        <div class="flex width-100" style="margin-top: 10px">
+          <div style="width: 40%">
+            <el-table
+                :data="detailData"
+                height="550px"
+                size="mini"
+                style="width: 100%">
+              <el-table-column
+                  prop="time"
+                  header-align="center"
+                  align="center"
+                  label="时间"
+              >
+              </el-table-column>
+              <el-table-column
+                  prop="xs"
+                  header-align="center"
+                  align="center"
+                  label="系数">
+              </el-table-column>
+              <el-table-column
+                  prop="sz"
+                  header-align="center"
+                  align="center"
+                  label="数值">
+              </el-table-column>
+              <el-table-column
+                  prop="ysValue"
+                  header-align="center"
+                  align="center"
+                  label="原始值">
+              </el-table-column>
+              <el-table-column
+                  prop="tkValue"
+                  header-align="center"
+                  align="center"
+                  label="调控值"
+              >
+              </el-table-column>
+            </el-table>
+          </div>
+          <div style="width:60%;margin-left: 5px;justify-content: center">
+            <div style="width: 100%;height: 550px" id="tkcharts"></div>
+          </div>
+        </div>
+      </el-dialog>
+    </div>
+
+
   </div>
 </template>
 
 <script>
+import * as echarts from "echarts";
+
 export default {
   name: 'inverterinfo',
   data() {
     return {
+      capacity: '',
+      detailData:[],
+      dialogShowTkDate:'',
+      dialogShowForecastDate:'',
+      selectRow:'',
+      chart: null,
+      detailOpen: false,
       isCheckAll: false, // 是否全选
       isIndeterminate: false, //全选复选框标识
       options: [],
@@ -122,6 +191,143 @@ export default {
       nameList: [],
       loading: false,
       modId: '',//备用id
+      hoursArray: [],
+      chartOption: {
+        backgroundColor: 'transparent',
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          }
+        },
+        legend: {
+          top: 20,
+          icon: 'rect',
+          itemWidth: 14,
+          itemHeight: 5,
+          itemGap: 13,
+          data: ['原始曲线', '调控曲线','上报曲线'],
+          right: '4%',
+          textStyle: {
+            fontSize: 12,
+            // color: this.lineColor
+          },
+          selected: {
+            '原始曲线': true,
+            '调控曲线': true,
+            '上报曲线': true,
+          }
+        },
+        dataZoom: [{
+          show: true,
+          realtime: true,
+          start: 0,
+          end: 100,
+          left: "15%",
+          right: "15%",
+          throttle: 50
+        }, {
+          type: 'inside'
+        }],
+        grid: {
+          top: 100,
+          left: '10%',
+          right: '2%',
+          bottom: '10%',
+          containLabel: true
+        },
+        xAxis: [{
+          type: 'category',
+          boundaryGap: false,
+          axisLine: {onZero: false},
+        }],
+        yAxis: [{
+          type: 'value',
+          name: 'MW',
+          axisTick: {
+            show: false
+          },
+          axisLabel: {
+            margin: 10,
+            textStyle: {
+              fontSize: 14
+            }
+          },
+          splitLine: {
+            lineStyle: {
+              color: '#57617B'
+            }
+          }
+        }],
+        series: [{
+          name: '原始曲线',
+          type: 'line',
+          smooth: true,
+          symbol: 'circle',
+          symbolSize: 5,
+          showSymbol: false,
+          connectNulls: true,
+          lineStyle: {
+            normal: {
+              width: 2
+            }
+          },
+          itemStyle: {
+            normal: {
+              color: 'rgb(219,50,51)',
+              borderWidth: 12
+            }
+          },
+          data: []
+        },
+          {
+            name: '调控曲线',
+            type: 'line',
+            showSymbol: false,
+            smooth: true,
+            symbol: 'circle',
+            symbolSize: 5,
+            connectNulls: true,
+            lineStyle: {
+              normal: {
+                color: 'rgb(0,136,212)',
+                width: 2
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: 'rgb(0,136,212)',
+                borderWidth: 50
+              }
+            },
+            data: []
+          },
+          {
+            name: '上报曲线',
+            type: 'line',
+            showSymbol: false,
+            smooth: true,
+            symbol: 'circle',
+            symbolSize: 5,
+            connectNulls: true,
+            lineStyle: {
+              normal: {
+                color: '#00FF00',
+                width: 2
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: '#00FF00',
+                borderWidth: 50
+              }
+            },
+            data: []
+          },
+        ]
+      }
     }
   },
   created() {
@@ -129,12 +335,60 @@ export default {
     this.getStationCode()
   },
   mounted() {
-    // this.biddingStage = [ '京广高速','京包客专', '京哈高速','崇礼线','京沪高铁','京津城际']
 
-    // this.biddingStage.unshift('全选')
+  },
+  beforeDestroy() {
+    if (!this.chart) {
+      return
+    }
+    this.chart.dispose()
+    this.chart = null
   },
   computed: {},
   methods: {
+    closeDialog(){
+      this.dialogShowForecastDate = ''
+      this.dialogShowTkDate = ''
+      this.hoursArray = []
+      this.detailData = []
+      this.chartOption.series[0].data = []
+      this.chartOption.series[1].data = []
+      this.chartOption.series[2].data = []
+      this.chart.setOption(this.chartOption)
+      this.detailOpen = false
+    },
+    initChart() {
+      // 弹出框上部显示日期
+      this.dialogShowForecastDate = this.selectRow.forecastDate
+      this.dialogShowTkDate = this.selectRow.tkDate
+      // 设置x轴时间
+      for (let i = 0; i < 24 * 60; i += 15) {
+        let hours = Math.floor(i / 60);
+        let minutes = i % 60;
+        this.hoursArray.push(`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`);
+      }
+      this.chartOption.xAxis[0].data = this.hoursArray
+      // 调用后端获取曲线数据和列表调控参数数据
+      let queryParams = {
+        "stationCode": this.selectRow.stationCode,
+        "tkDate": this.selectRow.tkDate,
+        "forecastDate": this.selectRow.forecastDate,
+      }
+
+      this.$axios.get('/dqRegulationController/getDqRegulationDetail', {params: queryParams}).then(response => {
+        this.detailData = response.data.detailList
+        this.chartOption.series[0].data = response.data.ysLineList
+        this.chartOption.series[1].data = response.data.tkLineList
+        this.chartOption.series[2].data = response.data.sbLineList
+        this.chartOption.yAxis[0].max = response.data.electricField.capacity
+        if (!this.chart) {
+          this.chart = echarts.init(document.getElementById('tkcharts'), 'dark')
+        }
+
+        this.chart.setOption(this.chartOption)
+      }).catch(() => {
+      });
+    },
     // 下拉框选择事件
     handleSelect(value) {
       const arr1 = this.options.filter((item) => {
@@ -169,7 +423,12 @@ export default {
     },
 
     jumpCamera(row) {
-      console.log(row)
+      this.detailOpen = true
+      const _this = this
+      this.$nextTick(() => {
+        _this.selectRow = row
+        _this.initChart()
+      })
     },
     beforeQuery() {
       if (this.biddingStage.length == 0) {
@@ -230,7 +489,7 @@ export default {
           }
           this.biddingStage.unshift('所有场站')
           this.isCheckAll = true
-
+          this.dataQuery()
         }
       })
     },
@@ -250,7 +509,27 @@ export default {
 /deep/ .el-select-dropdown.is-multiple .el-select-dropdown__item.selected {
   background-color: transparent !important;
 }
+
 /deep/ .el-checkbox__input.is-checked + .el-checkbox__label {
   color: #cddef1 !important;
 }
+
+
+.divTable {
+  position: relative;
+  top: 30px; /* 向下移动15px */
+  width: 30px;
+  text-align: center
+}
+
+.divDescribe {
+  position: relative;
+  top: 20px; /* 向下移动15px */
+  width: 100%;
+  text-align: center
+}
+
+.width-100 {
+  width: 100%;
+}
 </style>