1.新增稳态区域报告功能

This commit is contained in:
2026-01-08 13:52:09 +08:00
parent ed029139d3
commit b3ab5d2587
19 changed files with 1715 additions and 89 deletions

View File

@@ -0,0 +1,44 @@
package com.njcn.harmonic.pojo.dto.report;
import lombok.Data;
import java.util.List;
/**
* @Author: cdf
* @CreateTime: 2026-01-06
* @Description: 公共台账
*/
@Data
public class CommReportLedgerDto {
private String deptName;
private String monitorName;
private List<MonitorLedgerInfo> monitorNameList;
@Data
static class MonitorLedgerInfo {
private String monitorName;
private String gdName;
private String bdName;
private String busBarName;
private String voltageLevel;
private String shortCapacity;
private String devCapacity;
private String dealCapacity;
}
}

View File

@@ -0,0 +1,34 @@
package com.njcn.harmonic.pojo.dto.report;
import lombok.Data;
/**
* @Author: cdf
* @CreateTime: 2026-01-07
* @Description:
*/
@Data
public class TableMergeRule {
/** 文档中表格的索引从0开始 */
private Integer tableIndex;
/** 要合并的列索引比如0=第0列 */
private Integer mergeColIndex;
/** 从第几行开始合并从0开始计数比如从第2行开始填2 */
private Integer startRow = 0;
/** 每多少行合并一次比如5=每5行合并一组 */
private Integer mergeRowsPerGroup;
/** 是否启用该规则 */
private boolean enable = true;
// 快捷构造方法(包含起始行)
public static TableMergeRule build(int tableIndex, int mergeColIndex, int startRow, int mergeRowsPerGroup) {
TableMergeRule rule = new TableMergeRule();
rule.setTableIndex(tableIndex);
rule.setMergeColIndex(mergeColIndex);
rule.setStartRow(startRow);
rule.setMergeRowsPerGroup(mergeRowsPerGroup);
rule.setEnable(true);
return rule;
}
}

View File

@@ -0,0 +1,20 @@
package com.njcn.harmonic.pojo.param.report;
import com.njcn.harmonic.pojo.dto.report.CommReportLedgerDto;
import lombok.Data;
/**
* @Author: cdf
* @CreateTime: 2026-01-06
* @Description: 谐波区域报告
*/
@Data
public class AreaHarmReportParam {
private String startTime;
private String endTime;
private String deptId;
}

View File

@@ -2,6 +2,9 @@ package com.njcn.harmonic.pojo.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 类的介绍:
*
@@ -37,24 +40,44 @@ public class OverAreaLimitVO {
* 个数
*/
private Integer frequencyMonitorNumber = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> freqMonitorList = new ArrayList<>();;
/**
* 占比
*/
private Double frequencyBiLi = -1.0;
/**
* 日均超标占比
*/
private Double frequencyDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
private Double frequencyOverDayBiLi = -1.0;
//电压偏差超标情况
/**
* 个数
*/
private Integer voltageMonitorNumber = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> voltageMonitorList = new ArrayList<>();;
/**
* 占比
*/
private Double voltageBiLi = -1.0;
/**
* 日均超标占比
*/
private Double voltageDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
@@ -65,10 +88,19 @@ public class OverAreaLimitVO {
* 个数
*/
private Integer harmonicVoltageMonitorNumber = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> harmonicVoltageMonitorList = new ArrayList<>();
/**
* 占比
*/
private Double harmonicVoltageBiLi = -1.0;
/**
* 日均超标占比
*/
private Double harmonicVoltageDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
@@ -79,10 +111,18 @@ public class OverAreaLimitVO {
* 个数
*/
private Integer harmonicCurrentMonitorNumber = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> harmonicCurrentMonitorList = new ArrayList<>();;
/**
* 占比
*/
private Double harmonicCurrentBiLi = -1.0;
/**
* 日均超标占比
*/
private Double harmonicCurrentDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
@@ -93,10 +133,18 @@ public class OverAreaLimitVO {
* 个数
*/
private Integer threePhaseVoltageMonitorNumber = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> threePhaseVoltageMonitorList = new ArrayList<>();;
/**
* 占比
*/
private Double threePhaseVoltageBiLi = -1.0;
/**
* 日均超标占比
*/
private Double threePhaseVoltageDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
@@ -107,10 +155,18 @@ public class OverAreaLimitVO {
* 个数
*/
private Integer flickerMonitorNumber = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> flickerMonitorList = new ArrayList<>();;
/**
* 占比
*/
private Double flickerBiLi = -1.0;
/**
* 日均超标占比
*/
private Double flickerDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
@@ -125,6 +181,10 @@ public class OverAreaLimitVO {
* 占比
*/
private Double negativeBiLi = -1.0;
/**
* 日均超标占比
*/
private Double negativeDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
@@ -139,8 +199,48 @@ public class OverAreaLimitVO {
* 占比
*/
private Double interHarmonicBiLi = -1.0;
/**
* 日均超标占比
*/
private Double interHarmonicDayAvgBiLi = -1.0;
/**
* 平均超标天数
*/
private Double interHarmonicOverDayBiLi = -1.0;
private List<InnerHarmV> innerHarmVList;
private List<InnerHarmV> innerHarmIList;
@Data
public static class InnerHarmV{
private String name;
//谐波电压超标情况
/**
* 个数
*/
private Integer limitCount = 0;
/**
* 超标监测点集合,区域报告使用
*/
private List<String> limitIdList;
/**
* 占比
*/
private Double limitRate = -1.0;
/**
* 日均超标占比
*/
private Double dayAvg = -1.0;
/**
* 平均超标天数
*/
private Double dayLimit = -1.0;
}
}

View File

@@ -31,4 +31,7 @@ public class OverAreaVO extends DeviceInfoParam.BusinessParam{
@Range(min = 1,message = "条数必须大于0")
private Integer pageSize;
@ApiModelProperty("1.报告标志")
private Integer areaReportFlag;
}

View File

@@ -1,17 +1,20 @@
package com.njcn.harmonic.utils;
import cn.hutool.core.collection.CollUtil;
import com.njcn.harmonic.pojo.dto.report.TableMergeRule;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
@@ -26,7 +29,13 @@ public class WordUtil2 {
private final FileStorageUtil fileStorageUtil;
public void getWord(String path, Map<String, Object> params, String fileName,List<List<String[]>> tableList, HttpServletResponse response)
// 保留原有getWord方法兼容旧调用无合并规则时直接执行
public void getWord(String path, Map<String, Object> params, String fileName,
List<List<String[]>> tableList, HttpServletResponse response) throws Exception {
this.getWord(path, params, fileName, tableList, null, response);
}
public void getWord(String path, Map<String, Object> params, String fileName,List<List<String[]>> tableList,List<TableMergeRule> mergeRules, HttpServletResponse response)
throws Exception {
path = ClearPathUtil.cleanString(path);
InputStream inStream = null;
@@ -35,20 +44,29 @@ public class WordUtil2 {
try {
inStream = new ClassPathResource(path).getInputStream();;
doc = new CustomXWPFDocument(inStream);
// 替换表格里面的变量
if(CollUtil.isNotEmpty(tableList)){
this.replaceInTable(doc, params,tableList);
}else{
this.replaceInTable(doc, params);
}
// 替换表格里面的变量
this.replaceInPara(doc, params); // 替换文本里面的变量
// 替换文本里面的变量
this.replaceInPara(doc, params);
//新增:执行动态合并规则
if(CollUtil.isNotEmpty(mergeRules)) {
this.dynamicMergeTables(doc, mergeRules);
}
} catch (IOException e) {
e.printStackTrace();
getError("获取报告模板异常,原因为:" + e);
} finally {
if (null != inStream) {
inStream.close();
}
}
try {
ServletOutputStream outputStream = response.getOutputStream();
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
@@ -223,6 +241,74 @@ public class WordUtil2 {
}
}
/* public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> param,
CustomXWPFDocument doc) {
if (paragraphList != null && !paragraphList.isEmpty()) {
for (XWPFParagraph paragraph : paragraphList) {
// 先获取整个段落的完整文本
String fullText = paragraph.getText();
// 检查是否包含变量
boolean hasVariable = false;
for (String key : param.keySet()) {
if (fullText.contains(key)) {
hasVariable = true;
break;
}
}
if (hasVariable) {
// 进行变量替换
String replacedText = fullText;
boolean hasImage = false;
for (Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey();
if (replacedText.contains(key)) {
Object value = entry.getValue();
if (value instanceof String) {
replacedText = replacedText.replace(key, value.toString());
} else if (value instanceof Map) {
// 处理图片:需要特殊处理
hasImage = true;
break;
}
}
}
if (!hasImage) {
// 如果没有图片,直接替换整个段落文本
// 清空原有 Runs
List<XWPFRun> runs = paragraph.getRuns();
for (int i = runs.size() - 1; i >= 0; i--) {
paragraph.removeRun(i);
}
// 创建新的 Run
XWPFRun newRun = paragraph.createRun();
newRun.setText(replacedText);
} else {
// 有图片的情况:逐个 Run 处理(保留原逻辑)
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
String text = run.getText(0);
if (text != null) {
for (Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey();
if (text.contains(key)) {
// ... 原图片处理逻辑
}
}
}
}
}
}
}
}
}*/
/**
* 替换段落里面的变量
*
@@ -292,33 +378,6 @@ public class WordUtil2 {
// }
}
/**
* 为表格插入数据,行数不够添加新行
*
* @param table 需要插入数据的表格
* @param tableList 插入数据集合
*/
private static void insertTable(XWPFTable table, List<String[]> tableList) {
//删除占位符行数
table.removeRow(1);
if (CollUtil.isNotEmpty(tableList)) {
// 创建行,根据需要插入的数据添加新行,不处理表头
for (int i = 0; i < tableList.size(); i++) {
XWPFTableRow row = table.createRow();
List<XWPFTableCell> cells = row.getTableCells();
for (int j = 0; j < cells.size(); j++) {
String s = tableList.get(i)[j];
XWPFTableCell cell = cells.get(j);
cell.removeParagraph(0);
XWPFParagraph paragraph = cell.addParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
// 在段落中添加文本
XWPFRun run = paragraph.createRun();
run.setText(s);
}
}
}
}
/**
* 替换表格里面的变量
@@ -350,6 +409,7 @@ public class WordUtil2 {
}else {
if (CollUtil.isNotEmpty(tableList.get(num))){
insertTable(table, tableList.get(num)); // 插入数据
}
num++;
}
@@ -357,6 +417,53 @@ public class WordUtil2 {
}
}
/**
* 为表格插入数据,行数不够添加新行
*
* @param table 需要插入数据的表格
* @param tableList 插入数据集合
*/
private static void insertTable(XWPFTable table, List<String[]> tableList) {
//删除占位符行数
table.removeRow(1);
if (CollUtil.isNotEmpty(tableList)) {
// 创建行,根据需要插入的数据添加新行,不处理表头
for (int i = 0; i < tableList.size(); i++) {
XWPFTableRow row = table.createRow();
List<XWPFTableCell> cells = row.getTableCells();
String[] rowData = tableList.get(i);
for (int j = 0; j < cells.size(); j++) {
String s = tableList.get(i)[j];
XWPFTableCell cell = cells.get(j);
cell.removeParagraph(0);
XWPFParagraph paragraph = cell.addParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
// 在段落中添加文本
XWPFRun run = paragraph.createRun();
// 处理普通数据
if (j < rowData.length && !rowData[j].startsWith("merge:")) {
run.setText(rowData[j] == null ? "" : rowData[j]);
}
// 处理合并配置
else if (j < rowData.length && rowData[j].startsWith("merge:")) {
String[] mergeParams = rowData[j].replace("merge:", "").split(",");
int rowMerge = Integer.parseInt(mergeParams[0]);
int colMerge = Integer.parseInt(mergeParams[1]);
// 调用合并方法
setCellMerge(cell, rowMerge, colMerge);
// 清空跨列后续单元格
for (int k = j + 1; k < j + colMerge && k < cells.size(); k++) {
cells.get(k).removeParagraph(0);
}
}
}
}
}
}
/**
* 正则匹配字符串
*
@@ -398,4 +505,144 @@ public class WordUtil2 {
return res;
}
/**
* 适配 POI 4.1.1 的单元格合并核心方法
* @param cell 要合并的单元格
* @param rowMerge 纵向合并行数1=不合并,>1=合并行数)
* @param colMerge 横向合并列数1=不合并,>1=合并列数)
*/
private static void setCellMerge(XWPFTableCell cell, int rowMerge, int colMerge) {
CTTc ctTc = cell.getCTTc();
CTTcPr tcPr = ctTc.getTcPr() == null ? ctTc.addNewTcPr() : ctTc.getTcPr();
tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
// 1. 横向合并(跨列)- POI 4.1.1 写法
if (colMerge > 1) {
// 直接创建 gridSpan 并设置值
tcPr.addNewGridSpan().setVal(BigInteger.valueOf(colMerge));
}
// 2. 纵向合并(跨行)- POI 4.1.1 写法
if (rowMerge > 1) {
// 起始单元格标记为 RESTART
tcPr.addNewVMerge().setVal(STMerge.RESTART);
}
}
/**
* 适配 POI 4.1.1 的表格单元格合并工具方法
* @param table Word表格对象
* @param rowIndex 行索引从0开始
* @param colIndex 列索引从0开始
* @param mergeRows 跨行数如2表示合并当前行和下一行
* @param mergeCols 跨列数如2表示合并当前列和下一列
*/
public static void mergeTableCell(XWPFTable table, int rowIndex, int colIndex, int mergeRows, int mergeCols) {
// 参数校验
if (table == null || rowIndex < 0 || colIndex < 0 || mergeRows < 1 || mergeCols < 1) {
log.error("表格合并参数无效:行{} 列{} 跨行{} 跨列{}", rowIndex, colIndex, mergeRows, mergeCols);
return;
}
// 获取目标行和单元格
XWPFTableRow targetRow = table.getRow(rowIndex);
if (targetRow == null) {
log.error("指定行不存在:{}", rowIndex);
return;
}
XWPFTableCell targetCell = targetRow.getCell(colIndex);
if (targetCell == null) {
log.error("指定列不存在:{}", colIndex);
return;
}
// 设置起始单元格的合并属性
setCellMerge(targetCell, mergeRows, mergeCols);
// 处理跨行合并的后续单元格(标记为 CONTINUE
for (int i = rowIndex + 1; i < rowIndex + mergeRows; i++) {
XWPFTableRow row = table.getRow(i);
if (row == null) break;
XWPFTableCell cell = row.getCell(colIndex);
if (cell == null) continue;
CTTc ctTc = cell.getCTTc();
CTTcPr tcPr = ctTc.getTcPr() == null ? ctTc.addNewTcPr() : ctTc.getTcPr();
// 后续单元格标记为 CONTINUE
tcPr.addNewVMerge().setVal(STMerge.CONTINUE);
}
// 处理跨列合并的后续单元格(清空并标记为 CONTINUE
for (int j = colIndex + 1; j < colIndex + mergeCols; j++) {
XWPFTableCell cell = targetRow.getCell(j);
if (cell == null) break;
CTTc ctTc = cell.getCTTc();
CTTcPr tcPr = ctTc.getTcPr() == null ? ctTc.addNewTcPr() : ctTc.getTcPr();
tcPr.addNewVMerge().setVal(STMerge.CONTINUE);
// 清空跨列后续单元格的内容
cell.removeParagraph(0);
}
}
// ========== 新增:动态合并核心方法 ==========
/**
* 动态执行多个表格的合并规则
* @param doc Word文档对象
* @param mergeRules 合并规则列表
*/
public void dynamicMergeTables(CustomXWPFDocument doc, List<TableMergeRule> mergeRules) {
// 遍历文档中的所有表格,按规则合并
Iterator<XWPFTable> tableIterator = doc.getTablesIterator();
int currentTableIndex = 0; // 当前遍历到的表格索引从0开始
while (tableIterator.hasNext()) {
XWPFTable table = tableIterator.next();
// 查找当前表格是否有匹配的合并规则
for (TableMergeRule rule : mergeRules) {
if (rule.isEnable() && rule.getTableIndex().equals(currentTableIndex)) {
// 执行该表格的合并规则
mergeTableByRule(table, rule);
break; // 一个表格只执行一条规则,避免重复处理
}
}
currentTableIndex++;
}
}
/**
* 根据单条规则合并指定表格(支持指定起始行)
* @param table 要合并的表格
* @param rule 合并规则
*/
private void mergeTableByRule(XWPFTable table, TableMergeRule rule) {
if (table == null || rule == null || !rule.isEnable()) {
return;
}
int totalRows = table.getRows().size();
int mergeCol = rule.getMergeColIndex();
int startRow = rule.getStartRow(); // 新增:获取指定的起始行
int mergeRowsPerGroup = rule.getMergeRowsPerGroup();
// 参数校验起始行不能大于总行数、行数不足、列索引非法、合并行数小于2
if (startRow >= totalRows || totalRows < 2 || mergeCol < 0 || mergeRowsPerGroup < 2) {
log.warn("表格{}合并规则无效:总行数{} 起始行{} 合并列{} 每组行数{}",
rule.getTableIndex(), totalRows, startRow, mergeCol, mergeRowsPerGroup);
return;
}
// 核心改动从startRow开始每mergeRowsPerGroup行合并一组
for (int currentStart = startRow; currentStart < totalRows; currentStart += mergeRowsPerGroup) {
// 最后一组可能不足N行取实际行数
int actualMergeRows = Math.min(mergeRowsPerGroup, totalRows - currentStart);
// 复用原有mergeTableCell方法执行合并
mergeTableCell(table, currentStart, mergeCol, actualMergeRows, 1);
}
log.info("表格{}合并完成:第{}列 从第{}行开始 每{}行合并一次",
rule.getTableIndex(), mergeCol, startRow, mergeRowsPerGroup);
}
}

View File

@@ -9,6 +9,7 @@ import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.harmonic.pojo.dto.FpyReportDTO;
import com.njcn.harmonic.pojo.param.QualifiedReportParam;
import com.njcn.harmonic.pojo.param.report.AreaHarmReportParam;
import com.njcn.harmonic.service.majornetwork.QualifiedReportService;
import com.njcn.harmonic.service.report.AreaHarmonicService;
import com.njcn.web.controller.BaseController;
@@ -23,6 +24,8 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
/**
* pqs
@@ -47,9 +50,10 @@ public class AreaHarmonicReportController extends BaseController {
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/areaHarmonicReport")
@ApiOperation("区域稳态报告")
public HttpResult<Page<FpyReportDTO>> areaHarmonicReport() {
public HttpResult<Page<FpyReportDTO>> areaHarmonicReport(@RequestBody AreaHarmReportParam areaHarmReportParam, HttpServletResponse response) {
TimeInterval timeInterval = new TimeInterval();
String methodDescribe = getMethodDescribe("areaHarmonicReport");
areaHarmonicService.areaHarmonicReport(areaHarmReportParam,response);
log.info("区域稳态报告执行时长:"+timeInterval.interval());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);

View File

@@ -322,14 +322,14 @@ public class AnalyzeServiceImpl implements IAnalyzeService {
List<UserLedgerVO> userLedgerVOList = userLedgerFeignClient.selectUserList(new UserReportParam()).getData();
Map<String,UserLedgerVO> userLedgerVOMap = userLedgerVOList.stream().collect(Collectors.toMap(UserLedgerVO::getId,Function.identity()));
Map<String, UserLedgerVO> userLedgerVOMap = userLedgerVOList.stream().collect(Collectors.toMap(UserLedgerVO::getId, Function.identity()));
for (OverLimitLineDTO vo : overLimitLineList) {
MonitorOverLimitVO monitorOverLimitVO = new MonitorOverLimitVO();
BeanUtil.copyProperties(vo, monitorOverLimitVO);
MonitorOverLimitVO source = monMap.get(vo.getId()).get(0);
UserLedgerVO userLedgerVO = userLedgerVOMap.getOrDefault(vo.getObjId(),null);
monitorOverLimitVO.setLineObjectName(Objects.nonNull(userLedgerVO)?userLedgerVO.getProjectName():"/");
UserLedgerVO userLedgerVO = userLedgerVOMap.getOrDefault(vo.getObjId(), null);
monitorOverLimitVO.setLineObjectName(Objects.nonNull(userLedgerVO) ? userLedgerVO.getProjectName() : "/");
monitorOverLimitVO.setOverDay(source.getOverDay());
monitorOverLimitVO.setVolDevOverDay(source.getVolDevOverDay());
monitorOverLimitVO.setFreqOverDay(source.getFreqOverDay());
@@ -502,14 +502,28 @@ public class AnalyzeServiceImpl implements IAnalyzeService {
@SuppressWarnings("unchecked")
public OverAreaLimitVO handleAreaData(List<RStatLimitTargetDPO> list, List<String> line, OverAreaVO param) {
int onlineCount = 0, overLineCount = 0, freqCount = 0, voltageCount = 0, ubalanceCount = 0, flickerCount = 0, iNegCount = 0, uharmCount = 0, iharmCount = 0, inuharmCount = 0;
int freqOverDay = 0, voltageOverDay = 0, ubalanceOverDay = 0, flickerOverDay = 0, iNegOverDay = 0, uharmOverDay = 0, iharmOverDay = 0, inuharmOverDay = 0;
OverAreaLimitVO overAreaLimitVO = new OverAreaLimitVO();
Set<String> freqList = new HashSet<>();
Set<String> voltageMonitorList = new HashSet<>();
Set<String> threePhaseVoltageMonitorList = new HashSet<>();
Set<String> flickerMonitorList = new HashSet<>();
Set<String> harmonicVoltageMonitorList = new HashSet<>();
Set<String> harmonicCurrentMonitorList = new HashSet<>();
int threeV = 0, fiveV = 0, sevenV = 0, elevenV = 0;
Set<String> threeVList = new HashSet<>(), fiveVList = new HashSet<>(), sevenVList = new HashSet<>(), elevenVList = new HashSet<>();
int threeI = 0, fiveI = 0, sevenI = 0, elevenI = 0;
Set<String> threeIList = new HashSet<>(), fiveIList = new HashSet<>(), sevenIList = new HashSet<>(), elevenIList = new HashSet<>();
if (!CollectionUtils.isEmpty(list)) {
List<RStatLimitTargetDPO> data = (List<RStatLimitTargetDPO>) getAllData(line, param.getSearchBeginTime(), param.getSearchEndTime(), Param.LIMIT_TARGET);
if (!CollectionUtils.isEmpty(data)) {
onlineCount = data.size();
//在线监测点个数
overAreaLimitVO.setOnlineMonitorNumber(onlineCount);
for (RStatLimitTargetDPO item : data) {
if (item.getFreqDevOvertime() > 0 || item.getVoltageDevOvertime() > 0 || item.getUbalanceOvertime() > 0 || item.getFlickerOvertime() > 0 || item.getINegOvertime() > 0 || item.getUharm2Overtime() > 0 || item.getIharm2Overtime() > 0 || item.getInuharm1Overtime() > 0) {
overLineCount++;
@@ -529,89 +543,355 @@ public class AnalyzeServiceImpl implements IAnalyzeService {
if (item.getINegOvertime() > 0) {
iNegCount++;
}
if (item.getUharm2Overtime() > 0) {
if (vHarmFlag(item)) {
uharmCount++;
}
if (item.getIharm2Overtime() > 0) {
if (iHarmFlag(item)) {
iharmCount++;
}
if (item.getInuharm1Overtime() > 0) {
if (inHarmFlag(item)) {
inuharmCount++;
}
//区域报告
if (Objects.nonNull(param.getAreaReportFlag()) && param.getAreaReportFlag() == 1) {
if (item.getFreqDevOvertime() > 0) {
freqList.add(item.getLineId());
}
if (item.getVoltageDevOvertime() > 0) {
voltageMonitorList.add(item.getLineId());
}
if (item.getUbalanceOvertime() > 0) {
threePhaseVoltageMonitorList.add(item.getLineId());
}
if (item.getFlickerOvertime() > 0) {
flickerMonitorList.add(item.getLineId());
}
if (vHarmFlag(item)) {
harmonicVoltageMonitorList.add(item.getLineId());
}
if (iHarmFlag(item)) {
harmonicCurrentMonitorList.add(item.getLineId());
}
if (item.getUharm3Overtime() > 0) {
threeV++;
threeVList.add(item.getLineId());
}
if (item.getUharm5Overtime() > 0) {
fiveV++;
fiveVList.add(item.getLineId());
}
if (item.getUharm7Overtime() > 0) {
sevenV++;
sevenVList.add(item.getLineId());
}
if (item.getUharm11Overtime() > 0) {
elevenV++;
elevenVList.add(item.getLineId());
}
if (item.getIharm3Overtime() > 0) {
threeI++;
threeIList.add(item.getLineId());
}
if (item.getIharm5Overtime() > 0) {
fiveI++;
fiveIList.add(item.getLineId());
}
if (item.getIharm7Overtime() > 0) {
sevenI++;
sevenIList.add(item.getLineId());
}
if (item.getIharm11Overtime() > 0) {
elevenI++;
elevenIList.add(item.getLineId());
}
}
}
//超标监测点个数
overAreaLimitVO.setOverLimitMonitorNumber(overLineCount);
//超标监测点数占比
overAreaLimitVO.setOverBiLi(BigDecimal.valueOf(overLineCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
//频率偏差
overAreaLimitVO.setFrequencyMonitorNumber(freqCount);
overAreaLimitVO.setFrequencyBiLi(BigDecimal.valueOf(freqCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setFreqMonitorList(new ArrayList<>(flickerMonitorList));
//电压偏差
overAreaLimitVO.setVoltageMonitorNumber(voltageCount);
overAreaLimitVO.setVoltageBiLi(BigDecimal.valueOf(voltageCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
//谐波电压
overAreaLimitVO.setHarmonicVoltageMonitorNumber(uharmCount);
overAreaLimitVO.setHarmonicVoltageBiLi(BigDecimal.valueOf(uharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
//谐波电流
overAreaLimitVO.setHarmonicCurrentMonitorNumber(iharmCount);
overAreaLimitVO.setHarmonicCurrentBiLi(BigDecimal.valueOf(iharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setVoltageMonitorList(new ArrayList<>(voltageMonitorList));
//三相电压不平衡度
overAreaLimitVO.setThreePhaseVoltageMonitorNumber(ubalanceCount);
overAreaLimitVO.setThreePhaseVoltageBiLi(BigDecimal.valueOf(ubalanceCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setThreePhaseVoltageMonitorList(new ArrayList<>(threePhaseVoltageMonitorList));
//闪变
overAreaLimitVO.setFlickerMonitorNumber(flickerCount);
overAreaLimitVO.setFlickerBiLi(BigDecimal.valueOf(flickerCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setFlickerMonitorList(new ArrayList<>(flickerMonitorList));
//负序电流
overAreaLimitVO.setNegativeMonitorNumber(iNegCount);
overAreaLimitVO.setNegativeBiLi(BigDecimal.valueOf(iNegCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
//谐波电压
overAreaLimitVO.setHarmonicVoltageMonitorNumber(uharmCount);
overAreaLimitVO.setHarmonicVoltageBiLi(BigDecimal.valueOf(uharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicVoltageMonitorList(new ArrayList<>(harmonicVoltageMonitorList));
//谐波电流
overAreaLimitVO.setHarmonicCurrentMonitorNumber(iharmCount);
overAreaLimitVO.setHarmonicCurrentBiLi(BigDecimal.valueOf(iharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicCurrentMonitorList(new ArrayList<>(harmonicCurrentMonitorList));
//间谐波电压
overAreaLimitVO.setInterHarmonicMonitorNumber(inuharmCount);
overAreaLimitVO.setInterHarmonicBiLi(BigDecimal.valueOf(inuharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
}
}
Map<LocalDate, List<RStatLimitTargetDPO>> map = list.stream().collect(Collectors.groupingBy(RStatLimitTargetDPO::getTime));
for (LocalDate key : map.keySet()) {
List<RStatLimitTargetDPO> l = map.get(key);
for (RStatLimitTargetDPO pojo : l) {
if (pojo.getFreqDevOvertime() > 0) {
freqOverDay++;
}
if (pojo.getVoltageDevOvertime() > 0) {
voltageOverDay++;
}
if (pojo.getUbalanceOvertime() > 0) {
ubalanceOverDay++;
}
if (pojo.getFlickerOvertime() > 0) {
flickerOverDay++;
}
if (pojo.getINegOvertime() > 0) {
iNegOverDay++;
}
if (pojo.getUharm2Overtime() > 0) {
uharmOverDay++;
}
if (pojo.getIharm2Overtime() > 0) {
iharmOverDay++;
}
if (pojo.getInuharm2Overtime() > 0) {
inuharmOverDay++;
int freqOverDay = 0, voltageOverDay = 0, ubalanceOverDay = 0, flickerOverDay = 0, iNegOverDay = 0, uharmOverDay = 0, iharmOverDay = 0, inuharmOverDay = 0;
int threeOverV = 0, fiveOverV = 0, sevenOverV = 0, elevenOverV = 0;
int threeOverI = 0, fiveOverI = 0, sevenOverI = 0, elevenOverI = 0;
Map<LocalDate, List<RStatLimitTargetDPO>> map = list.stream().collect(Collectors.groupingBy(RStatLimitTargetDPO::getTime));
List<Double> freqOverOneDayList = new ArrayList<>(), voltageOverOneDayList = new ArrayList<>(), ubalanceOverOneDayList = new ArrayList<>(),
flickerOverOneDayList = new ArrayList<>(), iNegOverOneDayList = new ArrayList<>(), uharmOverOneDayList = new ArrayList<>(),
iharmOverOneDayList = new ArrayList<>(), inuharmOverOneDayList = new ArrayList<>();
List<Double> threeOverOneDayList = new ArrayList<>(), fiveOverOneDayList = new ArrayList<>(), sevenOverOneDayList = new ArrayList<>(), elevenOverOneDayList = new ArrayList<>();
List<Double> threeOverOneDayIList = new ArrayList<>(), fiveOverOneDayIList = new ArrayList<>(), sevenOverOneDayIList = new ArrayList<>(), elevenOverOneDayIList = new ArrayList<>();
for (LocalDate key : map.keySet()) {
int freqOverOneDay = 0, voltageOverOneDay = 0, ubalanceOverOneDay = 0, flickerOverOneDay = 0, iNegOverOneDay = 0, uharmOverOneDay = 0, iharmOverOneDay = 0, inuharmOverOneDay = 0;
int threeOneV = 0, fiveOneV = 0, sevenOneV = 0, elevenOneV = 0;
int threeOneI = 0, fiveOneI = 0, sevenOneI = 0, elevenOneI = 0;
List<RStatLimitTargetDPO> l = map.get(key);
for (RStatLimitTargetDPO pojo : l) {
if (pojo.getFreqDevOvertime() > 0) {
freqOverDay++;
freqOverOneDay++;
}
if (pojo.getVoltageDevOvertime() > 0) {
voltageOverDay++;
voltageOverOneDay++;
}
if (pojo.getUbalanceOvertime() > 0) {
ubalanceOverDay++;
ubalanceOverOneDay++;
}
if (pojo.getFlickerOvertime() > 0) {
flickerOverDay++;
flickerOverOneDay++;
}
if (pojo.getINegOvertime() > 0) {
iNegOverDay++;
iNegOverOneDay++;
}
if (vHarmFlag(pojo)) {
uharmOverDay++;
uharmOverOneDay++;
}
if (iHarmFlag(pojo)) {
iharmOverDay++;
iharmOverOneDay++;
}
if (inHarmFlag(pojo)) {
inuharmOverDay++;
inuharmOverOneDay++;
}
//区域报告
if (Objects.nonNull(param.getAreaReportFlag()) && param.getAreaReportFlag() == 1) {
if (pojo.getUharm3Overtime() > 0) {
threeOverV++;
threeOneV++;
}
if (pojo.getUharm5Overtime() > 0) {
fiveOverV++;
fiveOneV++;
}
if (pojo.getUharm7Overtime() > 0) {
sevenOverV++;
sevenOneV++;
}
if (pojo.getUharm11Overtime() > 0) {
elevenOverV++;
elevenOneV++;
}
if (pojo.getIharm3Overtime() > 0) {
threeOverI++;
threeOneI++;
}
if (pojo.getIharm5Overtime() > 0) {
fiveOverI++;
fiveOneI++;
}
if (pojo.getIharm7Overtime() > 0) {
sevenOverI++;
sevenOneI++;
}
if (pojo.getIharm11Overtime() > 0) {
elevenOverI++;
elevenOneI++;
}
}
}
freqOverOneDayList.add((double) freqOverOneDay / data.size() * 100);
voltageOverOneDayList.add((double) voltageOverOneDay / data.size() * 100);
ubalanceOverOneDayList.add((double) ubalanceOverOneDay / data.size() * 100);
flickerOverOneDayList.add((double) flickerOverOneDay / data.size() * 100);
iNegOverOneDayList.add((double) iNegOverOneDay / data.size() * 100);
uharmOverOneDayList.add((double) uharmOverOneDay / data.size() * 100);
iharmOverOneDayList.add((double) iharmOverOneDay / data.size() * 100);
inuharmOverOneDayList.add((double) inuharmOverOneDay / data.size() * 100);
threeOverOneDayList.add((double) threeOneV / data.size() * 100);
fiveOverOneDayList.add((double) fiveOneV / data.size() * 100);
sevenOverOneDayList.add((double) sevenOneV / data.size() * 100);
elevenOverOneDayList.add((double) elevenOneV / data.size() * 100);
threeOverOneDayIList.add((double) threeOneI / data.size() * 100);
fiveOverOneDayIList.add((double) fiveOneI / data.size() * 100);
sevenOverOneDayIList.add((double) sevenOneI / data.size() * 100);
elevenOverOneDayIList.add((double) elevenOneI / data.size() * 100);
}
}
if (onlineCount != 0) {
overAreaLimitVO.setFrequencyOverDayBiLi(freqCount == 0 ? 0.0 : BigDecimal.valueOf(freqOverDay * 1.0 / freqCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setVoltageOverDayBiLi(voltageCount == 0 ? 0.0 : BigDecimal.valueOf(voltageOverDay * 1.0 / voltageCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setThreePhaseVoltageOverDayBiLi(ubalanceCount == 0 ? 0.0 : BigDecimal.valueOf(ubalanceOverDay * 1.0 / ubalanceCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setFlickerOverDayBiLi(flickerCount == 0 ? 0.0 : BigDecimal.valueOf(flickerOverDay * 1.0 / flickerCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setNegativeOverDayBiLi(iNegCount == 0 ? 0.0 : BigDecimal.valueOf(iNegOverDay * 1.0 / iNegCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicVoltageOverDayBiLi(uharmCount == 0 ? 0.0 : BigDecimal.valueOf(uharmOverDay * 1.0 / uharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicCurrentOverDayBiLi(iharmCount == 0 ? 0.0 : BigDecimal.valueOf(iharmOverDay * 1.0 / iharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setInterHarmonicOverDayBiLi(inuharmCount == 0 ? 0.0 : BigDecimal.valueOf(inuharmOverDay * 1.0 / inuharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
if (onlineCount != 0) {
overAreaLimitVO.setFrequencyDayAvgBiLi(BigDecimal.valueOf(freqOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setVoltageDayAvgBiLi(BigDecimal.valueOf(voltageOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setThreePhaseVoltageDayAvgBiLi(BigDecimal.valueOf(ubalanceOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setFlickerDayAvgBiLi(BigDecimal.valueOf(flickerOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setNegativeDayAvgBiLi(BigDecimal.valueOf(iNegOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicVoltageDayAvgBiLi(BigDecimal.valueOf(uharmOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicCurrentDayAvgBiLi(BigDecimal.valueOf(iharmOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setInterHarmonicDayAvgBiLi(BigDecimal.valueOf(inuharmOverOneDayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setFrequencyOverDayBiLi(freqCount == 0 ? 0.0 : BigDecimal.valueOf(freqOverDay * 1.0 / freqCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setVoltageOverDayBiLi(voltageCount == 0 ? 0.0 : BigDecimal.valueOf(voltageOverDay * 1.0 / voltageCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setThreePhaseVoltageOverDayBiLi(ubalanceCount == 0 ? 0.0 : BigDecimal.valueOf(ubalanceOverDay * 1.0 / ubalanceCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setFlickerOverDayBiLi(flickerCount == 0 ? 0.0 : BigDecimal.valueOf(flickerOverDay * 1.0 / flickerCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setNegativeOverDayBiLi(iNegCount == 0 ? 0.0 : BigDecimal.valueOf(iNegOverDay * 1.0 / iNegCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicVoltageOverDayBiLi(uharmCount == 0 ? 0.0 : BigDecimal.valueOf(uharmOverDay * 1.0 / uharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setHarmonicCurrentOverDayBiLi(iharmCount == 0 ? 0.0 : BigDecimal.valueOf(iharmOverDay * 1.0 / iharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
overAreaLimitVO.setInterHarmonicOverDayBiLi(inuharmCount == 0 ? 0.0 : BigDecimal.valueOf(inuharmOverDay * 1.0 / inuharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
}
//以下代码只有再区域报告时候会被调用
if (Objects.nonNull(param.getAreaReportFlag()) && param.getAreaReportFlag() == 1) {
List<OverAreaLimitVO.InnerHarmV> innerHarmVList = new ArrayList<>();
innerHarmVList.add(assLimitVO("3",threeVList,threeV,data.size(),threeOverV,threeOverOneDayList));
innerHarmVList.add(assLimitVO("5",fiveVList,fiveV,data.size(),fiveOverV,fiveOverOneDayList));
innerHarmVList.add(assLimitVO("7",sevenVList,sevenV,data.size(),sevenOverV,sevenOverOneDayList));
innerHarmVList.add(assLimitVO("11",elevenVList,elevenV,data.size(),elevenOverV,elevenOverOneDayList));
overAreaLimitVO.setInnerHarmVList(innerHarmVList);
List<OverAreaLimitVO.InnerHarmV> innerHarmIList = new ArrayList<>();
innerHarmIList.add(assLimitVO("3",threeIList,threeI,data.size(),threeOverI,threeOverOneDayIList));
innerHarmIList.add(assLimitVO("5",fiveIList,fiveI,data.size(),fiveOverI,fiveOverOneDayIList));
innerHarmIList.add(assLimitVO("7",sevenIList,sevenI,data.size(),sevenOverI,sevenOverOneDayIList));
innerHarmIList.add(assLimitVO("11",elevenIList,elevenI,data.size(),elevenOverI,elevenOverOneDayIList));
overAreaLimitVO.setInnerHarmIList(innerHarmIList);
}
}
return overAreaLimitVO;
}
/**
* 对应报告表格一行数据
* @param name
* @param lineIds
* @param limitCount
* @param onlineNum
* @param everydayAllNum
* @param dayList 时间范围 日超标占比集合
* @return
*/
private OverAreaLimitVO.InnerHarmV assLimitVO(String name,Set<String> lineIds,int limitCount,int onlineNum,int everydayAllNum,List<Double> dayList){
OverAreaLimitVO.InnerHarmV inner = new OverAreaLimitVO.InnerHarmV();
inner.setName(name);
inner.setLimitIdList(new ArrayList<>(lineIds));
inner.setLimitCount(limitCount);
inner.setLimitRate(BigDecimal.valueOf(limitCount * 1.0 / onlineNum * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
inner.setDayAvg(BigDecimal.valueOf(dayList.stream().mapToDouble(it -> it).average().orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue());
inner.setDayLimit(limitCount == 0 ? 0.0 : BigDecimal.valueOf(everydayAllNum * 1.0 / limitCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
return inner;
}
private boolean vHarmFlag(RStatLimitTargetDPO x) {
int count = x.getUaberranceOvertime() +
x.getUharm2Overtime() + x.getUharm3Overtime() + x.getUharm4Overtime() + x.getUharm5Overtime() +
x.getUharm6Overtime() + x.getUharm7Overtime() + x.getUharm8Overtime() + x.getUharm9Overtime() +
x.getUharm10Overtime() + x.getUharm11Overtime() + x.getUharm12Overtime() + x.getUharm13Overtime() + x.getUharm14Overtime() +
x.getUharm15Overtime() + x.getUharm16Overtime() + x.getUharm17Overtime() + x.getUharm18Overtime() + x.getUharm19Overtime() +
x.getUharm20Overtime() + x.getUharm21Overtime() + x.getUharm22Overtime() + x.getUharm23Overtime() + x.getUharm24Overtime() +
x.getUharm25Overtime();
return count > 0;
}
private boolean iHarmFlag(RStatLimitTargetDPO rStatLimitRateDPO) {
int count = rStatLimitRateDPO.getIharm2Overtime() +
rStatLimitRateDPO.getIharm3Overtime() +
rStatLimitRateDPO.getIharm4Overtime() +
rStatLimitRateDPO.getIharm5Overtime() +
rStatLimitRateDPO.getIharm6Overtime() +
rStatLimitRateDPO.getIharm7Overtime() +
rStatLimitRateDPO.getIharm8Overtime() +
rStatLimitRateDPO.getIharm9Overtime() +
rStatLimitRateDPO.getIharm10Overtime() +
rStatLimitRateDPO.getIharm11Overtime() +
rStatLimitRateDPO.getIharm12Overtime() +
rStatLimitRateDPO.getIharm13Overtime() +
rStatLimitRateDPO.getIharm14Overtime() +
rStatLimitRateDPO.getIharm15Overtime() +
rStatLimitRateDPO.getIharm16Overtime() +
rStatLimitRateDPO.getIharm17Overtime() +
rStatLimitRateDPO.getIharm18Overtime() +
rStatLimitRateDPO.getIharm19Overtime() +
rStatLimitRateDPO.getIharm20Overtime() +
rStatLimitRateDPO.getIharm21Overtime() +
rStatLimitRateDPO.getIharm22Overtime() +
rStatLimitRateDPO.getIharm23Overtime() +
rStatLimitRateDPO.getIharm24Overtime() +
rStatLimitRateDPO.getIharm25Overtime();
return count > 0;
}
private boolean inHarmFlag(RStatLimitTargetDPO t) {
int count = t.getInuharm1Overtime() + t.getInuharm2Overtime() + t.getInuharm3Overtime() + t.getInuharm4Overtime() + t.getInuharm5Overtime() + t.getInuharm6Overtime() + t.getInuharm7Overtime() + t.getInuharm8Overtime() + t.getInuharm9Overtime() + t.getInuharm10Overtime() + t.getInuharm11Overtime() + t.getInuharm12Overtime() + t.getInuharm13Overtime() + t.getInuharm14Overtime() + t.getInuharm15Overtime() + t.getInuharm16Overtime();
return count > 0;
}
/**
* 功能描述: 处理区域在线监测点数、超标监测点数
*

View File

@@ -1,4 +1,11 @@
package com.njcn.harmonic.service.report;
import com.njcn.harmonic.pojo.param.report.AreaHarmReportParam;
import javax.servlet.http.HttpServletResponse;
public interface AreaHarmonicService {
void areaHarmonicReport(AreaHarmReportParam areaHarmReportParam, HttpServletResponse response);
}

View File

@@ -1,16 +1,783 @@
package com.njcn.harmonic.service.report.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.MonitorCommLedgerInfoDTO;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.harmonic.pojo.dto.report.TableMergeRule;
import com.njcn.harmonic.pojo.param.report.AreaHarmReportParam;
import com.njcn.harmonic.pojo.vo.OverAreaLimitVO;
import com.njcn.harmonic.pojo.vo.OverAreaVO;
import com.njcn.harmonic.service.IAnalyzeService;
import com.njcn.harmonic.service.report.AreaHarmonicService;
import com.njcn.harmonic.utils.WordUtil2;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.po.Dept;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* @Author: cdf
* @CreateTime: 2026-01-04
* @Description: 区域报告
* @Description: 区域报告 - 优化版本
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class AreaHarmonicServiceImpl implements AreaHarmonicService {
// 常量定义
private static final String REPORT_TEMPLATE_PATH = "file/areaReportTemplate.docx";
private static final String DEFAULT_PROVIDER_DEPT = "中国电力技术研究院";
private static final String NO_DATA_PLACEHOLDER = "";
private static final String UNKNOWN_VALUE = "/";
// 指标等级阈值
private static final double EXCELLENT_MAX_THRESHOLD = 5.0;
private static final double GOOD_MAX_THRESHOLD = 10.0;
private static final double MEDIUM_MAX_THRESHOLD = 30.0;
// 谐波次数顺序(保持原有顺序)
private static final List<String> HARMONIC_ORDERS = Arrays.asList("3", "5", "7", "11");
// 表格索引(保持原有顺序)
private static final int LEDGER_TABLE_INDEX = 1;
private static final int VOLTAGE_DEV_TABLE_INDEX = 3;
private static final int FREQUENCY_TABLE_INDEX = 4;
private static final int VOLTAGE_BALANCE_TABLE_INDEX = 5;
private static final int FLICKER_TABLE_INDEX = 6;
private static final int VOLTAGE_HARMONIC_TABLE_INDEX = 7;
private static final int CURRENT_HARMONIC_TABLE_INDEX = 8;
private final WordUtil2 wordUtil2;
private final DeptFeignClient deptFeignClient;
private final CommTerminalGeneralClient commTerminalGeneralClient;
private final IAnalyzeService iAnalyzeService; // 修正变量名
private final DicDataFeignClient dicDataFeignClient;
@Override
public void areaHarmonicReport(AreaHarmReportParam areaHarmReportParam, HttpServletResponse response) {
try {
Assert.notNull(areaHarmReportParam, "报告参数不能为空");
// 1. 构建报告数据
Map<String, Object> reportData = buildReportData(areaHarmReportParam);
// 2. 构建表格数据
List<List<String[]>> tableList = buildTableData(areaHarmReportParam,reportData);
// 3. 生成Word报告
generateWordReport(reportData, tableList, response);
} catch (Exception e) {
log.error("区域谐波报告生成失败,参数: {}", areaHarmReportParam, e);
throw new BusinessException(CommonResponseEnum.FAIL,"报告生成失败");
}
}
/**
* 构建报告基础数据
*/
private Map<String, Object> buildReportData(AreaHarmReportParam param) {
Map<String, Object> reportData = new HashMap<>(32);
// 部门信息
Dept dept = getDeptInfo(param.getDeptId());
reportData.put("$deptName$", dept.getName());
reportData.put("$provideDept$", DEFAULT_PROVIDER_DEPT);
reportData.put("$TitleTime$", DateUtil.format(new DateTime(), DatePattern.CHINESE_DATE_PATTERN));
// 时间范围
String timeRange = formatTimeRange(param.getStartTime(), param.getEndTime());
reportData.put("$reportRangeTime$", timeRange);
return reportData;
}
/**
* 构建所有表格数据
*/
private List<List<String[]>> buildTableData(AreaHarmReportParam param,Map<String, Object> reportData) {
List<List<String[]>> tableList = new ArrayList<>();
// 添加空行(保持原有结构)
tableList.add(new ArrayList<>());
// 1. 台账表格
List<String[]> ledgerTable = buildLedgerTable(param.getDeptId());
tableList.add(ledgerTable);
// 添加空行(保持原有结构)
tableList.add(new ArrayList<>());
// 2. 电能质量数据表格
List<OverAreaLimitVO> qualityData = getPowerQualityData(param);
if (CollUtil.isNotEmpty(qualityData)) {
// 构建监控点名称映射
Map<String, String> monitorNameMap = buildMonitorNameMap(param.getDeptId());
// 过滤有效数据(在线监控数>0
List<OverAreaLimitVO> validData = qualityData.stream()
.filter(vo -> vo.getOnlineMonitorNumber() != null && vo.getOnlineMonitorNumber() > 0)
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(validData)) {
tableList.add(buildVoltageDeviationTable(validData));
tableList.add(buildFrequencyTable(validData));
tableList.add(buildVoltageBalanceTable(validData));
tableList.add(buildFlickerTable(validData));
tableList.add(buildVoltageHarmonicTable(validData));
tableList.add(buildCurrentHarmonicTable(validData));
// 计算并设置指标数据到临时存储,稍后合并
calculateAndStoreIndicatorData(reportData, validData, monitorNameMap);
}
}
// 添加空行(保持原有结构)
tableList.add(new ArrayList<>());
return tableList;
}
/**
* 构建台账表格
*/
private List<String[]> buildLedgerTable(String deptId) {
List<MonitorCommLedgerInfoDTO> ledgerList = getLedgerInfo(deptId);
if (CollUtil.isEmpty(ledgerList)) {
return new ArrayList<>();
}
// 获取电压等级字典
Map<String, String> voltageLevelMap = getVoltageLevelMap();
return IntStream.range(0, ledgerList.size())
.mapToObj(i -> {
MonitorCommLedgerInfoDTO ledger = ledgerList.get(i);
return new String[]{
String.valueOf(i + 1),
ledger.getMonitorName(),
ledger.getBdName(),
ledger.getBusBarName(),
voltageLevelMap.getOrDefault(ledger.getVoltageLevel(), ""),
ledger.getShortCapacity(),
ledger.getDevCapacity(),
ledger.getDealCapacity()
};
})
.collect(Collectors.toList());
}
/**
* 构建电压偏差表格
*/
private List<String[]> buildVoltageDeviationTable(List<OverAreaLimitVO> dataList) {
return dataList.stream()
.filter(vo -> vo.getOnlineMonitorNumber() != null && vo.getOnlineMonitorNumber() > 0)
.map(vo -> new String[]{
vo.getName(),
vo.getOnlineMonitorNumber().toString(),
vo.getVoltageMonitorNumber().toString(),
vo.getVoltageBiLi().toString(),
vo.getVoltageDayAvgBiLi().toString(),
vo.getVoltageOverDayBiLi().toString()
})
.collect(Collectors.toList());
}
/**
* 构建频率表格
*/
private List<String[]> buildFrequencyTable(List<OverAreaLimitVO> dataList) {
return dataList.stream()
.filter(vo -> vo.getOnlineMonitorNumber() != null && vo.getOnlineMonitorNumber() > 0)
.map(vo -> new String[]{
vo.getName(),
vo.getOnlineMonitorNumber().toString(),
vo.getFrequencyMonitorNumber().toString(),
vo.getFrequencyBiLi().toString(),
vo.getFrequencyDayAvgBiLi().toString(),
vo.getFrequencyOverDayBiLi().toString()
})
.collect(Collectors.toList());
}
/**
* 构建三相电压不平衡度表格
*/
private List<String[]> buildVoltageBalanceTable(List<OverAreaLimitVO> dataList) {
return dataList.stream()
.filter(vo -> vo.getOnlineMonitorNumber() != null && vo.getOnlineMonitorNumber() > 0)
.map(vo -> new String[]{
vo.getName(),
vo.getOnlineMonitorNumber().toString(),
vo.getThreePhaseVoltageMonitorNumber().toString(),
vo.getThreePhaseVoltageBiLi().toString(),
vo.getThreePhaseVoltageDayAvgBiLi().toString(),
vo.getThreePhaseVoltageOverDayBiLi().toString()
})
.collect(Collectors.toList());
}
/**
* 构建闪变表格
*/
private List<String[]> buildFlickerTable(List<OverAreaLimitVO> dataList) {
return dataList.stream()
.filter(vo -> vo.getOnlineMonitorNumber() != null && vo.getOnlineMonitorNumber() > 0)
.map(vo -> new String[]{
vo.getName(),
vo.getOnlineMonitorNumber().toString(),
vo.getFlickerMonitorNumber().toString(),
vo.getFlickerBiLi().toString(),
vo.getFlickerDayAvgBiLi().toString(),
vo.getFlickerOverDayBiLi().toString()
})
.collect(Collectors.toList());
}
/**
* 构建谐波电压表格
*/
private List<String[]> buildVoltageHarmonicTable(List<OverAreaLimitVO> dataList) {
List<String[]> tableData = new ArrayList<>();
for (OverAreaLimitVO vo : dataList) {
if (vo.getOnlineMonitorNumber() == null || vo.getOnlineMonitorNumber() == 0) {
continue;
}
// 添加总行
tableData.add(new String[]{
vo.getName(),
"2~25",
vo.getOnlineMonitorNumber().toString(),
vo.getHarmonicVoltageMonitorNumber().toString(),
vo.getHarmonicVoltageBiLi().toString(),
vo.getHarmonicVoltageDayAvgBiLi().toString(),
vo.getHarmonicVoltageOverDayBiLi().toString()
});
// 添加各次谐波行
if (CollUtil.isNotEmpty(vo.getInnerHarmVList())) {
for (OverAreaLimitVO.InnerHarmV innerHarm : vo.getInnerHarmVList()) {
tableData.add(new String[]{
"",
innerHarm.getName(),
vo.getOnlineMonitorNumber().toString(),
innerHarm.getLimitCount().toString(),
innerHarm.getLimitRate().toString(),
innerHarm.getDayAvg().toString(),
innerHarm.getDayLimit().toString()
});
}
}
}
return tableData;
}
/**
* 构建谐波电流表格
*/
private List<String[]> buildCurrentHarmonicTable(List<OverAreaLimitVO> dataList) {
List<String[]> tableData = new ArrayList<>();
for (OverAreaLimitVO vo : dataList) {
if (vo.getOnlineMonitorNumber() == null || vo.getOnlineMonitorNumber() == 0) {
continue;
}
// 添加总行
tableData.add(new String[]{
vo.getName(),
"2~25",
vo.getOnlineMonitorNumber().toString(),
vo.getHarmonicCurrentMonitorNumber().toString(),
vo.getHarmonicCurrentBiLi().toString(),
vo.getHarmonicVoltageDayAvgBiLi().toString(), // 注意:这里保持原逻辑,使用谐波电压日均值
vo.getHarmonicCurrentOverDayBiLi().toString()
});
// 添加各次谐波行
if (CollUtil.isNotEmpty(vo.getInnerHarmIList())) {
for (OverAreaLimitVO.InnerHarmV innerHarm : vo.getInnerHarmIList()) {
tableData.add(new String[]{
"",
innerHarm.getName(),
vo.getOnlineMonitorNumber().toString(),
innerHarm.getLimitCount().toString(),
innerHarm.getLimitRate().toString(),
innerHarm.getDayAvg().toString(),
innerHarm.getDayLimit().toString()
});
}
}
}
return tableData;
}
/**
* 计算并存储指标数据
*/
private void calculateAndStoreIndicatorData(Map<String, Object> reportData,
List<OverAreaLimitVO> validData,
Map<String, String> monitorNameMap) {
// 电压偏差
processVoltageDeviation(reportData, validData, monitorNameMap);
// 频率偏差
processFrequencyDeviation(reportData, validData, monitorNameMap);
// 三相电压不平衡度
processVoltageBalance(reportData, validData, monitorNameMap);
// 闪变
processFlicker(reportData, validData, monitorNameMap);
// 谐波电压
processVoltageHarmonic(reportData, validData, monitorNameMap);
// 谐波电流
processCurrentHarmonic(reportData, validData, monitorNameMap);
// 生成结论
generateConclusion(reportData);
}
/**
* 处理电压偏差
*/
private void processVoltageDeviation(Map<String, Object> reportData,
List<OverAreaLimitVO> dataList,
Map<String, String> monitorNameMap) {
double avgRate = calculateAverage(dataList, OverAreaLimitVO::getVoltageBiLi);
List<String> monitorList = extractMonitorNames(dataList,
vo -> vo.getVoltageMonitorList(), monitorNameMap);
reportData.put("$voltageDevRate$", formatPercentage(avgRate));
reportData.put("$voltageDevMark$", getGrade(avgRate));
reportData.put("$voltageDevLine$", formatMonitorList(monitorList));
}
/**
* 处理频率偏差
*/
private void processFrequencyDeviation(Map<String, Object> reportData,
List<OverAreaLimitVO> dataList,
Map<String, String> monitorNameMap) {
double avgRate = calculateAverage(dataList, OverAreaLimitVO::getFrequencyBiLi);
List<String> monitorList = extractMonitorNames(dataList,
vo -> vo.getFreqMonitorList(), monitorNameMap);
reportData.put("$freqRate$", formatPercentage(avgRate));
reportData.put("$freqMark$", getGrade(avgRate));
reportData.put("$freqLine$", formatMonitorList(monitorList));
}
/**
* 处理三相电压不平衡度
*/
private void processVoltageBalance(Map<String, Object> reportData,
List<OverAreaLimitVO> dataList,
Map<String, String> monitorNameMap) {
double avgRate = calculateAverage(dataList, OverAreaLimitVO::getThreePhaseVoltageBiLi);
List<String> monitorList = extractMonitorNames(dataList,
vo -> vo.getThreePhaseVoltageMonitorList(), monitorNameMap);
reportData.put("$balanceRate$", formatPercentage(avgRate));
reportData.put("$balanceMark$", getGrade(avgRate));
reportData.put("$balanceLine$", formatMonitorList(monitorList));
}
/**
* 处理闪变
*/
private void processFlicker(Map<String, Object> reportData,
List<OverAreaLimitVO> dataList,
Map<String, String> monitorNameMap) {
double avgRate = calculateAverage(dataList, OverAreaLimitVO::getFlickerBiLi);
List<String> monitorList = extractMonitorNames(dataList,
vo -> vo.getFlickerMonitorList(), monitorNameMap);
reportData.put("$flickerRate$", formatPercentage(avgRate));
reportData.put("$flickerMark$", getGrade(avgRate));
reportData.put("$flickerLine$", formatMonitorList(monitorList));
}
/**
* 处理谐波电压
*/
private void processVoltageHarmonic(Map<String, Object> reportData,
List<OverAreaLimitVO> dataList,
Map<String, String> monitorNameMap) {
// 总谐波电压
double avgAll = calculateAverage(dataList, OverAreaLimitVO::getHarmonicVoltageBiLi);
List<String> monitorAllList = extractMonitorNames(dataList,
vo -> vo.getHarmonicVoltageMonitorList(), monitorNameMap);
reportData.put("$v_all_Rate$", formatPercentage(avgAll));
reportData.put("$v_all_Mark$", getGrade(avgAll));
reportData.put("$v_all_Line$", formatMonitorList(monitorAllList));
// 各次谐波电压(保持原有顺序)
for (int i = 0; i < HARMONIC_ORDERS.size(); i++) {
final int index = i;
double avgHarmonic = calculateAverageFromInnerList(dataList,
vo -> vo.getInnerHarmVList().get(index).getLimitRate());
List<String> monitorHarmonicList = extractMonitorNamesFromInnerList(dataList,
vo -> vo.getInnerHarmVList().get(index).getLimitIdList(), monitorNameMap);
String harmonicKey = HARMONIC_ORDERS.get(i);
reportData.put("$v_" + harmonicKey + "_Rate$", formatPercentage(avgHarmonic));
reportData.put("$v_" + harmonicKey + "_Mark$", getGrade(avgHarmonic));
reportData.put("$v_" + harmonicKey + "_Line$", formatMonitorList(monitorHarmonicList));
}
}
/**
* 处理谐波电流
*/
private void processCurrentHarmonic(Map<String, Object> reportData,
List<OverAreaLimitVO> dataList,
Map<String, String> monitorNameMap) {
// 总谐波电流
double avgAll = calculateAverage(dataList, OverAreaLimitVO::getHarmonicCurrentBiLi);
List<String> monitorAllList = extractMonitorNames(dataList,
vo -> vo.getHarmonicCurrentMonitorList(), monitorNameMap);
reportData.put("$i_all_Rate$", formatPercentage(avgAll));
reportData.put("$i_all_Mark$", getGrade(avgAll));
reportData.put("$i_all_Line$", formatMonitorList(monitorAllList));
// 各次谐波电流(保持原有顺序)
for (int i = 0; i < HARMONIC_ORDERS.size(); i++) {
final int index = i;
double avgHarmonic = calculateAverageFromInnerList(dataList,
vo -> vo.getInnerHarmIList().get(index).getLimitRate());
List<String> monitorHarmonicList = extractMonitorNamesFromInnerList(dataList,
vo -> vo.getInnerHarmIList().get(index).getLimitIdList(), monitorNameMap);
String harmonicKey = HARMONIC_ORDERS.get(i);
reportData.put("$i_" + harmonicKey + "_Rate$", formatPercentage(avgHarmonic));
reportData.put("$i_" + harmonicKey + "_Mark$", getGrade(avgHarmonic));
reportData.put("$i_" + harmonicKey + "_Line$", formatMonitorList(monitorHarmonicList));
}
}
/**
* 生成结论
*/
private void generateConclusion(Map<String, Object> reportData) {
Map<String, String> indicatorScores = new LinkedHashMap<>();
indicatorScores.put("供电电压偏差", reportData.get("$voltageDevMark$").toString());
indicatorScores.put("频率偏差", reportData.get("$freqMark$").toString());
indicatorScores.put("三相电压不平衡度", reportData.get("$balanceMark$").toString());
indicatorScores.put("闪变", reportData.get("$flickerMark$").toString());
indicatorScores.put("谐波电压", reportData.get("$v_all_Mark$").toString());
indicatorScores.put("谐波电流", reportData.get("$i_all_Mark$").toString());
// 按等级分类指标
Map<String, List<String>> categorizedIndicators = categorizeIndicators(indicatorScores);
// 构建结论文本
String conclusion = buildConclusionText(categorizedIndicators);
reportData.put("$conclusion$", conclusion);
}
/**
* 按等级分类指标
*/
private Map<String, List<String>> categorizeIndicators(Map<String, String> indicatorScores) {
Map<String, List<String>> categorized = new LinkedHashMap<>();
categorized.put("优秀", new ArrayList<>());
categorized.put("", new ArrayList<>());
categorized.put("", new ArrayList<>());
categorized.put("", new ArrayList<>());
indicatorScores.forEach((indicator, grade) -> {
if (categorized.containsKey(grade)) {
categorized.get(grade).add(indicator);
}
});
return categorized;
}
/**
* 构建结论文本
*/
private String buildConclusionText(Map<String, List<String>> categorizedIndicators) {
StringBuilder conclusion = new StringBuilder();
List<String> badIndicators = categorizedIndicators.get("");
// 按顺序构建结论
List<Map.Entry<String, List<String>>> entries = new ArrayList<>(categorizedIndicators.entrySet());
for (Map.Entry<String, List<String>> entry : entries) {
List<String> indicators = entry.getValue();
if (CollUtil.isNotEmpty(indicators)) {
if (conclusion.length() > 0) {
conclusion.append("");
}
conclusion.append(String.join("", indicators))
.append("等指标评分为").append(entry.getKey());
}
}
// 添加重点关注提示
if (CollUtil.isNotEmpty(badIndicators)) {
conclusion.append(",需要重点关注该区域")
.append(String.join("", badIndicators))
.append("等指标情况");
}
return conclusion.toString();
}
/**
* 生成Word报告
*/
private void generateWordReport(Map<String, Object> reportData,
List<List<String[]>> tableList,
HttpServletResponse response) {
try {
// 构建表格合并规则
List<TableMergeRule> mergeRules = buildTableMergeRules();
// 生成文件名
String fileName = generateFileName();
// 调用Word工具生成报告
wordUtil2.getWord(REPORT_TEMPLATE_PATH, reportData, fileName,
tableList, mergeRules, response);
} catch (Exception e) {
log.error("Word报告生成失败", e);
throw new BusinessException(CommonResponseEnum.FAIL,"Word报告生成失败");
}
}
/**
* 构建表格合并规则
*/
private List<TableMergeRule> buildTableMergeRules() {
List<TableMergeRule> mergeRules = new ArrayList<>();
// 表格7谐波电压的第0列每5行合并一次对应"单位"列)
mergeRules.add(TableMergeRule.build(VOLTAGE_HARMONIC_TABLE_INDEX, 0, 1, 5));
// 表格8谐波电流的第0列每5行合并一次对应"单位"列)
mergeRules.add(TableMergeRule.build(CURRENT_HARMONIC_TABLE_INDEX, 0, 1, 5));
return mergeRules;
}
/**
* 生成文件名
*/
private String generateFileName() {
return "fileName.docx"; // 保持原有文件名逻辑
}
/**
* 工具方法:计算平均值
*/
private double calculateAverage(List<OverAreaLimitVO> dataList,
Function<OverAreaLimitVO, Double> valueExtractor) {
return dataList.stream()
.map(valueExtractor)
.filter(value -> value != null && value >= 0)
.mapToDouble(Double::doubleValue)
.average()
.orElse(0.0);
}
/**
* 工具方法:从内部列表计算平均值
*/
private double calculateAverageFromInnerList(List<OverAreaLimitVO> dataList,
Function<OverAreaLimitVO, Double> valueExtractor) {
return dataList.stream()
.map(valueExtractor)
.filter(value -> value != null && value >= 0)
.mapToDouble(Double::doubleValue)
.average()
.orElse(0.0);
}
/**
* 工具方法:提取监控点名称
*/
private List<String> extractMonitorNames(List<OverAreaLimitVO> dataList,
Function<OverAreaLimitVO, List<String>> idExtractor,
Map<String, String> idToNameMap) {
return dataList.stream()
.flatMap(vo -> {
List<String> ids = idExtractor.apply(vo);
return ids != null ? ids.stream() : Stream.<String>empty();
})
.distinct()
.map(idToNameMap::get)
.filter(name -> name != null && !name.trim().isEmpty())
.collect(Collectors.toList());
}
/**
* 工具方法:从内部列表提取监控点名称
*/
private List<String> extractMonitorNamesFromInnerList(List<OverAreaLimitVO> dataList,
Function<OverAreaLimitVO, List<String>> idExtractor,
Map<String, String> idToNameMap) {
return dataList.stream()
.flatMap(vo -> {
List<String> ids = idExtractor.apply(vo);
return ids != null ? ids.stream() : Stream.<String>empty();
})
.distinct()
.map(idToNameMap::get)
.filter(name -> name != null && !name.trim().isEmpty())
.collect(Collectors.toList());
}
/**
* 工具方法:格式化百分比
*/
private String formatPercentage(double value) {
if (value < 0) {
return UNKNOWN_VALUE;
}
return BigDecimal.valueOf(value)
.setScale(2, RoundingMode.HALF_UP)
.doubleValue() + "%";
}
/**
* 工具方法:获取等级
*/
private String getGrade(double value) {
if (value < 0) {
return UNKNOWN_VALUE;
} else if (value <= EXCELLENT_MAX_THRESHOLD) {
return "优秀";
} else if (value <= GOOD_MAX_THRESHOLD) {
return "";
} else if (value <= MEDIUM_MAX_THRESHOLD) {
return "";
} else {
return "";
}
}
/**
* 工具方法:格式化时间范围
*/
private String formatTimeRange(String startTime, String endTime) {
try {
String start = DateUtil.format(
DateUtil.beginOfDay(DateUtil.parse(startTime)),
DatePattern.NORM_DATETIME_PATTERN
);
String end = DateUtil.format(
DateUtil.endOfDay(DateUtil.parse(endTime)),
DatePattern.NORM_DATETIME_PATTERN
);
return start + "-" + end;
} catch (Exception e) {
log.error("格式化时间范围失败", e);
return "";
}
}
/**
* 工具方法:格式化监控点列表
*/
private String formatMonitorList(List<String> monitorList) {
if (CollUtil.isEmpty(monitorList)) {
return NO_DATA_PLACEHOLDER;
}
return String.join(",", monitorList);
}
/**
* 获取部门信息
*/
private Dept getDeptInfo(String deptId) {
return deptFeignClient.getDeptById(deptId).getData();
}
/**
* 获取台账信息
*/
private List<MonitorCommLedgerInfoDTO> getLedgerInfo(String deptId) {
DeptGetLineParam param = new DeptGetLineParam();
param.setDeptId(deptId);
return commTerminalGeneralClient.deptGetLineInfo(param).getData();
}
/**
* 获取电压等级字典
*/
private Map<String, String> getVoltageLevelMap() {
List<DictData> dictDataList = dicDataFeignClient
.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE_STAND.getCode())
.getData();
return dictDataList.stream()
.collect(Collectors.toMap(DictData::getId, DictData::getName));
}
/**
* 构建监控点名称映射
*/
private Map<String, String> buildMonitorNameMap(String deptId) {
List<MonitorCommLedgerInfoDTO> ledgerList = getLedgerInfo(deptId);
return ledgerList.stream()
.collect(Collectors.toMap(
MonitorCommLedgerInfoDTO::getMonitorId,
MonitorCommLedgerInfoDTO::getMonitorName
));
}
/**
* 获取电能质量数据
*/
private List<OverAreaLimitVO> getPowerQualityData(AreaHarmReportParam param) {
OverAreaVO queryParam = new OverAreaVO();
queryParam.setDeptIndex(param.getDeptId());
queryParam.setPageNum(1);
queryParam.setPageSize(1000);
queryParam.setSearchBeginTime(param.getStartTime());
queryParam.setSearchEndTime(param.getEndTime());
queryParam.setStatisticalType(new SimpleDTO());
queryParam.setAreaReportFlag(1);
Page<OverAreaLimitVO> page = iAnalyzeService.getAreaData(queryParam);
return page.getRecords();
}
}