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 list() { List 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 queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByAsc(StZvarlB::getRz); List 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 zvarlList = queryZval(attResBaseVos.stream().map(AttResBaseVo::getStcd).collect(Collectors.toList())); // Map> zvalMap = zvarlList.stream().collect(Collectors.groupingBy(StZvarlB::getStcd)); // for(AttResBaseVo vo : attResBaseVos){ // String stcd = vo.getStcd(); // BigDecimal rz = vo.getRz(); // //计算当前库容 // List 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 stZvalMap = zvarlBS.stream().collect(Collectors.toMap(StZvarlB::getRz, StZvarlB::getW)); // List list = zvarlBS.stream().map(StZvarlB::getRz).sorted().collect(Collectors.toList()); // vo.setNowCap(DataHandleUtil.calcData(rz,stZvalMap,list)); // } // } return attResBaseVos; } public List listV2() { List voList = attResBaseMapper.queryListV2(); if(CollectionUtils.isEmpty(voList)){ return voList; } List 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 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 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 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 listV22() { List voList = attResBaseMapper.queryListV2(); if(CollectionUtils.isEmpty(voList)){ return voList; } List 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 irrQw1 = new QueryWrapper<>(); irrQw1.eq("stcd", stcd1).orderBy(true, false, "tm"); StWaterRReal stWaterRReal1 = stWaterRRealService.getOne(irrQw1); String stcd2 = "1113"; QueryWrapper 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 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 queryZval(List stcdList) { LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.in(StZvarlB::getStcd, stcdList); return stZvarlBMapper.selectList(queryWrapper); } public List realImg(ReservoirWaterCommonSo reservoirWaterCommonSo) { return attResBaseMapper.realImg(reservoirWaterCommonSo.getResCode()); } public List zvarl(String stcd) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByAsc(StZvarlB::getRz); return stZvarlBMapper.selectList(queryWrapper); } public List monitorData(DataQueryCommonSo dataQueryCommonSo) { String stcd = dataQueryCommonSo.getStcd(); //雨量数据 List drpData = attResBaseMapper.drpData(dataQueryCommonSo); //水位数据 List rzData = attResBaseMapper.rzData(dataQueryCommonSo); //获取库容曲线关系,算出库容 List 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 rzData, List zqrl) { /* 前期库容曲线数据不足,采用了计算近似值,废弃,直接查表 BigDecimal maxRz = zqrl.stream().max(Comparator.comparing(StZvarlB::getRz)).get().getRz(); BigDecimal minRz = zqrl.stream().min(Comparator.comparing(StZvarlB::getRz)).get().getRz(); Map 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 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值做key,bigdecimal的精度设置为3位 Map 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 bindData(String stcd, List drpData, List 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 channel(String resCode) { return attResBaseMapper.channel(resCode); } public Page imageInfo(PicQuerySo picQuerySo) { return attResBaseMapper.imageInfo(picQuerySo.getPageSo().toPage(),picQuerySo); } public List data(DataQueryCommonSo dataQueryCommonSo) { String stcd = dataQueryCommonSo.getStcd(); //水位数据 List rzData = attResBaseMapper.rzData(dataQueryCommonSo); //获取库容曲线关系,算出库容 List zvarl = zvarl(stcd); if(CollectionUtils.isNotEmpty(zvarl)){ calcTqData(rzData,zvarl); } return rzData; } public Page dataPage(PicQuerySo picQuerySo) { String stcd = picQuerySo.getStcd(); //水位数据 Page rzData = attResBaseMapper.rzDataPage(picQuerySo.getPageSo().toPage(),picQuerySo); //获取库容曲线关系,算出库容 List zvarl = zvarl(stcd); if(CollectionUtils.isNotEmpty(zvarl)){ calcTqData(rzData.getRecords(),zvarl); } return rzData; } public List listV3() { String stcd = "199999"; List voList = attResBaseMapper.queryYhd(stcd); return voList; } }