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

965 lines
42 KiB
Java
Raw Normal View History

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;
2025-11-18 16:26:32 +08:00
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;
2025-11-18 10:53:17 +08:00
@Autowired
private SyRegressionDataService syRegressionDataService;
2025-11-18 16:26:32 +08:00
@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();
2025-11-18 16:26:32 +08:00
if(eightAm.getMstm() == null || eightAm.getSpprwl() == null){
iterator.remove();
2025-11-18 16:26:32 +08:00
}
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);
2025-11-18 16:26:32 +08:00
if(rzValue == null){
iterator.remove();
2025-11-18 16:26:32 +08:00
}
detailVo.setRz(rzValue);
2025-11-18 16:26:32 +08:00
//获取数据清洗规则
SyDataCheckRule rule = syDataCheckRuleService.getByDvcd(dto.getDvcd());
if(rule != null && rule.getIsAvailable() == 1){
//校验这条数据是否符合规则
if(rzValue.compareTo(rule.getRz()) >=0){
//如果当前库水位大于等于设置库水位,则跳过这条数据
iterator.remove();
2025-11-18 16:26:32 +08:00
}
if(eightAm.getSpprwl().compareTo(rule.getSyValue()) <=0){
//如果当前监测值小于等于设置值,则跳过这套数据
iterator.remove();
2025-11-18 16:26:32 +08:00
}
}
data.add(detailVo);
}
if(data.isEmpty()){
return res;
}
2025-11-18 10:53:17 +08:00
List<SyRegressionData> saves = new ArrayList<>();
RegressionEquation first = RegressionAnalysis.calculateLinear(data);
2025-11-18 10:53:17 +08:00
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());
2025-11-18 10:53:17 +08:00
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());
2025-11-18 10:53:17 +08:00
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());
2025-11-18 10:53:17 +08:00
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());
2025-11-18 10:53:17 +08:00
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);
2025-11-18 10:53:17 +08:00
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;
}
}