Ver Fonte

这次提交的有点多1.飔合科技相关2.武穴相关3.林洋相关4.浙江广洋一体化

fanxiaoyu há 3 meses atrás
pai
commit
cbf8e8649c
50 ficheiros alterados com 2871 adições e 192 exclusões
  1. 4 0
      in-client-qn-ui/src/views/data/backstatdata/index.vue
  2. 8 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/constant/CommonStant.java
  3. 9 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/constant/TemplateStant.java
  4. 3 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/inenum/QNHLEnum.java
  5. 62 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/ActualPowerFeedbackForJYJob.java
  6. 32 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/SHComPermissonJob.java
  7. 126 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/permisson/com/SHComPermisson.java
  8. 9 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pushData/IPushRealValueData.java
  9. 178 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pushData/PushRealValueData.java
  10. 1 1
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/BackForeUsForecastDataService.java
  11. 2 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/BackStatDataService.java
  12. 51 1
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/BackDataAnalysisService.java
  13. 50 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/BackDataGenBodyService.java
  14. 22 3
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/InitRunner.java
  15. 114 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/RequestDataService.java
  16. 690 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/SHCorrforeService.java
  17. 8 1
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/impl/BackStatDataServiceImpl.java
  18. 1 1
      in-client-qn/src/main/resources/vms/DQ.vm
  19. 26 1
      in-cloud/src/main/java/com/jiayue/insu/incloud/controller/ApiController.java
  20. 53 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/entity/MonthPowerGeneration.java
  21. 54 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/entity/PowerGeneration.java
  22. 40 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/entity/PowerStationStatusData.java
  23. 40 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/job/powerGeneration/MonthPowerGenerationJob.java
  24. 40 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/job/powerGeneration/PowerGenerationJob.java
  25. 12 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/MonthPowerGenerationMapper.java
  26. 12 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/PowerGenerationMapper.java
  27. 12 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/PowerStationStatusDataMapper.java
  28. 233 103
      in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForQNHL.java
  29. 7 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/ApiService.java
  30. 2 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/ForecastDataService.java
  31. 22 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/MonthPowerGenerationService.java
  32. 25 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/PowerGenerationService.java
  33. 16 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/PowerStationStatusDataService.java
  34. 70 4
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/ApiServiceImpl.java
  35. 9 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/ForecastDataServiceImpl.java
  36. 137 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/MonthPowerGenerationServiceImpl.java
  37. 288 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/PowerGenerationServiceImpl.java
  38. 44 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/PowerStationStatusDataServiceImpl.java
  39. 172 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/utils/FixedCapacityList.java
  40. 37 0
      in-passback/src/main/java/com/jiayue/passback/entity/AccuracyPassRate.java
  41. 6 0
      in-passback/src/main/java/com/jiayue/passback/entity/PowerStationStatusData.java
  42. 7 1
      in-passback/src/main/java/com/jiayue/passback/entity/eunm/PredictionModelEnum.java
  43. 28 28
      in-passback/src/main/java/com/jiayue/passback/job/GenerateService.java
  44. 30 30
      in-passback/src/main/java/com/jiayue/passback/job/job.java
  45. 7 0
      in-passback/src/main/java/com/jiayue/passback/mapper/AccuracyPassRateMapper.java
  46. 8 0
      in-passback/src/main/java/com/jiayue/passback/service/AccuracyPassRateService.java
  47. 39 0
      in-passback/src/main/java/com/jiayue/passback/service/impl/AccuracyPassRateServiceImpl.java
  48. 1 16
      in-passback/src/main/java/com/jiayue/passback/service/impl/PowerStationStatusDataServiceImpl.java
  49. 5 2
      in-passback/src/main/java/com/jiayue/passback/service/impl/UploadFileLogServiceImpl.java
  50. 19 0
      in-passback/src/main/resources/template/template.ftl

+ 4 - 0
in-client-qn-ui/src/views/data/backstatdata/index.vue

@@ -83,6 +83,10 @@
       <el-table-column show-overflow-tooltip label="气压" prop="pressure" />
       <el-table-column show-overflow-tooltip label="超短期上报" prop="reportStateForecastshort" />
       <el-table-column show-overflow-tooltip label="短期上报" prop="reportStateForecast" />
+      <el-table-column show-overflow-tooltip label="理论功率" prop="theoryPower" />
+      <el-table-column show-overflow-tooltip label="可用功率" prop="availablePower" />
+      <el-table-column show-overflow-tooltip label="限电信号" prop="powerLimitSign" />
+      <el-table-column show-overflow-tooltip label="两则准确率" prop="accuracy" />
 
     </el-table>
     <el-pagination

+ 8 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/constant/CommonStant.java

@@ -49,6 +49,14 @@ public interface CommonStant {
      */
     String RECORD_TYPE_CDQ_BACK_DATA_FILE = "BACK_CDQ_DATA_FILE";
 
+    /**
+     * 日志类型:回传实际功率
+     */
+    String RECORD_TYPE_REAL_VALUE_FOR_JY = "BACK_REAL_VALUE_DATA";
+
+    /**
+     *  武穴一体化场站标识
+     */
     String RECORD_TYPE_CDQ_FILE = "HGRXGG";
 
     /**

+ 9 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/constant/TemplateStant.java

@@ -73,6 +73,15 @@ public interface TemplateStant {
 
     String BACK_STAT_THEORY_POWER_TEMPLATE= "# 1" + CommonStant.SPACE3_CONSTANT + "{}"+ CommonStant.SPACE3_CONSTANT + "{}" + CommonStant.LINE_CONSTANT;
 
+    String BACK_STAT_ACCURACY_RATE_TITLE= "@" + CommonStant.SPACE1_CONSTANT + "序号" + CommonStant.SPACE3_CONSTANT + "两则准确率"+ CommonStant.LINE_CONSTANT;
+
+    String BACK_STAT_ACCURACY_RATE_TEMPLATE= "# 1" + CommonStant.SPACE4_CONSTANT + "{}" + CommonStant.LINE_CONSTANT;
+
+    String BACK_STAT_LIMIT_POWER_FLAG_TITLE= "@" + CommonStant.SPACE1_CONSTANT + "序号" + CommonStant.SPACE3_CONSTANT + "限电"+ CommonStant.LINE_CONSTANT;
+
+    String BACK_STAT_LIMIT_POWER_FLAG_TEMPLATE= "# 1" + CommonStant.SPACE3_CONSTANT + "{}" + CommonStant.LINE_CONSTANT;
+
+
     String HEADER_TEMPLATE = "<! Entity={}  time='{}' !>" + CommonStant.LINE_CONSTANT;
 
 

+ 3 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/inenum/QNHLEnum.java

@@ -33,6 +33,7 @@ public enum QNHLEnum {
     DATA_TODAYFORE_TYPE("TODAYFORE","TODAYFORE","优化后当日预测"),
     DATA_CORRULTRSHOR_TYPE("CORRULTRSHOR","CORRULTRSHOR","超短期修正"),
     DATA_ORIGINALCDQ_TYPE("ULTRASHORTTERMPRIMITIVE","ULTRASHORTTERMPRIMITIVE","原始超短期"),
+    DATA_REALVALUE_TYPE("REALVALUE","REALVALUE","实际功率"),
     DATA_REPAPLAN_TYPE("REPAPLAN","REPAPLAN","检修计划"),
     /**
      * 回传数据类型划分
@@ -42,6 +43,8 @@ public enum QNHLEnum {
     DATA_STAT_TYPE_RealPower("RealPower","RealPower","实发功率回传"),
     DATA_STAT_TYPE_TheoryPower("TheoryPower","TheoryPower","理论可用回传"),
     DATA_STAT_TYPE_RealWeather("RealWeather","RealWeather","实际气象回传"),
+    DATA_STAT_TYPE_AccuracyRate("AccuracyRate","AccuracyRate","两则准确率回传"),
+    DATA_STAT_TYPE_LimitPowerFlag("LimitPowerFlag","LimitPowerFlag","限电回传"),
     DATA_STAT_TYPE_ForecastPowerReport("ForecastPowerReport","ForecastPowerReport","短期上报状态回传"),
     DATA_STAT_TYPE_UltraShortTermForecastReport("UltraShortTermForecastReport","UltraShortTermForecastReport","超短期上报状态回传"),
 

+ 62 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/ActualPowerFeedbackForJYJob.java

@@ -0,0 +1,62 @@
+package com.jiayue.insu.inclientqn.job;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import com.jiayue.insu.inclientqn.constant.CommonStant;
+import com.jiayue.insu.inclientqn.entity.Record;
+import com.jiayue.insu.inclientqn.entity.Station;
+import com.jiayue.insu.inclientqn.inenum.StatusEnum;
+import com.jiayue.insu.inclientqn.pushData.PushRealValueData;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import com.jiayue.insu.inclientqn.service.StationService;
+import com.jiayue.insu.inclientqn.service.client.BackDataAnalysisService;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ *  实际功率回传嘉越一体化云定时任务
+ */
+public class ActualPowerFeedbackForJYJob implements Job {
+
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private PushRealValueData pushRealValueData;
+
+    @Override
+    public void execute(JobExecutionContext context) throws JobExecutionException {
+        //查询是否有今天成功记录 (为提高稳定性,该定时任务采取在规定时间段内 重复循环执行的定时策略,故:需要查询是否存在成功记录)
+        Record successRecord;
+        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+        // 查询全部场站信息
+        List<Station> stationList = stationService.findAll();
+        // 如果场站大于1个,则循环请求一体化修正数据
+        if (stationList != null && stationList.size() > 1) {
+            for (Station station : stationList) {
+                // 如果有执行记录,则不再执行
+                successRecord = recordService.findTimeAndTypeAndStateAndStationCode(localDateTime, CommonStant.RECORD_TYPE_REAL_VALUE_FOR_JY, StatusEnum.SUCCESS.getCode(), station.getStationCode());
+                if (successRecord != null) {
+                    return;
+                }
+                // 实际功率回传嘉越云
+                pushRealValueData.pushRealValueForJy(station,localDateTime);
+            }
+            // 如果场站大于1个,则直接请求一体化修正数据
+        } else if (stationList != null && stationList.size() == 1) {
+            successRecord = recordService.findTimeAndTypeAndState(localDateTime, CommonStant.RECORD_TYPE_REAL_VALUE_FOR_JY, StatusEnum.SUCCESS.getCode());
+            // 如果有执行记录,则不再执行
+            if (successRecord != null) {
+                return;
+            }
+            // 实际功率回传嘉越云
+            pushRealValueData.pushRealValueForJy(stationList.get(0),localDateTime);
+        }
+
+    }
+}

+ 32 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/SHComPermissonJob.java

@@ -0,0 +1,32 @@
+package com.jiayue.insu.inclientqn.job;
+
+import com.jiayue.insu.inclientqn.entity.Station;
+import com.jiayue.insu.inclientqn.permisson.com.SHComPermisson;
+import com.jiayue.insu.inclientqn.service.StationService;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * @description:  请求飔合科技交互权限
+ * @author: yuanhao
+ * @createDate: 2022/6/17
+ * @version: 1.0
+ */
+public class SHComPermissonJob implements Job {
+
+    @Autowired
+    private SHComPermisson shComPermisson;
+    @Autowired
+    private StationService stationService;
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        List<Station> stationList = stationService.findAll();
+//        for(Station station : stationList){
+//            shComPermisson.generateKey(station);
+//        }
+    }
+}

+ 126 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/permisson/com/SHComPermisson.java

@@ -0,0 +1,126 @@
+package com.jiayue.insu.inclientqn.permisson.com;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONUtil;
+import com.jiayue.insu.inclientqn.constant.CommonStant;
+import com.jiayue.insu.inclientqn.entity.Record;
+import com.jiayue.insu.inclientqn.entity.Station;
+import com.jiayue.insu.inclientqn.inenum.SHKJLNEnum;
+import com.jiayue.insu.inclientqn.model.SHKJLNResponseVo;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import com.jiayue.insu.inclientqn.service.StationService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.DigestUtils;
+
+import java.time.LocalDateTime;
+
+/**
+ *  飔合科技生成通讯key
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Component
+@Slf4j
+public class SHComPermisson {
+
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+
+    /**
+     * 飔合科技token
+     * @param station
+     * @return
+     */
+    public Boolean generateKey(Station station) {
+        Record record = new Record();
+
+        record.setType(CommonStant.RECORD_TYPE_COM_PERMISSON);
+        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+        record.setTime(localDateTime);
+        record.setCreateTime(LocalDateTime.now());
+        record.setState(SHKJLNEnum.REQUEST_FAIL.getSign());
+        record.setStationCode(station.getStationCode());
+
+        boolean result = false;
+        String username = station.getUsername();
+        String password = station.getPassword();
+        String passwordMD5 = DigestUtils.md5DigestAsHex(password.getBytes()).toUpperCase();
+        String auth = username + ":" + passwordMD5;
+
+        String tokenUrl = station.getComurl();
+        String response;
+        String token;
+
+        try {
+            HttpRequest httpRequest = HttpRequest.post(tokenUrl)
+                    .header("Content-Type", "application/json")
+                    .header("Authorization", auth);
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.execute().body();
+            if (StrUtil.isNotEmpty(response)) {
+                boolean isJson = JSONUtil.isJsonObj(response);
+                if (isJson) {
+                    JSON resultJson = JSONUtil.parse(response);
+                    SHKJLNResponseVo shkjlnResponseVo = JSONUtil.toBean(response, SHKJLNResponseVo.class);
+                    if (shkjlnResponseVo.getCode().equals(SHKJLNEnum.REQUEST_TOKEN_SUCCESS.getCode())) {
+                        token = shkjlnResponseVo.getToken();
+                        log.info("========== 飔合科技token请求成功: {} token=" + token + "  ==========", station.getStationCode());
+                        station.setComKey(token);
+                        station.setKeyTime(LocalDateTime.now().plusDays(1));
+                        stationService.updateById(station);
+                        record.setState(SHKJLNEnum.REQUEST_TOKEN_FAIL.getSign());
+                        result = true;
+                    } else {
+                        log.error("========== 飔合科技token请求异常: {} 接收Code响应码非成功标识1 标识为" + resultJson.getByPath("code") + " " + resultJson.getByPath("msg") + " ==========", station.getStationCode());
+                        log.info("========== 请求参数 账号密码:" + username + ":" + password + " MD5加密:" + auth + " ==========");
+                    }
+                } else {
+                    log.error("========== 飔合科技token请求异常: {} 接收响应字符串非json格式 ==========", station.getStationCode());
+                }
+            } else {
+                log.error("========== 飔合科技token请求异常: {} 接收响应字符串为空 ==========", station.getStationCode());
+            }
+
+        } catch (Exception e) {
+            log.error("========== 飔合科技token请求异常: {} 连接断开或请求超时 ==========", station.getStationCode());
+            e.printStackTrace();
+
+        }
+
+        recordService.save(record);
+        return result;
+    }
+
+    /**
+     * 校验token
+     * @param station 场站
+     * @return 是否
+     */
+    public boolean isToken(Station station){
+        boolean result = false;
+        String token = station.getComKey();
+        LocalDateTime tokenTime = station.getKeyTime();
+        if (StrUtil.isEmpty(token) || LocalDateTime.now().isAfter(tokenTime)) {
+            if (generateKey(station)) {
+                station = stationService.findThis();
+                token = station.getComKey();
+                tokenTime = station.getKeyTime();
+            }
+        }
+
+        if (StrUtil.isNotEmpty(token) && LocalDateTime.now().isBefore(tokenTime)){
+            result = true;
+        }
+        return result;
+    }
+
+}

+ 9 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pushData/IPushRealValueData.java

@@ -0,0 +1,9 @@
+package com.jiayue.insu.inclientqn.pushData;
+
+import com.jiayue.insu.inclientqn.entity.Station;
+
+import java.time.LocalDateTime;
+
+public interface IPushRealValueData {
+    boolean pushRealValueForJy(Station station, LocalDateTime signTime);
+}

+ 178 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pushData/PushRealValueData.java

@@ -0,0 +1,178 @@
+package com.jiayue.insu.inclientqn.pushData;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.jiayue.insu.inclientqn.constant.CommonStant;
+import com.jiayue.insu.inclientqn.entity.BackForeUsForecastData;
+import com.jiayue.insu.inclientqn.entity.BackStatData;
+import com.jiayue.insu.inclientqn.entity.Record;
+import com.jiayue.insu.inclientqn.entity.Station;
+import com.jiayue.insu.inclientqn.inenum.QNHLEnum;
+import com.jiayue.insu.inclientqn.inenum.StatusEnum;
+import com.jiayue.insu.inclientqn.model.ResponseVo;
+import com.jiayue.insu.inclientqn.service.BackForeUsForecastDataService;
+import com.jiayue.insu.inclientqn.service.BackStatDataService;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.time.*;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@RefreshScope
+@Component
+public class PushRealValueData implements IPushRealValueData {
+
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private BackForeUsForecastDataService backForeUsForecastDataService;
+    @Autowired
+    private BackStatDataService backStatDataService;
+
+    /**
+     * 推送原始超短期数据给一体化云端
+     *
+     * @return
+     */
+    @Override
+    public boolean pushRealValueForJy(Station station, LocalDateTime signTime) {
+
+        // 获取场站编号
+        String stationCode = station.getStationCode();
+        Record record = new Record();
+        record.setStationCode(station.getStationCode());
+        record.setTime(signTime);
+        record.setCreateTime(LocalDateTime.now());
+        record.setType(CommonStant.RECORD_TYPE_REAL_VALUE_FOR_JY);
+        record.setContent(QNHLEnum.DATA_REALVALUE_TYPE.getCode());
+        log.info("开始给一体化云端推送昨日实际功率数据 --> {}" + station.getStationCode());
+        // 如果场站编号为空,则返回
+        if (stationCode == null || "".equals(stationCode)) {
+            record.setState(StatusEnum.STATION_CODE_NULL.getSign());
+            record.setStateContent(StatusEnum.STATION_CODE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+
+
+        // 获取昨天的日期
+        LocalDate yesterday = LocalDate.now().minusDays(1);
+
+        // 获取今天的00:00:00作为昨天的开始时间
+        LocalDateTime startOfYesterday = LocalDateTime.of(yesterday, LocalTime.MIDNIGHT);
+
+        LocalDateTime endOfYesterday = LocalDateTime.of(yesterday, LocalTime.MAX);
+
+        // 指定时区,例如系统默认时区
+        ZoneId zoneId = ZoneId.systemDefault();
+
+        // 将 LocalDateTime 转换为 ZonedDateTime
+        ZonedDateTime zonedDateTime = signTime.atZone(zoneId);
+
+        // 将 ZonedDateTime 转换为 Instant,Instant 可以获取到时间戳
+        Instant instant = zonedDateTime.toInstant();
+
+        // 获取时间戳(毫秒)
+        long timestamp = instant.toEpochMilli();
+
+        List<DataPointDTO> list = new ArrayList<>();
+        // 查询所需回传实际功率
+        List<BackStatData> backStatDataList = backStatDataService.findBySignTimeBetween(startOfYesterday, endOfYesterday);
+        if (backStatDataList.size() > 0) {
+            for (BackStatData backStatData : backStatDataList) {
+                DataPointDTO dto = new DataPointDTO();
+                if (null != backStatData.getSignTime()){
+                    zonedDateTime = backStatData.getSignTime().atZone(ZoneId.systemDefault());
+                    // 将ZonedDateTime转换为Instant
+                    instant = zonedDateTime.toInstant();
+                    // 获取时间戳(毫秒)
+                    Long forecastTime = instant.toEpochMilli();
+                    dto.setForecastTime(forecastTime.toString() == null ? String.valueOf(new Date().getTime()) : forecastTime.toString());
+                    dto.setFpValue(backStatData.getRealPower() == null ? BigDecimal.ZERO.toString() : backStatData.getRealPower().toString());
+                    list.add(dto);
+                }
+            }
+        }
+//        if (list.size() < 288) {
+//            log.error("实际功率:{}条,条数不符合要求,不进行上送", list.size());
+//            return false;
+//        }
+        String jyUrl = "http://49.4.68.219:8801/pfserver/putRealValueData";
+        BackRealValueDto backRealValueDto = new BackRealValueDto(stationCode, String.valueOf(timestamp), list);
+        JSONObject json = JSONUtil.parseObj(backRealValueDto, false);
+        String body = json.toString();
+        try {
+            String credentials = station.getUsername() + ":" + station.getPassword();
+            // Base64编码
+            String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
+            String response;
+            HttpRequest httpRequest = HttpRequest.post(jyUrl)
+                    .header("Content-Type", "application/json")
+                    .header("Authorization", "Basic " + encodedCredentials);
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.body(body).execute().body();
+
+            ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
+            if (responseVo.getRetCode().equals("200")) {
+                record.setState(StatusEnum.SUCCESS.getSign());
+                record.setStateContent("嘉越云" + responseVo.getRetMsg());
+                log.info("=========={}:{} ==>上送实际功率数据成功  {}条==========", station.getName(), station.getStationCode(), list.size());
+                log.info("{} 原始数据:{}", stationCode, body);
+                recordService.save(record);
+                return true;
+            } else {
+                log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因:{} ==========", station.getName(), station.getStationCode(), responseVo.getRetCode(), responseVo.getRetMsg());
+                log.info("{} 原始数据:{}", stationCode, body);
+                record.setState(StatusEnum.FILE_NULL.getSign());
+                record.setStateContent(responseVo.getRetMsg());
+                recordService.save(record);
+                return false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+
+    @Data
+    public class BackRealValueDto {
+
+        public BackRealValueDto(String stationIds, String genDate, List<DataPointDTO> data) {
+            this.stationIds = stationIds;
+            this.genDate = genDate;
+            this.data = data;
+        }
+
+        /**
+         * id
+         */
+        private String stationIds;
+        /**
+         * 生成日期
+         */
+        private String genDate;
+
+        /**
+         * 预测时间和数据
+         */
+        private List<DataPointDTO> data;
+
+    }
+
+    @Data
+    public static class DataPointDTO {
+        private String fpValue;
+        private String forecastTime;
+    }
+}

+ 1 - 1
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/BackForeUsForecastDataService.java

@@ -2,7 +2,6 @@ package com.jiayue.insu.inclientqn.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jiayue.insu.inclientqn.entity.BackForeUsForecastData;
-import com.jiayue.insu.inclientqn.entity.BackStatData;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -20,4 +19,5 @@ public interface BackForeUsForecastDataService extends IService<BackForeUsForeca
 
     List<BackForeUsForecastData> findBySignTimeAndStationCode(LocalDateTime time,String stationCode);
 
+
 }

+ 2 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/BackStatDataService.java

@@ -17,6 +17,8 @@ public interface BackStatDataService extends IService<BackStatData> {
 
     List<BackStatData> findBySignTime(LocalDateTime time);
 
+    List<BackStatData> findBySignTimeBetween(LocalDateTime startTime,LocalDateTime endTime);
+
 
 
 }

+ 51 - 1
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/BackDataAnalysisService.java

@@ -68,12 +68,24 @@ public class BackDataAnalysisService {
         rp.put("label_end", "</" + QNHLEnum.DATA_STAT_TYPE_RealPower.getCode() + ">");
         labelMap.put(QNHLEnum.DATA_STAT_TYPE_RealPower.getCode(), rp);
 
-        // 设定文件模板
+        // 理论可用功率
         Map<String, Object> ty = new HashMap<>();
         ty.put("label_start", "<" + QNHLEnum.DATA_STAT_TYPE_TheoryPower.getCode() + ">");
         ty.put("label_end", "</" + QNHLEnum.DATA_STAT_TYPE_TheoryPower.getCode() + ">");
         labelMap.put(QNHLEnum.DATA_STAT_TYPE_TheoryPower.getCode(), ty);
 
+        // 两则准确率
+        Map<String, Object> accuracy = new HashMap<>();
+        accuracy.put("label_start", "<" + QNHLEnum.DATA_STAT_TYPE_AccuracyRate.getCode() + ">");
+        accuracy.put("label_end", "</" + QNHLEnum.DATA_STAT_TYPE_AccuracyRate.getCode() + ">");
+        labelMap.put(QNHLEnum.DATA_STAT_TYPE_AccuracyRate.getCode(), accuracy);
+
+        // 限电
+        Map<String, Object> lpf = new HashMap<>();
+        lpf.put("label_start", "<" + QNHLEnum.DATA_STAT_TYPE_LimitPowerFlag.getCode() + ">");
+        lpf.put("label_end", "</" + QNHLEnum.DATA_STAT_TYPE_LimitPowerFlag.getCode() + ">");
+        labelMap.put(QNHLEnum.DATA_STAT_TYPE_LimitPowerFlag.getCode(), lpf);
+
         Map<String, Object> rw = new HashMap<>();
         rw.put("label_start", "<" + QNHLEnum.DATA_STAT_TYPE_RealWeather.getCode() + ">");
         rw.put("label_end", "</" + QNHLEnum.DATA_STAT_TYPE_RealWeather.getCode() + ">");
@@ -474,6 +486,44 @@ public class BackDataAnalysisService {
                         e.printStackTrace();
                     }
                     break;
+                case "TheoryPower":
+                    try {
+                        String[] tpData = value.get(0).split("\\s+");
+                        if (tpData.length == 4) {
+                            backStatData.setTheoryPower(new BigDecimal(tpData[2]));
+                            backStatData.setAvailablePower(new BigDecimal(tpData[3]));
+                            result += "TheoryPower,";
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    break;
+                case "AccuracyRate":
+                    try {
+                        String[] arData = value.get(0).split("\\s+");
+                        if (arData.length == 3) {
+                            if ("无可用数据计算".equals(arData[2]) || "无计算公式".equals(arData[2])){
+                                backStatData.setAccuracy(BigDecimal.ZERO);
+                            }else {
+                                backStatData.setAccuracy(new BigDecimal(arData[2]));
+                            }
+                            result += "AccuracyRate,";
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    break;
+                case "LimitPowerFlag":
+                    try {
+                        String[] lpfData = value.get(0).split("\\s+");
+                        if (lpfData.length == 3) {
+                            backStatData.setPowerLimitSign(new BigDecimal(lpfData[2]));
+                            result += "LimitPowerFlag,";
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    break;
                 case "ForecastPowerReport":
                     try {
                         String[] fpr = value.get(0).split("\\s+");

+ 50 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/BackDataGenBodyService.java

@@ -79,6 +79,56 @@ public class BackDataGenBodyService {
     }
 
     /**
+     *  生成回传两则准确率
+     * @param backStatDatas
+     * @return
+     */
+    public StringBuilder genStateAccuracyRate(List<BackStatData> backStatDatas) {
+        StringBuilder content = new StringBuilder();
+        // 如果统计数据中实际功率不为空
+        if (backStatDatas.get(0).getTheoryPower() != null && backStatDatas.get(0).getAvailablePower() != null){
+            // 获取开始、结束、title标签
+            String labelStart = TemplateStant.GEN_LABELSTART(QNHLEnum.DATA_STAT_TYPE_AccuracyRate.getCode());
+            String labelEnd = TemplateStant.GEN_LABELEND(QNHLEnum.DATA_STAT_TYPE_AccuracyRate.getCode());
+            String title = TemplateStant.BACK_STAT_ACCURACY_RATE_TITLE;
+            // 拼接开始、title、内容、结束
+            content.append(labelStart);
+            content.append(title);
+            String dataContent = StrUtil.format(TemplateStant.BACK_STAT_ACCURACY_RATE_TEMPLATE, backStatDatas.get(0).getAccuracy().toString());
+            content.append(dataContent);
+            content.append(labelEnd);
+        }else {
+            log.warn("回传数据-两则准确率缺少数据");
+        }
+        return content;
+    }
+
+    /**
+     *  生成回传限电信号
+     * @param backStatDatas
+     * @return
+     */
+    public StringBuilder genStateLimitPowerFlag(List<BackStatData> backStatDatas) {
+        StringBuilder content = new StringBuilder();
+        // 如果统计数据中实际功率不为空
+        if (backStatDatas.get(0).getTheoryPower() != null && backStatDatas.get(0).getAvailablePower() != null){
+            // 获取开始、结束、title标签
+            String labelStart = TemplateStant.GEN_LABELSTART(QNHLEnum.DATA_STAT_TYPE_LimitPowerFlag.getCode());
+            String labelEnd = TemplateStant.GEN_LABELEND(QNHLEnum.DATA_STAT_TYPE_LimitPowerFlag.getCode());
+            String title = TemplateStant.BACK_STAT_LIMIT_POWER_FLAG_TITLE;
+            // 拼接开始、title、内容、结束
+            content.append(labelStart);
+            content.append(title);
+            String dataContent = StrUtil.format(TemplateStant.BACK_STAT_LIMIT_POWER_FLAG_TEMPLATE, backStatDatas.get(0).getPowerLimitSign().toString());
+            content.append(dataContent);
+            content.append(labelEnd);
+        }else {
+            log.warn("回传数据-限电信号缺少数据");
+        }
+        return content;
+    }
+
+    /**
      * 生成回传实际气象
      *
      * @param stationType   场站类型

+ 22 - 3
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/InitRunner.java

@@ -4,6 +4,8 @@ import cn.hutool.core.date.DateUtil;
 import com.jiayue.insu.inclientqn.entity.Station;
 import com.jiayue.insu.inclientqn.permisson.com.BJZYYJYSDComPermisson;
 import com.jiayue.insu.inclientqn.permisson.com.ComPermisson;
+import com.jiayue.insu.inclientqn.permisson.com.SHComPermisson;
+import com.jiayue.insu.inclientqn.permisson.com.WXComPermisson;
 import com.jiayue.insu.inclientqn.service.StationService;
 import com.jiayue.insu.inclientqn.util.DateTimeUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,15 +23,32 @@ public class InitRunner implements CommandLineRunner {
     @Autowired
     private StationService stationService;
     @Autowired
+    private WXComPermisson wxComPermisson;
+    @Autowired
+    private SHComPermisson shComPermisson;
+    @Autowired
     private BackDataAnalysisService backDataAnalysisService;
+
+    /**
+     * 打包的时候 用哪个站放开哪个站 其他站注释掉 todo
+     *
+     * @param args
+     * @throws Exception
+     */
     @Override
     public void run(String... args) throws Exception {
         List<Station> stationList = stationService.findAll();
-        for(Station station :stationList){
+        for (Station station : stationList) {
+            // 清能token
             comPermisson.generateKey(station);
-            // 山东国家研究院
-            bjzyyjysdComPermisson.generateKey(station);
+//            // 山东国家研究院token
+//            bjzyyjysdComPermisson.generateKey(station);
+            // 武穴一体化请求token
+//            wxComPermisson.generateKey(station);
+            // 飔合科技token from一体化云
+//            shComPermisson.generateKey(station);
         }
+        // 有内网回传放开,没有不用管
         long time = DateTimeUtils.get15min(DateUtil.date().getTime());
         backDataAnalysisService.watchFile(time);
     }

+ 114 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/RequestDataService.java

@@ -74,6 +74,34 @@ public class RequestDataService {
         }
     }
 
+//    /**
+//     *  回传理论可用功率数据
+//     * @param signTime
+//     */
+//    public void requestLlKyBackStat(long signTime) {
+//        // 获取全部场站
+//        List<Station> stationList = stationService.findAll();
+//        Record record;
+//        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);
+//        // 如果场站大于2个,则为多场站情况
+//        if (stationList != null && stationList.size() > 1) {
+//            for (Station station : stationList) {
+//                record = recordService.findTimeAndTypeAndContentAndStateAndStationCode(localDateTime, CommonStant.RECORD_TYPE_BACK_LLkY_DATA, QNHLEnum.DATA_STAT_KYLL.getCode(), StatusEnum.SUCCESS.getSign(), station.getStationCode());
+//                if (record != null) {
+//                    return;
+//                }
+//                this.pullLlKyBackStatData(station, localDateTime, signTime);
+//            }
+//            // 如果只有一个场站
+//        } else if (stationList != null && stationList.size() == 1) {
+//            record = recordService.findTimeAndTypeAndContentAndState(localDateTime, CommonStant.RECORD_TYPE_BACK_LLkY_DATA, QNHLEnum.DATA_STAT_KYLL.getCode(), StatusEnum.SUCCESS.getSign());
+//            if (record != null) {
+//                return;
+//            }
+//            this.pullLlKyBackStatData(stationList.get(0), localDateTime, signTime);
+//        }
+//    }
+
     /**
      * 回传统计数据
      *
@@ -103,6 +131,12 @@ public class RequestDataService {
             stringBuilder.append(backDataGenBodyService.genStateRealPowerData(backStatDatas));
             // 根据统计数据拼接实际气象
             stringBuilder.append(backDataGenBodyService.genStateRealWeatherData(station.getType(), backStatDatas));
+            // 根据统计数据拼接理论可用
+            stringBuilder.append(backDataGenBodyService.genStateTheoryPowerData(backStatDatas));
+            // 根据统计数据拼接两则准确率
+            stringBuilder.append(backDataGenBodyService.genStateAccuracyRate(backStatDatas));
+            // 根据统计数据拼接限电
+            stringBuilder.append(backDataGenBodyService.genStateLimitPowerFlag(backStatDatas));
             // 根据统计数据拼接短期上报
             stringBuilder.append(backDataGenBodyService.genStateForecastPowerReport(backStatDatas));
             // 根据统计数据拼接超短期上报
@@ -161,6 +195,86 @@ public class RequestDataService {
     }
 
     /**
+     *  回传理论可用功率数据
+     * @param station
+     * @param localDateTime
+     * @param signTime
+     */
+    public void pullLlKyBackStatData(Station station, LocalDateTime localDateTime, long signTime) {
+
+        Record record = new Record();
+        record.setType(CommonStant.RECORD_TYPE_BACK_LLkY_DATA);
+        record.setTime(localDateTime);
+        record.setCreateTime(LocalDateTime.now());
+        record.setContent(QNHLEnum.DATA_STAT_KYLL.getCode());
+        record.setStationCode(station.getStationCode());
+
+
+        StringBuilder stringBuilder = new StringBuilder();
+        // 根据时间获取统计数据
+        List<BackStatData> backStatDatas = backStatDataService.findBySignTime(localDateTime);
+        // 如果统计数据不为空
+        if (CollectionUtil.isNotEmpty(backStatDatas)) {
+            // 拼接表头
+            String header = StrUtil.format(TemplateStant.HEADER_TEMPLATE, station.getSignCode(), DateUtil.parse(DateUtil.now()).toString("yyyy-MM-dd HH:mm:ss"));
+            stringBuilder.append(header);
+            // 根据统计数据拼接理论可用功率
+            stringBuilder.append(backDataGenBodyService.genStateTheoryPowerData(backStatDatas));
+            // 组装请求参数
+            RequestVo requestVo = RequestVo.UPLOAD_STAT(station.getSignCode(), stringBuilder.toString(), signTime);
+            //校验请求token是否有效
+            if (comPermisson.isToken(station)) {
+                // 将请求参数转为jsonString类型
+                JSONObject json = JSONUtil.parseObj(requestVo, true);
+                String body = json.toString();
+                // 发送请求
+                String response = RequestUtils.post(station.getBackurl(), body, station.getComKey());
+                // 返回结果校验成功
+                if (RequestUtils.checkResponse(response, record)) {
+                    ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
+                    String code = responseVo.getRetCode();
+                    // 如果请求成功
+                    if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
+                        // 设置日志状态
+                        record.setState(StatusEnum.SUCCESS.getSign());
+                        record.setStateContent(responseVo.getRetMsg());
+                        // 获取统计数据
+                        BackStatData backStatData = backStatDatas.get(0);
+                        // 设置统计时间
+                        backStatData.setBackTime(LocalDateTime.now());
+                        backStatData.setStationCode(station.getStationCode());
+                        try {
+                            // 保存或更新统计数据
+                            backStatDataService.saveOrUpdate(backStatData);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                        // 请求失败
+                    } else {
+                        // 设置日志状态
+                        record.setState(code);
+                        record.setStateContent(responseVo.getRetMsg());
+                    }
+                }
+                // token无效
+            } else {
+                // 设置日志状态
+                record.setState(QNHLEnum.PERMISSON_TOKEN_INVALID.getCode());
+                record.setStateContent(QNHLEnum.PERMISSON_TOKEN_INVALID.getMsg());
+            }
+            // 如果统计数据为空
+        } else {
+            // 设置日志状态
+            record.setState(StatusEnum.DATA_DEFICIENCY.getCode());
+            record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
+        }
+        // 保存日志信息
+        recordService.save(record);
+
+    }
+
+
+    /**
      * 回传短期数据
      *
      * @param signTime

+ 690 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/SHCorrforeService.java

@@ -0,0 +1,690 @@
+//package com.jiayue.insu.inclientqn.service.client;
+//
+//import cn.hutool.core.date.DateTime;
+//import cn.hutool.core.date.DateUtil;
+//import cn.hutool.core.date.LocalDateTimeUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.hutool.http.HttpRequest;
+//import cn.hutool.json.JSONObject;
+//import cn.hutool.json.JSONUtil;
+//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+//import com.jiayue.insu.inclientqn.constant.CommonStant;
+//import com.jiayue.insu.inclientqn.entity.*;
+//import com.jiayue.insu.inclientqn.inenum.QNHLEnum;
+//import com.jiayue.insu.inclientqn.inenum.StatusEnum;
+//import com.jiayue.insu.inclientqn.mapper.CorrforeStMapper;
+//import com.jiayue.insu.inclientqn.model.RequestVo;
+//import com.jiayue.insu.inclientqn.model.ResponseVo;
+//import com.jiayue.insu.inclientqn.permisson.com.ComPermisson;
+//import com.jiayue.insu.inclientqn.service.*;
+//import com.jiayue.insu.inclientqn.util.RequestUtils;
+//import com.jiayue.insu.inclientqn.util.SystermUtils;
+//import com.jiayue.insu.minio.util.MinioUtilService;
+//import lombok.RequiredArgsConstructor;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.velocity.Template;
+//import org.apache.velocity.VelocityContext;
+//import org.apache.velocity.app.VelocityEngine;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Service;
+//
+//import java.io.File;
+//import java.io.FileOutputStream;
+//import java.io.IOException;
+//import java.io.StringWriter;
+//import java.math.BigDecimal;
+//import java.time.LocalDateTime;
+//import java.util.*;
+//import java.util.regex.Matcher;
+//import java.util.regex.Pattern;
+//
+///**
+// * @description:
+// * @author: yuanhao
+// * @createDate: 2021/9/27
+// * @version: 1.0
+// */
+//@Service
+//@Slf4j
+//@RequiredArgsConstructor
+//public class SHCorrforeService extends ServiceImpl<CorrforeStMapper, CorrforeSt> {
+//
+//    private final RecordService recordService;
+//    private final StationService stationService;
+//    private final CorrforeStService corrforeStService;
+//    private final VelocityEngine velocityEngine;
+//    private final ComPermisson comPermisson;
+//    private final MinioUtilService minioUtilService;
+//    private final CorrectUltraShortTermService correctUltraShortTermService;
+//    private final RepairPlanService repairPlanService;
+//
+//    @Value("${minio.bucketname}")
+//    private String bucketName;
+//
+//    /**
+//     * 下载超短期数据
+//     *
+//     * @param signTime
+//     */
+//    public void downLoadUltraShortTerm(long signTime) {
+//        // 获取全部场站
+//        List<Station> stationList = stationService.findAll();
+//        Record record;
+//        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);
+//
+//        // 如果场站大于2个,则为多场站情况
+//        if (stationList != null && stationList.size() > 1) {
+//            for (Station station : stationList) {
+//                record = recordService.findTimeAndTypeAndContentAndStateAndStationCode(localDateTime.plusMinutes(15L), CommonStant.RECORD_TYPE_CORRECT_DATA, QNHLEnum.DATA_CORRULTRSHOR_TYPE.getCode(), StatusEnum.SUCCESS.getSign(),station.getStationCode());
+//                if (record != null) {
+//                    return;
+//                }
+//                this.getUltraShortTermAndGenFile(station, signTime);
+//            }
+//            // 如果只有一个场站
+//        } else if (stationList != null && stationList.size() == 1) {
+//            record = recordService.findTimeAndTypeAndContentAndState(localDateTime.plusMinutes(15L), CommonStant.RECORD_TYPE_CORRECT_DATA, QNHLEnum.DATA_CORRULTRSHOR_TYPE.getCode(), StatusEnum.SUCCESS.getSign());
+//            if (record != null) {
+//                return;
+//            }
+//            this.getUltraShortTermAndGenFile(stationList.get(0), signTime);
+//        }
+//    }
+//
+//    /**
+//     * 获取超短期修正数据并生成文件
+//     * @param station
+//     * @param signTime
+//     */
+//    public void getUltraShortTermAndGenFile(Station station, long signTime){
+//        //标记为要生成超短期的时刻
+//        LocalDateTime signLDT = LocalDateTimeUtil.of(signTime).plusMinutes(15L);
+//        // 初始化日志
+//        Record record = new Record();
+//        record.setType(CommonStant.RECORD_TYPE_CORRECT_DATA);
+//        record.setContent(QNHLEnum.DATA_CORRULTRSHOR_TYPE.getCode());
+//        record.setCreateTime(LocalDateTime.now());
+//        record.setStationCode(station.getStationCode());
+//        //标记为要生成超短期的时刻
+//        record.setTime(signLDT);
+//        // 组装请求参数
+//        RequestVo requestVo = RequestVo.CORRECT_US(station.getSignCode(), null, signTime);
+//        JSONObject json = JSONUtil.parseObj(requestVo, true);
+//        String body = json.toString();
+//        // 发送请求
+//        String response = RequestUtils.post(station.getDownloadurl(), body, station.getComKey());
+//        // 返回结果校验成功
+//        if (RequestUtils.checkResponse(response, record)) {
+//            ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
+//            String code = responseVo.getRetCode();
+//            // 如果请求成功
+//            if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
+//                // 获取请求结果
+//                JSONObject jsonObject = JSONUtil.parseObj(responseVo.getData());
+//                // 如果生成修正超短期文件成功
+//                if (genUs(station, jsonObject)) {
+//                    // 将修正后的超短期数据入库
+//                    correctUltraShortTerm(jsonObject.get("data").toString(), signLDT);
+//                    // 设置日志操作状态
+//                    record.setState(StatusEnum.SUCCESS.getSign());
+//                    record.setStateContent(responseVo.getRetMsg());
+//                    // 如果生成超短期修正文件失败
+//                } else {
+//                    // 设置日志操作状态
+//                    record.setState(StatusEnum.GEN_FILE_FAIL.getSign());
+//                    record.setStateContent(StatusEnum.GEN_FILE_FAIL.getMsg());
+//                }
+//                // 如果请求失败
+//            } else {
+//                // 设置日志操作状态
+//                record.setState(code);
+//                record.setStateContent(responseVo.getRetMsg());
+//            }
+//        }
+//        // 保存操作日志
+//        recordService.save(record);
+//    }
+//
+//    /**
+//     * 下载检修计划
+//     *
+//     * @param signTime
+//     */
+//    public void downLoadRepairPlan(long signTime,Station station) {
+//        // 获取当日开始时间
+//        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+//        //初始化操作日志
+//        Record record = new Record();
+//        record.setType(CommonStant.RECORD_TYPE_CORRECT_DATA);
+//        record.setContent(QNHLEnum.DATA_REPAPLAN_TYPE.getCode());
+//        record.setCreateTime(LocalDateTime.now());
+//        record.setTime(localDateTime);
+//        //组装请求参数
+//        RequestVo requestVo = RequestVo.CORRECT_RP(null, signTime);
+//        JSONObject json = JSONUtil.parseObj(requestVo, true);
+//        String body = json.toString();
+//        // 发送请求,下载检修计划
+//        String response = RequestUtils.post(station.getDownloadurl(), body, station.getComKey());
+//        // 如果返回结果正常
+//        if (RequestUtils.checkResponse(response, record)) {
+//            // 获取返回信息
+//            ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
+//            String code = responseVo.getRetCode();
+//            // 如果调用接口成功
+//            if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
+//                // 如果生成检修计划文件成功
+//                if (genRp(station, responseVo.getData())) {
+//                    // 保存检修计划数据
+//                    repairPlan(responseVo.getData(), localDateTime);
+//                    // 设置操作结果
+//                    record.setState(StatusEnum.SUCCESS.getSign());
+//                    record.setStateContent(responseVo.getRetMsg());
+//                } else {
+//                    // 设置操作结果
+//                    record.setState(StatusEnum.GEN_FILE_FAIL.getSign());
+//                    record.setStateContent(StatusEnum.GEN_FILE_FAIL.getMsg());
+//                }
+//                //调用接口失败
+//            } else {
+//                // 设置操作结果
+//                record.setState(code);
+//                record.setStateContent(responseVo.getRetMsg());
+//            }
+//        }
+//        // 保存操作记录
+//        recordService.save(record);
+//    }
+//
+//    /**
+//     * 下载修正文件,从嘉越云上
+//     *
+//     * @param station
+//     * @return
+//     */
+//    public boolean downLoadCorrforeFile(Station station) {
+//
+//        Record record = new Record();
+//        record.setType(CommonStant.RECORD_TYPE_PULL_CORRECT_JY);
+//        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+//        record.setTime(localDateTime);
+//        record.setCreateTime(LocalDateTime.now());
+//        boolean isUpload = false;
+//
+//        try {
+//            List<String> names = minioUtilService.listObjects(bucketName, station.getStationCode(), true);
+//            boolean isFile = false;
+//            String downfileName = "";
+//            String fileName = station.getStationCode() + "/DQ_" + DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMdd");
+//            for (String name : names) {
+//                if (name.contains(fileName)) {
+//                    isFile = true;
+//                    downfileName = name;
+//                    break;
+//                }
+//            }
+//
+//            if (isFile) {
+//                minioUtilService.downloadObject(bucketName, downfileName, station.getLocalFilePath() + File.separatorChar + downfileName.split("/")[1]);
+//                record.setState(StatusEnum.SUCCESS.getSign());
+//            } else {
+//                record.setState(StatusEnum.FILE_NULL.getSign());
+//            }
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            record.setState(StatusEnum.DOWNLOAD_FILE_ERROR.getSign());
+//            record.setStateContent(StatusEnum.DOWNLOAD_FILE_ERROR.getMsg());
+//        }
+//
+//        recordService.save(record);
+//        return isUpload;
+//    }
+//
+//    /**
+//     * 下载修正短期预测数据,从一体化上
+//     *
+//     * @param station
+//     * @return
+//     */
+//    public boolean downLoadCorrforeData(Station station) {
+//        // 初始化操作记录
+//        Record record = new Record();
+//        record.setType(CommonStant.RECORD_TYPE_PULL_CORRECT);
+//        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+//        record.setTime(localDateTime);
+//        record.setCreateTime(LocalDateTime.now());
+//        // 获取token
+//        String token = station.getComKey();
+//        // 获取下载路径
+//        String dataPullUrl = station.getDownloadurl();
+//
+//        boolean result = false;
+//        boolean isUpload = false;
+//        String response;
+//        RequestVo requestVo;
+//        List<CorrforeSt> list = new ArrayList<>();
+//        // 如果token为空或者token失效,从新获取token
+//        LocalDateTime tokenTime = station.getKeyTime();
+//        if (StrUtil.isEmpty(token) || LocalDateTime.now().isAfter(tokenTime)) {
+//            if (comPermisson.generateKey(station)) {
+//                station = stationService.findThis();
+//                token = station.getComKey();
+//                tokenTime = station.getKeyTime();
+//            }
+//        }
+//        // 如果token为不为空并且者token未失效
+//        if (StrUtil.isNotEmpty(token) && LocalDateTime.now().isBefore(tokenTime)) {
+//            try {
+//                //实装请求参数
+//                DateTime dateTime = DateUtil.parse(DateUtil.today());
+//                requestVo = RequestVo.builder()
+//                        .transferType(QNHLEnum.TRANSFER_TYPE_CORRECT.getCode())
+//                        .date(dateTime.toString("yyyyMMdd"))
+//                        .dataType(QNHLEnum.DATA_CORRFORE_TYPE.getCode())
+//                        .build();
+//                // 将求情转为jsonString
+//                JSONObject json = JSONUtil.parseObj(requestVo, true);
+//                String body = json.toString();
+//                // 发送请求
+//                HttpRequest httpRequest = HttpRequest.post(dataPullUrl)
+//                        .header("Content-Type", "application/json")
+//                        .header("Authorization", token);
+//                httpRequest.setGlobalTimeout(20000);
+//                response = httpRequest
+//                        .body(body)
+//                        .execute().body();
+//
+//                // 如果结果不为空
+//                if (StrUtil.isNotEmpty(response)) {
+//                    boolean isJson = JSONUtil.isJsonObj(response);
+//                    // 如果返回结果是json类型
+//                    if (isJson) {
+//                        ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
+//                        String code = responseVo.getRetCode();
+//                        // 如果调用结果成功
+//                        if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
+//                            log.info(station.getStationCode() + " 请求短期修正数据返回内容:{}", response);
+//                            try {
+//                                // 如果是光伏
+//                                if (CommonStant.ET_PHOTOVOLTAIC.equals(station.getType())) {
+//                                    //解析光伏数据
+//                                    list = correctPhotovoltaicData(responseVo.getData());
+//                                // 如果是风电
+//                                } else {
+//                                    //解析风电数据
+//                                    list = correctWindData(responseVo.getData());
+//                                }
+//                                /**************检测解析数据完整性*******************/
+//                                BigDecimal one = new BigDecimal("1");
+//                                BigDecimal checkCount = new BigDecimal(station.getDays().toString()).add(one).multiply(new BigDecimal("96")).add(one);
+//                                // 如果修正后短期数据不为0
+//                                if (list.size() > 0) {
+//                                    if (list.size() < checkCount.intValue()) {
+//                                        log.warn("========== 请求短期修正数据缺数: {}", list.size());
+//                                    }
+//                                    corrforeStService.updateBetweenForecastTime(list.get(0).getTimeFormat(), list.get(list.size() - 1).getTimeFormat(), list);
+//                                    // 生成短期修正后文件
+//                                    if(genFile(station, list)){
+//                                        result = true;
+//                                    }
+//                                // 如果短期数据为空
+//                                } else {
+//                                    record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getCode());
+//                                    record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
+//                                }
+//                                /**************检测解析数据完整性*******************/
+//                            } catch (Exception e) {
+//                                e.printStackTrace();
+//                                record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
+//                                record.setStateContent("解析短期或生成文件失败");
+//                                log.error("========== 解析短期或生成文件失败 ");
+//                            }
+//
+//                            if (result) {
+//                                log.info("========== 拉取短期修正数据成功! ==========");
+//                                record.setState(StatusEnum.SUCCESS.getSign());
+//                                record.setStateContent(String.valueOf(list.size()));
+//                            }
+//
+//                        } else {
+//                            record.setState(StatusEnum.RESPONSE_FAIL.getSign());
+//                            record.setStateContent(StatusEnum.RESPONSE_FAIL.getMsg());
+//                            log.error("========== 拉取短期修正数据失败 响应码异常 " + station.getStationCode() + " :请求短期修正数据返回内容:"+ response);
+//                        }
+//                    } else {
+//                        record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
+//                        record.setStateContent(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getMsg());
+//                        log.error("========== 拉取短期修正数据失败 接收响应字符串非json格式 ");
+//                    }
+//                } else {
+//                    record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getSign());
+//                    record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
+//                    log.error("========== 拉取短期修正数据失败  返回响应内容为空 ==========");
+//                }
+//
+//            } catch (Exception e) {
+//                record.setState(StatusEnum.CONNECT_ERROR.getSign());
+//                record.setStateContent(StatusEnum.CONNECT_ERROR.getMsg());
+//                log.error("========== 请求短期修正数据失败 连接断开或请求超时 ==========");
+//                e.printStackTrace();
+//
+//            }
+//        }
+//        recordService.save(record);
+//        return isUpload;
+//    }
+//
+//    /**
+//     * 光伏数据解析
+//     *
+//     * @param data 待解析数据
+//     * @return
+//     * @throws Exception
+//     */
+//    public List<CorrforeSt> correctPhotovoltaicData(String data) throws Exception {
+//        List<CorrforeSt> list = new ArrayList<>();
+//        String[] content = data.split("\n");
+//
+//        for (int i = 3; i < content.length - 1; i++) {
+//            CorrforeSt corrforeSt = new CorrforeSt();
+//            String column = content[i];
+//            String[] datas = column.split(CommonStant.SPACE1_CONSTANT);
+//            corrforeSt.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").getTime());
+//            corrforeSt.setTimeFormat(DateUtil.parse(datas[2], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
+//            corrforeSt.setFpValue(isNumberOrNull(datas[3]));
+//            corrforeSt.setGlobalR(isNumberOrNull(datas[4]));
+//            corrforeSt.setDirectR(isNumberOrNull(datas[5]));
+//            corrforeSt.setDiffuseR(isNumberOrNull(datas[6]));
+//            corrforeSt.setT(isNumberOrNull(datas[7]));
+//            corrforeSt.setRh(isNumberOrNull(datas[8]));
+//            corrforeSt.setP(isNumberOrNull(datas[9]));
+//            corrforeSt.setWs(isNumberOrNull(datas[10]));
+//            corrforeSt.setWd(isNumberOrNull(datas[11]));
+//            corrforeSt.setCorrectTime(LocalDateTime.now());
+//            Collections.sort(list, Comparator.comparing(CorrforeSt::getForecastTime));
+//            list.add(corrforeSt);
+//        }
+//        return list;
+//    }
+//
+//    /**
+//     * 风电数据解析
+//     *
+//     * @param data 待解析数据
+//     * @return 解析数据
+//     * @throws Exception
+//     */
+//    public List<CorrforeSt> correctWindData(String data) throws Exception {
+//        List<CorrforeSt> list = new ArrayList<>();
+//        String[] content = data.split("\n");
+//
+//        for (int i = 3; i < content.length - 1; i++) {
+//            CorrforeSt corrforeSt = new CorrforeSt();
+//            String column = content[i];
+//            String[] datas = column.split(CommonStant.SPACE1_CONSTANT);
+//            corrforeSt.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").getTime());
+//            corrforeSt.setTimeFormat(DateUtil.parse(datas[2], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
+//            corrforeSt.setFpValue(isNumberOrNull(datas[3]));
+//            corrforeSt.setWs(isNumberOrNull(datas[4]));
+//            corrforeSt.setWd(isNumberOrNull(datas[5]));
+//            corrforeSt.setT(isNumberOrNull(datas[6]));
+//            corrforeSt.setRh(isNumberOrNull(datas[7]));
+//            corrforeSt.setP(isNumberOrNull(datas[8]));
+//            corrforeSt.setCorrectTime(LocalDateTime.now());
+//            Collections.sort(list, Comparator.comparing(CorrforeSt::getForecastTime));
+//            list.add(corrforeSt);
+//        }
+//        return list;
+//    }
+//
+//    /**
+//     * 将修正后的超短期数据入库
+//     *
+//     * @param content
+//     * @param signTime
+//     * @return
+//     */
+//    public boolean correctUltraShortTerm(String content, LocalDateTime signTime) {
+//        boolean result = true;
+//        try {
+//            List<CorrectUltraShortTerm> list = new ArrayList<>();
+//            String[] contents = content.split("\n");
+//            for (int i = 3; i < contents.length - 1; i++) {
+//                CorrectUltraShortTerm cus = new CorrectUltraShortTerm();
+//                String column = contents[i];
+//                String[] datas = column.split("\\s+");
+//                cus.setSignTime(signTime);
+//                cus.setPassTime(LocalDateTime.now());
+//                cus.setRequestTime(LocalDateTime.now());
+//                cus.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
+//                cus.setRatio(new BigDecimal(datas[3]));
+//                list.add(cus);
+//            }
+//            correctUltraShortTermService.saveBatch(list);
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            result = false;
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * 批量保存检修计划
+//     *
+//     * @param content
+//     * @param signTime
+//     * @return
+//     */
+//    public boolean repairPlan(String content, LocalDateTime signTime) {
+//        boolean result = true;
+//        try {
+//            List<RepairPlan> list = new ArrayList<>();
+//            String[] contents = content.split("\n");
+//            for (int i = 3; i < contents.length - 1; i++) {
+//                RepairPlan rp = new RepairPlan();
+//                String column = contents[i];
+//                String[] datas = column.split("\\s+");
+//                rp.setSignTime(signTime);
+//                rp.setRequestTime(LocalDateTime.now());
+//                rp.setPassTime(LocalDateTime.now());
+//                rp.setStartTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
+//                rp.setEndTime(DateUtil.parse(datas[3], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
+//                rp.setCap(new BigDecimal(datas[4]));
+//                list.add(rp);
+//            }
+//            repairPlanService.saveBatch(list);
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            result = false;
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * 判断是否是NULL 和是否是数值
+//     *
+//     * @param data
+//     * @return
+//     */
+//    public BigDecimal isNumberOrNull(String data) {
+//        BigDecimal bigDecimal = new BigDecimal("-99");
+//        if (!data.contains("null") && !data.contains("NULL")) {
+//            Pattern pattern = Pattern.compile("-[0-9]+(.[0-9]+)?|[0-9]+(.[0-9]+)?");
+//            Matcher isNum = pattern.matcher(data);
+//            try {
+//                if (isNum.matches()) {
+//                    bigDecimal = new BigDecimal(data).setScale(2, BigDecimal.ROUND_DOWN);
+//                }
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//            }
+//        }
+//        return bigDecimal;
+//    }
+//
+//    /**
+//     * 生成修正后的短期文件
+//     *
+//     * @param station
+//     * @param list
+//     * @return
+//     */
+//    public boolean genFile(Station station, List<CorrforeSt> list) {
+//        boolean result = true;
+//        // 初始化模板
+//        String vmsPath = SystermUtils.getResourceBasePath() + "/vms/DQ.vm";
+//        File file ;
+//        Template template = this.velocityEngine.getTemplate(vmsPath);
+//        // 如果模板不为空
+//        if (template != null) {
+//            VelocityContext velocityContext;
+//            StringWriter writer;
+//            // 将修正后的短期数据按照预测时间排序
+//            list.sort(Comparator.comparing(CorrforeSt::getForecastTime));
+//            // 根据修正后的数据,拼接需要的数据
+//            List<Map<String, Object>> vList = new ArrayList<>();
+//            for (CorrforeSt a : list) {
+//                Map<String, Object> map = new HashMap<>();
+//                map.put("id", a.getId());
+//                map.put("stationName", station.getName());
+//                map.put("forecastTime", DateUtil.format(new Date(a.getForecastTime()), "yyyy-MM-dd HH:mm:ss"));
+//                map.put("fpValue", a.getFpValue() == null ? "-99" : a.getFpValue());
+//                vList.add(map);
+//            }
+//            // 格式化模板数据
+//            writer = new StringWriter();
+//            velocityContext = new VelocityContext();
+//            velocityContext.put("stationName", station.getName());
+//            velocityContext.put("date", DateUtil.format(new Date(), "yyyy-MM-dd"));
+//            velocityContext.put("vList", vList);
+//            template.merge(velocityContext, writer);
+//            // 获取文件路径
+//            File fileUrl = new File(station.getLocalFilePath());
+//            if (!fileUrl.exists()) {// 判断目录是否存在
+//                fileUrl.mkdirs();
+//            }
+//            // 获取文件名
+//            String fileName = "DQ_" + DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMddHHmmss") + "0.txt";
+//            file = new File(station.getLocalFilePath() + File.separatorChar + fileName);
+//            // 写入文件
+//            result = writeFile(file, station, writer, fileName);
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * 生成修正后的超短期文件
+//     *
+//     * @param station
+//     * @param jsonObject
+//     * @return
+//     */
+//    public boolean genUs(Station station, JSONObject jsonObject) {
+//        boolean result = true;
+//        // 获取模板
+//        String vmsPath = SystermUtils.getResourceBasePath() + "/vms/US.vm";
+//        Template template = this.velocityEngine.getTemplate(vmsPath);
+//        // 如果
+//        if (template != null) {
+//            // 获取文件名
+//            String fileName = jsonObject.get("fileName").toString();
+//            String[] s = fileName.split("_");
+//            String fn = "CDQ_" + s[1] + s[2] + "00.txt";
+//            File file = new File(station.getLocalFilePath() + File.separatorChar + fn);
+//            // 创建文件并写入
+//            result = mergeTemplateAndwriteFile(file, station, fileName, template, jsonObject.get("data").toString());
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * 生成检修计划文件
+//     *
+//     * @param station
+//     * @param content
+//     * @return
+//     */
+//    public boolean genRp(Station station, String content) {
+//        boolean result = true;
+//        // 初始化模板
+//        String vmsPath = SystermUtils.getResourceBasePath() + "/vms/RP.vm";
+//        File file;
+//        Template template = this.velocityEngine.getTemplate(vmsPath);
+//        // 如果模板不为空
+//        if (template != null) {
+//            // 获取文件名
+//            String fileName = "JX_" + LocalDateTimeUtil.format(LocalDateTimeUtil.beginOfDay(LocalDateTime.now()), "yyyyMMddHHmmss") + ".txt";
+//            file = new File(station.getLocalFilePath() + File.separatorChar + fileName);
+//            // 创建文件并写入
+//            result = mergeTemplateAndwriteFile(file, station, fileName, template, content);
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * 写入文件
+//     *
+//     * @param file
+//     * @param station
+//     * @return
+//     */
+//    private boolean mergeTemplateAndwriteFile(File file, Station station, String fileName, Template template, String content) {
+//        // 创建模板
+//        VelocityContext velocityContext = new VelocityContext();
+//        StringWriter writer = new StringWriter();
+//        // 放入内容
+//        velocityContext.put("content", content);
+//        // 写入数据
+//        template.merge(velocityContext, writer);
+//        return writeFile(file, station, writer, fileName);
+//    }
+//
+//    /**
+//     * 写入文件
+//     * @param file
+//     * @param station
+//     * @param writer
+//     * @param fileName
+//     * @return
+//     */
+//    private boolean writeFile(File file, Station station, StringWriter writer, String fileName) {
+//        boolean result = true;
+//        // 获取文件路径
+//        File fileUrl = new File(station.getLocalFilePath());
+//        // 判断目录是否存在
+//        if (!fileUrl.exists()) {
+//            fileUrl.mkdirs();
+//        }
+//        // 创建流
+//        FileOutputStream os = null;
+//        try {
+//            boolean res = file.createNewFile();
+//            // 如果创建成功
+//            if (res) {
+//                os = new FileOutputStream(file);
+//                // 采用UTF-8字符集
+//                os.write(writer.toString().getBytes("UTF-8"));
+//                os.flush();
+//                // 创建文件失败
+//            } else {
+//                result = false;
+//                log.warn(station.getStationCode() + "文件名:" + fileName + " 生成失败");
+//            }
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//            result = false;
+//            log.warn(station.getStationCode() + " 创建" + "文件名:" + fileName + "失败");
+//        } finally {
+//            // 如果流不为空,关闭流
+//            if (os != null) {
+//                try {
+//                    os.close();
+//                } catch (IOException e) {
+//                    log.error("文件生成关闭流失败", e);
+//                }
+//            }
+//            log.info("执行生成文件完毕:" + station.getLocalFilePath() + File.separatorChar + fileName);
+//            return result;
+//        }
+//    }
+//}

+ 8 - 1
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/impl/BackStatDataServiceImpl.java

@@ -15,7 +15,7 @@ import java.time.LocalDateTime;
 import java.util.List;
 
 /**
- * 修正数据业务实现
+ * 回传统计数据业务实现
  *
  * @author yh
  * @version 1.0
@@ -32,4 +32,11 @@ public class BackStatDataServiceImpl extends ServiceImpl<BackStatDataMapper, Bac
         lambdaQueryWrapper.eq(BackStatData::getSignTime,time);
         return this.list(lambdaQueryWrapper);
     }
+
+    @Override
+    public List<BackStatData> findBySignTimeBetween(LocalDateTime startTime, LocalDateTime endTime) {
+        LambdaQueryWrapper<BackStatData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.between(BackStatData::getSignTime,startTime,endTime);
+        return this.list(lambdaQueryWrapper);
+    }
 }

+ 1 - 1
in-client-qn/src/main/resources/vms/DQ.vm

@@ -1,5 +1,5 @@
 <功率预测::${stationName} date='${date}'>
-@@顺序	场站名称	时刻	预测功率
+@@顺序 	 场站名称	 时刻 	 预测功率
 #foreach( $dq in $vList )
 #${velocityCount}	${dq.stationName}	${dq.forecastTime}	${dq.fpValue}
 #end

+ 26 - 1
in-cloud/src/main/java/com/jiayue/insu/incloud/controller/ApiController.java

@@ -411,7 +411,32 @@ public class ApiController {
 
 
     /**
-     * 入参校验
+     * 接收浙江洋城光伏实际功率数据
+     *
+     * @param request
+     * @param data
+     * @return
+     */
+    @PostMapping("/putRealValueData")
+    public JSONObject putRealValueData(HttpServletRequest request, @RequestBody JSONObject data) {
+        // 武穴一体化入参验证
+        Station station = new Station();
+        JSONObject checkResult = checkRequestForWX(request, data, station);
+        // 如果校验结果为失败
+        String inCode = getInCode(station);
+        if (JsonResultUtil.Type.failure.value().equals(checkResult.get(JsonResultUtil.CODE_TAG))) {
+            Record record = new Record(CommonStant.RECORD_TYPE_PUT_CDQ, inCode, data.getStr("stationIds"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
+            recordService.save(record);
+            return checkResult;
+        }
+        JSONObject result = apiService.putRealValueData(data);
+        Record record = new Record(CommonStant.RECORD_TYPE_PUSH_INIT, inCode, data.getStr("stationIds"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr("retMsg"), result.getStr("retCode"));
+        recordService.save(record);
+        return result;
+    }
+
+    /**
+     * 入参校验(武穴/浙江中广核 共用)
      *
      * @return
      */

+ 53 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/entity/MonthPowerGeneration.java

@@ -0,0 +1,53 @@
+package com.jiayue.insu.incloud.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+
+/**
+ * 月预测发电量实体
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2020/7/8 10:56
+ */
+
+@TableName(value = "in_month_power_generation")
+@Data
+public class MonthPowerGeneration {
+    /**
+     * Id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+
+    private String stationCode;
+
+
+    private String inCode;
+
+    // 生成时间
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date genDate;
+
+    // 预测时间
+    private String forecastTime;
+
+    /**
+     * 预测电量(MWh)
+     */
+    private Double predictedElectricityConsumption;
+
+
+}

+ 54 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/entity/PowerGeneration.java

@@ -0,0 +1,54 @@
+package com.jiayue.insu.incloud.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+
+/**
+ * 发电量实体
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2020/7/8 10:56
+ */
+
+@TableName(value = "in_power_generation")
+@Data
+public class PowerGeneration {
+    /**
+     * Id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+
+    private String stationCode;
+
+
+    private String inCode;
+
+    // 生成时间
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date genDate;
+
+    // 预测时间
+    private String forecastTime;
+
+    /**
+     * 预测电量(MWh)
+     */
+    private Double predictedElectricityConsumption;
+
+
+}

+ 40 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/entity/PowerStationStatusData.java

@@ -0,0 +1,40 @@
+package com.jiayue.insu.incloud.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+
+/**
+ * 预测数据实体
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2020/7/8 10:56
+ */
+
+@TableName(value = "in_power_station_status_data")
+@Data
+public class PowerStationStatusData {
+
+    //id
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    // 场站编号
+    private String stationCode;
+
+    //生成时间
+    private Long genDate;
+
+    //预测时间
+    private Long forecastTime;
+
+    //实际功率
+    private BigDecimal realValue;
+
+}

+ 40 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/job/powerGeneration/MonthPowerGenerationJob.java

@@ -0,0 +1,40 @@
+package com.jiayue.insu.incloud.job.powerGeneration;
+
+import com.jiayue.insu.incloud.entity.Station;
+import com.jiayue.insu.incloud.service.MonthPowerGenerationService;
+import com.jiayue.insu.incloud.service.PowerGenerationService;
+import com.jiayue.insu.incloud.service.StationService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDateTime;
+
+/**
+ * 月发电量定时任务
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Slf4j
+public class MonthPowerGenerationJob implements Job {
+
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private MonthPowerGenerationService monthPowerGenerationService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        String code = jobExecutionContext.getTrigger().getJobKey().getName();
+        // 校验并获取场站信息
+        Station station = stationService.checkAndFindStation(code,null);
+        if (station == null) {
+            log.error("========== 一体化定时任务异常:  场站不存在  {}==========",code);
+        }
+        monthPowerGenerationService.generatePower(LocalDateTime.now(),station.getStationCode());
+    }
+}

+ 40 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/job/powerGeneration/PowerGenerationJob.java

@@ -0,0 +1,40 @@
+package com.jiayue.insu.incloud.job.powerGeneration;
+
+import com.jiayue.insu.incloud.compermisson.QNHLComPermisson;
+import com.jiayue.insu.incloud.entity.Station;
+import com.jiayue.insu.incloud.service.PowerGenerationService;
+import com.jiayue.insu.incloud.service.StationService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDateTime;
+
+/**
+ * 发电量定时任务
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Slf4j
+public class PowerGenerationJob implements Job {
+
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private PowerGenerationService powerGenerationService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        String code = jobExecutionContext.getTrigger().getJobKey().getName();
+        // 校验并获取场站信息
+        Station station = stationService.checkAndFindStation(code,null);
+        if (station == null) {
+            log.error("========== 一体化定时任务异常:  场站不存在  {}==========",code);
+        }
+        powerGenerationService.generatePower(LocalDateTime.now(),station.getStationCode());
+    }
+}

+ 12 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/MonthPowerGenerationMapper.java

@@ -0,0 +1,12 @@
+package com.jiayue.insu.incloud.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.insu.incloud.entity.MonthPowerGeneration;
+import com.jiayue.insu.incloud.entity.PowerGeneration;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface MonthPowerGenerationMapper extends BaseMapper<MonthPowerGeneration> {
+
+
+}

+ 12 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/PowerGenerationMapper.java

@@ -0,0 +1,12 @@
+package com.jiayue.insu.incloud.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.insu.incloud.entity.ForecastData;
+import com.jiayue.insu.incloud.entity.PowerGeneration;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PowerGenerationMapper extends BaseMapper<PowerGeneration> {
+
+
+}

+ 12 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/PowerStationStatusDataMapper.java

@@ -0,0 +1,12 @@
+package com.jiayue.insu.incloud.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.insu.incloud.entity.PowerStationStatusData;
+import com.jiayue.insu.incloud.entity.UltraShortTerm;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PowerStationStatusDataMapper extends BaseMapper<PowerStationStatusData> {
+
+
+}

+ 233 - 103
in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForQNHL.java

@@ -16,19 +16,15 @@ import com.jiayue.insu.incloud.constants.enums.QNHLEnum;
 import com.jiayue.insu.incloud.constants.enums.StatusEnum;
 import com.jiayue.insu.incloud.constants.vo.RequestVo;
 import com.jiayue.insu.incloud.constants.vo.ResponseVo;
-import com.jiayue.insu.incloud.entity.ForecastData;
-import com.jiayue.insu.incloud.entity.IntegrationCompany;
-import com.jiayue.insu.incloud.entity.Record;
-import com.jiayue.insu.incloud.entity.Station;
-import com.jiayue.insu.incloud.service.ForecastDataService;
-import com.jiayue.insu.incloud.service.IntegrationCompanyService;
-import com.jiayue.insu.incloud.service.RecordService;
-import com.jiayue.insu.incloud.service.StationService;
+import com.jiayue.insu.incloud.entity.*;
+import com.jiayue.insu.incloud.service.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -54,9 +50,14 @@ public class PushDataForQNHL implements IPushInitForecastData {
     private QNHLComPermisson qNHLComPermisson;
     @Autowired
     private RecordService recordService;
+    @Autowired
+    private PowerGenerationService powerGenerationService;
+    @Autowired
+    private MonthPowerGenerationService monthPowerGenerationService;
 
     /**
      * 推送原始预测数据
+     *
      * @param station 场站信息
      * @return 是否成功
      */
@@ -72,15 +73,14 @@ public class PushDataForQNHL implements IPushInitForecastData {
         record.setCreateTime(LocalDateTime.now());
 
         Station st = stationService.findByStationCode(station.getStationCode());
-        String token  = st.getComKey();
-        LocalDateTime tokenTime  = st.getKeyTime();
+        String token = st.getComKey();
+        LocalDateTime tokenTime = st.getKeyTime();
 
         IntegrationCompany integrationCompany = integrationCompanyService.findByCode(CompanyConstant.COMPANY_QNHL);
         String dataPushUrl = integrationCompany.getPushUrl();
 
 
-
-        boolean result =false;
+        boolean result = false;
         String response;
         RequestVo requestVo;
 
@@ -93,124 +93,124 @@ public class PushDataForQNHL implements IPushInitForecastData {
         }
 
         if (StrUtil.isNotEmpty(token) &&  LocalDateTime.now().isBefore(tokenTime)) {
-            long startTime = DateUtil.beginOfDay(new Date()).getTime();
-            long endTime = DateUtil.offsetDay(DateUtil.beginOfDay(DateUtil.tomorrow()), st.getDays()).getTime();
-            long momentTime = 900000L;
-            List<ForecastData> aList;
-            aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
-            aList.sort(Comparator.comparing(ForecastData::getForecastTime));
-
-            if (CollectionUtil.isNotEmpty(aList)) {
-
-                /**************************补点 start*************************/
-                if (aList.get(0).getForecastTime().longValue() != startTime) {
-                    List<ForecastData> bList = new ArrayList<>();
-                    long finallyTime = aList.get(0).getForecastTime().longValue();
-                    ForecastData source = aList.get(0);
-                    for (Long tempTime = startTime; tempTime < finallyTime; tempTime = tempTime + momentTime) {
-                        ForecastData target = new ForecastData();
-                        BeanUtil.copyProperties(source, target, false);
-                        target.setId(null);
-                        target.setForecastTime(tempTime);
-                        bList.add(target);
+        long startTime = DateUtil.beginOfDay(new Date()).getTime();
+        long endTime = DateUtil.offsetDay(DateUtil.beginOfDay(DateUtil.tomorrow()), st.getDays()).getTime();
+        long momentTime = 900000L;
+        List<ForecastData> aList;
+        aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
+        aList.sort(Comparator.comparing(ForecastData::getForecastTime));
+
+        if (CollectionUtil.isNotEmpty(aList)) {
+
+            /**************************补点 start*************************/
+            if (aList.get(0).getForecastTime().longValue() != startTime) {
+                List<ForecastData> bList = new ArrayList<>();
+                long finallyTime = aList.get(0).getForecastTime().longValue();
+                ForecastData source = aList.get(0);
+                for (Long tempTime = startTime; tempTime < finallyTime; tempTime = tempTime + momentTime) {
+                    ForecastData target = new ForecastData();
+                    BeanUtil.copyProperties(source, target, false);
+                    target.setId(null);
+                    target.setForecastTime(tempTime);
+                    bList.add(target);
 
-                    }
-                    forecastDataService.saveBatch(bList);
-                    aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
-                    aList.sort(Comparator.comparing(ForecastData::getForecastTime));
                 }
-                /**************************补点 end*************************/
+                forecastDataService.saveBatch(bList);
+                aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
+                aList.sort(Comparator.comparing(ForecastData::getForecastTime));
+            }
+            /**************************补点 end*************************/
 
-                BigDecimal one = new BigDecimal("1");
-                BigDecimal checkCount = new BigDecimal( st.getDays().toString()).add(one).multiply(new BigDecimal("96")).add(one);
-                //如果数据小于961条 不上送数据
-                if (aList.size() >= checkCount.intValue()) {
+            BigDecimal one = new BigDecimal("1");
+            BigDecimal checkCount = new BigDecimal(st.getDays().toString()).add(one).multiply(new BigDecimal("96")).add(one);
+            //如果数据小于961条 不上送数据
+            if (aList.size() >= checkCount.intValue()) {
 
-                    if (CommonStant.ET_PHOTOVOLTAIC.equals(station.getType())) {
-                        requestVo = generatePhotovoltaicRequest(station.getSignCode(), aList, startTime, endTime);
-                    } else {
-                        requestVo = generateWindRequest(station.getSignCode(), aList, startTime, endTime);
-                    }
+                if (CommonStant.ET_PHOTOVOLTAIC.equals(station.getType())) {
+                    requestVo = generatePhotovoltaicRequest(station.getSignCode(), aList, startTime, endTime, station.getStationCode());
+                } else {
+                    requestVo = generateWindRequest(station.getSignCode(), aList, startTime, endTime);
+                }
 
-                    JSONObject json = JSONUtil.parseObj(requestVo, false);
-                    String body = json.toString();
+                JSONObject json = JSONUtil.parseObj(requestVo, false);
+                String body = json.toString();
 
-                    try {
+                try {
 
-                        HttpRequest httpRequest = HttpRequest.post(dataPushUrl)
-                                .header("Content-Type", "application/json")
-                                .header("Authorization", token);
-                        httpRequest.setGlobalTimeout(20000);
+                    HttpRequest httpRequest = HttpRequest.post(dataPushUrl)
+                            .header("Content-Type", "application/json")
+                            .header("Authorization", token);
+                    httpRequest.setGlobalTimeout(20000);
 
-                        response = httpRequest
-                                .body(body)
-                                .execute().body();
+                    response = httpRequest
+                            .body(body)
+                            .execute().body();
 
-                        if (StrUtil.isNotEmpty(response)) {
-                            boolean isJson = JSONUtil.isJsonObj(response);
-                            if (isJson) {
-                                ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
-                                String code = responseVo.getRetCode();
-                                if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
+                    if (StrUtil.isNotEmpty(response)) {
+                        boolean isJson = JSONUtil.isJsonObj(response);
+                        if (isJson) {
+                            ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
+                            String code = responseVo.getRetCode();
+                            if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
 
-                                    for (ForecastData a : aList) {
-                                        a.setUploadTime(LocalDateTime.now());
-                                    }
-                                    forecastDataService.saveOrUpdateBatch(aList);
-                                    record.setState(QNHLEnum.REQUEST_SUCCESS.getSign());
-                                    record.setStateContent(String.valueOf(aList.size()));
-                                    result = true;
-                                    log.info("=========={}:{} ==>上送短期原始数据成功  {}条==========",integrationCompany.getName(), st.getStationCode(), aList.size());
-                                } else {
-                                    QNHLEnum[] values = QNHLEnum.values();
-                                    for (QNHLEnum q: values) {
-                                        if(code.equals(q.getCode())){
-                                            log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因:{} ==========", integrationCompany.getName(),st.getStationCode(),code, responseVo.getRetMsg());
-                                            record.setState(q.getSign());
-                                            record.setStateContent(q.getMsg());
-                                            if(q.name().startsWith("PERMISSON")){
-                                                log.error("=========={}:{} ==>重新请求token ==========", integrationCompany.getName(),st.getStationCode(),code);
-                                                qNHLComPermisson.generateKey(station);
-                                            }
+                                for (ForecastData a : aList) {
+                                    a.setUploadTime(LocalDateTime.now());
+                                }
+                                forecastDataService.saveOrUpdateBatch(aList);
+                                record.setState(QNHLEnum.REQUEST_SUCCESS.getSign());
+                                record.setStateContent(String.valueOf(aList.size()));
+                                result = true;
+                                log.info("=========={}:{} ==>上送短期原始数据成功  {}条==========", integrationCompany.getName(), st.getStationCode(), aList.size());
+                            } else {
+                                QNHLEnum[] values = QNHLEnum.values();
+                                for (QNHLEnum q : values) {
+                                    if (code.equals(q.getCode())) {
+                                        log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因:{} ==========", integrationCompany.getName(), st.getStationCode(), code, responseVo.getRetMsg());
+                                        record.setState(q.getSign());
+                                        record.setStateContent(q.getMsg());
+                                        if (q.name().startsWith("PERMISSON")) {
+                                            log.error("=========={}:{} ==>重新请求token ==========", integrationCompany.getName(), st.getStationCode(), code);
+                                            qNHLComPermisson.generateKey(station);
                                         }
-
                                     }
 
                                 }
-                            } else {
-                                record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
-                                record.setStateContent(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getMsg());
-                                log.error("=========={}:{} ==>上送短期原始数据失败 接收响应字符串非json格式 " ,integrationCompany.getName(),st.getStationCode());
+
                             }
                         } else {
-                            record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getSign());
-                            record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
-                            log.error("=========={}:{} ==>上送短期原始数据失败  返回响应内容为空 ==========" ,integrationCompany.getName(),st.getStationCode());
+                            record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
+                            record.setStateContent(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getMsg());
+                            log.error("=========={}:{} ==>上送短期原始数据失败 接收响应字符串非json格式 ", integrationCompany.getName(), st.getStationCode());
                         }
-                    } catch (Exception e) {
-
-                        record.setState(StatusEnum.CONNECT_ERROR.getSign());
-                        record.setStateContent(StatusEnum.CONNECT_ERROR.getMsg());
-                        log.error("=========={}:{} ==>上送短期原始数据失败 连接断开或请求超时 ==========",integrationCompany.getName(),st.getStationCode());
-                        e.printStackTrace();
-
+                    } else {
+                        record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getSign());
+                        record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
+                        log.error("=========={}:{} ==>上送短期原始数据失败  返回响应内容为空 ==========", integrationCompany.getName(), st.getStationCode());
                     }
+                } catch (Exception e) {
 
+                    record.setState(StatusEnum.CONNECT_ERROR.getSign());
+                    record.setStateContent(StatusEnum.CONNECT_ERROR.getMsg());
+                    log.error("=========={}:{} ==>上送短期原始数据失败 连接断开或请求超时 ==========", integrationCompany.getName(), st.getStationCode());
+                    e.printStackTrace();
 
-                } else {
-
-                    record.setState(StatusEnum.DATA_DEFICIENCY.getSign());
-                    record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
-                    log.warn("=========={}:{} ==>上送短期原始数据失败 上送数据不足 不上送数据 ==========",integrationCompany.getName(),st.getStationCode());
                 }
 
 
             } else {
+
                 record.setState(StatusEnum.DATA_DEFICIENCY.getSign());
                 record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
-                log.warn("=========={}:{} ==>上送短期原始数据失败 上送数据查询为空 不上送数据 ==========",integrationCompany.getName(),st.getStationCode());
+                log.warn("=========={}:{} ==>上送短期原始数据失败 上送数据不足 不上送数据 ==========", integrationCompany.getName(), st.getStationCode());
             }
 
+
+        } else {
+            record.setState(StatusEnum.DATA_DEFICIENCY.getSign());
+            record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
+            log.warn("=========={}:{} ==>上送短期原始数据失败 上送数据查询为空 不上送数据 ==========", integrationCompany.getName(), st.getStationCode());
+        }
+
         } else {
 
             record.setState(QNHLEnum.PERMISSON_LOGIN_NOT.getSign());
@@ -222,12 +222,25 @@ public class PushDataForQNHL implements IPushInitForecastData {
 
         return result;
     }
+
     /**
      * 生成光短期请求
      *
      * @return RequestVo
      */
-    public RequestVo generatePhotovoltaicRequest(String el, List<ForecastData> aList, long startTime, long endTime) {
+    public RequestVo generatePhotovoltaicRequest(String el, List<ForecastData> aList, long startTime, long endTime, String stationCode) {
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        String queryDateStr = simpleDateFormat.format(new Date());
+
+        Date queryDate = null;
+
+        try {
+            queryDate = simpleDateFormat.parse(queryDateStr);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
 
         DateTime dateTime = DateUtil.parse(DateUtil.now());
 
@@ -313,6 +326,123 @@ public class PushDataForQNHL implements IPushInitForecastData {
 
         content += labelEnd;
 
+        // 浙江一体化新增年月日发电量
+        if (el.equals("ZJSYJYGY")) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
+            String nowYear = sdf.format(new Date());
+
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+            String judgeDate = dateFormat.format(new Date());
+
+            String nextYear = String.valueOf(Integer.valueOf(nowYear) + 1);
+            List<MonthPowerGeneration> monthPowerGenerationList = monthPowerGenerationService.findByGenDateAndStationCode(queryDate, stationCode);
+            List<PowerGeneration> powerGenerationList = powerGenerationService.findByStationCodeAndInitTime(stationCode, queryDate);
+            // 年预测发电量
+            String yearLabelStart = "<YearForecastEnergy>" + CommonStant.LINE_CONSTANT;
+            String yearLabelEnd = "</YearForecastEnergy>" + CommonStant.LINE_CONSTANT;
+            String powerGenerationTitle = "@" + CommonStant.SPACE1_CONSTANT + "序号" + CommonStant.SPACE4_CONSTANT + "日期" + CommonStant.SPACE4_CONSTANT + "预测电量" + CommonStant.LINE_CONSTANT;
+            content = content + CommonStant.LINE_CONSTANT + yearLabelStart + powerGenerationTitle;
+
+            // 判断是否符合年预测电量上送日期
+            if (judgeDate.contains("10-15") || judgeDate.contains("11-15")) {
+                String yearTemplate = "#"
+                        + CommonStant.SPACE1_CONSTANT + "{}"
+                        + CommonStant.SPACE4_CONSTANT + "{}"
+                        + CommonStant.SPACE4_CONSTANT + "{}"
+                        + CommonStant.LINE_CONSTANT;
+                if (monthPowerGenerationList.size() > 0) {
+                    double yearValue = monthPowerGenerationList.stream()
+                            .mapToDouble(MonthPowerGeneration::getPredictedElectricityConsumption)
+                            .filter(value -> value >= 0).sum();
+                    String dataStr = StrUtil.format(yearTemplate,
+                            1,
+                            nextYear,
+                            yearValue
+                    );
+                    content += dataStr;
+                } else {
+                    String dataStr = StrUtil.format(yearTemplate,
+                            1,
+                            "NULL",
+                            "NULL"
+                    );
+                    content += dataStr;
+                }
+
+            }
+
+            content += yearLabelEnd;
+            // 月预测发电量
+            String monthLabelStart = "<MonthForecastEnergy>" + CommonStant.LINE_CONSTANT;
+            String monthLabelEnd = "</MonthForecastEnergy>" + CommonStant.LINE_CONSTANT;
+            content = content + CommonStant.LINE_CONSTANT + monthLabelStart + powerGenerationTitle;
+            String monthTemplate = "#"
+                    + CommonStant.SPACE1_CONSTANT + "{}"
+                    + CommonStant.SPACE4_CONSTANT + "{}"
+                    + CommonStant.SPACE4_CONSTANT + "{}"
+                    + CommonStant.LINE_CONSTANT;
+
+            if (monthPowerGenerationList.size() > 0) {
+                // 升序排列
+                monthPowerGenerationList = monthPowerGenerationList.stream().sorted(Comparator.comparing(MonthPowerGeneration::getForecastTime)).collect(Collectors.toList());
+                for (int j = 1; j < 3; j++) {
+                    String dataStr = StrUtil.format(monthTemplate,
+                            j,
+                            monthPowerGenerationList.get(j - 1).getForecastTime(),
+                            monthPowerGenerationList.get(j - 1).getPredictedElectricityConsumption() == 0.0 ? "NULL" : monthPowerGenerationList.get(j - 1).getPredictedElectricityConsumption()
+                    );
+                    content += dataStr;
+                }
+
+            } else {
+                for (int j = 1; j < 3; j++) {
+                    String dataStr = StrUtil.format(monthTemplate,
+                            j,
+                            "NULL",
+                            "NULL"
+                    );
+                    content += dataStr;
+                }
+            }
+            content += monthLabelEnd;
+
+            // 日预测发电量
+            String dayLabelStart = "<DayForecastEnergy>" + CommonStant.LINE_CONSTANT;
+            String dayLabelEnd = "</DayForecastEnergy>" + CommonStant.LINE_CONSTANT;
+            content = content + CommonStant.LINE_CONSTANT + dayLabelStart + powerGenerationTitle;
+            String dayTemplate = "#"
+                    + CommonStant.SPACE1_CONSTANT + "{}"
+                    + CommonStant.SPACE4_CONSTANT + "{}"
+                    + CommonStant.SPACE4_CONSTANT + "{}"
+                    + CommonStant.LINE_CONSTANT;
+            if (powerGenerationList.size() > 0) {
+                // 升序
+                powerGenerationList.stream().sorted(Comparator.comparing(PowerGeneration::getForecastTime)).collect(Collectors.toList());
+                // 过滤掉本月预测发电量
+                powerGenerationList = powerGenerationList.stream().filter(f -> !f.getForecastTime().equals(new SimpleDateFormat("yyyyMMdd").format(new Date()))).collect(Collectors.toList());
+
+                for (int j = 0; j < powerGenerationList.size(); j++) {
+                    String dataStr = StrUtil.format(dayTemplate,
+                            j + 1,
+                            powerGenerationList.get(j).getForecastTime(),
+                            powerGenerationList.get(j).getPredictedElectricityConsumption() == 0.0 ? "NULL" : powerGenerationList.get(j).getPredictedElectricityConsumption()
+                    );
+                    content += dataStr;
+                }
+
+            } else {
+                for (int j = 0; j < 31; j++) {
+                    String dataStr = StrUtil.format(dayTemplate,
+                            j + 1,
+                            "NULL",
+                            "NULL"
+                    );
+                    content += dataStr;
+                }
+
+            }
+            content += dayLabelEnd;
+        }
         RequestVo requestVo = RequestVo.builder()
                 .transferType(QNHLEnum.TRANSFER_TYPE_DOWNLOAD.getCode())
                 .date(dateTime.toString("yyyyMMdd"))

+ 7 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/ApiService.java

@@ -55,6 +55,13 @@ public interface ApiService  {
     JSONObject putUltraShortTermData(JSONObject requestJson);
 
     /**
+     * 接收实际功率数据
+     * @param requestJson
+     * @return
+     */
+    JSONObject putRealValueData(JSONObject requestJson);
+
+    /**
      * 获取nwp原始json数据
      * @param requestJson
      * @return

+ 2 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/ForecastDataService.java

@@ -33,4 +33,6 @@ public interface ForecastDataService extends IService<ForecastData> {
 
 
     List<ForecastData>  findInitTimeByStation(LocalDateTime initTime,String stationCode);
+
+    List<ForecastData>  findByInitTimeAndStationCodeAndForecastTimeBetween(LocalDateTime initTime,String stationCode,Long startTime,Long endTime);
 }

+ 22 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/MonthPowerGenerationService.java

@@ -0,0 +1,22 @@
+package com.jiayue.insu.incloud.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.insu.incloud.entity.MonthPowerGeneration;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 月发电量预测业务接口
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public interface MonthPowerGenerationService extends IService<MonthPowerGeneration> {
+
+    boolean generatePower(LocalDateTime initTime, String stationCode);
+
+    List<MonthPowerGeneration> findByGenDateAndStationCode(Date genDate,String stationCode);
+}

+ 25 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/PowerGenerationService.java

@@ -0,0 +1,25 @@
+package com.jiayue.insu.incloud.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.insu.incloud.entity.ForecastData;
+import com.jiayue.insu.incloud.entity.PowerGeneration;
+import com.jiayue.insu.incloud.entity.PowerStationStatusData;
+import com.jiayue.insu.incloud.entity.Station;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 发电量预测业务接口
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public interface PowerGenerationService extends IService<PowerGeneration> {
+    Boolean generatePower(LocalDateTime nowDate, String stationCode);
+
+    List<PowerGeneration> findByStationCodeAndInitTime(String stationCode, Date date);
+
+}

+ 16 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/PowerStationStatusDataService.java

@@ -0,0 +1,16 @@
+package com.jiayue.insu.incloud.service;
+
+import com.jiayue.insu.incloud.entity.PowerStationStatusData;
+import com.jiayue.insu.incloud.entity.UltraShortTerm;
+
+import java.util.List;
+
+/**
+ * 超短期接口
+ */
+public interface PowerStationStatusDataService {
+
+    List<PowerStationStatusData> findByGenDate(Long genDate, String stationCode);
+
+    void  save(List<PowerStationStatusData> list);
+}

+ 70 - 4
in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/ApiServiceImpl.java

@@ -13,10 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jiayue.insu.incloud.constants.CommonStant;
 import com.jiayue.insu.incloud.constants.enums.StatusEnum;
 import com.jiayue.insu.incloud.constants.vo.FileCreateLog;
-import com.jiayue.insu.incloud.entity.ForecastData;
-import com.jiayue.insu.incloud.entity.Record;
-import com.jiayue.insu.incloud.entity.Station;
-import com.jiayue.insu.incloud.entity.UltraShortTerm;
+import com.jiayue.insu.incloud.entity.*;
 import com.jiayue.insu.incloud.service.*;
 import com.jiayue.insu.incloud.utils.JsonResultUtil;
 import com.jiayue.insu.incloud.utils.SystermUtils;
@@ -87,6 +84,8 @@ public class ApiServiceImpl implements ApiService {
     private ForecastDataService forecastDataService;
     @Autowired
     private UltraShortTermService ultraShortTermService;
+    @Autowired
+    private PowerStationStatusDataService powerStationStatusDataService;
 
     /**
      * 获取token
@@ -1059,6 +1058,35 @@ public class ApiServiceImpl implements ApiService {
     }
 
     /**
+     *  接收实际功率数据
+     * @param requestJson
+     * @return
+     */
+    @Override
+    public JSONObject putRealValueData(JSONObject requestJson) {
+        JSONObject result = new JSONObject();
+        String stationCodeArr = requestJson.getStr("stationIds");
+        Long genDate = Long.valueOf(requestJson.getStr("genDate"));
+        List<PowerStationStatusData> powerStationStatusDataList = new ArrayList<>();
+        try {
+            powerStationStatusDataList = correctRealValueData(requestJson.getStr("data"), stationCodeArr, genDate);
+            if (powerStationStatusDataList.size() > 0) {
+                log.info("接收实际功率数据:{}", powerStationStatusDataList.size());
+                powerStationStatusDataService.save(powerStationStatusDataList);
+                result.set("retCode", 200);
+                result.set("retMsg", "接收实际功率数据成功!");
+            } else {
+                log.info("接收实际功率数据失败!数据为空!");
+                result.set("retCode", 500);
+                result.set("retMsg", "接收实际功率数据失败!");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return result;
+    }
+
+    /**
      * 解析传入超短期数据
      *
      * @param data 待解析数据
@@ -1097,6 +1125,44 @@ public class ApiServiceImpl implements ApiService {
 
 
     /**
+     * 解析传入实际功率数据
+     *
+     * @param data 待解析数据
+     * @return 解析数据
+     * @throws Exception
+     */
+    public List<PowerStationStatusData> correctRealValueData(String data, String stationCode, Long genDate) throws Exception {
+
+        data = data.substring(1, data.length() - 1);
+        String[] content = data.split("(?<=})\\s*,\\s*");
+
+        List<PowerStationStatusData> list = new ArrayList<>();
+
+        for (int i = 0; i < content.length; i++) {
+
+            PowerStationStatusData powerStationStatusData = new PowerStationStatusData();
+            String column = content[i];
+
+            //JSON 字符串转换为一个树状结构
+            ObjectMapper objectMapper = new ObjectMapper();
+            JsonNode rootNode = objectMapper.readTree(column);
+            // 通过键名获取相应的值
+            String forecastTime = rootNode.get("forecastTime").asText();
+            double fpValue = rootNode.get("fpValue").asDouble();
+            // 将预测时间转换为时间戳格式
+            Long forecast = Long.valueOf(forecastTime);
+
+            powerStationStatusData.setGenDate(genDate);
+            powerStationStatusData.setForecastTime(forecast);
+            powerStationStatusData.setRealValue(isNumberOrNull(String.valueOf(fpValue)));
+            powerStationStatusData.setStationCode(stationCode);
+            list.add(powerStationStatusData);
+        }
+        return list;
+    }
+
+
+    /**
      * 判断是否是NULL 和是否是数值
      *
      * @param data

+ 9 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/ForecastDataServiceImpl.java

@@ -59,4 +59,13 @@ public class ForecastDataServiceImpl extends ServiceImpl<ForecastDataMapper, For
         lambdaQueryWrapper.eq(ForecastData::getStationCode,stationCode);
         return this.list(lambdaQueryWrapper);
     }
+
+    @Override
+    public List<ForecastData> findByInitTimeAndStationCodeAndForecastTimeBetween(LocalDateTime initTime, String stationCode, Long startTime, Long endTime) {
+        LambdaQueryWrapper<ForecastData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(ForecastData::getInitTime,initTime);
+        lambdaQueryWrapper.eq(ForecastData::getStationCode,stationCode);
+        lambdaQueryWrapper.between(ForecastData::getForecastTime,startTime,endTime);
+        return this.list(lambdaQueryWrapper);
+    }
 }

+ 137 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/MonthPowerGenerationServiceImpl.java

@@ -0,0 +1,137 @@
+package com.jiayue.insu.incloud.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.comparator.CompareUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.insu.incloud.entity.ForecastData;
+import com.jiayue.insu.incloud.entity.MonthPowerGeneration;
+import com.jiayue.insu.incloud.entity.PowerGeneration;
+import com.jiayue.insu.incloud.entity.PowerStationStatusData;
+import com.jiayue.insu.incloud.mapper.MonthPowerGenerationMapper;
+import com.jiayue.insu.incloud.service.ForecastDataService;
+import com.jiayue.insu.incloud.service.MonthPowerGenerationService;
+import com.jiayue.insu.incloud.service.PowerGenerationService;
+import com.jiayue.insu.incloud.service.PowerStationStatusDataService;
+import com.jiayue.insu.incloud.utils.FixedCapacityList;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * 发电量预测业务实现
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Service
+@Slf4j
+public class MonthPowerGenerationServiceImpl extends ServiceImpl<MonthPowerGenerationMapper, MonthPowerGeneration> implements MonthPowerGenerationService {
+
+    @Autowired
+    private PowerGenerationService powerGenerationService;
+
+
+    /**
+     * 计算预测发电量
+     *
+     * @param nowDate
+     * @return
+     */
+    @Override
+    public boolean generatePower(LocalDateTime nowDate, String stationCode) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+        String changeDate = sdf.format(new Date());
+
+        Date date = null;
+        try {
+            date = sdf.parse(changeDate);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+        List<MonthPowerGeneration> checkList = findByGenDateAndStationCode(date,stationCode);
+        if (checkList.size() > 0){
+            log.info("月发电量已经生成过了,不再进行计算!");
+            return true;
+        }
+        // 查询今天生成的日发电量
+        List<PowerGeneration> powerGenerationList = powerGenerationService.findByStationCodeAndInitTime(stationCode, date);
+
+        List<MonthPowerGeneration> monthPowerGenerationList = new ArrayList<>();
+
+        if (powerGenerationList.size() > 0) {
+            monthPowerGenerationList =  calculateMonthPowerGeneration(powerGenerationList,changeDate,stationCode,date);
+        }else {
+            powerGenerationService.generatePower(LocalDateTime.now(),stationCode);
+            powerGenerationList = powerGenerationService.findByStationCodeAndInitTime(stationCode, date);
+            monthPowerGenerationList =  calculateMonthPowerGeneration(powerGenerationList,changeDate,stationCode,date);
+        }
+        this.saveBatch(monthPowerGenerationList);
+        return true;
+    }
+
+    @Override
+    public List<MonthPowerGeneration> findByGenDateAndStationCode(Date genDate, String stationCode) {
+        LambdaQueryWrapper<MonthPowerGeneration> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(MonthPowerGeneration::getGenDate,genDate);
+        lambdaQueryWrapper.eq(MonthPowerGeneration::getStationCode,stationCode);
+        return list(lambdaQueryWrapper);
+    }
+
+    public List<MonthPowerGeneration> calculateMonthPowerGeneration(List<PowerGeneration> powerGenerationList,String changeDate,String stationCode,Date date){
+        List<MonthPowerGeneration> monthPowerGenerationList = new ArrayList<>();
+        // 获取当前日期
+        LocalDate currentDate = LocalDate.now();
+        // 定义日期格式化器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
+
+        List<PowerGeneration> list =  powerGenerationList.stream().filter(f -> !f.getForecastTime().equals(changeDate)).collect(Collectors.toList());
+        double monthValue = list.stream()
+                .mapToDouble(PowerGeneration::getPredictedElectricityConsumption)
+                .filter(value -> value >= 0)
+                .sum();
+
+        // 下月预测功率
+        BigDecimal nextMouthVal;
+        for (int i = 1; i <= 12; i++) {
+            LocalDate futureMonth = currentDate.plusMonths(i);
+            String formattedMonth = futureMonth.format(formatter);
+            BigDecimal max = new BigDecimal(monthValue).multiply(new BigDecimal(1.2));
+            BigDecimal min = new BigDecimal(monthValue).multiply(new BigDecimal(0.8));
+            nextMouthVal = new BigDecimal(Math.random()).multiply(max.subtract(min)).add(min);
+            MonthPowerGeneration monthPowerGeneration = new MonthPowerGeneration();
+            monthPowerGeneration.setStationCode(stationCode);
+            monthPowerGeneration.setForecastTime(formattedMonth);
+            monthPowerGeneration.setPredictedElectricityConsumption(nextMouthVal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
+            monthPowerGeneration.setGenDate(date);
+            monthPowerGenerationList.add(monthPowerGeneration);
+        }
+        return monthPowerGenerationList;
+    }
+}

+ 288 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/PowerGenerationServiceImpl.java

@@ -0,0 +1,288 @@
+package com.jiayue.insu.incloud.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.comparator.CompareUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.insu.incloud.entity.ForecastData;
+import com.jiayue.insu.incloud.entity.PowerGeneration;
+import com.jiayue.insu.incloud.entity.PowerStationStatusData;
+import com.jiayue.insu.incloud.mapper.PowerGenerationMapper;
+import com.jiayue.insu.incloud.service.ForecastDataService;
+import com.jiayue.insu.incloud.service.PowerGenerationService;
+import com.jiayue.insu.incloud.service.PowerStationStatusDataService;
+import com.jiayue.insu.incloud.utils.FixedCapacityList;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * 发电量预测业务实现
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Service
+@Slf4j
+public class PowerGenerationServiceImpl extends ServiceImpl<PowerGenerationMapper, PowerGeneration> implements PowerGenerationService {
+
+    @Autowired
+    private ForecastDataService forecastDataService;
+    @Autowired
+    private PowerStationStatusDataService powerStationStatusDataService;
+
+    private static BigDecimal FIFTEEN_MINUTE = BigDecimal.valueOf(15 * 60 * 1000L);
+    private static BigDecimal ONE_DAY = BigDecimal.valueOf(24 * 60 * 60 * 1000L);
+    private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private final BigDecimal ForecastRadio = new BigDecimal(0.25);
+    private final BigDecimal RealValueRadio = new BigDecimal(0.25);
+
+
+    /**
+     * 计算预测发电量
+     *
+     * @param nowDate
+     * @return
+     */
+    @Override
+    public Boolean generatePower(LocalDateTime nowDate, String stationCode) {
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        String dateStr = simpleDateFormat.format(new Date());
+
+        Date date = null;
+        try {
+            date = simpleDateFormat.parse(dateStr);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+        // 查询是否今天生成的发电量
+        List<PowerGeneration> checkList = findByGenDate(date);
+
+        if (checkList.size() > 0 ){
+            log.info("已有当日生成的发电量,不再进行计算!");
+            return true;
+        }
+
+        // 获取今天的日期部分
+        LocalDate today = nowDate.toLocalDate();
+
+        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+        // 获取去年的今天
+        LocalDate lastYearToday = today.minusYears(1);
+        // 获取当前时间部分
+        LocalTime currentTime = nowDate.toLocalTime();
+        // 组合去年的日期和当前的时间来创建 LocalDateTime 对象
+        LocalDateTime lastYearTodaySameTime = lastYearToday.atTime(currentTime);
+
+        Long startTime = getDayStartTime(System.currentTimeMillis());
+
+        Long endTime = startTime + 12 * ONE_DAY.longValue() - 1;
+        // 查询预测数据
+        List<ForecastData> forecastDataList = forecastDataService.findByInitTimeAndStationCodeAndForecastTimeBetween(localDateTime, stationCode, startTime, endTime);
+
+        List<PowerGeneration> powerGenerationList = new ArrayList<>();
+
+        FixedCapacityList<BigDecimal> fixedCapacityList = new FixedCapacityList<>(10);
+
+        if (forecastDataList.size() > 0) {
+            for (int i = 0; i <= 31; i++) {
+                PowerGeneration powerGeneration = new PowerGeneration();
+                String forecastDay = DateFormatUtils.format(DateUtils.addDays(new Date(startTime), i), "yyyyMMdd");
+                // 电量和
+                BigDecimal sumValue = BigDecimal.ZERO;
+                // 一天一天数据进行过滤
+                String[] datas = findSendData(startTime + ONE_DAY.longValue() * (i), startTime + ONE_DAY.longValue() * (i+1) - FIFTEEN_MINUTE.longValue(), forecastDataList);
+                log.info("预测数据 {} {} - {}", datas.length, formatter.format(startTime + ONE_DAY.longValue() * (i)), formatter.format(startTime + ONE_DAY.longValue() * (i+1) - FIFTEEN_MINUTE.longValue()));
+                // 数据为空 查找去年相同时间点的实际功率
+                if (ObjectUtil.isEmpty(datas)) {
+                    // 查询去年同期(因为外网回传文件genDate是后一天的时间)
+                    long lastYear = DateUtils.addYears(new Date(startTime + ONE_DAY.longValue() * (i)), -1).getTime() + 24 * 3600 * 1000L;
+                    // 查询去年相同时间点实际功率
+                    List<PowerStationStatusData> powerStationStatusDataList = powerStationStatusDataService.findByGenDate(lastYear, stationCode);
+                    // 查询实际功率开始时间
+                    Long queryRealValueStartTime = new Date(startTime + ONE_DAY.longValue() * (i)).getTime();
+
+                    datas = findRealSendData(queryRealValueStartTime, queryRealValueStartTime + ONE_DAY.longValue() - 1, powerStationStatusDataList);
+
+                    if (ObjectUtil.isEmpty(datas)) {
+                        // 去年同期实际功率无数据,查询就近实际功率
+                        int missDayNum = 31 - i;
+                        // 查询实际功率时间
+                        Long beforeStartTime = new Date(startTime - ONE_DAY.longValue() * missDayNum).getTime();
+
+                        System.out.println(new Date(beforeStartTime));
+
+                        powerStationStatusDataList = powerStationStatusDataService.findByGenDate(beforeStartTime+24*60*60*1000L, stationCode);
+
+                        datas = findRealSendData(beforeStartTime, beforeStartTime + ONE_DAY.longValue() - 1, powerStationStatusDataList);
+
+                    } else {
+                        log.info("同期实际功率数据 {} {} - {}", datas.length, formatter.format(lastYearTodaySameTime.getSecond() + ONE_DAY.longValue() * (i - 1)), formatter.format(lastYearTodaySameTime.getSecond() + ONE_DAY.longValue() * i - FIFTEEN_MINUTE.longValue()));
+                    }
+                    if (datas.length > 0) {
+                        BigDecimal value;
+                        for (String data : datas) {
+                            if (StrUtil.isNotEmpty(data)) {
+                                if (datas.length > 96) {
+                                    value = new BigDecimal(data).multiply(RealValueRadio).setScale(2, RoundingMode.HALF_UP);
+                                } else {
+                                    value = new BigDecimal(data).multiply(ForecastRadio).setScale(2, RoundingMode.HALF_UP);
+                                }
+                                sumValue = sumValue.add(value);
+                            }
+                        }
+                        fixedCapacityList.push(sumValue);
+                    } else {
+                        FixedCapacityList<BigDecimal> capacityList = new FixedCapacityList<>(fixedCapacityList.size());
+                        capacityList.addAll(fixedCapacityList);
+                        if (capacityList.size() > 2) { // 减少极端值
+                            capacityList.removeFirstOccurrence(CollUtil.max(fixedCapacityList));
+                            capacityList.removeLastOccurrence(CollUtil.min(fixedCapacityList));
+                        }
+                        log.info("生成数据 {} {} - {}", datas.length, formatter.format(startTime + ONE_DAY.longValue() * (i - 1)), formatter.format(startTime + ONE_DAY.longValue() * i - FIFTEEN_MINUTE.longValue()));
+                        int n = capacityList.size();
+                        BigDecimal avgValue = avg(fixedCapacityList);
+                        BigDecimal lastValue = avg(capacityList.subList(n > 3 ? (n - 3) : n - 1, n - 1));
+                        //
+                        if (CompareUtil.compare(lastValue, avgValue) < 0) {
+                            sumValue = lastValue.add(lastValue.multiply(RandomUtil.randomBigDecimal(BigDecimal.valueOf(0.01), BigDecimal.valueOf(0.05))));
+                        } else if (CompareUtil.compare(lastValue, avgValue) > 0) {
+                            sumValue = lastValue.add(lastValue.multiply(RandomUtil.randomBigDecimal(BigDecimal.valueOf(-0.25), BigDecimal.valueOf(-0.1))));
+                        } else {
+                            sumValue = lastValue.add(lastValue.multiply(RandomUtil.randomBigDecimal(BigDecimal.valueOf(-0.02), BigDecimal.valueOf(0.02))));
+                        }
+                        sumValue = CompareUtil.compare(BigDecimal.ZERO, sumValue) >= 0 ? BigDecimal.ZERO : sumValue;
+                        //
+                        capacityList.clear();
+                    }
+                }else {
+                    for (String data : datas) {
+                        BigDecimal value;
+                        if (StrUtil.isNotEmpty(data)) {
+                            if (datas.length > 96) {
+                                value = new BigDecimal(data).multiply(RealValueRadio).setScale(2, RoundingMode.HALF_UP);
+                            } else {
+                                value = new BigDecimal(data).multiply(ForecastRadio).setScale(2, RoundingMode.HALF_UP);
+                            }
+                            sumValue = sumValue.add(value);
+                        }
+                    }
+                    fixedCapacityList.push(sumValue);
+                }
+                powerGeneration.setGenDate(new Date());
+                powerGeneration.setStationCode(stationCode);
+                powerGeneration.setPredictedElectricityConsumption(sumValue.setScale(2,RoundingMode.HALF_UP).doubleValue());
+                powerGeneration.setForecastTime(forecastDay);
+                powerGenerationList.add(powerGeneration);
+            }
+        }
+        this.saveBatch(powerGenerationList);
+        return true;
+    }
+
+    @Override
+    public List<PowerGeneration> findByStationCodeAndInitTime(String stationCode, Date date) {
+        LambdaQueryWrapper<PowerGeneration> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(PowerGeneration::getGenDate,date);
+        lambdaQueryWrapper.eq(PowerGeneration::getStationCode,stationCode);
+        return this.list(lambdaQueryWrapper);
+    }
+
+
+    @Transactional(propagation = Propagation.REQUIRED)
+    public String[] findSendData(Long stTime, Long eTime, List<ForecastData> list) {
+        String[] datas = new String[0];
+        List<ForecastData> collect = list.stream().filter(s -> s.getForecastTime() >= stTime && s.getForecastTime() <= eTime).collect(Collectors.toList());
+        if (!collect.isEmpty()) {
+            datas = new String[collect.size()];
+            if (null != collect && collect.size() > 0) {
+                int index = 0;
+                for (ForecastData f : collect) {
+                    datas[index] = String.valueOf(f.getFpValue());
+                    index++;
+                }
+            }
+        }
+        return datas;
+    }
+
+
+    @Transactional(propagation = Propagation.REQUIRED)
+    public String[] findRealSendData(Long stTime, Long eTime, List<PowerStationStatusData> list) {
+        String[] datas = new String[0];
+        List<PowerStationStatusData> collect = list.stream().filter(s -> s.getForecastTime() >= stTime && s.getForecastTime() <= eTime).collect(Collectors.toList());
+        if (!collect.isEmpty()) {
+            datas = new String[collect.size()];
+            if (null != collect && collect.size() > 0) {
+                int index = 0;
+                for (PowerStationStatusData f : collect) {
+                    datas[index] = String.valueOf(f.getRealValue());
+                    index++;
+                }
+            }
+        }
+        return datas;
+    }
+
+    private BigDecimal avg(List<BigDecimal> bs) {
+        BigDecimal value = BigDecimal.ZERO;
+        for (BigDecimal b : bs) {
+            value = value.add(b);
+        }
+        BigDecimal avgValue = null;
+        try {
+            avgValue = value.divide(new BigDecimal(bs.size()), 4, RoundingMode.HALF_UP);
+        } catch (Exception ex) {
+            log.error(ex.getLocalizedMessage(), ex.getCause());
+        }
+        return avgValue;
+    }
+
+    List<PowerGeneration> findByGenDate(Date genDate){
+        LambdaQueryWrapper<PowerGeneration> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(PowerGeneration::getGenDate,genDate);
+        return list(lambdaQueryWrapper);
+    }
+
+    /**
+     * 获取指定时间所在天的0点0分
+     *
+     * @param dateTime 时间毫秒
+     * @return 0点0分的毫秒
+     */
+    public static long getDayStartTime(Long dateTime) {
+        Calendar date = Calendar.getInstance();
+        date.setTimeInMillis(dateTime);
+        date.set(Calendar.HOUR_OF_DAY, 0);
+        date.set(Calendar.MINUTE, 0);
+        date.set(Calendar.SECOND, 0);
+        date.set(Calendar.MILLISECOND, 0);
+        return date.getTimeInMillis();
+    }
+}

+ 44 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/PowerStationStatusDataServiceImpl.java

@@ -0,0 +1,44 @@
+package com.jiayue.insu.incloud.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.insu.incloud.entity.PowerStationStatusData;
+import com.jiayue.insu.incloud.entity.UltraShortTerm;
+import com.jiayue.insu.incloud.mapper.PowerStationStatusDataMapper;
+import com.jiayue.insu.incloud.mapper.UltraShortTermMapper;
+import com.jiayue.insu.incloud.service.PowerStationStatusDataService;
+import com.jiayue.insu.incloud.service.UltraShortTermService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 实际功率数据业务实现
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Service
+public class PowerStationStatusDataServiceImpl extends ServiceImpl<PowerStationStatusDataMapper, PowerStationStatusData> implements PowerStationStatusDataService {
+
+
+    /**
+     *  根据生成时间查询超短期数据
+     * @param genDate
+     * @param stationCode
+     * @return
+     */
+    @Override
+    public List<PowerStationStatusData> findByGenDate(Long genDate,String stationCode) {
+        LambdaQueryWrapper<PowerStationStatusData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(PowerStationStatusData::getGenDate,genDate);
+        lambdaQueryWrapper.eq(PowerStationStatusData::getStationCode,stationCode);
+        return this.list(lambdaQueryWrapper);
+    }
+
+    @Override
+    public void save(List<PowerStationStatusData> list) {
+        this.saveOrUpdateBatch(list);
+    }
+}

+ 172 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/utils/FixedCapacityList.java

@@ -0,0 +1,172 @@
+package com.jiayue.insu.incloud.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class FixedCapacityList<E> extends LinkedList<E> {
+
+  int capacity;
+  int index = 0;
+
+  /**
+   * Constructs a list containing the elements of the specified
+   * collection, in the order they are returned by the collection's
+   * iterator.
+   *
+   * @param c the collection whose elements are to be placed into this list
+   * @throws NullPointerException if the specified collection is null
+   */
+  private FixedCapacityList(Collection<? extends E> c) {
+    super(c);
+  }
+
+  public FixedCapacityList(int size) {
+    super();
+    this.capacity = size;
+  }
+
+  /**
+   * Constructs an empty list.
+   */
+  private FixedCapacityList() {
+    super();
+  }
+
+  /**
+   * Inserts the specified element at the beginning of this list.
+   *
+   * @param e the element to add
+   */
+  @Override
+  public void addFirst(E e) {
+    if ((super.size() + 1) > capacity) {
+      super.removeLast();
+    }
+    super.addFirst(e);
+  }
+
+  /**
+   * Appends the specified element to the end of this list.
+   *
+   * <p>This method is equivalent to {@link #add}.
+   *
+   * @param e the element to add
+   */
+  @Override
+  public void addLast(E e) {
+    if ((super.size() + 1) > this.capacity) {
+      super.removeFirst();
+    }
+    super.addLast(e);
+  }
+
+  /**
+   * Appends the specified element to the end of this list.
+   *
+   * <p>This method is equivalent to {@link #addLast}.
+   *
+   * @param e element to be appended to this list
+   * @return {@code true} (as specified by {@link Collection#add})
+   */
+  @Override
+  public boolean add(E e) {
+    if ((super.size() + 1) > this.capacity) {
+      super.removeFirst();
+    }
+    return super.add(e);
+  }
+
+  /**
+   * Appends all of the elements in the specified collection to the end of
+   * this list, in the order that they are returned by the specified
+   * collection's iterator.  The behavior of this operation is undefined if
+   * the specified collection is modified while the operation is in
+   * progress.  (Note that this will occur if the specified collection is
+   * this list, and it's nonempty.)
+   *
+   * @param c collection containing elements to be added to this list
+   * @return {@code true} if this list changed as a result of the call
+   * @throws NullPointerException if the specified collection is null
+   */
+  @Override
+  public boolean addAll(Collection<? extends E> c) {
+    int length = this.capacity - super.size();
+    return super.addAll(c.stream().limit(length).collect(Collectors.toList()));
+  }
+
+  /**
+   * Inserts all of the elements in the specified collection into this
+   * list, starting at the specified position.  Shifts the element
+   * currently at that position (if any) and any subsequent elements to
+   * the right (increases their indices).  The new elements will appear
+   * in the list in the order that they are returned by the
+   * specified collection's iterator.
+   *
+   * @param index index at which to insert the first element
+   *              from the specified collection
+   * @param c     collection containing elements to be added to this list
+   * @return {@code true} if this list changed as a result of the call
+   * @throws IndexOutOfBoundsException {@inheritDoc}
+   * @throws NullPointerException      if the specified collection is null
+   */
+  @Override
+  public boolean addAll(int index, Collection<? extends E> c) {
+    if (index < (this.capacity - 1)) {
+      int length = this.capacity - index;
+      return super.addAll(index, c.stream().limit(length).collect(Collectors.toList()));
+    }
+    return false;
+  }
+
+  /**
+   * Replaces the element at the specified position in this list with the
+   * specified element.
+   *
+   * @param index   index of the element to replace
+   * @param element element to be stored at the specified position
+   * @return the element previously at the specified position
+   * @throws IndexOutOfBoundsException {@inheritDoc}
+   */
+  @Override
+  public E set(int index, E element) {
+    return super.set(index, element);
+  }
+
+  /**
+   * Inserts the specified element at the specified position in this list.
+   * Shifts the element currently at that position (if any) and any
+   * subsequent elements to the right (adds one to their indices).
+   *
+   * @param index   index at which the specified element is to be inserted
+   * @param element element to be inserted
+   * @throws IndexOutOfBoundsException {@inheritDoc}
+   */
+  @Override
+  public void add(int index, E element) {
+    if (index < (this.capacity - 1)) {
+      super.remove(index);
+      super.add(index, element);
+    }
+  }
+
+  /**
+   * Pushes an element onto the stack represented by this list.  In other
+   * words, inserts the element at the front of this list.
+   *
+   * <p>This method is equivalent to {@link #addFirst}.
+   *
+   * @param e the element to push
+   * @since 1.6
+   */
+  @Override
+  public void push(E e) {
+    if ((super.size() + 1) > this.capacity) {
+      super.pop();
+    }
+    super.push(e);
+  }
+}

+ 37 - 0
in-passback/src/main/java/com/jiayue/passback/entity/AccuracyPassRate.java

@@ -0,0 +1,37 @@
+package com.jiayue.passback.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jiayue.passback.entity.eunm.ElectricFieldTypeEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+
+/**
+ * 场站实体
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2019/7/22 11:16
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("T_ACCURACY_PASS_RATE")
+public class AccuracyPassRate extends AbstractBaseEntity {
+
+    /**
+     * 短期准确率
+     */
+    @TableField("C_SHORT_TERM_ACCURACY")
+    private String shortTermAccuracy;
+
+
+    /**
+     * 短期准确率
+     */
+    @TableField("C_TIME")
+    private Long time;
+
+}

+ 6 - 0
in-passback/src/main/java/com/jiayue/passback/entity/PowerStationStatusData.java

@@ -36,5 +36,11 @@ public class PowerStationStatusData extends AbstractEquipmentStatusData {
 	@TableField("C_THEORY_VALUE")
 	private BigDecimal theoryValue;
 
+	/**
+	 * 系统判断是否限电
+	 */
+	@TableField("C_IS_RATIONING_BY_AUTO_CONTROL")
+	private Boolean isRationingByAutoControl;
+
 
 }

+ 7 - 1
in-passback/src/main/java/com/jiayue/passback/entity/eunm/PredictionModelEnum.java

@@ -34,7 +34,13 @@ public enum PredictionModelEnum {
 	// 人工干预系数
 	E10(10, "干预系数模型"),
 
-	E11(11,"一体化修正形");
+	E11(11,"一体化修正模型"),
+
+	E12(12,"大风切机修正"),
+
+	E13(13,"超短期算法模型"),
+
+	E14(14,"集中功率预测修正");
 	private Integer code;
 	private String message;
 }

+ 28 - 28
in-passback/src/main/java/com/jiayue/passback/job/GenerateService.java

@@ -15,7 +15,7 @@ public abstract class GenerateService {
     private String sxglPath;
 
     public abstract void GenerateData();
-    public abstract void GenerateLlKyData();
+//    public abstract void GenerateLlKyData();
 
     public void generateFile(Map<String, Object> map, Date date) {
         log.info("====开始生成数据文件====");
@@ -40,32 +40,32 @@ public abstract class GenerateService {
 
     }
 
-    /**
-     * 理论,可用数据文件回传
-     * @param map
-     * @param date
-     */
-    public void generateLlKyFile(Map<String, Object> map, Date date) {
-        log.info("====开始生成数据文件====");
-
-        map.put("date",DateFormatUtils.format(date,"yyyyMMddHHmmss"));
-        File filePath = new File(sxglPath);
-        String fileName = "";
-        if (filePath.exists()) {
-            try {
-                fileName = "BACK_DATA_LLKY_FILE_"+DateFormatUtils.format(date,"yyyyMMddHHmmss") + ".CIME";
-                FreemarkerUtil.genLlkyFile(map, sxglPath, fileName);
-
-                log.info("{}目录下,{}文件生成成功!!!", sxglPath, fileName);
-            } catch (Exception e) {
-                log.info("{}目录下,{}文件生成时发生错误,文件生成失败", sxglPath, fileName);
-                log.info(e.getMessage());
-            }
-        } else {
-            log.info("{}正向隔离目录不存在,无法生成文件", sxglPath);
-        }
-        log.info("====生成数据文件结束====");
-
-    }
+//    /**
+//     * 理论,可用数据文件回传
+//     * @param map
+//     * @param date
+//     */
+//    public void generateLlKyFile(Map<String, Object> map, Date date) {
+//        log.info("====开始生成数据文件====");
+//
+//        map.put("date",DateFormatUtils.format(date,"yyyyMMddHHmmss"));
+//        File filePath = new File(sxglPath);
+//        String fileName = "";
+//        if (filePath.exists()) {
+//            try {
+//                fileName = "BACK_DATA_LLKY_FILE_"+DateFormatUtils.format(date,"yyyyMMddHHmmss") + ".CIME";
+//                FreemarkerUtil.genLlkyFile(map, sxglPath, fileName);
+//
+//                log.info("{}目录下,{}文件生成成功!!!", sxglPath, fileName);
+//            } catch (Exception e) {
+//                log.info("{}目录下,{}文件生成时发生错误,文件生成失败", sxglPath, fileName);
+//                log.info(e.getMessage());
+//            }
+//        } else {
+//            log.info("{}正向隔离目录不存在,无法生成文件", sxglPath);
+//        }
+//        log.info("====生成数据文件结束====");
+//
+//    }
 
 }

+ 30 - 30
in-passback/src/main/java/com/jiayue/passback/job/job.java

@@ -18,7 +18,7 @@ public class job extends GenerateService {
 
     private final List<GenerateDataService> generateDataServiceList;
 
-    private final List<GenerateDataLlKyService> generateDataLlKyServiceList;
+//    private final List<GenerateDataLlKyService> generateDataLlKyServiceList;
 
     private final ElectricFieldService electricFieldService;
 
@@ -41,40 +41,40 @@ public class job extends GenerateService {
             log.info("====数据生成业务结束====");
             generateFile(map,date);
         } catch (Exception e) {
-            log.info("数据生成业务发生错误  /(ㄒoㄒ)/~~");
+            log.info("数据生成业务发生错误  /(ㄒoㄒ)/~~",e);
             e.printStackTrace();
         }
 
     }
 
-    /**
-     *  内网回传理论可用功率数据
-     */
-    @Scheduled(cron = "${job.llKyjob}")
-//    @Scheduled(fixedDelay = 1000*60)
-    @Override
-    public void GenerateLlKyData() {
-        try {
-
-            Date date = new Date(DateMomentUtil.getMomentTime(new Date().getTime(), 1, 5 * 60 * 1000L));
-            Map<String,Object> map = new HashMap();
-            ElectricField electricField = electricFieldService.list().get(0);
-
-            map.put("elType",electricField.getElectricFieldTypeEnum().name());
-            log.info("====开始启动数据生成业务,时间:{}====",DateFormatUtils.format(date,"yyyy-MM-dd HH:mm:ss"));
-            generateDataLlKyServiceList.forEach(g -> {
-
-                map.putAll(g.GenerateDataLlKy(date));
-            });
-
-            log.info("====数据生成业务结束====");
-            generateLlKyFile(map,date);
-        } catch (Exception e) {
-            log.info("数据生成业务发生错误  /(ㄒoㄒ)/~~");
-            e.printStackTrace();
-        }
-
-    }
+//    /**
+//     *  内网回传理论可用功率数据
+//     */
+//    @Scheduled(cron = "${job.llKyjob}")
+////    @Scheduled(fixedDelay = 1000*60)
+//    @Override
+//    public void GenerateLlKyData() {
+//        try {
+//
+//            Date date = new Date(DateMomentUtil.getMomentTime(new Date().getTime(), 1, 5 * 60 * 1000L));
+//            Map<String,Object> map = new HashMap();
+//            ElectricField electricField = electricFieldService.list().get(0);
+//
+//            map.put("elType",electricField.getElectricFieldTypeEnum().name());
+//            log.info("====开始启动数据生成业务,时间:{}====",DateFormatUtils.format(date,"yyyy-MM-dd HH:mm:ss"));
+//            generateDataLlKyServiceList.forEach(g -> {
+//
+//                map.putAll(g.GenerateDataLlKy(date));
+//            });
+//
+//            log.info("====数据生成业务结束====");
+//            generateLlKyFile(map,date);
+//        } catch (Exception e) {
+//            log.info("数据生成业务发生错误  /(ㄒoㄒ)/~~");
+//            e.printStackTrace();
+//        }
+
+//    }
 
 
 

+ 7 - 0
in-passback/src/main/java/com/jiayue/passback/mapper/AccuracyPassRateMapper.java

@@ -0,0 +1,7 @@
+package com.jiayue.passback.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.passback.entity.AccuracyPassRate;
+
+public interface AccuracyPassRateMapper extends BaseMapper<AccuracyPassRate> {
+}

+ 8 - 0
in-passback/src/main/java/com/jiayue/passback/service/AccuracyPassRateService.java

@@ -0,0 +1,8 @@
+package com.jiayue.passback.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.passback.entity.AccuracyPassRate;
+
+public interface AccuracyPassRateService extends IService<AccuracyPassRate>,GenerateDataService{
+
+}

+ 39 - 0
in-passback/src/main/java/com/jiayue/passback/service/impl/AccuracyPassRateServiceImpl.java

@@ -0,0 +1,39 @@
+package com.jiayue.passback.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.passback.entity.AccuracyPassRate;
+import com.jiayue.passback.mapper.AccuracyPassRateMapper;
+import com.jiayue.passback.service.AccuracyPassRateService;
+import com.jiayue.passback.util.DateMomentUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+public class AccuracyPassRateServiceImpl extends ServiceImpl<AccuracyPassRateMapper, AccuracyPassRate> implements AccuracyPassRateService {
+
+    @Override
+    public Map<String, Object> GenerateData(Date date) {
+        Long startTime = DateMomentUtil.getDayStartTime(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
+        Long endTime = DateMomentUtil.getDayLastTime(startTime);
+        Map<String, Object> map = new HashMap<>();
+
+        List<AccuracyPassRate> accuracyPassRateList = list(lambdaQuery().between(AccuracyPassRate::getTime, startTime, endTime).getWrapper());
+
+        accuracyPassRateList.stream().filter(f -> !f.getShortTermAccuracy().equals("无可用数据计算") && !f.getShortTermAccuracy().equals("无计算公式")).collect(Collectors.toList());
+
+        if (accuracyPassRateList.size() > 0) {
+            accuracyPassRateList.sort(Comparator.comparing(AccuracyPassRate::getTime).reversed());
+            map.put("accuracy", accuracyPassRateList.get(0).getShortTermAccuracy().replace("%", ""));
+        } else {
+            map.put("accuracy", "NULL");
+        }
+
+        log.info("获取两个细则短期准确率:{}", map.get("accuracy"));
+        return map;
+    }
+
+}

+ 1 - 16
in-passback/src/main/java/com/jiayue/passback/service/impl/PowerStationStatusDataServiceImpl.java

@@ -25,23 +25,8 @@ public class PowerStationStatusDataServiceImpl extends ServiceImpl<PowerStationS
         }
 
         map.put(PowerStationStatusData.class.getSimpleName(), list);
-        log.info("获取实际功率记录数{}", list.size());
+        log.info("获取实际功率、可用功率、理论功率、限电记录数{}", list.size());
         return map;
     }
 
-    @Override
-    public Map<String, Object> GenerateDataLlKy(Date date) {
-        Map<String, Object> map = new HashMap<>();
-        List<PowerStationStatusData> list = new ArrayList<>();
-
-        List<PowerStationStatusData> powerStationStatusDataList = list(lambdaQuery().eq(PowerStationStatusData::getTime, date).getWrapper());
-
-        if (powerStationStatusDataList.size() > 0) {
-            list.add(powerStationStatusDataList.get(0));
-        }
-
-        map.put(PowerStationStatusData.class.getSimpleName(), list);
-        log.info("获取理论可用功率记录数{}", list.size());
-        return map;
-    }
 }

+ 5 - 2
in-passback/src/main/java/com/jiayue/passback/service/impl/UploadFileLogServiceImpl.java

@@ -6,6 +6,7 @@ import com.jiayue.passback.entity.UploadFileLog;
 import com.jiayue.passback.entity.eunm.FileStatusEnum;
 import com.jiayue.passback.mapper.UploadFileLogMapper;
 import com.jiayue.passback.service.UploadFileLogService;
+import com.jiayue.passback.util.DateMomentUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -37,9 +38,11 @@ public class UploadFileLogServiceImpl extends ServiceImpl<UploadFileLogMapper, U
 
         Date cdqEndTime = new Date(date.getTime() + 15 * 60 * 1000);
 
-        Date dqStartTime = new Date(date.getTime() - 15 * 60 * 1000);
+//        Date dqStartTime = new Date(date.getTime() - 15 * 60 * 1000);
+        Date dqStartTime = new Date(DateMomentUtil.getDayStartTime(new Date().getTime()));
 
-        Date dqEndTime = new Date(date.getTime() + 15 * 60 * 1000);
+//        Date dqEndTime = new Date(date.getTime() + 15 * 60 * 1000);
+        Date dqEndTime = new Date(DateMomentUtil.getDayLastTime(new Date().getTime()));
         Map<String, Object> map = new HashMap<>();
 
 

+ 19 - 0
in-passback/src/main/resources/template/template.ftl

@@ -24,6 +24,25 @@
 </RealWeather>
 
 </#if>
+<TheoryPower>
+@ 序号   理论功率值   可用功率值
+<#list PowerStationStatusData as p>
+# ${p_index+1}   ${p.theoryValue?string("0.00")}   ${p.ableValue?string("0.00")}
+</#list>
+</TheoryPower>
+
+<AccuracyRate>
+@ 序号   两则准确率
+# 1    ${accuracy}
+</AccuracyRate>
+
+<LimitPowerFlag>
+@ 序号   限电
+<#list PowerStationStatusData as p>
+# ${p_index+1}   ${(p.isRationingByAutoControl?then("1", "0"))}
+</#list>
+</LimitPowerFlag>
+
 <ForecastPowerReport>
 @ 序号   上报
 # 1    ${dqStatus}