package cn.gistack.nky.service.impl;
|
|
import cn.gistack.common.utils.CommonUtil;
|
import cn.gistack.common.utils.HttpClientUtils;
|
import cn.gistack.common.utils.SpringContextUtil;
|
import cn.gistack.nky.resultpojo.*;
|
import cn.gistack.nky.service.IHsybService;
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.parser.Feature;
|
import lombok.AllArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springblade.core.tool.utils.DateUtil;
|
import org.springblade.core.tool.utils.StringUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.http.*;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.MultiValueMap;
|
import org.springframework.web.client.RestTemplate;
|
|
import java.time.LocalDate;
|
import java.time.format.DateTimeFormatter;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
@Service
|
@AllArgsConstructor
|
@Slf4j
|
public class HsybServiceImpl implements IHsybService {
|
|
private RestTemplate restTemplate;
|
private static String PREFIX = "/hsybApi";
|
|
private static String ONLINE = "http://10.42.7.148:50001";
|
private static String LOCAL = "https://sk.hubeishuiyi.cn";
|
private static String GET_FUTURE = "/api/fh-admin/skkr/getFuture";
|
//新水位接口
|
private static String GET_NEW_FUTURE = "/api/fh-admin/skkr/getSkFutureSw";
|
//获取是否有预测模型接口
|
private static String GET_SK_GXZT = "/api/fh-admin/skkr/getSkgxzt";
|
//同步模型接口
|
private static String UPDATE_CJYSJ_BY_TM = "/api/fh-admin/skkr/updateCjysjByTm";
|
|
|
// private static String GET_FUTURE_ONLINE = "/api/fh-admin/skkr/getFuture";
|
// private static String GET_NEW_FUTURE_ONLINE = "/api/fh-admin/skkr/getSkFutureSw";
|
|
private static String AUTHORIZATION = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJBRE1JTiIsIlVzZXJJZCI6IjEiLCJzY29wZSI6WyJhbGwiXSwiVXNlclJlYWxOYW1lIjoi6LaF57qn566h55CG5ZGYIiwiVXNlclh6cWhkbSI6IjQyMDUiLCJleHAiOjI1MTk3NzIwMTAsImp0aSI6ImExNTcxYzk1LTBkNjMtNDkyYi1iOWEyLTE2ZTIzNTQ5ZTY1ZiIsImNsaWVudF9pZCI6InVzZXItc2VydmljZSJ9.ebNVZrw9LbhKaj2w6RR8b2wccQiDkhvBeq79SxxCK-yWiOlIFqBkotTN4TNJg8umcpyYvLILwvqXWRJhffEtgi25sX2y6MqLIWM4kMZ9d8ptdnSmTpBPhltSiQOM0KFa1kl5nSDCBwYOLn-pESJglam76cjpgZNoC88x3iNHacdiXDItY0rtY85HrQ26uyJu9UovKtmYmZRHsIbGMpDta5Q1p4vfaCIr-YUayDrCweZJiQDEEcOSpWJ7O7RMk3pRkX_4UmPHFzrOI2lMp1jQIhxnSTE7EVAz_4z8h8r46muSkpF54Ic4XSawHKqdSLHx8T05LB0MpvOzWMPS6c1uHA";
|
|
|
@Override
|
public List<List<String>> getFuture(String resCd) {
|
HsybGetFuturePo hsybGetFuturePo = apiRequest(GET_FUTURE, resCd);
|
|
if (hsybGetFuturePo != null && hsybGetFuturePo.getRespCode().equals("200")) {
|
List<List<String>> data = (List<List<String>>)hsybGetFuturePo.getData();
|
|
List<List<String>> collect = filterPredictData(data);
|
return collect;
|
} else {
|
return null;
|
}
|
}
|
|
@Override
|
public List<NewSwFuturePo> getNewFuture(String resId) {
|
//获取预测水位之前需要确认是否有预测水位模型
|
// Boolean isUpdate = isResHasModel(resId);
|
|
// if (isUpdate){
|
//数据模型已经更新过,就可以去拿预测水位
|
//设置预测73小时未来水位,因为最后一条是当前时间的整点数据,获取不到三天,多加一小时就可以获取到下一个整点的未来数据
|
String urlParams = StringUtil.format("?resId={}&yjq=73",resId);
|
|
HsybGetFuturePo hsybGetFuturePo = sendRequestToHsyb(GET_NEW_FUTURE, urlParams);
|
|
//程序转为hashmap,手动转换类型
|
List<NewSwFuturePo> data = JSON.parseArray(JSON.toJSONString(hsybGetFuturePo.getData()), NewSwFuturePo.class);
|
List<NewSwFuturePo> filterData = filterPredict(data);
|
|
log.info(StringUtil.format("过滤后的预测水位数据:{}", JSON.toJSONString(filterData)));
|
return filterData;
|
// }else{
|
// //拿不到预测水位
|
// return null;
|
// }
|
}
|
|
public Boolean isResHasModel(String resId){
|
String urlParams = StringUtil.format("?skbm={}",resId);
|
HsybGetFuturePo hsybGetFuturePo = sendRequestToHsyb(GET_SK_GXZT, urlParams);
|
String message = hsybGetFuturePo.getData().toString();
|
|
if (message.equals("请更新模型数据!")){
|
return false;
|
}else{
|
return true;
|
}
|
}
|
|
@Override
|
public String updateCjysjByTm(List<String> resIds) {
|
// 获取当前时间
|
LocalDate currentDate = LocalDate.now();
|
// 获取前30天的时间
|
LocalDate thirtyDaysBefore = currentDate.minusDays(30);
|
// 输出结果
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
|
String startTime = thirtyDaysBefore.format(formatter);
|
String endTime = currentDate.format(formatter);
|
|
String urlParams = StringUtil.format("?startTime={}&endTime={}", startTime, endTime);
|
String skbmListStr = String.join("&skbmList=", resIds);
|
HsybGetFuturePo res = sendRequestToHsyb(UPDATE_CJYSJ_BY_TM, urlParams + "&skbmList=" + skbmListStr);
|
return res.getData().toString();
|
}
|
|
private HsybGetFuturePo apiRequest(String url, String type, Map<String, Object> params) {
|
// 获取环境
|
String activeProfile = SpringContextUtil.getActiveProfile();
|
if (activeProfile.equals("dev")) {
|
url = LOCAL + PREFIX + url;
|
}
|
if (activeProfile.equals("prod")) {
|
url = ONLINE + url;
|
}
|
if (activeProfile.equals("test")) {
|
url = ONLINE + url;
|
}
|
|
HttpMethod method;
|
if (type.toLowerCase().equals("get".toLowerCase())) {
|
method = HttpMethod.GET;
|
} else {
|
method = HttpMethod.POST;
|
}
|
// 声明一个header变量
|
HttpHeaders headers = new HttpHeaders();
|
url = url + "?resId=" + params.get("resId");
|
HttpEntity<String> httpEntity = new HttpEntity(null, headers);
|
log.info("请求地址:" + url);
|
log.info("请求参数:" + params);
|
RestTemplate template = new RestTemplate();
|
ResponseEntity<HsybGetFuturePo> response = template.exchange(url, method, httpEntity, HsybGetFuturePo.class);
|
|
if (response.getStatusCodeValue() == 200) {
|
return response.getBody();
|
}
|
return null;
|
}
|
|
public HsybGetFuturePo apiRequest(String url, String jsonparams) {
|
|
// 获取环境
|
String activeProfile = SpringContextUtil.getActiveProfile();
|
if (activeProfile.equals("dev")) {
|
url = LOCAL + PREFIX + url;
|
}
|
if (activeProfile.equals("prod")) {
|
url = ONLINE + GET_FUTURE;
|
}
|
if (activeProfile.equals("test")) {
|
url = ONLINE + GET_FUTURE;
|
}
|
|
|
log.info("预测水位请求参数:" + jsonparams);
|
log.info("预测水位请求地址:" + url);
|
|
// 声明一个header变量
|
HttpHeaders headers = new HttpHeaders();
|
// 设置为json格式
|
MediaType mediaType = MediaType.parseMediaType("application/json;charset=utf-8");
|
headers.setContentType(mediaType);
|
//设置请求头
|
headers.set("Authorization", AUTHORIZATION);
|
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
|
|
HttpEntity<String> httpEntity = new HttpEntity(jsonparams, headers);
|
RestTemplate template = new RestTemplate();
|
try {
|
HsybGetFuturePo hsybGetFuturePo = template.postForObject(url, httpEntity, HsybGetFuturePo.class);
|
log.info("预测水位返回结果:" + hsybGetFuturePo.toString());
|
return hsybGetFuturePo;
|
} catch (Exception e) {
|
System.out.println(e);
|
}
|
|
return null;
|
}
|
|
public HsybGetFuturePo sendRequestToHsyb(String url, String urlParam) {
|
// 获取环境
|
String activeProfile = SpringContextUtil.getActiveProfile();
|
if (activeProfile.equals("dev")) {
|
url = LOCAL + PREFIX + url;
|
}
|
if (activeProfile.equals("prod")) {
|
url = ONLINE + url;
|
}
|
if (activeProfile.equals("test")) {
|
url = ONLINE + url;
|
}
|
url = url + urlParam;
|
log.info("洪水预报请求地址:{}", url);
|
//设置请求头
|
HttpHeaders headers = new HttpHeaders();
|
headers.add("Authorization", AUTHORIZATION);
|
//封装请求头
|
HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<MultiValueMap<String, Object>>(headers);
|
|
try {
|
ResponseEntity<HsybGetFuturePo> exchange = restTemplate.exchange(url, HttpMethod.GET, formEntity, HsybGetFuturePo.class);
|
return exchange.getBody();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
|
/**
|
* 对预测数据进行过滤
|
*
|
* @param data
|
* @return
|
*/
|
public List<List<String>> filterPredictData(List<List<String>> data) {
|
|
//获取当前时间
|
String formatter = "HH:00";
|
String nowTime = DateUtil.format(new Date(), formatter);
|
|
//获取等于当前时间的水位数据
|
List<List<String>> collect = data.stream().filter(infoList -> infoList.get(0).equals(nowTime)).collect(Collectors.toList());
|
|
collect.forEach(infoList -> {
|
//给第一项重新赋值,因为后面取的是第一项,且预测参数时间只要日期
|
infoList.set(0, infoList.get(4).split(" ")[0]);
|
});
|
return collect;
|
|
|
//
|
// String formatter = "yyyy-MM-dd";
|
// String today = DateUtil.format(new Date(), formatter);
|
//
|
// Long time = new Date().getTime() + 60 * 60 * 24 * 1000;
|
// Date tomorrowDate = new Date(time);
|
// String tomorrow = DateUtil.format(tomorrowDate, formatter);
|
//
|
//
|
// String nowHour = DateUtil.format(new Date(),"HH");
|
//
|
// //过滤空值数据
|
// List<List<String>> collect = data.stream().filter(item -> item.get(0) != null).collect(Collectors.toList());
|
//
|
// //切割过去数据
|
// Integer nowIndex = findIndex(collect, nowHour);
|
// List<List<String>> subList = collect.subList(nowIndex, collect.size());
|
// int index = -1;
|
// //添加日期
|
// for (int i = 0; i < subList.size(); i++) {
|
// List<String> temp = subList.get(i);
|
// if (index == -1 && temp.get(0).indexOf("/")>-1){
|
// index = i;
|
// temp.set(0,tomorrow + " " +temp.get(0).substring(5));
|
// }
|
//
|
// if (index != -1){
|
// temp.set(0,tomorrow + " " + temp.get(0).substring(5));
|
// }else {
|
// //给后面的时间添加今天的日期
|
// temp.set(0,today + " " + temp.get(0));
|
// }
|
//
|
// }
|
//
|
//
|
// //截取掉时间部分
|
// subList.forEach(e->{
|
// e.set(0,e.get(0).split(" ")[0]);
|
// });
|
//
|
// //去除重复数据
|
// List<List<String>> distinctList = subList.stream().distinct().collect(Collectors.toList());
|
//
|
//
|
// //去重
|
// for ( int i = 0 ; i < distinctList.size() - 1 ; i ++ ) {
|
// for ( int j = distinctList.size() - 1 ; j > i; j -- ) {
|
// // 这里是对象的比较,如果去重条件不一样,在这里修改即可
|
// if (distinctList.get(j).get(0).equals(distinctList.get(i).get(0))) {
|
// distinctList.remove(i);
|
// }
|
// }
|
// }
|
|
// return distinctList;
|
}
|
|
public List<NewSwFuturePo> filterPredict(List<NewSwFuturePo> list) {
|
|
/**
|
* {
|
* "sw": "88.72",
|
* "time": "2024-02-01 16:00:00",
|
* "resId": "42092250024"
|
* },
|
* {
|
* "sw": "88.72",
|
* "time": "2024-02-01 17:00:00",
|
* "resId": "42092250024"
|
* },
|
*/
|
if (list.size() == 0) {
|
return null;
|
}
|
|
//先拿第一个数据,第一个数据就是当前时间的下一个整点的预测数据
|
NewSwFuturePo newSwFuturePo = list.get(0);
|
|
//获取预测数据中,和第一条时间部分相同的数据;再筛选掉水位为0的数据
|
List<NewSwFuturePo> filterList = list.stream().filter(item -> item.getTime().indexOf(newSwFuturePo.getTime().split(" ")[1]) > -1).filter(item->!item.getSw().equals("0.0")).collect(Collectors.toList());
|
|
//给时间重新赋值,因为南科院hst预测只需要日期
|
filterList.forEach(e -> {
|
e.setTime(e.getTime().split(" ")[0]);
|
});
|
|
return filterList;
|
}
|
|
public Integer findIndex(List<List<String>> list, String reg) {
|
for (int i = 0; i < list.size(); i++) {
|
if (list.get(i).get(0).indexOf(reg) > -1) {
|
return i;
|
}
|
}
|
return -1;
|
}
|
}
|