parent
0bc0259e02
commit
086c405ff6
|
|
@ -76,7 +76,7 @@ public class WaterAlarmController {
|
|||
return counts;
|
||||
}
|
||||
|
||||
@Operation(summary = "根据年份进行统计圆柱图")
|
||||
@Operation(summary = "根据年份进行统计圆饼图")
|
||||
@GetMapping("/countTypeByYear")
|
||||
public List<WaterAlarmTypeCount> countTypeByYear(@RequestParam(value = "year") Integer year){
|
||||
List<WaterAlarmTypeCount> res = service.countTypeByYear(year);
|
||||
|
|
|
|||
|
|
@ -28,4 +28,12 @@ public interface StWaterRMapper extends BaseMapper<StWaterR> {
|
|||
</script>
|
||||
""")
|
||||
List<StWaterR> stat(@Param("obj") DateTimeRangeSo dateTimeRangeSo);
|
||||
|
||||
@Select("""
|
||||
select t1.* from st_water_r t1
|
||||
join
|
||||
(select stcd,max(tm) as max_tm from st_water_r GROUP BY stcd) t2
|
||||
on t1.stcd = t2.stcd and t1.tm = t2.max_tm ;
|
||||
""")
|
||||
List<StWaterR> getStcdLastWaterData();
|
||||
}
|
||||
|
|
@ -120,6 +120,7 @@ public class ReservoirWaterService {
|
|||
}
|
||||
|
||||
List<StZvarlB> zvarlList = stZvarlBService.list();
|
||||
zvarlList.sort(Comparator.comparing(StZvarlB::getRz));
|
||||
voList.forEach(vo -> {
|
||||
if(vo.getCalState() == 1){
|
||||
vo.setDesState(0);
|
||||
|
|
@ -130,8 +131,8 @@ public class ReservoirWaterService {
|
|||
|
||||
BigDecimal rz = vo.getRz();
|
||||
if (rz != null) {
|
||||
//TODO 这里可能也要更改一下水位-库容的计算方式,不能直接进行水库库容曲线的判断
|
||||
BigDecimal w = stZvarlBService.getWFromZvarl(rz, null, zvarlList);
|
||||
//BigDecimal w = stZvarlBService.getWFromZvarl(rz, null, zvarlList);
|
||||
BigDecimal w = stZvarlBService.getWByZvarl(zvarlList,rz);
|
||||
vo.setNowCap(w);
|
||||
}
|
||||
});
|
||||
|
|
@ -155,7 +156,7 @@ public class ReservoirWaterService {
|
|||
for (AttResBaseVo attResBaseVo : voList) {
|
||||
attResBaseVo.setIrrigationFlowSum(totalSum);
|
||||
}
|
||||
//获取生态供水流量
|
||||
//获取新建生态供水流量站最新得流量
|
||||
String ecologyStcd = "1114";
|
||||
QueryWrapper<StWaterRReal> ecologyQw = new QueryWrapper<>();
|
||||
ecologyQw.eq("stcd", ecologyStcd).orderBy(true, false, "tm");
|
||||
|
|
|
|||
|
|
@ -125,6 +125,10 @@ public class StQxWarnRService extends ServiceImpl<StQxWarnRMapper, StQxWarnR> {
|
|||
vo.setOverRvUp("告警设置未配置,请检查");
|
||||
}else{
|
||||
BigDecimal rz = stRiverRReal.getZ();
|
||||
if(rz == null){
|
||||
vo.setOverRvUp("暂无最新水位数据");
|
||||
return;
|
||||
}
|
||||
if(rz.compareTo(warnWaterLevel) >=0){
|
||||
BigDecimal gap = rz.subtract(warnWaterLevel);
|
||||
vo.setOverRvUp("超警戒(" +gap.setScale(2, RoundingMode.HALF_UP)+")m");
|
||||
|
|
@ -148,8 +152,13 @@ public class StQxWarnRService extends ServiceImpl<StQxWarnRMapper, StQxWarnR> {
|
|||
BigDecimal promiseWaterLevel = alarmSet.getPromiseWaterLevel();
|
||||
if(alarmSet == null){
|
||||
vo.setOverRvDown("告警设置未配置,请检查");
|
||||
|
||||
}else{
|
||||
BigDecimal rz = stRiverRReal.getZ();
|
||||
if(rz == null){
|
||||
vo.setOverRvUp("暂无最新水位数据");
|
||||
return;
|
||||
}
|
||||
if(rz.compareTo(warnWaterLevel) >=0){
|
||||
BigDecimal gap = rz.subtract(warnWaterLevel);
|
||||
vo.setOverRvDown("超警戒(" +gap.setScale(2, RoundingMode.HALF_UP)+")m");
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -138,13 +140,17 @@ public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
* 第一条数据的累计溢洪量设为0,第二条累计溢洪量=上一条累计溢洪量+本条溢洪流量*60分*60秒,以此类推
|
||||
*/
|
||||
|
||||
//TODO 这里得确定一下,这个新建的泄洪道水位站是不是从水库历史水位表中查
|
||||
//获取水位历史数据
|
||||
List<StRsvrR> rsvrList = rsvrRService.lambdaQuery()
|
||||
.eq(StRsvrR::getStcd, obj.getStcd())
|
||||
.between(StRsvrR::getTm, obj.getDateSo().getStart(), obj.getDateSo().getEnd())
|
||||
.orderBy(true, true, StRsvrR::getTm)
|
||||
.list();
|
||||
//查询水位-流量关系
|
||||
List<StZqrlB> zqrlList = stZqrlBService.list();
|
||||
zqrlList.sort(Comparator.comparing(StZqrlB::getZ));
|
||||
//获取水位-库容关系
|
||||
List<StZvarlB> zvarlList = stZvarlBService.list();
|
||||
zvarlList.sort(Comparator.comparing(StZvarlB::getRz));
|
||||
List<StZqrlBVo> ret = new ArrayList<>();
|
||||
|
|
@ -156,34 +162,27 @@ public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
vo.setStcd(rsvr.getStcd());
|
||||
vo.setTm(rsvr.getTm());
|
||||
vo.setWaterLevel(rz);
|
||||
|
||||
zqrlList.stream()
|
||||
.filter(zqrl -> zqrl.getZ().equals(new BigDecimal(rsvr.getRz())))
|
||||
.findFirst()
|
||||
.ifPresentOrElse(zqrl -> {
|
||||
vo.setFlowNum(zqrl.getQ());
|
||||
}, () -> vo.setFlowNum(BigDecimal.ZERO));
|
||||
|
||||
zvarlList.stream()
|
||||
.filter(zvarl -> zvarl.getRz().equals(new BigDecimal(rsvr.getRz())))
|
||||
.findFirst()
|
||||
.ifPresentOrElse(zvarl -> {
|
||||
vo.setBoxNum(zvarl.getW());
|
||||
}, () -> vo.setBoxNum(BigDecimal.ZERO));
|
||||
|
||||
//溢洪流量计算
|
||||
//TODO 这里水位->流量 需要计算公式
|
||||
BigDecimal q = stZqrlBService.getQByZqrl(zqrlList,rz);//根据水位计算流量
|
||||
vo.setFlowNum(q);//计算溢洪量(非累加值)
|
||||
BigDecimal w = stZvarlBService.getWByZvarl(zvarlList, rz);//根据水位计算库容
|
||||
vo.setBoxNum(w);
|
||||
if (i == 0) {
|
||||
vo.setQtotal(BigDecimal.ZERO);
|
||||
} else {
|
||||
StZqrlBVo voPrev = ret.get(i - 1);
|
||||
BigDecimal qTotal = vo.getFlowNum().multiply(BigDecimal.valueOf(60 * 60));
|
||||
BigDecimal prevQtotal = voPrev.getQtotal();
|
||||
qTotal = qTotal.add(prevQtotal);
|
||||
//累计溢洪量 = 上一条数据累计溢洪量 + 本条溢洪流量 * 2条数据之间的间隔
|
||||
Instant curInstant = vo.getTm().toInstant();
|
||||
Instant preInstant = voPrev.getTm().toInstant();
|
||||
long timeDiffSeconds = Duration.between(curInstant, preInstant).getSeconds();
|
||||
|
||||
BigDecimal qTotal = voPrev.getQtotal().add(vo.getFlowNum().multiply(BigDecimal.valueOf(timeDiffSeconds)));
|
||||
vo.setQtotal(qTotal);
|
||||
}
|
||||
|
||||
ret.add(vo);
|
||||
}
|
||||
|
||||
//倒序输出
|
||||
ret.sort(Comparator.comparing(StZqrlBVo::getTm).reversed());
|
||||
return ret;
|
||||
|
|
@ -239,12 +238,11 @@ public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
complex.setRz(rz);
|
||||
complex.setTm(rsvr.getTm());
|
||||
|
||||
//TODO 这里需要重新计算水位-流量对应数据
|
||||
//TODO 这里需要重新计算水位-流量(溢洪量)对应数据
|
||||
//BigDecimal q = stZqrlBService.getQFromZqrl(rz, zqrlList);
|
||||
BigDecimal q = stZqrlBService.getQByZqrl(zqrlList,rz);
|
||||
complex.setQ(q);
|
||||
//计算当前时间段溢洪量
|
||||
complex.setSv(complex.getQ().multiply(BigDecimal.valueOf(60 * 60)));
|
||||
complex.setSv(complex.getQ());
|
||||
// if (idx == 0) {
|
||||
// complex.setSv(BigDecimal.ZERO);
|
||||
// } else {
|
||||
|
|
@ -261,46 +259,70 @@ public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
vo.setVal(complexList.getLast().getQ());
|
||||
vo.setCreateTime(complexList.getLast().getTm());
|
||||
|
||||
|
||||
//今日sv的和
|
||||
BigDecimal sumToday = complexList.stream().filter(complex -> complex.getTm().after(dayStart))
|
||||
.map(RsvrComplexVo::getSv)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// 今日累计溢洪量(基于时间间隔的积分)
|
||||
List<RsvrComplexVo> complexDayList = complexList.stream().filter(complex -> complex.getTm().after(dayStart)).collect(Collectors.toList());
|
||||
BigDecimal sumToday = stZqrlBService.getFlowQSum(complexDayList);
|
||||
vo.setCurrDayValSum(sumToday);
|
||||
|
||||
// 当月溢洪量总和(筛选本月数据)
|
||||
BigDecimal sumMonth = complexList.stream()
|
||||
.filter(complex -> (complex.getTm().after(monthStart) || complex.getTm().equals(monthStart))
|
||||
&& complex.getTm().before(now) || complex.getTm().equals(now))
|
||||
.map(RsvrComplexVo::getSv)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// 当月累计溢洪量
|
||||
List<RsvrComplexVo> complexMonthList = complexList.stream().filter(complex -> (complex.getTm().after(monthStart) || complex.getTm().equals(monthStart))
|
||||
&& complex.getTm().before(now) || complex.getTm().equals(now)).collect(Collectors.toList());
|
||||
BigDecimal sumMonth = stZqrlBService.getFlowQSum(complexMonthList);
|
||||
vo.setCurrMonthSum(sumMonth);
|
||||
|
||||
// 当年溢洪量总和(所有数据都是当年的,直接求和)
|
||||
BigDecimal sumYear = complexList.stream()
|
||||
.map(RsvrComplexVo::getSv)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
|
||||
// 当年累计溢洪量
|
||||
BigDecimal sumYear = stZqrlBService.getFlowQSum(complexList);
|
||||
vo.setCurrYearSum(sumYear);
|
||||
|
||||
|
||||
// 计算本年溢洪次数(溢洪量>0)
|
||||
long overflowCount = complexList.stream()
|
||||
.filter(complex -> complex.getSv().compareTo(BigDecimal.ZERO) > 0)
|
||||
.count();
|
||||
vo.setCurrYearCount(overflowCount);
|
||||
// //今日sv的和
|
||||
// BigDecimal sumToday = complexList.stream().filter(complex -> complex.getTm().after(dayStart))
|
||||
// .map(RsvrComplexVo::getSv)
|
||||
// .reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// vo.setCurrDayValSum(sumToday);
|
||||
//
|
||||
// // 当月溢洪量总和(筛选本月数据)
|
||||
// BigDecimal sumMonth = complexList.stream()
|
||||
// .filter(complex -> (complex.getTm().after(monthStart) || complex.getTm().equals(monthStart))
|
||||
// && complex.getTm().before(now) || complex.getTm().equals(now))
|
||||
// .map(RsvrComplexVo::getSv)
|
||||
// .reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// vo.setCurrMonthSum(sumMonth);
|
||||
//
|
||||
// // 当年溢洪量总和(所有数据都是当年的,直接求和)
|
||||
// BigDecimal sumYear = complexList.stream()
|
||||
// .map(RsvrComplexVo::getSv)
|
||||
// .reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// vo.setCurrYearSum(sumYear);
|
||||
|
||||
|
||||
//计算溢洪次数
|
||||
// 0 0 0 1 1 0 1 0 1
|
||||
int overFlowCount = 0;
|
||||
boolean isOverFlow = false;
|
||||
//连续的sv > 0 才算一次 溢洪
|
||||
for(int i =0;i<complexList.size();i++){
|
||||
BigDecimal sv = complexList.get(i).getSv();
|
||||
if(sv.compareTo(BigDecimal.ZERO) > 0){
|
||||
if(!isOverFlow){
|
||||
overFlowCount++;
|
||||
isOverFlow = true;
|
||||
}
|
||||
}else{
|
||||
isOverFlow = false;
|
||||
}
|
||||
}
|
||||
vo.setCurrYearCount(Long.valueOf(overFlowCount));
|
||||
// 本年单次最大溢洪量
|
||||
Optional<RsvrComplexVo> maxOverflowComplex = complexList.stream()
|
||||
.max(Comparator.comparing(RsvrComplexVo::getSv));
|
||||
if (maxOverflowComplex.isPresent()) {
|
||||
RsvrComplexVo maxComplex = maxOverflowComplex.get();
|
||||
vo.setCurrYearMaxVal(maxComplex.getSv());
|
||||
|
||||
// 假设最大溢洪量持续了一段时间(这里需要根据业务逻辑确定)
|
||||
// 简单处理:显示发生时间
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss");
|
||||
// 如果需要更复杂的时间段计算,可以根据前后数据点来判断
|
||||
int maxIndex = complexList.indexOf(maxComplex);
|
||||
if (maxIndex < complexList.size() - 1) {
|
||||
// 可以取前后时间点作为时间段的参考
|
||||
|
|
@ -317,12 +339,6 @@ public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
vo.setCurrYearMaxVal(BigDecimal.ZERO);
|
||||
vo.setMaxOverflowPeriod("无溢洪记录");
|
||||
}
|
||||
// BigDecimal maxOverflow = complexList.stream()
|
||||
// .map(RsvrComplexVo::getSv)
|
||||
// .max(Comparator.naturalOrder())
|
||||
// .orElse(BigDecimal.ZERO);
|
||||
// vo.setCurrYearMaxVal(maxOverflow);
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
|
|
@ -335,14 +351,19 @@ public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
return vo;
|
||||
}
|
||||
BigDecimal rzLatest = new BigDecimal(rsvrLatest.getRz());
|
||||
BigDecimal qLatest = stZqrlBService.getQFromZqrl(rzLatest);
|
||||
//获取水位-流量数据k
|
||||
List<StZqrlB> zqrlBList = stZqrlBService.list();
|
||||
//TODO 转换溢洪流量计算
|
||||
BigDecimal qLatest = stZqrlBService.getQByZqrl(zqrlBList,rzLatest);
|
||||
//BigDecimal qLatest = stZqrlBService.getQFromZqrl(rzLatest);
|
||||
vo.setCurrWaterLevel(rzLatest);
|
||||
vo.setFlowNum(qLatest);
|
||||
vo.setFlowNum(qLatest);//当前溢洪量 就为 流量
|
||||
vo.setCreateTime(rsvrLatest.getTm());
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime before24 = now.minusHours(24);
|
||||
List<StRsvrR> rsvrList = rsvrRService.lambdaQuery().ge(StRsvrR::getTm, before24).le(StRsvrR::getTm, now).orderByAsc(StRsvrR::getTm).list();
|
||||
//TODO 这个溢洪流量汇总的计算也需要进行公式计算
|
||||
List<RsvrComplexVo> rsvrComplexVos = stZqrlBService.calculateSpilledVolumeList(rsvrList);
|
||||
BigDecimal totalSv = rsvrComplexVos.stream().map(RsvrComplexVo::getSv).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
vo.setSum24(totalSv);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ public class StWaterRService extends ServiceImpl<StWaterRMapper, StWaterR>
|
|||
return list.stream()
|
||||
.collect(Collectors.groupingBy(StWaterR::getStcd, Collectors.mapping(StWaterR::getV, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
|
||||
}
|
||||
|
||||
public List<StWaterR> getStcdLastWaterData() {
|
||||
return this.baseMapper.getStcdLastWaterData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -65,7 +66,8 @@ public class StZqrlBService extends ServiceImpl<StZqrlBMapper, StZqrlB> {
|
|||
BigDecimal rz = new BigDecimal(rsvr.getRz());
|
||||
Date tm = rsvr.getTm();
|
||||
RsvrComplexVo vo = RsvrComplexVo.of(rz, tm);
|
||||
|
||||
BigDecimal q = getQFromZqrl(rz, zqrlList);
|
||||
//TODO 这个需要公式进行对水位->流量的转换
|
||||
if (i == 0) {
|
||||
vo.setQ(getQFromZqrl(rz, zqrlList));
|
||||
vo.setSv(BigDecimal.ZERO);
|
||||
|
|
@ -74,6 +76,7 @@ public class StZqrlBService extends ServiceImpl<StZqrlBMapper, StZqrlB> {
|
|||
Date tmPrev = rsvrPrev.getTm();
|
||||
long seconds = tm.getTime() - tmPrev.getTime();
|
||||
vo.setQ(getQFromZqrl(rz, zqrlList));
|
||||
//TODO 这里有个函数调用,记得到时候也替换一下计算公式
|
||||
vo.setSv(calculateSpilledVolume(rz, seconds));
|
||||
}
|
||||
ret.add(vo);
|
||||
|
|
@ -128,6 +131,104 @@ public class StZqrlBService extends ServiceImpl<StZqrlBMapper, StZqrlB> {
|
|||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
public BigDecimal getQByZqrl(List<StZqrlB> zqrlBList, BigDecimal rz) {
|
||||
int l =0;
|
||||
int r = zqrlBList.size() - 1;
|
||||
if(rz.compareTo(zqrlBList.get(0).getZ()) < 0){
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
//使用二分法,来获取 避免On的查询时间复杂度
|
||||
while(l < r){
|
||||
int mid = l + (r - l) / 2;
|
||||
if(zqrlBList.get(mid).getZ().compareTo(rz) ==0){
|
||||
return zqrlBList.get(mid).getQ();
|
||||
}else if(zqrlBList.get(mid).getZ().compareTo(rz) >0){
|
||||
r = mid - 1;
|
||||
}else{
|
||||
l = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 现在 l 是最接近的索引,但需要比较前后三个值
|
||||
int closestIndex = l;
|
||||
|
||||
// 处理边界情况
|
||||
if (l == 0) {
|
||||
// 只有第一个元素,或者比较第一个和第二个哪个更接近
|
||||
if (zqrlBList.size() > 1) {
|
||||
BigDecimal diff1 = rz.subtract(zqrlBList.get(0).getZ()).abs();
|
||||
BigDecimal diff2 = rz.subtract(zqrlBList.get(1).getZ()).abs();
|
||||
closestIndex = diff1.compareTo(diff2) <= 0 ? 0 : 1;
|
||||
}
|
||||
//TODO 这里找到最接近的值后,仍然要通过公式,计算出真正的流量
|
||||
return zqrlBList.get(closestIndex).getQ();
|
||||
}
|
||||
|
||||
if (l == zqrlBList.size() - 1) {
|
||||
// 只有最后一个元素,或者比较最后两个哪个更接近
|
||||
if (zqrlBList.size() > 1) {
|
||||
BigDecimal diff1 = rz.subtract(zqrlBList.get(l - 1).getZ()).abs();
|
||||
BigDecimal diff2 = rz.subtract(zqrlBList.get(l).getZ()).abs();
|
||||
closestIndex = diff1.compareTo(diff2) <= 0 ? l - 1 : l;
|
||||
}
|
||||
//TODO 这里找到最接近的值后,仍然要通过公式,计算出真正的流量
|
||||
return zqrlBList.get(closestIndex).getQ();
|
||||
}
|
||||
|
||||
// 正常情况:比较前一个、当前、后一个三个值,找到最接近的
|
||||
BigDecimal preVal = zqrlBList.get(l - 1).getZ();
|
||||
BigDecimal curVal = zqrlBList.get(l).getZ();
|
||||
BigDecimal nextVal = zqrlBList.get(l + 1).getZ();
|
||||
|
||||
//计算他们与目标的插值
|
||||
BigDecimal diffPre = rz.subtract(preVal).abs();
|
||||
BigDecimal diffCur = rz.subtract(curVal).abs();
|
||||
BigDecimal diffNext = rz.subtract(nextVal).abs();
|
||||
|
||||
// 找到最小的差值
|
||||
if (diffPre.compareTo(diffCur) <= 0 && diffPre.compareTo(diffNext) <= 0) {
|
||||
closestIndex = l - 1;
|
||||
} else if (diffCur.compareTo(diffPre) <= 0 && diffCur.compareTo(diffNext) <= 0) {
|
||||
closestIndex = l;
|
||||
} else {
|
||||
closestIndex = l + 1;
|
||||
}
|
||||
|
||||
//TODO 这里找到最接近的值后,仍然要通过公式,计算出真正的流量
|
||||
|
||||
return zqrlBList.get(closestIndex).getQ();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算累计溢洪量
|
||||
* @param complexList
|
||||
* @return
|
||||
*/
|
||||
public BigDecimal getFlowQSum(List<RsvrComplexVo> complexList) {
|
||||
BigDecimal sum = BigDecimal.ZERO;
|
||||
for (int i = 0; i < complexList.size(); i++) {
|
||||
RsvrComplexVo current = complexList.get(i);
|
||||
if (i == 0) {
|
||||
// 第一条数据,累计量为0
|
||||
sum = BigDecimal.ZERO;
|
||||
} else {
|
||||
RsvrComplexVo previous = complexList.get(i - 1);
|
||||
|
||||
// 计算时间间隔(秒)
|
||||
long timeDiffSeconds = Duration.between(previous.getTm().toInstant(),
|
||||
current.getTm().toInstant()).getSeconds();
|
||||
|
||||
if (timeDiffSeconds > 0) {
|
||||
// 使用梯形法则计算这段时间内的溢洪量:(上一个流量 + 当前流量) / 2 * 时间间隔
|
||||
BigDecimal avgFlow = previous.getSv().add(current.getSv())
|
||||
.divide(BigDecimal.valueOf(2), 10, RoundingMode.HALF_UP);
|
||||
BigDecimal increment = avgFlow.multiply(BigDecimal.valueOf(timeDiffSeconds));
|
||||
sum = sum.add(increment);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,27 +6,15 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||
import com.gunshi.project.hsz.model.StPptnR;
|
||||
import com.gunshi.project.hsz.model.StPptnRD;
|
||||
import com.gunshi.project.hsz.model.StPptnRH;
|
||||
import com.gunshi.project.hsz.model.StRiverR;
|
||||
import com.gunshi.project.hsz.model.StRiverRReal;
|
||||
import com.gunshi.project.hsz.model.StRsvrR;
|
||||
import com.gunshi.project.hsz.model.StRsvrRReal;
|
||||
import com.gunshi.project.hsz.service.StPptnRDService;
|
||||
import com.gunshi.project.hsz.service.StPptnRHService;
|
||||
import com.gunshi.project.hsz.service.StPptnRRealService;
|
||||
import com.gunshi.project.hsz.service.StPptnRService;
|
||||
import com.gunshi.project.hsz.service.StRiverRRealService;
|
||||
import com.gunshi.project.hsz.service.StRiverRService;
|
||||
import com.gunshi.project.hsz.service.StRsvrRRealService;
|
||||
import com.gunshi.project.hsz.service.StRsvrRService;
|
||||
import com.gunshi.project.hsz.model.*;
|
||||
import com.gunshi.project.hsz.service.*;
|
||||
import com.gunshi.project.hsz.util.OkHttpUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
|
@ -40,9 +28,11 @@ import java.io.IOException;
|
|||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -80,6 +70,8 @@ public class DataTaskHsz {
|
|||
public static String jcskPathRrRiverRoute = "/river/";// ZZ河道水位接口
|
||||
public static String jcskPathZzRsvrRoute = "/rsvr/";// RR水库水位接口
|
||||
|
||||
public static String jcskPathWaterRRoute = "";//供水接口
|
||||
|
||||
// 实时雨情
|
||||
@Autowired
|
||||
private StPptnRRealService stPptnRRealService;
|
||||
|
|
@ -112,6 +104,18 @@ public class DataTaskHsz {
|
|||
@Autowired
|
||||
private StRiverRService stRiverRService;
|
||||
|
||||
//历史供水量
|
||||
@Autowired
|
||||
private StWaterRService stWaterRService;
|
||||
|
||||
//实时供水量
|
||||
@Autowired
|
||||
private StWaterRRealService stWaterRRealService;
|
||||
|
||||
//供水量整编
|
||||
@Autowired
|
||||
private StWaterRReorganizeService stWaterRReorganizeService;
|
||||
|
||||
/**
|
||||
* @param
|
||||
* @description: 定时获取水库雨情数据(历史、天、时、real)
|
||||
|
|
@ -236,6 +240,149 @@ public class DataTaskHsz {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时获取供水量数据
|
||||
*/
|
||||
//@Async
|
||||
//@Scheduled(fixedRate = 70 , timeUnit = TimeUnit.MINUTES)
|
||||
public void getWaterData(){
|
||||
Date now = new Date();
|
||||
System.out.println("供水量定时任务,执行时间:" + sdf.format(now));
|
||||
//获取供水量站点表中 每个站点的最新数据时间
|
||||
List<StWaterR> stcdLast = stWaterRService.getStcdLastWaterData();
|
||||
OkHttpClient client = OkHttpUtil.build();
|
||||
String stcd1 = "";//干渠灌溉1
|
||||
String stcd2 = "";//干渠灌溉2
|
||||
String ecoStcd = "";//生态供水
|
||||
try {
|
||||
if(ObjectUtils.isNotEmpty(stcdLast)){
|
||||
//对每个数据进行遍历
|
||||
for (StWaterR stWaterR : stcdLast) {
|
||||
Date stm = stWaterR.getTm();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if(ObjectUtils.isEmpty(stm)){
|
||||
//如果从来没有数据
|
||||
calendar.add(Calendar.DATE, -30);
|
||||
}else{
|
||||
//同步过数据
|
||||
int diffDays = new BigDecimal((int) Math.ceil((now.getTime() - stm.getTime()) / (24 * 60 * 60 * 1000))).intValue();
|
||||
if (diffDays > 3) {
|
||||
//如果时间差大于3天
|
||||
calendar.add(Calendar.DATE, -2);
|
||||
calendar.add(Calendar.HOUR_OF_DAY, -20);
|
||||
} else {
|
||||
//小于三天
|
||||
calendar.setTime(stm);
|
||||
calendar.add(Calendar.MINUTE, 1);
|
||||
}
|
||||
}
|
||||
stm = calendar.getTime();
|
||||
//构建url
|
||||
//TODO 这里还需要根据实际url来进行更改
|
||||
String url = jcskPath;
|
||||
String waterRSource = "";
|
||||
url += jcskPathWaterRRoute + waterRSource;
|
||||
//构建HTTP请求
|
||||
Response resp = client.newCall(new Request.Builder().url(url)
|
||||
.post(new FormBody.Builder().add("stcd", stWaterR.getStcd())
|
||||
.add("stm", sdf.format(stm))
|
||||
.add("etm", sdf.format(now))
|
||||
.build())
|
||||
.header("Token", jcskToken)
|
||||
.addHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||
.build()).execute();
|
||||
String respStr = resp.body().string();
|
||||
JSONObject jsonObject = JSONObject.parseObject(respStr.toLowerCase());
|
||||
if (!"200".equals(jsonObject.get("code").toString())) {
|
||||
continue;
|
||||
}
|
||||
JSONArray data = jsonObject.getJSONArray("data");
|
||||
if(CollectionUtils.isNotEmpty(data)){
|
||||
List<StWaterR> rList = data.toJavaList(StWaterR.class);
|
||||
stWaterRService.saveBatch(rList);
|
||||
//更新实时数据表
|
||||
StWaterR stWaterRLast = rList.get(rList.size() - 1);
|
||||
StWaterRReal stWaterRReal = new StWaterRReal();
|
||||
UpdateWrapper<StWaterRReal> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.set("stcd", stWaterR.getStcd())
|
||||
.eq("tm",stWaterRLast.getTm());
|
||||
BeanUtils.copyProperties(stWaterRLast, stWaterRReal);
|
||||
stWaterRRealService.saveOrUpdate(stWaterRReal);
|
||||
//同步至供水整编表中
|
||||
// 使用 DateTimeFormatter(线程安全)
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
|
||||
Map<String, List<StWaterR>> groupedByTime = rList.stream()
|
||||
.collect(Collectors.groupingBy(waterR -> {
|
||||
try {
|
||||
Instant instant = waterR.getTm().toInstant();
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
return localDateTime.format(formatter);
|
||||
} catch (Exception e) {
|
||||
return "未知时间";
|
||||
}
|
||||
}));
|
||||
|
||||
// 组装数据并保存
|
||||
List<StWaterRReorganize> reorganizeList = new ArrayList<>();
|
||||
for (Map.Entry<String, List<StWaterR>> entry : groupedByTime.entrySet()) {
|
||||
String timeKey = entry.getKey();
|
||||
List<StWaterR> timeData = entry.getValue();
|
||||
|
||||
StWaterRReorganize reorganize = new StWaterRReorganize();
|
||||
reorganize.setTm(timeKey);
|
||||
|
||||
// 初始化各字段为0
|
||||
reorganize.setEcologyQ(BigDecimal.ZERO);
|
||||
reorganize.setEcologyV(BigDecimal.ZERO);
|
||||
reorganize.setMci1Q(BigDecimal.ZERO);
|
||||
reorganize.setMci1V(BigDecimal.ZERO);
|
||||
reorganize.setMci2Q(BigDecimal.ZERO);
|
||||
reorganize.setMci2V(BigDecimal.ZERO);
|
||||
reorganize.setSumV(BigDecimal.ZERO);
|
||||
|
||||
// 按站点类型处理数据
|
||||
for (StWaterR waterR : timeData) {
|
||||
String stcd = waterR.getStcd();
|
||||
BigDecimal q = waterR.getQ();
|
||||
BigDecimal v = waterR.getV();
|
||||
|
||||
if (ecoStcd.equals(stcd)) {
|
||||
// 生态供水数据
|
||||
reorganize.setEcologyQ(q);
|
||||
reorganize.setEcologyV(v);
|
||||
} else if (stcd1.equals(stcd)) {
|
||||
// 干渠灌溉1数据
|
||||
reorganize.setMci1Q(q);
|
||||
reorganize.setMci1V(v);
|
||||
} else if (stcd2.equals(stcd)) {
|
||||
// 干渠灌溉2数据
|
||||
reorganize.setMci2Q(q);
|
||||
reorganize.setMci2V(v);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算水量小计
|
||||
BigDecimal sumV = reorganize.getEcologyV()
|
||||
.add(reorganize.getMci1V())
|
||||
.add(reorganize.getMci2V());
|
||||
reorganize.setSumV(sumV);
|
||||
|
||||
reorganizeList.add(reorganize);
|
||||
}
|
||||
|
||||
// 批量保存到重组表
|
||||
if (!reorganizeList.isEmpty()) {
|
||||
stWaterRReorganizeService.saveBatch(reorganizeList);
|
||||
System.out.println("成功同步 " + reorganizeList.size() + " 条数据到重组表");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("供水历史定时任务错误:", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 定时获取水库水情数据(历史、real)
|
||||
* @param
|
||||
|
|
@ -243,8 +390,8 @@ public class DataTaskHsz {
|
|||
* @auther: cxw
|
||||
* @date: 2024-09-23, 周一, 11:23:04
|
||||
*/
|
||||
@Async
|
||||
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
|
||||
//@Async
|
||||
//@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
|
||||
public void getRiverData() {
|
||||
Date now = new Date();
|
||||
System.out.println("水情历史定时任务,执行时间:" + sdf.format(now));
|
||||
|
|
@ -253,6 +400,7 @@ public class DataTaskHsz {
|
|||
OkHttpClient client = OkHttpUtil.build();
|
||||
try {
|
||||
if (CollectionUtils.isNotEmpty(stcdLast)) {
|
||||
//对每个数据进行遍历
|
||||
for (StRsvrR stRsvrR : stcdLast) {
|
||||
Date stm = stRsvrR.getStm();
|
||||
String source = stRsvrR.getSource().toLowerCase();
|
||||
|
|
@ -261,18 +409,24 @@ public class DataTaskHsz {
|
|||
// 默认40天前(接口最多40天),存在则加1小时(接口是按小时算且大于等于开始时间)
|
||||
// 默认30天前
|
||||
if (ObjectUtils.isEmpty(stm)) {
|
||||
//如果数据库中没有该站点任何时间得数据
|
||||
if ("sh".equals(source)) {
|
||||
//对于sh源得数据,取前30天至今
|
||||
calendar.add(Calendar.DATE, -30);
|
||||
} else {
|
||||
//其它源得数据,取前2天20小时
|
||||
calendar.add(Calendar.DATE, -2);
|
||||
calendar.add(Calendar.HOUR_OF_DAY, -20);
|
||||
}
|
||||
} else {
|
||||
//如果又时间,则计算当前时间与最后一次同步得时间差
|
||||
int diffDays = new BigDecimal((int) Math.ceil((now.getTime() - stm.getTime()) / (24 * 60 * 60 * 1000))).intValue();
|
||||
if (diffDays > 3) {
|
||||
//如果时间差大于3天
|
||||
calendar.add(Calendar.DATE, -2);
|
||||
calendar.add(Calendar.HOUR_OF_DAY, -20);
|
||||
} else {
|
||||
//小于三天
|
||||
calendar.setTime(stm);
|
||||
calendar.add(Calendar.MINUTE, 1);
|
||||
}
|
||||
|
|
@ -290,6 +444,7 @@ public class DataTaskHsz {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
//构建HTTP请求
|
||||
Response resp = client.newCall(new Request.Builder().url(url)
|
||||
.post(new FormBody.Builder().add("stcd", stRsvrR.getStcd())
|
||||
.add("stm", sdf.format(stm))
|
||||
|
|
@ -305,6 +460,7 @@ public class DataTaskHsz {
|
|||
}
|
||||
JSONArray data = jsonObject.getJSONArray("data");
|
||||
if (CollectionUtils.isNotEmpty(data)) {
|
||||
//如果是zz类型站得数据
|
||||
if ("zz".equals(sttp)) {
|
||||
List<StRiverR> rlist = data.toJavaList(StRiverR.class);
|
||||
stRiverRService.saveBatch(rlist);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@
|
|||
GROUP BY stcd
|
||||
) latest ON t.stcd = latest.stcd AND t.tm = latest.max_tm
|
||||
<where>
|
||||
stb.sttp in ('QQ', 'PQ')
|
||||
and stb.stcd in ('1112','1113','1114') -- 站点编码,这里到时候得改
|
||||
|
||||
<!-- stb.sttp in ('QQ', 'PQ','ZI') 站点类型 站点编码是唯一的,所以不用对类型进行 -->
|
||||
and stb.stcd in ('1112','1113','1114') <!-- 站点编码 -->
|
||||
</where>
|
||||
|
||||
</select>
|
||||
|
|
|
|||
Loading…
Reference in New Issue