356 lines
14 KiB
Java
356 lines
14 KiB
Java
|
|
package com.gunshi.project.hsz.service;
|
|||
|
|
|
|||
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|||
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|||
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||
|
|
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;
|
|||
|
|
import jakarta.annotation.Resource;
|
|||
|
|
import lombok.extern.slf4j.Slf4j;
|
|||
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|||
|
|
import org.springframework.stereotype.Service;
|
|||
|
|
import org.springframework.transaction.annotation.Transactional;
|
|||
|
|
|
|||
|
|
import java.io.Serializable;
|
|||
|
|
import java.math.BigDecimal;
|
|||
|
|
import java.time.Duration;
|
|||
|
|
import java.time.LocalDateTime;
|
|||
|
|
import java.util.*;
|
|||
|
|
import java.util.stream.Collectors;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 描述: sttp 以水利标准来
|
|||
|
|
* author: xusan
|
|||
|
|
* date: 2024-07-08 17:30:38
|
|||
|
|
*/
|
|||
|
|
@Service
|
|||
|
|
@Slf4j
|
|||
|
|
@Transactional(rollbackFor = Exception.class)
|
|||
|
|
public class StStbprpBService extends ServiceImpl<StStbprpBMapper, StStbprpB> {
|
|||
|
|
@Resource
|
|||
|
|
private OsmoticPressRMapper pressRMapper;
|
|||
|
|
|
|||
|
|
@Resource
|
|||
|
|
private OsmoticShiftRMapper shiftRMapper;
|
|||
|
|
|
|||
|
|
@Autowired
|
|||
|
|
private StZqrlBService stZqrlBService;
|
|||
|
|
|
|||
|
|
@Autowired
|
|||
|
|
private StZvarlBService stZvarlBService;
|
|||
|
|
|
|||
|
|
@Autowired
|
|||
|
|
private StRsvrRService rsvrRService;
|
|||
|
|
|
|||
|
|
public List<HomeStStbprpBVo> rainfallStationDetailsList(HomeStStbprpBSo dto) {
|
|||
|
|
return baseMapper.rainfallStationDetailsList(dto);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<HomeStStbprpBVo> reservoirStationDetailsList() {
|
|||
|
|
return baseMapper.reservoirStationDetailsList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<HomeStStbprpBVo> flowStationDetailsList() {
|
|||
|
|
return baseMapper.flowStationDetailsList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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();
|
|||
|
|
//图像站
|
|||
|
|
List<StStatusVo> imgList = baseMapper.imgList();
|
|||
|
|
rainList.addAll(rzList);
|
|||
|
|
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
|
|||
|
|
)).values().stream().collect(Collectors.toList());
|
|||
|
|
for (StStatusVo statusVo : rainList) {
|
|||
|
|
String tm = statusVo.getTm();
|
|||
|
|
if (StringUtils.isEmpty(tm) || DateUtil.hoursBetweenDate(DateUtil.convertStringToDate(tm), new Date()) > 2) {
|
|||
|
|
offLineList.add(statusVo);
|
|||
|
|
} else {
|
|||
|
|
onLineList.add(statusVo);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//渗压
|
|||
|
|
List<OsmoticPressVo> pressList = pressRMapper.listValue();
|
|||
|
|
list.addAll(pressList.stream().map(o -> {
|
|||
|
|
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 -> {
|
|||
|
|
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 -> {
|
|||
|
|
StStatusVo vo = new StStatusVo();
|
|||
|
|
vo.setStnm(o.getStationCode());
|
|||
|
|
vo.setTm(o.getTm());
|
|||
|
|
return vo;
|
|||
|
|
}).collect(Collectors.toList()));
|
|||
|
|
|
|||
|
|
for (StStatusVo vo : list) {
|
|||
|
|
String tm = vo.getTm();
|
|||
|
|
if (StringUtils.isEmpty(tm) || DateUtil.hoursBetweenDate(DateUtil.convertStringToDate(tm), new Date()) > 24) {
|
|||
|
|
offLineList.add(vo);
|
|||
|
|
} else {
|
|||
|
|
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()));
|
|||
|
|
return res;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<StStatusVo> rainList() {
|
|||
|
|
return this.baseMapper.rainList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<StZqrlBVo> flowList(StZqrlBDto obj) {
|
|||
|
|
/*
|
|||
|
|
* 查出时段内的水位列表,按时间升序排,根据水位查水位流量曲线表得到流量
|
|||
|
|
* 第一条数据的累计溢洪量设为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);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ret.add(vo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//倒序输出
|
|||
|
|
ret.sort(Comparator.comparing(StZqrlBVo::getTm).reversed());
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public StZqrlBCountVo count(Serializable stcd) {
|
|||
|
|
StZqrlBCountVo vo = new StZqrlBCountVo();
|
|||
|
|
vo.setStcd(stcd.toString());
|
|||
|
|
|
|||
|
|
//取出当月的水位
|
|||
|
|
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);
|
|||
|
|
List<StRsvrR> rsvrList = rsvrRService.lambdaQuery()
|
|||
|
|
.eq(StRsvrR::getStcd, stcd)
|
|||
|
|
.between(StRsvrR::getTm, calendar.getTime(), now)
|
|||
|
|
.orderByAsc(true, StRsvrR::getTm)
|
|||
|
|
.list();
|
|||
|
|
|
|||
|
|
List<StZqrlB> zqrlList = stZqrlBService.list();
|
|||
|
|
|
|||
|
|
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());
|
|||
|
|
|
|||
|
|
BigDecimal q = stZqrlBService.getQFromZqrl(rz, zqrlList);
|
|||
|
|
complex.setQ(q);
|
|||
|
|
if (idx == 0) {
|
|||
|
|
complex.setSv(BigDecimal.ZERO);
|
|||
|
|
} else {
|
|||
|
|
RsvrComplexVo complexPrev = complexList.get(idx - 1);
|
|||
|
|
complex.setSv(complexPrev.getSv().add(complexPrev.getQ().multiply(BigDecimal.valueOf(60 * 60))));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
complexList.add(complex);
|
|||
|
|
idx++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//当前流量
|
|||
|
|
vo.setVal(complexList.getLast().getQ());
|
|||
|
|
vo.setCreateTime(complexList.getLast().getTm());
|
|||
|
|
|
|||
|
|
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 today = calendar.getTime();
|
|||
|
|
//今日sv的和
|
|||
|
|
BigDecimal sumToday = complexList.stream().filter(complex -> complex.getTm().after(today))
|
|||
|
|
.map(RsvrComplexVo::getSv)
|
|||
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|||
|
|
vo.setCurrDayValSum(sumToday);
|
|||
|
|
//当月sv的和
|
|||
|
|
BigDecimal sumMonth = complexList.stream().map(RsvrComplexVo::getSv)
|
|||
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|||
|
|
vo.setCurrMonthSum(sumMonth);
|
|||
|
|
|
|||
|
|
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) {
|
|||
|
|
return vo;
|
|||
|
|
}
|
|||
|
|
BigDecimal rzLatest = new BigDecimal(rsvrLatest.getRz());
|
|||
|
|
BigDecimal qLatest = stZqrlBService.getQFromZqrl(rzLatest);
|
|||
|
|
vo.setCurrWaterLevel(rzLatest);
|
|||
|
|
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();
|
|||
|
|
List<RsvrComplexVo> rsvrComplexVos = stZqrlBService.calculateSpilledVolumeList(rsvrList);
|
|||
|
|
BigDecimal totalSv = rsvrComplexVos.stream().map(RsvrComplexVo::getSv).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|||
|
|
vo.setSum24(totalSv);
|
|||
|
|
|
|||
|
|
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) {
|
|||
|
|
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
|
|||
|
|
List<StZqrlB> list = stZqrlBService.list(qw);
|
|||
|
|
return list;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private BigDecimal sumVal(String stcd, LocalDateTime start, LocalDateTime end) {
|
|||
|
|
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
|
|||
|
|
qw.eq(StZqrlB::getStcd, stcd);
|
|||
|
|
qw.ge(StZqrlB::getModitime, start);
|
|||
|
|
qw.le(StZqrlB::getModitime, end);
|
|||
|
|
List<StZqrlB> list = stZqrlBService.list(qw);
|
|||
|
|
if (CollectionUtil.isNotEmpty(list)) {
|
|||
|
|
return list.stream().map(StZqrlB::getQ).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private Long countVal(String stcd, LocalDateTime start, LocalDateTime end) {
|
|||
|
|
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
|
|||
|
|
qw.eq(StZqrlB::getStcd, stcd);
|
|||
|
|
qw.ge(StZqrlB::getModitime, start);
|
|||
|
|
qw.le(StZqrlB::getModitime, end);
|
|||
|
|
List<StZqrlB> list = stZqrlBService.list(qw);
|
|||
|
|
if (CollectionUtil.isNotEmpty(list)) {
|
|||
|
|
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) {
|
|||
|
|
LambdaQueryWrapper<StZqrlB> qw = new LambdaQueryWrapper();
|
|||
|
|
qw.eq(StZqrlB::getStcd, stcd);
|
|||
|
|
qw.ge(StZqrlB::getModitime, start);
|
|||
|
|
qw.le(StZqrlB::getModitime, end);
|
|||
|
|
List<StZqrlB> list = stZqrlBService.list(qw);
|
|||
|
|
if (CollectionUtil.isNotEmpty(list)) {
|
|||
|
|
return list.stream().map(StZqrlB::getQ).filter(Objects::nonNull).max(Comparator.naturalOrder()).orElse(null);
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<StStbprpB> getPptnStations() {
|
|||
|
|
return baseMapper.getPptnStations();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public List<StStbprpB> getRsvrStations() {
|
|||
|
|
return baseMapper.getRsvrStations();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|