Преглед на файлове

实时nwp页面增加对比曲线,增加参数配置页面

songhaodong преди 2 години
родител
ревизия
0caebf07cc
променени са 33 файла, в които са добавени 3489 реда и са изтрити 13 реда
  1. 36 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/CutOutSpeedSpecifyInfo.java
  2. 49 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/FanUnitInfo.java
  3. 16 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/PowerMeteoforce1.java
  4. 36 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/WindSpeedPointInfo.java
  5. 25 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/WindTurbinePowerCurve.java
  6. 12 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/CutOutSpeedSpecifyInfoRepository.java
  7. 12 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/FanUnitInfoRepository.java
  8. 2 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/NwpRepository.java
  9. 20 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/WindSpeedPointInfoRepository.java
  10. 14 0
      ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/WindTurbinePowerCurveRepository.java
  11. 7 0
      ipfcst/ipfcst-console/pom.xml
  12. 3 3
      ipfcst/ipfcst-console/src/main/frontend/views/console/overHaulPlan/index.vue
  13. 500 0
      ipfcst/ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/job/UploadFileMatoushanJob.java
  14. 2 0
      ipfcst/ipfcst-reportquery/src/main/frontend/router/index.js
  15. 54 0
      ipfcst/ipfcst-reportquery/src/main/frontend/router/modules/parameterConfiguration.js
  16. 234 0
      ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/CutOutSpeedSpecifyInfo/index.vue
  17. 280 0
      ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/FanUnitInfo/index.vue
  18. 338 0
      ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/WindSpeedPointInfo/index.vue
  19. 248 0
      ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/WindTurbinePowerCurve/index.vue
  20. 247 0
      ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/windSpeedPointInfo1/index.vue
  21. 276 8
      ipfcst/ipfcst-reportquery/src/main/frontend/views/realTimeQuery/nwp/charts/index.vue
  22. 2 1
      ipfcst/ipfcst-reportquery/src/main/frontend/views/realTimeQuery/nwp/index.vue
  23. 67 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/CutOutSpeedSpecifyInfoController.java
  24. 68 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/FanUnitInfoController.java
  25. 89 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/ReadToMysqlController.java
  26. 93 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/WindSpeedPointInfoServiceController.java
  27. 78 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/WindTurbinePowerCurveController.java
  28. 104 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/CutOutSpeedSpecifyInfoService.java
  29. 115 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/FanUnitInfoService.java
  30. 130 1
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/NwpService.java
  31. 176 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/WindSpeedPointInfoService.java
  32. 141 0
      ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/WindTurbinePowerCurveService.java
  33. 15 0
      ipfcst/ipfcst-reportquery/src/main/resources/db.setting

+ 36 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/CutOutSpeedSpecifyInfo.java

@@ -0,0 +1,36 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * 切出停机风速范围 特殊发电功率
+ * 所属机组属性
+ *
+ * @author shd
+ * @since 2022-05-31
+ */
+@Data
+@Entity
+public class CutOutSpeedSpecifyInfo {
+    /**
+     * id
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "id")
+    private int id;
+    //发电风速下限
+    @Column
+    private float lowerWindSpeedLimit;
+    //发电风速上限
+    @Column
+    private float highWindSpeedLimit;
+    //发电功率 MW
+    @Column
+    private float powerGeneration;
+    //所属机组
+    @Column
+    private int UnitBelongs;
+
+}

+ 49 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/FanUnitInfo.java

@@ -0,0 +1,49 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.List;
+
+/**
+ * 机组信息
+ *
+ * @author shd
+ * @since 2022-05-31
+ */
+@Data
+@Entity
+public class FanUnitInfo {
+
+    /**
+     * 机组ID
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "id")
+    @Column
+    private int id;
+    //机组品牌名称
+    @Column
+    private String fanName;
+    //机组容量 KW
+    @Column
+    private float fanUnitCapacity;
+    //满发风速
+    @Column
+    private float fullWindSpeed;
+    //切出风速
+    @Column
+    private float cutOutSpeed;
+    //基准风机
+    @Column
+    private String benchmarkFan;
+    //风机编号组
+    @Column
+    private String fanNumArrs;
+
+    //切出风速参数
+    @OneToMany(fetch = FetchType.EAGER)
+    private List<CutOutSpeedSpecifyInfo> cutOutSpeedSpecifyInfos;
+
+}
+

+ 16 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/PowerMeteoforce1.java

@@ -0,0 +1,16 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+public class PowerMeteoforce1 {
+    private Float cForecast;
+    private String cFarmId;
+    private Date cTime;
+    private Float nwpSpeed;
+
+}

+ 36 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/WindSpeedPointInfo.java

@@ -0,0 +1,36 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * 风速点表信息
+ *
+ * @author shd
+ * @since 2022-06-01
+ */
+@Data
+@Entity
+public class WindSpeedPointInfo {
+
+    //ID
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "id")
+    private int id;
+    //风机编号
+    @Column
+    private String fanNumber;
+    //风向
+    @Column
+    private int wind;
+    //风速
+    @Column
+    private float speed;
+    //所属机组
+    @Column
+    private int UnitBelongs;
+    //所属行
+    @Column
+    private int belong;
+}

+ 25 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/WindTurbinePowerCurve.java

@@ -0,0 +1,25 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * 风机曲线
+ *
+ * @author shd
+ * @since 2022-06-01
+ */
+@Data
+@Entity
+public class WindTurbinePowerCurve {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "id")
+    private int id;
+    @Column
+    private float speed;
+    @Column
+    private float power;
+    @Column
+    private int fanId;
+}

+ 12 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/CutOutSpeedSpecifyInfoRepository.java

@@ -0,0 +1,12 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.CutOutSpeedSpecifyInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+/**
+ * @author shd
+ * @since 2022-05-31
+ */
+public interface CutOutSpeedSpecifyInfoRepository extends JpaRepository<CutOutSpeedSpecifyInfo, Integer>, JpaSpecificationExecutor<CutOutSpeedSpecifyInfo> {
+}

+ 12 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/FanUnitInfoRepository.java

@@ -0,0 +1,12 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.FanUnitInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+/**
+ * @author shd
+ * @since 2022-05-31
+ */
+public interface FanUnitInfoRepository extends JpaRepository<FanUnitInfo, Integer>, JpaSpecificationExecutor<FanUnitInfo> {
+}

+ 2 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/NwpRepository.java

@@ -22,4 +22,6 @@ public interface NwpRepository extends BaseRepository<Nwp, Integer> {
 	 * @param endTime
 	 */
 	List<Nwp> findByPreTimeBetween(Long startTime, Long endTime);
+
+	List<Nwp> findByFarmIdAndPreTimeBetween(String farmId, Long todayStart, Long todayEnd);
 }

+ 20 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/WindSpeedPointInfoRepository.java

@@ -0,0 +1,20 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.WindSpeedPointInfo;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.lang.Nullable;
+
+import java.util.List;
+
+/**
+ * @author shd
+ * @since 2022-06-01
+ */
+public interface WindSpeedPointInfoRepository extends JpaRepository<WindSpeedPointInfo, Integer>, JpaSpecificationExecutor<WindSpeedPointInfo> {
+    Page<WindSpeedPointInfo> findBySpeedContaining(float speed, Pageable pageable);
+
+}

+ 14 - 0
ipfcst/ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/WindTurbinePowerCurveRepository.java

@@ -0,0 +1,14 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.WindTurbinePowerCurve;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+import java.util.List;
+
+/**
+ * @author shd
+ * @since 2022-06-01
+ */
+public interface WindTurbinePowerCurveRepository extends JpaRepository<WindTurbinePowerCurve, Integer>, JpaSpecificationExecutor<WindTurbinePowerCurve> {
+}

+ 7 - 0
ipfcst/ipfcst-console/pom.xml

@@ -224,6 +224,13 @@
       <version>1.5</version>
     </dependency>
 
+    <!--文件存储服务器-->
+    <!-- https://mvnrepository.com/artifact/io.minio/minio -->
+    <dependency>
+      <groupId>io.minio</groupId>
+      <artifactId>minio</artifactId>
+      <version>7.0.2</version>
+    </dependency>
 
 
   </dependencies>

+ 3 - 3
ipfcst/ipfcst-console/src/main/frontend/views/console/overHaulPlan/index.vue

@@ -53,7 +53,7 @@
           :edit-config="{trigger: 'manual', mode: 'row',autoClear: false,icon:'none'}"
         >
           <vxe-table-column title="检修计划信息">
-            <vxe-table-column field="name" title="检修名称"
+            <vxe-table-column field="name" title="风机编号"
                               :edit-render="{name:'$input',attrs:{type:'text'}}"></vxe-table-column>
             <vxe-table-column field="describe" title="描述"
                               :edit-render="{name:'$input',attrs:{type:'text'}}"></vxe-table-column>
@@ -92,8 +92,8 @@
             <!--                              :edit-render="{}">-->
             <!--              <template v-slot="{ row }">{{ timestampToTime(row.finalEntryTime) }}</template>-->
             <!--            </vxe-table-column>-->
-            <vxe-table-column field="overhaulCapactity" title="检修容量(Mw)"
-                              :edit-render="{name:'$input',attrs:{type:'text'}}"></vxe-table-column>
+<!--            <vxe-table-column field="overhaulCapactity" title="检修容量(Mw)"-->
+<!--                              :edit-render="{name:'$input',attrs:{type:'text'}}"></vxe-table-column>-->
             <vxe-table-column field="status" title="计划状态">
               <template v-slot="{ row }">{{ row.status == 2 ? '已停止' : '执行中' }}</template>
             </vxe-table-column>

+ 500 - 0
ipfcst/ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/job/UploadFileMatoushanJob.java

@@ -0,0 +1,500 @@
+package com.jiayue.ipfcst.fileupload.job;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.poi.excel.ExcelReader;
+import cn.hutool.poi.excel.ExcelUtil;
+import com.jiayue.ipfcst.common.core.util.DateTimeUtil;
+import com.jiayue.ipfcst.common.data.entity.*;
+import com.jiayue.ipfcst.common.data.repository.*;
+import com.jiayue.ipfcst.console.service.NwpService;
+import com.jiayue.ipfcst.fileupload.util.UtilTools;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.util.unit.DataUnit;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author shd
+ * @since 2022-06-02
+ */
+@Service
+@Slf4j
+public class UploadFileMatoushanJob {
+  @Autowired
+  NwpRepository nwpRepository;
+  @Autowired
+  FanUnitInfoRepository fanUnitInfoRepository;
+  @Autowired
+  WindTurbinePowerCurveRepository windTurbinePowerCurveRepository;
+  @Autowired
+  CutOutSpeedSpecifyInfoRepository cutOutSpeedSpecifyInfoRepository;
+  @Autowired
+  WindSpeedPointInfoRepository windSpeedPointInfoRepository;
+  @Autowired
+  OverhaulPlanRepository overhaulPlanRepository;
+  //模板风机为key,其它风机id及风速为value
+  public static Map<String, List<String>> moduleFanMaps = new HashMap<>();
+  public static Map<String, FanUnitInfo> fanInfoMap = new HashMap<>();
+  public static List<String> fanIdList = new ArrayList<>();
+  public static List<OverhaulPlan> overhaulInfos = new ArrayList<>();
+  public static Map<String,Map<Float,Float>> windTurbinePowerCurveMaps = new HashMap<>();
+  //模板机ID
+  public static String modleFanId = "";
+
+  public static int dayNum = 16;
+
+  public static String stationCodeStr = "J00307";
+  //模板配置文件路径
+  public static String modleParamFilePath = "/usr/local/singleFan/单风机法模板-all.xlsx";
+
+  public static String overHaulFilePath = "/usr/local/singleFan/风机检修计划.xlsx";
+
+  /**
+   * 每天凌晨5点30执行  现场每日7点20开始执行文件生成定时任务
+   *
+   * 马头山查询nwp数据生成短期预测文件
+   */
+  //@Scheduled(fixedRate = 1000*60)
+  @Scheduled(cron = "30 30 5 * * ?")
+  public void createDqFile()  {
+    log.info("时间 【" + DateTimeUtil.dateToStrLong(new Date()) + "】 马头山短期文件生成开始");
+    //1.读取本地Excel配置
+    readExcelForParams();
+    //2.查询mongodb中的nwp数据
+    List<Nwp> listTemperature = getNwpDatasFromMongodb();
+    //3.计算短期预测
+    List<PowerMeteoforce1> powerMeteoforces = caculateDqs(listTemperature);
+    //4.生成短期文件并上传minio,向v3请求文件记录写入
+    fileCreate(powerMeteoforces,stationCodeStr,"马头山风电场");
+
+    log.info("时间 【" + DateTimeUtil.dateToStrLong(new Date()) + "】 马头山短期文件生成完成");
+
+
+  }
+
+  /**
+   * 读取excel中配置参数
+   */
+  private void readExcelForParams() {
+    List<FanUnitInfo> fanUnitInfoList = readFanUnitInfo(); //机组信息读取
+    //读取风速点表到缓存map中
+    readWindTurbinePowerCurveMap();
+
+    //整理风机编码及信息
+    for (FanUnitInfo fanUnitInfo:fanUnitInfoList
+    ) {
+      String[] fanarrs = fanUnitInfo.getFanNumArrs().split("\\|");
+      for (String fan: fanarrs) {
+        fanIdList.add(fan);//风机编号list
+        fanInfoMap.put(fan,fanUnitInfo);//风机编号为key的风机信息数据
+      }
+    }
+
+
+
+
+
+
+
+
+    //读取以14号风机为基准的风速点表
+    readerSpeedSheet();
+
+    //读取检修计划参数
+    readerOverhual();
+  }
+
+  /**
+   * 查询nwp未来15天的数据
+   * @return
+   */
+  private List<Nwp>  getNwpDatasFromMongodb() {
+    long startTimes = UtilTools.getMillisecondsSubDay();
+    long endTimes = startTimes + dayNum * 24 * 60 * 60 * 1000 - 15 * 60 * 1000;
+    List<Nwp> listTemperature = nwpRepository.findByFarmIdAndPreTimeBetween(stationCodeStr, startTimes, endTimes);
+    //排序后根据预测时间过滤
+    listTemperature = listTemperature.stream().sorted(Comparator.comparing(Nwp::getPreTime)).filter(distinctByKey(Nwp::getPreTime)).collect(Collectors.toList());
+    return listTemperature;
+  }
+
+
+
+
+  /**
+   * 根据nwp的风速计算短期数据
+   * @param listTemperature
+   */
+  private List<PowerMeteoforce1> caculateDqs(List<Nwp> listTemperature) {
+
+    List<PowerMeteoforce1> powerMeteoforces = new ArrayList<>();
+    for (Nwp nwp: listTemperature) {
+
+      Float speed = Convert.toFloat(nwp.getWs30().setScale(1, RoundingMode.HALF_UP));
+
+      //风速小于3米每秒不发电
+      if(speed<3f) {
+        continue;
+      }
+      //判断风速象限,不同风向获取不同风速列表
+      String fengxiangId = "1"; //东北风/西北风
+
+      Float wind = Convert.toFloat(nwp.getWd30());
+      if(90<= wind && wind<180){
+        fengxiangId = "2";//东南风
+      }else if(180<= wind && wind<270){
+        fengxiangId = "3";//西南风
+      }
+      //累加对应的所有风机功率值
+      Float totalPower = 0f;
+
+      //剔除检修风机
+      Map<String,List<String>>  removeOverhaulFansMaps =  removeOverhaulFans(fanIdList,new Date(nwp.getPreTime()));
+      //根据风向+风机模板id配置+风速 获取当前风速对应的其它风机应该有的风速list
+      List<String> fanKeys = removeOverhaulFansMaps.get(fengxiangId + "-" + modleFanId + "-" + speed);
+      for (String fanKey : fanKeys) {
+        //切出风机ID查询风机具体配置信息
+        FanUnitInfo fanInfo = fanInfoMap.get(fanKey.split("-")[0]);
+        //当前风速小于满发,查询点表发电功率
+        if (speed < fanInfo.getFullWindSpeed()) {
+          //根据风机曲线点表获取功率值
+          totalPower += windTurbinePowerCurveMaps.get(fanInfo.getId() + "").get(Convert.toFloat(fanKey.split("-")[1]));
+        } else if (speed > fanInfo.getCutOutSpeed()) {
+          //风速大于切出,发电为0
+        } else {
+          //在满发和切出之间,看具体机组信息和风速
+          for (CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo : fanInfo.getCutOutSpeedSpecifyInfos()
+          ) {
+            if (speed >= cutOutSpeedSpecifyInfo.getLowerWindSpeedLimit()
+              && speed < cutOutSpeedSpecifyInfo.getHighWindSpeedLimit()) {
+              //当前风速的发电功率
+              totalPower += cutOutSpeedSpecifyInfo.getPowerGeneration();
+            }
+          }
+        }
+      }
+      PowerMeteoforce1 powerMeteoforce1 = new PowerMeteoforce1();
+      powerMeteoforce1.setCFarmId(stationCodeStr);
+      powerMeteoforce1.setCTime(new Date(nwp.getPreTime()));
+      powerMeteoforce1.setCForecast(Convert.toFloat(NumberUtil.round(totalPower/1000,2)));
+      //powerMeteoforce1.setCForecast(totalPower);
+      powerMeteoforce1.setNwpSpeed(speed);
+      powerMeteoforces.add(powerMeteoforce1);
+    }
+    return powerMeteoforces;
+  }
+
+
+  public void fileCreate(List<PowerMeteoforce1> powerMeteoforces,String stationCode,String stationName) {
+    VelocityEngine ve = new VelocityEngine();
+    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
+    ve.setProperty("input.encoding", "UTF-8");
+    ve.setProperty("output.encoding", "UTF-8");
+    try {
+      ve.init();
+      Template dq = ve.getTemplate("DQ.vm");
+      String toDay = DateUtil.today();
+      String localPath = UtilTools.judeDirExists(UtilTools.getCreateFilePath() + stationCode+ File.separatorChar);
+      VelocityContext ctx;
+      String fileNameHouZui = UtilTools.getTimeShort() + "0.RB";
+
+      List<ForecastPowerShortTerm> listShort = getFormNwpsData(powerMeteoforces);
+      //排序后根据预测时间过滤
+      listShort = listShort.stream().sorted(Comparator.comparing(ForecastPowerShortTerm::getForecastTime)).filter(distinctByKey(ForecastPowerShortTerm::getForecastTime)).collect(Collectors.toList());
+
+      if (listShort.size() > 0) {
+        listShort = getDataDQ(listShort, Long.valueOf(dayNum),stationCode);
+        //生成短期文件
+        ctx = new VelocityContext();
+
+        ctx.put("entity", stationName);
+        ctx.put("date", toDay);
+        ctx.put("vList", listShort);
+
+        String fileName = "DQ_" + toDay.replaceAll("-", "") + fileNameHouZui;
+        UtilTools.merge(dq, ctx, localPath + fileName);//本地化模型文件格式DQ_201808080000000.RB
+        log.debug(toDay + "---------文件生成位置:" + localPath + fileName + "---------------");
+        File fileTemp = new File(localPath + fileName);
+        UtilTools.uploadFile(stationCode + "/" + fileName, fileTemp);
+        //请求云预测记录文件生成记录
+        postFileToV3Cloud(stationCodeStr,fileName);
+      } else {
+        log.error("无法生成短期文件,没查到短期数据");
+      }
+    } catch (Exception e) {
+      log.error("马头山短期文件生成错误:{}",e);
+    }
+  }
+
+
+  /**
+   * 读取机组信息
+   * @return
+   */
+  private List<FanUnitInfo> readFanUnitInfo(){
+
+    List<FanUnitInfo> fanUnitInfoList = fanUnitInfoRepository.findAll();
+
+    List<CutOutSpeedSpecifyInfo> cutOutSpeedSpecifyInfoList = readFanCutOutSpeedInfo(); //机组信息读取
+    modleFanId = fanUnitInfoList.get(0).getBenchmarkFan();
+    for (FanUnitInfo fanUnitInfo:fanUnitInfoList) {
+
+      //把机组切出风速参数填充到机组信息中
+      for (CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo:cutOutSpeedSpecifyInfoList) {
+        if(fanUnitInfo.getId() == cutOutSpeedSpecifyInfo.getUnitBelongs()){
+          if(null == fanUnitInfo.getCutOutSpeedSpecifyInfos()){
+            fanUnitInfo.setCutOutSpeedSpecifyInfos(new ArrayList<>());
+          }
+          fanUnitInfo.getCutOutSpeedSpecifyInfos().add(cutOutSpeedSpecifyInfo);
+        }
+      }
+
+    }
+    return fanUnitInfoList;
+  }
+
+  /**
+   * 读取风速曲线点表
+   */
+  private void readWindTurbinePowerCurveMap() {
+      Map<Float,Float> mapSpeed = new HashMap<>();
+      List<WindTurbinePowerCurve> windTurbinePowerCurves = windTurbinePowerCurveRepository.findAll();
+      for(WindTurbinePowerCurve windTurbinePowerCurve: windTurbinePowerCurves){
+        mapSpeed.put(windTurbinePowerCurve.getSpeed(),windTurbinePowerCurve.getPower());
+        windTurbinePowerCurveMaps.put(String.valueOf(windTurbinePowerCurve.getFanId()),mapSpeed);
+      }
+  }
+
+  /**
+   * 满发风速之后各风速发电曲线
+   * @return
+   */
+  private List<CutOutSpeedSpecifyInfo> readFanCutOutSpeedInfo() {
+    return cutOutSpeedSpecifyInfoRepository.findAll();
+  }
+
+  /**
+   * 读取 东北风向风速 东南风向风速  西南风向风速  西北风向风速 4个sheet表风速点表
+   */
+  private void readerSpeedSheet() {
+
+    List<WindSpeedPointInfo> WindSpeedPointInfos = windSpeedPointInfoRepository.findAll();
+    Map<String,List<String>> moduleFanMaps = new HashMap<>();
+    Map<Integer,List<String>> valMap = new HashMap<>();
+    Map<Integer,String> keyMap = new HashMap<>();
+    List<String> stringList = new ArrayList<>();
+    String modelFanName = null;
+    Integer belong = 1;
+    for (int i = 1; i < WindSpeedPointInfos.size(); i++) {
+      modelFanName = WindSpeedPointInfos.get(0).getFanNumber();
+      belong = WindSpeedPointInfos.get(0).getBelong();
+      if (i == 1 ){
+        break;
+      }
+    }
+    for (int i = 0; i < WindSpeedPointInfos.size(); i++) {
+      if (WindSpeedPointInfos.get(i).getBelong() != belong) {
+        valMap.put(belong,stringList);
+      }
+      if (WindSpeedPointInfos.get(i).getFanNumber().equals(modelFanName)) {
+        belong = WindSpeedPointInfos.get(i).getBelong();
+        stringList = new ArrayList<>();
+      }
+      if (!WindSpeedPointInfos.get(i).getFanNumber().equals(modelFanName)) {
+        String str = Convert.toStr(WindSpeedPointInfos.get(i).getFanNumber()) + "-"
+          + Convert.toFloat(new Formatter().format("%.1f", Convert.toDouble(WindSpeedPointInfos.get(i).getSpeed())));
+        stringList.add(str);
+      }
+      if (WindSpeedPointInfos.get(i).getFanNumber().equals(modelFanName)) {
+        String kString = WindSpeedPointInfos.get(i).getWind()+"-"+WindSpeedPointInfos.get(i).getFanNumber()+ "-"+Convert.toFloat(new Formatter().format("%.1f",Convert.toDouble( WindSpeedPointInfos.get(i).getSpeed())));
+        keyMap.put(belong,kString);
+      }
+      keyMap.forEach((k,v) -> {
+        valMap.forEach((k2,v2) -> {
+          if(k2==k){
+            moduleFanMaps.put(v,v2);
+          }
+        });
+      });
+    }
+
+  }
+
+  /**
+   * 读取检修计划数据
+   * @return
+   */
+  private void readerOverhual() {
+    overhaulInfos = overhaulPlanRepository.findAll();
+  }
+
+
+  /**
+   * 过滤重复数据
+   *
+   * @param keyExtractor
+   * @param <T>
+   * @return
+   */
+  private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+    Map<Object, Boolean> seen = new ConcurrentHashMap<>();
+    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
+  }
+
+  /**
+   * 移除当前时间在检修中的设备id
+   * @param fanIdList
+   * @param c_time
+   * @param 
+   * @return
+   */
+  private Map<String,List<String>> removeOverhaulFans(List<String> fanIdList, Date c_time) {
+
+    if(null == overhaulInfos || overhaulInfos.size()==0){
+      return moduleFanMaps;
+    }
+
+    List<String> runFans = removeFanIdByOverhual(fanIdList, c_time,overhaulInfos);
+
+    Map<String,List<String>>  removeOverhaulFansMaps = moduleFanMaps;
+    for (String str:runFans
+    ) {
+      removeOverhaulFansMaps.forEach((key, value) -> {
+        value.removeIf(e -> e.contains(str));
+      });
+    }
+
+    return removeOverhaulFansMaps;
+  }
+
+  /**
+   * 检查正常运行的风机,删除检修状态的风机
+   * @param fanIdList
+   * @param c_time
+   * @param overhaulInfos
+   * @return
+   */
+  private List<String> removeFanIdByOverhual(List<String> fanIdList, Date c_time, List<OverhaulPlan> overhaulInfos) {
+    List<String> runFanIds= new ArrayList<>();
+    for (String fanId:fanIdList
+    ) {
+      for (OverhaulPlan overhaul: overhaulInfos
+      ) {
+        //风机编号相同且在检修时间
+        if(fanId.equals(overhaul.getName())){
+          if( c_time.after(DateUtil.date(overhaul.getStartTime())) &&  c_time.before(DateUtil.date(overhaul.getEndTime()))){
+            runFanIds.add(fanId);
+          }
+        }
+      }
+    }
+
+    return runFanIds;
+  }
+
+  public List<ForecastPowerShortTerm> getDataDQ(List<ForecastPowerShortTerm> shortTermForcastList, Long ycts,String stationCode) {
+
+    List<ForecastPowerShortTerm> dm = new ArrayList<>();
+    dm.addAll(shortTermForcastList);
+    int index = dm.size();
+
+    Long timeD = 15 * 60 * 1000L;
+    Long lt = dm.get(dm.size() - 1).getForecastTime();
+    int i = 1;
+    //第11天数据不够,进行数据补充 ,如果预测值不为0 取预测-预测*1.1之间的随机值
+    while (shortTermForcastList.size() < ycts * 96) {
+      ForecastPowerShortTerm shortTermForcast = new ForecastPowerShortTerm();
+
+      if (dm.get(index - i).getFpValue().doubleValue() > 0) {
+        {
+          double randomDouble = RandomUtil.randomDouble(dm.get(index - i).getFpValue().doubleValue(), dm.get(index - i).getFpValue().doubleValue() * 1.1, 2, RoundingMode.HALF_UP);
+          shortTermForcast.setFpValue(new BigDecimal(randomDouble).setScale(2, RoundingMode.HALF_UP));
+        }
+      } else {
+        shortTermForcast.setFpValue(BigDecimal.ZERO);
+      }
+
+      shortTermForcast.setForecastTime(lt + timeD * i);
+      if (dm.get(index - i).getFpValue().doubleValue() > 0) {
+        {
+          double randomDouble = RandomUtil.randomDouble(dm.get(index - i).getFpValue().doubleValue(), dm.get(index - i).getFpValue().doubleValue() * 1.1, 2, RoundingMode.HALF_UP);
+          shortTermForcast.setFpValue(new BigDecimal(randomDouble).setScale(2, RoundingMode.HALF_UP));
+        }
+      } else {
+        shortTermForcast.setFpValue(BigDecimal.ZERO);
+      }
+//      shortTermForcast.setStationCode(stationCode);
+      shortTermForcastList.add(shortTermForcast);
+      if (i == index) {
+        break;
+      }
+      i++;
+    }
+    return shortTermForcastList;
+  }
+
+  /**
+   * 本地短期对象转换为原v3云预测所用对象
+   * @param powerMeteoforces
+   * @return
+   */
+  private List<ForecastPowerShortTerm> getFormNwpsData(List<PowerMeteoforce1> powerMeteoforces) {
+    List<ForecastPowerShortTerm> listShort = new ArrayList<>();
+    for (PowerMeteoforce1 power:powerMeteoforces
+    ) {
+      ForecastPowerShortTerm forcastDataDQ = new ForecastPowerShortTerm();
+//      forcastDataDQ.setStationCode(power.getCFarmId());
+      forcastDataDQ.setForecastTime(power.getCTime().getTime());
+//      forcastDataDQ.setForcastTimeString(DateTimeUtil.dateToStrLong(power.getCTime()));
+      forcastDataDQ.setFpValue(new BigDecimal(power.getCForecast()));
+//      forcastDataDQ.setModifyValue(new BigDecimal(power.getCForecast()).setScale(2, RoundingMode.HALF_UP));
+      listShort.add(forcastDataDQ);
+    }
+    return listShort;
+  }
+
+
+  public void postFileToV3Cloud(String stationCode,String fileName){
+    Map<String, Object> parmer = new HashMap<>();
+    parmer.put("stationCode", stationCode);
+    parmer.put("fileName", fileName);
+    String response = HttpUtil.post("http://117.78.19.70:9009/client/saveFileLogsForAio", parmer);
+    //String response = HttpUtil.post("http://127.0.0.1:9009/client/saveFileLogsForAio", parmer);
+    if (StringUtils.isNotEmpty(response)) {
+      boolean isJson = JSONUtil.isJsonObj(response);
+      if (isJson) {
+        JSONObject jsonObject = JSONUtil.parseObj(response);
+        String code = jsonObject.getStr("code");
+        if (code.equals("0")) {
+          log.warn("minlo上送日志响应正常");
+        } else {
+          log.warn("minlo上送日志响应不为0");
+        }
+      } else {
+        log.warn("minlo上送日志响应格式不对");
+      }
+    }
+  }
+}

+ 2 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/router/index.js

@@ -8,6 +8,7 @@ import statisticsQueryRouter from './modules/statisticsQuery'
 import qrCodeQuery from './modules/qrCodeQuery'
 import exportConfigQuery from './modules/exportConfigQuery'
 import contrastRealTimeQuery from './modules/contrastRealTimeQuery'
+import parameterConfigurationRouter from "./modules/parameterConfiguration";
 
 Vue.use(Router)
 
@@ -70,6 +71,7 @@ export const constantRoutes = [
   statisticsQueryRouter,
   qrCodeQuery,
   exportConfigQuery,
+  parameterConfigurationRouter,
 
   // 404 page must be placed at the end !!!
   { path: '*', redirect: '/404',sign: 'currency', hidden: true }

+ 54 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/router/modules/parameterConfiguration.js

@@ -0,0 +1,54 @@
+/** When your routing table is too long, you can split it into small modules**/
+
+import Layout from '@/layout'
+
+const parameterConfigurationRouter = {
+  path: '/parameterConfiguration',
+  component: Layout,
+  redirect: 'noRedirect',
+  name: 'parameterConfiguration',
+  meta: {
+    title: '参数配置',
+    icon: 'edit'
+  },
+  children: [
+
+    {
+      path: 'fanUnitInfo',
+      component: () => import('@/views/parameterConfiguration/FanUnitInfo'),
+      name: 'FanUnitInfo',
+      meta: {title: '机组信息', noCache: true},
+      sign: 'currency'
+    },
+    {
+      path: 'CutOutSpeedSpecifyInfo',
+      component: () => import('@/views/parameterConfiguration/CutOutSpeedSpecifyInfo'),
+      name: 'CutOutSpeedSpecifyInfo',
+      meta: {title: '切出停机', noCache: true},
+      sign: 'currency'
+    },
+    {
+      path: 'WindSpeedPointInfo',
+      component: () => import('@/views/parameterConfiguration/WindSpeedPointInfo'),
+      name: 'WindSpeedPointInfo',
+      meta: {title: '风速点表', noCache: true},
+      sign: 'currency'
+    },
+    {
+      path: 'WindTurbinePowerCurve',
+      component: () => import('@/views/parameterConfiguration/WindTurbinePowerCurve'),
+      name: 'WindTurbinePowerCurve',
+      meta: {title: '风机曲线', noCache: true},
+      sign: 'currency'
+    },
+    {
+      path: 'WindSpeedPointInfo1',
+      component: () => import('@/views/parameterConfiguration/windSpeedPointInfo1'),
+      name: 'WindSpeedPointInfo1',
+      meta: {title: '风速点表1', noCache: true},
+      sign: 'currency'
+    },
+  ]
+}
+
+export default parameterConfigurationRouter

+ 234 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/CutOutSpeedSpecifyInfo/index.vue

@@ -0,0 +1,234 @@
+<template>
+  <div class="app-container">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>切出停机</span>
+      </div>
+      <el-button type="primary" size="small" @click="insertEvent" style="round-clip: 10px">新增</el-button>
+      <el-button type="primary" size="small" :loading="loading" @click="cutOutSpeedSpecifyInfo" style="round-clip: 10px">读取excel</el-button>
+      <div>
+        <el-table
+          :data="tableData"
+          border
+          v-loading="loading"
+          element-loading-text="拼命加载中..."
+          element-loading-spinner="el-icon-loading"
+          element-loading-background="rgba(0, 0, 0, 0.8)"
+          style="width: 100%">
+          <el-table-column
+            prop="id"
+            label="id"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="lowerWindSpeedLimit"
+            label="发电风速下限"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="highWindSpeedLimit"
+            label="发电风速上限"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="powerGeneration"
+            label="发电功率 MW"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="unitBelongs"
+            label="所属机组"
+          >
+          </el-table-column>
+
+          <el-table-column label="操作">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                @click="handleEdit(scope.$index, scope.row)">编辑
+              </el-button>
+              <el-button
+                size="mini"
+                type="danger"
+                @click="handleDelete(scope.$index, scope.row)">删除
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <!--    分页-->
+        <div class="rtPageturning">
+          <vxe-pager
+            background
+            :current-page.sync="currentPage"
+            :page-size.sync="pageSize"
+            :total="total"
+            @page-change="handlePageChange"
+            :layouts="['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']">
+          </vxe-pager>
+        </div>
+
+        <el-dialog
+          title="切出停机"
+          :visible.sync="dialogVisible"
+          width="30%"
+        >
+          <el-form ref="form" :model="form" label-width="120px" :rules="rules">
+            <el-form-item label="发电风速下限" prop="lowerWindSpeedLimit">
+              <el-input v-model="form.lowerWindSpeedLimit" style="width: 70%" ></el-input>
+            </el-form-item>
+            <el-form-item label="发电风速上限" prop="highWindSpeedLimit">
+              <el-input v-model="form.highWindSpeedLimit" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="发电功率 MW" prop="powerGeneration">
+              <el-input v-model="form.powerGeneration" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="所属机组" prop="unitBelongs">
+              <el-input v-model="form.unitBelongs" style="width: 70%"></el-input>
+            </el-form-item>
+
+          </el-form>
+          <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false" style="color: #000000; border: 1px solid #000000">取 消</el-button>
+          <el-button type="primary" @click="saveRowEvent" style="color: #000000; border: 1px solid #000000">确 定</el-button>
+        </span>
+          </template>
+        </el-dialog>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      tableData: [],
+      form: {},
+      dialogVisible: false,
+      // 当前页
+      currentPage: 1,
+      // 当前页有几条数据
+      pageSize: 10,
+      // 总条数
+      total: 0,
+      loading: false,
+      rules: {
+        lowerWindSpeedLimit: [ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/,required: true,message: "名称必填", trigger: 'blur'}],
+        highWindSpeedLimit: [ {pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, required: true,message: "填写数字", trigger: 'blur'}],
+        powerGeneration: [ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/,required: true,message: "填写数字", trigger: 'blur'}],
+        unitBelongs: [ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/,required: true,message: "填写数字", trigger: 'blur'}],
+      }
+    }
+  },
+  methods: {
+    handlePageChange ({ currentPage, pageSize }) {
+      this.currentPage = currentPage
+      this.pageSize = pageSize
+      this.initPage()
+    },
+    // 获取分页数据
+    initPage() {
+      this.$axios.get("/cutOutSpeedSpecifyInfo/" + this.currentPage + '/' + this.pageSize).then(response => {
+        this.tableData = response.data.content
+        this.total = response.data.count
+        console.log(response.data);
+        console.log(response.data.content[0].unitBelongs);
+
+      })
+    },
+    insertEvent() {
+      this.form = {};
+      this.dialogVisible = true;
+    },
+    saveRowEvent() {
+      this.$axios.post('/cutOutSpeedSpecifyInfo', this.form).then(res => {
+        this.$message.success(res.data.message)
+        this.initPage()
+      }).catch(e => {
+        this.$message.error(e)
+      })
+      this.dialogVisible = false;
+      this.initPage()
+    },
+    handleEdit(index, row) {
+      console.log(index, row);
+      this.form = JSON.parse(JSON.stringify(row))
+      this.dialogVisible = true
+      this.initPage()
+    },
+    // 删除
+    handleDelete(index, row) {
+      console.log(index, row);
+      this.$XModal.confirm('您确定要删除该数据?').then(type => {
+        if (type === 'confirm') {
+          this.$axios.delete("/cutOutSpeedSpecifyInfo/", {data: row}).then(response => {
+            this.$XModal.message({status: 'warning', message: response.message})
+            this.initPage()
+          })
+        }
+
+      })
+    },
+    // pageSize 改变时会触发
+    handleSizeChange(pageSize) {
+      this.pageSize = pageSize
+      this.initPage()
+    },
+    // 改currentPage 改变时会触发
+    handleCurrentChange(pageNum) {
+      this.currentPage = pageNum
+      this.initPage()
+    },
+    cutOutSpeedSpecifyInfo() {
+      this.loading = true
+      this.$axios.get("/readToMysql/cutOutSpeedSpecifyInfo").then((res=>{
+        this.$message.success(res.data.message)
+        this.loading = false
+        this.initPage()
+      }))
+    },
+  },
+  mounted() {
+    this.initPage()
+  }
+}
+</script>
+
+<style scoped>
+.box-card {
+  background: transparent;
+  color: #ffffff;
+}
+.el-button {
+  round-clip: 10px;
+  color: #ffffff;
+  background: transparent;
+  border: 1px solid #fff;
+
+}
+::v-deep .el-table, .el-table__expanded-cell {
+  margin-top: 20px;
+  background-color: transparent;
+  color: #ffffff;
+  width: 100%
+}
+/deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
+  background-color: transparent;
+}
+
+::v-deep .el-table tr {
+  background-color: transparent !important;
+}
+::v-deep .el-table__body td,::v-deep .el-table__header th, .el-table .cell {
+  background-color: transparent;
+}
+::v-deep .el-table::before {
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  height: 0px;
+}
+</style>

+ 280 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/FanUnitInfo/index.vue

@@ -0,0 +1,280 @@
+<template>
+  <div class="app-container">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>机组信息</span>
+      </div>
+      <el-button type="primary" size="small" @click="insertEvent" >新增</el-button>
+      <el-button type="primary" size="small" :loading="loading" @click="readFanUnitInfo" >读取excel</el-button>
+      <div>
+        <el-table
+          :data="tableData"
+          v-loading="loading"
+          element-loading-text="拼命加载中..."
+          element-loading-spinner="el-icon-loading"
+          element-loading-background="rgba(0, 0, 0, 0.8)"
+          border
+          >
+          <el-table-column
+            prop="id"
+            label="id"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="fanName"
+            label="机组品牌名称"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="fanUnitCapacity"
+            label="机组容量 KW"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="fullWindSpeed"
+            label="满发风速"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="cutOutSpeed"
+            label="切出风速"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="benchmarkFan"
+            label="基准风机"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="fanNumArrs"
+            label="风机编号组"
+          >
+          </el-table-column>
+          <el-table-column label="操作">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                @click="handleEdit(scope.$index, scope.row)">编辑
+              </el-button>
+              <el-button
+                size="mini"
+                type="danger"
+                @click="handleDelete(scope.$index, scope.row)">删除
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <!--    分页-->
+        <div style="margin-top: 10px;">
+<!--            <el-pagination-->
+<!--              @size-change="handleSizeChange"-->
+<!--              @current-change="handleCurrentChange"-->
+<!--              :current-page="currentPage"-->
+<!--              :page-sizes="[10, 20, 50,]"-->
+<!--              :page-size="pageSize"-->
+<!--              layout="total, sizes, prev, pager, next, jumper"-->
+<!--              :total="total"-->
+<!--            >-->
+<!--            </el-pagination>-->
+
+          <div class="rtPageturning">
+            <vxe-pager
+              background
+              :current-page.sync="currentPage"
+              :page-size.sync="pageSize"
+              :total="total"
+              @page-change="handlePageChange"
+              :layouts="['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']">
+            </vxe-pager>
+          </div>
+        </div>
+        <el-dialog
+          title="机组信息"
+          :visible.sync="dialogVisible"
+          width="30%"
+        >
+          <el-form ref="form" :model="form" label-width="120px" :rules="rules">
+            <el-form-item label="机组品牌名称" prop="fanName">
+              <el-input v-model="form.fanName" style="width: 70%" ></el-input>
+            </el-form-item>
+            <el-form-item label="机组容量 KW" prop="fanUnitCapacity">
+              <el-input v-model="form.fanUnitCapacity" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="满发风速" prop="fullWindSpeed">
+              <el-input v-model="form.fullWindSpeed" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="切出风速" prop="cutOutSpeed">
+              <el-input v-model="form.cutOutSpeed" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="基准风机" prop="benchmarkFan">
+              <el-input v-model="form.benchmarkFan" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="风机编号组" prop="fanNumArrs">
+              <el-input
+                type="textarea"
+                :rows="3"
+                v-model="form.fanNumArrs" style="width: 70%"></el-input>
+            </el-form-item>
+          </el-form>
+          <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false" style="color: #000000; border: 1px solid #000000">取 消</el-button>
+          <el-button type="primary" @click="saveRowEvent" style="color: #000000; border: 1px solid #000000">确 定</el-button>
+        </span>
+          </template>
+        </el-dialog>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+
+export default {
+
+  data() {
+    return {
+      tableData: [],
+      form: {},
+      dialogVisible: false,
+      // 当前页
+      currentPage: 1,
+      // 当前页有几条数据
+      pageSize: 10,
+      // 总条数
+      total: 0,
+      loading: false,
+      rules: {
+        fanName: [
+          {required: true, message: '不能为空'},
+        ],
+        fanUnitCapacity: [
+          {required: true, message: '不能为空'},
+          {pattern: /^[0-9]*[1-9][0-9]*$/,  trigger: 'blur'}
+        ],
+        fullWindSpeed: [
+          {required: true, message: '不能为空'},
+          {pattern: /^[0-9]*[1-9][0-9]*$/,  trigger: 'blur'}
+        ],
+        cutOutSpeed: [
+          {required: true, message: '不能为空'},
+          {pattern: /^[0-9]*[1-9][0-9]*$/,  trigger: 'blur'}
+        ],
+        benchmarkFan: [
+          {required: true, message: '不能为空'},
+        ],
+        fanNumArrs: [
+          {required: true, message: '不能为空'},
+        ],
+      }
+    }
+  },
+  methods: {
+    handlePageChange ({ currentPage, pageSize }) {
+      this.currentPage = currentPage
+      this.pageSize = pageSize
+      this.initPage()
+    },
+    // 获取分页数据
+    initPage() {
+      this.$axios.get("/fanUnitInfo/" + this.currentPage + '/' + this.pageSize).then(response => {
+        this.tableData = response.data.content
+        this.total = response.data.count
+      })
+    },
+    insertEvent() {
+      this.form = {};
+      this.dialogVisible = true;
+    },
+    saveRowEvent() {
+      this.$axios.post('/fanUnitInfo', this.form).then(res => {
+        this.$message.success(res.message)
+        this.initPage()
+      }).catch(e => {
+        this.$message.error(e)
+      })
+      this.dialogVisible = false;
+      this.initPage()
+    },
+    handleEdit(index, row) {
+      console.log(index, row);
+      this.form = JSON.parse(JSON.stringify(row))
+      this.dialogVisible = true
+      this.initPage()
+    },
+    // 删除
+    handleDelete(index, row) {
+      console.log(index, row);
+      this.$XModal.confirm('您确定要删除该数据?').then(type => {
+        if (type === 'confirm') {
+          this.$axios.delete("/fanUnitInfo/", {data: row}).then(response => {
+            this.$XModal.message({status: 'warning', message: response.message})
+            this.initPage()
+          })
+        }
+      })
+    },
+    // pageSize 改变时会触发
+    handleSizeChange(pageSize) {
+      this.pageSize = pageSize
+      this.initPage()
+    },
+    // 改currentPage 改变时会触发
+    handleCurrentChange(pageNum) {
+      this.currentPage = pageNum
+      this.initPage()
+    },
+    readFanUnitInfo(){
+      this.loading = true
+      this.$axios.get("/readToMysql/getFanUnitInfo").then(res=>{
+        this.$message.success(
+          res.message
+        )
+        this.loading = false
+        this.initPage()
+      })
+    },
+  },
+  mounted() {
+    this.initPage()
+  }
+}
+</script>
+
+<style scoped>
+.box-card {
+  background: transparent;
+  color: #ffffff;
+}
+.el-button {
+  round-clip: 10px;
+  color: #ffffff;
+  background: transparent;
+  border: 1px solid #fff;
+
+}
+::v-deep .el-table, .el-table__expanded-cell {
+  margin-top: 20px;
+  background-color: transparent;
+  color: #ffffff;
+  width: 100%
+}
+/deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
+  background-color: transparent;
+}
+
+::v-deep .el-table tr {
+  background-color: transparent !important;
+}
+::v-deep .el-table__body td,::v-deep .el-table__header th, .el-table .cell {
+  background-color: transparent;
+}
+::v-deep .el-table::before {
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  height: 0px;
+}
+
+
+</style>

+ 338 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/WindSpeedPointInfo/index.vue

@@ -0,0 +1,338 @@
+<template>
+  <div class="app-container">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>风速点表</span>
+      </div>
+      <div >
+        <el-row>
+          <el-col :span="16">
+            <el-button type="primary" size="small" @click="insertEvent" >新增</el-button>
+            <el-button type="primary" size="small" :loading="loading" @click="readSpeedSheet" >读取excel</el-button>
+            <el-input type="text"
+                      v-model="speed"
+                      placeholder="请输入风速"
+                      prefix-icon="el-icon-search"
+                      clearable
+                      style="width: 200px;"
+                      size="small"
+                      disabled
+            ></el-input>
+            <el-button type="primary" size="small" :loading="loading" @click="findBySpeed" disabled>查询</el-button>
+          </el-col>
+        </el-row>
+      </div>
+      <div>
+        <el-table
+          :data="tableData"
+          v-loading="loading"
+          element-loading-text="拼命加载中..."
+          element-loading-spinner="el-icon-loading"
+          element-loading-background="rgba(0, 0, 0, 0.8)"
+          border
+          style="width: 100%">
+          <el-table-column
+            prop="id"
+            label="id"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="fanNumber"
+            label="风机编号"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="wind"
+            label="风向"
+            :formatter="windF"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="speed"
+            label="风速"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="unitBelongs"
+            label="所属机组"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="belong"
+            label="所属行"
+          >
+          </el-table-column>
+          <el-table-column label="操作">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                @click="handleEdit(scope.$index, scope.row)">编辑
+              </el-button>
+              <el-button
+                size="mini"
+                type="danger"
+                @click="handleDelete(scope.$index, scope.row)">删除
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <div class="rtPageturning">
+          <vxe-pager
+            background
+            :current-page.sync="currentPage"
+            :page-size.sync="pageSize"
+            :total="total"
+            @page-change="handlePageChange"
+            :layouts="['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']">
+          </vxe-pager>
+        </div>
+
+        <el-dialog
+          title="风速点表"
+          :visible.sync="dialogVisible"
+          width="30%"
+        >
+          <el-form ref="form" :model="form" label-width="120px" :rules="rules">
+            <el-form-item label="风机编号" prop="fanNumber">
+              <el-input v-model="form.fanNumber" style="width: 70%" ></el-input>
+            </el-form-item>
+            <el-form-item label="风向" prop="wind" >
+              <el-input v-model="form.wind" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="风速 MW" prop="speed">
+              <el-input v-model="form.speed" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="所属机组" prop="UnitBelongs">
+              <el-input v-model="form.unitBelongs" style="width: 70%"></el-input>
+            </el-form-item>
+            <el-form-item label="所属行" prop="belong">
+              <el-input v-model="form.belong" style="width: 70%"></el-input>
+            </el-form-item>
+          </el-form>
+          <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false" style="color: #000000; border: 1px solid #000000">取 消</el-button>
+          <el-button type="primary" @click="saveRowEvent" style="color: #000000; border: 1px solid #000000">确 定</el-button>
+        </span>
+          </template>
+        </el-dialog>
+      </div>
+
+
+<!--      <div class="tableContent">-->
+<!--        <vxe-grid-->
+<!--          id="nwpTable"-->
+<!--          ref="nwpRef"-->
+<!--          border-->
+<!--          export-config-->
+<!--          :loading="loading"-->
+<!--          @sort-change="sortChangeEvent"-->
+<!--          :custom-config="{storage: true, checkMethod: checkColumnMethod}"-->
+<!--          :auto-resize="true"-->
+<!--          highlight-hover-row-->
+<!--          :header-cell-style="styleStr"-->
+<!--          max-height="90%"-->
+<!--          :cell-style="styleTableStr"-->
+<!--          align="center"-->
+<!--          :data="tableData"-->
+<!--          :columns="tableColumn"-->
+<!--        >-->
+<!--        </vxe-grid>-->
+<!--        <div class="rtPageturning">-->
+<!--          <vxe-pager-->
+<!--            background-->
+<!--            :loading="loading"-->
+<!--            :current-page.sync="currentPage"-->
+<!--            :page-size.sync="pageSize"-->
+<!--            :total="total"-->
+<!--            @page-change="handlePageChange"-->
+<!--            :layouts="['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']">-->
+<!--          </vxe-pager>-->
+<!--        </div>-->
+<!--      </div>-->
+
+
+    </el-card>
+  </div>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      tableData: [],
+      tableColumn: [],
+      form: {},
+      dialogVisible: false,
+      // 当前页
+      currentPage: 1,
+      // 当前页有几条数据
+      pageSize: 10,
+      // 总条数
+      total: 0,
+      loading:false,
+      speed: '1',
+      fanNumber: '1',
+      wind: '1',
+      UnitBelongs: '1',
+      belong: '1',
+      rules: {
+        fanNumber: [ { type: 'string',required: true,message: "名称必填", trigger: 'blur'}],
+        wind: [ {pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, required: true,message: "填写数字", trigger: 'blur'}],
+        speed: [ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/,required: true,message: "填写数字", trigger: 'blur'}],
+        power: [ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/,required: true,message: "填写数字", trigger: 'blur'}],
+        UnitBelongs: [ { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/,required: true,message: "填写数字", trigger: 'blur'}],
+      }
+    }
+  },
+  methods: {
+    handlePageChange ({ currentPage, pageSize }) {
+      this.currentPage = currentPage
+      this.pageSize = pageSize
+      this.initPage()
+    },
+    windF: function (row, index){
+      if(row.wind == "1"){
+        return "北风"
+      }else if(row.wind == "2"){
+        return "东北风"
+      }else if(row.wind == "3"){
+        return "东风"
+      }else if(row.wind == "4"){
+        return "东南风"
+      }else if(row.wind == "5"){
+        return "南风"
+      }else if(row.wind == "6"){
+        return "西南风"
+      }else if(row.wind == "7"){
+        return "西风"
+      }else {
+        return "西北风"
+      }
+    },
+
+    // 获取分页数据
+    initPage() {
+      this.$axios.get("/windSpeedPointInfo/" + this.currentPage + '/' + this.pageSize).then(response => {
+        this.tableData = response.data.content
+        this.total = response.data.count
+        //
+        // this.tableColumn = [
+        //   { field: 'id', title: 'id',sortable:true,minWidth:"150",width:"180" },
+        //   { field: 'fanNumber', title: '风机编号',minWidth:"60"},
+        //   { field: 'wind', title: '风向',minWidth:"60"},
+        //   { field: 'speed', title: '风速',minWidth:"60"},
+        //   { field: 'unitBelongs', title: '所属机组',minWidth:"60"},
+        //   { field: 'belong', title: '所属',minWidth:"60"},
+        //
+        // ]
+
+      })
+    },
+// /{size}/{fanNumber}/{wind}/{speed}/{unitBelongs}/{belong}
+    init2() {
+      this.$axios.get("/windSpeedPointInfo/bySomeConditions/" + this.currentPage + "/" + this.pageSize + "/" + this.fanNumber + '/' + this.wind + '/' + this.speed + '/' + this.UnitBelongs   + '/' + this.belong).then(res =>{
+        console.log(res.data.content);
+      })
+    },
+    insertEvent() {
+      this.form = {};
+      this.dialogVisible = true;
+    },
+    saveRowEvent() {
+      this.$axios.post('/windSpeedPointInfo', this.form).then(res => {
+        this.$message.success(
+          '操作成功!!!'
+        )
+        this.initPage()
+      }).catch(e => {
+        this.$message.error(
+          '操作失败!!!'
+        )
+      })
+      this.dialogVisible = false;
+      this.initPage()
+    },
+    handleEdit(index, row) {
+      console.log(index, row);
+      this.form = JSON.parse(JSON.stringify(row))
+      this.dialogVisible = true
+      this.initPage()
+    },
+    // 删除
+    handleDelete(index, row) {
+      this.$XModal.confirm('您确定要删除该数据?').then(type => {
+        if (type === 'confirm') {
+          this.$axios.delete("/windSpeedPointInfo/", {data: row}).then(response => {
+            this.$XModal.message({status: 'warning', message: response.message})
+            this.initPage()
+          })
+        }
+      })
+    },
+
+    readSpeedSheet(){
+      this.$XModal.confirm('是否从Excel读取数据?').then(type => {
+        if (type === 'confirm') {
+          this.loading = true
+          this.$axios.get("/readToMysql/readSpeedSheet").then( res => {
+            this.$message.success(
+              res.message
+            )
+            this.loading = false
+            this.initPage()
+          })
+        }
+      })
+    },
+    findBySpeed(){
+      this.$axios.get("/windSpeedPointInfo/" + this.currentPage + '/' + this.pageSize + '/' + this.speed).then(response => {
+        this.tableData = response.data.content
+        this.total = response.data.count
+
+      })
+    }
+  },
+  mounted() {
+    this.initPage();
+    this.init2()
+  }
+}
+</script>
+
+<style scoped>
+.box-card {
+  background: transparent;
+  color: #ffffff;
+}
+.el-button {
+  round-clip: 10px;
+  color: #ffffff;
+  background: transparent;
+  border: 1px solid #fff;
+
+}
+::v-deep .el-table, .el-table__expanded-cell {
+  margin-top: 20px;
+  background-color: transparent;
+  color: #ffffff;
+}
+/deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
+  background-color: transparent;
+}
+
+::v-deep .el-table tr {
+  background-color: transparent !important;
+}
+::v-deep .el-table__body td,::v-deep .el-table__header th, .el-table .cell {
+  background-color: transparent;
+}
+::v-deep .el-table::before {
+left: 0;
+  bottom: 0;
+  width: 100%;
+  height: 0px;
+}
+</style>

+ 248 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/WindTurbinePowerCurve/index.vue

@@ -0,0 +1,248 @@
+<template>
+  <div class="chart-container">
+    <div class="filter" >
+      <div style="margin-left:-10px;">
+        <el-button type="primary" size="small" :loading="loading" @click="readWindTurbinePowerCurve"
+                   style="round-clip: 10px">读取excel
+        </el-button>
+      </div>
+      <div class="toolbar" v-show="this.showToolBar"> <vxe-toolbar ref="fstToolBar" custom >
+        <template v-slot:buttons>
+          <vxe-button class="downloadButton" style="border:none;"  @click="exportDataEvent"><i class="vxe-icon--download" ></i></vxe-button>
+        </template>
+      </vxe-toolbar></div>
+      <div class="toolbar" v-show="this.showToolBar"> <vxe-toolbar ref="nwpToolBar" custom></vxe-toolbar></div>
+    </div>
+
+    <div class="content">
+      <el-tabs type="card" v-model="activeName" @tab-click="Byresize">
+        <el-tab-pane label="图表" name="first">
+          <chart :drawData = this.drawData :resizeKey=this.resizeKey  />
+        </el-tab-pane>
+        <el-tab-pane label="表格" name="second">
+          <div class="tableContent">
+            <vxe-grid
+              id="nwpTable"
+              ref="windRef"
+              border
+              export-config
+              :loading="loading"
+              resizable
+              keep-source
+              :auto-resize="true"
+              :header-cell-style="styleStr"
+              max-height="90%"
+              :cell-style="styleTableStr"
+              align="center"
+              :data="tableData"
+              :columns="tableColumn"
+              :edit-config="{trigger: 'manual', mode: 'row', showStatus: true, }"
+            >
+              <template v-slot:operate="{ row }">
+                <template v-if="$refs.windRef.isActiveByRow(row)">
+                  <vxe-button  content="保存" circle @click="saveRowEvent(row)"></vxe-button>
+                </template>
+                <template v-else>
+                  <vxe-button content="编辑" circle @click="editRowEvent(row)"></vxe-button>
+                </template>
+                <vxe-button content="删除" circle @click="removeRowEvent(row)"></vxe-button>
+              </template>
+            </vxe-grid>
+            <div class="rtPageturning">
+              <vxe-pager
+                background
+                :loading="loading"
+                :current-page.sync="currentPage"
+                :page-size.sync="pageSize"
+                :page-sizes="pageSizes"
+                :total="total"
+                @page-change="handlePageChange"
+                :layouts="['PrevJump', 'PrevPage', 'JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']">
+              </vxe-pager>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
+</template>
+
+<script>
+  import Chart from './charts'
+  import resize from '../../../components/Charts/mixins/resize'
+  export default {
+
+    components: { Chart},
+    mixins: [resize],
+    data(){
+      return{
+        styleStr:{},
+        styleTableStr:{},
+        tableToolbar: {
+          export: true,
+          custom: true
+        },
+        tableColumn:[],
+        chart: null,
+        loading:true,
+        drawLoading:true,
+        tableLoading:true,
+        resizeKey:1,
+        activeName: 'first',
+        drawData:{Fan1:[], Fan2:[], Fan3:[], Fan4:[], Fan5:[], xData:[]},
+        tableData:[],
+        total:0,
+        pageSize: 10,
+        pageSizes: [10,50,100,{label: '大量数据', value: 1000},],
+        currentPage: 1,
+        showToolBar:false,
+      }
+    },
+    created () {
+      if(sessionStorage.getItem('styleSwitch') === 'blue'){
+        this.styleStr = {background:'black',color:'white',border:'white'}
+        this.styleTableStr = {background:'black',color:'white'}
+      }
+      this.$nextTick(() => {
+        // 手动将表格和工具栏进行关联
+        this.$refs.nwpRef.connect(this.$refs.nwpToolBar)
+      })
+    },
+    mounted() {
+      this.init()
+    },
+    methods:{
+      exportDataEvent() {
+        this.loading = true
+        this.$axios.get('export/powerStationStatus/'+this.startTime+'/'+this.endTime, {
+          responseType: 'blob'// 用于解决中文乱码
+        }).then((response) => {
+          this.loading = false
+        }).catch((error) => {
+          this.loading = false
+          this.$message.error('导出失败' + error)
+        })
+      },
+      init(){
+        this.loading = true
+        this.getDraw()
+        this.getTable()
+
+      },
+      getDraw(){
+        this.drawLoading = true
+        this.$axios.get('/windTurbinePowerCurve/new/').then((res) => {
+          this.drawData = res.data
+          this.drawLoading = false
+          if(!this.drawLoading && !this.tableLoading){
+            this.loading = false
+          }
+        }).catch((error) => {
+          this.drawLoading = false
+          if(!this.drawLoading && !this.tableLoading){
+            this.loading = false
+          }
+          this.$message.error('查询出错' + error)
+        })
+      },
+      getTable(){
+        this.tableLoading = true
+        this.$axios.get('/windTurbinePowerCurve/'+this.currentPage+'/'+this.pageSize).then((res) => {
+          this.tableData = res.data.content
+          // 表分页格数据总条数
+          this.total = res.data.count
+          this.tableColumn = []
+          this.tableColumn = [
+            { field: 'id', title: 'id',minWidth:"150",width:"180"},
+            { field: 'speed', title: '风速',minWidth:"60",editRender: { name: 'input' }},
+            { field: 'power', title: '功率',minWidth:"60",editRender: { name: 'input' }},
+            { field: 'fanId', title: '机组',minWidth:"60",editRender: { name: 'input' }},
+            { title: '操作', width: 200, slots: { default: 'operate' } }
+          ]
+
+          this.tableLoading = false
+          if(!this.drawLoading && !this.tableLoading){
+            this.loading = false
+          }
+        }).catch((error) => {
+          this.tableLoading = false
+          if(!this.drawLoading && !this.tableLoading){
+            this.loading = false
+          }
+          this.$message.error('查询table出错' + error)
+        })
+
+      },
+      handlePageChange ({ currentPage, pageSize }) {
+        this.currentPage = currentPage
+        this.pageSize = pageSize
+        this.loading = true
+        this.getTable();
+      },
+      readWindTurbinePowerCurve() {
+        this.$XModal.confirm('是否从Excel读取数据?').then(type => {
+          if (type === 'confirm') {
+            this.loading = true
+            this.$axios.get("/readToMysql/readWindTurbinePowerCurveMap").then(res=>{
+              this.$message.success(
+                res.message
+              )
+              this.loading = false
+              this.init()
+            })
+          }
+        })
+      },
+      Byresize(tab){
+        if(tab.name =='first'){
+          this.resizeKey++
+          this.showToolBar = false
+        }else{
+          this.showToolBar = true
+        }
+
+      },
+
+      editRowEvent (row) {
+        this.$refs.windRef.setActiveRow(row)
+      },
+      saveRowEvent (row) {
+        this.$refs.windRef.clearActived().then(() => {
+          this.loading = true
+          this.$axios.put('/windTurbinePowerCurve/',row).then((res) => {
+            this.$message.success(
+              res.message
+            )
+            this.loading = false
+          }).catch((error) => {
+            this.$message.error('修改失败' + error)
+            this.loading = false
+          })
+        })
+      },
+      removeRowEvent (row) {
+        this.$XModal.confirm('您确定要删除该数据?').then(type => {
+          if (type === 'confirm') {
+            this.$axios.delete('/windTurbinePowerCurve/',{data:row}).then((res) => {
+              this.$message.success(
+                res.message
+              )
+              this.loading = false
+              this.getTable()
+              this.init()
+            }).catch((error) => {
+              this.$message.error('删除' + error)
+              this.loading = false
+            })
+          }
+        })
+      }
+
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>
+

+ 247 - 0
ipfcst/ipfcst-reportquery/src/main/frontend/views/parameterConfiguration/windSpeedPointInfo1/index.vue

@@ -0,0 +1,247 @@
+<template>
+  <div className="app-container">
+    <div className="xTable">
+      <vxe-grid ref='xGrid' v-bind="gridOptions"></vxe-grid>
+    </div>
+  </div>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      gridOptions: {
+        border: true,
+        resizable: true,
+        showHeaderOverflow: true,
+        showOverflow: true,
+        highlightHoverRow: true,
+        keepSource: true,
+        id: 'full_edit_1',
+        height: 600,
+        rowId: 'id',
+        customConfig: {
+          storage: true,
+          checkMethod: this.checkColumnMethod
+        },
+        printConfig: {
+          columns: [
+            {field: 'name'},
+            {field: 'email'},
+            {field: 'nickname'},
+            {field: 'age'},
+            {field: 'amount'}
+          ]
+        },
+        sortConfig: {
+          trigger: 'cell',
+          remote: true
+        },
+        filterConfig: {
+          remote: true
+        },
+        pagerConfig: {
+          pageSize: 10,
+          pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000]
+        },
+        formConfig: {
+          titleWidth: 100,
+          titleAlign: 'right',
+          items: [
+            {
+              field: 'name',
+              title: '风机编号',
+              span: 8,
+              titlePrefix: {message: 'app.body.valid.rName', icon: 'fa fa-exclamation-circle'},
+              itemRender: {name: '$input', props: {placeholder: '请输入风机编号'}}
+            },
+            {field: 'wind', title: '风向', span: 8, itemRender: {name: '$select', options: [
+                  {}
+                ]}},
+            {field: 'speed', title: '风速', span: 8, itemRender: {name: '$input', props: {placeholder: '请输入风速'}}},
+            {
+              field: 'unitBelong',
+              title: '所属机组',
+              span: 8,
+              itemRender: {name: '$input', props: {placeholder: '请输入所属机组'}}
+            },
+            {field: 'belong', title: '所属行', span: 8, itemRender: {name: '$input', props: {placeholder: '请输入所属行'}}},
+            // { field: 'unitBelong', title: '所属机组', span: 8, folding: true, itemRender: { name: '$input', props: { placeholder: '请输入所属机组' } } },
+            // { field: 'belong', title: '所属行', span: 8, folding: true, titleSuffix: { message: '注意,必填信息!', icon: 'fa fa-info-circle' }, itemRender: { name: '$select', options: [] } },
+            // { field: 'age', title: '年龄', span: 8, folding: true, itemRender: { name: '$input', props: { type: 'number', min: 1, max: 120, placeholder: '请输入年龄' } } },
+            {
+              span: 24,
+              align: 'center',
+              itemRender: {
+                name: '$buttons',
+                children: [{props: {type: 'submit', content: '提交', status: 'primary'}}, {
+                  props: {
+                    type: 'reset',
+                    content: '重置'
+                  }
+                }]
+              }
+            }
+          ]
+        },
+        toolbarConfig: {
+          buttons: [
+            {code: 'insert_actived', name: '新增', icon: 'fa fa-plus'},
+            {code: 'delete', name: '直接删除', icon: 'fa fa-trash-o'},
+            {code: 'mark_cancel', name: '删除/取消', icon: 'fa fa-trash-o'},
+            {code: 'save', name: '保存', icon: 'fa fa-save', status: 'success'}
+          ],
+          refresh: true,
+          import: true,
+          export: true,
+          print: true,
+          zoom: true,
+          custom: true
+        },
+        proxyConfig: {
+          seq: true, // 启用动态序号代理
+          sort: true, // 启用排序代理
+          filter: true, // 启用筛选代理
+          form: true, // 启用表单代理
+          props: {
+            result: 'result',
+            total: 'page.total'
+          },
+          ajax: {
+            // // 接收 Promise 对象
+            // query: ({ page, sorts, filters, form }) => {
+            //   const queryParams = Object.assign({}, form)
+            //   // 处理排序条件
+            //   const firstSort = sorts[0]
+            //   if (firstSort) {
+            //     queryParams.sort = firstSort.property
+            //     queryParams.order = firstSort.order
+            //   }
+            //   // 处理筛选条件
+            //   filters.forEach(({ property, values }) => {
+            //     queryParams[property] = values.join(',')
+            //   })
+            //   return XEAjax.get(`${this.serveApiUrl}/api/pub/page/list/${page.pageSize}/${page.currentPage}`, queryParams)
+            // },
+            delete: ({body}) => XEAjax.post(`${this.serveApiUrl}/api/pub/save`, body),
+            save: ({body}) => XEAjax.post(`${this.serveApiUrl}/api/pub/save`, body)
+          }
+        },
+        columns: [
+          {type: 'checkbox', title: 'ID', width: 120},
+          {field: 'id', title: 'ID', sortable: true, editRender: {name: 'input'}},
+          {field: 'fanNumber', title: '风机编号', sortable: true, editRender: {name: 'input'}},
+          {field: 'wind', title: '风向', sortable: true, editRender: {name: 'input'}},
+          {field: 'speed', title: '风速', sortable: true, editRender: {name: 'input'}},
+          {field: 'unitBelongs', title: '所属机组', sortable: true, editRender: {name: 'input'}},
+          {field: 'belong', title: '所属行', sortable: true, editRender: {name: 'input'}},
+
+        ],
+        importConfig: {
+          remote: true,
+          importMethod: this.importMethod,
+          types: ['xlsx'],
+          modes: ['insert']
+        },
+        exportConfig: {
+          remote: true,
+          exportMethod: this.exportMethod,
+          types: ['xlsx'],
+          modes: ['current', 'selected', 'all']
+        },
+        checkboxConfig: {
+          labelField: 'id',
+          reserve: true,
+          highlight: true,
+          range: true
+        },
+        editRules: {},
+        editConfig: {
+          trigger: 'click',
+          mode: 'row',
+          showStatus: true
+        }
+      }
+    }
+  },
+  computed: {
+    // ...mapState([
+    //   'serveApiUrl'
+    // ])
+  },
+  created() {
+    this.findSexList()
+  },
+  methods: {
+    async findSexList() {
+      // const sexList = await XEAjax.get('/api/conf/sex/list')
+      // // 异步更新下拉选项
+      // this.sexList = sexList
+      // const xGrid = this.$refs.xGrid
+      // if (xGrid) {
+      //   const sexColumn = xGrid.getColumnByField('sex')
+      //   sexColumn.editRender.options = sexList
+      //   const sexItem = xGrid.getFormItems(4)
+      //   sexItem.itemRender.options = sexList
+      // }
+    },
+    formatAmount({cellValue}) {
+      // return cellValue ? `$${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : ''
+    },
+    formatDate({cellValue}) {
+      // return XEUtils.toDateString(cellValue, 'yyyy-MM-dd HH:ss:mm')
+    },
+    checkColumnMethod({column}) {
+      // if (['nickname', 'role'].includes(column.property)) {
+      //   return false
+      // }
+      // return true
+    },
+    importMethod({file}) {
+      // const formBody = new FormData()
+      // formBody.append('file', file)
+      // return XEAjax.post(`${this.serveApiUrl}/api/pub/import`, formBody).then(data => {
+      //   this.$XModal.message({ message: `成功导入 ${data.result.insertRows} 条记录!`, status: 'success' })
+      //   // 导入完成,刷新表格
+      //   this.$refs.xGrid.commitProxy('query')
+      // }).catch(() => {
+      //   this.$XModal.message({ message: '导入失败,请检查数据是否正确!', status: 'error' })
+      // })
+    },
+    exportMethod({options}) {
+      // const proxyInfo = this.$refs.xGrid.getProxyInfo()
+      // // 传给服务端的参数
+      // const body = {
+      //   filename: options.filename,
+      //   sheetName: options.sheetName,
+      //   isHeader: options.isHeader,
+      //   original: options.original,
+      //   mode: options.mode,
+      //   pager: proxyInfo.pager,
+      //   ids: options.mode === 'selected' ? options.data.map(item => item.id) : [],
+      //   fields: options.columns.map(column => {
+      //     return {
+      //       field: column.property,
+      //       title: column.title
+      //     }
+      //   })
+      // }
+      // // 开始服务端导出
+      // return XEAjax.post(`${this.serveApiUrl}/api/pub/export`, body).then(data => {
+      //   if (data.id) {
+      //     this.$XModal.message({ message: '导出成功,开始下载', status: 'success' })
+      //     // 读取路径,请求文件流 => 开始下载
+      //     location.href = `${this.serveApiUrl}/api/pub/export/download/${data.id}`
+      //   }
+      // }).catch(() => {
+      //   this.$XModal.message({ message: '导出失败!', status: 'error' })
+      // })
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 276 - 8
ipfcst/ipfcst-reportquery/src/main/frontend/views/realTimeQuery/nwp/charts/index.vue

@@ -14,6 +14,7 @@
       drawData:{
         handler(newValue, oldValue) {
           this.cName = newValue.cName
+          this.ncName = newValue.ncName
           if(newValue.cName.ws10==undefined){
             this.company = 'W/㎡'
             this.thFormat = [
@@ -29,10 +30,21 @@
               {key:"ws80",value:this.cName.ws80},
               {key:"ws90",value:this.cName.ws90},
               {key:"ws100",value:this.cName.ws100},
-              {key:"ws170",value:this.cName.ws170}]
+              {key:"ws170",value:this.cName.ws170},
+              ]
+            this.nthFormat = [
+              {key:"wsInst10",value:this.ncName.wsInst10},
+              {key:"wsInst30",value:this.ncName.wsInst30},
+              {key:"wsInst50",value:this.ncName.wsInst50},
+              {key:"wsInst70",value:this.ncName.wsInst70},
+              {key:"wsInst80",value:this.ncName.wsInst80},
+              {key:"wsInst90",value:this.ncName.wsInst90},
+              {key:"wsInst100",value:this.ncName.wsInst100},
+              {key:"wsInst170",value:this.ncName.wsInst170}
+            ]
           }
 
-          this.draw(newValue.times, newValue.datas)
+          this.draw(newValue.times, newValue.datas, newValue.ndatas)
 
         },
         deep: true
@@ -55,8 +67,10 @@
       return {
         lineColor:'',
         cName:{},
+        ncName: {},
         chart: null,
         thFormat:[],
+        nthFormat: [],
         company:'m/s',
         lineStyle:[
           {
@@ -256,6 +270,204 @@
                 borderWidth: 12
               }
             },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(219,50,51,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws10,
+                borderColor: 'rgba(219,50,51,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(219,196,50,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws30,
+                borderColor: 'rgba(219,196,50,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(101,219,50,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws50,
+                borderColor: 'rgba(101,219,50,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(50,219,171,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws70,
+                borderColor: 'rgba(50,219,171,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(50,118,219,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws80,
+                borderColor: 'rgba(50,118,219,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(140,50,219,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws90,
+                borderColor: 'rgba(140,50,219,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(202,50,219,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws100,
+                borderColor: 'rgba(202,50,219,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(50,199,219,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws110,
+                borderColor: 'rgba(50,199,219,0.2)',
+                borderWidth: 12
+              }
+            },
+          },
+          {
+            areaStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgba(219,143,50,0.3)'
+                }, {
+                  offset: 0.8,
+                  color: 'rgba(219, 50, 51, 0)'
+                }], false),
+                shadowColor: 'rgba(0, 0, 0, 0.1)',
+                shadowBlur: 10
+              }
+            },
+            itemStyle: {
+              normal: {
+                color: cc.ws120,
+                borderColor: 'rgba(219,143,50,0.2)',
+                borderWidth: 12
+              }
+            },
           }
         ]
       }
@@ -275,7 +487,7 @@
       this.chart = null
     },
     methods: {
-      draw(timeaxis,datas) {
+      draw(timeaxis,datas,ndatas) {
         this.chart = echarts.init(document.getElementById('nwpcharts'))
         var option = {
           backgroundColor: 'transparent',
@@ -319,6 +531,22 @@
               color: this.lineColor
             },
             selected:{
+              '10米风速': false,
+              '30米风速': false,
+              '50米风速': false,
+              '70米风速': false,
+              '80米风速': true,
+              '90米风速': false,
+              '100米风速': false,
+              '170米风速': false,
+              '实时10米风速': false,
+              '实时30米风速': false,
+              '实时50米风速': false,
+              '实时70米风速': false,
+              '实时80米风速': true,
+              '实时90米风速': false,
+              '实时100米风速': false,
+              '实时170米风速': false,
             }
           },
           dataZoom: [{
@@ -389,11 +617,11 @@
             }
           }
           option.legend.data.push(keyName)
-          if(index>5){
-            option.legend.selected[keyName] = false
-          }else{
-            option.legend.selected[keyName] = true
-          }
+          // if(index != 4 ){
+          //   option.legend.selected[keyName] = false
+          // }else{
+          //   option.legend.selected[keyName] = true
+          // }
           var sValue = {
             name: '',
             type: 'line',
@@ -417,6 +645,46 @@
           option.series.push(sValue)
           index++;
         }
+
+
+
+        for(var key in ndatas){
+          var keyName='';
+          for(var i = 0 ;i<this.nthFormat.length;i++){
+            if(key ==this.nthFormat[i].key ){
+              keyName =this.nthFormat[i].value;
+            }
+          }
+          option.legend.data.push(keyName)
+          // if(index != 4){
+          //   option.legend.selected[keyName] = false
+          // }else {
+          //   option.legend.selected[keyName] = true
+          // }
+          var nsValue = {
+            name: '',
+            type: 'line',
+            smooth: false,
+            symbol: 'circle',
+            symbolSize: 5,
+            showSymbol: false,
+            lineStyle: {
+              normal: {
+                width: 2
+              }
+            },
+            // areaStyle: {},
+            itemStyle: {},
+            data: []
+          }
+          nsValue.name = keyName
+          nsValue.data = ndatas[key]
+          // sValue.areaStyle = this.lineStyle[index].areaStyle
+          nsValue.itemStyle = this.lineStyle[index].itemStyle
+          option.series.push(nsValue)
+          index++;
+        }
+
         this.chart.setOption(option,true)
       },
 

+ 2 - 1
ipfcst/ipfcst-reportquery/src/main/frontend/views/realTimeQuery/nwp/index.vue

@@ -142,7 +142,7 @@
         tableLoading:true,
         resizeKey:1,
         activeName: 'first',
-        drawData:{datas:[],times:[]},
+        drawData:{datas:[],times:[],ndatas:[]},
         tableData:[],
         statisticsData:[],
         total:0,
@@ -195,6 +195,7 @@
         this.drawLoading = true
         this.$axios.get('/nwp/'+startTime+'/'+endTime).then((res) => {
           this.drawData = res.data
+          console.log(res.data.ndatas);
           this.drawLoading = false
           if(!this.drawLoading && !this.tableLoading){
             this.loading = false

+ 67 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/CutOutSpeedSpecifyInfoController.java

@@ -0,0 +1,67 @@
+package com.jiayue.ipfcst.controller;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
+import com.jiayue.ipfcst.common.data.entity.CutOutSpeedSpecifyInfo;
+import com.jiayue.ipfcst.service.CutOutSpeedSpecifyInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author shd
+ * @since 2022-05-31
+ */
+@RestController
+@RequestMapping("/cutOutSpeedSpecifyInfo")
+public class CutOutSpeedSpecifyInfoController {
+  @Autowired
+  private CutOutSpeedSpecifyInfoService cutOutSpeedSpecifyInfoService;
+
+  /**
+   * 新增
+   * @param cutOutSpeedSpecifyInfo
+   * @return
+   */
+  @PostMapping
+  public ResponseVO insert(@RequestBody CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo){
+    this.cutOutSpeedSpecifyInfoService.add(cutOutSpeedSpecifyInfo);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 修改 检修计划接口
+   */
+  @PutMapping
+  public ResponseVO update(@RequestBody CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo) throws BusinessException {
+    this.cutOutSpeedSpecifyInfoService.save(cutOutSpeedSpecifyInfo);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 删除 检修计划接口
+   * @param cutOutSpeedSpecifyInfo
+   * @return 操作结果
+   */
+  @DeleteMapping
+  public ResponseVO delete(@RequestBody CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo){
+    this.cutOutSpeedSpecifyInfoService.delete(cutOutSpeedSpecifyInfo.getId());
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 获取 检修计划接口
+   * @param page 页码
+   * @param size 条数
+   * @return 操作结果
+   */
+  @GetMapping(value = "/{page}/{size}")
+  public ResponseVO get(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
+    Map<String,Object> map = new HashMap<>();
+    map = this.cutOutSpeedSpecifyInfoService.get(page,size);
+    return ResponseVO.success(map);
+  }
+}
+

+ 68 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/FanUnitInfoController.java

@@ -0,0 +1,68 @@
+package com.jiayue.ipfcst.controller;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
+import com.jiayue.ipfcst.common.data.entity.FanUnitInfo;
+import com.jiayue.ipfcst.service.FanUnitInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author shd
+ * @since 2022-05-31
+ */
+@RestController
+@RequestMapping("/fanUnitInfo")
+public class FanUnitInfoController {
+
+  @Autowired
+  private FanUnitInfoService fanUnitInfoService;
+
+  /**
+   * 新增
+   * @param fanUnitInfo
+   * @return
+   */
+  @PostMapping
+  public ResponseVO insert(@RequestBody FanUnitInfo fanUnitInfo){
+    this.fanUnitInfoService.add(fanUnitInfo);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 修改 检修计划接口
+   */
+  @PutMapping
+  public ResponseVO update(@RequestBody FanUnitInfo fanUnitInfo) throws BusinessException {
+    this.fanUnitInfoService.save(fanUnitInfo);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 删除 检修计划接口
+   * @param fanUnitInfo
+   * @return 操作结果
+   */
+  @DeleteMapping
+  public ResponseVO delete(@RequestBody FanUnitInfo fanUnitInfo){
+    this.fanUnitInfoService.delete(fanUnitInfo.getId());
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 获取 检修计划接口
+   * @param page 页码
+   * @param size 条数
+   * @return 操作结果
+   */
+  @GetMapping(value = "/{page}/{size}")
+  public ResponseVO get(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
+    Map<String,Object> map = new HashMap<>();
+    map = this.fanUnitInfoService.get(page,size);
+    return ResponseVO.success(map);
+  }
+}
+

+ 89 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/ReadToMysqlController.java

@@ -0,0 +1,89 @@
+package com.jiayue.ipfcst.controller;
+
+import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
+import com.jiayue.ipfcst.common.data.repository.WindSpeedPointInfoRepository;
+import com.jiayue.ipfcst.common.data.repository.WindTurbinePowerCurveRepository;
+import com.jiayue.ipfcst.util.ReadtoMysql;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.sql.SQLException;
+
+/**
+ * @author shd
+ * @since 2022-06-02
+ */
+@RestController
+@RequestMapping("/readToMysql")
+public class ReadToMysqlController {
+
+  @Autowired
+  WindSpeedPointInfoRepository windSpeedPointInfoRepository;
+  @Autowired
+  WindTurbinePowerCurveRepository windTurbinePowerCurveRepository;
+  /**
+   * 读取机组信息
+   * @return
+   */
+  @GetMapping("/getFanUnitInfo")
+  public ResponseVO getFanUnitInfo() {
+    try {
+
+      return ReadtoMysql.readFanUnitInfo();
+    } catch (Exception e) {
+      e.printStackTrace();
+      return ResponseVO.error(e);
+    }
+  }
+
+  /**
+   * 读取切除
+   * @return
+   */
+  @GetMapping("/cutOutSpeedSpecifyInfo")
+  public ResponseVO getCutOutSpeedSpecifyInfo(){
+    try {
+
+      return ReadtoMysql.readFanCutOutSpeedInfo();
+    } catch (SQLException e) {
+      e.printStackTrace();
+      return ResponseVO.error(e);
+    }
+  }
+
+  /**
+   * 读取风速点表
+   * @return
+   */
+  @GetMapping("/readSpeedSheet")
+  public ResponseVO getSpeedSheet(){
+    try {
+      if(windSpeedPointInfoRepository.findAll().size() > 0){
+        windSpeedPointInfoRepository.deleteAll();
+      }
+      return ReadtoMysql.readSpeedSheet();
+    } catch (SQLException e) {
+      e.printStackTrace();
+      return ResponseVO.error(e);
+    }
+  }
+
+  /**
+   * 读取功率曲线
+   * @return
+   */
+  @GetMapping("/readWindTurbinePowerCurveMap")
+  public ResponseVO getReadWindTurbinePowerCurveMap(){
+    try {
+      if(windTurbinePowerCurveRepository.findAll().size() > 0){
+        windTurbinePowerCurveRepository.deleteAll();
+      }
+      return ReadtoMysql.readWindTurbinePowerCurveMap();
+    } catch (SQLException e) {
+      e.printStackTrace();
+      return ResponseVO.error(e);
+    }
+  }
+}

+ 93 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/WindSpeedPointInfoServiceController.java

@@ -0,0 +1,93 @@
+package com.jiayue.ipfcst.controller;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
+import com.jiayue.ipfcst.common.data.entity.WindSpeedPointInfo;
+import com.jiayue.ipfcst.service.WindSpeedPointInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author shd
+ * @since 2022-06-01
+ */
+@RestController
+@RequestMapping("/windSpeedPointInfo")
+public class WindSpeedPointInfoServiceController {
+
+  @Autowired
+  private WindSpeedPointInfoService windSpeedPointInfoService;
+
+  /**
+   * 新增
+   *
+   * @param windSpeedPointInfo
+   * @return
+   */
+  @PostMapping
+  public ResponseVO insert(@RequestBody WindSpeedPointInfo windSpeedPointInfo){
+    this.windSpeedPointInfoService.add(windSpeedPointInfo);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 删除
+   *
+   * @param windSpeedPointInfo
+   * @return
+   * @throws BusinessException
+   */
+  @PutMapping
+  public ResponseVO update(@RequestBody WindSpeedPointInfo windSpeedPointInfo) throws BusinessException {
+    this.windSpeedPointInfoService.save(windSpeedPointInfo);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 删除
+   *
+   * @param windSpeedPointInfo
+   * @return 操作结果
+   */
+  @DeleteMapping
+  public ResponseVO delete(@RequestBody WindSpeedPointInfo windSpeedPointInfo){
+    this.windSpeedPointInfoService.delete(windSpeedPointInfo.getId());
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 获取
+   *
+   * @param page 页码
+   * @param size 条数
+   * @return 操作结果
+   */
+  @GetMapping(value = "/{page}/{size}")
+  public ResponseVO get(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
+    Map<String,Object> map = new HashMap<>();
+    map = this.windSpeedPointInfoService.get(page,size);
+    return ResponseVO.success(map);
+  }
+
+  @GetMapping(value = "/{page}/{size}/{speed}")
+  public ResponseVO getBySpeed(@PathVariable("page") Integer page, @PathVariable("size") Integer size, @PathVariable("speed") float speed){
+    return ResponseVO.success(this.windSpeedPointInfoService.getBySpeed(page, size, speed));
+  }
+
+  @GetMapping(value = "/bySomeConditions/{page}/{size}/{fanNumber}/{wind}/{speed}/{unitBelongs}/{belong}")
+  public ResponseVO getBySomeConditions(@PathVariable("page") Integer page,
+                        @PathVariable("size") Integer size,
+                        @PathVariable("fanNumber") String fanNumber,
+                        @PathVariable("wind") Integer wind,
+                        @PathVariable("speed") Float speed,
+                        @PathVariable("unitBelongs") Integer unitBelongs,
+                        @PathVariable("belong") Integer belong){
+    Map<String, Object> map;
+    map = this.windSpeedPointInfoService.getBySomeConditions(page, size, fanNumber, wind, speed, unitBelongs, belong);
+    return ResponseVO.success(map);
+  }
+}
+

+ 78 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/controller/WindTurbinePowerCurveController.java

@@ -0,0 +1,78 @@
+package com.jiayue.ipfcst.controller;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
+import com.jiayue.ipfcst.common.data.entity.WindSpeedPointInfo;
+import com.jiayue.ipfcst.common.data.entity.WindTurbinePowerCurve;
+import com.jiayue.ipfcst.service.WindTurbinePowerCurveService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author shd
+ * @since 2022-06-01
+ */
+@RestController
+@RequestMapping("/windTurbinePowerCurve")
+public class WindTurbinePowerCurveController {
+  @Autowired
+  private WindTurbinePowerCurveService windTurbinePowerCurveService;
+
+  /**
+   * 新增
+   * @param windTurbinePowerCurve
+   * @return
+   */
+  @PostMapping
+  public ResponseVO insert(@RequestBody WindTurbinePowerCurve windTurbinePowerCurve){
+    this.windTurbinePowerCurveService.add(windTurbinePowerCurve);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 修改
+   */
+  @PutMapping
+  public ResponseVO update(@RequestBody WindTurbinePowerCurve windTurbinePowerCurve) throws BusinessException {
+    this.windTurbinePowerCurveService.save(windTurbinePowerCurve);
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 删除
+   * @param windTurbinePowerCurve
+   * @return 操作结果
+   */
+  @DeleteMapping
+  public ResponseVO delete(@RequestBody WindTurbinePowerCurve windTurbinePowerCurve){
+    this.windTurbinePowerCurveService.delete(windTurbinePowerCurve.getId());
+    return ResponseVO.success(1);
+  }
+
+  /**
+   * 获取
+   * @param page 页码
+   * @param size 条数
+   * @return 操作结果
+   */
+  @GetMapping(value = "/{page}/{size}")
+  public ResponseVO get(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
+    Map<String,Object> map = new HashMap<>();
+    map = this.windTurbinePowerCurveService.get(page,size);
+    return ResponseVO.success(map);
+  }
+
+  /**
+   * 曲线数据
+   * @return
+   */
+  @GetMapping(value = "/new")
+  public ResponseVO getBySpeedBetweenForPage(){
+    Map<String, Object> map;
+    map = this.windTurbinePowerCurveService.getByFanId();
+    return ResponseVO.success(map);
+  }
+}

+ 104 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/CutOutSpeedSpecifyInfoService.java

@@ -0,0 +1,104 @@
+package com.jiayue.ipfcst.service;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.data.entity.CutOutSpeedSpecifyInfo;
+import com.jiayue.ipfcst.common.data.repository.CutOutSpeedSpecifyInfoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.Predicate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author shd
+ * @since 2022-05-31
+ */
+@Service
+public class CutOutSpeedSpecifyInfoService {
+
+    private CutOutSpeedSpecifyInfoRepository cutOutSpeedSpecifyInfoRepository;
+
+    @Autowired
+    public CutOutSpeedSpecifyInfoService(CutOutSpeedSpecifyInfoRepository cutOutSpeedSpecifyInfoRepository){
+      this.cutOutSpeedSpecifyInfoRepository = cutOutSpeedSpecifyInfoRepository;
+    }
+    /**
+     * 新增
+     *
+     * @param cutOutSpeedSpecifyInfo 实体
+     */
+    public void add(CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo) {
+      this.cutOutSpeedSpecifyInfoRepository.save(cutOutSpeedSpecifyInfo);
+    }
+
+    /**
+     * 删除
+     *
+     * @param id 主键
+     */
+    public void delete(final Integer id) {
+      this.cutOutSpeedSpecifyInfoRepository.deleteById(id);
+    }
+
+    /**
+     * 修改检修计划信息
+     *
+     * @param cutOutSpeedSpecifyInfo
+     * @throws BusinessException
+     */
+    public void save(CutOutSpeedSpecifyInfo cutOutSpeedSpecifyInfo) throws BusinessException {
+      if (String.valueOf(cutOutSpeedSpecifyInfo.getId()) == null) {
+        throw new BusinessException("修改时主键不能为空");
+      } else {
+        this.cutOutSpeedSpecifyInfoRepository.save(cutOutSpeedSpecifyInfo);
+      }
+    }
+
+
+    /**
+     * 查询全部
+     * @return
+     */
+    public List<CutOutSpeedSpecifyInfo> getAll(){
+      return cutOutSpeedSpecifyInfoRepository.findAll();
+    }
+
+    /**
+     * (分页)
+     */
+    public Map<String, Object> get(Integer page, Integer size) {
+      Map<String, Object> map = new HashMap<>();
+      Specification<CutOutSpeedSpecifyInfo> specification = this.Specification();
+      Pageable pageable = PageRequest.of(page - 1, size);
+      Page windTowerStatusDatas = cutOutSpeedSpecifyInfoRepository.findAll(specification, pageable);
+      List<CutOutSpeedSpecifyInfo> wList = windTowerStatusDatas.getContent();
+      map.put("content", wList);
+      map.put("count", windTowerStatusDatas.getTotalElements());
+      return map;
+    }
+
+
+
+
+    /**
+     * 查询条件 yh
+     *
+     * @return 过滤条件
+     */
+    Specification<CutOutSpeedSpecifyInfo> Specification() {
+      return (Specification<CutOutSpeedSpecifyInfo>) (root, criteriaQuery, cb) -> {
+        List<Predicate> predicates = new ArrayList<>();
+        //添加排序的功能
+        return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+
+      };
+    }
+
+}

+ 115 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/FanUnitInfoService.java

@@ -0,0 +1,115 @@
+package com.jiayue.ipfcst.service;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.data.entity.FanUnitInfo;
+import com.jiayue.ipfcst.common.data.repository.FanUnitInfoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.Predicate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author shd
+ * @since 2022-05-31
+ */
+@Service
+public class FanUnitInfoService {
+
+  private FanUnitInfoRepository fanUnitInfoRepository;
+
+  @Autowired
+  public FanUnitInfoService(FanUnitInfoRepository fanUnitInfoRepository){
+    this.fanUnitInfoRepository = fanUnitInfoRepository;
+  }
+
+  /**
+   * 新增机组
+   *
+   * @param fanUnitInfo 机组实体
+   */
+  public void add(FanUnitInfo fanUnitInfo) {
+    this.fanUnitInfoRepository.save(fanUnitInfo);
+  }
+
+  /**
+   * 删除
+   *
+   * @param id 主键
+   */
+  public void delete(final Integer id) {
+    this.fanUnitInfoRepository.deleteById(id);
+  }
+
+  /**
+   * 修改检修计划信息
+   *
+   * @param fanUnitInfo
+   * @throws BusinessException
+   */
+  public void save(FanUnitInfo fanUnitInfo) throws BusinessException {
+    if (String.valueOf(fanUnitInfo.getId()) == null) {
+      throw new BusinessException("修改时主键不能为空");
+    } else {
+      this.fanUnitInfoRepository.save(fanUnitInfo);
+    }
+  }
+
+
+  /**
+   * 查询全部
+   * @return
+   */
+  public List<FanUnitInfo> getAll(){
+    return fanUnitInfoRepository.findAll();
+  }
+
+  /**
+   * (分页)
+   */
+  public Map<String, Object> get(Integer page, Integer size) {
+    Map<String, Object> map = new HashMap<>();
+    Specification<FanUnitInfo> specification = this.Specification();
+    Pageable pageable = PageRequest.of(page - 1, size);
+    Page windTowerStatusDatas = fanUnitInfoRepository.findAll(specification, pageable);
+    List<FanUnitInfo> wList = windTowerStatusDatas.getContent();
+    map.put("content", wList);
+    map.put("count", windTowerStatusDatas.getTotalElements());
+    return map;
+  }
+
+
+
+
+  /**
+   * 查询条件 yh
+   *
+   * @return 过滤条件
+   */
+  Specification<FanUnitInfo> Specification() {
+    return (Specification<FanUnitInfo>) (root, criteriaQuery, cb) -> {
+      List<Predicate> predicates = new ArrayList<>();
+//      if (startTime!=null) {
+//        //大于或等于传入时间
+//        predicates.add(cb.greaterThanOrEqualTo(root.get("time").as(Date.class), startTime));
+//      }
+//      if (endTime!=null) {
+//        //小于传入时间
+//        predicates.add(cb.lessThan(root.get("time").as(Date.class), endTime));
+//      }
+//      if(no!=null){
+//        predicates.add(cb.equal(root.get("equipmentNo").as(Integer.class), no));
+//      }
+      //添加排序的功能
+      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+
+    };
+  }
+}

+ 130 - 1
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/NwpService.java

@@ -6,8 +6,10 @@ import com.jiayue.ipfcst.common.core.util.DateMomentUtil;
 import com.jiayue.ipfcst.common.data.entity.ElectricField;
 import com.jiayue.ipfcst.common.data.entity.Nwp;
 import com.jiayue.ipfcst.common.data.entity.SysParameter;
+import com.jiayue.ipfcst.common.data.entity.WindTowerStatusData;
 import com.jiayue.ipfcst.common.data.repository.NwpRepository;
 import com.jiayue.ipfcst.common.data.repository.SysParameterRepository;
+import com.jiayue.ipfcst.common.data.repository.WindTowerStatusDataRepository;
 import com.jiayue.ipfcst.common.data.service.BaseService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.time.DateFormatUtils;
@@ -41,10 +43,14 @@ public class NwpService extends BaseService {
   private final NwpRepository nwpRepository;
 
   private final SysParameterRepository sysParameterRepository;
+
+  private final WindTowerStatusDataRepository windTowerStatusDataRepository;
+
   @Autowired
-  public NwpService(NwpRepository nwpRepository,SysParameterRepository sysParameterRepository){
+  public NwpService(NwpRepository nwpRepository, SysParameterRepository sysParameterRepository, WindTowerStatusDataRepository windTowerStatusDataRepository){
     this.nwpRepository = nwpRepository;
     this.sysParameterRepository = sysParameterRepository;
+    this.windTowerStatusDataRepository = windTowerStatusDataRepository;
   }
   /**
    * 按时间查询实时NWP yh
@@ -162,11 +168,95 @@ public class NwpService extends BaseService {
     map.put("cName",map1);
     map.put("times",times);
     map.put("datas",datas);
+    Map<String,Object> nMap = findRealNwpByTimeBetween(startTime, endTime);
+    map.put("ndatas",nMap.get("ndatas"));
+    map.put("ncName",nMap.get("ncName"));
     return map;
   }
 
+  /**
+   * 实时nwp
+   *
+   * @param startTime
+   * @param endTime
+   * @return
+   * @throws BusinessException
+   */
+  public Map<String,Object> findRealNwpByTimeBetween(Long startTime, Long endTime) throws BusinessException {
+    Map<String,Object> map = new HashMap<>();
+    List<WindTowerStatusData> list = new ArrayList<>();
+    List<WindTowerStatusData> checkList = new ArrayList<>();
+    Map<String,Object> datas = new LinkedHashMap<>();
+    list = windTowerStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
+    list.sort(Comparator.comparing(WindTowerStatusData::getTime));
+    long startTimeLong  = startTime;
+    long endTimeLong  = endTime;
+    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    long timeStep = 900000L;
+    if(startTimeLong%timeStep !=0){
+      startTimeLong = startTimeLong -(startTimeLong%timeStep);
+    }
+
+    for(long i = startTimeLong;i<endTimeLong;i=i+timeStep){
+      long finalI = i;
+      List<WindTowerStatusData> p = list.stream().filter(t -> t.getTime().getTime() == finalI).collect(Collectors.toList());
+      if (p != null && p.size() > 0) {
+        checkList.add(p.get(0));
+      }else{
+        checkList.add(new WindTowerStatusData());
+      }
+    }
+    this.defaultRealReplace(checkList);
 
 
+    ElectricField electricField = this.getElectricField();
+    List<BigDecimal> ws10Collect = new ArrayList<>();
+    List<BigDecimal> ws30Collect= new ArrayList<>();
+    List<BigDecimal> ws50Collect= new ArrayList<>();
+    List<BigDecimal> ws70Collect= new ArrayList<>();
+    List<BigDecimal> ws80Collect= new ArrayList<>();
+    List<BigDecimal> ws90Collect= new ArrayList<>();
+    List<BigDecimal> ws100Collect= new ArrayList<>();
+    List<BigDecimal> ws170Collect= new ArrayList<>();
+    Map<String,String> map1 = new HashMap<>();
+    if(electricField.getElectricFieldTypeEnum().getCode() == 1){
+
+    }else{
+      ws10Collect = checkList.stream().map(WindTowerStatusData::getWsInst10).collect(Collectors.toList());
+      ws30Collect = checkList.stream().map(WindTowerStatusData::getWsInst30).collect(Collectors.toList());
+      ws50Collect = checkList.stream().map(WindTowerStatusData::getWsInst50).collect(Collectors.toList());
+      ws70Collect = checkList.stream().map(WindTowerStatusData::getWsInst70).collect(Collectors.toList());
+      ws80Collect = checkList.stream().map(WindTowerStatusData::getWsInst80).collect(Collectors.toList());
+      ws90Collect = checkList.stream().map(WindTowerStatusData::getWsInst90).collect(Collectors.toList());
+      ws100Collect = checkList.stream().map(WindTowerStatusData::getWsInst100).collect(Collectors.toList());
+      ws170Collect = checkList.stream().map(WindTowerStatusData::getWsInst110).collect(Collectors.toList());
+      datas.put("wsInst10",ws10Collect);
+      datas.put("wsInst30",ws30Collect);
+      datas.put("wsInst50",ws50Collect);
+      datas.put("wsInst70",ws70Collect);
+      datas.put("wsInst80",ws80Collect);
+      datas.put("wsInst90",ws90Collect);
+      datas.put("wsInst100",ws100Collect);
+      datas.put("wsInst170",ws170Collect);
+
+
+    }
+
+    map1.put("wsInst10","实时10米风速");
+    map1.put("wsInst30","实时30米风速");
+    map1.put("wsInst50","实时50米风速");
+    map1.put("wsInst70","实时70米风速");
+    map1.put("wsInst80","实时80米风速");
+    map1.put("wsInst90","实时90米风速");
+    map1.put("wsInst100","实时100米风速");
+    map1.put("wsInst170","实时170米风速");
+
+    map.put("ndatas", datas);
+    map.put("ncName", map1);
+  return map;
+
+  }
+
   /**
    * 根据时间 分页查询 NWP数据 yh
    *
@@ -464,6 +554,45 @@ public class NwpService extends BaseService {
 
   }
 
+  /**
+   *  对集合进行 -99替换null操作,主要用于图标展示空值
+   *
+   * @param datas  需要替换集合
+   */
+  public void defaultRealReplace(List<WindTowerStatusData> datas){
+    BigDecimal nullBig =  new BigDecimal(-99);
+    for(WindTowerStatusData i :datas){
+
+
+
+      if(i.getWsInst10().compareTo(nullBig)==0){
+        i.setWsInst10(null);
+      }
+      if(i.getWsInst30().compareTo(nullBig)==0){
+        i.setWsInst30(null);
+      }
+      if(i.getWsInst50().compareTo(nullBig)==0){
+        i.setWsInst50(null);
+      }
+      if(i.getWsInst70().compareTo(nullBig)==0){
+        i.setWsInst70(null);
+      }
+      if(i.getWsInst80().compareTo(nullBig)==0){
+        i.setWsInst80(null);
+      }
+      if(i.getWsInst90().compareTo(nullBig)==0){
+        i.setWsInst90(null);
+      }
+      if(i.getWsInst100().compareTo(nullBig)==0){
+        i.setWsInst100(null);
+      }
+      if(i.getWsInst110().compareTo(nullBig)==0){
+        i.setWsInst110(null);
+      }
+
+    }
+
+  }
 
   /**
    * (统计查询:nwp风速统计(吉林22))

+ 176 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/WindSpeedPointInfoService.java

@@ -0,0 +1,176 @@
+package com.jiayue.ipfcst.service;
+
+import com.alibaba.druid.util.StringUtils;
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.data.entity.WindSpeedPointInfo;
+import com.jiayue.ipfcst.common.data.entity.WindTurbineStatusData;
+import com.jiayue.ipfcst.common.data.repository.WindSpeedPointInfoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.Predicate;
+import java.sql.Wrapper;
+import java.util.*;
+
+/**
+ *
+ *
+ * @author shd
+ * @since 2022-06-01
+ */
+@Service
+public class WindSpeedPointInfoService {
+  private WindSpeedPointInfoRepository windSpeedPointInfoRepository;
+
+  @Autowired
+  public WindSpeedPointInfoService(WindSpeedPointInfoRepository windSpeedPointInfoRepository){
+    this.windSpeedPointInfoRepository = windSpeedPointInfoRepository;
+  }
+
+  /**
+   * 新增
+   *
+   * @param windSpeedPointInfo 实体
+   */
+  public void add(WindSpeedPointInfo windSpeedPointInfo) {
+    this.windSpeedPointInfoRepository.save(windSpeedPointInfo);
+  }
+
+  /**
+   * 删除
+   *
+   * @param id 主键
+   */
+  public void delete(final Integer id) {
+    this.windSpeedPointInfoRepository.deleteById(id);
+  }
+
+  /**
+   * 修改
+   *
+   * @param windSpeedPointInfo
+   * @throws BusinessException
+   */
+  public void save(WindSpeedPointInfo windSpeedPointInfo) throws BusinessException {
+    if (String.valueOf(windSpeedPointInfo.getId()) == null) {
+      throw new BusinessException("修改时主键不能为空");
+    } else {
+      this.windSpeedPointInfoRepository.save(windSpeedPointInfo);
+    }
+  }
+
+  /**
+   * (分页)
+   */
+  public Map<String, Object> get(Integer page, Integer size) {
+    Map<String, Object> map = new HashMap<>();
+    Specification<WindSpeedPointInfo> specification = this.Specification();
+    Pageable pageable = PageRequest.of(page - 1, size);
+    Page windTowerStatusDatas = windSpeedPointInfoRepository.findAll(specification, pageable);
+    List<WindSpeedPointInfo> wList = windTowerStatusDatas.getContent();
+    map.put("content", wList);
+    map.put("count", windTowerStatusDatas.getTotalElements());
+    return map;
+  }
+
+  /**
+   * 根据风速查询
+   *
+   * @param page
+   * @param size
+   * @param speed
+   * @return
+   */
+  public Map<String, Object> getBySpeed(Integer page, Integer size,float speed){
+    Map<String, Object> map = new HashMap<>();
+    Specification<WindSpeedPointInfo> specification = this.Specification();
+    Pageable pageable = PageRequest.of(page - 1, size);
+    Page<WindSpeedPointInfo> bySpeedContaining = windSpeedPointInfoRepository.findBySpeedContaining( speed, pageable);
+    List<WindSpeedPointInfo> wList = bySpeedContaining.getContent();
+    map.put("content", wList);
+    map.put("count", bySpeedContaining.getTotalElements());
+    return map;
+  }
+
+  /**
+   * 获取全部
+   * @return
+   */
+  public List<WindSpeedPointInfo> getAll(){
+    return this.windSpeedPointInfoRepository.findAll();
+  }
+
+
+  public Map<String, Object> getBySomeConditions(Integer page, Integer size, String FanNumber,Integer wind, Float speed, Integer unitBelongs, Integer belong){
+    Map<String, Object> map = new HashMap<>();
+    WindSpeedPointInfo windSpeedPointInfo = new WindSpeedPointInfo();
+    windSpeedPointInfo.setFanNumber(FanNumber);
+    windSpeedPointInfo.setWind(wind);
+    windSpeedPointInfo.setSpeed(speed);
+    windSpeedPointInfo.setUnitBelongs(unitBelongs);
+    windSpeedPointInfo.setBelong(belong);
+    Specification<WindSpeedPointInfo> specification = this.specificationBySomeConditions(windSpeedPointInfo);
+    Pageable pageable = PageRequest.of(page - 1, size);
+    Page<WindSpeedPointInfo> windSpeedPointInfos = windSpeedPointInfoRepository.findAll(specification, pageable);
+    List<WindSpeedPointInfo> windSpeedPointInfoList = windSpeedPointInfos.getContent();
+    map.put("content", windSpeedPointInfoList);
+    map.put("count", windSpeedPointInfos.getTotalElements());
+    return map;
+  }
+
+
+  /**
+   * 查询条件 yh
+   *
+   * @return 过滤条件
+   */
+  Specification<WindSpeedPointInfo> Specification() {
+    return (root, criteriaQuery, cb) -> {
+      List<Predicate> predicates = new ArrayList<>();
+      //添加排序的功能
+      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+
+    };
+  }
+
+
+  Specification<WindSpeedPointInfo> specificationBySomeConditions(final WindSpeedPointInfo windSpeedPointInfo) {
+    return (Specification<WindSpeedPointInfo>) (root, criteriaQuery, cb) -> {
+      List<Predicate> predicates = new ArrayList<>();
+
+      // 风机编号模糊查询
+      if (!StringUtils.isEmpty(windSpeedPointInfo.getFanNumber())) {
+        predicates.add(cb.equal(root.get("fanNumber"), windSpeedPointInfo.getWind()));
+      }
+
+      // 风向查询
+      if (!StringUtils.isEmpty(Integer.toString(windSpeedPointInfo.getWind()))) {
+        predicates.add(cb.like(root.get("wind"), "%"+windSpeedPointInfo.getFanNumber()+"%"));
+      }
+
+      // 风速查询
+      if (!StringUtils.isEmpty(Float.toString(windSpeedPointInfo.getSpeed()))) {
+        predicates.add(cb.equal(root.get("speed"), windSpeedPointInfo.getSpeed()));
+      }
+
+      // 所属机组
+      if (!StringUtils.isEmpty(Integer.toString(windSpeedPointInfo.getUnitBelongs()))) {
+        predicates.add(cb.equal(root.get("UnitBelongs"), windSpeedPointInfo.getUnitBelongs()));
+      }
+
+      // 所属行
+      if (!StringUtils.isEmpty(Integer.toString(windSpeedPointInfo.getUnitBelongs()))) {
+        predicates.add(cb.equal(root.get("belong"), windSpeedPointInfo.getBelong()));
+      }
+
+      //添加排序的功能
+      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+
+    };
+  }
+
+}

+ 141 - 0
ipfcst/ipfcst-reportquery/src/main/java/com/jiayue/ipfcst/service/WindTurbinePowerCurveService.java

@@ -0,0 +1,141 @@
+package com.jiayue.ipfcst.service;
+
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
+import com.jiayue.ipfcst.common.data.entity.WindTurbinePowerCurve;
+import com.jiayue.ipfcst.common.data.repository.WindTurbinePowerCurveRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.Predicate;
+import java.text.DecimalFormat;
+import java.util.*;
+
+/**
+ * @author shd
+ * @since 2022-06-01
+ */
+@Service
+public class WindTurbinePowerCurveService {
+  private WindTurbinePowerCurveRepository windTurbinePowerCurveRepository;
+  @Autowired
+  public WindTurbinePowerCurveService(WindTurbinePowerCurveRepository windTurbinePowerCurveRepository){
+    this.windTurbinePowerCurveRepository = windTurbinePowerCurveRepository;
+  }
+
+  /**
+   * 新增
+   *
+   * @param windTurbinePowerCurve 实体
+   */
+  public void add(WindTurbinePowerCurve windTurbinePowerCurve) {
+    this.windTurbinePowerCurveRepository.save(windTurbinePowerCurve);
+  }
+
+  /**
+   * 删除
+   *
+   * @param id 主键
+   */
+  public void delete(final Integer id) {
+    this.windTurbinePowerCurveRepository.deleteById(id);
+  }
+
+  /**
+   * 修改
+   *
+   * @param windTurbinePowerCurve
+   * @throws BusinessException
+   */
+  public void save(WindTurbinePowerCurve windTurbinePowerCurve) throws BusinessException {
+    if (String.valueOf(windTurbinePowerCurve.getId()) == null) {
+      throw new BusinessException("修改时主键不能为空");
+    } else {
+      this.windTurbinePowerCurveRepository.save(windTurbinePowerCurve);
+    }
+  }
+
+  /**
+   * 查询所有
+   * @return
+   */
+  public List<WindTurbinePowerCurve> getAll(){
+    return windTurbinePowerCurveRepository.findAll();
+  }
+
+
+  /**
+   * (分页)
+   */
+  public Map<String, Object> get(Integer page, Integer size) {
+    Map<String, Object> map = new HashMap<>();
+    Specification<WindTurbinePowerCurve> specification = this.Specification();
+    Pageable pageable = PageRequest.of(page - 1, size);
+    Page windTowerStatusDatas = windTurbinePowerCurveRepository.findAll(specification, pageable);
+    List<WindTurbinePowerCurve> wList = windTowerStatusDatas.getContent();
+    map.put("content", wList);
+    map.put("count", windTowerStatusDatas.getTotalElements());
+    return map;
+  }
+
+  /**
+   * 曲线数据
+   * @return
+   */
+  public Map<String, Object> getByFanId() {
+    Map<String, Object> map = new HashMap<>();
+
+    DecimalFormat df1 = new DecimalFormat("#.00");
+    List<String> xData = new ArrayList<>();
+    List<WindTurbinePowerCurve> wList = this.getAll();
+    List<Float> w1List = new ArrayList<>();
+    List<Float> w2List = new ArrayList<>();
+    List<Float> w3List = new ArrayList<>();
+    List<Float> w4List = new ArrayList<>();
+    List<Float> w5List = new ArrayList<>();
+    for(WindTurbinePowerCurve w: wList){
+      if(w.getFanId() == 1){
+        w1List.add(w.getPower());
+      }else if(w.getFanId() == 2){
+        w2List.add(w.getPower());
+      }else if(w.getFanId() == 3){
+        w3List.add(w.getPower());
+      }else if(w.getFanId() == 4){
+        w4List.add(w.getPower());
+      }else {
+        w5List.add(w.getPower());
+      }
+    }
+    float j = 1;
+    for(int i = 0; i <= 190; i++){
+      xData.add(df1.format(j));
+      j = j + 0.1f;
+    }
+
+    map.put("Fan1",w1List);
+    map.put("Fan2",w2List);
+    map.put("Fan3",w3List);
+    map.put("Fan4",w4List);
+    map.put("Fan5",w5List);
+    map.put("xData", xData);
+    return map;
+  }
+
+  /**
+   * 查询条件 yh
+   *
+   * @return 过滤条件
+   */
+  Specification<WindTurbinePowerCurve> Specification() {
+    return (root, criteriaQuery, cb) -> {
+      List<Predicate> predicates = new ArrayList<>();
+      //添加排序的功能
+      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+    };
+  }
+
+}
+

+ 15 - 0
ipfcst/ipfcst-reportquery/src/main/resources/db.setting

@@ -0,0 +1,15 @@
+## db.setting文件
+
+url = jdbc:mysql://localhost:3306/ipfcst-v3-mts?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
+user = root
+pass = song
+
+## 可选配置
+# 是否在日志中显示执行的SQL
+showSql = true
+# 是否格式化显示的SQL
+formatSql = false
+# 是否显示SQL参数
+showParams = true
+# 打印SQL的日志等级,默认debug,可以是info、warn、error
+sqlLevel = debug