|
|
|
|
@@ -18,8 +18,6 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
|
|
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
|
|
|
|
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
|
|
|
|
import com.njcn.common.pojo.exception.BusinessException;
|
|
|
|
|
import com.njcn.csdevice.api.CsCommTerminalFeignClient;
|
|
|
|
|
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
|
|
|
|
|
import com.njcn.harmonic.common.mapper.ExcelRptTempMapper;
|
|
|
|
|
import com.njcn.harmonic.common.pojo.dto.DeviceUnitCommDTO;
|
|
|
|
|
import com.njcn.harmonic.common.service.CustomReportTableService;
|
|
|
|
|
@@ -29,6 +27,7 @@ import com.njcn.harmonic.pojo.param.ReportSearchParam;
|
|
|
|
|
import com.njcn.harmonic.pojo.po.ExcelRptTemp;
|
|
|
|
|
import com.njcn.influx.constant.InfluxDbSqlConstant;
|
|
|
|
|
import com.njcn.influx.pojo.constant.InfluxDBTableConstant;
|
|
|
|
|
import com.njcn.oss.constant.OssPath;
|
|
|
|
|
import com.njcn.oss.enums.OssResponseEnum;
|
|
|
|
|
import com.njcn.oss.utils.FileStorageUtil;
|
|
|
|
|
import com.njcn.system.api.DicDataFeignClient;
|
|
|
|
|
@@ -40,13 +39,16 @@ import com.njcn.system.pojo.po.EleEpdPqd;
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
|
import org.apache.poi.ss.usermodel.Row;
|
|
|
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
|
import org.apache.poi.ss.usermodel.Workbook;
|
|
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
|
|
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
import java.io.BufferedOutputStream;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.math.RoundingMode;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
@@ -69,18 +71,9 @@ import java.util.stream.Collectors;
|
|
|
|
|
public class CustomReportTableServiceImpl implements CustomReportTableService {
|
|
|
|
|
|
|
|
|
|
private final ExcelRptTempMapper excelRptTempMapper;
|
|
|
|
|
|
|
|
|
|
private final EpdFeignClient epdFeignClient;
|
|
|
|
|
|
|
|
|
|
private final FileStorageUtil fileStorageUtil;
|
|
|
|
|
|
|
|
|
|
private final DicDataFeignClient dicDataFeignClient;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final CommTerminalGeneralClient commTerminalGeneralClient;
|
|
|
|
|
|
|
|
|
|
private final CsCommTerminalFeignClient csCommTerminalFeignClient;
|
|
|
|
|
|
|
|
|
|
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
|
|
|
|
|
|
|
|
|
|
private final String CELL_DATA = "celldata";
|
|
|
|
|
@@ -113,8 +106,286 @@ public class CustomReportTableServiceImpl implements CustomReportTableService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String saveStableEventReport(ReportSearchParam reportSearchParam, Map<String, String> newMap, DeviceUnitCommDTO deviceUnitCommDTO) {
|
|
|
|
|
String filePath = "";
|
|
|
|
|
ExcelRptTemp excelRptTemp = excelRptTempMapper.selectById(reportSearchParam.getTempId());
|
|
|
|
|
if (Objects.isNull(excelRptTemp)) {
|
|
|
|
|
throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_ACTIVE);
|
|
|
|
|
} else {
|
|
|
|
|
if (Objects.isNull(reportSearchParam.getCustomType())) {
|
|
|
|
|
filePath = this.analyzeReport2(reportSearchParam, excelRptTemp, newMap, deviceUnitCommDTO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return filePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
private String analyzeReport2(ReportSearchParam reportSearchParam, ExcelRptTemp excelRptTemp,Map<String,String> newMap,DeviceUnitCommDTO deviceUnitCommDTO) {
|
|
|
|
|
Map<String, Object> dataMap = new HashMap<>();
|
|
|
|
|
//定义一个线程集合
|
|
|
|
|
List<Future<?>> futures = new ArrayList<>();
|
|
|
|
|
//指标
|
|
|
|
|
List<ReportTemplateDTO> reportTemplateDTOList = new ArrayList<>();
|
|
|
|
|
//限值
|
|
|
|
|
List<ReportTemplateDTO> reportLimitList = new ArrayList<>();
|
|
|
|
|
//台账
|
|
|
|
|
List<ReportTemplateDTO> terminalList = new ArrayList<>();
|
|
|
|
|
JSONArray jsonArray;
|
|
|
|
|
try (InputStream fileStream = fileStorageUtil.getFileStream(excelRptTemp.getContent())) {
|
|
|
|
|
jsonArray = new JSONArray(new JSONTokener(fileStream, new JSONConfig()));
|
|
|
|
|
parseTemplate(jsonArray, reportTemplateDTOList, reportLimitList, terminalList);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
if(e instanceof BusinessException){
|
|
|
|
|
throw new BusinessException(e.getMessage());
|
|
|
|
|
}else {
|
|
|
|
|
throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//查询不分相别的指标
|
|
|
|
|
DictData dictData = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.EPD.getCode(), DicDataTypeEnum.CS_DATA_TYPE.getCode()).getData();
|
|
|
|
|
if(Objects.isNull(dictData)){
|
|
|
|
|
throw new BusinessException(CommonResponseEnum.FAIL,"字典类型模板缺少!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DictData epdDic = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.EPD.getCode(),DicDataTypeEnum.CS_DATA_TYPE.getCode()).getData();
|
|
|
|
|
List<EleEpdPqd> eleEpdPqdList= epdFeignClient.dictMarkByDataType(epdDic.getId()).getData();
|
|
|
|
|
|
|
|
|
|
Map<String, String> tMap = new HashMap<>();
|
|
|
|
|
eleEpdPqdList.forEach(item->{
|
|
|
|
|
String phase;
|
|
|
|
|
if (Objects.isNull(PHASE_MAPPING.get(item.getPhase()))) {
|
|
|
|
|
phase = item.getPhase();
|
|
|
|
|
} else {
|
|
|
|
|
phase = PHASE_MAPPING.get(item.getPhase());
|
|
|
|
|
}
|
|
|
|
|
if (ObjectUtils.isNotNull(item.getHarmStart()) && ObjectUtils.isNotNull(item.getHarmEnd())) {
|
|
|
|
|
for (int i = item.getHarmStart(); i <= item.getHarmEnd() + 1; i++) {
|
|
|
|
|
tMap.put((item.getOtherName() + "_" + i + phase + item.getResourcesId()).toUpperCase(), item.getPrimaryFormula());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
tMap.put((item.getOtherName() + phase + item.getResourcesId()).toUpperCase(), item.getPrimaryFormula());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
eleEpdPqdList = eleEpdPqdList.stream().filter(it->"T".equals(it.getPhase())||"M".equals(it.getPhase())).collect(Collectors.toList());
|
|
|
|
|
List<String> noPhaseList = eleEpdPqdList.stream().filter(it->StrUtil.isNotBlank(it.getOtherName())).map(it->it.getOtherName().toUpperCase()).collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
//处理指标是否合格
|
|
|
|
|
reportLimitList = new LinkedHashSet<>(reportLimitList).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList());
|
|
|
|
|
Map<String, Float> limitMap = overLimitDeal(reportLimitList, reportSearchParam);
|
|
|
|
|
//存放限值指标的map
|
|
|
|
|
Map<String, ReportTemplateDTO> limitTargetMapX = reportLimitList.stream().collect(Collectors.toMap(ReportTemplateDTO::getItemName, Function.identity()));
|
|
|
|
|
|
|
|
|
|
List<ReportTemplateDTO> endList = new CopyOnWriteArrayList<>();
|
|
|
|
|
if (CollUtil.isNotEmpty(reportTemplateDTOList)) {
|
|
|
|
|
//开始组织sql
|
|
|
|
|
reportTemplateDTOList = new LinkedHashSet<>(reportTemplateDTOList).stream().sorted(Comparator.comparing(ReportTemplateDTO::getItemName)).collect(Collectors.toList());
|
|
|
|
|
Map<String, List<ReportTemplateDTO>> classMap = reportTemplateDTOList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getResourceId));
|
|
|
|
|
//定义存放越限指标的map
|
|
|
|
|
Map<String, ReportTemplateDTO> assNoPassMap = new HashMap<>();
|
|
|
|
|
classMap.forEach((classKey, templateValue) -> {
|
|
|
|
|
Map<String, List<ReportTemplateDTO>> valueTypeMap = templateValue.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getStatMethod));
|
|
|
|
|
//每张表开启一个独立线程查询
|
|
|
|
|
futures.add(executorService.submit(() -> {
|
|
|
|
|
DynamicDataSourceContextHolder.push("sjzx");
|
|
|
|
|
//avg.max,min,cp95
|
|
|
|
|
try {
|
|
|
|
|
valueTypeMap.forEach((valueTypeKey, valueTypeVal) -> {
|
|
|
|
|
//相别分组
|
|
|
|
|
Map<String, List<ReportTemplateDTO>> phaseMap = valueTypeVal.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getPhase));
|
|
|
|
|
phaseMap.forEach((phaseKey, phaseVal) -> {
|
|
|
|
|
StringBuilder sql = new StringBuilder(InfluxDbSqlConstant.SELECT);
|
|
|
|
|
if (InfluxDbSqlConstant.MAX.equalsIgnoreCase(valueTypeKey)) {
|
|
|
|
|
assSqlByMysql(tMap,newMap.get("LEVEL"),newMap.get("PT"),newMap.get("CT"),phaseVal, sql, endList, InfluxDbSqlConstant.MAX, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList);
|
|
|
|
|
} else if (InfluxDbSqlConstant.MIN.equalsIgnoreCase(valueTypeKey)) {
|
|
|
|
|
assSqlByMysql(tMap,newMap.get("LEVEL"),newMap.get("PT"),newMap.get("CT"),phaseVal, sql, endList, InfluxDbSqlConstant.MIN, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList);
|
|
|
|
|
} else if (InfluxDbSqlConstant.AVG_WEB.equalsIgnoreCase(valueTypeKey)) {
|
|
|
|
|
assSqlByMysql(tMap,newMap.get("LEVEL"),newMap.get("PT"),newMap.get("CT"),phaseVal, sql, endList, InfluxDbSqlConstant.AVG_WEB, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList);
|
|
|
|
|
} else if (InfluxDbSqlConstant.CP95.equalsIgnoreCase(valueTypeKey)) {
|
|
|
|
|
assSqlByMysql(tMap,newMap.get("LEVEL"),newMap.get("PT"),newMap.get("CT"),phaseVal, sql, endList, InfluxDbSqlConstant.CP95, reportSearchParam, limitTargetMapX, limitMap, assNoPassMap,noPhaseList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}finally {
|
|
|
|
|
DynamicDataSourceContextHolder.poll();
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 等待所有任务完成
|
|
|
|
|
for (Future<?> future : futures) {
|
|
|
|
|
try {
|
|
|
|
|
future.get(); // 这会阻塞直到任务完成或抛出异常
|
|
|
|
|
} catch (InterruptedException | ExecutionException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
log.error("自定义报表多线程查询流程出错!错误信息{}",e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//处理指标最终判定合格还是不合格
|
|
|
|
|
dealTargetResult(assNoPassMap, limitTargetMapX, endList);
|
|
|
|
|
}
|
|
|
|
|
resultAssemble2(endList,reportSearchParam,newMap,deviceUnitCommDTO,jsonArray,dataMap);
|
|
|
|
|
//存储自定义报表
|
|
|
|
|
return saveReport(jsonArray,dataMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void resultAssemble2(List<ReportTemplateDTO> endList, ReportSearchParam reportSearchParam, Map<String, String> finalTerminalMap, DeviceUnitCommDTO deviceUnitCommDTO, JSONArray jsonArray,Map<String, Object> dataMap) {
|
|
|
|
|
if (CollUtil.isNotEmpty(endList)) {
|
|
|
|
|
Map<String, String> unit = this.unitMap(deviceUnitCommDTO);
|
|
|
|
|
Map<String, List<ReportTemplateDTO>> assMap = (Map)endList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getItemName));
|
|
|
|
|
jsonArray.forEach((item) -> {
|
|
|
|
|
JSONObject jsonObject = (JSONObject)item;
|
|
|
|
|
JSONArray itemArr = (JSONArray)jsonObject.get("celldata");
|
|
|
|
|
itemArr.forEach((it) -> {
|
|
|
|
|
if (Objects.nonNull(it) && !"null".equals(it.toString())) {
|
|
|
|
|
JSONObject data = (JSONObject)it;
|
|
|
|
|
JSONObject son = (JSONObject)data.get("v");
|
|
|
|
|
if (son.containsKey("v")) {
|
|
|
|
|
String v = son.getStr("v");
|
|
|
|
|
String tem;
|
|
|
|
|
List rDto;
|
|
|
|
|
if (v.charAt(0) == '$' && v.contains("#")) {
|
|
|
|
|
tem = "";
|
|
|
|
|
rDto = (List)assMap.get(v.replace("$", "").toUpperCase());
|
|
|
|
|
if (Objects.nonNull(rDto)) {
|
|
|
|
|
tem = ((ReportTemplateDTO)rDto.get(0)).getValue();
|
|
|
|
|
if (StringUtils.isBlank(tem)) {
|
|
|
|
|
tem = "/";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
son.set("v", tem);
|
|
|
|
|
dataMap.put(v, tem);
|
|
|
|
|
if (Objects.nonNull(((ReportTemplateDTO)rDto.get(0)).getOverLimitFlag()) && ((ReportTemplateDTO)rDto.get(0)).getOverLimitFlag() == 1) {
|
|
|
|
|
son.set("fc", "#990000");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (v.charAt(0) == '%' && v.contains("#")) {
|
|
|
|
|
tem = "";
|
|
|
|
|
rDto = (List)assMap.get(v.replace("%", "").toUpperCase());
|
|
|
|
|
if (Objects.nonNull(rDto)) {
|
|
|
|
|
tem = ((ReportTemplateDTO)rDto.get(0)).getValue();
|
|
|
|
|
if (StringUtils.isBlank(tem)) {
|
|
|
|
|
tem = "/";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
son.set("v", tem);
|
|
|
|
|
dataMap.put(v, tem);
|
|
|
|
|
if ("不合格".equals(tem)) {
|
|
|
|
|
son.set("fc", "#990000");
|
|
|
|
|
dataMap.put("fc", "#990000");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (v.charAt(0) == '&') {
|
|
|
|
|
tem = v.replace("&", "").toUpperCase();
|
|
|
|
|
if (finalTerminalMap.size() > 0) {
|
|
|
|
|
if ("STATIS_TIME".equals(tem)) {
|
|
|
|
|
String localTime = " 23:59:59";
|
|
|
|
|
LocalDate localDate = LocalDateTimeUtil.parseDate(reportSearchParam.getEndTime(), "yyyy-MM-dd");
|
|
|
|
|
LocalDate nowDate = LocalDate.now();
|
|
|
|
|
if (nowDate.isAfter(localDate)) {
|
|
|
|
|
son.set("v", reportSearchParam.getStartTime() + " 00:00:00" + "_" + reportSearchParam.getEndTime() + localTime);
|
|
|
|
|
dataMap.put(v, reportSearchParam.getStartTime() + " 00:00:00" + "_" + reportSearchParam.getEndTime() + localTime);
|
|
|
|
|
} else {
|
|
|
|
|
localTime = " " + LocalTime.now().format(DatePattern.NORM_TIME_FORMATTER);
|
|
|
|
|
son.set("v", reportSearchParam.getStartTime() + " 00:00:00" + "_" + nowDate + localTime);
|
|
|
|
|
dataMap.put(v, reportSearchParam.getStartTime() + " 00:00:00" + "_" + nowDate + localTime);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
son.set("v", finalTerminalMap.getOrDefault(tem, "/"));
|
|
|
|
|
dataMap.put(v, finalTerminalMap.getOrDefault(tem, "/"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v.charAt(0) == '@' && v.contains("#")) {
|
|
|
|
|
tem = v.replace("@", "");
|
|
|
|
|
son.set("v", unit.getOrDefault(tem, "/"));
|
|
|
|
|
dataMap.put(v, unit.getOrDefault(tem, "/"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String saveReport(JSONArray jsonArray, Map<String, Object> dataMap) {
|
|
|
|
|
String filePath = "";
|
|
|
|
|
Workbook workbook = new XSSFWorkbook();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
|
|
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
|
|
|
|
String sheetName = jsonObject.getStr("name");
|
|
|
|
|
JSONArray data = jsonObject.getJSONArray("data");
|
|
|
|
|
|
|
|
|
|
Sheet sheet = workbook.createSheet(sheetName);
|
|
|
|
|
|
|
|
|
|
if (data != null) {
|
|
|
|
|
for (int j = 0; j < data.size(); j++) {
|
|
|
|
|
Row row = sheet.createRow(j);
|
|
|
|
|
JSONArray rowData = data.getJSONArray(j);
|
|
|
|
|
|
|
|
|
|
if (rowData != null) {
|
|
|
|
|
for (int k = 0; k < rowData.size(); k++) {
|
|
|
|
|
Cell cell = row.createCell(k);
|
|
|
|
|
JSONObject cellObj = rowData.getJSONObject(k);
|
|
|
|
|
|
|
|
|
|
if (cellObj != null && !cellObj.isEmpty()) {
|
|
|
|
|
Object v = cellObj.get("v");
|
|
|
|
|
if (v != null) {
|
|
|
|
|
Object vData = dataMap.get(v);
|
|
|
|
|
if (vData != null) {
|
|
|
|
|
if (vData instanceof String) {
|
|
|
|
|
cell.setCellValue((String) vData);
|
|
|
|
|
} else if (vData instanceof Number) {
|
|
|
|
|
cell.setCellValue(((Number) vData).doubleValue());
|
|
|
|
|
} else if (vData instanceof Boolean) {
|
|
|
|
|
cell.setCellValue((Boolean) vData);
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellValue(vData.toString());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (v instanceof String) {
|
|
|
|
|
cell.setCellValue((String) v);
|
|
|
|
|
} else if (v instanceof Number) {
|
|
|
|
|
cell.setCellValue(((Number) v).doubleValue());
|
|
|
|
|
} else if (v instanceof Boolean) {
|
|
|
|
|
cell.setCellValue((Boolean) v);
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellValue(v.toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
|
try {
|
|
|
|
|
workbook.write(baos);
|
|
|
|
|
workbook.close();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
throw new BusinessException(OssResponseEnum.DOWNLOAD_FILE_STREAM_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
|
|
|
|
filePath = fileStorageUtil.uploadStream(bais, OssPath.APP_HARMONIC_REPORT, "稳态报表.xlsx");
|
|
|
|
|
try {
|
|
|
|
|
bais.close();
|
|
|
|
|
baos.close();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
return filePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理
|
|
|
|
|
*
|
|
|
|
|
* @author cdf
|
|
|
|
|
|