gunshi-project-ss/src/main/java/com/gunshi/project/hsz/service/StStbprpBService.java

430 lines
17 KiB
Java
Raw Normal View History

2025-07-17 15:26:39 +08:00
package com.gunshi.project.hsz.service;
2024-07-08 17:47:02 +08:00
2025-04-01 11:24:38 +08:00
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
2024-07-17 11:49:48 +08:00
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
2024-07-08 17:47:02 +08:00
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
2025-07-17 15:26:39 +08:00
import com.gunshi.project.hsz.entity.dto.StZqrlBDto;
import com.gunshi.project.hsz.entity.so.HomeStStbprpBSo;
import com.gunshi.project.hsz.entity.vo.*;
import com.gunshi.project.hsz.mapper.OsmoticPressRMapper;
import com.gunshi.project.hsz.mapper.OsmoticShiftRMapper;
import com.gunshi.project.hsz.mapper.StStbprpBMapper;
import com.gunshi.project.hsz.model.StRsvrR;
import com.gunshi.project.hsz.model.StStbprpB;
import com.gunshi.project.hsz.model.StZqrlB;
import com.gunshi.project.hsz.model.StZvarlB;
import com.gunshi.project.hsz.util.DateUtil;
2024-07-17 11:49:48 +08:00
import jakarta.annotation.Resource;
2024-07-08 17:47:02 +08:00
import lombok.extern.slf4j.Slf4j;
2025-04-01 11:24:38 +08:00
import org.springframework.beans.factory.annotation.Autowired;
2024-07-08 17:47:02 +08:00
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
2025-04-01 11:24:38 +08:00
import java.io.Serializable;
import java.math.BigDecimal;
2025-09-05 10:55:00 +08:00
import java.text.SimpleDateFormat;
2025-04-01 11:24:38 +08:00
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
2024-07-17 11:49:48 +08:00
import java.util.stream.Collectors;
2024-07-08 17:47:02 +08:00
/**
* : sttp
* author: xusan
* date: 2024-07-08 17:30:38
*/
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
2024-07-17 11:49:48 +08:00
@Resource
private OsmoticPressRMapper pressRMapper;
@Resource
private OsmoticShiftRMapper shiftRMapper;
2025-04-01 11:24:38 +08:00
@Autowired
private StZqrlBService stZqrlBService;
@Autowired
private StZvarlBService stZvarlBService;
2025-04-07 11:49:39 +08:00
@Autowired
private StRsvrRService rsvrRService;
2024-07-08 17:47:02 +08:00
public List<HomeStStbprpBVo> rainfallStationDetailsList(HomeStStbprpBSo dto) {
return baseMapper.rainfallStationDetailsList(dto);
}
public List<HomeStStbprpBVo> reservoirStationDetailsList() {
return baseMapper.reservoirStationDetailsList();
}
public List<HomeStStbprpBVo> flowStationDetailsList() {
return baseMapper.flowStationDetailsList();
}
2024-07-17 11:49:48 +08:00
public StStatusListVo statusList() {
StStatusListVo res = new StStatusListVo();
//水雨情站超过2小时为离线渗压渗流位移暂定超过24小时为离线
List<StStatusVo> list = new ArrayList<>();
List<StStatusVo> onLineList = new ArrayList<>();
List<StStatusVo> offLineList = new ArrayList<>();
//雨量站
List<StStatusVo> rainList = baseMapper.realRainList();
//水位站
List<StStatusVo> rzList = baseMapper.rzList();
2024-07-18 10:24:37 +08:00
//图像站
List<StStatusVo> imgList = baseMapper.imgList();
2024-07-17 11:49:48 +08:00
rainList.addAll(rzList);
2024-07-18 10:24:37 +08:00
rainList.addAll(imgList);
rainList.stream().collect(Collectors.toMap(obj -> obj.getStcd(), obj -> obj, (obj1, obj2) ->
DateUtil.convertStringToDate(obj1.getTm()).after(DateUtil.convertStringToDate(obj2.getTm())) ? obj1 : obj2
2024-07-17 11:49:48 +08:00
)).values().stream().collect(Collectors.toList());
for (StStatusVo statusVo : rainList) {
2024-07-17 11:49:48 +08:00
String tm = statusVo.getTm();
if (StringUtils.isEmpty(tm) || DateUtil.hoursBetweenDate(DateUtil.convertStringToDate(tm), new Date()) > 2) {
2024-07-17 11:49:48 +08:00
offLineList.add(statusVo);
} else {
2024-07-17 11:49:48 +08:00
onLineList.add(statusVo);
}
}
//渗压
List<OsmoticPressVo> pressList = pressRMapper.listValue();
list.addAll(pressList.stream().map(o -> {
2024-07-17 11:49:48 +08:00
StStatusVo vo = new StStatusVo();
vo.setStnm(o.getStationCode());
vo.setTm(o.getTm());
return vo;
}).collect(Collectors.toList()));
//渗流
List<OsmoticPressVo> flowList = pressRMapper.flowListValue();
list.addAll(flowList.stream().map(o -> {
2024-07-17 11:49:48 +08:00
StStatusVo vo = new StStatusVo();
vo.setStnm(o.getStationCode());
vo.setTm(o.getTm());
return vo;
}).collect(Collectors.toList()));
//位移
List<OsmoticShiftListVo> shiftList = shiftRMapper.listValue();
list.addAll(shiftList.stream().map(o -> {
2024-07-17 11:49:48 +08:00
StStatusVo vo = new StStatusVo();
vo.setStnm(o.getStationCode());
vo.setTm(o.getTm());
return vo;
}).collect(Collectors.toList()));
for (StStatusVo vo : list) {
2024-07-17 11:49:48 +08:00
String tm = vo.getTm();
if (StringUtils.isEmpty(tm) || DateUtil.hoursBetweenDate(DateUtil.convertStringToDate(tm), new Date()) > 24) {
2024-07-17 11:49:48 +08:00
offLineList.add(vo);
} else {
2024-07-17 11:49:48 +08:00
onLineList.add(vo);
}
}
res.setOnline(onLineList.stream().sorted(Comparator.comparing(StStatusVo::getTm, Comparator.nullsFirst(String::compareTo)).reversed()).collect(Collectors.toList()));
res.setOffLine(offLineList.stream().sorted(Comparator.comparing(StStatusVo::getTm, Comparator.nullsFirst(String::compareTo)).reversed()).collect(Collectors.toList()));
2024-07-17 11:49:48 +08:00
return res;
}
2024-09-24 13:33:32 +08:00
public List<StStatusVo> rainList() {
2024-09-24 15:23:38 +08:00
return this.baseMapper.rainList();
2024-09-24 13:33:32 +08:00
}
2025-04-01 11:24:38 +08:00
public List<StZqrlBVo> flowList(StZqrlBDto obj) {
2025-04-07 11:49:39 +08:00
/*
* 线
* 0=+*60*60
*/
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<>();
for (int i = 0; i < rsvrList.size(); i++) {
StRsvrR rsvr = rsvrList.get(i);
BigDecimal rz = new BigDecimal(rsvr.getRz());
StZqrlBVo vo = new StZqrlBVo();
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));
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);
vo.setQtotal(qTotal);
2025-04-01 11:24:38 +08:00
}
ret.add(vo);
2025-04-01 11:24:38 +08:00
}
//倒序输出
ret.sort(Comparator.comparing(StZqrlBVo::getTm).reversed());
return ret;
2025-04-01 11:24:38 +08:00
}
public StZqrlBCountVo count(Serializable stcd) {
StZqrlBCountVo vo = new StZqrlBCountVo();
vo.setStcd(stcd.toString());
2025-09-05 10:55:00 +08:00
//取出当月的时间 20xx-xx-01 00:00:00
Calendar calendar = Calendar.getInstance();
Date now = calendar.getTime();
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
2025-09-05 10:55:00 +08:00
Date monthStart = calendar.getTime();
//取本年的时间 20xx-01-01 00:00:00
calendar.set(Calendar.MONTH,0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date yearStart = calendar.getTime();
calendar.setTime(now);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date dayStart = calendar.getTime();
//查询当年水位数据
List<StRsvrR> rsvrList = rsvrRService.lambdaQuery()
.eq(StRsvrR::getStcd, stcd)
2025-09-05 10:55:00 +08:00
.between(StRsvrR::getTm, yearStart, now)
.orderByAsc(true, StRsvrR::getTm)
.list();
2025-04-01 11:24:38 +08:00
2025-09-05 10:55:00 +08:00
//获取水位流量关系
List<StZqrlB> zqrlList = stZqrlBService.list();
2025-09-05 10:55:00 +08:00
zqrlList.sort(Comparator.comparing(StZqrlB::getZ));
2025-04-01 11:24:38 +08:00
List<RsvrComplexVo> complexList = new ArrayList<>();
int idx = 0;
for (StRsvrR rsvr : rsvrList) {
RsvrComplexVo complex = new RsvrComplexVo();
BigDecimal rz = new BigDecimal(rsvr.getRz());
complex.setRz(rz);
complex.setTm(rsvr.getTm());
2025-04-01 11:24:38 +08:00
2025-09-05 10:55:00 +08:00
//TODO 这里需要重新计算水位-流量对应数据
//BigDecimal q = stZqrlBService.getQFromZqrl(rz, zqrlList);
BigDecimal q = stZqrlBService.getQByZqrl(zqrlList,rz);
complex.setQ(q);
2025-09-05 10:55:00 +08:00
//计算当前时间段溢洪量
complex.setSv(complex.getQ().multiply(BigDecimal.valueOf(60 * 60)));
// if (idx == 0) {
// complex.setSv(BigDecimal.ZERO);
// } else {
// //计算溢洪量
// RsvrComplexVo complexPrev = complexList.get(idx - 1);
// complex.setSv(complexPrev.getSv().add(complex.getQ().multiply(BigDecimal.valueOf(60 * 60))));
// }
2025-04-01 11:24:38 +08:00
complexList.add(complex);
idx++;
}
2025-04-01 11:24:38 +08:00
//当前流量
vo.setVal(complexList.getLast().getQ());
vo.setCreateTime(complexList.getLast().getTm());
2025-09-05 10:55:00 +08:00
//今日sv的和
2025-09-05 10:55:00 +08:00
BigDecimal sumToday = complexList.stream().filter(complex -> complex.getTm().after(dayStart))
.map(RsvrComplexVo::getSv)
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setCurrDayValSum(sumToday);
2025-09-05 10:55:00 +08:00
// 当月溢洪量总和(筛选本月数据)
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);
2025-04-01 11:24:38 +08:00
2025-09-05 10:55:00 +08:00
// 当年溢洪量总和(所有数据都是当年的,直接求和)
BigDecimal sumYear = complexList.stream()
.map(RsvrComplexVo::getSv)
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setCurrYearSum(sumYear);
// 计算本年溢洪次数(溢洪量>0
long overflowCount = complexList.stream()
.filter(complex -> complex.getSv().compareTo(BigDecimal.ZERO) > 0)
.count();
vo.setCurrYearCount(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) {
// 可以取前后时间点作为时间段的参考
Date startTime = complexList.get(maxIndex).getTm();
Date endTime = complexList.get(maxIndex + 1).getTm();
String period = sdf.format(startTime) + " ~ " + sdf.format(endTime);
vo.setMaxOverflowPeriod(period);
}else{
Date startTime = complexList.get(maxIndex).getTm();
String period = sdf.format(startTime) + " ~ " + sdf.format(now);
vo.setMaxOverflowPeriod(period);
}
} else {
vo.setCurrYearMaxVal(BigDecimal.ZERO);
vo.setMaxOverflowPeriod("无溢洪记录");
}
// BigDecimal maxOverflow = complexList.stream()
// .map(RsvrComplexVo::getSv)
// .max(Comparator.naturalOrder())
// .orElse(BigDecimal.ZERO);
// vo.setCurrYearMaxVal(maxOverflow);
2025-04-01 11:24:38 +08:00
return vo;
}
public StZqrlBCount24Vo count24(Serializable stcd) {
StZqrlBCount24Vo vo = new StZqrlBCount24Vo();
vo.setStcd(stcd.toString());
StRsvrR rsvrLatest = rsvrRService.lambdaQuery().eq(StRsvrR::getStcd, stcd).orderByDesc(StRsvrR::getTm).last("limit 1").one();
if (rsvrLatest == null) {
2025-04-01 11:24:38 +08:00
return vo;
}
BigDecimal rzLatest = new BigDecimal(rsvrLatest.getRz());
BigDecimal qLatest = stZqrlBService.getQFromZqrl(rzLatest);
vo.setCurrWaterLevel(rzLatest);
vo.setFlowNum(qLatest);
vo.setCreateTime(rsvrLatest.getTm());
2025-04-01 11:24:38 +08:00
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();
List<RsvrComplexVo> rsvrComplexVos = stZqrlBService.calculateSpilledVolumeList(rsvrList);
BigDecimal totalSv = rsvrComplexVos.stream().map(RsvrComplexVo::getSv).reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setSum24(totalSv);
2025-04-01 11:24:38 +08:00
return vo;
}
public List<StZqrlB> calculateQtotal(List<StZqrlB> list) {
if (list == null || list.size() < 2) {
return list;
}
// 第一条数据设为0或null
list.get(0).setQtotal(BigDecimal.ZERO);
for (int i = 1; i < list.size(); i++) {
StZqrlB current = list.get(i);
StZqrlB previous = list.get(i - 1);
// 使用Duration计算分钟差(精确到小数)
Duration duration = Duration.between(previous.getModitimeAsLocalDateTime(), current.getModitimeAsLocalDateTime());
double minutesDiff = duration.toMillis() / 60000.0; // 毫秒转分钟
// 使用BigDecimal的valueOf方法避免new BigDecimal(double)的精度问题
BigDecimal minutesDecimal = BigDecimal.valueOf(minutesDiff);
// 计算并设置qtotal
current.setQtotal(current.getQ().multiply(minutesDecimal));
}
return list;
}
private List<StZqrlB> getList(String stcd, LocalDateTime start, LocalDateTime end) {
2025-04-01 11:24:38 +08:00
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
List<StZqrlB> list = stZqrlBService.list(qw);
return list;
}
private BigDecimal sumVal(String stcd, LocalDateTime start, LocalDateTime end) {
2025-04-01 11:24:38 +08:00
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
qw.eq(StZqrlB::getStcd, stcd);
qw.ge(StZqrlB::getModitime, start);
qw.le(StZqrlB::getModitime, end);
2025-04-01 11:24:38 +08:00
List<StZqrlB> list = stZqrlBService.list(qw);
if (CollectionUtil.isNotEmpty(list)) {
return list.stream().map(StZqrlB::getQ).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
2025-04-01 11:24:38 +08:00
}
return null;
}
private Long countVal(String stcd, LocalDateTime start, LocalDateTime end) {
2025-04-01 11:24:38 +08:00
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
qw.eq(StZqrlB::getStcd, stcd);
qw.ge(StZqrlB::getModitime, start);
qw.le(StZqrlB::getModitime, end);
2025-04-01 11:24:38 +08:00
List<StZqrlB> list = stZqrlBService.list(qw);
if (CollectionUtil.isNotEmpty(list)) {
2025-04-01 11:24:38 +08:00
return list.stream().map(StZqrlB::getQ).filter(Objects::nonNull).filter(q -> q.compareTo(BigDecimal.ZERO) > 0).count();
}
return 0l;
}
private BigDecimal maxVal(String stcd, LocalDateTime start, LocalDateTime end) {
2025-04-01 11:24:38 +08:00
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
qw.eq(StZqrlB::getStcd, stcd);
qw.ge(StZqrlB::getModitime, start);
qw.le(StZqrlB::getModitime, end);
2025-04-01 11:24:38 +08:00
List<StZqrlB> list = stZqrlBService.list(qw);
if (CollectionUtil.isNotEmpty(list)) {
2025-04-01 11:24:38 +08:00
return list.stream().map(StZqrlB::getQ).filter(Objects::nonNull).max(Comparator.naturalOrder()).orElse(null);
}
return null;
}
2025-04-25 17:01:53 +08:00
public List<StStbprpB> getPptnStations() {
return baseMapper.getPptnStations();
}
public List<StStbprpB> getRsvrStations() {
return baseMapper.getRsvrStations();
}
2024-07-08 17:47:02 +08:00
}