Browse Source

增加请求林洋修正短期 上送是minio

fanxiaoyu 5 tháng trước cách đây
mục cha
commit
1e03e06136

+ 61 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/entity/ForecastDataLx.java

@@ -0,0 +1,61 @@
+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_forecast_data_lx")
+@Data
+public class ForecastDataLx {
+    /**
+     * Id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    //场站编号
+    private String stationCode;
+
+    //公司信息
+    private String inCode;
+
+    //上送时间
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime uploadTime;
+
+    //修正时间
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime correctTime;
+
+    //预测时间
+    private Long forecastTime;
+
+    //预测功率
+    private BigDecimal fpValue;
+    private BigDecimal fpValueCorrect;
+
+    // 生成日期
+    private String genDate;
+
+    // 预测日期
+    private String forecastDate;
+}

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

@@ -0,0 +1,58 @@
+package com.jiayue.insu.incloud.job.data.pull;
+
+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.pulldata.PullCorrectDataForLx;
+import com.jiayue.insu.incloud.service.RecordService;
+import com.jiayue.insu.incloud.service.StationService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDateTime;
+
+/**
+ * 飔合科技 拉取修正数据定时任务
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Slf4j
+public class LxPullCorrectDataJob implements Job {
+
+    @Autowired
+    private PullCorrectDataForLx pullCorrectDataForLx;
+    @Autowired
+    private StationService stationService;
+    @Autowired
+    private RecordService recordService;
+
+    @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) {
+            //查询是否有今天成功记录 (为提高稳定性,该定时任务采取在规定时间段内 重复循环执行的定时策略,故:需要查询是否存在成功记录)
+            Record successRecord = recordService.findTimeAndTypeAndStateAndStation(
+                    LocalDateTimeUtil.beginOfDay(LocalDateTime.now()),
+                    CommonStant.RECORD_TYPE_PULL_CORRECT,
+                    StatusEnum.SUCCESS.getSign(), station.getStationCode());
+
+            // 没有成功记录进行请求业务
+            if (successRecord == null){
+                pullCorrectDataForLx.pullDQData(station);
+            }
+
+        }else{
+            log.error("========== 一体化定时任务异常:  场站信息为空  {}==========",code);
+        }
+    }
+}

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

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

+ 30 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/pulldata/IPullInitCorrectDataForLx.java

@@ -0,0 +1,30 @@
+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 IPullInitCorrectDataForLx {
+
+    /**
+     * 推送短期预测原始数据
+     * @return 是否成功
+     */
+    Boolean pullDQAndNWPData(Station station);
+
+    /**
+     * 推送短期预测原始数据
+     * @return 是否成功
+     */
+    Boolean pullDQData(Station station);
+    /**
+     * 推送NWP预测原始数据
+     * @return 是否成功
+     */
+    Boolean pullNWPData(Station station);
+}

+ 476 - 0
in-cloud/src/main/java/com/jiayue/insu/incloud/pulldata/PullCorrectDataForLx.java

@@ -0,0 +1,476 @@
+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.http.HttpUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+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.entity.*;
+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.JsonResultUtil;
+import com.jiayue.insu.incloud.utils.SystermUtils;
+import com.jiayue.insu.minio.util.MinioUtilService;
+import lombok.Data;
+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 PullCorrectDataForLx 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;
+
+    @Value("${minio.pushCorrFileUrl}")
+    private String pushCorrFileUrl;
+
+//    @Value("${minio.pull.cloudFileCreateLog}")
+//    private String cloudFileCreateLog;
+
+    /**
+     * 拉取修正预测数据并生成文件上送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_LX);
+//        String dataPullUrl = integrationCompany.getPullUrl();
+        String dataPullUrl = "http://112.2.27.84:4220/changeData";
+
+        boolean result = false;
+        boolean isUpload = false;
+        String response;
+        List<ForecastData> list = new ArrayList<>();
+        try {
+            DateTime dateTime = DateUtil.parse(DateUtil.today());
+            String day = dateTime.toString("yyyyMMdd");
+            StringBuilder queryString = new StringBuilder();
+            queryString.append("stationId=").append(station.getStationCode());
+            queryString.append("&version=").append(day);
+            queryString.append("&type=").append("E1".equals(station.getType()) ? 2 : 1);
+            String url = "http://112.2.27.84:4220/forecast/changeData?" + queryString.toString();
+            // 发送请求
+            HttpRequest httpRequest = HttpRequest.get(url)
+                    .header("Content-Type", "application/json");
+            httpRequest.setGlobalTimeout(20000);
+            response = httpRequest.execute().body();
+
+            if (StrUtil.isNotEmpty(response)) {
+                boolean isJson = JSONUtil.isJsonObj(response);
+                if (isJson) {
+                    LxCorrectResponse lxCorrectResponse = JSONUtil.toBean(response, LxCorrectResponse.class);
+                    String code = lxCorrectResponse.getCode();
+                    if (code.equals("200")) {
+                        List<ForecastData> aList = new ArrayList<>();
+                        long startTime = DateUtil.beginOfDay(DateUtil.tomorrow()).getTime();
+                        long endTime = startTime + 10 * 24 * 3600 * 1000L - 1;
+                        aList = forecastDataService.findTimeByStation(station.getStationCode(), startTime, endTime);
+                        log.info(station.getStationCode() + " 请求短期修正数据返回内容:{}", response);
+                        try {
+                            list = correctWindData(response.toString(), station);
+
+                            BigDecimal checkCount = new BigDecimal(960);
+                            if (list.size() < checkCount.intValue()) {
+//                            if (false) {
+                                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()));
+                            boolean b = forecastDataService.saveOrUpdateBatch(aList);
+                            if (b) {
+                                File file = genFile(station);
+                                if (file != null) {
+                                    String pushDate = DateUtil.format(new Date(), "yyyyMMdd");
+                                    boolean flag = minioUtilService.bucketExists(bucketName);
+                                    if (flag) {
+                                        InputStream in = new FileInputStream(file);
+                                        String fileName = "/" + station.getStationCode() + "/" + file.getName();
+                                        String minIoFileUrl = minioUtilService.putObject(bucketName, fileName, in);
+                                        // 如果文件放成功,回传文件生成信息到云端
+//                                        postFileCreateInfoToCloud(station.getStationCode(), file.getName(), minIoFileUrl);
+                                        pushCorr(station, file.getName(), pushDate, minIoFileUrl);
+                                    }
+
+                                }
+                            }
+                        }
+                    } 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, Station station) throws Exception {
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        List<ForecastData> list = new ArrayList<>();
+
+        JSONObject jsonObject = new JSONObject(data);
+
+        // 获取data数组
+        JSONArray dataArray = jsonObject.getJSONArray("data");
+
+        // 遍历data数组并获取每个对象的值
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject dataObject = dataArray.getJSONObject(i);
+            // 获取具体的值
+//            String date = dateFormat.format(DateUtil.parse(dataObject.getStr("date")));
+            String date = dateFormat.format(DateUtil.parse(dataObject.getStr("date")));
+            String time = dataObject.getStr("time");
+            double value = dataObject.getDouble("value");
+            String stationId = dataObject.getStr("stationId");
+//            String version = dataObject.getStr("version");
+
+
+            Long forecastTime = simpleDateFormat.parse(date + " " + time + ":00").getTime();
+            ForecastData forecastData = new ForecastData();
+            forecastData.setCorrectTime(LocalDateTime.now());
+            forecastData.setFpValueCorrect(new BigDecimal(value));
+            forecastData.setStationCode(station.getStationCode());
+            forecastData.setForecastTime(forecastTime);
+            forecastData.setInCode(station.getInCode());
+            list.add(forecastData);
+        }
+        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.getFpValueCorrect() == null ? a.getFpValue() : a.getFpValueCorrect());
+                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;
+    }
+
+
+    /**
+     * 光伏数据解析
+     *
+     * @param data 待解析数据
+     * @return
+     * @throws Exception
+     */
+    public List<ForecastData> correctPhotovoltaicData(String data) throws Exception {
+
+        String[] content = data.split("\n");
+
+        List<ForecastData> list = new ArrayList<>();
+
+        for (int i = 3; i < content.length - 1; i++) {
+
+            ForecastData inForecastPowerShortTerm = new ForecastData();
+            String column = content[i];
+            String[] datas = column.split(CommonStant.SPACE1_CONSTANT);
+            inForecastPowerShortTerm.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").getTime());
+
+
+            inForecastPowerShortTerm.setFpValueCorrect(isNumberOrNull(datas[3]));
+
+            inForecastPowerShortTerm.setSwrCorrect(isNumberOrNull(datas[4]));
+
+            inForecastPowerShortTerm.setDirectRadiationCorrect(isNumberOrNull(datas[5]));
+
+            inForecastPowerShortTerm.setDiffuseRadiationCorrect(isNumberOrNull(datas[6]));
+
+            inForecastPowerShortTerm.setTemperatureCorrect(isNumberOrNull(datas[7]));
+
+            inForecastPowerShortTerm.setHumidityCorrect(isNumberOrNull(datas[8]));
+
+            inForecastPowerShortTerm.setPressureCorrect(isNumberOrNull(datas[9]));
+
+            inForecastPowerShortTerm.setWindSpeedCorrect(isNumberOrNull(datas[10]));
+
+            inForecastPowerShortTerm.setWindDirCorrect(isNumberOrNull(datas[11]));
+
+            inForecastPowerShortTerm.setCorrectTime(LocalDateTime.now());
+
+
+            list.add(inForecastPowerShortTerm);
+        }
+
+        return list;
+
+    }
+
+
+//    /**
+//     * 上传文件
+//     *
+//     * @return
+//     */
+//    public void postFileCreateInfoToCloud(String stationCode, String fileName, String fileDownloadUrl) {
+//        fileDownloadUrl = fileDownloadUrl.split("\\?")[0];
+//        Map<String, Object> urlMap = new HashMap<>();
+//        urlMap.put("stationCode", stationCode);
+//        urlMap.put("stationName", stationCode);
+//        urlMap.put("fileName", fileName);
+//        urlMap.put("fileDownloadUrl", fileDownloadUrl);
+//        urlMap.put("sign", SystermUtils.caluMd5Sign(stationCode + DateUtil.today()));
+//        try {
+//            String body = HttpUtil.post(cloudFileCreateLog, urlMap, 10000);
+//            JSONObject result = JSONUtil.parseObj(body);
+//            if (!"0".equals(result.getStr(JsonResultUtil.CODE_TAG))) {
+//                log.info("请求V3云平台失败");
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            log.info("请求V3云平台失败");
+//        }
+//    }
+
+
+    /**
+     * @param station
+     * @param fileName
+     * @param url
+     */
+    public void pushCorr(Station station, String fileName, String pushDate, String url) {
+        // 如果场站信息为空或者 不推送修正数据
+        if (station == null || "0".equals(station.getIsPushCorr())) {
+            return;
+        }
+        Map params = new HashMap(5);
+        params.put("stationCode", station.getStationCode());
+        params.put("forecastDay", pushDate);
+        params.put("forecastFileName", fileName);
+        String fileDownloadUrl = url.split("\\?")[0];
+        params.put("fileDownloadPath", fileDownloadUrl);
+        params.put("remark", "数源:一体化修正");
+        log.info("发送下发修正文件请求");
+        String repose = HttpUtil.post(pushCorrFileUrl, params, 10000);
+        log.info("发送下发修正文件请求,请求响应 {}", repose);
+    }
+
+    @Data
+    public class LxCorrectResponse {
+
+        private String code;
+
+        private String message;
+
+        private String data;
+    }
+
+
+}

+ 156 - 5
in-cloud/src/main/java/com/jiayue/insu/incloud/pushdata/PushDataForLX.java

@@ -10,9 +10,11 @@ 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.ForecastDataLx;
 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.ForecastDataLxService;
 import com.jiayue.insu.incloud.service.IntegrationCompanyService;
 import com.jiayue.insu.incloud.service.RecordService;
 import lombok.extern.slf4j.Slf4j;
@@ -22,10 +24,16 @@ import org.springframework.stereotype.Component;
 
 import java.io.File;
 import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 /**
@@ -44,6 +52,8 @@ public class PushDataForLX implements IPushInitForecastData {
     private IntegrationCompanyService integrationCompanyService;
     @Autowired
     BJZYYJYSDComPermisson bjzyyjysdComPermisson;
+    @Autowired
+    private ForecastDataLxService forecastDataLxService;
 
     @Value("${localFilePath.lxFilePath}")
     String lxFilePath;
@@ -115,10 +125,20 @@ public class PushDataForLX implements IPushInitForecastData {
         List<String> originalContents = fileReader.readLines();
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
+        String genDate = dateFormat.format(new Date());
+
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
         List<Double> dataList = new ArrayList<>();
 
         StringBuilder content = new StringBuilder();
-        content = content.append(stationCode + "-dq|"+dateFormat.format(new Date(System.currentTimeMillis()+24*60*60*1000L))+"|");
+        content = content.append(stationCode + "-dq|" + dateFormat.format(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000L)) + "|");
+
+        List<ForecastDataLx> forecastDataLxList = new ArrayList<>();
+
+        List<ForecastDataLx> complementList = new ArrayList<>();
+
+        List<ForecastDataLx> goOnList = new ArrayList<>();
 
         int i = 0;
         // 循环解析原始短期文件
@@ -134,19 +154,106 @@ public class PushDataForLX implements IPushInitForecastData {
                 }
                 // 上送三天数据
                 try {
-                    if (95 < i && i < 1056){
-                        content.append(Double.valueOf(originalContentArr[3])).append("|");
-                        dataList.add(Double.valueOf(originalContentArr[3]));
+                    if ("J00797".equals(stationCode) || "J00637".equals(stationCode)) {
+                        if (95 < i && i < 1248) {
+                            content.append(Double.valueOf(originalContentArr[3])).append("|");
+                            ForecastDataLx forecastDataLx = new ForecastDataLx();
+                            forecastDataLx.setGenDate(genDate);
+                            forecastDataLx.setFpValue(new BigDecimal(originalContentArr[3]));
+                            forecastDataLx.setForecastTime(format.parse(originalContentArr[2]).getTime());
+                            forecastDataLx.setStationCode(stationCode);
+                            forecastDataLx.setInCode(station.getInCode());
+                            // 预测日期yyyy-MM-dd
+                            forecastDataLx.setForecastDate(dateFormat.format(new Date(forecastDataLx.getForecastTime())));
+                            forecastDataLxList.add(forecastDataLx);
+                            dataList.add(Double.valueOf(originalContentArr[3]));
+                        }
+                    } else {
+                        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++;
             }
+        }
+
+        if ("J00797".equals(stationCode) || "J00637".equals(stationCode)) {
+            // 一次补数
+            forecastDataLxList.stream().sorted(Comparator.comparing(ForecastDataLx::getForecastTime)).collect(Collectors.toList());
 
+            AtomicReference<String> changeForecastDate = new AtomicReference<>(addOneDay(forecastDataLxList.get(forecastDataLxList.size() - 1).getForecastDate()));
+            // 分组
+            Map<String, List<ForecastDataLx>> groupedByForecastDate = forecastDataLxList.stream()
+                    .collect(Collectors.groupingBy(ForecastDataLx::getForecastDate));
+            groupedByForecastDate.forEach((date, list) -> {
+                String[] result = changeForecastDate.get().split("--");
+                String genDateSpilt = result[0];
+
+                Long forecastSpit = Long.valueOf(result[1]);
+                AtomicInteger flag = new AtomicInteger();
+                BigDecimal random = new BigDecimal(getRandom());
+                list.forEach(forecastData -> {
+                    ForecastDataLx forecastDataLx = new ForecastDataLx();
+                    forecastDataLx.setFpValue(forecastData.getFpValue().multiply(random).setScale(2, RoundingMode.HALF_DOWN));
+                    forecastDataLx.setForecastDate(genDateSpilt);
+                    Long forecast = forecastSpit + flag.get() * 15 * 60 * 1000L;
+                    forecastDataLx.setForecastTime(forecast);
+                    forecastDataLx.setStationCode(stationCode);
+                    forecastDataLx.setInCode(station.getInCode());
+                    flag.getAndIncrement();
+                    complementList.add(forecastDataLx);
+                });
+                changeForecastDate.set(addOneDay(genDateSpilt));
+
+            });
+
+            // 二次补数
+            complementList.stream().sorted(Comparator.comparing(ForecastDataLx::getForecastTime)).collect(Collectors.toList());
+
+            AtomicReference<String> changeComplementDate = new AtomicReference<>(addOneDay(complementList.get(complementList.size() - 1).getForecastDate()));
+            // 分组
+            Map<String, List<ForecastDataLx>> groupedByComplement = complementList.stream()
+                    .collect(Collectors.groupingBy(ForecastDataLx::getForecastDate));
+            final int[] a = {0};
+            groupedByComplement.forEach((date, list) -> {
+                String[] result = changeComplementDate.get().split("--");
+                String genDateSpilt = result[0];
+
+                Long forecastSpit = Long.valueOf(result[1]);
+                BigDecimal random = new BigDecimal(getRandom());
+                if (a[0] <= 5) {
+                    AtomicInteger flag = new AtomicInteger();
+                    list.forEach(forecastData -> {
+                        ForecastDataLx forecastDataLx = new ForecastDataLx();
+                        forecastDataLx.setFpValue(forecastData.getFpValue().multiply(random).setScale(2, RoundingMode.HALF_DOWN));
+                        forecastDataLx.setForecastDate(genDateSpilt);
+                        Long forecast = forecastSpit + flag.get() * 15 * 60 * 1000L;
+                        forecastDataLx.setForecastTime(forecast);
+                        forecastDataLx.setStationCode(stationCode);
+                        forecastDataLx.setInCode(station.getInCode());
+                        flag.getAndIncrement();
+                        goOnList.add(forecastDataLx);
+                    });
+                }
+                changeComplementDate.set(addOneDay(genDateSpilt));
+                a[0]++;
+            });
+            complementList.addAll(goOnList);
+
+            complementList.stream().sorted(Comparator.comparing(ForecastDataLx::getForecastTime)).collect(Collectors.toList());
+            for (ForecastDataLx forecastDataLx : complementList) {
+                content.append(forecastDataLx.getFpValue().doubleValue()).append("|");
+            }
+            forecastDataLxList.addAll(complementList);
         }
+
         String body = content.toString();
         List<String> stringList = new ArrayList<>();
         stringList.add(body);
@@ -161,17 +268,19 @@ public class PushDataForLX implements IPushInitForecastData {
         try {
             String response;
             HttpRequest httpRequest = HttpRequest.post("http://112.2.27.84:4220/forecast/reportData")
+//            HttpRequest httpRequest = HttpRequest.post("http://112.2.27.4/forecast")
                     .header("Content-Type", "application/json");
             httpRequest.setGlobalTimeout(20000);
             response = httpRequest.body(jsonString).execute().body();
 
-            ResponseLXVo responseLXVo= JSONUtil.toBean(response, ResponseLXVo.class);
+            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);
+                forecastDataLxService.saveBatch(forecastDataLxList);
                 return true;
             } else {
                 log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因:{} ==========", integrationCompany.getName(), station.getStationCode(), responseLXVo.getCode(), responseLXVo.getMessage());
@@ -192,4 +301,46 @@ public class PushDataForLX implements IPushInitForecastData {
         return null;
     }
 
+    public String addOneDay(String lastForecastDateStr) {
+        // 定义日期格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+        // 将字符串解析为 LocalDate
+        LocalDate lastForecastDate = LocalDate.parse(lastForecastDateStr, formatter);
+
+        // 加一天
+        LocalDate nextForecastDate = lastForecastDate.plusDays(1);
+
+        // 格式化为字符串
+        String changeGenDate = nextForecastDate.format(formatter);
+
+        String dateTime = changeGenDate + " 00:00:00";
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long forecast = 0L;
+        try {
+            forecast = simpleDateFormat.parse(dateTime).getTime();
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        return changeGenDate + "--" + forecast;
+    }
+
+    /**
+     *  生成0.9~1.1之间不包括1的随机数
+     * @return
+     */
+    public Double getRandom(){
+        double decision = Math.random();
+
+        double randomNumber;
+        if (decision < 0.1) {
+
+            randomNumber = 0.9 + (Math.random() * 0.2);
+        } else {
+            randomNumber = 0.9 + (Math.random() * 0.1);
+        }
+        return randomNumber;
+    }
 }

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

@@ -0,0 +1,15 @@
+package com.jiayue.insu.incloud.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jiayue.insu.incloud.entity.ForecastDataLx;
+
+/**
+ * 预测数据业务接口(林祥)
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+public interface ForecastDataLxService extends IService<ForecastDataLx> {
+
+}

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

@@ -0,0 +1,21 @@
+package com.jiayue.insu.incloud.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jiayue.insu.incloud.entity.ForecastDataLx;
+import com.jiayue.insu.incloud.mapper.ForecastDataLxMapper;
+import com.jiayue.insu.incloud.service.ForecastDataLxService;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * 预测数据业务实现
+ *
+ * @author yh
+ * @version 1.0
+ * @since 2022/5/22 11:29
+ */
+@Service
+public class ForecastDataLxServiceImpl extends ServiceImpl<ForecastDataLxMapper, ForecastDataLx> implements ForecastDataLxService {
+
+
+}