Forráskód Böngészése

Merge branch 'rpt' of http://39.106.8.246:3003/persagy/dmp into rpt

fengyanjie@sagacloud.cn 4 éve
szülő
commit
549ff55a6f
44 módosított fájl, 4139 hozzáadás és 0 törlés
  1. 37 0
      dmp-report/doc/config.sql
  2. 144 0
      dmp-report/pom.xml
  3. 59 0
      dmp-report/src/main/java/com/persagy/dmp/report/ReportApp.java
  4. 633 0
      dmp-report/src/main/java/com/persagy/dmp/report/common/criteria/CriteriaUtils.java
  5. 561 0
      dmp-report/src/main/java/com/persagy/dmp/report/common/criteria/JacksonCriteria.java
  6. 304 0
      dmp-report/src/main/java/com/persagy/dmp/report/common/json/JsonMapper.java
  7. 46 0
      dmp-report/src/main/java/com/persagy/dmp/report/config/WebConfig.java
  8. 68 0
      dmp-report/src/main/java/com/persagy/dmp/report/controller/DataExecutorController.java
  9. 27 0
      dmp-report/src/main/java/com/persagy/dmp/report/controller/InitDataController.java
  10. 23 0
      dmp-report/src/main/java/com/persagy/dmp/report/controller/ReportController.java
  11. 18 0
      dmp-report/src/main/java/com/persagy/dmp/report/entity/BaseEntity.java
  12. 61 0
      dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportAlarmRecord.java
  13. 27 0
      dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportConfig.java
  14. 41 0
      dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportConfigGroup.java
  15. 53 0
      dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportRwdObject.java
  16. 29 0
      dmp-report/src/main/java/com/persagy/dmp/report/enumeration/CalculatedFunction.java
  17. 65 0
      dmp-report/src/main/java/com/persagy/dmp/report/enumeration/DateType.java
  18. 26 0
      dmp-report/src/main/java/com/persagy/dmp/report/enumeration/EnumReportMessageType.java
  19. 32 0
      dmp-report/src/main/java/com/persagy/dmp/report/feign/TaskClient.java
  20. 72 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/JmsConfig.java
  21. 14 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/MessageExecutor.java
  22. 88 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/MessageProcesser.java
  23. 115 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/AlarmRecordCreateExecutor.java
  24. 31 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/CreateTableExecutor.java
  25. 100 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/InstanceObjectCreateExecutor.java
  26. 68 0
      dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/ReportRwdObjectCreateExecutor.java
  27. 30 0
      dmp-report/src/main/java/com/persagy/dmp/report/model/TaskCfgModel.java
  28. 20 0
      dmp-report/src/main/java/com/persagy/dmp/report/model/TaskRecordModel.java
  29. 15 0
      dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportAlarmRecordRepository.java
  30. 9 0
      dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportConfigGroupRepository.java
  31. 9 0
      dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportConfigRepository.java
  32. 16 0
      dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportObjectRepository.java
  33. 17 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/BaseService.java
  34. 147 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/DataExecutorService.java
  35. 118 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/InitDataService.java
  36. 86 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/ReportAlarmRecordService.java
  37. 50 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/ReportConfigService.java
  38. 76 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/ReportRwdObjectService.java
  39. 114 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/ReportService.java
  40. 476 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/ReportUtils.java
  41. 56 0
      dmp-report/src/main/java/com/persagy/dmp/report/service/TestService.java
  42. 5 0
      dmp-report/src/main/resources/bootstrap-aliyun-test.yml
  43. 10 0
      dmp-report/src/main/resources/bootstrap.yml
  44. 143 0
      dmp-report/src/test/java/com/persagy/dmp.report/test.java

+ 37 - 0
dmp-report/doc/config.sql

@@ -0,0 +1,37 @@
+
+delete from integrated_config where application = 'dmp-report';
+insert into integrated_config(application,pprofile,lable,pkey,pvalue,description,isupdate,belongto)
+values
+('dmp-report','default','master','server.port', '8085', null, '1', 'DMP'),
+('dmp-report','default','master','spring.application.name', 'dmp-report', null, '1', 'DMP'),
+('dmp-report','default','master','spring.jackson.time-zone', 'Asia/Shanghai', null, '1', 'DMP'),
+('dmp-report','default','master','spring.datasource.driver-class-name', 'com.mysql.cj.jdbc.Driver', null, '1', 'DMP'),
+('dmp-report','default','master','spring.datasource.type', 'com.alibaba.druid.pool.DruidDataSource', null, '1', 'DMP'),
+('dmp-report','default','master','spring.jpa.show-sql', 'true', null, '1', 'DMP'),
+('dmp-report','default','master','spring.jpa.hibernate.ddl-auto', 'none', null, '1', 'DMP'),
+('dmp-report','default','master','management.endpoints.web.exposure.include', '*', null, '1', 'DMP'),
+('dmp-report','default','master','management.endpoint.health.show-details', 'ALWAYS', null, '1', 'DMP'),
+('dmp-report','default','master','eureka.client.fetch-registry','true',null, '1', 'DMP'),
+('dmp-report','default','master','eureka.client.register-with-eureka','true',null, '1', 'DMP'),
+('dmp-report','default','master','eureka.instance.lease-renewal-interval-in-seconds','10',null, '1', 'DMP'),
+('dmp-report','default','master','eureka.instance.lease-expiration-duration-in-seconds','30',null, '1', 'DMP'),
+('dmp-report','default','master','eureka.instance.hostname','${spring.application.name}',null, '1', 'DMP'),
+('dmp-report','default','master','eureka.instance.prefer-ip-address','true',null, '1', 'DMP'),
+('dmp-report','default','master','eureka.instance.instance-id','${spring.cloud.client.ip-address}:${server.port}',null, '1', 'DMP'),
+
+('dmp-report','dev','master','spring.datasource.url', 'jdbc:mysql://localhost:3301/dmp_dev?useUnicode=true&characterEncoding=utf-8&mysqlEncoding=utf8&useSSL=false', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.datasource.username', 'root', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.datasource.password', '123456', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.rabbitmq.host', 'host', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.rabbitmq.port', '5672', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.rabbitmq.username', 'admin', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.rabbitmq.password', '123456', null, '1', 'DMP'),
+('dmp-report','dev','master','spring.rabbitmq.virtual-host', '/test', null, '1', 'DMP'),
+('dmp-report','dev','master','eureka.client.service-url.defaultZone','http://frame:123456@localhost:9931/eureka/',null, '1', 'DMP'),
+('dmp-report','dev','master','eureka.instance.ip-address','localhost',null, '1', 'DMP'),
+('dmp-report','dev','master','dmp.report.exchange','exchange-dmp',null, '1', 'DMP'),
+('dmp-report','dev','master','dmp.report.routingKey','routing-dmp-report',null, '1', 'DMP'),
+('dmp-report','dev','master','dmp.report.queue','report-queue',null, '1', 'DMP'),
+('dmp-report','dev','master','feign.client.config.default.connectTimeout','5000',null, '1', 'DMP'),
+('dmp-report','dev','master','feign.client.config.default.readTimeout','10000',null, '1', 'DMP');
+

+ 144 - 0
dmp-report/pom.xml

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>com.persagy</groupId>
+        <artifactId>dmp</artifactId>
+        <version>4.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dmp-report</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.persagy</groupId>
+            <artifactId>dmp-common</artifactId>
+            <version>4.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.21</version>
+        </dependency>
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-apt</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-sql</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.vladmihalcea</groupId>
+            <artifactId>hibernate-types-52</artifactId>
+            <version>2.9.13</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <!-- 注册中心 -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+
+        <!-- 配置中心 -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-config</artifactId>
+        </dependency>
+        <!-- rabbitmq -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+
+        <!-- feign -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+
+        <!-- hystrix 熔断器 -->
+        <dependency>
+            <groupId>com.netflix.hystrix</groupId>
+            <artifactId>hystrix-javanica</artifactId>
+            <version>1.5.12</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>dmp-report</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <fork>true</fork>
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!--
+            -->
+            <plugin>
+                <groupId>com.mysema.maven</groupId>
+                <artifactId>apt-maven-plugin</artifactId>
+                <version>1.1.3</version>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>target/generated-sources</outputDirectory>
+                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 59 - 0
dmp-report/src/main/java/com/persagy/dmp/report/ReportApp.java

@@ -0,0 +1,59 @@
+package com.persagy.dmp.report;
+
+import com.persagy.common.criteria.JpaUtils;
+import com.persagy.dmp.common.SpringUtils;
+import com.persagy.dmp.common.http.HttpUtils;
+import com.persagy.dmp.report.common.criteria.CriteriaUtils;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.annotation.EnableRabbit;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import javax.persistence.EntityManager;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-2
+ * @verison: 1.0
+ */
+@Slf4j
+@EnableRabbit
+@SpringCloudApplication
+@EnableFeignClients
+@EnableScheduling
+public class ReportApp {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ReportApp.class, args);
+    }
+
+    @Bean
+    public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {
+        return new JPAQueryFactory(entityManager);
+    }
+
+    @Bean
+    public CriteriaUtils criteriaUtils(@Autowired JPAQueryFactory jpaQueryFactory) {
+        return new CriteriaUtils(jpaQueryFactory);
+    }
+
+    @Bean
+    public JpaUtils jpaUtils(@Autowired EntityManager entityManager) {
+        return new JpaUtils(entityManager);
+    }
+
+    @Bean
+    public HttpUtils httpUtils() {
+        return new HttpUtils();
+    }
+
+    @Bean
+    public SpringUtils springUtils() {
+        return new SpringUtils();
+    }
+}

+ 633 - 0
dmp-report/src/main/java/com/persagy/dmp/report/common/criteria/CriteriaUtils.java

@@ -0,0 +1,633 @@
+package com.persagy.dmp.report.common.criteria;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.*;
+import com.persagy.common.criteria.CriteriaExpressionParser;
+import com.persagy.common.date.DateUtils;
+import com.persagy.common.web.PagedResponse;
+import com.querydsl.core.Tuple;
+import com.querydsl.core.types.Expression;
+import com.querydsl.core.types.OrderSpecifier;
+import com.querydsl.core.types.dsl.*;
+import com.querydsl.jpa.impl.JPAQuery;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+
+import java.lang.reflect.Field;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-19
+ * @verison: 1.0
+ */
+public class CriteriaUtils {
+
+    private static final Integer DEFAULT_SIZE = 50;
+
+    private JPAQueryFactory queryFactory;
+
+    public CriteriaUtils(JPAQueryFactory queryFactory) {
+        this.queryFactory = queryFactory;
+    }
+
+    private <T, Q extends EntityPathBase<T>> List<BooleanExpression> parseNode(Q q, ObjectNode object) {
+        List<BooleanExpression> exps = new LinkedList<>();
+        if (object == null || object.isEmpty()) {
+            return exps;
+        }
+
+        Field[] fields = q.getClass().getFields();
+        for (Field field : fields) {
+            Class<?> type = field.getType();
+            if (type != NumberPath.class && type != DateTimePath.class && type != StringPath.class) {
+                continue;
+            }
+            String name = field.getName();
+            if (!object.has(name)) {
+                continue;
+            }
+            JsonNode jsonNode = object.get(name);
+            try {
+                if (type == NumberPath.class) {
+                    NumberPath path = (NumberPath) field.get(q);
+                    exps.addAll(parse(path, jsonNode));
+                }
+                if (type == DateTimePath.class) {
+                    DateTimePath path = (DateTimePath) field.get(q);
+                    exps.addAll(parse(path, jsonNode));
+                }
+                if (type == StringPath.class) {
+                    StringPath path = (StringPath) field.get(q);
+                    exps.addAll(parse(path, jsonNode));
+                }
+                // Boolean Enum
+            } catch (IllegalAccessException e) {
+            }
+        }
+        return exps;
+    }
+
+    private <T, Q extends EntityPathBase<T>> List<BooleanExpression> parseNode(Q q, CriteriaExpressionParser parser, ObjectNode objectNode) {
+        List<BooleanExpression> expressions = new LinkedList<>();
+        if (objectNode == null || objectNode.isEmpty()) {
+            return expressions;
+        }
+        List<BooleanExpression> exps = parseNode(q, objectNode);
+        if (exps != null && exps.size() > 0) {
+            expressions.addAll(exps);
+        }
+        if (parser != null) {
+            List<BooleanExpression> parseExps = parser.parse(objectNode);
+            if (parseExps != null && parseExps.size() > 0) {
+                expressions.addAll(parseExps);
+            }
+        }
+        return expressions;
+    }
+
+    public <T, Q extends EntityPathBase<T>> PagedResponse<T> query(Q q, CriteriaExpressionParser parser, JacksonCriteria request) {
+        PagedResponse<T> resp = new PagedResponse<>();
+
+        // 解析查询条件
+        ObjectNode criteria = request.getCriteria();
+        List<BooleanExpression> expressions = parseNode(q, parser, criteria);
+
+        // 处理or
+        JsonNode or = criteria.get("$or");
+        if (or != null && or.getNodeType() == JsonNodeType.ARRAY) {
+            ArrayNode arr = (ArrayNode) or;
+
+            BooleanExpression orExp = null;
+            for (JsonNode jsonNode : arr) {
+                if (jsonNode.getNodeType() != JsonNodeType.OBJECT) {
+                    continue;
+                }
+                List<BooleanExpression> subExpressions = parseNode(q, parser, (ObjectNode) jsonNode);
+                if (orExp == null) {
+                    orExp = and(subExpressions);
+                } else {
+                    orExp = orExp.or(and(subExpressions));
+                }
+            }
+            if (orExp != null) {
+                expressions.add(orExp);
+            }
+        }
+
+        JPAQuery<T> query = queryFactory.selectFrom(q).where(expressions.toArray(new BooleanExpression[0]));
+
+        // 统计总数
+        if (!request.isWithoutCount()) {
+            long count = query.fetchCount();
+            resp.setCount(count);
+        }
+
+        if (request.isOnlyCount()) {
+            return resp;
+        }
+
+        // 排序
+        OrderSpecifier[] specifiers = parseOrders(q, request);
+        if (specifiers != null) {
+            query = query.orderBy(specifiers);
+        }
+
+        // 分页
+        Integer page = request.getPage();
+        Integer size = request.getSize();
+        if (page != null) {
+            if (size == null) {
+                size = DEFAULT_SIZE; // 默认每页50
+            }
+            int offset = (page - 1) * size;
+            if (offset < 0) {
+                offset = 0;
+            }
+            query = query.offset(offset).limit(size);
+        }
+        List<T> data = query.fetch();
+        resp.setData(data);
+        return resp;
+    }
+
+    public <T, Q extends EntityPathBase<T>> PagedResponse<Tuple> groupbyQuery(Q q, CriteriaExpressionParser parser, JacksonCriteria request) {
+        PagedResponse<Tuple> resp = new PagedResponse<>();
+
+        // 解析查询条件
+        ObjectNode criteria = request.getCriteria();
+        List<BooleanExpression> expressions = parseNode(q, parser, criteria);
+
+        // 处理or
+        JsonNode or = criteria.get("$or");
+        if (or != null && or.getNodeType() == JsonNodeType.ARRAY) {
+            ArrayNode arr = (ArrayNode) or;
+
+            BooleanExpression orExp = null;
+            for (JsonNode jsonNode : arr) {
+                if (jsonNode.getNodeType() != JsonNodeType.OBJECT) {
+                    continue;
+                }
+                List<BooleanExpression> subExpressions = parseNode(q, parser, (ObjectNode) jsonNode);
+                if (orExp == null) {
+                    orExp = and(subExpressions);
+                } else {
+                    orExp = orExp.or(and(subExpressions));
+                }
+            }
+            if (orExp != null) {
+                expressions.add(orExp);
+            }
+        }
+
+        Expression[] groupby = parseGroupby(q, request);
+        List<Expression> ex = new LinkedList<>();
+        Field[] fields = q.getClass().getFields();
+
+        if(null != request.getCalculatedColumns()){
+            //计算列
+            for (JacksonCriteria.Calculated calculatedColumn : request.getCalculatedColumns()) {
+                for (Field field : fields) {
+                    String name = field.getName();
+                    Class<?> type = field.getType();
+                    if (calculatedColumn.getColumn().equals(name) && type == NumberPath.class) {
+                        NumberPath path = null;
+                        try {
+                            path = (NumberPath) field.get(q);
+                        } catch (IllegalAccessException e) {
+                            e.printStackTrace();
+                        }
+                        switch (calculatedColumn.getFunction()) {
+                            case SUM:
+                                ex.add(path.sum());
+                                break;
+                            case AVG:
+                                ex.add(path.avg());
+                                break;
+                            case MAX:
+                                ex.add(path.max());
+                                break;
+                            case MIN:
+                                ex.add(path.min());
+                                break;
+                            case COUNT:
+                                ex.add(path.count());
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+
+        //分组
+        for (String column : request.getGroupbyColumns()) {
+            for (Field field : fields) {
+                String name = field.getName();
+                Class<?> type = field.getType();
+                if (column.equals(name)) {
+                    try {
+                        if (type == NumberPath.class) {
+                            NumberPath path = (NumberPath) field.get(q);
+                            ex.add(path);
+                        }
+                        if (type == DateTimePath.class) {
+                            DateTimePath path = (DateTimePath) field.get(q);
+                            ex.add(path);
+                        }
+                        if (type == StringPath.class) {
+                            StringPath path = (StringPath) field.get(q);
+                            ex.add(path);
+                        }
+                        if (type == EnumPath.class) {
+                            EnumPath path = (EnumPath) field.get(q);
+                            ex.add(path);
+                        }
+                    } catch (IllegalAccessException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+
+        JPAQuery<Tuple> query = queryFactory.select(ex.toArray(new Expression[0])).from(q).where(expressions.toArray(new BooleanExpression[0]));
+        query = query.groupBy(groupby);
+
+        // 统计总数 todo
+        if (!request.isWithoutCount()) {
+            JPAQuery<Long> count = queryFactory.select(q.count()).from(q).where(expressions.toArray(new BooleanExpression[0])).groupBy(groupby);
+            resp.setCount((long) count.fetch().size());
+        }
+
+
+        if (request.isOnlyCount()) {
+            return resp;
+        }
+
+        // 排序
+        OrderSpecifier[] specifiers = parseOrders(q, request);
+        if (specifiers != null) {
+            query = query.orderBy(specifiers);
+        }
+
+        // 分页
+        Integer page = request.getPage();
+        Integer size = request.getSize();
+        if (page != null) {
+            if (size == null) {
+                size = DEFAULT_SIZE; // 默认每页50
+            }
+            int offset = (page - 1) * size;
+            if (offset < 0) {
+                offset = 0;
+            }
+            query = query.offset(offset).limit(size);
+        }
+
+        List<Tuple> data = query.fetch();
+        resp.setData(data);
+        return resp;
+    }
+
+    private <T, Q extends EntityPathBase<T>> OrderSpecifier[] parseOrders(Q q, JacksonCriteria criteria) {
+        List<JacksonCriteria.Order> orders = criteria.getOrders();
+        if (orders == null || orders.size() == 0) {
+            return null;
+        }
+        List<OrderSpecifier> specifiers = new LinkedList<>();
+        Field[] fields = q.getClass().getFields();
+        for (JacksonCriteria.Order order : orders) {
+            String column = order.getColumn();
+            try {
+                for (Field field : fields) {
+                    String name = field.getName();
+                    if (!column.equals(name)) {
+                        continue;
+                    }
+                    Class<?> type = field.getType();
+                    if (type == NumberPath.class) {
+                        NumberPath o = (NumberPath) field.get(q);
+                        specifiers.add(order.isAsc() ? o.asc() : o.desc());
+                    }
+                    if (type == DateTimePath.class) {
+                        DateTimePath o = (DateTimePath) field.get(q);
+                        specifiers.add(order.isAsc() ? o.asc() : o.desc());
+                    }
+                    if (type == StringPath.class) {
+                        StringPath o = (StringPath) field.get(q);
+                        specifiers.add(order.isAsc() ? o.asc() : o.desc());
+                    }
+                }
+            } catch (IllegalAccessException e) {
+
+            }
+        }
+
+        if (specifiers.size() == 0) {
+            return null;
+        } else {
+            return specifiers.toArray(new OrderSpecifier[0]);
+        }
+    }
+
+    private <T, Q extends EntityPathBase<T>> Expression[] parseGroupby(Q q, JacksonCriteria criteria) {
+        Set<String> groupbyColumns = criteria.getGroupbyColumns();
+        if (groupbyColumns == null || groupbyColumns.size() == 0) {
+            return null;
+        }
+        List<Expression> expressions = new LinkedList<>();
+        Field[] fields = q.getClass().getFields();
+        for (String column : groupbyColumns) {
+            try {
+                for (Field field : fields) {
+                    String name = field.getName();
+                    if (!column.equals(name)) {
+                        continue;
+                    }
+                    Class<?> type = field.getType();
+                    if (type == NumberPath.class) {
+                        NumberPath path = (NumberPath) field.get(q);
+                        expressions.add(path);
+                    }
+                    if (type == DateTimePath.class) {
+                        DateTimePath path = (DateTimePath) field.get(q);
+                        expressions.add(path);
+                    }
+                    if (type == StringPath.class) {
+                        StringPath path = (StringPath) field.get(q);
+                        expressions.add(path);
+                    }
+                    if (type == EnumPath.class) {
+                        EnumPath path = (EnumPath) field.get(q);
+                        expressions.add(path);
+                    }
+                }
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+        return expressions.toArray(new Expression[0]);
+    }
+
+    private BooleanExpression and(List<BooleanExpression> exps) {
+        if (exps == null || exps.size() == 0) {
+            return null;
+        }
+        BooleanExpression result = exps.get(0);
+        for (int i = 1; i < exps.size(); i++) {
+            result = result.and(exps.get(i));
+        }
+        return result;
+    }
+
+
+    public static List<BooleanExpression> parse(NumberExpression path, JsonNode node) {
+        return parse(path, node, null);
+    }
+
+    public static List<BooleanExpression> parse(NumberExpression path, JsonNode node, Integer defaultValue) {
+        List<BooleanExpression> result = new LinkedList<>();
+        if (node == null) {
+            if (defaultValue != null) {
+                result.add(path.eq(defaultValue));
+            }
+            return result;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (nodeType == JsonNodeType.STRING) {
+            result.add(path.eq(parseNumber(node)));
+        } else if (nodeType == JsonNodeType.NUMBER) {
+            result.add(path.eq(parseNumber(node)));
+        } else if (nodeType == JsonNodeType.ARRAY) {
+            ArrayNode arr = (ArrayNode) node;
+            result.add(path.in(parseNumberArr(arr)));
+        } else if (nodeType == JsonNodeType.OBJECT) {
+            if (node.has("$gt")) {
+                result.add(path.gt(parseNumber(node.get("$gt"))));
+            }
+            if (node.has("$gte")) {
+                result.add(path.goe(parseNumber(node.get("$gte"))));
+            }
+            if (node.has("$lt")) {
+                result.add(path.lt(parseNumber(node.get("$lt"))));
+            }
+            if (node.has("$lte")) {
+                result.add(path.loe(parseNumber(node.get("$lte"))));
+            }
+            if (node.has("$in")) {
+                ArrayNode arr = (ArrayNode) node.get("$in");
+                result.add(path.in(parseNumberArr(arr)));
+            }
+            if (node.has("$ne")) {
+                result.add(path.ne(parseNumber(node.get("$ne"))));
+            }
+            if (node.has("$null")) {
+                Boolean isNull = Boolean.valueOf(node.get("$null").asText());
+                if (isNull) {
+                    result.add(path.isNull());
+                } else {
+                    result.add(path.isNotNull());
+                }
+            }
+        }
+        return result;
+    }
+
+    private static Number parseNumber(JsonNode node) {
+        if (node instanceof IntNode) {
+            return node.asInt();
+        } else if (node instanceof LongNode) {
+            return node.asLong();
+        } else if (node instanceof DoubleNode) {
+            return node.doubleValue();
+        } else if (node instanceof TextNode) {
+            String n = node.asText();
+            if (n.indexOf(".") > -1) {
+                return node.asDouble();
+            } else {
+                return node.asLong();
+            }
+        }
+        return 0;
+    }
+
+    public static List<Number> parseNumberArr(ArrayNode arr) {
+        List<Number> values = new ArrayList<>(arr.size());
+        Iterator<JsonNode> elements = arr.elements();
+        while (elements.hasNext()) {
+            values.add(parseNumber(elements.next()));
+        }
+        return values;
+    }
+
+    public static List<BooleanExpression> parse(StringExpression path, JsonNode node) {
+        return parse(path, node, null);
+    }
+
+    public static List<BooleanExpression> parse(StringExpression path, JsonNode node, String defaultValue) {
+        List<BooleanExpression> result = new LinkedList<>();
+        if (node == null) {
+            if (defaultValue != null) {
+                result.add(path.eq(defaultValue));
+            }
+            return result;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (nodeType == JsonNodeType.STRING) {
+            result.add(path.eq(node.asText()));
+        } else if (nodeType == JsonNodeType.ARRAY) {
+            ArrayNode arr = (ArrayNode) node;
+            result.add(path.in(parseStringArr(arr)));
+        } else if (nodeType == JsonNodeType.OBJECT) {
+            if (node.has("$gt")) {
+                result.add(path.gt(node.get("$gt").asText()));
+            }
+            if (node.has("$gte")) {
+                result.add(path.goe(node.get("$gte").asText()));
+            }
+            if (node.has("$lt")) {
+                result.add(path.lt(node.get("$lt").asText()));
+            }
+            if (node.has("$lte")) {
+                result.add(path.loe(node.get("$lte").asText()));
+            }
+            if (node.has("$in")) {
+                ArrayNode arr = (ArrayNode) node.get("$in");
+                result.add(path.in(parseStringArr(arr)));
+            }
+            if (node.has("$ne")) {
+                result.add(path.ne(node.get("$ne").asText()));
+            }
+            if (node.has("$like")) {
+                result.add(path.like(node.get("$like").asText()));
+            }
+            if (node.has("$notLike")) {
+                result.add(path.notLike(node.get("$notLike").asText()));
+            }
+            if (node.has("$null")) {
+                Boolean isNull = Boolean.valueOf(node.get("$null").asText());
+                if (isNull) {
+                    result.add(path.isNull());
+                } else {
+                    result.add(path.isNotNull());
+                }
+            }
+        }
+        return result;
+    }
+
+    private static List<String> parseStringArr(ArrayNode arr) {
+        List<String> values = new ArrayList<>(arr.size());
+        Iterator<JsonNode> elements = arr.elements();
+        while (elements.hasNext()) {
+            values.add(elements.next().asText());
+        }
+        return values;
+    }
+
+    public static List<BooleanExpression> parse(DateTimeExpression path, JsonNode node) {
+        return parse(path, node, (Date) null);
+    }
+
+    /**
+     * @param path
+     * @param node
+     * @param time yyyyMMddHHmmss
+     * @return
+     */
+    public static List<BooleanExpression> parse(DateTimeExpression path, JsonNode node, String time) {
+        if (time != null) {
+            return parse(path, node, DateUtils.parse(time));
+        } else {
+            return parse(path, node, (Date) null);
+        }
+    }
+
+    public static List<BooleanExpression> parse(DateTimeExpression path, JsonNode node, Date time) {
+        List<BooleanExpression> result = new LinkedList<>();
+        if (node == null) {
+            if (time != null) {
+                result.add(path.eq(time));
+            }
+            return result;
+        }
+        SimpleDateFormat format = new SimpleDateFormat(DateUtils.PATTERN_yyyyMMddHHmmss);
+        JsonNodeType nodeType = node.getNodeType();
+        if (nodeType == JsonNodeType.STRING) {
+            try {
+                result.add(path.eq(format.parse(node.asText())));
+            } catch (ParseException e) {
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        } else if (nodeType == JsonNodeType.OBJECT) {
+            if (node.has("$gt")) {
+                result.add(path.gt(parse(format, node, "$gt")));
+            }
+            if (node.has("$gte")) {
+                result.add(path.goe(parse(format, node, "$gte")));
+            }
+            if (node.has("$lt")) {
+                result.add(path.lt(parse(format, node, "$lt")));
+            }
+            if (node.has("$lte")) {
+                result.add(path.loe(parse(format, node, "$lte")));
+            }
+            if (node.has("$null")) {
+                Boolean isNull = Boolean.valueOf(node.get("$null").asText());
+                if (isNull) {
+                    result.add(path.isNull());
+                } else {
+                    result.add(path.isNotNull());
+                }
+            }
+        }
+        return result;
+    }
+
+    private static Date parse(SimpleDateFormat format, JsonNode node, String name) {
+        try {
+            return format.parse(node.get(name).asText());
+        } catch (ParseException e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T extends Enum> List<BooleanExpression> parse(EnumExpression path, JsonNode node, Class<T> clazz) {
+        return parse(path, node, clazz, null);
+    }
+
+    public static <T extends Enum> List<BooleanExpression> parse(EnumExpression path, JsonNode node, Class<T> clazz, T defaultValue) {
+        List<BooleanExpression> result = new LinkedList<>();
+        if (node == null) {
+            if (defaultValue != null) {
+                result.add(path.eq(defaultValue));
+            }
+            return result;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (nodeType == JsonNodeType.STRING) {
+            result.add(path.eq(T.valueOf(clazz, node.asText())));
+        } else if (nodeType == JsonNodeType.ARRAY) {
+            ArrayNode arr = (ArrayNode) node;
+            result.add(path.in(parseEnumArr(arr, clazz)));
+        } else if (nodeType == JsonNodeType.OBJECT) {
+            ArrayNode arr = (ArrayNode) node.get("$in");
+            if (arr != null) {
+                result.add(path.in(parseEnumArr(arr, clazz)));
+            }
+        }
+        return result;
+    }
+
+    private static <T extends Enum> List parseEnumArr(ArrayNode arr, Class<T> clazz) {
+        List<Enum> values = new ArrayList<>(arr.size());
+        Iterator<JsonNode> elements = arr.elements();
+        while (elements.hasNext()) {
+            Enum anEnum = T.valueOf(clazz, elements.next().asText());
+            values.add(anEnum);
+        }
+        return values;
+    }
+}

+ 561 - 0
dmp-report/src/main/java/com/persagy/dmp/report/common/criteria/JacksonCriteria.java

@@ -0,0 +1,561 @@
+package com.persagy.dmp.report.common.criteria;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.common.date.DateUtils;
+import com.persagy.dmp.report.enumeration.CalculatedFunction;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-19
+ * @verison: 1.0
+ *
+ * <pre>
+ * {
+ *     "page": 1,
+ *     "size": 10,
+ *     "onlyCount": false,
+ *     "criteria": {
+ *         "name": "zhangsan",
+ *         "name": [ "zhangsan", "lisi" ],
+ *         "age": {
+ *             "$gt": 18,
+ *             "$lt": 35
+ *         },
+ *         "gender": {
+ *             "$null": false
+ *         }
+ *     },
+ *     "orders": [
+ *            {
+ *     		 	"column": "name",
+ *     		 	"asc": false
+ *            }
+ *     ],
+ *     "withColumns": [
+ *     		"name", "age"
+ *     ]
+ * }
+ * </pre>
+ */
+public class JacksonCriteria {
+
+    @Getter
+    @Setter
+    private Integer page;
+
+    @Getter
+    @Setter
+    private Integer size;
+
+    /**
+     * 是否只统计数量
+     */
+    @Getter
+    @Setter
+    private boolean onlyCount = false;
+
+    @Getter
+    @Setter
+    private boolean withoutCount = false;
+
+    @Getter
+    @Setter
+    private ObjectNode criteria;
+
+    @Getter
+    @Setter
+    private List<Order> orders;
+
+    @Getter
+    @Setter
+    private Set<String> withColumns;
+
+    @Getter
+    @Setter
+    private Set<String> groupbyColumns;
+
+    @Getter
+    @Setter
+    private List<Calculated> calculatedColumns;
+
+    public JacksonCriteria addCalculatedColumns(String column) {
+        return addCalculatedColumns(column, CalculatedFunction.SUM);
+    }
+
+    public JacksonCriteria addCalculatedColumns(String column, CalculatedFunction function) {
+        if (calculatedColumns == null) {
+            calculatedColumns = new LinkedList<>();
+        }
+        calculatedColumns.add(new Calculated(column, function));
+        return this;
+    }
+
+    public boolean groupbyColumn(String column) {
+        return groupbyColumns != null && groupbyColumns.contains(column);
+    }
+
+    public JacksonCriteria addGroupbyColumn(String column) {
+        if (groupbyColumns == null) {
+            groupbyColumns = new HashSet<>();
+        }
+        groupbyColumns.add(column);
+        return this;
+    }
+
+    public boolean withColumn(String column) {
+        return withColumns != null && withColumns.contains(column);
+    }
+
+    public JacksonCriteria addWithColumn(String column) {
+        if (withColumns == null) {
+            withColumns = new HashSet<>();
+        }
+        withColumns.add(column);
+        return this;
+    }
+
+    public JacksonCriteria addOrder(String column) {
+        return addOrder(column, true);
+    }
+
+    public JacksonCriteria addOrder(String column, boolean asc) {
+        if (orders == null) {
+            orders = new LinkedList<>();
+        }
+        orders.add(new Order(column, asc));
+        return this;
+    }
+
+    public JacksonCriteria setLimit(int page, int size) {
+        this.page = page;
+        this.size = size;
+        return this;
+    }
+
+    private JacksonCriteria() {
+        super();
+        this.criteria = JsonNodeFactory.instance.objectNode();
+    }
+
+    public static JacksonCriteria newInstance() {
+        return new JacksonCriteria();
+    }
+
+    public String getString(String nodeName) {
+        return getString(nodeName, null);
+    }
+
+    public String getString(String nodeName, String defaultValue) {
+        if (criteria.has(nodeName)) {
+            JsonNode node = criteria.get(nodeName);
+            return node.asText();
+        }
+        return defaultValue;
+    }
+
+    public Integer getInteger(String nodeName) {
+        return getInteger(nodeName, null);
+    }
+
+    public Integer getInteger(String nodeName, Integer defaultValue) {
+        if (criteria.has(nodeName)) {
+            JsonNode jsonNode = criteria.get(nodeName);
+            return Integer.valueOf(jsonNode.asText());
+        }
+        return defaultValue;
+    }
+
+    public Double getDouble(String nodeName) {
+        return getDouble(nodeName, null);
+    }
+
+    public Double getDouble(String nodeName, Double defaultValue) {
+        if (criteria.has(nodeName)) {
+            JsonNode jsonNode = criteria.get(nodeName);
+            return Double.valueOf(jsonNode.asText());
+        }
+        return defaultValue;
+    }
+
+    public Boolean getBoolean(String nodeName) {
+        return getBoolean(nodeName, null);
+    }
+
+    public Boolean getBoolean(String nodeName, Boolean defaultValue) {
+        if (criteria.has(nodeName)) {
+            JsonNode jsonNode = criteria.get(nodeName);
+            return Boolean.valueOf(jsonNode.asText());
+        }
+        return defaultValue;
+    }
+
+    /**
+     * 添加查询key,重复添加时后添加的会覆盖前面添加的
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public void add(String key, String value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, byte value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, short value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, int value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, long value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, float value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, double value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, BigDecimal value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, boolean value) {
+        criteria.put(key, value);
+    }
+
+    public void add(String key, byte[] value) {
+        criteria.put(key, value);
+    }
+
+    public <T> void add(String string, List<T> value) {
+        if (value != null) {
+            ArrayNode jsonNodes = criteria.putArray(string);
+            toArrayNode(jsonNodes, value);
+        }
+    }
+
+    public void add(String string, Enum value) {
+        if (value != null) {
+            criteria.put(string, value.name());
+        }
+    }
+
+    @JsonIgnore
+    private ObjectNode current;
+
+    /**
+     * 添加查询key,重复添加时后添加的会覆盖前面添加的
+     *
+     * @param key
+     * @return
+     */
+    public JacksonCriteria add(String key) {
+        current = criteria.putObject(key);
+        return this;
+    }
+
+    public JacksonCriteria isNull(boolean value) {
+        current.put("$null", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(byte value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(short value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(int value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(long value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(float value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(double value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(String value) {
+        current.put("$gt", value);
+        return this;
+    }
+
+    public JacksonCriteria gt(Date value) {
+        current.put("$gt", DateUtils.format(value));
+        return this;
+    }
+
+    public JacksonCriteria gte(byte value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(short value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(int value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(long value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(float value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(double value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(String value) {
+        current.put("$gte", value);
+        return this;
+    }
+
+    public JacksonCriteria gte(Date value) {
+        current.put("$gte", DateUtils.format(value));
+        return this;
+    }
+
+    public JacksonCriteria lt(byte value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(short value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(int value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(long value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(float value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(double value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(String value) {
+        current.put("$lt", value);
+        return this;
+    }
+
+    public JacksonCriteria lt(Date value) {
+        current.put("$lt", DateUtils.format(value));
+        return this;
+    }
+
+    public JacksonCriteria lte(byte value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(short value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(int value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(long value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(float value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(double value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(String value) {
+        current.put("$lte", value);
+        return this;
+    }
+
+    public JacksonCriteria lte(Date value) {
+        current.put("$lte", DateUtils.format(value));
+        return this;
+    }
+
+    public JacksonCriteria ne(byte value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(short value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(int value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(long value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(float value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(double value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(String value) {
+        current.put("$ne", value);
+        return this;
+    }
+
+    public JacksonCriteria ne(Date value) {
+        current.put("$ne", DateUtils.format(value));
+        return this;
+    }
+
+    public JacksonCriteria like(String value) {
+        current.put("$like", value);
+        return this;
+    }
+
+    public JacksonCriteria notLike(String value) {
+        current.put("$notLike", value);
+        return this;
+    }
+
+    public <T> JacksonCriteria in(List<T> value) {
+        if (value != null) {
+            ArrayNode inNode = current.putArray("$in");
+            toArrayNode(inNode, value);
+        }
+        return this;
+    }
+
+    private <T> void toArrayNode(ArrayNode arrayNode, List<T> value) {
+        value.forEach(o -> {
+            if (o instanceof String) {
+                arrayNode.add((String) o);
+            } else if (o instanceof Byte) {
+                arrayNode.add((Byte) o);
+            } else if (o instanceof Short) {
+                arrayNode.add((Short) o);
+            } else if (o instanceof Integer) {
+                arrayNode.add((Integer) o);
+            } else if (o instanceof Long) {
+                arrayNode.add((Long) o);
+            } else if (o instanceof Float) {
+                arrayNode.add((Float) o);
+            } else if (o instanceof Double) {
+                arrayNode.add((Double) o);
+            } else if (o instanceof Boolean) {
+                arrayNode.add((Boolean) o);
+            } else if (o instanceof byte[]) {
+                arrayNode.add((byte[]) o);
+            } else if (o instanceof Enum) {
+                arrayNode.add(((Enum) o).name());
+            }
+        });
+    }
+
+    @Data
+    public static class Order {
+        private String column;
+        private boolean asc = true;
+
+        public Order() {
+        }
+
+        public Order(String column) {
+            this.column = column;
+        }
+
+        public Order(String column, boolean asc) {
+            this.column = column;
+            this.asc = asc;
+        }
+    }
+
+    @Data
+    public static class Calculated {
+        private String column;
+        private CalculatedFunction function;
+        private Object value;
+
+        public Calculated() {
+        }
+
+        public Calculated(String column) {
+            this.column = column;
+        }
+
+        public Calculated(String column, CalculatedFunction function) {
+            this.column = column;
+            this.function = function;
+        }
+    }
+}

+ 304 - 0
dmp-report/src/main/java/com/persagy/dmp/report/common/json/JsonMapper.java

@@ -0,0 +1,304 @@
+package com.persagy.dmp.report.common.json;
+
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.JsonNodeType;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class JsonMapper {
+
+    private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
+
+    private static final ThreadLocal<JsonMapper> emptyMapper = new ThreadLocal<JsonMapper>();
+    private static final ThreadLocal<JsonMapper> defaultMapper = new ThreadLocal<JsonMapper>();
+
+    public static boolean isEmpty(final CharSequence cs) {
+        return cs == null || cs.length() == 0;
+    }
+
+    private ObjectMapper mapper;
+
+    @SuppressWarnings("unused")
+    private JsonMapper() {
+        this(null);
+    }
+
+    public JsonMapper(Include include) {
+        mapper = new ObjectMapper();
+        if (include != null) {
+            mapper.setSerializationInclusion(include);
+        }
+        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+    }
+
+    public static ObjectMapper nonEmptyObjectMapper() {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setSerializationInclusion(Include.NON_EMPTY);
+        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+        objectMapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+        return objectMapper;
+    }
+
+    public static JsonMapper nonEmptyMapper() {
+        JsonMapper jm = emptyMapper.get();
+        if (jm == null) {
+            jm = new JsonMapper(Include.NON_EMPTY);
+            emptyMapper.set(jm);
+        }
+        return jm;
+    }
+
+    public static JsonMapper nonDefaultMapper() {
+        JsonMapper jm = defaultMapper.get();
+        if (jm == null) {
+            jm = new JsonMapper(Include.NON_DEFAULT);
+            defaultMapper.set(jm);
+        }
+        return jm;
+    }
+
+    /**
+     * 简单调用
+     *
+     * @param object
+     * @return
+     */
+    public static String toSimpleJson(Object object) {
+        return JsonMapper.nonEmptyMapper().toJson(object);
+    }
+
+    public static <T> T fromJsonSimple(String jsonString, Class<T> clazz) {
+        return JsonMapper.nonDefaultMapper().fromJson(jsonString, clazz);
+    }
+
+    /**
+     * @param object
+     * @return
+     */
+    public String toJson(Object object) {
+
+        try {
+            return mapper.writeValueAsString(object);
+        } catch (IOException e) {
+            logger.warn("write to json string error:" + object, e);
+            return null;
+        }
+    }
+
+    /**
+     * @param jsonString
+     * @param clazz
+     * @return
+     */
+    public <T> T fromJson(String jsonString, Class<T> clazz) {
+        if (isEmpty(jsonString)) {
+            return null;
+        }
+
+        try {
+            return mapper.readValue(jsonString, clazz);
+        } catch (IOException e) {
+            logger.warn("parse json string error:" + jsonString, e);
+            return null;
+        }
+    }
+
+    /**
+     * @param jsonString
+     * @param javaType
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T fromJson(String jsonString, JavaType javaType) {
+        if (isEmpty(jsonString)) {
+            return null;
+        }
+
+        try {
+            return (T) mapper.readValue(jsonString, javaType);
+        } catch (IOException e) {
+            logger.warn("parse json string error:" + jsonString, e);
+            return null;
+        }
+    }
+
+    /**
+     * 构造Collection类型.
+     */
+    @SuppressWarnings("rawtypes")
+    public JavaType contructCollectionType(Class<? extends Collection> collectionClass, Class<?> elementClass) {
+        return mapper.getTypeFactory().constructCollectionType(collectionClass, elementClass);
+    }
+
+    /**
+     * 构造Map类型.
+     */
+    @SuppressWarnings("rawtypes")
+    public JavaType contructMapType(Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass) {
+        return mapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass);
+    }
+
+    /**
+     * 取出Mapper.
+     */
+    public static ObjectMapper getMapper() {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.setSerializationInclusion(Include.NON_EMPTY);
+        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+        return mapper;
+    }
+
+    public static String toFormatJson(Object object) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setSerializationInclusion(Include.NON_EMPTY);
+        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+
+        try {
+            return objectMapper.writeValueAsString(object);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static Map<String, Object> json2map(String str_json) {
+        Map<String, Object> res = null;
+        try {
+            Gson gson = new Gson();
+            res = gson.fromJson(str_json, new TypeToken<Map<String, Object>>() {
+            }.getType());
+        } catch (JsonSyntaxException e) {
+        }
+        return res;
+    }
+
+    public static List<Object> json2List(String str_json) {
+        List<Object> res = null;
+        try {
+            Gson gson = new Gson();
+            res = gson.fromJson(str_json, new TypeToken<List<Object>>() {
+            }.getType());
+        } catch (JsonSyntaxException e) {
+        }
+        return res;
+    }
+
+    public static Integer getInt(ObjectNode obj, String key) {
+        if (obj == null) {
+            return null;
+        }
+        JsonNode node = obj.get(key);
+        if (node == null) {
+            return null;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (node.isInt()) {
+            return node.asInt();
+        }
+        if (nodeType == JsonNodeType.NUMBER) {
+            return node.intValue();
+        } else {
+            String str = node.asText();
+            return Double.valueOf(str).intValue();
+        }
+    }
+
+    public static Integer getInt(ObjectNode obj, String key, Integer defaultValue) {
+        Integer result = getInt(obj, key);
+        return result == null ? defaultValue : result;
+
+    }
+
+    public static Double getDouble(ObjectNode obj, String key) {
+        if (obj == null) {
+            return null;
+        }
+        JsonNode node = obj.get(key);
+        if (node == null) {
+            return null;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (node.isDouble()) {
+            return node.asDouble();
+        }
+        if (nodeType == JsonNodeType.NUMBER) {
+            return node.doubleValue();
+        } else {
+            String str = node.asText();
+            return Double.valueOf(str);
+        }
+    }
+
+    public static Double getDouble(ObjectNode obj, String key, Double defaultValue) {
+        Double result = getDouble(obj, key);
+        return result == null ? defaultValue : result;
+    }
+
+    public static String getString(ObjectNode obj, String key) {
+        if (obj == null) {
+            return null;
+        }
+        JsonNode node = obj.get(key);
+        if (node == null) {
+            return null;
+        }
+        if (node.getNodeType() == JsonNodeType.STRING) {
+            return node.asText();
+        }
+        return node.toString();
+    }
+
+    public static String getString(ObjectNode obj, String key, String defaultValue) {
+        String result = getString(obj, key);
+        return result == null ? defaultValue : result;
+    }
+
+    public static ObjectNode getObject(ObjectNode obj, String key, String defaultValue) {
+        ObjectNode result = getObject(obj, key);
+        return result == null ? JsonMapper.fromJsonSimple(defaultValue, ObjectNode.class) : result;
+    }
+
+    public static ObjectNode getObject(ObjectNode obj, String key) {
+        if (obj == null) {
+            return null;
+        }
+        JsonNode node = obj.get(key);
+        if (node == null) {
+            return null;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (nodeType == JsonNodeType.OBJECT && node.isObject()) {
+            return (ObjectNode) node;
+        }
+        return null;
+    }
+
+    public static ArrayNode getArray(ObjectNode obj, String key) {
+        if (obj == null) {
+            return null;
+        }
+        JsonNode node = obj.get(key);
+        if (node == null) {
+            return null;
+        }
+        JsonNodeType nodeType = node.getNodeType();
+        if (nodeType == JsonNodeType.ARRAY && node.isArray()) {
+            return (ArrayNode) node;
+        }
+        return JsonNodeFactory.instance.arrayNode();
+    }
+}

+ 46 - 0
dmp-report/src/main/java/com/persagy/dmp/report/config/WebConfig.java

@@ -0,0 +1,46 @@
+package com.persagy.dmp.report.config;
+
+import com.persagy.common.json.JacksonMapper;
+import com.persagy.dmp.config.DmpParameterStorage;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-2
+ * @verison: 1.0
+ */
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+	@Bean
+	public DmpParameterStorage dmpParameterStorage() {
+		return new DmpParameterStorage();
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		// 设置拦截的路径、不拦截的路径、优先级等等
+		registry.addInterceptor(dmpParameterStorage()).addPathPatterns("/**");
+	}
+
+	@Bean
+	public HttpMessageConverters customConverters() {
+		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+		converter.setObjectMapper(JacksonMapper.nonEmptyMapper);
+		return new HttpMessageConverters(converter);
+	}
+
+	// JMS 使用
+	@Bean
+	public MessageConverter customMessageConvert() {
+		return new Jackson2JsonMessageConverter();
+	}
+
+}

+ 68 - 0
dmp-report/src/main/java/com/persagy/dmp/report/controller/DataExecutorController.java

@@ -0,0 +1,68 @@
+package com.persagy.dmp.report.controller;
+
+import com.persagy.common.date.DateUtils;
+import com.persagy.common.web.MapResponse;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.service.DataExecutorService;
+import com.persagy.dmp.report.service.ReportUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/report/data/executor")
+public class DataExecutorController {
+
+    @Autowired
+    DataExecutorService dataExecutorService;
+
+    @Autowired
+    ReportUtils reportUtils;
+
+    /**
+     * 生成对象信息统计报表
+     *
+     * @param startTime yyyyMMdd
+     * @param endTime   yyyyMMdd
+     */
+    @GetMapping("/rwdObject")
+    public MapResponse rwdObject(@RequestParam DateType dateType,
+                                 @RequestParam(required = false) String startTime,
+                                 @RequestParam(required = false) String endTime) throws Exception {
+        if (null == startTime && null == endTime) {
+            Map<String, Date> stringDateMap = reportUtils.getDateTime(dateType);
+            dataExecutorService.reportRwdObject(dateType, stringDateMap.get("startTimeDate"), stringDateMap.get("endTimeDate"));
+            return new MapResponse();
+        }
+        Date startTimeDate = DateUtils.parse(startTime);
+        Date endTimeDate = DateUtils.parse(endTime);
+        dataExecutorService.reportRwdObject(dateType, startTimeDate, endTimeDate);
+        return new MapResponse();
+    }
+
+    /**
+     * 生成报警信息统计报表
+     *
+     * @param startTime yyyyMMdd
+     * @param endTime   yyyyMMdd
+     */
+    @GetMapping("/alarmRecord")
+    public MapResponse alarmRecord(@RequestParam DateType dateType,
+                                   @RequestParam(required = false) String startTime,
+                                   @RequestParam(required = false) String endTime) throws Exception {
+        if (null == startTime && null == endTime) {
+            Map<String, Date> stringDateMap = reportUtils.getDateTime(dateType);
+            dataExecutorService.reportAlarmRecord(dateType, stringDateMap.get("startTimeDate"), stringDateMap.get("endTimeDate"));
+            return new MapResponse();
+        }
+        Date startTimeDate = DateUtils.parse(startTime);
+        Date endTimeDate = DateUtils.parse(endTime);
+        dataExecutorService.reportAlarmRecord(dateType, startTimeDate, endTimeDate);
+        return new MapResponse();
+    }
+}

+ 27 - 0
dmp-report/src/main/java/com/persagy/dmp/report/controller/InitDataController.java

@@ -0,0 +1,27 @@
+package com.persagy.dmp.report.controller;
+
+import com.persagy.common.web.MapResponse;
+import com.persagy.dmp.report.service.InitDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-29
+ * @verison: 1.0
+ */
+@RestController
+@RequestMapping("/report/init")
+public class InitDataController {
+
+    @Autowired
+    private InitDataService initService;
+
+    @GetMapping("/group")
+    public MapResponse initGroup(@RequestParam String createTime) {
+        return initService.initGroup(createTime);
+    }
+}

+ 23 - 0
dmp-report/src/main/java/com/persagy/dmp/report/controller/ReportController.java

@@ -0,0 +1,23 @@
+package com.persagy.dmp.report.controller;
+
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.service.ReportService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/report")
+public class ReportController {
+
+    @Autowired
+    private ReportService service;
+
+    @PostMapping("/query")
+    public PagedResponse query(@RequestParam DateType dateType, @RequestBody JacksonCriteria criteria) {
+        criteria.add("dateType", dateType);
+        return service.query(criteria);
+    }
+
+}

+ 18 - 0
dmp-report/src/main/java/com/persagy/dmp/report/entity/BaseEntity.java

@@ -0,0 +1,18 @@
+package com.persagy.dmp.report.entity;
+
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Transient;
+import java.io.Serializable;
+import java.util.List;
+
+
+@Setter
+@Getter
+public class BaseEntity implements Serializable {
+
+    @Transient
+    protected List<JacksonCriteria.Calculated> calculatedColumns;
+}

+ 61 - 0
dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportAlarmRecord.java

@@ -0,0 +1,61 @@
+package com.persagy.dmp.report.entity;
+
+import com.persagy.dmp.report.enumeration.DateType;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.*;
+
+@Setter
+@Getter
+@Entity
+@Table(name = "report_alarm_record")
+public class ReportAlarmRecord extends BaseEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+    private String itemCode;
+    private String projectId;
+    private String groupCode;
+    private String category;
+    private String classCode;
+    private String level;
+    private String alarmState;
+    private String year;
+    private String month;
+    private String day;
+    private String hour;
+    private String season;
+    private String week;
+    private String createTime;
+    private Long alarmRecordNum;
+    private Long alarmRecordNum2;
+    @Enumerated(value = EnumType.STRING)
+    private DateType dateType;
+
+    public ReportAlarmRecord() {
+
+    }
+
+    public ReportAlarmRecord(ReportAlarmRecord record) {
+        this.setId(record.getId());
+        this.setItemCode(record.getItemCode());
+        this.setProjectId(record.getProjectId());
+        this.setGroupCode(record.getGroupCode());
+        this.setCategory(record.getCategory());
+        this.setClassCode(record.getClassCode());
+        this.setLevel(record.getLevel());
+        this.setAlarmState(record.getAlarmState());
+        this.setYear(record.getYear());
+        this.setMonth(record.getMonth());
+        this.setDay(record.getDay());
+        this.setHour(record.getHour());
+        this.setSeason(record.getSeason());
+        this.setWeek(record.getWeek());
+        this.setCreateTime(record.getCreateTime());
+        this.setAlarmRecordNum(record.getAlarmRecordNum());
+        this.setAlarmRecordNum2(record.getAlarmRecordNum2());
+        this.setDateType(record.getDateType());
+    }
+}

+ 27 - 0
dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportConfig.java

@@ -0,0 +1,27 @@
+package com.persagy.dmp.report.entity;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.vladmihalcea.hibernate.type.json.JsonStringType;
+import lombok.Getter;
+import lombok.Setter;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
+
+import javax.persistence.*;
+
+@Setter
+@Getter
+@Entity
+@TypeDef(name = "json", typeClass = JsonStringType.class)
+@Table(name = "report_config")
+public class ReportConfig extends BaseEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private String calculated;
+    private String tableName;
+    private String mappingName;
+    private String groupColumn;
+    @Type(type = "json")
+    private ArrayNode tableGroup;
+}

+ 41 - 0
dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportConfigGroup.java

@@ -0,0 +1,41 @@
+package com.persagy.dmp.report.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Setter
+@Getter
+@Entity
+@Table(name = "report_config_group")
+public class ReportConfigGroup extends BaseEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private String conlumnName;
+    private String conlumnDesc;
+    private String method;
+    private String value;
+    private Integer valueType;
+    /**
+     * [{
+     * "conlumnName":"item_code,category",
+     * "valueList":[["1021","Sy"]]
+     * }]
+     */
+    @Transient
+    private List<Object[]> valueList;
+
+    public ReportConfigGroup() {
+    }
+
+    /**
+     * valueList,默认赋值
+     */
+    public ReportConfigGroup(String conlumnName, List<Object[]> valueList) {
+        this.conlumnName = conlumnName;
+        this.valueList = valueList;
+    }
+}

+ 53 - 0
dmp-report/src/main/java/com/persagy/dmp/report/entity/ReportRwdObject.java

@@ -0,0 +1,53 @@
+package com.persagy.dmp.report.entity;
+
+import com.persagy.dmp.report.enumeration.DateType;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.*;
+
+@Setter
+@Getter
+@Entity
+@Table(name = "report_rwd_object")
+public class ReportRwdObject extends BaseEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+    private String projectId;
+    private String groupCode;
+    private String objType;
+    private String classCode;
+    private String year;
+    private String month;
+    private String day;
+    private String hour;
+    private String season;
+    private String week;
+    private String createTime;
+    private Long rwdObjectNum;
+    @Enumerated(value = EnumType.STRING)
+    private DateType dateType;
+
+    public ReportRwdObject() {
+
+    }
+
+    public ReportRwdObject(ReportRwdObject rwdObject) {
+        this.id = rwdObject.id;
+        this.projectId = rwdObject.projectId;
+        this.groupCode = rwdObject.groupCode;
+        this.objType = rwdObject.objType;
+        this.classCode = rwdObject.classCode;
+        this.year = rwdObject.year;
+        this.month = rwdObject.month;
+        this.day = rwdObject.day;
+        this.hour = rwdObject.hour;
+        this.season = rwdObject.season;
+        this.week = rwdObject.week;
+        this.createTime = rwdObject.createTime;
+        this.rwdObjectNum = rwdObject.rwdObjectNum;
+        this.dateType = rwdObject.dateType;
+    }
+}

+ 29 - 0
dmp-report/src/main/java/com/persagy/dmp/report/enumeration/CalculatedFunction.java

@@ -0,0 +1,29 @@
+package com.persagy.dmp.report.enumeration;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-19
+ * @verison: 1.0
+ */
+public enum CalculatedFunction {
+	/**
+	 * 求和
+	 */
+	SUM,
+	/**
+	 * 求平均
+	 */
+	AVG,
+	/**
+	 * 求最大值
+	 */
+	MAX,
+	/**
+	 * 求最小值
+	 */
+	MIN,
+	/**
+	 * 求数量
+	 */
+	COUNT
+}

+ 65 - 0
dmp-report/src/main/java/com/persagy/dmp/report/enumeration/DateType.java

@@ -0,0 +1,65 @@
+package com.persagy.dmp.report.enumeration;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-19
+ * @verison: 1.0
+ */
+public enum DateType {
+    /**
+     * 年
+     */
+    YEAR("year"),
+    /**
+     * 月
+     */
+    MONTH("month"),
+    /**
+     * 日
+     */
+    DAY("day"),
+    /**
+     * 时
+     */
+    HOUR("hour"),
+
+    /**
+     * 周
+     */
+    WEEK("week"),
+
+    /**
+     * 季度 1:0101-0401,2:0401-0701,3:0701-1001,4: 1001-0101  (日期前闭后开)
+     */
+    SEASON("season");
+
+    private String code;
+
+    DateType(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public static DateType getByCode(String code) {
+        for (DateType value : DateType.values()) {
+            if(value.getCode().equals(code)){
+                return value;
+            }
+        }
+        return null;
+    }
+
+    public static Set<String> getAllCode() {
+        Set<String> set = new HashSet<>();
+        for (DateType value : DateType.values()) {
+            set.add(value.getCode());
+        }
+        return set;
+    }
+}

+ 26 - 0
dmp-report/src/main/java/com/persagy/dmp/report/enumeration/EnumReportMessageType.java

@@ -0,0 +1,26 @@
+package com.persagy.dmp.report.enumeration;
+
+import lombok.Getter;
+
+/**
+ * @description: 统计报表
+ * @author: fengyanjie
+ * @company: Persagy Technology Co.,Ltd
+ * @since: 2020/10/22 5:08 下午
+ * @version: V1.0
+ **/
+public enum EnumReportMessageType {
+    REPORT_RWD_OBJECT_CREATE("reportRwdObjectCreate", "生成报警信息统计报表"),
+    ALARM_RECORD_CREATE("alarmRecordCreate", "新增报警"),
+    RWD_OBJECT_CREATE("instanceObjectCreate", "新增对象");
+
+    @Getter
+    private String value;
+    @Getter
+    private String desc;
+
+    EnumReportMessageType(String value, String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+}

+ 32 - 0
dmp-report/src/main/java/com/persagy/dmp/report/feign/TaskClient.java

@@ -0,0 +1,32 @@
+package com.persagy.dmp.report.feign;
+
+import com.persagy.common.criteria.JacksonCriteria;
+import com.persagy.common.web.MapResponse;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.model.TaskCfgModel;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-25
+ * @verison: 1.0
+ */
+@FeignClient(name = "dmp-task")
+public interface TaskClient {
+
+    @PostMapping("/task/record/receive")
+    MapResponse sendTaskToRmq(@RequestParam(name = "groupCode") String groupCode,
+                              @RequestParam(name = "schemaId") String schemaId,
+                              @RequestParam(name = "projectId") String projectId,
+                              @RequestParam(name = "appId") String appId,
+                              @RequestParam(name = "userId") String userId,
+                              @RequestBody List<String> taskIds);
+
+    @PostMapping("/task/cfg/query")
+    PagedResponse<TaskCfgModel> query(@RequestBody JacksonCriteria criteria);
+}

+ 72 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/JmsConfig.java

@@ -0,0 +1,72 @@
+package com.persagy.dmp.report.jms;
+
+import com.persagy.common.json.JacksonMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Map;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-10
+ * @verison: 1.0
+ */
+@Slf4j
+@Configuration
+public class JmsConfig {
+
+
+    @Value("${dmp.report.exchange}")
+    private String exchange;
+
+    @Value("${dmp.report.routingKey}")
+    private String reportRoutingKey;
+
+    private String alarmRoutingKey = "routing-dmp-alarm";
+    private String rwdRoutingKey = "routing-dmp-rwd";
+
+    @Value("${dmp.report.queue}")
+    private String reportQueue;
+
+    @Autowired
+    private MessageProcesser messageProcesser;
+
+    @Bean
+    public TopicExchange exchange() {
+        return new TopicExchange(exchange);
+    }
+
+    @Bean
+    public Queue queue() {
+        return new Queue(reportQueue, true);
+    }
+
+    @Bean
+    public Binding reportBinding() {
+        return BindingBuilder.bind(queue()).to(exchange()).with(reportRoutingKey);
+    }
+
+    @Bean
+    public Binding alarmBinding() {
+        return BindingBuilder.bind(queue()).to(exchange()).with(alarmRoutingKey);
+    }
+
+    @Bean
+    public Binding rwdBinding() {
+        return BindingBuilder.bind(queue()).to(exchange()).with(rwdRoutingKey);
+    }
+
+    @RabbitListener(queues = "${dmp.report.queue}")    //监听器监听指定的Queue
+    public void processC(Map<String, Object> message) {
+        log.info("============================== Receive:" + JacksonMapper.toSimpleJson(message));
+        messageProcesser.listen(message);
+    }
+}

+ 14 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/MessageExecutor.java

@@ -0,0 +1,14 @@
+package com.persagy.dmp.report.jms;
+
+import java.util.Map;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-10
+ * @verison: 1.0
+ */
+public interface MessageExecutor {
+
+    void execute(Map<String, Object> message);
+
+}

+ 88 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/MessageProcesser.java

@@ -0,0 +1,88 @@
+package com.persagy.dmp.report.jms;
+
+import com.persagy.common.json.JacksonMapper;
+import com.persagy.dmp.common.SpringUtils;
+import com.persagy.dmp.config.DmpParameterStorage;
+import com.persagy.dmp.report.enumeration.EnumReportMessageType;
+import com.persagy.dmp.rwd.model.DmpMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-10
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class MessageProcesser {
+
+    @Value("${dmp.report.exchange}")
+    private String exchange;
+
+    @Value("${dmp.report.routingKey}")
+    private String reportRoutingKey;
+
+    @Autowired
+    private RabbitTemplate rabbitTemplate;
+
+    public void convertAndSend(DmpMessage message) {
+        log.info("向rabbitMQ发送消息,message:" + JacksonMapper.toSimpleJson(message));
+        rabbitTemplate.convertAndSend(exchange, reportRoutingKey, message);
+    }
+
+    private static final Set<String> beanNames = new HashSet<>();
+
+    static {
+        beanNames.add(EnumReportMessageType.REPORT_RWD_OBJECT_CREATE.getValue());
+        beanNames.add(EnumReportMessageType.ALARM_RECORD_CREATE.getValue());
+        beanNames.add(EnumReportMessageType.RWD_OBJECT_CREATE.getValue());
+    }
+
+    public void listen(Map<String, Object> message) {
+        String type = "";
+        if (null != MapUtils.getString(message, "type")) {
+            type = MapUtils.getString(message, "type");
+        } else {
+            type = MapUtils.getString(message, "beanName");
+        }
+        if (!beanNames.contains(type)) {
+            return;
+        }
+
+        String executorName = type + "Executor";
+
+        MessageExecutor executor = null;
+        try {
+            executor = SpringUtils.getBean(executorName, MessageExecutor.class);
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+        if (executor == null) {
+            log.error("bean for [" + executorName + "] not exists");
+        }
+
+        try {
+            DmpParameterStorage.ParameterData data = new DmpParameterStorage.ParameterData();
+            data.setGroupCode(MapUtils.getString(message, "groupCode"));
+            data.setProjectId(MapUtils.getString(message, "userId"));
+            data.setAppId(MapUtils.getString(message, "appId"));
+            DmpParameterStorage.set(data);
+
+            executor.execute(message);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            DmpParameterStorage.clear();
+        }
+    }
+
+}

+ 115 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/AlarmRecordCreateExecutor.java

@@ -0,0 +1,115 @@
+package com.persagy.dmp.report.jms.executor;
+
+import com.persagy.common.date.DateUtils;
+import com.persagy.dmp.report.common.json.JsonMapper;
+import com.persagy.dmp.report.entity.QReportAlarmRecord;
+import com.persagy.dmp.report.entity.ReportAlarmRecord;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.jms.MessageExecutor;
+import com.persagy.dmp.report.repository.ReportAlarmRecordRepository;
+import com.persagy.dmp.report.service.ReportUtils;
+import com.querydsl.core.types.dsl.BooleanExpression;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author: Fengyanjie
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class AlarmRecordCreateExecutor implements MessageExecutor {
+
+    @Autowired
+    private ReportAlarmRecordRepository reportAlarmRecordRepository;
+
+    @Autowired
+    private ReportUtils reportUtils;
+
+    @Override
+    public void execute(Map<String, Object> message) {
+        Map<String, Object> exts = JsonMapper.json2map(message.get("exts").toString());
+        Map<String, Object> obj = JsonMapper.json2map(exts.get("obj").toString());
+
+        String itemCode = MapUtils.getLong(obj, "itemCode") + "";
+        String projectId = MapUtils.getString(obj, "projectId");
+        String groupCode = MapUtils.getString(obj, "groupCode");
+        String category = MapUtils.getString(obj, "category");
+        String classCode = MapUtils.getString(obj, "classCode");
+        String level = MapUtils.getString(obj, "level");
+        String alarmState = MapUtils.getInteger(obj, "state") + "";
+        Long time = MapUtils.getLong(obj, "createTime");
+        Date createTime = new Date(time);
+        String year = DateUtils.format(createTime, DateUtils.PATTERN_yyyy);
+        String month = DateUtils.format(createTime, DateUtils.PATTERN_yyyyMM);
+        String day = DateUtils.format(createTime, DateUtils.PATTERN_yyyyMMdd);
+        String hour = DateUtils.format(createTime, "yyyyMMddHH");
+
+        QReportAlarmRecord qt = QReportAlarmRecord.reportAlarmRecord;
+        BooleanExpression ex = qt.itemCode.eq(itemCode).and(qt.projectId.eq(projectId)).and(qt.groupCode.eq(groupCode)).and(qt.category.eq(category))
+                .and(qt.classCode.eq(classCode)).and(qt.level.eq(level)).and(qt.alarmState.eq(alarmState)).and(qt.createTime.like(year + "%"));
+        Iterable<ReportAlarmRecord> all = reportAlarmRecordRepository.findAll(ex);
+        List<ReportAlarmRecord> data = new ArrayList<>();
+        all.forEach(data::add);
+        if (0 == data.size()) {
+            ReportAlarmRecord yearEntity = new ReportAlarmRecord();
+            yearEntity.setItemCode(itemCode);
+            yearEntity.setProjectId(projectId);
+            yearEntity.setGroupCode(groupCode);
+            yearEntity.setCategory(category);
+            yearEntity.setClassCode(classCode);
+            yearEntity.setLevel(level);
+            yearEntity.setAlarmState(alarmState);
+            yearEntity.setAlarmRecordNum(1L);
+            yearEntity.setYear(year);
+            yearEntity.setCreateTime(year);
+            yearEntity.setDateType(DateType.YEAR);
+            data.add(yearEntity);
+            ReportAlarmRecord monthEntity = new ReportAlarmRecord(yearEntity);
+            monthEntity.setMonth(month.substring(month.length() - 2));
+            monthEntity.setCreateTime(month);
+            monthEntity.setDateType(DateType.MONTH);
+            data.add(monthEntity);
+            ReportAlarmRecord dayEntity = new ReportAlarmRecord(monthEntity);
+            dayEntity.setDay(day.substring(day.length() - 2));
+            dayEntity.setCreateTime(day);
+            dayEntity.setDateType(DateType.DAY);
+            data.add(dayEntity);
+            ReportAlarmRecord hourEntity = new ReportAlarmRecord(dayEntity);
+            hourEntity.setHour(hour.substring(hour.length() - 2));
+            hourEntity.setCreateTime(hour);
+            hourEntity.setDateType(DateType.HOUR);
+            data.add(hourEntity);
+            reportAlarmRecordRepository.saveAll(data);
+            return;
+        }
+        for (ReportAlarmRecord datum : data) {
+            if (year.equals(datum.getCreateTime())) {
+                Long alarmRecordNum = datum.getAlarmRecordNum();
+                datum.setAlarmRecordNum((alarmRecordNum += 1));
+            }
+            if (month.equals(datum.getCreateTime())) {
+                Long alarmRecordNum = datum.getAlarmRecordNum();
+                datum.setAlarmRecordNum((alarmRecordNum += 1));
+            }
+            if (day.equals(datum.getCreateTime())) {
+                Long alarmRecordNum = datum.getAlarmRecordNum();
+                datum.setAlarmRecordNum((alarmRecordNum += 1));
+            }
+            if (hour.equals(datum.getCreateTime())) {
+                Long alarmRecordNum = datum.getAlarmRecordNum();
+                datum.setAlarmRecordNum((alarmRecordNum += 1));
+            }
+        }
+
+        reportAlarmRecordRepository.saveAll(data);
+    }
+}

+ 31 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/CreateTableExecutor.java

@@ -0,0 +1,31 @@
+package com.persagy.dmp.report.jms.executor;
+
+import com.persagy.common.json.JacksonMapper;
+import com.persagy.dmp.report.jms.MessageExecutor;
+import com.persagy.dmp.report.service.InitDataService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @author: yaoll
+ * @date: 2020-10-28
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class CreateTableExecutor implements MessageExecutor {
+
+	@Autowired
+	private InitDataService initService;
+
+	@Override
+	public void execute(Map<String, Object> message) {
+		log.info("group create : {}", JacksonMapper.toSimpleJson(message));
+		String createTime = MapUtils.getString(message, "createTime");
+		initService.initGroup(createTime);
+	}
+}

+ 100 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/InstanceObjectCreateExecutor.java

@@ -0,0 +1,100 @@
+package com.persagy.dmp.report.jms.executor;
+
+import com.persagy.dmp.report.entity.QReportRwdObject;
+import com.persagy.dmp.report.entity.ReportRwdObject;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.jms.MessageExecutor;
+import com.persagy.dmp.report.repository.ReportObjectRepository;
+import com.persagy.dmp.report.service.ReportUtils;
+import com.querydsl.core.types.dsl.BooleanExpression;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author: Fengyanjie
+ * @date: 2020-10-23
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class InstanceObjectCreateExecutor implements MessageExecutor {
+
+    @Autowired
+    private ReportObjectRepository reportObjectRepository;
+
+    @Autowired
+    private ReportUtils reportUtils;
+
+    @Override
+    public void execute(Map<String, Object> message) {
+        String projectId = MapUtils.getString(message, "projectId");
+        String groupCode = MapUtils.getString(message, "groupCode");
+        String objType = MapUtils.getString(message, "str1");
+        String classCode = MapUtils.getString(message, "str2");
+        String sendTime = MapUtils.getString(message, "sendTime");
+
+        String year = sendTime.substring(0, 4);
+        String month = sendTime.substring(0, 6);
+        String day = sendTime.substring(0, 8);
+        String hour = sendTime.substring(0, 10);
+
+        QReportRwdObject qt = QReportRwdObject.reportRwdObject;
+        BooleanExpression ex = qt.projectId.eq(projectId).and(qt.groupCode.eq(groupCode)).and(qt.objType.eq(objType)).and(qt.classCode.eq(classCode)).and(qt.createTime.like(year + "%"));
+        Iterable<ReportRwdObject> all = reportObjectRepository.findAll(ex);
+        List<ReportRwdObject> data = new ArrayList<>();
+        all.forEach(data::add);
+        if (0 == data.size()) {
+            ReportRwdObject yearEntity = new ReportRwdObject();
+            yearEntity.setProjectId(projectId);
+            yearEntity.setGroupCode(groupCode);
+            yearEntity.setObjType(objType);
+            yearEntity.setClassCode(classCode);
+            yearEntity.setYear(year);
+            yearEntity.setCreateTime(year);
+            yearEntity.setDateType(DateType.YEAR);
+            data.add(yearEntity);
+            ReportRwdObject monthEntity = new ReportRwdObject(yearEntity);
+            monthEntity.setMonth(month.substring(month.length() - 2));
+            monthEntity.setCreateTime(month);
+            monthEntity.setDateType(DateType.MONTH);
+            data.add(monthEntity);
+            ReportRwdObject dayEntity = new ReportRwdObject(monthEntity);
+            dayEntity.setDay(day.substring(day.length() - 2));
+            dayEntity.setCreateTime(day);
+            dayEntity.setDateType(DateType.DAY);
+            data.add(dayEntity);
+            ReportRwdObject hourEntity = new ReportRwdObject(dayEntity);
+            hourEntity.setHour(hour.substring(hour.length() - 2));
+            hourEntity.setCreateTime(hour);
+            hourEntity.setDateType(DateType.HOUR);
+            data.add(hourEntity);
+            reportObjectRepository.saveAll(data);
+            return;
+        }
+        for (ReportRwdObject datum : data) {
+            if (year.equals(datum.getCreateTime())) {
+                Long rwdObjectNum = datum.getRwdObjectNum();
+                datum.setRwdObjectNum((rwdObjectNum += 1));
+            }
+            if (month.equals(datum.getCreateTime())) {
+                Long rwdObjectNum = datum.getRwdObjectNum();
+                datum.setRwdObjectNum((rwdObjectNum += 1));
+            }
+            if (day.equals(datum.getCreateTime())) {
+                Long rwdObjectNum = datum.getRwdObjectNum();
+                datum.setRwdObjectNum((rwdObjectNum += 1));
+            }
+            if (hour.equals(datum.getCreateTime())) {
+                Long rwdObjectNum = datum.getRwdObjectNum();
+                datum.setRwdObjectNum((rwdObjectNum += 1));
+            }
+        }
+        reportObjectRepository.saveAll(data);
+    }
+}

+ 68 - 0
dmp-report/src/main/java/com/persagy/dmp/report/jms/executor/ReportRwdObjectCreateExecutor.java

@@ -0,0 +1,68 @@
+package com.persagy.dmp.report.jms.executor;
+
+import com.persagy.common.criteria.JacksonCriteria;
+import com.persagy.common.json.JacksonMapper;
+import com.persagy.common.web.MapResponse;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.json.JsonMapper;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.feign.TaskClient;
+import com.persagy.dmp.report.jms.MessageExecutor;
+import com.persagy.dmp.report.model.TaskCfgModel;
+import com.persagy.dmp.report.service.DataExecutorService;
+import com.persagy.dmp.report.service.ReportUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @author: fengyanjie
+ * @date: 2020-11-25
+ * @verison: 1.0
+ */
+@Slf4j
+@Component
+public class ReportRwdObjectCreateExecutor implements MessageExecutor {
+    @Autowired
+    private DataExecutorService dataExecutorService;
+
+    @Autowired
+    ReportUtils reportUtils;
+
+    @Override
+    public void execute(Map<String, Object> message) {
+        Map<String, Object> params = JsonMapper.json2map(message.get("params").toString());
+        log.info("reportRwdObjectCreate : {}", JacksonMapper.toSimpleJson(params));
+        DateType dateType = DateType.getByCode(params.get("dateType").toString());
+        if (StringUtils.isEmpty(dateType)) {
+            log.error("reportRwdObjectCreate消息中缺少dateType信息");
+            return;
+        }
+
+        Map<String, Date> stringDateMap = reportUtils.getDateTime(dateType);
+        try {
+            dataExecutorService.reportRwdObject(dateType, stringDateMap.get("startTimeDate"), stringDateMap.get("endTimeDate"));
+            dataExecutorService.reportAlarmRecord(dateType, stringDateMap.get("startTimeDate"), stringDateMap.get("endTimeDate"));
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+    }
+
+    @Autowired
+    private TaskClient taskClient;
+
+    //    @Scheduled(cron = "0/10 * * * * ?")
+    public void test() {
+        JacksonCriteria criteria = JacksonCriteria.newInstance();
+        criteria.add("id", "2e25858a-2eea-11eb-a703-0242ac110002");
+        PagedResponse<TaskCfgModel> query = taskClient.query(criteria);
+        TaskCfgModel taskCfgModel = query.getData().get(0);
+        MapResponse response = taskClient.sendTaskToRmq("a", "a", "a", "a", "a", Arrays.asList(taskCfgModel.getId()));
+        System.out.println();
+    }
+}

+ 30 - 0
dmp-report/src/main/java/com/persagy/dmp/report/model/TaskCfgModel.java

@@ -0,0 +1,30 @@
+package com.persagy.dmp.report.model;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Setter
+@Getter
+public class TaskCfgModel {
+
+	private String id;
+	private String groupCode;
+	private String appId;
+	private String projectId;
+	private String code;
+	private String name;
+	private String type;
+	private ObjectNode config;
+	private ObjectNode params;
+	private ObjectNode timeRule;
+	private Date startTime;
+	private Date endTime;
+	private Integer responseTime;
+	private String level;
+	private Integer status;
+	private String remark;
+
+}

+ 20 - 0
dmp-report/src/main/java/com/persagy/dmp/report/model/TaskRecordModel.java

@@ -0,0 +1,20 @@
+package com.persagy.dmp.report.model;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Setter
+@Getter
+public class TaskRecordModel {
+
+	private String id;
+	private String taskId;
+	private Date startTime;
+	private Date endTime;
+	private Integer success;
+	private ObjectNode errorInfo;
+
+}

+ 15 - 0
dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportAlarmRecordRepository.java

@@ -0,0 +1,15 @@
+package com.persagy.dmp.report.repository;
+
+import com.persagy.dmp.report.entity.ReportAlarmRecord;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+public interface ReportAlarmRecordRepository extends JpaRepository<ReportAlarmRecord, Integer>, QuerydslPredicateExecutor<ReportAlarmRecord> {
+
+    @Modifying
+    @Query(value = "delete from report_alarm_record where date_Type = ?1 and create_time >= ?2 and create_time < ?3", nativeQuery = true)
+    void deleteDateType(String dateType, String start, String end);
+}
+

+ 9 - 0
dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportConfigGroupRepository.java

@@ -0,0 +1,9 @@
+package com.persagy.dmp.report.repository;
+
+import com.persagy.dmp.report.entity.ReportConfigGroup;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+public interface ReportConfigGroupRepository extends JpaRepository<ReportConfigGroup, Integer>, QuerydslPredicateExecutor<ReportConfigGroup> {
+}
+

+ 9 - 0
dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportConfigRepository.java

@@ -0,0 +1,9 @@
+package com.persagy.dmp.report.repository;
+
+import com.persagy.dmp.report.entity.ReportConfig;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+public interface ReportConfigRepository extends JpaRepository<ReportConfig, Integer>, QuerydslPredicateExecutor<ReportConfig> {
+}
+

+ 16 - 0
dmp-report/src/main/java/com/persagy/dmp/report/repository/ReportObjectRepository.java

@@ -0,0 +1,16 @@
+package com.persagy.dmp.report.repository;
+
+import com.persagy.dmp.report.entity.ReportRwdObject;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+public interface ReportObjectRepository extends JpaRepository<ReportRwdObject, Integer>, QuerydslPredicateExecutor<ReportRwdObject> {
+
+    @Modifying
+    @Query(value = "delete from report_rwd_object where date_Type = ?1 and create_time >= ?2 and create_time < ?3", nativeQuery = true)
+    void deleteDateType(String dateType, String start, String end);
+
+}
+

+ 17 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/BaseService.java

@@ -0,0 +1,17 @@
+package com.persagy.dmp.report.service;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.entity.BaseEntity;
+import com.querydsl.core.Tuple;
+import com.querydsl.core.types.dsl.BooleanExpression;
+
+import java.util.List;
+
+public interface BaseService {
+
+    List<BooleanExpression> parse(ObjectNode criteria);
+
+    List<BaseEntity> getData(PagedResponse<Tuple> tuplePagedResponse, List<JacksonCriteria.Calculated> calculatedList);
+}

+ 147 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/DataExecutorService.java

@@ -0,0 +1,147 @@
+package com.persagy.dmp.report.service;
+
+import com.persagy.common.criteria.JpaUtils;
+import com.persagy.dmp.config.DmpParameterStorage;
+import com.persagy.dmp.report.common.json.JsonMapper;
+import com.persagy.dmp.report.entity.*;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.repository.ReportAlarmRecordRepository;
+import com.persagy.dmp.report.repository.ReportObjectRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author fengyanjie
+ */
+@Slf4j
+@Service
+public class DataExecutorService {
+    @Autowired
+    private ReportObjectRepository reportObjectRepository;
+
+    @Autowired
+    private ReportAlarmRecordRepository reportAlarmRecordRepository;
+
+    @Autowired
+    private ReportUtils reportUtils;
+
+    @Autowired
+    private JpaUtils jpaUtils;
+
+    @Transactional
+    public void reportRwdObject(DateType dateType, Date startTime, Date endTime) throws Exception {
+        String groupCode = DmpParameterStorage.getGroupCode();
+        String projectId = DmpParameterStorage.getProjectId();
+        String tableName = "rwd_object";
+        String sql = "";
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append("        select project_id,group_code,obj_type,class_code,'" + dateType + "' as date_type,          \n");
+        reportUtils.appendSql(sqlBuilder, dateType);
+        sqlBuilder.append("        count(0) rwd_object_num from dmp_rwd." + tableName + "_" + groupCode + "_" + projectId + "          \n");
+        sqlBuilder.append("        where create_time >= ? and create_time < ?          \n");
+        sqlBuilder.append("          and project_id = ? and group_code = ?          \n");
+        sqlBuilder.append("         group by project_id,group_code,obj_type,class_code,date_type,year,month,day,hour,season,date          \n");
+        sql = sqlBuilder.toString();
+        //TODO 返回字段值为null报错
+        List<Map<String, Object>> list = jpaUtils.queryList(sql, startTime, endTime, projectId, groupCode);
+        List<BaseEntity> data = new ArrayList<>();
+        list.forEach(item -> {
+            ReportRwdObject reportRwdObject = new ReportRwdObject();
+            String year = MapUtils.getString(item, "year");
+            String month = MapUtils.getString(item, "month");
+            String day = MapUtils.getString(item, "day");
+            String hour = MapUtils.getString(item, "hour");
+            String season = MapUtils.getString(item, "season");
+            reportRwdObject.setYear(year.equals("null") ? null : year);
+            reportRwdObject.setDay(day.equals("null") ? null : day);
+            reportRwdObject.setMonth(month.equals("null") ? null : month);
+            reportRwdObject.setHour(hour.equals("null") ? null : hour);
+            reportRwdObject.setSeason(season.equals("null") ? null : season);
+            reportRwdObject.setProjectId(MapUtils.getString(item, "project_id"));
+            reportRwdObject.setGroupCode(MapUtils.getString(item, "group_code"));
+            reportRwdObject.setObjType(MapUtils.getString(item, "obj_type"));
+            reportRwdObject.setClassCode(MapUtils.getString(item, "class_code"));
+            reportRwdObject.setCreateTime(MapUtils.getString(item, "date"));
+            reportRwdObject.setRwdObjectNum(MapUtils.getLong(item, "rwd_object_num"));
+            reportRwdObject.setDateType(DateType.valueOf(MapUtils.getString(item, "date_type")));
+            data.add(reportRwdObject);
+        });
+        ReportConfig reportConfig = reportUtils.queryReportConfig(tableName);
+        List<Object> tableGroup = JsonMapper.json2List(JsonMapper.toSimpleJson(reportConfig.getTableGroup()));
+        List<ReportConfigGroup> groupList = reportUtils.getGroupList(tableGroup, dateType, startTime, endTime);
+        List<BaseEntity> resultList = reportUtils.initData(0, groupList, ReportRwdObject.class, new ArrayList<>());
+        List<BaseEntity> result = reportUtils.addList(data, resultList, reportConfig.getCalculatedColumns());
+
+        Map<String, String> map = reportUtils.getDate(dateType, startTime, endTime);
+        String start = map.get("start");
+        String end = map.get("end");
+        reportObjectRepository.deleteDateType(dateType.name(), start, end);
+        List<ReportRwdObject> save = new ArrayList<>();
+        result.forEach(item -> save.add((ReportRwdObject) item));
+        reportObjectRepository.saveAll(save);
+    }
+
+    @Transactional
+    public void reportAlarmRecord(DateType dateType, Date startTime, Date endTime) throws Exception {
+        String groupCode = DmpParameterStorage.getGroupCode();
+        String projectId = DmpParameterStorage.getProjectId();
+        String tableName = "alarm_record";
+        String sql = "";
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append("        select item_code,project_id,group_code,category,class_code,level,state,'" + dateType + "' as date_type,          \n");
+        reportUtils.appendSql(sqlBuilder, dateType);
+        sqlBuilder.append("        count(0) alarm_record_num from dmp_alarm." + tableName + "           \n");
+        sqlBuilder.append("        where create_time >= ? and create_time < ?          \n");
+        sqlBuilder.append("          and project_id = ? and group_code = ?          \n");
+        sqlBuilder.append("         group by item_code,project_id,group_code,category,class_code,level,state,date_type,year,month,day,hour,season,date          \n");
+        sql = sqlBuilder.toString();
+
+        List<Map<String, Object>> list = jpaUtils.queryList(sql, startTime, endTime, projectId, groupCode);
+        List<BaseEntity> data = new ArrayList<>();
+        list.forEach(item -> {
+            ReportAlarmRecord reportAlarmRecord = new ReportAlarmRecord();
+            String year = MapUtils.getString(item, "year");
+            String month = MapUtils.getString(item, "month");
+            String day = MapUtils.getString(item, "day");
+            String hour = MapUtils.getString(item, "hour");
+            String season = MapUtils.getString(item, "season");
+            reportAlarmRecord.setYear(year.equals("null") ? null : year);
+            reportAlarmRecord.setDay(day.equals("null") ? null : day);
+            reportAlarmRecord.setMonth(month.equals("null") ? null : month);
+            reportAlarmRecord.setHour(hour.equals("null") ? null : hour);
+            reportAlarmRecord.setSeason(season.equals("null") ? null : season);
+            reportAlarmRecord.setItemCode(MapUtils.getString(item, "item_code"));
+            reportAlarmRecord.setProjectId(MapUtils.getString(item, "project_id"));
+            reportAlarmRecord.setGroupCode(MapUtils.getString(item, "group_code"));
+            reportAlarmRecord.setCategory(MapUtils.getString(item, "category"));
+            reportAlarmRecord.setClassCode(MapUtils.getString(item, "class_code"));
+            reportAlarmRecord.setLevel(MapUtils.getString(item, "level"));
+            reportAlarmRecord.setAlarmState(MapUtils.getString(item, "state"));
+            reportAlarmRecord.setCreateTime(MapUtils.getString(item, "date"));
+            reportAlarmRecord.setAlarmRecordNum(MapUtils.getLong(item, "alarm_record_num"));
+            reportAlarmRecord.setDateType(DateType.valueOf(MapUtils.getString(item, "date_type")));
+            data.add(reportAlarmRecord);
+        });
+        ReportConfig reportConfig = reportUtils.queryReportConfig(tableName);
+        List<Object> tableGroup = JsonMapper.json2List(JsonMapper.toSimpleJson(reportConfig.getTableGroup()));
+        List<ReportConfigGroup> groupList = reportUtils.getGroupList(tableGroup, dateType, startTime, endTime);
+        List<BaseEntity> resultList = reportUtils.initData(0, groupList, ReportAlarmRecord.class, new ArrayList<>());
+        List<BaseEntity> result = reportUtils.addList(data, resultList, reportConfig.getCalculatedColumns());
+
+        Map<String, String> map = reportUtils.getDate(dateType, startTime, endTime);
+        String start = map.get("start");
+        String end = map.get("end");
+        reportAlarmRecordRepository.deleteDateType(dateType.name(), start, end);
+        List<ReportAlarmRecord> save = new ArrayList<>();
+        result.forEach(item -> save.add((ReportAlarmRecord) item));
+        reportAlarmRecordRepository.saveAll(save);
+    }
+}

+ 118 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/InitDataService.java

@@ -0,0 +1,118 @@
+package com.persagy.dmp.report.service;
+
+import com.persagy.common.web.MapResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.sql.DataSource;
+import javax.transaction.Transactional;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * @author fengyanjie
+ */
+@Slf4j
+@Service
+public class InitDataService {
+
+    @Autowired
+    private DataSource dataSource;
+
+    @Transactional
+    public MapResponse initGroup(String createTime) {
+        MapResponse resp = new MapResponse();
+        String sql = null;
+        Connection connection = null;
+        Statement statement = null;
+        try {
+            connection = dataSource.getConnection();
+            statement = connection.createStatement();
+            // 创建对象信息统计报表
+            sql = getCreateReportRwdObjectSql(createTime);
+            statement.executeUpdate(sql);
+
+            // 创建报警信息统计报表
+            sql = getCreateReportAlarmRecordSql(createTime);
+            statement.executeUpdate(sql);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            resp.setFail(e.getMessage());
+        } finally {
+            close(statement);
+            close(connection);
+        }
+        return resp;
+    }
+
+    private String getCreateReportRwdObjectSql(String createTime) {
+        StringBuilder sql = new StringBuilder();
+        sql.append("  CREATE TABLE `report_rwd_object_" + createTime + "` (        \n");
+        sql.append("    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',        \n");
+        sql.append("    `project_id` varchar(50) NOT NULL COMMENT '项目id',        \n");
+        sql.append("    `group_code` varchar(40) DEFAULT NULL COMMENT '集团编码',        \n");
+        sql.append("    `obj_type` varchar(50) NOT NULL COMMENT '对象分类',        \n");
+        sql.append("    `class_code` varchar(50) NOT NULL COMMENT '对象类型编码',        \n");
+        sql.append("    `year` varchar(4) NOT NULL COMMENT '年',        \n");
+        sql.append("    `month` varchar(2) DEFAULT NULL COMMENT '月(小于10:01-09)',        \n");
+        sql.append("    `day` varchar(2) DEFAULT NULL COMMENT '日(小于10:01-09)',        \n");
+        sql.append("    `hour` varchar(2) DEFAULT NULL COMMENT '时(24小时制,小于10:01-09)',        \n");
+        sql.append("    `week` varchar(2) DEFAULT NULL COMMENT '周',        \n");
+        sql.append("    `season` varchar(1) DEFAULT NULL COMMENT '季度:1:0101-0401,2:0401-0701,3:0701-1001,4: 1001-0101  (日期前闭后开)',        \n");
+        sql.append("    `create_time` varchar(10) DEFAULT NULL COMMENT '创建时间  日期格式:yyyyMMddh24',        \n");
+        sql.append("    `rwd_object_num` int(11) DEFAULT '0' COMMENT '对象信息统计数量',        \n");
+        sql.append("    `date_type` varchar(100) NOT NULL COMMENT '日期类型(年:year 月:month 日:day 时:hour 周:week  季度:season)',        \n");
+        sql.append("    PRIMARY KEY (`id`)        \n");
+        sql.append("  ) ENGINE=InnoDB AUTO_INCREMENT=4206 DEFAULT CHARSET=utf8mb4 COMMENT='对象信息统计报表'       \n");
+        return sql.toString();
+    }
+
+    private String getCreateReportAlarmRecordSql(String createTime) {
+        StringBuilder sql = new StringBuilder();
+        sql.append("  CREATE TABLE `report_alarm_record_" + createTime + "` (                     \n");
+        sql.append("    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',                     \n");
+        sql.append("    `item_code` varchar(40) NOT NULL COMMENT '报警条目编码',                     \n");
+        sql.append("    `project_id` varchar(50) NOT NULL DEFAULT '' COMMENT '项目id',                     \n");
+        sql.append("    `group_code` varchar(40) DEFAULT NULL COMMENT '集团编码',                     \n");
+        sql.append("    `category` varchar(80) DEFAULT NULL COMMENT '报警分类',                     \n");
+        sql.append("    `class_code` varchar(50) DEFAULT NULL COMMENT '对象类型编码',                     \n");
+        sql.append("    `level` varchar(10) DEFAULT NULL COMMENT '严重程度',                     \n");
+        sql.append("    `alarm_state` varchar(2) DEFAULT NULL COMMENT '报警状态',                     \n");
+        sql.append("    `year` varchar(4) DEFAULT NULL COMMENT '年',                     \n");
+        sql.append("    `month` varchar(2) DEFAULT NULL COMMENT '月(小于10:01-09)',                     \n");
+        sql.append("    `day` varchar(2) DEFAULT NULL COMMENT '日(小于10:01-09)',                     \n");
+        sql.append("    `hour` varchar(2) DEFAULT NULL COMMENT '时(24小时制,小于10:01-09)',                     \n");
+        sql.append("    `week` varchar(2) DEFAULT NULL COMMENT '周',                     \n");
+        sql.append("    `season` varchar(1) DEFAULT NULL COMMENT '季度:1:0101-0401,2:0401-0701,3:0701-1001,4: 1001-0101  (日期前闭后开)',                     \n");
+        sql.append("    `create_time` varchar(10) DEFAULT NULL COMMENT '创建时间  日期格式:yyyyMMddh24',                     \n");
+        sql.append("    `alarm_record_num` int(11) DEFAULT '0' COMMENT '报警信息统计数量',                     \n");
+        sql.append("    `alarm_record_num2` int(11) DEFAULT NULL,                     \n");
+        sql.append("    `date_type` varchar(100) NOT NULL COMMENT '日期类型(年:year 月:month 日:day 时:hour 周:week  季度:season)',                     \n");
+        sql.append("    PRIMARY KEY (`id`)                     \n");
+        sql.append("  ) ENGINE=InnoDB AUTO_INCREMENT=39917 DEFAULT CHARSET=utf8mb4 COMMENT='报警信息统计报表';                     \n");
+        return sql.toString();
+    }
+
+    private void close(Statement statement) {
+        if (statement != null) {
+            try {
+                statement.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void close(Connection connection) {
+        if (connection != null) {
+
+            try {
+                connection.close();
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 86 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/ReportAlarmRecordService.java

@@ -0,0 +1,86 @@
+package com.persagy.dmp.report.service;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.criteria.CriteriaUtils;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.entity.BaseEntity;
+import com.persagy.dmp.report.entity.QReportAlarmRecord;
+import com.persagy.dmp.report.entity.ReportAlarmRecord;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.querydsl.core.Tuple;
+import com.querydsl.core.types.dsl.BooleanExpression;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author fengyanjie
+ */
+@Service
+public class ReportAlarmRecordService implements BaseService {
+
+    @Override
+    public List<BooleanExpression> parse(ObjectNode criteria) {
+        List<BooleanExpression> exps = new LinkedList<>();
+        QReportAlarmRecord qt = QReportAlarmRecord.reportAlarmRecord;
+        exps.addAll(CriteriaUtils.parse(qt.id, criteria.get("id")));
+        exps.addAll(CriteriaUtils.parse(qt.itemCode, criteria.get("itemCode")));
+        exps.addAll(CriteriaUtils.parse(qt.projectId, criteria.get("projectId")));
+        exps.addAll(CriteriaUtils.parse(qt.groupCode, criteria.get("groupCode")));
+        exps.addAll(CriteriaUtils.parse(qt.category, criteria.get("category")));
+        exps.addAll(CriteriaUtils.parse(qt.classCode, criteria.get("classCode")));
+        exps.addAll(CriteriaUtils.parse(qt.level, criteria.get("level")));
+        exps.addAll(CriteriaUtils.parse(qt.alarmState, criteria.get("alarm_state")));
+        exps.addAll(CriteriaUtils.parse(qt.createTime, criteria.get("createTime")));
+        exps.addAll(CriteriaUtils.parse(qt.alarmRecordNum, criteria.get("alarmRecordNum")));
+        exps.addAll(CriteriaUtils.parse(qt.dateType, criteria.get("dateType"), DateType.class));
+        return exps;
+    }
+
+    @Override
+    public List<BaseEntity> getData(PagedResponse<Tuple> tuplePagedResponse, List<JacksonCriteria.Calculated> calculatedColumns) {
+        List<BaseEntity> list = new ArrayList<>();
+        QReportAlarmRecord qt = QReportAlarmRecord.reportAlarmRecord;
+        tuplePagedResponse.getData().forEach(item -> {
+            ReportAlarmRecord entity = new ReportAlarmRecord();
+            entity.setId(item.get(qt.id));
+            entity.setItemCode(item.get(qt.itemCode));
+            entity.setProjectId(item.get(qt.projectId));
+            entity.setGroupCode(item.get(qt.groupCode));
+            entity.setCategory(item.get(qt.category));
+            entity.setClassCode(item.get(qt.classCode));
+            entity.setLevel(item.get(qt.level));
+            entity.setAlarmState(item.get(qt.alarmState));
+            entity.setYear(item.get(qt.year));
+            entity.setMonth(item.get(qt.month));
+            entity.setDay(item.get(qt.day));
+            entity.setHour(item.get(qt.hour));
+            entity.setSeason(item.get(qt.season));
+            entity.setWeek(item.get(qt.week));
+            entity.setCreateTime(item.get(qt.createTime));
+            entity.setAlarmRecordNum(item.get(qt.alarmRecordNum));
+            entity.setDateType(item.get(qt.dateType));
+            List<JacksonCriteria.Calculated> calculatedList = new ArrayList<>();
+            for (int i = 0; i < calculatedColumns.size(); i++) {
+                JacksonCriteria.Calculated calculated = new JacksonCriteria.Calculated();
+                if (calculatedColumns.get(i).getColumn().equals("alarmRecordNum")) {
+                    calculated.setColumn(calculatedColumns.get(i).getColumn());
+                    calculated.setFunction(calculatedColumns.get(i).getFunction());
+                    calculated.setValue(item.get(i, Long.class));
+                }
+                if (calculatedColumns.get(i).getColumn().equals("alarmRecordNum2")) {
+                    calculated.setColumn(calculatedColumns.get(i).getColumn());
+                    calculated.setFunction(calculatedColumns.get(i).getFunction());
+                    calculated.setValue(item.get(i, Long.class));
+                }
+                calculatedList.add(calculated);
+            }
+            entity.setCalculatedColumns(calculatedList);
+            list.add(entity);
+        });
+        return list;
+    }
+}

+ 50 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/ReportConfigService.java

@@ -0,0 +1,50 @@
+package com.persagy.dmp.report.service;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.criteria.CriteriaUtils;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.entity.BaseEntity;
+import com.persagy.dmp.report.entity.QReportConfig;
+import com.persagy.dmp.report.entity.ReportConfig;
+import com.querydsl.core.Tuple;
+import com.querydsl.core.types.dsl.BooleanExpression;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author fengyanjie
+ */
+@Service
+public class ReportConfigService implements BaseService {
+
+    @Override
+    public List<BooleanExpression> parse(ObjectNode criteria) {
+        List<BooleanExpression> exps = new LinkedList<>();
+        QReportConfig qt = QReportConfig.reportConfig;
+        exps.addAll(CriteriaUtils.parse(qt.calculated, criteria.get("calculated")));
+        exps.addAll(CriteriaUtils.parse(qt.tableName, criteria.get("tableName")));
+        exps.addAll(CriteriaUtils.parse(qt.mappingName, criteria.get("mappingName")));
+        exps.addAll(CriteriaUtils.parse(qt.groupColumn, criteria.get("group")));
+        return exps;
+    }
+
+    @Override
+    public List<BaseEntity> getData(PagedResponse<Tuple> tuplePagedResponse, List<JacksonCriteria.Calculated> calculatedColumns) {
+        List<BaseEntity> list = new ArrayList<>();
+        QReportConfig qt = QReportConfig.reportConfig;
+        tuplePagedResponse.getData().forEach(item -> {
+            ReportConfig entity = new ReportConfig();
+            entity.setCalculated(item.get(qt.calculated));
+            entity.setTableName(item.get(qt.tableName));
+            entity.setMappingName(item.get(qt.mappingName));
+            entity.setGroupColumn(item.get(qt.groupColumn));
+            entity.setTableGroup(item.get(qt.tableGroup));
+            list.add(entity);
+        });
+        return list;
+    }
+}

+ 76 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/ReportRwdObjectService.java

@@ -0,0 +1,76 @@
+package com.persagy.dmp.report.service;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.criteria.CriteriaUtils;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.entity.BaseEntity;
+import com.persagy.dmp.report.entity.QReportRwdObject;
+import com.persagy.dmp.report.entity.ReportRwdObject;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.querydsl.core.Tuple;
+import com.querydsl.core.types.dsl.BooleanExpression;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author fengyanjie
+ */
+@Service
+public class ReportRwdObjectService implements BaseService {
+
+    @Override
+    public List<BooleanExpression> parse(ObjectNode criteria) {
+        List<BooleanExpression> exps = new LinkedList<>();
+        QReportRwdObject qt = QReportRwdObject.reportRwdObject;
+        exps.addAll(CriteriaUtils.parse(qt.id, criteria.get("id")));
+        exps.addAll(CriteriaUtils.parse(qt.projectId, criteria.get("projectId")));
+        exps.addAll(CriteriaUtils.parse(qt.groupCode, criteria.get("groupCode")));
+        exps.addAll(CriteriaUtils.parse(qt.objType, criteria.get("objType")));
+        exps.addAll(CriteriaUtils.parse(qt.classCode, criteria.get("classCode")));
+        exps.addAll(CriteriaUtils.parse(qt.createTime, criteria.get("createTime")));
+        exps.addAll(CriteriaUtils.parse(qt.rwdObjectNum, criteria.get("rwdObjectNum")));
+        exps.addAll(CriteriaUtils.parse(qt.dateType, criteria.get("dateType"), DateType.class));
+        return exps;
+    }
+
+    @Override
+    public List<BaseEntity> getData(PagedResponse<Tuple> tuplePagedResponse, List<JacksonCriteria.Calculated> calculatedColumns) {
+        List<BaseEntity> list = new ArrayList<>();
+        QReportRwdObject qt = QReportRwdObject.reportRwdObject;
+        tuplePagedResponse.getData().forEach(item -> {
+            ReportRwdObject entity = new ReportRwdObject();
+            entity.setId(item.get(qt.id));
+            entity.setProjectId(item.get(qt.projectId));
+            entity.setGroupCode(item.get(qt.groupCode));
+            entity.setObjType(item.get(qt.objType));
+            entity.setClassCode(item.get(qt.classCode));
+            entity.setYear(item.get(qt.year));
+            entity.setMonth(item.get(qt.month));
+            entity.setDay(item.get(qt.day));
+            entity.setHour(item.get(qt.hour));
+            entity.setSeason(item.get(qt.season));
+            entity.setWeek(item.get(qt.week));
+            entity.setCreateTime(item.get(qt.createTime));
+            entity.setRwdObjectNum(item.get(qt.rwdObjectNum));
+            entity.setDateType(item.get(qt.dateType));
+            List<JacksonCriteria.Calculated> calculatedList = new ArrayList<>();
+            for (int i = 0; i < calculatedColumns.size(); i++) {
+                JacksonCriteria.Calculated calculated = new JacksonCriteria.Calculated();
+                if (calculatedColumns.get(i).getColumn().equals("rwdObjectNum")) {
+                    calculated = new JacksonCriteria.Calculated();
+                    calculated.setColumn(calculatedColumns.get(i).getColumn());
+                    calculated.setFunction(calculatedColumns.get(i).getFunction());
+                    calculated.setValue(item.get(i, Long.class));
+                }
+                calculatedList.add(calculated);
+            }
+            entity.setCalculatedColumns(calculatedList);
+            list.add(entity);
+        });
+        return list;
+    }
+}

+ 114 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/ReportService.java

@@ -0,0 +1,114 @@
+package com.persagy.dmp.report.service;
+
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.report.common.criteria.CriteriaUtils;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.common.json.JsonMapper;
+import com.persagy.dmp.report.entity.*;
+import com.persagy.dmp.report.repository.ReportConfigRepository;
+import com.querydsl.core.Tuple;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author fengyanjie
+ */
+@Service
+public class ReportService {
+
+    @Autowired
+    protected ReportConfigRepository reportConfigRepository;
+
+    @Autowired
+    protected CriteriaUtils criteriaUtils;
+
+    public PagedResponse<BaseEntity> query(JacksonCriteria criteria) {
+        PagedResponse<BaseEntity> response = new PagedResponse<>();
+        Map<String, List<JacksonCriteria.Calculated>> map = new HashMap<>();
+        for (JacksonCriteria.Calculated calculatedColumn : criteria.getCalculatedColumns()) {
+            ReportConfig reportConfig = getReportConfig(criteria.getGroupbyColumns(), calculatedColumn.getColumn());
+            if (null == reportConfig) {
+                response.setMessage(calculatedColumn.getColumn() + " 不支持该计算字段,请联系管理员。");
+                return response;
+            }
+            String mappingName = reportConfig.getMappingName();
+            List<JacksonCriteria.Calculated> list = map.get(mappingName);
+            if (null == list) {
+                list = new LinkedList<>();
+            }
+            list.add(calculatedColumn);
+            map.put(mappingName, list);
+        }
+        setData(map, criteria, response);
+        return response;
+    }
+
+    public void setData(Map<String, List<JacksonCriteria.Calculated>> map, JacksonCriteria criteria, PagedResponse<BaseEntity> response) {
+        List<BaseEntity> dataList = new LinkedList<>();
+        long count = 0;
+        for (Map.Entry<String, List<JacksonCriteria.Calculated>> entry : map.entrySet()) {
+            String key = entry.getKey();
+            List<JacksonCriteria.Calculated> value = entry.getValue();
+            PagedResponse<Tuple> tuplePagedResponse = null;
+            BaseService service = null;
+            switch (key) {
+                case "QReportAlarmRecord": {
+                    service = new ReportAlarmRecordService();
+                    tuplePagedResponse = criteriaUtils.groupbyQuery(QReportAlarmRecord.reportAlarmRecord, service::parse, criteria);
+                    break;
+                }
+                case "QReportRwdObject": {
+                    service = new ReportRwdObjectService();
+                    tuplePagedResponse = criteriaUtils.groupbyQuery(QReportRwdObject.reportRwdObject, service::parse, criteria);
+                    break;
+                }
+                default: {
+                    response.setMessage(key + " 该映射文件不存在,请联系管理员。");
+                    return;
+                }
+            }
+            count = tuplePagedResponse.getCount();
+            List<BaseEntity> data = service.getData(tuplePagedResponse, value);
+            setData(dataList, data, criteria.getGroupbyColumns());
+        }
+        response.setData(dataList);
+        response.setCount(count);
+    }
+
+    public void setData(List<BaseEntity> dataList, List<BaseEntity> data, Set<String> groupbyColumns) {
+        if (0 == dataList.size()) {
+            dataList.addAll(data);
+            return;
+        }
+        for (BaseEntity datum : data) {
+            for (BaseEntity entity : dataList) {
+                boolean bool = true;
+                Map<String, Object> dataMap = JsonMapper.json2map(JsonMapper.toSimpleJson(datum));
+                Map<String, Object> dataListMap = JsonMapper.json2map(JsonMapper.toSimpleJson(entity));
+                for (String groupbyColumn : groupbyColumns) {
+                    if (null == dataMap.get(groupbyColumn) || !dataMap.get(groupbyColumn).equals(dataListMap.get(groupbyColumn))) {
+                        bool = false;
+                    }
+                }
+                if (bool) {
+                    entity.getCalculatedColumns().addAll(datum.getCalculatedColumns());
+                }
+            }
+        }
+    }
+
+    public ReportConfig getReportConfig(Set<String> groupbyColumns, String calculatedColumn) {
+        QReportConfig qt = QReportConfig.reportConfig;
+        Optional<ReportConfig> one = reportConfigRepository.findOne(qt.calculated.eq(calculatedColumn));
+        if (!one.isPresent()) {
+            return null;
+        }
+        List<String> groupList = Arrays.asList(one.get().getGroupColumn().split(","));
+        if (groupList.containsAll(groupbyColumns)) {
+            return one.get();
+        }
+        return null;
+    }
+}

+ 476 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/ReportUtils.java

@@ -0,0 +1,476 @@
+package com.persagy.dmp.report.service;
+
+import com.persagy.common.date.DateUtils;
+import com.persagy.dmp.config.DmpParameterStorage;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.entity.*;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.repository.ReportConfigGroupRepository;
+import com.persagy.dmp.report.repository.ReportConfigRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author fengyanjie
+ */
+@Slf4j
+@Service
+public class ReportUtils {
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    @Autowired
+    private ReportConfigRepository reportConfigRepository;
+
+    @Autowired
+    private ReportConfigGroupRepository reportConfigGroupRepository;
+
+    /**
+     * 多维度处理
+     *
+     * @param index     下标
+     * @param groupList 维度数据
+     * @param clazz     对象实例
+     * @param list      处理后的数据
+     * @throws Exception
+     */
+    public List<BaseEntity> initData(Integer index, List<ReportConfigGroup> groupList, Class<? extends BaseEntity> clazz, List<BaseEntity> list) throws Exception {
+        if (index == groupList.size()) {
+            return list;
+        }
+        ReportConfigGroup reportConfigGroup = groupList.get(index);
+        List<Object[]> groupValueList = reportConfigGroup.getValueList();
+        String[] conlumnNameList = reportConfigGroup.getConlumnName().split(",");
+        int nextIndex = (index + 1);
+        if (0 != groupValueList.size()) {
+            initData(0, groupValueList, conlumnNameList, clazz, new ArrayList<>(), list);
+        }
+        return initData(nextIndex, groupList, clazz, list);
+    }
+
+    /**
+     * 组合维度处理
+     *
+     * @param index           下标
+     * @param groupValueList  组合维度值
+     * @param conlumnNameList 组合维度名称
+     * @param clazz           对象实例
+     * @param resultList      处理后的数据
+     * @param list            原数据
+     */
+    private void initData(Integer index, List<Object[]> groupValueList, String[] conlumnNameList, Class<? extends BaseEntity> clazz, List<BaseEntity> resultList, List<BaseEntity> list) throws Exception {
+        if (index == groupValueList.size()) {
+            list.clear();
+            list.addAll(resultList);
+            return;
+        }
+        Object[] valueList = groupValueList.get(index);
+        if (0 == list.size()) {
+            BaseEntity result = clazz.getDeclaredConstructor().newInstance();
+            for (int i = 0; i < conlumnNameList.length; i++) {
+                String conlumnName = conlumnNameList[i];
+                Object value = valueList[i];
+                setValue(value, conlumnName, clazz, result);
+            }
+            resultList.add(result);
+        } else {
+            for (BaseEntity baseEntity : list) {
+                Constructor<?> constructor = clazz.getConstructor(baseEntity.getClass());
+                BaseEntity result = (BaseEntity) constructor.newInstance(baseEntity);
+                for (int i = 0; i < conlumnNameList.length; i++) {
+                    String conlumnName = conlumnNameList[i];
+                    Object value = valueList[i];
+                    setValue(value, conlumnName, clazz, result);
+                }
+                resultList.add(result);
+            }
+        }
+        int nextIndex = index + 1;
+        initData(nextIndex, groupValueList, conlumnNameList, clazz, resultList, list);
+    }
+
+    private void setValue(Object value, String conlumnName, Class clazz, BaseEntity result) throws Exception {
+        String val = value.toString();
+        if (conlumnName.equals("year")) {
+            Method dateMethod = BeanUtils.findMethod(clazz, "setCreateTime", value.getClass());
+            dateMethod.invoke(result, val);
+        } else if (conlumnName.equals("month")) {
+            Method dateMethod = BeanUtils.findMethod(clazz, "setCreateTime", value.getClass());
+            dateMethod.invoke(result, val);
+            dateMethod = BeanUtils.findMethod(clazz, "setYear", value.getClass());
+            dateMethod.invoke(result, val.substring(0, 4));
+            value = val.substring(4, 6);
+        } else if (conlumnName.equals("day")) {
+            Method dateMethod = BeanUtils.findMethod(clazz, "setCreateTime", value.getClass());
+            dateMethod.invoke(result, val);
+            dateMethod = BeanUtils.findMethod(clazz, "setYear", value.getClass());
+            dateMethod.invoke(result, val.substring(0, 4));
+            dateMethod = BeanUtils.findMethod(clazz, "setMonth", value.getClass());
+            dateMethod.invoke(result, val.substring(4, 6));
+            value = val.substring(6, 8);
+        } else if (conlumnName.equals("hour")) {
+            Method dateMethod = BeanUtils.findMethod(clazz, "setCreateTime", value.getClass());
+            dateMethod.invoke(result, val);
+            dateMethod = BeanUtils.findMethod(clazz, "setYear", value.getClass());
+            dateMethod.invoke(result, val.substring(0, 4));
+            dateMethod = BeanUtils.findMethod(clazz, "setMonth", value.getClass());
+            dateMethod.invoke(result, val.substring(4, 6));
+            dateMethod = BeanUtils.findMethod(clazz, "setDay", value.getClass());
+            dateMethod.invoke(result, val.substring(6, 8));
+            value = val.substring(8, 10);
+        }
+        String methodName = under2camel(conlumnName);
+        Method method = BeanUtils.findMethod(clazz, "set" + methodName, value.getClass());
+        if (null == method) {
+            throw new Exception("set" + methodName + " 方法不存在。");
+        }
+        method.invoke(result, value);
+    }
+
+    private String concat(TreeSet<String> set) {
+        StringBuilder buff = new StringBuilder();
+        set.forEach(str -> buff.append(str).append("|"));
+        return buff.toString();
+    }
+
+    /**
+     * 添加不重复的统计数据
+     *
+     * @param list              已统计数据
+     * @param resultList        总维度统计数据
+     * @param calculatedColumns 计算列
+     */
+    public List<BaseEntity> addList(List<BaseEntity> list, List<BaseEntity> resultList, List<JacksonCriteria.Calculated> calculatedColumns) throws InvocationTargetException, IllegalAccessException {
+        log.info("begin time:{}  list.size:{} resultList.size:{} calculatedColumns.size:{}", DateUtils.format(new Date()), list.size(), resultList.size(), calculatedColumns.size());
+        String groupCode = DmpParameterStorage.getGroupCode();
+        String projectId = DmpParameterStorage.getProjectId();
+        Set<String> columnNameList = new HashSet<>();
+        calculatedColumns.forEach(item -> columnNameList.add(item.getColumn()));
+
+        Map<String, BaseEntity> maps = resultList.stream().collect(Collectors.toMap(entity -> {
+            TreeSet<String> treeSet = new TreeSet<>();
+            Field[] fields = entity.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                String columnName = field.getName();
+                String methodName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
+                try {
+                    //处理计算字段
+                    if (columnNameList.contains(columnName)) {
+                        Method method = BeanUtils.findMethod(entity.getClass(), "set" + methodName, Integer.class);
+                        Object val = 0;
+                        if (null == method) {
+                            method = BeanUtils.findMethod(entity.getClass(), "set" + methodName, Double.class);
+                            val = 0.0D;
+                        }
+                        if (null == method) {
+                            method = BeanUtils.findMethod(entity.getClass(), "set" + methodName, Long.class);
+                            val = 0L;
+                        }
+                        method.invoke(entity, val);
+                        continue;
+                    }
+                    //拼接key
+                    Method method = null;
+                    Object value = null;
+                    if ("ProjectId".equals(methodName)) {
+                        method = BeanUtils.findMethod(entity.getClass(), "set" + methodName, String.class);
+                        method.invoke(entity, projectId);
+                        value = projectId;
+                    } else if ("GroupCode".equals(methodName)) {
+                        method = BeanUtils.findMethod(entity.getClass(), "set" + methodName, String.class);
+                        method.invoke(entity, groupCode);
+                        value = groupCode;
+                    } else {
+                        method = BeanUtils.findMethod(entity.getClass(), "get" + methodName);
+                        value = method.invoke(entity);
+                    }
+                    treeSet.add(columnName + "=" + value);
+                } catch (IllegalAccessException | InvocationTargetException e) {
+                    e.printStackTrace();
+                }
+            }
+            String key = concat(treeSet);
+            return key;
+        }, Function.identity()));
+
+        for (BaseEntity data : list) {
+            TreeSet<String> treeSet = new TreeSet<>();
+            Field[] fields = data.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                String columnName = field.getName();
+                if (columnNameList.contains(columnName)) {
+                    continue;
+                }
+                String methodName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
+                Method dataMethod = BeanUtils.findMethod(data.getClass(), "get" + methodName);
+                Object invoke = dataMethod.invoke(data);
+                treeSet.add(columnName + "=" + invoke);
+            }
+            String key = concat(treeSet);
+            BaseEntity entity = maps.get(key);
+            if (null != entity) {
+                maps.put(key, data);
+            }
+        }
+
+        List<BaseEntity> result = new ArrayList<>(maps.values());
+        log.info("end time:{}  list.size:{} resultList.size:{} calculatedColumns.size:{}", DateUtils.format(new Date()), list.size(), resultList.size(), calculatedColumns.size());
+        return result;
+    }
+
+    /**
+     * 获取所有的统计维度
+     */
+    public List<ReportConfigGroup> getGroupList(List<Object> groupList, DateType dateType, Date startTime, Date endTime) throws Exception {
+        List<ReportConfigGroup> result = new ArrayList<>();
+        List<String> conlumnNameList = new ArrayList<>();
+        for (Object obj : groupList) {
+            List<String> group = (List<String>) obj;
+            StringBuilder str = new StringBuilder();
+            group.forEach(item -> {
+                str.append(item).append(",");
+            });
+            String conlumnName = str.deleteCharAt(str.length() - 1).toString();
+            conlumnNameList.add(conlumnName);
+        }
+        QReportConfigGroup groupQt = QReportConfigGroup.reportConfigGroup;
+        Iterable<ReportConfigGroup> groupAll = reportConfigGroupRepository.findAll(groupQt.conlumnName.in(conlumnNameList));
+        for (ReportConfigGroup reportConfigGroup : groupAll) {
+            if (1 == reportConfigGroup.getValueType()) {
+                List<Object[]> valueList = new ArrayList<>();
+                String[] split = reportConfigGroup.getValue().split(",");
+                for (String value : split) {
+                    valueList.add(new String[]{value});
+                }
+                reportConfigGroup.setValueList(valueList);
+            }
+            if (2 == reportConfigGroup.getValueType()) {
+                Class<?> groupClazz = Class.forName(reportConfigGroup.getValue());
+                Method groupMethod = BeanUtils.findMethod(groupClazz, reportConfigGroup.getMethod());
+                List<Object[]> invoke = (List<Object[]>) groupMethod.invoke(applicationContext.getBean(groupClazz));
+                reportConfigGroup.setValueList(invoke);
+            }
+            result.add(reportConfigGroup);
+        }
+        addDateType(result, dateType, startTime, endTime);
+        result.add(new ReportConfigGroup("date_type", Collections.singletonList(new Object[]{dateType})));
+        return result;
+    }
+
+    /**
+     * 根据日期类型 返回时间范围内的所有日期
+     */
+    private void addDateType(List<ReportConfigGroup> groupList, DateType dateType, Date startTime, Date endTime) {
+        List<Object[]> year = new ArrayList<>();
+        List<Object[]> month = new ArrayList<>();
+        List<Object[]> day = new ArrayList<>();
+        List<Object[]> hour = new ArrayList<>();
+
+        if (DateType.YEAR == dateType) {
+            Set<String> yearList = getDateList(startTime, endTime, DateUtils.PATTERN_yyyy, Calendar.YEAR);
+            yearList.forEach(item -> year.add(new Object[]{item}));
+        }
+        if (DateType.MONTH == dateType) {
+            Set<String> monthList = getDateList(startTime, endTime, DateUtils.PATTERN_yyyyMM, Calendar.MONTH);
+            monthList.forEach(item -> month.add(new Object[]{item}));
+        }
+        if (DateType.DAY == dateType) {
+            Set<String> dayList = getDateList(startTime, endTime, DateUtils.PATTERN_yyyyMMdd, Calendar.DAY_OF_YEAR);
+            dayList.forEach(item -> day.add(new Object[]{item}));
+        }
+        if (DateType.HOUR == dateType) {
+            Set<String> hourList = getDateList(startTime, endTime, "yyyyMMddHH", Calendar.HOUR_OF_DAY);
+            hourList.forEach(item -> hour.add(new Object[]{item}));
+        }
+        if (DateType.SEASON == dateType) {
+            //TODO
+        }
+        groupList.add(new ReportConfigGroup("year", year));
+        groupList.add(new ReportConfigGroup("month", month));
+        groupList.add(new ReportConfigGroup("day", day));
+        groupList.add(new ReportConfigGroup("hour", hour));
+    }
+
+    /**
+     * 查询报表配置信息
+     */
+    public ReportConfig queryReportConfig(String tableName) {
+        QReportConfig configQt = QReportConfig.reportConfig;
+        Iterable<ReportConfig> configAll = reportConfigRepository.findAll(configQt.tableName.eq(tableName));
+        ReportConfig reportConfig = new ReportConfig();
+        configAll.forEach(item -> {
+            reportConfig.setCalculated(item.getCalculated());
+            reportConfig.setTableGroup(item.getTableGroup());
+            reportConfig.setGroupColumn(item.getGroupColumn());
+            reportConfig.setMappingName(item.getMappingName());
+            reportConfig.setTableName(item.getTableName());
+            if (null == reportConfig.getCalculatedColumns()) {
+                reportConfig.setCalculatedColumns(new ArrayList<>());
+            }
+            reportConfig.getCalculatedColumns().add(new JacksonCriteria.Calculated(item.getCalculated()));
+        });
+        return reportConfig;
+    }
+
+    /**
+     * 根据日期类型 拼接合适的统计sql 和 返回合适的日期格式
+     */
+    public void appendSql(StringBuilder sql, DateType dateType) {
+        if (DateType.YEAR == dateType) {
+            sql.append("        date_format(create_time, '%Y') year,'null' as month,'null' as day,'null' as hour,'null' as season,date_format(create_time, '%Y') date,          \n");
+        }
+        if (DateType.MONTH == dateType) {
+            sql.append("        date_format(create_time, '%Y') year,date_format(create_time, '%m') month,'null' as day,'null' as hour,'null' as season,date_format(create_time, '%Y%m') date,          \n");
+        }
+        if (DateType.DAY == dateType) {
+            sql.append("        date_format(create_time, '%Y') year,date_format(create_time, '%m') month,date_format(create_time, '%d') day,'null' as hour,'null' as season,date_format(create_time, '%Y%m%d') date,          \n");
+        }
+        if (DateType.HOUR == dateType) {
+            sql.append("        date_format(create_time, '%Y') year,date_format(create_time, '%m') month,date_format(create_time, '%d') day,date_format(create_time, '%h') hour,'null' as season,date_format(create_time, '%Y%m%d%h') date,          \n");
+        }
+        if (DateType.SEASON == dateType) {
+            sql.append("        date_format(create_time, '%Y') year,'null' as month,'null' as day,'null' as hour,          \n");
+            sql.append("        QUARTER(create_time) season,CONCAT(date_format(create_time, '%Y'),(case QUARTER(create_time) when 1 then '01' when 2 then '04' when 3 then '07' when 4 then '10' end)) as date,          \n");
+        }
+    }
+
+    /**
+     * 根据日期类型 返回合适的日期格式
+     */
+    public Map<String, String> getDate(DateType dateType, Date startTime, Date endTime) {
+        Map<String, String> map = new HashMap<>();
+        String start = "";
+        String end = "";
+        if (DateType.YEAR == dateType) {
+            start = DateUtils.format(startTime, DateUtils.PATTERN_yyyy);
+            end = DateUtils.format(endTime, DateUtils.PATTERN_yyyy);
+        }
+        if (DateType.MONTH == dateType) {
+            start = DateUtils.format(startTime, DateUtils.PATTERN_yyyyMM);
+            end = DateUtils.format(endTime, DateUtils.PATTERN_yyyyMM);
+        }
+        if (DateType.DAY == dateType) {
+            start = DateUtils.format(startTime, DateUtils.PATTERN_yyyyMMdd);
+            end = DateUtils.format(endTime, DateUtils.PATTERN_yyyyMMdd);
+        }
+        if (DateType.HOUR == dateType) {
+            start = DateUtils.format(startTime, "yyyyMMddHH");
+            end = DateUtils.format(endTime, "yyyyMMddHH");
+        }
+        if (DateType.SEASON == dateType) {
+            start = DateUtils.format(startTime, DateUtils.PATTERN_yyyyMM);
+            end = DateUtils.format(endTime, DateUtils.PATTERN_yyyyMM);
+        }
+        map.put("start", start);
+        map.put("end", end);
+        return map;
+    }
+
+    /**
+     * 获取两个日期之间的所有月份
+     *
+     * @param start 开始日期 yyyyMM
+     * @param end   结束日期 yyyyMM
+     * @return 月份集合 {“yyyyMM”}
+     */
+    private Set<String> getDateList(Date start, Date end, String pattern, Integer field) {
+        Set<String> result = new HashSet<>();
+        Calendar tempStart = Calendar.getInstance();
+        tempStart.setTime(start);
+        tempStart.add(field, 1);
+        Calendar tempEnd = Calendar.getInstance();
+        tempEnd.setTime(end);
+        result.add(DateUtils.format(start, pattern));
+        while (tempStart.before(tempEnd)) {
+            result.add(DateUtils.format(tempStart.getTime(), pattern));
+            tempStart.add(field, 1);
+        }
+        return result;
+    }
+
+    /**
+     * 下划线命名转驼峰命名
+     */
+    public String under2camel(String s) {
+        String separator = "_";
+        String under = "";
+        s = s.toLowerCase().replace(separator, " ");
+        String sarr[] = s.split(" ");
+        for (int i = 0; i < sarr.length; i++) {
+            String w = sarr[i].substring(0, 1).toUpperCase() + sarr[i].substring(1);
+            under += w;
+        }
+        return under;
+    }
+
+    /**
+     * 根据日期类型返回合适的日期格式
+     */
+    public Map<String, Date> getDateTime(DateType dateType) {
+        Map<String, Date> map = new HashMap<>();
+        Date startTimeDate = null;
+        Date endTimeDate = null;
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        if (DateType.YEAR == dateType) {
+            calendar.set(Calendar.MONTH, 0);
+            calendar.set(Calendar.DATE, 1);
+            calendar.set(Calendar.HOUR_OF_DAY, 0);
+            startTimeDate = calendar.getTime();
+            endTimeDate = DateUtils.add(startTimeDate, Calendar.YEAR, 1);
+        }
+        if (DateType.MONTH == dateType) {
+            calendar.set(Calendar.DATE, 1);
+            calendar.set(Calendar.HOUR_OF_DAY, 0);
+            startTimeDate = calendar.getTime();
+            endTimeDate = DateUtils.add(startTimeDate, Calendar.MONTH, 1);
+        }
+        if (DateType.DAY == dateType) {
+            calendar.set(Calendar.HOUR_OF_DAY, 0);
+            startTimeDate = calendar.getTime();
+            endTimeDate = DateUtils.add(startTimeDate, Calendar.DATE, 1);
+        }
+        if (DateType.HOUR == dateType) {
+            startTimeDate = calendar.getTime();
+            endTimeDate = DateUtils.add(startTimeDate, Calendar.HOUR_OF_DAY, 1);
+        }
+        if (DateType.SEASON == dateType) {
+            int month = calendar.get(Calendar.MONTH);
+            if (3 > month) {
+                calendar.set(Calendar.MONTH, 0);
+            }
+            if (3 <= month && 6 > month) {
+                calendar.set(Calendar.MONTH, 3);
+            }
+            if (6 <= month && 9 > month) {
+                calendar.set(Calendar.MONTH, 6);
+            }
+            if (9 <= month) {
+                calendar.set(Calendar.MONTH, 9);
+            }
+            calendar.set(Calendar.DATE, 1);
+            calendar.set(Calendar.HOUR_OF_DAY, 0);
+            startTimeDate = calendar.getTime();
+            endTimeDate = DateUtils.add(startTimeDate, Calendar.MONTH, 3);
+        }
+        map.put("startTimeDate", startTimeDate);
+        map.put("endTimeDate", endTimeDate);
+        return map;
+    }
+}

+ 56 - 0
dmp-report/src/main/java/com/persagy/dmp/report/service/TestService.java

@@ -0,0 +1,56 @@
+package com.persagy.dmp.report.service;
+
+import com.persagy.common.criteria.JpaUtils;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author fengyanjie
+ */
+@Slf4j
+@Service
+public class TestService {
+
+    @Autowired
+    private JpaUtils jpaUtils;
+
+    @Autowired
+    JPAQueryFactory queryFactory;
+
+    public List<Object[]> itemCode() {
+        List<Object[]> result = new ArrayList<>();
+        String sql = "select distinct code from dmp_alarm.alarm_item where valid = 1";
+        List<Map<String, Object>> list = jpaUtils.queryList(sql);
+        for (Map<String, Object> map : list) {
+            result.add(new String[]{MapUtils.getString(map, "code")});
+        }
+        return result;
+    }
+
+    public List<Object[]> category() {
+        List<Object[]> result = new ArrayList<>();
+        String sql = "select distinct category from dmp_alarm.alarm_item where valid = 1";
+        List<Map<String, Object>> list = jpaUtils.queryList(sql);
+        for (Map<String, Object> map : list) {
+            result.add(new String[]{MapUtils.getString(map, "category")});
+        }
+        return result;
+    }
+
+    public List<Object[]> classCodeObjType() {
+        List<Object[]> result = new ArrayList<>();
+        String sql = "select distinct code,obj_type from dmp_rwd.rwd_def_class";
+        List<Map<String, Object>> list = jpaUtils.queryList(sql);
+        for (Map<String, Object> map : list) {
+            result.add(new String[]{MapUtils.getString(map, "code"), MapUtils.getString(map, "obj_type")});
+        }
+        return result;
+    }
+}

+ 5 - 0
dmp-report/src/main/resources/bootstrap-aliyun-test.yml

@@ -0,0 +1,5 @@
+spring:
+  cloud:
+    config:
+      profile: aliyun-test
+      uri: http://172.17.100.14:9932

+ 10 - 0
dmp-report/src/main/resources/bootstrap.yml

@@ -0,0 +1,10 @@
+spring:
+  application:
+    name: dmp-report
+  profiles:
+    active:
+      - dev
+  cloud:
+    config:
+      profile: dev
+      uri: http://localhost:9932

+ 143 - 0
dmp-report/src/test/java/com/persagy/dmp.report/test.java

@@ -0,0 +1,143 @@
+package com.persagy.dmp.report;
+
+import com.persagy.common.date.DateUtils;
+import com.persagy.common.json.JacksonMapper;
+import com.persagy.dmp.report.common.criteria.JacksonCriteria;
+import com.persagy.dmp.report.common.json.JsonMapper;
+import com.persagy.dmp.report.entity.BaseEntity;
+import com.persagy.dmp.report.entity.ReportAlarmRecord;
+import com.persagy.dmp.report.entity.ReportConfigGroup;
+import com.persagy.dmp.report.enumeration.DateType;
+import com.persagy.dmp.report.service.DataExecutorService;
+import com.persagy.dmp.report.service.ReportUtils;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class test {
+
+    @Autowired
+    JPAQueryFactory queryFactory;
+
+    @Autowired
+    DataExecutorService dataExecutorService;
+
+    @Autowired
+    ReportUtils reportUtils;
+
+//    @Test
+//    public void test1() {
+//        QAlarmItem qt = QAlarmItem.alarmItem;
+//        List<String> fetch = queryFactory.selectDistinct(qt.code).from(qt).where(qt.valid.eq(1)).fetch();
+//        fetch.forEach(item -> System.out.println(item));
+//    }
+
+    @Test
+    public void test2() throws Exception {
+        List<ReportConfigGroup> reportConfigGroupList = new ArrayList<>();
+        List<Object[]> valueList = Arrays.asList(new String[]{"1022", "Eq"},
+                new String[]{"1022", "Sy"},
+                new String[]{"1021", "Eq"},
+                new String[]{"1021", "Sy"},
+                new String[]{"1009", "Sp"},
+                new String[]{"1009", "Bd"},
+                new String[]{"1020", "Sp"},
+                new String[]{"1020", "Bd"}
+        );
+        ReportConfigGroup itemCodeCategory = new ReportConfigGroup("item_code,category", valueList);
+
+        reportConfigGroupList.add(itemCodeCategory);
+        List<Object[]> level = Arrays.asList(new String[]{"A"}, new String[]{"B"}, new String[]{"C"});
+        reportConfigGroupList.add(new ReportConfigGroup("level", level));
+        List<Object[]> alarm_state = Collections.singletonList(new String[]{"1"});
+        reportConfigGroupList.add(new ReportConfigGroup("alarm_state", alarm_state));
+        List<Object[]> class_code = Collections.singletonList(new String[]{"ACCCOP"});
+        reportConfigGroupList.add(new ReportConfigGroup("class_code", class_code));
+        reportConfigGroupList.add(new ReportConfigGroup("project_id", Collections.singletonList(new String[]{"Pj1101050029"})));
+
+        List<BaseEntity> list = new ArrayList<>();
+
+        ReportAlarmRecord entity = new ReportAlarmRecord();
+        entity.setItemCode("1022");
+        entity.setCategory("Sy");
+        entity.setLevel("A");
+        entity.setAlarmState("1");
+        entity.setClassCode("ACCCOP");
+        entity.setProjectId("Pj1101050029");
+        list.add(entity);
+
+        ReportAlarmRecord entity2 = new ReportAlarmRecord();
+        entity2.setItemCode("1010");
+        entity2.setProjectId("Pj1101050029");
+        entity2.setCategory("Sp");
+        entity2.setClassCode("ACATFC");
+        entity2.setLevel("D");
+        entity2.setAlarmState("4");
+        entity2.setYear("2020");
+        entity2.setCreateTime("2020");
+        entity2.setDateType(DateType.YEAR);
+        entity2.setAlarmRecordNum(123456L);
+        list.add(entity2);
+
+        List<JacksonCriteria.Calculated> calculatedColumns = new ArrayList<>();
+        calculatedColumns.add(new JacksonCriteria.Calculated("alarmRecordNum"));
+        calculatedColumns.add(new JacksonCriteria.Calculated("alarmRecordNum2"));
+        System.err.println(JacksonMapper.toFormatJson(reportConfigGroupList));
+        List<BaseEntity> resultList = new ArrayList<>();
+        reportUtils.initData(0, reportConfigGroupList, ReportAlarmRecord.class, resultList);
+        reportUtils.addList(list, resultList, calculatedColumns);
+
+        System.err.println(JacksonMapper.toFormatJson(list));
+    }
+
+
+    @Test
+    public void test3() throws Exception {
+        String tableName = "alarm_record";
+        //统计数据
+        dataExecutorService.reportAlarmRecord(DateType.YEAR, DateUtils.parse("20200101000000"), DateUtils.parse("20210101000000"));
+    }
+
+    @Test
+    public void test4() throws Exception {
+        String tableName = "rwd_object";
+        //统计数据
+        dataExecutorService.reportRwdObject(DateType.YEAR, DateUtils.parse("20200101000000"), DateUtils.parse("20210101000000"));
+    }
+
+
+    @Test
+    public void test5() throws Exception {
+        String json = "[[\"item_code\"],[\"project_id\"],[\"category\"],[\"obj_id\"],[\"class_code\"],[\"level\"],[\"alarm_state\"]]";
+        List<Object> list = JsonMapper.json2List(json);
+        System.err.println(list);
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+