package com.jiayue.passback.service.impl; import cn.hutool.core.date.DateUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.jiayue.passback.constants.CommonStant; import com.jiayue.passback.entity.ForecastPowerShortTerm; import com.jiayue.passback.entity.ForecastPowerUltraShortTerm; import com.jiayue.passback.entity.SysParameter; import com.jiayue.passback.entity.UploadFileLog; import com.jiayue.passback.entity.eunm.PredictionModelEnum; import com.jiayue.passback.mapper.ForecastPowerShortTermMapper; import com.jiayue.passback.mapper.ForecastPowerUltraShortTermMapper; import com.jiayue.passback.mapper.SystemParameterMapper; import com.jiayue.passback.mapper.UploadFileLogMapper; import com.jiayue.passback.service.ForecastPowerShortTermService; import com.jiayue.passback.service.ForecastPowerUltraShortTermService; import com.jiayue.passback.service.InApiService; import com.jiayue.passback.service.UploadFileLogService; import com.jiayue.passback.util.CacheUtil; import com.jiayue.passback.util.JsonResultUtil; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.extern.slf4j.Slf4j; import net.jodah.expiringmap.ExpirationPolicy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.DigestUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; /** * 预测数据业务实现 * * @author yh * @version 1.0 * @since 2022/5/22 11:29 */ @Slf4j @Service public class InApiServiceImpl implements InApiService { @Resource private SystemParameterMapper systemParameterMapper; @Resource private ForecastPowerShortTermMapper forecastPowerShortTermMapper; @Resource private ForecastPowerShortTermService forecastPowerShortTermService; @Resource private ForecastPowerUltraShortTermMapper forecastPowerUltraShortTermMapper; @Resource private ForecastPowerUltraShortTermService forecastPowerUltraShortTermService; @Resource private UploadFileLogService uploadFileLogService; /** * 获取token * * @param userInfo * @return */ @Override public JSONObject getToken(JSONObject userInfo) { CacheUtil.cacheMap.entrySet().forEach(entry -> log.info("==========user:" + entry.getKey() + "token" + entry.getValue() + "==========")); JSONObject result; //获取用户名密码 String requestUserName = userInfo.getStr(CommonStant.REQUEST_USER_NAME); String requestUserPass = userInfo.getStr(CommonStant.REQUEST_USER_PASS); // 设置参数 QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("C_SYS_KEY", "TOKEN_USER"); SysParameter systemParameter = systemParameterMapper.selectOne(wrapper); if (systemParameter == null || systemParameter.getSysValue() == null || "".equals(systemParameter.getSysValue()) || systemParameter.getSysValue().split(CommonStant.CHARACTER_COLON).length != 2) { log.error("系统参数TOKEN_USER不正常"); return JsonResultUtil.failureDesc("系统参数TOKEN_USER不正常"); } String tokenUser = systemParameter.getSysValue(); // 根据用户名获取密码 String userName = tokenUser.split(CommonStant.CHARACTER_COLON)[0]; String userPassWord = tokenUser.split(CommonStant.CHARACTER_COLON)[1]; // 加密后的密码 String passwordMD5t = DigestUtils.md5DigestAsHex(userPassWord.getBytes()).toUpperCase(); // 如果用户名或密码不匹配 if (!requestUserName.equals(userName) || !requestUserPass.equals(passwordMD5t)) { log.error("账户密码不匹配"); return JsonResultUtil.failureDesc("账户密码不匹配"); } // 根据用户名去缓存中获取token,如果token已存在,则返回token,如果token不存在,则创建新token并返回 // 根据用户名获取token String token = CacheUtil.cacheMap.get(userName); // 如果token不存在,则生成token if (token == null || "".equals(token) || "null".equals(token)) { // 生成token JwtBuilder builder = Jwts.builder() .setSubject(requestUserName) //用于设置签发时间 .setIssuedAt(new Date()) //用于设置签名秘钥 .signWith(SignatureAlgorithm.HS256, requestUserPass); // 获取token result = JsonResultUtil.success(); token = builder.compact(); result.set(CommonStant.TOKEN, token); // 将生成的token放入缓存中 CacheUtil.cacheMap.put(userName, token, ExpirationPolicy.CREATED, 1440, TimeUnit.MINUTES); CacheUtil.cacheMap.entrySet().forEach(entry -> log.info("==========user:" + entry.getKey() + "token" + entry.getValue() + "==========")); } else { // 将缓存中查到的token返回 result = JsonResultUtil.success(); result.set(CommonStant.TOKEN, token); } // 返回结果 return result; } /** * 获取短期数据并返回json格式 * * @param requestJson * @return */ @Override public JSONObject getShortWpfData(JSONObject requestJson) { // 获取场站id String stationCode = requestJson.getStr("wfId"); String startTime = requestJson.getStr("beginDate"); String endTime = requestJson.getStr("endDate"); SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); try { long startTimeL = sdfDate.parse(startTime).getTime(); long oneDay = 24 * 60 * 60 * 1000 - 1000; long endTimeL = sdfDate.parse(endTime).getTime() + oneDay; // 获取明日短期预测数据 List shortList = getShortArr(startTimeL, endTimeL); //解析短期文件 JSONObject result = fileAnalysis(stationCode, shortList, null, "dq", requestJson.getStr("beginDate"), requestJson.getStr("endDate")); return result; } catch (ParseException e) { log.error(String.valueOf(e)); return JsonResultUtil.failure("获取超短期数据失败"); } } /** * 接收修正短期数据 * * @param requestJson * @return */ @Override @Transactional(rollbackFor = Exception.class) public JSONObject putShortWpfData(JSONObject requestJson) { // 功率json JSONObject values = JSONUtil.parseObj(requestJson.getJSONArray("values").get(0)); if (values == null || values.getJSONArray("datas").size() == 0) { return JsonResultUtil.failureDesc("修正短期数据为空"); } // 明日修正后数据Arr JSONArray datas = values.getJSONArray("datas"); // 将修正后的明日的一体化数据数据转化为List List dqList = getDqListMap(datas); if (dqList == null || dqList.size() == 0 || dqList.size() > 96) { log.error("修正数据大于96条"); return JsonResultUtil.failureDesc("修正数据大于96条"); } // 更新 updateShortTerm(dqList); return JsonResultUtil.success(); } /** * 获取超短期文件并解析返回json格式 * * @param requestJson * @return */ @Override public JSONObject getSShortWpfData(JSONObject requestJson) { String stationCode = requestJson.getStr("wfId"); List ultraShortList = getUltraShortArr(requestJson.getStr("beginDate"), requestJson.getStr("endDate")); //解析短期文件 JSONObject result = fileAnalysis(stationCode, null, ultraShortList, "cdq", requestJson.getStr("beginDate"), requestJson.getStr("endDate")); return result; } /** * 接收修正超短期数据 * * @param requestJson * @return */ @Transactional(rollbackFor = Exception.class) @Override public JSONObject putSShortWpfData(JSONObject requestJson) { // 功率json JSONObject values = JSONUtil.parseObj(requestJson.getJSONArray("values").get(0)); // 所有日期的数据Arr JSONArray datas = values.getJSONArray("datas"); if (datas.size() == 0) { return JsonResultUtil.failureDesc("修正超短期数据为空"); } // 将json数据转化为ListMap List cdqListMap = getCdqListMap(datas); // 更新 updateUltraShortTerm(cdqListMap); return JsonResultUtil.success(); } /** * 获取上报文件 * * @param requestJson * @return */ @Override public JSONObject getUploadState(JSONObject requestJson) { String wfId = requestJson.getStr("wfId"); // 山东短期文件类型 String dqArr[] = {"E131", "E132"}; // 山东超短期文件类型 String cdqArr[] = {"E133"}; // 获取最新短期上报文件状态 UploadFileLog uploadFileLogDq = uploadFileLogService.getNewDateByType(dqArr); // 获取最新超短期上报文件状态 UploadFileLog uploadFileLogCdq = uploadFileLogService.getNewDateByType(cdqArr); // 拼接json JSONArray resultArr = new JSONArray(); JSONObject uploadStateJson = new JSONObject(); String dqFileName = ""; String cdqFileName = ""; int dqFileStatus = 0; int cdqFileStatus = 0; if (uploadFileLogDq != null) { dqFileName = uploadFileLogDq.getFileName(); // 如果是E2 则是上报成功,则设置为1,否则为0 dqFileStatus = ("E2".equals(uploadFileLogDq.getFileStatusEnum()) ? 1 : 0); } if (uploadFileLogCdq != null) { cdqFileName = uploadFileLogCdq.getFileName(); // 如果是E2 则是上报成功,则设置为1,否则为0 cdqFileStatus = ("E2".equals(uploadFileLogCdq.getFileStatusEnum()) ? 1 : 0); } uploadStateJson.set("spfupfilename", dqFileName); uploadStateJson.set("spfupstate", dqFileStatus); uploadStateJson.set("sspfupfilename", cdqFileName); uploadStateJson.set("sspfupstate", cdqFileStatus); uploadStateJson.set("wfId", wfId); resultArr.add(uploadStateJson); return JsonResultUtil.success(resultArr); } /** * 解析预测数据并返回规定格式的json * * @param startDate * @param endDate * @return */ public JSONObject fileAnalysis(String stationCode, List shortList, List ultraShortList, String type, String startDate, String endDate) { JSONArray resultArr = new JSONArray(); boolean jx = true; String compareDate = ""; // 获取短期文件生成日期 String recDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()); // 获取当前时间 // 如果当前时间>=13点,则为pm(下午),否则为上午 LocalDateTime now = LocalDateTime.now(); int nowHour = now.getHour(); String version = "AM"; if (nowHour >= 13) { version = "PM"; } // 超短期起始时间 String cdqFileStartTime; try { // 日数据 JSONObject dayInfoJson = new JSONObject(); //一天中的96条数据信息 JSONArray valuesArr = new JSONArray(); JSONObject oneJson; JSONArray datas = new JSONArray(); SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 如果是短期 if ("dq".equals(type)) { if (shortList == null || shortList.size() == 0) { log.error("短期实时数据为空"); return JsonResultUtil.failureDesc("短期实时数据为空"); } for (int i = 0; i < shortList.size(); i++) { ForecastPowerShortTerm shortTerm = shortList.get(i); //当条的日期 String thisDate = sdfDate.format(new Date(shortTerm.getForecastTime())); // 如果当条的日期和上调日期不一致,新建dayInfoJson(日数据json) if (!thisDate.equals(compareDate)) { // 如果不是第一条,且和上一条日期不是同一天,则将上条日期的96条数据放入日json数据 if (!"".equals(compareDate)) { dayInfoJson.set("datas", datas); valuesArr.add(dayInfoJson); datas = new JSONArray(); } // 将当条日期放入compareDate compareDate = thisDate; // 新建日json数据 dayInfoJson = new JSONObject(); dayInfoJson.set("version", version); dayInfoJson.set("date", thisDate); dayInfoJson.set("recDate", recDate); } // 每一条数据的json,放入预测数据和预测时间 oneJson = new JSONObject(); oneJson.set("data", shortTerm.getFpValue().multiply(new BigDecimal("1000"))); oneJson.set("time", sdfDateTime.format(shortTerm.getForecastTime())); // 将一每条数据放入datas(一天的json)中 datas.add(oneJson); } // 将最后一日数据放入valuesArr dayInfoJson.set("datas", datas); valuesArr.add(dayInfoJson); // 将短期预测数据放入powerJson中 JSONObject powerJson = new JSONObject(); powerJson.set("values", valuesArr); powerJson.set("wfId", stationCode); powerJson.set("type", "power"); //返回短期数据JSONArray resultArr.add(powerJson); } else if ("cdq".equals(type)) { if (ultraShortList == null || ultraShortList.size() == 0) { log.error("超短期实时数据为空"); return JsonResultUtil.failureDesc("超短期实时数据为空"); } cdqFileStartTime = sdfDateTime.format(ultraShortList.get(0).getForecastTime()); datas = new JSONArray(); dayInfoJson = new JSONObject(); dayInfoJson.set("date", cdqFileStartTime); for (int i = 0; i < ultraShortList.size(); i++) { ForecastPowerUltraShortTerm ultraShortTerm = ultraShortList.get(i); // 每一条数据的json,放入预测数据和预测时间 oneJson = new JSONObject(); oneJson.set("time", sdfDateTime.format(ultraShortTerm.getForecastTime())); oneJson.set("data", ultraShortTerm.getFpValue().multiply(new BigDecimal("1000"))); // 将一每条数据放入datas(一天的json)中 datas.add(oneJson); } // 将最后一日数据放入vaulesArr dayInfoJson.set("datas", datas); valuesArr.add(dayInfoJson); // 将短期预测数据放入powerJson中 JSONObject powerJson = new JSONObject(); powerJson.set("wfId", stationCode); powerJson.set("values", valuesArr); powerJson.set("type", "power"); //返回短期数据JSONArray resultArr.add(powerJson); } } catch (Exception e) { log.error(stationCode + " 解析当天DQ数据错误:", e); return JsonResultUtil.failureDesc("解析当天DQ数据错误"); } //如果解析成功 return JsonResultUtil.success(resultArr); } /** * 将修正后的短期数据转为list * * @param dqDate * @return */ public List getDqListMap(JSONArray dqDate) { // 短期预测数据 List shortTermList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); Date now = new Date(); try { // 循环短期数据 for (int i = 0; i < dqDate.size(); i++) { JSONObject oneJson = dqDate.getJSONObject(i); ForecastPowerShortTerm forecastPowerShortTerm = new ForecastPowerShortTerm(); // 初始化短期数据实体 forecastPowerShortTerm.setPredictionModelEnum(PredictionModelEnum.E11); forecastPowerShortTerm.setForecastTime(sdf.parse(oneJson.getStr("time")).getTime()); forecastPowerShortTerm.setGenDate(now); forecastPowerShortTerm.setFpValue(new BigDecimal(oneJson.getStr("data")).divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP)); shortTermList.add(forecastPowerShortTerm); } } catch (ParseException e) { e.printStackTrace(); } return shortTermList; } /** * 将修正后的超短期数据转为list * * @param dqDate * @return */ public List getCdqListMap(JSONArray dqDate) { Date now = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); List ultraShortTermList = new ArrayList<>(); try { for (int i = 0; i < dqDate.size(); i++) { JSONObject oneJson = dqDate.getJSONObject(i); ForecastPowerUltraShortTerm forecastPowerUltraShortTerm = new ForecastPowerUltraShortTerm(); // 初始化短期数据实体 forecastPowerUltraShortTerm.setGenDate(now); forecastPowerUltraShortTerm.setForecastTime(sdf.parse(oneJson.getStr("time")).getTime()); forecastPowerUltraShortTerm.setFpValue(new BigDecimal(oneJson.getStr("data")).divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP)); forecastPowerUltraShortTerm.setPredictionModelEnum(PredictionModelEnum.E11); ultraShortTermList.add(forecastPowerUltraShortTerm); } } catch (ParseException e) { e.printStackTrace(); } return ultraShortTermList; } /** * 获取短期预测数据 * * @return */ public List getShortArr(long startTime, long endTime) { // 获取短期预测数据 LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.between(ForecastPowerShortTerm::getForecastTime, startTime, endTime); List shortList = forecastPowerShortTermMapper.selectList(lambdaQueryWrapper); shortList.sort(Comparator.comparing(ForecastPowerShortTerm::getForecastTime)); return shortList; } /** * 根据开始时间和结束时间获取短期数据 * * @param beginDate * @param endDate * @return */ public List getUltraShortArr(String beginDate, String endDate) { // 获取短期预测数据 LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); long beginDateL = 0; long endDateL = 0; try { beginDateL = sdf.parse(beginDate).getTime(); endDateL = sdf.parse(endDate).getTime(); } catch (ParseException e) { e.printStackTrace(); } // 获取明天日期 lambdaQueryWrapper.between(ForecastPowerUltraShortTerm::getForecastTime, beginDateL, endDateL); List ultraShortList = forecastPowerUltraShortTermMapper.selectList(lambdaQueryWrapper); ultraShortList.sort(Comparator.comparing(ForecastPowerUltraShortTerm::getForecastTime)); return ultraShortList; } /** * 将修正后明日数据更新到短期实时表中 * * @return */ @Transactional(rollbackFor = Exception.class) public JSONObject updateShortTerm(List shortTermList) { //升序排列 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 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(); } /** * 将修正后的超短期数据更新到超短期实时表中 * * @return */ @Transactional public JSONObject updateUltraShortTerm(List ultraShortTermList) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); long startTimeL = ultraShortTermList.stream().mapToLong(ForecastPowerUltraShortTerm::getForecastTime).min().getAsLong(); long endTimeL = ultraShortTermList.stream().mapToLong(ForecastPowerUltraShortTerm::getForecastTime).max().getAsLong(); if (ultraShortTermList.size() > 16) { log.info("====================超短期个数大于16===================="); return JsonResultUtil.failureDesc("超短期个数大于16"); } ultraShortTermList.sort(Comparator.comparing(ForecastPowerUltraShortTerm::getForecastTime)); lambdaQueryWrapper.between(ForecastPowerUltraShortTerm::getForecastTime, startTimeL, endTimeL); forecastPowerUltraShortTermMapper.delete(lambdaQueryWrapper); forecastPowerUltraShortTermService.saveBatch(ultraShortTermList); return JsonResultUtil.success(); } }