feat(report): 新增敏感用户报表生成功能

This commit is contained in:
贾同学
2025-12-02 08:56:34 +08:00
parent 8e4c4383c0
commit cea2b9694a
4 changed files with 541 additions and 59 deletions

View File

@@ -9,14 +9,13 @@ import javax.validation.constraints.NotBlank;
@Data
public class SensitiveUserReportQueryParam {
@NotBlank(message = "监测对象id不可为空")
@ApiModelProperty(name = "lineId",value = "监测对象id")
private String sensitiveUserId;
@NotBlank(message = "模板ID不可为空")
@ApiModelProperty(name = "tempId",value = "模板ID")
private String tempId;
@ApiModelProperty(name = "searchBeginTime", value = "开始时间")
@NotBlank(message = "起始时间不可为空")
@DateTimeStrValid(message = "起始时间格式出错")
@@ -26,10 +25,4 @@ public class SensitiveUserReportQueryParam {
@NotBlank(message = "结束时间不可为空")
private String searchEndTime;
//目前用于区分不同系统资源null默认 1.无线系统配合cs-device
private Integer resourceType;
//浙江无线报表特殊标识 null为通用报表 1.浙江无线报表
private Integer customType;
}

View File

@@ -0,0 +1,45 @@
package com.njcn.csharmonic.pojo.vo;
import lombok.Data;
@Data
public class ReportTemplateDataVO {
/**
* $HA[_25]#B#max#classId#resourceId$
*/
private String itemName;
private String lineId;
/**
* 对应influxdb数据库中字段
*/
private String templateName;
/**
* 相别
*/
private String phase;
/**
* max min avg cp95
*/
private String statMethod;
/**
* 对应influxdb数据库的表名
*/
private String classId;
/**
* 对应mysql数据库的表名
*/
private String resourceId;
/**
* 填入的value值
*/
private String value;
}

View File

@@ -119,6 +119,27 @@
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>common-mq</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.njcn.platform</groupId>
<artifactId>message-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>harmonic-common</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>

View File

@@ -8,18 +8,18 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONTokener;
import cn.hutool.json.*;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.FileUtil;
import com.njcn.csdevice.api.CsCommTerminalFeignClient;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.api.WlRecordFeignClient;
import com.njcn.csdevice.pojo.po.CsLinePO;
import com.njcn.csdevice.pojo.po.WlRecord;
import com.njcn.csharmonic.enums.CsHarmonicResponseEnum;
import com.njcn.csharmonic.mapper.ExcelRptTempMapper;
@@ -28,6 +28,7 @@ import com.njcn.csharmonic.pojo.dto.ReportTemplateDTO;
import com.njcn.csharmonic.pojo.param.ReportSearchParam;
import com.njcn.csharmonic.pojo.param.ReportTemplateParam;
import com.njcn.csharmonic.pojo.po.ExcelRptTemp;
import com.njcn.csharmonic.pojo.vo.ReportTemplateDataVO;
import com.njcn.csharmonic.pojo.vo.ReportTemplateVO;
import com.njcn.csharmonic.pojo.vo.ReportTreeVO;
import com.njcn.csharmonic.pojo.vo.SysDeptTempVO;
@@ -47,7 +48,6 @@ import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.EleEpdPqd;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.po.User;
import lombok.RequiredArgsConstructor;
@@ -55,6 +55,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@@ -94,8 +95,6 @@ public class CustomReportServiceImpl implements CustomReportService {
private final DicDataFeignClient dicDataFeignClient;
private final DeptFeignClient deptFeignClient;
private final InfluxDbUtils influxDbUtils;
private final CommTerminalGeneralClient commTerminalGeneralClient;
@@ -104,17 +103,46 @@ public class CustomReportServiceImpl implements CustomReportService {
private final WlRecordFeignClient wlRecordFeignClient;
private final UserFeignClient userFeignClient;
private final CsLineFeignClient csLineFeignClient;
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
private final JdbcTemplate jdbcTemplate;
private final String CELL_DATA = "celldata";
private final String V = "v";
private final String STR_ONE = "#";
private final String STR_TWO = "$";
private final String STR_THREE = "&";
private final String STR_FOUR = "%";
private final String STR_FIVE = "~";
private final String limitTable = "pq_overlimit";
private final String GRID_SIDE_DICT_CODE = "Grid_Side";
private final String LOAD_SIDE_DICT_CODE = "Load_Side";
/**
* map key转大写
*/
public static <V> Map<String, V> convertKeysToUpperCase(Map<String, V> originalMap) {
Map<String, V> newMap = new HashMap<>();
if (CollUtil.isNotEmpty(originalMap)) {
for (Map.Entry<String, V> entry : originalMap.entrySet()) {
newMap.put(entry.getKey().toUpperCase(), entry.getValue());
}
}
return newMap;
}
public static boolean isInteger(String str) {
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public void getCustomReport(ReportSearchParam reportSearchParam, HttpServletResponse response) {
TimeInterval timeInterval = new TimeInterval();
@@ -133,7 +161,6 @@ public class CustomReportServiceImpl implements CustomReportService {
log.info("报表执行时间{}秒", timeInterval.intervalSecond());
}
@Override
public boolean addCustomReportTemplate(ReportTemplateParam reportTemplateParam) {
checkName(reportTemplateParam, false);
@@ -218,10 +245,171 @@ public class CustomReportServiceImpl implements CustomReportService {
@Override
public void getSensitiveUserReport(SensitiveUserReportQueryParam queryParam, HttpServletResponse response) {
TimeInterval timeInterval = new TimeInterval();
ExcelRptTemp excelRptTemp = excelRptTempMapper.selectById(queryParam.getTempId());
if (Objects.isNull(excelRptTemp)) {
throw new BusinessException(CsHarmonicResponseEnum.CUSTOM_REPORT_ACTIVE);
}
String sensitiveUserId = queryParam.getSensitiveUserId();
List<CsLinePO> linePOList = csLineFeignClient.getLineBySensitiveUser(Collections.singletonList(sensitiveUserId)).getData();
DictData loadSideDictData = dicDataFeignClient.getDicDataByCode(LOAD_SIDE_DICT_CODE).getData();
DictData gridSideDictData = dicDataFeignClient.getDicDataByCode(GRID_SIDE_DICT_CODE).getData();
CsLinePO gridSideLine = linePOList.stream().filter(linePO -> linePO.getPosition().equals(gridSideDictData.getId())).findFirst().orElse(null);
CsLinePO loadSideLine = linePOList.stream().filter(linePO -> linePO.getPosition().equals(loadSideDictData.getId())).findFirst().orElse(null);
String lineName = "";
// 模版内容数据
JSONArray templateData;
try (InputStream fileStream = fileStorageUtil.getFileStream(excelRptTemp.getContent())) {
templateData = new JSONArray(new JSONTokener(fileStream, new JSONConfig()));
} catch (Exception e) {
throw new BusinessException(CsHarmonicResponseEnum.CUSTOM_REPORT_JSON);
}
//指标数据
List<ReportTemplateDataVO> indexDataList = new ArrayList<>();
// 改善率数据
List<ReportTemplateDataVO> improvementRateDataList = new ArrayList<>();
// 基础数据
List<ReportTemplateDataVO> basicDataList = new ArrayList<>();
parseGovernTemplate(templateData, indexDataList, improvementRateDataList, basicDataList);
Set<ReportTemplateDataVO> beforeFinalDataList = new HashSet<>();
Set<ReportTemplateDataVO> afterFinalDataList = new HashSet<>();
if (CollUtil.isNotEmpty(indexDataList)) {
//开始组织sql
indexDataList = new LinkedHashSet<>(indexDataList).stream().sorted(Comparator.comparing(ReportTemplateDataVO::getItemName)).collect(Collectors.toList());
Map<String, List<ReportTemplateDataVO>> classMap = indexDataList.stream().collect(Collectors.groupingBy(ReportTemplateDataVO::getResourceId));
//定义存放指标的map
if (gridSideLine != null) {
lineName = gridSideLine.getName();
List<ReportTemplateDataVO> afterDataList = fetchDataList(gridSideLine, classMap, queryParam);
afterFinalDataList.addAll(afterDataList);
}
if (loadSideLine != null) {
lineName = loadSideLine.getName();
List<ReportTemplateDataVO> beforeDataList = fetchDataList(loadSideLine, classMap, queryParam);
beforeFinalDataList.addAll(beforeDataList);
}
}
//进行反向赋值到模板
//1、根据itemName分组
Map<String, List<ReportTemplateDataVO>> beforeAssMap = beforeFinalDataList.stream().collect(Collectors.groupingBy(ReportTemplateDataVO::getItemName));
Map<String, List<ReportTemplateDataVO>> afterAssMap = afterFinalDataList.stream().collect(Collectors.groupingBy(ReportTemplateDataVO::getItemName));
//处理台账信息,暂时没用到
/* Map<String, String> finalBasicMap = new HashMap<>();
if (CollUtil.isNotEmpty(basicDataList)) {
finalBasicMap.put("LINENAME", lineName);
}*/
//2、把itemName的value赋给v和m
JSONArray finalExcelData = new JSONArray();
for (Object sheet : templateData) {
JSONObject sheetData = JSONUtil.parseObj(sheet);
JSONArray cellDataArray = sheetData.getJSONArray(CELL_DATA);
JSONArray newCellDataArray = new JSONArray();
for (Object cell : cellDataArray) {
Object newCell = cell;
if (Objects.nonNull(cell) && !"null".equals(cell.toString())) {
//获取到1列
JSONObject data = JSONUtil.parseObj(cell);
JSONObject son = data.getJSONObject(V);
if (son.containsKey(V)) {
String v = son.getStr(V);
if (StrUtil.isNotEmpty(v)) {
//数据格式:$HA[_25]#B#max#classId$ 或 $HA[_25]#max#classId$
if (v.charAt(0) == '$' && v.contains(STR_ONE)) {
String value = "/";
List<ReportTemplateDataVO> rDto = beforeAssMap.getOrDefault(v.replace(STR_TWO, "").toUpperCase(), null);
if (CollUtil.isNotEmpty(rDto)) {
value = rDto.get(0).getValue();
}
son.putOpt(V, value);
} else if (v.charAt(0) == '~' && v.contains(STR_ONE)) {
String value = "/";
List<ReportTemplateDataVO> rDto = afterAssMap.getOrDefault(v.replace(STR_FIVE, "").replace(STR_TWO, "").toUpperCase(), null);
if (CollUtil.isNotEmpty(rDto)) {
value = rDto.get(0).getValue();
}
son.putOpt(V, value);
} else if (v.charAt(0) == '%' && v.contains(STR_ONE)) {
// 改善率计算
String value = "/";
if (CollUtil.isNotEmpty(improvementRateDataList)) {
String baseItem = v.replace(STR_FOUR, "").toUpperCase();
ReportTemplateDataVO beforeData = beforeFinalDataList.stream().filter(it -> it.getItemName().replace(STR_TWO, "").toUpperCase().startsWith(baseItem)).findFirst().orElse(null);
ReportTemplateDataVO afterData = afterFinalDataList.stream().filter(it -> it.getItemName().replace(STR_FIVE, "").replace(STR_TWO, "").toUpperCase().startsWith(baseItem)).findFirst().orElse(null);
if (afterData != null && beforeData != null) {
String beforeDataValue = beforeData.getValue();
String afterDataValue = afterData.getValue();
if (StrUtil.isNotEmpty(beforeDataValue) && StrUtil.isNotEmpty(afterDataValue)) {
// (治理前 - 治理后) / 治理前 * 100
BigDecimal before = new BigDecimal(beforeData.getValue());
if (before.compareTo(BigDecimal.ZERO) == 0) {
value = "0.00";
} else {
BigDecimal after = new BigDecimal(afterData.getValue());
BigDecimal result = before.subtract(after)
.divide(before, 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100))
.setScale(2, RoundingMode.HALF_UP);
value = result.toString();
}
}
}
}
son.putOpt(V, value);
} else if (v.charAt(0) == '&') {
// 基础数据
String baseItem = v.replace(STR_THREE, "").toUpperCase();
if (baseItem.startsWith("LINENAME")) {
//台账信息
son.putOpt(V, baseItem.replace("LINENAME", lineName));
}
} else if (v.contains("start_time") && v.contains("end_time")){
//如时间是大于当前时间则用当前时间
LocalDate startDate = LocalDateTimeUtil.parseDate(queryParam.getSearchBeginTime(), DatePattern.NORM_DATE_PATTERN);
LocalDate nowDate = LocalDate.now();
if (!nowDate.isAfter(startDate)) {
startDate = LocalDate.now();
}
String startTime = LocalDateTimeUtil.format(startDate, DatePattern.NORM_DATE_PATTERN) + InfluxDbSqlConstant.START_TIME;
//如时间是大于当前时间则用当前时间
String localTime = InfluxDbSqlConstant.END_TIME;
LocalDate endDate = LocalDateTimeUtil.parseDate(queryParam.getSearchEndTime(), DatePattern.NORM_DATE_PATTERN);
if (nowDate.isAfter(endDate)) {
localTime = " " + LocalTime.now().format(DatePattern.NORM_TIME_FORMATTER);
}
String endTime = queryParam.getSearchEndTime() + localTime;
String val = v.replace(STR_THREE, "").replace("start_time", startTime).replace("end_time", endTime);
son.putOpt(V, val);
}
}
}
data.putOpt(V, son);
newCell = data;
}
newCellDataArray.add(newCell);
}
sheetData.putOpt(CELL_DATA, newCellDataArray);
sheetData.remove("data");
sheetData.remove("data1");
finalExcelData.add(sheetData);
}
//导出自定义报表
downReport(finalExcelData, response);
log.info("报表执行时间{}秒", timeInterval.intervalSecond());
}
@Override
public List<ReportTemplateVO> getTemplateList(ReportSearchParam reportSearchParam) {
List<ReportTemplateVO> list = excelRptTempMapper.getReportTemplateList(reportSearchParam);
@@ -246,21 +434,20 @@ public class CustomReportServiceImpl implements CustomReportService {
return true;
}
@Override
public List<ReportTreeVO> reportChooseTree() {
List<ReportTreeVO> tree = new ArrayList<>();
DictData dic = dicDataFeignClient.getDicDataByNameAndTypeName(DicDataTypeEnum.CS_DATA_TYPE.getName(), DicDataEnum.PQD.getName()).getData();
List<EleEpdPqd> epdList = epdFeignClient.dictMarkByDataType(dic.getId()).getData();
epdList = epdList.stream().filter(it->StrUtil.isNotBlank(it.getResourcesId())).collect(Collectors.toList());
epdList = epdList.stream().filter(it -> StrUtil.isNotBlank(it.getResourcesId())).collect(Collectors.toList());
if(CollUtil.isEmpty(epdList)){
if (CollUtil.isEmpty(epdList)) {
return tree;
}
List<DictData> dayTableList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DATA_DAY.getCode()).getData();
Map<String,String> dayTableMap = dayTableList.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));
Map<String, String> dayTableMap = dayTableList.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));
epdList.forEach(item->item.setResourcesId(dayTableMap.get(item.getResourcesId())));
epdList.forEach(item -> item.setResourcesId(dayTableMap.get(item.getResourcesId())));
epdList.sort(Comparator.comparingInt(EleEpdPqd::getSort));
Map<String, List<EleEpdPqd>> map = epdList.stream().collect(Collectors.groupingBy(EleEpdPqd::getName, LinkedHashMap::new, Collectors.toList()));
@@ -375,7 +562,6 @@ public class CustomReportServiceImpl implements CustomReportService {
}
private void assStatMethod(EleEpdPqd item, List<ReportTreeVO> statTree, String oneKey, String twoKey) {
//存在相别为M但是Stat_Method不为空
if (StrUtil.isNotBlank(item.getStatMethod())) {
@@ -403,7 +589,6 @@ public class CustomReportServiceImpl implements CustomReportService {
}
}
/**
* 检查名称是否已存在
*
@@ -430,7 +615,6 @@ public class CustomReportServiceImpl implements CustomReportService {
}
/**
* 数据单位信息
*
@@ -493,7 +677,6 @@ public class CustomReportServiceImpl implements CustomReportService {
return unit;
}
/**
* @param data 同类型的cell模板
* @param sql 单个cell模板
@@ -645,7 +828,6 @@ public class CustomReportServiceImpl implements CustomReportService {
endList.addAll(data);
}
/**
* @param data 同类型的cell模板
* @param sql 单个cell模板
@@ -784,22 +966,124 @@ public class CustomReportServiceImpl implements CustomReportService {
endList.addAll(data);
}
/**
* map key转大写
*/
public static <V> Map<String, V> convertKeysToUpperCase(Map<String, V> originalMap) {
Map<String, V> newMap = new HashMap<>();
if (CollUtil.isNotEmpty(originalMap)) {
for (Map.Entry<String, V> entry : originalMap.entrySet()) {
newMap.put(entry.getKey().toUpperCase(), entry.getValue());
private void assSqlByMysqlNew(List<ReportTemplateDataVO> data, StringBuilder sql, List<ReportTemplateDataVO> finalDataList, String method, SensitiveUserReportQueryParam queryParam, String lineId) {
//sql拼接示例select MAX(IHA2) as IHA2 from power_quality_data where Phase = 'A' and LineId='1324564568' and Stat_Method='max' tz('Asia/Shanghai')
if (InfluxDbSqlConstant.CP95.equals(method)) {
for (int i = 0; i < data.size(); i++) {
if (i == data.size() - 1) {
sql.append(InfluxDbSqlConstant.MAX)
.append(InfluxDbSqlConstant.LBK)
.append(data.get(i).getTemplateName())
.append(InfluxDbSqlConstant.RBK)
.append(InfluxDbSqlConstant.AS)
.append("\"" + data.get(i).getItemName() + "\"");
} else {
sql.append(InfluxDbSqlConstant.MAX)
.append(InfluxDbSqlConstant.LBK)
.append(data.get(i).getTemplateName())
.append(InfluxDbSqlConstant.RBK)
.append(InfluxDbSqlConstant.AS)
.append("\"" + data.get(i).getItemName() + "\"").append(StrUtil.COMMA);
}
}
} else {
for (int i = 0; i < data.size(); i++) {
if (i == data.size() - 1) {
sql.append(method)
.append(InfluxDbSqlConstant.LBK)
.append(data.get(i).getTemplateName())
.append(InfluxDbSqlConstant.RBK)
.append(InfluxDbSqlConstant.AS)
.append("\"" + data.get(i).getItemName() + "\"");
} else {
sql.append(method)
.append(InfluxDbSqlConstant.LBK)
.append(data.get(i).getTemplateName())
.append(InfluxDbSqlConstant.RBK)
.append(InfluxDbSqlConstant.AS)
.append("\"" + data.get(i).getItemName() + "\"").append(StrUtil.COMMA);
}
}
}
return newMap;
}
//拼接表名
sql.append(StrPool.C_SPACE)
.append(InfluxDbSqlConstant.FROM)
.append(data.get(0).getResourceId());
sql.append(InfluxDbSqlConstant.WHERE)
.append(InfluxDBTableConstant.LINE_ID)
.append(InfluxDbSqlConstant.EQ)
.append(InfluxDbSqlConstant.QM)
.append(lineId)
.append(InfluxDbSqlConstant.QM);
//相别特殊处理
if (!InfluxDBTableConstant.NO_PHASE.equals(data.get(0).getPhase())) {
sql.append(InfluxDbSqlConstant.AND)
.append(InfluxDBTableConstant.PHASIC_TYPE)
.append(InfluxDbSqlConstant.EQ)
.append(InfluxDbSqlConstant.QM)
.append(data.get(0).getPhase())
.append(InfluxDbSqlConstant.QM);
}
sql.append(InfluxDbSqlConstant.AND)
.append(InfluxDBTableConstant.VALUE_TYPE)
.append(InfluxDbSqlConstant.EQ)
.append(InfluxDbSqlConstant.QM)
.append(data.get(0).getStatMethod())
.append(InfluxDbSqlConstant.QM);
//频率和频率偏差仅统计T相
if (data.get(0).getTemplateName().equals("freq_dev") || data.get(0).getTemplateName().equals("freq")) {
sql.append(InfluxDbSqlConstant.AND)
.append(InfluxDBTableConstant.PHASIC_TYPE)
.append(InfluxDbSqlConstant.EQ)
.append(InfluxDbSqlConstant.QM)
.append(InfluxDBTableConstant.PHASE_TYPE_T)
.append(InfluxDbSqlConstant.QM);
}
//时间范围处理
sql.append(InfluxDbSqlConstant.AND)
.append(InfluxDbSqlConstant.TIME).append(InfluxDbSqlConstant.GE).append(InfluxDbSqlConstant.QM).append(queryParam.getSearchBeginTime()).append(InfluxDbSqlConstant.START_TIME).append(InfluxDbSqlConstant.QM)
.append(InfluxDbSqlConstant.AND)
.append(InfluxDbSqlConstant.TIME).append(InfluxDbSqlConstant.LT).append(InfluxDbSqlConstant.QM).append(queryParam.getSearchEndTime()).append(InfluxDbSqlConstant.END_TIME).append(InfluxDbSqlConstant.QM);
System.out.println(sql);
List<Map<String, Object>> mapList = Collections.emptyList();
// 手动切换数据源
DynamicDataSourceContextHolder.push("sjzx");
try {
mapList = jdbcTemplate.queryForList(sql.toString());
} catch (Exception e) {
log.error("查询数据源异常", e);
} finally {
DynamicDataSourceContextHolder.poll();
}
if (CollUtil.isNotEmpty(data)) {
for (ReportTemplateDataVO item : data) {
item.setValue("/");
if (CollUtil.isNotEmpty(mapList)) {
Map<String, Object> map = convertKeysToUpperCase(mapList.get(0));
Object value = map.getOrDefault(item.getItemName(), 0);
if (Objects.nonNull(value)) {
double v = Double.parseDouble(value.toString());
item.setValue(String.format("%.3f", v));
} else {
item.setValue("/");
}
}
}
finalDataList.addAll(data);
}
}
/**
* 处理
*
@@ -829,7 +1113,7 @@ public class CustomReportServiceImpl implements CustomReportService {
}
//处理指标是否合格
reportLimitList = new LinkedHashSet<>(reportLimitList).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList());
Map<String, Float> limitMap = overLimitDeal(reportLimitList, reportSearchParam);
Map<String, Float> limitMap = overLimitDeal(reportLimitList, reportSearchParam.getLineId());
//存放限值指标的map
Map<String, ReportTemplateDTO> limitTargetMapX = reportLimitList.stream().collect(Collectors.toMap(ReportTemplateDTO::getItemName, Function.identity()));
@@ -969,7 +1253,6 @@ public class CustomReportServiceImpl implements CustomReportService {
downReport(jsonArray, response);
}
/**
* 解析模板
*
@@ -1046,6 +1329,101 @@ public class CustomReportServiceImpl implements CustomReportService {
}
}
/**
* 解析治理模板
*/
private void parseGovernTemplate(JSONArray jsonArray, List<ReportTemplateDataVO> indexDataList, List<ReportTemplateDataVO> improvementRateDataList, List<ReportTemplateDataVO> basicDataList) {
try {
//通过文件服务器获取
for (Object item : jsonArray) {
JSONObject itemJSON = JSONUtil.parseObj(item);
JSONArray itemArr = itemJSON.getJSONArray(CELL_DATA);
for (Object it : itemArr) {
if (!JSONUtil.isNull(it) && JSONUtil.isJsonObj(it.toString())) {
//获取到1列
JSONObject data = JSONUtil.parseObj(it);
JSONObject son = data.getJSONObject(V);
if (son.containsKey(V)) {
String v = son.getStr(V);
if (StrUtil.isNotEmpty(v)) {
//数据格式:$HA[_25]#B#max#classId$ 或 $HA[_25]#max#classId$
if (v.charAt(0) == '$' && v.contains(STR_ONE)) {
//剔除前后$
v = v.replace(STR_TWO, "");
//封装指标项
ReportTemplateDataVO indexDataVO = new ReportTemplateDataVO();
indexDataVO.setItemName(v.toUpperCase());
//根据#分割数据
String[] vItem = v.split(STR_ONE);
if (vItem.length == 5) {
//$HA[_25]#B#max#classId#no$
indexDataVO.setTemplateName(vItem[0].toUpperCase());
indexDataVO.setPhase(vItem[1].substring(0, 1).toUpperCase());
indexDataVO.setStatMethod(vItem[2].toUpperCase());
indexDataVO.setResourceId(vItem[3].toUpperCase());
} else if (vItem.length == 4) {
//$HA[_25]#max#classId#no$
indexDataVO.setTemplateName(vItem[0].toUpperCase());
indexDataVO.setPhase("M");
indexDataVO.setStatMethod(vItem[1].toUpperCase());
indexDataVO.setResourceId(vItem[2].toUpperCase());
}
indexDataList.add(indexDataVO);
} else if (v.charAt(0) == '%' && v.contains(STR_ONE)) {
//封装指标改善率
ReportTemplateDataVO improvementRateDataVO = new ReportTemplateDataVO();
v = v.replace(STR_FOUR, "");
improvementRateDataVO.setItemName(v.toUpperCase());
//根据#分割数据
String[] vItem = v.split(STR_ONE);
if (vItem.length == 3) {
//%vu_dev#A#max%
improvementRateDataVO.setTemplateName(vItem[0].toUpperCase());
improvementRateDataVO.setPhase(vItem[1].substring(0, 1).toUpperCase());
improvementRateDataVO.setStatMethod(vItem[2].toLowerCase());
}
improvementRateDataList.add(improvementRateDataVO);
} else if (v.charAt(0) == '&') {
//基础数据
ReportTemplateDataVO basicDataVO = new ReportTemplateDataVO();
v = v.replace(STR_THREE, "");
basicDataVO.setItemName(v.toUpperCase());
basicDataVO.setTemplateName(v.toUpperCase());
basicDataList.add(basicDataVO);
} else if (v.charAt(0) == '~' && v.contains(STR_ONE)) {
//~$HA[_25]#B#max#classId#no$ 治理后的
//剔除~再剔除前后$
v = v.replace(STR_FIVE, "").replace(STR_TWO, "");
//封装指标项
ReportTemplateDataVO indexDataVO = new ReportTemplateDataVO();
indexDataVO.setItemName(v.toUpperCase());
//根据#分割数据
String[] vItem = v.split(STR_ONE);
if (vItem.length == 5) {
//~$HA[_25]#B#max#classId#no$
indexDataVO.setTemplateName(vItem[0].toUpperCase());
indexDataVO.setPhase(vItem[1].substring(0, 1).toUpperCase());
indexDataVO.setStatMethod(vItem[2].toUpperCase());
indexDataVO.setResourceId(vItem[3].toUpperCase());
} else if (vItem.length == 4) {
//$HA[_25]#max#classId#no$
indexDataVO.setTemplateName(vItem[0].toUpperCase());
indexDataVO.setPhase("M");
indexDataVO.setStatMethod(vItem[1].toUpperCase());
indexDataVO.setResourceId(vItem[2].toUpperCase());
}
indexDataList.add(indexDataVO);
}
}
}
}
}
}
} catch (Exception e) {
throw new BusinessException(CsHarmonicResponseEnum.CUSTOM_REPORT_JSON);
}
}
/**
* 获取测点限值
@@ -1053,8 +1431,7 @@ public class CustomReportServiceImpl implements CustomReportService {
* @author cdf
* @date 2023/10/23
*/
private Map<String, Float> overLimitDeal(List<ReportTemplateDTO> reportLimitList, ReportSearchParam
reportSearchParam) {
private Map<String, Float> overLimitDeal(List<ReportTemplateDTO> reportLimitList, String lineId) {
Map<String, Float> limitMap = new HashMap<>();
if (CollUtil.isNotEmpty(reportLimitList)) {
StringBuilder sql = new StringBuilder(InfluxDbSqlConstant.SELECT);
@@ -1065,7 +1442,7 @@ public class CustomReportServiceImpl implements CustomReportService {
sql.append(reportLimitList.get(i).getTemplateName()).append(StrUtil.COMMA);
}
}
sql.append(InfluxDbSqlConstant.FROM).append(reportLimitList.get(0).getResourceId()).append(InfluxDbSqlConstant.WHERE).append("id ='").append(reportSearchParam.getLineId()).append("'");
sql.append(InfluxDbSqlConstant.FROM).append(reportLimitList.get(0).getResourceId()).append(InfluxDbSqlConstant.WHERE).append("id ='").append(lineId).append("'");
limitMap = excelRptTempMapper.dynamicSqlMap(sql.toString());
if (Objects.isNull(limitMap)) {
throw new BusinessException("当前报表测点限值缺失!");
@@ -1102,7 +1479,6 @@ public class CustomReportServiceImpl implements CustomReportService {
}
}
private void analyzeReportZhejiang(ReportSearchParam reportSearchParam, ExcelRptTemp excelRptTemp, HttpServletResponse response) {
//指标
List<ReportTemplateDTO> reportTemplateDTOList = new ArrayList<>();
@@ -1122,7 +1498,7 @@ public class CustomReportServiceImpl implements CustomReportService {
List<EleEpdPqd> eleEpdPqdList = epdFeignClient.dictMarkByDataType(pqdDic.getId()).getData()
.stream().filter(item -> StrUtil.isNotEmpty(item.getPrimaryFormula())).collect(Collectors.toList());
eleEpdPqdList.sort(Comparator.comparingInt(EleEpdPqd::getSort));
Map<String, List<EleEpdPqd>> pqdMap = eleEpdPqdList.stream().collect(Collectors.groupingBy(EleEpdPqd::getName));
Map<String, List<EleEpdPqd>> pqdMap = eleEpdPqdList.stream().collect(Collectors.groupingBy(EleEpdPqd::getName));
//处理指标是否合格
reportLimitList = new LinkedHashSet<>(reportLimitList)
@@ -1130,7 +1506,7 @@ public class CustomReportServiceImpl implements CustomReportService {
.sorted(Comparator.comparing(ReportTemplateDTO::getItemName))
.collect(Collectors.toList());
Map<String, Float> limitMap = overLimitDeal(reportLimitList, reportSearchParam);
Map<String, Float> limitMap = overLimitDeal(reportLimitList, reportSearchParam.getLineId());
//存放限值指标的map
Map<String, ReportTemplateDTO> limitTargetMapX = reportLimitList.stream().collect(Collectors.toMap(ReportTemplateDTO::getItemName, Function.identity()));
@@ -1223,7 +1599,6 @@ public class CustomReportServiceImpl implements CustomReportService {
System.out.println("导出耗时 " + (daochuEnd - daochu) / 1000 + "S");
}
private void assSqlZhejiang(List<ReportTemplateDTO> data, StringBuilder
sql, List<ReportTemplateDTO> endList, String method, ReportSearchParam reportSearchParam, Map<String, ReportTemplateDTO> limitMap, Map<String, Float> overLimitMap, Map<String,
ReportTemplateDTO> assNoPassMap, List<WlRecord> wlRecordList, Map<String, List<EleEpdPqd>> pqdMap) {
@@ -1376,7 +1751,6 @@ public class CustomReportServiceImpl implements CustomReportService {
endList.addAll(data);
}
/**
* 对多测点数据进行计算求出一组数据
*
@@ -1448,7 +1822,6 @@ public class CustomReportServiceImpl implements CustomReportService {
return resultMap;
}
private void dealExcelResult(JSONArray
jsonArray, Map<String, List<ReportTemplateDTO>> assMap, Map<String, String> unit, Map<String, String> finalTerminalMap) {
jsonArray.forEach(item -> {
@@ -1514,7 +1887,6 @@ public class CustomReportServiceImpl implements CustomReportService {
});
}
/**
* 处理指标超标结论
*/
@@ -1543,7 +1915,6 @@ public class CustomReportServiceImpl implements CustomReportService {
});
}
/**
* 解析模板
*
@@ -1623,15 +1994,67 @@ public class CustomReportServiceImpl implements CustomReportService {
}
}
public static boolean isInteger(String str) {
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
private List<ReportTemplateDataVO> fetchDataList(CsLinePO linePO,
Map<String, List<ReportTemplateDataVO>> classMap,
SensitiveUserReportQueryParam queryParam) {
String lineId = linePO.getLineId();
List<Future<List<ReportTemplateDataVO>>> futures = new ArrayList<>();
classMap.forEach((classKey, templateValue) -> {
Map<String, List<ReportTemplateDataVO>> valueTypeMap = templateValue.stream()
.collect(Collectors.groupingBy(ReportTemplateDataVO::getStatMethod));
futures.add(executorService.submit(() -> {
List<ReportTemplateDataVO> threadDataList = new ArrayList<>();
valueTypeMap.forEach((valueTypeKey, valueTypeVal) -> {
Map<String, List<ReportTemplateDataVO>> phaseMap = valueTypeVal.stream()
.collect(Collectors.groupingBy(ReportTemplateDataVO::getPhase));
phaseMap.forEach((phaseKey, phaseVal) -> {
// 创建新的数据对象列表,避免引用共享
List<ReportTemplateDataVO> newDataList = phaseVal.stream()
.map(vo -> {
ReportTemplateDataVO newVo = new ReportTemplateDataVO();
// 复制所有属性
newVo.setItemName(vo.getItemName());
newVo.setTemplateName(vo.getTemplateName());
newVo.setPhase(vo.getPhase());
newVo.setStatMethod(vo.getStatMethod());
newVo.setResourceId(vo.getResourceId());
newVo.setLineId(lineId);
return newVo;
})
.collect(Collectors.toList());
StringBuilder sql = new StringBuilder(InfluxDbSqlConstant.SELECT);
if (InfluxDbSqlConstant.MAX.equalsIgnoreCase(valueTypeKey)) {
assSqlByMysqlNew(newDataList, sql, threadDataList, InfluxDbSqlConstant.MAX, queryParam, lineId);
} else if (InfluxDbSqlConstant.MIN.equalsIgnoreCase(valueTypeKey)) {
assSqlByMysqlNew(newDataList, sql, threadDataList, InfluxDbSqlConstant.MIN, queryParam, lineId);
} else if (InfluxDbSqlConstant.AVG_WEB.equalsIgnoreCase(valueTypeKey)) {
assSqlByMysqlNew(newDataList, sql, threadDataList, InfluxDbSqlConstant.AVG_WEB, queryParam, lineId);
} else if (InfluxDbSqlConstant.CP95.equalsIgnoreCase(valueTypeKey)) {
assSqlByMysqlNew(newDataList, sql, threadDataList, InfluxDbSqlConstant.CP95, queryParam, lineId);
}
});
});
return threadDataList;
}));
});
List<ReportTemplateDataVO> dataList = new ArrayList<>();
for (Future<List<ReportTemplateDataVO>> future : futures) {
try {
dataList.addAll(future.get());
} catch (InterruptedException | ExecutionException e) {
log.error("自定义报表多线程查询流程出错!错误信息{}", e.getMessage());
}
}
return dataList;
}
}