冀北数据周报

This commit is contained in:
wr
2026-02-06 15:09:17 +08:00
parent 7410d32241
commit 7a5ef040bb
9 changed files with 621 additions and 48 deletions

View File

@@ -1,6 +1,7 @@
package com.njcn.device.pq.controller;
import cn.hutool.core.date.DateUtil;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
@@ -155,6 +156,8 @@ public class DataVerifyController extends BaseController {
public void dataVerifyExcel(HttpServletResponse response, MonitorBaseParam monitorBaseParam) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
monitorBaseParam.setSearchBeginTime(DateUtil.beginOfDay(DateUtil.parse(monitorBaseParam.getSearchBeginTime())).toString());
monitorBaseParam.setSearchEndTime(DateUtil.endOfDay(DateUtil.parse(monitorBaseParam.getSearchEndTime())).toString());
iPqDataVerifyBakService.dataVerifyExcel(response, monitorBaseParam);
}

View File

@@ -4,6 +4,7 @@ package com.njcn.device.pq.service.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.*;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
@@ -11,29 +12,39 @@ import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONTokener;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.dataProcess.api.PqReasonableRangeFeignClient;
import com.njcn.dataProcess.enums.DataCleanEnum;
import com.njcn.dataProcess.param.DataCleanParam;
import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto;
import com.njcn.device.common.mapper.onlinerate.OnLineRateMapper;
import com.njcn.device.common.service.GeneralDeviceService;
import com.njcn.device.line.mapper.LineMapper;
import com.njcn.device.line.service.DeptLineService;
import com.njcn.device.pq.constant.Param;
import com.njcn.device.pq.enums.LineBaseEnum;
import com.njcn.device.pq.mapper.PqDataVerifyBakMapper;
import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.param.DeviceInfoParam;
import com.njcn.device.pq.pojo.param.OnlineRateParam;
import com.njcn.device.pq.pojo.param.dataClean.MonitorBaseParam;
import com.njcn.device.pq.pojo.po.DeptLine;
import com.njcn.device.pq.pojo.po.PqDataVerifyBak;
import com.njcn.device.pq.pojo.vo.AreaLineInfoVO;
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
import com.njcn.device.pq.pojo.vo.*;
import com.njcn.device.pq.pojo.vo.dataClean.*;
import com.njcn.device.pq.service.CommTerminalService;
import com.njcn.device.pq.service.IPqDataVerifyBakService;
import com.njcn.device.pq.utils.DataLineExcelUtil;
import com.njcn.device.rstatintegrity.mapper.RStatIntegrityDMapper;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.poi.excel.ExcelUtil;
import com.njcn.supervision.api.UserLedgerFeignClient;
import com.njcn.system.api.DictTreeFeignClient;
import lombok.RequiredArgsConstructor;
@@ -43,6 +54,7 @@ import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
@@ -52,6 +64,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.njcn.device.pq.utils.FixedDynamicExcelExport.exportExcelByDataSize;
import static com.njcn.device.pq.utils.FixedDynamicExcelExport.writeCenterStyle;
/**
* <p>
@@ -75,6 +88,9 @@ public class PqDataVerifyBakServiceImpl extends ServiceImpl<PqDataVerifyBakMappe
private final UserLedgerFeignClient userLedgerFeignClient;
private final FileStorageUtil fileStorageUtil;
private final DeptLineService deptLineService;
private final GeneralDeviceService deviceService;
private final RStatIntegrityDMapper integrityDMapper;
private final OnLineRateMapper onLineRateMapper;
@Override
public VerifyMonitorVO getMonitorVerifyData(MonitorBaseParam monitorBaseParam) {
@@ -373,37 +389,225 @@ public class PqDataVerifyBakServiceImpl extends ServiceImpl<PqDataVerifyBakMappe
@Override
public void dataVerifyExcel(HttpServletResponse response, MonitorBaseParam monitorBaseParam) throws IOException {
if (StrUtil.isNotBlank(monitorBaseParam.getDeptId())) {
List<String> monitorIds = commTerminalService.getRunMonitorByDept(monitorBaseParam);
monitorBaseParam.setMonitorIds(monitorIds);
}
List<DataVerifyExcel> dataVerifyExcels = this.baseMapper.selectDataVerifySum(monitorBaseParam);
List<String> ids = dataVerifyExcels.stream().map(DataVerifyExcel::getLineId).collect(Collectors.toList());
List<AreaLineInfoVO> areaLineInfoVOList = lineMapper.getBaseLineAreaInfo(ids, null, null);
Map<String, AreaLineInfoVO> map = areaLineInfoVOList.stream().collect(Collectors.toMap(AreaLineInfoVO::getLineId, Function.identity()));
for (DataVerifyExcel dataVerifyExcel : dataVerifyExcels) {
if (map.containsKey(dataVerifyExcel.getLineId())) {
AreaLineInfoVO areaLineInfoVO = map.get(dataVerifyExcel.getLineId());
dataVerifyExcel.setCity(areaLineInfoVO.getGdName());
dataVerifyExcel.setLineName(areaLineInfoVO.getLineName());
dataVerifyExcel.setLoadType(areaLineInfoVO.getLoadType());
dataVerifyExcel.setObjName(areaLineInfoVO.getObjName());
dataVerifyExcel.setStationName(areaLineInfoVO.getSubName());
dataVerifyExcel.setPowerSubstationName(areaLineInfoVO.getPowerSubstationName());
dataVerifyExcel.setDevName(areaLineInfoVO.getDeviceName());
dataVerifyExcel.setIp(areaLineInfoVO.getIp());
dataVerifyExcel.setManufacturer(areaLineInfoVO.getManufacturer());
DeviceInfoParam param = new DeviceInfoParam();
param.setDeptIndex(monitorBaseParam.getDeptId());
param.setStatisticalType(new SimpleDTO());
//获取终端台账类信息
List<GeneralDeviceDTO> deviceInfo = deviceService.getDeviceInfo(param, Arrays.asList(0), Arrays.asList(1));
List<String> lineIds = deviceInfo.stream().flatMap(x -> x.getLineIndexes().stream()).distinct().collect(Collectors.toList());
List<String> devIds = deviceInfo.stream().flatMap(x -> x.getDeviceIndexes().stream()).distinct().collect(Collectors.toList());
List<LineInfoMonitorIdVO> areaLineInfoVOList = lineMapper.getBaseLineInfoMonitorIdInfo(lineIds);
List<LineInfoMonitorIdVO> monitorLine = areaLineInfoVOList.stream().filter(x -> StrUtil.isNotBlank(x.getMonitorId())).collect(Collectors.toList());
List<LineInfoMonitorIdVO> gridSide = areaLineInfoVOList.stream().filter(x -> x.getPowerFlag() == 0).collect(Collectors.toList());
List<LineInfoMonitorIdVO> nonGridSide = areaLineInfoVOList.stream().filter(x -> x.getPowerFlag() == 1).collect(Collectors.toList());
OnlineRateParam onlineRateParam = new OnlineRateParam();
onlineRateParam.setIds(devIds);
onlineRateParam.setStartTime(monitorBaseParam.getSearchBeginTime());
onlineRateParam.setEndTime(monitorBaseParam.getSearchEndTime());
//完整率
List<RStatIntegrityVO> integrityList = integrityDMapper.getLineIntegrityRateInfo(lineIds,
monitorBaseParam.getSearchBeginTime(),
monitorBaseParam.getSearchEndTime());
//获取所有终端在线率
List<RStatOnlineRateVO> onlineRateByDev = onLineRateMapper.getOnlineRateByDevIds(onlineRateParam);
List<CityDataExcel> cityData1 = new ArrayList<>();
List<CityDataExcel> cityData2 = new ArrayList<>();
List<CityDataExcel> cityData3 = new ArrayList<>();
for (GeneralDeviceDTO dto : deviceInfo) {
cityData1.add(addCityDataExcel(dto, monitorLine, onlineRateByDev, integrityList));
cityData2.add(addCityDataExcel(dto, gridSide, onlineRateByDev, integrityList));
cityData3.add(addCityDataExcel(dto, nonGridSide, onlineRateByDev, integrityList));
}
monitorBaseParam.setMonitorIds(lineIds);
List<DataVerifyExcel> dataVerifyExcels = this.baseMapper.selectDataVerifySum(monitorBaseParam);
Map<String, LineInfoMonitorIdVO> lineInfomap = areaLineInfoVOList.stream().collect(Collectors.toMap(LineInfoMonitorIdVO::getLineId, Function.identity()));
for (DataVerifyExcel dataVerifyExcel : dataVerifyExcels) {
if (lineInfomap.containsKey(dataVerifyExcel.getLineId())) {
LineInfoMonitorIdVO areaLineInfoVO = lineInfomap.get(dataVerifyExcel.getLineId());
dataVerifyExcel.setCity(areaLineInfoVO.getGdName());
dataVerifyExcel.setLineName(areaLineInfoVO.getLineName());
dataVerifyExcel.setLoadType(areaLineInfoVO.getLoadType());
dataVerifyExcel.setObjName(areaLineInfoVO.getObjName());
dataVerifyExcel.setStationName(areaLineInfoVO.getSubName());
dataVerifyExcel.setPowerSubstationName(areaLineInfoVO.getPowerSubstationName());
dataVerifyExcel.setDevName(areaLineInfoVO.getDeviceName());
dataVerifyExcel.setIp(areaLineInfoVO.getIp());
dataVerifyExcel.setManufacturer(areaLineInfoVO.getManufacturer());
}
}
dataVerifyExcels.sort(Comparator
.comparing(DataVerifyExcel::getAllTime, Comparator.reverseOrder())
.thenComparing((DataVerifyExcel item) -> item.getCity() + "_" + item.getStationName() + "_" + item.getDevName())
);
Map<String, List> map = exportExcelByDataSize(dataVerifyExcels);
// 步骤5导出Excel含列宽设置
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
.registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
.registerWriteHandler(writeCenterStyle()).build();
WriteSheet writeSheet0 = EasyExcel.writerSheet("监测点异常指标统计").build();
WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).head(map.get("head")).build();
excelWriter.write(map.get("data"), writeSheet0, writeTable0);
Map<Integer, List<CityDataExcel>> cityData = new HashMap<>();
cityData.put(1, cityData1);
cityData.put(2, cityData2);
cityData.put(3, cityData3);
Map<Integer, List<LineDataExcel>> lineData = new HashMap<>();
addLineDataExcel(cityData1, areaLineInfoVOList, onlineRateByDev, integrityList, lineData, 1);
addLineDataExcel(cityData2, areaLineInfoVOList, onlineRateByDev, integrityList, lineData, 2);
addLineDataExcel(cityData3, areaLineInfoVOList, onlineRateByDev, integrityList, lineData, 3);
excelExtracted(excelWriter, "数据质量", new HashMap<>(), cityData, true);
excelExtracted(excelWriter, "数据质量表格", lineData, new HashMap<>(), false);
excelWriter.finish();
}
}
private void addLineDataExcel(List<CityDataExcel> cityData1, List<LineInfoMonitorIdVO> areaLineInfoVOList, List<RStatOnlineRateVO> onlineRateByDev, List<RStatIntegrityVO> integrityList, Map<Integer, List<LineDataExcel>> lineData, Integer num) {
List<LineDataExcel> lineDataExcels1 = new ArrayList<>();
List<String> lineData1 = cityData1.stream().flatMap(x -> x.getAbnormalList().stream()).collect(Collectors.toList());
List<LineInfoMonitorIdVO> lineInfoData1 = areaLineInfoVOList.stream().filter(x -> lineData1.contains(x.getLineId())).collect(Collectors.toList());
LineDataExcel lineDataExcel;
for (int i = 0; i < lineInfoData1.size(); i++) {
LineInfoMonitorIdVO dto = lineInfoData1.get(i);
lineDataExcel = new LineDataExcel();
lineDataExcel.setLineNum(BigDecimal.valueOf((i + 1)));
lineDataExcel.setLineName(dto.getLineName());
lineDataExcel.setDeptName(dto.getDeviceName());
lineDataExcel.setPowerSubstationName(dto.getPowerSubstationName());
lineDataExcel.setObjName(dto.getObjName());
lineDataExcel.setDeviceName(dto.getDeviceName());
lineDataExcel.setIp(dto.getIp());
lineDataExcel.setManufacturer(dto.getManufacturer());
lineDataExcel.setOnlineRate(onLineRate(onlineRateByDev, Arrays.asList(dto.getDeviceId())));
lineDataExcel.setIntegrity(integrity(integrityList, Arrays.asList(dto.getLineId())));
if (num == 1) {
lineDataExcel.setMonitorId(new BigDecimal(dto.getMonitorId()));
}
lineDataExcels1.add(lineDataExcel);
}
lineData.put(num, lineDataExcels1);
}
private CityDataExcel addCityDataExcel(GeneralDeviceDTO dto, List<LineInfoMonitorIdVO> monitorLine, List<RStatOnlineRateVO> onlineRateByDev, List<RStatIntegrityVO> integrityList) {
CityDataExcel data = new CityDataExcel();
List<String> monitorLineList = monitorLine.stream()
.filter(x -> dto.getLineIndexes().contains(x.getLineId()))
.map(LineInfoMonitorIdVO::getLineId)
.distinct()
.collect(Collectors.toList());
List<String> devList = monitorLine.stream()
.filter(x -> dto.getDeviceIndexes().contains(x.getDeviceId()))
.map(LineInfoMonitorIdVO::getDeviceId)
.distinct()
.collect(Collectors.toList());
data.setDeptName(dto.getName());
data.setDeviceNum(BigDecimal.valueOf(devList.size()));
data.setLineNum(BigDecimal.valueOf(monitorLineList.size()));
data.setOnlineRate(onLineRate(onlineRateByDev, devList));
data.setIntegrity(integrity(integrityList, monitorLineList));
List<String> abnormalList = integrityList.stream()
.filter(x -> ObjUtil.isNotNull(x.getIntegrityRate()))
.filter(x -> x.getIntegrityRate().compareTo(BigDecimal.ZERO) == 0)
.filter(x -> monitorLineList.contains(x.getLineIndex()))
.map(RStatIntegrityVO::getLineIndex)
.distinct()
.collect(Collectors.toList());
data.setAbnormalNum(BigDecimal.valueOf(abnormalList.size()));
data.setAbnormalList(abnormalList);
return data;
}
private BigDecimal integrity(List<RStatIntegrityVO> integrityList, List<String> lineIds) {
//监测完整率
List<RStatIntegrityVO> integrityDS = integrityList.stream().filter(x -> lineIds.contains(x.getLineIndex())).collect(Collectors.toList());
if (CollUtil.isNotEmpty(integrityDS)) {
double realTime = integrityDS.stream().mapToDouble(RStatIntegrityVO::getRealTime).sum();
double dueTime = integrityDS.stream().mapToDouble(RStatIntegrityVO::getDueTime).sum();
if (dueTime == 0) {
return new BigDecimal(0);
}
return NumberUtil.round(Math.min(realTime * 100.0 / dueTime, 100), 2);
} else {
return new BigDecimal(0);
}
}
private BigDecimal onLineRate(List<RStatOnlineRateVO> onlineRateByDev, List<String> devIds) {
//终端在线率
List<RStatOnlineRateVO> onlineRateDS = onlineRateByDev.stream().filter(x -> devIds.contains(x.getDevIndex())).collect(Collectors.toList());
if (CollUtil.isNotEmpty(onlineRateDS)) {
double onlineTime = onlineRateDS.stream().mapToDouble(RStatOnlineRateVO::getOnlineMin).sum();
double offlineTime = onlineRateDS.stream().mapToDouble(RStatOnlineRateVO::getOfflineMin).sum();
if ((onlineTime + offlineTime) == 0) {
return new BigDecimal(0);
}
return NumberUtil.round(Math.min(onlineTime * 100.0 / (onlineTime + offlineTime), 100), 2);
} else {
return new BigDecimal(0);
}
}
private void excelExtracted(ExcelWriter excelWriter, String sheetName, Map<Integer, List<LineDataExcel>> lineData, Map<Integer, List<CityDataExcel>> cityData, Boolean fly) {
// 构建sheet页--表示不加表头
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).needHead(Boolean.FALSE).build();
// 表头的数量
int num = 0;
Boolean first = false;
// 模拟写5张表
for (int i = 1; i < 4; i++) {
String name = "";
if (i == 1) {
if (fly) {
name = "一类监测点";
} else {
name = "冀北公司一类监测点数据质量问题";
}
first = true;
}
if (i == 2) {
if (fly) {
name = "电网侧";
} else {
name = "冀北公司电网侧监测点数据质量问题(不包含一类监测点)";
}
first = false;
}
if (i == 3) {
if (fly) {
name = "非电网侧";
} else {
name = "冀北公司非电网侧问题监测点(不包含一类监测点)";
}
first = false;
}
String finalName = name;
List<List<String>> contentHeader;
if (fly) {
contentHeader = DataLineExcelUtil.cityHeader();
} else {
contentHeader = DataLineExcelUtil.lineHeader(first);
}
List<List<String>> nameHeader = contentHeader.stream().map(item -> Collections.singletonList(finalName)).collect(Collectors.toList());
// 这里必须指定需要头table 会继承sheet的配置sheet配置了不需要table 默认也是不需要
// 创建一个表头
WriteTable writeTable1 = EasyExcel.writerTable(num).needHead(Boolean.TRUE).head(nameHeader).build();
excelWriter.write(new ArrayList<>(), writeSheet, writeTable1);
//创建数据
WriteTable writeTable2 = EasyExcel.writerTable(num + 1).needHead(Boolean.TRUE).head(contentHeader).build();
List<List<Object>> body;
if (fly) {
body = DataLineExcelUtil.cityBody(cityData.get(i));
} else {
body = DataLineExcelUtil.lineBody(lineData.get(i));
}
excelWriter.write(body, writeSheet, writeTable2);
// 插入两次表头加2
num = num + 2;
}
dataVerifyExcels.sort(Comparator
.comparing(DataVerifyExcel::getAllTime, Comparator.reverseOrder())
.thenComparing((DataVerifyExcel item) -> item.getCity() + "_" + item.getStationName()+"_"+item.getDevName())
);
exportExcelByDataSize(dataVerifyExcels,response.getOutputStream());
// Set<String> excludeColumnFiledNames = new HashSet<>(1);
// excludeColumnFiledNames.add("lineId");
// EasyExcel.write(response.getOutputStream(), DataVerifyExcel.class)
// .excludeColumnFiledNames(excludeColumnFiledNames).sheet("sheet")
// .doWrite(dataVerifyExcels);
}