diff --git a/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/param/SensitiveUserReportQueryParam.java b/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/param/SensitiveUserReportQueryParam.java index 382c35f..85fb4d1 100644 --- a/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/param/SensitiveUserReportQueryParam.java +++ b/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/param/SensitiveUserReportQueryParam.java @@ -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; - } diff --git a/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/pojo/vo/ReportTemplateDataVO.java b/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/pojo/vo/ReportTemplateDataVO.java new file mode 100644 index 0000000..63aed8f --- /dev/null +++ b/cs-harmonic/cs-harmonic-api/src/main/java/com/njcn/csharmonic/pojo/vo/ReportTemplateDataVO.java @@ -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; + +} diff --git a/cs-harmonic/cs-harmonic-boot/pom.xml b/cs-harmonic/cs-harmonic-boot/pom.xml index a9184f1..1367ad1 100644 --- a/cs-harmonic/cs-harmonic-boot/pom.xml +++ b/cs-harmonic/cs-harmonic-boot/pom.xml @@ -119,6 +119,27 @@ dynamic-datasource-spring-boot-starter 3.5.1 + + + com.njcn + common-mq + ${project.version} + + + org.apache.rocketmq + rocketmq-spring-boot-starter + 2.2.2 + + + com.njcn.platform + message-api + 1.0.0 + + + com.njcn + harmonic-common + 1.0.0 + diff --git a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CustomReportServiceImpl.java b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CustomReportServiceImpl.java index daf6b82..7d15f8d 100644 --- a/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CustomReportServiceImpl.java +++ b/cs-harmonic/cs-harmonic-boot/src/main/java/com/njcn/csharmonic/service/impl/CustomReportServiceImpl.java @@ -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 Map convertKeysToUpperCase(Map originalMap) { + Map newMap = new HashMap<>(); + if (CollUtil.isNotEmpty(originalMap)) { + for (Map.Entry 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 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 indexDataList = new ArrayList<>(); + // 改善率数据 + List improvementRateDataList = new ArrayList<>(); + // 基础数据 + List basicDataList = new ArrayList<>(); + parseGovernTemplate(templateData, indexDataList, improvementRateDataList, basicDataList); + + Set beforeFinalDataList = new HashSet<>(); + Set afterFinalDataList = new HashSet<>(); + if (CollUtil.isNotEmpty(indexDataList)) { + //开始组织sql + indexDataList = new LinkedHashSet<>(indexDataList).stream().sorted(Comparator.comparing(ReportTemplateDataVO::getItemName)).collect(Collectors.toList()); + Map> classMap = indexDataList.stream().collect(Collectors.groupingBy(ReportTemplateDataVO::getResourceId)); + //定义存放指标的map + if (gridSideLine != null) { + lineName = gridSideLine.getName(); + List afterDataList = fetchDataList(gridSideLine, classMap, queryParam); + afterFinalDataList.addAll(afterDataList); + } + + if (loadSideLine != null) { + lineName = loadSideLine.getName(); + List beforeDataList = fetchDataList(loadSideLine, classMap, queryParam); + beforeFinalDataList.addAll(beforeDataList); + } + } + //进行反向赋值到模板 + //1、根据itemName分组 + Map> beforeAssMap = beforeFinalDataList.stream().collect(Collectors.groupingBy(ReportTemplateDataVO::getItemName)); + Map> afterAssMap = afterFinalDataList.stream().collect(Collectors.groupingBy(ReportTemplateDataVO::getItemName)); + //处理台账信息,暂时没用到 + /* Map 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 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 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 getTemplateList(ReportSearchParam reportSearchParam) { List list = excelRptTempMapper.getReportTemplateList(reportSearchParam); @@ -246,21 +434,20 @@ public class CustomReportServiceImpl implements CustomReportService { return true; } - @Override public List reportChooseTree() { List tree = new ArrayList<>(); DictData dic = dicDataFeignClient.getDicDataByNameAndTypeName(DicDataTypeEnum.CS_DATA_TYPE.getName(), DicDataEnum.PQD.getName()).getData(); List 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 dayTableList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DATA_DAY.getCode()).getData(); - Map dayTableMap = dayTableList.stream().collect(Collectors.toMap(DictData::getId, DictData::getName)); + Map 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> 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 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 Map convertKeysToUpperCase(Map originalMap) { - Map newMap = new HashMap<>(); - if (CollUtil.isNotEmpty(originalMap)) { - for (Map.Entry entry : originalMap.entrySet()) { - newMap.put(entry.getKey().toUpperCase(), entry.getValue()); + private void assSqlByMysqlNew(List data, StringBuilder sql, List 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> 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 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 limitMap = overLimitDeal(reportLimitList, reportSearchParam); + Map limitMap = overLimitDeal(reportLimitList, reportSearchParam.getLineId()); //存放限值指标的map Map 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 indexDataList, List improvementRateDataList, List 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 overLimitDeal(List reportLimitList, ReportSearchParam - reportSearchParam) { + private Map overLimitDeal(List reportLimitList, String lineId) { Map 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 reportTemplateDTOList = new ArrayList<>(); @@ -1122,7 +1498,7 @@ public class CustomReportServiceImpl implements CustomReportService { List eleEpdPqdList = epdFeignClient.dictMarkByDataType(pqdDic.getId()).getData() .stream().filter(item -> StrUtil.isNotEmpty(item.getPrimaryFormula())).collect(Collectors.toList()); eleEpdPqdList.sort(Comparator.comparingInt(EleEpdPqd::getSort)); - Map> pqdMap = eleEpdPqdList.stream().collect(Collectors.groupingBy(EleEpdPqd::getName)); + Map> 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 limitMap = overLimitDeal(reportLimitList, reportSearchParam); + Map limitMap = overLimitDeal(reportLimitList, reportSearchParam.getLineId()); //存放限值指标的map Map 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 data, StringBuilder sql, List endList, String method, ReportSearchParam reportSearchParam, Map limitMap, Map overLimitMap, Map assNoPassMap, List wlRecordList, Map> 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> assMap, Map unit, Map 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 fetchDataList(CsLinePO linePO, + Map> classMap, + SensitiveUserReportQueryParam queryParam) { + String lineId = linePO.getLineId(); + List>> futures = new ArrayList<>(); + + classMap.forEach((classKey, templateValue) -> { + Map> valueTypeMap = templateValue.stream() + .collect(Collectors.groupingBy(ReportTemplateDataVO::getStatMethod)); + + futures.add(executorService.submit(() -> { + List threadDataList = new ArrayList<>(); + valueTypeMap.forEach((valueTypeKey, valueTypeVal) -> { + Map> phaseMap = valueTypeVal.stream() + .collect(Collectors.groupingBy(ReportTemplateDataVO::getPhase)); + + phaseMap.forEach((phaseKey, phaseVal) -> { + // 创建新的数据对象列表,避免引用共享 + List 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 dataList = new ArrayList<>(); + for (Future> future : futures) { + try { + dataList.addAll(future.get()); + } catch (InterruptedException | ExecutionException e) { + log.error("自定义报表多线程查询流程出错!错误信息{}", e.getMessage()); + } } + return dataList; } + }