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

965 lines
42 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.hsz.service;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.db.dto.DateTimeRangeSo;
import com.gunshi.project.hsz.common.model.JcskSyR;
import com.gunshi.project.hsz.common.model.vo.*;
import com.gunshi.project.hsz.entity.dto.ArtificialJcskSyDeleteDto;
import com.gunshi.project.hsz.common.model.so.JcskSyRPageSo;
import com.gunshi.project.hsz.common.model.so.OsmoticDetailQuerySo;
import com.gunshi.project.hsz.common.model.so.OsmoticQuerySo;
import com.gunshi.project.hsz.entity.dto.ProjectSafeCalculateDto;
import com.gunshi.project.hsz.entity.vo.*;
import com.gunshi.project.hsz.common.mapper.JcskSlBMapper;
import com.gunshi.project.hsz.mapper.JcskSyREightAmMapper;
import com.gunshi.project.hsz.common.mapper.JcskSyRMapper;
import com.gunshi.project.hsz.common.model.JcskSyB;
import com.gunshi.project.hsz.model.*;
import com.gunshi.project.hsz.util.*;
import com.ruoyi.common.utils.StringUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class JcskSyRService extends ServiceImpl<JcskSyRMapper, JcskSyR> {
@Autowired
private JcskSyBService jcskSyBService;
@Autowired
private JcskGnssRService jcskGnssRService;
@Autowired
private JcskSlBMapper jcskSlBMapper;
@Autowired
private AttDamProfileService attDamProfileService;
@Autowired
private JcskSyREightAmMapper jcskSyREightAmMapper;
@Autowired
private SyRegressionDataService syRegressionDataService;
@Autowired
private SyDataCheckRuleService syDataCheckRuleService;
public Page<JcskSyR> pageQuery(JcskSyRPageSo page) {
Page<JcskSyR> res = this.baseMapper.queryPage(page.getPageSo().toPage(),page);
return res;
}
// 使用更现代的日期时间API
private Date parseDateSafe(String dateStr) {
if (dateStr == null) return null;
// 移除可能的时区信息
dateStr = dateStr.replace("T", " ").split("\\.")[0];
try {
LocalDateTime localDateTime = LocalDateTime.parse(dateStr,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
} catch (Exception e) {
try {
LocalDate localDate = LocalDate.parse(dateStr,
DateTimeFormatter.ofPattern("yyyy-MM-dd"));
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
} catch (Exception e2) {
throw new RuntimeException("无法解析日期: " + dateStr, e2);
}
}
}
public List<JcskSyRVo> listValue(Integer type) {
List<JcskSyRVo> list;
try {
if(type == 1){
list = baseMapper.listValue();
}else {
list = jcskSlBMapper.listValue();
//list = baseMapper.flowListValue();
}
OsmoticQuerySo so = new OsmoticQuerySo();
List<String> stationCodes = list.stream().map(JcskSyRVo::getStationCode).collect(Collectors.toList());
if(list.stream().filter(o->o.getTm() != null).collect(Collectors.toList()).size() > 0 ){
String maxTm = list.stream().filter(o->o.getTm() != null).max(Comparator.comparing(JcskSyRVo::getTm)).get().getTm().toString();
String minTm = list.stream().filter(o->o.getTm() != null).min(Comparator.comparing(JcskSyRVo::getTm)).get().getTm().toString();
so.setStationCodes(stationCodes);
DateTimeRangeSo dateTimeRangeSo = new DateTimeRangeSo();
dateTimeRangeSo.setStart(parseDateSafe(minTm));
dateTimeRangeSo.setEnd(parseDateSafe(maxTm));
so.setDateTimeRangeSo(dateTimeRangeSo);
List<OsmoticValueVo2> warnList = baseMapper.queryWarn(so);
list.stream().map(o->{
if(o.getTm() != null && DateUtil.hoursBetweenDate(parseDateSafe(o.getTm().toString()), new Date()) > 48){
o.setFlag(1);
}
Boolean b = warnList.stream().filter(t->t.getStationCode().equals(o.getStationCode()) && t.getTm().equals(o.getTm())).findAny().isPresent();
if(b){
o.setStatus(1);
}
String stationCode = o.getStationCode();
LambdaQueryWrapper<JcskSyB> wq = new LambdaQueryWrapper();
wq.eq(JcskSyB::getDvcd, stationCode);
List<JcskSyB> jcskSyBS = jcskSyBService.list(wq);
if(!jcskSyBS.isEmpty()){
o.setProfileName(jcskSyBS.get(0).getDm().toString());
}
return o;
}).collect(Collectors.toList());
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return list;
}
public List<OsmoticPressDetailVo> detailValue(OsmoticDetailQuerySo so) {
List<OsmoticPressDetailVo> list;
if(so.getType() == 1){
list = baseMapper.detailValue(so);
}else{
list = jcskSlBMapper.detailValue(so);
}
if(so.getType() == 2){
return list;
}
OsmoticQuerySo osmoticQuerySo = new OsmoticQuerySo();
BeanUtils.copyProperties(so,osmoticQuerySo);
List<StRzVo> stRzVos = baseMapper.queryLineRz(osmoticQuerySo,jcskGnssRService.getStcd());
return bindPressDetail(list,stRzVos);
}
/**
* 将时间转换为整点时间
* 例如2024-10-14 15:30:00 → 2024-10-14 15:00:00
* 2024-10-14 15:45:25 → 2024-10-14 15:00:00
*/
private String getHourTime(String timeStr) {
try {
if (timeStr == null || timeStr.length() < 16) {
return timeStr;
}
// 假设时间格式为 "yyyy-MM-dd HH:mm:ss"
// 取到小时部分分钟和秒设为00
return timeStr.substring(0, 14) + "00:00";
} catch (Exception e) {
return timeStr;
}
}
private List<OsmoticPressDetailVo> bindPressDetail(List<OsmoticPressDetailVo> list, List<StRzVo> stRzVos) {
HashSet<String> timeSet = new HashSet<>();
list.forEach(v -> timeSet.add(v.getTm()));
stRzVos.forEach(v -> timeSet.add(v.getTm()));
List<OsmoticPressDetailVo> result = new ArrayList<>();
timeSet.forEach(time -> {
OsmoticPressDetailVo vo = new OsmoticPressDetailVo();
vo.setTm(time);
result.add(vo);
});
List<OsmoticPressDetailVo> resList = result.stream().map(vo -> {
// 查询库水位数据:如果时间不是整点,使用整点时间查询
String hourTimeForRz = getHourTime(vo.getTm());
stRzVos.stream()
.filter(rz -> hourTimeForRz.equals(rz.getTm()))
.findFirst()
.ifPresent(rz -> vo.setRz(rz.getRz()));
// 匹配压力数据:使用原始时间
list.stream()
.filter(press -> vo.getTm().equals(press.getTm()))
.findFirst()
.ifPresent(press -> vo.setValue(press.getValue()));
return vo;
}).collect(Collectors.toList());
// 修改为倒序排序
return resList.stream()
.sorted(Comparator.comparing(OsmoticPressDetailVo::getTm).reversed())
.collect(Collectors.toList());
}
public Map<Integer, Integer> stat() {
Map<Integer, Integer> map = new HashMap<>();
List<JcskSyRVo> press = this.listValue(1);
Integer pressSize = press.size();
Long pressWarn = press.stream().filter(o -> o.getStatus() == 1).collect(Collectors.counting());
List<JcskSyRVo> flow = this.listValue(2);
Integer flowSize = flow.size();
Long flowWarn = flow.stream().filter(o -> o.getStatus() == 1).collect(Collectors.counting());
List<JcskGnessListVo> shift = jcskGnssRService.listValue();
Integer shiftSize = shift.size();
Long shiftWarn = shift.stream().filter(o -> o.getXStatus() == 1 || o.getYStatus() ==1 || o.getHStatus() == 1).collect(Collectors.counting());
Integer size = pressSize + flowSize + shiftSize;
Integer warn = Stream.of(pressWarn, flowWarn, shiftWarn).mapToInt(Long::intValue).sum();
map.put(warn,size);
return map;
}
/**
* 测值查询管水位和库水位数据固定查询每日早8点
* @param osmoticQuerySo
* @return
*/
public List<OsmoticStationVo2> queryValue(OsmoticQuerySo osmoticQuerySo, Integer year) {
if(osmoticQuerySo.getType() == null) {
osmoticQuerySo.setType(1);
}
List<OsmoticStationVo2> resList = new ArrayList<>();
if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(osmoticQuerySo.getStationCodes())){
return resList;
}
String stcd = jcskGnssRService.getStcd();
Boolean isDesc = true;
//查询测站降雨量
Map<String, BigDecimal> drpMap = new HashMap<>();
if(year != null){
isDesc = false;
List<StRzVo> drpList = baseMapper.queryDrp(year,stcd);
drpMap = drpList.stream().collect(Collectors.toMap(StRzVo::getTm, StRzVo::getRz));
}
List<String> dateList = DateUtil.getDatesBetween(osmoticQuerySo.getDateTimeRangeSo().getStart(), osmoticQuerySo.getDateTimeRangeSo().getEnd(),isDesc);
//查询库水位
List<StRzVo> list = baseMapper.queryRz(osmoticQuerySo,stcd);
Map<String, BigDecimal> rzMap = list.stream().collect(Collectors.toMap(StRzVo::getTm, StRzVo::getRz));
//查询测站管水位/渗流量
List<OsmoticValueVo2> valueList;
if(osmoticQuerySo.getType() == 1){
//渗压数据
valueList = baseMapper.query8AmValue(osmoticQuerySo);
}else{
//渗流数据
valueList = jcskSlBMapper.query8AmValue(osmoticQuerySo);
}
//数据处理
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(String str : dateList){
OsmoticStationVo2 vo = new OsmoticStationVo2();
vo.setTm(str);
vo.setRz(rzMap.get(str));
vo.setDrp(drpMap.get(str));
List<OsmoticValueVo2> collect = valueList.stream()
.filter(o -> {
if (o.getTm() != null) {
// 将Date格式化为yyyy-MM-dd字符串进行比较
String dateStr = o.getTm().substring(0,10);
return str.equals(dateStr);
}
return false;
})
.peek(o->o.setTm(str))
.collect(Collectors.toList());
vo.setList(collect);
resList.add(vo);
}
return resList;
}
public List<OsmoticChartVo2> queryChart(OsmoticQuerySo osmoticQuerySo,Integer year) {
List<OsmoticChartVo2> resList = new ArrayList<>();
List<String> stationCodes = osmoticQuerySo.getStationCodes();
if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(stationCodes)){
return resList;
}
String stcd = jcskGnssRService.getStcd();
//查询库水位
List<StRzVo> list = baseMapper.queryRz2(osmoticQuerySo,stcd);
Map<String, BigDecimal> rzMap = list.stream().collect(Collectors.toMap(StRzVo::getTm, StRzVo::getRz));
//查询测站管水位
List<OsmoticValueVo2> valueList;
if(osmoticQuerySo.getType() == 1){
//渗压数据
valueList = baseMapper.queryValue(osmoticQuerySo);
}else{
//渗流数据
valueList = jcskSlBMapper.queryValue(osmoticQuerySo);
}
//按测站分组
Map<String, List<OsmoticValueVo2>> map = valueList.stream().collect(Collectors.groupingBy(OsmoticValueVo2::getStationCode));
for(String code : stationCodes){
OsmoticChartVo2 vo = new OsmoticChartVo2();
vo.setCd(code);
if(map.containsKey(code)){
List<OsmoticValueVo2> voList = map.get(code);
OsmoticValueVo2 max = voList.stream().max(Comparator.comparing(OsmoticValueVo2::getValue)).get();
OsmoticValueVo2 min = voList.stream().min(Comparator.comparing(OsmoticValueVo2::getValue)).get();
vo.setCd(code);
vo.setMaxValue(max.getValue());
vo.setMaxTm(max.getTm());
vo.setMinValue(min.getValue());
vo.setMinTm(min.getTm());
vo.setDiff(max.getValue().subtract(min.getValue()));
if(year == null){
vo.setDetailVos(bindData(MyBeanUtil.collectionCopy(list,OsmoticChartDetailVo.class),MyBeanUtil.collectionCopy(voList,OsmoticChartDetailVo.class)));
}
}else {
vo.setDetailVos(new ArrayList<>());
}
if(vo.getDetailVos() != null){
for (OsmoticChartDetailVo detailVo : vo.getDetailVos()) {
detailVo.setRz(rzMap.get(detailVo.getTm()));
}
}else{
vo.setDetailVos(new ArrayList<>());
}
resList.add(vo);
}
//查询测站降雨量
List<StRzVo> drpList;
if(year != null){
drpList = baseMapper.queryDrp(year,stcd);
OsmoticChartVo2 chartVo = new OsmoticChartVo2();
chartVo.setCd("rz");
if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(list)){
StRzVo max = list.stream().max(Comparator.comparing(StRzVo::getRz)).get();
StRzVo min = list.stream().min(Comparator.comparing(StRzVo::getRz)).get();
chartVo.setMaxValue(max.getRz());
chartVo.setMaxTm(max.getTm());
chartVo.setMinValue(min.getRz());
chartVo.setMinTm(min.getTm());
chartVo.setDiff(max.getRz().subtract(min.getRz()));
resList.add(chartVo);
}
if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(drpList)){
OsmoticChartVo2 drpVo = new OsmoticChartVo2();
drpVo.setCd("drp");
StRzVo maxDrp = drpList.stream().max(Comparator.comparing(StRzVo::getRz)).get();
StRzVo minDrp = drpList.stream().min(Comparator.comparing(StRzVo::getRz)).get();
drpVo.setMaxValue(maxDrp.getRz());
drpVo.setMaxTm(maxDrp.getTm());
drpVo.setMinValue(minDrp.getRz());
drpVo.setMinTm(minDrp.getTm());
drpVo.setDiff(maxDrp.getRz().subtract(minDrp.getRz()));
resList.add(drpVo);
}
}
return resList;
}
//根据监测时间合并管水位和库水位数据
private List<OsmoticChartDetailVo> bindData(List<OsmoticChartDetailVo> tmRzList, List<OsmoticChartDetailVo> voList) {
HashSet<String> strings = new HashSet<>();
tmRzList.stream().forEach(v1 -> strings.add(v1.getTm()));
voList.stream().forEach(v1 -> strings.add(v1.getTm()));
List<OsmoticChartDetailVo> result = new ArrayList<>();
strings.stream().forEach(v1 ->{
OsmoticChartDetailVo v = new OsmoticChartDetailVo();
v.setTm(v1);
result.add(v);
});
List<OsmoticChartDetailVo> list = result.stream().map(v1 -> {
tmRzList.stream().filter(v2 -> v1.getTm().equals(v2.getTm())).forEach(v2 -> {
v1.setRz(v2.getRz());
});
voList.stream().filter(v2 -> v1.getTm().equals(v2.getTm())).forEach(v2 -> {
v1.setValue(v2.getValue());
});
return v1;
}).collect(Collectors.toList());
return list.stream().sorted(Comparator.comparing(OsmoticChartDetailVo::getTm)).collect(Collectors.toList());
}
public List<OsmoticStationVo2> infiltraLine(OsmoticQuerySo osmoticQuerySo) {
List<OsmoticStationVo2> resList = new ArrayList<>();
String stcd = jcskGnssRService.getStcd();
//查询库水位
//TODO 数据是每整点过五分监测一次(暂时修改,看后续实际数据来了之后会怎么样)
List<StRzVo> list = baseMapper.queryLineRz(osmoticQuerySo,stcd);
Map<String, BigDecimal> rzMap = list.stream().collect(Collectors.toMap(StRzVo::getTm, StRzVo::getRz));
//查询测站管水位
List<OsmoticValueVo2> valueList = baseMapper.queryLineValue(osmoticQuerySo);
//查询测站预警信息
List<OsmoticValueVo2> warnList = baseMapper.queryWarn(osmoticQuerySo);
valueList.stream().map(vo->{
Boolean b = warnList.stream().filter(o->o.getStationCode().equals(vo.getStationCode()) && o.getTm().equals(vo.getTm())).findAny().isPresent();
if(b){
vo.setStatus(0);
}
return vo;
}).collect(Collectors.toList());
HashSet<String> dateList = new HashSet<>();
list.stream().forEach(v1 -> dateList.add(v1.getTm()));
valueList.stream().forEach(v1 -> dateList.add(v1.getTm()));
// 过滤出整点时间数据
List<String> hourList = dateList.stream()
.filter(tm -> tm.matches(".*:00:00$")) // 匹配以:00:00结尾的时间
.collect(Collectors.toList());
for(String str : hourList){
OsmoticStationVo2 vo = new OsmoticStationVo2();
vo.setTm(str);
vo.setRz(rzMap.get(str));
List<OsmoticValueVo2> newList = valueList.stream().filter(o->str.equals(o.getTm())).collect(Collectors.toList());
vo.setList(newList);
if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(newList) && newList.stream().filter(o->o.getStatus() == 0).findAny().isPresent()){
vo.setStatus(0);
}
resList.add(vo);
}
return resList.stream().sorted(Comparator.comparing(OsmoticStationVo2::getTm).reversed()).collect(Collectors.toList());
}
public void export(OsmoticQuerySo osmoticQuerySo, HttpServletResponse response) {
//通过断面查询渗压设备
List<String> stationCodes = osmoticQuerySo.getStationCodes();
//表头信息
List<String> heads = new ArrayList<>();
heads.add("序号");
heads.add("时间");
heads.add("库水位(m)");
heads.addAll(stationCodes);
heads.add("结果分析");
//表格数据
List<OsmoticStationVo2> resList = infiltraLine(osmoticQuerySo);
List<Map<String, Object>> list = new ArrayList<>();
for (int j = 0;j < resList.size(); j++) {
OsmoticStationVo2 vo = resList.get(j);
Map<String, Object> test = new LinkedHashMap<>();
test.put("t0",j+1);
test.put("t1", vo.getTm());
test.put("t2", vo.getRz());
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
OsmoticValueVo2 valueVo = vo.getList().stream().filter(o->code.equals(o.getStationCode())).findFirst().orElse(null);
test.put(code,valueVo != null ? valueVo.getValue() : "");
}
test.put("t4", vo.getStatus() == 0 ? "异常":"正常");
list.add(test);
}
List<List<String>> hs = new ArrayList<>();
for (String s : heads) {
hs.add(Arrays.asList(s));
}
ExcelUtil.exportExcel(hs, DataHandleUtil.tableData(list), "浸润线", response, "浸润线");
}
private OsmoticQuerySo commonQueryHandle(OsmoticQuerySo osmoticQuerySo){
String year = osmoticQuerySo.getYear();
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date start = sdf.parse(year + "-01-01 00:00:00");
Date end = sdf.parse(year + "-12-31 23:59:59"); // 建议使用 23:59:59
DateTimeRangeSo so = new DateTimeRangeSo();
so.setStart(start);
so.setEnd(end);
osmoticQuerySo.setDateTimeRangeSo(so);
return osmoticQuerySo;
} catch (Exception e) {
throw new IllegalArgumentException("日期格式错误: " + year, e);
}
}
public List<OsmoticStationVo2> yearStat(OsmoticQuerySo osmoticQuerySo) {
commonQueryHandle(osmoticQuerySo);
return queryValue(osmoticQuerySo,Integer.valueOf(osmoticQuerySo.getYear()));
}
public List<OsmoticChartVo2> yearStatValue(OsmoticQuerySo osmoticQuerySo) {
commonQueryHandle(osmoticQuerySo);
return queryChart(osmoticQuerySo,Integer.valueOf(osmoticQuerySo.getYear()));
}
public void yearStatExport(OsmoticQuerySo osmoticQuerySo, HttpServletResponse response) {
String headName = osmoticQuerySo.getProfileName() + "断面测压管水位(m)";
String fileName = "断面年度渗压统计";
String sheetName = "年度渗压统计";
if(osmoticQuerySo.getType() == 1){
fileName = osmoticQuerySo.getProfileName() + fileName;
}else {
headName = "渗流量(L/s)";
fileName = "年度渗流统计";
sheetName = "年度渗流统计";
}
//上方表格数据
List<OsmoticStationVo2> resList = yearStat(osmoticQuerySo);
//下方特征值数据
List<OsmoticChartVo2> chartList = queryChart(osmoticQuerySo,Integer.valueOf(osmoticQuerySo.getYear()));
List<String> stationCodes = osmoticQuerySo.getStationCodes();
//表头信息
List<List<String>> headList = new ArrayList<>();
List<String> heads1 = new ArrayList<>();
heads1.add("序号");
heads1.add("序号");
headList.add(heads1);
List<String> heads2 = new ArrayList<>();
heads2.add("监测日期");
heads2.add("监测日期");
headList.add(heads2);
for(String code : stationCodes){
List<String> heads = new ArrayList<>();
heads.add(headName);
heads.add(code);
headList.add(heads);
}
List<String> heads3 = new ArrayList<>();
heads3.add("库水位(m)");
heads3.add("库水位(m)");
headList.add(heads3);
List<String> heads4 = new ArrayList<>();
heads4.add("降雨量(mm)");
heads4.add("降雨量(mm)");
headList.add(heads4);
List<Map<String, Object>> list = new ArrayList<>();
for (int j = 0;j < resList.size(); j++) {
OsmoticStationVo2 vo = resList.get(j);
Map<String, Object> test = new LinkedHashMap<>();
test.put("t0",j+1);
test.put("t1", vo.getTm());
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
OsmoticValueVo2 valueVo = vo.getList().stream().filter(o->code.equals(o.getStationCode())).findFirst().orElse(null);
test.put(code,valueVo != null ? valueVo.getValue() : "");
}
test.put("t2", vo.getRz());
test.put("t3", vo.getDrp());
list.add(test);
}
Map<String, Object> max = new LinkedHashMap<>();
max.put("t0","全年度特征值统计");
max.put("t1", "最大值");
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
max.put(code,chartList.stream().filter(o->code.equals(o.getCd())).findFirst().get().getMaxValue());
}
max.put("t2", chartList.stream().filter(o->"rz".equals(o.getCd())).findFirst().get().getMaxValue());
max.put("t3", chartList.stream().filter(o->"drp".equals(o.getCd())).findFirst().get().getMaxValue());
list.add(max);
Map<String, Object> maxTm = new LinkedHashMap<>();
maxTm.put("t0","全年度特征值统计");
maxTm.put("t1", "日期");
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
maxTm.put(code,chartList.stream().filter(o->code.equals(o.getCd())).findFirst().get().getMaxTm());
}
maxTm.put("t2", chartList.stream().filter(o->"rz".equals(o.getCd())).findFirst().get().getMaxTm());
maxTm.put("t3", chartList.stream().filter(o->"drp".equals(o.getCd())).findFirst().get().getMaxTm());
list.add(maxTm);
Map<String, Object> min = new LinkedHashMap<>();
min.put("t0","全年度特征值统计");
min.put("t1", "最小值");
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
min.put(code,chartList.stream().filter(o->code.equals(o.getCd())).findFirst().get().getMinValue());
}
min.put("t2", chartList.stream().filter(o->"rz".equals(o.getCd())).findFirst().get().getMinValue());
min.put("t3", chartList.stream().filter(o->"drp".equals(o.getCd())).findFirst().get().getMinValue());
list.add(min);
Map<String, Object> minTm = new LinkedHashMap<>();
minTm.put("t0","全年度特征值统计");
minTm.put("t1", "日期");
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
minTm.put(code,chartList.stream().filter(o->code.equals(o.getCd())).findFirst().get().getMinTm());
}
minTm.put("t2", chartList.stream().filter(o->"rz".equals(o.getCd())).findFirst().get().getMinTm());
minTm.put("t3", chartList.stream().filter(o->"drp".equals(o.getCd())).findFirst().get().getMinTm());
list.add(minTm);
Map<String, Object> diff = new LinkedHashMap<>();
diff.put("t0","全年度特征值统计");
diff.put("t1", "年变幅");
for(int i = 0;i < stationCodes.size();i++){
String code = stationCodes.get(i);
diff.put(code,chartList.stream().filter(o->code.equals(o.getCd())).findFirst().get().getDiff());
}
diff.put("t2", chartList.stream().filter(o->"rz".equals(o.getCd())).findFirst().get().getDiff());
diff.put("t3", chartList.stream().filter(o->"drp".equals(o.getCd())).findFirst().get().getDiff());
list.add(diff);
ExcelUtil.exportExcel(headList, DataHandleUtil.tableData(list),2,new int[]{0},fileName,response,sheetName);
}
public List<DmDvcdVo> listDvcd() {
List<String> dms = this.baseMapper.listDm();//查询断面
List<DmDvcdVo> res = new ArrayList<>();
for (String dm : dms) {
DmDvcdVo vo = new DmDvcdVo();
vo.setDm(dm);
vo.setDvcd(this.baseMapper.listDvcdByDm(dm));
res.add(vo);
}
return res;
}
public List<SyStcdMpcdVo> listStcdMpcd() {
List<JcskSyB> syBList = this.baseMapper.listStcdMpcd();
List<SyStcdMpcdVo> syStcdMpcdVoList = new ArrayList<>();
Map<String, List<String>> groupMapData = syBList.stream().collect(
Collectors.groupingBy(JcskSyB::getStcd, Collectors.mapping(JcskSyB::getMpcd, Collectors.toList()))
);
groupMapData.entrySet().stream().forEach(entry -> {
SyStcdMpcdVo entity = new SyStcdMpcdVo();
entity.setStcd(entry.getKey());
entity.setMpcdList(entry.getValue());
syStcdMpcdVoList.add(entity);
});
return syStcdMpcdVoList;
}
public Page<JcskSyRHisVo> historyPage(JcskSyRPageSo page) {
return this.baseMapper.historyPage(page.getPageSo().toPage(),page);
}
public boolean saveData(JcskSyR dto) {
List<JcskSyB> list = jcskSyBService.lambdaQuery().eq(JcskSyB::getDvcd, dto.getDvcd()).last("limit 1").list();
JcskSyB jcskSyB = list.get(0);
dto.setStcd(jcskSyB.getStcd());
dto.setMpcd(jcskSyB.getMpcd());
dto.setIsArtificial(1);
dto.setUpdateTm(LocalDateTime.now());
int insert = this.baseMapper.insert(dto);
return insert > 0;
}
public boolean updateData(JcskSyR dto) {
List<JcskSyB> list = jcskSyBService.lambdaQuery().eq(JcskSyB::getDvcd, dto.getDvcd()).last("limit 1").list();
JcskSyB jcskSyB = list.get(0);
String stcd = jcskSyB.getStcd();
String mpcd = jcskSyB.getMpcd();
LambdaUpdateWrapper<JcskSyR> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(JcskSyR::getMstm, dto.getMstm())
.eq(JcskSyR::getMpcd, dto.getMpcd())
.eq(JcskSyR::getStcd,dto.getStcd())
.set(JcskSyR::getHycncd, dto.getHycncd())
.set(JcskSyR::getRscd, dto.getRscd())
.set(JcskSyR::getSpprwl, dto.getSpprwl())
.set(JcskSyR::getTm, dto.getTm())
.set(JcskSyR::getUpdateTm, new Date())
.set(JcskSyR::getMpcd, mpcd)
.set(JcskSyR::getStcd, stcd)
.set(JcskSyR::getMstm,dto.getUpdateMstm());
int update = this.baseMapper.update(wrapper);
return update > 0;
}
public Page<JcskSyR> artificialPage(JcskSyRPageSo page) {
Page<JcskSyR> res = this.baseMapper.artificialPage(page.getPageSo().toPage(),page);
return res;
}
public String transforDateToString(Date date) {
// 将Date转换为LocalDateTime
if(date == null){
return null;
}
LocalDateTime localDateTime = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDate = localDateTime.format(formatter);
return formattedDate;
}
public void artificialExport(JcskSyRPageSo page, HttpServletResponse response) {
Page<JcskSyR> res = this.baseMapper.artificialPage(page.getPageSo().toPage(), page);
List<JcskSyR> records = res.getRecords();
// 创建导出数据列表
List<Map<String, Object>> exportData = new ArrayList<>();
for (JcskSyR record : records) {
Map<String, Object> row = new HashMap<>();
row.put("mstm", record.getMstm().toString());
row.put("tm", record.getTm());
row.put("spprwl", record.getSpprwl());
row.put("isArtificial", record.getIsArtificial() != null && record.getIsArtificial() == 1 ? "人工录入" : "自动采集");
row.put("updateTm", DateTransforUtil.transforLocalDateTimeToString(record.getUpdateTm(),"yyyy-MM-dd HH:mm:ss"));
row.put("dm", record.getDm());
row.put("dmName", record.getDmName());
row.put("dvcd", record.getDvcd()); // 改为测点编号
exportData.add(row);
}
// 通过工具类创建writer
ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter();
// 自定义标题去掉水库代码、水工建筑物编号、stcd、mpcd
writer.addHeaderAlias("dvcd", "测点编号");
writer.addHeaderAlias("mstm", "测量时间");
writer.addHeaderAlias("tm", "温度(℃)");
writer.addHeaderAlias("spprwl", "渗流压力水位(m)");
writer.addHeaderAlias("isArtificial", "录入方式");
writer.addHeaderAlias("updateTm", "更新时间");
writer.addHeaderAlias("dm", "断面编码");
writer.addHeaderAlias("dmName", "断面名称");
// 只写出设置了别名的字段
writer.setOnlyAlias(true);
// 一次性写出内容
writer.write(exportData, true);
// 设置响应内容类型
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
try {
// 设置响应头信息
String fileName = URLEncoder.encode("渗流压力人工录入数据", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
// 将writer对象刷新到响应输出流中
writer.flush(response.getOutputStream(), true);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("导出Excel失败", e);
} finally {
// 关闭writer释放内存
writer.close();
}
}
public boolean deleteData(ArtificialJcskSyDeleteDto dto) {
if(StringUtils.isBlank(dto.getStcd())) {
throw new IllegalArgumentException("stcd不能为空");
}
if(StringUtils.isBlank(dto.getMpcd())){
throw new IllegalArgumentException("mpcd不能为空");
}
if(dto.getMstm() == null){
throw new IllegalArgumentException("时间不能为空");
}
LambdaQueryWrapper<JcskSyR> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(JcskSyR::getStcd, dto.getStcd());
queryWrapper.eq(JcskSyR::getMstm, dto.getMstm());
queryWrapper.eq(JcskSyR::getMpcd,dto.getMpcd());
queryWrapper.eq(JcskSyR::getIsArtificial,1);
int delete = this.baseMapper.delete(queryWrapper);
return delete > 0;
}
@Autowired
private AttResBaseService attResBaseService;
/**
* 多项式方程计算
* @param dto
* @return
*/
public ProjectSafeCalculateVo calculate(@NotNull ProjectSafeCalculateDto dto) {
LambdaQueryWrapper<JcskSyB> queryWrapper = new LambdaQueryWrapper<>();
ProjectSafeCalculateVo res = new ProjectSafeCalculateVo();
//根据dvcd查询stcd和mpcd
queryWrapper.eq(JcskSyB::getDvcd, dto.getDvcd());
JcskSyB jcskSyB = jcskSyBService.getBaseMapper().selectOne(queryWrapper);
String stcd = jcskSyB.getStcd();
String mpcd = jcskSyB.getMpcd();
//取得这个时间段得所有八点得数据
LambdaQueryWrapper<JcskSyREightAm> eightAmLambdaQueryWrapper = new LambdaQueryWrapper<>();
eightAmLambdaQueryWrapper.eq(JcskSyREightAm::getStcd, stcd);
eightAmLambdaQueryWrapper.eq(JcskSyREightAm::getMpcd, mpcd);
eightAmLambdaQueryWrapper.ge(JcskSyREightAm::getMstm,dto.getDateTimeRangeSo().getStart());
eightAmLambdaQueryWrapper.le(JcskSyREightAm::getMstm,dto.getDateTimeRangeSo().getEnd());
eightAmLambdaQueryWrapper.orderByAsc(JcskSyREightAm::getMstm);
List<JcskSyREightAm> jcskSyREightAms = jcskSyREightAmMapper.selectList(eightAmLambdaQueryWrapper);
AttResBase attResBase = attResBaseService.list().get(0);
OsmoticQuerySo querySo = new OsmoticQuerySo();
querySo.setDateTimeRangeSo(dto.getDateTimeRangeSo());
List<StRzVo> stRzVos = baseMapper.qeury8AmRz(querySo,attResBase.getStcd());
Map<String, BigDecimal> rzMap = stRzVos.stream()
.collect(Collectors.toMap(
StRzVo::getTm, // key: 时间
StRzVo::getRz, // value: 水位
(existing, replacement) -> existing // 如果key冲突保留已存在的
));
//组合成为 时间 库水位 管道水位的数据
List<OsmoticPressDetailVo> data = new ArrayList<>();
Iterator<JcskSyREightAm> iterator = jcskSyREightAms.iterator();
while (iterator.hasNext()) {
JcskSyREightAm eightAm = iterator.next();
if(eightAm.getMstm() == null || eightAm.getSpprwl() == null){
iterator.remove();
}
OsmoticPressDetailVo detailVo = new OsmoticPressDetailVo();
// 设置监测时间和监测值(管道水位)
String mstmStr = eightAm.getMstm().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
detailVo.setTm(mstmStr);
detailVo.setValue(eightAm.getSpprwl());
// 查找对应的库水位
BigDecimal rzValue = findClosestRzValue(rzMap, mstmStr);
if(rzValue == null){
iterator.remove();
}
detailVo.setRz(rzValue);
//获取数据清洗规则
SyDataCheckRule rule = syDataCheckRuleService.getByDvcd(dto.getDvcd());
if(rule != null && rule.getIsAvailable() == 1){
//校验这条数据是否符合规则
if(rzValue.compareTo(rule.getRz()) >=0){
//如果当前库水位大于等于设置库水位,则跳过这条数据
iterator.remove();
}
if(eightAm.getSpprwl().compareTo(rule.getSyValue()) <=0){
//如果当前监测值小于等于设置值,则跳过这套数据
iterator.remove();
}
}
data.add(detailVo);
}
if(data.isEmpty()){
return res;
}
List<SyRegressionData> saves = new ArrayList<>();
RegressionEquation first = RegressionAnalysis.calculateLinear(data);
LocalDateTime createTime = LocalDateTime.now();
if(first != null){
LambdaQueryWrapper<SyRegressionData> query = new LambdaQueryWrapper<>();
query.eq(SyRegressionData::getDvcd, dto.getDvcd());
query.eq(SyRegressionData::getOrder,1);
syRegressionDataService.remove(query);
res.setOne(first.toString());
SyRegressionData syRegressionData = new SyRegressionData();
syRegressionData.setOrder(1);
syRegressionData.setRegressionEquation(first.toString());
syRegressionData.setDvcd(dto.getDvcd());
syRegressionData.setStartTime(dto.getDateTimeRangeSo().getStart());
syRegressionData.setEndTime(dto.getDateTimeRangeSo().getEnd());
syRegressionData.setCreateTime(createTime);
saves.add(syRegressionData);
}
RegressionEquation second = RegressionAnalysis.calculateQuadratic(data);
if(second != null){
LambdaQueryWrapper<SyRegressionData> query = new LambdaQueryWrapper<>();
query.eq(SyRegressionData::getDvcd, dto.getDvcd());
query.eq(SyRegressionData::getOrder,2);
syRegressionDataService.remove(query);
res.setTwo(second.toString());
SyRegressionData syRegressionData = new SyRegressionData();
syRegressionData.setOrder(2);
syRegressionData.setRegressionEquation(second.toString());
syRegressionData.setDvcd(dto.getDvcd());
syRegressionData.setStartTime(dto.getDateTimeRangeSo().getStart());
syRegressionData.setEndTime(dto.getDateTimeRangeSo().getEnd());
syRegressionData.setCreateTime(createTime);
saves.add(syRegressionData);
}
RegressionEquation three = RegressionAnalysis.calculateCubic(data);
if(three != null){
LambdaQueryWrapper<SyRegressionData> query = new LambdaQueryWrapper<>();
query.eq(SyRegressionData::getDvcd, dto.getDvcd());
query.eq(SyRegressionData::getOrder,3);
syRegressionDataService.remove(query);
res.setThree(three.toString());
SyRegressionData syRegressionData = new SyRegressionData();
syRegressionData.setOrder(3);
syRegressionData.setRegressionEquation(three.toString());
syRegressionData.setDvcd(dto.getDvcd());
syRegressionData.setStartTime(dto.getDateTimeRangeSo().getStart());
syRegressionData.setEndTime(dto.getDateTimeRangeSo().getEnd());
syRegressionData.setCreateTime(createTime);
saves.add(syRegressionData);
}
RegressionEquation four = RegressionAnalysis.calculateQuartic(data);
if(four != null){
LambdaQueryWrapper<SyRegressionData> query = new LambdaQueryWrapper<>();
query.eq(SyRegressionData::getDvcd, dto.getDvcd());
query.eq(SyRegressionData::getOrder,4);
syRegressionDataService.remove(query);
res.setFour(four.toString());
SyRegressionData syRegressionData = new SyRegressionData();
syRegressionData.setOrder(4);
syRegressionData.setRegressionEquation(four.toString());
syRegressionData.setDvcd(dto.getDvcd());
syRegressionData.setStartTime(dto.getDateTimeRangeSo().getStart());
syRegressionData.setEndTime(dto.getDateTimeRangeSo().getEnd());
syRegressionData.setCreateTime(createTime);
saves.add(syRegressionData);
}
res.setDatas(data);
syRegressionDataService.saveBatch(saves);
return res;
}
/**
* 查找最接近的库水位值
*/
private BigDecimal findClosestRzValue(Map<String, BigDecimal> rzMap, String targetTimeStr) {
// 如果直接匹配到,直接返回
if (rzMap.containsKey(targetTimeStr)) {
return rzMap.get(targetTimeStr);
}
// 如果没有直接匹配,查找最接近的时间
LocalDateTime targetTime = LocalDateTime.parse(targetTimeStr,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String closestTime = null;
long minDiff = Long.MAX_VALUE;
for (String timeStr : rzMap.keySet()) {
LocalDateTime time = LocalDateTime.parse(timeStr,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
long diff = Math.abs(Duration.between(targetTime, time).toMinutes());
if (diff < minDiff) {
minDiff = diff;
closestTime = timeStr;
}
}
return closestTime != null ? rzMap.get(closestTime) : BigDecimal.ZERO;
}
}