From 4be65353c96aec60dc1d2a78ae2c6f75e5fd1bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=E6=9C=A8c?= <857448963@qq.com> Date: Thu, 25 Aug 2022 16:34:15 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=88=E7=AB=AF=E6=A8=A1=E5=9D=97=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=AF=B9=E5=A4=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/InfluxDBResultMapperCn.java | 388 ++++++++++++++ .../njcn/influxdb/utils/InfluxDbUtils.java | 48 ++ .../njcn/web/filter/XssRequestWrapper.java | 2 +- .../controller/TerminalVersionController.java | 3 + .../service/impl/HighAnalyticServiceImpl.java | 7 +- .../njcn/event/pojo/po/EventDetailNew.java | 83 +++ .../harmonic/constant/ReportConstant.java | 23 + .../harmonic/enums/HarmonicResponseEnum.java | 9 +- .../harmonic/pojo/dto/ReportTemplateDTO.java | 42 ++ .../pojo/param/ReportTemplateParam.java | 51 ++ .../com/njcn/harmonic/pojo/po/EleEpdPqd.java | 44 ++ .../njcn/harmonic/pojo/po/ReportTemplate.java | 35 ++ .../harmonic/pojo/vo/ReportTemplateVO.java | 30 ++ .../njcn/harmonic/pojo/vo/ReportTreeVO.java | 24 + .../controller/CustomReportController.java | 192 +++++++ .../harmonic/mapper/CustomReportMapper.java | 19 + .../njcn/harmonic/mapper/EleEpdMapper.java | 13 + .../mapper/mapping/CustomReportMapper.xml | 25 + .../harmonic/service/CustomReportService.java | 75 +++ .../service/impl/CustomReportServiceImpl.java | 475 ++++++++++++++++++ .../njcn/system/enums/DicDataTypeEnum.java | 50 +- 21 files changed, 1610 insertions(+), 28 deletions(-) create mode 100644 pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/mapper/InfluxDBResultMapperCn.java create mode 100644 pqs-event/event-api/src/main/java/com/njcn/event/pojo/po/EventDetailNew.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/constant/ReportConstant.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/dto/ReportTemplateDTO.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/param/ReportTemplateParam.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/EleEpdPqd.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/ReportTemplate.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java create mode 100644 pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTreeVO.java create mode 100644 pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/controller/CustomReportController.java create mode 100644 pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/CustomReportMapper.java create mode 100644 pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/EleEpdMapper.java create mode 100644 pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/CustomReportMapper.xml create mode 100644 pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/CustomReportService.java create mode 100644 pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/CustomReportServiceImpl.java diff --git a/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/mapper/InfluxDBResultMapperCn.java b/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/mapper/InfluxDBResultMapperCn.java new file mode 100644 index 000000000..3c0bc4382 --- /dev/null +++ b/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/mapper/InfluxDBResultMapperCn.java @@ -0,0 +1,388 @@ +package com.njcn.influxdb.mapper; + +import io.swagger.models.auth.In; +import org.influxdb.InfluxDBMapperException; +import org.influxdb.annotation.Column; +import org.influxdb.annotation.Measurement; +import org.influxdb.dto.QueryResult; + +import java.lang.reflect.Field; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.temporal.ChronoField; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +/** + * pqs + * 用于处理格式化时间 + * @author cdf + * @date 2022/8/24 + */ +public class InfluxDBResultMapperCn { + + + /** + * Data structure used to cache classes used as measurements. + */ + private static final + ConcurrentMap> CLASS_FIELD_CACHE = new ConcurrentHashMap<>(); + + + + + + /** + *

+ * Process a {@link QueryResult} object returned by the InfluxDB client inspecting the internal + * data structure and creating the respective object instances based on the Class passed as + * parameter. + *

+ * + * @param queryResult the InfluxDB result object + * @param clazz the Class that will be used to hold your measurement data + * @param the target type + * + * @return a {@link List} of objects from the same Class passed as parameter and sorted on the + * same order as received from InfluxDB. + * + * @throws InfluxDBMapperException If {@link QueryResult} parameter contain errors, + * clazz parameter is not annotated with @Measurement or it was not + * possible to define the values of your POJO (e.g. due to an unsupported field type). + */ + public List toPOJO(final QueryResult queryResult, final Class clazz) throws InfluxDBMapperException { + return toPOJO(queryResult, clazz, TimeUnit.MILLISECONDS); + } + + /** + *

+ * Process a {@link QueryResult} object returned by the InfluxDB client inspecting the internal + * data structure and creating the respective object instances based on the Class passed as + * parameter. + *

+ * + * @param queryResult the InfluxDB result object + * @param clazz the Class that will be used to hold your measurement data + * @param precision the time precision of results + * @param the target type + * + * @return a {@link List} of objects from the same Class passed as parameter and sorted on the + * same order as received from InfluxDB. + * + * @throws InfluxDBMapperException If {@link QueryResult} parameter contain errors, + * clazz parameter is not annotated with @Measurement or it was not + * possible to define the values of your POJO (e.g. due to an unsupported field type). + */ + public List toPOJO(final QueryResult queryResult, final Class clazz, + final TimeUnit precision) throws InfluxDBMapperException { + throwExceptionIfMissingAnnotation(clazz); + String measurementName = getMeasurementName(clazz); + return this.toPOJO(queryResult, clazz, measurementName, precision); + } + + /** + *

+ * Process a {@link QueryResult} object returned by the InfluxDB client inspecting the internal + * data structure and creating the respective object instances based on the Class passed as + * parameter. + *

+ * + * @param queryResult the InfluxDB result object + * @param clazz the Class that will be used to hold your measurement data + * @param the target type + * @param measurementName name of the Measurement + * + * @return a {@link List} of objects from the same Class passed as parameter and sorted on the + * same order as received from InfluxDB. + * + * @throws InfluxDBMapperException If {@link QueryResult} parameter contain errors, + * clazz parameter is not annotated with @Measurement or it was not + * possible to define the values of your POJO (e.g. due to an unsupported field type). + */ + public List toPOJO(final QueryResult queryResult, final Class clazz, final String measurementName) + throws InfluxDBMapperException { + return toPOJO(queryResult, clazz, measurementName, TimeUnit.MILLISECONDS); + } + + /** + *

+ * Process a {@link QueryResult} object returned by the InfluxDB client inspecting the internal + * data structure and creating the respective object instances based on the Class passed as + * parameter. + *

+ * + * @param queryResult the InfluxDB result object + * @param clazz the Class that will be used to hold your measurement data + * @param the target type + * @param measurementName name of the Measurement + * @param precision the time precision of results + * + * @return a {@link List} of objects from the same Class passed as parameter and sorted on the + * same order as received from InfluxDB. + * + * @throws InfluxDBMapperException If {@link QueryResult} parameter contain errors, + * clazz parameter is not annotated with @Measurement or it was not + * possible to define the values of your POJO (e.g. due to an unsupported field type). + */ + public List toPOJO(final QueryResult queryResult, final Class clazz, final String measurementName, + final TimeUnit precision) + throws InfluxDBMapperException { + + Objects.requireNonNull(measurementName, "measurementName"); + Objects.requireNonNull(queryResult, "queryResult"); + Objects.requireNonNull(clazz, "clazz"); + + throwExceptionIfResultWithError(queryResult); + cacheMeasurementClass(clazz); + + List result = new LinkedList(); + + queryResult.getResults().stream() + .filter(internalResult -> Objects.nonNull(internalResult) && Objects.nonNull(internalResult.getSeries())) + .forEach(internalResult -> { + internalResult.getSeries().stream() + .filter(series -> series.getName().equals(measurementName)) + .forEachOrdered(series -> { + parseSeriesAs(series, clazz, result, precision); + }); + }); + + return result; + } + + void throwExceptionIfMissingAnnotation(final Class clazz) { + if (!clazz.isAnnotationPresent(Measurement.class)) { + throw new IllegalArgumentException( + "Class " + clazz.getName() + " is not annotated with @" + Measurement.class.getSimpleName()); + } + } + + void throwExceptionIfResultWithError(final QueryResult queryResult) { + if (queryResult.getError() != null) { + throw new InfluxDBMapperException("InfluxDB returned an error: " + queryResult.getError()); + } + + queryResult.getResults().forEach(seriesResult -> { + if (seriesResult.getError() != null) { + throw new InfluxDBMapperException("InfluxDB returned an error with Series: " + seriesResult.getError()); + } + }); + } + + ConcurrentMap getColNameAndFieldMap(final Class clazz) { + return CLASS_FIELD_CACHE.get(clazz.getName()); + } + + void cacheMeasurementClass(final Class... classVarAgrs) { + for (Class clazz : classVarAgrs) { + if (CLASS_FIELD_CACHE.containsKey(clazz.getName())) { + continue; + } + ConcurrentMap initialMap = new ConcurrentHashMap<>(); + ConcurrentMap influxColumnAndFieldMap = CLASS_FIELD_CACHE.putIfAbsent(clazz.getName(), initialMap); + if (influxColumnAndFieldMap == null) { + influxColumnAndFieldMap = initialMap; + } + + Class c = clazz; + while (c != null) { + for (Field field : c.getDeclaredFields()) { + Column colAnnotation = field.getAnnotation(Column.class); + if (colAnnotation != null) { + influxColumnAndFieldMap.put(colAnnotation.name(), field); + } + } + c = c.getSuperclass(); + } + } + } + + String getMeasurementName(final Class clazz) { + return ((Measurement) clazz.getAnnotation(Measurement.class)).name(); + } + + String getDatabaseName(final Class clazz) { + return ((Measurement) clazz.getAnnotation(Measurement.class)).database(); + } + + String getRetentionPolicy(final Class clazz) { + return ((Measurement) clazz.getAnnotation(Measurement.class)).retentionPolicy(); + } + + TimeUnit getTimeUnit(final Class clazz) { + return ((Measurement) clazz.getAnnotation(Measurement.class)).timeUnit(); + } + + List parseSeriesAs(final QueryResult.Series series, final Class clazz, final List result) { + return parseSeriesAs(series, clazz, result, TimeUnit.MILLISECONDS); + } + + List parseSeriesAs(final QueryResult.Series series, final Class clazz, final List result, + final TimeUnit precision) { + int columnSize = series.getColumns().size(); + ConcurrentMap colNameAndFieldMap = CLASS_FIELD_CACHE.get(clazz.getName()); + try { + T object = null; + for (List row : series.getValues()) { + for (int i = 0; i < columnSize; i++) { + Field correspondingField = colNameAndFieldMap.get(series.getColumns().get(i)/*InfluxDB columnName*/); + if (correspondingField != null) { + if (object == null) { + object = clazz.newInstance(); + } + setFieldValue(object, correspondingField, row.get(i), precision); + } + } + // When the "GROUP BY" clause is used, "tags" are returned as Map and + // accordingly with InfluxDB documentation + // https://docs.influxdata.com/influxdb/v1.2/concepts/glossary/#tag-value + // "tag" values are always String. + if (series.getTags() != null && !series.getTags().isEmpty()) { + for (Map.Entry entry : series.getTags().entrySet()) { + Field correspondingField = colNameAndFieldMap.get(entry.getKey()/*InfluxDB columnName*/); + if (correspondingField != null) { + // I don't think it is possible to reach here without a valid "object" + setFieldValue(object, correspondingField, entry.getValue(), precision); + } + } + } + if (object != null) { + result.add(object); + object = null; + } + } + } catch (InstantiationException | IllegalAccessException e) { + throw new InfluxDBMapperException(e); + } + return result; + } + + /** + * InfluxDB client returns any number as Double. + * See https://github.com/influxdata/influxdb-java/issues/153#issuecomment-259681987 + * for more information. + * + * @param object + * @param field + * @param value + * @param precision + * @throws IllegalArgumentException + * @throws IllegalAccessException + */ + void setFieldValue(final T object, final Field field, final Object value, final TimeUnit precision) + throws IllegalArgumentException, IllegalAccessException { + if (value == null) { + return; + } + Class fieldType = field.getType(); + try { + if (!field.isAccessible()) { + field.setAccessible(true); + } + if (fieldValueModified(fieldType, field, object, value, precision) + || fieldValueForPrimitivesModified(fieldType, field, object, value) + || fieldValueForPrimitiveWrappersModified(fieldType, field, object, value)) { + return; + } + String msg = "Class '%s' field '%s' is from an unsupported type '%s'."; + throw new InfluxDBMapperException( + String.format(msg, object.getClass().getName(), field.getName(), field.getType())); + } catch (ClassCastException e) { + String msg = "Class '%s' field '%s' was defined with a different field type and caused a ClassCastException. " + + "The correct type is '%s' (current field value: '%s')."; + throw new InfluxDBMapperException( + String.format(msg, object.getClass().getName(), field.getName(), value.getClass().getName(), value)); + } + } + + boolean fieldValueModified(final Class fieldType, final Field field, final T object, final Object value, + final TimeUnit precision) + throws IllegalArgumentException, IllegalAccessException { + if (String.class.isAssignableFrom(fieldType)) { + if("timeId".equals(field.getName()) || "time".equals(field.getName())){ + LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(String.valueOf(value))), ZoneId.systemDefault()); + String time = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + field.set(object,time); + }else { + field.set(object, String.valueOf(value)); + } + + return true; + } + if (Instant.class.isAssignableFrom(fieldType)) { + Instant instant; + if (value instanceof String) { + instant = Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(String.valueOf(value))); + } else if (value instanceof Long) { + instant = Instant.ofEpochMilli(toMillis((long) value, precision)); + } else if (value instanceof Double) { + instant = Instant.ofEpochMilli(toMillis(((Double) value).longValue(), precision)); + } else if (value instanceof Integer) { + instant = Instant.ofEpochMilli(toMillis(((Integer) value).longValue(), precision)); + } else { + throw new InfluxDBMapperException("Unsupported type " + field.getClass() + " for field " + field.getName()); + } + field.set(object, instant); + return true; + } + + return false; + } + + boolean fieldValueForPrimitivesModified(final Class fieldType, final Field field, final T object, + final Object value) throws IllegalArgumentException, IllegalAccessException { + if (double.class.isAssignableFrom(fieldType)) { + field.setDouble(object, ((Double) value).doubleValue()); + return true; + } + if (long.class.isAssignableFrom(fieldType)) { + field.setLong(object, ((Double) value).longValue()); + return true; + } + if (int.class.isAssignableFrom(fieldType)) { + field.setInt(object, ((Double) value).intValue()); + return true; + } + if (boolean.class.isAssignableFrom(fieldType)) { + field.setBoolean(object, Boolean.valueOf(String.valueOf(value)).booleanValue()); + return true; + } + return false; + } + + boolean fieldValueForPrimitiveWrappersModified(final Class fieldType, final Field field, final T object, + final Object value) throws IllegalArgumentException, IllegalAccessException { + if (Double.class.isAssignableFrom(fieldType)) { + field.set(object, value); + return true; + } + if (Long.class.isAssignableFrom(fieldType)) { + field.set(object, Long.valueOf(((Double) value).longValue())); + return true; + } + if (Integer.class.isAssignableFrom(fieldType)) { + field.set(object, Integer.valueOf(((Double) value).intValue())); + return true; + } + if (Boolean.class.isAssignableFrom(fieldType)) { + field.set(object, Boolean.valueOf(String.valueOf(value))); + return true; + } + return false; + } + + private Long toMillis(final long value, final TimeUnit precision) { + + return TimeUnit.MILLISECONDS.convert(value, precision); + } + + +} diff --git a/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/utils/InfluxDbUtils.java b/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/utils/InfluxDbUtils.java index dcb93c635..9840d8ecb 100644 --- a/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/utils/InfluxDbUtils.java +++ b/pqs-common/common-influxdb/src/main/java/com/njcn/influxdb/utils/InfluxDbUtils.java @@ -13,6 +13,8 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.temporal.ChronoField; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -29,6 +31,14 @@ import java.util.concurrent.TimeUnit; @Slf4j @Data public class InfluxDbUtils { + private static final int FRACTION_MIN_WIDTH = 0; + private static final int FRACTION_MAX_WIDTH = 9; + private static final boolean ADD_DECIMAL_POINT = true; + private static final DateTimeFormatter RFC3339_FORMATTER = new DateTimeFormatterBuilder() + .appendPattern("yyyy-MM-dd'T'HH:mm:ss") + .appendFraction(ChronoField.NANO_OF_SECOND, FRACTION_MIN_WIDTH, FRACTION_MAX_WIDTH, ADD_DECIMAL_POINT) + .appendZoneOrOffsetId() + .toFormatter(); /**用户名*/ private String username; @@ -174,6 +184,8 @@ public class InfluxDbUtils { influxDB.write(dbName, retentionPolicy, builder.build()); } + + /** * 批量写入测点 * @@ -254,6 +266,7 @@ public class InfluxDbUtils { * @param commond 单条sql语句 * @return 查询结果 */ + @Deprecated public List> getResult(String commond){ List> retList = new ArrayList<>(); QueryResult queryResult = influxDB.query(new Query(commond,dbName)); @@ -284,6 +297,7 @@ public class InfluxDbUtils { return retList; } + @Deprecated public List> getResult(String commond, String type){ List> retList = new ArrayList<>(); @@ -318,5 +332,39 @@ public class InfluxDbUtils { } + public List> getMapResult(String commond){ + + List> retList = new ArrayList<>(); + QueryResult queryResult = influxDB.query(new Query(commond,dbName)); + List results = queryResult.getResults(); + if (results==null||results.isEmpty()){ + return retList; + } + QueryResult.Result result = results.get(0); + List seriess = result.getSeries(); + if (seriess==null||seriess.isEmpty()){ + return retList; + } + QueryResult.Series series = seriess.get(0); + List columns = series.getColumns(); + List> values = series.getValues(); + for (List columnValue :values){ + Map map = new HashMap<>(1); + for (int i=0;i dictDataList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.ELE_LOAD_TYPE.getName()).getData(); + if (CollectionUtil.isNotEmpty(dictDataList)) { - dictDataList = dictDataList.stream().filter(num -> electComparaParam.getLoadType().contains(num.getId())).collect(Collectors.toList()); - if (CollectionUtil.isNotEmpty(dictDataList)) { - for (DictData dictData : dictDataList) { + List dictDataListQuery = dictDataList.stream().filter(num -> electComparaParam.getLoadType().contains(num.getId())).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(dictDataListQuery)) { + for (DictData dictData : dictDataListQuery) { LoadStatisticVO loadStatisticVO = new LoadStatisticVO(); loadStatisticVO.setLoadName(dictData.getName()); loadStatisticVO.setLoadId(dictData.getId()); diff --git a/pqs-event/event-api/src/main/java/com/njcn/event/pojo/po/EventDetailNew.java b/pqs-event/event-api/src/main/java/com/njcn/event/pojo/po/EventDetailNew.java new file mode 100644 index 000000000..18305011b --- /dev/null +++ b/pqs-event/event-api/src/main/java/com/njcn/event/pojo/po/EventDetailNew.java @@ -0,0 +1,83 @@ +package com.njcn.event.pojo.po; + +import lombok.Data; +import org.influxdb.annotation.Column; +import org.influxdb.annotation.Measurement; + +/** + * @author cdf + * @version 1.0.0 + * @date 2022年08月24日 20:59 + */ + +@Data +@Measurement(name = "pqs_eventdetail") +public class EventDetailNew { + + @Column(name = "line_id") + private String lineId; + + @Column(name = "time") + private String timeId; + + @Column(name = "event_describe") + private String eventDescribe; + + @Column(name = "wave_type") + private Integer waveType; + + @Column(name = "persist_time") + private Double persistTime; + + @Column(name = "event_value") + private Double eventValue; + + @Column(name = "event_reason") + private String eventReason; + + @Column(name = "event_type") + private String eventType; + + @Column(name = "eventass_index") + private String eventassIndex; + + @Column(name = "dq_time") + private Integer dqTime; + + @Column(name = "deal_time") + private String dealTime; + + @Column(name = "deal_flag") + private Integer dealFlag; + + @Column(name = "num") + private Integer num; + + @Column(name = "file_flag") + private Integer fileFlag; + + @Column(name = "first_time") + private String firstTime; + + @Column(name = "first_type") + private String firstType; + + @Column(name = "first_ms") + private Integer firstMs; + + @Column(name = "wave_name") + private String waveName; + + @Column(name = "energy") + private Double energy; + + @Column(name = "severity") + private Double severity; + + @Column(name = "sagsource") + private String sagSource; + + @Column(name = "create_time") + private String createTime; + +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/constant/ReportConstant.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/constant/ReportConstant.java new file mode 100644 index 000000000..d859fa16c --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/constant/ReportConstant.java @@ -0,0 +1,23 @@ +package com.njcn.harmonic.constant; + +/** + * pqs + * + * @author cdf + * @date 2022/8/18 + */ +public interface ReportConstant { + String aMax = "#A#MAX"; + String bMax = "#B#MAX"; + String cMax = "#C#MAX"; + String aMIN = "#A#MIN"; + String bMIN = "#B#MIN"; + String cMIN = "#C#MIN"; + String aAVG = "#A#AVG"; + String bAVG = "#B#AVG"; + String cAVG = "#C#AVG"; + String aCP95 = "#A#CP95"; + String bCP95 = "#B#CP95"; + String cCP95 = "#C#CP95"; + +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/enums/HarmonicResponseEnum.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/enums/HarmonicResponseEnum.java index 63715cfa6..cd370245f 100644 --- a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/enums/HarmonicResponseEnum.java +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/enums/HarmonicResponseEnum.java @@ -16,7 +16,14 @@ public enum HarmonicResponseEnum { */ HARMONIC_COMMON_ERROR("A00550","谐波模块异常"), - LIMIT_MISSING_ERROR("A00551","limit_rate表缺失限值数据") + LIMIT_MISSING_ERROR("A00551","limit_rate表缺失限值数据"), + + CUSTOM_REPORT_REPEAT("A00552","自定义报表模板名称已存在"), + + CUSTOM_REPORT_JSON("A00553","模板非严格json数据"), + + CUSTOM_REPORT_DEPT("A00554","该部门已存在绑定报表模板"), + CUSTOM_TYPE("A00555","字典中未查询到报表模板类型") ; private final String code; diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/dto/ReportTemplateDTO.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/dto/ReportTemplateDTO.java new file mode 100644 index 000000000..c2c3e287b --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/dto/ReportTemplateDTO.java @@ -0,0 +1,42 @@ +package com.njcn.harmonic.pojo.dto; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * pqs + * + * @author cdf + * @date 2022/8/22 + */ +@Data +public class ReportTemplateDTO { + /** + * $HA#B#max$ + */ + private String itemName; + + /** + * 对应mysql数据库中字段 HA + */ + private String name; + + /** + * 对应influxdb数据库中字段 HA_25 + */ + private String templateName; + + /** + * 相别 + */ + private String phase; + + /** + * max min avg cp95 + */ + private String statMethod; + + private String value; + +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/param/ReportTemplateParam.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/param/ReportTemplateParam.java new file mode 100644 index 000000000..125192f0f --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/param/ReportTemplateParam.java @@ -0,0 +1,51 @@ +package com.njcn.harmonic.pojo.param; + +import com.njcn.common.pojo.constant.PatternRegex; +import com.njcn.device.pojo.param.NodeParam; +import com.njcn.web.constant.ValidMessage; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * pqs + * + * @author cdf + * @date 2022/8/16 + */ +@Data +public class ReportTemplateParam { + + + + @ApiModelProperty(name = "name",value = "模板名称",required = true) + @NotBlank(message = "模板名称不可为空") + private String name; + + @ApiModelProperty(name = "docContent",value = "json内容",required = true) + @NotBlank(message = "模板内容不可为空") + private String docContent; + + @ApiModelProperty(name = "deptId",value = "部门id") + private String deptId; + + @ApiModelProperty(name = "reportType",value = "自定义报表类型",required = true) + @NotBlank(message = "自定义报表类型不可为空") + private String reportType; + + + + @Data + @EqualsAndHashCode(callSuper = true) + public static class UpdateReportTemplateParam extends ReportTemplateParam { + + @ApiModelProperty(name = "id",required = true) + @NotBlank(message = ValidMessage.ID_NOT_BLANK) + @Pattern(regexp = PatternRegex.SYSTEM_ID, message = ValidMessage.ID_FORMAT_ERROR) + private String id; + } + +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/EleEpdPqd.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/EleEpdPqd.java new file mode 100644 index 000000000..bf6e1e111 --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/EleEpdPqd.java @@ -0,0 +1,44 @@ +package com.njcn.harmonic.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 类的介绍: + * + * @author xuyang + * @version 1.0.0 + * @createTime 2022/3/14 19:57 + */ +@Data +@TableName("ele_epd_pqd_copy") +public class EleEpdPqd implements Serializable { + + private static final long serialVersionUID = 1L; + + private String id; + + private String name; + + private String showName; + + private String otherName; + + private Integer sort; + + private String type; + + private String phase; + + private String unit; + + private Integer harmStart; + + private Integer harmEnd; + + private String classId; + + private String statMethod; +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/ReportTemplate.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/ReportTemplate.java new file mode 100644 index 000000000..4dfe670d1 --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/po/ReportTemplate.java @@ -0,0 +1,35 @@ +package com.njcn.harmonic.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.mysql.cj.xdevapi.JsonArray; +import com.njcn.db.bo.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * pqs + * 自定义报表 + * @author cdf + * @date 2022/8/16 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName(value = "sys_report_template") +public class ReportTemplate extends BaseEntity { + private String id; + + private String name; + + private String docContent; + + private String deptId; + + private String reportType; + + private Integer active; + + private Integer state; +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java new file mode 100644 index 000000000..4614c6913 --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTemplateVO.java @@ -0,0 +1,30 @@ +package com.njcn.harmonic.pojo.vo; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.njcn.db.bo.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * pqs + * 自定义报表 + * @author cdf + * @date 2022/8/16 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ReportTemplateVO extends BaseEntity { + private String id; + + private String name; + + private String docContent; + + private String deptId; + + private Integer active; + + private Integer state; + + private String deptName; +} diff --git a/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTreeVO.java b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTreeVO.java new file mode 100644 index 000000000..20849a1cd --- /dev/null +++ b/pqs-harmonic/harmonic-api/src/main/java/com/njcn/harmonic/pojo/vo/ReportTreeVO.java @@ -0,0 +1,24 @@ +package com.njcn.harmonic.pojo.vo; + +import lombok.Data; + +import java.util.List; + +/** + * pqs + * + * @author cdf + * @date 2022/8/18 + */ +@Data +public class ReportTreeVO { + private String id; + + private String name; + + private String showName; + + private Integer flag; + + private List children; +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/controller/CustomReportController.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/controller/CustomReportController.java new file mode 100644 index 000000000..6c6551975 --- /dev/null +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/controller/CustomReportController.java @@ -0,0 +1,192 @@ +package com.njcn.harmonic.controller; + +import cn.hutool.json.JSONArray; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.common.pojo.annotation.OperateInfo; +import com.njcn.common.pojo.constant.OperateType; +import com.njcn.common.pojo.enums.common.LogEnum; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.response.HttpResult; +import com.njcn.common.utils.HttpResultUtil; +import com.njcn.common.utils.LogUtil; +import com.njcn.harmonic.pojo.param.ReportTemplateParam; +import com.njcn.harmonic.pojo.po.ReportTemplate; +import com.njcn.harmonic.pojo.vo.OverAreaLimitVO; +import com.njcn.harmonic.pojo.vo.OverAreaVO; +import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.harmonic.pojo.vo.ReportTreeVO; +import com.njcn.harmonic.service.CustomReportService; +import com.njcn.web.controller.BaseController; +import com.njcn.web.pojo.param.BaseParam; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * pqs + * 用户自定义报表 + * @author cdf + * @date 2022/8/15 + */ + +@Slf4j +@RestController +@RequestMapping("/customReport") +@Api(tags = "用户自定义报表") +@AllArgsConstructor +public class CustomReportController extends BaseController { + + private final CustomReportService customReportService; + + /** + * 新增自定义报表模板 + * @author cdf + * @date 2022/8/16 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON,operateType=OperateType.ADD) + @PostMapping("/addTemplate") + @ApiOperation("新增自定义报表模板") + @ApiImplicitParam(name = "reportTemplateParam", value = "实体参数", required = true) + public HttpResult addCustomReportTemplate(@RequestBody @Validated ReportTemplateParam reportTemplateParam){ + String methodDescribe = getMethodDescribe("addCustomReportTemplate"); + boolean res = customReportService.addCustomReportTemplate(reportTemplateParam); + if(res){ + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); + }else { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe); + } + } + + + /** + * 修改自定义报表模板 + * @author cdf + * @date 2022/8/16 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON,operateType=OperateType.UPDATE) + @PostMapping("/updateTemplate") + @ApiOperation("修改自定义报表模板") + @ApiImplicitParam(name = "reportTemplateParam", value = "实体参数", required = true) + public HttpResult updateCustomReportTemplate(@RequestBody @Validated ReportTemplateParam.UpdateReportTemplateParam reportTemplateParam){ + String methodDescribe = getMethodDescribe("updateCustomReportTemplate"); + boolean res = customReportService.updateCustomReportTemplate(reportTemplateParam); + if(res){ + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); + }else { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe); + } + } + + /** + * 分页查询 + * @author cdf + * @date 2022/8/16 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @PostMapping("/getTemplateList") + @ApiOperation("分页查询报表模板") + @ApiImplicitParam(name = "baseParam", value = "实体参数", required = true) + public HttpResult> getTemplateList(@RequestBody BaseParam baseParam){ + String methodDescribe = getMethodDescribe("getTemplateList"); + Page page = customReportService.getReportTemplateList(baseParam); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, page, methodDescribe); + } + + + /** + * 删除模板 + * @author cdf + * @date 2022/8/23 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON,operateType=OperateType.DELETE) + @GetMapping("/delTemplate") + @ApiOperation("删除报表模板") + @ApiImplicitParam(name = "id", value = "模板id", required = true) + public HttpResult delTemplate(@RequestParam("id")String id){ + String methodDescribe = getMethodDescribe("delTemplate"); + boolean res = customReportService.delTemplate(id); + if(res){ + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); + }else { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe); + } + } + + + /** + * 修改激活状态 + * @author cdf + * @date 2022/8/23 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON,operateType=OperateType.UPDATE) + @GetMapping("/updateTemplateActive") + @ApiOperation("修改激活状态") + @ApiImplicitParam(name = "id", value = "模板id", required = true) + public HttpResult> updateTemplateActive(@RequestParam("id")String id){ + String methodDescribe = getMethodDescribe("updateTemplateActive"); + boolean res = customReportService.updateStatus(id); + if(res){ + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); + }else { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe); + } + } + + + /** + * 根据id查询模板详情 + * @author cdf + * @date 2022/8/16 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @PostMapping("/getCustomReportTemplateById") + @ApiOperation("根据id查询模板详情") + @ApiImplicitParam(name = "id", value = "id", required = true) + public HttpResult getCustomReportTemplateById(@RequestParam("id") String id){ + String methodDescribe = getMethodDescribe("getCustomReportTemplateById"); + ReportTemplate reportTemplate = customReportService.getCustomReportTemplateById(id); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, reportTemplate, methodDescribe); + } + + + /** + * 根据id查询模板详情 + * @author cdf + * @date 2022/8/16 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @PostMapping("/getCustomReport") + @ApiOperation("获取报表") + @ApiImplicitParam(name = "id", value = "id", required = true) + public HttpResult getCustomReport(@RequestParam("id") String id){ + String methodDescribe = getMethodDescribe("getCustomReport"); + JSONArray res = customReportService.getCustomReport(); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, res, methodDescribe); + } + + + /** + * 获取报表模板树 + * @author cdf + * @date 2022/8/16 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @GetMapping("/reportChooseTree") + @ApiOperation("获取报表模板树") + public HttpResult> reportChooseTree(){ + String methodDescribe = getMethodDescribe("reportChooseTree"); + List res = customReportService.reportChooseTree(); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, res, methodDescribe); + } + + +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/CustomReportMapper.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/CustomReportMapper.java new file mode 100644 index 000000000..fa7765426 --- /dev/null +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/CustomReportMapper.java @@ -0,0 +1,19 @@ +package com.njcn.harmonic.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.harmonic.pojo.po.ReportTemplate; +import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.web.pojo.param.BaseParam; +import org.apache.ibatis.annotations.Param; + +/** + * pqs + * + * @author cdf + * @date 2022/8/16 + */ +public interface CustomReportMapper extends BaseMapper { + + Page getReportTemplateList(Page page, @Param("baseParam")BaseParam baseParam); +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/EleEpdMapper.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/EleEpdMapper.java new file mode 100644 index 000000000..f59f46a8c --- /dev/null +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/EleEpdMapper.java @@ -0,0 +1,13 @@ +package com.njcn.harmonic.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import com.njcn.harmonic.pojo.po.EleEpdPqd; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface EleEpdMapper extends BaseMapper { + + +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/CustomReportMapper.xml b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/CustomReportMapper.xml new file mode 100644 index 000000000..98332dc0a --- /dev/null +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/mapper/mapping/CustomReportMapper.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/CustomReportService.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/CustomReportService.java new file mode 100644 index 000000000..d3c718665 --- /dev/null +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/CustomReportService.java @@ -0,0 +1,75 @@ +package com.njcn.harmonic.service; + +import cn.hutool.json.JSONArray; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.common.pojo.response.HttpResult; +import com.njcn.harmonic.pojo.param.ReportTemplateParam; +import com.njcn.harmonic.pojo.po.ReportTemplate; +import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.harmonic.pojo.vo.ReportTreeVO; +import com.njcn.web.pojo.param.BaseParam; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +/** + * pqs + * + * @author cdf + * @date 2022/8/16 + */ +public interface CustomReportService { + + + /** + * 新增自定义报表模板 + * @author cdf + * @date 2022/8/16 + */ + boolean addCustomReportTemplate(ReportTemplateParam reportTemplateParam); + + + /** + * 修改自定义报表模板 + * @author cdf + * @date 2022/8/16 + */ + boolean updateCustomReportTemplate(ReportTemplateParam reportTemplateParam); + + /** + * 根据id获取模板 + * @author cdf + * @date 2022/8/16 + */ + ReportTemplate getCustomReportTemplateById(String id); + + + /** + * 模板列表 + * @author cdf + * @date 2022/8/16 + */ + Page getReportTemplateList(BaseParam baseParam); + + /** + * 删除模板 + * @author cdf + * @date 2022/8/23 + */ + boolean delTemplate(String id); + + + /** + * 切换模板激活状态 + * @author cdf + * @date 2022/8/23 + */ + boolean updateStatus(String id); + + + JSONArray getCustomReport(); + + List reportChooseTree(); +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/CustomReportServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/CustomReportServiceImpl.java new file mode 100644 index 000000000..11ba5e37f --- /dev/null +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/CustomReportServiceImpl.java @@ -0,0 +1,475 @@ +package com.njcn.harmonic.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.njcn.common.pojo.enums.common.DataStateEnum; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.harmonic.enums.HarmonicResponseEnum; +import com.njcn.harmonic.mapper.CustomReportMapper; +import com.njcn.harmonic.mapper.EleEpdMapper; +import com.njcn.harmonic.pojo.dto.ReportTemplateDTO; +import com.njcn.harmonic.pojo.param.ReportTemplateParam; +import com.njcn.harmonic.pojo.po.EleEpdPqd; +import com.njcn.harmonic.pojo.po.ReportTemplate; +import com.njcn.harmonic.pojo.vo.ReportTemplateVO; +import com.njcn.harmonic.pojo.vo.ReportTreeVO; +import com.njcn.harmonic.service.CustomReportService; + +import com.njcn.influxdb.param.InfluxDBPublicParam; +import com.njcn.influxdb.utils.InfluxDbUtils; +import com.njcn.system.api.DicDataFeignClient; +import com.njcn.system.pojo.po.DictData; +import com.njcn.user.api.DeptFeignClient; +import com.njcn.user.pojo.po.Dept; +import com.njcn.web.factory.PageFactory; +import com.njcn.web.pojo.param.BaseParam; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * pqs + * 自定义报表 + * + * @author cdf + * @date 2022/8/16 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class CustomReportServiceImpl implements CustomReportService { + + private final CustomReportMapper customReportMapper; + + private final DeptFeignClient deptFeignClient; + + private final EleEpdMapper eleEpdMapper; + + private final InfluxDbUtils influxDbUtils; + + private final DicDataFeignClient dicDataFeignClient; + + @Override + public boolean addCustomReportTemplate(ReportTemplateParam reportTemplateParam) { + checkName(reportTemplateParam, false); + + try { + new JSONArray(reportTemplateParam.getDocContent()); + } catch (Exception e) { + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON); + } + + ReportTemplate reportTemplate = new ReportTemplate(); + BeanUtils.copyProperties(reportTemplateParam, reportTemplate); + reportTemplate.setState(DataStateEnum.ENABLE.getCode()); + reportTemplate.setActive(DataStateEnum.DELETED.getCode()); + customReportMapper.insert(reportTemplate); + return true; + } + + @Override + public boolean updateCustomReportTemplate(ReportTemplateParam reportTemplateParam) { + checkName(reportTemplateParam, true); + + try { + new JSONArray(reportTemplateParam.getDocContent()); + } catch (Exception e) { + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_JSON); + } + + ReportTemplate reportTemplate = new ReportTemplate(); + BeanUtils.copyProperties(reportTemplateParam, reportTemplate); + customReportMapper.updateById(reportTemplate); + return true; + } + + @Override + public ReportTemplate getCustomReportTemplateById(String id) { + return customReportMapper.selectById(id); + } + + @Override + public Page getReportTemplateList(BaseParam baseParam) { + return customReportMapper.getReportTemplateList(new Page<>(PageFactory.getPageNum(baseParam),PageFactory.getPageSize(baseParam)),baseParam); + } + + @Override + public boolean delTemplate(String id) { + ReportTemplate reportTemplate = new ReportTemplate(); + reportTemplate.setId(id); + reportTemplate.setState(DataStateEnum.DELETED.getCode()); + customReportMapper.updateById(reportTemplate); + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateStatus(String id) { + ReportTemplate report = new ReportTemplate(); + report.setActive(0); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("sys_report_template.active",1).eq("sys_report_template.state",1); + customReportMapper.update(report,updateWrapper); + + ReportTemplate reportTemplate = new ReportTemplate(); + reportTemplate.setId(id); + reportTemplate.setActive(DataStateEnum.ENABLE.getCode()); + customReportMapper.updateById(reportTemplate); + return true; + } + + + @Override + public JSONArray getCustomReport() { + List stringList = new ArrayList<>(); + List reportTemplateDTOList = new ArrayList<>(); + + LambdaQueryWrapper lambdaQuery= new LambdaQueryWrapper<>(); + lambdaQuery.eq(ReportTemplate::getActive,DataStateEnum.ENABLE.getCode()) + .eq(ReportTemplate::getState,DataStateEnum.ENABLE.getCode()); + ReportTemplate tem = customReportMapper.selectOne(lambdaQuery); + JSONArray jsonArray = new JSONArray(tem.getDocContent()); + jsonArray.forEach(item->{ + JSONObject jsonObject = (JSONObject)item; + JSONArray itemArr = (JSONArray) jsonObject.get("data"); + itemArr.forEach((ite)->{ + JSONArray j = (JSONArray)ite; + j.forEach(it->{ + if (Objects.nonNull(it) && !"null".equals(it.toString())) { + JSONObject son = (JSONObject) it; //获取到1列 + if (son.containsKey("v")) { + String v = son.getStr("v"); + System.out.println(v); + if (v.charAt(0) == '$' && v.contains("#")) { + v=v.replace("$",""); + + String[] vItem = v.split("#"); + + ReportTemplateDTO reportTemplateDTO = new ReportTemplateDTO(); + reportTemplateDTO.setItemName(v); + String t = vItem[0].replace("_",""); + if(vItem.length == 3){ + + reportTemplateDTO.setTemplateName(t); + reportTemplateDTO.setPhase(vItem[1]); + reportTemplateDTO.setStatMethod(vItem[2]); + + }else if(vItem.length == 2){ + reportTemplateDTO.setTemplateName(t); + reportTemplateDTO.setStatMethod(vItem[1]); + reportTemplateDTO.setPhase("M"); + } + if (vItem[0].contains("_")) { + String col = vItem[0].split("_")[0]; + reportTemplateDTO.setName(col); + stringList.add(col); + } else { + reportTemplateDTO.setName(vItem[0]); + stringList.add(vItem[0]); + } + reportTemplateDTOList.add(reportTemplateDTO); + } + } + } + }); + }); + }); + + + + List endList = new ArrayList<>(); + + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.in(EleEpdPqd::getName,stringList.stream().distinct().collect(Collectors.toList())).orderByAsc(EleEpdPqd::getSort); + List eleEpdPqdList = eleEpdMapper.selectList(lambdaQueryWrapper); + Map> mapEpd = eleEpdPqdList.stream().collect(Collectors.groupingBy(EleEpdPqd::getClassId)); + mapEpd.forEach((key,tableClass)->{ + + List column = tableClass.stream().map(EleEpdPqd::getName).distinct().collect(Collectors.toList()); + List classList = reportTemplateDTOList.stream().filter(item->column.contains(item.getName())).collect(Collectors.toList()); + + Map> phaseMap = classList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getPhase)); + + //开始组织sql + phaseMap.forEach((phKey,phValue)->{ + + + if("M".equals(phKey)){ + + }else { + Map> statMap = phValue.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getStatMethod)); + statMap.forEach((statKey,statValue)->{ + StringBuilder sql = new StringBuilder("select "); + + if(statKey.equals("max")){ + for(int i = 0;i> resMap = influxDbUtils.getMapResult(sql.toString()); + + if(CollUtil.isNotEmpty(resMap)) { + List temValue = statValue.stream().map(item -> { + String value = resMap.get(0).get(item.getTemplateName()).toString(); + item.setValue(value); + return item; + }).collect(Collectors.toList()); + endList.addAll(temValue); + } + }else if(statKey.equals("min")){ + for(int i = 0;i> resMap = influxDbUtils.getMapResult(sql.toString()); + + if(CollUtil.isNotEmpty(resMap)) { + List temValue = statValue.stream().map(item -> { + String value = resMap.get(0).get(item.getTemplateName()).toString(); + item.setValue(value); + return item; + }).collect(Collectors.toList()); + endList.addAll(temValue); + } + }else if(statKey.equals("avg")){ + for(int i = 0;i> resMap = influxDbUtils.getMapResult(sql.toString()); + + if(CollUtil.isNotEmpty(resMap)) { + List temValue = statValue.stream().map(item -> { + String value = resMap.get(0).get(item.getTemplateName()).toString(); + item.setValue(value); + return item; + }).collect(Collectors.toList()); + endList.addAll(temValue); + } + }else if(statKey.equals("cp95")){ + for(int i = 0;i> resMap = influxDbUtils.getMapResult(sql.toString()); + + if(CollUtil.isNotEmpty(resMap)) { + List temValue = statValue.stream().map(item -> { + String value = resMap.get(0).get(item.getTemplateName()).toString(); + item.setValue(value); + return item; + }).collect(Collectors.toList()); + endList.addAll(temValue); + } + } + + + + }); + + + + } + + }); + }); + + + //进行反向赋值到模板 + Map> assMap = endList.stream().collect(Collectors.groupingBy(ReportTemplateDTO::getItemName)); + jsonArray.forEach(item->{ + JSONObject jsonObject = (JSONObject)item; + JSONArray itemArr = (JSONArray) jsonObject.get("data"); + itemArr.forEach((ite)->{ + JSONArray j = (JSONArray)ite; + j.forEach(it->{ + if (Objects.nonNull(it) && !"null".equals(it.toString())) { + JSONObject son = (JSONObject) it; //获取到1列 + if (son.containsKey("v")) { + String v = son.getStr("v"); + System.out.println(v); + if (v.charAt(0) == '$' && v.contains("#")) { + + String str = assMap.get(v.replace("$","")).get(0).getValue(); + son.set("v",str); + son.set("m",str); + } + } + } + }); + }); + }); + + + return jsonArray; + } + + @Override + public List reportChooseTree() { + long a = System.currentTimeMillis(); + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.orderByAsc(EleEpdPqd::getSort); + List list = eleEpdMapper.selectList(lambdaQueryWrapper); + Map> map = list.stream().collect(Collectors.groupingBy(EleEpdPqd::getName)); + + List tree = new ArrayList<>(); + map.forEach((key, value) -> { + + ReportTreeVO reportTreeVO = new ReportTreeVO(); + reportTreeVO.setName(key); + reportTreeVO.setShowName(value.get(0).getShowName()); + + //存在1-50次 2-50次情况 + if (Objects.nonNull(value.get(0).getHarmStart()) && Objects.nonNull(value.get(0).getHarmEnd())) { + List reHarm = new ArrayList<>(); + for (int i = value.get(0).getHarmStart(); i < value.get(0).getHarmEnd(); i++) { + ReportTreeVO reportTreeCount = new ReportTreeVO(); + reportTreeCount.setName(value.get(0).getName() + "_" + i); + reportTreeCount.setShowName(i + "次" + value.get(0).getShowName()); + reportTreeVO.setFlag(1); + assPhase(value, reportTreeCount); + reHarm.add(reportTreeCount); + } + reportTreeVO.setChildren(reHarm); + } else { + assPhase(value, reportTreeVO); + } + tree.add(reportTreeVO); + }); + + long b = System.currentTimeMillis(); + System.out.println(b - a); + return tree; + } + + + /*组装相别*/ + private void assPhase(List value, ReportTreeVO reportTreeItem) { + if (Objects.nonNull(value.get(0).getPhase()) && !"M".equals(value.get(0).getPhase())) { + List phaseTree = new ArrayList<>(); + value.forEach(item -> { + List statTree = new ArrayList<>(); + ReportTreeVO reportTreePhase = new ReportTreeVO(); + reportTreePhase.setName(item.getPhase()); + reportTreePhase.setShowName(item.getPhase()); + + assStatMethod(item, statTree); + reportTreePhase.setChildren(statTree); + phaseTree.add(reportTreePhase); + }); + reportTreeItem.setChildren(phaseTree); + } else { + List statTree = new ArrayList<>(); + assStatMethod(value.get(0), statTree); + reportTreeItem.setChildren(statTree); + } + } + + + private void assStatMethod(EleEpdPqd item, List statTree) { + //存在向别为M但是Stat_Method不为空 + if (StrUtil.isNotBlank(item.getStatMethod())) { + String[] arr = item.getStatMethod().split(","); + List stat = Stream.of(arr).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(stat)) { + stat.forEach(statItem -> { + ReportTreeVO reportTreeStat = new ReportTreeVO(); + reportTreeStat.setName(statItem); + reportTreeStat.setShowName(statItem); + statTree.add(reportTreeStat); + }); + } + } + } + + + private void checkName(ReportTemplateParam reportTemplateParam, boolean isUpdate) { + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(ReportTemplate::getState, DataStateEnum.ENABLE.getCode()).eq(ReportTemplate::getName, reportTemplateParam.getName()); + + + if (isUpdate) { + if (reportTemplateParam instanceof ReportTemplateParam.UpdateReportTemplateParam) { + lambdaQueryWrapper.ne(ReportTemplate::getId, ((ReportTemplateParam.UpdateReportTemplateParam) reportTemplateParam).getId()); + } + } + + int count = customReportMapper.selectCount(lambdaQueryWrapper); + if (count > 0) { + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_REPEAT); + } + + + + if(StrUtil.isNotBlank(reportTemplateParam.getDeptId())){ + Dept dept = deptFeignClient.getDeptById(reportTemplateParam.getDeptId()).getData(); + if(Objects.isNull(dept)){ + throw new BusinessException(CommonResponseEnum.FAIL); + } + + lambdaQueryWrapper.clear(); + lambdaQueryWrapper.eq(ReportTemplate::getDeptId,reportTemplateParam.getDeptId()) + .eq(ReportTemplate::getState,DataStateEnum.ENABLE.getCode()); + + if (isUpdate) { + if (reportTemplateParam instanceof ReportTemplateParam.UpdateReportTemplateParam) { + lambdaQueryWrapper.ne(ReportTemplate::getId, ((ReportTemplateParam.UpdateReportTemplateParam) reportTemplateParam).getId()); + } + } + + int countDept = customReportMapper.selectCount(lambdaQueryWrapper); + if(countDept>0){ + throw new BusinessException(HarmonicResponseEnum.CUSTOM_REPORT_DEPT); + } + } + + + DictData dictData = dicDataFeignClient.getDicDataById(reportTemplateParam.getReportType()).getData(); + + if(Objects.isNull(dictData)){ + throw new BusinessException(HarmonicResponseEnum.CUSTOM_TYPE); + } + + } +} diff --git a/pqs-system/system-api/src/main/java/com/njcn/system/enums/DicDataTypeEnum.java b/pqs-system/system-api/src/main/java/com/njcn/system/enums/DicDataTypeEnum.java index ffa13da35..710d2f5ab 100644 --- a/pqs-system/system-api/src/main/java/com/njcn/system/enums/DicDataTypeEnum.java +++ b/pqs-system/system-api/src/main/java/com/njcn/system/enums/DicDataTypeEnum.java @@ -14,36 +14,40 @@ public enum DicDataTypeEnum { /** * 字典类型名称 */ - FRONT_TYPE("前置类型"), - DEV_TYPE("终端型号"), - DEV_VARIETY("终端类型"), - DEV_FUN("终端功能"), - DEV_STATUS("终端状态"), - DEV_LEVEL("终端等级"), - DEV_CONNECT("接线方式"), - DEV_MANUFACTURER("制造厂商"), - DEV_VOLTAGE("电压等级"), - EVENT_REASON("暂降原因"), - EVENT_TYPE("暂降类型"), - BUSINESS_TYPE("行业类型"), - INTERFERENCE_SOURCE_TYPE("干扰源类型"), - ALARM_TYPE("告警类型"), - DEV_OPS("运维日志"), - INDICATOR_TYPE("指标类型"), - COMMUNICATE_TYPE("通讯类型"), - RATE_TYPE("费率类型"), - ELE_LOAD_TYPE("用能负荷类型"), - ELE_STATISTICAL_TYPE("用能统计类型"), - LINE_MARK("监测点评分等级"), - LINE_TYPE("监测点类型") + FRONT_TYPE("前置类型","Front_Type"), + DEV_TYPE("终端型号","Dev_Type"), + DEV_VARIETY("终端类型","Dev_Variety"), + DEV_FUN("终端功能","Dev_Fun"), + DEV_STATUS("终端状态","Dev_Status"), + DEV_LEVEL("终端等级","Dev_Level"), + DEV_CONNECT("接线方式","Dev_Connect"), + DEV_MANUFACTURER("制造厂商","Dev_Manufacturers"), + DEV_VOLTAGE("电压等级","Dev_Voltage"), + EVENT_REASON("暂降原因","Event_Reason"), + EVENT_TYPE("暂降类型","Event_Type"), + BUSINESS_TYPE("行业类型","Business_Type"), + INTERFERENCE_SOURCE_TYPE("干扰源类型","Interference_Source"), + ALARM_TYPE("告警类型","alarm_Type"), + DEV_OPS("运维日志","Dev_Ops"), + INDICATOR_TYPE("指标类型","Indicator_Type"), + COMMUNICATE_TYPE("通讯类型","Communicate_Type"), + RATE_TYPE("费率类型","Rate_Type"), + ELE_LOAD_TYPE("用能负荷类型","Ele_Load_Type"), + ELE_STATISTICAL_TYPE("用能统计类型","Ele_Statistical_Type"), + REPORT_TYPE("自定义报表类型","Report_Type"), + LINE_MARK("监测点评分等级","Line_Grade"), + LINE_TYPE("监测点类型","Line_Type") + ; private final String name; + private final String code; - DicDataTypeEnum(String name){ + DicDataTypeEnum(String name,String code){ this.name=name; + this.code=code; } }