Explorar el Código

这次提交的有点多1.飔合科技相关2.武穴相关3.林洋相关

fanxiaoyu hace 3 meses
padre
commit
e6f3fbd2e9
Se han modificado 64 ficheros con 4083 adiciones y 73 borrados
  1. 1 0
      in-client-qn-ui/src/views/data/usfpcorrect/index.vue
  2. 4 0
      in-client-qn-ui/src/views/record/index.vue
  3. 21 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/constant/CommonStant.java
  4. 4 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/constant/TemplateStant.java
  5. 1 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/entity/CorrectUltraShortTerm.java
  6. 74 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/entity/SHKJLNCorrfore.java
  7. 1 1
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/entity/Station.java
  8. 4 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/inenum/QNHLEnum.java
  9. 53 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/inenum/SHKJLNEnum.java
  10. 3 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/inenum/StatusEnum.java
  11. 25 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/CdqFileAnalysisJob.java
  12. 66 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/SHKJLNCorrforeDataJob.java
  13. 33 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/WXComPermissonJob.java
  14. 65 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/WXCorrforeDataJob.java
  15. 65 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/job/WXPushDataJob.java
  16. 16 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/mapper/SHKJLNCorrforeMapper.java
  17. 35 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/model/SHKJLNResponseVo.java
  18. 37 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/model/WXResponseVo.java
  19. 110 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/permisson/com/WXComPermisson.java
  20. 21 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pulldata/IPullInitForecastDataSH.java
  21. 194 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pulldata/PullInitDataSH.java
  22. 9 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pushData/IPushForecastData.java
  23. 166 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pushData/PushForecastData.java
  24. 22 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/SHKJLNCorrforeService.java
  25. 397 20
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/BackDataAnalysisService.java
  26. 26 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/BackDataGenBodyService.java
  27. 3 3
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/CorrforeService.java
  28. 218 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/SHKJCorrforeService.java
  29. 370 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/client/WXCorrforeService.java
  30. 44 0
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/impl/SHKJLNCorrforeServiceImpl.java
  31. 73 5
      in-client-qn/src/main/java/com/jiayue/insu/inclientqn/util/DateTimeUtils.java
  32. 9 0
      in-client-qn/src/main/resources/vms/CDQ.vm
  33. 5 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/constants/CommonStant.java
  34. 9 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/constants/CompanyConstant.java
  35. 44 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/constants/dto/SHKJLNPushDqDataParamsDto.java
  36. 72 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/constants/enums/SHKJEnum.java
  37. 41 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/constants/vo/ResponseLXVo.java
  38. 46 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/constants/vo/ResponseSHLNVo.java
  39. 190 25
      in-cloud/src/main/java/com/jiayue/insu/incloud/controller/ApiController.java
  40. 44 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/entity/UltraShortTerm.java
  41. 41 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/job/data/pull/SHKJPullCorrectDataJob.java
  42. 59 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/job/data/push/LXPushInitDqDataJob.java
  43. 58 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/job/data/push/SHKJLNPushInitDqDataJob.java
  44. 11 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/UltraShortTermMapper.java
  45. 20 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/pulldata/IPullInitCorrectDataForSH.java
  46. 410 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/pulldata/PullCorrectDataForSH.java
  47. 195 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForLX.java
  48. 234 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForSH.java
  49. 29 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/ApiService.java
  50. 4 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/ForecastDataService.java
  51. 15 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/UltraShortTermService.java
  52. 210 6
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/ApiServiceImpl.java
  53. 10 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/ForecastDataServiceImpl.java
  54. 41 0
      in-cloud/src/main/java/com/jiayue/insu/incloud/service/impl/UltraShortTermServiceImpl.java
  55. 1 1
      in-cloud/src/main/java/com/jiayue/insu/incloud/utils/HttpUtils.java
  56. 1 1
      in-passback/pom.xml
  57. 4 4
      in-passback/src/main/java/com/jiayue/passback/controller/InApiController.java
  58. 7 1
      in-passback/src/main/java/com/jiayue/passback/entity/PowerStationStatusData.java
  59. 29 0
      in-passback/src/main/java/com/jiayue/passback/job/GenerateService.java
  60. 31 0
      in-passback/src/main/java/com/jiayue/passback/job/job.java
  61. 1 1
      in-passback/src/main/java/com/jiayue/passback/service/PowerStationStatusDataService.java
  62. 9 3
      in-passback/src/main/java/com/jiayue/passback/service/impl/InApiServiceImpl.java
  63. 18 2
      in-passback/src/main/java/com/jiayue/passback/service/impl/PowerStationStatusDataServiceImpl.java
  64. 24 0
      in-passback/src/main/java/com/jiayue/passback/util/FreemarkerUtil.java

+ 1 - 0
in-client-qn-ui/src/views/data/usfpcorrect/index.vue

@@ -62,6 +62,7 @@
       <el-table-column show-overflow-tooltip label="请求时间" prop="requestTime" />
       <el-table-column show-overflow-tooltip label="传输时间" prop="passTime"/>
       <el-table-column show-overflow-tooltip label="预测时间" prop="forecastTime" />
+      <el-table-column show-overflow-tooltip label="修正数据" prop="correctValue" />
       <el-table-column show-overflow-tooltip label="预测系数" prop="ratio" />
 
 

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

@@ -122,11 +122,14 @@
         tableData: [],
         types: [
           {label:"修正DQ数据",value:"PULL_CORRECT"},
+          {label:"修正CDQ数据",value:"PULL_CDQ_CORRECT"},
           {label:"交互权限",value:"COM_PERMISSON"},
           {label:"修正DQ文件",value:"PULL_CORRECT_JY"},
           {label:"修正数据",value:"CORRECT_DATA"},
           {label:"回传数据",value:"BACK_DATA"},
           {label:"回传文件解析",value:"BACK_DATA_FILE"},
+          {label:"推送原始数据",value:"PUSH_INIT"},
+          {label:"超短期文件解析",value:"BACK_CDQ_DATA_FILE"},
         ],
         contents:[
           {label:"回传预测数据",value:"BACK_FORE_ALL"},
@@ -134,6 +137,7 @@
           {label:"下发超短期修正",value:"CORRULTRSHOR"},
           {label:"下发检修计划",value:"REPAPLAN"},
           {label:"文件解析",value:"BACK_FILE_ANALYSIS"},
+          {label:"超短期文件解析",value:"BACK_CDQ_DATA_FILE"},
         ],
         searchForm: {},
         times: [

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

@@ -25,6 +25,8 @@ public interface CommonStant {
      */
     String RECORD_TYPE_PULL_CORRECT = "PULL_CORRECT";
 
+    String RECORD_TYPE_PULL_CDQ_CORRECT = "PULL_CDQ_CORRECT";
+
 
     /**
      * 日志类型:下拉修正数据(嘉越修正)
@@ -41,10 +43,29 @@ public interface CommonStant {
      */
     String RECORD_TYPE_BACK_DATA_FILE = "BACK_DATA_FILE";
 
+
+    /**
+     * 日志类型:回传超短期文件解析
+     */
+    String RECORD_TYPE_CDQ_BACK_DATA_FILE = "BACK_CDQ_DATA_FILE";
+
+    String RECORD_TYPE_CDQ_FILE = "HGRXGG";
+
+    /**
+     * 日志类型:回传理论可用文件解析
+     */
+    String RECORD_TYPE_BACK_DATA_LLKY_FILE = "BACK_DATA_LLKY_FILE";
+
     /**
      * 日志类型:回传数据
      */
     String RECORD_TYPE_BACK_DATA = "BACK_DATA";
+
+    /**
+     * 日志类型:回传数据(理论可用)
+     */
+    String RECORD_TYPE_BACK_LLkY_DATA = "BACK_LLkY_DATA";
+
     /**
      * 日志类型:修正数据
      */

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

@@ -69,6 +69,10 @@ public interface TemplateStant {
     String BACK_STAT_REAL_POWER_TEMPLATE= "# 1" + CommonStant.SPACE2_CONSTANT + "{}" + CommonStant.LINE_CONSTANT;
 
 
+    String BACK_STAT_THEORY_POWER_TITLE= "@" + CommonStant.SPACE1_CONSTANT + "序号" + CommonStant.SPACE3_CONSTANT + "理论功率值" + CommonStant.SPACE3_CONSTANT + "可用功率值"+ CommonStant.LINE_CONSTANT;
+
+    String BACK_STAT_THEORY_POWER_TEMPLATE= "# 1" + CommonStant.SPACE3_CONSTANT + "{}"+ CommonStant.SPACE3_CONSTANT + "{}" + CommonStant.LINE_CONSTANT;
+
     String HEADER_TEMPLATE = "<! Entity={}  time='{}' !>" + CommonStant.LINE_CONSTANT;
 
 

+ 1 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/entity/CorrectUltraShortTerm.java

@@ -37,4 +37,5 @@ public class CorrectUltraShortTerm extends  BaseCorrectTime {
      */
     BigDecimal ratio;
 
+    BigDecimal correctValue;
 }

+ 74 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/entity/SHKJLNCorrfore.java

@@ -0,0 +1,74 @@
+package com.jiayue.insu.inclientqn.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.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 修正数据(飔合科技)
+ *
+ * @author fxy
+ * @date 2023-12-15 19:33:02
+ */
+@Data
+@TableName("shkjln_corrfore")
+public class SHKJLNCorrfore implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private String id;
+
+    /**
+     * 预测时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime timeFormat;
+
+    /**
+     * 预测时间
+     */
+    private Long forecastTime;
+    /**
+     * 预测值
+     */
+    private BigDecimal fpValue;
+
+    /**
+     *  数据最后一次修改时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     * 创建时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime correctTime;
+
+    @TableField( exist = false)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Long startTime;
+
+    @TableField( exist = false)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Long endTime;
+
+    /**
+     * 场站编码
+     */
+    String stationCode;
+}

+ 1 - 1
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/entity/Station.java

@@ -63,7 +63,7 @@ public class Station {
     String downloadurl;
 
     /**
-     * 回传url
+     * 回传url 武穴天机一体化回传url用作 上送云端原始超短期数据接口地址
      */
     String backurl;
     /**

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

@@ -32,6 +32,7 @@ public enum QNHLEnum {
     DATA_CORRFORE_TYPE("CORRFORE","CORRFORE","优化后预测"),
     DATA_TODAYFORE_TYPE("TODAYFORE","TODAYFORE","优化后当日预测"),
     DATA_CORRULTRSHOR_TYPE("CORRULTRSHOR","CORRULTRSHOR","超短期修正"),
+    DATA_ORIGINALCDQ_TYPE("ULTRASHORTTERMPRIMITIVE","ULTRASHORTTERMPRIMITIVE","原始超短期"),
     DATA_REPAPLAN_TYPE("REPAPLAN","REPAPLAN","检修计划"),
     /**
      * 回传数据类型划分
@@ -39,12 +40,15 @@ public enum QNHLEnum {
     DATA_FORE_TYPE_UltraShortTermForecast("UltraShortTermForecast","UltraShortTermForecast","超短期功率预测上报回传"),
     DATA_FORE_TYPE_ForecastPower("ForecastPower","ForecastPower","短期功率预测上报回传"),
     DATA_STAT_TYPE_RealPower("RealPower","RealPower","实发功率回传"),
+    DATA_STAT_TYPE_TheoryPower("TheoryPower","TheoryPower","理论可用回传"),
     DATA_STAT_TYPE_RealWeather("RealWeather","RealWeather","实际气象回传"),
     DATA_STAT_TYPE_ForecastPowerReport("ForecastPowerReport","ForecastPowerReport","短期上报状态回传"),
     DATA_STAT_TYPE_UltraShortTermForecastReport("UltraShortTermForecastReport","UltraShortTermForecastReport","超短期上报状态回传"),
 
     DATA_STAT_ALL("BACK_STAT_ALL","BACK_STAT_ALL","统计数据回传"),
 
+    DATA_STAT_KYLL("DATA_STAT_KYLL","DATA_STAT_KYLL","可用理论数据回传"),
+
     DATA_FORE_ALL("BACK_FORE_ALL","BACK_FORE_ALL","预测数据回传")
             ;
 

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

@@ -0,0 +1,53 @@
+package com.jiayue.insu.inclientqn.inenum;
+/**
+ * 飔合科技(辽宁) ENUM
+ *
+ * @author fxy
+ * @version 1.0
+ * @since 2023/12/15 11:29
+ */
+public enum SHKJLNEnum {
+
+    REQUEST_SUCCESS("200","success","请求曲线调整策略成功"),
+    REQUEST_FAIL("T000","fail","请求失败"),
+
+    REQUEST_TOKEN_SUCCESS("1","success","请求飔合科技token成功"),
+    REQUEST_TOKEN_FAIL("0","failure","请求飔合科技token失败");
+
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSuccess(String sign) {
+        this.sign = sign;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    SHKJLNEnum(String code, String sign, String msg) {
+        this.code = code;
+        this.sign = sign;
+        this.msg = msg;
+    }
+
+    private String code;
+    private String sign;
+    private String msg;
+
+
+}

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

@@ -22,6 +22,9 @@ public enum StatusEnum {
     GEN_FILE_FAIL("gen_file_fail","gen_file_fail","生成文件失败"),
 
     DATA_DEFICIENCY("data_deficiency","data_deficiency","数据缺失"),
+    STATION_CODE_NULL("station_code_null","station_code_null","场站编码为空"),
+
+
     ;
 
     private String code;

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

@@ -0,0 +1,25 @@
+package com.jiayue.insu.inclientqn.job;
+
+import cn.hutool.core.date.DateUtil;
+import com.jiayue.insu.inclientqn.service.BackForeUsForecastDataService;
+import com.jiayue.insu.inclientqn.service.client.BackDataAnalysisService;
+import com.jiayue.insu.inclientqn.util.DateTimeUtils;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ *  解析内网会回传超短期文件定时任务
+ */
+public class CdqFileAnalysisJob implements Job {
+
+    @Autowired
+    private BackDataAnalysisService backDataAnalysisService;
+    @Override
+    public void execute(JobExecutionContext context) throws JobExecutionException {
+        // 获取当前时间所在15分钟节点 例如 10:18=》10:15 、 11:29=>11:15
+        long time = DateTimeUtils.get15min(DateUtil.date().getTime()) + 15 * 60 * 1000L;
+        backDataAnalysisService.watchCdqFile(time);
+    }
+}

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

@@ -0,0 +1,66 @@
+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.service.RecordService;
+import com.jiayue.insu.inclientqn.service.SHKJLNCorrforeService;
+import com.jiayue.insu.inclientqn.service.StationService;
+import com.jiayue.insu.inclientqn.service.client.SHKJCorrforeService;
+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;
+
+/**
+ * @description: 请求一体化 修正数据  飔合科技(辽宁)
+ * @author: yuanhao
+ * @createDate: 2022/6/17
+ * @version: 1.0
+ */
+public class SHKJLNCorrforeDataJob implements Job {
+
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private SHKJCorrforeService shkjCorrforeService;
+
+    @Override
+
+    public void execute(JobExecutionContext jobExecutionContext) 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_PULL_CORRECT, StatusEnum.SUCCESS.getCode(), station.getStationCode());
+                if (successRecord != null) {
+                    return;
+                }
+                // 飔合科技 下载修正后短期数据
+                shkjCorrforeService.downLoadCorrforeData(station);
+            }
+            // 如果场站打扰等于于1个,则直接请求飔合科技修正数据
+        } else if (stationList != null && stationList.size() == 1) {
+            successRecord = recordService.findTimeAndTypeAndState(localDateTime, CommonStant.RECORD_TYPE_PULL_CORRECT, StatusEnum.SUCCESS.getCode());
+            // 如果有执行记录,则不再执行
+            if (successRecord != null) {
+                return;
+            }
+            // 飔合科技 下载修正后短期数据
+            shkjCorrforeService.downLoadCorrforeData(stationList.get(0));
+        }
+
+    }
+}

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

@@ -0,0 +1,33 @@
+package com.jiayue.insu.inclientqn.job;
+
+import com.jiayue.insu.inclientqn.entity.Station;
+import com.jiayue.insu.inclientqn.permisson.com.ComPermisson;
+import com.jiayue.insu.inclientqn.permisson.com.WXComPermisson;
+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 WXComPermissonJob implements Job {
+
+    @Autowired
+    private WXComPermisson wxComPermisson;
+    @Autowired
+    private StationService stationService;
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        List<Station> stationList = stationService.findAll();
+        for(Station station : stationList){
+            wxComPermisson.generateKey(station);
+        }
+    }
+}

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

@@ -0,0 +1,65 @@
+package com.jiayue.insu.inclientqn.job;
+
+import cn.hutool.core.date.DateUtil;
+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.QNHLEnum;
+import com.jiayue.insu.inclientqn.inenum.StatusEnum;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import com.jiayue.insu.inclientqn.service.StationService;
+import com.jiayue.insu.inclientqn.service.client.BJZYYJYCorrforeService;
+import com.jiayue.insu.inclientqn.service.client.WXCorrforeService;
+import com.jiayue.insu.inclientqn.util.DateTimeUtils;
+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;
+
+/**
+ * @description: 武穴请求一体化修正数据
+ * @author: yuanhao
+ * @createDate: 2022/6/17
+ * @version: 1.0
+ */
+public class WXCorrforeDataJob implements Job {
+
+    @Autowired
+    private WXCorrforeService wxCorrforeService;
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        long time = DateTimeUtils.get15min(DateUtil.date().getTime());
+        // 获取全部场站
+        List<Station> stationList = stationService.findAll();
+        Record record;
+        LocalDateTime localDateTime = LocalDateTimeUtil.of(time);
+
+        // 如果场站大于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;
+                }
+                wxCorrforeService.downLoadCorrforeData(station, time);
+            }
+            // 如果只有一个场站
+        } 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;
+            }
+            wxCorrforeService.downLoadCorrforeData(stationList.get(0), time);
+        }
+
+    }
+}

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

@@ -0,0 +1,65 @@
+package com.jiayue.insu.inclientqn.job;
+
+import cn.hutool.core.date.DateUtil;
+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.QNHLEnum;
+import com.jiayue.insu.inclientqn.inenum.StatusEnum;
+import com.jiayue.insu.inclientqn.pushData.PushForecastData;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import com.jiayue.insu.inclientqn.service.StationService;
+import com.jiayue.insu.inclientqn.service.client.WXCorrforeService;
+import com.jiayue.insu.inclientqn.util.DateTimeUtils;
+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;
+
+/**
+ * @description: 武穴向一体化云端传输超短期原始数据
+ * @author: yuanhao
+ * @createDate: 2022/6/17
+ * @version: 1.0
+ */
+public class WXPushDataJob implements Job {
+
+    @Autowired
+    private PushForecastData pushForecastData;
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        long time = DateTimeUtils.get15min(DateUtil.date().getTime());
+        // 获取全部场站
+        List<Station> stationList = stationService.findAll();
+        Record record;
+        LocalDateTime signTime = LocalDateTimeUtil.of(time);
+
+        // 如果场站大于2个,则为多场站情况
+        if (stationList != null && stationList.size() > 1) {
+            for (Station station : stationList) {
+                record = recordService.findTimeAndTypeAndContentAndStateAndStationCode(signTime, CommonStant.RECORD_TYPE_PUSH_INIT, QNHLEnum.DATA_ORIGINALCDQ_TYPE.getCode(), StatusEnum.SUCCESS.getSign(),station.getStationCode());
+                if (record != null) {
+                    return;
+                }
+                pushForecastData.pushUltraShortTermDataWX(station, signTime);
+            }
+            // 如果只有一个场站
+        } else if (stationList != null && stationList.size() == 1) {
+            record = recordService.findTimeAndTypeAndContentAndState(signTime, CommonStant.RECORD_TYPE_PUSH_INIT, QNHLEnum.DATA_ORIGINALCDQ_TYPE.getCode(), StatusEnum.SUCCESS.getSign());
+            if (record != null) {
+                return;
+            }
+            pushForecastData.pushUltraShortTermDataWX(stationList.get(0), signTime);
+        }
+
+    }
+}

+ 16 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/mapper/SHKJLNCorrforeMapper.java

@@ -0,0 +1,16 @@
+package com.jiayue.insu.inclientqn.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jiayue.insu.inclientqn.entity.SHKJLNCorrfore;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 修正数据mapper
+ *
+ * @author xsl
+ * @date 2022-04-12 19:33:02
+ */
+@Mapper
+public interface SHKJLNCorrforeMapper extends BaseMapper<SHKJLNCorrfore> {
+
+}

+ 35 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/model/SHKJLNResponseVo.java

@@ -0,0 +1,35 @@
+package com.jiayue.insu.inclientqn.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @description: 飔合科技(辽宁)一体化响应VO
+ * @author: fxy
+ * @createDate: 2023/12/15
+ * @version: 1.0
+ */
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SHKJLNResponseVo {
+
+    /**
+     * 响应码
+     */
+    private String code;
+
+    /**
+     * 响应信息
+     */
+    private String msg;
+
+    /**
+     *  是否成功
+     */
+    private String token;
+
+}

+ 37 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/model/WXResponseVo.java

@@ -0,0 +1,37 @@
+package com.jiayue.insu.inclientqn.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * @description: 武穴一体化响应VO
+ * @author: fxy
+ * @createDate: 2023/12/15
+ * @version: 1.0
+ */
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WXResponseVo {
+
+    /**
+     * 响应码
+     */
+    private String statusCode;
+    /**
+     * 响应信息
+     */
+    private String message;
+
+    /**
+     * 相应结果
+     */
+    private String result;
+    /**
+     * 响应数据
+     */
+    private String data;
+}

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

@@ -0,0 +1,110 @@
+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.JSONObject;
+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.BJZYYJYSDEnum;
+import com.jiayue.insu.inclientqn.inenum.QNHLEnum;
+import com.jiayue.insu.inclientqn.model.BJZYYJYSDTokenVo;
+import com.jiayue.insu.inclientqn.model.WXResponseVo;
+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 java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 武穴天机生成通讯token
+ *
+ * @author fxy
+ * @version 1.0
+ * @since 2023/12/14 11:29
+ */
+@Component
+@Slf4j
+public class WXComPermisson {
+
+    @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(QNHLEnum.REQUEST_FAIL.getSign());
+        record.setStationCode(station.getStationCode());
+        boolean result = false;
+        // token地址
+        String tokenUrl = station.getComurl();
+        String response;
+        String token;
+        Map<String,String> map = new HashMap<>();
+        // 固定的请求体 直接写死
+        map.put("accessKey","ik68V9W7YownNJwN8TyH6pW2DurQgbo3kFJtIBn58l");
+        map.put("secretKey","{noop}bCycOavnyAL25Jde2vXLClXuBJ6g0BenvVbEHFCmO0YZKiHxWxLk7zS5ct4i8lxOGBlLMiwhn1mriE0HQbBry");
+        // 请求token
+        try {
+            HttpRequest httpRequest = HttpRequest.post(tokenUrl)
+                    .header("Content-Type", "application/json");
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.body(JSONUtil.toJsonStr(map)).execute().body();
+            // 判断响应内容
+            if (StrUtil.isNotEmpty(response)) {
+                boolean isJson = JSONUtil.isJsonObj(response);
+                if (isJson) {
+                    WXResponseVo wxResponseVo = JSONUtil.toBean(response, WXResponseVo.class);
+                    if (wxResponseVo.getData() != null) {
+                        // 获取到token
+                        JSONObject jsonObject = new JSONObject(wxResponseVo.getData());
+                        String dataObject = jsonObject.getStr("token");
+                        token = dataObject;
+                        log.info("========== 武穴一体化token请求成功: {} token=" + token + "  ==========", station.getStationCode());
+                        station.setComKey(token);
+                        // token过期时间3小时
+                        station.setKeyTime(Instant.ofEpochMilli(System.currentTimeMillis() + 3 * 60 * 60 * 1000L).atZone(ZoneId.systemDefault()).toLocalDateTime());
+                        stationService.updateById(station);
+                        record.setState(QNHLEnum.REQUEST_SUCCESS.getSign());
+                        result = true;
+                    } else {
+                        log.error("========== 未成功获取到鉴权令牌 ========== ");
+                    }
+                } 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;
+    }
+}

+ 21 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pulldata/IPullInitForecastDataSH.java

@@ -0,0 +1,21 @@
+package com.jiayue.insu.inclientqn.pulldata;
+
+import com.jiayue.insu.inclientqn.entity.*;
+
+import java.util.List;
+
+/**
+ * 拉取预测原始数据接口
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public interface IPullInitForecastDataSH {
+
+    /**
+     * 拉取短期预测原始数据
+     */
+    List<CorrforeSt> pullDQData(Station station);
+
+}

+ 194 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/pulldata/PullInitDataSH.java

@@ -0,0 +1,194 @@
+package com.jiayue.insu.inclientqn.pulldata;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jiayue.insu.inclientqn.constant.CommonStant;
+import com.jiayue.insu.inclientqn.entity.*;
+import com.jiayue.insu.inclientqn.inenum.StatusEnum;
+import com.jiayue.insu.inclientqn.service.*;
+import com.jiayue.insu.inclientqn.util.DateTimeUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 拉取飔合科技修正数据from一体化云端(飔合科技)
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Component
+@Slf4j
+@RefreshScope
+public class PullInitDataSH implements IPullInitForecastDataSH {
+
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private CorrforeStService corrforeStService;
+    @Value("${minio.pull.url}")
+    String url;
+    @Value("${minio.pull.fileurl}")
+    String fileurl;
+    @Value("${minio.fileurl}")
+    String fileDir;
+
+    /**
+     * 拉取短期修正数据(飔合科技)
+     *
+     * @param station 场站信息
+     */
+    @Override
+    public List<CorrforeSt> pullDQData(Station station) {
+
+        Record record = new Record();
+        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+        record.setStationCode(station.getStationCode());
+        record.setTime(localDateTime);
+        record.setCreateTime(LocalDateTime.now());
+        record.setType(CommonStant.RECORD_TYPE_PULL_INIT);
+        log.info("开始从一体化云请求飔合科技修正数据 --> {}" + station.getStationCode());
+        // 下载地址
+        String postUrl = station.getDownloadurl();
+        List<CorrforeSt> list = new ArrayList<>();
+        Map<String, Object> mapBody = new HashMap<>();
+        mapBody.put("wfId", station.getStationCode());
+        mapBody.put("init_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(DateTimeUtils.getDayStartTime(System.currentTimeMillis()))).toString());
+        try {
+            HttpRequest httpRequest = HttpRequest.post(postUrl)
+                    .header("Content-Type", "application/json")
+                            .header("Authorization",station.getUsername()+":"+station.getComKey());
+            httpRequest.setGlobalTimeout(20000);
+            String body = httpRequest.body(JSONUtil.toJsonStr(mapBody)).execute().body();
+            JSONObject json = JSONUtil.parseObj(body);
+            String code = json.get("code").toString();
+            String data = json.get("data").toString();
+            if (code.equals("200") && data.length() > 0) {
+                // 如果data = null 则用原始数据进行上报
+                if (!"[]".equals(data)) {
+                    list = correctData(data);
+                    // 如果修正后短期数据不为0
+                    if (list.size() > 0) {
+                        // 将修正数据存库
+                        corrforeStService.updateBetweenForecastTime(list.get(0).getTimeFormat(), list.get(list.size() - 1).getTimeFormat(),list);
+                    }
+                } else {
+                    // 存入记录
+                    record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getCode());
+                    record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
+                }
+
+            } else {
+                record.setState(StatusEnum.RESPONSE_FAIL.getCode());
+                log.error("请求飔合科技修正数据 --> {} 失败,失败原因:{}", station.getStationCode(), StatusEnum.RESPONSE_FAIL.getMsg());
+            }
+        } catch (Exception e) {
+            record.setState(StatusEnum.RESPONSE_FAIL.getCode());
+            log.error("请求飔合科技修正数据 --> {} 失败,失败原因:{}", station.getStationCode(), StatusEnum.RESPONSE_FAIL.getMsg());
+            e.printStackTrace();
+
+        }
+
+        recordService.save(record);
+        return list;
+    }
+
+
+    /**
+     * 数据解析
+     *
+     * @param data 待解析数据
+     * @return
+     * @throws Exception
+     */
+    public List<CorrforeSt> correctData(String data) throws Exception {
+
+        List<CorrforeSt> list = new ArrayList<>();
+        data = data.substring(1, data.length() - 1);
+        String[] content = data.split("(?<=})\\s*,\\s*");
+
+        for (int i = 0; i < content.length; i++) {
+            CorrforeSt corrforeSt = new CorrforeSt();
+            String column = content[i];
+            //JSON 字符串转换为一个树状结构
+            ObjectMapper objectMapper = new ObjectMapper();
+            JsonNode rootNode = objectMapper.readTree(column);
+            // 通过键名获取相应的值
+            String forecastTime = rootNode.get("time").asText();
+            double ageValue = rootNode.get("power").asDouble();
+            // 将预测时间转换为时间戳格式
+            Long forecast = DateUtil.parse(forecastTime, "yyyy-MM-dd HH:mm:ss").getTime();
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            String forecastDateFormat = dateFormat.format(new Date(forecast));
+            // 存入实体
+            corrforeSt.setForecastTime(forecast);
+            corrforeSt.setCorrectTime(DateUtil.parse(dateFormat.format(new Date()), "yyyy-MM-dd HH:mm:ss").toTimestamp().toLocalDateTime());
+            corrforeSt.setTimeFormat(DateUtil.parse(forecastDateFormat, "yyyy-MM-dd HH:mm:ss").toTimestamp().toLocalDateTime());
+            corrforeSt.setFpValue(isNumberOrNull(String.valueOf(ageValue)));
+            list.add(corrforeSt);
+        }
+        // 排序
+        Collections.sort(list, Comparator.comparing(CorrforeSt::getForecastTime));
+        return list;
+    }
+
+
+    /**
+     * 判断是否是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 bufferedReader 字符数据
+     * @param read           字节流
+     */
+    private void close(BufferedReader bufferedReader, InputStreamReader read) {
+        try {
+            if (bufferedReader != null) {
+                bufferedReader.close();
+            }
+            if (read != null) {
+                read.close();
+            }
+        } catch (IOException e) {
+            log.error("关闭文件流失败:", e);
+        }
+    }
+
+
+}

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

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

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

@@ -0,0 +1,166 @@
+package com.jiayue.insu.inclientqn.pushData;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+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.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.RecordService;
+import com.jiayue.insu.inclientqn.util.DateTimeUtils;
+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.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+
+@Slf4j
+@RefreshScope
+@Component
+public class PushForecastData implements IPushForecastData {
+
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private BackForeUsForecastDataService backForeUsForecastDataService;
+
+    /**
+     * 推送原始超短期数据给一体化云端
+     *
+     * @return
+     */
+    @Override
+    public boolean pushUltraShortTermDataWX(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_PUSH_INIT);
+        record.setContent(QNHLEnum.DATA_ORIGINALCDQ_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;
+        }
+
+        // 指定时区,例如系统默认时区
+        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<BackForeUsForecastData> usForecastDataList = backForeUsForecastDataService.findBySignTime(signTime);
+        if (usForecastDataList.size() > 0) {
+            for (BackForeUsForecastData backForeUsForecastData : usForecastDataList) {
+                DataPointDTO dto = new DataPointDTO();
+                zonedDateTime = backForeUsForecastData.getForecastTime().atZone(ZoneId.systemDefault());
+                // 将ZonedDateTime转换为Instant
+                instant = zonedDateTime.toInstant();
+                // 获取时间戳(毫秒)
+                long forecastTime = instant.toEpochMilli();
+                dto.setForecastTime(String.valueOf(forecastTime));
+                dto.setFpValue(String.valueOf(backForeUsForecastData.getForecastValue()));
+                list.add(dto);
+            }
+        }
+        if (list.size() < 16){
+            log.error("原始超短期数据为:{}条,不进行原始数据上送",list.size());
+            return false;
+        }
+        WXPushCDqDataParamsDto wxPushCDqDataParamsDto = new WXPushCDqDataParamsDto(stationCode,String.valueOf(timestamp),list);
+        JSONObject json = JSONUtil.parseObj(wxPushCDqDataParamsDto, 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(station.getBackurl())
+                    .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 WXPushCDqDataParamsDto {
+
+        public WXPushCDqDataParamsDto(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;
+    }
+}

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

@@ -0,0 +1,22 @@
+package com.jiayue.insu.inclientqn.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.insu.inclientqn.entity.BJZYYJYSDCorrfore;
+import com.jiayue.insu.inclientqn.entity.SHKJLNCorrfore;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 定时任务初始业务接口
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public interface SHKJLNCorrforeService extends IService<SHKJLNCorrfore> {
+
+    boolean updateBetweenForecastTime(LocalDateTime statTime, LocalDateTime endTime, List<SHKJLNCorrfore> list);
+
+
+}

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

@@ -17,11 +17,20 @@ import com.jiayue.insu.inclientqn.util.DateTimeUtils;
 import com.jiayue.insu.inclientqn.util.SystermUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.stereotype.Service;
+
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.util.*;
 
@@ -59,6 +68,12 @@ 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> rw = new HashMap<>();
         rw.put("label_start", "<" + QNHLEnum.DATA_STAT_TYPE_RealWeather.getCode() + ">");
         rw.put("label_end", "</" + QNHLEnum.DATA_STAT_TYPE_RealWeather.getCode() + ">");
@@ -102,26 +117,26 @@ public class BackDataAnalysisService {
         String fileName = CommonStant.RECORD_TYPE_BACK_DATA_FILE + "_" + LocalDateTimeUtil.format(LocalDateTimeUtil.of(time), DatePattern.PURE_DATETIME_PATTERN) + ".CIME";
         File file;
         // 如果场站文件目录分为AB机的情况 例:/home/syjy/zxgl/new/J00195-A
-        if(stationCodeFileNames!=null&& stationCodeFileNames.size()>0){
+        if (stationCodeFileNames != null && stationCodeFileNames.size() > 0) {
             // 循环场站编码
-            for(String stationCode :stationCodeFileNames){
+            for (String stationCode : stationCodeFileNames) {
                 // 查询操作记录
-                Record record = recordService.findTimeAndTypeAndStateAndStationCode(LocalDateTimeUtil.of(time), CommonStant.RECORD_TYPE_BACK_DATA_FILE, StatusEnum.SUCCESS.getSign(),stationCode);
+                Record record = recordService.findTimeAndTypeAndStateAndStationCode(LocalDateTimeUtil.of(time), CommonStant.RECORD_TYPE_BACK_DATA_FILE, StatusEnum.SUCCESS.getSign(), stationCode);
                 // 如果操作记录存在,则不进行解析文件
                 if (record != null) {
                     log.info(LocalDateTimeUtil.of(time) + stationCode + "操作记录存在,不进行解析文件");
                     break;
                 }
-                file = FileUtil.file(backFilePath + File.separatorChar + stationCode + File.separatorChar+ fileName);
-                log.info("解析文件路径"+backFilePath + File.separatorChar + stationCode + File.separatorChar+ fileName);
+                file = FileUtil.file(backFilePath + File.separatorChar + stationCode + File.separatorChar + fileName);
+                log.info("解析文件路径" + backFilePath + File.separatorChar + stationCode + File.separatorChar + fileName);
                 // 根据文件及场站信息,解析文件
-                this.analysisAndSave(time,file,stationCode);
+                this.analysisAndSave(time, file, stationCode);
             }
-        }else{
+        } else {
 
             List<Station> stationList = stationService.findAll();
             String stationCode = "";
-            if(stationList!=null && stationList.size()>0){
+            if (stationList != null && stationList.size() > 0) {
                 stationCode = stationList.get(0).getStationCode();
             }
             // 查询操作记录
@@ -133,23 +148,69 @@ public class BackDataAnalysisService {
             }
             file = FileUtil.file(backFilePath + File.separatorChar + fileName);
             // 根据文件及场站信息,解析文件
-            this.analysisAndSave(time,file,stationCode);
+            this.analysisAndSave(time, file, stationCode);
         }
     }
 
     /**
-     * 根据文件及场站信息,解析文件
+     * 解析理论可用文件
+     *
      * @param time
-     * @param file
-     * @param stationCode
      */
-    public void analysisAndSave(Long time,File file,String stationCode){
+    public void watchLlKyFile(Long time) {
+        // 如果配置文件中回传路径未配置,则查询数据库
+        if (StrUtil.isEmpty(backFilePath)) {
+            // 获取回传文件路径
+            backFilePath = stationService.findThis().getBackFilePath();
+        }
+        // 获取指定目录下所有文件夹名称
+        List<String> stationCodeFileNames = SystermUtils.getFileNames(backFilePath);
+        // 获取文件名
+        String fileName = CommonStant.RECORD_TYPE_BACK_DATA_LLKY_FILE + "_" + LocalDateTimeUtil.format(LocalDateTimeUtil.of(time), DatePattern.PURE_DATETIME_PATTERN) + ".CIME";
+        File file;
+        // 如果场站文件目录分为AB机的情况 例:/home/syjy/zxgl/new/J00195-A
+        if (stationCodeFileNames != null && stationCodeFileNames.size() > 0) {
+            // 循环场站编码
+            for (String stationCode : stationCodeFileNames) {
+                // 查询操作记录
+                Record record = recordService.findTimeAndTypeAndStateAndStationCode(LocalDateTimeUtil.of(time), CommonStant.RECORD_TYPE_BACK_DATA_LLKY_FILE, StatusEnum.SUCCESS.getSign(), stationCode);
+                // 如果操作记录存在,则不进行解析文件
+                if (record != null) {
+                    log.info(LocalDateTimeUtil.of(time) + stationCode + "操作记录存在,不进行解析文件");
+                    break;
+                }
+                file = FileUtil.file(backFilePath + File.separatorChar + stationCode + File.separatorChar + fileName);
+                log.info("解析文件路径" + backFilePath + File.separatorChar + stationCode + File.separatorChar + fileName);
+                // 根据文件及场站信息,解析文件
+                this.analysisLlKyAndSave(time, file, stationCode);
+            }
+        } else {
+
+            List<Station> stationList = stationService.findAll();
+            String stationCode = "";
+            if (stationList != null && stationList.size() > 0) {
+                stationCode = stationList.get(0).getStationCode();
+            }
+            // 查询操作记录
+            Record record = recordService.findTimeAndTypeAndState(LocalDateTimeUtil.of(time), CommonStant.RECORD_TYPE_BACK_DATA_LLKY_FILE, StatusEnum.SUCCESS.getSign());
+            // 如果操作记录不存在,则进行解析文件
+            if (record != null) {
+                log.info(LocalDateTimeUtil.of(time) + "操作记录存在,不进行解析文件");
+                return;
+            }
+            file = FileUtil.file(backFilePath + File.separatorChar + fileName);
+            // 根据文件及场站信息,解析文件
+            this.analysisLlKyAndSave(time, file, stationCode);
+        }
+    }
+
+    public void analysisAndSave(Long time, File file, String stationCode) {
         // 获取当前时间所在15分钟节点 例如 10:18=》10:15 、 11:29=>11:15
         LocalDateTime localDateTime = LocalDateTimeUtil.of(DateTimeUtils.get15min(time));
         // 判断目录是否存在
         if (file.exists()) {
             // 初始化记录
-            Record record = new Record(CommonStant.RECORD_TYPE_BACK_DATA_FILE, null, localDateTime, LocalDateTime.now(), StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getCode(),stationCode);
+            Record record = new Record(CommonStant.RECORD_TYPE_BACK_DATA_FILE, null, localDateTime, LocalDateTime.now(), StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getCode(), stationCode);
             try {
                 // 读取文件
                 FileReader fileReader = new FileReader(file);
@@ -157,7 +218,50 @@ public class BackDataAnalysisService {
                 // 如果文件内容不为空
                 if (CollectionUtil.isNotEmpty(contents)) {
                     // 解析文件,获取操作类型
-                    String fileContentStr = fileAnalysis(contents,stationCode);
+                    String fileContentStr = fileAnalysis(contents, stationCode);
+                    // 如果操作类型不为空
+                    if (StrUtil.isNotEmpty(fileContentStr)) {
+                        //存入操作类型和状态
+                        record.setStateContent(fileContentStr);
+                        record.setState(StatusEnum.SUCCESS.getCode());
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                record.setCreateTime(LocalDateTime.now());
+                record.setTime(localDateTime);
+                recordService.save(record);
+            }
+        } else {
+            log.info("文件不存在,路径:" + file.getAbsolutePath() + file.getName());
+            Record record = new Record(CommonStant.RECORD_TYPE_BACK_DATA_FILE, null, localDateTime, localDateTime, StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getMsg(), stationCode);
+            recordService.save(record);
+        }
+    }
+
+    /**
+     * 根据文件及场站信息,解析文件
+     *
+     * @param time
+     * @param file
+     * @param stationCode
+     */
+    public void analysisLlKyAndSave(Long time, File file, String stationCode) {
+        // 获取当前时间所在5分钟节点
+        LocalDateTime localDateTime = LocalDateTimeUtil.of(DateTimeUtils.get5min(time));
+        // 判断目录是否存在
+        if (file.exists()) {
+            // 初始化记录
+            Record record = new Record(CommonStant.RECORD_TYPE_BACK_DATA_LLKY_FILE, null, localDateTime, LocalDateTime.now(), StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getCode(), stationCode);
+            try {
+                // 读取文件
+                FileReader fileReader = new FileReader(file);
+                List<String> contents = fileReader.readLines();
+                // 如果文件内容不为空
+                if (CollectionUtil.isNotEmpty(contents)) {
+                    // 解析理论可用文件,获取操作类型
+                    String fileContentStr = fileLlKyAnalysis(contents, stationCode);
                     // 如果操作类型不为空
                     if (StrUtil.isNotEmpty(fileContentStr)) {
                         //存入操作类型和状态
@@ -174,7 +278,7 @@ public class BackDataAnalysisService {
             }
         } else {
             log.info("文件不存在,路径:" + file.getAbsolutePath() + file.getName());
-            Record record = new Record(CommonStant.RECORD_TYPE_BACK_DATA_FILE, null, localDateTime, localDateTime, StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getMsg(),stationCode);
+            Record record = new Record(CommonStant.RECORD_TYPE_BACK_DATA_LLKY_FILE, null, localDateTime, localDateTime, StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getMsg(), stationCode);
             recordService.save(record);
         }
     }
@@ -270,10 +374,12 @@ public class BackDataAnalysisService {
 
     /**
      * 解析文件并返回操作类型
+     *
      * @param contents
      * @return
      */
-    public String fileAnalysis(List<String> contents,String stationCode) {
+    public String fileAnalysis(List<String> contents, String stationCode) {
+        BackStatData backStatData;
         String result = "";
         // 获取文件时间
         String[] fileTime = contents.get(0).split("\\s+")[2].split("=");
@@ -281,8 +387,14 @@ public class BackDataAnalysisService {
         LocalDateTime now = LocalDateTime.now();
         // 根据类型分类的文件内容
         Map<String, List<String>> contentMap = new HashMap<>();
+        // 查询数据库中是否有相同时间点的数据
+        List<BackStatData> backStatDataList = backStatDataService.findBySignTime(signTime);
+        if (null != backStatDataList && backStatDataList.size() > 0) {
+            backStatData = backStatDataList.get(0);
+        } else {
+            backStatData = new BackStatData();
+        }
         // 回传数据
-        BackStatData backStatData = new BackStatData();
         backStatData.setSignTime(signTime);
         backStatData.setAnalysisTime(LocalDateTime.now());
         backStatData.setStationCode(stationCode);
@@ -422,12 +534,277 @@ public class BackDataAnalysisService {
                     break;
             }
         }
-        // 保存回传数据
-        backStatDataService.save(backStatData);
+        // 保存或更新回传数据
+        backStatDataService.saveOrUpdate(backStatData);
         // 保存超短期数据
         backForeUsForecastDataService.saveBatch(usList);
         // 保存短期数据
         backForeForecastDataService.saveBatch(list);
         return result;
     }
+
+    /**
+     * 解析文件并返回操作类型
+     *
+     * @param contents
+     * @return
+     */
+    public String fileLlKyAnalysis(List<String> contents, String stationCode) {
+        BackStatData backStatData;
+
+        String result = "";
+        // 获取文件时间
+        String[] fileTime = contents.get(0).split("\\s+")[2].split("=");
+        LocalDateTime signTime = LocalDateTimeUtil.parse(fileTime[1].substring(1, fileTime[1].length() - 1), DatePattern.PURE_DATETIME_PATTERN);
+        // 根据类型分类的文件内容
+        Map<String, List<String>> contentMap = new HashMap<>();
+        // 先查询库中是否有相同时间点的数据
+        List<BackStatData> backStatDataList = backStatDataService.findBySignTime(signTime);
+        if (null != backStatDataList && backStatDataList.size() > 0) {
+            backStatData = backStatDataList.get(0);
+        } else {
+            backStatData = new BackStatData();
+        }
+        // 保存或修改回传数据
+        backStatData.setSignTime(signTime);
+        backStatData.setAnalysisTime(LocalDateTime.now());
+        backStatData.setStationCode(stationCode);
+
+        // 循环文件模板,根据标签内容,将文件内容分类存入map
+        for (Map.Entry<String, Map<String, Object>> entry : labelMap.entrySet()) {
+            Map<String, Object> map = entry.getValue();
+            // 获取起始标签和结束标签
+            String label_start = (String) map.get("label_start");
+            String label_end = (String) map.get("label_end");
+            int start_index = 0;
+            int end_index = 0;
+            // 获取标签头和标签尾位置
+            for (int i = 0; i < contents.size(); i++) {
+                if (contents.get(i).equals(label_start)) {
+                    start_index = i;
+                }
+                if (contents.get(i).equals(label_end)) {
+                    end_index = i;
+                }
+            }
+            //标签头和标签尾相减大于2  说明除了表头 至少还有1行数据,把数据放入map
+            if (end_index - start_index > 2) {
+                contentMap.put(entry.getKey(), ListUtil.sub(contents, start_index + 2, end_index));
+            }
+        }
+
+        // 循环分类后的文件
+        for (Map.Entry<String, List<String>> entry : contentMap.entrySet()) {
+            // 获取
+            List<String> value = entry.getValue();
+            // 判断内容分类的key名
+            switch (entry.getKey()) {
+                case "TheoryPower":
+                    try {
+                        String[] tyData = value.get(0).split("\\s+");
+                        if (tyData.length == 4) {
+                            backStatData.setTheoryPower(new BigDecimal(tyData[2]));
+                            backStatData.setAvailablePower(new BigDecimal(tyData[3]));
+                            result += "TheoryPower";
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    break;
+            }
+        }
+        // 保存或更新回传数据
+        backStatDataService.saveOrUpdate(backStatData);
+
+        return result;
+    }
+
+    /*----------------------------------------------------以下为新增-----------------------------------------------------------------------*/
+
+    /**
+     * 解析武穴回传超短期文件
+     *
+     * @param time
+     */
+    public void watchCdqFile(Long time) {
+        // 如果配置文件中回传路径未配置,则查询数据库
+        if (StrUtil.isEmpty(backFilePath)) {
+            // 获取回传文件路径
+            backFilePath = stationService.findThis().getBackFilePath();
+        }
+        // 获取指定目录下所有文件夹名称
+        List<String> stationCodeFileNames = SystermUtils.getFileNames(backFilePath);
+        // 获取文件名
+        String fileName = CommonStant.RECORD_TYPE_CDQ_FILE + "_" + LocalDateTimeUtil.format(LocalDateTimeUtil.of(time), "yyyyMMdd_HHmm") + "_CDQ.PVD";
+        File file;
+        // 如果场站文件目录分为AB机的情况 例:/home/syjy/zxgl/new/J00195-A
+        if (stationCodeFileNames != null && stationCodeFileNames.size() > 0) {
+            // 循环场站编码
+            for (String stationCode : stationCodeFileNames) {
+                // 查询操作记录
+                Record record = recordService.findTimeAndTypeAndStateAndStationCode(LocalDateTimeUtil.of(time), CommonStant.RECORD_TYPE_CDQ_BACK_DATA_FILE, StatusEnum.SUCCESS.getSign(), stationCode);
+                // 如果操作记录存在,则不进行解析文件
+                if (record != null) {
+                    log.info(LocalDateTimeUtil.of(time) + stationCode + "操作记录存在,不进行解析文件");
+                    break;
+                }
+                file = FileUtil.file(backFilePath + File.separatorChar + stationCode + File.separatorChar + fileName);
+                log.info("解析文件路径" + backFilePath + File.separatorChar + stationCode + File.separatorChar + fileName);
+                // 根据文件及场站信息,解析文件
+                this.cdqAnalysisAndSave(time, file, stationCode);
+            }
+        } else {
+
+            List<Station> stationList = stationService.findAll();
+            String stationCode = "";
+            if (stationList != null && stationList.size() > 0) {
+                stationCode = stationList.get(0).getStationCode();
+            }
+            // 查询操作记录
+            Record record = recordService.findTimeAndTypeAndState(LocalDateTimeUtil.of(time), CommonStant.RECORD_TYPE_CDQ_BACK_DATA_FILE, StatusEnum.SUCCESS.getSign());
+            // 如果操作记录不存在,则进行解析文件
+            if (record != null) {
+                log.info(LocalDateTimeUtil.of(time) + "操作记录存在,不进行解析文件");
+                return;
+            }
+            file = FileUtil.file(backFilePath + File.separatorChar + fileName);
+            // 根据文件及场站信息,解析文件
+            this.cdqAnalysisAndSave(time, file, stationCode);
+        }
+    }
+
+    /**
+     * 解析回传超短期文件
+     *
+     * @param time
+     * @param file
+     * @param stationCode
+     */
+    public void cdqAnalysisAndSave(Long time, File file, String stationCode) {
+        // 获取当前时间所在15分钟节点 例如 10:18=》10:15 、 11:29=>11:15
+        LocalDateTime localDateTime = LocalDateTimeUtil.of(DateTimeUtils.get15min(time));
+        // 判断目录是否存在
+        if (file.exists()) {
+            // 初始化记录
+            Record record = new Record(CommonStant.RECORD_TYPE_CDQ_BACK_DATA_FILE, null, localDateTime, LocalDateTime.now(), StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getCode(), stationCode);
+            try {
+
+                    // 解析文件,获取操作类型
+                   Map<String,List> map = cdqSave(file,stationCode);
+                    // 如果操作类型不为空
+                    if (map.get("list").size() > 0) {
+                        //存入操作类型和状态
+                        record.setStateContent("CDQ");
+                        record.setState(StatusEnum.SUCCESS.getCode());
+                        backForeUsForecastDataService.saveOrUpdateBatch(map.get("list"));
+                    }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                record.setCreateTime(LocalDateTime.now());
+                record.setTime(localDateTime);
+                recordService.save(record);
+            }
+        } else {
+            log.info("文件不存在,路径:" + file.getAbsolutePath());
+            Record record = new Record(CommonStant.RECORD_TYPE_CDQ_BACK_DATA_FILE, null, localDateTime, localDateTime, StatusEnum.FILE_NULL.getCode(), StatusEnum.FILE_NULL.getMsg(), stationCode);
+            recordService.save(record);
+        }
+    }
+
+    public Map<String,List> cdqSave(File file,String stationCode){
+        List<BackForeUsForecastData> backForeUsForecastDataList = new ArrayList<>();
+        List<BigDecimal> suCapacity=new ArrayList<>();
+        Long signTime = null;
+        // 当文件未被使用时,进行解析上报
+        if (file.renameTo(file)) {
+            InputStreamReader read = null;
+            BufferedReader bufferedReader = null;
+            String stringLine;
+            BackForeUsForecastData stf;
+
+            try {
+                read = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);
+                bufferedReader = new BufferedReader(read);
+
+                // 读取文件内容
+                String line;
+                int lineCount = 1;
+                Long time = null;
+                while ((line = bufferedReader.readLine()) != null) {
+                    //获取预测时间
+                    if (lineCount == 2) {
+                        String[] timeArr = line.split("'");
+                        if (timeArr.length >= 2) {
+                            String dateString =timeArr[1];
+                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH:mm");
+                            Date date = dateFormat.parse(dateString);
+                            time = date.getTime();
+                            signTime = time - 15 * 60 * 1000l;
+                        }
+                    }
+                    if (lineCount ==6){
+                        String[] dataKj = line.split("\\s+");
+                        if (dataKj.length >= 2) {
+                            suCapacity.add(new BigDecimal(dataKj[1]));
+                        }
+                    }
+                    if (line.startsWith("#") && lineCount>6) {
+                        stf = new BackForeUsForecastData();
+                        String[] dataArr = line.split("\\s+");
+                        if (dataArr.length >= 2) {
+                            BigDecimal power = new BigDecimal(dataArr[1]);
+                            stf.setForecastValue(power);
+                            stf.setForecastTime(LocalDateTimeUtil.of(time));
+                            stf.setSignTime(LocalDateTimeUtil.of(signTime));
+                            stf.setStationCode(stationCode);
+                            stf.setForecastOpenCap(suCapacity.get(0));
+                            stf.setAnalysisTime(LocalDateTime.now());
+                            backForeUsForecastDataList.add(stf);
+                            time += 15 * 60 * 1000;
+                        }
+                    }
+                    lineCount++;
+                }
+            }  catch (IOException | RuntimeException e) {
+                log.error("系统错误:", e);
+                File destFile = new File(file.getPath().replaceFirst("new", "error"));
+                if (destFile.exists()) {
+                    destFile.delete();
+                }
+                try {
+                    FileUtils.moveFile(file, destFile);
+                } catch (IOException e1) {
+                    log.error(file.getName() + "文件解析失败", e);
+                }
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            } finally {
+                close(bufferedReader, read);
+            }
+        }
+        Map<String ,List> map = new HashMap<>();
+        map.put("list", backForeUsForecastDataList);
+        map.put("suCapacity",suCapacity);
+        return map;
+    }
+    /**
+     * 关闭文件流
+     *
+     * @param bufferedReader 字符数据
+     * @param read           字节流
+     */
+    private void close(BufferedReader bufferedReader, InputStreamReader read) {
+        try {
+            if (bufferedReader != null) {
+                bufferedReader.close();
+            }
+            if (read != null) {
+                read.close();
+            }
+        } catch (IOException e) {
+            log.error("关闭文件流失败:", e);
+        }
+    }
 }

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

@@ -53,6 +53,32 @@ public class BackDataGenBodyService {
     }
 
     /**
+     * 生成回传理论可用功率
+     *
+     * @param backStatDatas 数据集
+     * @return RequestVo
+     */
+    public StringBuilder genStateTheoryPowerData(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_TheoryPower.getCode());
+            String labelEnd = TemplateStant.GEN_LABELEND(QNHLEnum.DATA_STAT_TYPE_TheoryPower.getCode());
+            String title = TemplateStant.BACK_STAT_THEORY_POWER_TITLE;
+            // 拼接开始、title、内容、结束
+            content.append(labelStart);
+            content.append(title);
+            String dataContent = StrUtil.format(TemplateStant.BACK_STAT_THEORY_POWER_TEMPLATE, backStatDatas.get(0).getTheoryPower().toString(),backStatDatas.get(0).getAvailablePower().toString());
+            content.append(dataContent);
+            content.append(labelEnd);
+        }else {
+            log.warn("回传数据-理论可用功率缺少数据");
+        }
+        return content;
+    }
+
+    /**
      * 生成回传实际气象
      *
      * @param stationType   场站类型

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

@@ -565,7 +565,7 @@ public class CorrforeService extends ServiceImpl<CorrforeStMapper, CorrforeSt> {
                 fileUrl.mkdirs();
             }
             // 获取文件名
-            String fileName = "DQ_" + DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMddHHmmss") + "0.RB";
+            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);
@@ -590,7 +590,7 @@ public class CorrforeService extends ServiceImpl<CorrforeStMapper, CorrforeSt> {
             // 获取文件名
             String fileName = jsonObject.get("fileName").toString();
             String[] s = fileName.split("_");
-            String fn = "CDQ_" + s[1] + s[2] + "00.RB";
+            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());
@@ -614,7 +614,7 @@ public class CorrforeService extends ServiceImpl<CorrforeStMapper, CorrforeSt> {
         // 如果模板不为空
         if (template != null) {
             // 获取文件名
-            String fileName = "JX_" + LocalDateTimeUtil.format(LocalDateTimeUtil.beginOfDay(LocalDateTime.now()), "yyyyMMddHHmmss") + ".RB";
+            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);

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

@@ -0,0 +1,218 @@
+package com.jiayue.insu.inclientqn.service.client;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+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.StatusEnum;
+import com.jiayue.insu.inclientqn.mapper.SHKJLNCorrforeMapper;
+import com.jiayue.insu.inclientqn.pulldata.IPullInitForecastDataSH;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import com.jiayue.insu.inclientqn.util.SystermUtils;
+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.stereotype.Service;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 飔合科技(辽宁)下载修正短期预测数据from 一体化云
+ * @description:
+ * @author: yuanhao
+ * @createDate: 2021/9/27
+ * @version: 1.0
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class SHKJCorrforeService extends ServiceImpl<SHKJLNCorrforeMapper, SHKJLNCorrfore> {
+
+    private final RecordService recordService;
+    private final VelocityEngine velocityEngine;
+    private final IPullInitForecastDataSH iPullInitForecastDataSH;
+
+    /**
+     * 飔合科技(辽宁)下载修正短期预测数据from 一体化云
+     *
+     * @param station
+     * @return
+     */
+    public boolean downLoadCorrforeData(Station station) {
+        // 初始化操作记录
+        Record record = new Record();
+        record.setType(CommonStant.RECORD_TYPE_PULL_CDQ_CORRECT);
+        record.setStationCode(station.getStationCode());
+        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+        record.setTime(localDateTime);
+        record.setCreateTime(LocalDateTime.now());
+
+        boolean result = false;
+        boolean isUpload = false;
+        List<CorrforeSt> listMinio = new ArrayList<>();
+        try {
+            try {
+                // 如果修正后短期数据不为0
+                listMinio = iPullInitForecastDataSH.pullDQData(station);
+                // 生成短期修正后文件
+                if (genFile(station, listMinio)) {
+                    result = true;
+                    // 存入记录文件已经生成过
+                    record.setState(CommonStant.RECORD_TYPE_PULL_CDQ_CORRECT);
+                    record.setStateContent(StatusEnum.SUCCESS.getCode());
+                }
+            } 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(listMinio.size()));
+            }
+
+        } 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 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);
+
+            String filePath = station.getLocalFilePath();
+            // 获取文件路径
+            File fileUrl = new File(filePath);
+            // 判断目录是否存在
+            if (!fileUrl.exists()) {
+                fileUrl.mkdirs();
+            }
+            // 获取文件名
+            String fileName = "DQ_" + DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMddHHmmss") + "0.RB";
+            file = new File(filePath + File.separatorChar + fileName);
+            // 写入文件
+            result = writeFile(file, station, writer, fileName, filePath);
+        }
+        return result;
+    }
+
+
+    /**
+     * 写入文件
+     *
+     * @param file
+     * @param station
+     * @param writer
+     * @param fileName
+     * @param filePath
+     * @return
+     */
+    private boolean writeFile(File file, Station station, StringWriter writer, String fileName, String filePath) {
+        boolean result = true;
+        // 获取文件路径
+        File fileUrl = new File(filePath);
+        // 判断目录是否存在
+        if (!fileUrl.exists()) {
+            fileUrl.mkdirs();
+        }
+        // 检查文件是否存在
+        File existingFile = new File(filePath + File.separator + fileName);
+        if (existingFile.exists()) {
+            // 如果存在同名文件,尝试删除
+            boolean deleted = existingFile.delete();
+            if (!deleted) {
+                // 如果无法删除,记录警告并返回false
+                log.warn("无法删除文件:" + fileName);
+                return false;
+            }
+        }
+
+        // 创建流
+        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("执行生成文件完毕:" + filePath + File.separatorChar + fileName);
+            return result;
+        }
+    }
+}

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

@@ -0,0 +1,370 @@
+package com.jiayue.insu.inclientqn.service.client;
+
+
+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.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jiayue.insu.inclientqn.constant.CommonStant;
+import com.jiayue.insu.inclientqn.entity.BJZYYJYSDCorrfore;
+import com.jiayue.insu.inclientqn.entity.CorrectUltraShortTerm;
+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.mapper.BJZYYJYSDCorrforeMapper;
+import com.jiayue.insu.inclientqn.model.WXResponseVo;
+import com.jiayue.insu.inclientqn.permisson.com.BJZYYJYSDComPermisson;
+import com.jiayue.insu.inclientqn.permisson.com.WXComPermisson;
+import com.jiayue.insu.inclientqn.pulldata.IPullInitForecastData;
+import com.jiayue.insu.inclientqn.service.BJZYYJYSDCorrforeService;
+import com.jiayue.insu.inclientqn.service.CorrectUltraShortTermService;
+import com.jiayue.insu.inclientqn.service.RecordService;
+import com.jiayue.insu.inclientqn.service.StationService;
+import com.jiayue.insu.inclientqn.util.DateTimeUtils;
+import com.jiayue.insu.inclientqn.util.SystermUtils;
+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.stereotype.Service;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
+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 WXCorrforeService extends ServiceImpl<BJZYYJYSDCorrforeMapper, BJZYYJYSDCorrfore> {
+
+    private final RecordService recordService;
+    private final StationService stationService;
+    private final VelocityEngine velocityEngine;
+    private final CorrectUltraShortTermService correctUltraShortTermService;
+    private final WXComPermisson wxComPermisson;
+
+    /**
+     * 武穴一体化请求超短期修正数据
+     *
+     * @param station
+     * @return
+     */
+    public boolean downLoadCorrforeData(Station station, Long time) {
+        //标记为要生成超短期的时刻
+        LocalDateTime signLDT = LocalDateTimeUtil.of(time).plusMinutes(15L);
+
+        // 初始化操作记录
+        Record record = new Record();
+        record.setType(CommonStant.RECORD_TYPE_PULL_CORRECT);
+        // 此处借用清能枚举,不新增武穴枚举
+        record.setContent(QNHLEnum.DATA_CORRULTRSHOR_TYPE.getCode());
+        record.setStationCode(station.getStationCode());
+        record.setTime(signLDT);
+        record.setCreateTime(LocalDateTime.now());
+
+        // 获取下载路径
+        String dataPullUrl = station.getDownloadurl();
+        // 获取token地址
+        String token = station.getComKey();
+        // 如果token为空或者token失效,从新获取token
+        LocalDateTime tokenTime = station.getKeyTime();
+        if (StrUtil.isEmpty(token) || LocalDateTime.now().isAfter(tokenTime)) {
+            if (wxComPermisson.generateKey(station)) {
+                station = stationService.findThis();
+                token = station.getComKey();
+                tokenTime = station.getKeyTime();
+            }
+        }
+
+        boolean result = false;
+        boolean isUpload = false;
+        String response;
+        List<CorrectUltraShortTerm> list = new ArrayList<>();
+        // 如果token为不为空并且者token未失效
+        if (StrUtil.isNotEmpty(token) && LocalDateTime.now().isBefore(tokenTime)) {
+            try {
+                // 实装请求参数
+                Long datetime = DateTimeUtils.getMomentTime(System.currentTimeMillis(), 2, 15 * 60 * 1000L);
+                String stationId = station.getStationCode();
+                Map<String, Object> map = new HashMap<>();
+                map.put("stationId",stationId);
+                map.put("datetime", datetime.toString());
+                // 发送请求
+                HttpRequest httpRequest = HttpRequest.post(dataPullUrl)
+                        .header("Content-Type", "application/json")
+                        .header("loginToken", token);
+                httpRequest.setGlobalTimeout(120000);
+                // 因本地测试相应时间30s左右,故设置读取超时间50s
+                httpRequest.setReadTimeout(50000);
+
+                response = httpRequest.body(JSONUtil.toJsonStr(map)).execute().body();
+                // 如果响应不为空
+                if (StrUtil.isNotEmpty(response)) {
+                    boolean isJson = JSONUtil.isJsonObj(response);
+                    // 如果返回结果是json类型
+                    if (isJson) {
+                        WXResponseVo wxResponseVo = JSONUtil.toBean(response, WXResponseVo.class);
+                        String code = wxResponseVo.getStatusCode();
+                        // 如果调用结果成功
+                        if (code.equals("1000")) {
+                            log.info(station.getStationCode() + " 武穴超短期请求修正内容为:{}", response);
+                            try {
+                                // 如果data = null 则用原始数据进行上报
+                                if (!"{}".equals(wxResponseVo.getData())) {
+                                    list = correctData(wxResponseVo.getData(), signLDT);
+                                    /**************检测解析数据完整性*******************/
+                                    // 如果修正后超短期数据不为0
+                                    if (list.size() > 0) {
+                                        // 生成超短期修正后文件
+                                        if (genFile(station, list)) {
+                                            result = true;
+                                            // 存入记录文件已经生成过
+                                            record.setState(CommonStant.RECORD_TYPE_PULL_CORRECT);
+                                            record.setStateContent(StatusEnum.SUCCESS.getCode());
+                                        }
+                                    }
+                                } 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<CorrectUltraShortTerm> correctData(String data, LocalDateTime signTime){
+        List<CorrectUltraShortTerm> list = new ArrayList<>();
+        // 解析JSON字符串为JSONObject
+        JSONObject jsonObject = new JSONObject(data);
+
+        // 获取stationId和datetime
+        String stationId = jsonObject.getStr("stationId");
+        String datetime = jsonObject.getStr("datetime");
+
+        // 获取fix数组并遍历
+        JSONArray fixArray = jsonObject.getJSONArray("fix");
+        for (int i = 0; i < fixArray.size(); i++) {
+            JSONObject fixObject = fixArray.getJSONObject(i);
+            Iterator<String> keys = fixObject.keySet().iterator();
+            while (keys.hasNext()) {
+                CorrectUltraShortTerm correctUltraShortTerm = new CorrectUltraShortTerm();
+                String key = keys.next(); // 时间戳
+                correctUltraShortTerm.setForecastTime(LocalDateTimeUtil.of(Long.valueOf(key)));
+                correctUltraShortTerm.setSignTime(signTime);
+                correctUltraShortTerm.setPassTime(LocalDateTime.now());
+                correctUltraShortTerm.setRequestTime(LocalDateTime.now());
+                correctUltraShortTerm.setStationCode(String.valueOf(stationId));
+                Double value = fixObject.getDouble(key);
+                // 武穴返回来的数据是需要上报的值,不是系数
+                correctUltraShortTerm.setCorrectValue(new BigDecimal(value));
+//                correctUltraShortTerm.setRatio(new BigDecimal(1));
+                list.add(correctUltraShortTerm);
+            }
+        }
+        JSONArray scaleArray = jsonObject.getJSONArray("scale");
+        for (int i = 0; i < scaleArray.size(); i++) {
+            JSONObject scaleObject = scaleArray.getJSONObject(i);
+            Iterator<String> keys = scaleObject.keySet().iterator();
+            while (keys.hasNext()) {
+                CorrectUltraShortTerm correctUltraShortTerm = new CorrectUltraShortTerm();
+                String key = keys.next();
+                correctUltraShortTerm.setForecastTime(LocalDateTimeUtil.of(Long.valueOf(key)));
+                correctUltraShortTerm.setSignTime(signTime);
+                correctUltraShortTerm.setPassTime(LocalDateTime.now());
+                correctUltraShortTerm.setRequestTime(LocalDateTime.now());
+                correctUltraShortTerm.setStationCode(String.valueOf(stationId));
+                // 武穴返回来的数据是需要上报的值,不是系数
+                Double value = scaleObject.getDouble(key);
+                correctUltraShortTerm.setCorrectValue(new BigDecimal(value));
+//                correctUltraShortTerm.setRatio(new BigDecimal(value));
+                list.add(correctUltraShortTerm);
+            }
+        }
+        list.stream().sorted(Comparator.comparing(CorrectUltraShortTerm::getForecastTime));
+        correctUltraShortTermService.saveOrUpdateBatch(list);
+        return list;
+    }
+
+    /**
+     * 生成修正后的短期文件(武穴一体化)
+     *
+     * @param station
+     * @param list
+     * @return
+     */
+    public boolean genFile(Station station, List<CorrectUltraShortTerm> list) {
+        boolean result = true;
+        // 初始化模板
+        String vmsPath = SystermUtils.getResourceBasePath() + "/vms/CDQ.vm";
+        File file;
+        Template template = this.velocityEngine.getTemplate(vmsPath);
+        // 如果模板不为空
+        if (template != null) {
+            VelocityContext velocityContext;
+            StringWriter writer;
+            // 将修正后的短期数据按照预测时间排序
+            list.sort(Comparator.comparing(CorrectUltraShortTerm::getForecastTime));
+            // 根据修正后的数据,拼接需要的数据
+            List<Map<String, Object>> vList = new ArrayList<>();
+            for (CorrectUltraShortTerm a : list) {
+                Map<String, Object> map = new HashMap<>();
+                map.put("ratio", a.getCorrectValue());
+                map.put("forecastTime", DateUtil.format(a.getForecastTime(), "yyyy-MM-dd HH:mm:ss"));
+                vList.add(map);
+            }
+            // 格式化模板数据
+            writer = new StringWriter();
+            velocityContext = new VelocityContext();
+            velocityContext.put("efiLabel", station.getStationCode());
+            velocityContext.put("currentTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+            velocityContext.put("vList", vList);
+            template.merge(velocityContext, writer);
+            String[] filePath = station.getLocalFilePath().split(";");
+            for (int i = 0; i < filePath.length; i++) {
+                // 获取文件路径
+                File fileUrl = new File(filePath[i]);
+                // 判断目录是否存在
+                if (!fileUrl.exists()) {
+                    fileUrl.mkdirs();
+                }
+                // 获取文件名
+                String fileName = "WXCDQ_" + DateUtil.format(list.get(0).getSignTime(), "yyyyMMddHHmmss") + ".RB";
+                file = new File(filePath[i] + File.separatorChar + fileName);
+                // 写入文件
+                result = writeFile(file, station, writer, fileName, filePath[i]);
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * 写入文件
+     *
+     * @param file
+     * @param station
+     * @param writer
+     * @param fileName
+     * @param filePath
+     * @return
+     */
+    private boolean writeFile(File file, Station station, StringWriter writer, String fileName, String filePath) {
+        boolean result = true;
+        // 获取文件路径
+        File fileUrl = new File(filePath);
+        // 判断目录是否存在
+        if (!fileUrl.exists()) {
+            fileUrl.mkdirs();
+        }
+        // 检查文件是否存在
+        File existingFile = new File(filePath + File.separator + fileName);
+        if (existingFile.exists()) {
+            // 如果存在同名文件,尝试删除
+            boolean deleted = existingFile.delete();
+            if (!deleted) {
+                // 如果无法删除,记录警告并返回false
+                log.warn("无法删除文件:" + fileName);
+                return false;
+            }
+        }
+
+        // 创建流
+        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("执行生成文件完毕:" + filePath + File.separatorChar + fileName);
+            return result;
+        }
+    }
+}

+ 44 - 0
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/service/impl/SHKJLNCorrforeServiceImpl.java

@@ -0,0 +1,44 @@
+package com.jiayue.insu.inclientqn.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.insu.inclientqn.entity.BJZYYJYSDCorrfore;
+import com.jiayue.insu.inclientqn.entity.SHKJLNCorrfore;
+import com.jiayue.insu.inclientqn.mapper.BJZYYJYSDCorrforeMapper;
+import com.jiayue.insu.inclientqn.mapper.SHKJLNCorrforeMapper;
+import com.jiayue.insu.inclientqn.service.BJZYYJYSDCorrforeService;
+import com.jiayue.insu.inclientqn.service.SHKJLNCorrforeService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 修正数据业务实现(飔合科技(辽宁))
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Service
+@Slf4j
+public class SHKJLNCorrforeServiceImpl extends ServiceImpl<SHKJLNCorrforeMapper, SHKJLNCorrfore> implements SHKJLNCorrforeService {
+
+
+    @Override
+    public boolean updateBetweenForecastTime(LocalDateTime statTime, LocalDateTime endTime, List<SHKJLNCorrfore> list) {
+
+        try {
+            LambdaQueryWrapper<SHKJLNCorrfore> remove = new LambdaQueryWrapper<>();
+            remove.between(SHKJLNCorrfore::getTimeFormat,statTime,endTime);
+            this.remove(remove);
+            this.saveBatch(list);
+            log.info("========== 数据入库成功");
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return Boolean.TRUE;
+
+    }
+}

+ 73 - 5
in-client-qn/src/main/java/com/jiayue/insu/inclientqn/util/DateTimeUtils.java

@@ -1,15 +1,83 @@
 package com.jiayue.insu.inclientqn.util;
 
+import java.util.Calendar;
+
 public class DateTimeUtils {
 
     /**
      * 得到整15分钟时间
+     *
+     * @return
+     */
+    public static long get15min(long time) {
+        if (time % 900000L != 0) {
+            time = time - time % 900000L;
+        }
+        return time;
+    }
+
+    /**
+     * 得到整5分钟时间
+     *
+     * @param time
      * @return
      */
-   public static long get15min(long time){
-       if(time%900000L !=0){
-           time = time -  time%900000L;
-       }
-       return time;
+    public static long get5min(long time) {
+        if (time % 300000L != 0) {
+            time = time - time % 300000L;
+        }
+        return time;
+    }
+
+
+    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();
+    }
+
+
+    /**
+     * 获取指定时间所在时刻的标记时间 <br>
+     * 例如:dateTime:2018-10-22 16:44:00 momentLength: 15*60*1000 <br>
+     * 当前标记signType:1 那么该时刻的标记时间为2018-10-22 16:30:00
+     * 当后标记singType:2 那么该时刻的标记时间为2018-10-22 16:45:00
+     *
+     * @param dateTime     时间毫秒
+     * @param signType     标记方式:1前标记 2后标记
+     * @param momentLength 时刻长度,单位:毫秒
+     * @return 指定时间所在时刻的标记时间,单位:毫秒
+     */
+    public static long getMomentTime(Long dateTime,int signType,Long momentLength) throws Exception {
+        if (24 * 3600 * 1000L % momentLength != 0)
+            throw new Exception("时刻长度非法,时刻长度需要能够被一天整除");
+        int moment = getMoment(dateTime, momentLength);// 获取指定时间所在时刻数
+        long differentTime = moment * momentLength;// 获取从0分0秒开始到现在的时间间隔,单位:毫秒
+        long dayStartTime = getDayStartTime(dateTime);
+        switch (signType) {
+            case 2:
+                return dayStartTime + differentTime;
+            default:
+                return dayStartTime + differentTime - momentLength;
+        }
+    }
+
+
+    /**
+     * 获取指定时间在当天所处于的时刻
+     * 例如:dateTime:2018-10-22 16:44:00 momentLength: 15分钟,既 15*60*1000毫秒
+     * 从0点0分开始计算,0点0分-0点15为第一个时刻,依次类推该时间的时刻数为67
+     *
+     * @param dateTime     时间毫秒
+     * @param momentLength 时刻长度,单位毫秒
+     * @return 时刻
+     */
+    public static int getMoment(Long dateTime,Long momentLength) {
+        return (int) ((dateTime - getDayStartTime(dateTime)) / momentLength) + 1;
     }
+
 }

+ 9 - 0
in-client-qn/src/main/resources/vms/CDQ.vm

@@ -0,0 +1,9 @@
+//${currentTime}
+<!	Entity=${efiLabel}	type=CDQ	!>
+
+<UltraShortTermForcast::${efiLabel}>
+@id	超短期预测功率
+#foreach( $cdq in $vList )
+#${velocityCount}	${cdq.ratio}	${cdq.forecastTime}
+#end
+</UltraShortTermForcast::${efiLabel}>

+ 5 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/constants/CommonStant.java

@@ -25,6 +25,11 @@ public interface CommonStant {
     String RECORD_TYPE_PULL_CDQ = "PULL_INIT_CDQ";
 
     /**
+     * 日志类型:接收原始超短期
+     */
+    String RECORD_TYPE_PUT_CDQ = "PUT_INIT_CDQ";
+
+    /**
      * 日志类型:推送原始
      */
     String RECORD_TYPE_PUSH_INIT = "PUSH_INIT";

+ 9 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/constants/CompanyConstant.java

@@ -24,4 +24,13 @@ public interface CompanyConstant {
      */
     String COMPANY_BJZYYJY_SD = "BJZYYJYSD";
 
+    /**
+     * 飔合科技(辽宁)
+     */
+    String COMPANY_SHKJ_LN = "SHKJLN";
+
+    String COMPANY_LX = "LX";
+
+
+
 }

+ 44 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/constants/dto/SHKJLNPushDqDataParamsDto.java

@@ -0,0 +1,44 @@
+package com.jiayue.insu.incloud.constants.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 飔合科技(辽宁)上送数据参数dto
+ *
+ * @Author: tl
+ * @Date: 2023/12/14 13:43
+ */
+@Data
+public class SHKJLNPushDqDataParamsDto {
+
+    public SHKJLNPushDqDataParamsDto(String station_id, String forecast_date, List<DataPointDTO> data) {
+        this.station_id = station_id;
+        this.forecast_date = forecast_date;
+        this.data = data;
+    }
+
+    /**
+     * id
+     */
+    private String station_id;
+    /**
+     * 预测日期
+     */
+    private String forecast_date;
+
+    /**
+     * 预测时间和数据
+     */
+    private List<DataPointDTO> data;
+
+
+
+    @Data
+    public static class DataPointDTO {
+        private double power;
+        private String time;
+    }
+}
+

+ 72 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/constants/enums/SHKJEnum.java

@@ -0,0 +1,72 @@
+package com.jiayue.insu.incloud.constants.enums;
+/**
+ * 飔合科技 ENUM
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public enum SHKJEnum {
+
+    REQUEST_SUCCESS("200","success","请求成功"),
+
+    PERMISSON_TOKEN_EXPIRE("I101","TOKEN_EXPIRE","token已过期"),
+    PERMISSON_TOKEN_INVALID("I102","TOKEN_INVALID","无效token"),
+    PERMISSON_AUTOGRAPH_FAIL("I103","AUTOGRAPH_FAIL","签名失败"),
+    PERMISSON_LOGIN_NOT("I104","LOGIN_NOT","用户未登录"),
+
+    /**
+     * 传输类型
+     */
+    TRANSFER_TYPE_DOWNLOAD("download","download","数据传输类型:功率预测主站下发"),
+    TRANSFER_TYPE_UPLOAD("upload","upload","数据传输类型:功率预测子站回传"),
+    TRANSFER_TYPE_CORRECT("correct","correct","数据传输类型:一体化平台修正下发"),
+
+    /**
+     * 数据类型
+     */
+    DATA_FORE_TYPE("FORE","FORE","预测"),
+    DATA_PROBDIST_TYPE("PROBDIST","PROBDIST","概率分布"),
+    DATA_STAT_TYPE("STAT","STAT","统计"),
+    DATA_CORRFORE_TYPE("CORRFORE","CORRFORE","优化后预测"),
+    DATA_TODAYFORE_TYPE("TODAYFORE","TODAYFORE","优化后当日预测"),
+    DATA_CORRULTRSHOR_TYPE("CORRULTRSHOR","CORRULTRSHOR","超短期修正"),
+    DATA_REPAPLAN_TYPE("REPAPLAN","REPAPLAN","检修计划"),
+            ;
+
+    private String code;
+    private String sign;
+    private String msg;
+
+    SHKJEnum(String code, String sign, String msg) {
+        this.code = code;
+        this.sign = sign;
+        this.msg  =msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}

+ 41 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/constants/vo/ResponseLXVo.java

@@ -0,0 +1,41 @@
+package com.jiayue.insu.incloud.constants.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+
+/**
+ * 林祥上送数据VO
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResponseLXVo {
+
+    /**
+     * 响应码
+     */
+    private String code;
+
+    /**
+     * 响应信息
+     */
+    private String message;
+
+    /**
+     *  是否成功
+     */
+    private Long timestamp;
+
+    /**
+     * 响应数据
+     */
+    private Boolean data;
+}

+ 46 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/constants/vo/ResponseSHLNVo.java

@@ -0,0 +1,46 @@
+package com.jiayue.insu.incloud.constants.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+
+/**
+ * 飔合科技(辽宁)上送/请求修正数据响应VO
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResponseSHLNVo {
+
+    /**
+     * 响应码
+     */
+    private String code;
+
+    /**
+     * 响应信息
+     */
+    private String message;
+
+    /**
+     *  是否成功
+     */
+    private Boolean success;
+
+    /**
+     *  场站id
+     */
+    private String station_id;
+
+    /**
+     * 响应数据
+     */
+    private String data;
+}

+ 190 - 25
in-cloud/src/main/java/com/jiayue/insu/incloud/controller/ApiController.java

@@ -3,9 +3,11 @@ package com.jiayue.insu.incloud.controller;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import com.jiayue.insu.incloud.constants.CommonStant;
+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.service.ApiService;
+import com.jiayue.insu.incloud.service.ForecastDataService;
 import com.jiayue.insu.incloud.service.RecordService;
 import com.jiayue.insu.incloud.service.StationService;
 import com.jiayue.insu.incloud.utils.JsonResultUtil;
@@ -14,8 +16,13 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.*;
+
 import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -38,6 +45,8 @@ public class ApiController {
     public StationService stationService;
     @Autowired
     public RecordService recordService;
+    @Autowired
+    public ForecastDataService forecastDataService;
 
     /**
      * 获取token
@@ -51,13 +60,13 @@ public class ApiController {
         JSONObject checkResult = checkAuthorization(request);
         // 如果校验结果为失败
         if (JsonResultUtil.Type.failure.value().equals(checkResult.get(JsonResultUtil.CODE_TAG))) {
-            Record record = new Record(CommonStant.RECORD_TYPE_COM_PERMISSON,null,null,null,LocalDateTime.now(),LocalDateTime.now(),JsonResultUtil.Type.failure.msg(),JsonResultUtil.Type.failure.value());
+            Record record = new Record(CommonStant.RECORD_TYPE_COM_PERMISSON, null, null, null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
             recordService.save(record);
             return checkResult;
         }
         // 根据用户名密码获取token
         JSONObject result = apiService.getToken(checkResult.getJSONObject(JsonResultUtil.DATA_TAG));
-        Record record = new Record(CommonStant.RECORD_TYPE_COM_PERMISSON,null,null,null,LocalDateTime.now(),LocalDateTime.now(),result.getStr(JsonResultUtil.MSG_TAG),result.getStr(JsonResultUtil.CODE_TAG));
+        Record record = new Record(CommonStant.RECORD_TYPE_COM_PERMISSON, null, null, null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
         recordService.save(record);
         return result;
     }
@@ -72,17 +81,17 @@ public class ApiController {
     public JSONObject getShortWpfData(HttpServletRequest request, @RequestBody JSONObject data) {
         Station station = new Station();
         // 入参验证
-        JSONObject checkResult = checkRequest(request,data,station);
+        JSONObject checkResult = checkRequest(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_PULL_INIT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),JsonResultUtil.Type.failure.msg(),JsonResultUtil.Type.failure.value());
+            Record record = new Record(CommonStant.RECORD_TYPE_PULL_INIT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
             recordService.save(record);
             return checkResult;
         }
         // 返回短期数据json格式
         JSONObject result = apiService.getShortWpfData(data);
-        Record record = new Record(CommonStant.RECORD_TYPE_PULL_INIT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),result.getStr(JsonResultUtil.MSG_TAG),result.getStr(JsonResultUtil.CODE_TAG));
+        Record record = new Record(CommonStant.RECORD_TYPE_PULL_INIT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
         recordService.save(record);
         return result;
     }
@@ -97,17 +106,17 @@ public class ApiController {
     public JSONObject getNwpData(HttpServletRequest request, @RequestBody JSONObject data) {
         Station station = new Station();
         // 入参验证
-        JSONObject checkResult = checkRequest(request,data,station);
+        JSONObject checkResult = checkRequest(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_PULL_NWP_INIT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),JsonResultUtil.Type.failure.msg(),JsonResultUtil.Type.failure.value());
+            Record record = new Record(CommonStant.RECORD_TYPE_PULL_NWP_INIT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
             recordService.save(record);
             return checkResult;
         }
         // 返回短期数据json格式
         JSONObject result = apiService.getNwpData(data);
-        Record record = new Record(CommonStant.RECORD_TYPE_PULL_NWP_INIT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),result.getStr(JsonResultUtil.MSG_TAG),result.getStr(JsonResultUtil.CODE_TAG));
+        Record record = new Record(CommonStant.RECORD_TYPE_PULL_NWP_INIT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
         recordService.save(record);
         return result;
     }
@@ -122,16 +131,16 @@ public class ApiController {
     public JSONObject putShortWpfData(HttpServletRequest request, @RequestBody JSONObject data) {
         Station station = new Station();
         // 入参验证
-        JSONObject checkResult = checkRequest(request,data,station);
+        JSONObject checkResult = checkRequest(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_DQ_CORRECT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),JsonResultUtil.Type.failure.msg(),JsonResultUtil.Type.failure.value());
+            Record record = new Record(CommonStant.RECORD_TYPE_PUT_DQ_CORRECT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
             recordService.save(record);
             return checkResult;
         }
         JSONObject result = apiService.putShortWpfData(data);
-        Record record = new Record(CommonStant.RECORD_TYPE_PUT_DQ_CORRECT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),result.getStr(JsonResultUtil.MSG_TAG),result.getStr(JsonResultUtil.CODE_TAG));
+        Record record = new Record(CommonStant.RECORD_TYPE_PUT_DQ_CORRECT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
         recordService.save(record);
         // 返回短期数据json格式
         return result;
@@ -147,17 +156,17 @@ public class ApiController {
     public JSONObject getSShortWpfData(HttpServletRequest request, @RequestBody JSONObject data) {
         Station station = new Station();
         // 入参验证
-        JSONObject checkResult = checkRequest(request,data,station);
+        JSONObject checkResult = checkRequest(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_PULL_CDQ,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),JsonResultUtil.Type.failure.msg(),JsonResultUtil.Type.failure.value());
+            Record record = new Record(CommonStant.RECORD_TYPE_PULL_CDQ, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
             recordService.save(record);
             return checkResult;
         }
         // 返回超短期数据json格式
-        JSONObject result =apiService.getSShortWpfData(data);
-        Record record = new Record(CommonStant.RECORD_TYPE_PULL_CDQ,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),result.getStr(JsonResultUtil.MSG_TAG),result.getStr(JsonResultUtil.CODE_TAG));
+        JSONObject result = apiService.getSShortWpfData(data);
+        Record record = new Record(CommonStant.RECORD_TYPE_PULL_CDQ, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
         recordService.save(record);
         return result;
     }
@@ -172,17 +181,17 @@ public class ApiController {
     public JSONObject putSShortWpfData(HttpServletRequest request, @RequestBody JSONObject data) {
         Station station = new Station();
         // 入参验证
-        JSONObject checkResult = checkRequest(request,data,station);
+        JSONObject checkResult = checkRequest(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_CORRECT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),JsonResultUtil.Type.failure.msg(),JsonResultUtil.Type.failure.value());
+            Record record = new Record(CommonStant.RECORD_TYPE_PUT_CDQ_CORRECT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
             recordService.save(record);
             return checkResult;
         }
         // 返回短期数据json格式
         JSONObject result = apiService.putSShortWpfData(data);
-        Record record = new Record(CommonStant.RECORD_TYPE_PUT_CDQ_CORRECT,inCode,data.getStr("wfId"),null,LocalDateTime.now(),LocalDateTime.now(),result.getStr(JsonResultUtil.MSG_TAG),result.getStr(JsonResultUtil.CODE_TAG));
+        Record record = new Record(CommonStant.RECORD_TYPE_PUT_CDQ_CORRECT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
         recordService.save(record);
         return result;
     }
@@ -261,7 +270,7 @@ public class ApiController {
      *
      * @return
      */
-    public JSONObject checkRequest(HttpServletRequest httpRequest,JSONObject requestJson,Station station) {
+    public JSONObject checkRequest(HttpServletRequest httpRequest, JSONObject requestJson, Station station) {
         // 验证token
         JSONObject tokenResult = checkToken(httpRequest);
         if (JsonResultUtil.Type.failure.value().equals(tokenResult.get(JsonResultUtil.CODE_TAG))) {
@@ -275,19 +284,19 @@ public class ApiController {
 
         JSONArray stationCodeArr = new JSONArray();
         // 获取场站id
-        if((requestJson.get("wfId") instanceof JSONArray)){
+        if ((requestJson.get("wfId") instanceof JSONArray)) {
             stationCodeArr = (requestJson.getJSONArray("wfId"));
-        }else{
+        } else {
             stationCodeArr.add(requestJson.get("wfId"));
         }
 
         // 如果场站id为空
-        if (stationCodeArr == null || stationCodeArr.size()==0) {
+        if (stationCodeArr == null || stationCodeArr.size() == 0) {
             log.info("场站id为空");
             return JsonResultUtil.failure("场站id为空");
         }
 
-        if(stationCodeArr.size() == 1){
+        if (stationCodeArr.size() == 1) {
             // 根据场站编号查询场站信息
             station = stationService.findByStationCode(stationCodeArr.get(0).toString());
             // 如果场站信息为空
@@ -301,14 +310,170 @@ public class ApiController {
 
     /**
      * 获取inCode
+     *
      * @param station
      * @return
      */
-    public String getInCode(Station station){
+    public String getInCode(Station station) {
         String inCode = "";
-        if(station!=null){
+        if (station != null) {
             inCode = station.getInCode();
         }
         return inCode;
     }
+
+
+    /*----------------------------------------------------------以下为新增-----------------------------------------------------------------*/
+
+    /**
+     * 获取短期修正数据(飔合科技)
+     *
+     * @param request
+     * @return
+     */
+    @PostMapping("/getCorrectShort")
+    public JSONObject getCorrectShort(HttpServletRequest request, @RequestBody JSONObject data) {
+
+        // 飔合科技入参验证
+        Station station = new Station();
+        JSONObject checkResult = checkRequest(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_PULL_CORRECT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), JsonResultUtil.Type.failure.msg(), JsonResultUtil.Type.failure.value());
+            recordService.save(record);
+            return checkResult;
+        }
+        // 根据场站编号获取场站信息
+        station = stationService.findByStationCode((String) data.get("wfId"));
+        // 获取文件生成日期
+        String initTime = (String) data.get("init_time");
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        // 将字符串转换为LocalDateTime
+        LocalDateTime dateTime = LocalDateTime.parse(initTime, formatter);
+        // 返回短期数据json格式
+        JSONObject result = apiService.getSHCorrect(station, dateTime);
+        Record record = new Record(CommonStant.RECORD_TYPE_PULL_CORRECT, inCode, data.getStr("wfId"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr(JsonResultUtil.MSG_TAG), result.getStr(JsonResultUtil.CODE_TAG));
+        recordService.save(record);
+        return result;
+    }
+
+    /**
+     * 获取武穴原始超短期数据
+     *
+     * @param request
+     * @param data
+     * @return
+     */
+    @PostMapping("/getUltraShortTermData")
+    public JSONObject getUltraShortTermData(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_PUSH_INIT, 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.getUltraShortTermData(data);
+        Record record = new Record(CommonStant.RECORD_TYPE_PUSH_INIT, inCode, data.getStr("stationIds"), null, LocalDateTime.now(), LocalDateTime.now(), result.getStr("message"), result.getStr("statusCode"));
+        recordService.save(record);
+        return result;
+    }
+
+
+    /**
+     * 接收武穴原始超短期
+     *
+     * @param request
+     * @param data
+     * @return
+     */
+    @PostMapping("/putUltraShortTermData")
+    public JSONObject putUltraShortTermData(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.putUltraShortTermData(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
+     */
+    public JSONObject checkRequestForWX(HttpServletRequest httpRequest, JSONObject requestJson, Station station) {
+
+        // 校验用户名密码
+        String authorization = httpRequest.getHeader(CommonStant.AUTHORIZATION);
+
+        // 如果授权信息不存在,返回失败
+        if (authorization == null) {
+            return JsonResultUtil.failure("authorization授权不存在");
+        }
+        // 身份
+        String[] info = authorization.split(CommonStant.SPACE1_CONSTANT);
+
+        String identity = new String(Base64.getDecoder().decode(info[1]));
+        if (identity.contains(CommonStant.CHARACTER_COLON)) {
+            String passwordWx = identity.split(CommonStant.CHARACTER_COLON)[1];
+            // 获取用户列表
+            Map<String, String> userMap = redisTemplate.opsForHash().entries(CommonStant.REDIS_USERS);
+            // 如果用户列表为空,返回失败
+            if (userMap == null) {
+                return JsonResultUtil.failure("用户列表为空");
+            }
+            // 根据用户名查找密码
+            String password = userMap.get(identity.split(CommonStant.CHARACTER_COLON)[0]);
+            // 如果密码为空,则证明用户不存在
+            if (password == null) {
+                return JsonResultUtil.failure("用户名不存在");
+            }
+            if (!password.equals(passwordWx)) {
+                return JsonResultUtil.failure("密码不正确");
+            }
+        }
+
+        if (requestJson == null) {
+            log.info("接收到的数据为空");
+            return JsonResultUtil.failure("接收到的数据为空");
+        }
+
+        JSONArray stationCodeArr = new JSONArray();
+        // 获取场站id
+        if ((requestJson.get("stationIds") instanceof JSONArray)) {
+            stationCodeArr = (requestJson.getJSONArray("stationIds"));
+        } else {
+            stationCodeArr.add(requestJson.get("stationIds"));
+        }
+
+        // 如果场站id为空
+        if (stationCodeArr == null || stationCodeArr.size() == 0) {
+            log.info("场站id为空");
+            return JsonResultUtil.failure("场站id为空");
+        }
+        if (stationCodeArr.size() == 1) {
+            // 根据场站编号查询场站信息
+            station = stationService.findByStationCode(stationCodeArr.get(0).toString());
+            // 如果场站信息为空
+            if (station == null) {
+                log.info("场站信息为空");
+                return JsonResultUtil.failure("场站信息为空");
+            }
+        }
+        return JsonResultUtil.success();
+    }
 }

+ 44 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/entity/UltraShortTerm.java

@@ -0,0 +1,44 @@
+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;
+
+
+/**
+ * 预测数据实体
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2020/7/8 10:56
+ */
+
+@TableName(value = "in_ultra_short_term")
+@Data
+public class UltraShortTerm {
+
+    // id
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    // 场站编号
+    private String stationCode;
+
+    //生成时间
+    private Long genDate;
+
+    //预测时间
+    private Long forecastTime;
+
+    // 预测功率
+    private BigDecimal fpValue;
+
+}

+ 41 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/job/data/pull/SHKJPullCorrectDataJob.java

@@ -0,0 +1,41 @@
+package com.jiayue.insu.incloud.job.data.pull;
+
+import com.jiayue.insu.incloud.constants.CommonStant;
+import com.jiayue.insu.incloud.entity.Station;
+import com.jiayue.insu.incloud.pulldata.PullCorrectDataForQNHL;
+import com.jiayue.insu.incloud.pulldata.PullCorrectDataForSH;
+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;
+
+/**
+ * 飔合科技 拉取修正数据定时任务
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Slf4j
+public class SHKJPullCorrectDataJob implements Job {
+
+    @Autowired
+    private PullCorrectDataForSH pullCorrectDataForSH;
+    @Autowired
+    private StationService stationService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        String code = jobExecutionContext.getTrigger().getJobKey().getName();
+        // 校验并获取场站信息
+        Station station = stationService.checkAndFindStation(code,CommonStant.RECORD_TYPE_PULL_CORRECT);
+        //没有成功记录进行业务
+        if (station != null) {
+            pullCorrectDataForSH.pullDQData(station);
+        }else{
+            log.error("========== 一体化定时任务异常:  场站信息为空  {}==========",code);
+        }
+    }
+}

+ 59 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/job/data/push/LXPushInitDqDataJob.java

@@ -0,0 +1,59 @@
+package com.jiayue.insu.incloud.job.data.push;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import com.jiayue.insu.incloud.constants.CommonStant;
+import com.jiayue.insu.incloud.constants.enums.StatusEnum;
+import com.jiayue.insu.incloud.entity.Record;
+import com.jiayue.insu.incloud.entity.Station;
+import com.jiayue.insu.incloud.pushdata.PushDataForLX;
+import com.jiayue.insu.incloud.pushdata.PushDataForSH;
+import com.jiayue.insu.incloud.service.RecordService;
+import com.jiayue.insu.incloud.service.StationService;
+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
+ */
+public class LXPushInitDqDataJob implements Job {
+
+    @Autowired
+    private PushDataForLX pushDataForLX;
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        String code = jobExecutionContext.getTrigger().getJobKey().getName();
+        String[] split = code.split("-");
+        if(split!=null && split.length>0){
+            String stationCode = split[0];
+            if (split.length>2){
+                stationCode = split[0]+"-"+split[1];
+            }
+
+            Station one = stationService.findByStationCode(stationCode);
+            if (one != null) {
+                //查询是否有今天成功记录 (为提高稳定性,该定时任务采取在规定时间段内 重复循环执行的定时策略,故:需要查询是否存在成功记录)
+                Record successRecord = recordService.findTimeAndTypeAndStateAndStation(
+                        LocalDateTimeUtil.beginOfDay(LocalDateTime.now()),
+                        CommonStant.RECORD_TYPE_PUSH_INIT,
+                        StatusEnum.SUCCESS.getSign(), stationCode);
+                //没有成功记录进行业务
+                if(successRecord == null) {
+                    pushDataForLX.pushDQData(one);
+                }
+            }
+        }
+
+    }
+}

+ 58 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/job/data/push/SHKJLNPushInitDqDataJob.java

@@ -0,0 +1,58 @@
+package com.jiayue.insu.incloud.job.data.push;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import com.jiayue.insu.incloud.constants.CommonStant;
+import com.jiayue.insu.incloud.constants.enums.StatusEnum;
+import com.jiayue.insu.incloud.entity.Record;
+import com.jiayue.insu.incloud.entity.Station;
+import com.jiayue.insu.incloud.pushdata.PushDataForSH;
+import com.jiayue.insu.incloud.service.RecordService;
+import com.jiayue.insu.incloud.service.StationService;
+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
+ */
+public class SHKJLNPushInitDqDataJob implements Job {
+
+    @Autowired
+    private PushDataForSH pushDataForSH;
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        String code = jobExecutionContext.getTrigger().getJobKey().getName();
+        String[] split = code.split("-");
+        if(split!=null && split.length>0){
+            String stationCode = split[0];
+            if (split.length>2){
+                stationCode = split[0]+"-"+split[1];
+            }
+
+            Station one = stationService.findByStationCode(stationCode);
+            if (one != null) {
+                //查询是否有今天成功记录 (为提高稳定性,该定时任务采取在规定时间段内 重复循环执行的定时策略,故:需要查询是否存在成功记录)
+                Record successRecord = recordService.findTimeAndTypeAndStateAndStation(
+                        LocalDateTimeUtil.beginOfDay(LocalDateTime.now()),
+                        CommonStant.RECORD_TYPE_PUSH_INIT,
+                        StatusEnum.SUCCESS.getSign(), stationCode);
+                //没有成功记录进行业务
+                if(successRecord == null) {
+                    pushDataForSH.pushDQData(one);
+                }
+            }
+        }
+
+    }
+}

+ 11 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/mapper/UltraShortTermMapper.java

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

+ 20 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/pulldata/IPullInitCorrectDataForSH.java

@@ -0,0 +1,20 @@
+package com.jiayue.insu.incloud.pulldata;
+
+import com.jiayue.insu.incloud.entity.Station;
+
+/**
+ * 拉取预测修正数据接口
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public interface IPullInitCorrectDataForSH {
+
+    /**
+     * 拉取飔合科技短期修正数据
+     * @return 是否成功
+     */
+    Boolean pullDQData(Station station);
+
+}

+ 410 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/pulldata/PullCorrectDataForSH.java

@@ -0,0 +1,410 @@
+package com.jiayue.insu.incloud.pulldata;
+
+import cn.hutool.core.collection.CollectionUtil;
+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.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jiayue.insu.incloud.compermisson.QNHLComPermisson;
+import com.jiayue.insu.incloud.constants.CommonStant;
+import com.jiayue.insu.incloud.constants.CompanyConstant;
+import com.jiayue.insu.incloud.constants.enums.QNHLEnum;
+import com.jiayue.insu.incloud.constants.enums.SHKJEnum;
+import com.jiayue.insu.incloud.constants.enums.StatusEnum;
+import com.jiayue.insu.incloud.constants.vo.RequestVo;
+import com.jiayue.insu.incloud.constants.vo.ResponseSHLNVo;
+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.utils.SystermUtils;
+import com.jiayue.insu.minio.util.MinioUtilService;
+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.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * 清能互联 拉取修正数据业务
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Component
+@Slf4j
+@RefreshScope
+public class PullCorrectDataForSH implements IPullInitCorrectDataForSH {
+
+    @Autowired
+    private ForecastDataService forecastDataService;
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private IntegrationCompanyService integrationCompanyService;
+
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private VelocityEngine velocityEngine;
+    @Autowired
+    private MinioUtilService minioUtilService;
+
+    @Value("${minio.fileurl}")
+    String fileurl;
+
+    @Value("${minio.bucketname}")
+    private String bucketName;
+
+    /**
+     * 拉取修正预测数据并生成文件上送minio服务器
+     *
+     * @param station 场站信息
+     * @return 是否成功
+     */
+    @Override
+    public Boolean pullDQData(Station station) {
+
+        Record record = new Record();
+        record.setStationCode(station.getStationCode());
+        record.setInCode(station.getInCode());
+        record.setType(CommonStant.RECORD_TYPE_PULL_CORRECT);
+        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
+        record.setTime(localDateTime);
+        record.setCreateTime(LocalDateTime.now());
+
+        Station st = stationService.findByStationCode(station.getStationCode());
+
+        IntegrationCompany integrationCompany = integrationCompanyService.findByCode(CompanyConstant.COMPANY_SHKJ_LN);
+//        String dataPullUrl = integrationCompany.getPullUrl();
+        String dataPullUrl = "https://dataservice.tradingthink.cn/api/thirdDatasourceSync/syjy/power_submit";
+
+        boolean result = false;
+        boolean isUpload = false;
+        String response;
+        List<ForecastData> list = new ArrayList<>();
+        try {
+            DateTime dateTime = DateUtil.parse(DateUtil.today());
+            DateTime tomorrow = DateUtil.offsetDay(dateTime, 1);
+            //https://dataservice.tradingthink.cn/api/thirdDatasourceSync/syjy/power_submit
+            String day = tomorrow.toString("yyyy-MM-dd");
+            Map<String, Object> map = new HashMap<>();
+            map.put("station_id", "2109001");
+            map.put("day", day);
+            // 发送请求
+            HttpRequest httpRequest = HttpRequest.post(dataPullUrl)
+                    .header("Content-Type", "application/json")
+                    .header("DATA_SERVICE_TOKEN", "eed451be-fe36-4d2a-a3b0-85cc440b406f")
+                    .body(JSONUtil.toJsonStr(map));
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.execute().body();
+
+            if (StrUtil.isNotEmpty(response)) {
+                boolean isJson = JSONUtil.isJsonObj(response);
+                if (isJson) {
+                    ResponseSHLNVo responseSHLNVo = JSONUtil.toBean(response, ResponseSHLNVo.class);
+                    String code = responseSHLNVo.getCode();
+                    if (code.equals(SHKJEnum.REQUEST_SUCCESS.getCode())) {
+                        List<ForecastData> aList = new ArrayList<>();
+                        long startTime = DateUtil.beginOfDay(DateUtil.tomorrow()).getTime() + 15 * 60 * 1000L;
+                        long endTime = startTime + 24 * 3600 * 1000L-1;
+                        aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
+                        log.info(station.getStationCode() + " 请求短期修正数据返回内容:{}", response);
+
+                        try {
+                            list = correctWindData(responseSHLNVo.getData());
+
+                            /**************检测解析数据完整性(飔合科技只修正96数据)*******************/
+                            BigDecimal one = new BigDecimal("1");
+                            BigDecimal checkCount = new BigDecimal(96);
+                            if (list.size() < checkCount.intValue()) {
+                                record.setState(StatusEnum.DATA_DEFICIENCY.getCode());
+                                record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
+                                log.warn("========== {}:{} ==> 请求短期修正数据缺数: {}", integrationCompany.getName(), st.getStationCode(), list.size());
+                            } else {
+                                result = true;
+                                for (ForecastData a : aList) {
+                                    List<ForecastData> collect = list.stream().filter(n -> n.getForecastTime().longValue() == a.getForecastTime().longValue()).collect(Collectors.toList());
+                                    if (CollectionUtil.isNotEmpty(collect)) {
+                                        ForecastData correct = collect.get(0);
+                                        a.setCorrectTime(LocalDateTime.now());
+                                        a.setFpValueCorrect(correct.getFpValueCorrect());
+                                    } else {
+                                        record.setState(StatusEnum.DATA_DEFICIENCY.getCode());
+                                        record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
+                                        log.warn("========== {}:{} ==> 请求短期修正数据缺数: {}", integrationCompany.getName(), st.getStationCode(), list.size());
+                                        break;
+                                    }
+                                }
+
+                            }
+                            /**************检测解析数据完整性*******************/
+                        } catch (Exception e) {
+                            record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
+                            record.setStateContent("解析短期修正数据失败");
+                            log.error("=========={}:{} ==> 解析短期修正数据失败 ", integrationCompany.getName(), st.getStationCode());
+                        }
+
+                        if (result) {
+                            log.info("=========={}:{} ==> 拉取短期修正数据成功! ==========", integrationCompany.getName(), st.getStationCode());
+                            record.setState(StatusEnum.SUCCESS.getSign());
+                            record.setStateContent(String.valueOf(list.size()));
+                            forecastDataService.saveOrUpdateBatch(aList);
+
+                        }
+
+                    } else {
+                        record.setState(StatusEnum.RESPONSE_FAIL.getSign());
+                        record.setStateContent(StatusEnum.RESPONSE_FAIL.getMsg());
+                        log.error("=========={}:{} ==>拉取短期修正数据失败 响应码异常 ", integrationCompany.getName(), st.getStationCode());
+                    }
+                } 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());
+            }
+
+        } catch (Exception e) {
+            record.setState(StatusEnum.CONNECT_ERROR.getSign());
+            record.setStateContent(StatusEnum.CONNECT_ERROR.getMsg());
+            log.error("=========={}:{} ==>请求短期修正数据失败 连接断开或请求超时 ==========", integrationCompany.getName(), st.getStationCode());
+            e.printStackTrace();
+
+        }
+//        }
+        recordService.save(record);
+        return isUpload;
+
+    }
+
+
+    /**
+     * 风电数据解析(飔合科技只修正短期预测数据)
+     *
+     * @param data 待解析数据
+     * @return 解析数据
+     * @throws Exception
+     */
+    public List<ForecastData> correctWindData(String data) throws Exception {
+
+        data = data.substring(1, data.length() - 1);
+        String[] content = data.split("(?<=})\\s*,\\s*");
+
+        List<ForecastData> list = new ArrayList<>();
+
+        for (int i = 0; i < content.length; i++) {
+
+            ForecastData inForecastPowerShortTerm = new ForecastData();
+            String column = content[i];
+
+            //JSON 字符串转换为一个树状结构
+            ObjectMapper objectMapper = new ObjectMapper();
+            JsonNode rootNode = objectMapper.readTree(column);
+            // 通过键名获取相应的值
+            String forecastTime = rootNode.get("time").asText();
+            double ageValue = rootNode.get("power").asDouble();
+            // 将预测时间转换为时间戳格式
+            Long forecast = DateUtil.parse(forecastTime, "yyyy-MM-dd HH:mm:ss").getTime();
+
+            inForecastPowerShortTerm.setForecastTime(forecast);
+
+            inForecastPowerShortTerm.setFpValueCorrect(isNumberOrNull(String.valueOf(ageValue)));
+
+            list.add(inForecastPowerShortTerm);
+        }
+
+
+        return list;
+
+    }
+
+    /**
+     * 判断是否是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;
+    }
+
+
+//    /**
+//     * 生成文件
+//     *
+//     * @return
+//     */
+//    public File genFile(Station station) {
+//
+//        String vmsPath = SystermUtils.getResourceBasePath() + "/vms/DQ.vm";
+//        File file = null;
+//        Template template = this.velocityEngine.getTemplate(vmsPath);
+//        if (template != null) {
+//            VelocityContext velocityContext;
+//            StringWriter writer;
+//
+//            long startTime = DateUtil.beginOfDay(new Date()).getTime();
+//            long endTime = DateUtil.offsetDay(DateUtil.beginOfDay(DateUtil.tomorrow()), station.getDays()).getTime();
+//            List<ForecastData> aList = new ArrayList<>();
+//            aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
+//            aList.sort(Comparator.comparing(ForecastData::getForecastTime));
+//            List<Map<String, Object>> vList = new ArrayList<>();
+//
+//            for (ForecastData a : aList) {
+//                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);
+//
+//            }
+//
+//            velocityContext = new VelocityContext();
+//            velocityContext.put("stationName", station.getName());
+//
+//            velocityContext.put("date", DateUtil.format(new Date(), "yyyy-MM-dd"));
+//            velocityContext.put("vList", vList);
+//
+//            writer = new StringWriter();
+//            template.merge(velocityContext, writer);
+//
+//            String fUrl = fileurl + File.separatorChar + "correct" + File.separatorChar + station.getStationCode();
+//            log.info(fUrl);
+//            File fileUrl = new File(fUrl);
+//            if (!fileUrl.exists()) {// 判断目录是否存在
+//                fileUrl.mkdirs();
+//            }
+//
+//            String fileName = "DQ_" + DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMddHHmmss") + "0.RB";
+//
+//            file = new File(fUrl + File.separatorChar + fileName);
+//
+//
+//            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 {
+//                    log.warn(station.getStationCode() + " 生成DQ文件失败");
+//                }
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//                log.warn(station.getStationCode() + " 创建DQ文件失败");
+//            } finally {
+//                if (os != null) {
+//                    try {
+//                        os.close();
+//                    } catch (IOException e) {
+//                        log.error("文件生成关闭流失败", e);
+//                    }
+//                }
+//            }
+//
+//        }
+//
+//        return file;
+//    }
+
+
+    /**
+     * 上传文件
+     *
+     * @return
+     */
+   /* public boolean uploadFile(String filePath, File file, String stationCode) {
+        boolean status = false;
+        try {
+            MinioClient minioClient = new MinioClient(minloHost, minloUser, minloPwd, false);
+
+            // 检查存储桶是否已经存在
+            boolean isExist = minioClient.bucketExists("forcast");
+            if (!isExist) {
+                // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
+                minioClient.makeBucket("forcast");
+            }
+
+            // 使用putObject上传一个文件到存储桶中。
+            minioClient.putObject("forcast", filePath, FileUtil.getInputStream(file), new PutObjectOptions(file.length(), -1));
+
+            Map<String, Object> parmer = new HashMap<>();
+            parmer.put("stationCode", stationCode);
+            parmer.put("fileName", file.getName());
+            String s = JSONUtil.toJsonStr(parmer);
+            String response = "";
+
+            response = HttpUtil.post(logurl, parmer);
+            if (StringUtils.isNotEmpty(response)) {
+                boolean isJson = JSONUtil.isJsonObj(response);
+                if (isJson) {
+                    JSONObject jsonObject = JSONUtil.parseObj(response);
+                    String code = jsonObject.getStr("code");
+                    if (code.equals("0")) {
+                        status = true;
+                    } else {
+                        log.warn(stationCode + " minlo上送日志响应不为0");
+                    }
+                } else {
+                    log.warn(stationCode + " minlo上送日志响应格式不对");
+                }
+
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("文件上传存储服务器失败" + filePath, e);
+        }
+
+        return status;
+    }*/
+
+
+}

+ 195 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForLX.java

@@ -0,0 +1,195 @@
+package com.jiayue.insu.incloud.pushdata;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.io.file.FileReader;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jiayue.insu.incloud.compermisson.BJZYYJYSDComPermisson;
+import com.jiayue.insu.incloud.constants.CommonStant;
+import com.jiayue.insu.incloud.constants.CompanyConstant;
+import com.jiayue.insu.incloud.constants.enums.StatusEnum;
+import com.jiayue.insu.incloud.constants.vo.ResponseLXVo;
+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.IntegrationCompanyService;
+import com.jiayue.insu.incloud.service.RecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 林祥上送短期数据
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Component
+@Slf4j
+public class PushDataForLX implements IPushInitForecastData {
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private IntegrationCompanyService integrationCompanyService;
+    @Autowired
+    BJZYYJYSDComPermisson bjzyyjysdComPermisson;
+
+    @Value("${localFilePath.lxFilePath}")
+    String lxFilePath;
+
+    /**
+     * 推送原始预测数据
+     *
+     * @param station 场站信息
+     * @return 是否成功
+     */
+    @Override
+    public Boolean pushDQAndNWPData(Station station) {
+        return null;
+    }
+
+    /**
+     * 将下载好的原始短期文件通过sftp推送
+     *
+     * @param station
+     * @return
+     */
+    @Override
+    public Boolean pushDQData(Station station) {
+
+        IntegrationCompany integrationCompany = integrationCompanyService.findByCode(CompanyConstant.COMPANY_LX);
+        // 获取场站编号
+        String stationCode = station.getStationCode();
+        Record record = new Record(CommonStant.RECORD_TYPE_PUSH_INIT, CompanyConstant.COMPANY_LX, stationCode, null, LocalDateTimeUtil.beginOfDay(LocalDateTime.now()), LocalDateTime.now(), null, null);
+        record.setState(StatusEnum.SUCCESS.getSign());
+        // 如果场站编号为空,则返回
+        if (stationCode == null || "".equals(stationCode)) {
+            record.setState(StatusEnum.STATION_CODE_NULL.getSign());
+            record.setStateContent(StatusEnum.STATION_CODE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+        // 获取指定目录下的短期原始数据(/jiayue/insu/file/init/J00269/)
+        String filePath = lxFilePath + stationCode + File.separatorChar;
+        File files = new File(filePath);
+        String[] fileNames = files.list();
+        // 如果文件名列表为空
+        if (fileNames == null || fileNames.length == 0) {
+            log.info("指定目录下无文件");
+            record.setState(StatusEnum.FILE_NULL.getSign());
+            record.setStateContent(StatusEnum.FILE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+        // 获取当天日期
+        LocalDateTime today = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+        String todayStr = today.format(formatter);
+        // 转为list并根据日期筛选排序
+        List<String> fileList = Arrays.stream(fileNames).collect(Collectors.toList());
+        List<String> filterFileList = fileList.stream().filter(s -> s.contains(todayStr)).filter(s -> s.contains("DQ")).collect(Collectors.toList());
+        // 如果筛选后无文件
+        if (filterFileList.size() == 0) {
+            log.info("无当日文件");
+            record.setState(StatusEnum.FILE_NULL.getSign());
+            record.setStateContent(StatusEnum.FILE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+        filterFileList.sort(Collections.reverseOrder());
+        // 获取原始文件
+        File originalFile = new File(filterFileList.get(0));
+        // 读取文件
+        FileReader fileReader = new FileReader(filePath + originalFile);
+        List<String> originalContents = fileReader.readLines();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        List<Double> dataList = new ArrayList<>();
+
+        StringBuilder content = new StringBuilder();
+        content = content.append(stationCode + "-dq|"+dateFormat.format(new Date(System.currentTimeMillis()+24*60*60*1000L))+"|");
+
+        int i = 0;
+        // 循环解析原始短期文件
+        for (String originalContent : originalContents) {
+            // 林祥上送数据开始时间为当天的00:00:00
+            if (originalContent.contains("#")) {
+                // 根据分隔符分割,取时间和功率
+                String[] originalContentArr = originalContent.split("\t");
+
+                // 如果分割后的数组长度小于4,则数据格式不正确
+                if (originalContentArr.length < 4) {
+                    continue;
+                }
+                // 上送三天数据
+                try {
+                    if (95 < i && i < 1056){
+                        content.append(Double.valueOf(originalContentArr[3])).append("|");
+                        dataList.add(Double.valueOf(originalContentArr[3]));
+                    }
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    break;
+                }
+                i++;
+            }
+
+        }
+        String body = content.toString();
+        List<String> stringList = new ArrayList<>();
+        stringList.add(body);
+        String jsonString = "";
+        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            // 将 List<String> 转换为 JSON 格式的字符串
+            jsonString = objectMapper.writeValueAsString(stringList);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            String response;
+            HttpRequest httpRequest = HttpRequest.post("http://112.2.27.84:4220/forecast/reportData")
+                    .header("Content-Type", "application/json");
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.body(jsonString).execute().body();
+
+            ResponseLXVo responseLXVo= JSONUtil.toBean(response, ResponseLXVo.class);
+            if (responseLXVo.getCode().equals("200")) {
+                record.setState(StatusEnum.SUCCESS.getSign());
+                record.setStateContent(responseLXVo.getMessage());
+                log.info("=========={}:{} ==>上送短期原始数据成功  {}条==========", integrationCompany.getName(), station.getStationCode(), dataList.size());
+                log.info("{} 原始数据:{}", stationCode, body);
+                recordService.save(record);
+                return true;
+            } else {
+                log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因:{} ==========", integrationCompany.getName(), station.getStationCode(), responseLXVo.getCode(), responseLXVo.getMessage());
+                log.info("{} 原始数据:{}", stationCode, body);
+                record.setState(StatusEnum.FILE_NULL.getSign());
+                record.setStateContent(responseLXVo.getMessage());
+                recordService.save(record);
+                return false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean pushNWPData(Station station) {
+        return null;
+    }
+
+}

+ 234 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForSH.java

@@ -0,0 +1,234 @@
+package com.jiayue.insu.incloud.pushdata;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.io.file.FileReader;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.jiayue.insu.incloud.compermisson.BJZYYJYSDComPermisson;
+import com.jiayue.insu.incloud.constants.CommonStant;
+import com.jiayue.insu.incloud.constants.CompanyConstant;
+import com.jiayue.insu.incloud.constants.dto.SHKJLNPushDqDataParamsDto;
+import com.jiayue.insu.incloud.constants.enums.StatusEnum;
+import com.jiayue.insu.incloud.constants.vo.ResponseSHLNVo;
+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.IntegrationCompanyService;
+import com.jiayue.insu.incloud.service.RecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 飔合科技(科技)上送数据
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Component
+@Slf4j
+public class PushDataForSH implements IPushInitForecastData {
+    @Autowired
+    private RecordService recordService;
+    @Autowired
+    private IntegrationCompanyService integrationCompanyService;
+    @Autowired
+    BJZYYJYSDComPermisson bjzyyjysdComPermisson;
+
+    @Value("${localFilePath.shFilePath}")
+    String shkjlnFilePath;
+
+    /**
+     * 推送原始预测数据
+     *
+     * @param station 场站信息
+     * @return 是否成功
+     */
+    @Override
+    public Boolean pushDQAndNWPData(Station station) {
+        return null;
+    }
+
+    /**
+     * 将下载好的原始短期文件通过sftp推送
+     *
+     * @param station
+     * @return
+     */
+    @Override
+    public Boolean pushDQData(Station station) {
+
+        IntegrationCompany integrationCompany = integrationCompanyService.findByCode(CompanyConstant.COMPANY_SHKJ_LN);
+        // 获取场站编号
+        String stationCode = station.getStationCode();
+        Record record = new Record(CommonStant.RECORD_TYPE_PUSH_INIT, CompanyConstant.COMPANY_SHKJ_LN, stationCode, null, LocalDateTimeUtil.beginOfDay(LocalDateTime.now()), LocalDateTime.now(), null, null);
+        record.setState(StatusEnum.SUCCESS.getSign());
+        // 如果场站编号为空,则返回
+        if (stationCode == null || "".equals(stationCode)) {
+            record.setState(StatusEnum.STATION_CODE_NULL.getSign());
+            record.setStateContent(StatusEnum.STATION_CODE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+        // 获取指定目录下的短期原始数据(/jiayue/insu/file/init/J00269/)
+        String filePath = shkjlnFilePath + stationCode + File.separatorChar;
+        File files = new File(filePath);
+        String[] fileNames = files.list();
+        // 如果文件名列表为空
+        if (fileNames == null || fileNames.length == 0) {
+            log.info("指定目录下无文件");
+            record.setState(StatusEnum.FILE_NULL.getSign());
+            record.setStateContent(StatusEnum.FILE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+        // 获取当天日期
+        LocalDateTime today = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+        DateTimeFormatter formatterSeparator = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        String todaySeparatorStr = today.format(formatterSeparator);
+        String tomorrowSeparatorStr = today.plusDays(1).format(formatterSeparator);
+        String todayStr = today.format(formatter);
+        // 转为list并根据日期筛选排序
+        List<String> fileList = Arrays.stream(fileNames).collect(Collectors.toList());
+        List<String> filterFileList = fileList.stream().filter(s -> s.contains(todayStr)).filter(s -> s.contains("DQ")).collect(Collectors.toList());
+        // 如果筛选后无文件
+        if (filterFileList.size() == 0) {
+            log.info("无当日文件");
+            record.setState(StatusEnum.FILE_NULL.getSign());
+            record.setStateContent(StatusEnum.FILE_NULL.getMsg());
+            recordService.save(record);
+            return false;
+        }
+        filterFileList.sort(Collections.reverseOrder());
+        // 获取原始文件
+        File originalFile = new File(filterFileList.get(0));
+        // 读取文件
+        FileReader fileReader = new FileReader(filePath + originalFile);
+        List<String> originalContents = fileReader.readLines();
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        List<SHKJLNPushDqDataParamsDto.DataPointDTO> list = new ArrayList<>();
+
+        List<String> daysList = new ArrayList<>();
+
+
+        int i = 0;
+        // 循环解析原始短期文件
+        for (String originalContent : originalContents) {
+            // 飔合上送数据开始时间为第二天的00:15:00
+            if (originalContent.contains("#")) {
+                // 刨除当天的数据
+                if (originalContent.contains(todaySeparatorStr) || originalContent.contains(tomorrowSeparatorStr + " 00:00:00")) {
+                    continue;
+                }
+                // 根据分隔符分割,取时间和功率
+                String[] originalContentArr = originalContent.split("\t");
+
+                // 如果分割后的数组长度小于4,则数据格式不正确
+                if (originalContentArr.length < 4) {
+                    continue;
+                }
+                // 将时间2023-06-22 00:00:00根据分隔分割并组成2023-06-22_00:00:00格式
+                try {
+                    String[] dayHour = originalContentArr[2].split(" ");
+                    String day = dayHour[0];
+                    String hour = dayHour[1];
+                    if (!daysList.contains(day) && !hour.equals("00:00:00")) {
+                        if (station.getDays() == i) {
+                            break;
+                        }
+                        daysList.add(day);
+                        i++;
+                    }
+
+                    SHKJLNPushDqDataParamsDto.DataPointDTO dto = new SHKJLNPushDqDataParamsDto.DataPointDTO();
+                    dto.setPower(Double.valueOf(originalContentArr[3]));
+                    if (simpleDateFormat.format(simpleDateFormat.parse(originalContentArr[2]).getTime()).toString().contains("00:00:00")){
+                        dto.setTime(timeFormat(simpleDateFormat.parse(originalContentArr[2])));
+                    }else {
+                        dto.setTime(simpleDateFormat.format(simpleDateFormat.parse(originalContentArr[2]).getTime()));
+                    }
+                    list.add(dto);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    break;
+                }
+            }
+        }
+
+        SHKJLNPushDqDataParamsDto dto = new SHKJLNPushDqDataParamsDto("2109001", dateFormat.format(new Date()), list);
+
+        JSONObject json = JSONUtil.parseObj(dto, false);
+        String body = json.toString();
+
+        try {
+            String response;
+            HttpRequest httpRequest = HttpRequest.post("https://dataservice.tradingthink.cn/api/thirdDatasourceSync/syjy/push_power_forecast")
+                    .header("Content-Type", "application/json")
+                    .header("DATA_SERVICE_TOKEN","eed451be-fe36-4d2a-a3b0-85cc440b406f");
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.body(body).execute().body();
+
+            ResponseSHLNVo responseSHLNVo = JSONUtil.toBean(response, ResponseSHLNVo.class);
+            if (responseSHLNVo.getCode().equals("200")) {
+                record.setState(StatusEnum.SUCCESS.getSign());
+                record.setStateContent(responseSHLNVo.getMessage());
+                log.info("=========={}:{} ==>上送短期原始数据成功  {}天==========", integrationCompany.getName(), station.getStationCode(), daysList.size());
+                log.info("{} 原始数据:{}", stationCode, body);
+                recordService.save(record);
+                return true;
+            } else {
+                log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因:{} ==========", integrationCompany.getName(), station.getStationCode(), responseSHLNVo.getCode(), responseSHLNVo.getMessage());
+                log.info("{} 原始数据:{}", stationCode, body);
+                record.setState(StatusEnum.FILE_NULL.getSign());
+                record.setStateContent(responseSHLNVo.getMessage());
+                recordService.save(record);
+                return false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean pushNWPData(Station station) {
+        return null;
+    }
+
+
+    public String timeFormat(Date date){
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+
+        if (calendar.get(Calendar.HOUR_OF_DAY) == 0 && calendar.get(Calendar.MINUTE) == 0 && calendar.get(Calendar.SECOND) == 0) {
+            // 回到前一天
+            calendar.add(Calendar.DAY_OF_MONTH, -1);
+
+            // 设置时间为前一天的23:59:59
+            calendar.set(Calendar.HOUR_OF_DAY, 23);
+            calendar.set(Calendar.MINUTE, 59);
+            calendar.set(Calendar.SECOND, 59);
+        }
+        // 格式化日期时间为字符串
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String endTimeString = sdf.format(calendar.getTime());
+
+
+        String nonStandardEndTimeString = endTimeString.replaceFirst("23:59:59", "24:00:00");
+        return nonStandardEndTimeString;
+    }
+
+}

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

@@ -1,6 +1,11 @@
 package com.jiayue.insu.incloud.service;
 
 import cn.hutool.json.JSONObject;
+import com.jiayue.insu.incloud.entity.Station;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 预测数据业务接口
@@ -25,6 +30,30 @@ public interface ApiService  {
      */
     JSONObject getShortWpfData(JSONObject requestJson);
 
+
+    /**
+     * 获取所有当天所有短期数据(飔合科技)
+     * @param station
+     * @param initTime
+     * @return
+     */
+    JSONObject getSHCorrect(Station station, LocalDateTime initTime);
+
+
+    /**
+     * 获取超短期原始json数据
+     * @param requestJson
+     * @return
+     */
+    JSONObject getUltraShortTermData(JSONObject requestJson);
+
+    /**
+     * 接收超短期原始json数据
+     * @param requestJson
+     * @return
+     */
+    JSONObject putUltraShortTermData(JSONObject requestJson);
+
     /**
      * 获取nwp原始json数据
      * @param requestJson

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

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.jiayue.insu.incloud.entity.ForecastData;
 import com.jiayue.insu.incloud.entity.IntegrationCompany;
 
+import java.time.LocalDateTime;
 import java.util.List;
 /**
  * 预测数据业务接口
@@ -29,4 +30,7 @@ public interface ForecastDataService extends IService<ForecastData> {
      * @return 结果
      */
     List<ForecastData>  findTimeByStation(String station,Long startTime,Long endTime);
+
+
+    List<ForecastData>  findInitTimeByStation(LocalDateTime initTime,String stationCode);
 }

+ 15 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/service/UltraShortTermService.java

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

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

@@ -8,14 +8,16 @@ import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+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.service.ApiService;
-import com.jiayue.insu.incloud.service.RecordService;
-import com.jiayue.insu.incloud.service.StationService;
+import com.jiayue.insu.incloud.entity.UltraShortTerm;
+import com.jiayue.insu.incloud.service.*;
 import com.jiayue.insu.incloud.utils.JsonResultUtil;
 import com.jiayue.insu.incloud.utils.SystermUtils;
 import com.jiayue.insu.minio.util.MinioUtilService;
@@ -34,11 +36,14 @@ import org.springframework.util.DigestUtils;
 
 import java.io.*;
 import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -78,6 +83,10 @@ public class ApiServiceImpl implements ApiService {
     private MinioUtilService minioUtilService;
     @Autowired
     public RecordService recordService;
+    @Autowired
+    private ForecastDataService forecastDataService;
+    @Autowired
+    private UltraShortTermService ultraShortTermService;
 
     /**
      * 获取token
@@ -608,12 +617,12 @@ public class ApiServiceImpl implements ApiService {
         if (minIoFileUrlArr.length > 1) {
             for (String url : minIoFileUrlArr) {
                 postFileCreateInfoToCloud(station.getStationCode(), file.getName(), url);
-                pushCorr(station, file.getName(),pushDate, url);
+                pushCorr(station, file.getName(), pushDate, url);
             }
         } else {
             // 如果文件放成功,回传文件生成信息到云端
             postFileCreateInfoToCloud(station.getStationCode(), file.getName(), pushMinIoResult.getStr(JsonResultUtil.DATA_TAG));
-            pushCorr(station, file.getName(),pushDate, minIoFileUrl);
+            pushCorr(station, file.getName(), pushDate, minIoFileUrl);
         }
 
         return JsonResultUtil.success();
@@ -901,7 +910,7 @@ public class ApiServiceImpl implements ApiService {
      * @param fileName
      * @param url
      */
-    public void pushCorr(Station station, String fileName,String pushDate, String url) {
+    public void pushCorr(Station station, String fileName, String pushDate, String url) {
         // 如果场站信息为空或者 不推送修正数据
         if (station == null || "0".equals(station.getIsPushCorr())) {
             return;
@@ -917,4 +926,199 @@ public class ApiServiceImpl implements ApiService {
         String repose = HttpUtil.post(pushCorrFileUrl, params, 10000);
         log.info("发送下发修正文件请求,请求响应 {}", repose);
     }
+
+    /*----------------------------------------------------------以下为新增-----------------------------------------------------------------*/
+
+    /**
+     * 获取所有今天的数据返给站端
+     *
+     * @param station
+     * @param initTime
+     * @return
+     */
+    @Override
+    public JSONObject getSHCorrect(Station station, LocalDateTime initTime) {
+        JSONArray jsonArray = new JSONArray();
+        JSONObject finalJsonObject = new JSONObject();
+        List<Map<String, Object>> list = new ArrayList<>();
+        if (station.getInCode().equals("SHKJLN")) {
+            List<ForecastData> forecastDataList = forecastDataService.findInitTimeByStation(initTime, station.getStationCode());
+            if (forecastDataList.size() > 0) {
+                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                forecastDataList.stream().sorted(Comparator.comparing(ForecastData::getForecastTime));
+
+                for (ForecastData forecastData : forecastDataList) {
+                    Map<String, Object> map = new HashMap<>();
+                    if (null != forecastData.getFpValueCorrect()) {
+                        map.put("power", forecastData.getFpValueCorrect());
+                    } else {
+                        map.put("power", forecastData.getFpValue());
+                    }
+                    map.put("time", simpleDateFormat.format(forecastData.getForecastTime()));
+                    list.add(map);
+                }
+                // 将 List<Map<String, Object>> 转换为 JSONArray
+                jsonArray = new JSONArray();
+                for (Map<String, Object> map : list) {
+                    JSONObject jsonObject = new JSONObject(map);
+                    jsonArray.add(jsonObject);
+                }
+                // 将 JSONArray 嵌入到一个 JSONObject 中
+                finalJsonObject.put("code", 200);
+                finalJsonObject.put("station_id", station.getStationCode());
+                finalJsonObject.put("data", jsonArray);
+            } else {
+                finalJsonObject.put("code", 500);
+                finalJsonObject.set("msg", "当天没有下载原始数据,请使用原始数据直接上送");
+                return finalJsonObject;
+            }
+            return finalJsonObject;
+        } else {
+            finalJsonObject.put("code", 500);
+            finalJsonObject.set("msg", "无该场站相关信息!");
+            return finalJsonObject;
+        }
+
+    }
+
+    /**
+     * 获取武穴原始超短期数据
+     *
+     * @param requestJson
+     * @return
+     */
+    @Override
+    public JSONObject getUltraShortTermData(JSONObject requestJson) {
+        JSONObject result = new JSONObject();
+        JSONArray stationCodeArr = requestJson.getJSONArray("stationIds");
+        JSONArray dateTimeArr = requestJson.getJSONArray("datetime");
+        JSONArray dataArr = new JSONArray();
+
+        // 创建一个最外层的LinkedHashMap
+        Map<String, Map<String, Double>> outerMap = new LinkedHashMap<>();
+
+        for (Object o : dateTimeArr) {
+            Long genDte = Long.valueOf(o.toString());
+            List<UltraShortTerm> ultraShortTermList = ultraShortTermService.findByGenDate(genDte, stationCodeArr.get(0).toString());
+
+            // 注意:这里应该使用 sorted() 的返回结果,因为它返回一个新的排序后的流
+            // 如果你需要保留排序后的列表,应该使用 collect(Collectors.toList())
+            List<UltraShortTerm> sortedUltraShortTermList = ultraShortTermList.stream()
+                    .sorted(Comparator.comparing(UltraShortTerm::getForecastTime))
+                    .collect(Collectors.toList());
+
+            Map<String, Double> innerMap = new LinkedHashMap<>();
+            for (UltraShortTerm ultraShortTerm : sortedUltraShortTermList) {
+                innerMap.put(ultraShortTerm.getForecastTime().toString(), ultraShortTerm.getFpValue().doubleValue());
+            }
+            outerMap.put(genDte.toString(), innerMap);
+        }
+
+        if (!outerMap.isEmpty()) {
+            result.put("statusCode", "1000");
+            result.put("message", "请求成功");
+            result.put("result", "OK");
+            result.put("data", outerMap);  // 直接将 outerMap 作为 data 的值
+        } else {
+            result.put("statusCode", "1004");
+            result.put("message", "系统异常");
+            result.put("result", "FALSE");
+        }
+
+        return result;
+    }
+
+    /**
+     * 接收超短期原始数据存入数据库
+     *
+     * @param requestJson
+     * @return
+     */
+    @Override
+    public JSONObject putUltraShortTermData(JSONObject requestJson) {
+        JSONObject result = new JSONObject();
+        String stationCodeArr = requestJson.getStr("stationIds");
+        Long genDate = Long.valueOf(requestJson.getStr("genDate"));
+        List<UltraShortTerm> ultraShortTermList = new ArrayList<>();
+        try {
+            ultraShortTermList = correctWindData(requestJson.getStr("data"), stationCodeArr, genDate);
+            if (ultraShortTermList.size() > 0) {
+                log.info("接收原始超短期数据:{}", ultraShortTermList.size());
+                ultraShortTermService.save(ultraShortTermList);
+                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 待解析数据
+     * @return 解析数据
+     * @throws Exception
+     */
+    public List<UltraShortTerm> correctWindData(String data, String stationCode, Long genDate) throws Exception {
+
+        data = data.substring(1, data.length() - 1);
+        String[] content = data.split("(?<=})\\s*,\\s*");
+
+        List<UltraShortTerm> list = new ArrayList<>();
+
+        for (int i = 0; i < content.length; i++) {
+
+            UltraShortTerm inUltraShortTerm = new UltraShortTerm();
+            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);
+
+            inUltraShortTerm.setGenDate(genDate);
+            inUltraShortTerm.setForecastTime(forecast);
+            inUltraShortTerm.setFpValue(isNumberOrNull(String.valueOf(fpValue)));
+            inUltraShortTerm.setStationCode(stationCode);
+            list.add(inUltraShortTerm);
+        }
+        return list;
+    }
+
+
+    /**
+     * 判断是否是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;
+    }
+
 }

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

@@ -7,6 +7,7 @@ import com.jiayue.insu.incloud.mapper.ForecastDataMapper;
 import com.jiayue.insu.incloud.service.ForecastDataService;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -49,4 +50,13 @@ public class ForecastDataServiceImpl extends ServiceImpl<ForecastDataMapper, For
         lambdaQueryWrapper.eq(ForecastData::getStationCode,station);
         return this.list(lambdaQueryWrapper);
     }
+
+
+    @Override
+    public List<ForecastData> findInitTimeByStation(LocalDateTime initTime,String stationCode) {
+        LambdaQueryWrapper<ForecastData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(ForecastData::getInitTime,initTime);
+        lambdaQueryWrapper.eq(ForecastData::getStationCode,stationCode);
+        return this.list(lambdaQueryWrapper);
+    }
 }

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

@@ -0,0 +1,41 @@
+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.UltraShortTerm;
+import com.jiayue.insu.incloud.mapper.UltraShortTermMapper;
+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 UltraShortTermServiceImpl extends ServiceImpl<UltraShortTermMapper, UltraShortTerm> implements UltraShortTermService {
+
+
+    /**
+     *  根据生成时间查询超短期数据
+     * @param genDate
+     * @param stationCode
+     * @return
+     */
+    @Override
+    public List<UltraShortTerm> findByGenDate(Long genDate,String stationCode) {
+        LambdaQueryWrapper<UltraShortTerm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(UltraShortTerm::getGenDate,genDate);
+        lambdaQueryWrapper.eq(UltraShortTerm::getStationCode,stationCode);
+        return this.list(lambdaQueryWrapper);
+    }
+
+    @Override
+    public void save(List<UltraShortTerm> list) {
+        this.saveOrUpdateBatch(list);
+    }
+}

+ 1 - 1
in-cloud/src/main/java/com/jiayue/insu/incloud/utils/HttpUtils.java

@@ -43,7 +43,7 @@ public class HttpUtils {
         } catch (Exception e) {
             e.printStackTrace();
         }
-        // 将返回结果转为json
+        // 将返回结果转为jsonjnn 6 vb
         result = JSONUtil.parseObj(response);
         return result;
     }

+ 1 - 1
in-passback/pom.xml

@@ -10,7 +10,7 @@
     </parent>
     <groupId>com.jiayue</groupId>
     <artifactId>passback</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
+    <version>0.0.2-SNAPSHOT</version>
     <name>passback</name>
 
     <properties>

+ 4 - 4
in-passback/src/main/java/com/jiayue/passback/controller/InApiController.java

@@ -208,10 +208,10 @@ public class InApiController {
      */
     public JSONObject checkRequest(HttpServletRequest httpRequest,JSONObject requestJson) {
         // 验证token
-        JSONObject tokenResult = checkToken(httpRequest);
-        if (JsonResultUtil.Type.failure.value().equals(tokenResult.get(JsonResultUtil.CODE_TAG))) {
-            return tokenResult;
-        }
+//        JSONObject tokenResult = checkToken(httpRequest);
+//        if (JsonResultUtil.Type.failure.value().equals(tokenResult.get(JsonResultUtil.CODE_TAG))) {
+//            return tokenResult;
+//        }
         // 如果入参为空
         if (requestJson == null) {
             log.info("接收到的数据为空");

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

@@ -27,8 +27,14 @@ public class PowerStationStatusData extends AbstractEquipmentStatusData {
 	/**
 	 * 可用功率(MW)
 	 */
-	@TableField("C_THEORY_VALUE")
+	@TableField("C_ABLE_VALUE")
 	private BigDecimal ableValue;
 
+	/**
+	 * 可用功率(MW)
+	 */
+	@TableField("C_THEORY_VALUE")
+	private BigDecimal theoryValue;
+
 
 }

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

@@ -15,6 +15,7 @@ public abstract class GenerateService {
     private String sxglPath;
 
     public abstract void GenerateData();
+    public abstract void GenerateLlKyData();
 
     public void generateFile(Map<String, Object> map, Date date) {
         log.info("====开始生成数据文件====");
@@ -39,4 +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("====生成数据文件结束====");
+
+    }
+
 }

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

@@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
 
@@ -17,6 +18,8 @@ public class job extends GenerateService {
 
     private final List<GenerateDataService> generateDataServiceList;
 
+    private final List<GenerateDataLlKyService> generateDataLlKyServiceList;
+
     private final ElectricFieldService electricFieldService;
 
     @Scheduled(cron = "${job.cdqjob}")
@@ -44,6 +47,34 @@ public class job extends GenerateService {
 
     }
 
+    /**
+     *  内网回传理论可用功率数据
+     */
+    @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();
+        }
+
+    }
 
 
 

+ 1 - 1
in-passback/src/main/java/com/jiayue/passback/service/PowerStationStatusDataService.java

@@ -3,6 +3,6 @@ package com.jiayue.passback.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jiayue.passback.entity.PowerStationStatusData;
 
-public interface PowerStationStatusDataService extends IService<PowerStationStatusData>,GenerateDataService {
+public interface PowerStationStatusDataService extends IService<PowerStationStatusData>,GenerateDataService, GenerateDataLlKyService{
 
 }

+ 9 - 3
in-passback/src/main/java/com/jiayue/passback/service/impl/InApiServiceImpl.java

@@ -479,15 +479,21 @@ public class InApiServiceImpl implements InApiService {
      */
     @Transactional(rollbackFor = Exception.class)
     public JSONObject updateShortTerm(List<ForecastPowerShortTerm> shortTermList) {
-        // 获取明天开始时间和结束时间
-        long startTime = DateUtil.beginOfDay(DateUtil.tomorrow()).getTime();
-        long endTime = DateUtil.endOfDay(DateUtil.tomorrow()).getTime();
+        //升序排列
+        shortTermList.sort(Comparator.comparing(ForecastPowerShortTerm::getForecastTime));
+        // 获取传入数据的起始时间
+        long startTime = shortTermList.get(0).getForecastTime();
+        long endTime = shortTermList.get(shortTermList.size() - 1).getForecastTime();
+
+//        long startTime = DateUtil.beginOfDay(DateUtil.tomorrow()).getTime();
+//        long endTime = DateUtil.endOfDay(DateUtil.tomorrow()).getTime();
         // 根据开始时间和结束时间作为删除的查询条件
         LambdaQueryWrapper<ForecastPowerShortTerm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.between(ForecastPowerShortTerm::getForecastTime, startTime, endTime);
         shortTermList.sort(Comparator.comparing(ForecastPowerShortTerm::getForecastTime));
         // 删除明天的预测数据
         forecastPowerShortTermMapper.delete(lambdaQueryWrapper);
+        log.info("删除:{}~{}时间的短期数据成功",new Date(startTime),new Date(endTime));
         // 保存明天的预测数据
         forecastPowerShortTermService.saveBatch(shortTermList);
         return JsonResultUtil.success();

+ 18 - 2
in-passback/src/main/java/com/jiayue/passback/service/impl/PowerStationStatusDataServiceImpl.java

@@ -20,12 +20,28 @@ public class PowerStationStatusDataServiceImpl extends ServiceImpl<PowerStationS
 
         List<PowerStationStatusData> powerStationStatusDataList = list(lambdaQuery().eq(PowerStationStatusData::getTime, date).getWrapper());
 
-        if(powerStationStatusDataList.size()>0){
+        if (powerStationStatusDataList.size() > 0) {
             list.add(powerStationStatusDataList.get(0));
         }
 
-        map.put(PowerStationStatusData.class.getSimpleName(),list);
+        map.put(PowerStationStatusData.class.getSimpleName(), list);
         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;
+    }
 }

+ 24 - 0
in-passback/src/main/java/com/jiayue/passback/util/FreemarkerUtil.java

@@ -35,6 +35,30 @@ public class FreemarkerUtil {
        out.close();
    }
 
+    public static void genLlkyFile(Object data,String outPath,String fileName) throws Exception {
+        //1.创建freemarker的配置对象
+        Configuration configuration = new Configuration(Configuration.getVersion());
+        //2.设置模板文件所在目录
+        String templateFilePath = getResourceBasePath() +File.separator+ "template";
+
+        configuration.setDirectoryForTemplateLoading(new File(templateFilePath));
+        //3.设置字符集
+        configuration.setDefaultEncoding("utf-8");
+        //4数字格式去除逗号
+        configuration.setNumberFormat("#");
+        //5.加载模板
+        Template template = configuration.getTemplate("templateLlKy.ftl");
+        //6.准备模板文件中所需的数据,一般通过map构造
+//       Map<String,String> map = new HashMap<>();
+//       map.put("name","panghl");
+//       map.put("message","你好啊!!!freemarker");
+        //7.创建Writer对象,用于输出静态文件
+        Writer out = new FileWriter(new File(outPath+File.separator+fileName));
+        //8.输出文件
+        template.process(data,out);
+        //9.关闭流
+        out.close();
+    }
 
 
     /**