gunshi-project-ss/src/main/java/com/gunshi/project/ss/service/ReservoirWaterService.java

497 lines
21 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.gunshi.project.ss.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.project.ss.common.model.StStbprpB;
import com.gunshi.project.ss.entity.so.DataQueryCommonSo;
import com.gunshi.project.ss.entity.so.PicQuerySo;
import com.gunshi.project.ss.entity.so.ReservoirWaterCommonSo;
import com.gunshi.project.ss.entity.vo.*;
import com.gunshi.project.ss.mapper.AttResBaseMapper;
import com.gunshi.project.ss.mapper.StZvarlBMapper;
import com.gunshi.project.ss.model.*;
import com.gunshi.project.ss.util.DateUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
/**
* Description:
* Created by wanyan on 2024/7/8
*
* @author wanyan
* @version 1.0
*/
@Service
@Slf4j
public class ReservoirWaterService {
@Resource
private AttResBaseMapper attResBaseMapper;
@Resource
private StZvarlBMapper stZvarlBMapper;
@Resource
private RainBasinDivisionService rainBasinDivisionService;
@Autowired
private StZvarlBService stZvarlBService;
@Autowired
private StRiverRRealService stRiverRRealServices;
//实时供水
@Autowired
private StWaterRRealService stWaterRRealService;
public List<AttResBaseVo> list() {
List<AttResBaseVo> attResBaseVos = attResBaseMapper.queryList();
if(CollectionUtils.isEmpty(attResBaseVos)){
return attResBaseVos;
}
attResBaseVos.stream().map(o->{
if(o.getCalState() == 1){
o.setDesState(0);
o.setFlState(0);
}else if(o.getCalState() == 0 && o.getDesState() ==1){
o.setFlState(0);
}
return o;
}).collect(Collectors.toList());
for (AttResBaseVo vo : attResBaseVos) {
BigDecimal rz = vo.getRz();
LambdaQueryWrapper<StZvarlB> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByAsc(StZvarlB::getRz);
List<StZvarlB> zvarlList = stZvarlBMapper.selectList(queryWrapper);
BigDecimal w = stZvarlBService.getWByZvarl(zvarlList, rz);
vo.setNowCap(w);
// for (StZvarlB zvarl : zvarlList) {
// if (zvarl.getRz().equals(rz)) {
// vo.setNowCap(zvarl.getW());
// break;
// }
// }
}
//查询所有测站的库容曲线
// List<StZvarlB> zvarlList = queryZval(attResBaseVos.stream().map(AttResBaseVo::getStcd).collect(Collectors.toList()));
// Map<String, List<StZvarlB>> zvalMap = zvarlList.stream().collect(Collectors.groupingBy(StZvarlB::getStcd));
// for(AttResBaseVo vo : attResBaseVos){
// String stcd = vo.getStcd();
// BigDecimal rz = vo.getRz();
// //计算当前库容
// List<StZvarlB> zvarlBS = zvalMap.get(stcd);
// if(rz != null && CollectionUtils.isNotEmpty(zvarlBS)){
// BigDecimal maxRz = zvarlBS.stream().max(Comparator.comparing(StZvarlB::getRz)).get().getRz();
// BigDecimal minRz = zvarlBS.stream().min(Comparator.comparing(StZvarlB::getRz)).get().getRz();
// if(rz.compareTo(minRz) < 0 || rz.compareTo(maxRz) > 0){
// //当期水位库容
// StZvarlB equals = zvarlBS.stream().filter(e -> e.getRz().compareTo(vo.getRz()) == 0).findFirst().orElse(new StZvarlB());
// //死水位库容
// StZvarlB dead = zvarlBS.stream().filter(e -> e.getRz().compareTo(vo.getDeadCap()) == 0).findFirst().orElse(new StZvarlB());
// if(Objects.nonNull(equals) && Objects.nonNull(dead)){
// BigDecimal subtract = equals.getW().subtract(dead.getW());
// vo.setNowCap(subtract);
// }
// continue;
// }
// Map<BigDecimal, BigDecimal> stZvalMap = zvarlBS.stream().collect(Collectors.toMap(StZvarlB::getRz, StZvarlB::getW));
// List<BigDecimal> list = zvarlBS.stream().map(StZvarlB::getRz).sorted().collect(Collectors.toList());
// vo.setNowCap(DataHandleUtil.calcData(rz,stZvalMap,list));
// }
// }
return attResBaseVos;
}
public List<AttResBaseVo> listV2() {
List<AttResBaseVo> voList = attResBaseMapper.queryListV2();
if(CollectionUtils.isEmpty(voList)){
return voList;
}
List<StZvarlB> zvarlList = stZvarlBService.list();
zvarlList.sort(Comparator.comparing(StZvarlB::getRz));
voList.forEach(vo -> {
if(vo.getCalState() == 1){
vo.setDesState(0);
vo.setFlState(0);
}else if(vo.getCalState() == 0 && vo.getDesState() ==1){
vo.setFlState(0);
}
BigDecimal rz = vo.getRz();
if (rz != null) {
//BigDecimal w = stZvarlBService.getWFromZvarl(rz, null, zvarlList);
BigDecimal w = stZvarlBService.getWByZvarl(zvarlList,rz);
vo.setNowCap(w);
}
Date tm = vo.getTm();
if(tm != null && DateUtil.hoursBetweenDate(tm,new Date()) > 24){
vo.setStatus(0);
}else if(tm == null){
vo.setStatus(0);
}else{
vo.setStatus(1);
}
});
//TODO 计算2个灌溉站的流量之和
BigDecimal totalSum = BigDecimal.ZERO;
String stcd1 = "1112";
QueryWrapper<StWaterRReal> irrQw1 = new QueryWrapper<>();
irrQw1.eq("stcd", stcd1).orderBy(true, false, "tm");
StWaterRReal stWaterRReal1 = stWaterRRealService.getOne(irrQw1);
if(stWaterRReal1 != null){
totalSum = totalSum.add(stWaterRReal1.getQ());
}
String stcd2 = "1113";
QueryWrapper<StWaterRReal> irrQw2 = new QueryWrapper<>();
irrQw2.eq("stcd", stcd2).orderBy(true, false, "tm");
StWaterRReal stWaterRReal2 = stWaterRRealService.getOne(irrQw2);
if(stWaterRReal2 != null){
totalSum = totalSum.add(stWaterRReal2.getQ());
}
for (AttResBaseVo attResBaseVo : voList) {
//设置灌溉流量
attResBaseVo.setIrrigationFlowSum(totalSum);
//设置灌溉流量时间
if(stWaterRReal1 != null){
attResBaseVo.setIrrigationFlowTm(stWaterRReal1.getTm());
}else if(stWaterRReal2 != null){
attResBaseVo.setIrrigationFlowTm(stWaterRReal2.getTm());
}
}
//获取新建生态供水流量站最新得流量
String ecologyStcd = "1114";
QueryWrapper<StWaterRReal> ecologyQw = new QueryWrapper<>();
ecologyQw.eq("stcd", ecologyStcd).orderBy(true, false, "tm");
StWaterRReal ecologyWaterRReal = stWaterRRealService.getOne(ecologyQw);
if(ecologyWaterRReal != null){
voList.stream().forEach(o -> {
o.setEcologyFlow(ecologyWaterRReal.getQ());
o.setEcologyFlowTm(ecologyWaterRReal.getTm());
});
}
return voList;
}
public List<AttResBaseVo> listV22() {
List<AttResBaseVo> voList = attResBaseMapper.queryListV2();
if(CollectionUtils.isEmpty(voList)){
return voList;
}
List<StZvarlB> zvarlList = stZvarlBService.list();
zvarlList.sort(Comparator.comparing(StZvarlB::getRz));
voList.forEach(vo -> {
if(vo.getCalState() == 1){
vo.setDesState(0);
vo.setFlState(0);
}else if(vo.getCalState() == 0 && vo.getDesState() ==1){
vo.setFlState(0);
}
//如果最新数据时间小于当前时间整点,那么不显示水位数据(他妈的,很多功能都是复用一个接口的,说实话,不知道以前的人怎么设计的,就单一责任原则不好吗,非得复用代码,这下搞得需求有变更的情况下,一个页面改好了,另一个页面又会出现问题,真是服了)
Date tm = vo.getTm();
BigDecimal rz = vo.getRz();
// 获取当前时间整点(去掉分钟和秒)
Calendar now = Calendar.getInstance();
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
Date currentHour = now.getTime();
if(tm != null && tm.before(currentHour)){
vo.setRz(null);
vo.setTm(null);
vo.setDrpTm(null);
}else if (tm != null && rz != null){
if (rz != null) {
//BigDecimal w = stZvarlBService.getWFromZvarl(rz, null, zvarlList);
BigDecimal w = stZvarlBService.getWByZvarl(zvarlList,rz);
vo.setNowCap(w);
}
}
});
Calendar now = Calendar.getInstance();
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
Date currentHour = now.getTime();
//TODO 计算2个灌溉站的流量之和
BigDecimal totalSum = null;
String stcd1 = "1112";
QueryWrapper<StWaterRReal> irrQw1 = new QueryWrapper<>();
irrQw1.eq("stcd", stcd1).orderBy(true, false, "tm");
StWaterRReal stWaterRReal1 = stWaterRRealService.getOne(irrQw1);
String stcd2 = "1113";
QueryWrapper<StWaterRReal> irrQw2 = new QueryWrapper<>();
irrQw2.eq("stcd", stcd2).orderBy(true, false, "tm");
StWaterRReal stWaterRReal2 = stWaterRRealService.getOne(irrQw2);
if(stWaterRReal1 != null ){
Date tm1 = stWaterRReal1.getTm();
if(tm1 != null && !tm1.before(currentHour)){
totalSum = BigDecimal.ZERO;
totalSum = totalSum.add(stWaterRReal1.getQ());
}
}
if(stWaterRReal2 != null){
Date tm2 = stWaterRReal2.getTm();
if(tm2 != null && !tm2.before(currentHour)){
if(totalSum == null){
totalSum = BigDecimal.ZERO;
}
totalSum = totalSum.add(stWaterRReal2.getQ());
}
}
for (AttResBaseVo attResBaseVo : voList) {
//设置灌溉流量
attResBaseVo.setIrrigationFlowSum(totalSum);
//设置灌溉流量时间
if(stWaterRReal1 != null){
attResBaseVo.setIrrigationFlowTm(stWaterRReal1.getTm());
}else if(stWaterRReal2 != null){
attResBaseVo.setIrrigationFlowTm(stWaterRReal2.getTm());
}
if(totalSum == null){
attResBaseVo.setIrrigationFlowTm(null);
}
}
//获取新建生态供水流量站最新得流量
String ecologyStcd = "1114";
QueryWrapper<StWaterRReal> ecologyQw = new QueryWrapper<>();
ecologyQw.eq("stcd", ecologyStcd).orderBy(true, false, "tm");
StWaterRReal ecologyWaterRReal = stWaterRRealService.getOne(ecologyQw);
if(ecologyWaterRReal != null){
Date tm = ecologyWaterRReal.getTm();
if(tm != null && !tm.before(currentHour)){
voList.stream().forEach(o -> {
o.setEcologyFlow(ecologyWaterRReal.getQ());
o.setEcologyFlowTm(ecologyWaterRReal.getTm());
});
}
}
return voList;
}
private List<StZvarlB> queryZval(List<String> stcdList) {
LambdaQueryWrapper<StZvarlB> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.in(StZvarlB::getStcd, stcdList);
return stZvarlBMapper.selectList(queryWrapper);
}
public List<StImgRReal> realImg(ReservoirWaterCommonSo reservoirWaterCommonSo) {
return attResBaseMapper.realImg(reservoirWaterCommonSo.getResCode());
}
public List<StZvarlB> zvarl(String stcd) {
LambdaQueryWrapper<StZvarlB> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByAsc(StZvarlB::getRz);
return stZvarlBMapper.selectList(queryWrapper);
}
public List<AttResMonitorVo> monitorData(DataQueryCommonSo dataQueryCommonSo) {
String stcd = dataQueryCommonSo.getStcd();
//雨量数据
List<AttResMonitorVo> drpData = attResBaseMapper.drpData(dataQueryCommonSo);
//水位数据
List<AttResMonitorVo> rzData = attResBaseMapper.rzData(dataQueryCommonSo);
//获取库容曲线关系,算出库容
List<StZvarlB> zvarl = zvarl(stcd);
if(CollectionUtils.isNotEmpty(zvarl)){
//calcTqData(rzData,zvarl);
rzData.stream().forEach(o -> {
BigDecimal w = stZvarlBService.getWByZvarl(zvarl, o.getRz());
o.setW(w);
});
}
//根据监测时间合并雨量和水位数据
return bindData(stcd,drpData,rzData);
}
private void calcTqData(List<AttResMonitorVo> rzData, List<StZvarlB> zqrl) {
/* 前期库容曲线数据不足,采用了计算近似值,废弃,直接查表
BigDecimal maxRz = zqrl.stream().max(Comparator.comparing(StZvarlB::getRz)).get().getRz();
BigDecimal minRz = zqrl.stream().min(Comparator.comparing(StZvarlB::getRz)).get().getRz();
Map<BigDecimal, BigDecimal> map = zqrl.stream().collect(Collectors.toMap(StZvarlB::getRz, StZvarlB::getW,
(existing, replacement) -> existing));
* 根据监测水位和库容曲线计算出当前库容
* 计算规则1.监测水位不在库容曲线范围内,无法计算当前库容
* 2.找出与监测水位最接近的一组水位值算出比例根据比例计算库容如监测水位为10最相近的一组水位值为9-11对应的库容为4-5
* 则计算公式为1/2 = x/1 x=0.5 当前库容=4+0.5=4.5
List<BigDecimal> list = zqrl.stream().map(StZvarlB::getRz).collect(Collectors.toList());
for (AttResMonitorVo vo : rzData) {
BigDecimal rz = vo.getRz();
if (rz.compareTo(minRz) < 0 || rz.compareTo(maxRz) > 0) {
continue;
}
vo.setW(DataHandleUtil.calcData(rz, map, list));
}
*/
//zqrl转map用rz值做keybigdecimal的精度设置为3位
Map<BigDecimal, BigDecimal> map = zqrl.stream().collect(Collectors.toMap(v -> v.getRz().setScale(3, RoundingMode.UNNECESSARY), v -> v.getW()));
for (AttResMonitorVo vo : rzData) {
BigDecimal rz = vo.getRz().setScale(3, RoundingMode.UNNECESSARY);
if (map.containsKey(rz)) {
vo.setW(map.get(rz));
}
}
}
private List<AttResMonitorVo> bindData(String stcd, List<AttResMonitorVo> drpData, List<AttResMonitorVo> rzData) {
// 以水位数据的时间为基准(过五分钟的数据)
return rzData.stream().map(rzVo -> {
AttResMonitorVo resultVo = AttResMonitorVo.builder()
.stcd(stcd)
.tm(rzVo.getTm()) // 使用水位数据的时间
.rz(rzVo.getRz())
.w(rzVo.getW())
.build();
// 为这个水位时间点查找最接近的降水数据
drpData.stream()
.min(Comparator.comparing(drpVo -> Math.abs(rzVo.getTm().getTime() - drpVo.getTm().getTime())))
.ifPresent(closestDrp -> {
long timeDiff = Math.abs(rzVo.getTm().getTime() - closestDrp.getTm().getTime());
if (timeDiff <= 30 * 60 * 1000) { // 30分钟容差
resultVo.setDrp(closestDrp.getDrp());
}
});
return resultVo;
})
.sorted(Comparator.comparing(AttResMonitorVo::getTm).reversed())
.collect(Collectors.toList());
}
public StRsvrVo rz(ReservoirWaterCommonSo reservoirWaterCommonSo) {
StRsvrVo vo = new StRsvrVo();
String resCode = reservoirWaterCommonSo.getResCode();
AttResBase attResBase = attResBaseMapper.selectById(resCode);
vo.setFlLowLimLev(attResBase.getFlLowLimLev());
//默认查询近一周水位
String endTime = DateUtil.convertDateToMDSString(new Date());
String startTime = DateUtil.getMinusTime(endTime, 7 * 24);
vo.setList(attResBaseMapper.queryRzList(attResBase.getStcd(),startTime,endTime));
return vo;
}
public AttRvMonitorDetailVo detail(String stcd) {
AttRvMonitorDetailVo vo = new AttRvMonitorDetailVo();
StPptnDetailsVo stPptnDetailsVo = rainBasinDivisionService.queryStPptnDetailsByStcd(stcd);
BeanUtils.copyProperties(stPptnDetailsVo,vo,AttRvMonitorDetailVo.class);
//最新水位
AttResMonitorVo monitorVo = attResBaseMapper.latestRz(stcd);
if(monitorVo == null){
return vo;
}
Date tm = monitorVo.getTm();
BigDecimal rz = monitorVo.getRz();
// 判断最新水位时间是否是今天
LocalDateTime nowTime = LocalDateTime.now();
LocalDateTime latestTime = LocalDateTime.ofInstant(tm.toInstant(), ZoneId.systemDefault());
boolean isToday = latestTime.toLocalDate().equals(nowTime.toLocalDate());
if(isToday){
//最新水位时间往前推24小时水位
LocalDateTime now = LocalDateTime.ofInstant(tm.toInstant(), ZoneId.systemDefault());
LocalDateTime dateTime = now.minusDays(1);
BigDecimal oldRz = attResBaseMapper.oldRz(stcd,2,Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant()),Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
if(oldRz != null){
vo.setRzDiff(rz.subtract(oldRz));
}
}else{
vo.setRzDiff(null);
}
//本年最高水位
BigDecimal maxYearRz = queryYearRzByStcdAndTime(stcd);
vo.setMaxRz(maxYearRz);
return vo;
}
private BigDecimal queryYearRzByStcdAndTime(String stcd) {
LocalDateTime now = LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());
LocalDateTime startTime;
LocalDateTime endTime;
if (now.getHour() >= 8 || (now.getHour() < 8 && now.getMonthValue() > 1) || (now.getHour() < 8 && now.getMonthValue() == 1 && now.getDayOfMonth() >= 1)){
startTime = LocalDateTime.of(
now.getYear(),
1,
1,
8,
0,
0
);
endTime = now;
return attResBaseMapper.queryMaxRzByStcdAndTime(stcd,Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()), Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
}
return new BigDecimal(0);
}
public List<StStbprpB> channel(String resCode) {
return attResBaseMapper.channel(resCode);
}
public Page<StImgR> imageInfo(PicQuerySo picQuerySo) {
return attResBaseMapper.imageInfo(picQuerySo.getPageSo().toPage(),picQuerySo);
}
public List<AttResMonitorVo> data(DataQueryCommonSo dataQueryCommonSo) {
String stcd = dataQueryCommonSo.getStcd();
//水位数据
List<AttResMonitorVo> rzData = attResBaseMapper.rzData(dataQueryCommonSo);
//获取库容曲线关系,算出库容
List<StZvarlB> zvarl = zvarl(stcd);
if(CollectionUtils.isNotEmpty(zvarl)){
calcTqData(rzData,zvarl);
}
return rzData;
}
public Page<AttResMonitorVo> dataPage(PicQuerySo picQuerySo) {
String stcd = picQuerySo.getStcd();
//水位数据
Page<AttResMonitorVo> rzData = attResBaseMapper.rzDataPage(picQuerySo.getPageSo().toPage(),picQuerySo);
//获取库容曲线关系,算出库容
List<StZvarlB> zvarl = zvarl(stcd);
if(CollectionUtils.isNotEmpty(zvarl)){
calcTqData(rzData.getRecords(),zvarl);
}
return rzData;
}
public List<AttResBaseVo> listV3() {
String stcd = "199999";
List<AttResBaseVo> voList = attResBaseMapper.queryYhd(stcd);
return voList;
}
}